* Waits for new prompts or shutdown request. * Polls the teammate's mailbox every 500ms, checking for: * - Shutdown request from leader (returned to caller for model decision) * - New messages/prompts from leader * - Abort signal * * This keeps the teammate alive in 'idle' state instead of ter
( identity: TeammateIdentity, abortController: AbortController, taskId: string, getAppState: () => AppState, setAppState: SetAppStateFn, taskListId: string, )
| 687 | * Does NOT auto-approve shutdown - the model should make that decision. |
| 688 | */ |
| 689 | async function waitForNextPromptOrShutdown( |
| 690 | identity: TeammateIdentity, |
| 691 | abortController: AbortController, |
| 692 | taskId: string, |
| 693 | getAppState: () => AppState, |
| 694 | setAppState: SetAppStateFn, |
| 695 | taskListId: string, |
| 696 | ): Promise<WaitResult> { |
| 697 | const POLL_INTERVAL_MS = 500 |
| 698 | |
| 699 | logForDebugging( |
| 700 | `[inProcessRunner] ${identity.agentName} starting poll loop (abort=${abortController.signal.aborted})`, |
| 701 | ) |
| 702 | |
| 703 | let pollCount = 0 |
| 704 | while (!abortController.signal.aborted) { |
| 705 | // Check for in-memory pending messages on every iteration (from transcript viewing) |
| 706 | const appState = getAppState() |
| 707 | const task = appState.tasks[taskId] |
| 708 | if ( |
| 709 | task && |
| 710 | task.type === 'in_process_teammate' && |
| 711 | task.pendingUserMessages.length > 0 |
| 712 | ) { |
| 713 | const message = task.pendingUserMessages[0]! // Safe: checked length > 0 |
| 714 | // Pop the message from the queue |
| 715 | setAppState(prev => { |
| 716 | const prevTask = prev.tasks[taskId] |
| 717 | if (!prevTask || prevTask.type !== 'in_process_teammate') { |
| 718 | return prev |
| 719 | } |
| 720 | return { |
| 721 | ...prev, |
| 722 | tasks: { |
| 723 | ...prev.tasks, |
| 724 | [taskId]: { |
| 725 | ...prevTask, |
| 726 | pendingUserMessages: prevTask.pendingUserMessages.slice(1), |
| 727 | }, |
| 728 | }, |
| 729 | } |
| 730 | }) |
| 731 | logForDebugging( |
| 732 | `[inProcessRunner] ${identity.agentName} found pending user message (poll #${pollCount})`, |
| 733 | ) |
| 734 | return { |
| 735 | type: 'new_message', |
| 736 | message, |
| 737 | from: 'user', |
| 738 | } |
| 739 | } |
| 740 | |
| 741 | // Wait before next poll (skip on first iteration to check immediately) |
| 742 | if (pollCount > 0) { |
| 743 | await sleep(POLL_INTERVAL_MS) |
| 744 | } |
| 745 | pollCount++ |
| 746 |
no test coverage detected