Files
pikasTech-HWLAB/internal/cloud/code-agent-agentrun-durable-admission.test.ts
T

212 lines
8.4 KiB
TypeScript

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}`);
};
}