fix(responses-continuation): fail closed on a log-truncated stored input/output array (#11473)

Validated in a combined 2-PR batch worktree off release/v3.8.51 tip.
- Focused test: responses-continuation-store.test.ts — part of batch's 46/46 node:test run
- typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity — all OK
- Full-repo lint: 228 pre-existing dashboard react-hooks/* findings, unrelated to this diff

Thanks for the live-verified root cause — a truncation sentinel getting forwarded upstream as a real Responses-API item, breaking the turn with a genuine 400, is exactly the kind of defect that's easy to miss without production traffic to reproduce against.
This commit is contained in:
Markus Hartung
2026-08-26 01:11:46 +02:00
committed by GitHub
parent d3c395bbcf
commit fff62f10a7
2 changed files with 56 additions and 0 deletions

View File

@@ -223,6 +223,44 @@ test("resolvePreviousResponseState resolves input from clientRawRequest when pro
});
});
test("resolvePreviousResponseState fails closed when the stored input array was log-truncated", () => {
// Real production shape: cloneBoundedChatLogPayload (chatCore/logTruncation.ts)
// and cloneBoundedForLog (utils/requestLogger.ts) both prepend an
// `_omniroute_truncated_array` sentinel in place of the items they dropped
// once a logged array exceeds their tail-item cap (~24 items) -- routine
// for any conversation that's been going a while, not an edge case. Reading
// that sentinel back as a real Responses-API item and forwarding it upstream
// produced a live 400: "input item type 'missing' cannot be represented in
// Chat Completions" -- worse than the plain cache-miss this function is
// otherwise designed to fail into.
insertCallLog({
id: "log-7",
responseId: "resp_gen-truncated-history",
apiKeyId: "key-1",
detailState: "ready",
artifactRelPath: "2026-01-01/log-7.json",
});
writeArtifact("2026-01-01/log-7.json", {
clientRawRequest: {
body: {
input: [
{ _omniroute_truncated_array: true, originalLength: 26, retainedTailItems: 24 },
{ type: "function_call_output", call_id: "call_1", output: "ok" },
],
},
},
providerRequest: { body: { input: [] } },
clientResponse: {
summary: {
id: "resp_gen-truncated-history",
output: [{ type: "message", role: "assistant", content: "hello" }],
},
},
});
assert.equal(store.resolvePreviousResponseState("resp_gen-truncated-history", "key-1"), null);
});
test("resolvePreviousResponseState returns null when detail logging was never captured for this row", () => {
insertCallLog({
id: "log-5",