@@ -5,16 +5,25 @@ import {
5
5
log ,
6
6
step ,
7
7
childExecute ,
8
+ agentInfo ,
8
9
} from "@restackio/ai/agent" ;
10
+ import { z } from "zod" ;
9
11
import * as functions from "../functions" ;
10
- import { executeTodoWorkflow } from "../workflows/executeTodo" ;
12
+ import { executeTodoWorkflow , ExecuteTodoSchema } from "../workflows/executeTodo" ;
13
+
14
+ const CreateTodoSchema = z . object ( {
15
+ todoTitle : z . string ( ) . min ( 1 ) ,
16
+ } ) ;
11
17
12
18
export type EndEvent = {
13
19
end : boolean ;
14
20
} ;
15
21
22
+ // Define events
16
23
export const messagesEvent = defineEvent < functions . Message [ ] > ( "messages" ) ;
17
24
export const endEvent = defineEvent ( "end" ) ;
25
+ export const createTodoEvent = defineEvent ( "createTodo" ) ;
26
+ export const executeTodoWorkflowEvent = defineEvent ( "executeTodoWorkflow" ) ;
18
27
19
28
type agentTodoOutput = {
20
29
messages : functions . Message [ ] ;
@@ -24,82 +33,111 @@ export async function agentTodo(): Promise<agentTodoOutput> {
24
33
let endReceived = false ;
25
34
let agentMessages : functions . Message [ ] = [ ] ;
26
35
27
- const tools = await step < typeof functions > ( { } ) . getTools ( ) ;
28
-
29
36
onEvent ( messagesEvent , async ( { messages } : { messages : functions . Message [ ] } ) => {
30
37
agentMessages . push ( ...messages ) ;
31
38
32
39
const result = await step < typeof functions > ( { } ) . llmChat ( {
33
40
messages : agentMessages ,
34
- tools,
41
+ systemContent : "You are a helpful assistant that can create and execute todos." ,
42
+ model : "gpt-4.1-mini"
35
43
} ) ;
36
44
37
45
agentMessages . push ( result ) ;
38
46
39
- if ( result . tool_calls ) {
40
- log . info ( "result.tool_calls" , { result } ) ;
41
- for ( const toolCall of result . tool_calls ) {
42
- switch ( toolCall . function . name ) {
43
- case "createTodo" :
44
- log . info ( "createTodo" , { toolCall } ) ;
45
- const toolResult = await step < typeof functions > ( { } ) . createTodo (
46
- JSON . parse ( toolCall . function . arguments )
47
- ) ;
48
-
49
- agentMessages . push ( {
50
- role : "tool" ,
51
- tool_call_id : toolCall . id ,
52
- content : toolResult ,
53
- } ) ;
54
-
55
- const toolChatResult = await step < typeof functions > ( { } ) . llmChat ( {
56
- messages : agentMessages ,
57
- tools,
58
- } ) ;
59
-
60
- agentMessages . push ( toolChatResult ) ;
61
-
62
- break ;
63
- case "executeTodoWorkflow" :
64
- log . info ( "executeTodoWorkflow" , { toolCall } ) ;
65
- const workflowId = `executeTodoWorkflow-${ new Date ( ) . getTime ( ) } ` ;
66
- const workflowResult = await childExecute ( {
67
- child : executeTodoWorkflow ,
68
- childId : workflowId ,
69
- input : JSON . parse ( toolCall . function . arguments ) ,
70
- taskQueue : "todo-workflows" ,
71
- } ) ;
72
-
73
- agentMessages . push ( {
74
- role : "tool" ,
75
- tool_call_id : toolCall . id ,
76
- content : JSON . stringify ( workflowResult ) ,
77
- } ) ;
78
-
79
- const toolWorkflowResult = await step < typeof functions > ( { } ) . llmChat (
80
- {
81
- messages : agentMessages ,
82
- tools,
83
- }
84
- ) ;
85
-
86
- agentMessages . push ( toolWorkflowResult ) ;
87
-
88
- break ;
89
- default :
90
- break ;
91
- }
47
+ if ( result . structured_data ?. type === "function_call" ) {
48
+ const { function_name, function_arguments } = result . structured_data ;
49
+ log . info ( function_name , { function_arguments } ) ;
50
+
51
+ switch ( function_name ) {
52
+ case "createTodo" :
53
+ await step < typeof functions > ( { } ) . sendEvent ( {
54
+ agentId : agentInfo ( ) . workflowId ,
55
+ runId : agentInfo ( ) . runId ,
56
+ eventName : "createTodo" ,
57
+ eventInput : { function_arguments }
58
+ } ) ;
59
+ break ;
60
+
61
+ case "executeTodoWorkflow" :
62
+ const args = ExecuteTodoSchema . parse ( function_arguments ) ;
63
+ await step < typeof functions > ( { } ) . sendEvent ( {
64
+ agentId : agentInfo ( ) . workflowId ,
65
+ runId : agentInfo ( ) . runId ,
66
+ eventName : "executeTodoWorkflow" ,
67
+ eventInput : { workflowId : `executeTodoWorkflow-${ Date . now ( ) } ` , args }
68
+ } ) ;
69
+ break ;
92
70
}
93
71
}
72
+
94
73
return agentMessages ;
95
74
} ) ;
96
75
76
+ onEvent ( createTodoEvent , async ( data : any ) => {
77
+ try {
78
+ const parsedArgs = CreateTodoSchema . parse ( data . function_arguments ) ;
79
+ const stepResult = await step < typeof functions > ( { } ) . createTodo ( parsedArgs ) ;
80
+
81
+ await step < typeof functions > ( { } ) . sendEvent ( {
82
+ agentId : agentInfo ( ) . workflowId ,
83
+ runId : agentInfo ( ) . runId ,
84
+ eventName : "messages" ,
85
+ eventInput : {
86
+ messages : [ {
87
+ role : "system" ,
88
+ content : `Function executed: ${ stepResult } `
89
+ } ]
90
+ }
91
+ } ) ;
92
+ } catch ( error : any ) {
93
+ log . error ( "Error in createTodo" , { error : error . toString ( ) } ) ;
94
+ agentMessages . push ( {
95
+ role : "system" ,
96
+ content : `Error handling createTodo: ${ error . message } `
97
+ } ) ;
98
+ }
99
+ } ) ;
100
+
101
+ onEvent ( executeTodoWorkflowEvent , async ( data : any ) => {
102
+ try {
103
+ const { workflowId, args } = data ;
104
+ const workflowResult = await childExecute ( {
105
+ child : executeTodoWorkflow ,
106
+ childId : workflowId ,
107
+ input : args ,
108
+ taskQueue : "todo-workflows"
109
+ } ) ;
110
+
111
+ await step < typeof functions > ( { } ) . sendEvent ( {
112
+ agentId : agentInfo ( ) . workflowId ,
113
+ runId : agentInfo ( ) . runId ,
114
+ eventName : "messages" ,
115
+ eventInput : {
116
+ messages : [ {
117
+ role : "system" ,
118
+ content : `Todo workflow executed successfully! Status: ${ workflowResult . status } Details: ${ workflowResult . details } ID: ${ workflowResult . todoId } `
119
+ } ]
120
+ }
121
+ } ) ;
122
+ } catch ( workflowError : any ) {
123
+ log . error ( "Workflow execution failed" , {
124
+ error : workflowError . toString ( ) ,
125
+ stack : workflowError . stack
126
+ } ) ;
127
+
128
+ agentMessages . push ( {
129
+ role : "system" ,
130
+ content : `The workflow execution failed: ${ workflowError . message } `
131
+ } ) ;
132
+ }
133
+ } ) ;
134
+
97
135
onEvent ( endEvent , async ( ) => {
98
136
endReceived = true ;
99
137
} ) ;
100
138
101
139
await condition ( ( ) => endReceived ) ;
102
-
103
140
log . info ( "end condition met" ) ;
141
+
104
142
return { messages : agentMessages } ;
105
143
}
0 commit comments