/ utils / inProcessTeammateHelpers.ts
inProcessTeammateHelpers.ts
  1  /**
  2   * In-Process Teammate Helpers
  3   *
  4   * Helper functions for in-process teammate integration.
  5   * Provides utilities to:
  6   * - Find task ID by agent name
  7   * - Handle plan approval responses
  8   * - Update awaitingPlanApproval state
  9   * - Detect permission-related messages
 10   */
 11  
 12  import type { AppState } from '../state/AppState.js'
 13  import {
 14    type InProcessTeammateTaskState,
 15    isInProcessTeammateTask,
 16  } from '../tasks/InProcessTeammateTask/types.js'
 17  import { updateTaskState } from './task/framework.js'
 18  import {
 19    isPermissionResponse,
 20    isSandboxPermissionResponse,
 21    type PlanApprovalResponseMessage,
 22  } from './teammateMailbox.js'
 23  
 24  type SetAppState = (updater: (prev: AppState) => AppState) => void
 25  
 26  /**
 27   * Find the task ID for an in-process teammate by agent name.
 28   *
 29   * @param agentName - The agent name (e.g., "researcher")
 30   * @param appState - Current AppState
 31   * @returns Task ID if found, undefined otherwise
 32   */
 33  export function findInProcessTeammateTaskId(
 34    agentName: string,
 35    appState: AppState,
 36  ): string | undefined {
 37    for (const task of Object.values(appState.tasks)) {
 38      if (
 39        isInProcessTeammateTask(task) &&
 40        task.identity.agentName === agentName
 41      ) {
 42        return task.id
 43      }
 44    }
 45    return undefined
 46  }
 47  
 48  /**
 49   * Set awaitingPlanApproval state for an in-process teammate.
 50   *
 51   * @param taskId - Task ID of the in-process teammate
 52   * @param setAppState - AppState setter
 53   * @param awaiting - Whether teammate is awaiting plan approval
 54   */
 55  export function setAwaitingPlanApproval(
 56    taskId: string,
 57    setAppState: SetAppState,
 58    awaiting: boolean,
 59  ): void {
 60    updateTaskState<InProcessTeammateTaskState>(taskId, setAppState, task => ({
 61      ...task,
 62      awaitingPlanApproval: awaiting,
 63    }))
 64  }
 65  
 66  /**
 67   * Handle plan approval response for an in-process teammate.
 68   * Called by the message callback when a plan_approval_response arrives.
 69   *
 70   * This resets awaitingPlanApproval to false. The permissionMode from the
 71   * response is handled separately by the agent loop (Task #11).
 72   *
 73   * @param taskId - Task ID of the in-process teammate
 74   * @param _response - The plan approval response message (for future use)
 75   * @param setAppState - AppState setter
 76   */
 77  export function handlePlanApprovalResponse(
 78    taskId: string,
 79    _response: PlanApprovalResponseMessage,
 80    setAppState: SetAppState,
 81  ): void {
 82    setAwaitingPlanApproval(taskId, setAppState, false)
 83  }
 84  
 85  // ============ Permission Delegation Helpers ============
 86  
 87  /**
 88   * Check if a message is a permission-related response.
 89   * Used by in-process teammate message handlers to detect and process
 90   * permission responses from the team leader.
 91   *
 92   * Handles both tool permissions and sandbox (network host) permissions.
 93   *
 94   * @param messageText - The raw message text to check
 95   * @returns true if the message is a permission response
 96   */
 97  export function isPermissionRelatedResponse(messageText: string): boolean {
 98    return (
 99      !!isPermissionResponse(messageText) ||
100      !!isSandboxPermissionResponse(messageText)
101    )
102  }