@gensx/openai
Version:
A wrapper around the OpenAI SDK for GenSX.
1 lines • 16 kB
Source Map (JSON)
{"version":3,"file":"openai.cjs","sources":["@gensx/openai/../../../../src/openai.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n\nimport type { ComponentOpts, WrapOptions } from \"@gensx/core\";\n\nimport { Component, wrap } from \"@gensx/core\";\nimport { OpenAI as OriginalOpenAI } from \"openai\";\nimport { RunnableToolFunctionWithParse } from \"openai/lib/RunnableFunction.mjs\";\n\n// Aggregates streaming ChatCompletionChunk objects into a single ChatCompletion object\nfunction aggregateChatCompletionChunks(chunks: unknown[]): unknown {\n if (chunks.length === 0) {\n return null;\n }\n\n // If we only have one chunk and it's a complete ChatCompletion (not streaming), return it as-is\n if (chunks.length === 1) {\n const singleChunk = chunks[0] as any;\n // Check if it's a complete ChatCompletion response (has choices array with content, not deltas)\n if (singleChunk?.choices?.[0]?.message?.content !== undefined) {\n return singleChunk;\n }\n }\n\n // Multiple chunks or streaming chunks - aggregate them\n const firstChunk = chunks[0] as any;\n if (!firstChunk || typeof firstChunk !== \"object\") {\n return chunks;\n }\n\n // Initialize the aggregated response structure\n const aggregated: any = {\n id: firstChunk.id ?? \"chatcmpl-\" + String(Date.now()),\n object: \"chat.completion\",\n created: firstChunk.created ?? Math.floor(Date.now() / 1000),\n model: firstChunk.model ?? \"gpt-3.5-turbo\",\n choices: [],\n };\n\n // Process each chunk\n for (const chunk of chunks) {\n const typedChunk = chunk as any;\n\n if (!typedChunk?.choices) continue;\n\n for (const choice of typedChunk.choices) {\n const index = parseInt(String(choice.index), 10);\n\n aggregated.choices[index] ??= {\n index,\n message: {\n role: \"assistant\",\n content: \"\",\n },\n finish_reason: null,\n };\n\n // Accumulate content from delta\n if (choice.delta?.content) {\n const existingContent = String(\n aggregated.choices[index].message.content,\n );\n const newContent = String(choice.delta.content);\n aggregated.choices[index].message.content =\n existingContent + newContent;\n }\n\n // Set role if present\n if (choice.delta?.role) {\n aggregated.choices[index].message.role = choice.delta.role;\n }\n\n // Set finish reason from the last chunk that has it\n if (choice.finish_reason) {\n aggregated.choices[index].finish_reason = choice.finish_reason;\n }\n\n // Handle tool calls if present\n if (choice.delta?.tool_calls) {\n aggregated.choices[index].message.tool_calls ??= [];\n\n for (const toolCallDelta of choice.delta.tool_calls) {\n const toolCallIndex = toolCallDelta.index;\n\n if (!aggregated.choices[index].message.tool_calls[toolCallIndex]) {\n aggregated.choices[index].message.tool_calls[toolCallIndex] = {\n id: toolCallDelta.id ?? \"\",\n type: toolCallDelta.type ?? \"function\",\n function: {\n name: toolCallDelta.function?.name ?? \"\",\n arguments: toolCallDelta.function?.arguments ?? \"\",\n },\n };\n } else {\n // Accumulate function arguments\n if (toolCallDelta.function?.arguments) {\n const existingArgs = String(\n aggregated.choices[index].message.tool_calls[toolCallIndex]\n .function.arguments,\n );\n const newArgs = String(toolCallDelta.function.arguments);\n aggregated.choices[index].message.tool_calls[\n toolCallIndex\n ].function.arguments = existingArgs + newArgs;\n }\n }\n }\n }\n }\n\n // Update usage from the last chunk that has it\n if (typedChunk.usage) {\n aggregated.usage = typedChunk.usage;\n }\n }\n\n // Convert choices object to array\n aggregated.choices = Object.values(\n aggregated.choices as Record<string, unknown>,\n );\n\n return aggregated;\n}\n\n/**\n * A pre-wrapped version of the OpenAI SDK that makes all methods available as GenSX components.\n *\n * @example\n * ```ts\n * import { openai } from \"@gensx/openai\";\n *\n * // Use chat completions\n * const completion = await openai.chat.completions.create({\n * model: \"gpt-4.1-mini\",\n * messages: [{ role: \"user\", content: \"Hello!\" }]\n * });\n *\n * // Use embeddings\n * const embedding = await openai.embeddings.create({\n * model: \"text-embedding-3-small\",\n * input: \"Hello world!\"\n * });\n * ```\n */\n\nexport class OpenAI extends OriginalOpenAI {\n constructor(config?: ConstructorParameters<typeof OriginalOpenAI>[0]) {\n super(config);\n return wrapOpenAI(this);\n }\n}\n\nexport const wrapOpenAI = (\n openAiInstance: OriginalOpenAI,\n opts: WrapOptions = {},\n) => {\n let wrapped: OriginalOpenAI;\n // Create a wrapped instance\n wrapped = wrap(openAiInstance, {\n ...opts,\n // Add metadata to component options\n getComponentOpts: (\n path: string[],\n args: unknown,\n ): Partial<ComponentOpts> => {\n // Always set aggregation for chat completions since we can't detect stream parameter at wrap time\n if (path.includes(\"completions\")) {\n return {\n aggregator: aggregateChatCompletionChunks,\n __streamingResultKey: \"stream\",\n };\n }\n\n if (args === undefined || typeof args !== \"object\") {\n return {};\n }\n\n // Extract relevant metadata from args\n const {\n model,\n temperature,\n max_tokens,\n top_p,\n frequency_penalty,\n presence_penalty,\n stream,\n } = args as Record<string, unknown>;\n\n return {\n metadata: {\n llm: {\n provider: inferProvider(openAiInstance.baseURL),\n model,\n temperature,\n max_tokens,\n top_p,\n frequency_penalty,\n presence_penalty,\n stream,\n },\n },\n };\n },\n replacementImplementations: {\n \"OpenAI.beta.chat.completions.runTools\": (_target, value) => {\n if (typeof value === \"function\") {\n const componentOpts = opts.getComponentOpts?.(\n [\"OpenAI\", \"beta\", \"chat\", \"completions\", \"runTools\"],\n value,\n );\n\n const fn = Component(\n \"OpenAI.beta.chat.completions.runTools\",\n async (\n ...params: Parameters<\n typeof openAiInstance.beta.chat.completions.runTools\n >\n ) => {\n const [first, ...rest] = params;\n const { tools } = first;\n\n // Wrap each tool with GenSX functionality\n const wrappedTools = tools.map((tool) => {\n if ((tool as any).$brand === \"auto-parseable-tool\") {\n const newTool = { ...tool };\n\n Object.defineProperty(newTool, \"$brand\", {\n value: (tool as any).$brand,\n });\n\n const boundCallback = (tool as any).$callback.bind(newTool);\n\n Object.defineProperty(newTool, \"$callback\", {\n value: Component(\n `Tool.${tool.function.name}`,\n boundCallback as (input?: object) => unknown,\n ),\n });\n Object.defineProperty(newTool, \"$parseRaw\", {\n value: (tool as any).$parseRaw,\n });\n\n return newTool;\n } else {\n const runnableTool =\n tool as RunnableToolFunctionWithParse<object>;\n return {\n ...runnableTool,\n function: {\n ...runnableTool.function,\n function: Component(\n `Tool.${runnableTool.function.name}`,\n runnableTool.function.function as (\n input?: object,\n ) => unknown,\n ),\n },\n };\n }\n });\n\n const result = (await value.apply(\n (wrapped as any).beta.chat.completions,\n [\n {\n ...first,\n tools: wrappedTools as (typeof params)[0][\"tools\"],\n },\n ...rest,\n ],\n )) as Record<string, unknown>;\n\n return result;\n },\n {\n ...componentOpts,\n },\n );\n\n return fn;\n }\n\n console.warn(\n \"beta.chat.completions.runTools is not a function. Type: \",\n typeof value,\n );\n return value;\n },\n },\n });\n\n return wrapped;\n};\n\nfunction inferProvider(baseURL: string) {\n if (baseURL.includes(\"openai\")) {\n return \"openai\";\n }\n if (baseURL.includes(\"anthropic\")) {\n return \"anthropic\";\n }\n if (baseURL.includes(\"groq\")) {\n return \"groq\";\n }\n if (baseURL.includes(\"gemini\")) {\n return \"google\";\n }\n if (baseURL.includes(\"claude\")) {\n return \"anthropic\";\n }\n if (baseURL.includes(\"perplexity\")) {\n return \"perplexity\";\n }\n if (baseURL.includes(\"grok\")) {\n return \"grok\";\n }\n\n return \"unknown\";\n}\n"],"names":["OriginalOpenAI","wrap","Component"],"mappings":"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"}