v1.3.0: Bedrock translator refactor, usage metrics, session restore fixes, and predefined rules
Major changes: - **Bedrock translator architecture**: Extract orchestration logic from `impl.rs` into a dedicated `translator.rs` module. Rename `convert_request.rs` → `request_translator.rs` and `stream.rs` → `response_translator.rs` for clarity. Remove `tool_docs.rs` (inlined). Remove `fallback_to_warp` setting and server fallback path — Bedrock is now the sole backend. - **Unknown tool handling**: The response translator now detects hallucinated/unknown tool calls from the model and synthesizes error tool_results so the conversation doesn't deadlock waiting for a result that will never come. - **Usage display overhaul**: Replace credit-based usage display with detailed token metrics showing context window %, cache hit rate (read/write/miss), and estimated cost in dollars. Add `total_input_tokens`, `total_cache_read_tokens`, `total_cache_write_tokens`, and `cache_miss_tokens` accessors to `AIConversation`. - **Predefined rules system**: Add `predefined_rules.rs` with 11 system-defined behavioral rules that are auto-seeded on first launch. Add "Add Predefined Rules" button to the Rules UI for re-adding them later. Track seeding state via `has_seeded_predefined_rules` setting. - **Session restore improvements**: Rename database file from `warp.sqlite` to `galaxy.sqlite` with automatic migration from both same-directory and state_dir legacy paths. Improve CWD persistence by falling back to `session_startup_path` for agent-mode and fresh tabs. Add extensive session-save/restore logging. - **Shell bootstrap rebrand**: Rename `WARP_INITIAL_WORKING_DIR` environment variable to `GALAXY_INITIAL_WORKING_DIR` across bash, zsh, and fish bootstrap scripts. - **Model defaults**: Change default Bedrock model from Opus 4.7 to Opus 4.6. Add `context_window_for_model()` helper with model-aware context sizes. Remove `is_bedrock_model()` (no longer needed without server fallback). - **User query persistence**: The response translator now emits a `UserQuery` proto message at stream start so the user's prompt persists across sessions for conversation titles. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
ec99146ccc
commit
eaa2ddc75e
@@ -23,7 +23,6 @@ fn get_test_config() -> Option<BedrockClientConfig> {
|
||||
access_key_id: String::new(),
|
||||
secret_access_key: String::new(),
|
||||
cross_region_inference: false,
|
||||
fallback_to_warp: false,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -65,6 +64,7 @@ async fn collect_stream_output(
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
None,
|
||||
Arc::new(Mutex::new(Vec::new())),
|
||||
)
|
||||
.await
|
||||
@@ -606,3 +606,85 @@ async fn test_reasoning_model_output() {
|
||||
&output.text[..output.text.len().min(300)]
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_all_tools_visible_to_model() {
|
||||
let Some(config) = get_test_config() else {
|
||||
eprintln!("Skipping: BEDROCK_INTEGRATION_TEST not set");
|
||||
return;
|
||||
};
|
||||
|
||||
let client = BedrockClient::from_config(config)
|
||||
.await
|
||||
.expect("client creation");
|
||||
let model = get_test_model();
|
||||
|
||||
let tools = super::request_translator::default_tool_definitions();
|
||||
let tool_names: Vec<&str> = tools.iter().map(|t| t.name.as_str()).collect();
|
||||
|
||||
println!("[test] Sending {} tools to Bedrock: {:?}", tools.len(), tool_names);
|
||||
|
||||
let messages = vec![ConversationMessage {
|
||||
role: MessageRole::User,
|
||||
content: MessageContent::Text(
|
||||
"List every tool you have access to. Output ONLY the tool names, one per line, no descriptions, no formatting, no markdown."
|
||||
.into(),
|
||||
),
|
||||
}];
|
||||
|
||||
let output = collect_stream_output(
|
||||
&client,
|
||||
&model,
|
||||
messages,
|
||||
Some("You are a helpful assistant. When asked about your tools, list them exactly as they appear in your tool configuration.".into()),
|
||||
tools.clone(),
|
||||
)
|
||||
.await;
|
||||
|
||||
println!("[test] Model's tool list response:\n{}", output.text);
|
||||
println!("[test] Total tokens: {}", output.total_tokens);
|
||||
|
||||
let response_lower = output.text.to_lowercase();
|
||||
|
||||
let mut missing_tools = Vec::new();
|
||||
for tool in &tools {
|
||||
if !response_lower.contains(&tool.name.to_lowercase()) {
|
||||
missing_tools.push(&tool.name);
|
||||
}
|
||||
}
|
||||
|
||||
if !missing_tools.is_empty() {
|
||||
println!("[test] WARNING: Model did not mention these tools: {:?}", missing_tools);
|
||||
}
|
||||
|
||||
let expected_core_tools = [
|
||||
"run_shell_command",
|
||||
"read_files",
|
||||
"apply_file_diffs",
|
||||
"grep",
|
||||
"file_glob",
|
||||
"search_codebase",
|
||||
"start_agent",
|
||||
"ask_user_question",
|
||||
];
|
||||
|
||||
let mut missing_core = Vec::new();
|
||||
for name in &expected_core_tools {
|
||||
if !response_lower.contains(name) {
|
||||
missing_core.push(*name);
|
||||
}
|
||||
}
|
||||
|
||||
assert!(
|
||||
missing_core.is_empty(),
|
||||
"Model failed to list these core tools: {:?}\n\nFull response:\n{}",
|
||||
missing_core,
|
||||
output.text
|
||||
);
|
||||
|
||||
assert!(
|
||||
tools.len() >= 17,
|
||||
"Expected at least 17 tool definitions, got {}",
|
||||
tools.len()
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user