fix: expose agentrun dispatch resource

This commit is contained in:
Codex
2026-06-11 03:59:00 +00:00
parent 0042b7dc85
commit b151fbbee8
8 changed files with 80 additions and 40 deletions
+11 -1
View File
@@ -45,6 +45,7 @@ assertCondition(
agentRunUsage.some((line) => line.includes("agentrun result run/<runId> --command <commandId>"))
&& agentRunUsage.some((line) => line.includes("agentrun ack task/<taskId> --reader-id cli"))
&& agentRunUsage.some((line) => line.includes("agentrun cancel task/<taskId> --reason <text> --dry-run"))
&& agentRunUsage.some((line) => line.includes("agentrun dispatch task/<taskId>"))
&& 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/<sessionId> --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",
],
+32 -9
View File
@@ -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/<runId> --command <commandId>",
"bun scripts/cli.ts agentrun ack task/<taskId> --reader-id cli",
"bun scripts/cli.ts agentrun cancel task/<taskId> --reason <text> --dry-run",
"bun scripts/cli.ts agentrun dispatch task/<taskId>",
"bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin --idempotency-key <key>",
"bun scripts/cli.ts agentrun apply -f - --dry-run",
"bun scripts/cli.ts agentrun steer session/<sessionId> --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/<taskId>|session/<sessionId> --reason <text> [--dry-run]";
}
if (verb === "dispatch") {
return "Usage: bun scripts/cli.ts agentrun dispatch task/<taskId>";
}
if (verb === "create") {
return "Usage: bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin [--idempotency-key <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: <AgentRun queue submit payload>.";
return "Usage: bun scripts/cli.ts agentrun apply -f task.yaml|json|- [--dry-run]\nTask manifests use kind: Task and spec: <AgentRun task payload>.";
}
if (verb === "steer") {
return "Usage: bun scripts/cli.ts agentrun steer session/<sessionId> --prompt-stdin";
@@ -235,7 +240,7 @@ function agentRunHelpText(args: string[]): string {
return [
"Usage: bun scripts/cli.ts agentrun <verb> <resource> [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 <taskId> [--limit 20] [-o wide|name|json|yaml]";
if (kind === "command") return "Usage: bun scripts/cli.ts agentrun get commands --run <runId> [--command <commandId>] [-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<string, unknown>;
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<RenderedCliResult> {
const ref = parseResourceRef(action, args, "task");
if (ref.kind !== "task") throw new Error("dispatch supports task/<taskId>");
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<RenderedCliResult> {
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<string, unknown>[] {
const items = arrayRecords(record(data).items ?? data);
return items.map((item) => ({
@@ -897,7 +920,7 @@ function parseTaskManifest(raw: string, source: string): Record<string, unknown>
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",
+13 -9
View File
@@ -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 <taskId> --json-stdin <<'JSON'",
sessionsTrace: "bun scripts/cli.ts agentrun sessions trace <sessionId> --after-seq 0 --limit 100",
sessionsOutput: "bun scripts/cli.ts agentrun sessions output <sessionId> --after-seq 0 --limit 100",
sessionsSteer: "bun scripts/cli.ts agentrun sessions steer <sessionId> --prompt-stdin <<'EOF'",
sessionsRead: "bun scripts/cli.ts agentrun sessions read <sessionId> --reader-id cli",
queueCancel: "bun scripts/cli.ts agentrun queue cancel <taskId> --reason <text>",
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/<taskId>",
taskDescribe: "bun scripts/cli.ts agentrun describe task/<taskId>",
runEvents: "bun scripts/cli.ts agentrun events run/<runId> --after-seq 0 --limit 100",
runResult: "bun scripts/cli.ts agentrun result run/<runId> --command <commandId>",
sessionLogs: "bun scripts/cli.ts agentrun logs session/<sessionId> --tail 100",
sessionSteer: "bun scripts/cli.ts agentrun steer session/<sessionId> --prompt-stdin",
sessionSend: "bun scripts/cli.ts agentrun send session/<sessionId> --aipod Artificer --prompt-stdin",
taskAck: "bun scripts/cli.ts agentrun ack task/<taskId>",
taskCancel: "bun scripts/cli.ts agentrun cancel task/<taskId> --reason <text>",
};
const codexTaskStatusAliases: Record<string, string> = {
completed: "succeeded",
@@ -103,7 +107,7 @@ function legacyCodeQueueFrozenMutation(command: string): Record<string, unknown>
frozen: true,
mutation: false,
degradedReason: "legacy-code-queue-frozen",
error: "旧 UniDesk Code Queue 新任务和执行写入口已冻结;新任务使用 AgentRun Queue。",
error: "旧 UniDesk Code Queue 新任务和执行写入口已冻结;新任务使用 AgentRun 资源原语。",
command,
replacement: agentRunQueueReplacementCommands,
legacy: {
+5 -4
View File
@@ -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/<sessionId> --tail 100",
"bun scripts/cli.ts agentrun result run/<runId> --command <commandId>",
"bun scripts/cli.ts agentrun ack task/<taskId>",
"bun scripts/cli.ts agentrun dispatch task/<taskId>",
"bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin",
"bun scripts/cli.ts agentrun control-plane status",
],