huskies: merge 967

This commit is contained in:
dave
2026-05-13 12:34:35 +00:00
parent 40ea100eae
commit 93f774fcbb
9 changed files with 165 additions and 0 deletions
+7
View File
@@ -42,6 +42,11 @@ impl AgentRuntime for ClaudeCodeRuntime {
event_log: Arc<Mutex<Vec<AgentEvent>>>,
log_writer: Option<Arc<Mutex<AgentLogWriter>>>,
) -> Result<RuntimeResult, String> {
let eager_record = if ctx.model.is_empty() {
None
} else {
Some((ctx.project_root.clone(), ctx.model.clone()))
};
let pty_result = super::super::pty::run_agent_pty_streaming(
&ctx.story_id,
&ctx.agent_name,
@@ -56,6 +61,7 @@ impl AgentRuntime for ClaudeCodeRuntime {
Arc::clone(&self.child_killers),
self.watcher_tx.clone(),
ctx.session_id_to_resume.as_deref(),
eager_record.clone(),
)
.await;
@@ -90,6 +96,7 @@ impl AgentRuntime for ClaudeCodeRuntime {
Arc::clone(&self.child_killers),
self.watcher_tx.clone(),
None, // no --resume on fallback
eager_record,
)
.await?;
Ok(RuntimeResult {
+4
View File
@@ -117,6 +117,8 @@ mod tests {
app_ctx: Some(test_app_ctx()),
session_id_to_resume: None,
fresh_prompt: None,
project_root: std::path::PathBuf::from("/tmp/project"),
model: String::new(),
};
let instruction = build_system_instruction(&ctx);
@@ -136,6 +138,8 @@ mod tests {
app_ctx: Some(test_app_ctx()),
session_id_to_resume: None,
fresh_prompt: None,
project_root: std::path::PathBuf::from("/tmp/project"),
model: String::new(),
};
let instruction = build_system_instruction(&ctx);
+2
View File
@@ -384,6 +384,8 @@ mod tests {
app_ctx: Some(test_app_ctx()),
session_id_to_resume: None,
fresh_prompt: None,
project_root: std::path::PathBuf::from("/tmp/project"),
model: String::new(),
};
// The model extraction logic is inside start(), but we test the
+10
View File
@@ -41,6 +41,14 @@ pub struct RuntimeContext {
/// resume (session expired, file missing, version mismatch), the runtime
/// retries with this full prompt and no `--resume` flag.
pub fresh_prompt: Option<String>,
/// Project root path — passed to the PTY runner so it can eagerly record
/// the session_id as soon as the `"system"` event is seen (bug 967).
/// Eager recording ensures the session survives a watchdog kill that aborts
/// the tokio task before `run_agent_spawn`'s `record_session()` call runs.
pub project_root: std::path::PathBuf,
/// Agent model name — forms part of the session store key used for eager
/// recording (bug 967). An empty string disables eager recording.
pub model: String,
}
/// Result returned by a runtime after the agent session completes.
@@ -125,6 +133,8 @@ mod tests {
app_ctx: Some(test_app_ctx()),
session_id_to_resume: None,
fresh_prompt: None,
project_root: std::path::PathBuf::from("/tmp/project"),
model: "sonnet".to_string(),
};
assert_eq!(ctx.story_id, "42_story_foo");
assert_eq!(ctx.agent_name, "coder-1");
+8
View File
@@ -560,6 +560,8 @@ mod tests {
app_ctx: Some(test_app_ctx()),
session_id_to_resume: None,
fresh_prompt: None,
project_root: std::path::PathBuf::from("/tmp/project"),
model: String::new(),
};
assert_eq!(build_system_text(&ctx), "Custom system prompt");
@@ -578,6 +580,8 @@ mod tests {
app_ctx: Some(test_app_ctx()),
session_id_to_resume: None,
fresh_prompt: None,
project_root: std::path::PathBuf::from("/tmp/project"),
model: String::new(),
};
let text = build_system_text(&ctx);
@@ -629,6 +633,8 @@ mod tests {
app_ctx: Some(test_app_ctx()),
session_id_to_resume: None,
fresh_prompt: None,
project_root: std::path::PathBuf::from("/tmp/project"),
model: String::new(),
};
assert!(ctx.command.starts_with("gpt"));
}
@@ -646,6 +652,8 @@ mod tests {
app_ctx: Some(test_app_ctx()),
session_id_to_resume: None,
fresh_prompt: None,
project_root: std::path::PathBuf::from("/tmp/project"),
model: String::new(),
};
assert!(ctx.command.starts_with("o"));
}