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
@@ -141,7 +141,8 @@ const COMMANDS_COUNT_LIMIT: i64 = 10000;
|
||||
|
||||
use galaxy_server_client::persistence::{upsert_cloud_object, CloudObjectId};
|
||||
|
||||
const WARP_SQLITE_FILE_NAME: &str = "warp.sqlite";
|
||||
const WARP_SQLITE_FILE_NAME: &str = "galaxy.sqlite";
|
||||
const LEGACY_SQLITE_FILE_NAME: &str = "warp.sqlite";
|
||||
|
||||
/// When delete a cloud object, this callback is used to delete the cloud
|
||||
/// object. It takes the id of the cloud object to delete as a parameter.
|
||||
@@ -162,7 +163,14 @@ pub fn initialize(ctx: &mut AppContext) -> (Option<PersistedData>, Option<Writer
|
||||
Ok(mut conn) => {
|
||||
let user_uid = AuthStateProvider::as_ref(ctx).get().user_id();
|
||||
let app_state = match read_sqlite_data(&mut conn, user_uid) {
|
||||
Ok(app_state) => Some(app_state),
|
||||
Ok(app_state) => {
|
||||
log::info!(
|
||||
"[session-restore] read_sqlite_data: windows={} conversations={}",
|
||||
app_state.app_state.windows.len(),
|
||||
app_state.multi_agent_conversations.len(),
|
||||
);
|
||||
Some(app_state)
|
||||
}
|
||||
Err(err) => {
|
||||
send_telemetry_from_app_ctx!(
|
||||
TelemetryEvent::DatabaseReadError(err.to_string()),
|
||||
@@ -335,6 +343,11 @@ pub(super) fn init_db() -> Result<SqliteConnection> {
|
||||
// First, make sure the parent directory of the file exists, otherwise
|
||||
// we'll get an error if the file doesn't already exist.
|
||||
let db_path = database_file_path();
|
||||
log::info!(
|
||||
"[session-restore] init_db: target={} exists={}",
|
||||
db_path.display(),
|
||||
db_path.exists()
|
||||
);
|
||||
// If we fail to create the necessary directories, log a warning and
|
||||
// continue; we'll return a sqlite error if it actually fails to initialize
|
||||
// a database connection.
|
||||
@@ -348,6 +361,55 @@ pub(super) fn init_db() -> Result<SqliteConnection> {
|
||||
);
|
||||
}
|
||||
|
||||
// Migrate from legacy "warp.sqlite" filename to "galaxy.sqlite" (same directory).
|
||||
if !db_path.exists() {
|
||||
let legacy_same_dir = db_path
|
||||
.parent()
|
||||
.expect("database file path should be absolute")
|
||||
.join(LEGACY_SQLITE_FILE_NAME);
|
||||
if legacy_same_dir.exists() {
|
||||
match std::fs::rename(&legacy_same_dir, &db_path) {
|
||||
Ok(_) => {
|
||||
log::info!("Migrated legacy warp.sqlite to galaxy.sqlite");
|
||||
let old_wal = legacy_same_dir.with_extension("sqlite-wal");
|
||||
let old_shm = legacy_same_dir.with_extension("sqlite-shm");
|
||||
let new_wal = db_path.with_extension("sqlite-wal");
|
||||
let new_shm = db_path.with_extension("sqlite-shm");
|
||||
let _ = std::fs::rename(&old_wal, &new_wal);
|
||||
let _ = std::fs::rename(&old_shm, &new_shm);
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("Failed to migrate legacy warp.sqlite: {err:#}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate from legacy "warp.sqlite" in state_dir (handles users who never
|
||||
// got the in-place rename above because they were on the old app ID path).
|
||||
if !db_path.exists() {
|
||||
let legacy_state_dir = galaxy_core::paths::state_dir().join(LEGACY_SQLITE_FILE_NAME);
|
||||
if legacy_state_dir.exists() {
|
||||
match std::fs::rename(&legacy_state_dir, &db_path) {
|
||||
Ok(_) => {
|
||||
log::info!(
|
||||
"Migrated legacy warp.sqlite from state_dir to {}",
|
||||
db_path.display()
|
||||
);
|
||||
let old_wal = legacy_state_dir.with_extension("sqlite-wal");
|
||||
let old_shm = legacy_state_dir.with_extension("sqlite-shm");
|
||||
let new_wal = db_path.with_extension("sqlite-wal");
|
||||
let new_shm = db_path.with_extension("sqlite-shm");
|
||||
let _ = std::fs::rename(&old_wal, &new_wal);
|
||||
let _ = std::fs::rename(&old_shm, &new_shm);
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("Failed to migrate legacy warp.sqlite from state_dir: {err:#}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate old SQLite files into the secure application container.
|
||||
let old_db_path = galaxy_core::paths::state_dir().join(WARP_SQLITE_FILE_NAME);
|
||||
if old_db_path != db_path && old_db_path.exists() && !db_path.exists() {
|
||||
@@ -2409,6 +2471,18 @@ fn read_node(conn: &mut SqliteConnection, node: model::PaneNode) -> Result<PaneN
|
||||
.active_conversation_id
|
||||
.and_then(|id_str| AIConversationId::try_from(id_str).ok());
|
||||
|
||||
log::info!(
|
||||
"[session-db-read] terminal_pane: cwd={:?} is_active={} \
|
||||
conversations={} active_conversation={:?} \
|
||||
has_shell_launch_data={} has_input_config={}",
|
||||
terminal_pane.cwd,
|
||||
terminal_pane.is_active,
|
||||
conversation_ids_to_restore.len(),
|
||||
active_conversation_id,
|
||||
shell_launch_data.is_some(),
|
||||
input_config.is_some(),
|
||||
);
|
||||
|
||||
LeafContents::Terminal(TerminalPaneSnapshot {
|
||||
uuid: terminal_pane.uuid,
|
||||
cwd: terminal_pane.cwd,
|
||||
|
||||
Reference in New Issue
Block a user