Merge pull request #472 from amarcin/fix/responses-tool-calls
fix: /v1/responses endpoint drops tool calls (function_call) in non-streaming mode
This commit is contained in:
commit
8f8c700a0f
3 changed files with 52 additions and 14 deletions
|
|
@ -1648,22 +1648,42 @@ export class ClaudeConverter extends BaseConverter {
|
|||
* Claude响应 -> OpenAI Responses响应
|
||||
*/
|
||||
toOpenAIResponsesResponse(claudeResponse, model) {
|
||||
const content = this.processClaudeResponseContent(claudeResponse.content);
|
||||
const textContent = typeof content === 'string' ? content : JSON.stringify(content);
|
||||
const output = [];
|
||||
const messageContent = [];
|
||||
let hasToolUse = false;
|
||||
|
||||
let output = [];
|
||||
output.push({
|
||||
// Process Claude content blocks, handling both text and tool_use
|
||||
if (Array.isArray(claudeResponse.content)) {
|
||||
for (const block of claudeResponse.content) {
|
||||
if (block.type === 'text' && block.text) {
|
||||
messageContent.push({
|
||||
annotations: [],
|
||||
logprobs: [],
|
||||
text: block.text,
|
||||
type: "output_text"
|
||||
});
|
||||
} else if (block.type === 'tool_use') {
|
||||
hasToolUse = true;
|
||||
output.push({
|
||||
type: "function_call",
|
||||
id: block.id || `fc_${uuidv4().replace(/-/g, '')}`,
|
||||
call_id: block.id || `call_${uuidv4().replace(/-/g, '')}`,
|
||||
name: block.name,
|
||||
arguments: typeof block.input === 'string' ? block.input : JSON.stringify(block.input || {}),
|
||||
status: "completed"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Always include the message output item (even if content is empty)
|
||||
output.unshift({
|
||||
type: "message",
|
||||
id: `msg_${uuidv4().replace(/-/g, '')}`,
|
||||
summary: [],
|
||||
role: "assistant",
|
||||
status: "completed",
|
||||
content: [{
|
||||
annotations: [],
|
||||
logprobs: [],
|
||||
text: textContent,
|
||||
type: "output_text"
|
||||
}]
|
||||
content: messageContent
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
@ -1684,7 +1704,7 @@ export class ClaudeConverter extends BaseConverter {
|
|||
reasoning: {},
|
||||
safety_identifier: "user-" + uuidv4().replace(/-/g, ''),
|
||||
service_tier: "default",
|
||||
status: "completed",
|
||||
status: hasToolUse ? "requires_action" : "completed",
|
||||
store: false,
|
||||
temperature: 1,
|
||||
text: {
|
||||
|
|
|
|||
|
|
@ -1642,11 +1642,29 @@ export class OpenAIConverter extends BaseConverter {
|
|||
content: messageContent
|
||||
});
|
||||
|
||||
// Handle tool calls (function_call output items)
|
||||
if (message.tool_calls && message.tool_calls.length > 0) {
|
||||
for (const tc of message.tool_calls) {
|
||||
if (tc.type === 'function' && tc.function) {
|
||||
output.push({
|
||||
type: 'function_call',
|
||||
id: tc.id || `fc_${Date.now()}`,
|
||||
call_id: tc.id || `call_${Date.now()}`,
|
||||
name: tc.function.name,
|
||||
arguments: tc.function.arguments || '{}',
|
||||
status: 'completed'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hasToolCalls = message.tool_calls && message.tool_calls.length > 0;
|
||||
|
||||
return {
|
||||
id: openaiResponse.id || `resp_${Date.now()}`,
|
||||
object: 'response',
|
||||
created_at: openaiResponse.created || Math.floor(Date.now() / 1000),
|
||||
status: choice.finish_reason === 'stop' ? 'completed' : 'in_progress',
|
||||
status: hasToolCalls ? 'requires_action' : (choice.finish_reason === 'stop' ? 'completed' : 'in_progress'),
|
||||
model: model || openaiResponse.model || 'unknown',
|
||||
output: output,
|
||||
usage: openaiResponse.usage ? {
|
||||
|
|
@ -1736,7 +1754,7 @@ export class OpenAIConverter extends BaseConverter {
|
|||
item_id: toolCall.id || `call_${uuidv4().replace(/-/g, '')}`,
|
||||
output_index: outputIndex,
|
||||
sequence_number: 3,
|
||||
type: "response.custom_tool_call_input.delta"
|
||||
type: "response.function_call_arguments.delta"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ function generateResponseCompleted(requestId, usage) {
|
|||
},
|
||||
safety_identifier: `user-${uuidv4().replace(/-/g, '')}`, // 随机值
|
||||
service_tier: "default",
|
||||
status: "completed",
|
||||
status: (state.toolCalls && state.toolCalls.length > 0) ? "requires_action" : "completed",
|
||||
store: false,
|
||||
temperature: 1,
|
||||
text: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue