@alvin0/ai-agent-sdk-core 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/agent/define/session.d.ts +5 -2
- package/dist/agent/define/session.d.ts.map +1 -1
- package/dist/agent/define/session.js +1 -1
- package/dist/agent/define/session.js.map +1 -1
- package/dist/agent/history/input-work.js +2 -0
- package/dist/agent/history/input-work.js.map +1 -0
- package/dist/agent/loop/control-text.d.ts +6 -0
- package/dist/agent/loop/control-text.d.ts.map +1 -0
- package/dist/agent/loop/control-text.js +2 -0
- package/dist/agent/loop/control-text.js.map +1 -0
- package/dist/agent/loop/run-turn.js +1 -1
- package/dist/agent/loop/run-turn.js.map +1 -1
- package/dist/agent/loop/turn/model-round.js +1 -1
- package/dist/agent/loop/turn/model-round.js.map +1 -1
- package/dist/agent/mode/run-agent.d.ts +8 -15
- package/dist/agent/mode/run-agent.d.ts.map +1 -1
- package/dist/agent/mode/run-agent.js +2 -2
- package/dist/agent/mode/run-agent.js.map +1 -1
- package/dist/agent/team/contracts.d.ts +3 -1
- package/dist/agent/team/contracts.d.ts.map +1 -1
- package/dist/agent/team/managed.d.ts.map +1 -1
- package/dist/agent/team/managed.js +5 -5
- package/dist/agent/team/managed.js.map +1 -1
- package/dist/agent/team/team.d.ts.map +1 -1
- package/dist/agent/team/team.js +1 -1
- package/dist/agent/team/team.js.map +1 -1
- package/dist/agent/tool/pipeline.js +1 -1
- package/dist/agent/tool/pipeline.js.map +1 -1
- package/dist/agent.d.ts +2 -1
- package/dist/agent.js +1 -1
- package/dist/composition/agent/session.js +1 -1
- package/dist/composition/agent/session.js.map +1 -1
- package/dist/composition/agent/types.d.ts +3 -1
- package/dist/composition/agent/types.d.ts.map +1 -1
- package/dist/observability/bus.js +1 -1
- package/dist/primitives/version.d.ts +1 -1
- package/dist/primitives/version.js +1 -1
- package/dist/primitives/version.js.map +1 -1
- package/dist/runtime/registry.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed.js","names":[],"sources":["../../../src/agent/team/managed.ts"],"sourcesContent":["/** Codex-style dynamic worker creation and delegation over AgentTeam. */\n\nimport type { JsonValue } from '../../primitives/index.ts'\nimport { timeoutValue } from '../../platform/config.ts'\nimport { createTextMessage } from '../../message/index.ts'\nimport type { ModelRegistry } from '../../runtime/index.ts'\nimport type { AgentRunEvent } from '../mode/run-agent.ts'\nimport { cloneAgent, type DefinedAgent } from '../define/definition.ts'\nimport {\n type AgentInput,\n type AgentInvocationOptions,\n type AgentResponse,\n type AgentSession,\n type AgentSessionOptions,\n} from '../define/session.ts'\nimport { History, type HistoryEntry, type HistorySnapshot } from '../history/index.ts'\nimport { defineTool, type ToolDefinition } from '../tool/definition.ts'\nimport { ToolRegistry, type ToolCatalog } from '../tool/registry.ts'\nimport { AgentTeam } from './team.ts'\nimport { DEFAULT_WAIT_TIMEOUT_MS } from './common.ts'\nimport type { AgentTeamOptions } from './types.ts'\nimport type { TurnHooks } from '../loop/events.ts'\nimport { waitForSettlement } from '../../async/index.ts'\ntype DetachedSessionOptions = Omit<AgentSessionOptions, 'registry' | 'team' | 'tools'>\n\n/**\n * Default bound on getting one worker RUNNING, overridable per harness with\n * {@link ManagedAgentTeamOptions.spawnTimeoutMs}.\n *\n * Not the worker's deadline — that is `workerTimeoutMs`. This bounds only the\n * setup, so a lead cannot be held for minutes by a call that no longer waits\n * for any work.\n */\nexport const DEFAULT_SPAWN_SETUP_TIMEOUT_MS = 30_000\n\n/** Default bound on stopping one worker; see {@link ManagedAgentTeamOptions.closeTimeoutMs}. */\nexport const DEFAULT_WORKER_CLOSE_TIMEOUT_MS = 30_000\n\n/**\n * Default bound on holding the lead's turn open for news from a worker; see\n * {@link ManagedAgentTeamOptions.holdWaitMs}.\n *\n * Long enough that a lead is not re-prompted about work that has visibly just\n * started, short enough that it keeps control of its own run: at the deadline\n * the turn comes back and the lead decides whether to wait again, close a\n * worker, or answer with what it has.\n */\nexport const DEFAULT_HOLD_WAIT_MS = 15_000\n\n/** Protocol facts only; task strategy and output contracts belong to the host. */\nconst LEAD_INSTRUCTIONS = [\n 'You have access to a managed team. Your task and coordination strategy are defined by the host instructions.',\n 'Return only the caller-requested result in the caller’s format; include explanation only when requested.',\n 'spawn_agent returns a worker lifecycle view, not its final result. list_agents exposes status and retained results; wait_agents waits within its timeout.',\n 'dependsOn references already registered producer instances. Pending dependents start after those producers settle and receive their results or failure status, even if a producer address is later closed or reused.',\n 'fresh starts from the assigned task; fork also copies the completed lead conversation.',\n 'writes declares relative scheduling scopes under the host conflict policy; it does not grant filesystem permissions. Omit it when no write scope is needed.',\n 'send_message is an update, not terminal completion. completed and failed are terminal worker states; pending and running are not.',\n 'Finished workers occupy slots until close_agent. Closing unfinished work requires cancelRunning: true and host authorization.',\n].join(' ')\n\n/** `fresh` starts from the task; `fork` copies the lead's completed conversation. */\nexport type ManagedAgentSpawnContext = 'fresh' | 'fork'\n\n/** Optional host-defined worker roles; the SDK supplies no domain-specific roles. */\nexport interface ManagedAgentRole {\n /** Referred to by `spawn_agent`; the enum the lead chooses from. */\n readonly name: string\n /** What this role is for. Shown to the lead in the spawn tool schema. */\n readonly description: string\n /** When choosing it is correct — and when it is premature. */\n readonly whenToUse?: string\n /** Added to the worker's own instructions; defaults to `description`. */\n readonly instructions?: string\n}\n\n/** What to do about two workers that would write the same files at once. */\nexport type WriteScopeConflictPolicy = 'reject' | 'warn' | 'off'\n\nexport interface ManagedAgentSpawnRequest {\n /** Optional stable team address; generated as worker_N when omitted. */\n readonly name?: string\n readonly task: string\n /** Short specialization added to the generated worker's instructions. */\n readonly specialty?: string\n /**\n * Context the worker starts from; defaults to\n * {@link ManagedAgentTeamOptions.defaultSpawnContext}.\n */\n readonly context?: ManagedAgentSpawnContext\n /** One of {@link ManagedAgentTeamOptions.roles}, when the host declared any. */\n readonly role?: string\n /** Registered producers that must settle before dispatch; failures also release dependents. */\n readonly dependsOn?: readonly string[]\n /** Workspace-relative scheduling declarations, not filesystem authorization. */\n readonly writes?: readonly string[]\n}\n\nexport interface ResolvedManagedAgentSpawnRequest extends ManagedAgentSpawnRequest {\n readonly name: string\n readonly context: ManagedAgentSpawnContext\n readonly dependsOn: readonly string[]\n readonly writes: readonly string[]\n}\n\nexport interface ManagedAgentWorkerResult {\n readonly worker: string\n readonly agentId: string\n readonly conversationId: string\n readonly text: string\n readonly succeeded: boolean\n}\n\n/**\n * Where a generated worker is in its life.\n *\n * `completed` and `failed` are final but NOT gone: a finished worker stays\n * addressable and keeps occupying a `maxWorkers` slot until it is closed, so\n * a lead that spawns without closing runs out of workers rather than silently\n * accumulating them.\n */\nexport type ManagedAgentWorkerStatus =\n | 'pending' | 'running' | 'completed' | 'failed' | 'closed'\n\nexport interface ManagedAgentWorker {\n readonly name: string\n readonly agentId: string\n readonly conversationId: string\n readonly task: string\n readonly specialty?: string\n /** Context this worker was started from. */\n readonly context: ManagedAgentSpawnContext\n readonly role?: string\n /** Workers that had to settle before this one could start. */\n readonly dependsOn: readonly string[]\n /** Files this worker declared it would write. */\n readonly writes: readonly string[]\n readonly status: ManagedAgentWorkerStatus\n /** Non-fatal problems with the division of work, e.g. an accepted overlap. */\n readonly warnings?: readonly string[]\n readonly result?: ManagedAgentWorkerResult\n readonly error?: string\n}\n\nexport interface ManagedAgentTeamOptions {\n readonly registry: ModelRegistry\n readonly lead: DefinedAgent\n readonly leadName?: string\n readonly leadDescription?: string\n readonly team?: AgentTeam | AgentTeamOptions\n readonly maxWorkers?: number\n /**\n * Automatically hold/continue the lead for pending work and wake it for reports.\n * Defaults to true for this convenience helper. Set false for host-driven turns;\n * reports remain delivered quietly and all lifecycle APIs stay available.\n */\n readonly autoLeadCoordination?: boolean\n /** Team tools exposed to workers; defaults to reporting. Full also enables peer coordination. */\n readonly workerTeamTools?: false | 'reporting' | 'full'\n /** Treat a clean completion with empty text as failure. Defaults to false (tool-only work is valid). */\n readonly requireWorkerText?: boolean\n /** Maximum UTF-8 worker task bytes. Defaults to 64 KiB. */\n readonly maxTaskBytes?: number\n /** Maximum UTF-8 specialty bytes. Defaults to 8 KiB. */\n readonly maxSpecialtyBytes?: number\n /**\n * Context a `spawn_agent` call starts a worker from when it does not say.\n * Defaults to `'fresh'`.\n *\n * `'fresh'` is the default because forking is not free: the worker pays for\n * the lead's whole conversation in input tokens on every round it runs, and\n * a worker whose task genuinely stands alone gains nothing for it. A host\n * that knows its workers always operate on the lead's workspace — and so\n * would otherwise watch each of them rediscover it — should set `'fork'`\n * here rather than hope the lead remembers to ask.\n */\n readonly defaultSpawnContext?: ManagedAgentSpawnContext\n /**\n * Worker kinds the lead may choose from, with what each is for.\n *\n * Declaring them replaces free-text `specialty` with an enum, and puts each\n * role's `whenToUse` in the spawn schema — the one place the lead is certain\n * to read before choosing. Leave it unset and `specialty` behaves as before.\n */\n readonly roles?: readonly ManagedAgentRole[]\n /**\n * What to do when a spawn declares `writes` overlapping a worker that would\n * run at the same time. Defaults to `'reject'`.\n *\n * Rejecting is the default because the alternative is silent data loss: both\n * workers write the file and the later write wins. The refusal names the\n * conflicting worker and the overlap, so the lead's available fix — add it\n * to `dependsOn`, or narrow the scope — is visible in the error itself.\n * `'warn'` records it on the worker instead and lets it run; `'off'` skips\n * the check.\n */\n readonly writeScopePolicy?: WriteScopeConflictPolicy\n /**\n * Cap on how much of a dependency's result is handed to its dependents.\n * Defaults to 8 KiB per dependency; at least 4 bytes. Full results remain readable by scoped tool.\n */\n readonly maxDependencyReportBytes?: number\n /** Active run deadline, excluding queued dependencies and setup. Defaults to 10 minutes. */\n readonly workerTimeoutMs?: number\n /** Maximum wait per worker event observer callback. Defaults to 1 second. */\n readonly observerTimeoutMs?: number\n /**\n * How long closing one worker waits for it to stop.\n * Defaults to {@link DEFAULT_WORKER_CLOSE_TIMEOUT_MS}.\n *\n * After that its slot is freed regardless. A worker that ignores its\n * cancellation must not be able to hold the harness at its cap forever.\n */\n readonly closeTimeoutMs?: number\n /**\n * How long the lead's turn is held open waiting for a worker to report,\n * before the lead is asked again. Defaults to {@link DEFAULT_HOLD_WAIT_MS}.\n *\n * Zero-length would be a spin: the lead answers, is told its workers are\n * still running, answers again, and burns its budget before any result\n * arrives. Codex blocks the parent inside its `wait_agent` tool for the same\n * reason.\n */\n readonly holdWaitMs?: number\n /** Allow model-invoked close_agent to cancel unfinished work (default true).\n * Host closeWorker, disposal and user cancellation are always available. */\n readonly allowModelWorkerCancellation?: boolean\n /**\n * How long `spawn_agent` may take to get a worker running.\n * Defaults to {@link DEFAULT_SPAWN_SETUP_TIMEOUT_MS}.\n *\n * Only the setup: the worker's own deadline is `workerTimeoutMs`, and how\n * long the lead may WAIT for it is the team's `waitTimeoutMs` — pass it\n * through `team: { waitTimeoutMs }` when building the harness.\n */\n readonly spawnTimeoutMs?: number\n /** Defaults to cloning the lead definition under the generated worker id. */\n readonly workerTemplate?: DefinedAgent\n readonly workerFactory?: (\n request: ResolvedManagedAgentSpawnRequest,\n ) => DefinedAgent | Promise<DefinedAgent>\n readonly leadSessionOptions?: DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] }\n readonly workerSessionOptions?: DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] }\n /** Per-worker runtime dependencies for least-privilege tools and workspace policy. */\n readonly workerSessionOptionsFactory?: (\n request: ResolvedManagedAgentSpawnRequest,\n ) => (DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] })\n | Promise<DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] }>\n /** Observe every generated worker's model, tool, trace, and compaction events. */\n readonly onWorkerEvent?: (\n worker: string,\n event: AgentRunEvent,\n ) => void | Promise<void>\n}\n\ninterface WorkerRuntime {\n readonly request: ResolvedManagedAgentSpawnRequest\n readonly session: AgentSession\n /** Exact commissioned workers, independent of address reuse or roster removal. */\n dependencies: readonly WorkerRuntime[]\n starting: boolean\n settledComplete: boolean\n closeTask: Promise<ManagedAgentWorkerStatus> | undefined\n status: ManagedAgentWorkerStatus\n /**\n * Whether the lead's own turn created this worker.\n *\n * It decides who is owed the completion report. A worker the MODEL spawned\n * belongs to a conversation that is waiting for a synthesis, so its report\n * wakes an idle lead. A worker the HOST spawned belongs to the host, which is\n * driving the lead itself; waking it there would start a turn the caller did\n * not ask for.\n */\n readonly leadDriven: boolean\n /**\n * Cancels this worker's run.\n *\n * Owned here rather than by the team: `AgentTeam.cancel` only aborts a\n * team-scheduled wake, not a run a host started itself, so without this a\n * detached worker would survive both `close_agent` and `dispose`.\n */\n readonly controller: AbortController\n /**\n * Set the moment a close begins, before anything is aborted.\n *\n * `status` cannot carry this: it only becomes `'closed'` after the run has\n * settled, so the abort's own rejection arrives while the worker still looks\n * like a running one — and gets reported to the lead as a FAILURE it did not\n * cause and cannot act on.\n */\n closing: boolean\n /**\n * This worker's own deadline, so a run that ended can say WHY.\n *\n * An expired deadline surfaces as an ordinary abort — indistinguishable from\n * a close, or from a cancelled parent — unless the signal that expired is\n * kept and asked. Codex reports a status the parent can branch on; this is\n * what makes one reportable here.\n */\n deadline: AbortSignal | undefined\n /** Resolves when the run has ended and been recorded. Never rejects. */\n settled: Promise<void>\n /**\n * Releases a worker held back by `dependsOn`; undefined once it has started.\n *\n * The team holds the matching promise, so `wait_agents` and `list_agents`\n * report a held worker as `pending` rather than as one that has finished.\n */\n start: (() => void) | undefined\n /** Resolves {@link settled}; called exactly once, whatever ended the worker. */\n readonly markSettled: () => void\n warnings: readonly string[]\n result: ManagedAgentWorkerResult | undefined\n error: string | undefined\n readonly evidence: { status: ManagedAgentWorkerStatus; result: ManagedAgentWorkerResult | undefined; error: string | undefined }\n}\n\n/**\n * A dynamic harness whose lead can create specialized workers with spawn_agent.\n *\n * Spawning starts independent work without blocking the lead. Dependencies refer\n * to the commissioned producer instance; closing its address cannot rebind them.\n */\nexport class ManagedAgentTeam {\n readonly team: AgentTeam\n readonly lead: AgentSession\n readonly leadName: string\n private readonly options: ManagedAgentTeamOptions\n private readonly maxWorkers: number\n private readonly maxTaskBytes: number\n private readonly maxSpecialtyBytes: number\n private readonly workerTimeoutMs: number\n private readonly observerTimeoutMs: number\n private readonly closeTimeoutMs: number\n private readonly holdWaitMs: number\n private readonly spawnTimeoutMs: number\n private readonly workerRuntimes = new Map<string, WorkerRuntime>()\n /** Closed roster entries may still own an in-flight follow-up after a bounded close. */\n private readonly drainingWrites = new Set<WorkerRuntime>()\n private readonly preparing = new Map<string, {\n readonly request: ResolvedManagedAgentSpawnRequest\n readonly dependencies: readonly WorkerRuntime[]\n readonly settled: Promise<void>\n }>()\n private readonly lifecycle = new AbortController()\n private disposeTask: Promise<void> | undefined\n private workerSequence = 0\n private readonly maxDependencyReportBytes: number\n private readonly roles: Map<string, ManagedAgentRole>\n\n constructor(options: ManagedAgentTeamOptions) {\n this.options = options\n this.maxWorkers = positiveInteger(options.maxWorkers ?? 7, 'maxWorkers')\n this.maxTaskBytes = positiveInteger(options.maxTaskBytes ?? 64 * 1024, 'maxTaskBytes')\n this.maxSpecialtyBytes = positiveInteger(options.maxSpecialtyBytes ?? 8 * 1024, 'maxSpecialtyBytes')\n this.workerTimeoutMs = timeoutValue(options.workerTimeoutMs ?? 10 * 60_000)\n this.observerTimeoutMs = timeoutValue(options.observerTimeoutMs ?? 1_000)\n this.closeTimeoutMs = timeoutValue(options.closeTimeoutMs ?? DEFAULT_WORKER_CLOSE_TIMEOUT_MS)\n this.holdWaitMs = timeoutValue(options.holdWaitMs ?? DEFAULT_HOLD_WAIT_MS)\n this.spawnTimeoutMs = timeoutValue(options.spawnTimeoutMs ?? DEFAULT_SPAWN_SETUP_TIMEOUT_MS)\n this.maxDependencyReportBytes = positiveInteger(\n options.maxDependencyReportBytes ?? 8 * 1024,\n 'maxDependencyReportBytes',\n )\n if (this.maxDependencyReportBytes < 4) throw new TypeError('maxDependencyReportBytes must be at least 4')\n this.roles = new Map((options.roles ?? []).map(role => [role.name, role]))\n if (this.roles.size !== (options.roles ?? []).length) {\n throw new Error('managed agent roles contain a duplicate name')\n }\n this.team = options.team instanceof AgentTeam\n ? options.team\n : new AgentTeam({\n ...options.team,\n maxMembers: options.team?.maxMembers ?? this.maxWorkers + 1,\n })\n this.leadName = memberName(options.leadName ?? options.lead.id)\n this.lead = options.lead.createSession({\n ...options.leadSessionOptions,\n hooks: this.leadHooks(options.leadSessionOptions?.hooks),\n registry: options.registry,\n tools: mergeTools(options.leadSessionOptions?.tools, this.controlTools()),\n team: {\n team: this.team,\n name: this.leadName,\n role: 'lead',\n instructions: LEAD_INSTRUCTIONS,\n ...(options.leadDescription === undefined ? {} : { description: options.leadDescription }),\n },\n })\n }\n\n /**\n * Hold the lead's turn open while a worker of its is unfinished.\n *\n * This is Codex's shape, arrived at from the other side: there the parent\n * stays inside its turn and loops on its wait tool until it has what it\n * needs. A lead that concludes while its workers are still running answers\n * from nothing — and once the turn is over, the reports that arrive\n * afterwards have no turn left to be read in, so the work stops with no\n * synthesis at all.\n *\n * `runTurn` re-runs a turn whose `onTurnEnd` hook appended history, so\n * saying so is enough to send the lead round again. Its own step and turn\n * budgets bound this, and `canContinue` leaves an aborted or exhausted turn\n * free to end.\n * @param host - Hooks the host supplied; theirs run first and are kept.\n * @returns The hooks to give the lead's session.\n */\n private leadHooks(host: TurnHooks | undefined): TurnHooks {\n return {\n ...host,\n beforeStep: async (context) => {\n // The request for this round is rebuilt from history, so anything\n // delivered quietly before now is about to be read.\n this.unreadReports = false\n this.leadSteer = new AbortController()\n this.leadSignal = context.signal\n return await host?.beforeStep?.(context) ?? { kind: 'proceed' as const }\n },\n onTurnEnd: async (context) => {\n await host?.onTurnEnd?.(context)\n if (this.options.autoLeadCoordination === false) return\n if (!context.canContinue) {\n // The turn is over and cannot be extended — a spent step budget, an\n // error, a stop. A report that arrived during it has no round left to\n // be read in, and the run would end with the synthesis unwritten, so\n // one more turn is scheduled for when the lead goes idle.\n if (this.unreadReports) {\n this.unreadReports = false\n try { this.team.wake(this.leadName) } catch { /* team disposed */ }\n }\n return\n }\n // Pending counts as busy. A worker held behind `dependsOn` has not\n // started, but it WILL run and report, and a lead that concluded while\n // its dependency chain was still queued answers from work that never\n // reached it.\n const outstanding = [...this.workerRuntimes.values()]\n .filter(runtime => runtime.status === 'running' || runtime.status === 'pending')\n if (outstanding.length === 0) return\n // WAIT for news before spending another model call.\n //\n // Re-prompting immediately is a spin: measured on a real run, a lead\n // with slow researchers answered \"still waiting\" twelve times in half a\n // second and had no budget left when the results finally arrived. Codex\n // has the parent block inside `wait_agent` until a mailbox update\n // arrives or a deadline passes; the DeepSeek harness starts the next\n // round only when there is something to start it for. This is the same\n // shape from inside the hook: the turn stays open, costing nothing,\n // until a worker reports or the wait expires.\n await this.awaitWorkerNews(outstanding)\n const busy = [...this.workerRuntimes.values()]\n .filter(runtime => runtime.status === 'running' || runtime.status === 'pending')\n .map(runtime => runtime.request.name)\n if (busy.length === 0) {\n this.lead.inject(\n 'All outstanding managed workers have settled. Their statuses and retained results are available through list_agents.',\n )\n return\n }\n this.lead.inject(\n `Outstanding managed workers: ${busy.join(', ')}. `\n + 'Their current lifecycle status is available through list_agents; wait_agents is bounded by its timeout.',\n )\n },\n }\n }\n\n /** Run the lead. It decides whether and how many workers to create. */\n run(input: AgentInput, invocation: AgentInvocationOptions = {}): Promise<AgentResponse> {\n this.lifecycle.signal.throwIfAborted()\n return this.lead.run(input, invocation)\n }\n\n /**\n * Add a message to the lead's context, and make sure something reads it.\n *\n * Injection alone is enough only while the lead is mid-turn: its next model\n * round rebuilds the request from history and picks the message up. Once the\n * lead has answered and is only waiting on its workers, an injected message\n * sits in history with nothing scheduled to read it — which is what happened\n * to a user who typed a correction while the researchers were still running\n * and never got an answer to it. Idle, the lead is scheduled one turn.\n * @param text - What the user said.\n * @returns True; the message is always accepted.\n */\n steer(text: string): boolean {\n this.lifecycle.signal.throwIfAborted()\n this.lead.inject(text)\n this.leadSteer.abort()\n // Ends a wait the lead is parked in, so the correction is read now rather\n // than after its wait budget expires.\n try { this.team.notifySteer(this.leadName) } catch { /* team disposed */ }\n if (!this.lead.isRunning) {\n try { this.team.wake(this.leadName) } catch { /* team disposed */ }\n }\n return true\n }\n\n /** Host-side equivalent of the model's spawn_agent tool. */\n /**\n * Create a worker and start it, WITHOUT waiting for it.\n *\n * Returns as soon as the worker is running. Use {@link awaitWorker} for its\n * result, {@link workers} for its status, or let the worker's completion\n * notification reach the lead on its own.\n * @param request - Task, and optionally a name and a specialty.\n * @param signal - Cancels the setup, not the worker's run.\n * @returns The worker, in its `running` state.\n */\n async spawn(\n request: ManagedAgentSpawnRequest,\n signal?: AbortSignal,\n ): Promise<ManagedAgentWorker> {\n this.lifecycle.signal.throwIfAborted()\n signal?.throwIfAborted()\n const resolved: ResolvedManagedAgentSpawnRequest = {\n name: memberName(request.name ?? this.nextWorkerName()),\n task: boundedString(request.task, 'worker task', this.maxTaskBytes),\n ...(request.specialty === undefined\n ? {}\n : { specialty: boundedString(request.specialty, 'worker specialty', this.maxSpecialtyBytes) }),\n context: spawnContext(request.context ?? this.options.defaultSpawnContext ?? 'fresh'),\n ...(request.role === undefined ? {} : { role: this.requireRole(request.role) }),\n dependsOn: this.resolveDependencies(request.dependsOn ?? []),\n writes: [...new Set((request.writes ?? []).map(normalizeWriteScope))],\n }\n Object.freeze(resolved.dependsOn)\n Object.freeze(resolved.writes)\n Object.freeze(resolved)\n const dependencies = resolved.dependsOn.map(name => this.workerRuntimes.get(name)!)\n if (this.workerRuntimes.size + this.preparing.size >= this.maxWorkers) {\n throw new Error(`managed agent team reached its ${this.maxWorkers}-worker limit`)\n }\n if (this.preparing.has(resolved.name) || this.workerRuntimes.has(resolved.name)\n || this.team.members().some(member => member.name === resolved.name)) {\n throw new Error(`managed worker '${resolved.name}' already exists`)\n }\n\n let markPrepared!: () => void\n const prepared = new Promise<void>(resolve => { markPrepared = resolve })\n this.preparing.set(resolved.name, { request: resolved, dependencies, settled: prepared })\n let runtime: WorkerRuntime | undefined\n try {\n const warnings = this.checkWriteScopes(resolved, dependencies)\n const operationSignal = combineSignals(signal, this.lifecycle.signal, AbortSignal.timeout(this.spawnTimeoutMs))\n const definition = await abortable(this.workerDefinition(resolved), operationSignal)\n operationSignal.throwIfAborted()\n const scopedSessionOptions = this.options.workerSessionOptionsFactory === undefined\n ? undefined\n : await abortable(Promise.resolve(this.options.workerSessionOptionsFactory(resolved)), operationSignal)\n operationSignal.throwIfAborted()\n const sessionOptions = { ...this.options.workerSessionOptions, ...scopedSessionOptions }\n const workerTeamTools = this.options.workerTeamTools ?? 'reporting'\n const session = definition.createSession({\n ...sessionOptions,\n ...(dependencies.length === 0 ? {} : { tools: mergeTools(sessionOptions.tools, [this.dependencyReadTool(dependencies)]) }),\n ...(resolved.context === 'fork' ? { history: this.forkLeadHistory(sessionOptions.historyLimits) } : {}),\n registry: this.options.registry,\n team: {\n team: this.team,\n name: resolved.name,\n role: 'peer',\n tools: workerTeamTools,\n instructions: [\n `You are managed worker '${resolved.name}'; lead: '${this.leadName}'.`,\n 'Return only the caller-requested result in the caller’s format; include explanation only when requested.',\n 'Your terminal result is delivered automatically.',\n ...(workerTeamTools === false ? [] : ['send_message is context, not a substitute result; it cannot target yourself.']),\n ].join(' '),\n ...(resolved.specialty === undefined ? {} : { description: resolved.specialty }),\n },\n })\n const controller = new AbortController()\n let markSettled!: () => void\n runtime = {\n request: resolved,\n session,\n dependencies,\n starting: false,\n settledComplete: false,\n closeTask: undefined,\n status: 'pending',\n leadDriven: this.lead.isRunning,\n closing: false,\n deadline: undefined,\n controller,\n settled: new Promise<void>((resolve) => { markSettled = resolve }),\n markSettled: () => { recordEvidence(runtime!); runtime!.settledComplete = true; markSettled() },\n start: undefined,\n warnings,\n result: undefined,\n error: undefined,\n evidence: { status: 'pending', result: undefined, error: undefined },\n }\n this.workerRuntimes.set(resolved.name, runtime)\n this.preparing.delete(resolved.name)\n\n const deliverySignal = combineSignals(operationSignal, controller.signal)\n await abortable(this.team.sendMessage({\n from: this.leadName,\n target: resolved.name,\n message: resolved.task,\n delivery: 'quiet',\n signal: deliverySignal,\n }), deliverySignal)\n deliverySignal.throwIfAborted()\n if (definition.memory.autoCaptureObjective) {\n session.memory.captureOriginalObjective(createTextMessage(resolved.task))\n }\n\n if (dependencies.length > 0 && !this.dependenciesSettled(dependencies, resolved.writes)) {\n // Held, not started. The promise handed to the team is what makes the\n // wait honest: without it `wait_agents` asks an idle session whether it\n // is finished, is told yes, and the lead reads a worker that never ran\n // as one that had nothing to report.\n const held = new Promise<void>((resolve) => { runtime!.start = resolve })\n this.team.markPending(resolved.name, held)\n for (const dependency of dependencies) {\n if (SETTLED_WORKER_STATUS.has(dependency.status) && this.workerHasWork(dependency)) {\n // A completed worker may be running a team-scheduled follow-up.\n // Its original managed watcher has already finished.\n void this.team.whenIdle(dependency.request.name).then(() => this.releaseDependents(dependency)).catch(() => {})\n }\n }\n return this.workerView(runtime)\n }\n await this.startWorker(runtime, deliverySignal)\n return this.workerView(runtime)\n } catch (error: unknown) {\n if (runtime !== undefined && this.workerRuntimes.get(resolved.name) === runtime && !runtime.closing) {\n runtime.status = 'failed'\n runtime.error = errorMessage(error)\n runtime.start = undefined\n runtime.dependencies = []\n try { this.team.markPending(resolved.name, undefined) } catch { /* team already disposed */ }\n runtime.markSettled()\n this.workerRuntimes.delete(resolved.name)\n try { this.team.detach(resolved.name) } catch { /* registration already removed */ }\n await this.releaseDependents(runtime)\n }\n throw error\n } finally {\n this.preparing.delete(resolved.name)\n markPrepared()\n }\n }\n\n /**\n * Put a worker on the model, at last.\n *\n * Separate from `spawn` because a worker with dependencies is created now and\n * started later; the two used to be the same moment.\n */\n private beginWorker(runtime: WorkerRuntime): void {\n const name = runtime.request.name\n if (runtime.status !== 'pending' || runtime.closing || this.lifecycle.signal.aborted\n || this.workerRuntimes.get(name) !== runtime) return\n runtime.start?.()\n runtime.start = undefined\n this.team.markPending(name, undefined)\n // Closed while it was held: there is nothing left to start, and starting it\n // anyway would resurrect a worker the lead had already let go.\n runtime.status = 'running'\n\n // Started, NOT awaited. `runPending` begins the run eagerly and\n // synchronously, so by the time this returns the worker is genuinely\n // going; the promise is simply left for `followWorker` to watch.\n // Awaiting it in `spawn` is what blinded the lead: parked inside its own\n // tool call it could not read the worker's messages, could not spawn\n // anything else, and could not be told that the worker had gone quiet.\n //\n // `runPending` rather than `streamPending`, and that is load-bearing:\n // `onEvent` is delivered by the consumer `runPending` wraps around the\n // handle, so a bare `streamPending` starts the run and reports NOTHING.\n // Every worker event is lost with it — including the approval requests a\n // worker parks on, which leaves it waiting for an answer nobody was ever\n // shown, and the run hangs.\n const deadline = AbortSignal.timeout(this.workerTimeoutMs)\n runtime.deadline = deadline\n const running = runtime.session.runPending({\n signal: combineSignals(runtime.controller.signal, deadline),\n ...(this.options.onWorkerEvent === undefined\n ? {}\n : { onEvent: (event: AgentRunEvent) => this.observeWorkerEvent(name, event) }),\n })\n void this.followWorker(runtime, running)\n }\n\n /** One handoff path for both already-settled and asynchronously released dependencies. */\n private async startWorker(runtime: WorkerRuntime, setupSignal?: AbortSignal): Promise<void> {\n if (runtime.starting || runtime.status !== 'pending' || runtime.closing || this.lifecycle.signal.aborted) return\n runtime.starting = true\n try {\n const report = this.dependencyReport(runtime.dependencies)\n if (report !== undefined) {\n const signal = combineSignals(setupSignal, runtime.controller.signal, this.lifecycle.signal,\n AbortSignal.timeout(this.spawnTimeoutMs))\n await abortable(this.team.sendMessage({ from: this.leadName, target: runtime.request.name,\n message: report, delivery: 'quiet', signal }), signal)\n signal.throwIfAborted()\n }\n this.beginWorker(runtime)\n } catch (error: unknown) {\n // Missing required context is a visible failure, never a successful task\n // dispatched with the dependencies silently omitted.\n if (!runtime.closing && !this.lifecycle.signal.aborted) {\n runtime.status = 'failed'\n runtime.error = `dependency handoff failed: ${errorMessage(error)}`\n recordEvidence(runtime)\n runtime.start?.()\n runtime.start = undefined\n try {\n this.team.markPending(runtime.request.name, undefined)\n this.team.recordOutcome(runtime.request.name, { kind: 'failed', message: runtime.error })\n } catch { /* shared team already disposed */ }\n await this.notifyLead(runtime, `failed: ${runtime.error}`)\n runtime.markSettled()\n await this.releaseDependents(runtime)\n }\n } finally {\n // Retain producer facts only while queued/preparing. Completed ancestors\n // must not keep entire sessions alive through an arbitrarily long chain.\n runtime.dependencies = []\n }\n }\n\n /**\n * The `role` parameter, when the host declared any roles.\n *\n * Each role's purpose and precondition go in the description, which is where\n * Codex puts its role registry too: the lead is choosing a role at the\n * moment it reads this, so this is the only place the guidance can arrive in\n * time to change the choice.\n * @returns A one-property object to spread, or nothing.\n */\n private roleSchema(): Record<string, unknown> {\n if (this.roles.size === 0) return {}\n const lines = [...this.roles.values()].map(role =>\n `- ${role.name}: ${role.description}`\n + (role.whenToUse === undefined ? '' : ` Use when: ${role.whenToUse}`))\n return {\n role: {\n type: 'string',\n enum: [...this.roles.keys()],\n description: `Which kind of worker this is.\\n${lines.join('\\n')}`,\n },\n }\n }\n\n /** Resolve a declared role name, or say which ones exist. */\n private requireRole(name: unknown): string {\n const value = nonEmpty(name, 'worker role')\n if (this.roles.size === 0) {\n throw new Error('this managed team declares no roles, so spawn_agent takes no role')\n }\n if (!this.roles.has(value)) {\n throw new Error(\n `unknown worker role '${value}'; declared roles are ${[...this.roles.keys()].join(', ')}`,\n )\n }\n return value\n }\n\n /**\n * Check the named dependencies and return them deduplicated.\n *\n * A dependency can only name a worker that already exists, and a new worker\n * is not yet nameable by anything, so the graph cannot contain a cycle by\n * construction — no cycle check is needed here, and a `dependsOn` that could\n * name a future worker would need one.\n */\n private resolveDependencies(names: readonly string[]): readonly string[] {\n return [...new Set(names.map((name) => {\n const address = memberName(name)\n if (!this.workerRuntimes.has(address)) {\n throw new Error(\n `unknown dependency '${address}'; a worker can only depend on one that already exists`,\n )\n }\n return address\n }))]\n }\n\n /**\n * Judge a new worker's write scopes against the ones already in flight.\n *\n * Only workers that could run AT THE SAME TIME conflict. One that this\n * worker depends on, directly or through others, writes its files before\n * this one begins, so sharing a scope with it is ordinary sequential work —\n * and is in fact the fix the refusal points at.\n * @param request - The resolved spawn request.\n * @returns Warnings to record; throws instead under the `reject` policy.\n */\n private checkWriteScopes(request: ResolvedManagedAgentSpawnRequest, dependencies: readonly WorkerRuntime[]): readonly string[] {\n const policy = this.options.writeScopePolicy ?? 'reject'\n if (policy === 'off' || request.writes.length === 0) return []\n const ancestors = this.ancestorsOf(dependencies)\n const found: string[] = []\n const runningRoster = new Set(this.team.members().filter(member => member.status === 'running').map(member => member.conversationId))\n const others = [\n ...[...this.workerRuntimes.values()].filter(other => other.status === 'pending' || other.status === 'running' || this.workerHasWork(other, runningRoster))\n .filter(other => !ancestors.has(other)),\n ...this.drainingWrites,\n ...[...this.preparing.values()].filter(other => other.request.name !== request.name),\n ]\n for (const other of others) {\n const clash = request.writes.filter(mine =>\n other.request.writes.some(theirs => scopesOverlap(mine, theirs)))\n if (clash.length === 0) continue\n const detail = `'${other.request.name}' also writes ${clash.join(', ')}`\n if (policy === 'reject') {\n throw new Error(\n `worker '${request.name}' would write files another running worker writes: ${detail}.`\n + ` Add '${other.request.name}' to dependsOn so it runs after, or narrow the scopes`\n // Observed in a real run: four read-only researchers each declared the\n // same placeholder scope and collided over a file none of them would\n // ever write. The refusal used to offer only dependsOn and narrowing,\n // which sends a worker that writes nothing looking for a better fake\n // path instead of dropping the field.\n + ' — or omit writes entirely if this worker only reads.',\n )\n }\n found.push(detail)\n }\n return found\n }\n\n /**\n * Say what actually happened to a worker, in words the lead can act on.\n *\n * A raw abort reads \"The operation was aborted due to timeout\", which tells\n * the lead nothing about WHOSE timeout or whether re-delegating would help.\n * Codex reports a status the parent can branch on; the DeepSeek harness\n * records a blocker code with an explanation. This is the same idea at the\n * size this harness needs.\n * @param error - Whatever ended the run.\n * @returns The explanation to record and report.\n */\n private describeWorkerFailure(error: unknown, runtime: WorkerRuntime | undefined): string {\n if (runtime?.deadline?.aborted === true) return this.deadlineFailure()\n const name = (error as { name?: unknown } | null)?.name\n if (name === 'TimeoutError') return this.deadlineFailure()\n if (name === 'AbortError') return 'its work was cancelled before it finished'\n return errorMessage(error)\n }\n\n /** The one explanation an expired worker deadline deserves. */\n private deadlineFailure(): string {\n return `it ran past its ${String(this.workerTimeoutMs)}ms deadline without finishing.`\n + ' Narrow the task, or split it, before delegating it again'\n }\n\n /**\n * Block until a worker reports, or the hold deadline passes.\n *\n * Bounded on purpose. An unbounded wait would hand the whole run's liveness to\n * the slowest worker and, since this runs inside a turn hook, would be cut off\n * by the hook timeout rather than by anything that understands the work. When\n * it expires the lead gets its turn back and decides for itself — wait again\n * with `wait_agents`, close one, or answer with what it has.\n * @param outstanding - Workers that have not settled.\n */\n private async awaitWorkerNews(outstanding: readonly WorkerRuntime[]): Promise<void> {\n let removeSteer: (() => void) | undefined\n let timer: ReturnType<typeof setTimeout> | undefined\n const deadline = new Promise<void>((resolve) => {\n timer = setTimeout(resolve, this.holdWaitMs)\n // A timer must never be the reason a process stays alive. Node exposes\n // `unref`; a browser timer has no such handle and needs none.\n ;(timer as unknown as { unref?: () => void }).unref?.()\n })\n try {\n const steered = this.leadSteer.signal\n const correction = new Promise<void>(resolve => {\n if (steered.aborted) resolve()\n else steered.addEventListener('abort', resolveSteer, { once: true })\n function resolveSteer() { resolve() }\n removeSteer = () => steered.removeEventListener('abort', resolveSteer)\n })\n await abortable(Promise.race([...outstanding.map(runtime => runtime.settled), deadline, correction]),\n combineSignals(this.lifecycle.signal, this.leadSignal))\n } finally {\n if (timer !== undefined) clearTimeout(timer)\n removeSteer?.()\n }\n }\n\n /** Every worker reachable through `dependsOn`, transitively. */\n private ancestorsOf(workers: readonly WorkerRuntime[], seen = new Set<WorkerRuntime>()): Set<WorkerRuntime> {\n for (const runtime of workers) {\n if (seen.has(runtime)) continue\n seen.add(runtime)\n this.ancestorsOf(runtime.dependencies, seen)\n }\n return seen\n }\n\n /** Includes team-owned follow-ups queued between session runs. */\n private workerHasWork(runtime: WorkerRuntime, runningRoster?: ReadonlySet<string | undefined>): boolean {\n return runtime.session.isRunning || this.drainingWrites.has(runtime)\n || (runningRoster === undefined\n ? this.team.members().some(member => member.name === runtime.request.name\n && member.conversationId === runtime.session.conversationId && member.status === 'running')\n : runningRoster.has(runtime.session.conversationId))\n }\n\n /** Whether every named worker has reached a final state without conflicting active writes. */\n private dependenciesSettled(workers: readonly WorkerRuntime[], writes: readonly string[] = []): boolean {\n return workers.every(runtime => SETTLED_WORKER_STATUS.has(runtime.status)\n && !((this.options.writeScopePolicy ?? 'reject') === 'reject'\n && writes.some(mine => runtime.request.writes.some(theirs => scopesOverlap(mine, theirs)))\n && this.workerHasWork(runtime)))\n }\n\n /**\n * Start whatever was waiting on the worker that just settled.\n *\n * Dependents are released when their dependencies SETTLE, not when they\n * succeed. Requiring success would let one failed worker strand every step\n * planned after it, and a plan that stalls silently is worse than one whose\n * later stages are told the earlier ones broke — which is exactly what they\n * are told: each dependent starts with what its dependencies produced.\n */\n private async releaseDependents(finished: WorkerRuntime): Promise<void> {\n if (this.lifecycle.signal.aborted) return\n const ready = [...this.workerRuntimes.values()].filter(runtime =>\n runtime.status === 'pending'\n && !runtime.closing\n && runtime.dependencies.includes(finished)\n && this.dependenciesSettled(runtime.dependencies, runtime.request.writes))\n for (const runtime of ready) {\n await this.startWorker(runtime)\n }\n }\n\n /** What the dependencies produced, as context for a dependent about to start. */\n private dependencyReport(workers: readonly WorkerRuntime[]): string | undefined {\n let hasTruncatedResult = false\n const lines = workers.map((runtime) => {\n const name = runtime.request.name\n if (runtime.error !== undefined) {\n const partial = runtime.result?.text\n const payload = partial ? truncate(partial, this.maxDependencyReportBytes) : undefined\n hasTruncatedResult ||= payload !== undefined && payload !== partial\n return `- worker address '${name}' FAILED: ${runtime.error}`\n + (partial ? '' : '\\nResult payload: absent. No result data was returned.')\n + (payload === undefined ? '' : `\\nPartial findings (not a completed task): ${payload}`)\n }\n if (runtime.result === undefined && runtime.status === 'closed') return `- worker address '${name}': closed before reporting. Result payload: absent. No result data was returned.`\n const text = runtime.result?.text ?? ''\n const payload = truncate(text, this.maxDependencyReportBytes)\n hasTruncatedResult ||= payload !== text\n return `- worker address '${name}' finished. ${payload === text ? 'Full' : 'Truncated'} result payload:\\n${payload}`\n })\n if (lines.length === 0) return undefined\n return [\n 'Dependency result data: worker addresses are routing metadata. Preserve source identifiers supplied in payloads; an absent payload supplies no evidence identifiers.',\n ...lines,\n ...(hasTruncatedResult ? ['Read truncated results with read_dependency_result, the original worker address and nextOffset.'] : []),\n ].join('\\n')\n }\n\n /** Only this worker's commissioned producer instances are readable, including after closure. */\n private dependencyReadTool(dependencies: readonly WorkerRuntime[]): ToolDefinition {\n const scope = new Map(dependencies.map(runtime => [runtime.request.name, runtime.evidence]))\n return defineTool({\n name: 'read_dependency_result',\n description: 'Read a bounded page from an original dependency result, including after closure. Full handoffs already contain the same result. Use nextOffset until null; partial/failed results are not completed work.',\n parameters: { type: 'object', properties: { name: { type: 'string' }, offset: { type: 'integer', minimum: 0 } }, required: ['name'], additionalProperties: false },\n parse(raw: unknown) {\n if (typeof raw !== 'object' || raw === null) throw new TypeError('dependency name and offset required')\n const name = Reflect.get(raw, 'name'), offset = Reflect.get(raw, 'offset') ?? 0\n if (typeof name !== 'string' || !Number.isSafeInteger(offset) || offset < 0) throw new TypeError('invalid dependency name or offset')\n return { name, offset: offset as number }\n },\n execute: ({ name, offset }) => {\n const producer = scope.get(name)\n if (producer === undefined) throw new Error('this worker was not commissioned against that dependency')\n const text = producer.result?.text ?? ''\n if (offset > text.length || (offset > 0 && /[\\uDC00-\\uDFFF]/.test(text[offset]!))) throw new RangeError('offset must be a valid character boundary')\n // Offsets count UTF-16 code units, returned pages stay within the byte cap.\n const page = prefixWithinBytes(text.slice(offset), this.maxDependencyReportBytes)\n const next = offset + page.length\n return { name, status: producer.status, succeeded: producer.result?.succeeded ?? false,\n ...(producer.error === undefined ? {} : { error: producer.error }), text: page,\n nextOffset: next < text.length ? next : null }\n },\n isConcurrencySafe: () => true,\n })\n }\n\n /**\n * Watch a detached worker run to its end and report it.\n *\n * Never rejects: the run has no awaiting caller, so a throw here would be an\n * unhandled rejection. Failures are recorded on the runtime and told to the\n * lead instead, which is the same shape `AgentTeam.runWakeLoop` uses for the\n * other kind of un-awaited member run.\n */\n private async followWorker(\n runtime: WorkerRuntime,\n running: Promise<AgentResponse>,\n ): Promise<void> {\n const name = runtime.request.name\n try {\n const response = await running\n if (runtime.status !== 'closed' && !runtime.closing) {\n // A run that RESOLVES has not necessarily succeeded: a model call that\n // failed ends the turn with an error reason and an empty answer. Read\n // as a success it became \"Worker 'x' finished:\" with nothing after the\n // colon — the lead told a sector was done by a worker that never got\n // an answer out of the model, which is worse than being told nothing.\n const failure = runtime.deadline?.aborted === true\n ? this.deadlineFailure()\n : failureOf(response, this.options.requireWorkerText === true)\n if (failure !== undefined) {\n runtime.status = 'failed'\n runtime.error = failure\n // A failed final request must not erase evidence already returned.\n // Preserve partial output, but never report it as successful work.\n if (response.text.trim() !== '') {\n runtime.result = Object.freeze({\n worker: name,\n agentId: runtime.session.definition.id,\n conversationId: runtime.session.conversationId,\n text: response.text,\n succeeded: false,\n })\n }\n recordEvidence(runtime)\n this.team.recordOutcome(name, { kind: 'failed', message: failure })\n await this.notifyLead(runtime, `failed: ${failure}`\n + (runtime.result === undefined ? '' : `\\nPartial findings (not a completed task): ${runtime.result.text}`))\n } else {\n runtime.status = 'completed'\n runtime.result = Object.freeze({\n worker: name,\n agentId: runtime.session.definition.id,\n conversationId: runtime.session.conversationId,\n text: response.text,\n succeeded: response.outcome.completed,\n })\n recordEvidence(runtime)\n this.team.recordOutcome(name, { kind: 'completed', text: response.text })\n await this.notifyLead(runtime, `finished: ${response.text}`)\n }\n }\n } catch (error: unknown) {\n // A close is not a failure. Reporting the abort it caused would tell the\n // lead its own decision went wrong, and — once a report can wake an idle\n // lead — would start a turn about a worker it deliberately abandoned.\n if (runtime.status !== 'closed' && !runtime.closing) {\n runtime.status = 'failed'\n runtime.error = this.describeWorkerFailure(error, runtime)\n recordEvidence(runtime)\n try { this.team.recordOutcome(name, { kind: 'failed', message: runtime.error }) } catch { /* shared team disposed */ }\n await this.notifyLead(runtime, `failed: ${runtime.error}`)\n }\n } finally {\n runtime.markSettled()\n // Whatever ended this worker — success, failure, or a close — the work\n // planned after it is no longer waiting on anything.\n await this.releaseDependents(runtime)\n }\n }\n\n /**\n * Tell the lead what one of its workers did.\n *\n * Quiet WHILE THE LEAD IS STILL IN ITS TURN: the report appends to history\n * and the next model round rebuilds its request from history, so the lead\n * reads it without an extra turn being scheduled. Holding that turn open is\n * {@link leadHooks}'s job.\n *\n * A wake-up once the lead has gone idle, because then nothing else will ever\n * read the report. The hold cannot cover every case — a turn that ended on\n * its step budget, or on an error, is not eligible to continue, and a worker\n * that outlives the run reports into a conversation with no turn left. That\n * is the failure this exists for: the transcript ends on a worker's own\n * output, and the synthesis the lead was there to write never happens. One\n * more turn is the point, not a duplicate answer.\n */\n private async notifyLead(runtime: WorkerRuntime, summary: string): Promise<void> {\n const worker = runtime.request.name\n if (runtime.closing || this.lifecycle.signal.aborted || this.workerRuntimes.get(worker) !== runtime) return\n const delivery = this.deliveryFor(worker)\n // A quiet report is a bet that the lead's next model round will read it.\n // Cleared by `beforeStep`, which is that round; still set at the end of a\n // turn that cannot continue, it means the bet lost and nobody ever will.\n if (delivery === 'quiet') this.unreadReports = true\n try {\n const signal = combineSignals(runtime.controller.signal, this.lifecycle.signal,\n AbortSignal.timeout(this.spawnTimeoutMs))\n await abortable(this.team.sendMessage({\n from: worker,\n target: this.leadName,\n message: `Worker '${worker}' ${truncate(summary, Math.min(this.maxDependencyReportBytes, Math.max(64, Math.floor(this.team.messageByteLimit / 4))))}`,\n delivery,\n signal,\n }), signal)\n } catch {\n // The lead may already be gone, or the team disposed. A worker's report\n // is not worth failing anything else over; `workers()` still has it.\n }\n }\n\n /**\n * Quiet into an open turn, a wake-up into an idle conversation.\n * @param worker - The worker whose report is being delivered.\n * @returns The delivery the report needs to actually be read.\n */\n private deliveryFor(worker: string): 'quiet' | 'wakeup' {\n // Mid-turn: the next model round rebuilds its request from history, so the\n // report is read without scheduling anything.\n if (this.options.autoLeadCoordination === false || this.lead.isRunning) return 'quiet'\n // Idle, and the host is driving: waking would start a turn it did not ask\n // for, and it can read the result from `workers()` whenever it likes.\n if (this.workerRuntimes.get(worker)?.leadDriven !== true) return 'quiet'\n return 'wakeup'\n }\n\n /** Set when a worker report was delivered quietly and no round has read it. */\n private unreadReports = false\n private leadSteer = new AbortController()\n private leadSignal: AbortSignal | undefined\n\n /**\n * Wait until no worker is outstanding and the lead has nothing left to do.\n *\n * The roster cannot answer this on its own. A worker's last event fires\n * before its run resolves, and its completion report — the thing that wakes\n * the lead — is delivered after that. For the moment in between, every member\n * looks idle: a caller watching the roster sees a finished team and stops\n * listening, exactly as the synthesis is about to be written. Waiting here\n * covers that gap, because a worker's `settled` resolves only once its report\n * has been delivered.\n * @param signal - Gives up waiting; the work itself is not cancelled.\n */\n async whenQuiet(signal?: AbortSignal): Promise<void> {\n for (;;) {\n signal?.throwIfAborted()\n const outstanding = [...this.workerRuntimes.values()]\n .filter(runtime => !runtime.settledComplete)\n const preparing = [...this.preparing.values()].map(prepared => prepared.settled)\n if (outstanding.length + preparing.length > 0) {\n await abortable(Promise.all([...outstanding.map(runtime => runtime.settled), ...preparing]), signal)\n }\n await this.team.whenIdle(this.leadName, signal)\n const busy = this.preparing.size > 0 || [...this.workerRuntimes.values()]\n .some(runtime => !runtime.settledComplete)\n if (!busy) return\n }\n }\n\n /** Current detached worker lifecycle view. */\n workers(): readonly ManagedAgentWorker[] {\n return Object.freeze([...this.workerRuntimes.values()].map(runtime => this.workerView(runtime)))\n }\n\n private workerView(runtime: WorkerRuntime): ManagedAgentWorker {\n return Object.freeze({\n name: runtime.request.name,\n agentId: runtime.session.definition.id,\n conversationId: runtime.session.conversationId,\n task: runtime.request.task,\n status: runtime.status,\n context: runtime.request.context,\n dependsOn: runtime.request.dependsOn,\n writes: runtime.request.writes,\n ...(runtime.request.role === undefined ? {} : { role: runtime.request.role }),\n ...(runtime.warnings.length === 0 ? {} : { warnings: runtime.warnings }),\n ...(runtime.request.specialty === undefined ? {} : { specialty: runtime.request.specialty }),\n ...(runtime.result === undefined ? {} : { result: runtime.result }),\n ...(runtime.error === undefined ? {} : { error: runtime.error }),\n })\n }\n\n /**\n * Wait for one worker to finish, for at most `timeoutMs`.\n *\n * Bounded on purpose. An unbounded wait is how a host loses the ability to\n * tell a slow worker from a stuck one; a caller that gets `undefined` back\n * still holds every other option.\n * @param name - Worker address.\n * @param options - Budget, default {@link DEFAULT_WAIT_TIMEOUT_MS}, and a signal.\n * @returns Its result, or undefined if it had not finished in time.\n */\n async awaitWorker(\n name: string,\n options: { readonly timeoutMs?: number; readonly signal?: AbortSignal } = {},\n ): Promise<ManagedAgentWorkerResult | undefined> {\n const address = memberName(name)\n const runtime = this.workerRuntimes.get(address)\n if (runtime === undefined) throw new Error(`unknown managed worker '${address}'`)\n const budget = timeoutValue(options.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS)\n // The timer is cleared either way: a worker that finishes early must not\n // leave one pending, which in a long-lived host is a slow leak.\n let timer: ReturnType<typeof setTimeout> | undefined\n const deadline = new Promise<void>((resolve) => { timer = setTimeout(resolve, budget) })\n try {\n await abortable(Promise.race([runtime.settled, deadline]), options.signal)\n } finally {\n clearTimeout(timer)\n }\n options.signal?.throwIfAborted()\n return runtime.result\n }\n\n /**\n * Stop a worker and give up its slot.\n *\n * This is the stopping point a delegated agent otherwise lacks. A worker that\n * has already finished is still occupying a `maxWorkers` slot, so closing is\n * how a lead makes room for the next one.\n * @param name - Worker address.\n * @param reason - Cancellation reason for a worker still running.\n * @returns The status it held before being closed.\n */\n async closeWorker(\n name: string,\n reason: unknown = new Error('managed worker closed'),\n ): Promise<ManagedAgentWorkerStatus> {\n const address = memberName(name)\n const runtime = this.workerRuntimes.get(address)\n if (runtime === undefined) throw new Error(`unknown managed worker '${address}'`)\n runtime.closing = true\n runtime.closeTask ??= Promise.resolve().then(() => this.closeRuntime(runtime, reason))\n return runtime.closeTask\n }\n\n private async closeRuntime(runtime: WorkerRuntime, reason: unknown): Promise<ManagedAgentWorkerStatus> {\n const address = runtime.request.name\n const previous = runtime.status\n runtime.closing = true\n runtime.controller.abort(reason)\n const closeDeadline = AbortSignal.timeout(this.closeTimeoutMs)\n // The controller only governs the run THIS harness started. A worker the\n // lead reached with followup_task, or any wake-up delivery, is running\n // under the team's own scheduler, and aborting the harness controller does\n // nothing to it: observed in a real run, a closed worker kept calling the\n // model for another fourteen seconds and submitted its result after the\n // lead had already answered, so the conversation ended on the worker's\n // output instead of the lead's synthesis.\n try {\n await abortable(this.team.cancel(address, reason), closeDeadline)\n } catch {\n // A cancellation that times out must not wedge the close: the slot is\n // freed either way, exactly as it is for a run that ignores its signal.\n }\n if (previous === 'pending') {\n // Never started, so there is no run to wait for — and `settled` would\n // never resolve on its own, because nothing is going to end.\n runtime.status = 'closed'\n runtime.start = undefined\n this.team.markPending(address, undefined)\n runtime.markSettled()\n } else {\n // Waited for, but not indefinitely, and a worker that ignores its signal\n // does not get to wedge the harness: the slot is freed either way. The\n // wait is what usually lets `detach` succeed, since it refuses a member\n // whose session is still running.\n try { await abortable(runtime.settled, closeDeadline) } catch { /* non-cooperative run remains bounded */ }\n runtime.status = 'closed'\n runtime.markSettled()\n }\n recordEvidence(runtime)\n if (this.workerHasWork(runtime)) {\n if (runtime.request.writes.length > 0) this.drainingWrites.add(runtime)\n // Closing frees the managed slot, but cannot establish that an active\n // session stopped writing. Release only its write claim at actual idle.\n void this.team.whenIdle(address).then(async () => {\n this.drainingWrites.delete(runtime)\n try {\n if (this.team.members().some(member => member.name === address && member.conversationId === runtime.session.conversationId)) {\n this.team.detach(address)\n }\n } catch { /* roster already removed or disposed */ }\n await this.releaseDependents(runtime)\n }).catch(() => { /* team lifecycle may already be disposed */ })\n }\n if (this.workerRuntimes.get(address) === runtime) {\n this.workerRuntimes.delete(address)\n try { this.team.detach(address) } catch { /* already gone, or the team is disposed */ }\n }\n // Closing is a settlement too: work planned after this worker must not be\n // left waiting on one the lead has abandoned.\n runtime.dependencies = []\n await this.releaseDependents(runtime)\n return previous\n }\n\n /**\n * Stop every worker this harness started.\n *\n * Workers outlive the lead's turn by design, so something has to end them:\n * without this a detached run would keep calling the model after the host had\n * moved on. Disposing the underlying `AgentTeam` is left to whoever owns it.\n * @param reason - Cancellation reason handed to each worker.\n */\n dispose(reason: unknown = new Error('managed agent team disposed')): Promise<void> {\n if (this.disposeTask !== undefined) return this.disposeTask\n this.lifecycle.abort(reason)\n const names = [...this.workerRuntimes.keys()]\n this.disposeTask = Promise.allSettled([\n ...[...this.preparing.values()].map(prepared => prepared.settled),\n ...names.map(name => this.closeWorker(name, reason)),\n ]).then(() => undefined)\n return this.disposeTask\n }\n\n /** Remove one idle generated worker from the harness and shared roster. */\n removeWorker(name: string): void {\n const address = memberName(name)\n const runtime = this.workerRuntimes.get(address)\n if (runtime === undefined) throw new Error(`unknown managed worker '${address}'`)\n if (runtime.status === 'pending' || runtime.status === 'running' || !runtime.settledComplete || runtime.session.isRunning) {\n throw new Error(`cannot remove running managed worker '${address}'`)\n }\n this.team.detach(address)\n this.workerRuntimes.delete(address)\n }\n\n private controlTools(): readonly ToolDefinition<any>[] {\n return Object.freeze([\n defineTool({\n name: 'spawn_agent',\n description: [\n 'Create a managed worker for the supplied task.',\n 'Returns a lifecycle view after setup; a dependent may still be pending.',\n 'Use list_agents for retained status/results and wait_agents for bounded waits.',\n 'dependsOn binds already registered producer instances; writes declares relative scheduling scopes under host policy.',\n ].join(' '),\n parameters: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Optional unique worker address; omitted generates worker_N.',\n },\n task: {\n type: 'string',\n description: 'Task and any output contract assigned to the worker.',\n },\n specialty: {\n type: 'string',\n description: 'Optional worker role or domain specialization.',\n },\n context: {\n type: 'string',\n enum: ['fresh', 'fork'],\n description: 'fresh starts from the task; fork also copies the completed lead conversation.',\n },\n dependsOn: {\n type: 'array',\n items: { type: 'string' },\n description: 'Names of workers that must finish before this one starts.'\n + ' The worker is created now and held until they do, then given what they'\n + ' produced. Register the producers first; a dependency cannot name a'\n + ' future or still-preparing worker. Failed producers also release dependents with failure status.',\n },\n writes: {\n type: 'array',\n items: { type: 'string' },\n description: 'Workspace-relative scheduling scopes. Overlaps are rejected, warned or allowed'\n + ' according to host writeScopePolicy. This is not filesystem authorization.'\n + ' Omit when no writes are declared; placeholder paths claim real scopes.',\n },\n ...this.roleSchema(),\n },\n required: ['task'],\n additionalProperties: false,\n },\n parse: parseSpawnTool,\n execute: async (request, context) => asJson(await this.spawn(request, context.signal)),\n // Seconds, not the worker's whole deadline: this call only starts the\n // worker now. Leaving it at workerTimeoutMs would let a stuck SETUP\n // hold the lead for ten minutes.\n timeoutMs: this.spawnTimeoutMs,\n isConcurrencySafe: () => true,\n }),\n defineTool({\n name: 'close_agent',\n budgetExempt: true,\n description: [\n 'Close a worker you no longer need and free its slot.',\n 'A finished worker still occupies one until closed, so close it once you have read its result.',\n 'A running or pending worker is kept alive by default so it can finish its final report.',\n this.options.allowModelWorkerCancellation === false\n ? 'The host requires worker reports: you cannot cancel unfinished workers. Wait for their result.'\n : 'Set cancelRunning: true only to deliberately abandon unfinished work and cancel it.',\n 'Returns the status it held before closing.',\n ].join(' '),\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Worker address returned by spawn_agent.' },\n cancelRunning: { type: 'boolean', description: 'Explicitly cancel an unfinished worker. Defaults to false.' },\n },\n required: ['name'],\n additionalProperties: false,\n },\n parse: parseCloseTool,\n execute: async ({ name, cancelRunning }) => {\n const runtime = this.workerRuntimes.get(name)\n if (runtime !== undefined && (!cancelRunning || this.options.allowModelWorkerCancellation === false)\n && (runtime.status === 'pending' || runtime.status === 'running' || runtime.session.isRunning)) {\n return asJson({\n worker: name, closed: false,\n status: runtime.status === 'pending' ? 'pending' : 'running',\n instruction: 'The worker has not finished its final report. Use wait_agents and read its completed result before closing.'\n + (this.options.allowModelWorkerCancellation === false ? ' Model cancellation is disabled by the host.'\n : ' To deliberately abandon this work, call close_agent with cancelRunning: true.'),\n })\n }\n return asJson({ worker: name, closed: true, previousStatus: await this.closeWorker(name) })\n },\n timeoutMs: this.workerTimeoutMs,\n }),\n ])\n }\n\n /**\n * Build the history a `fork` worker starts from.\n *\n * Limits come from the WORKER's session options, not the lead's: this is the\n * worker's own history from here on, and it is the worker's configured\n * ceiling that has to hold it.\n * @returns The lead's completed conversation as a fresh history.\n */\n private forkLeadHistory(limits: AgentSessionOptions['historyLimits']): History {\n const entries = completedHistoryPrefix(this.lead.snapshot().history)\n return History.fromSnapshot(\n { version: 1, entries },\n limits ?? {},\n )\n }\n\n private async workerDefinition(\n request: ResolvedManagedAgentSpawnRequest,\n ): Promise<DefinedAgent> {\n if (this.options.workerFactory !== undefined) return this.options.workerFactory(request)\n const template = this.options.workerTemplate ?? this.options.lead\n const role = request.role === undefined ? undefined : this.roles.get(request.role)\n const roleText = role === undefined\n ? ''\n : ` You are the '${role.name}' worker. ${role.instructions ?? role.description}`\n const specialty = request.specialty === undefined\n ? ''\n : ` Your specialization is: ${request.specialty}.`\n return cloneAgent(template, {\n id: request.name,\n name: request.name,\n instructions: `${template.instructions}\\n\\nYou are dynamically assigned worker '${request.name}'.${roleText}${specialty}`,\n })\n }\n\n private nextWorkerName(): string {\n while (true) {\n const candidate = `worker_${++this.workerSequence}`\n if (!this.preparing.has(candidate) && !this.workerRuntimes.has(candidate)\n && !this.team.members().some(member => member.name === candidate)) return candidate\n }\n }\n\n private async observeWorkerEvent(worker: string, event: AgentRunEvent): Promise<void> {\n const observer = Promise.resolve().then(() => this.options.onWorkerEvent?.(worker, event))\n await waitForSettlement(observer, this.observerTimeoutMs)\n }\n}\n\nexport function createManagedAgentTeam(options: ManagedAgentTeamOptions): ManagedAgentTeam {\n return new ManagedAgentTeam(options)\n}\n\nfunction mergeTools(\n supplied: ToolCatalog | readonly ToolDefinition<any>[] | undefined,\n generated: readonly ToolDefinition<any>[],\n): ToolRegistry {\n const registry = new ToolRegistry()\n if (supplied !== undefined) {\n const tools = 'names' in supplied\n ? supplied.names().map(name => supplied.get(name))\n .filter((tool): tool is ToolDefinition => tool !== undefined)\n : supplied\n for (const tool of tools) registry.register(tool)\n }\n for (const tool of generated) registry.register(tool)\n return registry\n}\n\nfunction parseCloseTool(value: unknown): { name: string; cancelRunning: boolean } {\n const input = object(value, 'close_agent arguments')\n if (Object.keys(input).some(key => key !== 'name' && key !== 'cancelRunning')) {\n throw new TypeError('close_agent arguments contain unknown fields')\n }\n if (input.cancelRunning !== undefined && typeof input.cancelRunning !== 'boolean') {\n throw new TypeError('close_agent cancelRunning must be a boolean')\n }\n return { name: memberName(input.name), cancelRunning: input.cancelRunning === true }\n}\n\nfunction parseSpawnTool(value: unknown): ManagedAgentSpawnRequest {\n const input = object(value, 'spawn_agent arguments')\n const known = new Set([\n 'name', 'task', 'specialty', 'context', 'role', 'dependsOn', 'writes',\n ])\n if (Object.keys(input).some(key => !known.has(key))) {\n throw new TypeError('spawn_agent arguments contain unknown fields')\n }\n return {\n task: nonEmpty(input.task, 'worker task'),\n ...(input.name === undefined ? {} : { name: memberName(input.name) }),\n ...(input.specialty === undefined\n ? {}\n : { specialty: nonEmpty(input.specialty, 'worker specialty') }),\n ...(input.context === undefined ? {} : { context: spawnContext(input.context) }),\n ...(input.role === undefined ? {} : { role: nonEmpty(input.role, 'worker role') }),\n ...(input.dependsOn === undefined\n ? {}\n : { dependsOn: stringArray(input.dependsOn, 'dependsOn') }),\n ...(input.writes === undefined ? {} : { writes: stringArray(input.writes, 'writes') }),\n }\n}\n\nfunction stringArray(value: unknown, label: string): readonly string[] {\n if (!Array.isArray(value)) throw new TypeError(`${label} must be an array of strings`)\n return value.map(entry => nonEmpty(entry, `${label} entry`))\n}\n\nfunction spawnContext(value: unknown): ManagedAgentSpawnContext {\n if (value !== 'fresh' && value !== 'fork') {\n throw new TypeError(\"worker context must be 'fresh' or 'fork'\")\n }\n return value\n}\n\n/**\n * Copy the lead's conversation up to the last point it was complete.\n *\n * The lead is INSIDE a turn when it calls `spawn_agent`: the assistant message\n * carrying that very call is already in history, and its result cannot be,\n * because producing it is what this code is doing. Handing that tail to a\n * worker gives it a conversation ending in an unanswered tool call — which\n * providers reject, and which would turn a context optimisation into a spawn\n * that fails outright.\n *\n * So the fork is cut at the last position where no tool call was outstanding.\n * That is also the honest boundary in meaning: work still in flight is not yet\n * something the lead knows. The DeepSeek harness names the same rule a\n * \"completed-turn prefix\".\n *\n * A prefix is safe to hydrate as a history in its own right: `replace` surface\n * ops and compaction records only ever reference earlier entries, so cutting\n * from the end cannot orphan a reference.\n * @param snapshot - The lead's history, taken mid-turn.\n * @returns Entries up to that boundary; empty when nothing has completed.\n */\nexport function completedHistoryPrefix(\n snapshot: HistorySnapshot,\n): readonly HistoryEntry[] {\n const pending = new Set<string>()\n let cut = 0\n snapshot.entries.forEach((entry, index) => {\n const event = entry.event\n if (event.kind === 'tool-call') pending.add(event.callId)\n else if (event.kind === 'tool-result') pending.delete(event.callId)\n else if (event.kind === 'assistant') {\n // The assistant MESSAGE carries its own tool-call blocks, separately from\n // the `tool-call` events beside it. Counting only the events left the\n // spawn call in the fork, complete with the synthetic \"interrupted before\n // a result was recorded\" error the request builder pairs it with — the\n // worker's first sight of its lead being that it had just failed.\n for (const block of event.message.content) {\n if (block.type === 'tool-call') pending.add(block.id)\n }\n }\n // An interrupted assistant message is a turn that never finished; treating\n // it as settled context would hand a worker a half-formed intention.\n const settled = pending.size === 0\n && !(event.kind === 'assistant' && event.interrupted === true)\n if (settled) cut = index + 1\n })\n return snapshot.entries.slice(0, cut)\n}\n\nfunction object(value: unknown, label: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new TypeError(`${label} must be an object`)\n }\n return value as Record<string, unknown>\n}\n\nfunction memberName(value: unknown): string {\n const name = nonEmpty(value, 'managed agent name')\n if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {\n throw new TypeError('managed agent name must start with a letter and contain only letters, digits, _ or -')\n }\n if (name.length > 128) throw new TypeError('managed agent name must not exceed 128 characters')\n return name\n}\n\nfunction nonEmpty(value: unknown, label: string): string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new TypeError(`${label} must be a non-empty string`)\n }\n return value\n}\n\nfunction boundedString(value: unknown, label: string, maxBytes: number): string {\n const text = nonEmpty(value, label)\n if (new TextEncoder().encode(text).byteLength > maxBytes) {\n throw new TypeError(`${label} exceeds the ${maxBytes}-byte limit`)\n }\n return text\n}\n\nfunction positiveInteger(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value < 1) throw new TypeError(`${label} must be a positive integer`)\n return value\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nasync function abortable<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (signal === undefined) return promise\n if (signal.aborted) {\n // Calling a host callback can synchronously abort and return a rejected\n // promise; retain its rejection observer even though cancellation won.\n void promise.catch(() => undefined)\n throw signal.reason ?? new Error('managed worker aborted')\n }\n return await new Promise<T>((resolve, reject) => {\n const abort = () => {\n signal.removeEventListener('abort', abort)\n reject(signal.reason ?? new Error('managed worker aborted'))\n }\n signal.addEventListener('abort', abort, { once: true })\n void promise.then(\n value => { signal.removeEventListener('abort', abort); resolve(value) },\n error => { signal.removeEventListener('abort', abort); reject(error) },\n )\n })\n}\n\nfunction combineSignals(...signals: readonly (AbortSignal | undefined)[]): AbortSignal {\n const active = signals.filter((candidate): candidate is AbortSignal => candidate !== undefined)\n return active.length === 1 ? active[0]! : AbortSignal.any(active)\n}\n\nfunction asJson(value: unknown): JsonValue { return value as JsonValue }\n\n/** Worker states that will never change again on their own. */\nconst SETTLED_WORKER_STATUS: ReadonlySet<ManagedAgentWorkerStatus> =\n new Set<ManagedAgentWorkerStatus>(['completed', 'failed', 'closed'])\n\n/**\n * Reduce one declared write scope to a comparable path.\n *\n * Comparison is by path component, so the shapes that mean the same directory\n * have to arrive spelled the same way: `./app/`, `app`, and `app\\` all name\n * `app`, and a worker writing `app/page.tsx` conflicts with one writing `app`.\n */\n/**\n * Why a worker's run did not produce an answer, if it did not.\n *\n * A rejected run is obvious; a run that ends on an error reason is not, because\n * it resolves like any other. Both leave the lead with nothing to read, so both\n * are failures as far as the report is concerned.\n * @param response - What the worker's run returned.\n * @returns The failure to report, or undefined when the worker actually answered.\n */\nfunction failureOf(response: AgentResponse, requireText: boolean): string | undefined {\n const reason = response.outcome.reason\n if (reason.kind === 'error') return reason.failure.message\n if (reason.kind === 'max-tokens') return 'the model stopped at its output limit'\n if (reason.kind === 'usage-unavailable') return 'the provider reported no usage for a billed call'\n if (reason.kind === 'aborted') return 'the run was aborted'\n if (reason.kind === 'budget-exhausted' && !response.outcome.completed) {\n return `the run stopped at its ${reason.budget} limit before completing the task`\n }\n // Tool-only agents may intentionally complete without a textual answer.\n if (requireText && response.text.trim() === '') return 'it produced no answer'\n return undefined\n}\n\nfunction normalizeWriteScope(value: unknown): string {\n const text = nonEmpty(value, 'worker write scope').trim().split('\\\\').join('/')\n if (text.startsWith('/') || /^[a-zA-Z]:/.test(text)) {\n throw new TypeError('a worker write scope must be workspace-relative')\n }\n const parts: string[] = []\n for (const part of text.split('/')) {\n if (part === '' || part === '.') continue\n if (part === '..') {\n if (parts.length === 0) throw new TypeError('a worker write scope must not escape the workspace')\n parts.pop()\n } else parts.push(part)\n }\n if (parts.length === 0) {\n throw new TypeError('a worker write scope must name a file or directory, not the whole workspace')\n }\n return parts.join('/')\n}\n\n/** Whether two normalized scopes cover any of the same files. */\nfunction scopesOverlap(left: string, right: string): boolean {\n return left === right || left.startsWith(`${right}/`) || right.startsWith(`${left}/`)\n}\n\n/** Cut text to a byte budget without splitting a UTF-16 surrogate pair. */\nfunction prefixWithinBytes(text: string, maxBytes: number): string {\n return new TextDecoder('utf-8', { fatal: false }).decode(new TextEncoder().encode(text).subarray(0, maxBytes), { stream: true })\n}\n\n/** Keep both the initial findings and final verdict; the marker is inside the byte cap. */\nfunction truncate(text: string, maxBytes: number): string {\n const encoded = new TextEncoder().encode(text)\n if (encoded.byteLength <= maxBytes) return text\n const marker = '\\n… (truncated; read full result) …\\n'\n const markerBytes = new TextEncoder().encode(marker).byteLength\n if (maxBytes <= markerBytes) return prefixWithinBytes('(truncated)', maxBytes)\n const remaining = maxBytes - markerBytes\n const head = prefixWithinBytes(text, Math.ceil(remaining / 2))\n let tailStart = encoded.length - Math.floor(remaining / 2)\n while (tailStart < encoded.length && (encoded[tailStart]! & 0xc0) === 0x80) tailStart++\n const tail = new TextDecoder().decode(encoded.subarray(tailStart))\n return head + marker + tail\n}\n\n/** Detached evidence keeps full reports available without retaining producer sessions or ancestor chains. */\nfunction recordEvidence(runtime: WorkerRuntime): void {\n runtime.evidence.status = runtime.status\n runtime.evidence.result = runtime.result\n runtime.evidence.error = runtime.error\n}\n"],"mappings":"wbAiCA,MAAa,EAAiC,IAGjC,EAAkC,IAWlC,EAAuB,KAG9B,EAAoB,CACxB,+GACA,2GACA,4JACA,uNACA,yFACA,8JACA,oIACA,+HACF,CAAC,CAAC,KAAK,GAAG,EAwQV,IAAa,EAAb,KAA8B,CAC5B,KACA,KACA,SACA,QACA,WACA,aACA,kBACA,gBACA,kBACA,eACA,WACA,eACA,eAAkC,IAAI,IAEtC,eAAkC,IAAI,IACtC,UAA6B,IAAI,IAKjC,UAA6B,IAAI,gBACjC,YACA,eAAyB,EACzB,yBACA,MAEA,YAAY,EAAkC,CAc5C,GAbA,KAAK,QAAU,EACf,KAAK,WAAa,EAAgB,EAAQ,YAAc,EAAG,YAAY,EACvE,KAAK,aAAe,EAAgB,EAAQ,cAAgB,MAAW,cAAc,EACrF,KAAK,kBAAoB,EAAgB,EAAQ,mBAAqB,KAAU,mBAAmB,EACnG,KAAK,gBAAkB,EAAa,EAAQ,iBAAmB,GAAW,EAC1E,KAAK,kBAAoB,EAAa,EAAQ,mBAAqB,GAAK,EACxE,KAAK,eAAiB,EAAa,EAAQ,gBAAA,GAAiD,EAC5F,KAAK,WAAa,EAAa,EAAQ,YAAA,IAAkC,EACzE,KAAK,eAAiB,EAAa,EAAQ,gBAAA,GAAgD,EAC3F,KAAK,yBAA2B,EAC9B,EAAQ,0BAA4B,KACpC,0BACF,EACI,KAAK,yBAA2B,EAAG,MAAU,UAAU,6CAA6C,EAExG,GADA,KAAK,MAAQ,IAAI,KAAK,EAAQ,OAAS,CAAC,EAAA,CAAG,IAAI,GAAQ,CAAC,EAAK,KAAM,CAAI,CAAC,CAAC,EACrE,KAAK,MAAM,QAAU,EAAQ,OAAS,CAAC,EAAA,CAAG,OAC5C,MAAU,MAAM,8CAA8C,EAEhE,KAAK,KAAO,EAAQ,gBAAgB,EAChC,EAAQ,KACR,IAAI,EAAU,CACZ,GAAG,EAAQ,KACX,WAAY,EAAQ,MAAM,YAAc,KAAK,WAAa,CAC5D,CAAC,EACL,KAAK,SAAW,EAAW,EAAQ,UAAY,EAAQ,KAAK,EAAE,EAC9D,KAAK,KAAO,EAAQ,KAAK,cAAc,CACrC,GAAG,EAAQ,mBACX,MAAO,KAAK,UAAU,EAAQ,oBAAoB,KAAK,EACvD,SAAU,EAAQ,SAClB,MAAO,EAAW,EAAQ,oBAAoB,MAAO,KAAK,aAAa,CAAC,EACxE,KAAM,CACJ,KAAM,KAAK,KACX,KAAM,KAAK,SACX,KAAM,OACN,aAAc,EACd,GAAI,EAAQ,kBAAoB,IAAA,GAAY,CAAC,EAAI,CAAE,YAAa,EAAQ,eAAgB,CAC1F,CACF,CAAC,CACH,CAmBA,UAAkB,EAAwC,CACxD,MAAO,CACL,GAAG,EACH,WAAY,KAAO,KAGjB,KAAK,cAAgB,GACrB,KAAK,UAAY,IAAI,gBACrB,KAAK,WAAa,EAAQ,OACnB,MAAM,GAAM,aAAa,CAAO,GAAK,CAAE,KAAM,SAAmB,GAEzE,UAAW,KAAO,IAAY,CAE5B,GADA,MAAM,GAAM,YAAY,CAAO,EAC3B,KAAK,QAAQ,uBAAyB,GAAO,OACjD,GAAI,CAAC,EAAQ,YAAa,CAKxB,GAAI,KAAK,cAAe,CACtB,KAAK,cAAgB,GACrB,GAAI,CAAE,KAAK,KAAK,KAAK,KAAK,QAAQ,CAAE,MAAQ,CAAsB,CACpE,CACA,MACF,CAKA,IAAM,EAAc,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAClD,OAAO,GAAW,EAAQ,SAAW,WAAa,EAAQ,SAAW,SAAS,EACjF,GAAI,EAAY,SAAW,EAAG,OAW9B,MAAM,KAAK,gBAAgB,CAAW,EACtC,IAAM,EAAO,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAC3C,OAAO,GAAW,EAAQ,SAAW,WAAa,EAAQ,SAAW,SAAS,CAAC,CAC/E,IAAI,GAAW,EAAQ,QAAQ,IAAI,EACtC,GAAI,EAAK,SAAW,EAAG,CACrB,KAAK,KAAK,OACR,sHACF,EACA,MACF,CACA,KAAK,KAAK,OACR,gCAAgC,EAAK,KAAK,IAAI,EAAE,0GAElD,CACF,CACF,CACF,CAGA,IAAI,EAAmB,EAAqC,CAAC,EAA2B,CAEtF,OADA,KAAK,UAAU,OAAO,eAAe,EAC9B,KAAK,KAAK,IAAI,EAAO,CAAU,CACxC,CAcA,MAAM,EAAuB,CAC3B,KAAK,UAAU,OAAO,eAAe,EACrC,KAAK,KAAK,OAAO,CAAI,EACrB,KAAK,UAAU,MAAM,EAGrB,GAAI,CAAE,KAAK,KAAK,YAAY,KAAK,QAAQ,CAAE,MAAQ,CAAsB,CACzE,GAAI,CAAC,KAAK,KAAK,UACb,GAAI,CAAE,KAAK,KAAK,KAAK,KAAK,QAAQ,CAAE,MAAQ,CAAsB,CAEpE,MAAO,EACT,CAaA,MAAM,MACJ,EACA,EAC6B,CAC7B,KAAK,UAAU,OAAO,eAAe,EACrC,GAAQ,eAAe,EACvB,IAAM,EAA6C,CACjD,KAAM,EAAW,EAAQ,MAAQ,KAAK,eAAe,CAAC,EACtD,KAAM,EAAc,EAAQ,KAAM,cAAe,KAAK,YAAY,EAClE,GAAI,EAAQ,YAAc,IAAA,GACtB,CAAC,EACD,CAAE,UAAW,EAAc,EAAQ,UAAW,mBAAoB,KAAK,iBAAiB,CAAE,EAC9F,QAAS,EAAa,EAAQ,SAAW,KAAK,QAAQ,qBAAuB,OAAO,EACpF,GAAI,EAAQ,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,KAAK,YAAY,EAAQ,IAAI,CAAE,EAC7E,UAAW,KAAK,oBAAoB,EAAQ,WAAa,CAAC,CAAC,EAC3D,OAAQ,CAAC,GAAG,IAAI,KAAK,EAAQ,QAAU,CAAC,EAAA,CAAG,IAAI,CAAmB,CAAC,CAAC,CACtE,EACA,OAAO,OAAO,EAAS,SAAS,EAChC,OAAO,OAAO,EAAS,MAAM,EAC7B,OAAO,OAAO,CAAQ,EACtB,IAAM,EAAe,EAAS,UAAU,IAAI,GAAQ,KAAK,eAAe,IAAI,CAAI,CAAE,EAClF,GAAI,KAAK,eAAe,KAAO,KAAK,UAAU,MAAQ,KAAK,WACzD,MAAU,MAAM,kCAAkC,KAAK,WAAW,cAAc,EAElF,GAAI,KAAK,UAAU,IAAI,EAAS,IAAI,GAAK,KAAK,eAAe,IAAI,EAAS,IAAI,GACzE,KAAK,KAAK,QAAQ,CAAC,CAAC,KAAK,GAAU,EAAO,OAAS,EAAS,IAAI,EACnE,MAAU,MAAM,mBAAmB,EAAS,KAAK,iBAAiB,EAGpE,IAAI,EACE,EAAW,IAAI,QAAc,GAAW,CAAE,EAAe,CAAQ,CAAC,EACxE,KAAK,UAAU,IAAI,EAAS,KAAM,CAAE,QAAS,EAAU,eAAc,QAAS,CAAS,CAAC,EACxF,IAAI,EACJ,GAAI,CACF,IAAM,EAAW,KAAK,iBAAiB,EAAU,CAAY,EACvD,EAAkB,EAAe,EAAQ,KAAK,UAAU,OAAQ,YAAY,QAAQ,KAAK,cAAc,CAAC,EACxG,EAAa,MAAM,EAAU,KAAK,iBAAiB,CAAQ,EAAG,CAAe,EACnF,EAAgB,eAAe,EAC/B,IAAM,EAAuB,KAAK,QAAQ,8BAAgC,IAAA,GACtE,IAAA,GACA,MAAM,EAAU,QAAQ,QAAQ,KAAK,QAAQ,4BAA4B,CAAQ,CAAC,EAAG,CAAe,EACxG,EAAgB,eAAe,EAC/B,IAAM,EAAiB,CAAE,GAAG,KAAK,QAAQ,qBAAsB,GAAG,CAAqB,EACjF,EAAkB,KAAK,QAAQ,iBAAmB,YAClD,EAAU,EAAW,cAAc,CACvC,GAAG,EACH,GAAI,EAAa,SAAW,EAAI,CAAC,EAAI,CAAE,MAAO,EAAW,EAAe,MAAO,CAAC,KAAK,mBAAmB,CAAY,CAAC,CAAC,CAAE,EACxH,GAAI,EAAS,UAAY,OAAS,CAAE,QAAS,KAAK,gBAAgB,EAAe,aAAa,CAAE,EAAI,CAAC,EACrG,SAAU,KAAK,QAAQ,SACvB,KAAM,CACJ,KAAM,KAAK,KACX,KAAM,EAAS,KACf,KAAM,OACN,MAAO,EACP,aAAc,CACZ,2BAA2B,EAAS,KAAK,YAAY,KAAK,SAAS,IACnE,2GACA,mDACA,GAAI,IAAoB,GAAQ,CAAC,EAAI,CAAC,8EAA8E,CACtH,CAAC,CAAC,KAAK,GAAG,EACV,GAAI,EAAS,YAAc,IAAA,GAAY,CAAC,EAAI,CAAE,YAAa,EAAS,SAAU,CAChF,CACF,CAAC,EACK,EAAa,IAAI,gBACnB,EACJ,EAAU,CACR,QAAS,EACT,UACA,eACA,SAAU,GACV,gBAAiB,GACjB,UAAW,IAAA,GACX,OAAQ,UACR,WAAY,KAAK,KAAK,UACtB,QAAS,GACT,SAAU,IAAA,GACV,aACA,QAAS,IAAI,QAAe,GAAY,CAAE,EAAc,CAAQ,CAAC,EACjE,gBAAmB,CAAE,EAAe,CAAQ,EAAG,EAAS,gBAAkB,GAAM,EAAY,CAAE,EAC9F,MAAO,IAAA,GACP,WACA,OAAQ,IAAA,GACR,MAAO,IAAA,GACP,SAAU,CAAE,OAAQ,UAAW,OAAQ,IAAA,GAAW,MAAO,IAAA,EAAU,CACrE,EACA,KAAK,eAAe,IAAI,EAAS,KAAM,CAAO,EAC9C,KAAK,UAAU,OAAO,EAAS,IAAI,EAEnC,IAAM,EAAiB,EAAe,EAAiB,EAAW,MAAM,EAaxE,GAZA,MAAM,EAAU,KAAK,KAAK,YAAY,CACpC,KAAM,KAAK,SACX,OAAQ,EAAS,KACjB,QAAS,EAAS,KAClB,SAAU,QACV,OAAQ,CACV,CAAC,EAAG,CAAc,EAClB,EAAe,eAAe,EAC1B,EAAW,OAAO,sBACpB,EAAQ,OAAO,yBAAyB,EAAkB,EAAS,IAAI,CAAC,EAGtE,EAAa,OAAS,GAAK,CAAC,KAAK,oBAAoB,EAAc,EAAS,MAAM,EAAG,CAKvF,IAAM,EAAO,IAAI,QAAe,GAAY,CAAE,EAAS,MAAQ,CAAQ,CAAC,EACxE,KAAK,KAAK,YAAY,EAAS,KAAM,CAAI,EACzC,IAAK,IAAM,KAAc,EACnB,EAAsB,IAAI,EAAW,MAAM,GAAK,KAAK,cAAc,CAAU,GAG/E,KAAU,KAAK,SAAS,EAAW,QAAQ,IAAI,CAAC,CAAC,SAAW,KAAK,kBAAkB,CAAU,CAAC,CAAC,CAAC,UAAY,CAAC,CAAC,EAGlH,OAAO,KAAK,WAAW,CAAO,CAChC,CAEA,OADA,MAAM,KAAK,YAAY,EAAS,CAAc,EACvC,KAAK,WAAW,CAAO,CAChC,OAAS,EAAgB,CACvB,GAAI,IAAY,IAAA,IAAa,KAAK,eAAe,IAAI,EAAS,IAAI,IAAM,GAAW,CAAC,EAAQ,QAAS,CACnG,EAAQ,OAAS,SACjB,EAAQ,MAAQ,EAAa,CAAK,EAClC,EAAQ,MAAQ,IAAA,GAChB,EAAQ,aAAe,CAAC,EACxB,GAAI,CAAE,KAAK,KAAK,YAAY,EAAS,KAAM,IAAA,EAAS,CAAE,MAAQ,CAA8B,CAC5F,EAAQ,YAAY,EACpB,KAAK,eAAe,OAAO,EAAS,IAAI,EACxC,GAAI,CAAE,KAAK,KAAK,OAAO,EAAS,IAAI,CAAE,MAAQ,CAAqC,CACnF,MAAM,KAAK,kBAAkB,CAAO,CACtC,CACA,MAAM,CACR,QAAU,CACR,KAAK,UAAU,OAAO,EAAS,IAAI,EACnC,EAAa,CACf,CACF,CAQA,YAAoB,EAA8B,CAChD,IAAM,EAAO,EAAQ,QAAQ,KAC7B,GAAI,EAAQ,SAAW,WAAa,EAAQ,SAAW,KAAK,UAAU,OAAO,SACxE,KAAK,eAAe,IAAI,CAAI,IAAM,EAAS,OAChD,EAAQ,QAAQ,EAChB,EAAQ,MAAQ,IAAA,GAChB,KAAK,KAAK,YAAY,EAAM,IAAA,EAAS,EAGrC,EAAQ,OAAS,UAejB,IAAM,EAAW,YAAY,QAAQ,KAAK,eAAe,EACzD,EAAQ,SAAW,EACnB,IAAM,EAAU,EAAQ,QAAQ,WAAW,CACzC,OAAQ,EAAe,EAAQ,WAAW,OAAQ,CAAQ,EAC1D,GAAI,KAAK,QAAQ,gBAAkB,IAAA,GAC/B,CAAC,EACD,CAAE,QAAU,GAAyB,KAAK,mBAAmB,EAAM,CAAK,CAAE,CAChF,CAAC,EACD,KAAU,aAAa,EAAS,CAAO,CACzC,CAGA,MAAc,YAAY,EAAwB,EAA0C,CACtF,OAAQ,UAAY,EAAQ,SAAW,WAAa,EAAQ,SAAW,KAAK,UAAU,OAAO,SACjG,GAAQ,SAAW,GACnB,GAAI,CACF,IAAM,EAAS,KAAK,iBAAiB,EAAQ,YAAY,EACzD,GAAI,IAAW,IAAA,GAAW,CACxB,IAAM,EAAS,EAAe,EAAa,EAAQ,WAAW,OAAQ,KAAK,UAAU,OACnF,YAAY,QAAQ,KAAK,cAAc,CAAC,EAC1C,MAAM,EAAU,KAAK,KAAK,YAAY,CAAE,KAAM,KAAK,SAAU,OAAQ,EAAQ,QAAQ,KACnF,QAAS,EAAQ,SAAU,QAAS,QAAO,CAAC,EAAG,CAAM,EACvD,EAAO,eAAe,CACxB,CACA,KAAK,YAAY,CAAO,CAC1B,OAAS,EAAgB,CAGvB,GAAI,CAAC,EAAQ,SAAW,CAAC,KAAK,UAAU,OAAO,QAAS,CACtD,EAAQ,OAAS,SACjB,EAAQ,MAAQ,8BAA8B,EAAa,CAAK,IAChE,EAAe,CAAO,EACtB,EAAQ,QAAQ,EAChB,EAAQ,MAAQ,IAAA,GAChB,GAAI,CACF,KAAK,KAAK,YAAY,EAAQ,QAAQ,KAAM,IAAA,EAAS,EACrD,KAAK,KAAK,cAAc,EAAQ,QAAQ,KAAM,CAAE,KAAM,SAAU,QAAS,EAAQ,KAAM,CAAC,CAC1F,MAAQ,CAAqC,CAC7C,MAAM,KAAK,WAAW,EAAS,WAAW,EAAQ,OAAO,EACzD,EAAQ,YAAY,EACpB,MAAM,KAAK,kBAAkB,CAAO,CACtC,CACF,QAAU,CAGR,EAAQ,aAAe,CAAC,CAC1B,CAhCmB,CAiCrB,CAWA,YAA8C,CAC5C,GAAI,KAAK,MAAM,OAAS,EAAG,MAAO,CAAC,EACnC,IAAM,EAAQ,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC,CAAC,CAAC,IAAI,GACzC,KAAK,EAAK,KAAK,IAAI,EAAK,eACrB,EAAK,YAAc,IAAA,GAAY,GAAK,cAAc,EAAK,YAAY,EACxE,MAAO,CACL,KAAM,CACJ,KAAM,SACN,KAAM,CAAC,GAAG,KAAK,MAAM,KAAK,CAAC,EAC3B,YAAa,kCAAkC,EAAM,KAAK;CAAI,GAChE,CACF,CACF,CAGA,YAAoB,EAAuB,CACzC,IAAM,EAAQ,EAAS,EAAM,aAAa,EAC1C,GAAI,KAAK,MAAM,OAAS,EACtB,MAAU,MAAM,mEAAmE,EAErF,GAAI,CAAC,KAAK,MAAM,IAAI,CAAK,EACvB,MAAU,MACR,wBAAwB,EAAM,wBAAwB,CAAC,GAAG,KAAK,MAAM,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,GACxF,EAEF,OAAO,CACT,CAUA,oBAA4B,EAA6C,CACvE,MAAO,CAAC,GAAG,IAAI,IAAI,EAAM,IAAK,GAAS,CACrC,IAAM,EAAU,EAAW,CAAI,EAC/B,GAAI,CAAC,KAAK,eAAe,IAAI,CAAO,EAClC,MAAU,MACR,uBAAuB,EAAQ,uDACjC,EAEF,OAAO,CACT,CAAC,CAAC,CAAC,CACL,CAYA,iBAAyB,EAA2C,EAA2D,CAC7H,IAAM,EAAS,KAAK,QAAQ,kBAAoB,SAChD,GAAI,IAAW,OAAS,EAAQ,OAAO,SAAW,EAAG,MAAO,CAAC,EAC7D,IAAM,EAAY,KAAK,YAAY,CAAY,EACzC,EAAkB,CAAC,EACnB,EAAgB,IAAI,IAAI,KAAK,KAAK,QAAQ,CAAC,CAAC,OAAO,GAAU,EAAO,SAAW,SAAS,CAAC,CAAC,IAAI,GAAU,EAAO,cAAc,CAAC,EAC9H,EAAS,CACb,GAAG,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAAC,OAAO,GAAS,EAAM,SAAW,WAAa,EAAM,SAAW,WAAa,KAAK,cAAc,EAAO,CAAa,CAAC,CAAC,CACvJ,OAAO,GAAS,CAAC,EAAU,IAAI,CAAK,CAAC,EACxC,GAAG,KAAK,eACR,GAAG,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,OAAO,GAAS,EAAM,QAAQ,OAAS,EAAQ,IAAI,CACrF,EACA,IAAK,IAAM,KAAS,EAAQ,CAC1B,IAAM,EAAQ,EAAQ,OAAO,OAAO,GAClC,EAAM,QAAQ,OAAO,KAAK,GAAU,EAAc,EAAM,CAAM,CAAC,CAAC,EAClE,GAAI,EAAM,SAAW,EAAG,SACxB,IAAM,EAAS,IAAI,EAAM,QAAQ,KAAK,gBAAgB,EAAM,KAAK,IAAI,IACrE,GAAI,IAAW,SACb,MAAU,MACR,WAAW,EAAQ,KAAK,qDAAqD,EAAO,SACzE,EAAM,QAAQ,KAAK,2GAOhC,EAEF,EAAM,KAAK,CAAM,CACnB,CACA,OAAO,CACT,CAaA,sBAA8B,EAAgB,EAA4C,CACxF,GAAI,GAAS,UAAU,UAAY,GAAM,OAAO,KAAK,gBAAgB,EACrE,IAAM,EAAQ,GAAqC,KAGnD,OAFI,IAAS,eAAuB,KAAK,gBAAgB,EACrD,IAAS,aAAqB,4CAC3B,EAAa,CAAK,CAC3B,CAGA,iBAAkC,CAChC,MAAO,mBAAmB,OAAO,KAAK,eAAe,EAAE,wFAEzD,CAYA,MAAc,gBAAgB,EAAsD,CAClF,IAAI,EACA,EACE,EAAW,IAAI,QAAe,GAAY,CAC9C,EAAQ,WAAW,EAAS,KAAK,UAAU,EAG1C,EAA6C,QAAQ,CACxD,CAAC,EACD,GAAI,CACF,IAAM,EAAU,KAAK,UAAU,OACzB,EAAa,IAAI,QAAc,GAAW,CAC1C,EAAQ,QAAS,EAAQ,EACxB,EAAQ,iBAAiB,QAAS,EAAc,CAAE,KAAM,EAAK,CAAC,EACnE,SAAS,GAAe,CAAE,EAAQ,CAAE,CACpC,MAAoB,EAAQ,oBAAoB,QAAS,CAAY,CACvE,CAAC,EACD,MAAM,EAAU,QAAQ,KAAK,CAAC,GAAG,EAAY,IAAI,GAAW,EAAQ,OAAO,EAAG,EAAU,CAAU,CAAC,EACjG,EAAe,KAAK,UAAU,OAAQ,KAAK,UAAU,CAAC,CAC1D,QAAU,CACJ,IAAU,IAAA,IAAW,aAAa,CAAK,EAC3C,IAAc,CAChB,CACF,CAGA,YAAoB,EAAmC,EAAO,IAAI,IAA0C,CAC1G,IAAK,IAAM,KAAW,EAChB,EAAK,IAAI,CAAO,IACpB,EAAK,IAAI,CAAO,EAChB,KAAK,YAAY,EAAQ,aAAc,CAAI,GAE7C,OAAO,CACT,CAGA,cAAsB,EAAwB,EAA0D,CACtG,OAAO,EAAQ,QAAQ,WAAa,KAAK,eAAe,IAAI,CAAO,IAC7D,IAAkB,IAAA,GAClB,KAAK,KAAK,QAAQ,CAAC,CAAC,KAAK,GAAU,EAAO,OAAS,EAAQ,QAAQ,MAChE,EAAO,iBAAmB,EAAQ,QAAQ,gBAAkB,EAAO,SAAW,SAAS,EAC1F,EAAc,IAAI,EAAQ,QAAQ,cAAc,EACxD,CAGA,oBAA4B,EAAmC,EAA4B,CAAC,EAAY,CACtG,OAAO,EAAQ,MAAM,GAAW,EAAsB,IAAI,EAAQ,MAAM,GACnE,GAAG,KAAK,QAAQ,kBAAoB,YAAc,UAChD,EAAO,KAAK,GAAQ,EAAQ,QAAQ,OAAO,KAAK,GAAU,EAAc,EAAM,CAAM,CAAC,CAAC,GACtF,KAAK,cAAc,CAAO,EAAE,CACrC,CAWA,MAAc,kBAAkB,EAAwC,CACtE,GAAI,KAAK,UAAU,OAAO,QAAS,OACnC,IAAM,EAAQ,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAAC,OAAO,GACrD,EAAQ,SAAW,WAChB,CAAC,EAAQ,SACT,EAAQ,aAAa,SAAS,CAAQ,GACtC,KAAK,oBAAoB,EAAQ,aAAc,EAAQ,QAAQ,MAAM,CAAC,EAC3E,IAAK,IAAM,KAAW,EACpB,MAAM,KAAK,YAAY,CAAO,CAElC,CAGA,iBAAyB,EAAuD,CAC9E,IAAI,EAAqB,GACnB,EAAQ,EAAQ,IAAK,GAAY,CACrC,IAAM,EAAO,EAAQ,QAAQ,KAC7B,GAAI,EAAQ,QAAU,IAAA,GAAW,CAC/B,IAAM,EAAU,EAAQ,QAAQ,KAC1B,EAAU,EAAU,EAAS,EAAS,KAAK,wBAAwB,EAAI,IAAA,GAE7E,MADA,KAAuB,IAAY,IAAA,IAAa,IAAY,EACrD,qBAAqB,EAAK,YAAY,EAAQ,SAChD,EAAU,GAAK;wDACf,IAAY,IAAA,GAAY,GAAK,8CAA8C,IAClF,CACA,GAAI,EAAQ,SAAW,IAAA,IAAa,EAAQ,SAAW,SAAU,MAAO,qBAAqB,EAAK,kFAClG,IAAM,EAAO,EAAQ,QAAQ,MAAQ,GAC/B,EAAU,EAAS,EAAM,KAAK,wBAAwB,EAE5D,MADA,KAAuB,IAAY,EAC5B,qBAAqB,EAAK,cAAc,IAAY,EAAO,OAAS,YAAY,oBAAoB,GAC7G,CAAC,EACG,KAAM,SAAW,EACrB,MAAO,CACL,uKACA,GAAG,EACH,GAAI,EAAqB,CAAC,iGAAiG,EAAI,CAAC,CAClI,CAAC,CAAC,KAAK;CAAI,CACb,CAGA,mBAA2B,EAAwD,CACjF,IAAM,EAAQ,IAAI,IAAI,EAAa,IAAI,GAAW,CAAC,EAAQ,QAAQ,KAAM,EAAQ,QAAQ,CAAC,CAAC,EAC3F,OAAO,EAAW,CAChB,KAAM,yBACN,YAAa,4MACb,WAAY,CAAE,KAAM,SAAU,WAAY,CAAE,KAAM,CAAE,KAAM,QAAS,EAAG,OAAQ,CAAE,KAAM,UAAW,QAAS,CAAE,CAAE,EAAG,SAAU,CAAC,MAAM,EAAG,qBAAsB,EAAM,EACjK,MAAM,EAAc,CAClB,GAAI,OAAO,GAAQ,WAAY,EAAc,MAAU,UAAU,qCAAqC,EACtG,IAAM,EAAO,QAAQ,IAAI,EAAK,MAAM,EAAG,EAAS,QAAQ,IAAI,EAAK,QAAQ,GAAK,EAC9E,GAAI,OAAO,GAAS,UAAY,CAAC,OAAO,cAAc,CAAM,GAAK,EAAS,EAAG,MAAU,UAAU,mCAAmC,EACpI,MAAO,CAAE,OAAc,QAAiB,CAC1C,EACA,SAAU,CAAE,OAAM,YAAa,CAC7B,IAAM,EAAW,EAAM,IAAI,CAAI,EAC/B,GAAI,IAAa,IAAA,GAAW,MAAU,MAAM,0DAA0D,EACtG,IAAM,EAAO,EAAS,QAAQ,MAAQ,GACtC,GAAI,EAAS,EAAK,QAAW,EAAS,GAAK,kBAAkB,KAAK,EAAK,EAAQ,EAAI,MAAU,WAAW,2CAA2C,EAEnJ,IAAM,EAAO,EAAkB,EAAK,MAAM,CAAM,EAAG,KAAK,wBAAwB,EAC1E,EAAO,EAAS,EAAK,OAC3B,MAAO,CAAE,OAAM,OAAQ,EAAS,OAAQ,UAAW,EAAS,QAAQ,WAAa,GAC/E,GAAI,EAAS,QAAU,IAAA,GAAY,CAAC,EAAI,CAAE,MAAO,EAAS,KAAM,EAAI,KAAM,EAC1E,WAAY,EAAO,EAAK,OAAS,EAAO,IAAK,CACjD,EACA,sBAAyB,EAC3B,CAAC,CACH,CAUA,MAAc,aACZ,EACA,EACe,CACf,IAAM,EAAO,EAAQ,QAAQ,KAC7B,GAAI,CACF,IAAM,EAAW,MAAM,EACvB,GAAI,EAAQ,SAAW,UAAY,CAAC,EAAQ,QAAS,CAMnD,IAAM,EAAU,EAAQ,UAAU,UAAY,GAC1C,KAAK,gBAAgB,EACrB,EAAU,EAAU,KAAK,QAAQ,oBAAsB,EAAI,EAC3D,IAAY,IAAA,IAmBd,EAAQ,OAAS,YACjB,EAAQ,OAAS,OAAO,OAAO,CAC7B,OAAQ,EACR,QAAS,EAAQ,QAAQ,WAAW,GACpC,eAAgB,EAAQ,QAAQ,eAChC,KAAM,EAAS,KACf,UAAW,EAAS,QAAQ,SAC9B,CAAC,EACD,EAAe,CAAO,EACtB,KAAK,KAAK,cAAc,EAAM,CAAE,KAAM,YAAa,KAAM,EAAS,IAAK,CAAC,EACxE,MAAM,KAAK,WAAW,EAAS,aAAa,EAAS,MAAM,IA5B3D,EAAQ,OAAS,SACjB,EAAQ,MAAQ,EAGZ,EAAS,KAAK,KAAK,IAAM,KAC3B,EAAQ,OAAS,OAAO,OAAO,CAC7B,OAAQ,EACR,QAAS,EAAQ,QAAQ,WAAW,GACpC,eAAgB,EAAQ,QAAQ,eAChC,KAAM,EAAS,KACf,UAAW,EACb,CAAC,GAEH,EAAe,CAAO,EACtB,KAAK,KAAK,cAAc,EAAM,CAAE,KAAM,SAAU,QAAS,CAAQ,CAAC,EAClE,MAAM,KAAK,WAAW,EAAS,WAAW,KACrC,EAAQ,SAAW,IAAA,GAAY,GAAK,8CAA8C,EAAQ,OAAO,OAAO,EAcjH,CACF,OAAS,EAAgB,CAIvB,GAAI,EAAQ,SAAW,UAAY,CAAC,EAAQ,QAAS,CACnD,EAAQ,OAAS,SACjB,EAAQ,MAAQ,KAAK,sBAAsB,EAAO,CAAO,EACzD,EAAe,CAAO,EACtB,GAAI,CAAE,KAAK,KAAK,cAAc,EAAM,CAAE,KAAM,SAAU,QAAS,EAAQ,KAAM,CAAC,CAAE,MAAQ,CAA6B,CACrH,MAAM,KAAK,WAAW,EAAS,WAAW,EAAQ,OAAO,CAC3D,CACF,QAAU,CACR,EAAQ,YAAY,EAGpB,MAAM,KAAK,kBAAkB,CAAO,CACtC,CACF,CAkBA,MAAc,WAAW,EAAwB,EAAgC,CAC/E,IAAM,EAAS,EAAQ,QAAQ,KAC/B,GAAI,EAAQ,SAAW,KAAK,UAAU,OAAO,SAAW,KAAK,eAAe,IAAI,CAAM,IAAM,EAAS,OACrG,IAAM,EAAW,KAAK,YAAY,CAAM,EAIpC,IAAa,UAAS,KAAK,cAAgB,IAC/C,GAAI,CACF,IAAM,EAAS,EAAe,EAAQ,WAAW,OAAQ,KAAK,UAAU,OACtE,YAAY,QAAQ,KAAK,cAAc,CAAC,EAC1C,MAAM,EAAU,KAAK,KAAK,YAAY,CACpC,KAAM,EACN,OAAQ,KAAK,SACb,QAAS,WAAW,EAAO,IAAI,EAAS,EAAS,KAAK,IAAI,KAAK,yBAA0B,KAAK,IAAI,GAAI,KAAK,MAAM,KAAK,KAAK,iBAAmB,CAAC,CAAC,CAAC,CAAC,IAClJ,WACA,QACF,CAAC,EAAG,CAAM,CACZ,MAAQ,CAGR,CACF,CAOA,YAAoB,EAAoC,CAOtD,OAJI,KAAK,QAAQ,uBAAyB,IAAS,KAAK,KAAK,WAGzD,KAAK,eAAe,IAAI,CAAM,CAAC,EAAE,aAAe,GAAa,QAC1D,QACT,CAGA,cAAwB,GACxB,UAAoB,IAAI,gBACxB,WAcA,MAAM,UAAU,EAAqC,CACnD,OAAS,CACP,GAAQ,eAAe,EACvB,IAAM,EAAc,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAClD,OAAO,GAAW,CAAC,EAAQ,eAAe,EACvC,EAAY,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,IAAI,GAAY,EAAS,OAAO,EAO/E,GANI,EAAY,OAAS,EAAU,OAAS,GAC1C,MAAM,EAAU,QAAQ,IAAI,CAAC,GAAG,EAAY,IAAI,GAAW,EAAQ,OAAO,EAAG,GAAG,CAAS,CAAC,EAAG,CAAM,EAErG,MAAM,KAAK,KAAK,SAAS,KAAK,SAAU,CAAM,EAG1C,EAFS,KAAK,UAAU,KAAO,GAAK,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CACtE,KAAK,GAAW,CAAC,EAAQ,eAAe,GAChC,MACb,CACF,CAGA,SAAyC,CACvC,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAAC,IAAI,GAAW,KAAK,WAAW,CAAO,CAAC,CAAC,CACjG,CAEA,WAAmB,EAA4C,CAC7D,OAAO,OAAO,OAAO,CACnB,KAAM,EAAQ,QAAQ,KACtB,QAAS,EAAQ,QAAQ,WAAW,GACpC,eAAgB,EAAQ,QAAQ,eAChC,KAAM,EAAQ,QAAQ,KACtB,OAAQ,EAAQ,OAChB,QAAS,EAAQ,QAAQ,QACzB,UAAW,EAAQ,QAAQ,UAC3B,OAAQ,EAAQ,QAAQ,OACxB,GAAI,EAAQ,QAAQ,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAQ,QAAQ,IAAK,EAC3E,GAAI,EAAQ,SAAS,SAAW,EAAI,CAAC,EAAI,CAAE,SAAU,EAAQ,QAAS,EACtE,GAAI,EAAQ,QAAQ,YAAc,IAAA,GAAY,CAAC,EAAI,CAAE,UAAW,EAAQ,QAAQ,SAAU,EAC1F,GAAI,EAAQ,SAAW,IAAA,GAAY,CAAC,EAAI,CAAE,OAAQ,EAAQ,MAAO,EACjE,GAAI,EAAQ,QAAU,IAAA,GAAY,CAAC,EAAI,CAAE,MAAO,EAAQ,KAAM,CAChE,CAAC,CACH,CAYA,MAAM,YACJ,EACA,EAA0E,CAAC,EAC5B,CAC/C,IAAM,EAAU,EAAW,CAAI,EACzB,EAAU,KAAK,eAAe,IAAI,CAAO,EAC/C,GAAI,IAAY,IAAA,GAAW,MAAU,MAAM,2BAA2B,EAAQ,EAAE,EAChF,IAAM,EAAS,EAAa,EAAQ,WAAA,GAAoC,EAGpE,EACE,EAAW,IAAI,QAAe,GAAY,CAAE,EAAQ,WAAW,EAAS,CAAM,CAAE,CAAC,EACvF,GAAI,CACF,MAAM,EAAU,QAAQ,KAAK,CAAC,EAAQ,QAAS,CAAQ,CAAC,EAAG,EAAQ,MAAM,CAC3E,QAAU,CACR,aAAa,CAAK,CACpB,CAEA,OADA,EAAQ,QAAQ,eAAe,EACxB,EAAQ,MACjB,CAYA,MAAM,YACJ,EACA,EAAsB,MAAM,uBAAuB,EAChB,CACnC,IAAM,EAAU,EAAW,CAAI,EACzB,EAAU,KAAK,eAAe,IAAI,CAAO,EAC/C,GAAI,IAAY,IAAA,GAAW,MAAU,MAAM,2BAA2B,EAAQ,EAAE,EAGhF,MAFA,GAAQ,QAAU,GAClB,EAAQ,YAAc,QAAQ,QAAQ,CAAC,CAAC,SAAW,KAAK,aAAa,EAAS,CAAM,CAAC,EAC9E,EAAQ,SACjB,CAEA,MAAc,aAAa,EAAwB,EAAoD,CACrG,IAAM,EAAU,EAAQ,QAAQ,KAC1B,EAAW,EAAQ,OACzB,EAAQ,QAAU,GAClB,EAAQ,WAAW,MAAM,CAAM,EAC/B,IAAM,EAAgB,YAAY,QAAQ,KAAK,cAAc,EAQ7D,GAAI,CACF,MAAM,EAAU,KAAK,KAAK,OAAO,EAAS,CAAM,EAAG,CAAa,CAClE,MAAQ,CAGR,CACA,GAAI,IAAa,UAGf,EAAQ,OAAS,SACjB,EAAQ,MAAQ,IAAA,GAChB,KAAK,KAAK,YAAY,EAAS,IAAA,EAAS,EACxC,EAAQ,YAAY,MACf,CAKL,GAAI,CAAE,MAAM,EAAU,EAAQ,QAAS,CAAa,CAAE,MAAQ,CAA4C,CAC1G,EAAQ,OAAS,SACjB,EAAQ,YAAY,CACtB,CAgBA,GAfA,EAAe,CAAO,EAClB,KAAK,cAAc,CAAO,IACxB,EAAQ,QAAQ,OAAO,OAAS,GAAG,KAAK,eAAe,IAAI,CAAO,EAGtE,KAAU,KAAK,SAAS,CAAO,CAAC,CAAC,KAAK,SAAY,CAChD,KAAK,eAAe,OAAO,CAAO,EAClC,GAAI,CACE,KAAK,KAAK,QAAQ,CAAC,CAAC,KAAK,GAAU,EAAO,OAAS,GAAW,EAAO,iBAAmB,EAAQ,QAAQ,cAAc,GACxH,KAAK,KAAK,OAAO,CAAO,CAE5B,MAAQ,CAA2C,CACnD,MAAM,KAAK,kBAAkB,CAAO,CACtC,CAAC,CAAC,CAAC,UAAY,CAA+C,CAAC,GAE7D,KAAK,eAAe,IAAI,CAAO,IAAM,EAAS,CAChD,KAAK,eAAe,OAAO,CAAO,EAClC,GAAI,CAAE,KAAK,KAAK,OAAO,CAAO,CAAE,MAAQ,CAA8C,CACxF,CAKA,MAFA,GAAQ,aAAe,CAAC,EACxB,MAAM,KAAK,kBAAkB,CAAO,EAC7B,CACT,CAUA,QAAQ,EAAsB,MAAM,6BAA6B,EAAkB,CACjF,GAAI,KAAK,cAAgB,IAAA,GAAW,OAAO,KAAK,YAChD,KAAK,UAAU,MAAM,CAAM,EAC3B,IAAM,EAAQ,CAAC,GAAG,KAAK,eAAe,KAAK,CAAC,EAK5C,MAJA,MAAK,YAAc,QAAQ,WAAW,CACpC,GAAG,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,IAAI,GAAY,EAAS,OAAO,EAChE,GAAG,EAAM,IAAI,GAAQ,KAAK,YAAY,EAAM,CAAM,CAAC,CACrD,CAAC,CAAC,CAAC,SAAW,IAAA,EAAS,EAChB,KAAK,WACd,CAGA,aAAa,EAAoB,CAC/B,IAAM,EAAU,EAAW,CAAI,EACzB,EAAU,KAAK,eAAe,IAAI,CAAO,EAC/C,GAAI,IAAY,IAAA,GAAW,MAAU,MAAM,2BAA2B,EAAQ,EAAE,EAChF,GAAI,EAAQ,SAAW,WAAa,EAAQ,SAAW,WAAa,CAAC,EAAQ,iBAAmB,EAAQ,QAAQ,UAC9G,MAAU,MAAM,yCAAyC,EAAQ,EAAE,EAErE,KAAK,KAAK,OAAO,CAAO,EACxB,KAAK,eAAe,OAAO,CAAO,CACpC,CAEA,cAAuD,CACrD,OAAO,OAAO,OAAO,CACnB,EAAW,CACT,KAAM,cACN,YAAa,CACX,iDACA,0EACA,iFACA,sHACF,CAAC,CAAC,KAAK,GAAG,EACV,WAAY,CACV,KAAM,SACN,WAAY,CACV,KAAM,CACJ,KAAM,SACN,YAAa,6DACf,EACA,KAAM,CACJ,KAAM,SACN,YAAa,sDACf,EACA,UAAW,CACT,KAAM,SACN,YAAa,gDACf,EACA,QAAS,CACP,KAAM,SACN,KAAM,CAAC,QAAS,MAAM,EACtB,YAAa,+EACf,EACA,UAAW,CACT,KAAM,QACN,MAAO,CAAE,KAAM,QAAS,EACxB,YAAa,qSAIf,EACA,OAAQ,CACN,KAAM,QACN,MAAO,CAAE,KAAM,QAAS,EACxB,YAAa,iOAGf,EACA,GAAG,KAAK,WAAW,CACrB,EACA,SAAU,CAAC,MAAM,EACjB,qBAAsB,EACxB,EACA,MAAO,EACP,QAAS,MAAO,EAAS,IAAY,EAAO,MAAM,KAAK,MAAM,EAAS,EAAQ,MAAM,CAAC,EAIrF,UAAW,KAAK,eAChB,sBAAyB,EAC3B,CAAC,EACD,EAAW,CACT,KAAM,cACN,aAAc,GACd,YAAa,CACX,uDACA,gGACA,0FACA,KAAK,QAAQ,+BAAiC,GAC1C,iGACA,sFACJ,4CACF,CAAC,CAAC,KAAK,GAAG,EACV,WAAY,CACV,KAAM,SACN,WAAY,CACV,KAAM,CAAE,KAAM,SAAU,YAAa,yCAA0C,EAC/E,cAAe,CAAE,KAAM,UAAW,YAAa,4DAA6D,CAC9G,EACA,SAAU,CAAC,MAAM,EACjB,qBAAsB,EACxB,EACA,MAAO,EACP,QAAS,MAAO,CAAE,OAAM,mBAAoB,CAC1C,IAAM,EAAU,KAAK,eAAe,IAAI,CAAI,EAW5C,OAVI,IAAY,IAAA,KAAc,CAAC,GAAiB,KAAK,QAAQ,+BAAiC,MACxF,EAAQ,SAAW,WAAa,EAAQ,SAAW,WAAa,EAAQ,QAAQ,WAC7E,EAAO,CACZ,OAAQ,EAAM,OAAQ,GACtB,OAAQ,EAAQ,SAAW,UAAY,UAAY,UACnD,YAAa,+GACR,KAAK,QAAQ,+BAAiC,GAAQ,+CACrD,iFACR,CAAC,EAEI,EAAO,CAAE,OAAQ,EAAM,OAAQ,GAAM,eAAgB,MAAM,KAAK,YAAY,CAAI,CAAE,CAAC,CAC5F,EACA,UAAW,KAAK,eAClB,CAAC,CACH,CAAC,CACH,CAUA,gBAAwB,EAAuD,CAC7E,IAAM,EAAU,EAAuB,KAAK,KAAK,SAAS,CAAC,CAAC,OAAO,EACnE,OAAO,EAAQ,aACb,CAAE,QAAS,EAAG,SAAQ,EACtB,GAAU,CAAC,CACb,CACF,CAEA,MAAc,iBACZ,EACuB,CACvB,GAAI,KAAK,QAAQ,gBAAkB,IAAA,GAAW,OAAO,KAAK,QAAQ,cAAc,CAAO,EACvF,IAAM,EAAW,KAAK,QAAQ,gBAAkB,KAAK,QAAQ,KACvD,EAAO,EAAQ,OAAS,IAAA,GAAY,IAAA,GAAY,KAAK,MAAM,IAAI,EAAQ,IAAI,EAC3E,EAAW,IAAS,IAAA,GACtB,GACA,iBAAiB,EAAK,KAAK,YAAY,EAAK,cAAgB,EAAK,cAC/D,EAAY,EAAQ,YAAc,IAAA,GACpC,GACA,4BAA4B,EAAQ,UAAU,GAClD,OAAO,EAAW,EAAU,CAC1B,GAAI,EAAQ,KACZ,KAAM,EAAQ,KACd,aAAc,GAAG,EAAS,aAAa,2CAA2C,EAAQ,KAAK,IAAI,IAAW,GAChH,CAAC,CACH,CAEA,gBAAiC,CAC/B,OAAa,CACX,IAAM,EAAY,UAAU,EAAE,KAAK,iBACnC,GAAI,CAAC,KAAK,UAAU,IAAI,CAAS,GAAK,CAAC,KAAK,eAAe,IAAI,CAAS,GACnE,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,KAAK,GAAU,EAAO,OAAS,CAAS,EAAG,OAAO,CAC9E,CACF,CAEA,MAAc,mBAAmB,EAAgB,EAAqC,CACpF,IAAM,EAAW,QAAQ,QAAQ,CAAC,CAAC,SAAW,KAAK,QAAQ,gBAAgB,EAAQ,CAAK,CAAC,EACzF,MAAM,EAAkB,EAAU,KAAK,iBAAiB,CAC1D,CACF,EAEA,SAAgB,EAAuB,EAAoD,CACzF,OAAO,IAAI,EAAiB,CAAO,CACrC,CAEA,SAAS,EACP,EACA,EACc,CACd,IAAM,EAAW,IAAI,EACrB,GAAI,IAAa,IAAA,GAAW,CAC1B,IAAM,EAAQ,UAAW,EACrB,EAAS,MAAM,CAAC,CAAC,IAAI,GAAQ,EAAS,IAAI,CAAI,CAAC,CAAC,CAC/C,OAAQ,GAAiC,IAAS,IAAA,EAAS,EAC5D,EACJ,IAAK,IAAM,KAAQ,EAAO,EAAS,SAAS,CAAI,CAClD,CACA,IAAK,IAAM,KAAQ,EAAW,EAAS,SAAS,CAAI,EACpD,OAAO,CACT,CAEA,SAAS,EAAe,EAA0D,CAChF,IAAM,EAAQ,EAAO,EAAO,uBAAuB,EACnD,GAAI,OAAO,KAAK,CAAK,CAAC,CAAC,KAAK,GAAO,IAAQ,QAAU,IAAQ,eAAe,EAC1E,MAAU,UAAU,8CAA8C,EAEpE,GAAI,EAAM,gBAAkB,IAAA,IAAa,OAAO,EAAM,eAAkB,UACtE,MAAU,UAAU,6CAA6C,EAEnE,MAAO,CAAE,KAAM,EAAW,EAAM,IAAI,EAAG,cAAe,EAAM,gBAAkB,EAAK,CACrF,CAEA,SAAS,EAAe,EAA0C,CAChE,IAAM,EAAQ,EAAO,EAAO,uBAAuB,EAC7C,EAAQ,IAAI,IAAI,CACpB,OAAQ,OAAQ,YAAa,UAAW,OAAQ,YAAa,QAC/D,CAAC,EACD,GAAI,OAAO,KAAK,CAAK,CAAC,CAAC,KAAK,GAAO,CAAC,EAAM,IAAI,CAAG,CAAC,EAChD,MAAU,UAAU,8CAA8C,EAEpE,MAAO,CACL,KAAM,EAAS,EAAM,KAAM,aAAa,EACxC,GAAI,EAAM,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAW,EAAM,IAAI,CAAE,EACnE,GAAI,EAAM,YAAc,IAAA,GACpB,CAAC,EACD,CAAE,UAAW,EAAS,EAAM,UAAW,kBAAkB,CAAE,EAC/D,GAAI,EAAM,UAAY,IAAA,GAAY,CAAC,EAAI,CAAE,QAAS,EAAa,EAAM,OAAO,CAAE,EAC9E,GAAI,EAAM,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAS,EAAM,KAAM,aAAa,CAAE,EAChF,GAAI,EAAM,YAAc,IAAA,GACpB,CAAC,EACD,CAAE,UAAW,EAAY,EAAM,UAAW,WAAW,CAAE,EAC3D,GAAI,EAAM,SAAW,IAAA,GAAY,CAAC,EAAI,CAAE,OAAQ,EAAY,EAAM,OAAQ,QAAQ,CAAE,CACtF,CACF,CAEA,SAAS,EAAY,EAAgB,EAAkC,CACrE,GAAI,CAAC,MAAM,QAAQ,CAAK,EAAG,MAAU,UAAU,GAAG,EAAM,6BAA6B,EACrF,OAAO,EAAM,IAAI,GAAS,EAAS,EAAO,GAAG,EAAM,OAAO,CAAC,CAC7D,CAEA,SAAS,EAAa,EAA0C,CAC9D,GAAI,IAAU,SAAW,IAAU,OACjC,MAAU,UAAU,0CAA0C,EAEhE,OAAO,CACT,CAuBA,SAAgB,EACd,EACyB,CACzB,IAAM,EAAU,IAAI,IAChB,EAAM,EAqBV,OApBA,EAAS,QAAQ,SAAS,EAAO,IAAU,CACzC,IAAM,EAAQ,EAAM,MACpB,GAAI,EAAM,OAAS,YAAa,EAAQ,IAAI,EAAM,MAAM,OACnD,GAAI,EAAM,OAAS,cAAe,EAAQ,OAAO,EAAM,MAAM,OAC7D,GAAI,EAAM,OAAS,YAMjB,IAAA,IAAM,KAAS,EAAM,QAAQ,QAC5B,EAAM,OAAS,aAAa,EAAQ,IAAI,EAAM,EAAE,EAKxC,EAAQ,OAAS,IAC1B,EAAM,OAAS,aAAe,EAAM,cAAgB,MAC9C,EAAM,EAAQ,EAC7B,CAAC,EACM,EAAS,QAAQ,MAAM,EAAG,CAAG,CACtC,CAEA,SAAS,EAAO,EAAgB,EAAwC,CACtE,GAAI,OAAO,GAAU,WAAY,GAAkB,MAAM,QAAQ,CAAK,EACpE,MAAU,UAAU,GAAG,EAAM,mBAAmB,EAElD,OAAO,CACT,CAEA,SAAS,EAAW,EAAwB,CAC1C,IAAM,EAAO,EAAS,EAAO,oBAAoB,EACjD,GAAI,CAAC,2BAA2B,KAAK,CAAI,EACvC,MAAU,UAAU,sFAAsF,EAE5G,GAAI,EAAK,OAAS,IAAK,MAAU,UAAU,mDAAmD,EAC9F,OAAO,CACT,CAEA,SAAS,EAAS,EAAgB,EAAuB,CACvD,GAAI,OAAO,GAAU,UAAY,EAAM,KAAK,CAAC,CAAC,SAAW,EACvD,MAAU,UAAU,GAAG,EAAM,4BAA4B,EAE3D,OAAO,CACT,CAEA,SAAS,EAAc,EAAgB,EAAe,EAA0B,CAC9E,IAAM,EAAO,EAAS,EAAO,CAAK,EAClC,GAAI,IAAI,YAAY,CAAC,CAAC,OAAO,CAAI,CAAC,CAAC,WAAa,EAC9C,MAAU,UAAU,GAAG,EAAM,eAAe,EAAS,YAAY,EAEnE,OAAO,CACT,CAEA,SAAS,EAAgB,EAAe,EAAuB,CAC7D,GAAI,CAAC,OAAO,cAAc,CAAK,GAAK,EAAQ,EAAG,MAAU,UAAU,GAAG,EAAM,4BAA4B,EACxG,OAAO,CACT,CAEA,SAAS,EAAa,EAAwB,CAC5C,OAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,CAC9D,CAEA,eAAe,EAAa,EAAqB,EAAkC,CACjF,GAAI,IAAW,IAAA,GAAW,OAAO,EACjC,GAAI,EAAO,QAIT,MADA,EAAa,UAAY,IAAA,EAAS,EAC5B,EAAO,QAAc,MAAM,wBAAwB,EAE3D,OAAO,MAAM,IAAI,SAAY,EAAS,IAAW,CAC/C,IAAM,MAAc,CAClB,EAAO,oBAAoB,QAAS,CAAK,EACzC,EAAO,EAAO,QAAc,MAAM,wBAAwB,CAAC,CAC7D,EACA,EAAO,iBAAiB,QAAS,EAAO,CAAE,KAAM,EAAK,CAAC,EACtD,EAAa,KACX,GAAS,CAAE,EAAO,oBAAoB,QAAS,CAAK,EAAG,EAAQ,CAAK,CAAE,EACtE,GAAS,CAAE,EAAO,oBAAoB,QAAS,CAAK,EAAG,EAAO,CAAK,CAAE,CACvE,CACF,CAAC,CACH,CAEA,SAAS,EAAe,GAAG,EAA4D,CACrF,IAAM,EAAS,EAAQ,OAAQ,GAAwC,IAAc,IAAA,EAAS,EAC9F,OAAO,EAAO,SAAW,EAAI,EAAO,GAAM,YAAY,IAAI,CAAM,CAClE,CAEA,SAAS,EAAO,EAA2B,CAAE,OAAO,CAAmB,CAGvE,MAAM,EACJ,IAAI,IAA8B,CAAC,YAAa,SAAU,QAAQ,CAAC,EAkBrE,SAAS,EAAU,EAAyB,EAA0C,CACpF,IAAM,EAAS,EAAS,QAAQ,OAChC,GAAI,EAAO,OAAS,QAAS,OAAO,EAAO,QAAQ,QACnD,GAAI,EAAO,OAAS,aAAc,MAAO,wCACzC,GAAI,EAAO,OAAS,oBAAqB,MAAO,mDAChD,GAAI,EAAO,OAAS,UAAW,MAAO,sBACtC,GAAI,EAAO,OAAS,oBAAsB,CAAC,EAAS,QAAQ,UAC1D,MAAO,0BAA0B,EAAO,OAAO,mCAGjD,GAAI,GAAe,EAAS,KAAK,KAAK,IAAM,GAAI,MAAO,uBAEzD,CAEA,SAAS,EAAoB,EAAwB,CACnD,IAAM,EAAO,EAAS,EAAO,oBAAoB,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,GAAG,EAC9E,GAAI,EAAK,WAAW,GAAG,GAAK,aAAa,KAAK,CAAI,EAChD,MAAU,UAAU,iDAAiD,EAEvE,IAAM,EAAkB,CAAC,EACzB,IAAK,IAAM,KAAQ,EAAK,MAAM,GAAG,EAC3B,OAAS,IAAM,IAAS,IAC5B,IAAI,IAAS,KAAM,CACjB,GAAI,EAAM,SAAW,EAAG,MAAU,UAAU,oDAAoD,EAChG,EAAM,IAAI,CACZ,MAAO,EAAM,KAAK,CAAI,CAAA,CAExB,GAAI,EAAM,SAAW,EACnB,MAAU,UAAU,6EAA6E,EAEnG,OAAO,EAAM,KAAK,GAAG,CACvB,CAGA,SAAS,EAAc,EAAc,EAAwB,CAC3D,OAAO,IAAS,GAAS,EAAK,WAAW,GAAG,EAAM,EAAE,GAAK,EAAM,WAAW,GAAG,EAAK,EAAE,CACtF,CAGA,SAAS,EAAkB,EAAc,EAA0B,CACjE,OAAO,IAAI,YAAY,QAAS,CAAE,MAAO,EAAM,CAAC,CAAC,CAAC,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,CAAI,CAAC,CAAC,SAAS,EAAG,CAAQ,EAAG,CAAE,OAAQ,EAAK,CAAC,CACjI,CAGA,SAAS,EAAS,EAAc,EAA0B,CACxD,IAAM,EAAU,IAAI,YAAY,CAAC,CAAC,OAAO,CAAI,EAC7C,GAAI,EAAQ,YAAc,EAAU,OAAO,EAC3C,IAAM,EAAS;;EACT,EAAc,IAAI,YAAY,CAAC,CAAC,OAAO,CAAM,CAAC,CAAC,WACrD,GAAI,GAAY,EAAa,OAAO,EAAkB,cAAe,CAAQ,EAC7E,IAAM,EAAY,EAAW,EACvB,EAAO,EAAkB,EAAM,KAAK,KAAK,EAAY,CAAC,CAAC,EACzD,EAAY,EAAQ,OAAS,KAAK,MAAM,EAAY,CAAC,EACzD,KAAO,EAAY,EAAQ,SAAW,EAAQ,GAAc,MAAU,KAAM,IAC5E,IAAM,EAAO,IAAI,YAAY,CAAC,CAAC,OAAO,EAAQ,SAAS,CAAS,CAAC,EACjE,OAAO,EAAO,EAAS,CACzB,CAGA,SAAS,EAAe,EAA8B,CACpD,EAAQ,SAAS,OAAS,EAAQ,OAClC,EAAQ,SAAS,OAAS,EAAQ,OAClC,EAAQ,SAAS,MAAQ,EAAQ,KACnC"}
|
|
1
|
+
{"version":3,"file":"managed.js","names":[],"sources":["../../../src/agent/team/managed.ts"],"sourcesContent":["/** Codex-style dynamic worker creation and delegation over AgentTeam. */\n\nimport type { JsonValue } from '../../primitives/index.ts'\nimport { timeoutValue } from '../../platform/config.ts'\nimport { createTextMessage, createUserMessage } from '../../message/index.ts'\nimport type { ModelRegistry } from '../../runtime/index.ts'\nimport type { AgentRunEvent } from '../mode/run-agent.ts'\nimport { cloneAgent, type DefinedAgent } from '../define/definition.ts'\nimport {\n type AgentInput,\n type AgentInvocationOptions,\n type AgentResponse,\n type AgentSession,\n type AgentSessionOptions,\n} from '../define/session.ts'\nimport { History, type HistoryEntry, type HistorySnapshot } from '../history/index.ts'\nimport { managedTeamNoticeRequest } from '../history/input-work.ts'\nimport { defineTool, type ToolDefinition } from '../tool/definition.ts'\nimport { ToolRegistry, type ToolCatalog } from '../tool/registry.ts'\nimport { AgentTeam } from './team.ts'\nimport { DEFAULT_WAIT_TIMEOUT_MS } from './common.ts'\nimport type { AgentTeamOptions } from './types.ts'\nimport type { TurnHooks } from '../loop/events.ts'\nimport { waitForSettlement } from '../../async/index.ts'\ntype DetachedSessionOptions = Omit<AgentSessionOptions, 'registry' | 'team' | 'tools'>\n\n/**\n * Default bound on getting one worker RUNNING, overridable per harness with\n * {@link ManagedAgentTeamOptions.spawnTimeoutMs}.\n *\n * Not the worker's deadline — that is `workerTimeoutMs`. This bounds only the\n * setup, so a lead cannot be held for minutes by a call that no longer waits\n * for any work.\n */\nexport const DEFAULT_SPAWN_SETUP_TIMEOUT_MS = 30_000\n\n/** Default bound on stopping one worker; see {@link ManagedAgentTeamOptions.closeTimeoutMs}. */\nexport const DEFAULT_WORKER_CLOSE_TIMEOUT_MS = 30_000\n\n/**\n * Default bound on holding the lead's turn open for news from a worker; see\n * {@link ManagedAgentTeamOptions.holdWaitMs}.\n *\n * Long enough that a lead is not re-prompted about work that has visibly just\n * started, short enough that it keeps control of its own run: at the deadline\n * the turn comes back and the lead decides whether to wait again, close a\n * worker, or answer with what it has.\n */\nexport const DEFAULT_HOLD_WAIT_MS = 15_000\n\n/** Protocol facts only; task strategy and output contracts belong to the host. */\nconst LEAD_INSTRUCTIONS = [\n 'You have access to a managed team. Your task and coordination strategy are defined by the host instructions.',\n 'Return only the caller-requested result in the caller’s format; include explanation only when requested.',\n 'spawn_agent returns a worker lifecycle view, not its final result. list_agents exposes status and retained results; wait_agents waits within its timeout.',\n 'dependsOn references already registered producer instances. Pending dependents start after those producers settle and receive their results or failure status, even if a producer address is later closed or reused.',\n 'fresh starts from the assigned task; fork also copies the completed lead conversation.',\n 'writes declares relative scheduling scopes under the host conflict policy; it does not grant filesystem permissions. Omit it when no write scope is needed.',\n 'send_message is an update, not terminal completion. completed and failed are terminal worker states; pending and running are not.',\n 'Finished workers occupy slots until close_agent. Closing unfinished work requires cancelRunning: true and host authorization.',\n].join(' ')\n\n/** `fresh` starts from the task; `fork` copies the lead's completed conversation. */\nexport type ManagedAgentSpawnContext = 'fresh' | 'fork'\n\n/** Optional host-defined worker roles; the SDK supplies no domain-specific roles. */\nexport interface ManagedAgentRole {\n /** Referred to by `spawn_agent`; the enum the lead chooses from. */\n readonly name: string\n /** What this role is for. Shown to the lead in the spawn tool schema. */\n readonly description: string\n /** When choosing it is correct — and when it is premature. */\n readonly whenToUse?: string\n /** Added to the worker's own instructions; defaults to `description`. */\n readonly instructions?: string\n}\n\n/** What to do about two workers that would write the same files at once. */\nexport type WriteScopeConflictPolicy = 'reject' | 'warn' | 'off'\n\nexport interface ManagedAgentSpawnRequest {\n /** Optional stable team address; generated as worker_N when omitted. */\n readonly name?: string\n readonly task: string\n /** Short specialization added to the generated worker's instructions. */\n readonly specialty?: string\n /**\n * Context the worker starts from; defaults to\n * {@link ManagedAgentTeamOptions.defaultSpawnContext}.\n */\n readonly context?: ManagedAgentSpawnContext\n /** One of {@link ManagedAgentTeamOptions.roles}, when the host declared any. */\n readonly role?: string\n /** Registered producers that must settle before dispatch; failures also release dependents. */\n readonly dependsOn?: readonly string[]\n /** Workspace-relative scheduling declarations, not filesystem authorization. */\n readonly writes?: readonly string[]\n}\n\nexport interface ResolvedManagedAgentSpawnRequest extends ManagedAgentSpawnRequest {\n readonly name: string\n readonly context: ManagedAgentSpawnContext\n readonly dependsOn: readonly string[]\n readonly writes: readonly string[]\n}\n\nexport interface ManagedAgentWorkerResult {\n readonly worker: string\n readonly agentId: string\n readonly conversationId: string\n readonly text: string\n readonly succeeded: boolean\n}\n\n/**\n * Where a generated worker is in its life.\n *\n * `completed` and `failed` are final but NOT gone: a finished worker stays\n * addressable and keeps occupying a `maxWorkers` slot until it is closed, so\n * a lead that spawns without closing runs out of workers rather than silently\n * accumulating them.\n */\nexport type ManagedAgentWorkerStatus =\n | 'pending' | 'running' | 'completed' | 'failed' | 'closed'\n\nexport interface ManagedAgentWorker {\n readonly name: string\n readonly agentId: string\n readonly conversationId: string\n readonly task: string\n readonly specialty?: string\n /** Context this worker was started from. */\n readonly context: ManagedAgentSpawnContext\n readonly role?: string\n /** Workers that had to settle before this one could start. */\n readonly dependsOn: readonly string[]\n /** Files this worker declared it would write. */\n readonly writes: readonly string[]\n readonly status: ManagedAgentWorkerStatus\n /** Non-fatal problems with the division of work, e.g. an accepted overlap. */\n readonly warnings?: readonly string[]\n readonly result?: ManagedAgentWorkerResult\n readonly error?: string\n}\n\nexport interface ManagedAgentTeamOptions {\n readonly registry: ModelRegistry\n readonly lead: DefinedAgent\n readonly leadName?: string\n readonly leadDescription?: string\n readonly team?: AgentTeam | AgentTeamOptions\n readonly maxWorkers?: number\n /**\n * Automatically hold/continue the lead for pending work and wake it for reports.\n * Defaults to true for this convenience helper. Set false for host-driven turns;\n * reports remain delivered quietly and all lifecycle APIs stay available.\n */\n readonly autoLeadCoordination?: boolean\n /** Team tools exposed to workers; defaults to reporting. Full also enables peer coordination. */\n readonly workerTeamTools?: false | 'reporting' | 'full'\n /** Treat a clean completion with empty text as failure. Defaults to false (tool-only work is valid). */\n readonly requireWorkerText?: boolean\n /** Maximum UTF-8 worker task bytes. Defaults to 64 KiB. */\n readonly maxTaskBytes?: number\n /** Maximum UTF-8 specialty bytes. Defaults to 8 KiB. */\n readonly maxSpecialtyBytes?: number\n /**\n * Context a `spawn_agent` call starts a worker from when it does not say.\n * Defaults to `'fresh'`.\n *\n * `'fresh'` is the default because forking is not free: the worker pays for\n * the lead's whole conversation in input tokens on every round it runs, and\n * a worker whose task genuinely stands alone gains nothing for it. A host\n * that knows its workers always operate on the lead's workspace — and so\n * would otherwise watch each of them rediscover it — should set `'fork'`\n * here rather than hope the lead remembers to ask.\n */\n readonly defaultSpawnContext?: ManagedAgentSpawnContext\n /**\n * Worker kinds the lead may choose from, with what each is for.\n *\n * Declaring them replaces free-text `specialty` with an enum, and puts each\n * role's `whenToUse` in the spawn schema — the one place the lead is certain\n * to read before choosing. Leave it unset and `specialty` behaves as before.\n */\n readonly roles?: readonly ManagedAgentRole[]\n /**\n * What to do when a spawn declares `writes` overlapping a worker that would\n * run at the same time. Defaults to `'reject'`.\n *\n * Rejecting is the default because the alternative is silent data loss: both\n * workers write the file and the later write wins. The refusal names the\n * conflicting worker and the overlap, so the lead's available fix — add it\n * to `dependsOn`, or narrow the scope — is visible in the error itself.\n * `'warn'` records it on the worker instead and lets it run; `'off'` skips\n * the check.\n */\n readonly writeScopePolicy?: WriteScopeConflictPolicy\n /**\n * Cap on how much of a dependency's result is handed to its dependents.\n * Defaults to 8 KiB per dependency; at least 4 bytes. Full results remain readable by scoped tool.\n */\n readonly maxDependencyReportBytes?: number\n /** Active run deadline, excluding queued dependencies and setup. Defaults to 10 minutes. */\n readonly workerTimeoutMs?: number\n /** Maximum wait per worker event observer callback. Defaults to 1 second. */\n readonly observerTimeoutMs?: number\n /**\n * How long closing one worker waits for it to stop.\n * Defaults to {@link DEFAULT_WORKER_CLOSE_TIMEOUT_MS}.\n *\n * After that its slot is freed regardless. A worker that ignores its\n * cancellation must not be able to hold the harness at its cap forever.\n */\n readonly closeTimeoutMs?: number\n /**\n * How long the lead's turn is held open waiting for a worker to report,\n * before the lead is asked again. Defaults to {@link DEFAULT_HOLD_WAIT_MS}.\n *\n * Zero-length would be a spin: the lead answers, is told its workers are\n * still running, answers again, and burns its budget before any result\n * arrives. Codex blocks the parent inside its `wait_agent` tool for the same\n * reason.\n */\n readonly holdWaitMs?: number\n /** Allow model-invoked close_agent to cancel unfinished work (default true).\n * Host closeWorker, disposal and user cancellation are always available. */\n readonly allowModelWorkerCancellation?: boolean\n /**\n * How long `spawn_agent` may take to get a worker running.\n * Defaults to {@link DEFAULT_SPAWN_SETUP_TIMEOUT_MS}.\n *\n * Only the setup: the worker's own deadline is `workerTimeoutMs`, and how\n * long the lead may WAIT for it is the team's `waitTimeoutMs` — pass it\n * through `team: { waitTimeoutMs }` when building the harness.\n */\n readonly spawnTimeoutMs?: number\n /** Defaults to cloning the lead definition under the generated worker id. */\n readonly workerTemplate?: DefinedAgent\n readonly workerFactory?: (\n request: ResolvedManagedAgentSpawnRequest,\n ) => DefinedAgent | Promise<DefinedAgent>\n readonly leadSessionOptions?: DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] }\n readonly workerSessionOptions?: DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] }\n /** Per-worker runtime dependencies for least-privilege tools and workspace policy. */\n readonly workerSessionOptionsFactory?: (\n request: ResolvedManagedAgentSpawnRequest,\n ) => (DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] })\n | Promise<DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] }>\n /** Observe every generated worker's model, tool, trace, and compaction events. */\n readonly onWorkerEvent?: (\n worker: string,\n event: AgentRunEvent,\n ) => void | Promise<void>\n}\n\ninterface WorkerRuntime {\n readonly request: ResolvedManagedAgentSpawnRequest\n readonly session: AgentSession\n /** Exact commissioned workers, independent of address reuse or roster removal. */\n dependencies: readonly WorkerRuntime[]\n starting: boolean\n settledComplete: boolean\n closeTask: Promise<ManagedAgentWorkerStatus> | undefined\n status: ManagedAgentWorkerStatus\n /**\n * Whether the lead's own turn created this worker.\n *\n * It decides who is owed the completion report. A worker the MODEL spawned\n * belongs to a conversation that is waiting for a synthesis, so its report\n * wakes an idle lead. A worker the HOST spawned belongs to the host, which is\n * driving the lead itself; waking it there would start a turn the caller did\n * not ask for.\n */\n readonly leadDriven: boolean\n /**\n * Cancels this worker's run.\n *\n * Owned here rather than by the team: `AgentTeam.cancel` only aborts a\n * team-scheduled wake, not a run a host started itself, so without this a\n * detached worker would survive both `close_agent` and `dispose`.\n */\n readonly controller: AbortController\n /**\n * Set the moment a close begins, before anything is aborted.\n *\n * `status` cannot carry this: it only becomes `'closed'` after the run has\n * settled, so the abort's own rejection arrives while the worker still looks\n * like a running one — and gets reported to the lead as a FAILURE it did not\n * cause and cannot act on.\n */\n closing: boolean\n /**\n * This worker's own deadline, so a run that ended can say WHY.\n *\n * An expired deadline surfaces as an ordinary abort — indistinguishable from\n * a close, or from a cancelled parent — unless the signal that expired is\n * kept and asked. Codex reports a status the parent can branch on; this is\n * what makes one reportable here.\n */\n deadline: AbortSignal | undefined\n /** Resolves when the run has ended and been recorded. Never rejects. */\n settled: Promise<void>\n /**\n * Releases a worker held back by `dependsOn`; undefined once it has started.\n *\n * The team holds the matching promise, so `wait_agents` and `list_agents`\n * report a held worker as `pending` rather than as one that has finished.\n */\n start: (() => void) | undefined\n /** Resolves {@link settled}; called exactly once, whatever ended the worker. */\n readonly markSettled: () => void\n warnings: readonly string[]\n result: ManagedAgentWorkerResult | undefined\n error: string | undefined\n readonly evidence: { status: ManagedAgentWorkerStatus; result: ManagedAgentWorkerResult | undefined; error: string | undefined }\n}\n\n/**\n * A dynamic harness whose lead can create specialized workers with spawn_agent.\n *\n * Spawning starts independent work without blocking the lead. Dependencies refer\n * to the commissioned producer instance; closing its address cannot rebind them.\n */\nexport class ManagedAgentTeam {\n readonly team: AgentTeam\n readonly lead: AgentSession\n readonly leadName: string\n private readonly options: ManagedAgentTeamOptions\n private readonly maxWorkers: number\n private readonly maxTaskBytes: number\n private readonly maxSpecialtyBytes: number\n private readonly workerTimeoutMs: number\n private readonly observerTimeoutMs: number\n private readonly closeTimeoutMs: number\n private readonly holdWaitMs: number\n private readonly spawnTimeoutMs: number\n private readonly workerRuntimes = new Map<string, WorkerRuntime>()\n /** Closed roster entries may still own an in-flight follow-up after a bounded close. */\n private readonly drainingWrites = new Set<WorkerRuntime>()\n private readonly preparing = new Map<string, {\n readonly request: ResolvedManagedAgentSpawnRequest\n readonly dependencies: readonly WorkerRuntime[]\n readonly settled: Promise<void>\n }>()\n private readonly lifecycle = new AbortController()\n private disposeTask: Promise<void> | undefined\n private workerSequence = 0\n private readonly maxDependencyReportBytes: number\n private readonly roles: Map<string, ManagedAgentRole>\n\n constructor(options: ManagedAgentTeamOptions) {\n this.options = options\n this.maxWorkers = positiveInteger(options.maxWorkers ?? 7, 'maxWorkers')\n this.maxTaskBytes = positiveInteger(options.maxTaskBytes ?? 64 * 1024, 'maxTaskBytes')\n this.maxSpecialtyBytes = positiveInteger(options.maxSpecialtyBytes ?? 8 * 1024, 'maxSpecialtyBytes')\n this.workerTimeoutMs = timeoutValue(options.workerTimeoutMs ?? 10 * 60_000)\n this.observerTimeoutMs = timeoutValue(options.observerTimeoutMs ?? 1_000)\n this.closeTimeoutMs = timeoutValue(options.closeTimeoutMs ?? DEFAULT_WORKER_CLOSE_TIMEOUT_MS)\n this.holdWaitMs = timeoutValue(options.holdWaitMs ?? DEFAULT_HOLD_WAIT_MS)\n this.spawnTimeoutMs = timeoutValue(options.spawnTimeoutMs ?? DEFAULT_SPAWN_SETUP_TIMEOUT_MS)\n this.maxDependencyReportBytes = positiveInteger(\n options.maxDependencyReportBytes ?? 8 * 1024,\n 'maxDependencyReportBytes',\n )\n if (this.maxDependencyReportBytes < 4) throw new TypeError('maxDependencyReportBytes must be at least 4')\n this.roles = new Map((options.roles ?? []).map(role => [role.name, role]))\n if (this.roles.size !== (options.roles ?? []).length) {\n throw new Error('managed agent roles contain a duplicate name')\n }\n this.team = options.team instanceof AgentTeam\n ? options.team\n : new AgentTeam({\n ...options.team,\n maxMembers: options.team?.maxMembers ?? this.maxWorkers + 1,\n })\n this.leadName = memberName(options.leadName ?? options.lead.id)\n this.lead = options.lead.createSession({\n ...options.leadSessionOptions,\n hooks: this.leadHooks(options.leadSessionOptions?.hooks),\n registry: options.registry,\n tools: mergeTools(options.leadSessionOptions?.tools, this.controlTools()),\n team: {\n team: this.team,\n name: this.leadName,\n role: 'lead',\n instructions: LEAD_INSTRUCTIONS,\n ...(options.leadDescription === undefined ? {} : { description: options.leadDescription }),\n },\n })\n }\n\n /**\n * Hold the lead's turn open while a worker of its is unfinished.\n *\n * This is Codex's shape, arrived at from the other side: there the parent\n * stays inside its turn and loops on its wait tool until it has what it\n * needs. A lead that concludes while its workers are still running answers\n * from nothing — and once the turn is over, the reports that arrive\n * afterwards have no turn left to be read in, so the work stops with no\n * synthesis at all.\n *\n * `runTurn` re-runs a turn whose `onTurnEnd` hook appended history, so\n * saying so is enough to send the lead round again. Its own step and turn\n * budgets bound this, and `canContinue` leaves an aborted or exhausted turn\n * free to end.\n * @param host - Hooks the host supplied; theirs run first and are kept.\n * @returns The hooks to give the lead's session.\n */\n private leadHooks(host: TurnHooks | undefined): TurnHooks {\n return {\n ...host,\n beforeStep: async (context) => {\n // The request for this round is rebuilt from history, so anything\n // delivered quietly before now is about to be read.\n this.unreadReports = false\n this.leadSteer = new AbortController()\n this.leadSignal = context.signal\n return await host?.beforeStep?.(context) ?? { kind: 'proceed' as const }\n },\n onTurnEnd: async (context) => {\n await host?.onTurnEnd?.(context)\n if (this.options.autoLeadCoordination === false) return\n if (!context.canContinue) {\n // The turn is over and cannot be extended — a spent step budget, an\n // error, a stop. A report that arrived during it has no round left to\n // be read in, and the run would end with the synthesis unwritten, so\n // one more turn is scheduled for when the lead goes idle.\n if (this.unreadReports) {\n this.unreadReports = false\n try { this.team.wake(this.leadName) } catch { /* team disposed */ }\n }\n return\n }\n // Pending counts as busy. A worker held behind `dependsOn` has not\n // started, but it WILL run and report, and a lead that concluded while\n // its dependency chain was still queued answers from work that never\n // reached it.\n const outstanding = [...this.workerRuntimes.values()]\n .filter(runtime => runtime.status === 'running' || runtime.status === 'pending')\n if (outstanding.length === 0) return\n // WAIT for news before spending another model call.\n //\n // Re-prompting immediately is a spin: measured on a real run, a lead\n // with slow researchers answered \"still waiting\" twelve times in half a\n // second and had no budget left when the results finally arrived. Codex\n // has the parent block inside `wait_agent` until a mailbox update\n // arrives or a deadline passes; the DeepSeek harness starts the next\n // round only when there is something to start it for. This is the same\n // shape from inside the hook: the turn stays open, costing nothing,\n // until a worker reports or the wait expires.\n await this.awaitWorkerNews(outstanding)\n const busy = [...this.workerRuntimes.values()]\n .filter(runtime => runtime.status === 'running' || runtime.status === 'pending')\n .map(runtime => runtime.request.name)\n if (busy.length === 0) {\n this.lead.inject(createUserMessage({\n source: { kind: 'app', producer: 'managed-team' },\n content: [{ type: 'text', text: 'All outstanding managed workers have settled. Their statuses and retained results are available through list_agents.' }],\n }))\n return\n }\n this.lead.inject(createUserMessage({\n source: { kind: 'app', producer: 'managed-team' },\n content: [{ type: 'text', text: `Outstanding managed workers: ${busy.join(', ')}. `\n + 'Their current lifecycle status is available through list_agents; wait_agents is bounded by its timeout.' }],\n }))\n },\n }\n }\n\n /** Run the lead. It decides whether and how many workers to create. */\n run(input: AgentInput, invocation: AgentInvocationOptions = {}): Promise<AgentResponse> {\n this.lifecycle.signal.throwIfAborted()\n return this.lead.run(input, invocation)\n }\n\n /**\n * Add a message to the lead's context, and make sure something reads it.\n *\n * Injection alone is enough only while the lead is mid-turn: its next model\n * round rebuilds the request from history and picks the message up. Once the\n * lead has answered and is only waiting on its workers, an injected message\n * sits in history with nothing scheduled to read it — which is what happened\n * to a user who typed a correction while the researchers were still running\n * and never got an answer to it. Idle, the lead is scheduled one turn.\n * @param text - What the user said.\n * @returns True; the message is always accepted.\n */\n steer(text: string): boolean {\n this.lifecycle.signal.throwIfAborted()\n this.lead.inject(text)\n this.leadSteer.abort()\n // Ends a wait the lead is parked in, so the correction is read now rather\n // than after its wait budget expires.\n try { this.team.notifySteer(this.leadName) } catch { /* team disposed */ }\n if (!this.lead.isRunning) {\n try { this.team.wake(this.leadName) } catch { /* team disposed */ }\n }\n return true\n }\n\n /** Host-side equivalent of the model's spawn_agent tool. */\n /**\n * Create a worker and start it, WITHOUT waiting for it.\n *\n * Returns as soon as the worker is running. Use {@link awaitWorker} for its\n * result, {@link workers} for its status, or let the worker's completion\n * notification reach the lead on its own.\n * @param request - Task, and optionally a name and a specialty.\n * @param signal - Cancels the setup, not the worker's run.\n * @returns The worker, in its `running` state.\n */\n async spawn(\n request: ManagedAgentSpawnRequest,\n signal?: AbortSignal,\n ): Promise<ManagedAgentWorker> {\n this.lifecycle.signal.throwIfAborted()\n signal?.throwIfAborted()\n const resolved: ResolvedManagedAgentSpawnRequest = {\n name: memberName(request.name ?? this.nextWorkerName()),\n task: boundedString(request.task, 'worker task', this.maxTaskBytes),\n ...(request.specialty === undefined\n ? {}\n : { specialty: boundedString(request.specialty, 'worker specialty', this.maxSpecialtyBytes) }),\n context: spawnContext(request.context ?? this.options.defaultSpawnContext ?? 'fresh'),\n ...(request.role === undefined ? {} : { role: this.requireRole(request.role) }),\n dependsOn: this.resolveDependencies(request.dependsOn ?? []),\n writes: [...new Set((request.writes ?? []).map(normalizeWriteScope))],\n }\n Object.freeze(resolved.dependsOn)\n Object.freeze(resolved.writes)\n Object.freeze(resolved)\n const dependencies = resolved.dependsOn.map(name => this.workerRuntimes.get(name)!)\n if (this.workerRuntimes.size + this.preparing.size >= this.maxWorkers) {\n throw new Error(`managed agent team reached its ${this.maxWorkers}-worker limit`)\n }\n if (this.preparing.has(resolved.name) || this.workerRuntimes.has(resolved.name)\n || this.team.members().some(member => member.name === resolved.name)) {\n throw new Error(`managed worker '${resolved.name}' already exists`)\n }\n\n let markPrepared!: () => void\n const prepared = new Promise<void>(resolve => { markPrepared = resolve })\n this.preparing.set(resolved.name, { request: resolved, dependencies, settled: prepared })\n let runtime: WorkerRuntime | undefined\n try {\n const warnings = this.checkWriteScopes(resolved, dependencies)\n const operationSignal = combineSignals(signal, this.lifecycle.signal, AbortSignal.timeout(this.spawnTimeoutMs))\n const definition = await abortable(this.workerDefinition(resolved), operationSignal)\n operationSignal.throwIfAborted()\n const scopedSessionOptions = this.options.workerSessionOptionsFactory === undefined\n ? undefined\n : await abortable(Promise.resolve(this.options.workerSessionOptionsFactory(resolved)), operationSignal)\n operationSignal.throwIfAborted()\n const sessionOptions = { ...this.options.workerSessionOptions, ...scopedSessionOptions }\n const workerTeamTools = this.options.workerTeamTools ?? 'reporting'\n const session = definition.createSession({\n ...sessionOptions,\n ...(dependencies.length === 0 ? {} : { tools: mergeTools(sessionOptions.tools, [this.dependencyReadTool(dependencies)]) }),\n ...(resolved.context === 'fork' ? { history: this.forkLeadHistory(sessionOptions.historyLimits) } : {}),\n registry: this.options.registry,\n team: {\n team: this.team,\n name: resolved.name,\n role: 'peer',\n tools: workerTeamTools,\n instructions: [\n `You are managed worker '${resolved.name}'; lead: '${this.leadName}'.`,\n 'Return only the caller-requested result in the caller’s format; include explanation only when requested.',\n 'Your terminal result is delivered automatically.',\n ...(workerTeamTools === false ? [] : ['send_message is context, not a substitute result; it cannot target yourself.']),\n ].join(' '),\n ...(resolved.specialty === undefined ? {} : { description: resolved.specialty }),\n },\n })\n const controller = new AbortController()\n let markSettled!: () => void\n runtime = {\n request: resolved,\n session,\n dependencies,\n starting: false,\n settledComplete: false,\n closeTask: undefined,\n status: 'pending',\n leadDriven: this.lead.isRunning,\n closing: false,\n deadline: undefined,\n controller,\n settled: new Promise<void>((resolve) => { markSettled = resolve }),\n markSettled: () => { recordEvidence(runtime!); runtime!.settledComplete = true; markSettled() },\n start: undefined,\n warnings,\n result: undefined,\n error: undefined,\n evidence: { status: 'pending', result: undefined, error: undefined },\n }\n this.workerRuntimes.set(resolved.name, runtime)\n this.preparing.delete(resolved.name)\n\n const deliverySignal = combineSignals(operationSignal, controller.signal)\n await abortable(this.team.sendMessage({\n from: this.leadName,\n target: resolved.name,\n message: resolved.task,\n delivery: 'quiet',\n signal: deliverySignal,\n }), deliverySignal)\n deliverySignal.throwIfAborted()\n if (definition.memory.autoCaptureObjective) {\n session.memory.captureOriginalObjective(createTextMessage(resolved.task))\n }\n\n if (dependencies.length > 0 && !this.dependenciesSettled(dependencies, resolved.writes)) {\n // Held, not started. The promise handed to the team is what makes the\n // wait honest: without it `wait_agents` asks an idle session whether it\n // is finished, is told yes, and the lead reads a worker that never ran\n // as one that had nothing to report.\n const held = new Promise<void>((resolve) => { runtime!.start = resolve })\n this.team.markPending(resolved.name, held)\n for (const dependency of dependencies) {\n if (SETTLED_WORKER_STATUS.has(dependency.status) && this.workerHasWork(dependency)) {\n // A completed worker may be running a team-scheduled follow-up.\n // Its original managed watcher has already finished.\n void this.team.whenIdle(dependency.request.name).then(() => this.releaseDependents(dependency)).catch(() => {})\n }\n }\n return this.workerView(runtime)\n }\n await this.startWorker(runtime, deliverySignal)\n return this.workerView(runtime)\n } catch (error: unknown) {\n if (runtime !== undefined && this.workerRuntimes.get(resolved.name) === runtime && !runtime.closing) {\n runtime.status = 'failed'\n runtime.error = errorMessage(error)\n runtime.start = undefined\n runtime.dependencies = []\n try { this.team.markPending(resolved.name, undefined) } catch { /* team already disposed */ }\n runtime.markSettled()\n this.workerRuntimes.delete(resolved.name)\n try { this.team.detach(resolved.name) } catch { /* registration already removed */ }\n await this.releaseDependents(runtime)\n }\n throw error\n } finally {\n this.preparing.delete(resolved.name)\n markPrepared()\n }\n }\n\n /**\n * Put a worker on the model, at last.\n *\n * Separate from `spawn` because a worker with dependencies is created now and\n * started later; the two used to be the same moment.\n */\n private beginWorker(runtime: WorkerRuntime): void {\n const name = runtime.request.name\n if (runtime.status !== 'pending' || runtime.closing || this.lifecycle.signal.aborted\n || this.workerRuntimes.get(name) !== runtime) return\n runtime.start?.()\n runtime.start = undefined\n this.team.markPending(name, undefined)\n // Closed while it was held: there is nothing left to start, and starting it\n // anyway would resurrect a worker the lead had already let go.\n runtime.status = 'running'\n\n // Started, NOT awaited. `runPending` begins the run eagerly and\n // synchronously, so by the time this returns the worker is genuinely\n // going; the promise is simply left for `followWorker` to watch.\n // Awaiting it in `spawn` is what blinded the lead: parked inside its own\n // tool call it could not read the worker's messages, could not spawn\n // anything else, and could not be told that the worker had gone quiet.\n //\n // `runPending` rather than `streamPending`, and that is load-bearing:\n // `onEvent` is delivered by the consumer `runPending` wraps around the\n // handle, so a bare `streamPending` starts the run and reports NOTHING.\n // Every worker event is lost with it — including the approval requests a\n // worker parks on, which leaves it waiting for an answer nobody was ever\n // shown, and the run hangs.\n const deadline = AbortSignal.timeout(this.workerTimeoutMs)\n runtime.deadline = deadline\n const running = runtime.session.runPending({\n signal: combineSignals(runtime.controller.signal, deadline),\n ...(this.options.onWorkerEvent === undefined\n ? {}\n : { onEvent: (event: AgentRunEvent) => this.observeWorkerEvent(name, event) }),\n })\n void this.followWorker(runtime, running)\n }\n\n /** One handoff path for both already-settled and asynchronously released dependencies. */\n private async startWorker(runtime: WorkerRuntime, setupSignal?: AbortSignal): Promise<void> {\n if (runtime.starting || runtime.status !== 'pending' || runtime.closing || this.lifecycle.signal.aborted) return\n runtime.starting = true\n try {\n const report = this.dependencyReport(runtime.dependencies)\n if (report !== undefined) {\n const signal = combineSignals(setupSignal, runtime.controller.signal, this.lifecycle.signal,\n AbortSignal.timeout(this.spawnTimeoutMs))\n await abortable(this.team.sendMessage({ from: this.leadName, target: runtime.request.name,\n message: report, delivery: 'quiet', signal }), signal)\n signal.throwIfAborted()\n }\n this.beginWorker(runtime)\n } catch (error: unknown) {\n // Missing required context is a visible failure, never a successful task\n // dispatched with the dependencies silently omitted.\n if (!runtime.closing && !this.lifecycle.signal.aborted) {\n runtime.status = 'failed'\n runtime.error = `dependency handoff failed: ${errorMessage(error)}`\n recordEvidence(runtime)\n runtime.start?.()\n runtime.start = undefined\n try {\n this.team.markPending(runtime.request.name, undefined)\n this.team.recordOutcome(runtime.request.name, { kind: 'failed', message: runtime.error })\n } catch { /* shared team already disposed */ }\n await this.notifyLead(runtime, `failed: ${runtime.error}`)\n runtime.markSettled()\n await this.releaseDependents(runtime)\n }\n } finally {\n // Retain producer facts only while queued/preparing. Completed ancestors\n // must not keep entire sessions alive through an arbitrarily long chain.\n runtime.dependencies = []\n }\n }\n\n /**\n * The `role` parameter, when the host declared any roles.\n *\n * Each role's purpose and precondition go in the description, which is where\n * Codex puts its role registry too: the lead is choosing a role at the\n * moment it reads this, so this is the only place the guidance can arrive in\n * time to change the choice.\n * @returns A one-property object to spread, or nothing.\n */\n private roleSchema(): Record<string, unknown> {\n if (this.roles.size === 0) return {}\n const lines = [...this.roles.values()].map(role =>\n `- ${role.name}: ${role.description}`\n + (role.whenToUse === undefined ? '' : ` Use when: ${role.whenToUse}`))\n return {\n role: {\n type: 'string',\n enum: [...this.roles.keys()],\n description: `Which kind of worker this is.\\n${lines.join('\\n')}`,\n },\n }\n }\n\n /** Resolve a declared role name, or say which ones exist. */\n private requireRole(name: unknown): string {\n const value = nonEmpty(name, 'worker role')\n if (this.roles.size === 0) {\n throw new Error('this managed team declares no roles, so spawn_agent takes no role')\n }\n if (!this.roles.has(value)) {\n throw new Error(\n `unknown worker role '${value}'; declared roles are ${[...this.roles.keys()].join(', ')}`,\n )\n }\n return value\n }\n\n /**\n * Check the named dependencies and return them deduplicated.\n *\n * A dependency can only name a worker that already exists, and a new worker\n * is not yet nameable by anything, so the graph cannot contain a cycle by\n * construction — no cycle check is needed here, and a `dependsOn` that could\n * name a future worker would need one.\n */\n private resolveDependencies(names: readonly string[]): readonly string[] {\n return [...new Set(names.map((name) => {\n const address = memberName(name)\n if (!this.workerRuntimes.has(address)) {\n throw new Error(\n `unknown dependency '${address}'; a worker can only depend on one that already exists`,\n )\n }\n return address\n }))]\n }\n\n /**\n * Judge a new worker's write scopes against the ones already in flight.\n *\n * Only workers that could run AT THE SAME TIME conflict. One that this\n * worker depends on, directly or through others, writes its files before\n * this one begins, so sharing a scope with it is ordinary sequential work —\n * and is in fact the fix the refusal points at.\n * @param request - The resolved spawn request.\n * @returns Warnings to record; throws instead under the `reject` policy.\n */\n private checkWriteScopes(request: ResolvedManagedAgentSpawnRequest, dependencies: readonly WorkerRuntime[]): readonly string[] {\n const policy = this.options.writeScopePolicy ?? 'reject'\n if (policy === 'off' || request.writes.length === 0) return []\n const ancestors = this.ancestorsOf(dependencies)\n const found: string[] = []\n const runningRoster = new Set(this.team.members().filter(member => member.status === 'running').map(member => member.conversationId))\n const others = [\n ...[...this.workerRuntimes.values()].filter(other => other.status === 'pending' || other.status === 'running' || this.workerHasWork(other, runningRoster))\n .filter(other => !ancestors.has(other)),\n ...this.drainingWrites,\n ...[...this.preparing.values()].filter(other => other.request.name !== request.name),\n ]\n for (const other of others) {\n const clash = request.writes.filter(mine =>\n other.request.writes.some(theirs => scopesOverlap(mine, theirs)))\n if (clash.length === 0) continue\n const detail = `'${other.request.name}' also writes ${clash.join(', ')}`\n if (policy === 'reject') {\n throw new Error(\n `worker '${request.name}' would write files another running worker writes: ${detail}.`\n + ` Add '${other.request.name}' to dependsOn so it runs after, or narrow the scopes`\n // Observed in a real run: four read-only researchers each declared the\n // same placeholder scope and collided over a file none of them would\n // ever write. The refusal used to offer only dependsOn and narrowing,\n // which sends a worker that writes nothing looking for a better fake\n // path instead of dropping the field.\n + ' — or omit writes entirely if this worker only reads.',\n )\n }\n found.push(detail)\n }\n return found\n }\n\n /**\n * Say what actually happened to a worker, in words the lead can act on.\n *\n * A raw abort reads \"The operation was aborted due to timeout\", which tells\n * the lead nothing about WHOSE timeout or whether re-delegating would help.\n * Codex reports a status the parent can branch on; the DeepSeek harness\n * records a blocker code with an explanation. This is the same idea at the\n * size this harness needs.\n * @param error - Whatever ended the run.\n * @returns The explanation to record and report.\n */\n private describeWorkerFailure(error: unknown, runtime: WorkerRuntime | undefined): string {\n if (runtime?.deadline?.aborted === true) return this.deadlineFailure()\n const name = (error as { name?: unknown } | null)?.name\n if (name === 'TimeoutError') return this.deadlineFailure()\n if (name === 'AbortError') return 'its work was cancelled before it finished'\n return errorMessage(error)\n }\n\n /** The one explanation an expired worker deadline deserves. */\n private deadlineFailure(): string {\n return `it ran past its ${String(this.workerTimeoutMs)}ms deadline without finishing.`\n + ' Narrow the task, or split it, before delegating it again'\n }\n\n /**\n * Block until a worker reports, or the hold deadline passes.\n *\n * Bounded on purpose. An unbounded wait would hand the whole run's liveness to\n * the slowest worker and, since this runs inside a turn hook, would be cut off\n * by the hook timeout rather than by anything that understands the work. When\n * it expires the lead gets its turn back and decides for itself — wait again\n * with `wait_agents`, close one, or answer with what it has.\n * @param outstanding - Workers that have not settled.\n */\n private async awaitWorkerNews(outstanding: readonly WorkerRuntime[]): Promise<void> {\n let removeSteer: (() => void) | undefined\n let timer: ReturnType<typeof setTimeout> | undefined\n const deadline = new Promise<void>((resolve) => {\n timer = setTimeout(resolve, this.holdWaitMs)\n // A timer must never be the reason a process stays alive. Node exposes\n // `unref`; a browser timer has no such handle and needs none.\n ;(timer as unknown as { unref?: () => void }).unref?.()\n })\n try {\n const steered = this.leadSteer.signal\n const correction = new Promise<void>(resolve => {\n if (steered.aborted) resolve()\n else steered.addEventListener('abort', resolveSteer, { once: true })\n function resolveSteer() { resolve() }\n removeSteer = () => steered.removeEventListener('abort', resolveSteer)\n })\n await abortable(Promise.race([...outstanding.map(runtime => runtime.settled), deadline, correction]),\n combineSignals(this.lifecycle.signal, this.leadSignal))\n } finally {\n if (timer !== undefined) clearTimeout(timer)\n removeSteer?.()\n }\n }\n\n /** Every worker reachable through `dependsOn`, transitively. */\n private ancestorsOf(workers: readonly WorkerRuntime[], seen = new Set<WorkerRuntime>()): Set<WorkerRuntime> {\n for (const runtime of workers) {\n if (seen.has(runtime)) continue\n seen.add(runtime)\n this.ancestorsOf(runtime.dependencies, seen)\n }\n return seen\n }\n\n /** Includes team-owned follow-ups queued between session runs. */\n private workerHasWork(runtime: WorkerRuntime, runningRoster?: ReadonlySet<string | undefined>): boolean {\n return runtime.session.isRunning || this.drainingWrites.has(runtime)\n || (runningRoster === undefined\n ? this.team.members().some(member => member.name === runtime.request.name\n && member.conversationId === runtime.session.conversationId && member.status === 'running')\n : runningRoster.has(runtime.session.conversationId))\n }\n\n /** Whether every named worker has reached a final state without conflicting active writes. */\n private dependenciesSettled(workers: readonly WorkerRuntime[], writes: readonly string[] = []): boolean {\n return workers.every(runtime => SETTLED_WORKER_STATUS.has(runtime.status)\n && !((this.options.writeScopePolicy ?? 'reject') === 'reject'\n && writes.some(mine => runtime.request.writes.some(theirs => scopesOverlap(mine, theirs)))\n && this.workerHasWork(runtime)))\n }\n\n /**\n * Start whatever was waiting on the worker that just settled.\n *\n * Dependents are released when their dependencies SETTLE, not when they\n * succeed. Requiring success would let one failed worker strand every step\n * planned after it, and a plan that stalls silently is worse than one whose\n * later stages are told the earlier ones broke — which is exactly what they\n * are told: each dependent starts with what its dependencies produced.\n */\n private async releaseDependents(finished: WorkerRuntime): Promise<void> {\n if (this.lifecycle.signal.aborted) return\n const ready = [...this.workerRuntimes.values()].filter(runtime =>\n runtime.status === 'pending'\n && !runtime.closing\n && runtime.dependencies.includes(finished)\n && this.dependenciesSettled(runtime.dependencies, runtime.request.writes))\n for (const runtime of ready) {\n await this.startWorker(runtime)\n }\n }\n\n /** What the dependencies produced, as context for a dependent about to start. */\n private dependencyReport(workers: readonly WorkerRuntime[]): string | undefined {\n let hasTruncatedResult = false\n const lines = workers.map((runtime) => {\n const name = runtime.request.name\n if (runtime.error !== undefined) {\n const partial = runtime.result?.text\n const payload = partial ? truncate(partial, this.maxDependencyReportBytes) : undefined\n hasTruncatedResult ||= payload !== undefined && payload !== partial\n return `- worker address '${name}' FAILED: ${runtime.error}`\n + (partial ? '' : '\\nResult payload: absent. No result data was returned.')\n + (payload === undefined ? '' : `\\nPartial findings (not a completed task): ${payload}`)\n }\n if (runtime.result === undefined && runtime.status === 'closed') return `- worker address '${name}': closed before reporting. Result payload: absent. No result data was returned.`\n const text = runtime.result?.text ?? ''\n const payload = truncate(text, this.maxDependencyReportBytes)\n hasTruncatedResult ||= payload !== text\n return `- worker address '${name}' finished. ${payload === text ? 'Full' : 'Truncated'} result payload:\\n${payload}`\n })\n if (lines.length === 0) return undefined\n return [\n 'Dependency result data: worker addresses are routing metadata. Preserve source identifiers supplied in payloads; an absent payload supplies no evidence identifiers.',\n ...lines,\n ...(hasTruncatedResult ? ['Read truncated results with read_dependency_result, the original worker address and nextOffset.'] : []),\n ].join('\\n')\n }\n\n /** Only this worker's commissioned producer instances are readable, including after closure. */\n private dependencyReadTool(dependencies: readonly WorkerRuntime[]): ToolDefinition {\n const scope = new Map(dependencies.map(runtime => [runtime.request.name, runtime.evidence]))\n return defineTool({\n name: 'read_dependency_result',\n description: 'Read a bounded page from an original dependency result, including after closure. Full handoffs already contain the same result. Use nextOffset until null; partial/failed results are not completed work.',\n parameters: { type: 'object', properties: { name: { type: 'string' }, offset: { type: 'integer', minimum: 0 } }, required: ['name'], additionalProperties: false },\n parse(raw: unknown) {\n if (typeof raw !== 'object' || raw === null) throw new TypeError('dependency name and offset required')\n const name = Reflect.get(raw, 'name'), offset = Reflect.get(raw, 'offset') ?? 0\n if (typeof name !== 'string' || !Number.isSafeInteger(offset) || offset < 0) throw new TypeError('invalid dependency name or offset')\n return { name, offset: offset as number }\n },\n execute: ({ name, offset }) => {\n const producer = scope.get(name)\n if (producer === undefined) throw new Error('this worker was not commissioned against that dependency')\n const text = producer.result?.text ?? ''\n if (offset > text.length || (offset > 0 && /[\\uDC00-\\uDFFF]/.test(text[offset]!))) throw new RangeError('offset must be a valid character boundary')\n // Offsets count UTF-16 code units, returned pages stay within the byte cap.\n const page = prefixWithinBytes(text.slice(offset), this.maxDependencyReportBytes)\n const next = offset + page.length\n return { name, status: producer.status, succeeded: producer.result?.succeeded ?? false,\n ...(producer.error === undefined ? {} : { error: producer.error }), text: page,\n nextOffset: next < text.length ? next : null }\n },\n isConcurrencySafe: () => true,\n })\n }\n\n /**\n * Watch a detached worker run to its end and report it.\n *\n * Never rejects: the run has no awaiting caller, so a throw here would be an\n * unhandled rejection. Failures are recorded on the runtime and told to the\n * lead instead, which is the same shape `AgentTeam.runWakeLoop` uses for the\n * other kind of un-awaited member run.\n */\n private async followWorker(\n runtime: WorkerRuntime,\n running: Promise<AgentResponse>,\n ): Promise<void> {\n const name = runtime.request.name\n try {\n const response = await running\n if (runtime.status !== 'closed' && !runtime.closing) {\n // A run that RESOLVES has not necessarily succeeded: a model call that\n // failed ends the turn with an error reason and an empty answer. Read\n // as a success it became \"Worker 'x' finished:\" with nothing after the\n // colon — the lead told a sector was done by a worker that never got\n // an answer out of the model, which is worse than being told nothing.\n const failure = runtime.deadline?.aborted === true\n ? this.deadlineFailure()\n : failureOf(response, this.options.requireWorkerText === true)\n if (failure !== undefined) {\n runtime.status = 'failed'\n runtime.error = failure\n // A failed final request must not erase evidence already returned.\n // Preserve partial output, but never report it as successful work.\n if (response.text.trim() !== '') {\n runtime.result = Object.freeze({\n worker: name,\n agentId: runtime.session.definition.id,\n conversationId: runtime.session.conversationId,\n text: response.text,\n succeeded: false,\n })\n }\n recordEvidence(runtime)\n this.team.recordOutcome(name, { kind: 'failed', message: failure })\n await this.notifyLead(runtime, `failed: ${failure}`\n + (runtime.result === undefined ? '' : `\\nPartial findings (not a completed task): ${runtime.result.text}`))\n } else {\n runtime.status = 'completed'\n runtime.result = Object.freeze({\n worker: name,\n agentId: runtime.session.definition.id,\n conversationId: runtime.session.conversationId,\n text: response.text,\n succeeded: response.outcome.completed,\n })\n recordEvidence(runtime)\n this.team.recordOutcome(name, { kind: 'completed', text: response.text })\n await this.notifyLead(runtime, `finished: ${response.text}`)\n }\n }\n } catch (error: unknown) {\n // A close is not a failure. Reporting the abort it caused would tell the\n // lead its own decision went wrong, and — once a report can wake an idle\n // lead — would start a turn about a worker it deliberately abandoned.\n if (runtime.status !== 'closed' && !runtime.closing) {\n runtime.status = 'failed'\n runtime.error = this.describeWorkerFailure(error, runtime)\n recordEvidence(runtime)\n try { this.team.recordOutcome(name, { kind: 'failed', message: runtime.error }) } catch { /* shared team disposed */ }\n await this.notifyLead(runtime, `failed: ${runtime.error}`)\n }\n } finally {\n runtime.markSettled()\n // Whatever ended this worker — success, failure, or a close — the work\n // planned after it is no longer waiting on anything.\n await this.releaseDependents(runtime)\n }\n }\n\n /**\n * Tell the lead what one of its workers did.\n *\n * Quiet WHILE THE LEAD IS STILL IN ITS TURN: the report appends to history\n * and the next model round rebuilds its request from history, so the lead\n * reads it without an extra turn being scheduled. Holding that turn open is\n * {@link leadHooks}'s job.\n *\n * A wake-up once the lead has gone idle, because then nothing else will ever\n * read the report. The hold cannot cover every case — a turn that ended on\n * its step budget, or on an error, is not eligible to continue, and a worker\n * that outlives the run reports into a conversation with no turn left. That\n * is the failure this exists for: the transcript ends on a worker's own\n * output, and the synthesis the lead was there to write never happens. One\n * more turn is the point, not a duplicate answer.\n */\n private async notifyLead(runtime: WorkerRuntime, summary: string): Promise<void> {\n const worker = runtime.request.name\n if (runtime.closing || this.lifecycle.signal.aborted || this.workerRuntimes.get(worker) !== runtime) return\n const delivery = this.deliveryFor(worker)\n // A quiet report is a bet that the lead's next model round will read it.\n // Cleared by `beforeStep`, which is that round; still set at the end of a\n // turn that cannot continue, it means the bet lost and nobody ever will.\n if (delivery === 'quiet') this.unreadReports = true\n try {\n const signal = combineSignals(runtime.controller.signal, this.lifecycle.signal,\n AbortSignal.timeout(this.spawnTimeoutMs))\n await abortable(this.team.sendMessage(managedTeamNoticeRequest({\n from: worker,\n target: this.leadName,\n message: `Worker '${worker}' ${truncate(summary, Math.min(this.maxDependencyReportBytes, Math.max(64, Math.floor(this.team.messageByteLimit / 4))))}`,\n delivery,\n signal,\n })), signal)\n } catch {\n // The lead may already be gone, or the team disposed. A worker's report\n // is not worth failing anything else over; `workers()` still has it.\n }\n }\n\n /**\n * Quiet into an open turn, a wake-up into an idle conversation.\n * @param worker - The worker whose report is being delivered.\n * @returns The delivery the report needs to actually be read.\n */\n private deliveryFor(worker: string): 'quiet' | 'wakeup' {\n // Mid-turn: the next model round rebuilds its request from history, so the\n // report is read without scheduling anything.\n if (this.options.autoLeadCoordination === false || this.lead.isRunning) return 'quiet'\n // Idle, and the host is driving: waking would start a turn it did not ask\n // for, and it can read the result from `workers()` whenever it likes.\n if (this.workerRuntimes.get(worker)?.leadDriven !== true) return 'quiet'\n return 'wakeup'\n }\n\n /** Set when a worker report was delivered quietly and no round has read it. */\n private unreadReports = false\n private leadSteer = new AbortController()\n private leadSignal: AbortSignal | undefined\n\n /**\n * Wait until no worker is outstanding and the lead has nothing left to do.\n *\n * The roster cannot answer this on its own. A worker's last event fires\n * before its run resolves, and its completion report — the thing that wakes\n * the lead — is delivered after that. For the moment in between, every member\n * looks idle: a caller watching the roster sees a finished team and stops\n * listening, exactly as the synthesis is about to be written. Waiting here\n * covers that gap, because a worker's `settled` resolves only once its report\n * has been delivered.\n * @param signal - Gives up waiting; the work itself is not cancelled.\n */\n async whenQuiet(signal?: AbortSignal): Promise<void> {\n for (;;) {\n signal?.throwIfAborted()\n const outstanding = [...this.workerRuntimes.values()]\n .filter(runtime => !runtime.settledComplete)\n const preparing = [...this.preparing.values()].map(prepared => prepared.settled)\n if (outstanding.length + preparing.length > 0) {\n await abortable(Promise.all([...outstanding.map(runtime => runtime.settled), ...preparing]), signal)\n }\n await this.team.whenIdle(this.leadName, signal)\n const busy = this.preparing.size > 0 || [...this.workerRuntimes.values()]\n .some(runtime => !runtime.settledComplete)\n if (!busy) return\n }\n }\n\n /** Current detached worker lifecycle view. */\n workers(): readonly ManagedAgentWorker[] {\n return Object.freeze([...this.workerRuntimes.values()].map(runtime => this.workerView(runtime)))\n }\n\n private workerView(runtime: WorkerRuntime): ManagedAgentWorker {\n return Object.freeze({\n name: runtime.request.name,\n agentId: runtime.session.definition.id,\n conversationId: runtime.session.conversationId,\n task: runtime.request.task,\n status: runtime.status,\n context: runtime.request.context,\n dependsOn: runtime.request.dependsOn,\n writes: runtime.request.writes,\n ...(runtime.request.role === undefined ? {} : { role: runtime.request.role }),\n ...(runtime.warnings.length === 0 ? {} : { warnings: runtime.warnings }),\n ...(runtime.request.specialty === undefined ? {} : { specialty: runtime.request.specialty }),\n ...(runtime.result === undefined ? {} : { result: runtime.result }),\n ...(runtime.error === undefined ? {} : { error: runtime.error }),\n })\n }\n\n /**\n * Wait for one worker to finish, for at most `timeoutMs`.\n *\n * Bounded on purpose. An unbounded wait is how a host loses the ability to\n * tell a slow worker from a stuck one; a caller that gets `undefined` back\n * still holds every other option.\n * @param name - Worker address.\n * @param options - Budget, default {@link DEFAULT_WAIT_TIMEOUT_MS}, and a signal.\n * @returns Its result, or undefined if it had not finished in time.\n */\n async awaitWorker(\n name: string,\n options: { readonly timeoutMs?: number; readonly signal?: AbortSignal } = {},\n ): Promise<ManagedAgentWorkerResult | undefined> {\n const address = memberName(name)\n const runtime = this.workerRuntimes.get(address)\n if (runtime === undefined) throw new Error(`unknown managed worker '${address}'`)\n const budget = timeoutValue(options.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS)\n // The timer is cleared either way: a worker that finishes early must not\n // leave one pending, which in a long-lived host is a slow leak.\n let timer: ReturnType<typeof setTimeout> | undefined\n const deadline = new Promise<void>((resolve) => { timer = setTimeout(resolve, budget) })\n try {\n await abortable(Promise.race([runtime.settled, deadline]), options.signal)\n } finally {\n clearTimeout(timer)\n }\n options.signal?.throwIfAborted()\n return runtime.result\n }\n\n /**\n * Stop a worker and give up its slot.\n *\n * This is the stopping point a delegated agent otherwise lacks. A worker that\n * has already finished is still occupying a `maxWorkers` slot, so closing is\n * how a lead makes room for the next one.\n * @param name - Worker address.\n * @param reason - Cancellation reason for a worker still running.\n * @returns The status it held before being closed.\n */\n async closeWorker(\n name: string,\n reason: unknown = new Error('managed worker closed'),\n ): Promise<ManagedAgentWorkerStatus> {\n const address = memberName(name)\n const runtime = this.workerRuntimes.get(address)\n if (runtime === undefined) throw new Error(`unknown managed worker '${address}'`)\n runtime.closing = true\n runtime.closeTask ??= Promise.resolve().then(() => this.closeRuntime(runtime, reason))\n return runtime.closeTask\n }\n\n private async closeRuntime(runtime: WorkerRuntime, reason: unknown): Promise<ManagedAgentWorkerStatus> {\n const address = runtime.request.name\n const previous = runtime.status\n runtime.closing = true\n runtime.controller.abort(reason)\n const closeDeadline = AbortSignal.timeout(this.closeTimeoutMs)\n // The controller only governs the run THIS harness started. A worker the\n // lead reached with followup_task, or any wake-up delivery, is running\n // under the team's own scheduler, and aborting the harness controller does\n // nothing to it: observed in a real run, a closed worker kept calling the\n // model for another fourteen seconds and submitted its result after the\n // lead had already answered, so the conversation ended on the worker's\n // output instead of the lead's synthesis.\n try {\n await abortable(this.team.cancel(address, reason), closeDeadline)\n } catch {\n // A cancellation that times out must not wedge the close: the slot is\n // freed either way, exactly as it is for a run that ignores its signal.\n }\n if (previous === 'pending') {\n // Never started, so there is no run to wait for — and `settled` would\n // never resolve on its own, because nothing is going to end.\n runtime.status = 'closed'\n runtime.start = undefined\n this.team.markPending(address, undefined)\n runtime.markSettled()\n } else {\n // Waited for, but not indefinitely, and a worker that ignores its signal\n // does not get to wedge the harness: the slot is freed either way. The\n // wait is what usually lets `detach` succeed, since it refuses a member\n // whose session is still running.\n try { await abortable(runtime.settled, closeDeadline) } catch { /* non-cooperative run remains bounded */ }\n runtime.status = 'closed'\n runtime.markSettled()\n }\n recordEvidence(runtime)\n if (this.workerHasWork(runtime)) {\n if (runtime.request.writes.length > 0) this.drainingWrites.add(runtime)\n // Closing frees the managed slot, but cannot establish that an active\n // session stopped writing. Release only its write claim at actual idle.\n void this.team.whenIdle(address).then(async () => {\n this.drainingWrites.delete(runtime)\n try {\n if (this.team.members().some(member => member.name === address && member.conversationId === runtime.session.conversationId)) {\n this.team.detach(address)\n }\n } catch { /* roster already removed or disposed */ }\n await this.releaseDependents(runtime)\n }).catch(() => { /* team lifecycle may already be disposed */ })\n }\n if (this.workerRuntimes.get(address) === runtime) {\n this.workerRuntimes.delete(address)\n try { this.team.detach(address) } catch { /* already gone, or the team is disposed */ }\n }\n // Closing is a settlement too: work planned after this worker must not be\n // left waiting on one the lead has abandoned.\n runtime.dependencies = []\n await this.releaseDependents(runtime)\n return previous\n }\n\n /**\n * Stop every worker this harness started.\n *\n * Workers outlive the lead's turn by design, so something has to end them:\n * without this a detached run would keep calling the model after the host had\n * moved on. Disposing the underlying `AgentTeam` is left to whoever owns it.\n * @param reason - Cancellation reason handed to each worker.\n */\n dispose(reason: unknown = new Error('managed agent team disposed')): Promise<void> {\n if (this.disposeTask !== undefined) return this.disposeTask\n this.lifecycle.abort(reason)\n const names = [...this.workerRuntimes.keys()]\n this.disposeTask = Promise.allSettled([\n ...[...this.preparing.values()].map(prepared => prepared.settled),\n ...names.map(name => this.closeWorker(name, reason)),\n ]).then(() => undefined)\n return this.disposeTask\n }\n\n /** Remove one idle generated worker from the harness and shared roster. */\n removeWorker(name: string): void {\n const address = memberName(name)\n const runtime = this.workerRuntimes.get(address)\n if (runtime === undefined) throw new Error(`unknown managed worker '${address}'`)\n if (runtime.status === 'pending' || runtime.status === 'running' || !runtime.settledComplete || runtime.session.isRunning) {\n throw new Error(`cannot remove running managed worker '${address}'`)\n }\n this.team.detach(address)\n this.workerRuntimes.delete(address)\n }\n\n private controlTools(): readonly ToolDefinition<any>[] {\n return Object.freeze([\n defineTool({\n name: 'spawn_agent',\n description: [\n 'Create a managed worker for the supplied task.',\n 'Returns a lifecycle view after setup; a dependent may still be pending.',\n 'Use list_agents for retained status/results and wait_agents for bounded waits.',\n 'dependsOn binds already registered producer instances; writes declares relative scheduling scopes under host policy.',\n ].join(' '),\n parameters: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Optional unique worker address; omitted generates worker_N.',\n },\n task: {\n type: 'string',\n description: 'Task and any output contract assigned to the worker.',\n },\n specialty: {\n type: 'string',\n description: 'Optional worker role or domain specialization.',\n },\n context: {\n type: 'string',\n enum: ['fresh', 'fork'],\n description: 'fresh starts from the task; fork also copies the completed lead conversation.',\n },\n dependsOn: {\n type: 'array',\n items: { type: 'string' },\n description: 'Names of workers that must finish before this one starts.'\n + ' The worker is created now and held until they do, then given what they'\n + ' produced. Register the producers first; a dependency cannot name a'\n + ' future or still-preparing worker. Failed producers also release dependents with failure status.',\n },\n writes: {\n type: 'array',\n items: { type: 'string' },\n description: 'Workspace-relative scheduling scopes. Overlaps are rejected, warned or allowed'\n + ' according to host writeScopePolicy. This is not filesystem authorization.'\n + ' Omit when no writes are declared; placeholder paths claim real scopes.',\n },\n ...this.roleSchema(),\n },\n required: ['task'],\n additionalProperties: false,\n },\n parse: parseSpawnTool,\n execute: async (request, context) => asJson(await this.spawn(request, context.signal)),\n // Seconds, not the worker's whole deadline: this call only starts the\n // worker now. Leaving it at workerTimeoutMs would let a stuck SETUP\n // hold the lead for ten minutes.\n timeoutMs: this.spawnTimeoutMs,\n isConcurrencySafe: () => true,\n }),\n defineTool({\n name: 'close_agent',\n budgetExempt: true,\n description: [\n 'Close a worker you no longer need and free its slot.',\n 'A finished worker still occupies one until closed, so close it once you have read its result.',\n 'A running or pending worker is kept alive by default so it can finish its final report.',\n this.options.allowModelWorkerCancellation === false\n ? 'The host requires worker reports: you cannot cancel unfinished workers. Wait for their result.'\n : 'Set cancelRunning: true only to deliberately abandon unfinished work and cancel it.',\n 'Returns the status it held before closing.',\n ].join(' '),\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Worker address returned by spawn_agent.' },\n cancelRunning: { type: 'boolean', description: 'Explicitly cancel an unfinished worker. Defaults to false.' },\n },\n required: ['name'],\n additionalProperties: false,\n },\n parse: parseCloseTool,\n execute: async ({ name, cancelRunning }) => {\n const runtime = this.workerRuntimes.get(name)\n if (runtime !== undefined && (!cancelRunning || this.options.allowModelWorkerCancellation === false)\n && (runtime.status === 'pending' || runtime.status === 'running' || runtime.session.isRunning)) {\n return asJson({\n worker: name, closed: false,\n status: runtime.status === 'pending' ? 'pending' : 'running',\n instruction: 'The worker has not finished its final report. Use wait_agents and read its completed result before closing.'\n + (this.options.allowModelWorkerCancellation === false ? ' Model cancellation is disabled by the host.'\n : ' To deliberately abandon this work, call close_agent with cancelRunning: true.'),\n })\n }\n return asJson({ worker: name, closed: true, previousStatus: await this.closeWorker(name) })\n },\n timeoutMs: this.workerTimeoutMs,\n }),\n ])\n }\n\n /**\n * Build the history a `fork` worker starts from.\n *\n * Limits come from the WORKER's session options, not the lead's: this is the\n * worker's own history from here on, and it is the worker's configured\n * ceiling that has to hold it.\n * @returns The lead's completed conversation as a fresh history.\n */\n private forkLeadHistory(limits: AgentSessionOptions['historyLimits']): History {\n const entries = completedHistoryPrefix(this.lead.snapshot().history)\n return History.fromSnapshot(\n { version: 1, entries },\n limits ?? {},\n )\n }\n\n private async workerDefinition(\n request: ResolvedManagedAgentSpawnRequest,\n ): Promise<DefinedAgent> {\n if (this.options.workerFactory !== undefined) return this.options.workerFactory(request)\n const template = this.options.workerTemplate ?? this.options.lead\n const role = request.role === undefined ? undefined : this.roles.get(request.role)\n const roleText = role === undefined\n ? ''\n : ` You are the '${role.name}' worker. ${role.instructions ?? role.description}`\n const specialty = request.specialty === undefined\n ? ''\n : ` Your specialization is: ${request.specialty}.`\n return cloneAgent(template, {\n id: request.name,\n name: request.name,\n instructions: `${template.instructions}\\n\\nYou are dynamically assigned worker '${request.name}'.${roleText}${specialty}`,\n })\n }\n\n private nextWorkerName(): string {\n while (true) {\n const candidate = `worker_${++this.workerSequence}`\n if (!this.preparing.has(candidate) && !this.workerRuntimes.has(candidate)\n && !this.team.members().some(member => member.name === candidate)) return candidate\n }\n }\n\n private async observeWorkerEvent(worker: string, event: AgentRunEvent): Promise<void> {\n const observer = Promise.resolve().then(() => this.options.onWorkerEvent?.(worker, event))\n await waitForSettlement(observer, this.observerTimeoutMs)\n }\n}\n\nexport function createManagedAgentTeam(options: ManagedAgentTeamOptions): ManagedAgentTeam {\n return new ManagedAgentTeam(options)\n}\n\nfunction mergeTools(\n supplied: ToolCatalog | readonly ToolDefinition<any>[] | undefined,\n generated: readonly ToolDefinition<any>[],\n): ToolRegistry {\n const registry = new ToolRegistry()\n if (supplied !== undefined) {\n const tools = 'names' in supplied\n ? supplied.names().map(name => supplied.get(name))\n .filter((tool): tool is ToolDefinition => tool !== undefined)\n : supplied\n for (const tool of tools) registry.register(tool)\n }\n for (const tool of generated) registry.register(tool)\n return registry\n}\n\nfunction parseCloseTool(value: unknown): { name: string; cancelRunning: boolean } {\n const input = object(value, 'close_agent arguments')\n if (Object.keys(input).some(key => key !== 'name' && key !== 'cancelRunning')) {\n throw new TypeError('close_agent arguments contain unknown fields')\n }\n if (input.cancelRunning !== undefined && typeof input.cancelRunning !== 'boolean') {\n throw new TypeError('close_agent cancelRunning must be a boolean')\n }\n return { name: memberName(input.name), cancelRunning: input.cancelRunning === true }\n}\n\nfunction parseSpawnTool(value: unknown): ManagedAgentSpawnRequest {\n const input = object(value, 'spawn_agent arguments')\n const known = new Set([\n 'name', 'task', 'specialty', 'context', 'role', 'dependsOn', 'writes',\n ])\n if (Object.keys(input).some(key => !known.has(key))) {\n throw new TypeError('spawn_agent arguments contain unknown fields')\n }\n return {\n task: nonEmpty(input.task, 'worker task'),\n ...(input.name === undefined ? {} : { name: memberName(input.name) }),\n ...(input.specialty === undefined\n ? {}\n : { specialty: nonEmpty(input.specialty, 'worker specialty') }),\n ...(input.context === undefined ? {} : { context: spawnContext(input.context) }),\n ...(input.role === undefined ? {} : { role: nonEmpty(input.role, 'worker role') }),\n ...(input.dependsOn === undefined\n ? {}\n : { dependsOn: stringArray(input.dependsOn, 'dependsOn') }),\n ...(input.writes === undefined ? {} : { writes: stringArray(input.writes, 'writes') }),\n }\n}\n\nfunction stringArray(value: unknown, label: string): readonly string[] {\n if (!Array.isArray(value)) throw new TypeError(`${label} must be an array of strings`)\n return value.map(entry => nonEmpty(entry, `${label} entry`))\n}\n\nfunction spawnContext(value: unknown): ManagedAgentSpawnContext {\n if (value !== 'fresh' && value !== 'fork') {\n throw new TypeError(\"worker context must be 'fresh' or 'fork'\")\n }\n return value\n}\n\n/**\n * Copy the lead's conversation up to the last point it was complete.\n *\n * The lead is INSIDE a turn when it calls `spawn_agent`: the assistant message\n * carrying that very call is already in history, and its result cannot be,\n * because producing it is what this code is doing. Handing that tail to a\n * worker gives it a conversation ending in an unanswered tool call — which\n * providers reject, and which would turn a context optimisation into a spawn\n * that fails outright.\n *\n * So the fork is cut at the last position where no tool call was outstanding.\n * That is also the honest boundary in meaning: work still in flight is not yet\n * something the lead knows. The DeepSeek harness names the same rule a\n * \"completed-turn prefix\".\n *\n * A prefix is safe to hydrate as a history in its own right: `replace` surface\n * ops and compaction records only ever reference earlier entries, so cutting\n * from the end cannot orphan a reference.\n * @param snapshot - The lead's history, taken mid-turn.\n * @returns Entries up to that boundary; empty when nothing has completed.\n */\nexport function completedHistoryPrefix(\n snapshot: HistorySnapshot,\n): readonly HistoryEntry[] {\n const pending = new Set<string>()\n let cut = 0\n snapshot.entries.forEach((entry, index) => {\n const event = entry.event\n if (event.kind === 'tool-call') pending.add(event.callId)\n else if (event.kind === 'tool-result') pending.delete(event.callId)\n else if (event.kind === 'assistant') {\n // The assistant MESSAGE carries its own tool-call blocks, separately from\n // the `tool-call` events beside it. Counting only the events left the\n // spawn call in the fork, complete with the synthetic \"interrupted before\n // a result was recorded\" error the request builder pairs it with — the\n // worker's first sight of its lead being that it had just failed.\n for (const block of event.message.content) {\n if (block.type === 'tool-call') pending.add(block.id)\n }\n }\n // An interrupted assistant message is a turn that never finished; treating\n // it as settled context would hand a worker a half-formed intention.\n const settled = pending.size === 0\n && !(event.kind === 'assistant' && event.interrupted === true)\n if (settled) cut = index + 1\n })\n return snapshot.entries.slice(0, cut)\n}\n\nfunction object(value: unknown, label: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new TypeError(`${label} must be an object`)\n }\n return value as Record<string, unknown>\n}\n\nfunction memberName(value: unknown): string {\n const name = nonEmpty(value, 'managed agent name')\n if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {\n throw new TypeError('managed agent name must start with a letter and contain only letters, digits, _ or -')\n }\n if (name.length > 128) throw new TypeError('managed agent name must not exceed 128 characters')\n return name\n}\n\nfunction nonEmpty(value: unknown, label: string): string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new TypeError(`${label} must be a non-empty string`)\n }\n return value\n}\n\nfunction boundedString(value: unknown, label: string, maxBytes: number): string {\n const text = nonEmpty(value, label)\n if (new TextEncoder().encode(text).byteLength > maxBytes) {\n throw new TypeError(`${label} exceeds the ${maxBytes}-byte limit`)\n }\n return text\n}\n\nfunction positiveInteger(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value < 1) throw new TypeError(`${label} must be a positive integer`)\n return value\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nasync function abortable<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (signal === undefined) return promise\n if (signal.aborted) {\n // Calling a host callback can synchronously abort and return a rejected\n // promise; retain its rejection observer even though cancellation won.\n void promise.catch(() => undefined)\n throw signal.reason ?? new Error('managed worker aborted')\n }\n return await new Promise<T>((resolve, reject) => {\n const abort = () => {\n signal.removeEventListener('abort', abort)\n reject(signal.reason ?? new Error('managed worker aborted'))\n }\n signal.addEventListener('abort', abort, { once: true })\n void promise.then(\n value => { signal.removeEventListener('abort', abort); resolve(value) },\n error => { signal.removeEventListener('abort', abort); reject(error) },\n )\n })\n}\n\nfunction combineSignals(...signals: readonly (AbortSignal | undefined)[]): AbortSignal {\n const active = signals.filter((candidate): candidate is AbortSignal => candidate !== undefined)\n return active.length === 1 ? active[0]! : AbortSignal.any(active)\n}\n\nfunction asJson(value: unknown): JsonValue { return value as JsonValue }\n\n/** Worker states that will never change again on their own. */\nconst SETTLED_WORKER_STATUS: ReadonlySet<ManagedAgentWorkerStatus> =\n new Set<ManagedAgentWorkerStatus>(['completed', 'failed', 'closed'])\n\n/**\n * Reduce one declared write scope to a comparable path.\n *\n * Comparison is by path component, so the shapes that mean the same directory\n * have to arrive spelled the same way: `./app/`, `app`, and `app\\` all name\n * `app`, and a worker writing `app/page.tsx` conflicts with one writing `app`.\n */\n/**\n * Why a worker's run did not produce an answer, if it did not.\n *\n * A rejected run is obvious; a run that ends on an error reason is not, because\n * it resolves like any other. Both leave the lead with nothing to read, so both\n * are failures as far as the report is concerned.\n * @param response - What the worker's run returned.\n * @returns The failure to report, or undefined when the worker actually answered.\n */\nfunction failureOf(response: AgentResponse, requireText: boolean): string | undefined {\n const reason = response.outcome.reason\n if (reason.kind === 'error') return reason.failure.message\n if (reason.kind === 'max-tokens') return 'the model stopped at its output limit'\n if (reason.kind === 'usage-unavailable') return 'the provider reported no usage for a billed call'\n if (reason.kind === 'aborted') return 'the run was aborted'\n if (reason.kind === 'budget-exhausted' && !response.outcome.completed) {\n return `the run stopped at its ${reason.budget} limit before completing the task`\n }\n // Tool-only agents may intentionally complete without a textual answer.\n if (requireText && response.text.trim() === '') return 'it produced no answer'\n return undefined\n}\n\nfunction normalizeWriteScope(value: unknown): string {\n const text = nonEmpty(value, 'worker write scope').trim().split('\\\\').join('/')\n if (text.startsWith('/') || /^[a-zA-Z]:/.test(text)) {\n throw new TypeError('a worker write scope must be workspace-relative')\n }\n const parts: string[] = []\n for (const part of text.split('/')) {\n if (part === '' || part === '.') continue\n if (part === '..') {\n if (parts.length === 0) throw new TypeError('a worker write scope must not escape the workspace')\n parts.pop()\n } else parts.push(part)\n }\n if (parts.length === 0) {\n throw new TypeError('a worker write scope must name a file or directory, not the whole workspace')\n }\n return parts.join('/')\n}\n\n/** Whether two normalized scopes cover any of the same files. */\nfunction scopesOverlap(left: string, right: string): boolean {\n return left === right || left.startsWith(`${right}/`) || right.startsWith(`${left}/`)\n}\n\n/** Cut text to a byte budget without splitting a UTF-16 surrogate pair. */\nfunction prefixWithinBytes(text: string, maxBytes: number): string {\n return new TextDecoder('utf-8', { fatal: false }).decode(new TextEncoder().encode(text).subarray(0, maxBytes), { stream: true })\n}\n\n/** Keep both the initial findings and final verdict; the marker is inside the byte cap. */\nfunction truncate(text: string, maxBytes: number): string {\n const encoded = new TextEncoder().encode(text)\n if (encoded.byteLength <= maxBytes) return text\n const marker = '\\n… (truncated; read full result) …\\n'\n const markerBytes = new TextEncoder().encode(marker).byteLength\n if (maxBytes <= markerBytes) return prefixWithinBytes('(truncated)', maxBytes)\n const remaining = maxBytes - markerBytes\n const head = prefixWithinBytes(text, Math.ceil(remaining / 2))\n let tailStart = encoded.length - Math.floor(remaining / 2)\n while (tailStart < encoded.length && (encoded[tailStart]! & 0xc0) === 0x80) tailStart++\n const tail = new TextDecoder().decode(encoded.subarray(tailStart))\n return head + marker + tail\n}\n\n/** Detached evidence keeps full reports available without retaining producer sessions or ancestor chains. */\nfunction recordEvidence(runtime: WorkerRuntime): void {\n runtime.evidence.status = runtime.status\n runtime.evidence.result = runtime.result\n runtime.evidence.error = runtime.error\n}\n"],"mappings":"mhBAkCA,MAAa,EAAiC,IAGjC,EAAkC,IAWlC,EAAuB,KAG9B,EAAoB,CACxB,+GACA,2GACA,4JACA,uNACA,yFACA,8JACA,oIACA,+HACF,CAAC,CAAC,KAAK,GAAG,EAwQV,IAAa,EAAb,KAA8B,CAC5B,KACA,KACA,SACA,QACA,WACA,aACA,kBACA,gBACA,kBACA,eACA,WACA,eACA,eAAkC,IAAI,IAEtC,eAAkC,IAAI,IACtC,UAA6B,IAAI,IAKjC,UAA6B,IAAI,gBACjC,YACA,eAAyB,EACzB,yBACA,MAEA,YAAY,EAAkC,CAc5C,GAbA,KAAK,QAAU,EACf,KAAK,WAAa,EAAgB,EAAQ,YAAc,EAAG,YAAY,EACvE,KAAK,aAAe,EAAgB,EAAQ,cAAgB,MAAW,cAAc,EACrF,KAAK,kBAAoB,EAAgB,EAAQ,mBAAqB,KAAU,mBAAmB,EACnG,KAAK,gBAAkB,EAAa,EAAQ,iBAAmB,GAAW,EAC1E,KAAK,kBAAoB,EAAa,EAAQ,mBAAqB,GAAK,EACxE,KAAK,eAAiB,EAAa,EAAQ,gBAAA,GAAiD,EAC5F,KAAK,WAAa,EAAa,EAAQ,YAAA,IAAkC,EACzE,KAAK,eAAiB,EAAa,EAAQ,gBAAA,GAAgD,EAC3F,KAAK,yBAA2B,EAC9B,EAAQ,0BAA4B,KACpC,0BACF,EACI,KAAK,yBAA2B,EAAG,MAAU,UAAU,6CAA6C,EAExG,GADA,KAAK,MAAQ,IAAI,KAAK,EAAQ,OAAS,CAAC,EAAA,CAAG,IAAI,GAAQ,CAAC,EAAK,KAAM,CAAI,CAAC,CAAC,EACrE,KAAK,MAAM,QAAU,EAAQ,OAAS,CAAC,EAAA,CAAG,OAC5C,MAAU,MAAM,8CAA8C,EAEhE,KAAK,KAAO,EAAQ,gBAAgB,EAChC,EAAQ,KACR,IAAI,EAAU,CACZ,GAAG,EAAQ,KACX,WAAY,EAAQ,MAAM,YAAc,KAAK,WAAa,CAC5D,CAAC,EACL,KAAK,SAAW,EAAW,EAAQ,UAAY,EAAQ,KAAK,EAAE,EAC9D,KAAK,KAAO,EAAQ,KAAK,cAAc,CACrC,GAAG,EAAQ,mBACX,MAAO,KAAK,UAAU,EAAQ,oBAAoB,KAAK,EACvD,SAAU,EAAQ,SAClB,MAAO,EAAW,EAAQ,oBAAoB,MAAO,KAAK,aAAa,CAAC,EACxE,KAAM,CACJ,KAAM,KAAK,KACX,KAAM,KAAK,SACX,KAAM,OACN,aAAc,EACd,GAAI,EAAQ,kBAAoB,IAAA,GAAY,CAAC,EAAI,CAAE,YAAa,EAAQ,eAAgB,CAC1F,CACF,CAAC,CACH,CAmBA,UAAkB,EAAwC,CACxD,MAAO,CACL,GAAG,EACH,WAAY,KAAO,KAGjB,KAAK,cAAgB,GACrB,KAAK,UAAY,IAAI,gBACrB,KAAK,WAAa,EAAQ,OACnB,MAAM,GAAM,aAAa,CAAO,GAAK,CAAE,KAAM,SAAmB,GAEzE,UAAW,KAAO,IAAY,CAE5B,GADA,MAAM,GAAM,YAAY,CAAO,EAC3B,KAAK,QAAQ,uBAAyB,GAAO,OACjD,GAAI,CAAC,EAAQ,YAAa,CAKxB,GAAI,KAAK,cAAe,CACtB,KAAK,cAAgB,GACrB,GAAI,CAAE,KAAK,KAAK,KAAK,KAAK,QAAQ,CAAE,MAAQ,CAAsB,CACpE,CACA,MACF,CAKA,IAAM,EAAc,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAClD,OAAO,GAAW,EAAQ,SAAW,WAAa,EAAQ,SAAW,SAAS,EACjF,GAAI,EAAY,SAAW,EAAG,OAW9B,MAAM,KAAK,gBAAgB,CAAW,EACtC,IAAM,EAAO,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAC3C,OAAO,GAAW,EAAQ,SAAW,WAAa,EAAQ,SAAW,SAAS,CAAC,CAC/E,IAAI,GAAW,EAAQ,QAAQ,IAAI,EACtC,GAAI,EAAK,SAAW,EAAG,CACrB,KAAK,KAAK,OAAO,EAAkB,CACjC,OAAQ,CAAE,KAAM,MAAO,SAAU,cAAe,EAChD,QAAS,CAAC,CAAE,KAAM,OAAQ,KAAM,sHAAuH,CAAC,CAC1J,CAAC,CAAC,EACF,MACF,CACA,KAAK,KAAK,OAAO,EAAkB,CACjC,OAAQ,CAAE,KAAM,MAAO,SAAU,cAAe,EAChD,QAAS,CAAC,CAAE,KAAM,OAAQ,KAAM,gCAAgC,EAAK,KAAK,IAAI,EAAE,0GAC8B,CAAC,CACjH,CAAC,CAAC,CACJ,CACF,CACF,CAGA,IAAI,EAAmB,EAAqC,CAAC,EAA2B,CAEtF,OADA,KAAK,UAAU,OAAO,eAAe,EAC9B,KAAK,KAAK,IAAI,EAAO,CAAU,CACxC,CAcA,MAAM,EAAuB,CAC3B,KAAK,UAAU,OAAO,eAAe,EACrC,KAAK,KAAK,OAAO,CAAI,EACrB,KAAK,UAAU,MAAM,EAGrB,GAAI,CAAE,KAAK,KAAK,YAAY,KAAK,QAAQ,CAAE,MAAQ,CAAsB,CACzE,GAAI,CAAC,KAAK,KAAK,UACb,GAAI,CAAE,KAAK,KAAK,KAAK,KAAK,QAAQ,CAAE,MAAQ,CAAsB,CAEpE,MAAO,EACT,CAaA,MAAM,MACJ,EACA,EAC6B,CAC7B,KAAK,UAAU,OAAO,eAAe,EACrC,GAAQ,eAAe,EACvB,IAAM,EAA6C,CACjD,KAAM,EAAW,EAAQ,MAAQ,KAAK,eAAe,CAAC,EACtD,KAAM,EAAc,EAAQ,KAAM,cAAe,KAAK,YAAY,EAClE,GAAI,EAAQ,YAAc,IAAA,GACtB,CAAC,EACD,CAAE,UAAW,EAAc,EAAQ,UAAW,mBAAoB,KAAK,iBAAiB,CAAE,EAC9F,QAAS,EAAa,EAAQ,SAAW,KAAK,QAAQ,qBAAuB,OAAO,EACpF,GAAI,EAAQ,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,KAAK,YAAY,EAAQ,IAAI,CAAE,EAC7E,UAAW,KAAK,oBAAoB,EAAQ,WAAa,CAAC,CAAC,EAC3D,OAAQ,CAAC,GAAG,IAAI,KAAK,EAAQ,QAAU,CAAC,EAAA,CAAG,IAAI,CAAmB,CAAC,CAAC,CACtE,EACA,OAAO,OAAO,EAAS,SAAS,EAChC,OAAO,OAAO,EAAS,MAAM,EAC7B,OAAO,OAAO,CAAQ,EACtB,IAAM,EAAe,EAAS,UAAU,IAAI,GAAQ,KAAK,eAAe,IAAI,CAAI,CAAE,EAClF,GAAI,KAAK,eAAe,KAAO,KAAK,UAAU,MAAQ,KAAK,WACzD,MAAU,MAAM,kCAAkC,KAAK,WAAW,cAAc,EAElF,GAAI,KAAK,UAAU,IAAI,EAAS,IAAI,GAAK,KAAK,eAAe,IAAI,EAAS,IAAI,GACzE,KAAK,KAAK,QAAQ,CAAC,CAAC,KAAK,GAAU,EAAO,OAAS,EAAS,IAAI,EACnE,MAAU,MAAM,mBAAmB,EAAS,KAAK,iBAAiB,EAGpE,IAAI,EACE,EAAW,IAAI,QAAc,GAAW,CAAE,EAAe,CAAQ,CAAC,EACxE,KAAK,UAAU,IAAI,EAAS,KAAM,CAAE,QAAS,EAAU,eAAc,QAAS,CAAS,CAAC,EACxF,IAAI,EACJ,GAAI,CACF,IAAM,EAAW,KAAK,iBAAiB,EAAU,CAAY,EACvD,EAAkB,EAAe,EAAQ,KAAK,UAAU,OAAQ,YAAY,QAAQ,KAAK,cAAc,CAAC,EACxG,EAAa,MAAM,EAAU,KAAK,iBAAiB,CAAQ,EAAG,CAAe,EACnF,EAAgB,eAAe,EAC/B,IAAM,EAAuB,KAAK,QAAQ,8BAAgC,IAAA,GACtE,IAAA,GACA,MAAM,EAAU,QAAQ,QAAQ,KAAK,QAAQ,4BAA4B,CAAQ,CAAC,EAAG,CAAe,EACxG,EAAgB,eAAe,EAC/B,IAAM,EAAiB,CAAE,GAAG,KAAK,QAAQ,qBAAsB,GAAG,CAAqB,EACjF,EAAkB,KAAK,QAAQ,iBAAmB,YAClD,EAAU,EAAW,cAAc,CACvC,GAAG,EACH,GAAI,EAAa,SAAW,EAAI,CAAC,EAAI,CAAE,MAAO,EAAW,EAAe,MAAO,CAAC,KAAK,mBAAmB,CAAY,CAAC,CAAC,CAAE,EACxH,GAAI,EAAS,UAAY,OAAS,CAAE,QAAS,KAAK,gBAAgB,EAAe,aAAa,CAAE,EAAI,CAAC,EACrG,SAAU,KAAK,QAAQ,SACvB,KAAM,CACJ,KAAM,KAAK,KACX,KAAM,EAAS,KACf,KAAM,OACN,MAAO,EACP,aAAc,CACZ,2BAA2B,EAAS,KAAK,YAAY,KAAK,SAAS,IACnE,2GACA,mDACA,GAAI,IAAoB,GAAQ,CAAC,EAAI,CAAC,8EAA8E,CACtH,CAAC,CAAC,KAAK,GAAG,EACV,GAAI,EAAS,YAAc,IAAA,GAAY,CAAC,EAAI,CAAE,YAAa,EAAS,SAAU,CAChF,CACF,CAAC,EACK,EAAa,IAAI,gBACnB,EACJ,EAAU,CACR,QAAS,EACT,UACA,eACA,SAAU,GACV,gBAAiB,GACjB,UAAW,IAAA,GACX,OAAQ,UACR,WAAY,KAAK,KAAK,UACtB,QAAS,GACT,SAAU,IAAA,GACV,aACA,QAAS,IAAI,QAAe,GAAY,CAAE,EAAc,CAAQ,CAAC,EACjE,gBAAmB,CAAE,EAAe,CAAQ,EAAG,EAAS,gBAAkB,GAAM,EAAY,CAAE,EAC9F,MAAO,IAAA,GACP,WACA,OAAQ,IAAA,GACR,MAAO,IAAA,GACP,SAAU,CAAE,OAAQ,UAAW,OAAQ,IAAA,GAAW,MAAO,IAAA,EAAU,CACrE,EACA,KAAK,eAAe,IAAI,EAAS,KAAM,CAAO,EAC9C,KAAK,UAAU,OAAO,EAAS,IAAI,EAEnC,IAAM,EAAiB,EAAe,EAAiB,EAAW,MAAM,EAaxE,GAZA,MAAM,EAAU,KAAK,KAAK,YAAY,CACpC,KAAM,KAAK,SACX,OAAQ,EAAS,KACjB,QAAS,EAAS,KAClB,SAAU,QACV,OAAQ,CACV,CAAC,EAAG,CAAc,EAClB,EAAe,eAAe,EAC1B,EAAW,OAAO,sBACpB,EAAQ,OAAO,yBAAyB,EAAkB,EAAS,IAAI,CAAC,EAGtE,EAAa,OAAS,GAAK,CAAC,KAAK,oBAAoB,EAAc,EAAS,MAAM,EAAG,CAKvF,IAAM,EAAO,IAAI,QAAe,GAAY,CAAE,EAAS,MAAQ,CAAQ,CAAC,EACxE,KAAK,KAAK,YAAY,EAAS,KAAM,CAAI,EACzC,IAAK,IAAM,KAAc,EACnB,EAAsB,IAAI,EAAW,MAAM,GAAK,KAAK,cAAc,CAAU,GAG/E,KAAU,KAAK,SAAS,EAAW,QAAQ,IAAI,CAAC,CAAC,SAAW,KAAK,kBAAkB,CAAU,CAAC,CAAC,CAAC,UAAY,CAAC,CAAC,EAGlH,OAAO,KAAK,WAAW,CAAO,CAChC,CAEA,OADA,MAAM,KAAK,YAAY,EAAS,CAAc,EACvC,KAAK,WAAW,CAAO,CAChC,OAAS,EAAgB,CACvB,GAAI,IAAY,IAAA,IAAa,KAAK,eAAe,IAAI,EAAS,IAAI,IAAM,GAAW,CAAC,EAAQ,QAAS,CACnG,EAAQ,OAAS,SACjB,EAAQ,MAAQ,EAAa,CAAK,EAClC,EAAQ,MAAQ,IAAA,GAChB,EAAQ,aAAe,CAAC,EACxB,GAAI,CAAE,KAAK,KAAK,YAAY,EAAS,KAAM,IAAA,EAAS,CAAE,MAAQ,CAA8B,CAC5F,EAAQ,YAAY,EACpB,KAAK,eAAe,OAAO,EAAS,IAAI,EACxC,GAAI,CAAE,KAAK,KAAK,OAAO,EAAS,IAAI,CAAE,MAAQ,CAAqC,CACnF,MAAM,KAAK,kBAAkB,CAAO,CACtC,CACA,MAAM,CACR,QAAU,CACR,KAAK,UAAU,OAAO,EAAS,IAAI,EACnC,EAAa,CACf,CACF,CAQA,YAAoB,EAA8B,CAChD,IAAM,EAAO,EAAQ,QAAQ,KAC7B,GAAI,EAAQ,SAAW,WAAa,EAAQ,SAAW,KAAK,UAAU,OAAO,SACxE,KAAK,eAAe,IAAI,CAAI,IAAM,EAAS,OAChD,EAAQ,QAAQ,EAChB,EAAQ,MAAQ,IAAA,GAChB,KAAK,KAAK,YAAY,EAAM,IAAA,EAAS,EAGrC,EAAQ,OAAS,UAejB,IAAM,EAAW,YAAY,QAAQ,KAAK,eAAe,EACzD,EAAQ,SAAW,EACnB,IAAM,EAAU,EAAQ,QAAQ,WAAW,CACzC,OAAQ,EAAe,EAAQ,WAAW,OAAQ,CAAQ,EAC1D,GAAI,KAAK,QAAQ,gBAAkB,IAAA,GAC/B,CAAC,EACD,CAAE,QAAU,GAAyB,KAAK,mBAAmB,EAAM,CAAK,CAAE,CAChF,CAAC,EACD,KAAU,aAAa,EAAS,CAAO,CACzC,CAGA,MAAc,YAAY,EAAwB,EAA0C,CACtF,OAAQ,UAAY,EAAQ,SAAW,WAAa,EAAQ,SAAW,KAAK,UAAU,OAAO,SACjG,GAAQ,SAAW,GACnB,GAAI,CACF,IAAM,EAAS,KAAK,iBAAiB,EAAQ,YAAY,EACzD,GAAI,IAAW,IAAA,GAAW,CACxB,IAAM,EAAS,EAAe,EAAa,EAAQ,WAAW,OAAQ,KAAK,UAAU,OACnF,YAAY,QAAQ,KAAK,cAAc,CAAC,EAC1C,MAAM,EAAU,KAAK,KAAK,YAAY,CAAE,KAAM,KAAK,SAAU,OAAQ,EAAQ,QAAQ,KACnF,QAAS,EAAQ,SAAU,QAAS,QAAO,CAAC,EAAG,CAAM,EACvD,EAAO,eAAe,CACxB,CACA,KAAK,YAAY,CAAO,CAC1B,OAAS,EAAgB,CAGvB,GAAI,CAAC,EAAQ,SAAW,CAAC,KAAK,UAAU,OAAO,QAAS,CACtD,EAAQ,OAAS,SACjB,EAAQ,MAAQ,8BAA8B,EAAa,CAAK,IAChE,EAAe,CAAO,EACtB,EAAQ,QAAQ,EAChB,EAAQ,MAAQ,IAAA,GAChB,GAAI,CACF,KAAK,KAAK,YAAY,EAAQ,QAAQ,KAAM,IAAA,EAAS,EACrD,KAAK,KAAK,cAAc,EAAQ,QAAQ,KAAM,CAAE,KAAM,SAAU,QAAS,EAAQ,KAAM,CAAC,CAC1F,MAAQ,CAAqC,CAC7C,MAAM,KAAK,WAAW,EAAS,WAAW,EAAQ,OAAO,EACzD,EAAQ,YAAY,EACpB,MAAM,KAAK,kBAAkB,CAAO,CACtC,CACF,QAAU,CAGR,EAAQ,aAAe,CAAC,CAC1B,CAhCmB,CAiCrB,CAWA,YAA8C,CAC5C,GAAI,KAAK,MAAM,OAAS,EAAG,MAAO,CAAC,EACnC,IAAM,EAAQ,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC,CAAC,CAAC,IAAI,GACzC,KAAK,EAAK,KAAK,IAAI,EAAK,eACrB,EAAK,YAAc,IAAA,GAAY,GAAK,cAAc,EAAK,YAAY,EACxE,MAAO,CACL,KAAM,CACJ,KAAM,SACN,KAAM,CAAC,GAAG,KAAK,MAAM,KAAK,CAAC,EAC3B,YAAa,kCAAkC,EAAM,KAAK;CAAI,GAChE,CACF,CACF,CAGA,YAAoB,EAAuB,CACzC,IAAM,EAAQ,EAAS,EAAM,aAAa,EAC1C,GAAI,KAAK,MAAM,OAAS,EACtB,MAAU,MAAM,mEAAmE,EAErF,GAAI,CAAC,KAAK,MAAM,IAAI,CAAK,EACvB,MAAU,MACR,wBAAwB,EAAM,wBAAwB,CAAC,GAAG,KAAK,MAAM,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,GACxF,EAEF,OAAO,CACT,CAUA,oBAA4B,EAA6C,CACvE,MAAO,CAAC,GAAG,IAAI,IAAI,EAAM,IAAK,GAAS,CACrC,IAAM,EAAU,EAAW,CAAI,EAC/B,GAAI,CAAC,KAAK,eAAe,IAAI,CAAO,EAClC,MAAU,MACR,uBAAuB,EAAQ,uDACjC,EAEF,OAAO,CACT,CAAC,CAAC,CAAC,CACL,CAYA,iBAAyB,EAA2C,EAA2D,CAC7H,IAAM,EAAS,KAAK,QAAQ,kBAAoB,SAChD,GAAI,IAAW,OAAS,EAAQ,OAAO,SAAW,EAAG,MAAO,CAAC,EAC7D,IAAM,EAAY,KAAK,YAAY,CAAY,EACzC,EAAkB,CAAC,EACnB,EAAgB,IAAI,IAAI,KAAK,KAAK,QAAQ,CAAC,CAAC,OAAO,GAAU,EAAO,SAAW,SAAS,CAAC,CAAC,IAAI,GAAU,EAAO,cAAc,CAAC,EAC9H,EAAS,CACb,GAAG,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAAC,OAAO,GAAS,EAAM,SAAW,WAAa,EAAM,SAAW,WAAa,KAAK,cAAc,EAAO,CAAa,CAAC,CAAC,CACvJ,OAAO,GAAS,CAAC,EAAU,IAAI,CAAK,CAAC,EACxC,GAAG,KAAK,eACR,GAAG,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,OAAO,GAAS,EAAM,QAAQ,OAAS,EAAQ,IAAI,CACrF,EACA,IAAK,IAAM,KAAS,EAAQ,CAC1B,IAAM,EAAQ,EAAQ,OAAO,OAAO,GAClC,EAAM,QAAQ,OAAO,KAAK,GAAU,EAAc,EAAM,CAAM,CAAC,CAAC,EAClE,GAAI,EAAM,SAAW,EAAG,SACxB,IAAM,EAAS,IAAI,EAAM,QAAQ,KAAK,gBAAgB,EAAM,KAAK,IAAI,IACrE,GAAI,IAAW,SACb,MAAU,MACR,WAAW,EAAQ,KAAK,qDAAqD,EAAO,SACzE,EAAM,QAAQ,KAAK,2GAOhC,EAEF,EAAM,KAAK,CAAM,CACnB,CACA,OAAO,CACT,CAaA,sBAA8B,EAAgB,EAA4C,CACxF,GAAI,GAAS,UAAU,UAAY,GAAM,OAAO,KAAK,gBAAgB,EACrE,IAAM,EAAQ,GAAqC,KAGnD,OAFI,IAAS,eAAuB,KAAK,gBAAgB,EACrD,IAAS,aAAqB,4CAC3B,EAAa,CAAK,CAC3B,CAGA,iBAAkC,CAChC,MAAO,mBAAmB,OAAO,KAAK,eAAe,EAAE,wFAEzD,CAYA,MAAc,gBAAgB,EAAsD,CAClF,IAAI,EACA,EACE,EAAW,IAAI,QAAe,GAAY,CAC9C,EAAQ,WAAW,EAAS,KAAK,UAAU,EAG1C,EAA6C,QAAQ,CACxD,CAAC,EACD,GAAI,CACF,IAAM,EAAU,KAAK,UAAU,OACzB,EAAa,IAAI,QAAc,GAAW,CAC1C,EAAQ,QAAS,EAAQ,EACxB,EAAQ,iBAAiB,QAAS,EAAc,CAAE,KAAM,EAAK,CAAC,EACnE,SAAS,GAAe,CAAE,EAAQ,CAAE,CACpC,MAAoB,EAAQ,oBAAoB,QAAS,CAAY,CACvE,CAAC,EACD,MAAM,EAAU,QAAQ,KAAK,CAAC,GAAG,EAAY,IAAI,GAAW,EAAQ,OAAO,EAAG,EAAU,CAAU,CAAC,EACjG,EAAe,KAAK,UAAU,OAAQ,KAAK,UAAU,CAAC,CAC1D,QAAU,CACJ,IAAU,IAAA,IAAW,aAAa,CAAK,EAC3C,IAAc,CAChB,CACF,CAGA,YAAoB,EAAmC,EAAO,IAAI,IAA0C,CAC1G,IAAK,IAAM,KAAW,EAChB,EAAK,IAAI,CAAO,IACpB,EAAK,IAAI,CAAO,EAChB,KAAK,YAAY,EAAQ,aAAc,CAAI,GAE7C,OAAO,CACT,CAGA,cAAsB,EAAwB,EAA0D,CACtG,OAAO,EAAQ,QAAQ,WAAa,KAAK,eAAe,IAAI,CAAO,IAC7D,IAAkB,IAAA,GAClB,KAAK,KAAK,QAAQ,CAAC,CAAC,KAAK,GAAU,EAAO,OAAS,EAAQ,QAAQ,MAChE,EAAO,iBAAmB,EAAQ,QAAQ,gBAAkB,EAAO,SAAW,SAAS,EAC1F,EAAc,IAAI,EAAQ,QAAQ,cAAc,EACxD,CAGA,oBAA4B,EAAmC,EAA4B,CAAC,EAAY,CACtG,OAAO,EAAQ,MAAM,GAAW,EAAsB,IAAI,EAAQ,MAAM,GACnE,GAAG,KAAK,QAAQ,kBAAoB,YAAc,UAChD,EAAO,KAAK,GAAQ,EAAQ,QAAQ,OAAO,KAAK,GAAU,EAAc,EAAM,CAAM,CAAC,CAAC,GACtF,KAAK,cAAc,CAAO,EAAE,CACrC,CAWA,MAAc,kBAAkB,EAAwC,CACtE,GAAI,KAAK,UAAU,OAAO,QAAS,OACnC,IAAM,EAAQ,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAAC,OAAO,GACrD,EAAQ,SAAW,WAChB,CAAC,EAAQ,SACT,EAAQ,aAAa,SAAS,CAAQ,GACtC,KAAK,oBAAoB,EAAQ,aAAc,EAAQ,QAAQ,MAAM,CAAC,EAC3E,IAAK,IAAM,KAAW,EACpB,MAAM,KAAK,YAAY,CAAO,CAElC,CAGA,iBAAyB,EAAuD,CAC9E,IAAI,EAAqB,GACnB,EAAQ,EAAQ,IAAK,GAAY,CACrC,IAAM,EAAO,EAAQ,QAAQ,KAC7B,GAAI,EAAQ,QAAU,IAAA,GAAW,CAC/B,IAAM,EAAU,EAAQ,QAAQ,KAC1B,EAAU,EAAU,EAAS,EAAS,KAAK,wBAAwB,EAAI,IAAA,GAE7E,MADA,KAAuB,IAAY,IAAA,IAAa,IAAY,EACrD,qBAAqB,EAAK,YAAY,EAAQ,SAChD,EAAU,GAAK;wDACf,IAAY,IAAA,GAAY,GAAK,8CAA8C,IAClF,CACA,GAAI,EAAQ,SAAW,IAAA,IAAa,EAAQ,SAAW,SAAU,MAAO,qBAAqB,EAAK,kFAClG,IAAM,EAAO,EAAQ,QAAQ,MAAQ,GAC/B,EAAU,EAAS,EAAM,KAAK,wBAAwB,EAE5D,MADA,KAAuB,IAAY,EAC5B,qBAAqB,EAAK,cAAc,IAAY,EAAO,OAAS,YAAY,oBAAoB,GAC7G,CAAC,EACG,KAAM,SAAW,EACrB,MAAO,CACL,uKACA,GAAG,EACH,GAAI,EAAqB,CAAC,iGAAiG,EAAI,CAAC,CAClI,CAAC,CAAC,KAAK;CAAI,CACb,CAGA,mBAA2B,EAAwD,CACjF,IAAM,EAAQ,IAAI,IAAI,EAAa,IAAI,GAAW,CAAC,EAAQ,QAAQ,KAAM,EAAQ,QAAQ,CAAC,CAAC,EAC3F,OAAO,EAAW,CAChB,KAAM,yBACN,YAAa,4MACb,WAAY,CAAE,KAAM,SAAU,WAAY,CAAE,KAAM,CAAE,KAAM,QAAS,EAAG,OAAQ,CAAE,KAAM,UAAW,QAAS,CAAE,CAAE,EAAG,SAAU,CAAC,MAAM,EAAG,qBAAsB,EAAM,EACjK,MAAM,EAAc,CAClB,GAAI,OAAO,GAAQ,WAAY,EAAc,MAAU,UAAU,qCAAqC,EACtG,IAAM,EAAO,QAAQ,IAAI,EAAK,MAAM,EAAG,EAAS,QAAQ,IAAI,EAAK,QAAQ,GAAK,EAC9E,GAAI,OAAO,GAAS,UAAY,CAAC,OAAO,cAAc,CAAM,GAAK,EAAS,EAAG,MAAU,UAAU,mCAAmC,EACpI,MAAO,CAAE,OAAc,QAAiB,CAC1C,EACA,SAAU,CAAE,OAAM,YAAa,CAC7B,IAAM,EAAW,EAAM,IAAI,CAAI,EAC/B,GAAI,IAAa,IAAA,GAAW,MAAU,MAAM,0DAA0D,EACtG,IAAM,EAAO,EAAS,QAAQ,MAAQ,GACtC,GAAI,EAAS,EAAK,QAAW,EAAS,GAAK,kBAAkB,KAAK,EAAK,EAAQ,EAAI,MAAU,WAAW,2CAA2C,EAEnJ,IAAM,EAAO,EAAkB,EAAK,MAAM,CAAM,EAAG,KAAK,wBAAwB,EAC1E,EAAO,EAAS,EAAK,OAC3B,MAAO,CAAE,OAAM,OAAQ,EAAS,OAAQ,UAAW,EAAS,QAAQ,WAAa,GAC/E,GAAI,EAAS,QAAU,IAAA,GAAY,CAAC,EAAI,CAAE,MAAO,EAAS,KAAM,EAAI,KAAM,EAC1E,WAAY,EAAO,EAAK,OAAS,EAAO,IAAK,CACjD,EACA,sBAAyB,EAC3B,CAAC,CACH,CAUA,MAAc,aACZ,EACA,EACe,CACf,IAAM,EAAO,EAAQ,QAAQ,KAC7B,GAAI,CACF,IAAM,EAAW,MAAM,EACvB,GAAI,EAAQ,SAAW,UAAY,CAAC,EAAQ,QAAS,CAMnD,IAAM,EAAU,EAAQ,UAAU,UAAY,GAC1C,KAAK,gBAAgB,EACrB,EAAU,EAAU,KAAK,QAAQ,oBAAsB,EAAI,EAC3D,IAAY,IAAA,IAmBd,EAAQ,OAAS,YACjB,EAAQ,OAAS,OAAO,OAAO,CAC7B,OAAQ,EACR,QAAS,EAAQ,QAAQ,WAAW,GACpC,eAAgB,EAAQ,QAAQ,eAChC,KAAM,EAAS,KACf,UAAW,EAAS,QAAQ,SAC9B,CAAC,EACD,EAAe,CAAO,EACtB,KAAK,KAAK,cAAc,EAAM,CAAE,KAAM,YAAa,KAAM,EAAS,IAAK,CAAC,EACxE,MAAM,KAAK,WAAW,EAAS,aAAa,EAAS,MAAM,IA5B3D,EAAQ,OAAS,SACjB,EAAQ,MAAQ,EAGZ,EAAS,KAAK,KAAK,IAAM,KAC3B,EAAQ,OAAS,OAAO,OAAO,CAC7B,OAAQ,EACR,QAAS,EAAQ,QAAQ,WAAW,GACpC,eAAgB,EAAQ,QAAQ,eAChC,KAAM,EAAS,KACf,UAAW,EACb,CAAC,GAEH,EAAe,CAAO,EACtB,KAAK,KAAK,cAAc,EAAM,CAAE,KAAM,SAAU,QAAS,CAAQ,CAAC,EAClE,MAAM,KAAK,WAAW,EAAS,WAAW,KACrC,EAAQ,SAAW,IAAA,GAAY,GAAK,8CAA8C,EAAQ,OAAO,OAAO,EAcjH,CACF,OAAS,EAAgB,CAIvB,GAAI,EAAQ,SAAW,UAAY,CAAC,EAAQ,QAAS,CACnD,EAAQ,OAAS,SACjB,EAAQ,MAAQ,KAAK,sBAAsB,EAAO,CAAO,EACzD,EAAe,CAAO,EACtB,GAAI,CAAE,KAAK,KAAK,cAAc,EAAM,CAAE,KAAM,SAAU,QAAS,EAAQ,KAAM,CAAC,CAAE,MAAQ,CAA6B,CACrH,MAAM,KAAK,WAAW,EAAS,WAAW,EAAQ,OAAO,CAC3D,CACF,QAAU,CACR,EAAQ,YAAY,EAGpB,MAAM,KAAK,kBAAkB,CAAO,CACtC,CACF,CAkBA,MAAc,WAAW,EAAwB,EAAgC,CAC/E,IAAM,EAAS,EAAQ,QAAQ,KAC/B,GAAI,EAAQ,SAAW,KAAK,UAAU,OAAO,SAAW,KAAK,eAAe,IAAI,CAAM,IAAM,EAAS,OACrG,IAAM,EAAW,KAAK,YAAY,CAAM,EAIpC,IAAa,UAAS,KAAK,cAAgB,IAC/C,GAAI,CACF,IAAM,EAAS,EAAe,EAAQ,WAAW,OAAQ,KAAK,UAAU,OACtE,YAAY,QAAQ,KAAK,cAAc,CAAC,EAC1C,MAAM,EAAU,KAAK,KAAK,YAAY,EAAyB,CAC7D,KAAM,EACN,OAAQ,KAAK,SACb,QAAS,WAAW,EAAO,IAAI,EAAS,EAAS,KAAK,IAAI,KAAK,yBAA0B,KAAK,IAAI,GAAI,KAAK,MAAM,KAAK,KAAK,iBAAmB,CAAC,CAAC,CAAC,CAAC,IAClJ,WACA,QACF,CAAC,CAAC,EAAG,CAAM,CACb,MAAQ,CAGR,CACF,CAOA,YAAoB,EAAoC,CAOtD,OAJI,KAAK,QAAQ,uBAAyB,IAAS,KAAK,KAAK,WAGzD,KAAK,eAAe,IAAI,CAAM,CAAC,EAAE,aAAe,GAAa,QAC1D,QACT,CAGA,cAAwB,GACxB,UAAoB,IAAI,gBACxB,WAcA,MAAM,UAAU,EAAqC,CACnD,OAAS,CACP,GAAQ,eAAe,EACvB,IAAM,EAAc,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAClD,OAAO,GAAW,CAAC,EAAQ,eAAe,EACvC,EAAY,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,IAAI,GAAY,EAAS,OAAO,EAO/E,GANI,EAAY,OAAS,EAAU,OAAS,GAC1C,MAAM,EAAU,QAAQ,IAAI,CAAC,GAAG,EAAY,IAAI,GAAW,EAAQ,OAAO,EAAG,GAAG,CAAS,CAAC,EAAG,CAAM,EAErG,MAAM,KAAK,KAAK,SAAS,KAAK,SAAU,CAAM,EAG1C,EAFS,KAAK,UAAU,KAAO,GAAK,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CACtE,KAAK,GAAW,CAAC,EAAQ,eAAe,GAChC,MACb,CACF,CAGA,SAAyC,CACvC,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC,CAAC,CAAC,IAAI,GAAW,KAAK,WAAW,CAAO,CAAC,CAAC,CACjG,CAEA,WAAmB,EAA4C,CAC7D,OAAO,OAAO,OAAO,CACnB,KAAM,EAAQ,QAAQ,KACtB,QAAS,EAAQ,QAAQ,WAAW,GACpC,eAAgB,EAAQ,QAAQ,eAChC,KAAM,EAAQ,QAAQ,KACtB,OAAQ,EAAQ,OAChB,QAAS,EAAQ,QAAQ,QACzB,UAAW,EAAQ,QAAQ,UAC3B,OAAQ,EAAQ,QAAQ,OACxB,GAAI,EAAQ,QAAQ,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAQ,QAAQ,IAAK,EAC3E,GAAI,EAAQ,SAAS,SAAW,EAAI,CAAC,EAAI,CAAE,SAAU,EAAQ,QAAS,EACtE,GAAI,EAAQ,QAAQ,YAAc,IAAA,GAAY,CAAC,EAAI,CAAE,UAAW,EAAQ,QAAQ,SAAU,EAC1F,GAAI,EAAQ,SAAW,IAAA,GAAY,CAAC,EAAI,CAAE,OAAQ,EAAQ,MAAO,EACjE,GAAI,EAAQ,QAAU,IAAA,GAAY,CAAC,EAAI,CAAE,MAAO,EAAQ,KAAM,CAChE,CAAC,CACH,CAYA,MAAM,YACJ,EACA,EAA0E,CAAC,EAC5B,CAC/C,IAAM,EAAU,EAAW,CAAI,EACzB,EAAU,KAAK,eAAe,IAAI,CAAO,EAC/C,GAAI,IAAY,IAAA,GAAW,MAAU,MAAM,2BAA2B,EAAQ,EAAE,EAChF,IAAM,EAAS,EAAa,EAAQ,WAAA,GAAoC,EAGpE,EACE,EAAW,IAAI,QAAe,GAAY,CAAE,EAAQ,WAAW,EAAS,CAAM,CAAE,CAAC,EACvF,GAAI,CACF,MAAM,EAAU,QAAQ,KAAK,CAAC,EAAQ,QAAS,CAAQ,CAAC,EAAG,EAAQ,MAAM,CAC3E,QAAU,CACR,aAAa,CAAK,CACpB,CAEA,OADA,EAAQ,QAAQ,eAAe,EACxB,EAAQ,MACjB,CAYA,MAAM,YACJ,EACA,EAAsB,MAAM,uBAAuB,EAChB,CACnC,IAAM,EAAU,EAAW,CAAI,EACzB,EAAU,KAAK,eAAe,IAAI,CAAO,EAC/C,GAAI,IAAY,IAAA,GAAW,MAAU,MAAM,2BAA2B,EAAQ,EAAE,EAGhF,MAFA,GAAQ,QAAU,GAClB,EAAQ,YAAc,QAAQ,QAAQ,CAAC,CAAC,SAAW,KAAK,aAAa,EAAS,CAAM,CAAC,EAC9E,EAAQ,SACjB,CAEA,MAAc,aAAa,EAAwB,EAAoD,CACrG,IAAM,EAAU,EAAQ,QAAQ,KAC1B,EAAW,EAAQ,OACzB,EAAQ,QAAU,GAClB,EAAQ,WAAW,MAAM,CAAM,EAC/B,IAAM,EAAgB,YAAY,QAAQ,KAAK,cAAc,EAQ7D,GAAI,CACF,MAAM,EAAU,KAAK,KAAK,OAAO,EAAS,CAAM,EAAG,CAAa,CAClE,MAAQ,CAGR,CACA,GAAI,IAAa,UAGf,EAAQ,OAAS,SACjB,EAAQ,MAAQ,IAAA,GAChB,KAAK,KAAK,YAAY,EAAS,IAAA,EAAS,EACxC,EAAQ,YAAY,MACf,CAKL,GAAI,CAAE,MAAM,EAAU,EAAQ,QAAS,CAAa,CAAE,MAAQ,CAA4C,CAC1G,EAAQ,OAAS,SACjB,EAAQ,YAAY,CACtB,CAgBA,GAfA,EAAe,CAAO,EAClB,KAAK,cAAc,CAAO,IACxB,EAAQ,QAAQ,OAAO,OAAS,GAAG,KAAK,eAAe,IAAI,CAAO,EAGtE,KAAU,KAAK,SAAS,CAAO,CAAC,CAAC,KAAK,SAAY,CAChD,KAAK,eAAe,OAAO,CAAO,EAClC,GAAI,CACE,KAAK,KAAK,QAAQ,CAAC,CAAC,KAAK,GAAU,EAAO,OAAS,GAAW,EAAO,iBAAmB,EAAQ,QAAQ,cAAc,GACxH,KAAK,KAAK,OAAO,CAAO,CAE5B,MAAQ,CAA2C,CACnD,MAAM,KAAK,kBAAkB,CAAO,CACtC,CAAC,CAAC,CAAC,UAAY,CAA+C,CAAC,GAE7D,KAAK,eAAe,IAAI,CAAO,IAAM,EAAS,CAChD,KAAK,eAAe,OAAO,CAAO,EAClC,GAAI,CAAE,KAAK,KAAK,OAAO,CAAO,CAAE,MAAQ,CAA8C,CACxF,CAKA,MAFA,GAAQ,aAAe,CAAC,EACxB,MAAM,KAAK,kBAAkB,CAAO,EAC7B,CACT,CAUA,QAAQ,EAAsB,MAAM,6BAA6B,EAAkB,CACjF,GAAI,KAAK,cAAgB,IAAA,GAAW,OAAO,KAAK,YAChD,KAAK,UAAU,MAAM,CAAM,EAC3B,IAAM,EAAQ,CAAC,GAAG,KAAK,eAAe,KAAK,CAAC,EAK5C,MAJA,MAAK,YAAc,QAAQ,WAAW,CACpC,GAAG,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,IAAI,GAAY,EAAS,OAAO,EAChE,GAAG,EAAM,IAAI,GAAQ,KAAK,YAAY,EAAM,CAAM,CAAC,CACrD,CAAC,CAAC,CAAC,SAAW,IAAA,EAAS,EAChB,KAAK,WACd,CAGA,aAAa,EAAoB,CAC/B,IAAM,EAAU,EAAW,CAAI,EACzB,EAAU,KAAK,eAAe,IAAI,CAAO,EAC/C,GAAI,IAAY,IAAA,GAAW,MAAU,MAAM,2BAA2B,EAAQ,EAAE,EAChF,GAAI,EAAQ,SAAW,WAAa,EAAQ,SAAW,WAAa,CAAC,EAAQ,iBAAmB,EAAQ,QAAQ,UAC9G,MAAU,MAAM,yCAAyC,EAAQ,EAAE,EAErE,KAAK,KAAK,OAAO,CAAO,EACxB,KAAK,eAAe,OAAO,CAAO,CACpC,CAEA,cAAuD,CACrD,OAAO,OAAO,OAAO,CACnB,EAAW,CACT,KAAM,cACN,YAAa,CACX,iDACA,0EACA,iFACA,sHACF,CAAC,CAAC,KAAK,GAAG,EACV,WAAY,CACV,KAAM,SACN,WAAY,CACV,KAAM,CACJ,KAAM,SACN,YAAa,6DACf,EACA,KAAM,CACJ,KAAM,SACN,YAAa,sDACf,EACA,UAAW,CACT,KAAM,SACN,YAAa,gDACf,EACA,QAAS,CACP,KAAM,SACN,KAAM,CAAC,QAAS,MAAM,EACtB,YAAa,+EACf,EACA,UAAW,CACT,KAAM,QACN,MAAO,CAAE,KAAM,QAAS,EACxB,YAAa,qSAIf,EACA,OAAQ,CACN,KAAM,QACN,MAAO,CAAE,KAAM,QAAS,EACxB,YAAa,iOAGf,EACA,GAAG,KAAK,WAAW,CACrB,EACA,SAAU,CAAC,MAAM,EACjB,qBAAsB,EACxB,EACA,MAAO,EACP,QAAS,MAAO,EAAS,IAAY,EAAO,MAAM,KAAK,MAAM,EAAS,EAAQ,MAAM,CAAC,EAIrF,UAAW,KAAK,eAChB,sBAAyB,EAC3B,CAAC,EACD,EAAW,CACT,KAAM,cACN,aAAc,GACd,YAAa,CACX,uDACA,gGACA,0FACA,KAAK,QAAQ,+BAAiC,GAC1C,iGACA,sFACJ,4CACF,CAAC,CAAC,KAAK,GAAG,EACV,WAAY,CACV,KAAM,SACN,WAAY,CACV,KAAM,CAAE,KAAM,SAAU,YAAa,yCAA0C,EAC/E,cAAe,CAAE,KAAM,UAAW,YAAa,4DAA6D,CAC9G,EACA,SAAU,CAAC,MAAM,EACjB,qBAAsB,EACxB,EACA,MAAO,EACP,QAAS,MAAO,CAAE,OAAM,mBAAoB,CAC1C,IAAM,EAAU,KAAK,eAAe,IAAI,CAAI,EAW5C,OAVI,IAAY,IAAA,KAAc,CAAC,GAAiB,KAAK,QAAQ,+BAAiC,MACxF,EAAQ,SAAW,WAAa,EAAQ,SAAW,WAAa,EAAQ,QAAQ,WAC7E,EAAO,CACZ,OAAQ,EAAM,OAAQ,GACtB,OAAQ,EAAQ,SAAW,UAAY,UAAY,UACnD,YAAa,+GACR,KAAK,QAAQ,+BAAiC,GAAQ,+CACrD,iFACR,CAAC,EAEI,EAAO,CAAE,OAAQ,EAAM,OAAQ,GAAM,eAAgB,MAAM,KAAK,YAAY,CAAI,CAAE,CAAC,CAC5F,EACA,UAAW,KAAK,eAClB,CAAC,CACH,CAAC,CACH,CAUA,gBAAwB,EAAuD,CAC7E,IAAM,EAAU,EAAuB,KAAK,KAAK,SAAS,CAAC,CAAC,OAAO,EACnE,OAAO,EAAQ,aACb,CAAE,QAAS,EAAG,SAAQ,EACtB,GAAU,CAAC,CACb,CACF,CAEA,MAAc,iBACZ,EACuB,CACvB,GAAI,KAAK,QAAQ,gBAAkB,IAAA,GAAW,OAAO,KAAK,QAAQ,cAAc,CAAO,EACvF,IAAM,EAAW,KAAK,QAAQ,gBAAkB,KAAK,QAAQ,KACvD,EAAO,EAAQ,OAAS,IAAA,GAAY,IAAA,GAAY,KAAK,MAAM,IAAI,EAAQ,IAAI,EAC3E,EAAW,IAAS,IAAA,GACtB,GACA,iBAAiB,EAAK,KAAK,YAAY,EAAK,cAAgB,EAAK,cAC/D,EAAY,EAAQ,YAAc,IAAA,GACpC,GACA,4BAA4B,EAAQ,UAAU,GAClD,OAAO,EAAW,EAAU,CAC1B,GAAI,EAAQ,KACZ,KAAM,EAAQ,KACd,aAAc,GAAG,EAAS,aAAa,2CAA2C,EAAQ,KAAK,IAAI,IAAW,GAChH,CAAC,CACH,CAEA,gBAAiC,CAC/B,OAAa,CACX,IAAM,EAAY,UAAU,EAAE,KAAK,iBACnC,GAAI,CAAC,KAAK,UAAU,IAAI,CAAS,GAAK,CAAC,KAAK,eAAe,IAAI,CAAS,GACnE,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,KAAK,GAAU,EAAO,OAAS,CAAS,EAAG,OAAO,CAC9E,CACF,CAEA,MAAc,mBAAmB,EAAgB,EAAqC,CACpF,IAAM,EAAW,QAAQ,QAAQ,CAAC,CAAC,SAAW,KAAK,QAAQ,gBAAgB,EAAQ,CAAK,CAAC,EACzF,MAAM,EAAkB,EAAU,KAAK,iBAAiB,CAC1D,CACF,EAEA,SAAgB,EAAuB,EAAoD,CACzF,OAAO,IAAI,EAAiB,CAAO,CACrC,CAEA,SAAS,EACP,EACA,EACc,CACd,IAAM,EAAW,IAAI,EACrB,GAAI,IAAa,IAAA,GAAW,CAC1B,IAAM,EAAQ,UAAW,EACrB,EAAS,MAAM,CAAC,CAAC,IAAI,GAAQ,EAAS,IAAI,CAAI,CAAC,CAAC,CAC/C,OAAQ,GAAiC,IAAS,IAAA,EAAS,EAC5D,EACJ,IAAK,IAAM,KAAQ,EAAO,EAAS,SAAS,CAAI,CAClD,CACA,IAAK,IAAM,KAAQ,EAAW,EAAS,SAAS,CAAI,EACpD,OAAO,CACT,CAEA,SAAS,EAAe,EAA0D,CAChF,IAAM,EAAQ,EAAO,EAAO,uBAAuB,EACnD,GAAI,OAAO,KAAK,CAAK,CAAC,CAAC,KAAK,GAAO,IAAQ,QAAU,IAAQ,eAAe,EAC1E,MAAU,UAAU,8CAA8C,EAEpE,GAAI,EAAM,gBAAkB,IAAA,IAAa,OAAO,EAAM,eAAkB,UACtE,MAAU,UAAU,6CAA6C,EAEnE,MAAO,CAAE,KAAM,EAAW,EAAM,IAAI,EAAG,cAAe,EAAM,gBAAkB,EAAK,CACrF,CAEA,SAAS,EAAe,EAA0C,CAChE,IAAM,EAAQ,EAAO,EAAO,uBAAuB,EAC7C,EAAQ,IAAI,IAAI,CACpB,OAAQ,OAAQ,YAAa,UAAW,OAAQ,YAAa,QAC/D,CAAC,EACD,GAAI,OAAO,KAAK,CAAK,CAAC,CAAC,KAAK,GAAO,CAAC,EAAM,IAAI,CAAG,CAAC,EAChD,MAAU,UAAU,8CAA8C,EAEpE,MAAO,CACL,KAAM,EAAS,EAAM,KAAM,aAAa,EACxC,GAAI,EAAM,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAW,EAAM,IAAI,CAAE,EACnE,GAAI,EAAM,YAAc,IAAA,GACpB,CAAC,EACD,CAAE,UAAW,EAAS,EAAM,UAAW,kBAAkB,CAAE,EAC/D,GAAI,EAAM,UAAY,IAAA,GAAY,CAAC,EAAI,CAAE,QAAS,EAAa,EAAM,OAAO,CAAE,EAC9E,GAAI,EAAM,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAS,EAAM,KAAM,aAAa,CAAE,EAChF,GAAI,EAAM,YAAc,IAAA,GACpB,CAAC,EACD,CAAE,UAAW,EAAY,EAAM,UAAW,WAAW,CAAE,EAC3D,GAAI,EAAM,SAAW,IAAA,GAAY,CAAC,EAAI,CAAE,OAAQ,EAAY,EAAM,OAAQ,QAAQ,CAAE,CACtF,CACF,CAEA,SAAS,EAAY,EAAgB,EAAkC,CACrE,GAAI,CAAC,MAAM,QAAQ,CAAK,EAAG,MAAU,UAAU,GAAG,EAAM,6BAA6B,EACrF,OAAO,EAAM,IAAI,GAAS,EAAS,EAAO,GAAG,EAAM,OAAO,CAAC,CAC7D,CAEA,SAAS,EAAa,EAA0C,CAC9D,GAAI,IAAU,SAAW,IAAU,OACjC,MAAU,UAAU,0CAA0C,EAEhE,OAAO,CACT,CAuBA,SAAgB,EACd,EACyB,CACzB,IAAM,EAAU,IAAI,IAChB,EAAM,EAqBV,OApBA,EAAS,QAAQ,SAAS,EAAO,IAAU,CACzC,IAAM,EAAQ,EAAM,MACpB,GAAI,EAAM,OAAS,YAAa,EAAQ,IAAI,EAAM,MAAM,OACnD,GAAI,EAAM,OAAS,cAAe,EAAQ,OAAO,EAAM,MAAM,OAC7D,GAAI,EAAM,OAAS,YAMjB,IAAA,IAAM,KAAS,EAAM,QAAQ,QAC5B,EAAM,OAAS,aAAa,EAAQ,IAAI,EAAM,EAAE,EAKxC,EAAQ,OAAS,IAC1B,EAAM,OAAS,aAAe,EAAM,cAAgB,MAC9C,EAAM,EAAQ,EAC7B,CAAC,EACM,EAAS,QAAQ,MAAM,EAAG,CAAG,CACtC,CAEA,SAAS,EAAO,EAAgB,EAAwC,CACtE,GAAI,OAAO,GAAU,WAAY,GAAkB,MAAM,QAAQ,CAAK,EACpE,MAAU,UAAU,GAAG,EAAM,mBAAmB,EAElD,OAAO,CACT,CAEA,SAAS,EAAW,EAAwB,CAC1C,IAAM,EAAO,EAAS,EAAO,oBAAoB,EACjD,GAAI,CAAC,2BAA2B,KAAK,CAAI,EACvC,MAAU,UAAU,sFAAsF,EAE5G,GAAI,EAAK,OAAS,IAAK,MAAU,UAAU,mDAAmD,EAC9F,OAAO,CACT,CAEA,SAAS,EAAS,EAAgB,EAAuB,CACvD,GAAI,OAAO,GAAU,UAAY,EAAM,KAAK,CAAC,CAAC,SAAW,EACvD,MAAU,UAAU,GAAG,EAAM,4BAA4B,EAE3D,OAAO,CACT,CAEA,SAAS,EAAc,EAAgB,EAAe,EAA0B,CAC9E,IAAM,EAAO,EAAS,EAAO,CAAK,EAClC,GAAI,IAAI,YAAY,CAAC,CAAC,OAAO,CAAI,CAAC,CAAC,WAAa,EAC9C,MAAU,UAAU,GAAG,EAAM,eAAe,EAAS,YAAY,EAEnE,OAAO,CACT,CAEA,SAAS,EAAgB,EAAe,EAAuB,CAC7D,GAAI,CAAC,OAAO,cAAc,CAAK,GAAK,EAAQ,EAAG,MAAU,UAAU,GAAG,EAAM,4BAA4B,EACxG,OAAO,CACT,CAEA,SAAS,EAAa,EAAwB,CAC5C,OAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,CAC9D,CAEA,eAAe,EAAa,EAAqB,EAAkC,CACjF,GAAI,IAAW,IAAA,GAAW,OAAO,EACjC,GAAI,EAAO,QAIT,MADA,EAAa,UAAY,IAAA,EAAS,EAC5B,EAAO,QAAc,MAAM,wBAAwB,EAE3D,OAAO,MAAM,IAAI,SAAY,EAAS,IAAW,CAC/C,IAAM,MAAc,CAClB,EAAO,oBAAoB,QAAS,CAAK,EACzC,EAAO,EAAO,QAAc,MAAM,wBAAwB,CAAC,CAC7D,EACA,EAAO,iBAAiB,QAAS,EAAO,CAAE,KAAM,EAAK,CAAC,EACtD,EAAa,KACX,GAAS,CAAE,EAAO,oBAAoB,QAAS,CAAK,EAAG,EAAQ,CAAK,CAAE,EACtE,GAAS,CAAE,EAAO,oBAAoB,QAAS,CAAK,EAAG,EAAO,CAAK,CAAE,CACvE,CACF,CAAC,CACH,CAEA,SAAS,EAAe,GAAG,EAA4D,CACrF,IAAM,EAAS,EAAQ,OAAQ,GAAwC,IAAc,IAAA,EAAS,EAC9F,OAAO,EAAO,SAAW,EAAI,EAAO,GAAM,YAAY,IAAI,CAAM,CAClE,CAEA,SAAS,EAAO,EAA2B,CAAE,OAAO,CAAmB,CAGvE,MAAM,EACJ,IAAI,IAA8B,CAAC,YAAa,SAAU,QAAQ,CAAC,EAkBrE,SAAS,EAAU,EAAyB,EAA0C,CACpF,IAAM,EAAS,EAAS,QAAQ,OAChC,GAAI,EAAO,OAAS,QAAS,OAAO,EAAO,QAAQ,QACnD,GAAI,EAAO,OAAS,aAAc,MAAO,wCACzC,GAAI,EAAO,OAAS,oBAAqB,MAAO,mDAChD,GAAI,EAAO,OAAS,UAAW,MAAO,sBACtC,GAAI,EAAO,OAAS,oBAAsB,CAAC,EAAS,QAAQ,UAC1D,MAAO,0BAA0B,EAAO,OAAO,mCAGjD,GAAI,GAAe,EAAS,KAAK,KAAK,IAAM,GAAI,MAAO,uBAEzD,CAEA,SAAS,EAAoB,EAAwB,CACnD,IAAM,EAAO,EAAS,EAAO,oBAAoB,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,GAAG,EAC9E,GAAI,EAAK,WAAW,GAAG,GAAK,aAAa,KAAK,CAAI,EAChD,MAAU,UAAU,iDAAiD,EAEvE,IAAM,EAAkB,CAAC,EACzB,IAAK,IAAM,KAAQ,EAAK,MAAM,GAAG,EAC3B,OAAS,IAAM,IAAS,IAC5B,IAAI,IAAS,KAAM,CACjB,GAAI,EAAM,SAAW,EAAG,MAAU,UAAU,oDAAoD,EAChG,EAAM,IAAI,CACZ,MAAO,EAAM,KAAK,CAAI,CAAA,CAExB,GAAI,EAAM,SAAW,EACnB,MAAU,UAAU,6EAA6E,EAEnG,OAAO,EAAM,KAAK,GAAG,CACvB,CAGA,SAAS,EAAc,EAAc,EAAwB,CAC3D,OAAO,IAAS,GAAS,EAAK,WAAW,GAAG,EAAM,EAAE,GAAK,EAAM,WAAW,GAAG,EAAK,EAAE,CACtF,CAGA,SAAS,EAAkB,EAAc,EAA0B,CACjE,OAAO,IAAI,YAAY,QAAS,CAAE,MAAO,EAAM,CAAC,CAAC,CAAC,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,CAAI,CAAC,CAAC,SAAS,EAAG,CAAQ,EAAG,CAAE,OAAQ,EAAK,CAAC,CACjI,CAGA,SAAS,EAAS,EAAc,EAA0B,CACxD,IAAM,EAAU,IAAI,YAAY,CAAC,CAAC,OAAO,CAAI,EAC7C,GAAI,EAAQ,YAAc,EAAU,OAAO,EAC3C,IAAM,EAAS;;EACT,EAAc,IAAI,YAAY,CAAC,CAAC,OAAO,CAAM,CAAC,CAAC,WACrD,GAAI,GAAY,EAAa,OAAO,EAAkB,cAAe,CAAQ,EAC7E,IAAM,EAAY,EAAW,EACvB,EAAO,EAAkB,EAAM,KAAK,KAAK,EAAY,CAAC,CAAC,EACzD,EAAY,EAAQ,OAAS,KAAK,MAAM,EAAY,CAAC,EACzD,KAAO,EAAY,EAAQ,SAAW,EAAQ,GAAc,MAAU,KAAM,IAC5E,IAAM,EAAO,IAAI,YAAY,CAAC,CAAC,OAAO,EAAQ,SAAS,CAAS,CAAC,EACjE,OAAO,EAAO,EAAS,CACzB,CAGA,SAAS,EAAe,EAA8B,CACpD,EAAQ,SAAS,OAAS,EAAQ,OAClC,EAAQ,SAAS,OAAS,EAAQ,OAClC,EAAQ,SAAS,MAAQ,EAAQ,KACnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team.d.ts","names":[],"sources":["../../../src/agent/team/team.ts"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"team.d.ts","names":[],"sources":["../../../src/agent/team/team.ts"],"mappings":";;;;;;;;;cA8Ea,qBAAqB;mBA4Bb;WA3BV;mBACQ;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;UACT;UACA;mBACS;mBACA;mBACA;UACT;UACA;UACA;mBACS;mBACA;UACT;UACA;EAER,YACE,UAAS,kBACQ,kBAAiB,QAAQ;;EA2B5C,OAAO,SAAS,iBAAiB,UAAS;;EA2B1C,UAAU,SAAS;;EAyBnB,OAAO;;EAUP,oBAAoB;;EAQpB,qBAAqB;;EAKf,YAAY,SAAS,0BAA0B,QAAQ;;EA4E7D,SACE,cACA,gBACA,2BAA2B,gBAC3B,SAAS,cACR,QAAQ;;EAQL,SAAS,cAAc,SAAS,cAAc;;;;;;;;;;EAoCpD,YAAY;;;;;;;;;;;EAiBZ,KAAK;;EAMC,OAAO,cAAc,mBAA2D;;EA2BtF,QAAQ,mBAAmD;;EAmC3D,SAAS,gBAAgB,SAAQ,0BAAmC;;EAwIpE,gBAAgB;UAsBF;UA+CN;;MAoBJ;UAEU;UAqEN;;;;;;;;;;;;;;;;;EAuBR,UAAU,gBAAgB;UA2BlB;UAUA;UAOA;UAMA;UAMA;UAIA;;;;;;;;;;;EA4BR,cAAc,cAAc,SAAS;;;;;;;;;;;;;;;;EAqBrC,YAAY,cAAc,OAAO;UAIzB;UA2BA;UAIM"}
|