diff --git a/server/packages/sandbox-agent/src/acp_proxy_runtime.rs b/server/packages/sandbox-agent/src/acp_proxy_runtime.rs index ec33581..3710e2f 100644 --- a/server/packages/sandbox-agent/src/acp_proxy_runtime.rs +++ b/server/packages/sandbox-agent/src/acp_proxy_runtime.rs @@ -517,6 +517,8 @@ fn normalize_payload_for_agent(agent: AgentId, payload: Value) -> Value { return payload; } + // Pi's ACP adapter is stricter than other adapters for a couple of bootstrap + // fields. Normalize here so older/raw ACP clients still work against Pi. normalize_pi_payload(payload) } @@ -528,6 +530,8 @@ fn normalize_pi_payload(mut payload: Value) -> Value { match method { "initialize" => { + // Some clients send ACP protocolVersion as a string ("1.0"), but + // pi-acp expects a numeric JSON value and rejects strings. if let Some(protocol) = payload.pointer_mut("/params/protocolVersion") { if let Some(raw) = protocol.as_str() { if let Some(number) = parse_json_number(raw) { @@ -537,6 +541,9 @@ fn normalize_pi_payload(mut payload: Value) -> Value { } } "session/new" => { + // The TypeScript SDK and opencode adapter already send mcpServers: [], + // but raw /v1/acp callers may omit it. pi-acp currently validates + // mcpServers as required, so default it here for compatibility. if let Some(params) = payload.get_mut("params").and_then(Value::as_object_mut) { params .entry("mcpServers".to_string()) diff --git a/server/packages/sandbox-agent/tests/v1_api/acp_transport.rs b/server/packages/sandbox-agent/tests/v1_api/acp_transport.rs index 7b1c6cd..147d844 100644 --- a/server/packages/sandbox-agent/tests/v1_api/acp_transport.rs +++ b/server/packages/sandbox-agent/tests/v1_api/acp_transport.rs @@ -34,6 +34,13 @@ done } fn write_strict_pi_agent_process(path: &Path) { + // This stub intentionally mirrors the strict bootstrap validation behavior + // observed in pi-acp: + // - initialize.params.protocolVersion must be numeric + // - session/new.params.mcpServers must be present (array) + // + // The proxy normalization layer should adapt legacy/raw client payloads so + // requests still succeed against this stricter contract. let script = r#"#!/usr/bin/env sh if [ "${1:-}" = "--help" ] || [ "${1:-}" = "--version" ] || [ "${1:-}" = "version" ] || [ "${1:-}" = "-V" ]; then echo "pi-agent-process 0.0.1"