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:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user