huskies: merge 1015

This commit is contained in:
dave
2026-05-13 23:33:30 +00:00
parent 69b207872a
commit 5ed1438ab9
22 changed files with 227 additions and 73 deletions
+2 -2
View File
@@ -68,7 +68,7 @@ pub struct AgentConfigEntry {
pub name: String,
pub role: String,
pub stage: Option<String>,
pub model: Option<String>,
pub model: Option<crate::agents::AgentModel>,
pub allowed_tools: Option<Vec<String>>,
pub max_turns: Option<u32>,
pub max_budget_usd: Option<f64>,
@@ -283,7 +283,7 @@ max_budget_usd = 5.0
let entries = get_agent_config(tmp.path()).unwrap();
assert_eq!(entries.len(), 1);
assert_eq!(entries[0].name, "coder-1");
assert_eq!(entries[0].model, Some("sonnet".to_string()));
assert_eq!(entries[0].model, Some(crate::agents::AgentModel::Sonnet));
assert_eq!(entries[0].max_turns, Some(30));
}
+6 -3
View File
@@ -9,7 +9,7 @@ use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq)]
pub struct AgentTokenCost {
pub agent_name: String,
pub model: Option<String>,
pub model: Option<crate::agents::AgentModel>,
pub input_tokens: u64,
pub output_tokens: u64,
pub cache_creation_input_tokens: u64,
@@ -153,8 +153,11 @@ mod tests {
#[test]
fn aggregate_preserves_model_from_first_record() {
let mut r = make_record("42_story_foo", "coder-1", 1.0);
r.model = Some("claude-sonnet".to_string());
r.model = Some(crate::agents::AgentModel::Sonnet);
let summary = aggregate_for_story(&[r], "42_story_foo");
assert_eq!(summary.agents[0].model, Some("claude-sonnet".to_string()));
assert_eq!(
summary.agents[0].model,
Some(crate::agents::AgentModel::Sonnet)
);
}
}
+9 -8
View File
@@ -5,6 +5,7 @@
//! [`merge_settings_into_toml`] (the pure TOML key-updating logic used by the
//! write path in `mod.rs` + `io.rs`).
use crate::agents::AgentModel;
use crate::config::ProjectConfig;
use serde::{Deserialize, Serialize};
@@ -17,8 +18,8 @@ use serde::{Deserialize, Serialize};
pub struct ProjectSettings {
/// Project-wide default QA mode: "server", "agent", or "human". Default: "server".
pub default_qa: String,
/// Default model for coder-stage agents (e.g. "sonnet").
pub default_coder_model: Option<String>,
/// Default model for coder-stage agents (e.g. `Sonnet`).
pub default_coder_model: Option<AgentModel>,
/// Maximum number of concurrent coder-stage agents.
pub max_coders: Option<u32>,
/// Maximum retries per story per pipeline stage before marking as blocked. Default: 2.
@@ -89,7 +90,7 @@ pub fn merge_settings_into_toml(
Some(v) => {
table.insert(
"default_coder_model".to_string(),
toml::Value::String(v.clone()),
toml::Value::String(v.as_str().to_string()),
);
}
None => {
@@ -180,7 +181,7 @@ mod tests {
fn settings_from_config_copies_all_scalar_fields() {
let cfg = ProjectConfig {
default_qa: "human".to_string(),
default_coder_model: Some("opus".to_string()),
default_coder_model: Some(AgentModel::Opus),
max_coders: Some(4),
max_retries: 5,
base_branch: Some("main".to_string()),
@@ -196,7 +197,7 @@ mod tests {
let s = settings_from_config(&cfg);
assert_eq!(s.default_qa, "human");
assert_eq!(s.default_coder_model, Some("opus".to_string()));
assert_eq!(s.default_coder_model, Some(AgentModel::Opus));
assert_eq!(s.max_coders, Some(4));
assert_eq!(s.max_retries, 5);
assert_eq!(s.base_branch, Some("main".to_string()));
@@ -247,7 +248,7 @@ mod tests {
let mut val = empty_toml();
let s = ProjectSettings {
default_qa: "server".to_string(),
default_coder_model: Some("sonnet".to_string()),
default_coder_model: Some(AgentModel::Sonnet),
max_coders: Some(2),
max_retries: 2,
base_branch: Some("main".to_string()),
@@ -273,7 +274,7 @@ mod tests {
// First set them
let s_with = ProjectSettings {
default_qa: "server".to_string(),
default_coder_model: Some("sonnet".to_string()),
default_coder_model: Some(AgentModel::Sonnet),
max_coders: Some(3),
max_retries: 2,
base_branch: Some("master".to_string()),
@@ -372,7 +373,7 @@ path = "."
let mut val = empty_toml();
let s = ProjectSettings {
default_qa: "human".to_string(),
default_coder_model: Some("opus".to_string()),
default_coder_model: Some(AgentModel::Opus),
max_coders: Some(2),
max_retries: 4,
base_branch: Some("develop".to_string()),
+1 -1
View File
@@ -117,7 +117,7 @@ mod tests {
fn valid_settings_with_all_optional_fields_set() {
let s = ProjectSettings {
default_qa: "agent".to_string(),
default_coder_model: Some("opus".to_string()),
default_coder_model: Some(crate::agents::AgentModel::Opus),
max_coders: Some(4),
max_retries: 5,
base_branch: Some("main".to_string()),
+2 -2
View File
@@ -296,7 +296,7 @@ mod tests {
merge_failure: None,
agent: Some(crate::http::workflow::pipeline::AgentAssignment {
agent_name: crate::config::AgentName::Coder1,
model: Some("claude-3-5-sonnet".to_string()),
model: Some(crate::agents::AgentModel::Sonnet),
status: crate::agents::AgentStatus::Running,
}),
review_hold: None,
@@ -316,7 +316,7 @@ mod tests {
let resp: WsResponse = state.into();
let json = serde_json::to_value(&resp).unwrap();
assert_eq!(json["current"][0]["agent"]["agent_name"], "coder-1");
assert_eq!(json["current"][0]["agent"]["model"], "claude-3-5-sonnet");
assert_eq!(json["current"][0]["agent"]["model"], "sonnet");
assert_eq!(json["current"][0]["agent"]["status"], "running");
}