Files
pikasTech-HWLAB/internal/workbench/native-agentrun-application.test.ts
T
2026-07-18 04:41:49 +02:00

139 lines
6.5 KiB
TypeScript

import { mkdtemp, readFile, rm } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterEach, expect, test } from "bun:test";
import { createNativeAgentRunWorkbenchApplication } from "./native-agentrun-application.ts";
const temporaryDirectories: string[] = [];
afterEach(async () => {
await Promise.all(temporaryDirectories.splice(0).map((directory) => rm(directory, { force: true, recursive: true })));
});
test("L1 AgentRun application projects a gpt.pika command through terminal response", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "hwlab-workbench-agentrun-"));
temporaryDirectories.push(directory);
const stateFile = path.join(directory, "state.json");
const calls: Array<{ method: string; path: string; authorization: string | null; body: any }> = [];
const app = createNativeAgentRunWorkbenchApplication({
stateFile,
env: agentRunEnvironment(),
fetchImpl: fakeAgentRunManager(calls),
});
const created = await app.createSession({ actor: { id: "usr_native", role: "user" }, params: { providerProfile: "gpt.pika" } });
const session = created.session as Record<string, any>;
const input = {
actor: { id: "usr_native", role: "user" },
traceId: "trc_l1_gpt_pika_smoke",
sessionId: session.sessionId,
params: { message: "hi", providerProfile: "gpt.pika" },
};
const admitted = await app.admitTurn(input);
const result = await app.dispatchTurn(admitted);
expect(result).toMatchObject({
status: "completed",
finalResponse: { text: "Hi from gpt.pika." },
agentRun: {
runId: "run_l1_gpt_pika",
commandId: "cmd_l1_gpt_pika",
runnerJobId: "rjob_l1_gpt_pika",
completed: true,
},
});
const state = JSON.parse(await readFile(stateFile, "utf8"));
expect(state.turns[input.traceId]).toMatchObject({
status: "completed",
terminal: true,
runId: "run_l1_gpt_pika",
commandId: "cmd_l1_gpt_pika",
runnerJobId: "rjob_l1_gpt_pika",
finalResponse: { text: "Hi from gpt.pika." },
});
expect(state.sessions[session.sessionId]).toMatchObject({ status: "idle", providerProfile: "gpt.pika" });
expect(state.sessions[session.sessionId].messages.at(-1)).toMatchObject({ role: "assistant", content: "Hi from gpt.pika." });
expect(calls.every((call) => call.authorization === "Bearer test-agentrun-key")).toBe(true);
});
test("L1 AgentRun application projects manager failures instead of leaving a running turn", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "hwlab-workbench-agentrun-failure-"));
temporaryDirectories.push(directory);
const stateFile = path.join(directory, "state.json");
const app = createNativeAgentRunWorkbenchApplication({
stateFile,
env: agentRunEnvironment(),
fetchImpl: (async () => Response.json({ ok: false, failureKind: "manager-unavailable", message: "manager unavailable" }, { status: 503 })) as typeof fetch,
});
const created = await app.createSession({ actor: { id: "usr_native" }, params: { providerProfile: "gpt.pika" } });
const session = created.session as Record<string, any>;
const input = await app.admitTurn({
actor: { id: "usr_native" },
traceId: "trc_l1_manager_failure",
sessionId: session.sessionId,
params: { message: "hi", providerProfile: "gpt.pika" },
});
expect(await app.dispatchTurn(input)).toMatchObject({ status: "failed", terminal: true, error: { code: "manager-unavailable" } });
expect((await app.snapshot!()).turns[input.traceId]).toMatchObject({ status: "failed", terminal: true, error: { code: "manager-unavailable" } });
});
function agentRunEnvironment(): Record<string, string> {
return {
WORKBENCH_MODE: "agentrun-native",
AGENTRUN_MGR_URL: "http://127.0.0.1:65535",
AGENTRUN_API_KEY: "test-agentrun-key",
HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1",
HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "NC01",
HWLAB_CODE_AGENT_AGENTRUN_SOURCE_COMMIT: "0123456789abcdef0123456789abcdef01234567",
HWLAB_CODE_AGENT_AGENTRUN_REPO_URL: "http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git",
HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: "gpt.pika",
HWLAB_CODE_AGENT_AGENTRUN_RUNNER_NAMESPACE: "agentrun-v02",
HWLAB_CODE_AGENT_AGENTRUN_DISPATCH_RETRY_MAX: "1",
HWLAB_CODE_AGENT_AGENTRUN_DISPATCH_RETRY_BASE_MS: "1",
HWLAB_CODE_AGENT_AGENTRUN_DISPATCH_RETRY_MAX_DELAY_MS: "1",
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",
WORKBENCH_AGENTRUN_TERMINAL_TIMEOUT_MS: "1000",
WORKBENCH_AGENTRUN_POLL_INTERVAL_MS: "1",
};
}
function fakeAgentRunManager(calls: Array<{ method: string; path: string; authorization: string | null; body: any }>): typeof fetch {
return (async (input: string | URL | Request, init: RequestInit = {}) => {
const url = new URL(String(input));
const method = init.method ?? "GET";
const body = init.body ? JSON.parse(String(init.body)) : null;
calls.push({ method, path: url.pathname, authorization: new Headers(init.headers).get("authorization"), body });
const send = (data: unknown) => Response.json({ ok: true, data });
if (method === "POST" && url.pathname === "/api/v1/sessions") {
return send({ session: { id: "ses_agentrun_l1_gpt_pika", metadata: {} } });
}
if (method === "POST" && url.pathname === "/api/v1/runs") {
expect(body.backendProfile).toBe("gpt-pika");
return send({ id: "run_l1_gpt_pika", status: "pending", sessionRef: body.sessionRef, backendProfile: body.backendProfile });
}
if (method === "POST" && url.pathname === "/api/v1/runs/run_l1_gpt_pika/commands") {
expect(body.payload.prompt).toBe("hi");
return send({
id: "cmd_l1_gpt_pika",
runId: "run_l1_gpt_pika",
state: "pending",
type: "turn",
seq: 1,
dispatchIntent: { id: "dispatch_l1_gpt_pika", state: "pending", runnerJobId: "rjob_l1_gpt_pika", attemptCount: 0, durable: true },
});
}
if (method === "GET" && url.pathname === "/api/v1/runs/run_l1_gpt_pika/commands/cmd_l1_gpt_pika/result") {
return send({ runId: "run_l1_gpt_pika", commandId: "cmd_l1_gpt_pika", terminalStatus: "completed", completed: true, reply: "Hi from gpt.pika." });
}
throw new Error(`unexpected AgentRun call ${method} ${url.pathname}`);
}) as typeof fetch;
}