Skip to content

Instantly share code, notes, and snippets.

@mizchi
Created September 21, 2024 12:29
Show Gist options
  • Save mizchi/493c2439f53a7ee79b324d1f5fb07546 to your computer and use it in GitHub Desktop.
Save mizchi/493c2439f53a7ee79b324d1f5fb07546 to your computer and use it in GitHub Desktop.
Vercel's ai sdk (claude-stream+tools) does not work with deno. Not compat?
// It does not work.
/*
$ deno run -A vai-claude-tools.ts
Certainly! I can help you get the current weather information for San Francisco. To do this, I'll use the weather function to retrieve the data. Let me make the call for you.error: Uncaught (in promise) AI_TypeValidationError: Type validation failed: Value: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_01S1YL68SUTQiQhfMrF8ENNr","name":"weather","input":{}}}.
Error message: [
{
"received": "tool_use",
"code": "invalid_literal",
"expected": "text",
"path": [
"content_block",
"type"
],
"message": "Invalid literal value, expected \"text\""
},
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"content_block",
"text"
],
"message": "Required"
}
]
at safeValidateTypes (file:///home/mizchi/clis/node_modules/.deno/@[email protected]/node_modules/@ai-sdk/provider-utils/dist/index.mjs:101:14)
at safeParseJSON (file:///home/mizchi/clis/node_modules/.deno/@[email protected]/node_modules/@ai-sdk/provider-utils/dist/index.mjs:144:12)
at Object.transform (file:///home/mizchi/clis/node_modules/.deno/@[email protected]/node_modules/@ai-sdk/provider-utils/dist/index.mjs:336:13)
at Module.invokeCallbackFunction (ext:deno_webidl/00_webidl.js:981:16)
at TransformStreamDefaultController.transformAlgorithm (ext:deno_web/06_streams.js:3789:14)
at transformStreamDefaultControllerPerformTransform (ext:deno_web/06_streams.js:4058:59)
at transformStreamDefaultSinkWriteAlgorithm (ext:deno_web/06_streams.js:4161:10)
at WritableStreamDefaultController.writeAlgorithm (ext:deno_web/06_streams.js:631:12)
at writableStreamDefaultControllerProcessWrite (ext:deno_web/06_streams.js:4485:55)
at writableStreamDefaultControllerAdvanceQueueIfNeeded (ext:deno_web/06_streams.js:4388:5)
Caused by: ZodError: [
{
"received": "tool_use",
"code": "invalid_literal",
"expected": "text",
"path": [
"content_block",
"type"
],
"message": "Invalid literal value, expected \"text\""
},
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"content_block",
"text"
],
"message": "Required"
}
]
at Object.get error (file:///home/mizchi/clis/node_modules/.deno/[email protected]/node_modules/zod/lib/index.mjs:587:31)
at safeValidateTypes (file:///home/mizchi/clis/node_modules/.deno/@[email protected]/node_modules/@ai-sdk/provider-utils/dist/index.mjs:103:33)
at safeParseJSON (file:///home/mizchi/clis/node_modules/.deno/@[email protected]/node_modules/@ai-sdk/provider-utils/dist/index.mjs:144:12)
at Object.transform (file:///home/mizchi/clis/node_modules/.deno/@[email protected]/node_modules/@ai-sdk/provider-utils/dist/index.mjs:336:13)
at Module.invokeCallbackFunction (ext:deno_webidl/00_webidl.js:981:16)
at TransformStreamDefaultController.transformAlgorithm (ext:deno_web/06_streams.js:3789:14)
at transformStreamDefaultControllerPerformTransform (ext:deno_web/06_streams.js:4058:59)
at transformStreamDefaultSinkWriteAlgorithm (ext:deno_web/06_streams.js:4161:10)
at WritableStreamDefaultController.writeAlgorithm (ext:deno_web/06_streams.js:631:12)
at writableStreamDefaultControllerProcessWrite (ext:deno_web/06_streams.js:4485:55)
*/
// for deno
import { anthropic } from "npm:@ai-sdk/[email protected]";
import { streamText, tool } from "npm:[email protected]";
import { z } from "npm:[email protected]";
const _encoder = new TextEncoder();
const write = (text: string) => {
Deno.stdout.write(_encoder.encode(text));
};
const { textStream } = await streamText({
model: anthropic("claude-3-5-sonnet-20240620"),
tools: {
weather: tool({
description: "Get the weather in a location",
// @ts-ignore no types for zod
parameters: z.object({
location: z.string().describe("The location to get the weather for"),
}),
execute: async ({ location }) => {
// This is a fake implementation
return {
location,
temperature: 72 + Math.floor(Math.random() * 21) - 10,
};
},
}),
},
onStepFinish({ text, toolCalls, toolResults, finishReason, usage }) {
console.log("[Step finished]", {
text,
toolCalls,
toolResults,
finishReason,
usage,
});
// your own logic, e.g. for saving the chat history or recording usage
},
// toolChoice: "required",
maxSteps: 5,
prompt: "What is the weather in San Francisco?",
// prompt: "Write a poem about embedding models.",
});
for await (const textPart of textStream) {
write(textPart);
}
write("\n");
// It works.
/*
~/clis took 4s
$ nodets vai-claude-tools-node.ts
Certainly! I can help you get the current weather information for San Francisco. To do this, I'll use the weather function to retrieve the data. Let me make the call for you.
[Step finished] {
text: "Certainly! I can help you get the current weather information for San Francisco. To do this, I'll use the weather function to retrieve the data. Let me make the call for you.",
toolCalls: [
{
type: 'tool-call',
toolCallId: 'toolu_012ixXN18FDaUJrEHv7QiZ9i',
toolName: 'weather',
args: [Object]
}
],
toolResults: [
{
type: 'tool-result',
toolCallId: 'toolu_012ixXN18FDaUJrEHv7QiZ9i',
toolName: 'weather',
args: [Object],
result: [Object]
}
],
finishReason: 'tool-calls',
usage: { promptTokens: 400, completionTokens: 91, totalTokens: 491 }
}
Based on the information I've received, here's the current weather in San Francisco:
The temperature in San Francisco is 81°F (about 27°C).
This temperature suggests that it's quite warm in San Francisco right now. It's a pleasant, summery day, perfect for outdoor activities or enjoying the city. Remember to stay hydrated and use sun protection if you're planning to spend time outside.
Is there anything else you'd like to know about the weather in San Francisco or any other location?
[Step finished] {
text: '\n' +
'\n' +
"Based on the information I've received, here's the current weather in San Francisco:\n" +
'\n' +
'The temperature in San Francisco is 81°F (about 27°C).\n' +
'\n' +
"This temperature suggests that it's quite warm in San Francisco right now. It's a pleasant, summery day, perfect for outdoor activities or enjoying the city. Remember to stay hydrated and use sun protection if you're planning to spend time outside.\n" +
'\n' +
"Is there anything else you'd like to know about the weather in San Francisco or any other location?",
toolCalls: [],
toolResults: [],
finishReason: 'stop',
usage: { promptTokens: 512, completionTokens: 111, totalTokens: 623 }
}
*/
// for node
import { anthropic } from "@ai-sdk/anthropic";
import { streamText, tool } from "ai";
import { z } from "zod";
const _encoder = new TextEncoder();
const write = (text: string) => {
// Deno.stdout.write(_encoder.encode(text));
// for node
// @ts-ignore
process.stdout.write(_encoder.encode(text));
};
const { textStream } = await streamText({
model: anthropic("claude-3-5-sonnet-20240620"),
tools: {
weather: tool({
description: "Get the weather in a location",
// @ts-ignore no types for zod
parameters: z.object({
location: z.string().describe("The location to get the weather for"),
}),
execute: async ({ location }) => {
// This is a fake implementation
return {
location,
temperature: 72 + Math.floor(Math.random() * 21) - 10,
};
},
}),
},
onStepFinish({ text, toolCalls, toolResults, finishReason, usage }) {
write("\n");
console.log("[Step finished]", {
text,
toolCalls,
toolResults,
finishReason,
usage,
});
// your own logic, e.g. for saving the chat history or recording usage
},
// toolChoice: "required",
maxSteps: 5,
prompt: "What is the weather in San Francisco?",
// prompt: "Write a poem about embedding models.",
});
for await (const textPart of textStream) {
write(textPart);
}
write("\n");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment