Files
pikasTech-agentrun/docs/reference/spec-v01-cli.md
T
2026-06-11 22:39:40 +08:00

24 KiB
Raw Blame History

v0.1 AgentRun CLI 规格

AgentRun CLI 是 v0.1 的受控人工操作和验收入口。它必须遵循 UniDesk cli-spec 原则:默认 JSON 输出、禁止空输出伪成功、禁止长阻塞、日志可见、配置显式校验,并优先通过 agentrun-mgr RESTful API 完成跨服务操作。

在系统中的职责划分

  • 创建 run、查询 run、提交 command、查询 command、分页读取 events。
  • 创建和查询 Queue task,查看 Queue stats/read/commander,并从 Queue task 获取 Session 引用。
  • 查询 Session 输出、trace 和会话控制;Queue 命令不得代理输出或 trace。
  • 手动启动 runner,本地 process 或 Kubernetes Job 均必须快速返回 job/process identity 和 logPath。
  • 查询 backend capability 和 manager health。
  • 为综合联调提供 CLI 交互面;不得替代 RESTful API 合同测试。
  • 不直连 Postgres,不读取 provider Secret 值,不把 debug/mock 路径伪装成正式验收。

CLI 入口

v0.1 固定规划入口:

scripts/agentrun-cli.ts
scripts/src/*.ts

CLI 官方 TypeScript 入口固定为 scripts/agentrun-cli.ts。在 G14 非交互 SSH route、CI task 和人工验收命令中,推荐使用仓库内 launcher:

./scripts/agentrun ...

该 launcher 只负责定位 bun(优先 BUN_BIN、其次 PATH、$HOME/.bun/bin/bun 和 G14 默认 /root/.bun/bin/bun),然后转入同一个 scripts/agentrun-cli.ts。它不实现第二套路由、不读取额外配置、不绕过 TypeScript CLI。bun scripts/agentrun-cli.ts ... 仍可在 PATH 已包含 Bun 的交互 shell 中使用;nodetsx 或其他 wrapper 只能作为本地开发辅助,不能成为 v0.1 综合联调的权威入口。

入口文件只负责参数解析和路由,具体实现拆到 scripts/src/。CLI 命令默认输出 JSON;任何命令无 stdout 都是失败。单次 CLI 调用必须在 60 秒内返回,长时间模型 turn 通过 status/events 后续命令观察。

初始命令族

./scripts/agentrun runs create --json-stdin|--json-file <run.json>
./scripts/agentrun runs show <runId>
./scripts/agentrun runs events <runId> --after-seq <n> --limit <n> [--summary|--tail-summary] [--tail <n>] [--summary-chars <n>] [--format json|tsv]
./scripts/agentrun runs result <runId> [--command-id <commandId>]
./scripts/agentrun runs cancel <runId> [--reason <text>]
./scripts/agentrun commands create <runId> --type turn|steer|interrupt --json-stdin|--json-file <payload.json>
./scripts/agentrun commands show <commandId> --run-id <runId>
./scripts/agentrun commands result <commandId> --run-id <runId>
./scripts/agentrun commands cancel <commandId> [--reason <text>]
./scripts/agentrun runner start --run-id <runId> --backend <backendProfile>
./scripts/agentrun runner job --run-id <runId> --command-id <commandId> [--idempotency-key <key>]
./scripts/agentrun runner job --dry-run --run-id <runId> --command-id <commandId> --image <image>
./scripts/agentrun runner jobs --run-id <runId> [--command-id <commandId>]
./scripts/agentrun runner job-status [runnerJobId] --run-id <runId>
./scripts/agentrun secrets codex render --dry-run [--profile codex|deepseek|minimax-m3|dsflash-go] [--codex-home <dir>] [--model-catalog-file <file>]
./scripts/agentrun provider-profiles list
./scripts/agentrun provider-profiles show <profile>
./scripts/agentrun provider-profiles remove <profile>
./scripts/agentrun provider-profiles set-key <profile> --key-stdin
./scripts/agentrun provider-profiles validate <profile> [--wait] [--timeout-ms <ms>]
./scripts/agentrun tool-credentials list
./scripts/agentrun tool-credentials show github-ssh|unidesk-ssh
./scripts/agentrun tool-credentials set-github-ssh --private-key-file <id_ed25519> --known-hosts-file <known_hosts> [--config-file <ssh_config>] [--dry-run]
./scripts/agentrun backends list
./scripts/agentrun server start [--port <port>] [--host <host>] [--foreground]
./scripts/agentrun server status [--port <port>]
./scripts/agentrun server logs [--port <port>] [--tail-bytes <bytes>] [--log-file <path>]
./scripts/agentrun server stop [--port <port>]
./scripts/agentrun queue submit --json-stdin|--json-file <task.json> [--dry-run]
./scripts/agentrun queue submit --aipod <name> [--prompt-stdin|--prompt-file <file>|--prompt <text>] [--idempotency-key <key>] [--dry-run]
./scripts/agentrun queue list [--queue <queue>] [--state <state>] [--cursor <cursor>] [--limit <limit>] [--full|--raw]
./scripts/agentrun queue show <taskId> [--full|--raw]
./scripts/agentrun queue stats [--queue <queue>]
./scripts/agentrun queue commander [--queue <queue>] [--reader-id <reader>] [--limit <display-limit>] [--full|--raw]
./scripts/agentrun queue read <taskId> [--reader-id <reader>] [--dry-run] [--full|--raw]
./scripts/agentrun queue cancel <taskId> [--reason <text>] [--dry-run] [--full|--raw]
./scripts/agentrun queue dispatch <taskId> [--json-stdin|--json-file <dispatch.json>] [--dry-run] [--full|--raw]
./scripts/agentrun queue refresh <taskId> [--dry-run] [--full|--raw]
./scripts/agentrun sessions ps [--state default|running|unread|terminal|idle|all] [--profile codex|deepseek|minimax-m3|dsflash-go|M3] [--reader-id <reader>]
./scripts/agentrun sessions show <sessionId> [--reader-id <reader>]
./scripts/agentrun sessions send [sessionId] [--json-stdin|--json-file <run-base.json>] [--prompt-stdin|--prompt-file <file>|--prompt <text>] [--profile codex|deepseek|minimax-m3|dsflash-go|M3] [--runner-json-stdin|--runner-json-file <job.json>] [--no-runner-job] [--dry-run]
./scripts/agentrun sessions send [sessionId] --aipod <name> [--prompt-stdin|--prompt-file <file>|--prompt <text>] [--runner-json-stdin|--runner-json-file <job.json>] [--no-runner-job] [--dry-run]
./scripts/agentrun sessions cancel <sessionId> [--reason <text>]
./scripts/agentrun sessions trace <sessionId> [--after-seq <n>] [--limit <limit>] [--run-id <runId>] [--include-output] [--seq <n>|--event-id <id>|--item-id <id>] [--detail-scan-pages <n>] [--full|--raw]
./scripts/agentrun sessions output <sessionId> [--after-seq <n>] [--limit <limit>] [--run-id <runId>] [--include-output] [--seq <n>|--event-id <id>|--item-id <id>] [--detail-scan-pages <n>] [--full|--raw]
./scripts/agentrun sessions read <sessionId> [--reader-id <reader>]
./scripts/agentrun aipod-specs list
./scripts/agentrun aipod-specs show <name>
./scripts/agentrun aipod-specs render <name> [--json-stdin|--json-file <input.json>] [--prompt-stdin|--prompt-file <file>|--prompt <text>]
./scripts/agentrun aipod-specs apply [name] --yaml-stdin|--yaml-file <spec.yaml> [--dry-run]
./scripts/agentrun aipod-specs delete <name>

具体参数可以在实现时按代码结构微调,但行为必须保持:

  • 创建类命令返回 runIdcommandId、status 和下一步 poll command。
  • runner start 返回 attemptId、job/process identity、logPath 和后续 status/events 命令。
  • runner jobs / runner job-status 返回 manager 持久化的 runner Job 最小状态摘要,包括 attemptId、runnerId、namespace、jobName、phase、terminalStatus、logPath、retention 和 redacted Kubernetes identity;业务方不需要直连 Kubernetes 才能定位当前 attempt。
  • runs show/resultcommands show/resultqueue show/commanderrunner jobs/job-status 的低噪声视图必须暴露 compact diagnosis,把 stale claimed、runner lost、terminal command/open run、sessionRef=null、provider interruption known/unknown、runner job phase 和下一步 drill-down 命令放到同一层级,避免监督者人工拼接 run、command、runner job 和 events 才能判断恢复入口。
  • aipod-specs renderqueue submit --aipod 必须调用同一 manager /api/v1/aipod-specs/:name/render 路径,把 YAML 展开为标准 Queue taskCLI 不得在本地复制一套 render 逻辑。
  • queue submit --aipod <name> 只接受本次任务输入(prompt、idempotencyKey、tenant/project/queue/lane/provider 覆盖等),模型、provider credential、tool credential、gitbundle 和 requiredSkills 由 spec-v01-aipod-spec.md 定义。
  • 查询类命令返回当前 state、terminal_status、failureKind、event cursor 或 logPath。
  • events 默认分页且有界,必须支持 afterSeqlimit;默认输出保持 manager raw JSON。
  • events --summary 返回低噪声 JSON summary,单条至少包含 seqtypemethodstatuscommandtextexitCodedurationMsoutputTruncatedoutputBytesoutputSummarysummary;summary 文本必须压缩换行并继续沿用 redaction,不能泄漏 Secret/env value。
  • events --tail <n>--after-seq/--limit 组合时,只显示本次分页结果最后 n 条 summary--tail-summary 是默认取最多 20 条 tail 的低噪声快捷入口。
  • events --format tsv 只在显式请求时输出 TSV 文本,用于人工现场跟踪和上层 trace 压缩;默认 JSON envelope 行为不得改变。
  • server start 默认以本地后台进程启动 manager,立刻返回 pid、pidFile、logPath、baseUrl 和后续 status/stop 命令;只有显式 --foreground 才允许占用当前终端。启动前必须检查 pidFile 与端口占用,避免同一端口上堆叠临时 manager。
  • server status 必须同时返回本地 pid/port/logPath 状态和 /health/readiness 结果;即使 readiness 失败,也要输出结构化 JSON 和 failure details。
  • server logs 必须返回有界日志尾部、bytes、truncated 和 logPath;找不到日志文件时也必须返回非空 JSON。
  • server stop 必须按 pidFile 与端口进程清理本地 manager,并返回 before/after 状态;不得要求人工用 ps/kill/ss 组合命令清理常见临时服务。
  • secrets codex render --dry-run 返回 Codex stdio profile Secret 创建计划、输入文件 bytes/hash、SecretRef、manifest 摘要和 apply 命令形状;--profile codex 默认 Secret name 为 agentrun-v01-provider-codex--profile deepseek 默认 Secret name 为 agentrun-v01-provider-deepseek--profile minimax-m3 默认 Secret name 为 agentrun-v01-provider-minimax-m3--profile dsflash-go 默认 Secret name 为 agentrun-v01-provider-dsflash-go 并包含 model-catalog.json;它不得输出 Secret value 或执行 Kubernetes 写操作。
  • provider-profiles 命令族调用 manager REST 管理 API,覆盖 profile status、删除、API Key 写入和 canary 验证。set-key --key-stdin 从 stdin 读取 API Key,响应只显示 SecretRef、resourceVersion、hash 后缀和 failureKind;不得输出 key、Codex auth/config 或 Secret data。
  • tool-credentials list|show 调用 manager REST 读取固定 tool credential 状态,只显示 SecretRef、key presence 和 hash 后缀;不得输出 Secret data。
  • tool-credentials set-github-ssh 是 GitHub SSH runtime Secret 的受控 bootstrap 入口;输入只能来自本地文件,CLI/manager response 只能显示 bytes、hash suffix、SecretRef 和 valuesPrinted=false,不得输出 private key、known_hosts 或 ssh config 内容。
  • backends list 必须显示 codexdeepseekminimax-m3dsflash-go profile 的 backendKind、protocol、transport、command、requiredSecretKeys 和状态;dsflash-gorequiredSecretKeys 必须包含 model-catalog.json;已配置的动态 provider profile(例如 hy)必须同样可见,并带动态 discovery 状态;不得因为某个 provider Secret 尚未配置就隐藏 capability。
  • queue submit/read/cancel/dispatch/refresh --dry-run 必须只返回 non-mutating plan,固定 dryRun=truemutation=false,不得创建 task、mark read、cancel、dispatch、refresh 或启动 runner job。
  • queue dispatch 是 Q2 的受控手动调度入口,只对单个 task 显式创建 attempt 和 Core run/command/runner job;不得伪装成自动 scheduler;带 --dry-run 时只读取 task 并展示将要 POST 的路径和有界 request 摘要。
  • queue refresh 只根据 Queue task 中保存的 Core run/command 引用回写 Queue attempt 状态,不读取 Core trace 反推 commander 或统计;带 --dry-run 时不得写回状态。
  • queue list/show/commander 默认返回低噪声 summary,只显示 task/attempt/session ids、state、read cursor、stats 相关字段、compact supervisor 和 drill-down 命令;commander 的 supervisor 只能放 phase、last activity source seq/id、timeout budget 和恢复动作摘要,不得展开完整 payload、trace、tool command、stdout/stderr 或 runnerTrace。需要完整 task payload、resource bundle 或 metadata 时显式使用 --full|--raw;需要 trace/output 细节时继续按返回的 sessionId/sourceSeqsessions trace|output --seq/--event-id/--item-id --full
  • queue show 不得返回或代理完整 output/trace;输出和 trace 只能通过返回的 sessionPath 对应 sessions ... 命令查询。
  • 需要提交较长 Queue task、dispatch body、run base 或 command payload 时,CLI 必须把 --json-stdin 作为首选入口,避免为了 heredoc/stdin 内容先写临时 dump 文件再传 --json-file--json-file 只用于可复用、已受控的输入文件。queue submit/dispatch --dry-runnext.confirm 不得默认推荐 --json-file,有 JSON body 时应提示 --json-stdin;只有用户显式维护可复用文件时才使用 file fallback。sessions send 的 runner job override 也必须支持 --runner-json-stdin。所有 stdin JSON 仍必须解析为 object,并在 dry-run 中只展示有界 body 摘要、bytes 和 keys。
  • sessions ps 默认只显示 running 和 unread session--state all 才显示历史 read session,避免旧 session 噪声淹没当前进度。
  • sessions send 是异步 subagent 的唯一用户级受控 CLI 入口:短返回 manager 决策、内部 command type、run/command/runnerJob 摘要和后续 poll/read/cancel 命令,不等待模型完成。CLI 只做 render-only clientmanager 的 /api/v1/sessions/:sessionId/send 读取 durable session 状态后自动决定内部创建 type=steer 还是新 type=turn + runner job。--profile M3minimax-m3 的 CLI aliasprofile 仍写入 canonical backendProfile,不得 fallback。
  • sessions send --dry-run 必须全路径 non-mutating,只返回将提交给 manager 的有界计划和 manager 根据当前 session 状态可判断的 decision,不得创建 session、PVC、run、command 或 runner job。sessions turn / sessions steer 已删除且不兼容;不得作为隐藏 alias、低层诊断入口、默认 help、恢复建议或调度者工作流重新出现。
  • sessions cancel 通过 Session control 取消 active command 或 runsessions read 写入 reader cursor,使 terminal session 从默认 ps 中消失。
  • sessions outputsessions trace 是输出和 trace 的唯一 CLI 查询入口;不得新增 queue outputqueue trace 兼容命令。
  • sessions outputsessions trace 默认必须按渐进披露输出低噪声 JSON:只展示 assistant_messagetool_call/error 摘要,command_outputbackend_status、raw event、runnerTrace 和大 stdout/stderr 只进入 suppressedEvents 计数与 bytes,不得默认展开正文。需要查看工具输出、backend_status 或原始 event 时,必须通过默认摘要中的 detailCommands,或显式使用 --seq <n>--event-id <id>--item-id <id>--include-output--full/--raw 做定点展开;默认摘要生成的 detailCommands 必须带上能定位该 event 的最小 --after-seq/--limit hint,避免按 id 拉详情时重新扫描长 trace。这样保证默认不爆上下文,同时按 id/seq 可完整追溯。

配置与 Secret 边界

  • CLI 配置必须显式校验;部署关键值不得静默 fallback。
  • CLI 调用 manager REST API;不得直接连 Postgres 或读 Kubernetes Secret value。
  • CLI 可以直接连接公网 HTTPS manager,例如 https://agentrun.74-48-78-17.nip.io/,但它仍只是 REST clientCLI 渲染、k8s 风格命令、human 输出、分页、--full|--raw 渐进披露都保留在客户端;manager 只返回稳定 JSON 业务事实,不承载 UniDesk 或其他客户端的展示逻辑。
  • 调用 runtime /api/v1/** 时 CLI 必须发送 Authorization: Bearer <token>。客户端 token 可以来自 AGENTRUN_API_KEYHWLAB_API_KEY 或对应 *_FILE,但输出只能展示来源、是否存在、hash/preview 等 redacted 元数据,不得打印 token value。/health* 探针不要求鉴权。
  • CLI 可以显示 SecretRef 名称、key、credential source、tool credential scope 和 readiness,但不得显示 Secret value、Codex auth.json、Codex config.toml、DSN password、token、SSH private key 或 URL credential。
  • CLI 不得把 GitHub token、UniDesk SSH client token、provider key 或长期 SSH key 通过 transientEnv 传入 runner;涉及 agent shell/tool 授权时,必须先按 spec-v01-runtime-assembly.mdtoolCredentials 装配路径实现,再提供 CLI 参数。非敏感服务地址例如 UNIDESK_MAIN_SERVER_IP 可以作为 runner-job transientEnv 的执行上下文注入。
  • Debug 子命令可以用于开发,但综合联调和测试规格不得用 debug 子命令作为通过证据。

测试规格

T1 CLI run 生命周期

阅读 AGENTS.md、本文和 spec-v01-validation.md,然后用 ./scripts/agentrun 创建 run、提交 turn command、启动 runner、轮询 command 和 events 直到 terminal_status。确认每个命令输出非空 JSON,60 秒内返回,并给出下一步可执行命令或 logPath。若直接执行 bun scripts/agentrun-cli.ts,必须先证明当前 shell 的 PATH 能找到 BunG14 route 默认以 ./scripts/agentrun 为准。

T2 CLI 错误可见性

阅读本文,然后用非法 backendProfile、缺失 SecretRef 和无效 runId 分别调用正式 CLI。确认每次失败都有 JSON 输出、failureKind、message、trace correlation 和 logPath 或诊断入口;不得空输出或只输出布尔值。

T3 CLI 日志可见性

阅读本文,然后启动一个会失败的 runner,并通过 CLI 返回的 logPath 或 pod identity 读取实际日志。确认日志包含足够定位失败原因的信息、异常 trace 或错误分类,同时没有 Secret value。

T4 CLI 与 RESTful 一致性

阅读本文和 spec-v01-agentrun-mgr.md,然后对同一个 run 分别使用 CLI 和 RESTful API 查询 run、command、events 和 terminal_status。确认 CLI 不维护独立状态,两种交互面观察结果一致。

T5 Backend profile CLI 切换

阅读本文、spec-v01-backend-codex.mdspec-v01-validation.md,然后用正式 CLI 分别创建 backendProfile=codexbackendProfile=deepseekbackendProfile=minimax-m3backendProfile=dsflash-go 的 run,按 codex -> deepseek -> minimax-m3 -> dsflash-go -> codex 顺序执行真实 runner。确认 CLI 输出非空 JSONbackend_status 显示正确 profile/backendKind/protocoldsflash-go 显示 deepseek-v4-flash、1M/900k context 和 model catalog 摘要,缺失对应 profile SecretRef 时返回 secret-unavailable,不会 fallback 到 codex 或其他 profile。

T5.1 Provider profile 管理 CLI

阅读本文和 spec-v01-provider-profile-management.md,然后用 ./scripts/agentrun provider-profiles listremove <profile>set-key deepseek --key-stdinvalidate deepseek --wait 验证 profile 管理闭环。确认 CLI 调 manager REST,不直连 Postgres,不读取 Kubernetes Secret value;输出包含 validationId/runId/commandId/jobName/resourceVersion/hash 后缀,且不包含 API Key、Codex auth/config 或 Secret data。

T6 Queue 与 Session CLI 分层

阅读本文和 spec-v01-queue.md,然后用正式 CLI 创建一个 Queue task,轮询 queue list/show/stats/commander/read,再使用 queue show 返回的 sessionPath 调用 sessions output/trace。确认 Queue 命令只返回 summary/stats/read/sessionPath,不代理 output/traceSession 命令能查询输出和 trace。最终交互验收必须使用真实 runtime,不使用 mock,不写自动交互脚本。

规格的实现情况

规格项 状态 说明
AgentRun CLI 规格 已定义 本文为 v0.1 CLI 权威。
scripts/agentrun-cli.ts 已实现 已提供 run/command/event/backend/server 基础命令和 JSON envelopescripts/agentrun 是同一入口的 Bun 定位 launcher。
CLI 调 manager REST 已实现 CLI 通过 ManagerClient 调 manager REST;自测试可用内存 manager,综合联调必须指向真实 agentrun-v01 manager。
runner start/job 已实现 runner start 可执行 host process runnerrunner job --dry-run 可渲染 Kubernetes Job JSONrunner job 正式路径通过 manager REST 创建 Kubernetes Job,支持 --idempotency-key 并快速返回 job identity、SecretRef、retention 和轮询命令。
runner jobs/job-status 已实现 CLI 通过 manager REST 查询 runner Job 持久记录和最小状态摘要,不直连 Kubernetes、不读取 Secret 值。
result/cancel CLI 已实现 runs resultcommands resultruns cancelcommands cancel 均调用 manager REST,不维护独立状态。
Queue CLI 已实现/Q1 已提供 queue submit/list/show/stats/commander/read/cancel,通过 manager REST 访问 Queue task 和 stats,不直连 Postgres。
Queue dispatch/refresh CLI 已实现/Q2 queue dispatch 受控创建 Core run/command/runner jobqueue refresh 从 Core run/command 终态回写 Queue task/latestAttempt。
本地 server 生命周期 CLI 已实现/Q2 hardening server start 默认后台短返回,server status/stop 提供 pid、port、logPath 和 readiness 可见性;--foreground 保留给容器/显式调试。
Session CLI 已实现/Q3 已提供 sessions ps/show/send/cancel/trace/output/read;默认 ps 只显示 running/unreadterminal 后自动 unreadread cursor 由 CLI 标记。用户级 CLI 只保留 sendturn/steer 只作为 manager 内部 command type,不再作为 CLI 入口或兼容 alias。
CLI 测试规格 已定义/已验证主闭环 综合联调见 spec-v01-validation.md;每次发布仍按手动交互验收复跑。
deepseek profile CLI 已实现/已通过主闭环 secrets codex render --profile deepseekbackends listrunner start --backendrunner job 和 JSON 错误可见性已实现;真实 CLI/RESTful 联调已通过 codex -> deepseek -> codex 切换主闭环。
Provider profile 管理 CLI 已实现 provider-profiles list/show/remove/set-key/validate 调用 manager REST API,用于 HWLAB 委托和 operator 验收;输出必须持续保持 Secret/API Key 脱敏。
Tool credential 管理 CLI 已实现 tool-credentials list/show/set-github-ssh 调用 manager REST API,用于 Artificer GitHub SSH Secret bootstrap;输出只包含 SecretRef、key presence、bytes 和 hash suffix。
minimax-m3 profile CLI 已实现/待真实主闭环 secrets codex render --profile minimax-m3backends listrunner start --backendrunner job、`sessions send --profile minimax-m3
dsflash-go profile CLI 已实现/待真实主闭环 secrets codex render --profile dsflash-go --model-catalog-filebackends listrunner start --backendrunner jobsessions send --profile dsflash-go 和 JSON 错误可见性已实现;真实 CLI/RESTful 联调需要按 codex -> deepseek -> minimax-m3 -> dsflash-go -> codex 手动验收,并确认 compact 404 分类为 provider-compact-unsupported