diff --git a/src/api/providers/base-openai-compatible-provider.ts b/src/api/providers/base-openai-compatible-provider.ts index 5aee7267b3..5adf56b001 100644 --- a/src/api/providers/base-openai-compatible-provider.ts +++ b/src/api/providers/base-openai-compatible-provider.ts @@ -90,7 +90,13 @@ export abstract class BaseOpenAiCompatibleProvider model, max_tokens, temperature, - messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + // Enable mergeToolResultText to merge environment_details and other text content + // after tool_results into the last tool message. This prevents reasoning/thinking + // models from dropping reasoning_content when they see a user message after tool results. + messages: [ + { role: "system", content: systemPrompt }, + ...convertToOpenAiMessages(messages, { mergeToolResultText: true }), + ], stream: true, stream_options: { include_usage: true }, ...(metadata?.tools && { tools: this.convertToolsForOpenAI(metadata.tools) }), diff --git a/src/api/providers/cerebras.ts b/src/api/providers/cerebras.ts index 99e7c4cc3d..d0ff747688 100644 --- a/src/api/providers/cerebras.ts +++ b/src/api/providers/cerebras.ts @@ -106,7 +106,7 @@ export class CerebrasHandler extends BaseProvider implements SingleCompletionHan supportsNativeTools && metadata?.tools && metadata.tools.length > 0 && metadata?.toolProtocol !== "xml" // Convert Anthropic messages to OpenAI format (Cerebras is OpenAI-compatible) - const openaiMessages = convertToOpenAiMessages(messages) + const openaiMessages = convertToOpenAiMessages(messages, { mergeToolResultText: true }) // Prepare request body following Cerebras API specification exactly const requestBody: Record = { diff --git a/src/api/providers/chutes.ts b/src/api/providers/chutes.ts index 78ac7e591f..ac2281190e 100644 --- a/src/api/providers/chutes.ts +++ b/src/api/providers/chutes.ts @@ -44,7 +44,10 @@ export class ChutesHandler extends RouterProvider implements SingleCompletionHan const params: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = { model, max_tokens, - messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + messages: [ + { role: "system", content: systemPrompt }, + ...convertToOpenAiMessages(messages, { mergeToolResultText: true }), + ], stream: true, stream_options: { include_usage: true }, ...(metadata?.tools && { tools: metadata.tools }), diff --git a/src/api/providers/deepinfra.ts b/src/api/providers/deepinfra.ts index 4dfad2689a..a221927c2b 100644 --- a/src/api/providers/deepinfra.ts +++ b/src/api/providers/deepinfra.ts @@ -72,7 +72,10 @@ export class DeepInfraHandler extends RouterProvider implements SingleCompletion const requestOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = { model: modelId, - messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + messages: [ + { role: "system", content: systemPrompt }, + ...convertToOpenAiMessages(messages, { mergeToolResultText: true }), + ], stream: true, stream_options: { include_usage: true }, reasoning_effort, diff --git a/src/api/providers/featherless.ts b/src/api/providers/featherless.ts index 3dcd0821b8..64df12bc97 100644 --- a/src/api/providers/featherless.ts +++ b/src/api/providers/featherless.ts @@ -44,7 +44,10 @@ export class FeatherlessHandler extends BaseOpenAiCompatibleProvider