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
+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",