Fix static import issue in convertToolsToVercel causing Gemini test failures

The static import of 'ai' package in convertToolsToVercel.ts was still
loading the package early, interfering with @google/genai SDK's stream
handling and causing 'getReader is not a function' errors.

Changes:
- Made convertToolsToVercelFormat async with dynamic import of 'ai'
- Updated all call sites in OpenAI.ts and Anthropic.ts to await the function
- Updated convertToolsToVercel.test.ts to handle async function

This completes the dynamic import strategy across the entire import chain.
This commit is contained in:
Nate
2025-12-09 17:12:26 -08:00
parent d5f670fae4
commit cc3b4ea4f8
4 changed files with 24 additions and 23 deletions

View File

@@ -426,7 +426,7 @@ export class AnthropicApi implements BaseLlmApi {
const model = this.anthropicProvider(body.model);
// Convert OpenAI tools to Vercel AI SDK format
const vercelTools = convertToolsToVercelFormat(body.tools);
const vercelTools = await convertToolsToVercelFormat(body.tools);
const result = await generateText({
model,
@@ -639,7 +639,7 @@ export class AnthropicApi implements BaseLlmApi {
const model = this.anthropicProvider(body.model);
// Convert OpenAI tools to Vercel AI SDK format
const vercelTools = convertToolsToVercelFormat(body.tools);
const vercelTools = await convertToolsToVercelFormat(body.tools);
const stream = await streamText({
model,

View File

@@ -191,7 +191,7 @@ export class OpenAIApi implements BaseLlmApi {
const model = this.openaiProvider(modifiedBody.model);
// Convert OpenAI tools to Vercel AI SDK format
const vercelTools = convertToolsToVercelFormat(modifiedBody.tools);
const vercelTools = await convertToolsToVercelFormat(modifiedBody.tools);
const result = await generateText({
model,
@@ -312,7 +312,7 @@ export class OpenAIApi implements BaseLlmApi {
const model = this.openaiProvider(modifiedBody.model);
// Convert OpenAI tools to Vercel AI SDK format
const vercelTools = convertToolsToVercelFormat(modifiedBody.tools);
const vercelTools = await convertToolsToVercelFormat(modifiedBody.tools);
const stream = await streamText({
model,

View File

@@ -3,7 +3,6 @@
*/
import type { ChatCompletionCreateParams } from "openai/resources/index.js";
import { jsonSchema as aiJsonSchema } from "ai";
/**
* Converts OpenAI tool format to Vercel AI SDK format.
@@ -14,13 +13,15 @@ import { jsonSchema as aiJsonSchema } from "ai";
* @param openaiTools - Array of OpenAI tools or undefined
* @returns Object with tool names as keys, or undefined if no tools
*/
export function convertToolsToVercelFormat(
export async function convertToolsToVercelFormat(
openaiTools?: ChatCompletionCreateParams["tools"],
): Record<string, any> | undefined {
): Promise<Record<string, any> | undefined> {
if (!openaiTools || openaiTools.length === 0) {
return undefined;
}
const { jsonSchema: aiJsonSchema } = await import("ai");
const vercelTools: Record<string, any> = {};
for (const tool of openaiTools) {
if (tool.type === "function") {

View File

@@ -3,17 +3,17 @@ import { convertToolsToVercelFormat } from "../convertToolsToVercel.js";
import type { ChatCompletionCreateParams } from "openai/resources/index.js";
describe("convertToolsToVercelFormat", () => {
test("returns undefined for undefined tools", () => {
const result = convertToolsToVercelFormat(undefined);
test("returns undefined for undefined tools", async () => {
const result = await convertToolsToVercelFormat(undefined);
expect(result).toBeUndefined();
});
test("returns undefined for empty tools array", () => {
const result = convertToolsToVercelFormat([]);
test("returns undefined for empty tools array", async () => {
const result = await convertToolsToVercelFormat([]);
expect(result).toBeUndefined();
});
test("converts single function tool", () => {
test("converts single function tool", async () => {
const tools: ChatCompletionCreateParams["tools"] = [
{
type: "function",
@@ -34,7 +34,7 @@ describe("convertToolsToVercelFormat", () => {
},
];
const result = convertToolsToVercelFormat(tools);
const result = await convertToolsToVercelFormat(tools);
expect(result).toBeDefined();
expect(result).toHaveProperty("readFile");
@@ -47,7 +47,7 @@ describe("convertToolsToVercelFormat", () => {
expect(result?.readFile.parameters).toBeDefined();
});
test("converts multiple function tools", () => {
test("converts multiple function tools", async () => {
const tools: ChatCompletionCreateParams["tools"] = [
{
type: "function",
@@ -78,7 +78,7 @@ describe("convertToolsToVercelFormat", () => {
},
];
const result = convertToolsToVercelFormat(tools);
const result = await convertToolsToVercelFormat(tools);
expect(result).toBeDefined();
expect(Object.keys(result!)).toHaveLength(2);
@@ -88,7 +88,7 @@ describe("convertToolsToVercelFormat", () => {
expect(result?.writeFile.description).toBe("Write a file");
});
test("handles tool without description", () => {
test("handles tool without description", async () => {
const tools: ChatCompletionCreateParams["tools"] = [
{
type: "function",
@@ -102,14 +102,14 @@ describe("convertToolsToVercelFormat", () => {
},
];
const result = convertToolsToVercelFormat(tools);
const result = await convertToolsToVercelFormat(tools);
expect(result).toBeDefined();
expect(result).toHaveProperty("testTool");
expect(result?.testTool.description).toBeUndefined();
});
test("filters out non-function tools", () => {
test("filters out non-function tools", async () => {
const tools: any[] = [
{
type: "function",
@@ -125,7 +125,7 @@ describe("convertToolsToVercelFormat", () => {
},
];
const result = convertToolsToVercelFormat(tools);
const result = await convertToolsToVercelFormat(tools);
expect(result).toBeDefined();
expect(Object.keys(result!)).toHaveLength(1);
@@ -133,7 +133,7 @@ describe("convertToolsToVercelFormat", () => {
expect(result).not.toHaveProperty("customTool");
});
test("returns undefined if all tools are filtered out", () => {
test("returns undefined if all tools are filtered out", async () => {
const tools: any[] = [
{
type: "custom", // Not a function type
@@ -141,12 +141,12 @@ describe("convertToolsToVercelFormat", () => {
},
];
const result = convertToolsToVercelFormat(tools);
const result = await convertToolsToVercelFormat(tools);
expect(result).toBeUndefined();
});
test("preserves parameter schema structure", () => {
test("preserves parameter schema structure", async () => {
const tools: ChatCompletionCreateParams["tools"] = [
{
type: "function",
@@ -178,7 +178,7 @@ describe("convertToolsToVercelFormat", () => {
},
];
const result = convertToolsToVercelFormat(tools);
const result = await convertToolsToVercelFormat(tools);
expect(result).toBeDefined();
expect(result?.complexTool.parameters).toBeDefined();