refactor(open-sse): dedup fallback tool_call id helper (B3)
Add fallbackToolCallId() and apply to kiro/ollama/openai-responses response translators (identical id shape). Leave commandcode (different order) and request-side gemini/antigravity (random suffix) untouched. Golden + gate clean. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,6 +3,11 @@
|
||||
// Anthropic tool_use.id must match: ^[a-zA-Z0-9_-]+$
|
||||
const TOOL_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
||||
|
||||
// Fallback streaming tool_call id when provider omits one (index optional)
|
||||
export function fallbackToolCallId(index) {
|
||||
return index === undefined ? `call_${Date.now()}` : `call_${index}_${Date.now()}`;
|
||||
}
|
||||
|
||||
// Generate deterministic tool call ID from position + tool name (cache-friendly)
|
||||
export function generateToolCallId(msgIndex = 0, tcIndex = 0, toolName = "") {
|
||||
const name = toolName ? `_${toolName.replace(/[^a-zA-Z0-9_-]/g, "")}` : "";
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import { register } from "../index.js";
|
||||
import { FORMATS } from "../formats.js";
|
||||
import { buildChunk } from "../helpers/chunkBuilder.js";
|
||||
import { fallbackToolCallId } from "../helpers/toolCallHelper.js";
|
||||
|
||||
// Build chunk meta for current kiro state
|
||||
function chunkMeta(state) {
|
||||
@@ -105,7 +106,7 @@ export function convertKiroToOpenAI(chunk, state) {
|
||||
// Handle tool use events
|
||||
if (eventType === "toolUseEvent" || data.toolUseEvent) {
|
||||
const toolUse = data.toolUseEvent || data;
|
||||
const toolCallId = toolUse.toolUseId || `call_${Date.now()}`;
|
||||
const toolCallId = toolUse.toolUseId || fallbackToolCallId();
|
||||
const toolName = toolUse.name || "";
|
||||
const toolInput = toolUse.input || {};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { register } from "../index.js";
|
||||
import { FORMATS } from "../formats.js";
|
||||
import { buildChunk } from "../helpers/chunkBuilder.js";
|
||||
import { fallbackToolCallId } from "../helpers/toolCallHelper.js";
|
||||
|
||||
/**
|
||||
* Convert Ollama NDJSON response to OpenAI SSE format
|
||||
@@ -91,7 +92,7 @@ function extractUsage(ollamaChunk) {
|
||||
function convertToolCalls(toolCalls) {
|
||||
return toolCalls.map((tc, i) => ({
|
||||
index: tc.function?.index ?? i,
|
||||
id: tc.id || `call_${i}_${Date.now()}`,
|
||||
id: tc.id || fallbackToolCallId(i),
|
||||
type: "function",
|
||||
function: {
|
||||
name: tc.function?.name || "",
|
||||
|
||||
@@ -6,6 +6,7 @@ import { register } from "../index.js";
|
||||
import { FORMATS } from "../formats.js";
|
||||
import { buildChunk } from "../helpers/chunkBuilder.js";
|
||||
import { buildUsage } from "../helpers/usageHelper.js";
|
||||
import { fallbackToolCallId } from "../helpers/toolCallHelper.js";
|
||||
|
||||
/**
|
||||
* Translate OpenAI chunk to Responses API events
|
||||
@@ -424,7 +425,7 @@ export function openaiResponsesToOpenAIResponse(chunk, state) {
|
||||
// Function call started (standard function_call or custom_tool_call)
|
||||
if (eventType === "response.output_item.added" && (data.item?.type === "function_call" || data.item?.type === "custom_tool_call")) {
|
||||
const item = data.item;
|
||||
state.currentToolCallId = item.call_id || `call_${Date.now()}`;
|
||||
state.currentToolCallId = item.call_id || fallbackToolCallId();
|
||||
|
||||
return buildChunk(
|
||||
{ id: state.chatId, created: state.created, model: state.model || "unknown" },
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user