feat: compact worker サーキットブレーカーを占有量ベースに統一
This commit is contained in:
@@ -116,6 +116,8 @@ pub struct CompactionConfigPartial {
|
||||
#[serde(default)]
|
||||
pub compact_worker_max_input_tokens: Option<u64>,
|
||||
#[serde(default)]
|
||||
pub compact_worker_max_turns: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub model: Option<ModelManifest>,
|
||||
}
|
||||
|
||||
@@ -325,6 +327,9 @@ impl CompactionConfigPartial {
|
||||
compact_worker_max_input_tokens: upper
|
||||
.compact_worker_max_input_tokens
|
||||
.or(self.compact_worker_max_input_tokens),
|
||||
compact_worker_max_turns: upper
|
||||
.compact_worker_max_turns
|
||||
.or(self.compact_worker_max_turns),
|
||||
model: merge_option(self.model, upper.model, ModelManifest::merge),
|
||||
}
|
||||
}
|
||||
@@ -461,6 +466,9 @@ impl TryFrom<PodManifestConfig> for PodManifest {
|
||||
compact_worker_max_input_tokens: c
|
||||
.compact_worker_max_input_tokens
|
||||
.unwrap_or(defaults::COMPACT_WORKER_MAX_INPUT_TOKENS),
|
||||
compact_worker_max_turns: c
|
||||
.compact_worker_max_turns
|
||||
.or(defaults::COMPACT_WORKER_MAX_TURNS),
|
||||
model: c.model,
|
||||
})
|
||||
})
|
||||
@@ -949,6 +957,32 @@ stop_sequences = ["\n\n", "</stop>"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_toml_accepts_compact_worker_max_turns() {
|
||||
let cfg = PodManifestConfig::from_toml(
|
||||
r#"
|
||||
[compaction]
|
||||
compact_worker_max_turns = 7
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(cfg.compaction.unwrap().compact_worker_max_turns, Some(7));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_from_compaction_defaults_compact_worker_max_turns() {
|
||||
let mut cfg = minimal_valid();
|
||||
cfg.compaction = Some(CompactionConfigPartial::default());
|
||||
|
||||
let manifest = PodManifest::try_from(cfg).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
manifest.compaction.unwrap().compact_worker_max_turns,
|
||||
defaults::COMPACT_WORKER_MAX_TURNS
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_toml_partial_layer_succeeds() {
|
||||
// A project-layer manifest with only scope set must parse fine.
|
||||
@@ -1042,7 +1076,10 @@ name = "dbg"
|
||||
fn skills_directories_resolved_against_base() {
|
||||
let mut cfg = minimal_valid();
|
||||
cfg.skills = Some(SkillsConfig {
|
||||
directories: vec![PathBuf::from(".claude/skills"), PathBuf::from("/abs/elsewhere")],
|
||||
directories: vec![
|
||||
PathBuf::from(".claude/skills"),
|
||||
PathBuf::from("/abs/elsewhere"),
|
||||
],
|
||||
});
|
||||
let resolved = cfg.resolve_paths(Path::new("/workspace/proj"));
|
||||
let dirs = resolved.skills.as_ref().unwrap().directories.clone();
|
||||
|
||||
@@ -36,12 +36,16 @@ pub const DEFAULT_INSTRUCTION: &str = "$insomnia/default";
|
||||
/// [`crate::CompactionConfig::compact_auto_read_budget`].
|
||||
pub const COMPACT_AUTO_READ_BUDGET: u64 = 8000;
|
||||
|
||||
/// Cumulative input-token cap for the compact worker's own LLM
|
||||
/// Current prompt-occupancy cap for the compact worker's own LLM
|
||||
/// calls. Exceeding this aborts the compact run (circuit-breaker
|
||||
/// path). See
|
||||
/// [`crate::CompactionConfig::compact_worker_max_input_tokens`].
|
||||
pub const COMPACT_WORKER_MAX_INPUT_TOKENS: u64 = 50_000;
|
||||
|
||||
/// Optional maximum compact-worker tool-loop depth. `None` means unlimited.
|
||||
/// See [`crate::CompactionConfig::compact_worker_max_turns`].
|
||||
pub const COMPACT_WORKER_MAX_TURNS: Option<u32> = Some(20);
|
||||
|
||||
/// Number of recently-touched files fed to the compact worker as
|
||||
/// default references.
|
||||
pub const COMPACT_DEFAULT_REFERENCE_COUNT: usize = 5;
|
||||
|
||||
@@ -321,11 +321,16 @@ pub struct CompactionConfig {
|
||||
#[serde(default = "default_compact_auto_read_budget")]
|
||||
pub compact_auto_read_budget: u64,
|
||||
|
||||
/// Cumulative input-token cap for the compact worker's own LLM
|
||||
/// calls. Exceeding this aborts the compact run.
|
||||
/// Current prompt-occupancy cap for the compact worker's own LLM
|
||||
/// requests. Exceeding this aborts the compact run.
|
||||
#[serde(default = "default_compact_worker_max_input_tokens")]
|
||||
pub compact_worker_max_input_tokens: u64,
|
||||
|
||||
/// Optional maximum compact-worker tool-loop depth. `None` leaves the
|
||||
/// worker unlimited; the default bounds runaway short-context loops.
|
||||
#[serde(default = "default_compact_worker_max_turns")]
|
||||
pub compact_worker_max_turns: Option<u32>,
|
||||
|
||||
/// Optional model for the compactor (summary) LLM.
|
||||
/// If omitted, the main model is cloned via `clone_boxed()`.
|
||||
#[serde(default)]
|
||||
@@ -347,6 +352,9 @@ fn default_compact_auto_read_budget() -> u64 {
|
||||
fn default_compact_worker_max_input_tokens() -> u64 {
|
||||
defaults::COMPACT_WORKER_MAX_INPUT_TOKENS
|
||||
}
|
||||
fn default_compact_worker_max_turns() -> Option<u32> {
|
||||
defaults::COMPACT_WORKER_MAX_TURNS
|
||||
}
|
||||
|
||||
impl Default for CompactionConfig {
|
||||
fn default() -> Self {
|
||||
@@ -358,6 +366,7 @@ impl Default for CompactionConfig {
|
||||
compact_retained_tokens: default_compact_retained_tokens(),
|
||||
compact_auto_read_budget: default_compact_auto_read_budget(),
|
||||
compact_worker_max_input_tokens: default_compact_worker_max_input_tokens(),
|
||||
compact_worker_max_turns: default_compact_worker_max_turns(),
|
||||
model: None,
|
||||
}
|
||||
}
|
||||
@@ -521,6 +530,19 @@ model_id = "claude-sonnet-4-20250514"
|
||||
assert_eq!(c.compact_threshold, Some(80000));
|
||||
assert_eq!(c.compact_request_threshold, None);
|
||||
assert_eq!(c.compact_retained_tokens, 8000);
|
||||
assert_eq!(c.compact_worker_max_turns, Some(20));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_compaction_worker_max_turns() {
|
||||
let toml = format!(
|
||||
"{MINIMAL_REQUIRED}\n\
|
||||
[compaction]\n\
|
||||
compact_worker_max_turns = 7\n"
|
||||
);
|
||||
let manifest = PodManifest::from_toml(&toml).unwrap();
|
||||
let c = manifest.compaction.unwrap();
|
||||
assert_eq!(c.compact_worker_max_turns, Some(7));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user