mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 07:03:25 +00:00
fix(ai): handle same-provider different-model handoff in OpenAI Responses API
When switching between OpenAI models (e.g., gpt-5-mini to gpt-5.2-codex), function_call IDs with fc_ prefix trigger pairing validation errors because OpenAI tracks which fc_xxx IDs were paired with rs_xxx reasoning items. The fix omits the id field for function_calls from different models, which avoids the pairing validation while keeping call_id for matching with function_call_output. Fixes #886
This commit is contained in:
parent
de58391085
commit
d327b9c768
3 changed files with 279 additions and 142 deletions
|
|
@ -488,6 +488,15 @@ function convertMessages(model: Model<"openai-responses">, context: Context): Re
|
|||
}
|
||||
} else if (msg.role === "assistant") {
|
||||
const output: ResponseInput = [];
|
||||
const assistantMsg = msg as AssistantMessage;
|
||||
|
||||
// Check if this message is from a different model (same provider, different model ID).
|
||||
// For such messages, tool call IDs with fc_ prefix need to be stripped to avoid
|
||||
// OpenAI's reasoning/function_call pairing validation errors.
|
||||
const isDifferentModel =
|
||||
assistantMsg.model !== model.id &&
|
||||
assistantMsg.provider === model.provider &&
|
||||
assistantMsg.api === model.api;
|
||||
|
||||
for (const block of msg.content) {
|
||||
if (block.type === "thinking") {
|
||||
|
|
@ -513,10 +522,20 @@ function convertMessages(model: Model<"openai-responses">, context: Context): Re
|
|||
} satisfies ResponseOutputMessage);
|
||||
} else if (block.type === "toolCall") {
|
||||
const toolCall = block as ToolCall;
|
||||
const callId = toolCall.id.split("|")[0];
|
||||
let itemId: string | undefined = toolCall.id.split("|")[1];
|
||||
|
||||
// For different-model messages, set id to undefined to avoid pairing validation.
|
||||
// OpenAI tracks which fc_xxx IDs were paired with rs_xxx reasoning items.
|
||||
// By omitting the id, we avoid triggering that validation (like cross-provider does).
|
||||
if (isDifferentModel && itemId?.startsWith("fc_")) {
|
||||
itemId = undefined;
|
||||
}
|
||||
|
||||
output.push({
|
||||
type: "function_call",
|
||||
id: toolCall.id.split("|")[1],
|
||||
call_id: toolCall.id.split("|")[0],
|
||||
id: itemId,
|
||||
call_id: callId,
|
||||
name: toolCall.name,
|
||||
arguments: JSON.stringify(toolCall.arguments),
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue