mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 10:02:23 +00:00
fix(ai): normalize pipe-separated tool call IDs for cross-provider handoff
- Handle pipe-separated IDs from OpenAI Responses API in openai-completions provider - Strip trailing underscores after truncation in openai-responses-shared (OpenAI Codex rejects them) - Add regression tests for tool call ID normalization fixes #1022
This commit is contained in:
parent
4f004adefa
commit
605f6f494b
4 changed files with 308 additions and 2 deletions
|
|
@ -497,6 +497,17 @@ export function convertMessages(
|
|||
|
||||
const normalizeToolCallId = (id: string): string => {
|
||||
if (compat.requiresMistralToolIds) return normalizeMistralToolId(id);
|
||||
|
||||
// Handle pipe-separated IDs from OpenAI Responses API
|
||||
// Format: {call_id}|{id} where {id} can be 400+ chars with special chars (+, /, =)
|
||||
// These come from providers like github-copilot, openai-codex, opencode
|
||||
// Extract just the call_id part and normalize it
|
||||
if (id.includes("|")) {
|
||||
const [callId] = id.split("|");
|
||||
// Sanitize to allowed chars and truncate to 40 chars (OpenAI limit)
|
||||
return callId.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 40);
|
||||
}
|
||||
|
||||
if (model.provider === "openai") return id.length > 40 ? id.slice(0, 40) : id;
|
||||
// Copilot Claude models route to Claude backend which requires Anthropic ID format
|
||||
if (model.provider === "github-copilot" && model.id.toLowerCase().includes("claude")) {
|
||||
|
|
|
|||
|
|
@ -86,8 +86,11 @@ export function convertResponsesMessages<TApi extends Api>(
|
|||
if (!sanitizedItemId.startsWith("fc")) {
|
||||
sanitizedItemId = `fc_${sanitizedItemId}`;
|
||||
}
|
||||
const normalizedCallId = sanitizedCallId.length > 64 ? sanitizedCallId.slice(0, 64) : sanitizedCallId;
|
||||
const normalizedItemId = sanitizedItemId.length > 64 ? sanitizedItemId.slice(0, 64) : sanitizedItemId;
|
||||
// Truncate to 64 chars and strip trailing underscores (OpenAI Codex rejects them)
|
||||
let normalizedCallId = sanitizedCallId.length > 64 ? sanitizedCallId.slice(0, 64) : sanitizedCallId;
|
||||
let normalizedItemId = sanitizedItemId.length > 64 ? sanitizedItemId.slice(0, 64) : sanitizedItemId;
|
||||
normalizedCallId = normalizedCallId.replace(/_+$/, "");
|
||||
normalizedItemId = normalizedItemId.replace(/_+$/, "");
|
||||
return `${normalizedCallId}|${normalizedItemId}`;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue