fix: normalize finish_reason to 'tool_calls' when tool calls are present (#379)
Some upstream providers (e.g. Antigravity) return non-standard finish_reason values like 'other' instead of the OpenAI-standard 'tool_calls' when the model invokes tools. This causes downstream consumers (e.g. OpenClaw) to fail to execute tool calls, breaking agentic sub-agent workflows. Changes: - nonStreamingHandler: post-translation guard that normalizes finish_reason to 'tool_calls' when message.tool_calls is present - sseToJsonHandler: accumulate tool_calls from streaming deltas in parseSSEToOpenAIResponse; extract function_call items from Responses API output in handleForcedSSEToJson - openai-responses translator: use toolCallIndex to choose between 'tool_calls' and 'stop' in flush and response.completed events Tested: 7 scenarios (non-stream text, single/multiple tool calls, stream text/tool calls, multi-turn tool conversation, tools present but unused)
This commit is contained in:
@@ -364,6 +364,7 @@ export function openaiResponsesToOpenAIResponse(chunk, state) {
|
||||
// Flush: send final chunk with finish_reason
|
||||
if (!state.finishReasonSent && state.started) {
|
||||
state.finishReasonSent = true;
|
||||
const hasToolCalls = state.toolCallIndex > 0;
|
||||
return {
|
||||
id: state.chatId || `chatcmpl-${Date.now()}`,
|
||||
object: "chat.completion.chunk",
|
||||
@@ -372,7 +373,7 @@ export function openaiResponsesToOpenAIResponse(chunk, state) {
|
||||
choices: [{
|
||||
index: 0,
|
||||
delta: {},
|
||||
finish_reason: "stop"
|
||||
finish_reason: hasToolCalls ? "tool_calls" : "stop"
|
||||
}]
|
||||
};
|
||||
}
|
||||
@@ -505,7 +506,9 @@ export function openaiResponsesToOpenAIResponse(chunk, state) {
|
||||
|
||||
if (!state.finishReasonSent) {
|
||||
state.finishReasonSent = true;
|
||||
state.finishReason = "stop"; // Mark for usage injection in stream.js
|
||||
const hasToolCalls = state.toolCallIndex > 0;
|
||||
const resolvedFinishReason = hasToolCalls ? "tool_calls" : "stop";
|
||||
state.finishReason = resolvedFinishReason; // Mark for usage injection in stream.js
|
||||
|
||||
const finalChunk = {
|
||||
id: state.chatId,
|
||||
@@ -515,7 +518,7 @@ export function openaiResponsesToOpenAIResponse(chunk, state) {
|
||||
choices: [{
|
||||
index: 0,
|
||||
delta: {},
|
||||
finish_reason: "stop"
|
||||
finish_reason: resolvedFinishReason
|
||||
}]
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user