@@ -111,7 +111,9 @@ export function createDeepAgent<
111111 skills,
112112 } = params ;
113113
114- // Combine system prompt with base prompt like Python implementation
114+ /**
115+ * Combine system prompt with base prompt like Python implementation
116+ */
115117 const finalSystemPrompt = systemPrompt
116118 ? typeof systemPrompt === "string"
117119 ? `${ systemPrompt } \n\n${ BASE_PROMPT } `
@@ -128,15 +130,19 @@ export function createDeepAgent<
128130 } )
129131 : BASE_PROMPT ;
130132
131- // Create backend configuration for filesystem middleware
132- // If no backend is provided, use a factory that creates a StateBackend
133+ /**
134+ * Create backend configuration for filesystem middleware
135+ * If no backend is provided, use a factory that creates a StateBackend
136+ */
133137 const filesystemBackend = backend
134138 ? backend
135139 : ( config : { state : unknown ; store ?: BaseStore } ) =>
136140 new StateBackend ( config ) ;
137141
138- // Add skills middleware if skill sources provided
139- const skillsMiddleware =
142+ /**
143+ * Skills middleware (created conditionally for runtime use)
144+ */
145+ const skillsMiddlewareArray =
140146 skills != null && skills . length > 0
141147 ? [
142148 createSkillsMiddleware ( {
@@ -146,111 +152,144 @@ export function createDeepAgent<
146152 ]
147153 : [ ] ;
148154
149- // Built-in middleware array
155+ /**
156+ * Memory middleware (created conditionally for runtime use)
157+ */
158+ const memoryMiddlewareArray =
159+ memory != null && memory . length > 0
160+ ? [
161+ createMemoryMiddleware ( {
162+ backend : filesystemBackend ,
163+ sources : memory ,
164+ } ) ,
165+ ]
166+ : [ ] ;
167+
168+ /**
169+ * Built-in middleware array - core middleware with known types
170+ * This tuple is typed without conditional spreads to preserve TypeScript's tuple inference.
171+ * Optional middleware (skills, memory, HITL) are handled at runtime but typed explicitly.
172+ */
150173 const builtInMiddleware = [
151- // Provides todo list management capabilities for tracking tasks
174+ /**
175+ * Provides todo list management capabilities for tracking tasks
176+ */
152177 todoListMiddleware ( ) ,
153- // Add skills middleware if skill sources provided
154- ... skillsMiddleware ,
155- // Enables filesystem operations and optional long-term memory storage
178+ /**
179+ * Enables filesystem operations and optional long-term memory storage
180+ */
156181 createFilesystemMiddleware ( { backend : filesystemBackend } ) ,
157- // Enables delegation to specialized subagents for complex tasks
182+ /**
183+ * Enables delegation to specialized subagents for complex tasks
184+ */
158185 createSubAgentMiddleware ( {
159186 defaultModel : model ,
160187 defaultTools : tools as StructuredTool [ ] ,
161188 defaultMiddleware : [
162- // Subagent middleware: Todo list management
189+ /**
190+ * Subagent middleware: Todo list management
191+ */
163192 todoListMiddleware ( ) ,
164- // Subagent middleware: Skills (if provided)
165- ...skillsMiddleware ,
166- // Subagent middleware: Filesystem operations
193+ /**
194+ * Subagent middleware: Skills (if provided) - added at runtime
195+ */
196+ ...skillsMiddlewareArray ,
197+ /**
198+ * Subagent middleware: Filesystem operations
199+ */
167200 createFilesystemMiddleware ( {
168201 backend : filesystemBackend ,
169202 } ) ,
170- // Subagent middleware: Automatic conversation summarization when token limits are approached
203+ /**
204+ * Subagent middleware: Automatic conversation summarization when token limits are approached
205+ */
171206 summarizationMiddleware ( {
172207 model,
173208 trigger : { tokens : 170_000 } ,
174209 keep : { messages : 6 } ,
175210 } ) ,
176- // Subagent middleware: Anthropic prompt caching for improved performance
211+ /**
212+ * Subagent middleware: Anthropic prompt caching for improved performance
213+ */
177214 anthropicPromptCachingMiddleware ( {
178215 unsupportedModelBehavior : "ignore" ,
179216 } ) ,
180- // Subagent middleware: Patches tool calls for compatibility
217+ /**
218+ * Subagent middleware: Patches tool calls for compatibility
219+ */
181220 createPatchToolCallsMiddleware ( ) ,
182221 ] ,
183222 defaultInterruptOn : interruptOn ,
184223 subagents : subagents as unknown as ( SubAgent | CompiledSubAgent ) [ ] ,
185224 generalPurposeAgent : true ,
186225 } ) ,
187- // Automatically summarizes conversation history when token limits are approached
226+ /**
227+ * Automatically summarizes conversation history when token limits are approached
228+ */
188229 summarizationMiddleware ( {
189230 model,
190231 trigger : { tokens : 170_000 } ,
191232 keep : { messages : 6 } ,
192233 } ) ,
193- // Enables Anthropic prompt caching for improved performance and reduced costs
234+ /**
235+ * Enables Anthropic prompt caching for improved performance and reduced costs
236+ */
194237 anthropicPromptCachingMiddleware ( {
195238 unsupportedModelBehavior : "ignore" ,
196239 } ) ,
197- // Patches tool calls to ensure compatibility across different model providers
240+ /**
241+ * Patches tool calls to ensure compatibility across different model providers
242+ */
198243 createPatchToolCallsMiddleware ( ) ,
199- // Add memory middleware if memory sources provided
200- ...( memory != null && memory . length > 0
201- ? [
202- createMemoryMiddleware ( {
203- backend : filesystemBackend ,
204- sources : memory ,
205- } ) ,
206- ]
207- : [ ] ) ,
208244 ] as const ;
209245
210- // Add human-in-the-loop middleware if interrupt config provided
211- if ( interruptOn ) {
212- // builtInMiddleware is typed as readonly to enable type inference
213- // however, we need to push to it to add the middleware, so let's ignore the type error
214- // @ts -expect-error - builtInMiddleware is readonly
215- builtInMiddleware . push ( humanInTheLoopMiddleware ( { interruptOn } ) ) ;
216- }
217-
218- // Combine built-in middleware with custom middleware
219- // The custom middleware is typed as TMiddleware to preserve type information
220- const allMiddleware = [
246+ /**
247+ * Runtime middleware array: combine built-in + optional middleware
248+ * Note: The type is handled separately via AllMiddleware type alias
249+ */
250+ const runtimeMiddleware : AgentMiddleware [ ] = [
221251 ...builtInMiddleware ,
222- ...( customMiddleware as unknown as TMiddleware ) ,
223- ] as const ;
252+ ...skillsMiddlewareArray ,
253+ ...memoryMiddlewareArray ,
254+ ...( interruptOn ? [ humanInTheLoopMiddleware ( { interruptOn } ) ] : [ ] ) ,
255+ ...( customMiddleware as unknown as AgentMiddleware [ ] ) ,
256+ ] ;
224257
225- // Note: Recursion limit of 1000 (matching Python behavior) should be passed
226- // at invocation time: agent.invoke(input, { recursionLimit: 1000 })
258+ /**
259+ * Note: Recursion limit of 1000 (matching Python behavior) should be passed
260+ * at invocation time: agent.invoke(input, { recursionLimit: 1000 })
261+ */
227262 const agent = createAgent ( {
228263 model,
229264 systemPrompt : finalSystemPrompt ,
230265 tools : tools as StructuredTool [ ] ,
231- middleware : allMiddleware as unknown as AgentMiddleware [ ] ,
266+ middleware : runtimeMiddleware ,
232267 responseFormat : responseFormat as ResponseFormat ,
233268 contextSchema,
234269 checkpointer,
235270 store,
236271 name,
237272 } ) ;
238273
239- // Combine custom middleware with flattened subagent middleware for complete type inference
240- // This ensures InferMiddlewareStates captures state from both sources
274+ /**
275+ * Combine custom middleware with flattened subagent middleware for complete type inference
276+ * This ensures InferMiddlewareStates captures state from both sources
277+ */
241278 type AllMiddleware = readonly [
242279 ...typeof builtInMiddleware ,
243280 ...TMiddleware ,
244281 ...FlattenSubAgentMiddleware < TSubagents > ,
245282 ] ;
246283
247- // Return as DeepAgent with proper DeepAgentTypeConfig
248- // - Response: TResponse (from responseFormat parameter)
249- // - State: undefined (state comes from middleware)
250- // - Context: ContextSchema
251- // - Middleware: AllMiddleware (built-in + custom + subagent middleware for state inference)
252- // - Tools: TTools
253- // - Subagents: TSubagents (for type-safe streaming)
284+ /**
285+ * Return as DeepAgent with proper DeepAgentTypeConfig
286+ * - Response: TResponse (from responseFormat parameter)
287+ * - State: undefined (state comes from middleware)
288+ * - Context: ContextSchema
289+ * - Middleware: AllMiddleware (built-in + custom + subagent middleware for state inference)
290+ * - Tools: TTools
291+ * - Subagents: TSubagents (for type-safe streaming)
292+ */
254293 return agent as unknown as DeepAgent <
255294 DeepAgentTypeConfig <
256295 TResponse ,
0 commit comments