mirror of
https://github.com/block/buzz.git
synced 2026-10-31 14:31:02 +00:00
fix(acp): preserve Claude compaction settings
Co-authored-by: Atish Patel <atish@squareup.com> Signed-off-by: Atish Patel <atish@squareup.com> Signed-off-by: Brainy Bumble <0ed7657b57c0e8a9f5288390dd6c8d5d0a3a06abe9b01b9006814f52077d6cdf@buzz.block.builderlab.xyz> Co-authored-by: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -2969,52 +2969,58 @@ mod tests {
|
||||
/// before `extra_env`, so the later `Command::env` write wins).
|
||||
#[cfg(unix)]
|
||||
#[tokio::test]
|
||||
async fn spawn_applies_runtime_env_defaults_with_extra_env_precedence() {
|
||||
const HERMES_VAR: &str = "HERMES_ACP_SKIP_CONFIGURED_MCP";
|
||||
const CLAUDE_VAR: &str = "CLAUDE_CODE_AUTO_COMPACT_WINDOW";
|
||||
if std::env::var_os(HERMES_VAR).is_some() || std::env::var_os(CLAUDE_VAR).is_some() {
|
||||
// Inherited parent values win over both layers; the default and
|
||||
// override behavior below is unobservable in such an environment.
|
||||
async fn spawn_applies_hermes_env_default_with_extra_env_precedence() {
|
||||
const VAR: &str = "HERMES_ACP_SKIP_CONFIGURED_MCP";
|
||||
if std::env::var_os(VAR).is_some() {
|
||||
// An inherited parent value wins over both layers, so the default
|
||||
// and override behavior below is unobservable in this environment.
|
||||
return;
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
spawn_named_and_read_child_env("hermes-acp", HERMES_VAR, &[]).await,
|
||||
spawn_named_and_read_child_env("hermes-acp", VAR, &[]).await,
|
||||
"1",
|
||||
"Hermes spawns must default {HERMES_VAR}=1"
|
||||
"Hermes spawns must default {VAR}=1"
|
||||
);
|
||||
assert_eq!(
|
||||
spawn_named_and_read_child_env(
|
||||
"hermes-acp",
|
||||
HERMES_VAR,
|
||||
&[(HERMES_VAR.into(), "0".into())]
|
||||
)
|
||||
.await,
|
||||
spawn_named_and_read_child_env("hermes-acp", VAR, &[(VAR.into(), "0".into())]).await,
|
||||
"0",
|
||||
"an explicit extra_env entry must override the runtime default"
|
||||
);
|
||||
assert_eq!(
|
||||
spawn_named_and_read_child_env("claude-agent-acp", CLAUDE_VAR, &[]).await,
|
||||
"200000",
|
||||
"Claude spawns must default {CLAUDE_VAR}=200000"
|
||||
spawn_named_and_read_child_env("other-agent", VAR, &[]).await,
|
||||
"<unset>",
|
||||
"non-Hermes spawns must not receive Hermes defaults"
|
||||
);
|
||||
}
|
||||
|
||||
/// Buzz must leave Claude's compaction window unset unless it was supplied
|
||||
/// by the parent environment or an explicit persona entry.
|
||||
#[cfg(unix)]
|
||||
#[tokio::test]
|
||||
async fn spawn_does_not_default_claude_compaction_window() {
|
||||
const VAR: &str = "CLAUDE_CODE_AUTO_COMPACT_WINDOW";
|
||||
if std::env::var_os(VAR).is_some() {
|
||||
// An inherited parent value is intentionally forwarded and makes
|
||||
// the unset behavior below unobservable in this environment.
|
||||
return;
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
spawn_named_and_read_child_env("claude-agent-acp", VAR, &[]).await,
|
||||
"<unset>",
|
||||
"Claude spawns must preserve Claude's own effective configuration"
|
||||
);
|
||||
assert_eq!(
|
||||
spawn_named_and_read_child_env(
|
||||
"claude-agent-acp",
|
||||
CLAUDE_VAR,
|
||||
&[(CLAUDE_VAR.into(), "300000".into())]
|
||||
VAR,
|
||||
&[(VAR.into(), "300000".into())]
|
||||
)
|
||||
.await,
|
||||
"300000",
|
||||
"an explicit extra_env entry must override the runtime default"
|
||||
"an explicit persona entry must be forwarded"
|
||||
);
|
||||
for agent in ["goose", "codex-acp", "other-agent"] {
|
||||
assert_eq!(
|
||||
spawn_named_and_read_child_env(agent, CLAUDE_VAR, &[]).await,
|
||||
"<unset>",
|
||||
"non-Claude spawn {agent} must not receive Claude defaults"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@@ -712,17 +712,9 @@ fn default_agent_args(command: &str) -> Option<Vec<String>> {
|
||||
/// startup budget (see block/buzz#3355). Skip that unrelated global startup
|
||||
/// by default; an operator or persona can still opt back in by setting the
|
||||
/// variable explicitly.
|
||||
///
|
||||
/// Claude: set a 200,000-token automatic-compaction window for Buzz-owned
|
||||
/// children only. Claude Code caps this to the selected model's context
|
||||
/// capacity. An inherited parent value or explicit persona value wins, so an
|
||||
/// operator can select a different window without modifying Claude settings.
|
||||
pub(crate) fn default_agent_env(command: &str) -> &'static [(&'static str, &'static str)] {
|
||||
match normalize_agent_command_identity(command).as_str() {
|
||||
"hermes" | "hermes-agent" | "hermes-acp" => &[("HERMES_ACP_SKIP_CONFIGURED_MCP", "1")],
|
||||
"claude-agent-acp" | "claude-code-acp" | "claude-code" | "claudecode" => {
|
||||
&[("CLAUDE_CODE_AUTO_COMPACT_WINDOW", "200000")]
|
||||
}
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
@@ -1643,7 +1635,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_agent_env_recognizes_runtime_identities() {
|
||||
fn default_agent_env_recognizes_hermes_identities() {
|
||||
for command in [
|
||||
"hermes",
|
||||
"hermes-agent",
|
||||
@@ -1659,23 +1651,18 @@ mod tests {
|
||||
);
|
||||
}
|
||||
for command in [
|
||||
"goose",
|
||||
"codex-acp",
|
||||
"claude-agent-acp",
|
||||
"claude-code-acp",
|
||||
"claude-code",
|
||||
"claudecode",
|
||||
"/opt/claude/bin/claude-agent-acp",
|
||||
r"C:\Users\test\AppData\Roaming\npm\CLAUDE-CODE-ACP.cmd",
|
||||
"buzz-agent",
|
||||
"",
|
||||
] {
|
||||
assert_eq!(
|
||||
default_agent_env(command),
|
||||
&[("CLAUDE_CODE_AUTO_COMPACT_WINDOW", "200000")],
|
||||
"unexpected env defaults for {command}"
|
||||
);
|
||||
}
|
||||
for command in ["goose", "codex-acp", "buzz-agent", ""] {
|
||||
assert!(
|
||||
default_agent_env(command).is_empty(),
|
||||
"unrecognized command must have no env defaults: {command}"
|
||||
"non-Hermes command must have no env defaults: {command}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user