import assert from "node:assert/strict"; import { startManagerServer } from "../../mgr/server.js"; import { MemoryAgentRunStore } from "../../mgr/store.js"; import { ManagerClient } from "../../mgr/client.js"; import type { CommandRecord, RunEvent, RunRecord, SessionEventPage, SessionListResult, SessionReadCursorRecord, SessionSummary } from "../../common/types.js"; import type { SelfTestCase } from "../harness.js"; const selfTest: SelfTestCase = async (context) => { const server = await startManagerServer({ port: 0, host: "127.0.0.1", sourceCommit: "self-test", store: new MemoryAgentRunStore() }); try { const client = new ManagerClient(server.baseUrl); const sessionId = "ses_selftest_control"; const run = await client.post("/api/v1/runs", { tenantId: "unidesk", projectId: "pikasTech/agentrun", workspaceRef: { kind: "host-path", path: context.workspace }, sessionRef: { sessionId, metadata: { title: "session control self-test" } }, providerId: "G14", backendProfile: "codex", executionPolicy: { sandbox: "workspace-write", approval: "never", timeoutMs: 300000, network: "default", secretScope: { allowCredentialEcho: false, providerCredentials: [{ profile: "codex", secretRef: { name: "agentrun-v01-provider-codex", keys: ["auth.json", "config.toml"], mountPath: context.codexHome } }] }, }, traceSink: null, }) as RunRecord; const command = await client.post(`/api/v1/runs/${run.id}/commands`, { type: "turn", payload: { prompt: "write a concise status" }, idempotencyKey: "session-control-turn" }) as CommandRecord; const running = await client.get("/api/v1/sessions?state=running&readerId=self-test") as SessionListResult; assert.equal(running.count, 1); assert.equal(running.items[0]?.sessionId, sessionId); assert.equal(running.items[0]?.active, true); await client.post(`/api/v1/runs/${run.id}/events`, { type: "assistant_message", payload: { text: "done" } }) as RunEvent; await client.patch(`/api/v1/commands/${command.id}/status`, { terminalStatus: "completed", failureKind: null, failureMessage: null, threadId: "thread_selftest", turnId: "turn_selftest" }) as CommandRecord; const unread = await client.get("/api/v1/sessions?state=default&readerId=self-test") as SessionListResult; assert.equal(unread.count, 1); assert.equal(unread.items[0]?.sessionId, sessionId); assert.equal(unread.items[0]?.unread, true); assert.equal(unread.items[0]?.executionState, "terminal"); const trace = await client.get(`/api/v1/sessions/${sessionId}/trace?limit=20`) as SessionEventPage; assert.ok(trace.count >= 3); assert.equal(trace.runId, run.id); const output = await client.get(`/api/v1/sessions/${sessionId}/output?limit=20`) as SessionEventPage; assert.equal(output.items.some((event) => event.type === "assistant_message"), true); const read = await client.post(`/api/v1/sessions/${sessionId}/read`, { readerId: "self-test" }) as SessionReadCursorRecord; assert.equal(read.sessionId, sessionId); assert.equal(read.readerId, "self-test"); const readDefault = await client.get("/api/v1/sessions?state=default&readerId=self-test") as SessionListResult; assert.equal(readDefault.count, 0); const shown = await client.get(`/api/v1/sessions/${sessionId}?readerId=self-test`) as SessionSummary; assert.equal(shown.unread, false); assert.equal(shown.threadId, "thread_selftest"); return { name: "session-control", tests: ["session-control-rest-memory"] }; } finally { await new Promise((resolve) => server.server.close(() => resolve())); } }; export default selfTest;