1+ import { actor , setup } from "actor-core" ;
2+ import { generateText , jsonSchema , tool } from "ai" ;
3+ import { openai } from "@ai-sdk/openai" ;
4+ import { getWeather } from "../utils/weather" ;
5+ import dotenv from "dotenv" ;
6+
7+ dotenv . config ( ) ;
8+
9+ export type Message = { role : "user" | "assistant" ; content : string ; timestamp : number ; }
10+
11+ const aiAgent = actor ( {
12+ // State is automatically persisted
13+ state : {
14+ messages : [ ] as Message [ ]
15+ } ,
16+
17+ actions : {
18+ // Get conversation history
19+ getMessages : ( c ) => c . state . messages ,
20+
21+ // Send a message to the AI and get a response
22+ sendMessage : async ( c , userMessage : string ) => {
23+ // Add user message to conversation
24+ const userMsg : Message = {
25+ role : "user" ,
26+ content : userMessage ,
27+ timestamp : Date . now ( )
28+ } ;
29+ c . state . messages . push ( userMsg ) ;
30+
31+ // Generate AI response using Vercel AI SDK with tools
32+ const out = await generateText ( {
33+ model : openai ( "o3-mini" ) ,
34+ messages : c . state . messages ,
35+ tools : {
36+ weather : tool ( {
37+ description : 'Get the weather in a location' ,
38+ parameters : jsonSchema < { coords : { longitude : number , latitude : number } } > ( {
39+ type : 'object' ,
40+ properties : {
41+ coords : {
42+ type : 'object' ,
43+ description : 'The location to get the weather for' ,
44+ properties : {
45+ longitude : {
46+ type : 'number' ,
47+ description : 'Longitude of the location'
48+ } ,
49+ latitude : {
50+ type : 'number' ,
51+ description : 'Latitude of the location'
52+ }
53+ } ,
54+ required : [ 'longitude' , 'latitude' ] ,
55+ additionalProperties : false
56+ }
57+ } ,
58+ required : [ 'coords' ] ,
59+ additionalProperties : false
60+ } ) ,
61+ execute : async ( { coords } ) => {
62+ return await getWeather ( coords ) ;
63+ }
64+ } ) ,
65+ } ,
66+ maxSteps : 2 ,
67+ } ) ;
68+
69+ const { text } = out ;
70+
71+ // Add AI response to conversation
72+ const assistantMsg : Message = {
73+ role : "assistant" ,
74+ content : text ,
75+ timestamp : Date . now ( )
76+ } ;
77+ c . state . messages . push ( assistantMsg ) ;
78+
79+ // Broadcast the new message to all connected clients
80+ c . broadcast ( "messageReceived" , assistantMsg ) ;
81+
82+ return assistantMsg ;
83+ } ,
84+ }
85+ } ) ;
86+
87+ // Create and export the app
88+ export const app = setup ( {
89+ actors : { aiAgent } ,
90+ } ) ;
91+
92+ // Export type for client type checking
93+ export type App = typeof app ;
0 commit comments