File size: 2,296 Bytes
064bfd6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | import { useEffect, useRef } from 'react'
import { getIsRemoteMode } from '../../bootstrap/state.js'
import {
type Notification,
useNotifications,
} from '../../context/notifications.js'
import { useAppState } from '../../state/AppState.js'
import { isInProcessTeammateTask } from '../../tasks/InProcessTeammateTask/types.js'
function parseCount(notif: Notification): number {
if (!('text' in notif)) {
return 1
}
const match = notif.text.match(/^(\d+)/)
return match?.[1] ? parseInt(match[1], 10) : 1
}
function foldSpawn(acc: Notification, _incoming: Notification): Notification {
return makeSpawnNotif(parseCount(acc) + 1)
}
function makeSpawnNotif(count: number): Notification {
return {
key: 'teammate-spawn',
text: count === 1 ? '1 agent spawned' : `${count} agents spawned`,
priority: 'low',
timeoutMs: 5000,
fold: foldSpawn,
}
}
function foldShutdown(
acc: Notification,
_incoming: Notification,
): Notification {
return makeShutdownNotif(parseCount(acc) + 1)
}
function makeShutdownNotif(count: number): Notification {
return {
key: 'teammate-shutdown',
text: count === 1 ? '1 agent shut down' : `${count} agents shut down`,
priority: 'low',
timeoutMs: 5000,
fold: foldShutdown,
}
}
/**
* Fires batched notifications when in-process teammates spawn or shut down.
* Uses fold() to combine repeated events into a single notification
* like "3 agents spawned" or "2 agents shut down".
*/
export function useTeammateLifecycleNotification(): void {
const tasks = useAppState(s => s.tasks)
const { addNotification } = useNotifications()
const seenRunningRef = useRef<Set<string>>(new Set())
const seenCompletedRef = useRef<Set<string>>(new Set())
useEffect(() => {
if (getIsRemoteMode()) return
for (const [id, task] of Object.entries(tasks)) {
if (!isInProcessTeammateTask(task)) {
continue
}
if (task.status === 'running' && !seenRunningRef.current.has(id)) {
seenRunningRef.current.add(id)
addNotification(makeSpawnNotif(1))
}
if (task.status === 'completed' && !seenCompletedRef.current.has(id)) {
seenCompletedRef.current.add(id)
addNotification(makeShutdownNotif(1))
}
}
}, [tasks, addNotification])
}
|