Help us shape the future of Go! Take the 2026 Go Developer Survey

acpx

package
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package acpx 统一调用 CLI Coding Agent(claude / zcode / codex / opencode / minimax / kimi / gemini / qwen / mimo / pi / dsh 共 11 家,另有 GenericAgent 通用出口)。

核心抽象:Agent 接口把各家 headless 模式收敛为统一契约——

Run(Prompt/WorkDir/Model/Session/AllowedTools/Sandbox) → Result(Text/SessionID/Usage)
+ OnEvent 流式回调(文本增量/工具调用事件透传)

设计对齐 eino:AsTool() 把任意 Agent 包成 tool.BaseTool,挂进 ReAct agent 工具表 (与 rag.KnowledgeService.AsTool 同范式),让 LLM 自主决定调用哪个编码 agent。

安全模型(继承 Argus adapter_cli 实战纪律):

  • 进程组执行:Setpgid + 超时/取消 TERM 整组 → killGrace 宽限后 SIGKILL(cmd.Cancel/WaitDelay)
  • 环境变量白名单:绝不继承 ARGUS_*/OPENAI_* 等凭证给子进程
  • stdout 限容:异常 agent 刷屏防内存放大(单行另设 maxLineLen 上限防无换行洪泛)
  • prompt 注入防线:位置参数传递的 prompt 经 promptArg 防护,"-"/"--" 开头的 内容不会被 CLI flag 解析器消费(否则 LLM 自填 prompt 可注入沙箱旁路开关)

Index

Constants

View Source
const (
	SandboxReadonly  = "readonly"
	SandboxWorkspace = "workspace"
	SandboxFull      = "full"
)

sandbox 词表。

View Source
const (
	EventText       = "text"
	EventThinking   = "thinking"
	EventToolCall   = "tool_call"
	EventToolResult = "tool_result"
	EventError      = "error"
	EventResult     = "result"
)

事件词表。

Variables

This section is empty.

Functions

func CapsNames

func CapsNames(c Capability) (supported, unsupported []string)

CapsNames 能力五字段的支持/不支持双名单(小写字段名,声明序)。capsString 与直连调用方的能力展示面(如 huginn agents 清单的「支持:… | 不支持:…」)共用 此单源——字段表只此一份,增删 Capability 字段时名单自动跟上。

func UnsupportedFields

func UnsupportedFields(a Agent, req RunRequest) []string

UnsupportedFields 返回 req 中非零但 agent 声明不支持的控制面字段名(Go 字段 名,字段声明序)。Registry.Run 的 fail-fast 与直连调用方的降级裁决共用此单源: 经 Registry 的调用方无须自行调用(不支持的请求直接报错);绕过 Registry 直连 Agent.Run 的嵌入方(如 huginn preFlight 范式——整跑失败代价高,选择降级而非 fail-fast)按返回名单自行裁决「剔除降级 / 保留透传+显式告警,绝不静默」。

Types

type Agent

type Agent interface {
	// Name agent 标识(claude / codex / opencode / zcode / minimax)。
	Name() string
	// Run 执行一次任务(headless 模式)。
	Run(ctx context.Context, req RunRequest) (*RunResult, error)
	// Capabilities 声明对 RunRequest 控制面字段的支持度。能力声明是接口契约的
	// 一部分(编译期强制,不给实现者"忘记声明"的余地):Registry.Run 对请求中
	// 声明不支持的非零字段 fail-fast——静默丢弃已证伪(kimi 收到 Sandbox=readonly
	// 实则全自主裸跑,安全语义静默降级不可接受)。
	Capabilities() Capability
}

Agent CLI 编码 agent 统一接口。

type Capability

type Capability struct {
	Model        bool // 响应 Model 覆盖
	Session      bool // 响应 SessionID 续聊
	MaxTurns     bool // 响应 MaxTurns 轮数上限
	AllowedTools bool // 响应 AllowedTools 工具白名单
	Sandbox      bool // 响应 Sandbox 沙箱级别
}

Capability agent 对 RunRequest 控制面字段的支持声明(五字段独立判定)。

type ClaudeCode

type ClaudeCode struct {
	Bin string // 默认 "claude"
	// contains filtered or unexported fields
}

ClaudeCode Claude Code 适配器(headless:`claude -p --output-format stream-json`)。

func NewClaudeCode

func NewClaudeCode() *ClaudeCode

NewClaudeCode 创建 Claude Code 适配器。

func NewZCode

func NewZCode() *ClaudeCode

NewZCode 创建 ZCode 适配器(CLI 参数协议与 Claude Code 同族)。

func (*ClaudeCode) Capabilities

func (c *ClaudeCode) Capabilities() Capability

Capabilities 全量支持:--model / --resume / --max-turns / --allowedTools / --permission-mode。

func (*ClaudeCode) Name

func (a *ClaudeCode) Name() string

Name Agent 接口的 Name 实现(适配器嵌入即得)。

func (*ClaudeCode) Run

func (c *ClaudeCode) Run(ctx context.Context, req RunRequest) (*RunResult, error)

Run 执行 headless 任务(stream-json NDJSON 事件流解析)。

type Codex

type Codex struct {
	Bin string // 默认 "codex"
}

Codex OpenAI Codex CLI 适配器(`codex exec --json --output-last-message <file>`)。

func NewCodex

func NewCodex() *Codex

NewCodex 创建 Codex 适配器。

func (*Codex) Capabilities

func (c *Codex) Capabilities() Capability

Capabilities 支持 Model/Sandbox(-m / --sandbox);exec 无续聊、轮数与工具白名单无对应参数。

func (*Codex) Name

func (c *Codex) Name() string

func (*Codex) Run

func (c *Codex) Run(ctx context.Context, req RunRequest) (*RunResult, error)

Run 执行 Codex exec 任务。 最终文本优先取 --output-last-message 文件(官方保证的最终消息),事件流兜底。

type Event

type Event struct {
	Type string // text | thinking | tool_call | tool_result | error | result
	Text string
	Tool string // tool_call/tool_result 的工具名
	Raw  json.RawMessage
}

Event 流式事件。 各适配器转发覆盖(v0.10.10 起错误事件全量转发——此前只转 text,纯错误跑的 transcript 为空、排障断链):mimo=error/text/result(step_finish);codex= error/text;claude=text/thinking/tool_call/result(is_error 以 error 型转发); pi=error(含 abort)/text/assistant 终态(result);kimi=text;gemini/ opencode 非流式(错误走 Run 返回值,无流式事件)。

type Gemini

type Gemini struct {
	Bin string // 默认 "gemini"
	// contains filtered or unexported fields
}

Gemini Gemini CLI 适配器(google-gemini/gemini-cli;Qwen Code 为其 fork,参数同族)。

协议要点(非交互模式):

  • `gemini -p "<prompt>" --output-format json` 输出单 JSON 对象: {"response":"...","stats":{"models":{"<model>":{"tokens":{"prompt":N,"candidates":N}}}}}
  • `-m/--model`;`--approval-mode default|auto_edit|yolo`(沙箱映射)

func NewGemini

func NewGemini() *Gemini

NewGemini 创建 Gemini CLI 适配器。

func NewQwen

func NewQwen() *Gemini

NewQwen 创建 Qwen Code 适配器(gemini-cli fork,参数同族)。

func (*Gemini) Capabilities

func (g *Gemini) Capabilities() Capability

Capabilities 支持 Model/Sandbox(-m / --approval-mode);非交互模式无续聊、轮数与工具白名单无对应参数。

func (*Gemini) Name

func (a *Gemini) Name() string

Name Agent 接口的 Name 实现(适配器嵌入即得)。

func (*Gemini) Run

func (g *Gemini) Run(ctx context.Context, req RunRequest) (*RunResult, error)

Run 执行 Gemini CLI 非交互任务。

type GenericAgent

type GenericAgent struct {
	AgentName string   // agent 标识(Name() 返回值)
	Argv      []string // argv 模板
	IsJSON    bool
}

GenericAgent 通用 CLI agent:以显式 argv 模板驱动任意 agent。 模板占位符:{prompt}(原样单参传入,无 shell 注入面)、{model}、{session}。 flag+占位符是**条件单元**:{model}/{session} 缺值时整体移除——连带移除紧邻的 前一个以 "-" 开头的参数(如 ["run","--model","{model}"] 在无 Model 时展开为 ["run"],绝不产生吞掉后续位置参数的悬空 flag)。 IsJSON=true 时按 {"text","sessionID","tokens":{"input","output"}} 解析输出。

用途:CLI 参数协议未稳定或私有 agent 的快速接入;协议稳定后应收敛为 专用适配器(mcode 于 2026-10-04 收敛为 Mcode,Minimax 预设随之移除)。

func NewDsh

func NewDsh() *GenericAgent

NewDsh dsh(DeepSeek Harness)预设:headless profile 单任务出口—— `dsh --profile headless "<task>"` 打印最终 assistant 消息后退出(2026-09-28 本机真实 CLI 核实:stdout 即最终答复、exit 0;无 JSON/会话/模型参数面)。

func NewGenericAgent

func NewGenericAgent(name string, argv []string, isJSON bool) *GenericAgent

NewGenericAgent 创建通用适配器。

func (*GenericAgent) Capabilities

func (g *GenericAgent) Capabilities() Capability

Capabilities 由 argv 模板推导:含 {model} 占位 → 支持 Model,含 {session} → 支持 Session;模板机制无法表达轮数/工具白名单/沙箱,一律不支持。

func (*GenericAgent) Name

func (g *GenericAgent) Name() string

func (*GenericAgent) Run

func (g *GenericAgent) Run(ctx context.Context, req RunRequest) (*RunResult, error)

Run 执行通用 CLI agent。

type Kimi

type Kimi struct {
	Bin string // 默认 "kimi"
}

Kimi Kimi Code CLI 适配器(MoonshotAI/kimi-code,参数经本机真实 CLI --help 核实)。

协议要点(非交互模式,headless):

  • `kimi -p "<prompt>"` 非交互执行(本身即全自主;不可与 --auto 组合——真实 CLI 实测报错)
  • `--output-format stream-json` 输出 JSONL 消息流:{"role":"assistant","content":"..."}
  • `-m/--model NAME` 覆盖模型;`-S/--session ID` 续聊

注:文档站描述的旧版 kimi-cli 用 `--print`;新一代 kimi-code 已改为 `-p` 直跑。

func NewKimi

func NewKimi() *Kimi

NewKimi 创建 Kimi 适配器。

func (*Kimi) Capabilities

func (k *Kimi) Capabilities() Capability

Capabilities 支持 Model/Session(--model / --session);沙箱/轮数/工具白名单无对应参数 (非交互模式本身即全自主——传 Sandbox 会被拒绝而非裸跑)。

func (*Kimi) Name

func (k *Kimi) Name() string

func (*Kimi) Run

func (k *Kimi) Run(ctx context.Context, req RunRequest) (*RunResult, error)

Run 执行 Kimi print 模式任务。

type Mcode

type Mcode struct {
	Bin string // 默认 "mcode"
	// contains filtered or unexported fields
}

Mcode MiniMax Code CLI 适配器(`mcode exec <prompt> --output-format json`, 参数与信封经本机真实 CLI 核实)。注册名沿历史键 "minimax"(bin 名为 mcode)。

协议要点(0.6.2 实弹):

  • exec 单 JSON 信封输出(stdout 单行): {"schemaVersion","type":"exec.result","sessionId":"mvs_...","status": "succeeded","output","model":{...},"usage":{"inputTokens","outputTokens", "cacheReadTokens","totalTokens"},"usageIncomplete"}
  • ⚠ 运行期失败 exit code 仍为 0(假模型名实弹核实)——失败识别只能靠信封 status=failed + error{category,message},本适配器如实上抛并经 EventError 全量转发(不因 exit 0 或有部分文本而当成功——mimo 同纪律)
  • `--model provider/model` 覆盖模型;不传用 CLI 缺省(实测 MiniMax-M3.1-Flash-Preview)
  • `--session mvs_...` 续聊(实测跨轮记忆成立,sessionId 稳定不变)
  • `--max-steps N` 轮数预算(对应 MaxTurns)
  • ⚠ 无沙箱可映射:--permission smart 在 headless 下工作区外写也放行 (实测于 $HOME 建文件成功),无"工作区内放行/外禁止"的运行时硬边界—— Capabilities 不声明 Sandbox,工作区硬条款仅剩 prompt 纪律(mimo 同款)
  • 非 JSON 输出(版本差异/日志混入)走全文兜底,不崩不误报

func NewMcode

func NewMcode() *Mcode

NewMcode 创建 MiniMax Code 适配器(注册名 minimax)。

func (*Mcode) Capabilities

func (m *Mcode) Capabilities() Capability

Capabilities 支持 Model/Session/MaxTurns(--model / --session / --max-steps); 沙箱与工具白名单无对应参数面(见类型注释 ⚠ 条目)。

func (*Mcode) Name

func (a *Mcode) Name() string

Name Agent 接口的 Name 实现(适配器嵌入即得)。

func (*Mcode) Run

func (m *Mcode) Run(ctx context.Context, req RunRequest) (*RunResult, error)

Run 执行 mcode exec 任务。

type Mimo

type Mimo struct {
	Bin string // 默认 "mimo"
	// DefaultModel 请求未指定 Model 时的缺省模型(xiaomi/ 全名)。空 = 尊重
	// 本机 CLI 配置(其缺省模型可能已被服务端下线)。
	DefaultModel string
	// contains filtered or unexported fields
}

Mimo 小米 MiMo Code 适配器(`mimo run --format json`,参数经本机真实 CLI 核实)。

协议要点:

  • `mimo run "<prompt>" --format json` 输出 JSONL 事件: {"type":"text","part":{"text":"..."}}" 增量文本 {"type":"step_finish","sessionID":"...","part":{"tokens":{"input","output"},"cost":N}} {"type":"error","error":{"data":{"message":"..."},"message":"..."}}(错误详情在 error.data.message——2026-09 实弹核实;error.message 顶层路径为兼容回退)
  • `-m provider/model` 覆盖模型:**须 xiaomi/ 全名前缀**(短名被服务端拒绝; 本机 CLI 缺省模型可能被服务端下线——ultraspeed 前车之鉴,生产装配建议显式 配置 DefaultModel)
  • `-s/--session ID` 续聊
  • ⚠ 运行期错误 exit code 仍为 0——错误识别只能靠事件流,本适配器对 error 事件如实上抛(不因恰好有部分文本而掩盖),并经 EventError 全量转发

func NewMimo

func NewMimo() *Mimo

NewMimo 创建 MiMo 适配器。

func (*Mimo) Capabilities

func (m *Mimo) Capabilities() Capability

Capabilities 支持 Model/Session(-m / -s);沙箱/轮数/工具白名单无对应参数。

func (*Mimo) Name

func (a *Mimo) Name() string

Name Agent 接口的 Name 实现(适配器嵌入即得)。

func (*Mimo) Run

func (m *Mimo) Run(ctx context.Context, req RunRequest) (*RunResult, error)

Run 执行 mimo run 任务。

type OpenCode

type OpenCode struct {
	Bin string // 默认 "opencode"
}

OpenCode opencode 适配器(`opencode run --json`)。

func NewOpenCode

func NewOpenCode() *OpenCode

NewOpenCode 创建 opencode 适配器。

func (*OpenCode) Capabilities

func (c *OpenCode) Capabilities() Capability

Capabilities 支持 Model/Session(-m / --session);沙箱/轮数/工具白名单无对应参数。

func (*OpenCode) Name

func (c *OpenCode) Name() string

func (*OpenCode) Run

func (c *OpenCode) Run(ctx context.Context, req RunRequest) (*RunResult, error)

Run 执行 opencode run 任务(--session 续聊、-m provider/model)。

type Pi

type Pi struct {
	Bin string // 默认 "pi"
	// DefaultModel 请求未指定 Model 时的缺省(provider/id 形态)。空 = 尊重
	// 本机 CLI 配置。
	DefaultModel string
	// contains filtered or unexported fields
}

Pi pi-coding-agent 适配器(`pi --mode json -p --no-session`,参数经本机真实 CLI 核实,2026-09-28 实弹采样)。

协议要点:

  • `pi --mode json -p "<prompt>"` 输出 JSONL 事件流: {"type":"message_start","message":{"role":...,"provider":...,"model":...}} {"type":"message_update","assistantMessageEvent":{"type":"text_delta",...}} {"type":"message_end","message":{"role":"assistant","content":[{"type": "thinking",...},{"type":"text","text":"..."}],"usage":{"input","output", "totalTokens","cost":{...}},"stopReason":...}} {"type":"turn_end"| "agent_end" | "agent_settled" | "session" | ...} 文本取 assistant message_end 的 "text" 内容块(thinking 块不计入正文); usage 含 input/output/reasoning 与 cost(多轮 message_end 后者覆盖前者)。
  • `-p/--print` 非交互执行;`--no-session` 不落会话(acpx 语义:每次 Run = 独立任务,不在 ~/.pi 留状态);扩展/技能/AGENTS.md 发现保持本机默认 (编码任务需要这些环境)。
  • `--model provider/id[:thinking]` 覆盖模型(支持 provider/id 形态)。
  • 中止形态(turn_abort 等)无 assistant message_end:有 exit!=0 时以退出错 误为准;exit=0 且事件流含 abort 类事件时如实报错(不静默空成功)。

func NewPi

func NewPi() *Pi

NewPi 创建 Pi 适配器。

func (*Pi) Capabilities

func (p *Pi) Capabilities() Capability

Capabilities 支持 Model(--model)与 Session(--session-id 精确续聊, 缺省则 --no-session 一次性);沙箱/轮数/工具白名单无对应参数。

func (*Pi) Name

func (a *Pi) Name() string

Name Agent 接口的 Name 实现(适配器嵌入即得)。

func (*Pi) Run

func (p *Pi) Run(ctx context.Context, req RunRequest) (*RunResult, error)

Run 执行 pi(--mode json 事件流解析)。

type Registry

type Registry struct {

	// OnRun 每次经本 Registry 发起的运行结束后的回调(nil 安全)。
	// 观测入口:接结构化日志/Prometheus/trace 均可,本包不硬依赖任何观测后端。
	OnRun func(RunEvent)
	// contains filtered or unexported fields
}

Registry agent 注册表:名字 → Agent 实例。

func NewRegistry

func NewRegistry() *Registry

NewRegistry 创建注册表并注册缺省 agent (claude/zcode/codex/opencode/minimax/kimi/gemini/qwen/mimo/pi/dsh,11 家)。

func (*Registry) AsTool

func (r *Registry) AsTool() tool.BaseTool

AsTool 把注册表包成 eino 工具(run_coding_agent),供 ReAct agent 自主调用。 与 rag.KnowledgeService.AsTool 同范式。 InferTool 失败(模板/schema 问题,属配置期错误)返回 nil——调用方不得把返回值 不判空就挂进工具表。

func (*Registry) Get

func (r *Registry) Get(name string) (Agent, bool)

Get 按名查找。

func (*Registry) Names

func (r *Registry) Names() []string

Names 返回全部注册名(注册序)。

func (*Registry) Register

func (r *Registry) Register(a Agent)

Register 注册 agent(重名覆盖)。

func (*Registry) Run

func (r *Registry) Run(ctx context.Context, name string, req RunRequest) (*RunResult, error)

Run 按名执行。入口先做能力校验:请求中 agent 声明不支持的非零字段 → fail-fast 报错(请求了即须兑现,拒绝静默降级——直连 Agent.Run 的调用方 应自行经 Capabilities 判断)。执行结束后发 RunEvent。

type RunEvent

type RunEvent struct {
	Agent     string        // agent 名
	Duration  time.Duration // 运行耗时
	Err       error         // 非空 = 运行失败
	TextLen   int           // 产出文本长度(不落内容,防泄露)
	Usage     Usage
	SessionID string
}

RunEvent 一次 agent 运行的观测事件(Registry.OnRun 钩子载荷)。

type RunRequest

type RunRequest struct {
	Prompt  string // 任务描述
	WorkDir string // 工作目录(agent 在此目录下执行)
	Model   string // 模型覆盖(空 = agent 默认)
	// SessionID 续接会话(Claude --resume / opencode --session;Codex 暂不支持续聊)。
	SessionID string
	// MaxTurns 最大 agent 轮数上限(防失控循环;0 = agent 默认)。
	MaxTurns int
	// AllowedTools 工具白名单(claude 族语义:"Bash(git:*)" "Read" "Edit";
	// 空 = agent 默认)。
	AllowedTools []string
	// Sandbox 沙箱级别:readonly | workspace | full(Codex 原生支持;
	// claude 族映射 permission-mode)。
	Sandbox string
	// Env 额外环境变量白名单,两种形态:纯名("HF_TOKEN")按名从当前进程
	// 透传;"KEY=VALUE" 字面注入(同名父进程值不透传——显式注入优先,见
	// procx.ChildEnv)。值会进入子进程环境,调用方自负泄漏面。
	Env []string
	// Timeout 单次运行超时(0 = 10 分钟缺省)。
	Timeout time.Duration
	// OnEvent 流式事件回调(nil = 只取最终结果)。
	// 注意:回调在 stdout 读取 goroutine 中同步执行——不得阻塞(拖慢子进程
	// 输出消费),不得 panic(会击穿整个进程)。
	OnEvent func(Event)
}

RunRequest 统一运行请求。

type RunResult

type RunResult struct {
	Text      string // 最终 assistant 文本
	SessionID string // 会话 ID(供续聊)
	Usage     Usage
	Duration  time.Duration
	ExitCode  int
	Raw       []byte // 原始 stdout(调试用)
	// Stderr 子进程 stderr 尾巴(≤400 字节,rune 对齐;空 = 无输出)。成功
	// 解析路径也有值——CLI 的告警/弃用提示走 stderr,transcript 排障需要。
	Stderr string
}

RunResult 统一运行结果。

type Usage

type Usage struct {
	InputTokens  int
	OutputTokens int
	CostUSD      float64
}

Usage token 用量与成本(agent 输出缺失时为 0)。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL