forked from boos/BoosAPI
Fix orphaned responses tool outputs in messages fallback (#342)
This commit is contained in:
@@ -863,6 +863,51 @@ describe('convertOpenAiBodyToResponsesBody', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('drops tool outputs whose prior tool call cannot be converted into an OpenAI-compatible tool call', () => {
|
||||||
|
const result = convertResponsesBodyToOpenAiBody(
|
||||||
|
{
|
||||||
|
model: 'gpt-5',
|
||||||
|
input: [
|
||||||
|
{
|
||||||
|
type: 'function_call',
|
||||||
|
call_id: 'call_invalid',
|
||||||
|
name: ' ',
|
||||||
|
arguments: '{"plan":true}',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'function_call_output',
|
||||||
|
call_id: 'call_invalid',
|
||||||
|
output: 'unsupported call',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'message',
|
||||||
|
role: 'assistant',
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'output_text',
|
||||||
|
text: 'continue normally',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'gpt-5',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.messages).toEqual([
|
||||||
|
{
|
||||||
|
role: 'assistant',
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
text: 'continue normally',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
it('shortens long MCP tool names consistently across tools, tool_choice and assistant tool calls', () => {
|
it('shortens long MCP tool names consistently across tools, tool_choice and assistant tool calls', () => {
|
||||||
const sharedSuffix = 'server__execute_super_long_nested_tool_name_that_needs_shortening';
|
const sharedSuffix = 'server__execute_super_long_nested_tool_name_that_needs_shortening';
|
||||||
const firstName = `mcp__alpha_workspace__${sharedSuffix}`;
|
const firstName = `mcp__alpha_workspace__${sharedSuffix}`;
|
||||||
|
|||||||
@@ -844,9 +844,14 @@ export function convertResponsesBodyToOpenAiBody(
|
|||||||
const input = stripOrphanedResponsesToolOutputs(normalizedBody.input);
|
const input = stripOrphanedResponsesToolOutputs(normalizedBody.input);
|
||||||
let functionCallIndex = 0;
|
let functionCallIndex = 0;
|
||||||
let pendingToolCalls: OpenAiToolCall[] = [];
|
let pendingToolCalls: OpenAiToolCall[] = [];
|
||||||
|
const emittedToolCallIds = new Set<string>();
|
||||||
|
|
||||||
const flushPendingToolCalls = () => {
|
const flushPendingToolCalls = () => {
|
||||||
if (pendingToolCalls.length <= 0) return;
|
if (pendingToolCalls.length <= 0) return;
|
||||||
|
for (const toolCall of pendingToolCalls) {
|
||||||
|
const callId = asTrimmedString(toolCall.id);
|
||||||
|
if (callId) emittedToolCallIds.add(callId);
|
||||||
|
}
|
||||||
messages.push({
|
messages.push({
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
content: '',
|
content: '',
|
||||||
@@ -894,7 +899,9 @@ export function convertResponsesBodyToOpenAiBody(
|
|||||||
|
|
||||||
if (itemType === 'function_call_output' || itemType === 'custom_tool_call_output') {
|
if (itemType === 'function_call_output' || itemType === 'custom_tool_call_output') {
|
||||||
flushPendingToolCalls();
|
flushPendingToolCalls();
|
||||||
pushToolOutputMessage(item.call_id ?? item.id, item.output ?? item.content);
|
const toolCallId = asTrimmedString(item.call_id ?? item.id);
|
||||||
|
if (!toolCallId || !emittedToolCallIds.has(toolCallId)) return;
|
||||||
|
pushToolOutputMessage(toolCallId, item.output ?? item.content);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -924,7 +931,9 @@ export function convertResponsesBodyToOpenAiBody(
|
|||||||
const content = toOpenAiMessageContent(item.content ?? item.input ?? item);
|
const content = toOpenAiMessageContent(item.content ?? item.input ?? item);
|
||||||
|
|
||||||
if (normalizedRole === 'tool') {
|
if (normalizedRole === 'tool') {
|
||||||
pushToolOutputMessage(item.tool_call_id ?? item.call_id ?? item.id, item.content);
|
const toolCallId = asTrimmedString(item.tool_call_id ?? item.call_id ?? item.id);
|
||||||
|
if (!toolCallId || !emittedToolCallIds.has(toolCallId)) return;
|
||||||
|
pushToolOutputMessage(toolCallId, item.content);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user