|
1 | 1 | import { Agent } from ".";
|
2 |
| -import { user } from "../base"; |
3 |
| -import type { ModelConfig } from "../llm"; |
4 |
| -import { StateFn } from "../state"; |
5 |
| -import { createTool, runToolCalls } from "../tools"; |
| 2 | +import { userMessage } from "../../functions"; |
| 3 | +import { type ModelProvider } from "../llm"; |
| 4 | +import { Tool, type ToolSet } from "../tools"; |
6 | 5 | import fetch from "node-fetch";
|
7 |
| -import type { ChatCompletionAssistantMessageParam } from "openai/resources"; |
8 | 6 | import { describe, expect, test } from "vitest";
|
9 | 7 | import { z } from "zod";
|
10 | 8 |
|
11 |
| -describe("agent", () => { |
12 |
| - const providers: ModelConfig[] = [ |
| 9 | +describe("@ai-agent-sdk/agent", () => { |
| 10 | + const providers: ModelProvider[] = [ |
13 | 11 | {
|
14 |
| - provider: "OPEN_AI", |
15 |
| - name: "gpt-4o-mini", |
| 12 | + provider: "openai", |
| 13 | + id: "gpt-4o-mini", |
16 | 14 | },
|
17 | 15 | {
|
18 |
| - provider: "GEMINI", |
19 |
| - name: "gemini-1.5-flash", |
| 16 | + provider: "google", |
| 17 | + id: "gemini-1.5-flash", |
20 | 18 | },
|
21 |
| - ] as const; |
| 19 | + ]; |
22 | 20 |
|
23 |
| - providers.forEach((config) => { |
24 |
| - describe(config.provider, () => { |
| 21 | + providers.forEach((model) => { |
| 22 | + describe(`${model.provider}::${model.id}`, () => { |
25 | 23 | test("default agent flow", async () => {
|
26 | 24 | const agent = new Agent({
|
27 | 25 | name: "research agent",
|
28 |
| - model: config, |
| 26 | + model: model, |
29 | 27 | description:
|
30 |
| - "You are a senior NYT researcher writing an article on a topic.", |
| 28 | + "You are a senior New York Times researcher writing an article on a topic.", |
31 | 29 | instructions: [
|
32 | 30 | "For a given topic, search for the top 5 links.",
|
33 | 31 | "Then read each URL and extract the article text, if a URL isn't available, ignore it.",
|
34 |
| - "Analyse and prepare an NYT worthy article based on the information.", |
| 32 | + "Analyze and prepare an New York Times worthy article based on the information.", |
35 | 33 | ],
|
36 | 34 | });
|
37 | 35 |
|
38 |
| - const schema = { |
39 |
| - article: z.object({ |
40 |
| - title: z.string(), |
41 |
| - text: z.string(), |
42 |
| - }), |
43 |
| - }; |
44 |
| - |
45 |
| - const result = await agent.generate( |
46 |
| - [user("The future of AI")], |
47 |
| - schema |
48 |
| - ); |
| 36 | + const result = await agent.generate({ |
| 37 | + messages: [userMessage("Future of AI")], |
| 38 | + }); |
49 | 39 |
|
50 | 40 | console.log(result);
|
51 | 41 |
|
52 |
| - if (result.type !== "article") { |
53 |
| - throw new Error( |
54 |
| - `Expected article response, got ${result.type}` |
55 |
| - ); |
56 |
| - } |
57 |
| - |
58 |
| - expect(result.value["title"]).toBeDefined(); |
59 |
| - expect(result.value["text"]).toBeDefined(); |
| 42 | + expect(result.type).toBe("assistant"); |
| 43 | + expect(result.value).toBeDefined(); |
60 | 44 | });
|
61 | 45 |
|
62 | 46 | test("agent with custom tool", async () => {
|
63 |
| - const tools = { |
64 |
| - weather: createTool({ |
65 |
| - id: "weather-tool", |
66 |
| - description: |
67 |
| - "Fetch the current weather in Vancouver, BC", |
68 |
| - schema: z.object({ |
69 |
| - temperature: z.number(), |
| 47 | + const tools: ToolSet = { |
| 48 | + weather: new Tool({ |
| 49 | + provider: model.provider, |
| 50 | + name: "weather", |
| 51 | + description: "Fetch the current weather in a location", |
| 52 | + parameters: z.object({ |
| 53 | + location: z.string(), |
70 | 54 | }),
|
71 |
| - execute: async (_args) => { |
72 |
| - const lat = 49.2827, |
73 |
| - lon = -123.1207; |
74 |
| - |
75 |
| - const url = `https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}¤t_weather=true`; |
76 |
| - |
77 |
| - const r = await fetch(url); |
78 |
| - const data = await r.json(); |
79 |
| - |
80 |
| - // eslint-disable-next-line @typescript-eslint/ban-ts-comment |
81 |
| - // @ts-expect-error |
82 |
| - return `Current temperature in Vancouver, BC is ${data.current_weather.temperature}°C`; |
| 55 | + execute: async ({ location }) => { |
| 56 | + const response = await fetch( |
| 57 | + `https://api.weatherapi.com/v1/current.json?q=${location}&key=88f97127772c41a991095603230604` |
| 58 | + ); |
| 59 | + const data = await response.json(); |
| 60 | + return data; |
83 | 61 | },
|
84 | 62 | }),
|
85 | 63 | };
|
86 | 64 |
|
87 | 65 | const agent = new Agent({
|
88 |
| - name: "research agent", |
89 |
| - model: config, |
| 66 | + name: "weather agent", |
| 67 | + model, |
90 | 68 | description:
|
91 |
| - "You are a senior NYT researcher writing an article on the current weather in Vancouver, BC.", |
| 69 | + "You are a senior weather analyst writing a summary on the current weather for the provided location.", |
92 | 70 | instructions: [
|
93 | 71 | "Use the weather tool to get the current weather in Celsius.",
|
94 | 72 | "Elaborate on the weather.",
|
95 | 73 | ],
|
96 | 74 | tools,
|
97 | 75 | });
|
98 | 76 |
|
99 |
| - const state = StateFn.root(agent.description); |
100 |
| - state.messages.push( |
101 |
| - user("What is the weather in Vancouver, BC?") |
102 |
| - ); |
103 |
| - |
104 |
| - const result = await agent.run(state); |
105 |
| - expect(result.status).toEqual("paused"); |
106 |
| - expect(result.messages.length).toBeGreaterThan(0); |
107 |
| - |
108 |
| - const toolCall = result.messages[ |
109 |
| - result.messages.length - 1 |
110 |
| - ] as ChatCompletionAssistantMessageParam; |
111 |
| - expect(toolCall?.tool_calls?.length).toBeGreaterThanOrEqual(1); |
112 |
| - |
113 |
| - const toolResponses = await runToolCalls( |
114 |
| - tools, |
115 |
| - toolCall?.tool_calls ?? [] |
116 |
| - ); |
117 |
| - |
118 |
| - const updatedState = { |
119 |
| - ...result, |
120 |
| - status: "running" as const, |
121 |
| - messages: [...result.messages, ...toolResponses], |
122 |
| - }; |
123 |
| - |
124 |
| - const finalResult = await agent.run(updatedState); |
| 77 | + const result = await agent.generate({ |
| 78 | + messages: [userMessage("What is the weather in Delhi?")], |
| 79 | + }); |
125 | 80 |
|
126 |
| - console.log(finalResult); |
| 81 | + console.log(result); |
127 | 82 |
|
128 |
| - expect(finalResult.messages.length).toBeGreaterThan(1); |
129 |
| - expect(finalResult.status).toEqual("finished"); |
| 83 | + expect(result.type).toBe("assistant"); |
| 84 | + expect(result.value).toBeDefined(); |
130 | 85 | });
|
131 | 86 | });
|
132 | 87 | });
|
|
0 commit comments