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:
@@ -358,6 +358,41 @@ describe('convertOpenAiBodyToAnthropicMessagesBody', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('preserves top-level reasoning_signature when rebuilding assistant thinking blocks for messages fallback', () => {
|
||||
const body = convertOpenAiBodyToAnthropicMessagesBody(
|
||||
{
|
||||
model: 'gpt-5',
|
||||
messages: [
|
||||
{
|
||||
role: 'assistant',
|
||||
content: 'final answer',
|
||||
reasoning_content: 'internal only',
|
||||
reasoning_signature: 'metapi:anthropic-signature:sig-top-level-1',
|
||||
},
|
||||
],
|
||||
},
|
||||
'claude-opus-4-6',
|
||||
false,
|
||||
);
|
||||
|
||||
expect(body.messages).toEqual([
|
||||
{
|
||||
role: 'assistant',
|
||||
content: [
|
||||
{
|
||||
type: 'thinking',
|
||||
thinking: 'internal only',
|
||||
signature: 'sig-top-level-1',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
text: 'final answer',
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('strips cache_control from thinking blocks and empty text blocks', () => {
|
||||
const body = convertOpenAiBodyToAnthropicMessagesBody(
|
||||
{
|
||||
|
||||
@@ -301,9 +301,10 @@ function sanitizeAnthropicContentBlock(item: Record<string, unknown>): Record<st
|
||||
|
||||
if (type === 'thinking' || type === 'redacted_thinking' || type === 'reasoning') {
|
||||
const text = asTrimmedString(item.thinking ?? item.text ?? item.content ?? item.data);
|
||||
if (!text) return null;
|
||||
const signature = type === 'redacted_thinking' ? undefined : resolveAnthropicThinkingSignature(item);
|
||||
if (signature === null) return null;
|
||||
const hasThinkingCarrier = type !== 'redacted_thinking' && signature !== undefined;
|
||||
if (!text && !hasThinkingCarrier) return null;
|
||||
const next: Record<string, unknown> = { ...item };
|
||||
if (type === 'redacted_thinking') {
|
||||
next.type = 'redacted_thinking';
|
||||
@@ -772,6 +773,15 @@ export function convertOpenAiBodyToAnthropicMessagesBody(
|
||||
if (role !== 'assistant') return;
|
||||
|
||||
const contentBlocks = convertOpenAiContentToAnthropicBlocks(item.content);
|
||||
const reasoningCarrier = sanitizeAnthropicContentBlock({
|
||||
type: 'thinking',
|
||||
thinking: asTrimmedString(item.reasoning_content ?? item.reasoning),
|
||||
reasoning_signature: item.reasoning_signature,
|
||||
signature: item.signature,
|
||||
});
|
||||
if (reasoningCarrier) {
|
||||
contentBlocks.unshift(reasoningCarrier);
|
||||
}
|
||||
|
||||
const rawToolCalls = Array.isArray(item.tool_calls) ? item.tool_calls : [];
|
||||
for (let index = 0; index < rawToolCalls.length; index += 1) {
|
||||
|
||||
Reference in New Issue
Block a user