82 lines
3.1 KiB
TypeScript
82 lines
3.1 KiB
TypeScript
/**
|
|
* Swarm Initialization Hook
|
|
*
|
|
* Initializes swarm features: teammate hooks and context.
|
|
* Handles both fresh spawns and resumed teammate sessions.
|
|
*
|
|
* This hook is conditionally loaded to allow dead code elimination when swarms are disabled.
|
|
*/
|
|
|
|
import { useEffect } from 'react'
|
|
import { getSessionId } from '../bootstrap/state.js'
|
|
import type { AppState } from '../state/AppState.js'
|
|
import type { Message } from '../types/message.js'
|
|
import { isAgentSwarmsEnabled } from '../utils/agentSwarmsEnabled.js'
|
|
import { initializeTeammateContextFromSession } from '../utils/swarm/reconnection.js'
|
|
import { readTeamFile } from '../utils/swarm/teamHelpers.js'
|
|
import { initializeTeammateHooks } from '../utils/swarm/teammateInit.js'
|
|
import { getDynamicTeamContext } from '../utils/teammate.js'
|
|
|
|
type SetAppState = (f: (prevState: AppState) => AppState) => void
|
|
|
|
/**
|
|
* Hook that initializes swarm features when ENABLE_AGENT_SWARMS is true.
|
|
*
|
|
* Handles both:
|
|
* - Resumed teammate sessions (from --resume or /resume) where teamName/agentName
|
|
* are stored in transcript messages
|
|
* - Fresh spawns where context is read from environment variables
|
|
*/
|
|
export function useSwarmInitialization(
|
|
setAppState: SetAppState,
|
|
initialMessages: Message[] | undefined,
|
|
{ enabled = true }: { enabled?: boolean } = {},
|
|
): void {
|
|
useEffect(() => {
|
|
if (!enabled) return
|
|
if (isAgentSwarmsEnabled()) {
|
|
// Check if this is a resumed agent session (from --resume or /resume)
|
|
// Resumed sessions have teamName/agentName stored in transcript messages
|
|
const firstMessage = initialMessages?.[0]
|
|
const teamName =
|
|
firstMessage && 'teamName' in firstMessage
|
|
? (firstMessage.teamName as string | undefined)
|
|
: undefined
|
|
const agentName =
|
|
firstMessage && 'agentName' in firstMessage
|
|
? (firstMessage.agentName as string | undefined)
|
|
: undefined
|
|
|
|
if (teamName && agentName) {
|
|
// Resumed agent session - set up team context from stored info
|
|
initializeTeammateContextFromSession(setAppState, teamName, agentName)
|
|
|
|
// Get agentId from team file for hook initialization
|
|
const teamFile = readTeamFile(teamName)
|
|
const member = teamFile?.members.find(
|
|
(m: { name: string }) => m.name === agentName,
|
|
)
|
|
if (member) {
|
|
initializeTeammateHooks(setAppState, getSessionId(), {
|
|
teamName,
|
|
agentId: member.agentId,
|
|
agentName,
|
|
})
|
|
}
|
|
} else {
|
|
// Fresh spawn or standalone session
|
|
// teamContext is already computed in main.tsx via computeInitialTeamContext()
|
|
// and included in initialState, so we only need to initialize hooks here
|
|
const context = getDynamicTeamContext?.()
|
|
if (context?.teamName && context?.agentId && context?.agentName) {
|
|
initializeTeammateHooks(setAppState, getSessionId(), {
|
|
teamName: context.teamName,
|
|
agentId: context.agentId,
|
|
agentName: context.agentName,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}, [setAppState, initialMessages, enabled])
|
|
}
|