diff --git a/.agents/skills/unidesk-code-queue/SKILL.md b/.agents/skills/unidesk-code-queue/SKILL.md index 710bd7ab..7fc123bd 100644 --- a/.agents/skills/unidesk-code-queue/SKILL.md +++ b/.agents/skills/unidesk-code-queue/SKILL.md @@ -1,11 +1,11 @@ --- name: unidesk-code-queue -description: UniDesk AgentRun-backed Code Queue CLI — Skill(cli-spec)。legacy `codex` 子命令只保留历史只读/残留停止/prompt-lint;新任务提交、Aipod/Artificer 派单、steer/send、events/logs/result、ack/cancel、run/command/runner 状态 drill-down 和 HWLAB Code Agent/CaseRun follow-up 必须使用 `agentrun get|describe|events|logs|result|ack|cancel|create|apply|steer|send` 资源原语。用户提到 codex、Code Queue、submit、steer、resume、tasks、unread、code-queue、aipod、Artificer、HWLAB Code Agent 时使用。 +description: UniDesk AgentRun-backed Code Queue CLI — Skill(cli-spec)。legacy `codex` 子命令只保留历史只读/残留停止/prompt-lint;新任务提交、Aipod/Artificer 派单、steer/send、events/logs/result、ack/cancel、dispatch、run/command/runner 状态 drill-down 和 HWLAB Code Agent/CaseRun follow-up 必须使用 `agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|steer|send` 资源原语。用户提到 codex、Code Queue、submit、steer、resume、tasks、unread、code-queue、aipod、Artificer、HWLAB Code Agent 时使用。 --- # UniDesk Code Queue / AgentRun CLI -旧 Code Queue 已冻结新任务和写入口。`bun scripts/cli.ts codex ...` 现在只作为历史归档、只读排障、残留任务停止和 prompt-lint 入口;新的指挥官派单、Aipod/Artificer 执行、events/logs/result、ack/cancel、steer/send 必须走 AgentRun 资源原语,并按 cli-spec 渐进披露。默认输出是低噪声 human 表格/摘要;脚本读取显式使用 `-o json|yaml`,原始官方 bridge 调试显式使用 `--raw`。 +旧 Code Queue 已冻结新任务和写入口。`bun scripts/cli.ts codex ...` 现在只作为历史归档、只读排障、残留任务停止和 prompt-lint 入口;新的指挥官派单、Aipod/Artificer 执行、events/logs/result、ack/cancel、dispatch、steer/send 必须走 AgentRun 资源原语,并按 cli-spec 渐进披露。默认输出是低噪声 human 表格/摘要;脚本读取显式使用 `-o json|yaml`,原始官方 bridge 调试显式使用 `--raw`。 **固定入口前缀**: `cd /root/unidesk && bun scripts/cli.ts agentrun ...` @@ -53,6 +53,7 @@ bun scripts/cli.ts agentrun create task --aipod Artificer \ # 查看/控制 AgentRun session bun scripts/cli.ts agentrun logs session/ --tail 100 bun scripts/cli.ts agentrun ack session/ +bun scripts/cli.ts agentrun dispatch task/ bun scripts/cli.ts agentrun send session/ --aipod Artificer --prompt-stdin bun scripts/cli.ts agentrun steer session/ --prompt-stdin bun scripts/cli.ts agentrun cancel session/ --reason --dry-run @@ -62,7 +63,7 @@ bun scripts/cli.ts agentrun cancel session/ --reason --dry-run `AipodSpec` 是 AgentRun v0.1 的声明式 agent 装配:模型 profile、gitbundle、skills/tools、SecretRef 和 tool credential 都从 YAML 规格渲染。`Artificer` 默认用于 UniDesk 分布式开发任务,使用 `sub2api` provider、`gpt-5.5`、`reasoningEffort=xhigh`,并通过 SecretRef 注入 GitHub PR token、GitHub SSH 和 UniDesk SSH 透传能力。更新规格时使用 `agentrun aipod-specs apply --yaml-stdin --dry-run` 先看计划,确认后再去掉 `--dry-run`;不得把 API key、SSH key 或 token 写入 prompt、payload、YAML 或 issue。 -AgentRun Queue payload 需要 runner 内使用 UniDesk SSH 透传时,只通过 `executionPolicy.secretScope.toolCredentials[].tool=unidesk-ssh` 请求 `agentrun-v01-tool-unidesk-ssh/UNIDESK_SSH_CLIENT_TOKEN` SecretRef;不要把 token 写入 prompt、payload 或 `transientEnv`。非敏感 endpoint 使用 `UNIDESK_MAIN_SERVER_IP`、`UNIDESK_MAIN_SERVER_HOST` 或 `UNIDESK_FRONTEND_URL`,可由 runner-job `transientEnv` 显式提供;G14 `agentrun-v01` manager 也会在缺省时按受控默认值自动补齐,并在 trace 中只显示 env name/count/hash 与 `valuesPrinted=false`。 +AgentRun task payload 需要 runner 内使用 UniDesk SSH 透传时,只通过 `executionPolicy.secretScope.toolCredentials[].tool=unidesk-ssh` 请求 `agentrun-v01-tool-unidesk-ssh/UNIDESK_SSH_CLIENT_TOKEN` SecretRef;不要把 token 写入 prompt、payload 或 `transientEnv`。非敏感 endpoint 使用 `UNIDESK_MAIN_SERVER_IP`、`UNIDESK_MAIN_SERVER_HOST` 或 `UNIDESK_FRONTEND_URL`,可由 runner-job `transientEnv` 显式提供;G14 `agentrun-v01` manager 也会在缺省时按受控默认值自动补齐,并在 trace 中只显示 env name/count/hash 与 `valuesPrinted=false`。 ## Queue 渐进披露 @@ -74,6 +75,7 @@ AgentRun queue 生命周期不是一个单独的 `queue lifecycle` 命令,而 4. Command 级状态用 `describe command/ --run ` 和 `result command/ --run `,确认 command state、ack、terminal status 和结果摘要。 5. Runner job 只读状态用 `describe runnerjob/ --run `,确认 env image reuse、jobName、namespace、phase、exitCode、retention 和 `valuesPrinted=false`。不要为了这些字段手动调用 `trans G14:k3s kubectl ...`。 6. Session trace/output 只在 `describe task` 或 result 里有实际 `sessionId` 时使用 `logs|ack|steer|send|cancel session/`;`sessionRef=null` 时不要猜 session 命令。 +7. 已创建但尚未运行的 task 使用 `dispatch task/` 派发,不再退回旧 bridge `queue dispatch`。 默认视图必须低噪声且不是 JSON envelope,`-o json|yaml` 才输出稳定机器结构,`--raw` 才保留官方 AgentRun bridge 原始响应;命令返回里的下一步应优先是 `bun scripts/cli.ts agentrun ...` 资源原语,不得把人工 k8s 查询作为日常下一步。 diff --git a/docs/reference/agentrun.md b/docs/reference/agentrun.md index e8cf6772..1166cd85 100644 --- a/docs/reference/agentrun.md +++ b/docs/reference/agentrun.md @@ -111,7 +111,7 @@ UniDesk 不能作为以下内容的事实来源: AgentRun `v0.1` 的指挥官任务面已经按 AgentRun issue #105 完成真实运行面验收,可作为新任务派发、commander queue 观察、events/logs/result、steer/send、ack 和 cancel 的 AgentRun 侧标准路径。长期使用时仍以 AgentRun 仓库自身 SPEC 为能力事实来源;UniDesk 只记录该路径已经通过 G14 `agentrun-v01` 运行面和 `hy` profile + `gpt-5.5` 验证。 -UniDesk 指挥官新任务入口固定使用 `bun scripts/cli.ts agentrun get|describe|events|logs|result|ack|cancel|create|apply|steer|send` 资源原语。该入口是 G14 `/root/agentrun-v01` 中官方 `./scripts/agentrun --manager-url auto` CLI 的低噪声包装;默认 human 输出只显示表格、生命周期摘要和下一步命令,脚本读取显式使用 `-o json|yaml`,官方 bridge 原始响应显式使用 `--raw`。日常派单优先用 `agentrun create task --aipod Artificer --prompt-stdin` 或 `agentrun apply -f -` 的 quoted YAML/JSON heredoc/stdin 形式;旧 bridge 的 `--json-file`、`--prompt-file` 和 `--runner-json-file` 只用于已审阅且可复用的兼容调试。UniDesk 不实现 AgentRun queue 协议,也不把任务 double-write 回旧 Code Queue。 +UniDesk 指挥官新任务入口固定使用 `bun scripts/cli.ts agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|steer|send` 资源原语。该入口是 G14 `/root/agentrun-v01` 中官方 `./scripts/agentrun --manager-url auto` CLI 的低噪声包装;默认 human 输出只显示表格、生命周期摘要和下一步命令,脚本读取显式使用 `-o json|yaml`,官方 bridge 原始响应显式使用 `--raw`。日常派单优先用 `agentrun create task --aipod Artificer --prompt-stdin` 或 `agentrun apply -f -` 的 quoted YAML/JSON heredoc/stdin 形式;已创建未运行任务用 `agentrun dispatch task/` 派发;旧 bridge 的 `--json-file`、`--prompt-file` 和 `--runner-json-file` 只用于已审阅且可复用的兼容调试。UniDesk 不实现 AgentRun queue 协议,也不把任务 double-write 回旧 Code Queue。 `agentrun control-plane ...`、资源原语和兼容 bridge 组共用同一 UniDesk SSH capture bridge。主 server 本机可继续使用本地 backend-core broker;AgentRun runner、Artificer 或其他没有本地 Docker / `unidesk-backend-core` 容器的环境会自动改走既有 frontend `/ws/ssh` WebSocket backend,并在输出的 `bridge.capture.backend`、`reason` 和 `localBackendCore` 中披露选择依据。本地 `unidesk-backend-core` 容器不是 runner 环境使用这些 AgentRun CLI 入口的隐式前置条件。若所有 capture backend 都不可用,CLI 必须返回 `failureKind=bridge-execution-environment` 与 `capture-backend-unavailable` 或 `bridge-execution-environment-unavailable`,并给出受控恢复入口;AgentRun 官方 CLI 自身返回的 run/command/schema 错误不得被改写成 bridge 失败。 diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 51dc36fc..c3bc52de 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -93,7 +93,7 @@ CI/CD、GitOps、rollout、artifact 发布、PR 合并后的 runtime lane 滚动 - `ci install|status|run|publish-backend-core|publish-user-service|run-dev-e2e|logs` 管理 D601 原生 k3s 上的 Tekton CI。`run` 手动创建每 commit 检查和 Code Queue 只读性能门禁;`publish-backend-core` 与 `publish-user-service` 从 pushed Git commit 构建并发布 `127.0.0.1:5000/unidesk/:` commit-pinned artifacts,输出 `artifactSummary`(含 `serviceId`、`sourceCommit`、`sourceRepo`、`dockerfile`、`imageRef`、`tag`、`digest`、`digestRef`),但不部署生产;`run-dev-e2e` 的 Git 控制 runner、短 launcher、host fetch 边界、临时 smoke namespace 和 no-CD 规则只在 `docs/reference/dev-ci-runner.md` 定义;Tekton CI 通用规则见 `docs/reference/ci.md`。 - `schedule list|get|runs|run|retry-run|delete|upsert-pgdata-backup` 管理 backend-core 定时任务和运行历史。`schedule list`、`schedule get`、`schedule runs --limit N` 和 `schedule runs --limit N` 是只读观察入口;`schedule run`、`schedule retry-run`、`schedule delete` 和 `schedule upsert-pgdata-backup` 会触发运行或写入配置,生产恢复时必须有明确授权。`schedule runs --limit N` 是全局历史视图,返回 `scope=global` 和 `scheduleId=null`;`schedule runs --limit N` 是指定 schedule 历史视图,返回 `scope=schedule` 和对应 `scheduleId`。CLI 必须拒绝 `schedule runs 50` 这类纯数字位置参数,并提示使用 `schedule runs --limit 50`,避免把空数组误判成“没有历史 run”。`schedule run --wait-ms N` 触发同一 schedule,并且即使 wait 超时也必须返回 `newRunId` 和 `observeCommand`;`schedule retry-run ` 只接受 failed run,从原 run 反查 `scheduleId` 后重触发同一 schedule,并输出 `originalRunId`、`scheduleId`、`newRunId` 和 `observeCommand`。当 backend-core 目标容器缺失或只观察到 verify-only 容器时,schedule/microservice 命令必须以非零退出并返回 `failureKind=target-stack-not-running`、`runnerDisposition=infra-blocked`、`readOnlyCommands` 和 `authorizationRequiredForRecovery`,不得把 Docker 的 `No such container` 当成成功的空历史。 - `codex deploy ` 是旧 Code Queue 兼容部署入口,已禁用以防止维护通道直连 D601 部署 Code Queue;当前 dev 自动化只做 `ci run-dev-e2e` smoke,不提供 Code Queue CD,详细规则见 `docs/reference/codex-deploy.md`。 -- `agentrun get|describe|events|logs|result|ack|cancel|create|apply|steer|send` 是当前指挥官新任务和 AgentRun session 控制入口。UniDesk CLI 通过 G14 `/root/agentrun-v01` 中官方 `./scripts/agentrun --manager-url auto` 执行,默认 human 输出只显示表格、生命周期摘要和下一步命令;脚本读取显式使用 `-o json|yaml`,官方 bridge 原始响应显式使用 `--raw`。日常查看用 `get tasks --queue commander`、`describe task/`、`events run/`、`logs session/`、`result run/ --command `;日常写入用 `create task --aipod Artificer --prompt-stdin`、`apply -f -`、`steer/send session/`、`ack/cancel task|session/`。兼容 bridge 组 `queue|runs|commands|runner|sessions|aipod-specs` 只保留为 raw/debug 和尚未包装的低频能力入口。 +- `agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|steer|send` 是当前指挥官新任务和 AgentRun session 控制入口。UniDesk CLI 通过 G14 `/root/agentrun-v01` 中官方 `./scripts/agentrun --manager-url auto` 执行,默认 human 输出只显示表格、生命周期摘要和下一步命令;脚本读取显式使用 `-o json|yaml`,官方 bridge 原始响应显式使用 `--raw`。日常查看用 `get tasks --queue commander`、`describe task/`、`events run/`、`logs session/`、`result run/ --command `;日常写入用 `create task --aipod Artificer --prompt-stdin`、`apply -f -`、`dispatch task/`、`steer/send session/`、`ack/cancel task|session/`。兼容 bridge 组 `queue|runs|commands|runner|sessions|aipod-specs` 只保留为 raw/debug 和尚未包装的低频能力入口。 - `agentrun control-plane ...`、资源原语和兼容 bridge 组共用 UniDesk SSH capture bridge。主 server 本机可使用本地 backend-core broker;Artificer/AgentRun runner 等没有本地 Docker 或 `unidesk-backend-core` 容器的环境会自动使用 frontend `/ws/ssh` WebSocket backend,并在 `bridge.capture.backend`、`reason`、`localBackendCore` 中披露选择依据。本地 `unidesk-backend-core` 不是 runner 环境的隐式前置条件;若 capture backend 不可用,错误必须归类为 `failureKind=bridge-execution-environment` 并给出受控恢复入口。 - `codex submit/enqueue`、`codex steer`、`codex resume`、`codex queue create`、`codex queue merge`、`codex move`、旧 Web 提交表单、旧队列管理和旧 workdir 管理是冻结的 legacy Code Queue 写入口。CLI 必须返回 `ok=false`、`frozen=true`、`degradedReason=legacy-code-queue-frozen` 和 AgentRun 替代命令;服务端旧 API 写入口必须返回 410。新任务、steer/send、events/logs/result、ack 和 cancel 走 AgentRun 资源原语。 - 旧 Code Queue 只保留历史归档、只读排障和残留任务停止。`codex task/tasks/output/read/unread/queues` 继续通过 backend-core 私有代理读取旧 PostgreSQL 历史;`codex interrupt|cancel ` 只用于停止旧运行面残留任务。旧 `steer-confirm` 只作为历史 trace confirmation 查询,不是新任务控制入口。 diff --git a/docs/reference/code-queue-supervision.md b/docs/reference/code-queue-supervision.md index 2f6afb00..368667fa 100644 --- a/docs/reference/code-queue-supervision.md +++ b/docs/reference/code-queue-supervision.md @@ -87,18 +87,18 @@ HWLAB M3 口径使用同一分级:只读报告、fixture、LOCAL/DRY-RUN 和 d 靠近生产的任务 prompt 必须明确禁止在 master server 上跑已知可能 OOM 的重型本地检查,并说明哪些验证应在 D601 CI、dev env 或目标服务容器中执行。 -当一个指挥机需要突发创建大量 AgentRun 任务时,`queue submit` 默认应串行或接近串行。为了避免控制面在确认任务前被打爆,可以使用短本地锁或短延迟,尤其是在低内存主机上。目标是保持任务创建可观测且稳定,而不是最大化瞬时入队吞吐。 +当一个指挥机需要突发创建大量 AgentRun 任务时,`agentrun create task` 或 `agentrun apply -f -` 默认应串行或接近串行。为了避免控制面在确认任务前被打爆,可以使用短本地锁或短延迟,尤其是在低内存主机上。目标是保持任务创建可观测且稳定,而不是最大化瞬时入队吞吐。 ## 模型和成本路由 AgentRun 新派单和历史 Code Queue 审阅都按成本、可信度和 blast radius 分层:GPT-5.5/Codex 处理高风险和复杂任务,DeepSeek/OpenCode 处理中等复杂度且边界清晰的任务,MiniMax/OpenCode 处理简单、低权限、可复核任务,生产重启、密钥、数据库手工写入和运行中任务控制保留给指挥官或人工。 -当前新任务派发合同由 `bun scripts/cli.ts agentrun queue|sessions` 暴露:`queue commander` 查看 AgentRun 指挥官队列,`queue submit --json-stdin` 创建任务,`queue dispatch --json-stdin` 派发,`sessions trace/output/read/steer/cancel` 读取和控制 AgentRun session。日常一次性 JSON、prompt 和 runner JSON 输入优先用 quoted heredoc/stdin;`--json-file`、`--prompt-file`、`--runner-json-file` 只用于已审阅且可复用的受控文件。本地 UniDesk bridge 会把 stdin 直通官方 G14 `/root/agentrun-v01` CLI,不先落 dump 文件;它不是旧 Code Queue adapter,不做双写,也不迁移旧历史。 +当前新任务派发合同由 `bun scripts/cli.ts agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|steer|send` 资源原语暴露:`get tasks --queue commander` 查看指挥官队列,`create task --aipod Artificer --prompt-stdin` 或 `apply -f -` 创建任务,`dispatch task/` 派发,`events/logs/result/ack/cancel/steer/send` 读取和控制 AgentRun task、run 与 session。日常一次性 YAML/JSON 和 prompt 输入优先用 quoted heredoc/stdin;`--json-file`、`--prompt-file` 和旧 bridge 参数只用于已审阅且可复用的兼容调试。本地 UniDesk bridge 会把 stdin 直通官方 G14 `/root/agentrun-v01` CLI,不先落 dump 文件;它不是旧 Code Queue adapter,不做双写,也不迁移旧历史。 旧 `codex submit/enqueue`、`codex steer`、`codex resume`、旧 queue mutation、task move 和旧 workdir mutation 已冻结。CLI 必须返回 `ok=false`、`frozen=true`、`degradedReason=legacy-code-queue-frozen` 和 AgentRun 替代命令;服务端旧 API 写入口必须返回 410。旧 `codex task/tasks/output/read/unread/queues` 继续作为历史归档和只读排障入口,`codex interrupt|cancel` 只用于停止残留旧任务。 -新任务模型由 AgentRun queue payload 和 AgentRun runtime 配置决定;旧 Code Queue 的 `CODE_QUEUE_MODELS` 只作为历史任务审阅和残留运行面配置参考,长期合同至少包含 GPT-5.5、GPT-5.4、GPT-5.4 Mini、DeepSeek Chat、MiniMax M3 和 MiniMax M2.7 两路并行配置;`deepseek`/`deepseek-chat`、`minimax-m3` 与 `minimax-m2.7` 会走 OpenCode port,其余模型走 Codex port。PROD 集群把 `MINIMAX_MODEL` 切到 `MiniMax-M3`(M3 是新任务的默认 provider model),judge 与 opencode 跟随;M2.7 仍然作为并行配置存在,切换只需把 `MINIMAX_MODEL` 改成 `MiniMax-M2.7` 后 rollout restart。两者不存在自动 fallback 关系:M3 任务失败不会自动改派 M2.7,task 要用 M2.7 必须显式 `--model minimax-m2.7`。只有当执行面 `/health` 或等价配置已经显示 DeepSeek 模型可用、并完成轻量 runner smoke 后,才允许真实提交 `--model deepseek-chat`。 +新任务模型由 AgentRun task payload 和 AgentRun runtime 配置决定;旧 Code Queue 的 `CODE_QUEUE_MODELS` 只作为历史任务审阅和残留运行面配置参考,长期合同至少包含 GPT-5.5、GPT-5.4、GPT-5.4 Mini、DeepSeek Chat、MiniMax M3 和 MiniMax M2.7 两路并行配置;`deepseek`/`deepseek-chat`、`minimax-m3` 与 `minimax-m2.7` 会走 OpenCode port,其余模型走 Codex port。PROD 集群把 `MINIMAX_MODEL` 切到 `MiniMax-M3`(M3 是新任务的默认 provider model),judge 与 opencode 跟随;M2.7 仍然作为并行配置存在,切换只需把 `MINIMAX_MODEL` 改成 `MiniMax-M2.7` 后 rollout restart。两者不存在自动 fallback 关系:M3 任务失败不会自动改派 M2.7,task 要用 M2.7 必须显式 `--model minimax-m2.7`。只有当执行面 `/health` 或等价配置已经显示 DeepSeek 模型可用、并完成轻量 runner smoke 后,才允许真实提交 `--model deepseek-chat`。 -`codex prompt-lint [prompt|--prompt-file path|--prompt-stdin]` 仍是派单前的本地 dry-run guardrail,用于检查 runner prompt 是否声明 `DEV test class`、允许的 live mutation、禁止动作和 closeout 字段。它只返回分类、缺失或矛盾项和有界 evidence,不提交任务、不连接 live service、不打印完整 prompt;新派单时由指挥官把 lint 结果纳入 AgentRun `queue submit` payload 审查。 +`codex prompt-lint [prompt|--prompt-file path|--prompt-stdin]` 仍是派单前的本地 dry-run guardrail,用于检查 runner prompt 是否声明 `DEV test class`、允许的 live mutation、禁止动作和 closeout 字段。它只返回分类、缺失或矛盾项和有界 evidence,不提交任务、不连接 live service、不打印完整 prompt;新派单时由指挥官把 lint 结果纳入 AgentRun task payload 审查。 @@ -226,7 +226,7 @@ GPT-5.5 PR/收口类 prompt 在提交前可先用 host commander 辅助 lint 做 bun scripts/cli.ts commander prompt-lint --kind gpt55-pr --prompt-file /tmp/code-queue-prompt.md ``` -该检查只服务于指挥官补齐派单边界,不是业务 PR 门禁;legacy `codex submit` 已冻结,新任务 payload 审查走 AgentRun Queue。输出只包含 `ok`、`missingClauses`、`riskLevel`、`suggestedPatchSnippet` 和 prompt shape,不回显完整 prompt;`data.ok=false` 表示建议补齐 PR/自合并/rebase/update 授权、artifact build/publish 授权、host-owned DEV rollout、未显式 `ROLLOUT_OK` 时禁止 runner rollout、以及 PROD/secret/DB/破坏性回滚边界。 +该检查只服务于指挥官补齐派单边界,不是业务 PR 门禁;legacy `codex submit` 已冻结,新任务 payload 审查走 AgentRun 资源原语。输出只包含 `ok`、`missingClauses`、`riskLevel`、`suggestedPatchSnippet` 和 prompt shape,不回显完整 prompt;`data.ok=false` 表示建议补齐 PR/自合并/rebase/update 授权、artifact build/publish 授权、host-owned DEV rollout、未显式 `ROLLOUT_OK` 时禁止 runner rollout、以及 PROD/secret/DB/破坏性回滚边界。 Runner preflight 优先使用执行面诊断入口: @@ -275,7 +275,7 @@ bun scripts/cli.ts codex pr-preflight --remote --issue ### Runner Resume 收口 -PR 小修、冲突、rebase、补测和 reviewer feedback 的新执行入口是 AgentRun Queue/Sessions。仍在 AgentRun session 内的工作优先使用 `bun scripts/cli.ts agentrun sessions steer --prompt-stdin` 或 AgentRun reuse/turn 能力;已沉淀成新工作项时使用 `bun scripts/cli.ts agentrun queue submit --json-stdin`。旧 `codex resume` 已冻结,不再作为 follow-up turn 入口。 +PR 小修、冲突、rebase、补测和 reviewer feedback 的新执行入口是 AgentRun 资源原语。仍在 AgentRun session 内的工作优先使用 `bun scripts/cli.ts agentrun steer session/ --prompt-stdin` 或 `send session/`;已沉淀成新工作项时使用 `bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin` 或 `agentrun apply -f -`。旧 `codex resume` 已冻结,不再作为 follow-up turn 入口。 旧 Code Queue task 只保留历史审阅和残留停止;需要基于旧任务产出继续推进时,在 AgentRun payload 中显式引用旧 task id、PR/branch 和审阅结论,而不是把旧 task 重新入队、resume 或 double-write。 @@ -288,7 +288,7 @@ replacement runner 只用于方向明显错误、质量不可接受、原 task 常用入口: - `bun scripts/cli.ts codex tasks --view commander --limit N`:host commander 轮询的推荐入口。输出是有界 action map,必须直接显示 `activeRunners.count`、计数来源、split-brain/heartbeat 处置、queued/retry_wait 精确计数、terminal-unread 总数和已省略行数、active 风险数、stale/heartbeat/trace gap、`finalResponse` 已出现但仍非终态的 awaiting terminal/judge、blocker-like final response、HWLAB#7/#99/#116/#164/#317 与 UniDesk#20/#118 命中、任务分类和下一步 drill-down 命令。默认不得输出完整 prompt、完整 final response、raw output、完整 trace 或 raw overview;需要详情只能按 task id 使用 `codex task`、`codex task --trace`、`codex output`、`codex read` 或 `rawOverview` 命令渐进展开。 -- `bun scripts/cli.ts codex tasks --view supervisor --limit N`:查看旧 Code Queue 历史默认低噪声监督视图,包括 `activeRunning`、running、完成未读、少量最近完成、queued/runnable、activity、commanderConcurrency、execution diagnostics、任务分类和下一步 drill-down 命令。默认行只保留 task id、队列、短 prompt/body 预览和原始字符数;`--limit` 是扫描/分页预算,不是返回几十条肥行的开关,CLI effective limit 安全上限为 100,输出必须用 `filters.requestedLimit`、`filters.effectiveLimit`、`filters.limitCapped`、`source.requestedLimit` 和 `source.effectiveLimit` 区分用户请求、CLI cap 和 overview 源拉取预算。新任务派发和 follow-up 不再使用旧 `codex submit/resume/steer`,统一走 AgentRun Queue/Sessions。 +- `bun scripts/cli.ts codex tasks --view supervisor --limit N`:查看旧 Code Queue 历史默认低噪声监督视图,包括 `activeRunning`、running、完成未读、少量最近完成、queued/runnable、activity、commanderConcurrency、execution diagnostics、任务分类和下一步 drill-down 命令。默认行只保留 task id、队列、短 prompt/body 预览和原始字符数;`--limit` 是扫描/分页预算,不是返回几十条肥行的开关,CLI effective limit 安全上限为 100,输出必须用 `filters.requestedLimit`、`filters.effectiveLimit`、`filters.limitCapped`、`source.requestedLimit` 和 `source.effectiveLimit` 区分用户请求、CLI cap 和 overview 源拉取预算。新任务派发和 follow-up 不再使用旧 `codex submit/resume/steer`,统一走 AgentRun 资源原语。 - `bun scripts/cli.ts codex queues`:默认是 commander-first 队列态势摘要,`--commander` 是显式同义开关。输出前部固定使用 `.data.queues.commander`,先给出 `activeRunnerCount`、`source`、`target=15`、`slotDeficit`、`queuedCount`、`runningTasks`、`heartbeat.fresh`、`heartbeat.risk`、`heartbeat.staleRecoveryCandidates`、active/runnable queue 小页和 drill-down 命令;历史 queue item 列表保留在 `.data.queues.items[]`,但只是分页的次要行。需要完整队列行视图时加 `--full`,但 `--full` 仍默认分页,继续用 `--limit N`、`--page N` 或 `--offset N` 渐进展开。summary 和 full 都使用稳定 JSON path `.data.queues.items[]` 读取队列行,并从 `.data.queues.commander`、`.data.queues.commanderConcurrency`、`.data.queues.activity`、`.data.queues.counts` 与 `.data.queues.executionDiagnostics` 读取全局活跃计数和执行诊断;完整 upstream 只通过输出中的 raw command 显式获取。若 `/api/queues` 没有返回 task row,`runningTasks.items[].name` 会是 `null` 且 `nameSource=not-returned-by-api-queues`,此时按返回的 `codex task ` 或 supervisor 命令展开,不要假设任务没有名称。 - `bun scripts/cli.ts codex execution-plane [--full|--raw]`:只读巡检 D601 原生 k3s `unidesk` namespace 下的旧 Code Queue 执行面。该命令用于历史归档和残留任务诊断,不作为新任务能力门禁;新任务真实运行面验收走 AgentRun `v0.1` queue/session 原入口。默认不打印完整 Kubernetes Deployment JSON、环境变量全集、SecretRef 值或命令 stdout;需要逐项展开时使用 `--full`,需要安全裁剪后的原始观察对象时使用 `--raw`。 - `bun scripts/cli.ts codex unread --limit N`:查看完成未读审阅积压的默认 triage,按 repo、issue、status 和 queue 汇总,并给出有界最新任务紧凑行;默认行只包含 task id、状态、queue、issues、updatedAt/finishedAt 和一条 `nextStep`,不重复每任务 `show/detail/trace/output/read` 命令,也不输出 raw prompt、final response、trace 或 output。完整 per-task 命令必须显式使用 `codex unread --full`、`codex unread --view full`、`codex unread list` 或单任务 `codex task `/`codex read ` 展开;默认输出必须保留一次性的模板命令和分页命令。 @@ -297,7 +297,7 @@ replacement runner 只用于方向明显错误、质量不可接受、原 task - `bun scripts/cli.ts codex tasks --status succeeded --unread --limit N`:按具体终态过滤监督结果;不支持的 status filter 必须显式失败,不能扩大为未过滤结果。 - `bun scripts/cli.ts codex task `:默认只查看原始 prompt、最终 response、最后错误和 drill-down 命令,这是完成未读任务审阅的第一步。 - 当默认审阅摘要不足时,再逐级使用 `bun scripts/cli.ts codex task --detail`、`bun scripts/cli.ts codex task --trace --limit N` 或 `codex output`。 -- `bun scripts/cli.ts agentrun sessions steer --prompt-stdin`:对 AgentRun 中仍可继续的 session 追加修正;旧 `codex resume` 已冻结。 +- `bun scripts/cli.ts agentrun steer session/ --prompt-stdin`:对 AgentRun 中仍可继续的 session 追加修正;旧 `codex resume` 已冻结。 - 当 master 控制面状态和 D601 scheduler 状态看起来分裂时,使用 `docs/reference/observability.md` 中的活性规则判断。 默认 commander/supervisor 视图必须保持低噪声。commander 视图用于回答“现在需要处理什么”,supervisor 视图用于看分区小页和红线细节。commander 的 `activeRunners.count` 是指挥官 active runner 计数,supervisor 的 `activeRunning.count` 是 running+judging 状态计数;两者都必须标明 exact/source,不能把返回行数当成并发总数。`activeRunning.count` 来源是 queue summary 的 status counts 时 `activeRunning.exact=true`,用于 redline 判断;`activeRunning.rowPage.returned` / `running.returned` 只表示本次返回的紧凑任务行。`activeRunning.redline` 必须写明 `countField`、routine target、burst redline、hard redline、`state` 和 `decisionReady`;只有 `decisionReady=true` 时,才能直接用该 count 做红线/补派判断。commander 的 `attention.items` 只返回最需要处理的有界任务,`attention.total/returned/omitted` 必须保留省略计数;`sections.recentCompleted` 不得重复 `sections.terminalUnread` 的未读终态。`running`、`completedUnread` 和 `queued` 即使传入较大的 `--limit`,默认也只返回一个很小的有界页,并通过 section `commands.next` 继续分页;`--limit` 保留为扫描/分页预算和 full view 返回预算,不得让一次 commander/supervisor 调用输出几十条肥行。每个任务行只应带 task id 和必要摘要,`show`、`detail`、`trace`、`output`、`full`、`read` 使用 section template 或 row commands 表达,让下一步渐进披露动作明确且不重复;默认不得嵌入完整 queue 列表、完整 final response、raw output 页或完整 trace 行。`recentCompleted` 必须默认限量,且不得重复 `completedUnread` 里的未读终态,避免完成历史把当前 running、阻塞和未读审阅挤出视野;需要完整当前页时显式使用 `--view full`。`executionDiagnostics` 只能展示有界 task-id/reason 预览、总数、截断标记和 omitted counts;需要全量诊断时使用输出中的 raw command。`commands.read` 只是在人工审阅后的建议命令,listing 命令绝不能自动执行。 @@ -312,7 +312,7 @@ commander 视图的任务分类必须是确定性字段,至少区分 `user-fac 队列诊断中的 `split-brain` 表示控制面/执行面观测分裂,不自动证明任务已经死亡。只要任务 heartbeat 还在刷新、trace 仍在推进,就不能把它判成服务中断或要求立刻 stop;应把它视为 `splitBrainLive=true` 的 live 任务,继续监督并推进 #20 里的已排任务,而不是 interrupt、替换或把 backend 当成已经挂掉。队列摘要应显示 `effectiveLiveness=live`、`splitBrainLive=true` 和 `recommendedAction=continue-supervision`;compact 输出还应在 `executionDiagnostics.liveness` 中重复这些低噪声字段,并突出 `activeHeartbeatCount`、有界 `heartbeatFreshTaskIds`、`databaseActiveTaskCount` 和 `schedulerActiveRunSlotCount`。当 master/control-plane 的 `schedulerActiveRunSlotCount=0` 但 `heartbeatFreshTaskIds` 非空时,active 数应优先按 scheduler heartbeat 摘要解释为 live,而不是按 master 本地 slot 0 解释为执行停摆。只有 heartbeat expired/missing 或满足 stale-recovery 条件时,才应显示 `effectiveLiveness=at-risk` 并进入恢复判断。 -旧 Code Queue 的 bounded snapshot 只作为历史监督证据,不再作为新派单或恢复判据。新任务派发后应通过 `bun scripts/cli.ts agentrun queue commander --reader-id `、`queue show`、`sessions trace` 和 `sessions output` 观察 AgentRun 队列与 session。 +旧 Code Queue 的 bounded snapshot 只作为历史监督证据,不再作为新派单或恢复判据。新任务派发后应通过 `bun scripts/cli.ts agentrun get tasks --queue commander --limit 20`、`describe task/`、`events run/`、`logs session/` 和 `result run/ --command ` 观察 AgentRun 队列、run 与 session。 默认 supervisor poll 也遵循同一低噪声语义:heartbeat expired/missing、`heartbeatRiskTaskIds` 和 `staleRecoveryCandidateTaskIds` 必须可见,但第一次 poll 只表示 `transient-needs-repoll`,`activity.recovery.hint` 应为 `re-poll supervisor before recovery`。只有 repeated poll 仍确认 owner heartbeat expired、scheduler local no active run、database-active task 仍存在,并且输出显式带 `repeatedPollConfirmed=true` 或 confirmed stale candidate,才允许进入 bounded dry-run reconcile;真实恢复仍受高风险边界约束。 @@ -356,7 +356,7 @@ D601 artifact registry 的 systemd unit inactive 不等于 D601 全局离线。 每次新增 Code Queue 任务、补发 follow-up task,或处理一批完成未读任务后,都必须同步更新 GitHub 总看板 issue `#20` 的正文主表;如果发生实质态势变化,还要同步更新指挥简报 issue `#24` 的正文。看板更新应反映当前任务分布、关键 blocker 和粗略进度,不要只改聊天上下文或只改单个 issue,而让总态势图落后于实际调度状态。 -成本路由接入 #20 看板时,#20 的每个 AgentRun/历史 Code Queue 任务行都应显式保留推荐或实际 runner/model、风险等级、验证证据和审阅状态。推荐列的语义来自指挥官判断或 AgentRun queue payload 审查,不能来自 worker 自评。MiniMax 和 DeepSeek 任务在 #20 中必须先保持“待指挥官审阅”状态;只有指挥官核验 diff、commit、轻量验证和未越界后,才更新为已验收并执行对应的 AgentRun/历史 read 标记。 +成本路由接入 #20 看板时,#20 的每个 AgentRun/历史 Code Queue 任务行都应显式保留推荐或实际 runner/model、风险等级、验证证据和审阅状态。推荐列的语义来自指挥官判断或 AgentRun task payload 审查,不能来自 worker 自评。MiniMax 和 DeepSeek 任务在 #20 中必须先保持“待指挥官审阅”状态;只有指挥官核验 diff、commit、轻量验证和未越界后,才更新为已验收并执行对应的 AgentRun/历史 read 标记。 ## 指挥工作流 @@ -376,9 +376,9 @@ D601 artifact registry 的 systemd unit inactive 不等于 D601 全局离线。 只有存在明确理由时才干预。 - 如果任务还在运行且 trace 或 scheduler heartbeat 新鲜,应引导而不是 interrupt。 -- 对 AgentRun 运行中 session 的引导应优先使用正式 CLI:`bun scripts/cli.ts agentrun sessions steer --prompt-stdin`,再用 `sessions trace/output/read` 确认。旧 `codex steer` 已冻结,只保留历史 trace confirmation 查询。 +- 对 AgentRun 运行中 session 的引导应优先使用正式 CLI:`bun scripts/cli.ts agentrun steer session/ --prompt-stdin`,再用 `logs/events/result/ack` 确认。旧 `codex steer` 已冻结,只保留历史 trace confirmation 查询。 - 真实 steer 输出必须保持低噪声:成功显示 `steer.status`、`steer.deliveryState`、`steer.steerId`、有界 `traceConfirmation` 和后续命令,不回显 prompt 或完整 task state;失败默认不带 request body、不带 upstream body preview,也不带 raw response,需要上游预览或原始失败对象时显式重跑 `--full` 或 `--raw`。`deliveryState=accepted` 表示 backend 已接受;`not_accepted` 表示任务状态/权限/输入未接受;`accepted_response_timeout` 表示 stable proxy 响应超时但 trace confirmation 找到该 `steerId`;`unknown` 表示响应路径失败且确认查询仍未证明接受。 -- 旧 Code Queue 的 provider tunnel 失败只作为历史运行面诊断线索;新任务控制面失败优先按 AgentRun `queue show`、`sessions trace/output`、G14 `agentrun-v01` manager 和 runner job 证据分流。 +- 旧 Code Queue 的 provider tunnel 失败只作为历史运行面诊断线索;新任务控制面失败优先按 AgentRun `describe task`、`events`、`logs`、`result`、G14 `agentrun-v01` manager 和 runner job 证据分流。 - 新 AgentRun 任务失败分流以 AgentRun queue/session/runner-job 返回字段为准。旧 Code Queue `.data.diagnostics.reason` 只用于历史任务和残留运行面,不再引导新 `codex submit/steer/resume`。 - 如果任务进入终态但缺少必要验收证据,应使用聚焦 continuation prompt retry 同一任务。 - 如果任务被可复用基础设施缺陷阻塞,应把该缺陷分配给合适的空闲或低风险队列,让原业务任务等待,或在修复后 retry。 diff --git a/scripts/agentrun-cli-contract-test.ts b/scripts/agentrun-cli-contract-test.ts index 189fd286..963ffcbe 100644 --- a/scripts/agentrun-cli-contract-test.ts +++ b/scripts/agentrun-cli-contract-test.ts @@ -45,6 +45,7 @@ assertCondition( agentRunUsage.some((line) => line.includes("agentrun result run/ --command ")) && agentRunUsage.some((line) => line.includes("agentrun ack task/ --reader-id cli")) && agentRunUsage.some((line) => line.includes("agentrun cancel task/ --reason --dry-run")) + && agentRunUsage.some((line) => line.includes("agentrun dispatch task/")) && agentRunUsage.some((line) => line.includes("agentrun create task --aipod Artificer --prompt-stdin")) && agentRunUsage.some((line) => line.includes("agentrun apply -f - --dry-run")) && agentRunUsage.some((line) => line.includes("agentrun steer session/ --prompt-stdin")) @@ -62,7 +63,7 @@ assertCondition( const globalHelp = JSON.stringify(rootHelp()); assertCondition( - globalHelp.includes("agentrun get|describe|events|logs|result|ack|cancel|create|apply|steer|send"), + globalHelp.includes("agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|steer|send"), "global help must index AgentRun v0.1 entrypoints", rootHelp(), ); @@ -98,6 +99,14 @@ assertCondition( "AgentRun resource parser must parse verb-level flags such as apply -f - before requiring runtime config", ); +assertCondition( + agentRunSource.includes('if (verb === "dispatch") return await resourceDispatch(config, command, action, actionArgs, options);') + && agentRunSource.includes('runOfficialAgentRunCli(config, "queue", ["dispatch", ref.name') + && agentRunSource.includes('"list", "--state", taskListState(options)') + && agentRunSource.includes('["commander", "--reader-id", options.readerId'), + "AgentRun resources must wrap task dispatch and keep default get tasks on active list visibility", +); + assertCondition( agentRunSource.includes("const effectiveLimit = options.tail ?? options.limit;") && agentRunSource.includes("return renderEventLike(command, result, { ...options, limit: effectiveLimit }, \"Log\""), @@ -124,6 +133,7 @@ console.log(JSON.stringify({ "AgentRun CLI bridge selects remote frontend backend in runner/no-Docker environments", "AgentRun CLI bridge keeps AgentRun failures distinct from bridge failures", "AgentRun resource parser supports apply -f -", + "AgentRun resource task dispatch and active task list visibility", "AgentRun logs tail controls page limit", "AgentRun dry-run mutations keep resource-command follow-up", ], diff --git a/scripts/src/agentrun.ts b/scripts/src/agentrun.ts index 8fd7eee1..6662227c 100644 --- a/scripts/src/agentrun.ts +++ b/scripts/src/agentrun.ts @@ -26,7 +26,7 @@ const mirrorToolsImage = "127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine export function agentRunHelp(): unknown { return { - command: "agentrun get|describe|events|logs|result|ack|cancel|create|apply|steer|send|explain", + command: "agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|steer|send|explain", output: "human by default; use -o json|yaml or --raw for machine/debug output", usage: [ "bun scripts/cli.ts agentrun get tasks --queue commander --limit 20", @@ -38,6 +38,7 @@ export function agentRunHelp(): unknown { "bun scripts/cli.ts agentrun result run/ --command ", "bun scripts/cli.ts agentrun ack task/ --reader-id cli", "bun scripts/cli.ts agentrun cancel task/ --reason --dry-run", + "bun scripts/cli.ts agentrun dispatch task/", "bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin --idempotency-key ", "bun scripts/cli.ts agentrun apply -f - --dry-run", "bun scripts/cli.ts agentrun steer session/ --prompt-stdin", @@ -62,7 +63,7 @@ export function agentRunHelp(): unknown { ], resources: ["task/qt", "run", "command/cmd", "runnerjob/rjob", "session/ses", "aipodspec/aps"], description: "Operate AgentRun v0.1 through Kubernetes-style resource verbs. Human output is compact by default; -o json|yaml returns the UniDesk resource schema, and --raw exposes the official G14 /root/agentrun-v01 CLI bridge response.", - legacyCompatibility: "queue/runs/commands/runner/sessions/aipod-specs remain as compatibility bridge groups, but new commander work should use get/describe/events/logs/result/ack/cancel/create/apply/steer/send.", + legacyCompatibility: "queue/runs/commands/runner/sessions/aipod-specs remain as compatibility bridge groups, but new commander work should use get/describe/events/logs/result/ack/cancel/dispatch/create/apply/steer/send.", }; } @@ -133,6 +134,7 @@ function isResourceVerb(value: string | undefined): value is AgentRunResourceVer || value === "result" || value === "ack" || value === "cancel" + || value === "dispatch" || value === "create" || value === "apply" || value === "steer" @@ -187,11 +189,14 @@ function agentRunHelpText(args: string[]): string { if (verb === "cancel") { return "Usage: bun scripts/cli.ts agentrun cancel task/|session/ --reason [--dry-run]"; } + if (verb === "dispatch") { + return "Usage: bun scripts/cli.ts agentrun dispatch task/"; + } if (verb === "create") { return "Usage: bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin [--idempotency-key ] [--dry-run]"; } if (verb === "apply") { - return "Usage: bun scripts/cli.ts agentrun apply -f task.yaml|json|- [--dry-run]\nTask manifests use kind: Task and spec: ."; + return "Usage: bun scripts/cli.ts agentrun apply -f task.yaml|json|- [--dry-run]\nTask manifests use kind: Task and spec: ."; } if (verb === "steer") { return "Usage: bun scripts/cli.ts agentrun steer session/ --prompt-stdin"; @@ -235,7 +240,7 @@ function agentRunHelpText(args: string[]): string { return [ "Usage: bun scripts/cli.ts agentrun [options]", "", - "Verbs: get, describe, events, logs, result, ack, cancel, create, apply, steer, send, explain", + "Verbs: get, describe, events, logs, result, ack, cancel, dispatch, create, apply, steer, send, explain", "Resources: task/qt, run, command/cmd, runnerjob/rjob, session/ses, aipodspec/aps", "", "Common:", @@ -253,7 +258,7 @@ function agentRunHelpText(args: string[]): string { function agentRunGetKindHelp(kindRaw: string): string { const kind = parseResourceKind(kindRaw); - if (kind === "task") return "Usage: bun scripts/cli.ts agentrun get tasks [--queue commander] [--state running,completed,failed] [--unread] [--limit 20] [-o wide|name|json|yaml]"; + if (kind === "task") return "Usage: bun scripts/cli.ts agentrun get tasks [--queue commander] [--state running,pending,completed,failed] [--unread] [--limit 20] [-o wide|name|json|yaml]"; if (kind === "session") return "Usage: bun scripts/cli.ts agentrun get sessions [--limit 20] [-o wide|name|json|yaml]"; if (kind === "run") return "Usage: bun scripts/cli.ts agentrun get runs --task [--limit 20] [-o wide|name|json|yaml]"; if (kind === "command") return "Usage: bun scripts/cli.ts agentrun get commands --run [--command ] [-o wide|name|json|yaml]"; @@ -276,6 +281,7 @@ async function runAgentRunResourceCommand(config: UniDeskConfig, verb: AgentRunR if (verb === "result") return await resourceResult(config, command, action, actionArgs, options); if (verb === "ack") return await resourceAck(config, command, action, actionArgs, options); if (verb === "cancel") return await resourceCancel(config, command, action, actionArgs, options); + if (verb === "dispatch") return await resourceDispatch(config, command, action, actionArgs, options); if (verb === "create") return await resourceCreate(config, command, action, actionArgs, options); if (verb === "apply") return await resourceApply(config, command, actionArgs, options); if (verb === "steer") return await resourceSessionPromptCommand(config, command, "steer", action, actionArgs, options); @@ -383,7 +389,10 @@ async function resourceGet(config: UniDeskConfig, command: string, action: strin if (kind === null) throw new Error("get requires a resource: tasks|sessions|runs|commands|runnerjobs|aipodspecs"); let result: Record; if (kind === "task") { - result = await runOfficialAgentRunCli(config, "queue", ["commander", "--reader-id", options.readerId, "--limit", String(options.limit)]); + const taskListArgs = options.unread + ? ["commander", "--reader-id", options.readerId, "--limit", String(options.limit)] + : ["list", "--state", taskListState(options), "--limit", String(options.queue === null ? options.limit : Math.max(options.limit, 100))]; + result = await runOfficialAgentRunCli(config, "queue", taskListArgs); return renderResourceResult(command, result, options, "Task", normalizeTaskItems(innerData(result), options).slice(0, options.limit)); } if (kind === "session") { @@ -503,6 +512,15 @@ async function resourceCancel(config: UniDeskConfig, command: string, action: st return renderMutationSummary(command, result, options, `${options.dryRun ? "Planned cancel" : "Cancel requested"} ${ref.kind}/${shortId(ref.name)}`, options.dryRun ? [rerunWithoutDryRun(command)] : undefined); } +async function resourceDispatch(config: UniDeskConfig, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise { + const ref = parseResourceRef(action, args, "task"); + if (ref.kind !== "task") throw new Error("dispatch supports task/"); + const result = await runOfficialAgentRunCli(config, "queue", ["dispatch", ref.name, ...stripLeadingResource(args, ref.name)]); + return renderMutationSummary(command, result, options, `Task dispatch submitted ${shortId(ref.name)}`, [ + `bun scripts/cli.ts agentrun describe task/${ref.name}`, + ]); +} + async function resourceCreate(config: UniDeskConfig, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise { const kind = parseResourceKind(action); if (kind !== "task") throw new Error("create currently supports: create task"); @@ -698,6 +716,11 @@ function normalizeTaskItems(data: unknown, options: AgentRunResourceOptions): Re }); } +function taskListState(options: AgentRunResourceOptions): string { + const requested = options.state?.split(",").map((item) => item.trim()).filter((item) => item.length > 0); + return requested?.[0] ?? "running"; +} + function normalizeSessionItems(data: unknown): Record[] { const items = arrayRecords(record(data).items ?? data); return items.map((item) => ({ @@ -897,7 +920,7 @@ function parseTaskManifest(raw: string, source: string): Record const spec = record(input.spec); const payload = Object.keys(spec).length > 0 ? spec : input; if (!isRecord(payload.payload) && !isRecord(payload.executionPolicy) && stringOrNull(payload.title) === null) { - throw new Error("task manifest must contain spec with an AgentRun queue submit payload"); + throw new Error("task manifest must contain spec with an AgentRun task payload"); } return payload; } @@ -2475,7 +2498,7 @@ interface PreparedAgentRunCliArgs { } type AgentRunOfficialCliBridgeGroup = "queue" | "sessions" | "aipod-specs" | "aipods" | "runs" | "commands" | "runner"; -type AgentRunResourceVerb = "get" | "describe" | "events" | "logs" | "result" | "ack" | "cancel" | "create" | "apply" | "steer" | "send" | "explain"; +type AgentRunResourceVerb = "get" | "describe" | "events" | "logs" | "result" | "ack" | "cancel" | "dispatch" | "create" | "apply" | "steer" | "send" | "explain"; type AgentRunResourceKind = "task" | "run" | "command" | "runnerjob" | "session" | "aipodspec"; type AgentRunOutputMode = "human" | "wide" | "name" | "json" | "yaml"; @@ -3125,7 +3148,7 @@ function unsupported(args: string[]): RenderedCliResult { `Error: unsupported AgentRun command: ${command}`, "", "Supported resource commands:", - " agentrun get|describe|events|logs|result|ack|cancel|create|apply|steer|send", + " agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|steer|send", "", "Compatibility bridge groups:", " agentrun aipod-specs|queue|runs|commands|runner|sessions", diff --git a/scripts/src/code-queue.ts b/scripts/src/code-queue.ts index 76c222d0..2755a232 100644 --- a/scripts/src/code-queue.ts +++ b/scripts/src/code-queue.ts @@ -65,14 +65,18 @@ const maxSteerRetryDelayMs = 5_000; const codexTaskStatuses = ["queued", "running", "judging", "retry_wait", "succeeded", "failed", "canceled"] as const; const codexTerminalTaskStatuses = ["succeeded", "failed", "canceled"] as const; const agentRunQueueReplacementCommands = { - queueCommander: "bun scripts/cli.ts agentrun queue commander --reader-id cli", - queueSubmit: "bun scripts/cli.ts agentrun queue submit --json-stdin <<'JSON'", - queueDispatch: "bun scripts/cli.ts agentrun queue dispatch --json-stdin <<'JSON'", - sessionsTrace: "bun scripts/cli.ts agentrun sessions trace --after-seq 0 --limit 100", - sessionsOutput: "bun scripts/cli.ts agentrun sessions output --after-seq 0 --limit 100", - sessionsSteer: "bun scripts/cli.ts agentrun sessions steer --prompt-stdin <<'EOF'", - sessionsRead: "bun scripts/cli.ts agentrun sessions read --reader-id cli", - queueCancel: "bun scripts/cli.ts agentrun queue cancel --reason ", + taskOverview: "bun scripts/cli.ts agentrun get tasks --queue commander --limit 20", + taskCreate: "bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin", + taskApply: "bun scripts/cli.ts agentrun apply -f - <<'YAML'", + taskDispatch: "bun scripts/cli.ts agentrun dispatch task/", + taskDescribe: "bun scripts/cli.ts agentrun describe task/", + runEvents: "bun scripts/cli.ts agentrun events run/ --after-seq 0 --limit 100", + runResult: "bun scripts/cli.ts agentrun result run/ --command ", + sessionLogs: "bun scripts/cli.ts agentrun logs session/ --tail 100", + sessionSteer: "bun scripts/cli.ts agentrun steer session/ --prompt-stdin", + sessionSend: "bun scripts/cli.ts agentrun send session/ --aipod Artificer --prompt-stdin", + taskAck: "bun scripts/cli.ts agentrun ack task/", + taskCancel: "bun scripts/cli.ts agentrun cancel task/ --reason ", }; const codexTaskStatusAliases: Record = { completed: "succeeded", @@ -103,7 +107,7 @@ function legacyCodeQueueFrozenMutation(command: string): Record frozen: true, mutation: false, degradedReason: "legacy-code-queue-frozen", - error: "旧 UniDesk Code Queue 新任务和执行写入口已冻结;新任务使用 AgentRun Queue。", + error: "旧 UniDesk Code Queue 新任务和执行写入口已冻结;新任务使用 AgentRun 资源原语。", command, replacement: agentRunQueueReplacementCommands, legacy: { diff --git a/scripts/src/help.ts b/scripts/src/help.ts index 4e1bd5d5..b8c2da6d 100644 --- a/scripts/src/help.ts +++ b/scripts/src/help.ts @@ -57,7 +57,7 @@ export function rootHelp(): unknown { { command: "commander contract|plan --dry-run|smoke --dry-run|approval request --dry-run|prompt-lint --kind gpt55-pr", description: "Host Codex commander skeleton contract, no-daemon smoke plan, dry-run approval preview, and advisory GPT-5.5 PR prompt boundary lint without live bridges, message sends, or submit gating." }, { command: "hwlab nodes control-plane|git-mirror|secret --node G14 --lane v03", description: "Manage HWLAB node/lane runtime prerequisites for v0.3+ with the node identity passed as data instead of a command family." }, { command: "hwlab g14 monitor-prs | hwlab g14 control-plane status|apply|trigger-current|runtime-migration|cleanup-runs|cleanup-released-pvs | hwlab g14 git-mirror status|apply|sync|flush | hwlab g14 tools-image status|build", description: "Start the legacy G14 PR monitor, run bounded v0.2 Tekton/Argo control-plane, manual PipelineRun trigger, runtime migration, CI workspace retention, manual devops-infra git mirror/relay maintenance, or fixed HWLAB CI tools image actions; long confirmed trigger/sync/flush actions return async jobs by default." }, - { command: "agentrun get|describe|events|logs|result|ack|cancel|create|apply|steer|send|control-plane|git-mirror", description: "Use AgentRun v0.1 resource primitives with low-noise human output by default; legacy bridge groups remain available for raw compatibility." }, + { command: "agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|steer|send|control-plane|git-mirror", description: "Use AgentRun v0.1 resource primitives with low-noise human output by default; legacy bridge groups remain available for raw compatibility." }, { command: "platform-infra sub2api plan|apply|status|validate|codex-pool", description: "Deploy Sub2API in G14 platform-infra, manage the YAML-controlled Codex upstream pool, expose the unified API through FRP when needed, and configure master ~/.codex without printing API keys." }, { command: "hwlab cd audit --env dev | hwlab cd status --env dev | hwlab cd apply --env dev --dry-run", description: "Legacy D601 HWLAB DEV CD wrapper kept for explicit old-path diagnostics; current HWLAB rollout uses G14 GitOps." }, { command: "code-agent-sandbox", description: "Independent Code Agent Sandbox service skeleton for adapter, mode, and credential-boundary diagnostics." }, @@ -418,7 +418,7 @@ function codexHelp(): unknown { }, executionMode: { validModes: ["default", "windows-native"], - boundary: "Legacy Code Queue submit is frozen; new runtime placement is selected by AgentRun Queue payloads.", + boundary: "Legacy Code Queue submit is frozen; new runtime placement is selected by AgentRun task payloads.", permissionVisibility: "Legacy Code Queue read commands expose historical runner metadata only; new tasks use AgentRun resource primitives.", }, submitSummary: { @@ -482,7 +482,7 @@ function codexHelp(): unknown { embeddedIn: [], reference: "docs/reference/code-queue-supervision.md#dev-测试授权分级", }, - description: "Operate legacy Code Queue as a read-only archive through bounded task/output/read/unread/queues views. New task dispatch, retry/resume, steer, queue mutation, move, and workdir mutation are frozen and replaced by AgentRun resource primitives via bun scripts/cli.ts agentrun get|describe|events|logs|result|ack|cancel|create|apply|steer|send.", + description: "Operate legacy Code Queue as a read-only archive through bounded task/output/read/unread/queues views. New task dispatch, retry/resume, steer, queue mutation, move, and workdir mutation are frozen and replaced by AgentRun resource primitives via bun scripts/cli.ts agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|steer|send.", }; } @@ -597,7 +597,7 @@ function artifactRegistryHelp(): unknown { function agentRunHelpSummary(): unknown { return { - command: "agentrun get|describe|events|logs|result|ack|cancel|create|apply|steer|send|control-plane|git-mirror", + command: "agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|steer|send|control-plane|git-mirror", output: "human by default; use -o json|yaml or --raw", usage: [ "bun scripts/cli.ts agentrun get tasks --queue commander --limit 20", @@ -606,6 +606,7 @@ function agentRunHelpSummary(): unknown { "bun scripts/cli.ts agentrun logs session/ --tail 100", "bun scripts/cli.ts agentrun result run/ --command ", "bun scripts/cli.ts agentrun ack task/", + "bun scripts/cli.ts agentrun dispatch task/", "bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin", "bun scripts/cli.ts agentrun control-plane status", ],