From 17ab91132a71fe262f8cbafb8f7b11c3d8dbb93c Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 15 Jul 2026 16:23:22 +0200 Subject: [PATCH] =?UTF-8?q?Revert=20"feat:=20=E4=B8=BA=20Artificer=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=AD=E6=96=87=E4=BB=BB=E5=8A=A1=E6=A0=87?= =?UTF-8?q?=E9=A2=98"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 9f1df6a1f20c0a0ff7965fb1a16f794e4d24c80c. --- .agents/skills/unidesk-code-queue/SKILL.md | 14 +--- .../references/resources.md | 5 -- .agents/skills/unidesk-subagent/SKILL.md | 2 - docs/reference/agentrun.md | 9 -- .../src/agentrun-session-send-render.test.ts | 1 - scripts/src/agentrun.test.ts | 14 +--- scripts/src/agentrun/entry.ts | 16 ++-- scripts/src/agentrun/render.ts | 1 - scripts/src/agentrun/resource-actions.ts | 82 ++----------------- scripts/src/agentrun/rest-bridge.ts | 9 -- scripts/src/agentrun/target-task-output.ts | 17 +--- scripts/src/agentrun/target-task.ts | 44 +--------- scripts/src/agentrun/utils.ts | 1 - 13 files changed, 27 insertions(+), 188 deletions(-) diff --git a/.agents/skills/unidesk-code-queue/SKILL.md b/.agents/skills/unidesk-code-queue/SKILL.md index 584a4a23..fdfd19aa 100644 --- a/.agents/skills/unidesk-code-queue/SKILL.md +++ b/.agents/skills/unidesk-code-queue/SKILL.md @@ -11,19 +11,18 @@ description: UniDesk AgentRun-backed Code Queue CLI — Skill(cli-spec)。legacy ```bash bun scripts/cli.ts agentrun get tasks --limit 20 -bun scripts/cli.ts agentrun describe "修复 HWLAB 的 cicd" +bun scripts/cli.ts agentrun describe task/ bun scripts/cli.ts agentrun describe task/ --input -o json bun scripts/cli.ts agentrun describe aipodspec/ -bun scripts/cli.ts agentrun events "修复 HWLAB 的 cicd" --after-seq 0 --expect 10 --timeout 120s --limit 20 +bun scripts/cli.ts agentrun events run/ --after-seq 0 --expect 10 --timeout 120s --limit 20 bun scripts/cli.ts agentrun events run/ --detail-seq -o json -bun scripts/cli.ts agentrun logs "修复 HWLAB 的 cicd" --tail 120 -bun scripts/cli.ts agentrun result "修复 HWLAB 的 cicd" +bun scripts/cli.ts agentrun logs session/ --tail 120 +bun scripts/cli.ts agentrun result run/ --command bun scripts/cli.ts agentrun get attempts --task bun scripts/cli.ts agentrun retry task/ --idempotency-key --reason --dry-run bun scripts/cli.ts agentrun send --prompt-stdin bun scripts/cli.ts agentrun create task \ --aipod Artificer \ - --title "修复 HWLAB 的 cicd" \ --target \ --target-workspace \ --repo \ @@ -44,11 +43,6 @@ AipodSpec/Artificer、task manifest 和 queue 渐进披露见 [references/resour ## P0 边界 -- Artificer `create task` 必须显式提供唯一中文短标题: - - 标题为单行 2 到 80 字符,并至少包含一个中文汉字; - - `HWLAB`、`CI/CD` 等专有名和空格可以保留; - - `describe/events/logs/result` 优先使用标题的完全匹配查询; - - 标题重复时 CLI 必须报歧义,不得猜测;内部 ID 仅用于深度下钻和机器身份。 - AgentRun 与调用方之间的契约版本、源码/镜像版本和 `commitId` 对齐只能产生非阻塞 warning;可安全归一化的请求继续 admission/dispatch,不得因版本或契约漂移阻止用户任务、session、run、command 或 runner。 - 新写入口不要用 `codex submit/steer/resume`;这些 legacy mutation 已冻结。 - Artificer 的 runner primary workspace 与任务 Target 必须分开判定: diff --git a/.agents/skills/unidesk-code-queue/references/resources.md b/.agents/skills/unidesk-code-queue/references/resources.md index de4edf67..3b6c0f99 100644 --- a/.agents/skills/unidesk-code-queue/references/resources.md +++ b/.agents/skills/unidesk-code-queue/references/resources.md @@ -18,7 +18,6 @@ ```bash bun scripts/cli.ts agentrun create task \ --aipod Artificer \ - --title "修复 HWLAB 的 cicd" \ --target \ --target-workspace \ --repo \ @@ -27,10 +26,6 @@ bun scripts/cli.ts agentrun create task \ --prompt-stdin ``` -- `--title` 为必填中文短标题,允许英文专有名和空格; -- 后续 `describe/events/logs/result` 直接传入标题字符串; -- 标题按规范化后的完全匹配解析,重复标题必须改用内部 ID 处理歧义。 - - 默认直接执行 live 单命令;不要把 `--dry-run` 作为派单前置步骤; - live 必须先经 owning YAML 选中的 Target `trans` 重入并完成只读 preflight; - preflight 必须验证: diff --git a/.agents/skills/unidesk-subagent/SKILL.md b/.agents/skills/unidesk-subagent/SKILL.md index 6f7e822b..3a3e9644 100644 --- a/.agents/skills/unidesk-subagent/SKILL.md +++ b/.agents/skills/unidesk-subagent/SKILL.md @@ -38,8 +38,6 @@ description: UniDesk 主代理调度子代理的必读技能。用户提到子 - 审查证据只保留 issue/PR/commit、验证摘要和必要下钻链接,不复制无界日志或构造额外实证体系; - 只有直接保护真实业务资源、不可逆操作或明确损害风险时才允许最小 guard,且只覆盖实际风险窗口并在风险解除后立即释放; - Artificer 的 `create task` 外层入口: - - 必须使用与子 issue / MDTODO 语义一致的唯一中文短标题; - - 标题至少包含一个中文汉字,专有名和空格可以保留; - 必须按 owning YAML 选中 Target; - 必须通过 `trans :` 重入目标节点; - 预检、创建、自动派发和观察都在重入后完成; diff --git a/docs/reference/agentrun.md b/docs/reference/agentrun.md index a72192b7..746fe5af 100644 --- a/docs/reference/agentrun.md +++ b/docs/reference/agentrun.md @@ -254,7 +254,6 @@ UniDesk 指挥官新任务入口固定使用 `bun scripts/cli.ts agentrun get|de ```bash bun scripts/cli.ts agentrun create task \ --aipod Artificer \ - --title "修复 HWLAB 的 cicd" \ --target \ --target-workspace \ --repo \ @@ -263,14 +262,6 @@ bun scripts/cli.ts agentrun create task \ --prompt-stdin ``` -Artificer 标题契约: - -- `create task` 必须显式提供单行中文短标题; -- 标题长度为 2 到 80 字符,至少包含一个中文汉字; -- `HWLAB`、`CI/CD` 等专有名和空格可以保留; -- `describe/events/logs/result` 使用标题完全匹配并解析最新执行资源; -- 标题重复时返回歧义错误,内部 ID 继续作为不可变机器身份。 - - 默认直接执行 live 单命令,不把 `--dry-run` 作为派单前置步骤; - live 先经 Target `trans` 重入并执行 source/worktree/Aipod/SecretRef 只读预检; - 预检通过后在同一命令内 submit 并自动 dispatch; diff --git a/scripts/src/agentrun-session-send-render.test.ts b/scripts/src/agentrun-session-send-render.test.ts index d7e3b712..bba2e39f 100644 --- a/scripts/src/agentrun-session-send-render.test.ts +++ b/scripts/src/agentrun-session-send-render.test.ts @@ -259,7 +259,6 @@ function options(output: AgentRunOutputMode): AgentRunResourceOptions { dryRun: false, file: null, aipod: null, - title: null, idempotencyKey: null, promptStdin: false, node: null, diff --git a/scripts/src/agentrun.test.ts b/scripts/src/agentrun.test.ts index caa6859c..0ac6752f 100644 --- a/scripts/src/agentrun.test.ts +++ b/scripts/src/agentrun.test.ts @@ -221,7 +221,6 @@ describe("AgentRun render-only REST client config", () => { describe("Artificer Target one-command dispatch", () => { test("requires trans re-entry before Target filesystem preflight and derives a stable idempotency key", () => { const request = targetTaskRequestFromArgs([ - "--title", "修复 SelfMedia 的 OCR 规划器", "--target", "NC01", "--target-workspace", "/root/.worktrees/selfmedia/r6-ocr-visual-planner", "--repo", "pikainc/selfmedia", @@ -270,7 +269,6 @@ describe("Artificer Target one-command dispatch", () => { test("scopes post-task create replay to one complete logical operation", () => { const base = { - title: "修复 UniDesk 的 Artificer 派单", target: "NC01", targetRoute: "NC01:/root/unidesk/.worktree/base", projectId: "pikasTech/unidesk", @@ -1644,7 +1642,6 @@ describe("AgentRun YAML tool credential binding", () => { test("preserves explicit credential subsets across Aipod admission and rejects unknown identities or conflicts", async () => { const renderBodies: Record[] = []; const submittedBodies: Record[] = []; - const taskTitle = "验证 Artificer 工具凭据"; let credentialMode: "all" | "subset" | "conflict" | "unknown" = "all"; const renderedToolCredentials = (): Record[] => { const credentials = [ @@ -1682,9 +1679,6 @@ describe("AgentRun YAML tool credential binding", () => { return credentials; }; const renderedTask = () => ({ - title: taskTitle, - metadata: { title: taskTitle }, - sessionRef: { metadata: { title: taskTitle } }, tenantId: "unidesk", projectId: "pikasTech/unidesk", queue: "commander", @@ -1732,7 +1726,7 @@ describe("AgentRun YAML tool credential binding", () => { process.env.AGENTRUN_CLIENT_CONFIG = tempConfigPath; await Bun.write(tempConfigPath, agentRunMinimalClientYaml.replace("http://agentrun.example.local:8080", server.url.href.replace(/\/$/u, ""))); - const accepted = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--title", taskTitle, "--prompt", "fixture", "--model", "gpt-explicit", "--reasoning-effort", "high", "-o", "json"]); + const accepted = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--prompt", "fixture", "--model", "gpt-explicit", "--reasoning-effort", "high", "-o", "json"]); expect(accepted.ok).toBe(true); expect(renderBodies).toHaveLength(1); expect(submittedBodies).toHaveLength(1); @@ -1743,20 +1737,20 @@ describe("AgentRun YAML tool credential binding", () => { expect(submittedBodies[0]).toEqual(renderedTask()); credentialMode = "subset"; - const subsetAccepted = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--title", taskTitle, "--prompt", "fixture", "-o", "json"]); + const subsetAccepted = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--prompt", "fixture", "-o", "json"]); expect(subsetAccepted.ok).toBe(true); expect(renderBodies).toHaveLength(2); expect(submittedBodies).toHaveLength(2); expect(submittedBodies[1]).toEqual(renderedTask()); credentialMode = "conflict"; - const rejected = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--title", taskTitle, "--prompt", "fixture", "-o", "json"]); + const rejected = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--prompt", "fixture", "-o", "json"]); expect(rejected.ok).toBe(false); expect(submittedBodies).toHaveLength(2); expect(renderedTextOf(rejected)).toContain("github/github-ssh keys conflict"); credentialMode = "unknown"; - const unknownRejected = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--title", taskTitle, "--prompt", "fixture", "-o", "json"]); + const unknownRejected = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--prompt", "fixture", "-o", "json"]); expect(unknownRejected.ok).toBe(false); expect(submittedBodies).toHaveLength(2); expect(renderedTextOf(unknownRejected)).toContain("artifact-store/publish is not declared by YAML lane"); diff --git a/scripts/src/agentrun/entry.ts b/scripts/src/agentrun/entry.ts index 758488b5..71f2f599 100644 --- a/scripts/src/agentrun/entry.ts +++ b/scripts/src/agentrun/entry.ts @@ -57,19 +57,19 @@ export function agentRunHelp(): unknown { "bun scripts/cli.ts agentrun describe run/ --node NC01 --lane nc01-v02", "bun scripts/cli.ts agentrun get tasks -o wide", "bun scripts/cli.ts agentrun get tasks -o json", - "bun scripts/cli.ts agentrun describe \"修复 HWLAB 的 cicd\"", + "bun scripts/cli.ts agentrun describe task/", "bun scripts/cli.ts agentrun describe task/ --input -o json", - "bun scripts/cli.ts agentrun events \"修复 HWLAB 的 cicd\" --after-seq 0 --expect 10 --timeout 120s --limit 100", + "bun scripts/cli.ts agentrun events run/ --after-seq 0 --expect 10 --timeout 120s --limit 100", "bun scripts/cli.ts agentrun events run/ --detail-seq ", - "bun scripts/cli.ts agentrun logs \"修复 HWLAB 的 cicd\" --tail 100", - "bun scripts/cli.ts agentrun result \"修复 HWLAB 的 cicd\"", + "bun scripts/cli.ts agentrun logs session/ --tail 100", + "bun scripts/cli.ts agentrun result run/ --command ", "bun scripts/cli.ts agentrun ack task/ --reader-id cli", "bun scripts/cli.ts agentrun cancel task/ --reason --dry-run", "bun scripts/cli.ts agentrun retry task/ --idempotency-key --reason --dry-run", "bun scripts/cli.ts agentrun get attempts --task --limit 20", "bun scripts/cli.ts agentrun dispatch task/", - "bun scripts/cli.ts agentrun create task --aipod Artificer --title \"修复 HWLAB 的 cicd\" --prompt-stdin --idempotency-key ", - "bun scripts/cli.ts agentrun create task --aipod Artificer --title \"修复 HWLAB 的 cicd\" --target --target-workspace --repo --ref --mdtodo-id --prompt-stdin [--dry-run]", + "bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin --idempotency-key ", + "bun scripts/cli.ts agentrun create task --aipod Artificer --target --target-workspace --repo --ref --mdtodo-id --prompt-stdin [--dry-run]", "bun scripts/cli.ts agentrun apply -f - --dry-run", "bun scripts/cli.ts agentrun send session/ --aipod Artificer --prompt-stdin", "bun scripts/cli.ts agentrun explain task", @@ -318,7 +318,7 @@ export function agentRunHelpText(args: string[]): string { return "Usage: bun scripts/cli.ts agentrun dispatch task/"; } if (verb === "create") { - return "Usage: bun scripts/cli.ts agentrun create task --aipod Artificer --title <中文短标题> --target --target-workspace --repo --ref --mdtodo-id --prompt-stdin [--idempotency-key ] [--dry-run]"; + return "Usage: bun scripts/cli.ts agentrun create task --aipod Artificer --target --target-workspace --repo --ref --mdtodo-id --prompt-stdin [--idempotency-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: ."; @@ -413,7 +413,7 @@ export function agentRunHelpText(args: string[]): string { " bun scripts/cli.ts agentrun logs session/ --tail 100", " bun scripts/cli.ts agentrun retry task/ --idempotency-key --reason --dry-run", " bun scripts/cli.ts agentrun get attempts --task --limit 20", - " bun scripts/cli.ts agentrun create task --aipod Artificer --title \"修复 HWLAB 的 cicd\" --target --target-workspace --repo --ref --mdtodo-id --prompt-stdin", + " bun scripts/cli.ts agentrun create task --aipod Artificer --target --target-workspace --repo --ref --mdtodo-id --prompt-stdin", "", "Machine/debug output:", " -o json|yaml emits a stable UniDesk resource object without the global JSON envelope.", diff --git a/scripts/src/agentrun/render.ts b/scripts/src/agentrun/render.ts index 5d1816fd..98a174d9 100644 --- a/scripts/src/agentrun/render.ts +++ b/scripts/src/agentrun/render.ts @@ -528,7 +528,6 @@ export function renderTargetTaskMutationLines(targetTask: Record"); } - if (verb === "create" && parseResourceKind(action) === "task" && options.aipod === "Artificer") { - validateChineseTaskTitle(options.title); - } } function resourceErrorOutputOptions(args: string[]): AgentRunResourceOptions { @@ -191,7 +187,6 @@ export function parseResourceOptions(args: string[]): AgentRunResourceOptions { dryRun: false, file: null, aipod: null, - title: null, idempotencyKey: null, promptStdin: false, node: null, @@ -203,7 +198,7 @@ export function parseResourceOptions(args: string[]): AgentRunResourceOptions { mdtodoId: null, passthroughArgs: [], }; - const valueFlags = new Set(["-o", "--output", "--limit", "--cursor", "--queue", "--state", "--reader-id", "--task", "--task-id", "--run", "--run-id", "--command", "--command-id", "--session", "--session-id", "--after-seq", "--expect", "--timeout", "--detail-seq", "--tail", "--reason", "-f", "--file", "--filename", "--aipod", "--title", "--idempotency-key", "--node", "--lane", "--target", "--target-workspace", "--repo", "--ref", "--mdtodo-id"]); + const valueFlags = new Set(["-o", "--output", "--limit", "--cursor", "--queue", "--state", "--reader-id", "--task", "--task-id", "--run", "--run-id", "--command", "--command-id", "--session", "--session-id", "--after-seq", "--expect", "--timeout", "--detail-seq", "--tail", "--reason", "-f", "--file", "--filename", "--aipod", "--idempotency-key", "--node", "--lane", "--target", "--target-workspace", "--repo", "--ref", "--mdtodo-id"]); const booleanFlags = new Set(["--full", "--raw", "--debug", "--input", "--unread", "--dry-run", "--full-text", "--prompt-stdin", "--stdin"]); for (let index = 0; index < args.length; index += 1) { const arg = args[index] ?? ""; @@ -346,7 +341,6 @@ export function applyResourceOption(options: AgentRunResourceOptions, flag: stri else if (flag === "--reason") options.reason = requiredValue(value, flag); else if (flag === "-f" || flag === "--file" || flag === "--filename") options.file = requiredValue(value, flag); else if (flag === "--aipod") options.aipod = requiredValue(value, flag); - else if (flag === "--title") options.title = requiredValue(value, flag); else if (flag === "--idempotency-key") options.idempotencyKey = requiredValue(value, flag); else if (flag === "--node") options.node = requiredValue(value, flag); else if (flag === "--lane") options.lane = requiredValue(value, flag); @@ -464,8 +458,7 @@ export async function resourceRetry(config: UniDeskConfig | null, command: strin } export async function resourceDescribe(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise { - const titleContext = await resolveTaskTitleContext(config, action); - const ref = titleContext === null ? parseResourceRef(action, args) : { kind: "task", name: titleContext.taskId } as const; + const ref = parseResourceRef(action, args); if (options.taskInput && ref.kind !== "task") throw new AgentRunRestError("validation-failed", "describe --input supports task/ only"); if (ref.kind === "task") { const result = await runAgentRunRestCommand(config, "queue", ["show", ref.name, ...(options.full ? ["--full"] : [])]); @@ -626,11 +619,8 @@ function runnerJobObservationIdentity(managerResource: Record, } export async function resourceEvents(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise { - const titleContext = await resolveTaskTitleContext(config, action); - const ref = titleContext === null ? parseResourceRef(action, args, "run") : null; - const runId = titleContext === null - ? ref?.kind === "run" ? ref.name : options.runId ?? requiredContext("events", "--run ") - : requiredTitleResource(titleContext, "runId", "events"); + const ref = parseResourceRef(action, args, "run"); + const runId = ref.kind === "run" ? ref.name : options.runId ?? requiredContext("events", "--run "); if (options.eventDetailSeq !== null) { const detailSeq = options.eventDetailSeq; const result = await runAgentRunRestCommand(config, "runs", ["events", runId, "--after-seq", String(detailSeq - 1), "--limit", "1"]); @@ -709,11 +699,8 @@ export async function resourceEvents(config: UniDeskConfig | null, command: stri } export async function resourceLogs(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise { - const titleContext = await resolveTaskTitleContext(config, action); - const ref = titleContext === null - ? parseResourceRef(action, args, "session") - : { kind: "session", name: requiredTitleResource(titleContext, "sessionId", "logs") } as const; - if (ref.kind !== "session") throw new Error("logs currently requires session/ or an exact Chinese task title"); + const ref = parseResourceRef(action, args, "session"); + if (ref.kind !== "session") throw new Error("logs currently requires session/"); const effectiveLimit = options.tail ?? options.limit; const logArgs = ["output", ref.name, "--limit", String(effectiveLimit)]; if (options.afterSeq !== null) logArgs.push("--after-seq", String(options.afterSeq)); @@ -766,13 +753,6 @@ export async function resourceLogsTailResult(config: UniDeskConfig | null, sessi } export async function resourceResult(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise { - const titleContext = await resolveTaskTitleContext(config, action); - if (titleContext !== null) { - const runId = requiredTitleResource(titleContext, "runId", "result"); - const commandId = requiredTitleResource(titleContext, "commandId", "result"); - const result = await runAgentRunRestCommand(config, "runs", ["result", runId, "--command-id", commandId]); - return renderResultSummary(command, result, options, { kind: "run", name: runId }); - } const ref = parseResourceRef(action, args); if (ref.kind === "run") { const commandId = options.commandId ?? requiredContext("run result", "--command "); @@ -787,56 +767,6 @@ export async function resourceResult(config: UniDeskConfig | null, command: stri throw new Error("result supports run/ or command/"); } -interface AgentRunTaskTitleContext { - title: string; - taskId: string; - runId: string | null; - commandId: string | null; - sessionId: string | null; -} - -async function resolveTaskTitleContext(config: UniDeskConfig | null, action: string | undefined): Promise { - if (!isChineseTaskTitle(action)) return null; - const title = validateChineseTaskTitle(action); - const result = await runAgentRunRestCommand(config, "queue", ["list", "--limit", "500"]); - const tasks = arrayRecords(record(innerData(result)).items ?? innerData(result)); - const matches = tasks.filter((task) => normalizeStoredTaskTitle(task) === title); - if (matches.length === 0) { - throw new AgentRunRestError("not-found", `未找到中文标题完全匹配“${title}”的 Artificer 任务。`); - } - if (matches.length > 1) { - throw new AgentRunRestError("validation-failed", `中文标题“${title}”匹配到多个任务,不能猜测。`, { - details: { - title, - candidates: matches.map((task) => ({ id: stringOrNull(task.id), state: stringOrNull(task.state ?? task.status) })), - valuesPrinted: false, - }, - }); - } - const task = matches[0] ?? {}; - const attempt = record(task.latestAttempt); - const taskId = stringOrNull(task.id); - if (taskId === null) throw new AgentRunRestError("schema-mismatch", `中文标题“${title}”匹配的任务缺少 id。`); - return { - title, - taskId, - runId: stringOrNull(attempt.runId ?? task.runId), - commandId: stringOrNull(attempt.commandId ?? task.commandId), - sessionId: stringOrNull(attempt.sessionId ?? record(task.sessionRef).sessionId ?? task.sessionId), - }; -} - -function normalizeStoredTaskTitle(task: Record): string | null { - const title = stringOrNull(task.title ?? record(task.metadata).title ?? record(record(task.sessionRef).metadata).title); - return title === null ? null : title.trim().replace(/\s+/gu, " "); -} - -function requiredTitleResource(context: AgentRunTaskTitleContext, key: "runId" | "commandId" | "sessionId", operation: string): string { - const value = context[key]; - if (value !== null) return value; - throw new AgentRunRestError("not-found", `中文标题“${context.title}”对应任务尚无可用于 ${operation} 的 ${key}。`); -} - export async function resourceAck(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise { const ref = parseResourceRef(action, args, "task"); const result = ref.kind === "task" diff --git a/scripts/src/agentrun/rest-bridge.ts b/scripts/src/agentrun/rest-bridge.ts index 6231a02f..b946fdef 100644 --- a/scripts/src/agentrun/rest-bridge.ts +++ b/scripts/src/agentrun/rest-bridge.ts @@ -50,7 +50,6 @@ import { targetTaskDisclosure, targetTaskPrompt, targetTaskRequestFromArgs, - validateChineseTaskTitle, type AgentRunTargetTaskPreflight, } from "./target-task"; import { capture, captureJsonPayload, compactCapture, nonNegativeIntegerOrNull, progressEvent, record, shQuote, sleep, stringOrNull } from "./utils"; @@ -600,10 +599,8 @@ export async function runAgentRunAipodSpecsRest(action: string | undefined, id: export async function submitQueueTaskRest(args: string[]): Promise> { const aipod = agentRunOption(args, "aipod") ?? agentRunOption(args, "aipod-spec"); if (aipod) { - const taskTitle = aipod === "Artificer" ? validateChineseTaskTitle(agentRunOption(args, "title")) : null; const targetTask = targetTaskPreflightFromArgs(args, aipod); const renderInput = await aipodRenderInputFromArgs(args, targetTask === null ? 2 : args.length); - if (taskTitle !== null) renderInput.title = taskTitle; let targetTaskOperation: Record | null = null; let canonicalIdempotencyKey: string | null = null; if (targetTask !== null) { @@ -628,12 +625,6 @@ export async function submitQueueTaskRest(args: string[]): Promise): Record { const workspace = asRecord(targetTask.workspace); return { - title: boundedText(targetTask.title, 80), mdtodoId: boundedText(targetTask.mdtodoId, 80), target: boundedText(targetTask.target, 120), targetWorkspace: boundedText(targetTask.targetWorkspace, 360), @@ -183,8 +182,6 @@ function targetTaskIdentityNext( const commandId = asString(identity.commandId); const runnerJobId = asString(identity.runnerJobId); const sessionId = asString(identity.sessionId); - const title = asString(targetTask.title); - const selector = title === null ? null : shellQuote(title); const target = asString(targetTask.target) ?? asString(aipodBinding.node); const lane = asString(aipodBinding.lane); const suffix = [ @@ -194,30 +191,24 @@ function targetTaskIdentityNext( const scoped = (command: string): string => suffix.length === 0 ? command : `${command} ${suffix}`; return { ...(taskId === null ? {} : { - task: scoped(`bun scripts/cli.ts agentrun describe ${selector ?? `task/${taskId}`}`), + task: scoped(`bun scripts/cli.ts agentrun describe task/${taskId}`), attempts: scoped(`bun scripts/cli.ts agentrun get attempts --task ${taskId}`), }), ...(runId === null ? {} : { - events: scoped(`bun scripts/cli.ts agentrun events ${selector ?? `run/${runId}`} --after-seq 0 --limit 20`), + events: scoped(`bun scripts/cli.ts agentrun events run/${runId} --after-seq 0 --limit 20`), }), ...(runId === null || commandId === null ? {} : { - result: scoped(selector === null - ? `bun scripts/cli.ts agentrun result run/${runId} --command ${commandId}` - : `bun scripts/cli.ts agentrun result ${selector}`), + result: scoped(`bun scripts/cli.ts agentrun result run/${runId} --command ${commandId}`), }), ...(runnerJobId === null || runId === null ? {} : { runner: scoped(`bun scripts/cli.ts agentrun describe runnerjob/${runnerJobId} --run ${runId}`), }), ...(sessionId === null ? {} : { - logs: scoped(`bun scripts/cli.ts agentrun logs ${selector ?? `session/${sessionId}`} --tail 120`), + logs: scoped(`bun scripts/cli.ts agentrun logs session/${sessionId} --tail 120`), }), }; } -function shellQuote(value: string): string { - return `'${value.replace(/'/gu, `'"'"'`)}'`; -} - function innerData(value: Record): unknown { return value.data ?? value; } diff --git a/scripts/src/agentrun/target-task.ts b/scripts/src/agentrun/target-task.ts index 5d0d345e..64c2e1d1 100644 --- a/scripts/src/agentrun/target-task.ts +++ b/scripts/src/agentrun/target-task.ts @@ -3,7 +3,6 @@ import { realpathSync, statSync } from "node:fs"; import { spawnSync } from "node:child_process"; export interface AgentRunTargetTaskRequest { - readonly title: string; readonly target: string; readonly targetWorkspace: string; readonly repository: string; @@ -44,7 +43,6 @@ export interface AgentRunTargetTaskOperationEvidence { readonly tenantId: string; readonly projectId: string; readonly aipod: string; - readonly title: string; readonly mdtodoId: string; readonly target: string; readonly repository: string; @@ -70,7 +68,6 @@ export class AgentRunTargetTaskPreflightError extends Error { export function targetTaskRequestFromArgs(args: string[]): AgentRunTargetTaskRequest | null { const raw = { - title: option(args, "title"), target: option(args, "target"), targetWorkspace: option(args, "target-workspace"), repository: option(args, "repo"), @@ -83,12 +80,11 @@ export function targetTaskRequestFromArgs(args: string[]): AgentRunTargetTaskReq if (missing.length > 0) { throw new AgentRunTargetTaskPreflightError( "target-context", - `Artificer Target 派单缺少 ${missing.join(", ")};请同时提供 --title、--target、--target-workspace、--repo、--ref 和 --mdtodo-id。`, + `Artificer Target 派单缺少 ${missing.join(", ")};请同时提供 --target、--target-workspace、--repo、--ref 和 --mdtodo-id。`, { missing }, ); } return { - title: validateChineseTaskTitle(raw.title), target: validateTarget(raw.target as string), targetWorkspace: validateTargetWorkspace(raw.targetWorkspace as string), repository: normalizeRepository(raw.repository as string), @@ -213,7 +209,6 @@ export function preflightTargetTask(request: AgentRunTargetTaskRequest, markerEn export function targetTaskPrompt(preflight: AgentRunTargetTaskPreflight, userPrompt: string | null): string { const context = [ "任务目标上下文(由 UniDesk YAML-first CLI 在创建 task 前经 Target trans 只读核验):", - `- 中文任务标题: ${preflight.title}`, `- MDTODO ID: ${preflight.mdtodoId}`, `- Target: ${preflight.target}`, `- targetWorkspace: ${preflight.targetWorkspace}`, @@ -234,7 +229,6 @@ export function targetTaskPrompt(preflight: AgentRunTargetTaskPreflight, userPro export function targetTaskDisclosure(preflight: AgentRunTargetTaskPreflight): Record { return { - title: preflight.title, mdtodoId: preflight.mdtodoId, target: preflight.target, targetWorkspace: preflight.targetWorkspace, @@ -266,7 +260,6 @@ export function targetTaskOperationEvidence( tenantId: operation.tenantId, projectId: operation.projectId, aipod: operation.aipod, - title: preflight.title, mdtodoId: preflight.mdtodoId, target: preflight.target, repository: preflight.repository, @@ -318,41 +311,6 @@ export function targetTaskIdempotencyKey( return resolveTargetTaskIdempotency(preflight, operation, null).idempotencyKey; } -export function validateChineseTaskTitle(raw: string | null): string { - if (raw === null || raw.trim().length === 0) { - throw new AgentRunTargetTaskPreflightError( - "task-title", - "Artificer 创建任务必须提供 --title <中文短标题>,例如 --title \"修复 HWLAB 的 cicd\"。", - { reason: "missing-chinese-task-title" }, - ); - } - if (/\r|\n|[\u0000-\u001f\u007f]/u.test(raw)) { - throw new AgentRunTargetTaskPreflightError("task-title", "Artificer 任务标题必须是单行短字符串。", { - reason: "invalid-task-title-control-character", - }); - } - const title = raw.trim().replace(/\s+/gu, " "); - const length = Array.from(title).length; - if (length < 2 || length > 80) { - throw new AgentRunTargetTaskPreflightError("task-title", "Artificer 任务标题长度必须为 2 到 80 个字符。", { - reason: "invalid-task-title-length", - length, - }); - } - if (!isChineseTaskTitle(title)) { - throw new AgentRunTargetTaskPreflightError( - "task-title", - "Artificer 任务标题必须至少包含一个中文汉字;HWLAB、CI/CD 等专有名和空格可以保留。", - { reason: "missing-han-character" }, - ); - } - return title; -} - -export function isChineseTaskTitle(value: string | undefined): value is string { - return typeof value === "string" && /\p{Script=Han}/u.test(value); -} - function git(request: AgentRunTargetTaskRequest, args: string[], stage: string): string { const result = spawnSync("git", args, { cwd: request.targetWorkspace, diff --git a/scripts/src/agentrun/utils.ts b/scripts/src/agentrun/utils.ts index 815d7ccf..83d5a770 100644 --- a/scripts/src/agentrun/utils.ts +++ b/scripts/src/agentrun/utils.ts @@ -85,7 +85,6 @@ export interface AgentRunResourceOptions { dryRun: boolean; file: string | null; aipod: string | null; - title: string | null; idempotencyKey: string | null; promptStdin: boolean; node: string | null;