fix(responses): preserve safe output text schema

This commit is contained in:
diegosouzapw
2026-09-02 15:54:27 -03:00
parent 12728c4ac7
commit 373b183ddb
3 changed files with 8 additions and 4 deletions

View File

@@ -38,6 +38,9 @@ export function projectResponsesFailureOutput(
content.push({
type: "output_text",
text: projectString("text", contentPart.text),
// Preserve the required Responses schema without forwarding any
// untrusted citation/file metadata supplied by the provider.
annotations: [],
});
} else if (contentPart.type === "refusal" && typeof contentPart.refusal === "string") {
content.push({

View File

@@ -335,7 +335,7 @@ test("sanitizes response.failed messages without rewriting unrelated deep diagno
{
type: "message",
role: "assistant",
content: [{ type: "output_text", text: "safe direct partial output" }],
content: [{ type: "output_text", text: "safe direct partial output", annotations: [] }],
},
]);
assert.doesNotMatch(serialized, /private direct reasoning/);
@@ -409,7 +409,7 @@ test("sanitizes response.completed failed siblings in objects, SSE, and NDJSON",
role: "assistant",
status: "in_progress",
content: [
{ type: "output_text", text: "partial safe output" },
{ type: "output_text", text: "partial safe output", annotations: [] },
{ type: "refusal", refusal: "safe refusal" },
],
},
@@ -440,7 +440,8 @@ test("sanitizes response.completed failed siblings in objects, SSE, and NDJSON",
serialized,
/completed-failed-secret|srv\/private|completed-failed\.ts|private commentary|private roleless|private chain|private encrypted|private tool/i
);
assert.doesNotMatch(serialized, /"annotations"|"diagnostics"|"function_call"|"reasoning"/);
assert.match(serialized, /"annotations":\[\]/);
assert.doesNotMatch(serialized, /"url_citation"|"diagnostics"|"function_call"|"reasoning"/);
assert.match(serialized, /partial safe output/);
assert.match(serialized, /safe refusal/);
assert.deepEqual(

View File

@@ -285,7 +285,7 @@ test("Responses response.failed is projected before forwarding, logging, and onF
assert.match(result.output, /"last_error":\{/);
assert.match(result.output, /safe partial output/);
assert.match(result.output, /safe refusal/);
assert.doesNotMatch(result.output, /"annotations"/);
assert.match(result.output, /"annotations":\[\]/);
assert.doesNotMatch(result.output, /hidden nested commentary must not be public/);
assert.doesNotMatch(result.output, /roleless output must not be public/);
assert.match(result.output, /"cached_tokens":1/);