fix: support AgentRun command cancellation
This commit is contained in:
@@ -56,6 +56,7 @@ bun scripts/cli.ts agentrun ack session/<sessionId>
|
||||
bun scripts/cli.ts agentrun dispatch task/<taskId>
|
||||
bun scripts/cli.ts agentrun send session/<sessionId> --aipod Artificer --prompt-stdin
|
||||
bun scripts/cli.ts agentrun cancel session/<sessionId> --reason <text> --dry-run
|
||||
bun scripts/cli.ts agentrun cancel command/<commandId> --run <runId> --reason <text> --dry-run
|
||||
```
|
||||
|
||||
日常 task manifest 优先使用 YAML heredoc:`agentrun apply -f -`;单 prompt 派单优先 `agentrun create task --aipod Artificer --prompt-stdin`;同 session 续跑只使用 `agentrun send session/<sessionId>`。UniDesk 客户端按 `config/agentrun.yaml` 直连 AgentRun REST API,不经过 HWLAB runtime、SSH official CLI 或旧 bridge wrapper;`send` 是唯一用户级 session follow-up 写入口,服务端按 durable session/run/command 状态自动决定内部 `steer` 或新 `turn`,旧 CLI `turn/steer` 路径不保留兼容。`--json-file`、`--prompt-file` 和 `--runner-json-file` 只是客户端输入来源,用于已审阅且可复用的受控文件。它不是旧 Code Queue adapter,不双写,也不迁移旧历史。
|
||||
@@ -71,9 +72,9 @@ AgentRun queue 生命周期不是一个单独的 `queue lifecycle` 命令,而
|
||||
1. 默认总览用 `get tasks --queue commander --limit 20`,只看 task state、queue/lane、run/cmd/rjob/session ref、age 和 attention。
|
||||
2. 单任务用 `describe task/<taskId>`,读取 `latestAttempt.runId`、`commandId`、`runnerJobId`、`sessionId/sessionPath` 和少量 `Next:`。
|
||||
3. Run 级状态用 `events run/<runId>` 和 `result run/<runId> --command <commandId>`,判断 terminalClassification、failureKind、provider interruption、timeoutBudget 和 recoveryActions。
|
||||
4. Command 级状态用 `describe command/<commandId> --run <runId>` 和 `result command/<commandId> --run <runId>`,确认 command state、ack、terminal status 和结果摘要。
|
||||
4. Command 级状态用 `describe command/<commandId> --run <runId>` 和 `result command/<commandId> --run <runId>`,确认 command state、ack、terminal status 和结果摘要;确认为单个 active command 卡住时,用 `cancel command/<commandId> --run <runId> --reason <text>` 清理该 command,保留同一个 session 后再用 `send session/<sessionId>` 续跑。
|
||||
5. Runner job 只读状态用 `describe runnerjob/<runnerJobId> --run <runId>`,确认 env image reuse、jobName、namespace、phase、exitCode、retention 和 `valuesPrinted=false`。不要为了这些字段手动调用 `trans G14:k3s kubectl ...`。
|
||||
6. Session trace/output 只在 `describe task` 或 result 里有实际 `sessionId` 时使用 `logs|ack|send|cancel session/<sessionId>`;`sessionRef=null` 时不要猜 session 命令。
|
||||
6. Session trace/output 只在 `describe task` 或 result 里有实际 `sessionId` 时使用 `logs|ack|send|cancel session/<sessionId>`;`sessionRef=null` 时不要猜 session 命令。用户级 follow-up 一律使用 `send session/<sessionId>`,不要回到旧 `turn/steer` 或 `sessions ...` 兼容路径。
|
||||
7. 已创建但尚未运行的 task 使用 `dispatch task/<taskId>` 派发,不再退回旧 bridge `queue dispatch`。
|
||||
|
||||
默认视图必须低噪声且不是 JSON envelope,`-o json|yaml` 才输出稳定机器结构,`--raw` 才保留直连 AgentRun REST envelope;命令返回里的下一步应优先是 `bun scripts/cli.ts agentrun ...` 资源原语,不得把人工 k8s 查询作为日常下一步。
|
||||
@@ -188,7 +189,7 @@ bun scripts/cli.ts codex interrupt <taskId>
|
||||
bun scripts/cli.ts codex cancel <taskId>
|
||||
```
|
||||
|
||||
仅用于停止旧 Code Queue 残留任务;新 AgentRun session 使用 `bun scripts/cli.ts agentrun cancel session/<sessionId>`。
|
||||
仅用于停止旧 Code Queue 残留任务;新 AgentRun session 使用 `bun scripts/cli.ts agentrun cancel session/<sessionId>`,单个卡住 command 使用 `bun scripts/cli.ts agentrun cancel command/<commandId> --run <runId>`。
|
||||
|
||||
---
|
||||
|
||||
|
||||
+31
-6
@@ -198,7 +198,7 @@ function agentRunHelpText(args: string[]): string {
|
||||
return "Usage: bun scripts/cli.ts agentrun ack task/<taskId>|session/<sessionId> [--reader-id cli]";
|
||||
}
|
||||
if (verb === "cancel") {
|
||||
return "Usage: bun scripts/cli.ts agentrun cancel task/<taskId>|session/<sessionId> --reason <text> [--dry-run]";
|
||||
return "Usage: bun scripts/cli.ts agentrun cancel task/<taskId>|session/<sessionId>|run/<runId>|command/<commandId> --reason <text> [--run <runId>] [--dry-run]";
|
||||
}
|
||||
if (verb === "dispatch") {
|
||||
return "Usage: bun scripts/cli.ts agentrun dispatch task/<taskId>";
|
||||
@@ -576,16 +576,41 @@ async function resourceAck(config: UniDeskConfig | null, command: string, action
|
||||
|
||||
async function resourceCancel(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
|
||||
const ref = parseResourceRef(action, args, "task");
|
||||
const cancelArgs = ref.kind === "task" ? ["cancel", ref.name] : ref.kind === "session" ? ["cancel", ref.name] : null;
|
||||
if (cancelArgs === null) throw new Error("cancel supports task/<taskId> or session/<sessionId>");
|
||||
if (options.reason !== null && ref.kind === "task") cancelArgs.push("--reason", options.reason);
|
||||
if (options.dryRun) cancelArgs.push("--dry-run");
|
||||
const cancelArgs = ["cancel", ref.name];
|
||||
if (options.reason !== null) cancelArgs.push("--reason", options.reason);
|
||||
if (ref.kind === "command") cancelArgs.push("--run-id", options.runId ?? requiredContext("command cancel", "--run <runId>"));
|
||||
if (options.dryRun) {
|
||||
const result = agentRunResourceCancelDryRunPlan(ref, options, rerunWithoutDryRun(command));
|
||||
return renderMutationSummary(command, result, options, `Planned cancel ${ref.kind}/${shortId(ref.name)}`, [rerunWithoutDryRun(command)]);
|
||||
}
|
||||
const result = ref.kind === "task"
|
||||
? await runAgentRunRestCommand(config, "queue", cancelArgs)
|
||||
: await runAgentRunRestCommand(config, "sessions", cancelArgs);
|
||||
: ref.kind === "session"
|
||||
? await runAgentRunRestCommand(config, "sessions", cancelArgs)
|
||||
: ref.kind === "run"
|
||||
? await runAgentRunRestCommand(config, "runs", cancelArgs)
|
||||
: ref.kind === "command"
|
||||
? await runAgentRunRestCommand(config, "commands", cancelArgs)
|
||||
: null;
|
||||
if (result === null) throw new Error("cancel supports task/<taskId>, session/<sessionId>, run/<runId>, or command/<commandId>");
|
||||
return renderMutationSummary(command, result, options, `${options.dryRun ? "Planned cancel" : "Cancel requested"} ${ref.kind}/${shortId(ref.name)}`, options.dryRun ? [rerunWithoutDryRun(command)] : undefined);
|
||||
}
|
||||
|
||||
function agentRunResourceCancelDryRunPlan(ref: AgentRunResourceRef, options: AgentRunResourceOptions, confirmCommand: string): Record<string, unknown> {
|
||||
const body: Record<string, unknown> = {};
|
||||
if (options.reason !== null) body.reason = options.reason;
|
||||
if (ref.kind === "task") return agentRunDryRunPlan("task-cancel", `/api/v1/queue/tasks/${encodeURIComponent(ref.name)}/cancel`, body, confirmCommand);
|
||||
if (ref.kind === "session") return agentRunDryRunPlan("session-cancel", `/api/v1/sessions/${encodeURIComponent(ref.name)}/control`, { action: "cancel", ...body }, confirmCommand);
|
||||
if (ref.kind === "run") return agentRunDryRunPlan("run-cancel", `/api/v1/runs/${encodeURIComponent(ref.name)}/cancel`, body, confirmCommand);
|
||||
if (ref.kind === "command") {
|
||||
const runId = options.runId ?? requiredContext("command cancel", "--run <runId>");
|
||||
return agentRunDryRunPlan("command-cancel", `/api/v1/commands/${encodeURIComponent(ref.name)}/cancel`, body, confirmCommand, "POST", {
|
||||
commandRef: { runId, commandId: ref.name, valuesPrinted: false },
|
||||
});
|
||||
}
|
||||
throw new Error("cancel supports task/<taskId>, session/<sessionId>, run/<runId>, or command/<commandId>");
|
||||
}
|
||||
|
||||
async function resourceDispatch(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
|
||||
const ref = parseResourceRef(action, args, "task");
|
||||
if (ref.kind !== "task") throw new Error("dispatch supports task/<taskId>");
|
||||
|
||||
Reference in New Issue
Block a user