fix(runtime): derive unattributed cost from usage status

This commit is contained in:
ZacharyZhang-NY committed 2026-04-22 16:18:03 -04:00
1 parent f107415f4f
commit ebcc15c68d
8 files changed
+61 -7

No files matched your search

+4
View File
@@ -56,6 +56,10 @@ export function classifyRunUsage(input: RunUsageClassificationInput): RunUsageSt
return "pre_first_message";
}
export function isUsageStatusUnattributed(status: RunUsageStatus): boolean {
return status !== "ok";
}
export function deriveLegacyRunUsageStatus(input: {
runStatus: RunStatus;
unattributedCost: boolean;
-1
View File
@@ -108,7 +108,6 @@ function cancelRun(runId: string) {
signal: null,
model: null,
usageStatus: "aborted_before_usage",
unattributedCost: true,
inputTokens: null,
outputTokens: null,
});
+1 -2
View File
@@ -53,10 +53,9 @@ export const workerMessageSchema = z.union([
signal: z.string().nullable(),
model: z.string().nullable(),
usageStatus: runUsageStatusSchema,
unattributedCost: z.boolean(),
inputTokens: z.number().nullable(),
outputTokens: z.number().nullable(),
}),
}).strict(),
z.object({
type: z.literal("agent-event"),
runId: z.string().uuid(),
@@ -4,6 +4,7 @@ import { handleFailureEscalation, handleSuccessReset } from "../observability/fa
import { persistRunEvent } from "../observability/run-event-recorder";
import type { workerMessageSchema } from "../entry/types";
import type { HandlerContext, HandlerDeps, WorkerMessageEvent } from "./handler-context";
import { isUsageStatusUnattributed } from "../../run-usage-status";
type RunFinishedEvent = Extract<WorkerMessageEvent, { type: "run-finished" }>;
type RunRecord = ReturnType<HandlerDeps["db"]["runs"]["getRun"]>;
@@ -33,6 +34,8 @@ export function finalizeRun(
return null;
}
const unattributedCost = isUsageStatusUnattributed(event.usageStatus);
persistRunEvent(db, logger, {
companyId: run.companyId,
runId: run.id,
@@ -48,7 +51,7 @@ export function finalizeRun(
signal: event.signal,
model: event.model,
usageStatus: event.usageStatus,
unattributedCost: event.unattributedCost,
unattributedCost,
inputTokens: event.inputTokens,
outputTokens: event.outputTokens,
},
@@ -67,7 +70,7 @@ export function finalizeRun(
}
leaseRenewalMap.delete(event.runId);
const runOutcome = db.runs.finishRun(event);
const runOutcome = db.runs.finishRun({ ...event, unattributedCost });
if (run.workspaceId) {
db.workspacesMod.releaseWorkspaceLock(run.workspaceId, run.id);
}
-1
View File
@@ -65,7 +65,6 @@ export type ChildMessage =
signal: string | null;
model: string | null;
usageStatus: RunUsageStatus;
unattributedCost: boolean;
inputTokens: number | null;
outputTokens: number | null;
}
-1
View File
@@ -290,7 +290,6 @@ export class WorkerRunner {
signal: null,
model: resolvedModelId,
usageStatus,
unattributedCost: usageStatus !== "ok",
inputTokens: finalUsage.inputTokens,
outputTokens: finalUsage.outputTokens,
});
+8
View File
@@ -3,6 +3,7 @@ import {
classifyRunUsage,
deriveLegacyRunUsageStatus,
hasAttributableAssistantUsage,
isUsageStatusUnattributed,
} from "../../src/main/run-usage-status";
describe("run usage status", () => {
@@ -81,4 +82,11 @@ describe("run usage status", () => {
);
expect(deriveLegacyRunUsageStatus({ runStatus: "failed", unattributedCost: true })).toBe("pre_first_message");
});
it("derives the legacy unattributed-cost flag from usage status", () => {
expect(isUsageStatusUnattributed("ok")).toBe(false);
expect(isUsageStatusUnattributed("pre_first_message")).toBe(true);
expect(isUsageStatusUnattributed("error_stop")).toBe(true);
expect(isUsageStatusUnattributed("aborted_before_usage")).toBe(true);
});
});
+43
View File
@@ -0,0 +1,43 @@
import { describe, expect, it } from "vitest";
import { workerMessageSchema } from "../../src/main/worker/entry/types";
const RUN_ID = "00000000-0000-4000-8000-000000000001";
describe("worker message schema", () => {
it("accepts run-finished messages keyed by usage status", () => {
expect(
workerMessageSchema.safeParse({
type: "run-finished",
runId: RUN_ID,
status: "failed",
summary: null,
errorMessage: "Agent stopped with error.",
exitCode: null,
signal: null,
model: "gpt-5.4",
usageStatus: "error_stop",
inputTokens: 12,
outputTokens: 1,
}).success,
).toBe(true);
});
it("rejects legacy unattributed-cost truth in run-finished messages", () => {
expect(
workerMessageSchema.safeParse({
type: "run-finished",
runId: RUN_ID,
status: "failed",
summary: null,
errorMessage: "Agent stopped with error.",
exitCode: null,
signal: null,
model: "gpt-5.4",
usageStatus: "error_stop",
unattributedCost: false,
inputTokens: 12,
outputTokens: 1,
}).success,
).toBe(false);
});
});