import { configureTaskView, taskTraceSummaryFixtureResponse } from "../src/components/microservices/code-queue/src/task-view"; import { configureTaskOutput } from "../src/components/microservices/code-queue/src/task-output"; import { configureJudge } from "../src/components/microservices/code-queue/src/judge"; import type { OaTraceStepSummary } from "../src/components/microservices/code-queue/src/oa-events"; import type { JsonValue, PromptHistoryItem, QueueTask, QueuedStatusReason } from "../src/components/microservices/code-queue/src/types"; type JsonRecord = Record; function assertCondition(condition: unknown, message: string, detail: JsonRecord = {}): void { if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`); } function asRecord(value: unknown): JsonRecord | null { return typeof value === "object" && value !== null && !Array.isArray(value) ? value as JsonRecord : null; } function pageBySeq( items: T[], _url: URL, _limit: number, ): { mode: "tail" | "after" | "before"; afterSeq: number; beforeSeq: number | null; nextAfterSeq: number; previousBeforeSeq: number | null; hasMore: boolean; hasBefore: boolean; chunk: T[] } { return { mode: "tail", afterSeq: 0, beforeSeq: null, nextAfterSeq: items.at(-1)?.seq ?? 0, previousBeforeSeq: null, hasMore: false, hasBefore: false, chunk: items, }; } function configureFixtureTaskView(): void { configureTaskOutput({ config: { maxInMemoryOutputRecords: 1000, outputArchiveDir: "/tmp/code-queue-trace-summary-contract/output" }, allocateSeq: () => 1000, errorToJson: (error: unknown): JsonValue => error instanceof Error ? { message: error.message } : String(error), logger: () => undefined, markTaskDirty: () => undefined, nowIso: () => "2026-05-19T00:10:00.000Z", schedulePersistState: () => undefined, }); configureJudge({ config: { minimaxApiKey: "", minimaxApiBase: "", minimaxModel: "minimax-m1", judgeTimeoutMs: 1000, judgeRepairAttempts: 0, judgeMaxTokens: 1000, }, logger: () => undefined, safePreview: (value: string, max = 300) => value.length > max ? `${value.slice(0, max)}...` : value, userPromptForDisplay: (prompt: string) => prompt, taskFullOutput: (task: QueueTask) => task.output, taskReferenceIds: (task: QueueTask) => task.referenceTaskIds, extractRecord: (value: unknown) => typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record : null, extractString: (value: unknown, key: string) => { const record = typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record : null; const item = record?.[key]; return typeof item === "string" ? item : null; }, promptLineCount: (text: string) => text.length > 0 ? text.split(/\r\n|\r|\n/u).length : 0, judgeFailRetryLimit: 3, }); configureTaskView({ config: { codexHome: "/tmp/code-queue-trace-summary-contract" }, errorToJson: (error: unknown): JsonValue => error instanceof Error ? { message: error.message } : String(error), jsonResponse: (body: unknown, status = 200): Response => Response.json(body, { status }), logger: () => undefined, mergePromptHistory: (items: PromptHistoryItem[]) => items, nowIso: () => "2026-05-19T00:10:00.000Z", outputPromptHistory: () => [], pageBySeq, parseLimit: () => 100, parseSeqParam: () => null, queueIdOf: (task: QueueTask) => task.queueId, queuedStatusReason: (): QueuedStatusReason | null => null, queuedTaskPromptEditable: () => false, taskQueueEnteredAt: (task: QueueTask) => task.queueEnteredAt, }); } function fixtureTask(): QueueTask { const at = "2026-05-19T00:00:00.000Z"; return { id: "codex_trace_contract", queueId: "default", queueEnteredAt: at, prompt: "Trace summary contract fixture", basePrompt: "Trace summary contract fixture", referenceTaskIds: [], referenceInjection: null, providerId: "D601", cwd: "/workspace", model: "gpt-5.5", reasoningEffort: null, executionMode: "default", maxAttempts: 99, status: "running", createdAt: at, updatedAt: "2026-05-19T00:06:30.000Z", startedAt: at, finishedAt: null, readAt: null, currentAttempt: 2, currentMode: "retry", codexThreadId: "thread_trace_contract", activeTurnId: "turn_trace_contract", finalResponse: "", lastError: null, lastJudge: { decision: "retry", confidence: 1, reason: "attempt 1 asked for retry", source: "fallback" }, judgeFailCount: 0, promptHistory: [], output: [ { seq: 1, at, channel: "user", text: "Trace summary contract fixture", method: "enqueue" }, { seq: 2, at: "2026-05-19T00:00:10.000Z", channel: "system", text: "attempt 1 / 99", method: "queue" }, { seq: 3, at: "2026-05-19T00:01:00.000Z", channel: "command", text: "rg trace-summary src/components/microservices/code-queue/src", method: "item/started", itemId: "call-1" }, { seq: 4, at: "2026-05-19T00:02:00.000Z", channel: "system", text: "judge=retry confidence=1 source=fallback: attempt 1 asked for retry", method: "judge" }, ], events: [], attempts: [ { index: 1, mode: "initial", startedAt: "2026-05-19T00:00:10.000Z", finishedAt: "2026-05-19T00:02:00.000Z", terminalStatus: "completed", transportClosedBeforeTerminal: false, appServerExitCode: 0, appServerSignal: null, error: null, finalResponse: "Attempt 1 response", finalResponsePreview: "Attempt 1 response", finalResponseChars: 18, stderrTail: "", judge: { decision: "retry", confidence: 1, reason: "attempt 1 asked for retry", source: "fallback" }, judgeAt: "2026-05-19T00:02:00.000Z", judgeSeq: 4, outputStartSeq: 2, outputEndSeq: 4, }, ], cancelRequested: false, nextPrompt: null, nextMode: null, }; } function attempt2Steps(): OaTraceStepSummary[] { return [ { eventSequence: 20, seq: 20, at: "2026-05-19T00:06:00.000Z", kind: "ran", title: "Run", status: "item/started", summaryLines: ["attempt 2 / 99", "pnpm test"], rawSeqs: [20], scopeId: "task:codex_trace_contract:attempt:2", attemptIndex: 2, source: "oa-event-flow", }, { eventSequence: 21, seq: 21, at: "2026-05-19T00:06:20.000Z", kind: "explored", title: "Read", status: "item/completed", summaryLines: ["src/components/microservices/code-queue/src/task-view.ts"], rawSeqs: [21], scopeId: "task:codex_trace_contract:attempt:2", attemptIndex: 2, source: "oa-event-flow", }, ]; } export function runCodeQueueTraceSummaryContract(): JsonRecord { configureFixtureTaskView(); const task = fixtureTask(); const steps = attempt2Steps(); const summary = taskTraceSummaryFixtureResponse(task, { stats: null, taskStats: null, allSteps: [ { eventSequence: 1, seq: 1, at: "2026-05-19T00:00:10.000Z", kind: "message", title: "Assistant message", status: "item/completed", summaryLines: ["Attempt 1 judge complete"], rawSeqs: [4], scopeId: "task:codex_trace_contract", attemptIndex: null, source: "oa-event-flow", }, ...steps, ], attemptSteps: new Map([[2, steps]]), }) as JsonRecord; const attempts = Array.isArray(summary.attempts) ? summary.attempts.map(asRecord).filter((item): item is JsonRecord => item !== null) : []; const attempt2 = attempts.find((attempt) => Number(attempt.index) === 2) ?? null; const taskStats = asRecord(summary.traceStats); const taskExecution = asRecord(summary.execution); const attempt2Stats = asRecord(attempt2?.traceStats); const attempt2Execution = asRecord(attempt2?.execution); assertCondition(summary.currentAttempt === 2, "summary must retain currentAttempt=2", summary); assertCondition(summary.statsSource === "raw-trace-fallback", "summary must distinguish raw trace fallback from empty STEP", summary); assertCondition(summary.traceStatsState === "degraded", "summary must mark OA stats sync degraded", summary); assertCondition(summary.traceStatsReason === "oa-event-flow-stats-unavailable-raw-trace-present", "summary must explain degraded OA sync", summary); assertCondition(taskStats?.source === "oa-event-flow" && taskStats?.sourceHint === "raw-trace-fallback", "summary must expose countable synthetic stats with source hint", taskStats ?? {}); assertCondition(taskExecution?.statsSource === "oa-event-flow" && taskExecution?.traceStatsState === "degraded", "execution summary must stay countable while degraded", taskExecution ?? {}); assertCondition(Number(summary.stepCount ?? 0) > 0, "summary fallback STEP count must be visible", summary); assertCondition(attempt2 !== null, "summary must materialize the latest running retry attempt", { attempts }); assertCondition(Number(attempt2?.stepCount ?? 0) > 0, "attempt 2 must expose live fallback STEP count", attempt2 ?? {}); assertCondition(attempt2Stats?.source === "oa-event-flow" && attempt2Stats?.sourceHint === "raw-trace-fallback", "attempt 2 fallback stats must remain countable", attempt2Stats ?? {}); assertCondition(attempt2Execution?.statsSource === "oa-event-flow" && attempt2Execution?.traceStatsState === "degraded", "attempt 2 execution must be countable while degraded", attempt2Execution ?? {}); return { ok: true, checks: [ { name: "code-queue:trace-summary-latest-attempt-visible", ok: true }, { name: "code-queue:trace-summary-raw-trace-step-fallback", ok: true }, ], taskId: task.id, stepCount: summary.stepCount, statsSource: summary.statsSource, traceStatsState: summary.traceStatsState, attempt2StepCount: attempt2?.stepCount, }; } if (import.meta.main) { process.stdout.write(`${JSON.stringify(runCodeQueueTraceSummaryContract(), null, 2)}\n`); }