feat: 实现 Queue Q1 API 和 CLI 骨架
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { createHash, randomUUID } from "node:crypto";
|
||||
import type { BackendProfile, CreateCommandInput, CreateRunInput, ExecutionPolicy, JsonRecord, JsonValue, ResourceBundleRef, SecretRef, SessionRef } from "./types.js";
|
||||
import type { BackendProfile, CreateCommandInput, CreateQueueTaskInput, CreateRunInput, ExecutionPolicy, JsonRecord, JsonValue, QueueTaskState, ResourceBundleRef, SecretRef, SessionRef } from "./types.js";
|
||||
import { AgentRunError } from "./errors.js";
|
||||
import { backendProfileSpec, backendProfiles, isBackendProfile } from "./backend-profiles.js";
|
||||
|
||||
@@ -168,3 +168,41 @@ export function validateCreateCommand(input: unknown): CreateCommandInput {
|
||||
const idempotencyKey = typeof record.idempotencyKey === "string" && record.idempotencyKey.trim().length > 0 ? record.idempotencyKey.trim() : undefined;
|
||||
return { type, payload, ...(idempotencyKey ? { idempotencyKey } : {}) };
|
||||
}
|
||||
|
||||
export function validateCreateQueueTask(input: unknown): CreateQueueTaskInput {
|
||||
const record = asRecord(input, "queueTask");
|
||||
const tenantId = requiredString(record, "tenantId");
|
||||
if (!allowedTenants.has(tenantId)) throw new AgentRunError("tenant-policy-denied", `tenantId ${tenantId} is not allowed`, { httpStatus: 403 });
|
||||
const backendProfileValue = optionalString(record.backendProfile) ?? "codex";
|
||||
if (!isBackendProfile(backendProfileValue)) throw new AgentRunError("schema-invalid", `backendProfile ${backendProfileValue} is not supported in v0.1`, { httpStatus: 400, details: { allowedBackends: [...backendProfiles] } });
|
||||
const queue = optionalString(record.queue) ?? "default";
|
||||
const lane = optionalString(record.lane) ?? "default";
|
||||
const priorityValue = record.priority ?? 0;
|
||||
if (typeof priorityValue !== "number" || !Number.isFinite(priorityValue)) throw new AgentRunError("schema-invalid", "priority must be a finite number", { httpStatus: 400 });
|
||||
const referencesValue = record.references ?? [];
|
||||
if (!Array.isArray(referencesValue)) throw new AgentRunError("schema-invalid", "references must be an array", { httpStatus: 400 });
|
||||
const result: CreateQueueTaskInput = {
|
||||
tenantId,
|
||||
projectId: requiredString(record, "projectId"),
|
||||
queue,
|
||||
lane,
|
||||
title: requiredString(record, "title"),
|
||||
priority: priorityValue,
|
||||
backendProfile: backendProfileValue,
|
||||
providerId: optionalString(record.providerId) ?? null,
|
||||
workspaceRef: record.workspaceRef === undefined || record.workspaceRef === null ? null : requiredRecord(record, "workspaceRef") as CreateQueueTaskInput["workspaceRef"],
|
||||
executionPolicy: record.executionPolicy === undefined || record.executionPolicy === null ? null : validateExecutionPolicy(requiredRecord(record, "executionPolicy")),
|
||||
resourceBundleRef: validateResourceBundleRef(record.resourceBundleRef),
|
||||
payload: record.payload === undefined ? {} : asRecord(record.payload, "payload"),
|
||||
references: referencesValue.map((item, index) => asRecord(item, `references[${index}]`)),
|
||||
metadata: record.metadata === undefined ? {} : asRecord(record.metadata, "metadata"),
|
||||
};
|
||||
const idempotencyKey = optionalString(record.idempotencyKey);
|
||||
if (idempotencyKey) result.idempotencyKey = idempotencyKey;
|
||||
return result;
|
||||
}
|
||||
|
||||
export function validateQueueTaskState(value: string): QueueTaskState {
|
||||
if (value === "pending" || value === "running" || value === "completed" || value === "failed" || value === "blocked" || value === "cancelled") return value;
|
||||
throw new AgentRunError("schema-invalid", `queue task state ${value} is not supported`, { httpStatus: 400 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user