import assert from "node:assert/strict"; import { test } from "bun:test"; import { submitAgentRunChatTurn } from "./code-agent-agentrun-adapter.ts"; import { createCodeAgentTraceStore } from "./code-agent-trace-store.ts"; const sourceCommit = "0123456789abcdef0123456789abcdef01234567"; test("fresh gpt.pika turn returns running only after durable dispatch intent is confirmed", async () => { const traceId = "trc_gpt_pika_durable_admission"; const calls = []; const traceStore = createCodeAgentTraceStore(); const result = await submitAgentRunChatTurn({ traceId, traceStore, params: { ownerUserId: "usr_gpt_pika", projectId: "pikasTech/HWLAB", conversationId: "cnv_gpt_pika_durable", sessionId: "ses_gpt_pika_durable", message: "verify durable admission", providerProfile: "gpt.pika" }, options: { env: agentRunTestEnv(), accessController: { async codeAgentToolCapabilitiesForOwner() { return { tools: { hwpod: { allowed: true } } }; }, store: { async findActiveDefaultApiKeyForUser() { return { displaySecret: "hwl_live_must_not_be_persisted" }; } } }, fetchImpl: createAgentRunFetch(calls, { dispatchIntent: { id: "dispatch_gpt_pika_durable", state: "pending", runnerJobId: "rjob_gpt_pika_durable", attemptCount: 0, durable: true } }) } }); assert.equal(result.status, "running"); assert.equal(result.agentRun.runId, "run_gpt_pika_durable"); assert.equal(result.agentRun.commandId, "cmd_gpt_pika_durable"); assert.equal(result.agentRun.dispatchIntentId, "dispatch_gpt_pika_durable"); assert.equal(result.agentRun.dispatchIntentState, "pending"); assert.equal(result.agentRun.runnerJobId, "rjob_gpt_pika_durable"); assert.equal(result.agentRun.durableDispatch, true); assert.equal(result.agentRun.status, "dispatch-intent-pending"); const commandCall = calls.find((call) => call.path.endsWith("/commands")); assert.ok(commandCall); assert.equal(commandCall.body.idempotencyKey, traceId); assert.equal(commandCall.body.payload.traceId, traceId); assert.equal(commandCall.body.payload.sessionId, "ses_agentrun_gpt_pika_durable"); assert.equal(commandCall.body.payload.hwlabSessionId, "ses_gpt_pika_durable"); assert.equal(commandCall.body.payload.conversationId, "cnv_gpt_pika_durable"); assert.equal(commandCall.body.dispatch.kind, "kubernetes-job"); assert.equal(Object.hasOwn(commandCall.body.dispatch.input, "commandId"), false); assert.equal(commandCall.body.dispatch.input.idempotencyKey, traceId); assert.equal(Object.hasOwn(commandCall.body.dispatch.input, "namespace"), false); assert.equal(Object.hasOwn(commandCall.body.dispatch.input, "image"), false); assert.equal(Object.hasOwn(commandCall.body.dispatch.input, "serviceAccountName"), false); assert.equal(commandCall.body.dispatch.input.transientEnv.every((entry) => entry.sensitive === false), true); assert.equal(commandCall.body.dispatch.input.transientEnv.every((entry) => !entry.name.startsWith("AGENTRUN_") && !entry.name.startsWith("KUBERNETES_")), true); assert.equal(JSON.stringify(commandCall.body).includes("hwl_live_must_not_be_persisted"), false); assert.equal(calls.some((call) => call.path.endsWith("/runner-jobs")), false); assert.ok(traceStore.snapshot(traceId).events.some((event) => event.label === "agentrun:dispatch-intent:admitted")); }); test("fresh turn rejects an unconfirmed dispatch intent instead of returning false running", async () => { const calls = []; await assert.rejects( submitAgentRunChatTurn({ traceId: "trc_dispatch_intent_missing", traceStore: createCodeAgentTraceStore(), params: { sessionId: "ses_dispatch_intent_missing", conversationId: "cnv_dispatch_intent_missing", message: "must fail admission", providerProfile: "gpt.pika" }, options: { env: agentRunTestEnv(), fetchImpl: createAgentRunFetch(calls, { dispatchIntent: null }) } }), (error) => error?.code === "agentrun_dispatch_intent_unconfirmed" && error?.statusCode === 502 ); assert.equal(calls.some((call) => call.path.endsWith("/runner-jobs")), false); }); test("fresh turn rejects a durable dispatch intent with missing contract fields", async () => { await assert.rejects( submitAgentRunChatTurn({ traceId: "trc_dispatch_intent_attempt_missing", traceStore: createCodeAgentTraceStore(), params: { sessionId: "ses_dispatch_intent_attempt_missing", message: "must require explicit attempt count", providerProfile: "gpt.pika" }, options: { env: agentRunTestEnv(), fetchImpl: createAgentRunFetch([], { dispatchIntent: { id: "dispatch_attempt_missing", state: "pending", runnerJobId: "rjob_attempt_missing", durable: true } }) } }), (error) => error?.code === "agentrun_dispatch_intent_unconfirmed" && error?.statusCode === 502 ); }); for (const terminal of [ { state: "failed", code: "agentrun_dispatch_intent_failed", statusCode: 503 }, { state: "cancelled", code: "agentrun_dispatch_intent_cancelled", statusCode: 409 } ]) { test(`fresh turn exposes ${terminal.state} durable dispatch replay instead of returning running`, async () => { await assert.rejects( submitAgentRunChatTurn({ traceId: `trc_dispatch_intent_${terminal.state}`, traceStore: createCodeAgentTraceStore(), params: { sessionId: `ses_dispatch_intent_${terminal.state}`, message: `surface ${terminal.state} admission`, providerProfile: "gpt.pika" }, options: { env: agentRunTestEnv(), fetchImpl: createAgentRunFetch([], { dispatchIntent: { id: `dispatch_terminal_${terminal.state}`, state: terminal.state, runnerJobId: `rjob_terminal_${terminal.state}`, attemptCount: 2, durable: true } }) } }), (error) => error?.code === terminal.code && error?.statusCode === terminal.statusCode ); }); } function agentRunTestEnv() { return { AGENTRUN_MGR_URL: "http://127.0.0.1:65535", HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1", HWLAB_CODE_AGENT_AGENTRUN_DISPATCH_RETRY_MAX: "0", HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "NC01", HWLAB_CODE_AGENT_AGENTRUN_SOURCE_COMMIT: sourceCommit, HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: "gpt.pika", HWLAB_CODE_AGENT_AGENTRUN_RUNNER_NAMESPACE: "caller-controlled-namespace-must-be-ignored", HWLAB_CODE_AGENT_AGENTRUN_RUNNER_IMAGE: "caller-controlled-image-must-be-ignored", HWLAB_CODE_AGENT_AGENTRUN_RUNNER_SERVICE_ACCOUNT: "caller-controlled-service-account-must-be-ignored", HWLAB_RUNTIME_API_URL: "http://hwlab-cloud-api.hwlab-v03.svc.cluster.local:6667", HWLAB_RUNTIME_WEB_URL: "http://hwlab-cloud-web.hwlab-v03.svc.cluster.local:8080", HWLAB_RUNTIME_NAMESPACE: "hwlab-v03", HWLAB_RUNTIME_LANE: "v03", HWLAB_RUNTIME_ENDPOINT_LOCKED: "1", HWLAB_CODE_AGENT_ASSEMBLED_RUNTIME: "1", UNIDESK_MAIN_SERVER_IP: "http://127.0.0.1:18081" }; } function createAgentRunFetch(calls, { dispatchIntent }) { return async (url, init = {}) => { const parsed = new URL(url); const method = init.method ?? "GET"; const body = init.body ? JSON.parse(String(init.body)) : null; calls.push({ method, path: parsed.pathname, body }); const send = (data) => new Response(JSON.stringify({ ok: true, data }), { status: 200, headers: { "content-type": "application/json" } }); if (method === "POST" && parsed.pathname === "/api/v1/sessions") { return send({ session: { id: "ses_agentrun_gpt_pika_durable", metadata: {} } }); } if (method === "POST" && parsed.pathname === "/api/v1/runs") { return send({ id: "run_gpt_pika_durable", status: "pending", sessionRef: body.sessionRef, backendProfile: body.backendProfile }); } if (method === "POST" && parsed.pathname === "/api/v1/runs/run_gpt_pika_durable/commands") { return send({ id: "cmd_gpt_pika_durable", runId: "run_gpt_pika_durable", state: "pending", type: "turn", seq: 1, dispatchIntent }); } throw new Error(`unexpected AgentRun call ${method} ${parsed.pathname}`); }; }