swarm: a soft context limit per agent, as a percent of the window, applied at turn end
This commit is contained in:
parent
c56faf9dff
commit
1e03979836
2 changed files with 214 additions and 35 deletions
|
|
@ -36,6 +36,7 @@ impl SetFlags {
|
|||
effort: effort.or(current.effort),
|
||||
subagent_models: self.subagent_models.or(current.subagent_models),
|
||||
max_subagents: current.max_subagents,
|
||||
soft_context_percent: current.soft_context_percent,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -130,14 +131,18 @@ fn render_configured(s: Option<&InferenceSettings>) -> String {
|
|||
fn render(s: &InferenceSettings) -> String {
|
||||
const UNSET: &str = "(not set; the agent's own)";
|
||||
format!(
|
||||
"model: {}\neffort: {}\nsubagent_models: {}\nmax_subagents: {}\n",
|
||||
"model: {}\neffort: {}\nsubagent_models: {}\nmax_subagents: {}\nsoft_context_percent: {}\n",
|
||||
s.model.as_deref().unwrap_or(UNSET),
|
||||
s.effort.map_or(UNSET, Effort::as_str),
|
||||
s.subagent_models
|
||||
.as_ref()
|
||||
.map_or_else(|| UNSET.to_owned(), |m| m.join(", ")),
|
||||
s.max_subagents
|
||||
.map_or_else(|| "(not set; no cap)".to_owned(), |n| n.to_string())
|
||||
.map_or_else(|| "(not set; no cap)".to_owned(), |n| n.to_string()),
|
||||
s.soft_context_percent.map_or_else(
|
||||
|| "(not set; the harness's own watermark)".to_owned(),
|
||||
|n| format!("{n}%")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -198,10 +203,12 @@ mod tests {
|
|||
assert_eq!(merged.effort, Some(Effort::High));
|
||||
}
|
||||
|
||||
/// `set` has no flag for the cap, and a stored one survives it.
|
||||
/// `set` has no flag for the cap or the soft limit, and stored ones
|
||||
/// survive it.
|
||||
#[test]
|
||||
fn set_keeps_the_stored_max_subagents() {
|
||||
let current: InferenceSettings = serde_json::from_str(r#"{"max_subagents":3}"#).unwrap();
|
||||
fn set_keeps_the_stored_cap_and_soft_limit() {
|
||||
let current: InferenceSettings =
|
||||
serde_json::from_str(r#"{"max_subagents":3,"soft_context_percent":20}"#).unwrap();
|
||||
let merged = SetFlags {
|
||||
model: Some("opus".to_owned()),
|
||||
..flags()
|
||||
|
|
@ -209,6 +216,7 @@ mod tests {
|
|||
.merge(current)
|
||||
.unwrap();
|
||||
assert_eq!(merged.max_subagents, Some(3));
|
||||
assert_eq!(merged.soft_context_percent, Some(20));
|
||||
}
|
||||
|
||||
/// An effort the controller would answer 422 for fails before the request.
|
||||
|
|
@ -259,15 +267,19 @@ mod tests {
|
|||
serde_json::from_str(r#"{"configured":{},"effective":null}"#).unwrap();
|
||||
assert_eq!(
|
||||
render_configured(empty.configured.as_ref()).lines().count(),
|
||||
4
|
||||
5
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_empty_value_renders_every_field_as_unset() {
|
||||
let row = render(&serde_json::from_str("{}").unwrap());
|
||||
assert_eq!(row.lines().count(), 4);
|
||||
assert!(row.ends_with("max_subagents: (not set; no cap)\n"), "{row}");
|
||||
assert_eq!(row.lines().count(), 5);
|
||||
assert!(
|
||||
row.ends_with("soft_context_percent: (not set; the harness's own watermark)\n"),
|
||||
"{row}"
|
||||
);
|
||||
assert!(row.contains("max_subagents: (not set; no cap)\n"), "{row}");
|
||||
assert!(
|
||||
row.lines()
|
||||
.take(3)
|
||||
|
|
|
|||
|
|
@ -386,11 +386,13 @@ enum AgentVerb {
|
|||
/// show what it last did. Fails when the swarm has never heard from the
|
||||
/// agent.
|
||||
Watch(AgentWatchArgs),
|
||||
/// Show the model, effort, subagent models and subagent cap the swarm sets
|
||||
/// for an agent, or change the model, effort and subagent models.
|
||||
/// Show the model, effort, subagent models, subagent cap and soft context
|
||||
/// limit the swarm sets for an agent, or change the model, effort and
|
||||
/// subagent models.
|
||||
///
|
||||
/// `get` prints the subagent cap (`max_subagents`); `set` has no flag for
|
||||
/// it and keeps a stored one. Only swarm-ui sets it.
|
||||
/// `get` prints the subagent cap (`max_subagents`) and the soft context
|
||||
/// limit (`soft_context_percent`); `set` has no flag for them and keeps
|
||||
/// stored ones. Only swarm-ui sets them.
|
||||
///
|
||||
/// A field the swarm sets wins over the agent's own value (its agent.nix
|
||||
/// or a `hyperhive-model`/`hyperhive-effort` file) from its next turn on;
|
||||
|
|
|
|||
Loading…
Reference in a new issue