@ai-sdk-tool/proxy 0.0.0 → 0.0.1-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +13 -0
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +16 -16
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2025 Woonggi Min (https://github.com/minpeter)
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/dist/index.cjs
CHANGED
|
@@ -293,7 +293,7 @@ function mapOpenAIToolChoice(choice) {
|
|
|
293
293
|
}
|
|
294
294
|
function convertAISDKToolCallsToOpenAI(toolCalls) {
|
|
295
295
|
return toolCalls.map((call) => ({
|
|
296
|
-
id: `call_${Date.now()}_${Math.random().toString(36).
|
|
296
|
+
id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`,
|
|
297
297
|
type: "function",
|
|
298
298
|
function: {
|
|
299
299
|
name: call.toolName,
|
|
@@ -304,7 +304,7 @@ function convertAISDKToolCallsToOpenAI(toolCalls) {
|
|
|
304
304
|
|
|
305
305
|
// src/response-utils.ts
|
|
306
306
|
function generateResponseId() {
|
|
307
|
-
return `chatcmpl-${Date.now()}-${Math.random().toString(36).
|
|
307
|
+
return `chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
308
308
|
}
|
|
309
309
|
function getCurrentTimestamp() {
|
|
310
310
|
return Math.floor(Date.now() / 1e3);
|
|
@@ -339,7 +339,7 @@ function convertAISDKResultToOpenAI(aisdkResult, model, stream = false) {
|
|
|
339
339
|
};
|
|
340
340
|
const openAIToolCalls = (_a = aisdkResult.toolCalls) == null ? void 0 : _a.map(
|
|
341
341
|
(call) => ({
|
|
342
|
-
id: `call_${Date.now()}_${Math.random().toString(36).
|
|
342
|
+
id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`,
|
|
343
343
|
type: "function",
|
|
344
344
|
function: {
|
|
345
345
|
name: call.toolName,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/openai-request-converter.ts","../src/response-utils.ts","../src/response-converter.ts","../src/server.ts"],"sourcesContent":["// biome-ignore lint/performance/noBarrelFile: Package entrypoint - must re-export for public API\nexport {\n convertAISDKToolCallsToOpenAI,\n convertOpenAIRequestToAISDK,\n} from \"./openai-request-converter.js\";\nexport {\n convertAISDKResultToOpenAI,\n convertAISDKStreamChunkToOpenAI,\n createOpenAIStreamConverter,\n createSSEResponse,\n} from \"./response-converter.js\";\nexport { generateResponseId, getCurrentTimestamp } from \"./response-utils.js\";\nexport { OpenAIProxyServer } from \"./server.js\";\nexport type {\n AISDKTool,\n Logger,\n OpenAIChatRequest,\n OpenAIChatResponse,\n OpenAIChoice,\n OpenAIMessage,\n OpenAITool,\n OpenAIToolCall,\n OpenAIUsage,\n ProxyConfig,\n StreamChunk,\n} from \"./types.js\";\n","import type {\n ModelMessage,\n ToolContent,\n ToolResultOutput,\n} from \"@ai-sdk/provider-utils\";\nimport { z } from \"zod\";\nimport type {\n OpenAIChatRequest,\n OpenAICompleteToolCall,\n OpenAIMessage,\n ProxyConfig,\n} from \"./types.js\";\n\n// Type definitions for OpenAI tool parameters\ninterface OpenAIToolProperty {\n type: string;\n description?: string;\n enum?: string[];\n}\n\ninterface OpenAIToolParameters {\n type: string;\n properties?: Record<string, OpenAIToolProperty>;\n required?: string[];\n}\n\n// Type for AI SDK tool definition\ninterface AISDKTool {\n description: string;\n inputSchema: z.ZodTypeAny;\n}\n\n// Type for tool call object\ninterface ToolCall {\n toolName: string;\n args: unknown;\n}\n\n/**\n * Create Zod schema for OpenAI tool property\n */\nfunction createZodSchema(prop: OpenAIToolProperty): z.ZodTypeAny {\n if (prop.type === \"string\") {\n return prop.enum ? z.enum(prop.enum as [string, ...string[]]) : z.string();\n }\n if (prop.type === \"number\") {\n return z.number();\n }\n if (prop.type === \"boolean\") {\n return z.boolean();\n }\n if (prop.type === \"array\") {\n return z.array(z.any());\n }\n if (prop.type === \"object\") {\n return z.object({});\n }\n return z.any();\n}\n\n/**\n * Convert OpenAI tool schema to Zod schema\n */\nfunction convertOpenAIToolToZod(\n parameters: Record<string, unknown> | undefined\n): z.ZodObject<Record<string, z.ZodTypeAny>> {\n if (!parameters) {\n return z.object({});\n }\n\n const params = parameters as unknown as OpenAIToolParameters;\n if (!params.properties) {\n return z.object({});\n }\n\n const schemaShape: Record<string, z.ZodTypeAny> = {};\n for (const [key, prop] of Object.entries(params.properties)) {\n schemaShape[key] = createZodSchema(prop);\n }\n\n return z.object(schemaShape);\n}\n\n/**\n * Convert OpenAI tools to AI SDK format\n */\nfunction convertOpenAITools(\n openaiTools:\n | Array<{\n function: {\n name: string;\n description?: string;\n parameters: Record<string, unknown>;\n };\n }>\n | undefined\n): Record<string, AISDKTool> {\n const aisdkTools: Record<string, AISDKTool> = {};\n\n if (!openaiTools) {\n return aisdkTools;\n }\n\n for (const openaiTool of openaiTools) {\n const toolName = openaiTool.function.name;\n aisdkTools[toolName] = {\n description: openaiTool.function.description || \"\",\n inputSchema: convertOpenAIToolToZod(openaiTool.function.parameters),\n };\n }\n\n return aisdkTools;\n}\n\n/**\n * Convert stop parameter to stop sequences\n */\nfunction convertStopToSequences(\n stop: string | string[] | undefined\n): string[] | undefined {\n if (!stop) {\n return;\n }\n return Array.isArray(stop) ? stop : [stop];\n}\n\ninterface AITextPart {\n type: \"text\";\n text: string;\n}\ninterface AIToolCallPart {\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n input: unknown;\n}\ntype TextToolOutput = Extract<ToolResultOutput, { type: \"text\" }>;\ntype JsonToolOutput = Extract<ToolResultOutput, { type: \"json\" }>;\n\n/**\n * Convert OpenAI chat completion request to AI SDK format\n */\nexport function normalizeMessageContent(\n content: OpenAIMessage[\"content\"]\n): AITextPart[] {\n if (typeof content === \"string\") {\n return content ? [{ type: \"text\" as const, text: content }] : [];\n }\n\n if (Array.isArray(content)) {\n const parts = content as Array<string | { text?: unknown }>;\n return parts\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n }\n if (part && typeof part === \"object\" && \"text\" in part) {\n const textValue = part.text;\n if (typeof textValue === \"string\") {\n return textValue;\n }\n if (textValue !== undefined) {\n return JSON.stringify(textValue);\n }\n }\n return JSON.stringify(part);\n })\n .filter((text): text is string => Boolean(text))\n .map((text) => ({ type: \"text\" as const, text }));\n }\n\n if (content === null || content === undefined) {\n return [];\n }\n\n if (typeof content === \"object\") {\n return [{ type: \"text\" as const, text: JSON.stringify(content) }];\n }\n\n return [{ type: \"text\" as const, text: String(content) }];\n}\n\nfunction buildToolCallParts(\n toolCalls: OpenAICompleteToolCall[]\n): AIToolCallPart[] {\n return toolCalls.map((toolCall) => {\n let parsedArgs: unknown = toolCall.function.arguments;\n if (typeof toolCall.function.arguments === \"string\") {\n try {\n parsedArgs = JSON.parse(toolCall.function.arguments || \"{}\");\n } catch {\n parsedArgs = toolCall.function.arguments;\n }\n }\n\n return {\n type: \"tool-call\" as const,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input: parsedArgs,\n } satisfies AIToolCallPart;\n });\n}\n\nfunction buildAssistantContent(\n message: OpenAIMessage & { role: \"assistant\" }\n): Array<AITextPart | AIToolCallPart> | string {\n const textParts = normalizeMessageContent(message.content);\n const toolCallParts = message.tool_calls?.length\n ? buildToolCallParts(message.tool_calls)\n : [];\n\n if (toolCallParts.length === 0) {\n if (textParts.length === 0) {\n return \"\";\n }\n if (textParts.length === 1) {\n return textParts[0].text;\n }\n return textParts;\n }\n\n return [...textParts, ...toolCallParts];\n}\n\nfunction isJsonValue(value: unknown): value is JsonToolOutput[\"value\"] {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every(isJsonValue);\n }\n\n if (typeof value === \"object\") {\n return Object.values(value as Record<string, unknown>).every(isJsonValue);\n }\n\n return false;\n}\n\nfunction buildToolOutput(rawValue: string): ToolResultOutput {\n if (!rawValue) {\n return { type: \"text\", value: \"\" } satisfies TextToolOutput;\n }\n\n try {\n const parsed = JSON.parse(rawValue);\n if (isJsonValue(parsed)) {\n return { type: \"json\", value: parsed } satisfies JsonToolOutput;\n }\n } catch {\n // Fall through to text output below\n }\n\n return { type: \"text\", value: rawValue } satisfies TextToolOutput;\n}\n\nfunction buildToolContent(\n message: OpenAIMessage & { role: \"tool\" },\n toolNameLookup: Map<string, string>\n): ToolContent {\n const textParts = normalizeMessageContent(message.content);\n const combined = textParts.map((part) => part.text).join(\"\\n\");\n const toolCallId = message.tool_call_id ?? \"\";\n const toolName = toolCallId\n ? (toolNameLookup.get(toolCallId) ?? toolCallId)\n : \"\";\n\n return [\n {\n type: \"tool-result\",\n toolCallId,\n toolName,\n output: buildToolOutput(combined),\n },\n ];\n}\n\nfunction convertMessageToModelMessage(\n message: OpenAIMessage,\n toolNameLookup: Map<string, string>\n): ModelMessage {\n if (message.role === \"assistant\") {\n if (message.tool_calls?.length) {\n for (const toolCall of message.tool_calls) {\n toolNameLookup.set(toolCall.id, toolCall.function.name);\n }\n }\n\n return {\n role: \"assistant\",\n content: buildAssistantContent(\n message as OpenAIMessage & { role: \"assistant\" }\n ),\n };\n }\n\n if (message.role === \"tool\") {\n return {\n role: \"tool\",\n content: buildToolContent(\n message as OpenAIMessage & { role: \"tool\" },\n toolNameLookup\n ),\n };\n }\n\n if (message.role === \"system\") {\n const text = normalizeMessageContent(message.content)\n .map((part) => part.text)\n .join(\"\\n\");\n return {\n role: \"system\",\n content: text,\n };\n }\n\n const userParts = normalizeMessageContent(message.content);\n if (userParts.length === 0) {\n return {\n role: \"user\",\n content: \"\",\n };\n }\n\n if (userParts.length === 1) {\n return {\n role: \"user\",\n content: userParts[0].text,\n };\n }\n\n return {\n role: \"user\",\n content: userParts,\n };\n}\n\nexport function convertOpenAIRequestToAISDK(\n openaiRequest: OpenAIChatRequest,\n proxyConfig?: Pick<ProxyConfig, \"parserDebug\">\n) {\n const {\n messages,\n tools: openaiTools,\n temperature,\n max_tokens,\n stop,\n tool_choice,\n } = openaiRequest;\n\n const toolNameLookup = new Map<string, string>();\n\n const aiMessages: ModelMessage[] = messages.map((message) =>\n convertMessageToModelMessage(message, toolNameLookup)\n );\n\n // Convert OpenAI tools to AI SDK format dynamically\n const aisdkTools = convertOpenAITools(openaiTools);\n\n const providerOptions = proxyConfig?.parserDebug\n ? {\n toolCallMiddleware: {\n debugLevel: proxyConfig.parserDebug.level,\n logErrors: proxyConfig.parserDebug.logErrors,\n captureSummary: proxyConfig.parserDebug.captureSummary,\n },\n }\n : undefined;\n\n return {\n messages: aiMessages,\n tools: aisdkTools,\n temperature,\n maxOutputTokens: max_tokens,\n stopSequences: convertStopToSequences(stop),\n toolChoice: mapOpenAIToolChoice(tool_choice),\n ...(providerOptions ? { providerOptions } : {}),\n };\n}\n\n// Map OpenAI tool_choice to AI SDK toolChoice\nexport function mapOpenAIToolChoice(\n choice: OpenAIChatRequest[\"tool_choice\"]\n): \"auto\" | \"none\" | { type: \"tool\"; toolName: string } | undefined {\n if (!choice) {\n return;\n }\n if (choice === \"auto\" || choice === \"none\") {\n return choice;\n }\n if (typeof choice === \"object\" && choice.type === \"function\") {\n return { type: \"tool\", toolName: choice.function.name };\n }\n return;\n}\n\n/**\n * Convert AI SDK tool calls to OpenAI format\n */\nexport function convertAISDKToolCallsToOpenAI(toolCalls: ToolCall[]): Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n}> {\n return toolCalls.map((call) => ({\n id: `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n type: \"function\" as const,\n function: {\n name: call.toolName,\n arguments: JSON.stringify(call.args),\n },\n }));\n}\n","export function generateResponseId(): string {\n return `chatcmpl-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\nexport function getCurrentTimestamp(): number {\n return Math.floor(Date.now() / 1000);\n}\n","import { generateResponseId, getCurrentTimestamp } from \"./response-utils.js\";\nimport type {\n OpenAIChatResponse,\n OpenAIChoice,\n OpenAIStreamingToolCall,\n OpenAIUsage,\n StreamChunk,\n} from \"./types.js\";\n\n/**\n * Convert AI SDK result to OpenAI chat completion response\n */\nexport function convertAISDKResultToOpenAI(\n // biome-ignore lint/suspicious/noExplicitAny: AI sdk integration boundary\n aisdkResult: any,\n model: string,\n stream = false\n): OpenAIChatResponse {\n const choices: OpenAIChoice[] = [];\n\n // Handle text content\n if (aisdkResult.text) {\n const choice: OpenAIChoice = {\n index: 0,\n finish_reason: aisdkResult.finishReason || \"stop\",\n };\n\n if (stream) {\n choice.delta = {\n role: \"assistant\",\n content: aisdkResult.text,\n };\n } else {\n choice.message = {\n role: \"assistant\",\n content: aisdkResult.text,\n };\n }\n choices.push(choice);\n }\n\n // Handle tool calls\n if (aisdkResult.toolCalls && aisdkResult.toolCalls.length > 0) {\n const choice: OpenAIChoice = {\n index: 0,\n finish_reason: \"tool_calls\",\n };\n\n const openAIToolCalls = aisdkResult.toolCalls?.map(\n (\n // biome-ignore lint/suspicious/noExplicitAny: AI SDK integration boundary\n call: any\n ) => ({\n id: `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n type: \"function\" as const,\n function: {\n name: call.toolName,\n arguments: JSON.stringify(call.args),\n },\n })\n );\n\n if (stream) {\n choice.delta = {\n role: \"assistant\",\n tool_calls: openAIToolCalls,\n };\n } else {\n choice.message = {\n role: \"assistant\",\n content: null,\n tool_calls: openAIToolCalls,\n };\n }\n\n choices.push(choice);\n }\n\n const response: OpenAIChatResponse = {\n id: generateResponseId(),\n object: stream ? \"chat.completion.chunk\" : \"chat.completion\",\n created: getCurrentTimestamp(),\n model,\n choices,\n };\n\n // Add usage if available\n if (aisdkResult.usage) {\n response.usage = {\n prompt_tokens: aisdkResult.usage.promptTokens || 0,\n completion_tokens: aisdkResult.usage.completionTokens || 0,\n total_tokens: aisdkResult.usage.totalTokens || 0,\n } as OpenAIUsage;\n }\n\n return response;\n}\n\n/**\n * Convert AI SDK stream chunk to OpenAI SSE format\n */\n\n// Type definitions for better type safety\ninterface ToolCallDelta {\n index?: number;\n id?: string;\n type?: \"function\";\n function?: {\n name?: string;\n arguments?: string;\n };\n}\n\ninterface AIStreamChunk {\n type: string;\n id?: string;\n text?: string;\n toolCallId?: string;\n toolName?: string;\n args?: string;\n input?: Record<string, unknown>;\n finishReason?: string;\n [key: string]: unknown;\n}\n\ntype ChunkHandler = (chunk: AIStreamChunk, model: string) => StreamChunk[];\n\n// Helper function to create finish response\nfunction createFinishResponse(\n model: string,\n finishReason: string,\n responseId: string\n): OpenAIChatResponse {\n // Ensure finish reason matches OpenAI's allowed types\n let validFinishReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\";\n\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n validFinishReason = \"tool_calls\";\n } else if (finishReason === \"stop\") {\n validFinishReason = \"stop\";\n } else if (finishReason === \"length\") {\n validFinishReason = \"length\";\n } else if (finishReason === \"content_filter\") {\n validFinishReason = \"content_filter\";\n } else {\n validFinishReason = \"stop\"; // fallback to \"stop\" for unknown reasons\n }\n\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta: {},\n finish_reason: validFinishReason,\n },\n ],\n };\n}\n\n// Helper function to create content response\nfunction createContentResponse(\n model: string,\n content: string,\n responseId: string,\n isReasoning = false\n): OpenAIChatResponse {\n const delta: Record<string, unknown> = { role: \"assistant\" };\n\n if (isReasoning) {\n delta.reasoning_content = content;\n } else {\n delta.content = content;\n }\n\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta,\n },\n ],\n };\n}\n\n// Helper function to create tool call response\nfunction createToolCallResponse(\n model: string,\n toolCall: ToolCallDelta,\n responseId: string,\n includeRole = false\n): OpenAIChatResponse {\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta: {\n ...(includeRole ? { role: \"assistant\" as const } : {}),\n tool_calls: [\n {\n index: toolCall.index || 0,\n type: \"function\" as const,\n function: {\n name: toolCall.function?.name || \"\",\n arguments: toolCall.function?.arguments || \"\",\n },\n },\n ],\n },\n },\n ],\n };\n}\n\n// (legacy stateless handler removed)\n\nexport function createOpenAIStreamConverter(\n model: string,\n options?: {\n logChunks?: boolean;\n }\n) {\n let streamHasToolCalls = false;\n let streamFinishSent = false;\n let streamResponseId = generateResponseId();\n\n const logChunk =\n options?.logChunks === false\n ? undefined\n : (chunk: unknown) => {\n const logType =\n process.env.USE_MIDDLEWARE === \"true\" ? \"middleware\" : \"native\";\n console.log(\n `🔍 AI SDK Chunk [${logType}]:`,\n JSON.stringify(chunk, null, 2)\n );\n };\n\n const handlers: Record<string, ChunkHandler> = {\n start: () => [],\n \"reasoning-delta\": (chunk) => {\n if (!chunk.text) {\n return [];\n }\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, chunk.text, streamResponseId, true)\n ),\n },\n ];\n },\n \"text-delta\": (chunk) => {\n if (!chunk.text) {\n return [];\n }\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, chunk.text, streamResponseId, false)\n ),\n },\n ];\n },\n \"tool-call\": (chunk) => {\n const toolCallId = chunk.toolCallId || `call_${generateResponseId()}`;\n const toolName = chunk.toolName || \"\";\n const argsString =\n typeof chunk.input === \"string\"\n ? chunk.input\n : JSON.stringify(chunk.input ?? {});\n const toolCallDelta: OpenAIStreamingToolCall = {\n index: 0,\n id: toolCallId,\n type: \"function\",\n function: { name: toolName, arguments: argsString },\n };\n const response = createToolCallResponse(\n model,\n toolCallDelta,\n streamResponseId,\n true\n );\n return [{ data: JSON.stringify(response) }];\n },\n \"reasoning-end\": () => [],\n \"text-end\": () => [],\n \"finish-step\": (chunk) => {\n if (streamFinishSent) {\n return [];\n }\n const hadToolCalls = streamHasToolCalls;\n let finishReason = chunk.finishReason || \"stop\";\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n finishReason = \"tool_calls\";\n }\n const resolvedReason = hadToolCalls ? \"tool_calls\" : finishReason;\n streamFinishSent = true;\n streamHasToolCalls = false;\n return [\n {\n data: JSON.stringify(\n createFinishResponse(model, resolvedReason, streamResponseId)\n ),\n },\n ];\n },\n \"tool-call-delta\": (chunk) => {\n const toolCall = {\n index: chunk.toolCallId ? Number(chunk.toolCallId) : 0,\n type: \"function\" as const,\n function: {\n name: chunk.toolName || \"\",\n arguments: chunk.args || \"\",\n },\n };\n return [\n {\n data: JSON.stringify(\n createToolCallResponse(model, toolCall, streamResponseId)\n ),\n },\n ];\n },\n \"tool-result\": (chunk) => {\n const resultText = `\\n[Tool: ${chunk.toolName} returned ${JSON.stringify(chunk.output)}]\\n`;\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, resultText, streamResponseId, false)\n ),\n },\n ];\n },\n finish: (chunk) => {\n if (streamFinishSent) {\n return [];\n }\n const hadToolCalls = streamHasToolCalls;\n let finishReason = chunk.finishReason || \"stop\";\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n finishReason = \"tool_calls\";\n }\n const resolvedReason = hadToolCalls ? \"tool_calls\" : finishReason;\n streamFinishSent = true;\n streamHasToolCalls = false;\n return [\n {\n data: JSON.stringify(\n createFinishResponse(model, resolvedReason, streamResponseId)\n ),\n },\n ];\n },\n };\n\n return (\n // biome-ignore lint/suspicious/noExplicitAny: ai sdk boundary\n chunk: any\n ): StreamChunk[] => {\n const out: StreamChunk[] = [];\n\n logChunk?.(chunk);\n\n if (chunk.type === \"start\") {\n streamHasToolCalls = false;\n streamFinishSent = false;\n streamResponseId = chunk.id ?? generateResponseId();\n }\n\n const handler = handlers[chunk.type];\n if (handler) {\n const result = handler(chunk as AIStreamChunk, model);\n if (chunk.type === \"tool-call\" || chunk.type === \"tool-call-delta\") {\n streamHasToolCalls = true;\n }\n out.push(...result);\n } else {\n console.warn(`⚠️ Unknown AI SDK chunk type: ${chunk.type}`, chunk);\n }\n\n if (chunk.type === \"finish-step\" || chunk.type === \"finish\") {\n streamHasToolCalls = false;\n }\n\n return out.filter((resultChunk) => {\n try {\n const parsed = JSON.parse(resultChunk.data);\n const delta = parsed.choices?.[0]?.delta;\n return (\n delta &&\n (delta.role ||\n delta.content ||\n (delta as NonNullable<OpenAIChoice[\"delta\"]>).reasoning_content ||\n (delta.tool_calls && delta.tool_calls.length > 0) ||\n parsed.choices?.[0]?.finish_reason)\n );\n } catch {\n return true;\n }\n });\n };\n}\n\nexport function convertAISDKStreamChunkToOpenAI(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n chunk: any,\n model: string\n): StreamChunk[] {\n const convert = createOpenAIStreamConverter(model);\n return convert(chunk);\n}\n\n/**\n * Create SSE formatted response\n */\nexport function createSSEResponse(chunks: StreamChunk[]): string {\n return chunks.map((chunk) => `data: ${chunk.data}\\n\\n`).join(\"\");\n}\n","import { zodSchema } from \"@ai-sdk/provider-utils\";\nimport cors from \"@fastify/cors\";\nimport { generateText, streamText } from \"ai\";\nimport Fastify, {\n type FastifyInstance,\n type FastifyReply,\n type FastifyRequest,\n} from \"fastify\";\nimport { toJSONSchema, type ZodTypeAny } from \"zod\";\nimport { convertOpenAIRequestToAISDK } from \"./openai-request-converter.js\";\nimport {\n convertAISDKResultToOpenAI,\n createOpenAIStreamConverter,\n} from \"./response-converter.js\";\nimport type {\n AISDKTool,\n Logger,\n OpenAIChatRequest,\n ProxyConfig,\n} from \"./types.js\";\n\ntype ConvertedParams = ReturnType<typeof convertOpenAIRequestToAISDK>;\n\nfunction serializeZodSchema(schema: ZodTypeAny | undefined): unknown {\n if (!schema) {\n return null;\n }\n\n // Use Zod v4's built-in JSON Schema conversion\n const jsonSchema = toJSONSchema(schema, {\n unrepresentable: \"any\",\n });\n\n // Remove $schema field for cleaner output\n if (typeof jsonSchema === \"object\" && jsonSchema !== null) {\n const { $schema, ...rest } = jsonSchema as Record<string, unknown>;\n return rest;\n }\n\n return jsonSchema;\n}\n\nfunction serializeMessages(messages: OpenAIChatRequest[\"messages\"]) {\n return messages.map((message, index) => ({\n index,\n role: message.role,\n content: message.content,\n toolCalls: message.tool_calls,\n }));\n}\n\nfunction logIncomingRequest(\n openaiRequest: OpenAIChatRequest,\n enabled: boolean\n) {\n if (!enabled) {\n return;\n }\n const toolNames = (openaiRequest.tools ?? [])\n .map((tool) => (\"function\" in tool ? tool.function?.name : undefined))\n .filter((name): name is string => Boolean(name));\n\n console.log(\n \"[proxy] Incoming OpenAI request\",\n JSON.stringify(\n {\n model: openaiRequest.model,\n stream: Boolean(openaiRequest.stream),\n temperature: openaiRequest.temperature,\n maxTokens: openaiRequest.max_tokens,\n toolNames,\n toolChoice: openaiRequest.tool_choice,\n messages: serializeMessages(openaiRequest.messages),\n tools: openaiRequest.tools,\n },\n null,\n 2\n )\n );\n}\n\nfunction serializeAISDKMessages(messages: ConvertedParams[\"messages\"]) {\n return messages?.map((message, index) => ({\n index,\n role: message.role,\n content: message.content,\n }));\n}\n\nfunction logRequestConversion(\n openaiRequest: OpenAIChatRequest,\n aisdkParams: ConvertedParams,\n enabled: boolean\n) {\n if (!enabled) {\n return;\n }\n const messages = aisdkParams.messages ?? [];\n console.log(\n \"[proxy] Converted AI SDK params\",\n JSON.stringify(\n {\n model: openaiRequest.model,\n hasSystemMessage: messages.some((message) => message.role === \"system\"),\n messages: serializeAISDKMessages(messages),\n tools: Object.entries(aisdkParams.tools ?? {}).map(([name, tool]) => ({\n name,\n description: tool.description,\n inputSchema: serializeZodSchema(tool.inputSchema),\n })),\n temperature: aisdkParams.temperature,\n maxOutputTokens: aisdkParams.maxOutputTokens,\n stopSequences: aisdkParams.stopSequences,\n },\n null,\n 2\n )\n );\n}\n\nexport class OpenAIProxyServer {\n private readonly fastify: FastifyInstance;\n private readonly config: ProxyConfig;\n private readonly logger: Logger;\n\n constructor(config: ProxyConfig) {\n this.config = {\n port: 3000,\n host: \"localhost\",\n cors: true,\n ...config,\n };\n this.logger = (config.logger ?? console) as Logger;\n\n this.fastify = Fastify();\n\n // Enable CORS\n if (this.config.cors) {\n this.fastify.register(cors);\n }\n\n this.setupRoutes();\n }\n\n private setupRoutes(): void {\n // Health check endpoint\n this.fastify.get(\n \"/health\",\n async (_request: FastifyRequest, _reply: FastifyReply) => ({\n status: \"ok\",\n timestamp: new Date().toISOString(),\n })\n );\n\n // OpenAI-compatible chat completions endpoint\n this.fastify.post(\n \"/v1/chat/completions\",\n (request: FastifyRequest, reply: FastifyReply) => {\n try {\n const openaiRequest = request.body as OpenAIChatRequest;\n\n // Validate request\n if (\n !(openaiRequest.messages && Array.isArray(openaiRequest.messages))\n ) {\n return reply.code(400).send({\n error: {\n message: \"Messages array is required\",\n type: \"invalid_request_error\",\n },\n });\n }\n\n logIncomingRequest(\n openaiRequest,\n this.config.logging?.requests ?? true\n );\n\n // Convert OpenAI request to AI SDK format\n const aisdkParams = convertOpenAIRequestToAISDK(openaiRequest, {\n parserDebug: this.config.parserDebug,\n });\n logRequestConversion(\n openaiRequest,\n aisdkParams,\n this.config.logging?.conversions ?? true\n );\n\n // Handle streaming vs non-streaming\n if (openaiRequest.stream) {\n return this.handleStreamingRequest(\n aisdkParams,\n openaiRequest,\n reply\n );\n }\n return this.handleNonStreamingRequest(\n aisdkParams,\n openaiRequest,\n reply\n );\n } catch (error) {\n this.logger.error(\"Request handling error:\", error);\n return reply.code(500).send({\n error: {\n message: \"Internal server error\",\n type: \"server_error\",\n },\n });\n }\n }\n );\n\n // Models endpoint\n this.fastify.get(\"/v1/models\", async () => ({\n object: \"list\",\n data: [\n {\n id: \"wrapped-model\",\n object: \"model\",\n created: Math.floor(Date.now() / 1000),\n owned_by: \"ai-sdk-tool-proxy\",\n },\n ],\n }));\n }\n\n // Merge server-defined tools (with execute) and request-defined tools (schema-only)\n // Server tools take precedence when names overlap.\n private mergeTools(\n serverTools?: Record<string, AISDKTool>,\n requestTools?: Record<string, AISDKTool>\n ) {\n const toProviderTool = (tool: AISDKTool | undefined): unknown => {\n if (!tool) {\n return;\n }\n\n return {\n description: tool.description,\n inputSchema: zodSchema(tool.inputSchema),\n ...(tool.execute ? { execute: tool.execute } : {}),\n };\n };\n\n const merged: Record<string, unknown> = {};\n\n for (const [name, t] of Object.entries(requestTools ?? {})) {\n const pt = toProviderTool(t);\n if (pt) {\n merged[name] = pt;\n }\n }\n\n for (const [name, t] of Object.entries(serverTools ?? {})) {\n const pt = toProviderTool(t);\n if (pt) {\n merged[name] = pt; // override request tool\n }\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n }\n\n private async handleStreamingRequest(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n aisdkParams: any,\n openaiRequest: OpenAIChatRequest,\n reply: FastifyReply\n ): Promise<void> {\n // Set SSE headers\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n\n try {\n const mergedTools = this.mergeTools(this.config.tools, aisdkParams.tools);\n const result = await streamText({\n model: this.config.model,\n ...aisdkParams,\n ...(mergedTools ? { tools: mergedTools } : {}),\n });\n\n const convert = createOpenAIStreamConverter(openaiRequest.model, {\n logChunks: this.config.logging?.streamChunks ?? true,\n });\n for await (const chunk of result.fullStream) {\n const openaiChunks = convert(chunk);\n for (const openaiChunk of openaiChunks) {\n reply.raw.write(`data: ${openaiChunk.data}\\n\\n`);\n }\n }\n\n reply.raw.write(\"data: [DONE]\\n\\n\");\n reply.raw.end();\n } catch (error) {\n this.logger.error(\"Streaming error:\", error);\n reply.raw.write('data: {\"error\": {\"message\": \"Streaming error\"}}\\n\\n');\n reply.raw.end();\n }\n\n return reply;\n }\n\n private async handleNonStreamingRequest(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n aisdkParams: any,\n openaiRequest: OpenAIChatRequest,\n reply: FastifyReply\n ): Promise<void> {\n try {\n const mergedTools = this.mergeTools(this.config.tools, aisdkParams.tools);\n const result = await generateText({\n model: this.config.model,\n ...aisdkParams,\n ...(mergedTools ? { tools: mergedTools } : {}),\n });\n\n const openaiResponse = convertAISDKResultToOpenAI(\n result,\n openaiRequest.model,\n false\n );\n\n reply.send(openaiResponse);\n } catch (error) {\n this.logger.error(\"Generation error:\", error);\n return reply.code(500).send({\n error: {\n message: \"Generation failed\",\n type: \"generation_error\",\n },\n });\n }\n }\n\n async start(): Promise<void> {\n try {\n await this.fastify.listen({\n port: this.config.port || 3000,\n host: this.config.host || \"localhost\",\n });\n\n this.logger.info(\n `🚀 OpenAI Proxy Server running on http://${this.config.host}:${this.config.port}`\n );\n this.logger.info(\n `📡 Endpoint: http://${this.config.host}:${this.config.port}/v1/chat/completions`\n );\n this.logger.info(\n `🏥 Health: http://${this.config.host}:${this.config.port}/health`\n );\n } catch (error) {\n this.logger.error(\"Failed to start server:\", error);\n process.exit(1);\n }\n }\n\n async stop(): Promise<void> {\n try {\n await this.fastify.close();\n this.logger.info(\"🛑 Server stopped\");\n } catch (error) {\n this.logger.error(\"Error stopping server:\", error);\n }\n }\n}\n"],"mappings":"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","names":["_a","import_zod","_a","Fastify","cors"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/openai-request-converter.ts","../src/response-utils.ts","../src/response-converter.ts","../src/server.ts"],"sourcesContent":["// biome-ignore lint/performance/noBarrelFile: Package entrypoint - must re-export for public API\nexport {\n convertAISDKToolCallsToOpenAI,\n convertOpenAIRequestToAISDK,\n} from \"./openai-request-converter.js\";\nexport {\n convertAISDKResultToOpenAI,\n convertAISDKStreamChunkToOpenAI,\n createOpenAIStreamConverter,\n createSSEResponse,\n} from \"./response-converter.js\";\nexport { generateResponseId, getCurrentTimestamp } from \"./response-utils.js\";\nexport { OpenAIProxyServer } from \"./server.js\";\nexport type {\n AISDKTool,\n Logger,\n OpenAIChatRequest,\n OpenAIChatResponse,\n OpenAIChoice,\n OpenAIMessage,\n OpenAITool,\n OpenAIToolCall,\n OpenAIUsage,\n ProxyConfig,\n StreamChunk,\n} from \"./types.js\";\n","import type {\n ModelMessage,\n ToolContent,\n ToolResultOutput,\n} from \"@ai-sdk/provider-utils\";\nimport { z } from \"zod\";\nimport type {\n OpenAIChatRequest,\n OpenAICompleteToolCall,\n OpenAIMessage,\n ProxyConfig,\n} from \"./types.js\";\n\n// Type definitions for OpenAI tool parameters\ninterface OpenAIToolProperty {\n type: string;\n description?: string;\n enum?: string[];\n}\n\ninterface OpenAIToolParameters {\n type: string;\n properties?: Record<string, OpenAIToolProperty>;\n required?: string[];\n}\n\n// Type for AI SDK tool definition\ninterface AISDKTool {\n description: string;\n inputSchema: z.ZodTypeAny;\n}\n\n// Type for tool call object\ninterface ToolCall {\n toolName: string;\n args: unknown;\n}\n\n/**\n * Create Zod schema for OpenAI tool property\n */\nfunction createZodSchema(prop: OpenAIToolProperty): z.ZodTypeAny {\n if (prop.type === \"string\") {\n return prop.enum ? z.enum(prop.enum as [string, ...string[]]) : z.string();\n }\n if (prop.type === \"number\") {\n return z.number();\n }\n if (prop.type === \"boolean\") {\n return z.boolean();\n }\n if (prop.type === \"array\") {\n return z.array(z.any());\n }\n if (prop.type === \"object\") {\n return z.object({});\n }\n return z.any();\n}\n\n/**\n * Convert OpenAI tool schema to Zod schema\n */\nfunction convertOpenAIToolToZod(\n parameters: Record<string, unknown> | undefined\n): z.ZodObject<Record<string, z.ZodTypeAny>> {\n if (!parameters) {\n return z.object({});\n }\n\n const params = parameters as unknown as OpenAIToolParameters;\n if (!params.properties) {\n return z.object({});\n }\n\n const schemaShape: Record<string, z.ZodTypeAny> = {};\n for (const [key, prop] of Object.entries(params.properties)) {\n schemaShape[key] = createZodSchema(prop);\n }\n\n return z.object(schemaShape);\n}\n\n/**\n * Convert OpenAI tools to AI SDK format\n */\nfunction convertOpenAITools(\n openaiTools:\n | Array<{\n function: {\n name: string;\n description?: string;\n parameters: Record<string, unknown>;\n };\n }>\n | undefined\n): Record<string, AISDKTool> {\n const aisdkTools: Record<string, AISDKTool> = {};\n\n if (!openaiTools) {\n return aisdkTools;\n }\n\n for (const openaiTool of openaiTools) {\n const toolName = openaiTool.function.name;\n aisdkTools[toolName] = {\n description: openaiTool.function.description || \"\",\n inputSchema: convertOpenAIToolToZod(openaiTool.function.parameters),\n };\n }\n\n return aisdkTools;\n}\n\n/**\n * Convert stop parameter to stop sequences\n */\nfunction convertStopToSequences(\n stop: string | string[] | undefined\n): string[] | undefined {\n if (!stop) {\n return;\n }\n return Array.isArray(stop) ? stop : [stop];\n}\n\ninterface AITextPart {\n type: \"text\";\n text: string;\n}\ninterface AIToolCallPart {\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n input: unknown;\n}\ntype TextToolOutput = Extract<ToolResultOutput, { type: \"text\" }>;\ntype JsonToolOutput = Extract<ToolResultOutput, { type: \"json\" }>;\n\n/**\n * Convert OpenAI chat completion request to AI SDK format\n */\nexport function normalizeMessageContent(\n content: OpenAIMessage[\"content\"]\n): AITextPart[] {\n if (typeof content === \"string\") {\n return content ? [{ type: \"text\" as const, text: content }] : [];\n }\n\n if (Array.isArray(content)) {\n const parts = content as Array<string | { text?: unknown }>;\n return parts\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n }\n if (part && typeof part === \"object\" && \"text\" in part) {\n const textValue = part.text;\n if (typeof textValue === \"string\") {\n return textValue;\n }\n if (textValue !== undefined) {\n return JSON.stringify(textValue);\n }\n }\n return JSON.stringify(part);\n })\n .filter((text): text is string => Boolean(text))\n .map((text) => ({ type: \"text\" as const, text }));\n }\n\n if (content === null || content === undefined) {\n return [];\n }\n\n if (typeof content === \"object\") {\n return [{ type: \"text\" as const, text: JSON.stringify(content) }];\n }\n\n return [{ type: \"text\" as const, text: String(content) }];\n}\n\nfunction buildToolCallParts(\n toolCalls: OpenAICompleteToolCall[]\n): AIToolCallPart[] {\n return toolCalls.map((toolCall) => {\n let parsedArgs: unknown = toolCall.function.arguments;\n if (typeof toolCall.function.arguments === \"string\") {\n try {\n parsedArgs = JSON.parse(toolCall.function.arguments || \"{}\");\n } catch {\n parsedArgs = toolCall.function.arguments;\n }\n }\n\n return {\n type: \"tool-call\" as const,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input: parsedArgs,\n } satisfies AIToolCallPart;\n });\n}\n\nfunction buildAssistantContent(\n message: OpenAIMessage & { role: \"assistant\" }\n): Array<AITextPart | AIToolCallPart> | string {\n const textParts = normalizeMessageContent(message.content);\n const toolCallParts = message.tool_calls?.length\n ? buildToolCallParts(message.tool_calls)\n : [];\n\n if (toolCallParts.length === 0) {\n if (textParts.length === 0) {\n return \"\";\n }\n if (textParts.length === 1) {\n return textParts[0].text;\n }\n return textParts;\n }\n\n return [...textParts, ...toolCallParts];\n}\n\nfunction isJsonValue(value: unknown): value is JsonToolOutput[\"value\"] {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every(isJsonValue);\n }\n\n if (typeof value === \"object\") {\n return Object.values(value as Record<string, unknown>).every(isJsonValue);\n }\n\n return false;\n}\n\nfunction buildToolOutput(rawValue: string): ToolResultOutput {\n if (!rawValue) {\n return { type: \"text\", value: \"\" } satisfies TextToolOutput;\n }\n\n try {\n const parsed = JSON.parse(rawValue);\n if (isJsonValue(parsed)) {\n return { type: \"json\", value: parsed } satisfies JsonToolOutput;\n }\n } catch {\n // Fall through to text output below\n }\n\n return { type: \"text\", value: rawValue } satisfies TextToolOutput;\n}\n\nfunction buildToolContent(\n message: OpenAIMessage & { role: \"tool\" },\n toolNameLookup: Map<string, string>\n): ToolContent {\n const textParts = normalizeMessageContent(message.content);\n const combined = textParts.map((part) => part.text).join(\"\\n\");\n const toolCallId = message.tool_call_id ?? \"\";\n const toolName = toolCallId\n ? (toolNameLookup.get(toolCallId) ?? toolCallId)\n : \"\";\n\n return [\n {\n type: \"tool-result\",\n toolCallId,\n toolName,\n output: buildToolOutput(combined),\n },\n ];\n}\n\nfunction convertMessageToModelMessage(\n message: OpenAIMessage,\n toolNameLookup: Map<string, string>\n): ModelMessage {\n if (message.role === \"assistant\") {\n if (message.tool_calls?.length) {\n for (const toolCall of message.tool_calls) {\n toolNameLookup.set(toolCall.id, toolCall.function.name);\n }\n }\n\n return {\n role: \"assistant\",\n content: buildAssistantContent(\n message as OpenAIMessage & { role: \"assistant\" }\n ),\n };\n }\n\n if (message.role === \"tool\") {\n return {\n role: \"tool\",\n content: buildToolContent(\n message as OpenAIMessage & { role: \"tool\" },\n toolNameLookup\n ),\n };\n }\n\n if (message.role === \"system\") {\n const text = normalizeMessageContent(message.content)\n .map((part) => part.text)\n .join(\"\\n\");\n return {\n role: \"system\",\n content: text,\n };\n }\n\n const userParts = normalizeMessageContent(message.content);\n if (userParts.length === 0) {\n return {\n role: \"user\",\n content: \"\",\n };\n }\n\n if (userParts.length === 1) {\n return {\n role: \"user\",\n content: userParts[0].text,\n };\n }\n\n return {\n role: \"user\",\n content: userParts,\n };\n}\n\nexport function convertOpenAIRequestToAISDK(\n openaiRequest: OpenAIChatRequest,\n proxyConfig?: Pick<ProxyConfig, \"parserDebug\">\n) {\n const {\n messages,\n tools: openaiTools,\n temperature,\n max_tokens,\n stop,\n tool_choice,\n } = openaiRequest;\n\n const toolNameLookup = new Map<string, string>();\n\n const aiMessages: ModelMessage[] = messages.map((message) =>\n convertMessageToModelMessage(message, toolNameLookup)\n );\n\n // Convert OpenAI tools to AI SDK format dynamically\n const aisdkTools = convertOpenAITools(openaiTools);\n\n const providerOptions = proxyConfig?.parserDebug\n ? {\n toolCallMiddleware: {\n debugLevel: proxyConfig.parserDebug.level,\n logErrors: proxyConfig.parserDebug.logErrors,\n captureSummary: proxyConfig.parserDebug.captureSummary,\n },\n }\n : undefined;\n\n return {\n messages: aiMessages,\n tools: aisdkTools,\n temperature,\n maxOutputTokens: max_tokens,\n stopSequences: convertStopToSequences(stop),\n toolChoice: mapOpenAIToolChoice(tool_choice),\n ...(providerOptions ? { providerOptions } : {}),\n };\n}\n\n// Map OpenAI tool_choice to AI SDK toolChoice\nexport function mapOpenAIToolChoice(\n choice: OpenAIChatRequest[\"tool_choice\"]\n): \"auto\" | \"none\" | { type: \"tool\"; toolName: string } | undefined {\n if (!choice) {\n return;\n }\n if (choice === \"auto\" || choice === \"none\") {\n return choice;\n }\n if (typeof choice === \"object\" && choice.type === \"function\") {\n return { type: \"tool\", toolName: choice.function.name };\n }\n return;\n}\n\n/**\n * Convert AI SDK tool calls to OpenAI format\n */\nexport function convertAISDKToolCallsToOpenAI(toolCalls: ToolCall[]): Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n}> {\n return toolCalls.map((call) => ({\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`,\n type: \"function\" as const,\n function: {\n name: call.toolName,\n arguments: JSON.stringify(call.args),\n },\n }));\n}\n","export function generateResponseId(): string {\n return `chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n\nexport function getCurrentTimestamp(): number {\n return Math.floor(Date.now() / 1000);\n}\n","import { generateResponseId, getCurrentTimestamp } from \"./response-utils.js\";\nimport type {\n OpenAIChatResponse,\n OpenAIChoice,\n OpenAIStreamingToolCall,\n OpenAIUsage,\n StreamChunk,\n} from \"./types.js\";\n\n/**\n * Convert AI SDK result to OpenAI chat completion response\n */\nexport function convertAISDKResultToOpenAI(\n // biome-ignore lint/suspicious/noExplicitAny: AI sdk integration boundary\n aisdkResult: any,\n model: string,\n stream = false\n): OpenAIChatResponse {\n const choices: OpenAIChoice[] = [];\n\n // Handle text content\n if (aisdkResult.text) {\n const choice: OpenAIChoice = {\n index: 0,\n finish_reason: aisdkResult.finishReason || \"stop\",\n };\n\n if (stream) {\n choice.delta = {\n role: \"assistant\",\n content: aisdkResult.text,\n };\n } else {\n choice.message = {\n role: \"assistant\",\n content: aisdkResult.text,\n };\n }\n choices.push(choice);\n }\n\n // Handle tool calls\n if (aisdkResult.toolCalls && aisdkResult.toolCalls.length > 0) {\n const choice: OpenAIChoice = {\n index: 0,\n finish_reason: \"tool_calls\",\n };\n\n const openAIToolCalls = aisdkResult.toolCalls?.map(\n (\n // biome-ignore lint/suspicious/noExplicitAny: AI SDK integration boundary\n call: any\n ) => ({\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`,\n type: \"function\" as const,\n function: {\n name: call.toolName,\n arguments: JSON.stringify(call.args),\n },\n })\n );\n\n if (stream) {\n choice.delta = {\n role: \"assistant\",\n tool_calls: openAIToolCalls,\n };\n } else {\n choice.message = {\n role: \"assistant\",\n content: null,\n tool_calls: openAIToolCalls,\n };\n }\n\n choices.push(choice);\n }\n\n const response: OpenAIChatResponse = {\n id: generateResponseId(),\n object: stream ? \"chat.completion.chunk\" : \"chat.completion\",\n created: getCurrentTimestamp(),\n model,\n choices,\n };\n\n // Add usage if available\n if (aisdkResult.usage) {\n response.usage = {\n prompt_tokens: aisdkResult.usage.promptTokens || 0,\n completion_tokens: aisdkResult.usage.completionTokens || 0,\n total_tokens: aisdkResult.usage.totalTokens || 0,\n } as OpenAIUsage;\n }\n\n return response;\n}\n\n/**\n * Convert AI SDK stream chunk to OpenAI SSE format\n */\n\n// Type definitions for better type safety\ninterface ToolCallDelta {\n index?: number;\n id?: string;\n type?: \"function\";\n function?: {\n name?: string;\n arguments?: string;\n };\n}\n\ninterface AIStreamChunk {\n type: string;\n id?: string;\n text?: string;\n toolCallId?: string;\n toolName?: string;\n args?: string;\n input?: Record<string, unknown>;\n finishReason?: string;\n [key: string]: unknown;\n}\n\ntype ChunkHandler = (chunk: AIStreamChunk, model: string) => StreamChunk[];\n\n// Helper function to create finish response\nfunction createFinishResponse(\n model: string,\n finishReason: string,\n responseId: string\n): OpenAIChatResponse {\n // Ensure finish reason matches OpenAI's allowed types\n let validFinishReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\";\n\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n validFinishReason = \"tool_calls\";\n } else if (finishReason === \"stop\") {\n validFinishReason = \"stop\";\n } else if (finishReason === \"length\") {\n validFinishReason = \"length\";\n } else if (finishReason === \"content_filter\") {\n validFinishReason = \"content_filter\";\n } else {\n validFinishReason = \"stop\"; // fallback to \"stop\" for unknown reasons\n }\n\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta: {},\n finish_reason: validFinishReason,\n },\n ],\n };\n}\n\n// Helper function to create content response\nfunction createContentResponse(\n model: string,\n content: string,\n responseId: string,\n isReasoning = false\n): OpenAIChatResponse {\n const delta: Record<string, unknown> = { role: \"assistant\" };\n\n if (isReasoning) {\n delta.reasoning_content = content;\n } else {\n delta.content = content;\n }\n\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta,\n },\n ],\n };\n}\n\n// Helper function to create tool call response\nfunction createToolCallResponse(\n model: string,\n toolCall: ToolCallDelta,\n responseId: string,\n includeRole = false\n): OpenAIChatResponse {\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta: {\n ...(includeRole ? { role: \"assistant\" as const } : {}),\n tool_calls: [\n {\n index: toolCall.index || 0,\n type: \"function\" as const,\n function: {\n name: toolCall.function?.name || \"\",\n arguments: toolCall.function?.arguments || \"\",\n },\n },\n ],\n },\n },\n ],\n };\n}\n\n// (legacy stateless handler removed)\n\nexport function createOpenAIStreamConverter(\n model: string,\n options?: {\n logChunks?: boolean;\n }\n) {\n let streamHasToolCalls = false;\n let streamFinishSent = false;\n let streamResponseId = generateResponseId();\n\n const logChunk =\n options?.logChunks === false\n ? undefined\n : (chunk: unknown) => {\n const logType =\n process.env.USE_MIDDLEWARE === \"true\" ? \"middleware\" : \"native\";\n console.log(\n `🔍 AI SDK Chunk [${logType}]:`,\n JSON.stringify(chunk, null, 2)\n );\n };\n\n const handlers: Record<string, ChunkHandler> = {\n start: () => [],\n \"reasoning-delta\": (chunk) => {\n if (!chunk.text) {\n return [];\n }\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, chunk.text, streamResponseId, true)\n ),\n },\n ];\n },\n \"text-delta\": (chunk) => {\n if (!chunk.text) {\n return [];\n }\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, chunk.text, streamResponseId, false)\n ),\n },\n ];\n },\n \"tool-call\": (chunk) => {\n const toolCallId = chunk.toolCallId || `call_${generateResponseId()}`;\n const toolName = chunk.toolName || \"\";\n const argsString =\n typeof chunk.input === \"string\"\n ? chunk.input\n : JSON.stringify(chunk.input ?? {});\n const toolCallDelta: OpenAIStreamingToolCall = {\n index: 0,\n id: toolCallId,\n type: \"function\",\n function: { name: toolName, arguments: argsString },\n };\n const response = createToolCallResponse(\n model,\n toolCallDelta,\n streamResponseId,\n true\n );\n return [{ data: JSON.stringify(response) }];\n },\n \"reasoning-end\": () => [],\n \"text-end\": () => [],\n \"finish-step\": (chunk) => {\n if (streamFinishSent) {\n return [];\n }\n const hadToolCalls = streamHasToolCalls;\n let finishReason = chunk.finishReason || \"stop\";\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n finishReason = \"tool_calls\";\n }\n const resolvedReason = hadToolCalls ? \"tool_calls\" : finishReason;\n streamFinishSent = true;\n streamHasToolCalls = false;\n return [\n {\n data: JSON.stringify(\n createFinishResponse(model, resolvedReason, streamResponseId)\n ),\n },\n ];\n },\n \"tool-call-delta\": (chunk) => {\n const toolCall = {\n index: chunk.toolCallId ? Number(chunk.toolCallId) : 0,\n type: \"function\" as const,\n function: {\n name: chunk.toolName || \"\",\n arguments: chunk.args || \"\",\n },\n };\n return [\n {\n data: JSON.stringify(\n createToolCallResponse(model, toolCall, streamResponseId)\n ),\n },\n ];\n },\n \"tool-result\": (chunk) => {\n const resultText = `\\n[Tool: ${chunk.toolName} returned ${JSON.stringify(chunk.output)}]\\n`;\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, resultText, streamResponseId, false)\n ),\n },\n ];\n },\n finish: (chunk) => {\n if (streamFinishSent) {\n return [];\n }\n const hadToolCalls = streamHasToolCalls;\n let finishReason = chunk.finishReason || \"stop\";\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n finishReason = \"tool_calls\";\n }\n const resolvedReason = hadToolCalls ? \"tool_calls\" : finishReason;\n streamFinishSent = true;\n streamHasToolCalls = false;\n return [\n {\n data: JSON.stringify(\n createFinishResponse(model, resolvedReason, streamResponseId)\n ),\n },\n ];\n },\n };\n\n return (\n // biome-ignore lint/suspicious/noExplicitAny: ai sdk boundary\n chunk: any\n ): StreamChunk[] => {\n const out: StreamChunk[] = [];\n\n logChunk?.(chunk);\n\n if (chunk.type === \"start\") {\n streamHasToolCalls = false;\n streamFinishSent = false;\n streamResponseId = chunk.id ?? generateResponseId();\n }\n\n const handler = handlers[chunk.type];\n if (handler) {\n const result = handler(chunk as AIStreamChunk, model);\n if (chunk.type === \"tool-call\" || chunk.type === \"tool-call-delta\") {\n streamHasToolCalls = true;\n }\n out.push(...result);\n } else {\n console.warn(`⚠️ Unknown AI SDK chunk type: ${chunk.type}`, chunk);\n }\n\n if (chunk.type === \"finish-step\" || chunk.type === \"finish\") {\n streamHasToolCalls = false;\n }\n\n return out.filter((resultChunk) => {\n try {\n const parsed = JSON.parse(resultChunk.data);\n const delta = parsed.choices?.[0]?.delta;\n return (\n delta &&\n (delta.role ||\n delta.content ||\n (delta as NonNullable<OpenAIChoice[\"delta\"]>).reasoning_content ||\n (delta.tool_calls && delta.tool_calls.length > 0) ||\n parsed.choices?.[0]?.finish_reason)\n );\n } catch {\n return true;\n }\n });\n };\n}\n\nexport function convertAISDKStreamChunkToOpenAI(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n chunk: any,\n model: string\n): StreamChunk[] {\n const convert = createOpenAIStreamConverter(model);\n return convert(chunk);\n}\n\n/**\n * Create SSE formatted response\n */\nexport function createSSEResponse(chunks: StreamChunk[]): string {\n return chunks.map((chunk) => `data: ${chunk.data}\\n\\n`).join(\"\");\n}\n","import { zodSchema } from \"@ai-sdk/provider-utils\";\nimport cors from \"@fastify/cors\";\nimport { generateText, streamText } from \"ai\";\nimport Fastify, {\n type FastifyInstance,\n type FastifyReply,\n type FastifyRequest,\n} from \"fastify\";\nimport { toJSONSchema, type ZodTypeAny } from \"zod\";\nimport { convertOpenAIRequestToAISDK } from \"./openai-request-converter.js\";\nimport {\n convertAISDKResultToOpenAI,\n createOpenAIStreamConverter,\n} from \"./response-converter.js\";\nimport type {\n AISDKTool,\n Logger,\n OpenAIChatRequest,\n ProxyConfig,\n} from \"./types.js\";\n\ntype ConvertedParams = ReturnType<typeof convertOpenAIRequestToAISDK>;\n\nfunction serializeZodSchema(schema: ZodTypeAny | undefined): unknown {\n if (!schema) {\n return null;\n }\n\n // Use Zod v4's built-in JSON Schema conversion\n const jsonSchema = toJSONSchema(schema, {\n unrepresentable: \"any\",\n });\n\n // Remove $schema field for cleaner output\n if (typeof jsonSchema === \"object\" && jsonSchema !== null) {\n const { $schema, ...rest } = jsonSchema as Record<string, unknown>;\n return rest;\n }\n\n return jsonSchema;\n}\n\nfunction serializeMessages(messages: OpenAIChatRequest[\"messages\"]) {\n return messages.map((message, index) => ({\n index,\n role: message.role,\n content: message.content,\n toolCalls: message.tool_calls,\n }));\n}\n\nfunction logIncomingRequest(\n openaiRequest: OpenAIChatRequest,\n enabled: boolean\n) {\n if (!enabled) {\n return;\n }\n const toolNames = (openaiRequest.tools ?? [])\n .map((tool) => (\"function\" in tool ? tool.function?.name : undefined))\n .filter((name): name is string => Boolean(name));\n\n console.log(\n \"[proxy] Incoming OpenAI request\",\n JSON.stringify(\n {\n model: openaiRequest.model,\n stream: Boolean(openaiRequest.stream),\n temperature: openaiRequest.temperature,\n maxTokens: openaiRequest.max_tokens,\n toolNames,\n toolChoice: openaiRequest.tool_choice,\n messages: serializeMessages(openaiRequest.messages),\n tools: openaiRequest.tools,\n },\n null,\n 2\n )\n );\n}\n\nfunction serializeAISDKMessages(messages: ConvertedParams[\"messages\"]) {\n return messages?.map((message, index) => ({\n index,\n role: message.role,\n content: message.content,\n }));\n}\n\nfunction logRequestConversion(\n openaiRequest: OpenAIChatRequest,\n aisdkParams: ConvertedParams,\n enabled: boolean\n) {\n if (!enabled) {\n return;\n }\n const messages = aisdkParams.messages ?? [];\n console.log(\n \"[proxy] Converted AI SDK params\",\n JSON.stringify(\n {\n model: openaiRequest.model,\n hasSystemMessage: messages.some((message) => message.role === \"system\"),\n messages: serializeAISDKMessages(messages),\n tools: Object.entries(aisdkParams.tools ?? {}).map(([name, tool]) => ({\n name,\n description: tool.description,\n inputSchema: serializeZodSchema(tool.inputSchema),\n })),\n temperature: aisdkParams.temperature,\n maxOutputTokens: aisdkParams.maxOutputTokens,\n stopSequences: aisdkParams.stopSequences,\n },\n null,\n 2\n )\n );\n}\n\nexport class OpenAIProxyServer {\n private readonly fastify: FastifyInstance;\n private readonly config: ProxyConfig;\n private readonly logger: Logger;\n\n constructor(config: ProxyConfig) {\n this.config = {\n port: 3000,\n host: \"localhost\",\n cors: true,\n ...config,\n };\n this.logger = (config.logger ?? console) as Logger;\n\n this.fastify = Fastify();\n\n // Enable CORS\n if (this.config.cors) {\n this.fastify.register(cors);\n }\n\n this.setupRoutes();\n }\n\n private setupRoutes(): void {\n // Health check endpoint\n this.fastify.get(\n \"/health\",\n async (_request: FastifyRequest, _reply: FastifyReply) => ({\n status: \"ok\",\n timestamp: new Date().toISOString(),\n })\n );\n\n // OpenAI-compatible chat completions endpoint\n this.fastify.post(\n \"/v1/chat/completions\",\n (request: FastifyRequest, reply: FastifyReply) => {\n try {\n const openaiRequest = request.body as OpenAIChatRequest;\n\n // Validate request\n if (\n !(openaiRequest.messages && Array.isArray(openaiRequest.messages))\n ) {\n return reply.code(400).send({\n error: {\n message: \"Messages array is required\",\n type: \"invalid_request_error\",\n },\n });\n }\n\n logIncomingRequest(\n openaiRequest,\n this.config.logging?.requests ?? true\n );\n\n // Convert OpenAI request to AI SDK format\n const aisdkParams = convertOpenAIRequestToAISDK(openaiRequest, {\n parserDebug: this.config.parserDebug,\n });\n logRequestConversion(\n openaiRequest,\n aisdkParams,\n this.config.logging?.conversions ?? true\n );\n\n // Handle streaming vs non-streaming\n if (openaiRequest.stream) {\n return this.handleStreamingRequest(\n aisdkParams,\n openaiRequest,\n reply\n );\n }\n return this.handleNonStreamingRequest(\n aisdkParams,\n openaiRequest,\n reply\n );\n } catch (error) {\n this.logger.error(\"Request handling error:\", error);\n return reply.code(500).send({\n error: {\n message: \"Internal server error\",\n type: \"server_error\",\n },\n });\n }\n }\n );\n\n // Models endpoint\n this.fastify.get(\"/v1/models\", async () => ({\n object: \"list\",\n data: [\n {\n id: \"wrapped-model\",\n object: \"model\",\n created: Math.floor(Date.now() / 1000),\n owned_by: \"ai-sdk-tool-proxy\",\n },\n ],\n }));\n }\n\n // Merge server-defined tools (with execute) and request-defined tools (schema-only)\n // Server tools take precedence when names overlap.\n private mergeTools(\n serverTools?: Record<string, AISDKTool>,\n requestTools?: Record<string, AISDKTool>\n ) {\n const toProviderTool = (tool: AISDKTool | undefined): unknown => {\n if (!tool) {\n return;\n }\n\n return {\n description: tool.description,\n inputSchema: zodSchema(tool.inputSchema),\n ...(tool.execute ? { execute: tool.execute } : {}),\n };\n };\n\n const merged: Record<string, unknown> = {};\n\n for (const [name, t] of Object.entries(requestTools ?? {})) {\n const pt = toProviderTool(t);\n if (pt) {\n merged[name] = pt;\n }\n }\n\n for (const [name, t] of Object.entries(serverTools ?? {})) {\n const pt = toProviderTool(t);\n if (pt) {\n merged[name] = pt; // override request tool\n }\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n }\n\n private async handleStreamingRequest(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n aisdkParams: any,\n openaiRequest: OpenAIChatRequest,\n reply: FastifyReply\n ): Promise<void> {\n // Set SSE headers\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n\n try {\n const mergedTools = this.mergeTools(this.config.tools, aisdkParams.tools);\n const result = await streamText({\n model: this.config.model,\n ...aisdkParams,\n ...(mergedTools ? { tools: mergedTools } : {}),\n });\n\n const convert = createOpenAIStreamConverter(openaiRequest.model, {\n logChunks: this.config.logging?.streamChunks ?? true,\n });\n for await (const chunk of result.fullStream) {\n const openaiChunks = convert(chunk);\n for (const openaiChunk of openaiChunks) {\n reply.raw.write(`data: ${openaiChunk.data}\\n\\n`);\n }\n }\n\n reply.raw.write(\"data: [DONE]\\n\\n\");\n reply.raw.end();\n } catch (error) {\n this.logger.error(\"Streaming error:\", error);\n reply.raw.write('data: {\"error\": {\"message\": \"Streaming error\"}}\\n\\n');\n reply.raw.end();\n }\n\n return reply;\n }\n\n private async handleNonStreamingRequest(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n aisdkParams: any,\n openaiRequest: OpenAIChatRequest,\n reply: FastifyReply\n ): Promise<void> {\n try {\n const mergedTools = this.mergeTools(this.config.tools, aisdkParams.tools);\n const result = await generateText({\n model: this.config.model,\n ...aisdkParams,\n ...(mergedTools ? { tools: mergedTools } : {}),\n });\n\n const openaiResponse = convertAISDKResultToOpenAI(\n result,\n openaiRequest.model,\n false\n );\n\n reply.send(openaiResponse);\n } catch (error) {\n this.logger.error(\"Generation error:\", error);\n return reply.code(500).send({\n error: {\n message: \"Generation failed\",\n type: \"generation_error\",\n },\n });\n }\n }\n\n async start(): Promise<void> {\n try {\n await this.fastify.listen({\n port: this.config.port || 3000,\n host: this.config.host || \"localhost\",\n });\n\n this.logger.info(\n `🚀 OpenAI Proxy Server running on http://${this.config.host}:${this.config.port}`\n );\n this.logger.info(\n `📡 Endpoint: http://${this.config.host}:${this.config.port}/v1/chat/completions`\n );\n this.logger.info(\n `🏥 Health: http://${this.config.host}:${this.config.port}/health`\n );\n } catch (error) {\n this.logger.error(\"Failed to start server:\", error);\n process.exit(1);\n }\n }\n\n async stop(): Promise<void> {\n try {\n await this.fastify.close();\n this.logger.info(\"🛑 Server stopped\");\n } catch (error) {\n this.logger.error(\"Error stopping server:\", error);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKA,iBAAkB;AAoClB,SAAS,gBAAgB,MAAwC;AAC/D,MAAI,KAAK,SAAS,UAAU;AAC1B,WAAO,KAAK,OAAO,aAAE,KAAK,KAAK,IAA6B,IAAI,aAAE,OAAO;AAAA,EAC3E;AACA,MAAI,KAAK,SAAS,UAAU;AAC1B,WAAO,aAAE,OAAO;AAAA,EAClB;AACA,MAAI,KAAK,SAAS,WAAW;AAC3B,WAAO,aAAE,QAAQ;AAAA,EACnB;AACA,MAAI,KAAK,SAAS,SAAS;AACzB,WAAO,aAAE,MAAM,aAAE,IAAI,CAAC;AAAA,EACxB;AACA,MAAI,KAAK,SAAS,UAAU;AAC1B,WAAO,aAAE,OAAO,CAAC,CAAC;AAAA,EACpB;AACA,SAAO,aAAE,IAAI;AACf;AAKA,SAAS,uBACP,YAC2C;AAC3C,MAAI,CAAC,YAAY;AACf,WAAO,aAAE,OAAO,CAAC,CAAC;AAAA,EACpB;AAEA,QAAM,SAAS;AACf,MAAI,CAAC,OAAO,YAAY;AACtB,WAAO,aAAE,OAAO,CAAC,CAAC;AAAA,EACpB;AAEA,QAAM,cAA4C,CAAC;AACnD,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,OAAO,UAAU,GAAG;AAC3D,gBAAY,GAAG,IAAI,gBAAgB,IAAI;AAAA,EACzC;AAEA,SAAO,aAAE,OAAO,WAAW;AAC7B;AAKA,SAAS,mBACP,aAS2B;AAC3B,QAAM,aAAwC,CAAC;AAE/C,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,aAAW,cAAc,aAAa;AACpC,UAAM,WAAW,WAAW,SAAS;AACrC,eAAW,QAAQ,IAAI;AAAA,MACrB,aAAa,WAAW,SAAS,eAAe;AAAA,MAChD,aAAa,uBAAuB,WAAW,SAAS,UAAU;AAAA,IACpE;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,uBACP,MACsB;AACtB,MAAI,CAAC,MAAM;AACT;AAAA,EACF;AACA,SAAO,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;AAC3C;AAkBO,SAAS,wBACd,SACc;AACd,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO,UAAU,CAAC,EAAE,MAAM,QAAiB,MAAM,QAAQ,CAAC,IAAI,CAAC;AAAA,EACjE;AAEA,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,UAAM,QAAQ;AACd,WAAO,MACJ,IAAI,CAAC,SAAS;AACb,UAAI,OAAO,SAAS,UAAU;AAC5B,eAAO;AAAA,MACT;AACA,UAAI,QAAQ,OAAO,SAAS,YAAY,UAAU,MAAM;AACtD,cAAM,YAAY,KAAK;AACvB,YAAI,OAAO,cAAc,UAAU;AACjC,iBAAO;AAAA,QACT;AACA,YAAI,cAAc,QAAW;AAC3B,iBAAO,KAAK,UAAU,SAAS;AAAA,QACjC;AAAA,MACF;AACA,aAAO,KAAK,UAAU,IAAI;AAAA,IAC5B,CAAC,EACA,OAAO,CAAC,SAAyB,QAAQ,IAAI,CAAC,EAC9C,IAAI,CAAC,UAAU,EAAE,MAAM,QAAiB,KAAK,EAAE;AAAA,EACpD;AAEA,MAAI,YAAY,QAAQ,YAAY,QAAW;AAC7C,WAAO,CAAC;AAAA,EACV;AAEA,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,OAAO,EAAE,CAAC;AAAA,EAClE;AAEA,SAAO,CAAC,EAAE,MAAM,QAAiB,MAAM,OAAO,OAAO,EAAE,CAAC;AAC1D;AAEA,SAAS,mBACP,WACkB;AAClB,SAAO,UAAU,IAAI,CAAC,aAAa;AACjC,QAAI,aAAsB,SAAS,SAAS;AAC5C,QAAI,OAAO,SAAS,SAAS,cAAc,UAAU;AACnD,UAAI;AACF,qBAAa,KAAK,MAAM,SAAS,SAAS,aAAa,IAAI;AAAA,MAC7D,SAAQ;AACN,qBAAa,SAAS,SAAS;AAAA,MACjC;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,YAAY,SAAS;AAAA,MACrB,UAAU,SAAS,SAAS;AAAA,MAC5B,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;AAEA,SAAS,sBACP,SAC6C;AA9M/C;AA+ME,QAAM,YAAY,wBAAwB,QAAQ,OAAO;AACzD,QAAM,kBAAgB,aAAQ,eAAR,mBAAoB,UACtC,mBAAmB,QAAQ,UAAU,IACrC,CAAC;AAEL,MAAI,cAAc,WAAW,GAAG;AAC9B,QAAI,UAAU,WAAW,GAAG;AAC1B,aAAO;AAAA,IACT;AACA,QAAI,UAAU,WAAW,GAAG;AAC1B,aAAO,UAAU,CAAC,EAAE;AAAA,IACtB;AACA,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,GAAG,WAAW,GAAG,aAAa;AACxC;AAEA,SAAS,YAAY,OAAkD;AACrE,MACE,UAAU,QACV,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,WACjB;AACA,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,MAAM,WAAW;AAAA,EAChC;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,OAAO,OAAO,KAAgC,EAAE,MAAM,WAAW;AAAA,EAC1E;AAEA,SAAO;AACT;AAEA,SAAS,gBAAgB,UAAoC;AAC3D,MAAI,CAAC,UAAU;AACb,WAAO,EAAE,MAAM,QAAQ,OAAO,GAAG;AAAA,EACnC;AAEA,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,QAAQ;AAClC,QAAI,YAAY,MAAM,GAAG;AACvB,aAAO,EAAE,MAAM,QAAQ,OAAO,OAAO;AAAA,IACvC;AAAA,EACF,SAAQ;AAAA,EAER;AAEA,SAAO,EAAE,MAAM,QAAQ,OAAO,SAAS;AACzC;AAEA,SAAS,iBACP,SACA,gBACa;AA1Qf;AA2QE,QAAM,YAAY,wBAAwB,QAAQ,OAAO;AACzD,QAAM,WAAW,UAAU,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,KAAK,IAAI;AAC7D,QAAM,cAAa,aAAQ,iBAAR,YAAwB;AAC3C,QAAM,WAAW,cACZ,oBAAe,IAAI,UAAU,MAA7B,YAAkC,aACnC;AAEJ,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,QAAQ,gBAAgB,QAAQ;AAAA,IAClC;AAAA,EACF;AACF;AAEA,SAAS,6BACP,SACA,gBACc;AA/RhB;AAgSE,MAAI,QAAQ,SAAS,aAAa;AAChC,SAAI,aAAQ,eAAR,mBAAoB,QAAQ;AAC9B,iBAAW,YAAY,QAAQ,YAAY;AACzC,uBAAe,IAAI,SAAS,IAAI,SAAS,SAAS,IAAI;AAAA,MACxD;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,QAAQ;AAC3B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,UAAU;AAC7B,UAAM,OAAO,wBAAwB,QAAQ,OAAO,EACjD,IAAI,CAAC,SAAS,KAAK,IAAI,EACvB,KAAK,IAAI;AACZ,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,YAAY,wBAAwB,QAAQ,OAAO;AACzD,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAEA,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,UAAU,CAAC,EAAE;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AACF;AAEO,SAAS,4BACd,eACA,aACA;AACA,QAAM;AAAA,IACJ;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,iBAAiB,oBAAI,IAAoB;AAE/C,QAAM,aAA6B,SAAS;AAAA,IAAI,CAAC,YAC/C,6BAA6B,SAAS,cAAc;AAAA,EACtD;AAGA,QAAM,aAAa,mBAAmB,WAAW;AAEjD,QAAM,mBAAkB,2CAAa,eACjC;AAAA,IACE,oBAAoB;AAAA,MAClB,YAAY,YAAY,YAAY;AAAA,MACpC,WAAW,YAAY,YAAY;AAAA,MACnC,gBAAgB,YAAY,YAAY;AAAA,IAC1C;AAAA,EACF,IACA;AAEJ,SAAO;AAAA,IACL,UAAU;AAAA,IACV,OAAO;AAAA,IACP;AAAA,IACA,iBAAiB;AAAA,IACjB,eAAe,uBAAuB,IAAI;AAAA,IAC1C,YAAY,oBAAoB,WAAW;AAAA,IAC3C,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,EAC/C;AACF;AAGO,SAAS,oBACd,QACkE;AAClE,MAAI,CAAC,QAAQ;AACX;AAAA,EACF;AACA,MAAI,WAAW,UAAU,WAAW,QAAQ;AAC1C,WAAO;AAAA,EACT;AACA,MAAI,OAAO,WAAW,YAAY,OAAO,SAAS,YAAY;AAC5D,WAAO,EAAE,MAAM,QAAQ,UAAU,OAAO,SAAS,KAAK;AAAA,EACxD;AACA;AACF;AAKO,SAAS,8BAA8B,WAO3C;AACD,SAAO,UAAU,IAAI,CAAC,UAAU;AAAA,IAC9B,IAAI,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,IACjE,MAAM;AAAA,IACN,UAAU;AAAA,MACR,MAAM,KAAK;AAAA,MACX,WAAW,KAAK,UAAU,KAAK,IAAI;AAAA,IACrC;AAAA,EACF,EAAE;AACJ;;;ACtaO,SAAS,qBAA6B;AAC3C,SAAO,YAAY,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AAC1E;AAEO,SAAS,sBAA8B;AAC5C,SAAO,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACrC;;;ACMO,SAAS,2BAEd,aACA,OACA,SAAS,OACW;AAjBtB;AAkBE,QAAM,UAA0B,CAAC;AAGjC,MAAI,YAAY,MAAM;AACpB,UAAM,SAAuB;AAAA,MAC3B,OAAO;AAAA,MACP,eAAe,YAAY,gBAAgB;AAAA,IAC7C;AAEA,QAAI,QAAQ;AACV,aAAO,QAAQ;AAAA,QACb,MAAM;AAAA,QACN,SAAS,YAAY;AAAA,MACvB;AAAA,IACF,OAAO;AACL,aAAO,UAAU;AAAA,QACf,MAAM;AAAA,QACN,SAAS,YAAY;AAAA,MACvB;AAAA,IACF;AACA,YAAQ,KAAK,MAAM;AAAA,EACrB;AAGA,MAAI,YAAY,aAAa,YAAY,UAAU,SAAS,GAAG;AAC7D,UAAM,SAAuB;AAAA,MAC3B,OAAO;AAAA,MACP,eAAe;AAAA,IACjB;AAEA,UAAM,mBAAkB,iBAAY,cAAZ,mBAAuB;AAAA,MAC7C,CAEE,UACI;AAAA,QACJ,IAAI,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,QACjE,MAAM;AAAA,QACN,UAAU;AAAA,UACR,MAAM,KAAK;AAAA,UACX,WAAW,KAAK,UAAU,KAAK,IAAI;AAAA,QACrC;AAAA,MACF;AAAA;AAGF,QAAI,QAAQ;AACV,aAAO,QAAQ;AAAA,QACb,MAAM;AAAA,QACN,YAAY;AAAA,MACd;AAAA,IACF,OAAO;AACL,aAAO,UAAU;AAAA,QACf,MAAM;AAAA,QACN,SAAS;AAAA,QACT,YAAY;AAAA,MACd;AAAA,IACF;AAEA,YAAQ,KAAK,MAAM;AAAA,EACrB;AAEA,QAAM,WAA+B;AAAA,IACnC,IAAI,mBAAmB;AAAA,IACvB,QAAQ,SAAS,0BAA0B;AAAA,IAC3C,SAAS,oBAAoB;AAAA,IAC7B;AAAA,IACA;AAAA,EACF;AAGA,MAAI,YAAY,OAAO;AACrB,aAAS,QAAQ;AAAA,MACf,eAAe,YAAY,MAAM,gBAAgB;AAAA,MACjD,mBAAmB,YAAY,MAAM,oBAAoB;AAAA,MACzD,cAAc,YAAY,MAAM,eAAe;AAAA,IACjD;AAAA,EACF;AAEA,SAAO;AACT;AAgCA,SAAS,qBACP,OACA,cACA,YACoB;AAEpB,MAAI;AAEJ,MAAI,iBAAiB,gBAAgB,iBAAiB,cAAc;AAClE,wBAAoB;AAAA,EACtB,WAAW,iBAAiB,QAAQ;AAClC,wBAAoB;AAAA,EACtB,WAAW,iBAAiB,UAAU;AACpC,wBAAoB;AAAA,EACtB,WAAW,iBAAiB,kBAAkB;AAC5C,wBAAoB;AAAA,EACtB,OAAO;AACL,wBAAoB;AAAA,EACtB;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR,SAAS,oBAAoB;AAAA,IAC7B;AAAA,IACA,SAAS;AAAA,MACP;AAAA,QACE,OAAO;AAAA,QACP,OAAO,CAAC;AAAA,QACR,eAAe;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAGA,SAAS,sBACP,OACA,SACA,YACA,cAAc,OACM;AACpB,QAAM,QAAiC,EAAE,MAAM,YAAY;AAE3D,MAAI,aAAa;AACf,UAAM,oBAAoB;AAAA,EAC5B,OAAO;AACL,UAAM,UAAU;AAAA,EAClB;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR,SAAS,oBAAoB;AAAA,IAC7B;AAAA,IACA,SAAS;AAAA,MACP;AAAA,QACE,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAGA,SAAS,uBACP,OACA,UACA,YACA,cAAc,OACM;AAtMtB;AAuME,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR,SAAS,oBAAoB;AAAA,IAC7B;AAAA,IACA,SAAS;AAAA,MACP;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,UACL,GAAI,cAAc,EAAE,MAAM,YAAqB,IAAI,CAAC;AAAA,UACpD,YAAY;AAAA,YACV;AAAA,cACE,OAAO,SAAS,SAAS;AAAA,cACzB,MAAM;AAAA,cACN,UAAU;AAAA,gBACR,QAAM,cAAS,aAAT,mBAAmB,SAAQ;AAAA,gBACjC,aAAW,cAAS,aAAT,mBAAmB,cAAa;AAAA,cAC7C;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAIO,SAAS,4BACd,OACA,SAGA;AACA,MAAI,qBAAqB;AACzB,MAAI,mBAAmB;AACvB,MAAI,mBAAmB,mBAAmB;AAE1C,QAAM,YACJ,mCAAS,eAAc,QACnB,SACA,CAAC,UAAmB;AAClB,UAAM,UACJ,QAAQ,IAAI,mBAAmB,SAAS,eAAe;AACzD,YAAQ;AAAA,MACN,2BAAoB,OAAO;AAAA,MAC3B,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,IAC/B;AAAA,EACF;AAEN,QAAM,WAAyC;AAAA,IAC7C,OAAO,MAAM,CAAC;AAAA,IACd,mBAAmB,CAAC,UAAU;AAC5B,UAAI,CAAC,MAAM,MAAM;AACf,eAAO,CAAC;AAAA,MACV;AACA,aAAO;AAAA,QACL;AAAA,UACE,MAAM,KAAK;AAAA,YACT,sBAAsB,OAAO,MAAM,MAAM,kBAAkB,IAAI;AAAA,UACjE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,cAAc,CAAC,UAAU;AACvB,UAAI,CAAC,MAAM,MAAM;AACf,eAAO,CAAC;AAAA,MACV;AACA,aAAO;AAAA,QACL;AAAA,UACE,MAAM,KAAK;AAAA,YACT,sBAAsB,OAAO,MAAM,MAAM,kBAAkB,KAAK;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,aAAa,CAAC,UAAU;AAnR5B;AAoRM,YAAM,aAAa,MAAM,cAAc,QAAQ,mBAAmB,CAAC;AACnE,YAAM,WAAW,MAAM,YAAY;AACnC,YAAM,aACJ,OAAO,MAAM,UAAU,WACnB,MAAM,QACN,KAAK,WAAU,WAAM,UAAN,YAAe,CAAC,CAAC;AACtC,YAAM,gBAAyC;AAAA,QAC7C,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,UAAU,EAAE,MAAM,UAAU,WAAW,WAAW;AAAA,MACpD;AACA,YAAM,WAAW;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO,CAAC,EAAE,MAAM,KAAK,UAAU,QAAQ,EAAE,CAAC;AAAA,IAC5C;AAAA,IACA,iBAAiB,MAAM,CAAC;AAAA,IACxB,YAAY,MAAM,CAAC;AAAA,IACnB,eAAe,CAAC,UAAU;AACxB,UAAI,kBAAkB;AACpB,eAAO,CAAC;AAAA,MACV;AACA,YAAM,eAAe;AACrB,UAAI,eAAe,MAAM,gBAAgB;AACzC,UAAI,iBAAiB,gBAAgB,iBAAiB,cAAc;AAClE,uBAAe;AAAA,MACjB;AACA,YAAM,iBAAiB,eAAe,eAAe;AACrD,yBAAmB;AACnB,2BAAqB;AACrB,aAAO;AAAA,QACL;AAAA,UACE,MAAM,KAAK;AAAA,YACT,qBAAqB,OAAO,gBAAgB,gBAAgB;AAAA,UAC9D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,mBAAmB,CAAC,UAAU;AAC5B,YAAM,WAAW;AAAA,QACf,OAAO,MAAM,aAAa,OAAO,MAAM,UAAU,IAAI;AAAA,QACrD,MAAM;AAAA,QACN,UAAU;AAAA,UACR,MAAM,MAAM,YAAY;AAAA,UACxB,WAAW,MAAM,QAAQ;AAAA,QAC3B;AAAA,MACF;AACA,aAAO;AAAA,QACL;AAAA,UACE,MAAM,KAAK;AAAA,YACT,uBAAuB,OAAO,UAAU,gBAAgB;AAAA,UAC1D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,eAAe,CAAC,UAAU;AACxB,YAAM,aAAa;AAAA,SAAY,MAAM,QAAQ,aAAa,KAAK,UAAU,MAAM,MAAM,CAAC;AAAA;AACtF,aAAO;AAAA,QACL;AAAA,UACE,MAAM,KAAK;AAAA,YACT,sBAAsB,OAAO,YAAY,kBAAkB,KAAK;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,QAAQ,CAAC,UAAU;AACjB,UAAI,kBAAkB;AACpB,eAAO,CAAC;AAAA,MACV;AACA,YAAM,eAAe;AACrB,UAAI,eAAe,MAAM,gBAAgB;AACzC,UAAI,iBAAiB,gBAAgB,iBAAiB,cAAc;AAClE,uBAAe;AAAA,MACjB;AACA,YAAM,iBAAiB,eAAe,eAAe;AACrD,yBAAmB;AACnB,2BAAqB;AACrB,aAAO;AAAA,QACL;AAAA,UACE,MAAM,KAAK;AAAA,YACT,qBAAqB,OAAO,gBAAgB,gBAAgB;AAAA,UAC9D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,CAEL,UACkB;AAlXtB;AAmXI,UAAM,MAAqB,CAAC;AAE5B,yCAAW;AAEX,QAAI,MAAM,SAAS,SAAS;AAC1B,2BAAqB;AACrB,yBAAmB;AACnB,0BAAmB,WAAM,OAAN,YAAY,mBAAmB;AAAA,IACpD;AAEA,UAAM,UAAU,SAAS,MAAM,IAAI;AACnC,QAAI,SAAS;AACX,YAAM,SAAS,QAAQ,OAAwB,KAAK;AACpD,UAAI,MAAM,SAAS,eAAe,MAAM,SAAS,mBAAmB;AAClE,6BAAqB;AAAA,MACvB;AACA,UAAI,KAAK,GAAG,MAAM;AAAA,IACpB,OAAO;AACL,cAAQ,KAAK,2CAAiC,MAAM,IAAI,IAAI,KAAK;AAAA,IACnE;AAEA,QAAI,MAAM,SAAS,iBAAiB,MAAM,SAAS,UAAU;AAC3D,2BAAqB;AAAA,IACvB;AAEA,WAAO,IAAI,OAAO,CAAC,gBAAgB;AA5YvC,UAAAA,KAAA;AA6YM,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,YAAY,IAAI;AAC1C,cAAM,SAAQ,MAAAA,MAAA,OAAO,YAAP,gBAAAA,IAAiB,OAAjB,mBAAqB;AACnC,eACE,UACC,MAAM,QACL,MAAM,WACL,MAA6C,qBAC7C,MAAM,cAAc,MAAM,WAAW,SAAS,OAC/C,kBAAO,YAAP,mBAAiB,OAAjB,mBAAqB;AAAA,MAE3B,SAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,gCAEd,OACA,OACe;AACf,QAAM,UAAU,4BAA4B,KAAK;AACjD,SAAO,QAAQ,KAAK;AACtB;AAKO,SAAS,kBAAkB,QAA+B;AAC/D,SAAO,OAAO,IAAI,CAAC,UAAU,SAAS,MAAM,IAAI;AAAA;AAAA,CAAM,EAAE,KAAK,EAAE;AACjE;;;AC7aA,4BAA0B;AAC1B,kBAAiB;AACjB,gBAAyC;AACzC,qBAIO;AACP,IAAAC,cAA8C;AAe9C,SAAS,mBAAmB,QAAyC;AACnE,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAGA,QAAM,iBAAa,0BAAa,QAAQ;AAAA,IACtC,iBAAiB;AAAA,EACnB,CAAC;AAGD,MAAI,OAAO,eAAe,YAAY,eAAe,MAAM;AACzD,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,UAAyC;AAClE,SAAO,SAAS,IAAI,CAAC,SAAS,WAAW;AAAA,IACvC;AAAA,IACA,MAAM,QAAQ;AAAA,IACd,SAAS,QAAQ;AAAA,IACjB,WAAW,QAAQ;AAAA,EACrB,EAAE;AACJ;AAEA,SAAS,mBACP,eACA,SACA;AAtDF;AAuDE,MAAI,CAAC,SAAS;AACZ;AAAA,EACF;AACA,QAAM,cAAa,mBAAc,UAAd,YAAuB,CAAC,GACxC,IAAI,CAAC,SAAM;AA3DhB,QAAAC;AA2DoB,yBAAc,QAAOA,MAAA,KAAK,aAAL,gBAAAA,IAAe,OAAO;AAAA,GAAU,EACpE,OAAO,CAAC,SAAyB,QAAQ,IAAI,CAAC;AAEjD,UAAQ;AAAA,IACN;AAAA,IACA,KAAK;AAAA,MACH;AAAA,QACE,OAAO,cAAc;AAAA,QACrB,QAAQ,QAAQ,cAAc,MAAM;AAAA,QACpC,aAAa,cAAc;AAAA,QAC3B,WAAW,cAAc;AAAA,QACzB;AAAA,QACA,YAAY,cAAc;AAAA,QAC1B,UAAU,kBAAkB,cAAc,QAAQ;AAAA,QAClD,OAAO,cAAc;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,UAAuC;AACrE,SAAO,qCAAU,IAAI,CAAC,SAAS,WAAW;AAAA,IACxC;AAAA,IACA,MAAM,QAAQ;AAAA,IACd,SAAS,QAAQ;AAAA,EACnB;AACF;AAEA,SAAS,qBACP,eACA,aACA,SACA;AA7FF;AA8FE,MAAI,CAAC,SAAS;AACZ;AAAA,EACF;AACA,QAAM,YAAW,iBAAY,aAAZ,YAAwB,CAAC;AAC1C,UAAQ;AAAA,IACN;AAAA,IACA,KAAK;AAAA,MACH;AAAA,QACE,OAAO,cAAc;AAAA,QACrB,kBAAkB,SAAS,KAAK,CAAC,YAAY,QAAQ,SAAS,QAAQ;AAAA,QACtE,UAAU,uBAAuB,QAAQ;AAAA,QACzC,OAAO,OAAO,SAAQ,iBAAY,UAAZ,YAAqB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO;AAAA,UACpE;AAAA,UACA,aAAa,KAAK;AAAA,UAClB,aAAa,mBAAmB,KAAK,WAAW;AAAA,QAClD,EAAE;AAAA,QACF,aAAa,YAAY;AAAA,QACzB,iBAAiB,YAAY;AAAA,QAC7B,eAAe,YAAY;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,oBAAN,MAAwB;AAAA,EAK7B,YAAY,QAAqB;AA7HnC;AA8HI,SAAK,SAAS;AAAA,MACZ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,GAAG;AAAA,IACL;AACA,SAAK,UAAU,YAAO,WAAP,YAAiB;AAEhC,SAAK,cAAU,eAAAC,SAAQ;AAGvB,QAAI,KAAK,OAAO,MAAM;AACpB,WAAK,QAAQ,SAAS,YAAAC,OAAI;AAAA,IAC5B;AAEA,SAAK,YAAY;AAAA,EACnB;AAAA,EAEQ,cAAoB;AAE1B,SAAK,QAAQ;AAAA,MACX;AAAA,MACA,OAAO,UAA0B,YAA0B;AAAA,QACzD,QAAQ;AAAA,QACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC;AAAA,IACF;AAGA,SAAK,QAAQ;AAAA,MACX;AAAA,MACA,CAAC,SAAyB,UAAwB;AA7JxD;AA8JQ,YAAI;AACF,gBAAM,gBAAgB,QAAQ;AAG9B,cACE,EAAE,cAAc,YAAY,MAAM,QAAQ,cAAc,QAAQ,IAChE;AACA,mBAAO,MAAM,KAAK,GAAG,EAAE,KAAK;AAAA,cAC1B,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,MAAM;AAAA,cACR;AAAA,YACF,CAAC;AAAA,UACH;AAEA;AAAA,YACE;AAAA,aACA,gBAAK,OAAO,YAAZ,mBAAqB,aAArB,YAAiC;AAAA,UACnC;AAGA,gBAAM,cAAc,4BAA4B,eAAe;AAAA,YAC7D,aAAa,KAAK,OAAO;AAAA,UAC3B,CAAC;AACD;AAAA,YACE;AAAA,YACA;AAAA,aACA,gBAAK,OAAO,YAAZ,mBAAqB,gBAArB,YAAoC;AAAA,UACtC;AAGA,cAAI,cAAc,QAAQ;AACxB,mBAAO,KAAK;AAAA,cACV;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AACA,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AACd,eAAK,OAAO,MAAM,2BAA2B,KAAK;AAClD,iBAAO,MAAM,KAAK,GAAG,EAAE,KAAK;AAAA,YAC1B,OAAO;AAAA,cACL,SAAS;AAAA,cACT,MAAM;AAAA,YACR;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,SAAK,QAAQ,IAAI,cAAc,aAAa;AAAA,MAC1C,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ;AAAA,UACE,IAAI;AAAA,UACJ,QAAQ;AAAA,UACR,SAAS,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,UACrC,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AAAA;AAAA;AAAA,EAIQ,WACN,aACA,cACA;AACA,UAAM,iBAAiB,CAAC,SAAyC;AAC/D,UAAI,CAAC,MAAM;AACT;AAAA,MACF;AAEA,aAAO;AAAA,QACL,aAAa,KAAK;AAAA,QAClB,iBAAa,iCAAU,KAAK,WAAW;AAAA,QACvC,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,MAClD;AAAA,IACF;AAEA,UAAM,SAAkC,CAAC;AAEzC,eAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,sCAAgB,CAAC,CAAC,GAAG;AAC1D,YAAM,KAAK,eAAe,CAAC;AAC3B,UAAI,IAAI;AACN,eAAO,IAAI,IAAI;AAAA,MACjB;AAAA,IACF;AAEA,eAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,oCAAe,CAAC,CAAC,GAAG;AACzD,YAAM,KAAK,eAAe,CAAC;AAC3B,UAAI,IAAI;AACN,eAAO,IAAI,IAAI;AAAA,MACjB;AAAA,IACF;AAEA,WAAO,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,SAAS;AAAA,EACnD;AAAA,EAEA,MAAc,uBAEZ,aACA,eACA,OACe;AA7QnB;AA+QI,UAAM,IAAI,UAAU,KAAK;AAAA,MACvB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,YAAY;AAAA,MACZ,+BAA+B;AAAA,IACjC,CAAC;AAED,QAAI;AACF,YAAM,cAAc,KAAK,WAAW,KAAK,OAAO,OAAO,YAAY,KAAK;AACxE,YAAM,SAAS,UAAM,sBAAW;AAAA,QAC9B,OAAO,KAAK,OAAO;AAAA,QACnB,GAAG;AAAA,QACH,GAAI,cAAc,EAAE,OAAO,YAAY,IAAI,CAAC;AAAA,MAC9C,CAAC;AAED,YAAM,UAAU,4BAA4B,cAAc,OAAO;AAAA,QAC/D,YAAW,gBAAK,OAAO,YAAZ,mBAAqB,iBAArB,YAAqC;AAAA,MAClD,CAAC;AACD,uBAAiB,SAAS,OAAO,YAAY;AAC3C,cAAM,eAAe,QAAQ,KAAK;AAClC,mBAAW,eAAe,cAAc;AACtC,gBAAM,IAAI,MAAM,SAAS,YAAY,IAAI;AAAA;AAAA,CAAM;AAAA,QACjD;AAAA,MACF;AAEA,YAAM,IAAI,MAAM,kBAAkB;AAClC,YAAM,IAAI,IAAI;AAAA,IAChB,SAAS,OAAO;AACd,WAAK,OAAO,MAAM,oBAAoB,KAAK;AAC3C,YAAM,IAAI,MAAM,qDAAqD;AACrE,YAAM,IAAI,IAAI;AAAA,IAChB;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,0BAEZ,aACA,eACA,OACe;AACf,QAAI;AACF,YAAM,cAAc,KAAK,WAAW,KAAK,OAAO,OAAO,YAAY,KAAK;AACxE,YAAM,SAAS,UAAM,wBAAa;AAAA,QAChC,OAAO,KAAK,OAAO;AAAA,QACnB,GAAG;AAAA,QACH,GAAI,cAAc,EAAE,OAAO,YAAY,IAAI,CAAC;AAAA,MAC9C,CAAC;AAED,YAAM,iBAAiB;AAAA,QACrB;AAAA,QACA,cAAc;AAAA,QACd;AAAA,MACF;AAEA,YAAM,KAAK,cAAc;AAAA,IAC3B,SAAS,OAAO;AACd,WAAK,OAAO,MAAM,qBAAqB,KAAK;AAC5C,aAAO,MAAM,KAAK,GAAG,EAAE,KAAK;AAAA,QAC1B,OAAO;AAAA,UACL,SAAS;AAAA,UACT,MAAM;AAAA,QACR;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI;AACF,YAAM,KAAK,QAAQ,OAAO;AAAA,QACxB,MAAM,KAAK,OAAO,QAAQ;AAAA,QAC1B,MAAM,KAAK,OAAO,QAAQ;AAAA,MAC5B,CAAC;AAED,WAAK,OAAO;AAAA,QACV,mDAA4C,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI;AAAA,MAClF;AACA,WAAK,OAAO;AAAA,QACV,8BAAuB,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI;AAAA,MAC7D;AACA,WAAK,OAAO;AAAA,QACV,4BAAqB,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI;AAAA,MAC3D;AAAA,IACF,SAAS,OAAO;AACd,WAAK,OAAO,MAAM,2BAA2B,KAAK;AAClD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI;AACF,YAAM,KAAK,QAAQ,MAAM;AACzB,WAAK,OAAO,KAAK,0BAAmB;AAAA,IACtC,SAAS,OAAO;AACd,WAAK,OAAO,MAAM,0BAA0B,KAAK;AAAA,IACnD;AAAA,EACF;AACF;","names":["_a","import_zod","_a","Fastify","cors"]}
|
package/dist/index.js
CHANGED
|
@@ -249,7 +249,7 @@ function mapOpenAIToolChoice(choice) {
|
|
|
249
249
|
}
|
|
250
250
|
function convertAISDKToolCallsToOpenAI(toolCalls) {
|
|
251
251
|
return toolCalls.map((call) => ({
|
|
252
|
-
id: `call_${Date.now()}_${Math.random().toString(36).
|
|
252
|
+
id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`,
|
|
253
253
|
type: "function",
|
|
254
254
|
function: {
|
|
255
255
|
name: call.toolName,
|
|
@@ -260,7 +260,7 @@ function convertAISDKToolCallsToOpenAI(toolCalls) {
|
|
|
260
260
|
|
|
261
261
|
// src/response-utils.ts
|
|
262
262
|
function generateResponseId() {
|
|
263
|
-
return `chatcmpl-${Date.now()}-${Math.random().toString(36).
|
|
263
|
+
return `chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
264
264
|
}
|
|
265
265
|
function getCurrentTimestamp() {
|
|
266
266
|
return Math.floor(Date.now() / 1e3);
|
|
@@ -295,7 +295,7 @@ function convertAISDKResultToOpenAI(aisdkResult, model, stream = false) {
|
|
|
295
295
|
};
|
|
296
296
|
const openAIToolCalls = (_a = aisdkResult.toolCalls) == null ? void 0 : _a.map(
|
|
297
297
|
(call) => ({
|
|
298
|
-
id: `call_${Date.now()}_${Math.random().toString(36).
|
|
298
|
+
id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`,
|
|
299
299
|
type: "function",
|
|
300
300
|
function: {
|
|
301
301
|
name: call.toolName,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/openai-request-converter.ts","../src/response-utils.ts","../src/response-converter.ts","../src/server.ts"],"sourcesContent":["import type {\n ModelMessage,\n ToolContent,\n ToolResultOutput,\n} from \"@ai-sdk/provider-utils\";\nimport { z } from \"zod\";\nimport type {\n OpenAIChatRequest,\n OpenAICompleteToolCall,\n OpenAIMessage,\n ProxyConfig,\n} from \"./types.js\";\n\n// Type definitions for OpenAI tool parameters\ninterface OpenAIToolProperty {\n type: string;\n description?: string;\n enum?: string[];\n}\n\ninterface OpenAIToolParameters {\n type: string;\n properties?: Record<string, OpenAIToolProperty>;\n required?: string[];\n}\n\n// Type for AI SDK tool definition\ninterface AISDKTool {\n description: string;\n inputSchema: z.ZodTypeAny;\n}\n\n// Type for tool call object\ninterface ToolCall {\n toolName: string;\n args: unknown;\n}\n\n/**\n * Create Zod schema for OpenAI tool property\n */\nfunction createZodSchema(prop: OpenAIToolProperty): z.ZodTypeAny {\n if (prop.type === \"string\") {\n return prop.enum ? z.enum(prop.enum as [string, ...string[]]) : z.string();\n }\n if (prop.type === \"number\") {\n return z.number();\n }\n if (prop.type === \"boolean\") {\n return z.boolean();\n }\n if (prop.type === \"array\") {\n return z.array(z.any());\n }\n if (prop.type === \"object\") {\n return z.object({});\n }\n return z.any();\n}\n\n/**\n * Convert OpenAI tool schema to Zod schema\n */\nfunction convertOpenAIToolToZod(\n parameters: Record<string, unknown> | undefined\n): z.ZodObject<Record<string, z.ZodTypeAny>> {\n if (!parameters) {\n return z.object({});\n }\n\n const params = parameters as unknown as OpenAIToolParameters;\n if (!params.properties) {\n return z.object({});\n }\n\n const schemaShape: Record<string, z.ZodTypeAny> = {};\n for (const [key, prop] of Object.entries(params.properties)) {\n schemaShape[key] = createZodSchema(prop);\n }\n\n return z.object(schemaShape);\n}\n\n/**\n * Convert OpenAI tools to AI SDK format\n */\nfunction convertOpenAITools(\n openaiTools:\n | Array<{\n function: {\n name: string;\n description?: string;\n parameters: Record<string, unknown>;\n };\n }>\n | undefined\n): Record<string, AISDKTool> {\n const aisdkTools: Record<string, AISDKTool> = {};\n\n if (!openaiTools) {\n return aisdkTools;\n }\n\n for (const openaiTool of openaiTools) {\n const toolName = openaiTool.function.name;\n aisdkTools[toolName] = {\n description: openaiTool.function.description || \"\",\n inputSchema: convertOpenAIToolToZod(openaiTool.function.parameters),\n };\n }\n\n return aisdkTools;\n}\n\n/**\n * Convert stop parameter to stop sequences\n */\nfunction convertStopToSequences(\n stop: string | string[] | undefined\n): string[] | undefined {\n if (!stop) {\n return;\n }\n return Array.isArray(stop) ? stop : [stop];\n}\n\ninterface AITextPart {\n type: \"text\";\n text: string;\n}\ninterface AIToolCallPart {\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n input: unknown;\n}\ntype TextToolOutput = Extract<ToolResultOutput, { type: \"text\" }>;\ntype JsonToolOutput = Extract<ToolResultOutput, { type: \"json\" }>;\n\n/**\n * Convert OpenAI chat completion request to AI SDK format\n */\nexport function normalizeMessageContent(\n content: OpenAIMessage[\"content\"]\n): AITextPart[] {\n if (typeof content === \"string\") {\n return content ? [{ type: \"text\" as const, text: content }] : [];\n }\n\n if (Array.isArray(content)) {\n const parts = content as Array<string | { text?: unknown }>;\n return parts\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n }\n if (part && typeof part === \"object\" && \"text\" in part) {\n const textValue = part.text;\n if (typeof textValue === \"string\") {\n return textValue;\n }\n if (textValue !== undefined) {\n return JSON.stringify(textValue);\n }\n }\n return JSON.stringify(part);\n })\n .filter((text): text is string => Boolean(text))\n .map((text) => ({ type: \"text\" as const, text }));\n }\n\n if (content === null || content === undefined) {\n return [];\n }\n\n if (typeof content === \"object\") {\n return [{ type: \"text\" as const, text: JSON.stringify(content) }];\n }\n\n return [{ type: \"text\" as const, text: String(content) }];\n}\n\nfunction buildToolCallParts(\n toolCalls: OpenAICompleteToolCall[]\n): AIToolCallPart[] {\n return toolCalls.map((toolCall) => {\n let parsedArgs: unknown = toolCall.function.arguments;\n if (typeof toolCall.function.arguments === \"string\") {\n try {\n parsedArgs = JSON.parse(toolCall.function.arguments || \"{}\");\n } catch {\n parsedArgs = toolCall.function.arguments;\n }\n }\n\n return {\n type: \"tool-call\" as const,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input: parsedArgs,\n } satisfies AIToolCallPart;\n });\n}\n\nfunction buildAssistantContent(\n message: OpenAIMessage & { role: \"assistant\" }\n): Array<AITextPart | AIToolCallPart> | string {\n const textParts = normalizeMessageContent(message.content);\n const toolCallParts = message.tool_calls?.length\n ? buildToolCallParts(message.tool_calls)\n : [];\n\n if (toolCallParts.length === 0) {\n if (textParts.length === 0) {\n return \"\";\n }\n if (textParts.length === 1) {\n return textParts[0].text;\n }\n return textParts;\n }\n\n return [...textParts, ...toolCallParts];\n}\n\nfunction isJsonValue(value: unknown): value is JsonToolOutput[\"value\"] {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every(isJsonValue);\n }\n\n if (typeof value === \"object\") {\n return Object.values(value as Record<string, unknown>).every(isJsonValue);\n }\n\n return false;\n}\n\nfunction buildToolOutput(rawValue: string): ToolResultOutput {\n if (!rawValue) {\n return { type: \"text\", value: \"\" } satisfies TextToolOutput;\n }\n\n try {\n const parsed = JSON.parse(rawValue);\n if (isJsonValue(parsed)) {\n return { type: \"json\", value: parsed } satisfies JsonToolOutput;\n }\n } catch {\n // Fall through to text output below\n }\n\n return { type: \"text\", value: rawValue } satisfies TextToolOutput;\n}\n\nfunction buildToolContent(\n message: OpenAIMessage & { role: \"tool\" },\n toolNameLookup: Map<string, string>\n): ToolContent {\n const textParts = normalizeMessageContent(message.content);\n const combined = textParts.map((part) => part.text).join(\"\\n\");\n const toolCallId = message.tool_call_id ?? \"\";\n const toolName = toolCallId\n ? (toolNameLookup.get(toolCallId) ?? toolCallId)\n : \"\";\n\n return [\n {\n type: \"tool-result\",\n toolCallId,\n toolName,\n output: buildToolOutput(combined),\n },\n ];\n}\n\nfunction convertMessageToModelMessage(\n message: OpenAIMessage,\n toolNameLookup: Map<string, string>\n): ModelMessage {\n if (message.role === \"assistant\") {\n if (message.tool_calls?.length) {\n for (const toolCall of message.tool_calls) {\n toolNameLookup.set(toolCall.id, toolCall.function.name);\n }\n }\n\n return {\n role: \"assistant\",\n content: buildAssistantContent(\n message as OpenAIMessage & { role: \"assistant\" }\n ),\n };\n }\n\n if (message.role === \"tool\") {\n return {\n role: \"tool\",\n content: buildToolContent(\n message as OpenAIMessage & { role: \"tool\" },\n toolNameLookup\n ),\n };\n }\n\n if (message.role === \"system\") {\n const text = normalizeMessageContent(message.content)\n .map((part) => part.text)\n .join(\"\\n\");\n return {\n role: \"system\",\n content: text,\n };\n }\n\n const userParts = normalizeMessageContent(message.content);\n if (userParts.length === 0) {\n return {\n role: \"user\",\n content: \"\",\n };\n }\n\n if (userParts.length === 1) {\n return {\n role: \"user\",\n content: userParts[0].text,\n };\n }\n\n return {\n role: \"user\",\n content: userParts,\n };\n}\n\nexport function convertOpenAIRequestToAISDK(\n openaiRequest: OpenAIChatRequest,\n proxyConfig?: Pick<ProxyConfig, \"parserDebug\">\n) {\n const {\n messages,\n tools: openaiTools,\n temperature,\n max_tokens,\n stop,\n tool_choice,\n } = openaiRequest;\n\n const toolNameLookup = new Map<string, string>();\n\n const aiMessages: ModelMessage[] = messages.map((message) =>\n convertMessageToModelMessage(message, toolNameLookup)\n );\n\n // Convert OpenAI tools to AI SDK format dynamically\n const aisdkTools = convertOpenAITools(openaiTools);\n\n const providerOptions = proxyConfig?.parserDebug\n ? {\n toolCallMiddleware: {\n debugLevel: proxyConfig.parserDebug.level,\n logErrors: proxyConfig.parserDebug.logErrors,\n captureSummary: proxyConfig.parserDebug.captureSummary,\n },\n }\n : undefined;\n\n return {\n messages: aiMessages,\n tools: aisdkTools,\n temperature,\n maxOutputTokens: max_tokens,\n stopSequences: convertStopToSequences(stop),\n toolChoice: mapOpenAIToolChoice(tool_choice),\n ...(providerOptions ? { providerOptions } : {}),\n };\n}\n\n// Map OpenAI tool_choice to AI SDK toolChoice\nexport function mapOpenAIToolChoice(\n choice: OpenAIChatRequest[\"tool_choice\"]\n): \"auto\" | \"none\" | { type: \"tool\"; toolName: string } | undefined {\n if (!choice) {\n return;\n }\n if (choice === \"auto\" || choice === \"none\") {\n return choice;\n }\n if (typeof choice === \"object\" && choice.type === \"function\") {\n return { type: \"tool\", toolName: choice.function.name };\n }\n return;\n}\n\n/**\n * Convert AI SDK tool calls to OpenAI format\n */\nexport function convertAISDKToolCallsToOpenAI(toolCalls: ToolCall[]): Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n}> {\n return toolCalls.map((call) => ({\n id: `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n type: \"function\" as const,\n function: {\n name: call.toolName,\n arguments: JSON.stringify(call.args),\n },\n }));\n}\n","export function generateResponseId(): string {\n return `chatcmpl-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\nexport function getCurrentTimestamp(): number {\n return Math.floor(Date.now() / 1000);\n}\n","import { generateResponseId, getCurrentTimestamp } from \"./response-utils.js\";\nimport type {\n OpenAIChatResponse,\n OpenAIChoice,\n OpenAIStreamingToolCall,\n OpenAIUsage,\n StreamChunk,\n} from \"./types.js\";\n\n/**\n * Convert AI SDK result to OpenAI chat completion response\n */\nexport function convertAISDKResultToOpenAI(\n // biome-ignore lint/suspicious/noExplicitAny: AI sdk integration boundary\n aisdkResult: any,\n model: string,\n stream = false\n): OpenAIChatResponse {\n const choices: OpenAIChoice[] = [];\n\n // Handle text content\n if (aisdkResult.text) {\n const choice: OpenAIChoice = {\n index: 0,\n finish_reason: aisdkResult.finishReason || \"stop\",\n };\n\n if (stream) {\n choice.delta = {\n role: \"assistant\",\n content: aisdkResult.text,\n };\n } else {\n choice.message = {\n role: \"assistant\",\n content: aisdkResult.text,\n };\n }\n choices.push(choice);\n }\n\n // Handle tool calls\n if (aisdkResult.toolCalls && aisdkResult.toolCalls.length > 0) {\n const choice: OpenAIChoice = {\n index: 0,\n finish_reason: \"tool_calls\",\n };\n\n const openAIToolCalls = aisdkResult.toolCalls?.map(\n (\n // biome-ignore lint/suspicious/noExplicitAny: AI SDK integration boundary\n call: any\n ) => ({\n id: `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n type: \"function\" as const,\n function: {\n name: call.toolName,\n arguments: JSON.stringify(call.args),\n },\n })\n );\n\n if (stream) {\n choice.delta = {\n role: \"assistant\",\n tool_calls: openAIToolCalls,\n };\n } else {\n choice.message = {\n role: \"assistant\",\n content: null,\n tool_calls: openAIToolCalls,\n };\n }\n\n choices.push(choice);\n }\n\n const response: OpenAIChatResponse = {\n id: generateResponseId(),\n object: stream ? \"chat.completion.chunk\" : \"chat.completion\",\n created: getCurrentTimestamp(),\n model,\n choices,\n };\n\n // Add usage if available\n if (aisdkResult.usage) {\n response.usage = {\n prompt_tokens: aisdkResult.usage.promptTokens || 0,\n completion_tokens: aisdkResult.usage.completionTokens || 0,\n total_tokens: aisdkResult.usage.totalTokens || 0,\n } as OpenAIUsage;\n }\n\n return response;\n}\n\n/**\n * Convert AI SDK stream chunk to OpenAI SSE format\n */\n\n// Type definitions for better type safety\ninterface ToolCallDelta {\n index?: number;\n id?: string;\n type?: \"function\";\n function?: {\n name?: string;\n arguments?: string;\n };\n}\n\ninterface AIStreamChunk {\n type: string;\n id?: string;\n text?: string;\n toolCallId?: string;\n toolName?: string;\n args?: string;\n input?: Record<string, unknown>;\n finishReason?: string;\n [key: string]: unknown;\n}\n\ntype ChunkHandler = (chunk: AIStreamChunk, model: string) => StreamChunk[];\n\n// Helper function to create finish response\nfunction createFinishResponse(\n model: string,\n finishReason: string,\n responseId: string\n): OpenAIChatResponse {\n // Ensure finish reason matches OpenAI's allowed types\n let validFinishReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\";\n\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n validFinishReason = \"tool_calls\";\n } else if (finishReason === \"stop\") {\n validFinishReason = \"stop\";\n } else if (finishReason === \"length\") {\n validFinishReason = \"length\";\n } else if (finishReason === \"content_filter\") {\n validFinishReason = \"content_filter\";\n } else {\n validFinishReason = \"stop\"; // fallback to \"stop\" for unknown reasons\n }\n\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta: {},\n finish_reason: validFinishReason,\n },\n ],\n };\n}\n\n// Helper function to create content response\nfunction createContentResponse(\n model: string,\n content: string,\n responseId: string,\n isReasoning = false\n): OpenAIChatResponse {\n const delta: Record<string, unknown> = { role: \"assistant\" };\n\n if (isReasoning) {\n delta.reasoning_content = content;\n } else {\n delta.content = content;\n }\n\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta,\n },\n ],\n };\n}\n\n// Helper function to create tool call response\nfunction createToolCallResponse(\n model: string,\n toolCall: ToolCallDelta,\n responseId: string,\n includeRole = false\n): OpenAIChatResponse {\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta: {\n ...(includeRole ? { role: \"assistant\" as const } : {}),\n tool_calls: [\n {\n index: toolCall.index || 0,\n type: \"function\" as const,\n function: {\n name: toolCall.function?.name || \"\",\n arguments: toolCall.function?.arguments || \"\",\n },\n },\n ],\n },\n },\n ],\n };\n}\n\n// (legacy stateless handler removed)\n\nexport function createOpenAIStreamConverter(\n model: string,\n options?: {\n logChunks?: boolean;\n }\n) {\n let streamHasToolCalls = false;\n let streamFinishSent = false;\n let streamResponseId = generateResponseId();\n\n const logChunk =\n options?.logChunks === false\n ? undefined\n : (chunk: unknown) => {\n const logType =\n process.env.USE_MIDDLEWARE === \"true\" ? \"middleware\" : \"native\";\n console.log(\n `🔍 AI SDK Chunk [${logType}]:`,\n JSON.stringify(chunk, null, 2)\n );\n };\n\n const handlers: Record<string, ChunkHandler> = {\n start: () => [],\n \"reasoning-delta\": (chunk) => {\n if (!chunk.text) {\n return [];\n }\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, chunk.text, streamResponseId, true)\n ),\n },\n ];\n },\n \"text-delta\": (chunk) => {\n if (!chunk.text) {\n return [];\n }\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, chunk.text, streamResponseId, false)\n ),\n },\n ];\n },\n \"tool-call\": (chunk) => {\n const toolCallId = chunk.toolCallId || `call_${generateResponseId()}`;\n const toolName = chunk.toolName || \"\";\n const argsString =\n typeof chunk.input === \"string\"\n ? chunk.input\n : JSON.stringify(chunk.input ?? {});\n const toolCallDelta: OpenAIStreamingToolCall = {\n index: 0,\n id: toolCallId,\n type: \"function\",\n function: { name: toolName, arguments: argsString },\n };\n const response = createToolCallResponse(\n model,\n toolCallDelta,\n streamResponseId,\n true\n );\n return [{ data: JSON.stringify(response) }];\n },\n \"reasoning-end\": () => [],\n \"text-end\": () => [],\n \"finish-step\": (chunk) => {\n if (streamFinishSent) {\n return [];\n }\n const hadToolCalls = streamHasToolCalls;\n let finishReason = chunk.finishReason || \"stop\";\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n finishReason = \"tool_calls\";\n }\n const resolvedReason = hadToolCalls ? \"tool_calls\" : finishReason;\n streamFinishSent = true;\n streamHasToolCalls = false;\n return [\n {\n data: JSON.stringify(\n createFinishResponse(model, resolvedReason, streamResponseId)\n ),\n },\n ];\n },\n \"tool-call-delta\": (chunk) => {\n const toolCall = {\n index: chunk.toolCallId ? Number(chunk.toolCallId) : 0,\n type: \"function\" as const,\n function: {\n name: chunk.toolName || \"\",\n arguments: chunk.args || \"\",\n },\n };\n return [\n {\n data: JSON.stringify(\n createToolCallResponse(model, toolCall, streamResponseId)\n ),\n },\n ];\n },\n \"tool-result\": (chunk) => {\n const resultText = `\\n[Tool: ${chunk.toolName} returned ${JSON.stringify(chunk.output)}]\\n`;\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, resultText, streamResponseId, false)\n ),\n },\n ];\n },\n finish: (chunk) => {\n if (streamFinishSent) {\n return [];\n }\n const hadToolCalls = streamHasToolCalls;\n let finishReason = chunk.finishReason || \"stop\";\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n finishReason = \"tool_calls\";\n }\n const resolvedReason = hadToolCalls ? \"tool_calls\" : finishReason;\n streamFinishSent = true;\n streamHasToolCalls = false;\n return [\n {\n data: JSON.stringify(\n createFinishResponse(model, resolvedReason, streamResponseId)\n ),\n },\n ];\n },\n };\n\n return (\n // biome-ignore lint/suspicious/noExplicitAny: ai sdk boundary\n chunk: any\n ): StreamChunk[] => {\n const out: StreamChunk[] = [];\n\n logChunk?.(chunk);\n\n if (chunk.type === \"start\") {\n streamHasToolCalls = false;\n streamFinishSent = false;\n streamResponseId = chunk.id ?? generateResponseId();\n }\n\n const handler = handlers[chunk.type];\n if (handler) {\n const result = handler(chunk as AIStreamChunk, model);\n if (chunk.type === \"tool-call\" || chunk.type === \"tool-call-delta\") {\n streamHasToolCalls = true;\n }\n out.push(...result);\n } else {\n console.warn(`⚠️ Unknown AI SDK chunk type: ${chunk.type}`, chunk);\n }\n\n if (chunk.type === \"finish-step\" || chunk.type === \"finish\") {\n streamHasToolCalls = false;\n }\n\n return out.filter((resultChunk) => {\n try {\n const parsed = JSON.parse(resultChunk.data);\n const delta = parsed.choices?.[0]?.delta;\n return (\n delta &&\n (delta.role ||\n delta.content ||\n (delta as NonNullable<OpenAIChoice[\"delta\"]>).reasoning_content ||\n (delta.tool_calls && delta.tool_calls.length > 0) ||\n parsed.choices?.[0]?.finish_reason)\n );\n } catch {\n return true;\n }\n });\n };\n}\n\nexport function convertAISDKStreamChunkToOpenAI(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n chunk: any,\n model: string\n): StreamChunk[] {\n const convert = createOpenAIStreamConverter(model);\n return convert(chunk);\n}\n\n/**\n * Create SSE formatted response\n */\nexport function createSSEResponse(chunks: StreamChunk[]): string {\n return chunks.map((chunk) => `data: ${chunk.data}\\n\\n`).join(\"\");\n}\n","import { zodSchema } from \"@ai-sdk/provider-utils\";\nimport cors from \"@fastify/cors\";\nimport { generateText, streamText } from \"ai\";\nimport Fastify, {\n type FastifyInstance,\n type FastifyReply,\n type FastifyRequest,\n} from \"fastify\";\nimport { toJSONSchema, type ZodTypeAny } from \"zod\";\nimport { convertOpenAIRequestToAISDK } from \"./openai-request-converter.js\";\nimport {\n convertAISDKResultToOpenAI,\n createOpenAIStreamConverter,\n} from \"./response-converter.js\";\nimport type {\n AISDKTool,\n Logger,\n OpenAIChatRequest,\n ProxyConfig,\n} from \"./types.js\";\n\ntype ConvertedParams = ReturnType<typeof convertOpenAIRequestToAISDK>;\n\nfunction serializeZodSchema(schema: ZodTypeAny | undefined): unknown {\n if (!schema) {\n return null;\n }\n\n // Use Zod v4's built-in JSON Schema conversion\n const jsonSchema = toJSONSchema(schema, {\n unrepresentable: \"any\",\n });\n\n // Remove $schema field for cleaner output\n if (typeof jsonSchema === \"object\" && jsonSchema !== null) {\n const { $schema, ...rest } = jsonSchema as Record<string, unknown>;\n return rest;\n }\n\n return jsonSchema;\n}\n\nfunction serializeMessages(messages: OpenAIChatRequest[\"messages\"]) {\n return messages.map((message, index) => ({\n index,\n role: message.role,\n content: message.content,\n toolCalls: message.tool_calls,\n }));\n}\n\nfunction logIncomingRequest(\n openaiRequest: OpenAIChatRequest,\n enabled: boolean\n) {\n if (!enabled) {\n return;\n }\n const toolNames = (openaiRequest.tools ?? [])\n .map((tool) => (\"function\" in tool ? tool.function?.name : undefined))\n .filter((name): name is string => Boolean(name));\n\n console.log(\n \"[proxy] Incoming OpenAI request\",\n JSON.stringify(\n {\n model: openaiRequest.model,\n stream: Boolean(openaiRequest.stream),\n temperature: openaiRequest.temperature,\n maxTokens: openaiRequest.max_tokens,\n toolNames,\n toolChoice: openaiRequest.tool_choice,\n messages: serializeMessages(openaiRequest.messages),\n tools: openaiRequest.tools,\n },\n null,\n 2\n )\n );\n}\n\nfunction serializeAISDKMessages(messages: ConvertedParams[\"messages\"]) {\n return messages?.map((message, index) => ({\n index,\n role: message.role,\n content: message.content,\n }));\n}\n\nfunction logRequestConversion(\n openaiRequest: OpenAIChatRequest,\n aisdkParams: ConvertedParams,\n enabled: boolean\n) {\n if (!enabled) {\n return;\n }\n const messages = aisdkParams.messages ?? [];\n console.log(\n \"[proxy] Converted AI SDK params\",\n JSON.stringify(\n {\n model: openaiRequest.model,\n hasSystemMessage: messages.some((message) => message.role === \"system\"),\n messages: serializeAISDKMessages(messages),\n tools: Object.entries(aisdkParams.tools ?? {}).map(([name, tool]) => ({\n name,\n description: tool.description,\n inputSchema: serializeZodSchema(tool.inputSchema),\n })),\n temperature: aisdkParams.temperature,\n maxOutputTokens: aisdkParams.maxOutputTokens,\n stopSequences: aisdkParams.stopSequences,\n },\n null,\n 2\n )\n );\n}\n\nexport class OpenAIProxyServer {\n private readonly fastify: FastifyInstance;\n private readonly config: ProxyConfig;\n private readonly logger: Logger;\n\n constructor(config: ProxyConfig) {\n this.config = {\n port: 3000,\n host: \"localhost\",\n cors: true,\n ...config,\n };\n this.logger = (config.logger ?? console) as Logger;\n\n this.fastify = Fastify();\n\n // Enable CORS\n if (this.config.cors) {\n this.fastify.register(cors);\n }\n\n this.setupRoutes();\n }\n\n private setupRoutes(): void {\n // Health check endpoint\n this.fastify.get(\n \"/health\",\n async (_request: FastifyRequest, _reply: FastifyReply) => ({\n status: \"ok\",\n timestamp: new Date().toISOString(),\n })\n );\n\n // OpenAI-compatible chat completions endpoint\n this.fastify.post(\n \"/v1/chat/completions\",\n (request: FastifyRequest, reply: FastifyReply) => {\n try {\n const openaiRequest = request.body as OpenAIChatRequest;\n\n // Validate request\n if (\n !(openaiRequest.messages && Array.isArray(openaiRequest.messages))\n ) {\n return reply.code(400).send({\n error: {\n message: \"Messages array is required\",\n type: \"invalid_request_error\",\n },\n });\n }\n\n logIncomingRequest(\n openaiRequest,\n this.config.logging?.requests ?? true\n );\n\n // Convert OpenAI request to AI SDK format\n const aisdkParams = convertOpenAIRequestToAISDK(openaiRequest, {\n parserDebug: this.config.parserDebug,\n });\n logRequestConversion(\n openaiRequest,\n aisdkParams,\n this.config.logging?.conversions ?? true\n );\n\n // Handle streaming vs non-streaming\n if (openaiRequest.stream) {\n return this.handleStreamingRequest(\n aisdkParams,\n openaiRequest,\n reply\n );\n }\n return this.handleNonStreamingRequest(\n aisdkParams,\n openaiRequest,\n reply\n );\n } catch (error) {\n this.logger.error(\"Request handling error:\", error);\n return reply.code(500).send({\n error: {\n message: \"Internal server error\",\n type: \"server_error\",\n },\n });\n }\n }\n );\n\n // Models endpoint\n this.fastify.get(\"/v1/models\", async () => ({\n object: \"list\",\n data: [\n {\n id: \"wrapped-model\",\n object: \"model\",\n created: Math.floor(Date.now() / 1000),\n owned_by: \"ai-sdk-tool-proxy\",\n },\n ],\n }));\n }\n\n // Merge server-defined tools (with execute) and request-defined tools (schema-only)\n // Server tools take precedence when names overlap.\n private mergeTools(\n serverTools?: Record<string, AISDKTool>,\n requestTools?: Record<string, AISDKTool>\n ) {\n const toProviderTool = (tool: AISDKTool | undefined): unknown => {\n if (!tool) {\n return;\n }\n\n return {\n description: tool.description,\n inputSchema: zodSchema(tool.inputSchema),\n ...(tool.execute ? { execute: tool.execute } : {}),\n };\n };\n\n const merged: Record<string, unknown> = {};\n\n for (const [name, t] of Object.entries(requestTools ?? {})) {\n const pt = toProviderTool(t);\n if (pt) {\n merged[name] = pt;\n }\n }\n\n for (const [name, t] of Object.entries(serverTools ?? {})) {\n const pt = toProviderTool(t);\n if (pt) {\n merged[name] = pt; // override request tool\n }\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n }\n\n private async handleStreamingRequest(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n aisdkParams: any,\n openaiRequest: OpenAIChatRequest,\n reply: FastifyReply\n ): Promise<void> {\n // Set SSE headers\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n\n try {\n const mergedTools = this.mergeTools(this.config.tools, aisdkParams.tools);\n const result = await streamText({\n model: this.config.model,\n ...aisdkParams,\n ...(mergedTools ? { tools: mergedTools } : {}),\n });\n\n const convert = createOpenAIStreamConverter(openaiRequest.model, {\n logChunks: this.config.logging?.streamChunks ?? true,\n });\n for await (const chunk of result.fullStream) {\n const openaiChunks = convert(chunk);\n for (const openaiChunk of openaiChunks) {\n reply.raw.write(`data: ${openaiChunk.data}\\n\\n`);\n }\n }\n\n reply.raw.write(\"data: [DONE]\\n\\n\");\n reply.raw.end();\n } catch (error) {\n this.logger.error(\"Streaming error:\", error);\n reply.raw.write('data: {\"error\": {\"message\": \"Streaming error\"}}\\n\\n');\n reply.raw.end();\n }\n\n return reply;\n }\n\n private async handleNonStreamingRequest(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n aisdkParams: any,\n openaiRequest: OpenAIChatRequest,\n reply: FastifyReply\n ): Promise<void> {\n try {\n const mergedTools = this.mergeTools(this.config.tools, aisdkParams.tools);\n const result = await generateText({\n model: this.config.model,\n ...aisdkParams,\n ...(mergedTools ? { tools: mergedTools } : {}),\n });\n\n const openaiResponse = convertAISDKResultToOpenAI(\n result,\n openaiRequest.model,\n false\n );\n\n reply.send(openaiResponse);\n } catch (error) {\n this.logger.error(\"Generation error:\", error);\n return reply.code(500).send({\n error: {\n message: \"Generation failed\",\n type: \"generation_error\",\n },\n });\n }\n }\n\n async start(): Promise<void> {\n try {\n await this.fastify.listen({\n port: this.config.port || 3000,\n host: this.config.host || \"localhost\",\n });\n\n this.logger.info(\n `🚀 OpenAI Proxy Server running on http://${this.config.host}:${this.config.port}`\n );\n this.logger.info(\n `📡 Endpoint: http://${this.config.host}:${this.config.port}/v1/chat/completions`\n );\n this.logger.info(\n `🏥 Health: http://${this.config.host}:${this.config.port}/health`\n );\n } catch (error) {\n this.logger.error(\"Failed to start server:\", error);\n process.exit(1);\n }\n }\n\n async stop(): Promise<void> {\n try {\n await this.fastify.close();\n this.logger.info(\"🛑 Server stopped\");\n } catch (error) {\n this.logger.error(\"Error stopping server:\", error);\n }\n }\n}\n"],"mappings":"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","names":["_a","_a"]}
|
|
1
|
+
{"version":3,"sources":["../src/openai-request-converter.ts","../src/response-utils.ts","../src/response-converter.ts","../src/server.ts"],"sourcesContent":["import type {\n ModelMessage,\n ToolContent,\n ToolResultOutput,\n} from \"@ai-sdk/provider-utils\";\nimport { z } from \"zod\";\nimport type {\n OpenAIChatRequest,\n OpenAICompleteToolCall,\n OpenAIMessage,\n ProxyConfig,\n} from \"./types.js\";\n\n// Type definitions for OpenAI tool parameters\ninterface OpenAIToolProperty {\n type: string;\n description?: string;\n enum?: string[];\n}\n\ninterface OpenAIToolParameters {\n type: string;\n properties?: Record<string, OpenAIToolProperty>;\n required?: string[];\n}\n\n// Type for AI SDK tool definition\ninterface AISDKTool {\n description: string;\n inputSchema: z.ZodTypeAny;\n}\n\n// Type for tool call object\ninterface ToolCall {\n toolName: string;\n args: unknown;\n}\n\n/**\n * Create Zod schema for OpenAI tool property\n */\nfunction createZodSchema(prop: OpenAIToolProperty): z.ZodTypeAny {\n if (prop.type === \"string\") {\n return prop.enum ? z.enum(prop.enum as [string, ...string[]]) : z.string();\n }\n if (prop.type === \"number\") {\n return z.number();\n }\n if (prop.type === \"boolean\") {\n return z.boolean();\n }\n if (prop.type === \"array\") {\n return z.array(z.any());\n }\n if (prop.type === \"object\") {\n return z.object({});\n }\n return z.any();\n}\n\n/**\n * Convert OpenAI tool schema to Zod schema\n */\nfunction convertOpenAIToolToZod(\n parameters: Record<string, unknown> | undefined\n): z.ZodObject<Record<string, z.ZodTypeAny>> {\n if (!parameters) {\n return z.object({});\n }\n\n const params = parameters as unknown as OpenAIToolParameters;\n if (!params.properties) {\n return z.object({});\n }\n\n const schemaShape: Record<string, z.ZodTypeAny> = {};\n for (const [key, prop] of Object.entries(params.properties)) {\n schemaShape[key] = createZodSchema(prop);\n }\n\n return z.object(schemaShape);\n}\n\n/**\n * Convert OpenAI tools to AI SDK format\n */\nfunction convertOpenAITools(\n openaiTools:\n | Array<{\n function: {\n name: string;\n description?: string;\n parameters: Record<string, unknown>;\n };\n }>\n | undefined\n): Record<string, AISDKTool> {\n const aisdkTools: Record<string, AISDKTool> = {};\n\n if (!openaiTools) {\n return aisdkTools;\n }\n\n for (const openaiTool of openaiTools) {\n const toolName = openaiTool.function.name;\n aisdkTools[toolName] = {\n description: openaiTool.function.description || \"\",\n inputSchema: convertOpenAIToolToZod(openaiTool.function.parameters),\n };\n }\n\n return aisdkTools;\n}\n\n/**\n * Convert stop parameter to stop sequences\n */\nfunction convertStopToSequences(\n stop: string | string[] | undefined\n): string[] | undefined {\n if (!stop) {\n return;\n }\n return Array.isArray(stop) ? stop : [stop];\n}\n\ninterface AITextPart {\n type: \"text\";\n text: string;\n}\ninterface AIToolCallPart {\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n input: unknown;\n}\ntype TextToolOutput = Extract<ToolResultOutput, { type: \"text\" }>;\ntype JsonToolOutput = Extract<ToolResultOutput, { type: \"json\" }>;\n\n/**\n * Convert OpenAI chat completion request to AI SDK format\n */\nexport function normalizeMessageContent(\n content: OpenAIMessage[\"content\"]\n): AITextPart[] {\n if (typeof content === \"string\") {\n return content ? [{ type: \"text\" as const, text: content }] : [];\n }\n\n if (Array.isArray(content)) {\n const parts = content as Array<string | { text?: unknown }>;\n return parts\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n }\n if (part && typeof part === \"object\" && \"text\" in part) {\n const textValue = part.text;\n if (typeof textValue === \"string\") {\n return textValue;\n }\n if (textValue !== undefined) {\n return JSON.stringify(textValue);\n }\n }\n return JSON.stringify(part);\n })\n .filter((text): text is string => Boolean(text))\n .map((text) => ({ type: \"text\" as const, text }));\n }\n\n if (content === null || content === undefined) {\n return [];\n }\n\n if (typeof content === \"object\") {\n return [{ type: \"text\" as const, text: JSON.stringify(content) }];\n }\n\n return [{ type: \"text\" as const, text: String(content) }];\n}\n\nfunction buildToolCallParts(\n toolCalls: OpenAICompleteToolCall[]\n): AIToolCallPart[] {\n return toolCalls.map((toolCall) => {\n let parsedArgs: unknown = toolCall.function.arguments;\n if (typeof toolCall.function.arguments === \"string\") {\n try {\n parsedArgs = JSON.parse(toolCall.function.arguments || \"{}\");\n } catch {\n parsedArgs = toolCall.function.arguments;\n }\n }\n\n return {\n type: \"tool-call\" as const,\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input: parsedArgs,\n } satisfies AIToolCallPart;\n });\n}\n\nfunction buildAssistantContent(\n message: OpenAIMessage & { role: \"assistant\" }\n): Array<AITextPart | AIToolCallPart> | string {\n const textParts = normalizeMessageContent(message.content);\n const toolCallParts = message.tool_calls?.length\n ? buildToolCallParts(message.tool_calls)\n : [];\n\n if (toolCallParts.length === 0) {\n if (textParts.length === 0) {\n return \"\";\n }\n if (textParts.length === 1) {\n return textParts[0].text;\n }\n return textParts;\n }\n\n return [...textParts, ...toolCallParts];\n}\n\nfunction isJsonValue(value: unknown): value is JsonToolOutput[\"value\"] {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every(isJsonValue);\n }\n\n if (typeof value === \"object\") {\n return Object.values(value as Record<string, unknown>).every(isJsonValue);\n }\n\n return false;\n}\n\nfunction buildToolOutput(rawValue: string): ToolResultOutput {\n if (!rawValue) {\n return { type: \"text\", value: \"\" } satisfies TextToolOutput;\n }\n\n try {\n const parsed = JSON.parse(rawValue);\n if (isJsonValue(parsed)) {\n return { type: \"json\", value: parsed } satisfies JsonToolOutput;\n }\n } catch {\n // Fall through to text output below\n }\n\n return { type: \"text\", value: rawValue } satisfies TextToolOutput;\n}\n\nfunction buildToolContent(\n message: OpenAIMessage & { role: \"tool\" },\n toolNameLookup: Map<string, string>\n): ToolContent {\n const textParts = normalizeMessageContent(message.content);\n const combined = textParts.map((part) => part.text).join(\"\\n\");\n const toolCallId = message.tool_call_id ?? \"\";\n const toolName = toolCallId\n ? (toolNameLookup.get(toolCallId) ?? toolCallId)\n : \"\";\n\n return [\n {\n type: \"tool-result\",\n toolCallId,\n toolName,\n output: buildToolOutput(combined),\n },\n ];\n}\n\nfunction convertMessageToModelMessage(\n message: OpenAIMessage,\n toolNameLookup: Map<string, string>\n): ModelMessage {\n if (message.role === \"assistant\") {\n if (message.tool_calls?.length) {\n for (const toolCall of message.tool_calls) {\n toolNameLookup.set(toolCall.id, toolCall.function.name);\n }\n }\n\n return {\n role: \"assistant\",\n content: buildAssistantContent(\n message as OpenAIMessage & { role: \"assistant\" }\n ),\n };\n }\n\n if (message.role === \"tool\") {\n return {\n role: \"tool\",\n content: buildToolContent(\n message as OpenAIMessage & { role: \"tool\" },\n toolNameLookup\n ),\n };\n }\n\n if (message.role === \"system\") {\n const text = normalizeMessageContent(message.content)\n .map((part) => part.text)\n .join(\"\\n\");\n return {\n role: \"system\",\n content: text,\n };\n }\n\n const userParts = normalizeMessageContent(message.content);\n if (userParts.length === 0) {\n return {\n role: \"user\",\n content: \"\",\n };\n }\n\n if (userParts.length === 1) {\n return {\n role: \"user\",\n content: userParts[0].text,\n };\n }\n\n return {\n role: \"user\",\n content: userParts,\n };\n}\n\nexport function convertOpenAIRequestToAISDK(\n openaiRequest: OpenAIChatRequest,\n proxyConfig?: Pick<ProxyConfig, \"parserDebug\">\n) {\n const {\n messages,\n tools: openaiTools,\n temperature,\n max_tokens,\n stop,\n tool_choice,\n } = openaiRequest;\n\n const toolNameLookup = new Map<string, string>();\n\n const aiMessages: ModelMessage[] = messages.map((message) =>\n convertMessageToModelMessage(message, toolNameLookup)\n );\n\n // Convert OpenAI tools to AI SDK format dynamically\n const aisdkTools = convertOpenAITools(openaiTools);\n\n const providerOptions = proxyConfig?.parserDebug\n ? {\n toolCallMiddleware: {\n debugLevel: proxyConfig.parserDebug.level,\n logErrors: proxyConfig.parserDebug.logErrors,\n captureSummary: proxyConfig.parserDebug.captureSummary,\n },\n }\n : undefined;\n\n return {\n messages: aiMessages,\n tools: aisdkTools,\n temperature,\n maxOutputTokens: max_tokens,\n stopSequences: convertStopToSequences(stop),\n toolChoice: mapOpenAIToolChoice(tool_choice),\n ...(providerOptions ? { providerOptions } : {}),\n };\n}\n\n// Map OpenAI tool_choice to AI SDK toolChoice\nexport function mapOpenAIToolChoice(\n choice: OpenAIChatRequest[\"tool_choice\"]\n): \"auto\" | \"none\" | { type: \"tool\"; toolName: string } | undefined {\n if (!choice) {\n return;\n }\n if (choice === \"auto\" || choice === \"none\") {\n return choice;\n }\n if (typeof choice === \"object\" && choice.type === \"function\") {\n return { type: \"tool\", toolName: choice.function.name };\n }\n return;\n}\n\n/**\n * Convert AI SDK tool calls to OpenAI format\n */\nexport function convertAISDKToolCallsToOpenAI(toolCalls: ToolCall[]): Array<{\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n}> {\n return toolCalls.map((call) => ({\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`,\n type: \"function\" as const,\n function: {\n name: call.toolName,\n arguments: JSON.stringify(call.args),\n },\n }));\n}\n","export function generateResponseId(): string {\n return `chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n\nexport function getCurrentTimestamp(): number {\n return Math.floor(Date.now() / 1000);\n}\n","import { generateResponseId, getCurrentTimestamp } from \"./response-utils.js\";\nimport type {\n OpenAIChatResponse,\n OpenAIChoice,\n OpenAIStreamingToolCall,\n OpenAIUsage,\n StreamChunk,\n} from \"./types.js\";\n\n/**\n * Convert AI SDK result to OpenAI chat completion response\n */\nexport function convertAISDKResultToOpenAI(\n // biome-ignore lint/suspicious/noExplicitAny: AI sdk integration boundary\n aisdkResult: any,\n model: string,\n stream = false\n): OpenAIChatResponse {\n const choices: OpenAIChoice[] = [];\n\n // Handle text content\n if (aisdkResult.text) {\n const choice: OpenAIChoice = {\n index: 0,\n finish_reason: aisdkResult.finishReason || \"stop\",\n };\n\n if (stream) {\n choice.delta = {\n role: \"assistant\",\n content: aisdkResult.text,\n };\n } else {\n choice.message = {\n role: \"assistant\",\n content: aisdkResult.text,\n };\n }\n choices.push(choice);\n }\n\n // Handle tool calls\n if (aisdkResult.toolCalls && aisdkResult.toolCalls.length > 0) {\n const choice: OpenAIChoice = {\n index: 0,\n finish_reason: \"tool_calls\",\n };\n\n const openAIToolCalls = aisdkResult.toolCalls?.map(\n (\n // biome-ignore lint/suspicious/noExplicitAny: AI SDK integration boundary\n call: any\n ) => ({\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`,\n type: \"function\" as const,\n function: {\n name: call.toolName,\n arguments: JSON.stringify(call.args),\n },\n })\n );\n\n if (stream) {\n choice.delta = {\n role: \"assistant\",\n tool_calls: openAIToolCalls,\n };\n } else {\n choice.message = {\n role: \"assistant\",\n content: null,\n tool_calls: openAIToolCalls,\n };\n }\n\n choices.push(choice);\n }\n\n const response: OpenAIChatResponse = {\n id: generateResponseId(),\n object: stream ? \"chat.completion.chunk\" : \"chat.completion\",\n created: getCurrentTimestamp(),\n model,\n choices,\n };\n\n // Add usage if available\n if (aisdkResult.usage) {\n response.usage = {\n prompt_tokens: aisdkResult.usage.promptTokens || 0,\n completion_tokens: aisdkResult.usage.completionTokens || 0,\n total_tokens: aisdkResult.usage.totalTokens || 0,\n } as OpenAIUsage;\n }\n\n return response;\n}\n\n/**\n * Convert AI SDK stream chunk to OpenAI SSE format\n */\n\n// Type definitions for better type safety\ninterface ToolCallDelta {\n index?: number;\n id?: string;\n type?: \"function\";\n function?: {\n name?: string;\n arguments?: string;\n };\n}\n\ninterface AIStreamChunk {\n type: string;\n id?: string;\n text?: string;\n toolCallId?: string;\n toolName?: string;\n args?: string;\n input?: Record<string, unknown>;\n finishReason?: string;\n [key: string]: unknown;\n}\n\ntype ChunkHandler = (chunk: AIStreamChunk, model: string) => StreamChunk[];\n\n// Helper function to create finish response\nfunction createFinishResponse(\n model: string,\n finishReason: string,\n responseId: string\n): OpenAIChatResponse {\n // Ensure finish reason matches OpenAI's allowed types\n let validFinishReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\";\n\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n validFinishReason = \"tool_calls\";\n } else if (finishReason === \"stop\") {\n validFinishReason = \"stop\";\n } else if (finishReason === \"length\") {\n validFinishReason = \"length\";\n } else if (finishReason === \"content_filter\") {\n validFinishReason = \"content_filter\";\n } else {\n validFinishReason = \"stop\"; // fallback to \"stop\" for unknown reasons\n }\n\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta: {},\n finish_reason: validFinishReason,\n },\n ],\n };\n}\n\n// Helper function to create content response\nfunction createContentResponse(\n model: string,\n content: string,\n responseId: string,\n isReasoning = false\n): OpenAIChatResponse {\n const delta: Record<string, unknown> = { role: \"assistant\" };\n\n if (isReasoning) {\n delta.reasoning_content = content;\n } else {\n delta.content = content;\n }\n\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta,\n },\n ],\n };\n}\n\n// Helper function to create tool call response\nfunction createToolCallResponse(\n model: string,\n toolCall: ToolCallDelta,\n responseId: string,\n includeRole = false\n): OpenAIChatResponse {\n return {\n id: responseId,\n object: \"chat.completion.chunk\",\n created: getCurrentTimestamp(),\n model,\n choices: [\n {\n index: 0,\n delta: {\n ...(includeRole ? { role: \"assistant\" as const } : {}),\n tool_calls: [\n {\n index: toolCall.index || 0,\n type: \"function\" as const,\n function: {\n name: toolCall.function?.name || \"\",\n arguments: toolCall.function?.arguments || \"\",\n },\n },\n ],\n },\n },\n ],\n };\n}\n\n// (legacy stateless handler removed)\n\nexport function createOpenAIStreamConverter(\n model: string,\n options?: {\n logChunks?: boolean;\n }\n) {\n let streamHasToolCalls = false;\n let streamFinishSent = false;\n let streamResponseId = generateResponseId();\n\n const logChunk =\n options?.logChunks === false\n ? undefined\n : (chunk: unknown) => {\n const logType =\n process.env.USE_MIDDLEWARE === \"true\" ? \"middleware\" : \"native\";\n console.log(\n `🔍 AI SDK Chunk [${logType}]:`,\n JSON.stringify(chunk, null, 2)\n );\n };\n\n const handlers: Record<string, ChunkHandler> = {\n start: () => [],\n \"reasoning-delta\": (chunk) => {\n if (!chunk.text) {\n return [];\n }\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, chunk.text, streamResponseId, true)\n ),\n },\n ];\n },\n \"text-delta\": (chunk) => {\n if (!chunk.text) {\n return [];\n }\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, chunk.text, streamResponseId, false)\n ),\n },\n ];\n },\n \"tool-call\": (chunk) => {\n const toolCallId = chunk.toolCallId || `call_${generateResponseId()}`;\n const toolName = chunk.toolName || \"\";\n const argsString =\n typeof chunk.input === \"string\"\n ? chunk.input\n : JSON.stringify(chunk.input ?? {});\n const toolCallDelta: OpenAIStreamingToolCall = {\n index: 0,\n id: toolCallId,\n type: \"function\",\n function: { name: toolName, arguments: argsString },\n };\n const response = createToolCallResponse(\n model,\n toolCallDelta,\n streamResponseId,\n true\n );\n return [{ data: JSON.stringify(response) }];\n },\n \"reasoning-end\": () => [],\n \"text-end\": () => [],\n \"finish-step\": (chunk) => {\n if (streamFinishSent) {\n return [];\n }\n const hadToolCalls = streamHasToolCalls;\n let finishReason = chunk.finishReason || \"stop\";\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n finishReason = \"tool_calls\";\n }\n const resolvedReason = hadToolCalls ? \"tool_calls\" : finishReason;\n streamFinishSent = true;\n streamHasToolCalls = false;\n return [\n {\n data: JSON.stringify(\n createFinishResponse(model, resolvedReason, streamResponseId)\n ),\n },\n ];\n },\n \"tool-call-delta\": (chunk) => {\n const toolCall = {\n index: chunk.toolCallId ? Number(chunk.toolCallId) : 0,\n type: \"function\" as const,\n function: {\n name: chunk.toolName || \"\",\n arguments: chunk.args || \"\",\n },\n };\n return [\n {\n data: JSON.stringify(\n createToolCallResponse(model, toolCall, streamResponseId)\n ),\n },\n ];\n },\n \"tool-result\": (chunk) => {\n const resultText = `\\n[Tool: ${chunk.toolName} returned ${JSON.stringify(chunk.output)}]\\n`;\n return [\n {\n data: JSON.stringify(\n createContentResponse(model, resultText, streamResponseId, false)\n ),\n },\n ];\n },\n finish: (chunk) => {\n if (streamFinishSent) {\n return [];\n }\n const hadToolCalls = streamHasToolCalls;\n let finishReason = chunk.finishReason || \"stop\";\n if (finishReason === \"tool_calls\" || finishReason === \"tool-calls\") {\n finishReason = \"tool_calls\";\n }\n const resolvedReason = hadToolCalls ? \"tool_calls\" : finishReason;\n streamFinishSent = true;\n streamHasToolCalls = false;\n return [\n {\n data: JSON.stringify(\n createFinishResponse(model, resolvedReason, streamResponseId)\n ),\n },\n ];\n },\n };\n\n return (\n // biome-ignore lint/suspicious/noExplicitAny: ai sdk boundary\n chunk: any\n ): StreamChunk[] => {\n const out: StreamChunk[] = [];\n\n logChunk?.(chunk);\n\n if (chunk.type === \"start\") {\n streamHasToolCalls = false;\n streamFinishSent = false;\n streamResponseId = chunk.id ?? generateResponseId();\n }\n\n const handler = handlers[chunk.type];\n if (handler) {\n const result = handler(chunk as AIStreamChunk, model);\n if (chunk.type === \"tool-call\" || chunk.type === \"tool-call-delta\") {\n streamHasToolCalls = true;\n }\n out.push(...result);\n } else {\n console.warn(`⚠️ Unknown AI SDK chunk type: ${chunk.type}`, chunk);\n }\n\n if (chunk.type === \"finish-step\" || chunk.type === \"finish\") {\n streamHasToolCalls = false;\n }\n\n return out.filter((resultChunk) => {\n try {\n const parsed = JSON.parse(resultChunk.data);\n const delta = parsed.choices?.[0]?.delta;\n return (\n delta &&\n (delta.role ||\n delta.content ||\n (delta as NonNullable<OpenAIChoice[\"delta\"]>).reasoning_content ||\n (delta.tool_calls && delta.tool_calls.length > 0) ||\n parsed.choices?.[0]?.finish_reason)\n );\n } catch {\n return true;\n }\n });\n };\n}\n\nexport function convertAISDKStreamChunkToOpenAI(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n chunk: any,\n model: string\n): StreamChunk[] {\n const convert = createOpenAIStreamConverter(model);\n return convert(chunk);\n}\n\n/**\n * Create SSE formatted response\n */\nexport function createSSEResponse(chunks: StreamChunk[]): string {\n return chunks.map((chunk) => `data: ${chunk.data}\\n\\n`).join(\"\");\n}\n","import { zodSchema } from \"@ai-sdk/provider-utils\";\nimport cors from \"@fastify/cors\";\nimport { generateText, streamText } from \"ai\";\nimport Fastify, {\n type FastifyInstance,\n type FastifyReply,\n type FastifyRequest,\n} from \"fastify\";\nimport { toJSONSchema, type ZodTypeAny } from \"zod\";\nimport { convertOpenAIRequestToAISDK } from \"./openai-request-converter.js\";\nimport {\n convertAISDKResultToOpenAI,\n createOpenAIStreamConverter,\n} from \"./response-converter.js\";\nimport type {\n AISDKTool,\n Logger,\n OpenAIChatRequest,\n ProxyConfig,\n} from \"./types.js\";\n\ntype ConvertedParams = ReturnType<typeof convertOpenAIRequestToAISDK>;\n\nfunction serializeZodSchema(schema: ZodTypeAny | undefined): unknown {\n if (!schema) {\n return null;\n }\n\n // Use Zod v4's built-in JSON Schema conversion\n const jsonSchema = toJSONSchema(schema, {\n unrepresentable: \"any\",\n });\n\n // Remove $schema field for cleaner output\n if (typeof jsonSchema === \"object\" && jsonSchema !== null) {\n const { $schema, ...rest } = jsonSchema as Record<string, unknown>;\n return rest;\n }\n\n return jsonSchema;\n}\n\nfunction serializeMessages(messages: OpenAIChatRequest[\"messages\"]) {\n return messages.map((message, index) => ({\n index,\n role: message.role,\n content: message.content,\n toolCalls: message.tool_calls,\n }));\n}\n\nfunction logIncomingRequest(\n openaiRequest: OpenAIChatRequest,\n enabled: boolean\n) {\n if (!enabled) {\n return;\n }\n const toolNames = (openaiRequest.tools ?? [])\n .map((tool) => (\"function\" in tool ? tool.function?.name : undefined))\n .filter((name): name is string => Boolean(name));\n\n console.log(\n \"[proxy] Incoming OpenAI request\",\n JSON.stringify(\n {\n model: openaiRequest.model,\n stream: Boolean(openaiRequest.stream),\n temperature: openaiRequest.temperature,\n maxTokens: openaiRequest.max_tokens,\n toolNames,\n toolChoice: openaiRequest.tool_choice,\n messages: serializeMessages(openaiRequest.messages),\n tools: openaiRequest.tools,\n },\n null,\n 2\n )\n );\n}\n\nfunction serializeAISDKMessages(messages: ConvertedParams[\"messages\"]) {\n return messages?.map((message, index) => ({\n index,\n role: message.role,\n content: message.content,\n }));\n}\n\nfunction logRequestConversion(\n openaiRequest: OpenAIChatRequest,\n aisdkParams: ConvertedParams,\n enabled: boolean\n) {\n if (!enabled) {\n return;\n }\n const messages = aisdkParams.messages ?? [];\n console.log(\n \"[proxy] Converted AI SDK params\",\n JSON.stringify(\n {\n model: openaiRequest.model,\n hasSystemMessage: messages.some((message) => message.role === \"system\"),\n messages: serializeAISDKMessages(messages),\n tools: Object.entries(aisdkParams.tools ?? {}).map(([name, tool]) => ({\n name,\n description: tool.description,\n inputSchema: serializeZodSchema(tool.inputSchema),\n })),\n temperature: aisdkParams.temperature,\n maxOutputTokens: aisdkParams.maxOutputTokens,\n stopSequences: aisdkParams.stopSequences,\n },\n null,\n 2\n )\n );\n}\n\nexport class OpenAIProxyServer {\n private readonly fastify: FastifyInstance;\n private readonly config: ProxyConfig;\n private readonly logger: Logger;\n\n constructor(config: ProxyConfig) {\n this.config = {\n port: 3000,\n host: \"localhost\",\n cors: true,\n ...config,\n };\n this.logger = (config.logger ?? console) as Logger;\n\n this.fastify = Fastify();\n\n // Enable CORS\n if (this.config.cors) {\n this.fastify.register(cors);\n }\n\n this.setupRoutes();\n }\n\n private setupRoutes(): void {\n // Health check endpoint\n this.fastify.get(\n \"/health\",\n async (_request: FastifyRequest, _reply: FastifyReply) => ({\n status: \"ok\",\n timestamp: new Date().toISOString(),\n })\n );\n\n // OpenAI-compatible chat completions endpoint\n this.fastify.post(\n \"/v1/chat/completions\",\n (request: FastifyRequest, reply: FastifyReply) => {\n try {\n const openaiRequest = request.body as OpenAIChatRequest;\n\n // Validate request\n if (\n !(openaiRequest.messages && Array.isArray(openaiRequest.messages))\n ) {\n return reply.code(400).send({\n error: {\n message: \"Messages array is required\",\n type: \"invalid_request_error\",\n },\n });\n }\n\n logIncomingRequest(\n openaiRequest,\n this.config.logging?.requests ?? true\n );\n\n // Convert OpenAI request to AI SDK format\n const aisdkParams = convertOpenAIRequestToAISDK(openaiRequest, {\n parserDebug: this.config.parserDebug,\n });\n logRequestConversion(\n openaiRequest,\n aisdkParams,\n this.config.logging?.conversions ?? true\n );\n\n // Handle streaming vs non-streaming\n if (openaiRequest.stream) {\n return this.handleStreamingRequest(\n aisdkParams,\n openaiRequest,\n reply\n );\n }\n return this.handleNonStreamingRequest(\n aisdkParams,\n openaiRequest,\n reply\n );\n } catch (error) {\n this.logger.error(\"Request handling error:\", error);\n return reply.code(500).send({\n error: {\n message: \"Internal server error\",\n type: \"server_error\",\n },\n });\n }\n }\n );\n\n // Models endpoint\n this.fastify.get(\"/v1/models\", async () => ({\n object: \"list\",\n data: [\n {\n id: \"wrapped-model\",\n object: \"model\",\n created: Math.floor(Date.now() / 1000),\n owned_by: \"ai-sdk-tool-proxy\",\n },\n ],\n }));\n }\n\n // Merge server-defined tools (with execute) and request-defined tools (schema-only)\n // Server tools take precedence when names overlap.\n private mergeTools(\n serverTools?: Record<string, AISDKTool>,\n requestTools?: Record<string, AISDKTool>\n ) {\n const toProviderTool = (tool: AISDKTool | undefined): unknown => {\n if (!tool) {\n return;\n }\n\n return {\n description: tool.description,\n inputSchema: zodSchema(tool.inputSchema),\n ...(tool.execute ? { execute: tool.execute } : {}),\n };\n };\n\n const merged: Record<string, unknown> = {};\n\n for (const [name, t] of Object.entries(requestTools ?? {})) {\n const pt = toProviderTool(t);\n if (pt) {\n merged[name] = pt;\n }\n }\n\n for (const [name, t] of Object.entries(serverTools ?? {})) {\n const pt = toProviderTool(t);\n if (pt) {\n merged[name] = pt; // override request tool\n }\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n }\n\n private async handleStreamingRequest(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n aisdkParams: any,\n openaiRequest: OpenAIChatRequest,\n reply: FastifyReply\n ): Promise<void> {\n // Set SSE headers\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n\n try {\n const mergedTools = this.mergeTools(this.config.tools, aisdkParams.tools);\n const result = await streamText({\n model: this.config.model,\n ...aisdkParams,\n ...(mergedTools ? { tools: mergedTools } : {}),\n });\n\n const convert = createOpenAIStreamConverter(openaiRequest.model, {\n logChunks: this.config.logging?.streamChunks ?? true,\n });\n for await (const chunk of result.fullStream) {\n const openaiChunks = convert(chunk);\n for (const openaiChunk of openaiChunks) {\n reply.raw.write(`data: ${openaiChunk.data}\\n\\n`);\n }\n }\n\n reply.raw.write(\"data: [DONE]\\n\\n\");\n reply.raw.end();\n } catch (error) {\n this.logger.error(\"Streaming error:\", error);\n reply.raw.write('data: {\"error\": {\"message\": \"Streaming error\"}}\\n\\n');\n reply.raw.end();\n }\n\n return reply;\n }\n\n private async handleNonStreamingRequest(\n // biome-ignore lint/suspicious/noExplicitAny: o sdk integration boundary\n aisdkParams: any,\n openaiRequest: OpenAIChatRequest,\n reply: FastifyReply\n ): Promise<void> {\n try {\n const mergedTools = this.mergeTools(this.config.tools, aisdkParams.tools);\n const result = await generateText({\n model: this.config.model,\n ...aisdkParams,\n ...(mergedTools ? { tools: mergedTools } : {}),\n });\n\n const openaiResponse = convertAISDKResultToOpenAI(\n result,\n openaiRequest.model,\n false\n );\n\n reply.send(openaiResponse);\n } catch (error) {\n this.logger.error(\"Generation error:\", error);\n return reply.code(500).send({\n error: {\n message: \"Generation failed\",\n type: \"generation_error\",\n },\n });\n }\n }\n\n async start(): Promise<void> {\n try {\n await this.fastify.listen({\n port: this.config.port || 3000,\n host: this.config.host || \"localhost\",\n });\n\n this.logger.info(\n `🚀 OpenAI Proxy Server running on http://${this.config.host}:${this.config.port}`\n );\n this.logger.info(\n `📡 Endpoint: http://${this.config.host}:${this.config.port}/v1/chat/completions`\n );\n this.logger.info(\n `🏥 Health: http://${this.config.host}:${this.config.port}/health`\n );\n } catch (error) {\n this.logger.error(\"Failed to start server:\", error);\n process.exit(1);\n }\n }\n\n async stop(): Promise<void> {\n try {\n await this.fastify.close();\n this.logger.info(\"🛑 Server stopped\");\n } catch (error) {\n this.logger.error(\"Error stopping server:\", error);\n }\n }\n}\n"],"mappings":"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","names":["_a","_a"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk-tool/proxy",
|
|
3
|
-
"version": "0.0.0",
|
|
3
|
+
"version": "0.0.1-canary.0",
|
|
4
4
|
"description": "OpenAI-compatible proxy server for AI SDK tool middleware",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -24,30 +24,23 @@
|
|
|
24
24
|
"publishConfig": {
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
|
-
"scripts": {
|
|
28
|
-
"build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
|
|
29
|
-
"build:watch": "pnpm clean && tsup --watch --tsconfig tsconfig.build.json",
|
|
30
|
-
"clean": "rm -rf dist *.tsbuildinfo",
|
|
31
|
-
"typecheck": "tsc --noEmit",
|
|
32
|
-
"test": "vitest run"
|
|
33
|
-
},
|
|
34
27
|
"dependencies": {
|
|
35
28
|
"@ai-sdk/provider": "3.0.0",
|
|
36
|
-
"@ai-sdk/provider-utils": "4.0.
|
|
29
|
+
"@ai-sdk/provider-utils": "4.0.1",
|
|
37
30
|
"@fastify/cors": "^11.2.0",
|
|
38
|
-
"ai": "6.0.
|
|
31
|
+
"ai": "6.0.3",
|
|
39
32
|
"fastify": "^5.6.2",
|
|
40
33
|
"zod": "^4.2.1"
|
|
41
34
|
},
|
|
42
35
|
"devDependencies": {
|
|
43
|
-
"@ai-sdk-
|
|
44
|
-
"@ai-sdk/openai-compatible": "2.0.0",
|
|
45
|
-
"@ai-sdkx/tsconfig": "workspace:*",
|
|
36
|
+
"@ai-sdk/openai-compatible": "2.0.1",
|
|
46
37
|
"@types/node": "^25.0.3",
|
|
47
38
|
"@vitest/coverage-v8": "^4.0.16",
|
|
48
39
|
"@vitest/ui": "^4.0.16",
|
|
49
40
|
"tsup": "^8.5.1",
|
|
50
|
-
"vitest": "^4.0.16"
|
|
41
|
+
"vitest": "^4.0.16",
|
|
42
|
+
"@ai-sdk-tool/parser": "3.0.0-canary.3",
|
|
43
|
+
"@ai-sdkx/tsconfig": "0.0.1-canary.0"
|
|
51
44
|
},
|
|
52
45
|
"keywords": [
|
|
53
46
|
"ai",
|
|
@@ -58,5 +51,12 @@
|
|
|
58
51
|
"middleware"
|
|
59
52
|
],
|
|
60
53
|
"author": "",
|
|
61
|
-
"license": "Apache-2.0"
|
|
62
|
-
|
|
54
|
+
"license": "Apache-2.0",
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
|
|
57
|
+
"build:watch": "pnpm clean && tsup --watch --tsconfig tsconfig.build.json",
|
|
58
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
59
|
+
"typecheck": "tsc --noEmit",
|
|
60
|
+
"test": "vitest run"
|
|
61
|
+
}
|
|
62
|
+
}
|