fix(runner): retain Grok accounting during cancellation

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-11-04 00:06:02 -06:00
1 parent a3e6d637fb
commit 17c9f7e091
2 files changed
+40 -1

No files matched your search

@@ -952,6 +952,45 @@ describe("Codex ACPX runtime adapter", () => {
} finally { await port.close({ reason: "fixture done" }); }
});
it.each(["cancel", "closeStream"] as const)("retains the bound Grok usage response during %s until the prompt settles", async (stop) => {
const runtime = fakeRuntime();
const durableRecord = { acpxRecordId: "record-1", acpSessionId: "backend-1", agentSessionId: "agent-1", lastRequestId: "previous" };
const durableStore: AcpSessionStore = { load: vi.fn(async () => structuredClone(durableRecord) as never), save: vi.fn() };
let created!: AcpRuntimeOptions;
let settle!: (value: { status: "completed" }) => void;
const result = new Promise<{ status: "completed" }>(resolve => { settle = resolve; });
const options = openOptions(fakeCommand());
options.profile = { ...options.profile, agent: "grok" };
const port = await openCodexAcpxRuntime(options, { createRegistry: () => registry(), createStore: () => durableStore,
createRuntime: value => { created = value; return runtime; } });
vi.mocked(runtime.startTurn).mockImplementation(input => {
durableRecord.lastRequestId = input.requestId;
created.onAcpMessage?.("outbound", { id: 1, method: "session/prompt", params: { sessionId: "backend-1" } });
return { requestId: input.requestId, promptStarted: Promise.resolve(), events: (async function* () {})(), result,
cancel: async () => undefined, closeStream: async () => undefined };
});
try {
const before = await port.getStatus();
const turn = port.startTurn({ requestId: "runner-cancelled", text: "fixture" });
await turn[stop]({ reason: "fixture stopped" });
created.onAcpMessage?.("outbound", { id: 2, method: "session/prompt", params: { sessionId: "backend-1" } });
created.onAcpMessage?.("inbound", { id: 1, result: { _meta: {
sessionId: "backend-1", promptId: "prompt-1", requestId: "prompt-1",
usage: { inputTokens: 50, outputTokens: 5, totalTokens: 55, cachedReadTokens: 20, cacheCreationTokens: 0,
reasoningTokens: 2, modelCalls: 1, costUsdTicks: 10000000 },
} } });
settle({ status: "completed" });
await turn.result;
const after = await port.getStatus();
expect(persistedAcpxTurnUsage(before, after, "runner-cancelled")).toMatchObject({
cost: { amount: 0.001, currency: "USD", basis: "turn" },
breakdown: { inputTokens: 30, outputTokens: 5, cachedReadTokens: 20, thoughtTokens: 0 },
});
created.onAcpMessage?.("inbound", { id: 1, error: { message: "late conflicting response" } });
expect(await port.getStatus()).toEqual(after);
} finally { settle({ status: "completed" }); await port.close({ reason: "fixture done" }); }
});
it("reads verified status from durable state without draining live updates", async () => {
const runtime = fakeRuntime();
vi.mocked(runtime.getStatus!).mockReturnValue(new Promise(() => {}));
@@ -470,7 +470,7 @@ export async function openQualifiedAcpxRuntime(
onSessionNotification: acceptGoalNotification,
onAcpMessage: (direction, message) => {
const active = extensionBoundary.active;
if (active && !active.signal.aborted) promptUsage?.observe(direction, message);
if (active && (direction === "inbound" || !active.signal.aborted)) promptUsage?.observe(direction, message);
},
spawnEnvironment: () => ({
...definedEnvironment(options.launchEnvironment),