diff --git a/llm_client/src/clients/anthropic.rs b/llm_client/src/clients/anthropic.rs index 3aef2eb14..940319a78 100644 --- a/llm_client/src/clients/anthropic.rs +++ b/llm_client/src/clients/anthropic.rs @@ -39,7 +39,7 @@ enum AnthropicMessageContent { cache_control: Option, }, #[serde(rename = "image")] - Image { + Image { source: AnthropicImageSource, cache_control: Option, }, @@ -96,10 +96,22 @@ impl AnthropicMessageContent { fn set_cache_control(&mut self, cache_control: Option) { match self { - Self::Text { cache_control: ref mut cc, .. } => *cc = cache_control, - Self::Image { cache_control: ref mut cc, .. } => *cc = cache_control, - Self::ToolUse { cache_control: ref mut cc, .. } => *cc = cache_control, - Self::ToolReturn { cache_control: ref mut cc, .. } => *cc = cache_control, + Self::Text { + cache_control: ref mut cc, + .. + } => *cc = cache_control, + Self::Image { + cache_control: ref mut cc, + .. + } => *cc = cache_control, + Self::ToolUse { + cache_control: ref mut cc, + .. + } => *cc = cache_control, + Self::ToolReturn { + cache_control: ref mut cc, + .. + } => *cc = cache_control, } } } @@ -275,7 +287,7 @@ impl AnthropicRequest { let mut content = Vec::new(); let mut anthropic_message_content = AnthropicMessageContent::text(message.content().to_owned(), None); - + let images = message .images() .into_iter() @@ -924,4 +936,4 @@ impl LLMClient for AnthropicClient { Ok(buffered_string) } -} \ No newline at end of file +} diff --git a/sidecar/src/agentic/tool/session/service.rs b/sidecar/src/agentic/tool/session/service.rs index c899a9d58..b139199e5 100644 --- a/sidecar/src/agentic/tool/session/service.rs +++ b/sidecar/src/agentic/tool/session/service.rs @@ -1143,7 +1143,7 @@ impl SessionService { storage_path: String, ) -> Result { let session = self.load_from_storage(storage_path).await?; - + // Create a SearchTreeMinimal from the action nodes let search_tree = SearchTreeMinimal::from_action_nodes( session.action_nodes(), @@ -1151,7 +1151,7 @@ impl SessionService { "".to_owned(), // No need for MCTS log directory "".to_owned(), // No need for MCTS log directory ); - + Ok(search_tree) } @@ -1366,4 +1366,4 @@ pub enum TestGenerateCompletion { LLMChoseToFinish(String), /// Hit the maximum iteration limit (lower confidence) HitIterationLimit(String), -} \ No newline at end of file +} diff --git a/sidecar/src/agentic/tool/session/tool_use_agent.rs b/sidecar/src/agentic/tool/session/tool_use_agent.rs index baa1db139..682e00bd7 100644 --- a/sidecar/src/agentic/tool/session/tool_use_agent.rs +++ b/sidecar/src/agentic/tool/session/tool_use_agent.rs @@ -1284,6 +1284,7 @@ You accomplish a given task iteratively, breaking it down into clear steps and w message_properties.ui_sender().clone(), message_properties.request_id_str(), vec![system_message, user_message], + Some("context_crunching".to_owned()), ) .await? { @@ -1393,6 +1394,7 @@ You accomplish a given task iteratively, breaking it down into clear steps and w ui_sender.clone(), exchange_id, final_messages.to_vec(), + None, ) .await { @@ -1420,6 +1422,7 @@ You accomplish a given task iteratively, breaking it down into clear steps and w ui_sender.clone(), exchange_id, final_messages.to_vec(), + None, ) .await? { @@ -1448,6 +1451,7 @@ You accomplish a given task iteratively, breaking it down into clear steps and w ui_sender, exchange_id, final_messages, + None, ) .await? { @@ -1466,6 +1470,7 @@ You accomplish a given task iteratively, breaking it down into clear steps and w ui_sender: tokio::sync::mpsc::UnboundedSender, exchange_id: &str, final_messages: Vec, + event_type: Option, ) -> Result, SymbolError> { let agent_temperature = self.temperature; let (sender, receiver) = @@ -1488,7 +1493,10 @@ You accomplish a given task iteratively, breaking it down into clear steps and w ), llm_properties.provider().clone(), vec![ - ("event_type".to_owned(), "tool_use".to_owned()), + ( + "event_type".to_owned(), + event_type.unwrap_or_else(|| "tool_use".to_owned()), + ), ("root_id".to_owned(), cloned_root_request_id), ] .into_iter() diff --git a/sidecar/src/mcts/action_node.rs b/sidecar/src/mcts/action_node.rs index c1b2c5643..e2f662d1b 100644 --- a/sidecar/src/mcts/action_node.rs +++ b/sidecar/src/mcts/action_node.rs @@ -2165,4 +2165,4 @@ where map_serializer.serialize_entry(&k.to_string(), v)?; } map_serializer.end() -} \ No newline at end of file +} diff --git a/sidecar/src/webserver/agentic.rs b/sidecar/src/webserver/agentic.rs index 93c803954..84ece20e0 100644 --- a/sidecar/src/webserver/agentic.rs +++ b/sidecar/src/webserver/agentic.rs @@ -846,26 +846,34 @@ impl ApiResponse for MCTSDataResponse {} pub async fn get_mcts_data( Extension(app): Extension, - Json(MCTSDataRequest { session_id, exchange_id }): Json, + Json(MCTSDataRequest { + session_id, + exchange_id, + }): Json, ) -> Result { - let session_storage_path = check_session_storage_path(app.config.clone(), session_id.to_string()).await; + let session_storage_path = + check_session_storage_path(app.config.clone(), session_id.to_string()).await; let session_service = app.session_service.clone(); // Get the MCTS data from session storage - let mcts_data = session_service.get_mcts_data(&session_id, &exchange_id, session_storage_path).await; - + let mcts_data = session_service + .get_mcts_data(&session_id, &exchange_id, session_storage_path) + .await; + // Generate HTML with color-coded tool types and tool input/output let html = match mcts_data { Ok(data) => { - let mut html = String::from(r#""#); - + "#, + ); + html.push_str("
"); - + // Add nodes in order for node in data.nodes() { if let Some(action) = &node.action() { @@ -873,49 +881,61 @@ pub async fn get_mcts_data( if let Some(tool_type) = tool_type { // Get color based on tool type using the same logic as print_tree let color = match tool_type { - ToolType::CodeEditing => "#4A90E2", // blue - ToolType::FindFiles => "#F5A623", // yellow - ToolType::ListFiles => "#F5A623", // yellow + ToolType::CodeEditing => "#4A90E2", // blue + ToolType::FindFiles => "#F5A623", // yellow + ToolType::ListFiles => "#F5A623", // yellow ToolType::SearchFileContentWithRegex => "#9013FE", // purple - ToolType::OpenFile => "#E91E63", // magenta - ToolType::SemanticSearch => "#9013FE", // purple - ToolType::LSPDiagnostics => "#00BCD4", // cyan - ToolType::TerminalCommand => "#FF5252", // red - ToolType::AskFollowupQuestions => "#757575", // gray - ToolType::AttemptCompletion => "#4CAF50", // green - ToolType::RepoMapGeneration => "#E91E63", // magenta - ToolType::TestRunner => "#FF5252", // red - ToolType::Reasoning => "#4A90E2", // blue - ToolType::ContextCrunching => "#4A90E2", // blue - ToolType::RequestScreenshot => "#757575", // gray - ToolType::McpTool(_) => "#00BCD4", // cyan - _ => "#9E9E9E", // default gray for other variants + ToolType::OpenFile => "#E91E63", // magenta + ToolType::SemanticSearch => "#9013FE", // purple + ToolType::LSPDiagnostics => "#00BCD4", // cyan + ToolType::TerminalCommand => "#FF5252", // red + ToolType::AskFollowupQuestions => "#757575", // gray + ToolType::AttemptCompletion => "#4CAF50", // green + ToolType::RepoMapGeneration => "#E91E63", // magenta + ToolType::TestRunner => "#FF5252", // red + ToolType::Reasoning => "#4A90E2", // blue + ToolType::ContextCrunching => "#4A90E2", // blue + ToolType::RequestScreenshot => "#757575", // gray + ToolType::McpTool(_) => "#00BCD4", // cyan + _ => "#9E9E9E", // default gray for other variants }; - + html.push_str(&format!("
\n")); - html.push_str(&format!("
{:?}
\n", color, tool_type)); - + html.push_str(&format!( + "
{:?}
\n", + color, tool_type + )); + // Add tool input/output with proper formatting html.push_str("
\n"); - html.push_str(&format!("

Tool Input:

\n
{}
\n", action.to_string())); + html.push_str(&format!( + "

Tool Input:

\n
{}
\n", + action.to_string() + )); if let Some(observation) = node.observation() { - html.push_str(&format!("

Tool Output:

\n
{}
\n", observation.message())); + html.push_str(&format!( + "

Tool Output:

\n
{}
\n", + observation.message() + )); } html.push_str("
\n"); // Close tool-content - + // Add reward if present if let Some(reward) = node.reward() { - html.push_str(&format!("
Reward: {}
\n", reward.value())); + html.push_str(&format!( + "
Reward: {}
\n", + reward.value() + )); } - + html.push_str("
\n"); // Close node } } } - + html.push_str("
"); html - }, + } Err(_) => String::from("No MCTS data found"), }; @@ -2123,4 +2143,4 @@ pub async fn agent_session_plan( let stream = init_stream.chain(answer_stream).chain(done_stream); Ok(Sse::new(Box::pin(stream))) -} \ No newline at end of file +}