feat: 实现 Queue Q2 受控 dispatch
This commit is contained in:
@@ -40,6 +40,8 @@ async function dispatch(args: ParsedArgs): Promise<JsonValue> {
|
||||
if (group === "queue" && command === "commander") return client(args).get(`/api/v1/queue/commander${queueQuery(args)}`);
|
||||
if (group === "queue" && command === "read" && id) return client(args).post(`/api/v1/queue/tasks/${encodeURIComponent(id)}/read`, { readerId: optionalFlag(args, "reader-id") ?? "cli" });
|
||||
if (group === "queue" && command === "cancel" && id) return client(args).post(`/api/v1/queue/tasks/${encodeURIComponent(id)}/cancel`, cancelBody(args));
|
||||
if (group === "queue" && command === "dispatch" && id) return dispatchQueueTask(args, id);
|
||||
if (group === "queue" && command === "refresh" && id) return client(args).post(`/api/v1/queue/tasks/${encodeURIComponent(id)}/refresh`, {});
|
||||
if (group === "runs" && command === "create") return client(args).post("/api/v1/runs", await jsonFile(args));
|
||||
if (group === "runs" && command === "show" && id) return client(args).get(`/api/v1/runs/${encodeURIComponent(id)}`);
|
||||
if (group === "runs" && command === "events" && id) return client(args).get(`/api/v1/runs/${encodeURIComponent(id)}/events?afterSeq=${flag(args, "after-seq", "0")}&limit=${flag(args, "limit", "100")}`);
|
||||
@@ -132,6 +134,23 @@ function queueQuery(args: ParsedArgs): string {
|
||||
return queue ? `?queue=${encodeURIComponent(queue)}` : "";
|
||||
}
|
||||
|
||||
async function dispatchQueueTask(args: ParsedArgs, taskId: string): Promise<JsonValue> {
|
||||
const body = await optionalJsonFile(args);
|
||||
const copy = (flagName: string, key = flagName.replace(/-([a-z])/gu, (_, letter: string) => letter.toUpperCase())): void => {
|
||||
const value = optionalFlag(args, flagName);
|
||||
if (value) body[key] = value;
|
||||
};
|
||||
copy("idempotency-key", "idempotencyKey");
|
||||
copy("image");
|
||||
copy("namespace");
|
||||
copy("attempt-id", "attemptId");
|
||||
copy("runner-id", "runnerId");
|
||||
copy("source-commit", "sourceCommit");
|
||||
copy("runner-manager-url", "managerUrl");
|
||||
copy("service-account-name", "serviceAccountName");
|
||||
return client(args).post(`/api/v1/queue/tasks/${encodeURIComponent(taskId)}/dispatch`, body);
|
||||
}
|
||||
|
||||
async function showRunnerJobStatus(args: ParsedArgs): Promise<JsonValue> {
|
||||
const runId = flag(args, "run-id", "");
|
||||
if (!runId) throw new AgentRunError("schema-invalid", "runner job-status requires --run-id", { httpStatus: 2 });
|
||||
@@ -228,6 +247,12 @@ async function jsonFile(args: ParsedArgs): Promise<JsonRecord> {
|
||||
throw new AgentRunError("schema-invalid", "json file must contain an object", { httpStatus: 2 });
|
||||
}
|
||||
|
||||
async function optionalJsonFile(args: ParsedArgs): Promise<JsonRecord> {
|
||||
const file = optionalFlag(args, "json-file");
|
||||
if (!file) return {};
|
||||
return jsonFile(args);
|
||||
}
|
||||
|
||||
function parseArgs(argv: string[]): ParsedArgs {
|
||||
const positional: string[] = [];
|
||||
const flags = new Map<string, string | boolean>();
|
||||
@@ -287,6 +312,8 @@ function help(): JsonRecord {
|
||||
"queue commander [--queue <queue>]",
|
||||
"queue read <taskId> [--reader-id <reader>]",
|
||||
"queue cancel <taskId> [--reason <text>]",
|
||||
"queue dispatch <taskId> [--json-file <dispatch.json>] [--idempotency-key <key>] [--image <image>] [--namespace <namespace>]",
|
||||
"queue refresh <taskId>",
|
||||
"secrets codex render --dry-run [--profile codex|deepseek] [--codex-home <dir>] [--namespace agentrun-v01] [--secret-name <name>]",
|
||||
"backends list",
|
||||
"server start|status",
|
||||
|
||||
Reference in New Issue
Block a user