feat: close AgentRun commander task plane gaps

This commit is contained in:
Codex
2026-06-09 00:06:53 +08:00
parent 96c8283574
commit 2f5cf8b3d4
15 changed files with 411 additions and 23 deletions
+3 -1
View File
@@ -13,11 +13,13 @@ const selfTest: SelfTestCase = async () => {
(error) => error instanceof AgentRunError && error.failureKind === "infra-failed" && error.message.includes("DATABASE_URL is required"),
);
const postgresContract = postgresMigrationContract();
assert.equal(postgresContract.latestMigrationId, "009_v01_dsflash_go_model_catalog");
assert.equal(postgresContract.latestMigrationId, "010_v01_queue_session_ref");
assert.equal((postgresContract.migrationIds as string[]).includes("008_v01_dsflash_go_backend_profile"), true);
assert.equal((postgresContract.migrationIds as string[]).includes("009_v01_dsflash_go_model_catalog"), true);
assert.equal((postgresContract.migrationIds as string[]).includes("010_v01_queue_session_ref"), true);
assert.ok(typeof (postgresContract.checksums as Record<string, string>)["008_v01_dsflash_go_backend_profile"] === "string" && (postgresContract.checksums as Record<string, string>)["008_v01_dsflash_go_backend_profile"].length > 0);
assert.ok(typeof (postgresContract.checksums as Record<string, string>)["009_v01_dsflash_go_model_catalog"] === "string" && (postgresContract.checksums as Record<string, string>)["009_v01_dsflash_go_model_catalog"].length > 0);
assert.ok(typeof (postgresContract.checksums as Record<string, string>)["010_v01_queue_session_ref"] === "string" && (postgresContract.checksums as Record<string, string>)["010_v01_queue_session_ref"].length > 0);
assert.equal((postgresContract.checksums as Record<string, string>)["002_v01_backend_profiles"], "928b5c490cc4539cb64ecef34784557601b2724fa2870570f16a53576804e49c");
assert.ok(Array.isArray(postgresContract.requiredTables));
assert.ok(postgresContract.requiredTables.includes("agentrun_schema_migrations"));
+8 -2
View File
@@ -19,6 +19,7 @@ const selfTest: SelfTestCase = async (context) => {
backendProfile: "codex",
providerId: "G14",
workspaceRef: { kind: "host-path", path: context.workspace },
sessionRef: { sessionId: "sess_queue_q1_selftest", metadata: { source: "queue-q1-self-test" } },
executionPolicy: null,
resourceBundleRef: null,
payload: { prompt: "hello" },
@@ -28,10 +29,15 @@ const selfTest: SelfTestCase = async (context) => {
};
const created = await client.post("/api/v1/queue/tasks", input) as QueueTaskRecord;
assert.equal(created.state, "pending");
assert.equal(created.sessionPath, null);
assert.equal(created.sessionRef?.sessionId, "sess_queue_q1_selftest");
assert.equal(created.sessionPath, "/api/v1/sessions/sess_queue_q1_selftest");
assert.equal(created.latestAttempt, null);
const duplicate = await client.post("/api/v1/queue/tasks", input) as QueueTaskRecord;
assert.equal(duplicate.id, created.id);
await assert.rejects(
() => client.post("/api/v1/queue/tasks", { ...input, sessionRef: { sessionId: "sess_queue_q1_other" } }),
(error) => error instanceof Error && error.message.includes("idempotency key reused"),
);
const listed = await client.get("/api/v1/queue/tasks?queue=dev&limit=10") as QueueTaskListResult;
assert.equal(listed.count, 1);
@@ -39,7 +45,7 @@ const selfTest: SelfTestCase = async (context) => {
const shown = await client.get(`/api/v1/queue/tasks/${created.id}`) as QueueTaskRecord;
assert.equal(shown.title, "Q1 queue task");
assert.equal(shown.sessionPath, null);
assert.equal(shown.sessionPath, "/api/v1/sessions/sess_queue_q1_selftest");
const stats = await client.get("/api/v1/queue/stats?queue=dev") as QueueStats;
assert.equal(stats.total, 1);
+6 -1
View File
@@ -44,6 +44,7 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
backendProfile: "codex",
providerId: "G14",
workspaceRef: { kind: "host-path", path: context.workspace },
sessionRef: { sessionId: "sess_queue_q2_dispatch_selftest", metadata: { source: "queue-q2-self-test" } },
executionPolicy: {
sandbox: "workspace-write",
approval: "never",
@@ -64,9 +65,12 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
assert.equal(dispatched.latestAttempt.runId, dispatched.run.id);
assert.equal(dispatched.latestAttempt.commandId, dispatched.command.id);
assert.ok(dispatched.latestAttempt.runnerJobId);
assert.equal(dispatched.latestAttempt.sessionId, "sess_queue_q2_dispatch_selftest");
assert.equal(dispatched.latestAttempt.sessionPath, "/api/v1/sessions/sess_queue_q2_dispatch_selftest");
assert.equal(dispatched.task.state, "running");
assert.equal(dispatched.task.latestAttempt?.attemptId, "attempt_queue_q2_selftest");
assert.equal(dispatched.task.sessionPath, null);
assert.equal(dispatched.task.sessionPath, "/api/v1/sessions/sess_queue_q2_dispatch_selftest");
assert.equal(dispatched.run.sessionRef?.sessionId, "sess_queue_q2_dispatch_selftest");
const shown = await client.get(`/api/v1/queue/tasks/${created.id}`) as QueueTaskRecord;
assert.equal(shown.state, "running");
@@ -88,6 +92,7 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
assert.equal(refreshed.state, "completed");
assert.equal(refreshed.latestAttempt?.state, "completed");
assert.equal(refreshed.latestAttempt?.runId, dispatched.run.id);
assert.equal(refreshed.latestAttempt?.sessionPath, "/api/v1/sessions/sess_queue_q2_dispatch_selftest");
const manifest = JSON.parse(await readFile(createdManifest, "utf8")) as JsonRecord;
assert.ok(JSON.stringify(manifest).includes(dispatched.run.id));
assertNoSecretLeak(dispatched);
+17 -1
View File
@@ -1,19 +1,35 @@
import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import { execFile } from "node:child_process";
import { promisify } from "node:util";
import path from "node:path";
import type { SelfTestCase } from "../harness.js";
const requiredRunnerPackages = Object.freeze(["git", "openssh-client", "ripgrep"]);
const execFileAsync = promisify(execFile);
const selfTest: SelfTestCase = async (context) => {
const containerfile = await readFile(path.join(context.root, "deploy/container/Containerfile"), "utf8");
const apkPackages = installedApkPackages(containerfile);
const tran = await readFile(path.join(context.root, "tools/tran"), "utf8");
const trans = await readFile(path.join(context.root, "tools/trans"), "utf8");
for (const packageName of requiredRunnerPackages) {
assert.equal(apkPackages.has(packageName), true, `runner image must install ${packageName}`);
}
return { name: "90-runner-image-tools", tests: ["runner image installs required CLI tools"] };
assert.equal(tran.startsWith("#!/usr/bin/env bun\n"), true, "tools/tran must be a shebang executable discovered by gitbundle tools");
assert.equal(trans.startsWith("#!/bin/sh\n"), true, "tools/trans must be a shebang executable discovered by gitbundle tools");
assert.equal(tran.includes("UNIDESK_SSH_CLIENT_TOKEN"), true, "tools/tran must require the scoped UniDesk SSH client token");
assert.equal(tran.includes("/ws/ssh"), true, "tools/tran must use the frontend SSH WebSocket path");
const help = await execFileAsync(path.join(context.root, "tools/tran"), ["--help"], { cwd: context.root, timeout: 10_000 });
const parsed = JSON.parse(help.stdout) as { ok?: boolean; supported?: string[]; valuesPrinted?: boolean };
assert.equal(parsed.ok, true);
assert.equal(parsed.valuesPrinted, false);
assert.equal(parsed.supported?.some((line) => line.includes("script")), true);
return { name: "90-runner-image-tools", tests: ["runner image installs required CLI tools", "gitbundle tran tools are executable and documented"] };
};
function installedApkPackages(containerfile: string): Set<string> {