| import { logEvent } from '../services/analytics/index.js' |
| import { isTerminalTaskStatus } from '../Task.js' |
| import type { LocalAgentTaskState } from '../tasks/LocalAgentTask/LocalAgentTask.js' |
|
|
| |
| |
| const PANEL_GRACE_MS = 30_000 |
|
|
| import type { AppState } from './AppState.js' |
|
|
| |
| |
| |
| function isLocalAgent(task: unknown): task is LocalAgentTaskState { |
| return ( |
| typeof task === 'object' && |
| task !== null && |
| 'type' in task && |
| task.type === 'local_agent' |
| ) |
| } |
|
|
| |
| |
| |
| |
| |
| function release(task: LocalAgentTaskState): LocalAgentTaskState { |
| return { |
| ...task, |
| retain: false, |
| messages: undefined, |
| diskLoaded: false, |
| evictAfter: isTerminalTaskStatus(task.status) |
| ? Date.now() + PANEL_GRACE_MS |
| : undefined, |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export function enterTeammateView( |
| taskId: string, |
| setAppState: (updater: (prev: AppState) => AppState) => void, |
| ): void { |
| logEvent('tengu_transcript_view_enter', {}) |
| setAppState(prev => { |
| const task = prev.tasks[taskId] |
| const prevId = prev.viewingAgentTaskId |
| const prevTask = prevId !== undefined ? prev.tasks[prevId] : undefined |
| const switching = |
| prevId !== undefined && |
| prevId !== taskId && |
| isLocalAgent(prevTask) && |
| prevTask.retain |
| const needsRetain = |
| isLocalAgent(task) && (!task.retain || task.evictAfter !== undefined) |
| const needsView = |
| prev.viewingAgentTaskId !== taskId || |
| prev.viewSelectionMode !== 'viewing-agent' |
| if (!needsRetain && !needsView && !switching) return prev |
| let tasks = prev.tasks |
| if (switching || needsRetain) { |
| tasks = { ...prev.tasks } |
| if (switching) tasks[prevId] = release(prevTask) |
| if (needsRetain) { |
| tasks[taskId] = { ...task, retain: true, evictAfter: undefined } |
| } |
| } |
| return { |
| ...prev, |
| viewingAgentTaskId: taskId, |
| viewSelectionMode: 'viewing-agent', |
| tasks, |
| } |
| }) |
| } |
|
|
| |
| |
| |
| |
| |
| export function exitTeammateView( |
| setAppState: (updater: (prev: AppState) => AppState) => void, |
| ): void { |
| logEvent('tengu_transcript_view_exit', {}) |
| setAppState(prev => { |
| const id = prev.viewingAgentTaskId |
| const cleared = { |
| ...prev, |
| viewingAgentTaskId: undefined, |
| viewSelectionMode: 'none' as const, |
| } |
| if (id === undefined) { |
| return prev.viewSelectionMode === 'none' ? prev : cleared |
| } |
| const task = prev.tasks[id] |
| if (!isLocalAgent(task) || !task.retain) return cleared |
| return { |
| ...cleared, |
| tasks: { ...prev.tasks, [id]: release(task) }, |
| } |
| }) |
| } |
|
|
| |
| |
| |
| |
| |
| export function stopOrDismissAgent( |
| taskId: string, |
| setAppState: (updater: (prev: AppState) => AppState) => void, |
| ): void { |
| setAppState(prev => { |
| const task = prev.tasks[taskId] |
| if (!isLocalAgent(task)) return prev |
| if (task.status === 'running') { |
| task.abortController?.abort() |
| return prev |
| } |
| if (task.evictAfter === 0) return prev |
| const viewingThis = prev.viewingAgentTaskId === taskId |
| return { |
| ...prev, |
| tasks: { |
| ...prev.tasks, |
| [taskId]: { ...release(task), evictAfter: 0 }, |
| }, |
| ...(viewingThis && { |
| viewingAgentTaskId: undefined, |
| viewSelectionMode: 'none', |
| }), |
| } |
| }) |
| } |
|
|