* Handle spawn operation for in-process teammates. * In-process teammates run in the same Node.js process using AsyncLocalStorage.
( input: SpawnInput, context: ToolUseContext, )
| 827 | * In-process teammates run in the same Node.js process using AsyncLocalStorage. |
| 828 | */ |
| 829 | async function handleSpawnInProcess( |
| 830 | input: SpawnInput, |
| 831 | context: ToolUseContext, |
| 832 | ): Promise<{ data: SpawnOutput }> { |
| 833 | const { setAppState, getAppState } = context |
| 834 | const { name, prompt, agent_type, plan_mode_required } = input |
| 835 | |
| 836 | // Resolve model: 'inherit' → leader's model; undefined → default Opus |
| 837 | const model = resolveTeammateModel(input.model, getAppState().mainLoopModel) |
| 838 | |
| 839 | if (!name || !prompt) { |
| 840 | throw new Error('name and prompt are required for spawn operation') |
| 841 | } |
| 842 | |
| 843 | // Get team name from input or inherit from leader's team context |
| 844 | const appState = getAppState() |
| 845 | const teamName = input.team_name || appState.teamContext?.teamName |
| 846 | |
| 847 | if (!teamName) { |
| 848 | throw new Error( |
| 849 | 'team_name is required for spawn operation. Either provide team_name in input or call spawnTeam first to establish team context.', |
| 850 | ) |
| 851 | } |
| 852 | |
| 853 | // Generate unique name if duplicate exists in team |
| 854 | const uniqueName = await generateUniqueTeammateName(name, teamName) |
| 855 | |
| 856 | // Sanitize the name to prevent @ in agent IDs |
| 857 | const sanitizedName = sanitizeAgentName(uniqueName) |
| 858 | |
| 859 | // Generate deterministic agent ID from name and team |
| 860 | const teammateId = formatAgentId(sanitizedName, teamName) |
| 861 | |
| 862 | // Assign a unique color to this teammate |
| 863 | const teammateColor = assignTeammateColor(teammateId) |
| 864 | |
| 865 | // Look up custom agent definition if agent_type is provided |
| 866 | let agentDefinition: CustomAgentDefinition | undefined |
| 867 | if (agent_type) { |
| 868 | const allAgents = context.options.agentDefinitions.activeAgents |
| 869 | const foundAgent = allAgents.find(a => a.agentType === agent_type) |
| 870 | if (foundAgent && isCustomAgent(foundAgent)) { |
| 871 | agentDefinition = foundAgent |
| 872 | } |
| 873 | logForDebugging( |
| 874 | `[handleSpawnInProcess] agent_type=${agent_type}, found=${!!agentDefinition}`, |
| 875 | ) |
| 876 | } |
| 877 | |
| 878 | // Spawn in-process teammate |
| 879 | const config: InProcessSpawnConfig = { |
| 880 | name: sanitizedName, |
| 881 | teamName, |
| 882 | prompt, |
| 883 | color: teammateColor, |
| 884 | planModeRequired: plan_mode_required ?? false, |
| 885 | model, |
| 886 | } |
no test coverage detected