Refactor reasoning handling and metadata management in responses

- Updated chat stream tests to clarify reasoning behavior and ensure correct handling of include lists.
- Enhanced responses proxy route to normalize include lists and apply default reasoning includes based on request context.
- Improved transformer metadata handling, ensuring proper serialization and deserialization of metadata records.
- Added tests for preserving reasoning signatures and managing citations in OpenAI-compatible responses.
- Refined the logic for injecting default includes in responses and ensured compatibility with codex surface defaults.
This commit is contained in:
cita
2026-03-08 23:03:33 +08:00
parent 7bd3114ea0
commit 3dcf45851f
12 changed files with 830 additions and 56 deletions
@@ -7,6 +7,7 @@ import type {
OpenAiChatToolCall,
OpenAiChatUsageDetails,
} from './model.js';
import { fromTransformerMetadataRecord } from '../../shared/normalized.js';
function isRecord(value: unknown): value is Record<string, unknown> {
return !!value && typeof value === 'object' && !Array.isArray(value);
@@ -345,7 +346,9 @@ function extractCitationsFromPayload(
citations.add(citation);
}
const transformerMetadata = asRecord(payload.transformer_metadata) ?? asRecord(payload.transformerMetadata);
const transformerMetadata = fromTransformerMetadataRecord(
payload.transformer_metadata ?? payload.transformerMetadata,
);
if (transformerMetadata) {
for (const citation of dedupeCitations(transformerMetadata.citations)) {
citations.add(citation);
@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest';
import { createClaudeDownstreamContext } from '../../shared/normalized.js';
import { toTransformerMetadataRecord } from '../../shared/normalized.js';
import { openAiChatTransformer } from './index.js';
function parseSsePayloads(lines: string[]): Array<Record<string, unknown>> {
@@ -154,6 +155,32 @@ describe('openAiChatTransformer.outbound', () => {
});
});
it('consumes shared transformer metadata citations on openai-compatible final responses', () => {
const normalized = openAiChatTransformer.transformFinalResponse({
id: 'chatcmpl-shared-metadata',
model: 'gpt-5',
created: 123,
transformer_metadata: toTransformerMetadataRecord({
citations: [{ uri: 'https://shared.example/citation' }],
thoughtSignature: 'sig-final',
thoughtSignatures: ['sig-tool', 'sig-final'],
passthrough: {
cachedContent: 'cached/item-1',
},
}),
choices: [{
index: 0,
finish_reason: 'stop',
message: {
role: 'assistant',
content: 'hello',
},
}],
}, 'gpt-5');
expect((normalized as any).citations).toEqual(['https://shared.example/citation']);
});
it('serializes multi-choice chat responses with per-choice annotations, reasoning, tool calls, and shared citations', () => {
const normalized = openAiChatTransformer.transformFinalResponse({
id: 'chatcmpl-multi',