11import { z } from 'zod'
22import { ALLOWED_MODEL_PREFIXES , models } from '../constants'
33import { toolNames } from '../constants/tools'
4+ import type { AgentConfig } from '../templates/agent-template'
45
56// Filter models to only include those that begin with allowed prefixes
67const filteredModels = Object . values ( models ) . filter ( ( model ) =>
@@ -11,19 +12,42 @@ if (filteredModels.length === 0) {
1112 throw new Error ( 'No valid models found with allowed prefixes' )
1213}
1314
14- // JSON Schema for params - supports any valid JSON schema
15- const JsonSchemaSchema = z . record ( z . any ( ) ) . refine (
16- ( schema ) => {
17- // Basic validation that it looks like a JSON schema
18- return typeof schema === 'object' && schema !== null
19- } ,
20- { message : 'Must be a valid JSON schema object' }
15+ // Simplified JSON Schema definition - supports object schemas with nested properties
16+ const JsonSchemaSchema : z . ZodType < any > = z . lazy ( ( ) =>
17+ z
18+ . object ( {
19+ type : z . literal ( 'object' ) ,
20+ description : z . string ( ) . optional ( ) ,
21+ properties : z
22+ . record (
23+ JsonSchemaSchema . or (
24+ z
25+ . object ( {
26+ type : z . enum ( [
27+ 'string' ,
28+ 'number' ,
29+ 'integer' ,
30+ 'boolean' ,
31+ 'array' ,
32+ ] ) ,
33+ description : z . string ( ) . optional ( ) ,
34+ enum : z . array ( z . any ( ) ) . optional ( ) ,
35+ } )
36+ . passthrough ( )
37+ )
38+ )
39+ . optional ( ) ,
40+ required : z . array ( z . string ( ) ) . optional ( ) ,
41+ } )
42+ . passthrough ( )
2143)
2244
2345// Schema for the combined inputSchema object
2446const InputSchemaObjectSchema = z
2547 . object ( {
26- prompt : JsonSchemaSchema . optional ( ) , // Optional JSON schema for prompt validation
48+ prompt : z
49+ . object ( { type : z . literal ( 'string' ) , description : z . string ( ) . optional ( ) } )
50+ . optional ( ) , // Optional JSON schema for prompt validation
2751 params : JsonSchemaSchema . optional ( ) , // Optional JSON schema for params validation
2852 } )
2953 . optional ( )
@@ -38,7 +62,7 @@ export type PromptField = z.infer<typeof PromptFieldSchema>
3862// Validates the Typescript template file.
3963export const DynamicAgentConfigSchema = z . object ( {
4064 id : z . string ( ) , // The unique identifier for this agent
41- version : z . string ( ) ,
65+ version : z . string ( ) . optional ( ) ,
4266 override : z . literal ( false ) . optional ( ) . default ( false ) , // Must be false for new agents, defaults to false if missing
4367
4468 // Required fields for new agents
@@ -50,17 +74,20 @@ export const DynamicAgentConfigSchema = z.object({
5074 outputSchema : JsonSchemaSchema . optional ( ) , // Optional JSON schema for output validation
5175 includeMessageHistory : z . boolean ( ) . default ( true ) ,
5276 toolNames : z
53- . array ( z . string ( ) )
54- . default ( [ 'end_turn' ] )
77+ . array ( z . enum ( toolNames ) )
78+ . optional ( )
79+ . default ( [ ] )
5580 . refine (
5681 ( tools ) => {
82+ if ( ! tools ) return true
5783 const validToolNames = toolNames as readonly string [ ]
5884 const invalidTools = tools . filter (
5985 ( tool ) => ! validToolNames . includes ( tool )
6086 )
6187 return invalidTools . length === 0
6288 } ,
6389 ( tools ) => {
90+ if ( ! tools ) return { message : 'Tools array is undefined' }
6491 const validToolNames = toolNames as readonly string [ ]
6592 const invalidTools = tools . filter (
6693 ( tool ) => ! validToolNames . includes ( tool )
@@ -70,34 +97,37 @@ export const DynamicAgentConfigSchema = z.object({
7097 }
7198 }
7299 ) ,
73- subagents : z . array ( z . string ( ) ) . default ( [ ] ) ,
100+ subagents : z . array ( z . string ( ) ) . optional ( ) . default ( [ ] ) ,
74101 inputSchema : InputSchemaObjectSchema ,
75102 parentInstructions : z . record ( z . string ( ) , z . string ( ) ) . optional ( ) ,
76103
77104 // Prompts
78105 parentPrompt : z . string ( ) . optional ( ) ,
79- systemPrompt : PromptFieldSchema ,
80- instructionsPrompt : PromptFieldSchema ,
81- stepPrompt : PromptFieldSchema ,
106+ systemPrompt : z . string ( ) . optional ( ) ,
107+ instructionsPrompt : z . string ( ) . optional ( ) ,
108+ stepPrompt : z . string ( ) ,
82109
83110 // Optional generator function for programmatic agents
84111 handleSteps : z
85112 . function (
86113 z . tuple ( [
87114 z . object ( {
88115 agentState : z . any ( ) ,
89- prompt : z . string ( ) ,
116+ prompt : z . string ( ) . optional ( ) ,
90117 params : z . any ( ) ,
91118 } ) ,
92119 ] ) ,
93120 z . any ( )
94121 )
95122 . optional ( ) ,
96123} )
97-
98124export type DynamicAgentConfig = z . input < typeof DynamicAgentConfigSchema >
99125export type DynamicAgentConfigParsed = z . infer < typeof DynamicAgentConfigSchema >
100126
127+ // Checks that the AgentConfig and DynamicAgentConfig types are compatible
128+ // NOTE TO LLM: Don't remove this line!
129+ const _typecheck : AgentConfig = { } as DynamicAgentConfig
130+
101131export const DynamicAgentTemplateSchema = DynamicAgentConfigSchema . extend ( {
102132 systemPrompt : z . string ( ) ,
103133 instructionsPrompt : z . string ( ) ,
0 commit comments