Deployment type
self-host
What do you want and why?
The CodeBuddy backend in server/pkg/agent/codebuddy.go currently drives the CodeBuddy CLI using Claude Code's private --output-format stream-json / -p headless protocol. This diverges from the ACP (Agent Client Protocol) standard already used by the kimi and hermes backends in the same package, forcing multica to maintain a parallel SDK JSON parsing layer (codebuddySDKMessage, handleAssistant, handleControlRequest, writeCodebuddyInput, etc.) and a separate code path for permission auto-approval, MCP config handling, and session resume.
CodeBuddy Code now natively supports ACP via codebuddy --acp (official docs: https://www.codebuddy.cn/docs/cli/acp and https://www.codebuddy.ai/docs/cli/acp). Switching to ACP would:
- Unify the transport: reuse the existing
hermesClient ACP transport (already proven by kimiBackend) instead of a backend-specific stream-json parser.
- Reduce maintenance burden: delete ~250 lines of CodeBuddy-specific SDK types and handlers; permission approval, MCP config translation, stderr sniffing, and provider-error promotion all flow through the shared ACP helpers (
buildACPMcpServers, filterACPMcpServersByCapability, newACPProviderErrorSniffer, promoteACPResultOnProviderError).
- Unlock ACP-native features: tool proxy (
fs.readTextFile/fs.writeTextFile/terminal), available_commands_update slash-command push, and the codebuddy.ai/teamUpdate Agent Teams extension — none of which the stream-json path exposes.
- Standardize the session lifecycle:
initialize → session/new|resume → session/set_model → session/prompt, matching how kimi/hermes already work. Model switching goes through session/set_model (single source of truth) rather than a root --model flag; resume goes through session/resume rather than --resume; MCP servers go through session/new.mcpServers rather than a temp file + --mcp-config.
Proposed solution
Rewrite codebuddyBackend.Execute to mirror kimiBackend:
- Launch
codebuddy --acp (blocked-args collapses to {"--acp": blockedStandalone}).
- Instantiate
hermesClient with onMessage calling a new codebuddyToolNameFromTitle (mirrors kimiToolNameFromTitle) to normalize CodeBuddy's capitalized ACP tool titles ("Read file: …" → read_file).
- Drive the standard ACP lifecycle:
initialize → session/new (or session/resume when ResumeSessionID is set, with the same stale-session-id fallback kimi/hermes use) → session/set_model when Model is set → session/prompt.
- Translate
McpConfig via buildACPMcpServers + filterACPMcpServersByCapability.
- Sniff stderr via
newACPProviderErrorSniffer("codebuddy") and promote upstream LLM errors via promoteACPResultOnProviderError.
- Keep the root-level
--effort, --max-turns, and --append-system-prompt flags (CodeBuddy CLI root params coexist with --acp); drop -p, --output-format, --input-format, --permission-mode, --mcp-config, --disallowedTools, --verbose, --strict-mcp-config.
Open questions that need validation against a real codebuddy --acp runtime (cannot be answered from the docs alone):
- Do
--effort / --max-turns / --append-system-prompt take effect under --acp mode?
- Does
session/set_model accept modelId (same field name as kimi)?
- Does
session/new return models.availableModels?
References
Deployment type
self-host
What do you want and why?
The CodeBuddy backend in
server/pkg/agent/codebuddy.gocurrently drives the CodeBuddy CLI using Claude Code's private--output-format stream-json/-pheadless protocol. This diverges from the ACP (Agent Client Protocol) standard already used by thekimiandhermesbackends in the same package, forcing multica to maintain a parallel SDK JSON parsing layer (codebuddySDKMessage,handleAssistant,handleControlRequest,writeCodebuddyInput, etc.) and a separate code path for permission auto-approval, MCP config handling, and session resume.CodeBuddy Code now natively supports ACP via
codebuddy --acp(official docs: https://www.codebuddy.cn/docs/cli/acp and https://www.codebuddy.ai/docs/cli/acp). Switching to ACP would:hermesClientACP transport (already proven bykimiBackend) instead of a backend-specific stream-json parser.buildACPMcpServers,filterACPMcpServersByCapability,newACPProviderErrorSniffer,promoteACPResultOnProviderError).fs.readTextFile/fs.writeTextFile/terminal),available_commands_updateslash-command push, and thecodebuddy.ai/teamUpdateAgent Teams extension — none of which the stream-json path exposes.initialize→session/new|resume→session/set_model→session/prompt, matching howkimi/hermesalready work. Model switching goes throughsession/set_model(single source of truth) rather than a root--modelflag; resume goes throughsession/resumerather than--resume; MCP servers go throughsession/new.mcpServersrather than a temp file +--mcp-config.Proposed solution
Rewrite
codebuddyBackend.Executeto mirrorkimiBackend:codebuddy --acp(blocked-args collapses to{"--acp": blockedStandalone}).hermesClientwithonMessagecalling a newcodebuddyToolNameFromTitle(mirrorskimiToolNameFromTitle) to normalize CodeBuddy's capitalized ACP tool titles ("Read file: …" →read_file).initialize→session/new(orsession/resumewhenResumeSessionIDis set, with the same stale-session-id fallbackkimi/hermesuse) →session/set_modelwhenModelis set →session/prompt.McpConfigviabuildACPMcpServers+filterACPMcpServersByCapability.newACPProviderErrorSniffer("codebuddy")and promote upstream LLM errors viapromoteACPResultOnProviderError.--effort,--max-turns, and--append-system-promptflags (CodeBuddy CLI root params coexist with--acp); drop-p,--output-format,--input-format,--permission-mode,--mcp-config,--disallowedTools,--verbose,--strict-mcp-config.Open questions that need validation against a real
codebuddy --acpruntime (cannot be answered from the docs alone):--effort/--max-turns/--append-system-prompttake effect under--acpmode?session/set_modelacceptmodelId(same field name askimi)?session/newreturnmodels.availableModels?References
kimiBackend(reference implementation):server/pkg/agent/kimi.gohermesClient(shared ACP transport):server/pkg/agent/hermes.goserver/pkg/agent/codebuddy.go