Compare commits

...

5 Commits

Author SHA1 Message Date
Jochen
e696366ada add cache_control to user messages 2025-11-27 13:10:52 +11:00
Jochen
c837308148 never add more than 4 cache controls
Anthropic API throws errors otherwise.
2025-11-26 18:38:30 +11:00
Jochen
c6c35bf2ca Merge pull request #31 from dhanji/jochen_fast_start
add code exploration fast start
2025-11-26 17:10:42 +11:00
Jochen
c9fde4ecef Merge pull request #32 from dhanji/jochen_reorder_system_prompt
minor change: reorder system prompt
2025-11-26 11:07:08 +11:00
Jochen
467e300ec2 reorder system prompt 2025-11-26 09:30:26 +11:00

View File

@@ -1087,6 +1087,14 @@ impl<W: UiWriter> Agent<W> {
} }
} }
/// Count how many cache_control annotations exist in the conversation history
fn count_cache_controls_in_history(&self) -> usize {
self.context_window.conversation_history
.iter()
.filter(|msg| msg.cache_control.is_some())
.count()
}
/// Get the configured max_tokens for a provider from top-level config /// Get the configured max_tokens for a provider from top-level config
fn provider_max_tokens(config: &Config, provider_name: &str) -> Option<u32> { fn provider_max_tokens(config: &Config, provider_name: &str) -> Option<u32> {
match provider_name { match provider_name {
@@ -1404,7 +1412,21 @@ impl<W: UiWriter> Agent<W> {
} }
// Add user message to context window // Add user message to context window
let user_message = Message::new(MessageRole::User, format!("Task: {}", description)); let user_message = {
// Check if we should use cache control (every 10 tool calls)
// But only if we haven't already added 4 cache_control annotations
let provider = self.providers.get(None)?;
if let Some(cache_config) = match provider.name() {
"anthropic" => self.config.providers.anthropic.as_ref()
.and_then(|c| c.cache_config.as_ref())
.and_then(|config| Self::parse_cache_control(config)),
_ => None,
} {
Message::with_cache_control_validated(MessageRole::User, format!("Task: {}", description), cache_config, provider)
} else {
Message::new(MessageRole::User, format!("Task: {}", description))
}
};
self.context_window.add_message(user_message); self.context_window.add_message(user_message);
// Execute fast-discovery tool calls if provided (immediately after user message) // Execute fast-discovery tool calls if provided (immediately after user message)
@@ -1426,7 +1448,7 @@ impl<W: UiWriter> Agent<W> {
// Add cache_control to the last user message if provider supports it (anthropic) // Add cache_control to the last user message if provider supports it (anthropic)
let is_last = idx == message_count - 1; let is_last = idx == message_count - 1;
let result_message = if is_last && supports_cache { let result_message = if supports_cache && is_last && self.count_cache_controls_in_history() < 4 {
Message::with_cache_control( Message::with_cache_control(
MessageRole::User, MessageRole::User,
format!("Tool result: {}", result), format!("Tool result: {}", result),
@@ -1506,24 +1528,7 @@ impl<W: UiWriter> Agent<W> {
// Add assistant response to context window only if not empty // Add assistant response to context window only if not empty
// This prevents the "Skipping empty message" warning when only tools were executed // This prevents the "Skipping empty message" warning when only tools were executed
if !response_content.trim().is_empty() { if !response_content.trim().is_empty() {
let assistant_message = { let assistant_message = Message::new(MessageRole::Assistant, response_content.clone());
// Check if we should use cache control (every 10 tool calls)
if self.tool_call_count > 0 && self.tool_call_count % 10 == 0 {
let provider = self.providers.get(None)?;
if let Some(cache_config) = match provider.name() {
"anthropic" => self.config.providers.anthropic.as_ref()
.and_then(|c| c.cache_config.as_ref())
.and_then(|config| Self::parse_cache_control(config)),
_ => None,
} {
Message::with_cache_control_validated(MessageRole::Assistant, response_content.clone(), cache_config, provider)
} else {
Message::new(MessageRole::Assistant, response_content.clone())
}
} else {
Message::new(MessageRole::Assistant, response_content.clone())
}
};
self.context_window.add_message(assistant_message); self.context_window.add_message(assistant_message);
} else { } else {
debug!("Assistant response was empty (likely only tool execution), skipping message addition"); debug!("Assistant response was empty (likely only tool execution), skipping message addition");
@@ -3372,7 +3377,25 @@ impl<W: UiWriter> Agent<W> {
tool_call.tool, tool_call.args tool_call.tool, tool_call.args
)) ))
}; };
let result_message = Message::new(MessageRole::User, format!("Tool result: {}", tool_result)); let result_message = {
// Check if we should use cache control (every 10 tool calls)
// But only if we haven't already added 4 cache_control annotations
if self.tool_call_count > 0 && self.tool_call_count % 10 == 0 && self.count_cache_controls_in_history() < 4 {
let provider = self.providers.get(None)?;
if let Some(cache_config) = match provider.name() {
"anthropic" => self.config.providers.anthropic.as_ref()
.and_then(|c| c.cache_config.as_ref())
.and_then(|config| Self::parse_cache_control(config)),
_ => None,
} {
Message::with_cache_control_validated(MessageRole::User, format!("Tool result: {}", tool_result), cache_config, provider)
} else {
Message::new(MessageRole::User, format!("Tool result: {}", tool_result))
}
} else {
Message::new(MessageRole::User, format!("Tool result: {}", tool_result))
}
};
self.context_window.add_message(tool_message); self.context_window.add_message(tool_message);
self.context_window.add_message(result_message); self.context_window.add_message(result_message);
@@ -3722,24 +3745,7 @@ impl<W: UiWriter> Agent<W> {
.replace("<</SYS>>", ""); .replace("<</SYS>>", "");
if !raw_clean.trim().is_empty() { if !raw_clean.trim().is_empty() {
let assistant_message = { let assistant_message = Message::new(MessageRole::Assistant, raw_clean);
// Check if we should use cache control (every 10 tool calls)
if self.tool_call_count > 0 && self.tool_call_count % 10 == 0 {
let provider = self.providers.get(None)?;
if let Some(cache_config) = match provider.name() {
"anthropic" => self.config.providers.anthropic.as_ref()
.and_then(|c| c.cache_config.as_ref())
.and_then(|config| Self::parse_cache_control(config)),
_ => None,
} {
Message::with_cache_control_validated(MessageRole::Assistant, raw_clean, cache_config, provider)
} else {
Message::new(MessageRole::Assistant, raw_clean)
}
} else {
Message::new(MessageRole::Assistant, raw_clean)
}
};
self.context_window.add_message(assistant_message); self.context_window.add_message(assistant_message);
} }
} }