Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions shai-cli/src/fc/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@ impl ShaiSessionClient {
let response = ShaiProtocol::read_response(&mut stream)?;

match response {
ShaiResponse::Ok { data: ResponseData::Commands(entries) } => Ok(entries.into()),
ShaiResponse::Ok { data: ResponseData::Commands(entries) } => {
// Handle empty vec to avoid creating buffer with capacity 0
if entries.is_empty() {
Ok(CommandHistory::new(1))
} else {
Ok(entries.into())
}
},
ShaiResponse::Ok { .. } => Err("Unexpected response type".into()),
ShaiResponse::Error { message } => Err(message.into()),
}
Expand All @@ -41,7 +48,14 @@ impl ShaiSessionClient {
let response = ShaiProtocol::read_response(&mut stream)?;

match response {
ShaiResponse::Ok { data: ResponseData::Commands(entries) } => Ok(entries.into()),
ShaiResponse::Ok { data: ResponseData::Commands(entries) } => {
// Handle empty vec to avoid creating buffer with capacity 0
if entries.is_empty() {
Ok(CommandHistory::new(1))
} else {
Ok(entries.into())
}
},
ShaiResponse::Ok { .. } => Err("Unexpected response type".into()),
ShaiResponse::Error { message } => Err(message.into()),
}
Expand Down
13 changes: 10 additions & 3 deletions shai-cli/src/fc/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::fc::protocol::{ShaiProtocol, ShaiRequest, ShaiResponse, ResponseData}
/// Socket server for serving command history data
pub struct ShaiSessionServer {
history: Arc<Mutex<CommandHistory>>,
history_capacity: usize,
socket_path: String,
shutdown: Arc<AtomicBool>,
pending_command: Arc<Mutex<Option<String>>>,
Expand All @@ -20,6 +21,7 @@ impl ShaiSessionServer {
pub fn new(session_id: &str, history_size: usize, output_buffer_size: usize) -> Self {
Self {
history: Arc::new(Mutex::new(CommandHistory::new(history_size))),
history_capacity: history_size,
socket_path: format!("/tmp/shai_history_{}", session_id),
shutdown: Arc::new(AtomicBool::new(false)),
pending_command: Arc::new(Mutex::new(None)),
Expand All @@ -38,6 +40,7 @@ impl ShaiSessionServer {

let listener = UnixListener::bind(&self.socket_path)?;
let history = Arc::clone(&self.history);
let history_capacity = self.history_capacity;
let socket_path = self.socket_path.clone();
let shutdown = Arc::clone(&self.shutdown);
let pending_command = Arc::clone(&self.pending_command);
Expand All @@ -53,7 +56,7 @@ impl ShaiSessionServer {
let history = Arc::clone(&history);
let pending_command = Arc::clone(&pending_command);
thread::spawn(move || {
if let Err(e) = Self::handle_client(stream, history, pending_command) {
if let Err(e) = Self::handle_client(stream, history, history_capacity, pending_command) {
eprintln!("Error handling client: {}", e);
}
});
Expand Down Expand Up @@ -81,11 +84,12 @@ impl ShaiSessionServer {
fn handle_client(
mut stream: UnixStream,
history: Arc<Mutex<CommandHistory>>,
history_capacity: usize,
pending_command: Arc<Mutex<Option<String>>>,
) -> Result<(), Box<dyn std::error::Error>> {
let request = ShaiProtocol::read_request(&mut stream)?;

let response = Self::process_request(request, &history, &pending_command);
let response = Self::process_request(request, &history, history_capacity, &pending_command);
ShaiProtocol::write_response(&mut stream, &response)?;

Ok(())
Expand All @@ -94,6 +98,7 @@ impl ShaiSessionServer {
fn process_request(
request: ShaiRequest,
history_ref: &Arc<Mutex<CommandHistory>>,
history_capacity: usize,
pending_command_ref: &Arc<Mutex<Option<String>>>,
) -> ShaiResponse {
match request {
Expand Down Expand Up @@ -133,7 +138,9 @@ impl ShaiSessionServer {
ShaiRequest::Clear => {
match history_ref.lock() {
Ok(mut history) => {
history.clear();
// Recreate the buffer with the original capacity instead of calling clear()
// because AllocRingBuffer::clear() sets capacity to 0
*history = CommandHistory::new(history_capacity);
ShaiResponse::Ok { data: ResponseData::Empty }
}
Err(_) => ShaiResponse::Error { message: "Lock error".to_string() },
Expand Down
4 changes: 2 additions & 2 deletions shai-core/src/runners/gerund/prompt.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

static GERUND_PROMPT: &str = r#"
Transform the user's request into a single uplifting verb ending in -ing that captures the essence of their message. Your response must be exactly one word - no explanations, no punctuation, no extra text. Capitalize only the first letter.
Transform the user's request into a single uplifting gerund (verb ending in -ing) that captures the essence of their message. Your response must be exactly one word - no explanations, no punctuation, no extra text. Capitalize only the first letter.

Guidelines for word selection:
• Choose words that spark joy and convey progress
• Choose positive, cheerful words that spark joy and convey progress
• Prioritize creativity and linguistic flair - unusual or sophisticated words are encouraged
• Ensure strong thematic connection to the user's intent
• Craft words that would make a developer smile when seen as a status indicator
Expand Down
6 changes: 4 additions & 2 deletions shai-core/src/tools/todo/todo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,19 @@ impl TodoWriteTool {
async fn execute(&self, params: TodoWriteParams) -> ToolResult {
// Convert input todos to full TodoItems
let todo_items: Vec<TodoItem> = params.todos.into_iter().map(|input| input.into()).collect();
let count = todo_items.len();

// Replace entire list
self.storage.replace_all(todo_items.clone()).await;

let output = self.storage.format_all(&todo_items);
let formatted_todos = self.storage.format_all(&todo_items);
let output = format!("Updated {} todo items.\n\n{}", count, formatted_todos);

ToolResult::Success {
output,
metadata: Some({
let mut meta = HashMap::new();
meta.insert("todo_count".to_string(), json!(todo_items.len()));
meta.insert("todo_count".to_string(), json!(count));
meta
}),
}
Expand Down