* Runs the subagent in a non-interactive mode. * This method orchestrates the subagent's execution loop, including prompt templating, * tool execution, and termination conditions. * @param {ContextState} context - The current context state containing variables for prompt templating. * @r
(context: ContextState)
| 342 | * @returns {Promise<void>} A promise that resolves when the subagent has completed its execution. |
| 343 | */ |
| 344 | async runNonInteractive(context: ContextState): Promise<void> { |
| 345 | const chat = await this.createChatObject(context); |
| 346 | |
| 347 | if (!chat) { |
| 348 | this.output.terminate_reason = SubagentTerminateMode.ERROR; |
| 349 | return; |
| 350 | } |
| 351 | |
| 352 | const abortController = new AbortController(); |
| 353 | const toolRegistry: ToolRegistry = |
| 354 | await this.runtimeContext.getToolRegistry(); |
| 355 | |
| 356 | // Prepare the list of tools available to the subagent. |
| 357 | const toolsList: FunctionDeclaration[] = []; |
| 358 | if (this.toolConfig) { |
| 359 | const toolsToLoad: string[] = []; |
| 360 | for (const tool of this.toolConfig.tools) { |
| 361 | if (typeof tool === 'string') { |
| 362 | toolsToLoad.push(tool); |
| 363 | } else { |
| 364 | toolsList.push(tool); |
| 365 | } |
| 366 | } |
| 367 | toolsList.push( |
| 368 | ...toolRegistry.getFunctionDeclarationsFiltered(toolsToLoad), |
| 369 | ); |
| 370 | } |
| 371 | // Add local scope functions if outputs are expected. |
| 372 | if (this.outputConfig && this.outputConfig.outputs) { |
| 373 | toolsList.push(...this.getScopeLocalFuncDefs()); |
| 374 | } |
| 375 | |
| 376 | let currentMessages: Content[] = [ |
| 377 | { role: 'user', parts: [{ text: 'Get Started!' }] }, |
| 378 | ]; |
| 379 | |
| 380 | const startTime = Date.now(); |
| 381 | let turnCounter = 0; |
| 382 | try { |
| 383 | while (true) { |
| 384 | // Check termination conditions. |
| 385 | if ( |
| 386 | this.runConfig.max_turns && |
| 387 | turnCounter >= this.runConfig.max_turns |
| 388 | ) { |
| 389 | this.output.terminate_reason = SubagentTerminateMode.MAX_TURNS; |
| 390 | break; |
| 391 | } |
| 392 | let durationMin = (Date.now() - startTime) / (1000 * 60); |
| 393 | if (durationMin >= this.runConfig.max_time_minutes) { |
| 394 | this.output.terminate_reason = SubagentTerminateMode.TIMEOUT; |
| 395 | break; |
| 396 | } |
| 397 | |
| 398 | const promptId = `${this.runtimeContext.getSessionId()}#${this.subagentId}#${turnCounter++}`; |
| 399 | const messageParams = { |
| 400 | message: currentMessages[0]?.parts || [], |
| 401 | config: { |
no test coverage detected