types.ts
tasks/InProcessTeammateTask/types.ts
122
Lines
4322
Bytes
5
Exports
6
Imports
10
Keywords
What this is
This page documents one file from the repository and includes its full source so you can read it without leaving the docs site.
Beginner explanation
This file is one piece of the larger system. Its name, directory, imports, and exports show where it fits. Start by reading the exports and related files first.
How it is used
Start from the exports list and related files. Those are the easiest clues for where this file fits into the system.
Expert explanation
Architecturally, this file intersects with tasks-background-jobs. It contains 122 lines, 6 detected imports, and 5 detected exports.
Important relationships
- tasks/InProcessTeammateTask/InProcessTeammateTask.tsx
- bridge/types.ts
- buddy/types.ts
- components/agents/types.ts
- ink/termio/types.ts
- server/types.ts
- services/mcp/types.ts
- services/policyLimits/types.ts
- services/remoteManagedSettings/types.ts
- services/settingsSync/types.ts
- services/teamMemorySync/types.ts
- tasks/types.ts
Detected exports
TeammateIdentityInProcessTeammateTaskStateisInProcessTeammateTaskTEAMMATE_MESSAGES_UI_CAPappendCappedMessage
Keywords
taskteammatemessagesonlyprevmessageruntimearrayitempermissionmode
Detected imports
../../Task.js../../tools/AgentTool/agentToolUtils.js../../tools/AgentTool/loadAgentsDir.js../../types/message.js../../utils/permissions/PermissionMode.js../LocalAgentTask/LocalAgentTask.js
Source notes
This page embeds the full file contents. Small or leaf files are still indexed honestly instead of being over-explained.
Full source
import type { TaskStateBase } from '../../Task.js'
import type { AgentToolResult } from '../../tools/AgentTool/agentToolUtils.js'
import type { AgentDefinition } from '../../tools/AgentTool/loadAgentsDir.js'
import type { Message } from '../../types/message.js'
import type { PermissionMode } from '../../utils/permissions/PermissionMode.js'
import type { AgentProgress } from '../LocalAgentTask/LocalAgentTask.js'
/**
* Teammate identity stored in task state.
* Same shape as TeammateContext (runtime) but stored as plain data.
* TeammateContext is for AsyncLocalStorage; this is for AppState persistence.
*/
export type TeammateIdentity = {
agentId: string // e.g., "researcher@my-team"
agentName: string // e.g., "researcher"
teamName: string
color?: string
planModeRequired: boolean
parentSessionId: string // Leader's session ID
}
export type InProcessTeammateTaskState = TaskStateBase & {
type: 'in_process_teammate'
// Identity as sub-object (matches TeammateContext shape for consistency)
// Stored as plain data in AppState, NOT a reference to AsyncLocalStorage
identity: TeammateIdentity
// Execution
prompt: string
// Optional model override for this teammate
model?: string
// Optional: Only set if teammate uses a specific agent definition
// Many teammates run as general-purpose agents without a predefined definition
selectedAgent?: AgentDefinition
abortController?: AbortController // Runtime only, not serialized to disk - kills WHOLE teammate
currentWorkAbortController?: AbortController // Runtime only - aborts current turn without killing teammate
unregisterCleanup?: () => void // Runtime only
// Plan mode approval tracking (planModeRequired is in identity)
awaitingPlanApproval: boolean
// Permission mode for this teammate (cycled independently via Shift+Tab when viewing)
permissionMode: PermissionMode
// State
error?: string
result?: AgentToolResult // Reuse existing type since teammates run via runAgent()
progress?: AgentProgress
// Conversation history for zoomed view (NOT mailbox messages)
// Mailbox messages are stored separately in teamContext.inProcessMailboxes
messages?: Message[]
// Tool use IDs currently being executed (for animation in transcript view)
inProgressToolUseIDs?: Set<string>
// Queue of user messages to deliver when viewing teammate transcript
pendingUserMessages: string[]
// UI: random spinner verbs (stable across re-renders, shared between components)
spinnerVerb?: string
pastTenseVerb?: string
// Lifecycle
isIdle: boolean
shutdownRequested: boolean
// Callbacks to notify when teammate becomes idle (runtime only)
// Used by leader to efficiently wait without polling
onIdleCallbacks?: Array<() => void>
// Progress tracking (for computing deltas in notifications)
lastReportedToolCount: number
lastReportedTokenCount: number
}
export function isInProcessTeammateTask(
task: unknown,
): task is InProcessTeammateTaskState {
return (
typeof task === 'object' &&
task !== null &&
'type' in task &&
task.type === 'in_process_teammate'
)
}
/**
* Cap on the number of messages kept in task.messages (the AppState UI mirror).
*
* task.messages exists purely for the zoomed transcript dialog, which only
* needs recent context. The full conversation lives in the local allMessages
* array (inProcessRunner) and on disk at the agent transcript path.
*
* BQ analysis (round 9, 2026-03-20) showed ~20MB RSS per agent at 500+ turn
* sessions and ~125MB per concurrent agent in swarm bursts. Whale session
* 9a990de8 launched 292 agents in 2 minutes and reached 36.8GB. The dominant
* cost is this array holding a second full copy of every message.
*/
export const TEAMMATE_MESSAGES_UI_CAP = 50
/**
* Append an item to a message array, capping the result at
* TEAMMATE_MESSAGES_UI_CAP entries by dropping the oldest. Always returns
* a new array (AppState immutability).
*/
export function appendCappedMessage<T>(
prev: readonly T[] | undefined,
item: T,
): T[] {
if (prev === undefined || prev.length === 0) {
return [item]
}
if (prev.length >= TEAMMATE_MESSAGES_UI_CAP) {
const next = prev.slice(-(TEAMMATE_MESSAGES_UI_CAP - 1))
next.push(item)
return next
}
return [...prev, item]
}