Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion js/src/experimental/vercel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ const _wrapTools = (
const wrappedTools: Record<string, any> = {};
if (tools) {
for (const [key, tool] of Object.entries(tools)) {
wrappedTools[key] = { ...(tool as Record<string, unknown>) };
wrappedTools[key] = Object.assign(
Object.create(Object.getPrototypeOf(tool)),
tool
);
if (
wrappedTools[key] != null &&
typeof wrappedTools[key] === "object" &&
Expand Down
41 changes: 41 additions & 0 deletions js/src/tests/vercel/wrapper/openai.int.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,47 @@ test("wrap generateText", async () => {
expect(result.providerMetadata).toBeDefined();
});

test("wrap generateText with tool class", async () => {
class MyTool {
inputSchema: z.ZodSchema;
description: string;

constructor(inputSchema: z.ZodSchema, description: string) {
this.inputSchema = inputSchema;
this.description = description;
}

async execute() {
return this.helperMethod();
}

helperMethod() {
return `User has the following orders: 1`;
}
}

const result = await generateText({
model: openai("gpt-5-nano"),
messages: [
{
role: "user",
content: "What are my orders? My user ID is 123. Always use tools.",
},
],
tools: {
listOrders: new MyTool(
z.object({ userId: z.string() }),
"list all orders"
),
},
stopWhen: stepCountIs(10),
});
expect(result.text).toBeDefined();
expect(result.text.length).toBeGreaterThan(0);
expect(result.usage).toBeDefined();
expect(result.providerMetadata).toBeDefined();
});

test("wrap generateText with flex service tier", async () => {
const { client, callSpy } = mockClient();

Expand Down
Loading