@ponythewhite/base-context 1.0.13 → 1.0.14
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/CHANGELOG.md +9 -0
- package/dist/base-context-runtime/pyproject.toml +1 -1
- package/dist/base-context-runtime/uv.lock +1 -1
- package/dist/build-info.json +1 -1
- package/dist/bundle/amazon-bedrock.js +3 -3
- package/dist/bundle/{anthropic-BJVPUMPB.js → anthropic-AXUXEET7.js} +1 -1
- package/dist/bundle/{azure-openai-responses-ERRMAXK6.js → azure-openai-responses-J3NTJKEO.js} +2 -2
- package/dist/bundle/{bundled-modules-URKVA3UB.js → bundled-modules-UODO7ZR7.js} +5 -5
- package/dist/bundle/{chunk-FOGKLC7V.js → chunk-72LSQYUV.js} +1 -1
- package/dist/bundle/{chunk-MUFZODP5.js → chunk-EGFIZABJ.js} +1 -1
- package/dist/bundle/{chunk-AEMRBMI2.js → chunk-IEM74GZ5.js} +9 -9
- package/dist/bundle/{chunk-25VYRAC6.js → chunk-JKKXN6JE.js} +72 -0
- package/dist/bundle/{chunk-TXVF6Q5H.js → chunk-NLRWERWA.js} +37 -32
- package/dist/bundle/{chunk-TKOBEJ5E.js → chunk-SX7CAXWU.js} +22 -4
- package/dist/bundle/{chunk-Q6UAHLII.js → chunk-V6LOBH6X.js} +2 -2
- package/dist/bundle/{cli-main-ZTJM5EEH.js → cli-main-6GXXIMQQ.js} +4 -4
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/{google-4GA4YMUX.js → google-QLKV2ZLC.js} +2 -2
- package/dist/bundle/{google-vertex-7AMALD7D.js → google-vertex-UGLUZV6B.js} +2 -2
- package/dist/bundle/{main-53I74INO.js → main-HF64B4HM.js} +5 -5
- package/dist/bundle/{mistral-74BXMNRM.js → mistral-2ITSLHYF.js} +1 -1
- package/dist/bundle/{openai-codex-responses-COXNC4IH.js → openai-codex-responses-FRREQXS3.js} +5 -4
- package/dist/bundle/{openai-completions-BCSA5Q6S.js → openai-completions-HF6UPPLW.js} +1 -1
- package/dist/bundle/{openai-responses-ONCIZSJS.js → openai-responses-LRTMBDFW.js} +2 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +6 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomous.d.ts +2 -0
- package/dist/core/autonomous.d.ts.map +1 -1
- package/dist/core/autonomous.js +4 -0
- package/dist/core/autonomous.js.map +1 -1
- package/dist/core/canonical-context.d.ts.map +1 -1
- package/dist/core/canonical-context.js +7 -0
- package/dist/core/canonical-context.js.map +1 -1
- package/dist/core/public-context.d.ts.map +1 -1
- package/dist/core/public-context.js +2 -0
- package/dist/core/public-context.js.map +1 -1
- package/dist/core/view-units.d.ts.map +1 -1
- package/dist/core/view-units.js +3 -0
- package/dist/core/view-units.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/daemon/daemon-mode.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-mode.js +4 -3
- package/dist/modes/daemon/daemon-mode.js.map +1 -1
- package/dist/modes/daemon/daemon-supervisor.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-supervisor.js +11 -5
- package/dist/modes/daemon/daemon-supervisor.js.map +1 -1
- package/dist/modes/daemon/daemon-worker-protocol.d.ts +3 -0
- package/dist/modes/daemon/daemon-worker-protocol.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-worker-protocol.js +2 -0
- package/dist/modes/daemon/daemon-worker-protocol.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +24 -21
- package/dist/modes/print-mode.js.map +1 -1
- package/docs/json.md +14 -1
- package/docs/long-running-agents.md +23 -2
- package/docs/providers.md +17 -0
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session.d.ts","sourceRoot":"","sources":["../../src/core/agent-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { randomUUID } from \"node:crypto\";\nimport { existsSync, mkdirSync, mkdtempSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport {\n\tAgent,\n\ttype AgentContext,\n\ttype AgentContinuationOutcome,\n\tAgentContinueError,\n\ttype AgentEvent,\n\ttype AgentMessage,\n\tAgentOutputLimitError,\n\ttype AgentOutputLimits,\n\ttype AgentState,\n\ttype AgentTool,\n\ttype AgentTurnOutcome,\n\ttype BoundToolExecution,\n\ttype GetContinuationMessagesContext,\n\ttype GetTurnOutcomeContext,\n\ttype ShouldStopAfterTurnContext,\n\ttype ThinkingLevel,\n} from \"@ponythewhite/base-context-agent\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tImageContent,\n\tModel,\n\tRequestTokenBudgetOptions,\n\tServiceTier,\n\tTextContent,\n\tUsage,\n\tUserMessage,\n} from \"@ponythewhite/base-context-ai\";\nimport {\n\tclampThinkingLevel,\n\tcleanupSessionResources,\n\tconservativeTextTokenCost,\n\tgetSupportedThinkingLevels,\n\tisContextOverflow,\n\tisTransientProviderFailure,\n\tmodelsAreEqual,\n\tresetApiProviders,\n\tsupportsFastMode,\n} from \"@ponythewhite/base-context-ai\";\nimport { theme } from \"../modes/interactive/theme/theme.js\";\nimport { PRODUCT } from \"../product-identity.js\";\n\nimport { sleep } from \"../utils/sleep.js\";\nimport {\n\tAGENT_MESSAGE_CUSTOM_TYPE,\n\tAGENT_MESSAGE_RECEIVED_PREVIEW_LABEL,\n\tAGENT_MESSAGE_SKILL_NAME,\n\ttype AgentFamilyCatalogEntry,\n\ttype AgentFamilyRosterResult,\n\ttype AgentSessionMessage,\n\ttype AgentSessionMessageAgentSummary,\n\ttype AgentSessionMessageController,\n\ttype AgentSessionMessageListResult,\n\ttype AgentSessionMessageReceipt,\n\tassertAgentMessageQueueCapacity,\n\tassertAgentSessionNameAvailable,\n\tassertDirectAgentMessageTarget,\n\tcreateAgentMessageHostHandlers,\n\tDEFAULT_AGENT_MESSAGE_MAX_PENDING_PER_SESSION,\n\tformatAgentSessionNameUnavailable,\n\tisAgentSessionMessage,\n\tisAgentSessionMessagePrompt,\n\tnormalizeAgentSessionMessage,\n\tparseAgentSessionMessagePromptId,\n\tstartsAgentRun,\n} from \"./agent-messages.js\";\nimport {\n\tAGENT_OBSERVE_SKILL_NAME,\n\ttype AgentObserveAgentSnapshot,\n\ttype AgentObserveController,\n\ttype AgentObserveListResult,\n\ttype AgentObserveRecentMessagesResult,\n\tcreateAgentObserveHostHandlers,\n\tnormalizeObserveLimit,\n\tnormalizeObserveMaxChars,\n\tORCHESTRATION_HEARTBEAT_SKILL_NAME,\n} from \"./agent-observe.js\";\nimport {\n\taddLoginGuidanceToAuthError,\n\tformatAuthenticationFailedMessage,\n\tformatNoApiKeyFoundMessage,\n\tformatNoModelSelectedMessage,\n\tisLikelyAuthenticationError,\n} from \"./auth-guidance.js\";\nimport type { AuthSourceToken } from \"./auth-storage.js\";\nimport {\n\ttype AgentAutonomousConfig,\n\ttype AgentAutonomousStatus,\n\ttype AutonomousRuntimeState,\n\taddAutonomousContinuation,\n\taddAutonomousUsage,\n\tautonomousStatus,\n\tcreateAutonomousRuntimeState,\n\tnextAutonomousContinuation,\n\trefreshAutonomousQualityGates,\n\tsetAutonomousEnabled,\n} from \"./autonomous.js\";\nimport { type BashResult, executeBashWithOperations } from \"./bash-executor.js\";\nimport { stringifyBoundedJson } from \"./bounded-json.js\";\nimport {\n\tCanonicalContextCompiler,\n\tcanonicalRecoveryBoundary,\n\tgetCanonicalEpochContext,\n\tgetCanonicalMessageSource,\n\tgetCanonicalViewSelectionSource,\n\tgetCanonicalViewUnits,\n\tMissingRecoveryReplayContractError,\n\tprepareCanonicalEpoch,\n\tprepareContextModeEpoch,\n\tprepareRecoveryCompaction,\n\treadCanonicalContextMode,\n} from \"./canonical-context.js\";\nimport {\n\ttype BranchSummaryResult,\n\tCOMPACT_SKILL_NAME,\n\ttype CompactionPreparation,\n\ttype CompactionResult,\n\tcalculateContextTokens,\n\tcollectEntriesForBranchSummary,\n\tcompact,\n\testimateContextTokens,\n\testimateFixedCompactionTokens,\n\tgenerateBranchSummary,\n\tprepareCompaction,\n\tprepareViewCompaction,\n\tserializeConversation,\n\tshouldCompact,\n\ttakeNativeBranchSummaryWrite,\n} from \"./compaction/index.js\";\nimport {\n\tappendContextEpoch,\n\tassertContextRequestContract,\n\tCONTEXT_EPOCH_DETAIL,\n\tCONTEXT_SKILL_EPOCH_RENDERER,\n\ttype ContextMode,\n\ttype ContextReplayContract,\n\tcontextEpochMode,\n\tcontextEpochRepresentation,\n\tcontextRequestContract,\n\treadContextEpoch,\n\tretainedContextRequestContract,\n\tsnapshotContextEpoch,\n\tUnsupportedContextEpochConfigurationError,\n} from \"./context-epoch.js\";\nimport {\n\ttype ContextTreeNode,\n\tContextTreeRequest,\n\ttype ContextTreeRequestLimits,\n\ttype ContextWindowResolver,\n\tcomputeOwnAndTotalUsage,\n\tloadContextTreeChildFromDisk,\n\tloadContextTreeChildrenFromDisk,\n\treadContextTreeUsage,\n\treadResidentContextTreeUsage,\n} from \"./context-tree.js\";\nimport type { AgentCronJob, AgentRlmHeartbeatController, AgentRlmHeartbeatStatusUpdate } from \"./cron-jobs.js\";\nimport { normalizeHeartbeatDeliveryMode } from \"./cron-jobs.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport { exportSessionToHtml, type ToolHtmlRenderer } from \"./export-html/index.js\";\nimport { createToolHtmlRenderer } from \"./export-html/tool-renderer.js\";\nimport {\n\ttype ContextUsage,\n\ttype ExtensionCommandContextActions,\n\ttype ExtensionErrorListener,\n\tExtensionRunner,\n\ttype ExtensionUIContext,\n\ttype InputSource,\n\ttype MessageEndEvent,\n\ttype MessageStartEvent,\n\ttype MessageUpdateEvent,\n\ttype ReplacedSessionContext,\n\ttype SessionBeforeCompactResult,\n\ttype SessionBeforeRefineResult,\n\ttype SessionBeforeTreeResult,\n\ttype SessionStartEvent,\n\ttype ShutdownHandler,\n\ttype ToolDefinition,\n\ttype ToolExecutionEndEvent,\n\ttype ToolExecutionStartEvent,\n\ttype ToolExecutionUpdateEvent,\n\ttype ToolInfo,\n\ttype TreePreparation,\n\ttype TurnEndEvent,\n\ttype TurnStartEvent,\n\twrapRegisteredTools,\n} from \"./extensions/index.js\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.js\";\nimport {\n\tcreateGoalContextMessage,\n\temptyGoalState,\n\tGOAL_CONTEXT_CUSTOM_TYPE,\n\tGOAL_CONTEXT_PREVIEW_LABEL,\n\tGOAL_SKILL_NAME,\n\tGOAL_STATE_CUSTOM_TYPE,\n\ttype GoalHostResponse,\n\ttype GoalState,\n\ttype GoalStatus,\n\tgoalHostResponse,\n\tgoalTokenDeltaForUsage,\n\tisPersistedGoalState,\n\tnormalizeGoalState,\n\tvalidateGoalBudget,\n\tvalidateGoalObjective,\n} from \"./goals.js\";\nimport type { ContextManifestCursor, ContextRef, IpythonSentMessagesCursor } from \"./history-index.js\";\nimport {\n\tcaptureNativeBranchRequests,\n\tcaptureNativeCompactionRequests,\n\tcaptureNativePlannerRequests,\n\tcaptureNativeReviewerRequests,\n\tInferenceCoordinator,\n\ttype SessionRuntimeServices,\n\ttakeNativeInferenceAuthSource,\n} from \"./inference-coordinator.js\";\nimport type { HostRequestHandlers, KernelSentAgentMessage } from \"./kernel/index.js\";\nimport { type RestoreResult, snapshotPathIn } from \"./kernel/state-snapshot.js\";\nimport type { AcpMcpServerConfig } from \"./mcp/acp-mcp-types.js\";\nimport type { McpManager } from \"./mcp/mcp-manager.js\";\nimport {\n\ttype BashExecutionMessage,\n\ttype CompactionOutcome,\n\ttype CompactionOutcomeReason,\n\ttype CustomMessage,\n\tconvertToLlm,\n\tcreateCompactionOutcomeMessage,\n\tcreateHeartbeatPromptMessage,\n\tcreateRefinementOutcomeMessage,\n\tcreateRlmChildFailureMessage,\n\tcreateRlmChildTerminalNoticeMessage,\n\tcreateSessionSlashCommandMessage,\n\tcreateSessionSlashCommandResultMessage,\n\tHARNESS_SNAPSHOT_CUSTOM_TYPE,\n\tHEARTBEAT_PROMPT_CUSTOM_TYPE,\n\tHEARTBEAT_PROMPT_PREVIEW_LABEL,\n\tIPYTHON_STATE_RESTORED_CUSTOM_TYPE,\n\tisSessionSlashCommandMessage,\n\tRLM_CHILD_FAILURE_CUSTOM_TYPE,\n\tRLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE,\n} from \"./messages.js\";\nimport type { ModelRegistry } from \"./model-registry.js\";\nimport { throwIfPromptAdmissionCancelled } from \"./prompt-admission.js\";\nimport { expandPromptTemplate, type PromptTemplate } from \"./prompt-templates.js\";\nimport {\n\ttype AutoRefineReason,\n\ttype AutoRefineReview,\n\tappendGlobalRefinement,\n\tapplyRefinementProposal,\n\tformatHarnessStateForPrompt,\n\tgenerateRefinementId,\n\tgetGlobalHarnessStateDir,\n\tgetLocalHarnessStateDir,\n\tgetRefinementHistory,\n\tgetWorkspaceHarnessStateDir,\n\ttype HarnessState,\n\tinferRefinementResultScope,\n\tloadGlobalRefinementHistory,\n\tloadHarnessState,\n\tmergeHarnessStates,\n\tmergeRefinementHistory,\n\tnormalizeRefinementProposal,\n\tplanRefinement,\n\tprepareRefinementApplication,\n\tREFINE_SKILL_NAME,\n\ttype RefinementPlan,\n\ttype RefinementResult,\n\treviewAutoRefine,\n\tsaveHarnessState,\n\ttakeNativePlannerRequestWrite,\n\twithRefinementBaseline,\n} from \"./refinement/index.js\";\nimport { getRecoveryCompactionAuthorization, PublicContextBudgetError } from \"./request-view-selection.js\";\nimport { resolveConfigValue } from \"./resolve-config-value.js\";\nimport type { ResourceExtensionPaths, ResourceLoader } from \"./resource-loader.js\";\nimport { assertResourceCurrent, type OwnedResourceCapture } from \"./resource-view.js\";\nimport {\n\ttype CreateRlmSubagentRuntimeOptions,\n\tcreateDefaultRlmSubagentSessionName,\n\tcreateRlmDeleteSubagentHostHandler,\n\tcreateRlmFindModelsHostHandler,\n\tcreateRlmListSubagentsHostHandler,\n\tcreateRlmRunHostHandler,\n\tfindRlmModelMatches,\n\tnormalizeRequestedRlmSubagentModel,\n\tnormalizeRequestedRlmSubagentSessionName,\n\tnormalizeRequestedRlmSubagentThinkingLevel,\n\ttype RlmChildAdmission,\n\ttype RlmDeleteSubagentResult,\n\ttype RlmFindModelsResult,\n\ttype RlmListSubagentsResult,\n\ttype RlmSpawnHandle,\n\ttype RlmSubagentRegistryEntry,\n\ttype RlmSubagentRuntime,\n\ttype SubagentRuntimeHost,\n} from \"./rlm-runtime.js\";\nimport {\n\ttype CapturedSkillSelectionWriter,\n\tcaptureSelectedSkill,\n\tcaptureSkillDescriptor,\n\ttype NativeSkillSourceRef,\n\treadSkillSelection,\n\ttype SelectedSkillCapture,\n\tsameSelectedSkills,\n\tselectedSkillBlock,\n\tselectedSkillIdentity,\n} from \"./selected-skills.js\";\nimport {\n\tcreateNativeRecoveryRefusal,\n\tDEFAULT_NATIVE_RECOVERY_LIMITS,\n\tNativeRecoveryBudgetRefusal,\n\tNativeRecoveryCursorStore,\n\ttype NativeRecoveryInput,\n\ttype NativeRecoveryResponse,\n\tparseNativeRecoveryInput,\n\trecoverCapturedHistory,\n} from \"./selective-recovery.js\";\nimport {\n\tmodelRequestHeaders,\n\tSemanticEdgeRecorder,\n\tsemanticEdgeLedgerPath,\n\twrapStreamFnWithSemanticEdges,\n} from \"./semantic-edges.js\";\nimport {\n\tActionStore,\n\ttype ActionTicket,\n\tcanSelectSessionAction,\n\ttype DeliveryPolicy,\n\ttype DeliveryRecord,\n\ttype QueuedMessageLane,\n\ttype QueuedMessageMutation,\n\ttype QueuedMessageMutationStatus,\n\tqueuedMessageLaneDeliveryPolicy,\n\ttype RuntimeActivity,\n\ttype SessionAction,\n\ttype SessionActionSnapshot,\n\ttype SessionCommandPayload,\n\ttype SessionTurnPayload,\n\ttransitionSessionAction,\n\ttype WakePolicy,\n} from \"./session-action-store.js\";\nimport { readSessionBootstrap } from \"./session-bootstrap.js\";\nimport {\n\tappendSentAgentMessageToToolResult,\n\tIPYTHON_SENT_AGENT_MESSAGE_CUSTOM_ENTRY,\n\tparsePersistedIpythonSentAgentMessage,\n} from \"./session-context-updates.js\";\nimport { ContextUsageReader } from \"./session-context-usage.js\";\nimport {\n\tbindNativeEntryWriter,\n\ttype CapturedNativeGoalWrite,\n\ttype CapturedNativeMessageWrite,\n\ttype NativeEntryOrigin,\n\ttype NativeEntryWriter,\n\ttype NativeSubmittedInput,\n} from \"./session-entry-origin.js\";\nimport { readUserMessagesForForking } from \"./session-fork-messages.js\";\nimport {\n\thydrateCapturedHistoryEntry,\n\ttype SessionHistoryReadLimits,\n\ttype SessionHistoryReadView,\n} from \"./session-history-index.js\";\nimport { exportSessionBranchToJsonl } from \"./session-jsonl-export.js\";\nimport {\n\ttype BoundCompactionSink,\n\ttype BranchSummaryEntry,\n\tgetLatestCompactionEntry,\n\ttype SessionContext,\n\ttype SessionEntry,\n\tSessionManager,\n} from \"./session-manager.js\";\nimport type { SessionStats } from \"./session-stats.js\";\nimport type { SettingsManager } from \"./settings-manager.js\";\nimport { getPythonSkillRuntimeInfo, type Skill } from \"./skills.js\";\n\nimport {\n\tparseRefineCommandOptions,\n\tparseSessionSlashCommand,\n\tparseSlashCommand,\n\ttype SessionSlashCommand,\n\ttype SlashCommandInfo,\n} from \"./slash-commands.js\";\nimport { createSyntheticSourceInfo, type SourceInfo } from \"./source-info.js\";\nimport { type BuildSystemPromptOptions, buildSystemPrompt } from \"./system-prompt.js\";\nimport { THINKING_LEVELS } from \"./thinking-levels.js\";\nimport { acpMcpToolNames, createAcpMcpToolDefinitions } from \"./tools/acp-mcp.js\";\nimport { type BashOperations, createLocalBashOperations } from \"./tools/bash.js\";\nimport { createAllToolDefinitions } from \"./tools/index.js\";\nimport { IpythonKernelProvisioner } from \"./tools/ipython.js\";\nimport { createToolDefinitionFromAgentTool } from \"./tools/tool-definition-wrapper.js\";\nimport { type SessionUsageSummary, sessionUsageSummaryFrom } from \"./usage.js\";\nimport { SERPER_CREDENTIAL_ID, SERPER_ENV_VAR, WEBSEARCH_SKILL_NAME } from \"./websearch-credential.js\";\n\n// The native owner reads its actual provisioner, not a replaceable public reader method.\nconst captureOwnedKernelState = IpythonKernelProvisioner.prototype.captureKernelState;\n\nexport type { GoalState, GoalStatus } from \"./goals.js\";\nexport type { SessionStats } from \"./session-stats.js\";\nexport { type ParsedSkillBlock, parseSkillBlock } from \"./skill-blocks.js\";\n\nexport type RlmChildAgentStatus = \"queued\" | \"running\" | \"done\" | \"error\" | \"cancelled\";\n\nexport interface RlmChildAgentActivity {\n\tkind: \"waiting\" | \"writing\" | \"executing\";\n\ttoolName?: string;\n}\n\nexport interface RlmChildAgentSnapshot {\n\tid: string;\n\tparentId?: string;\n\tactiveSessionId?: string;\n\tsessionName?: string;\n\tmodel?: string;\n\tlabel: string;\n\tstatus: RlmChildAgentStatus;\n\tdurationMs?: number;\n\tanswerPreview?: string;\n\ttoolUseCount?: number;\n\ttokenCount?: number;\n\trecap?: string;\n\tsessionDir: string;\n\tactivity?: RlmChildAgentActivity;\n\trepliedSinceTask?: boolean;\n\terror?: string;\n}\n\nexport type CompactionReason = \"manual\" | \"threshold\" | \"overflow\" | \"requested\";\n\nexport type AgentSessionEvent =\n\t| AgentEvent\n\t| {\n\t\t\ttype: \"ipython_sent_agent_message\";\n\t\t\ttoolCallId: string;\n\t\t\tmessage: KernelSentAgentMessage;\n\t }\n\t| { type: \"session_action_update\"; actions: SessionActionSnapshot }\n\t| {\n\t\t\ttype: \"compaction_start\";\n\t\t\treason: CompactionReason;\n\t\t\tcustomInstructions?: string;\n\t }\n\t| { type: \"session_info_changed\"; name: string | undefined }\n\t| { type: \"thinking_level_changed\"; level: ThinkingLevel }\n\t| { type: \"service_tier_changed\"; serviceTier: ServiceTier }\n\t| {\n\t\t\ttype: \"compaction_end\";\n\t\t\treason: CompactionReason;\n\t\t\tresult: CompactionResult | undefined;\n\t\t\taborted: boolean;\n\t\t\twillRetry: boolean;\n\t\t\terrorMessage?: string;\n\t\t\terrorSeverity?: \"warning\" | \"error\";\n\t\t\tcustomInstructions?: string;\n\t }\n\t| {\n\t\t\ttype: \"auto_retry_start\";\n\t\t\tattempt: number;\n\t\t\tmaxAttempts?: number;\n\t\t\tdelayMs: number;\n\t\t\terrorMessage: string;\n\t }\n\t| {\n\t\t\ttype: \"auto_retry_end\";\n\t\t\tsuccess: boolean;\n\t\t\tattempt: number;\n\t\t\tfinalError?: string;\n\t }\n\t| {\n\t\t\ttype: \"auth_stale\";\n\t\t\tprovider: string;\n\t\t\tsourceTokens?: readonly AuthSourceToken[];\n\t }\n\t| { type: \"rlm_child_update\"; child: RlmChildAgentSnapshot }\n\t| { type: \"recap_update\"; recap: string | undefined }\n\t| { type: \"goal_update\"; goal: GoalState }\n\t| {\n\t\t\ttype: \"bash_start\";\n\t\t\tcommand: string;\n\t\t\texcludeFromContext: boolean;\n\t\t\ttransient?: boolean;\n\t\t\trunId?: string;\n\t }\n\t| { type: \"bash_output\"; chunk: string }\n\t| {\n\t\t\ttype: \"bash_end\";\n\t\t\texitCode: number | undefined;\n\t\t\tcancelled: boolean;\n\t\t\ttruncated: boolean;\n\t\t\tfullOutputPath?: string;\n\t\t\terrorMessage?: string;\n\t\t\ttransient?: boolean;\n\t\t\trunId?: string;\n\t }\n\t| { type: \"refine_complete\"; result: RefinementResult }\n\t| { type: \"refine_failed\"; error: string };\n\nexport type AgentSessionEventListener = (event: AgentSessionEvent) => void;\n\ntype UserBashEndDetails = {\n\texitCode: number | undefined;\n\tcancelled: boolean;\n\ttruncated: boolean;\n\tfullOutputPath?: string;\n\terrorMessage?: string;\n};\n\nexport class CompactionSkippedError extends Error {}\n\ninterface CompactionCommit {\n\tentryId: string;\n\tresult: CompactionResult;\n}\n\n/** The canonical compaction is already ACKed; only subsequent setup failed. */\nexport class CompactionCommittedError extends Error {\n\tconstructor(\n\t\treadonly entryId: string,\n\t\treadonly result: CompactionResult,\n\t\tcause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Compaction ${entryId} committed, but setup failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\t{ cause },\n\t\t);\n\t\tthis.name = \"CompactionCommittedError\";\n\t}\n}\n\nfunction primaryCommittedCompactionError(error: unknown): CompactionCommittedError | undefined {\n\twhile (error instanceof AggregateError) error = error.errors[0];\n\treturn error instanceof CompactionCommittedError ? error : undefined;\n}\n\n/** Thrown when a session_before_refine extension skips the refinement round. */\nexport class RefineSkippedError extends Error {}\n\nexport interface AgentSessionConfig {\n\t/** Explicit request budget profiles; absent preserves control behavior. */\n\trequestTokenBudget?: RequestTokenBudgetOptions;\n\tcontextMode?: ContextMode;\n\t/** Override native invocationOutput settings; complete finalized values or explicit refusal. */\n\tinvocationOutputLimits?: AgentOutputLimits;\n\tagent: Agent;\n\tsessionManager: SessionManager;\n\tsettingsManager: SettingsManager;\n\tserviceTierPreference?: ServiceTier;\n\tcwd: string;\n\tagentDir?: string;\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\tresourceLoader: ResourceLoader;\n\tcustomTools?: ToolDefinition[];\n\tmodelRegistry: ModelRegistry;\n\tinitialActiveToolNames?: string[];\n\tallowedToolNames?: string[];\n\t/**\n\t * Whether the built-in long-running goals feature is available: the bundled\n\t * goal skill in the Python kernel, its goal.* host handlers, and /goal.\n\t * Default: true.\n\t */\n\tincludeGoals?: boolean;\n\tagentMessageController?: AgentSessionMessageController;\n\tagentObserveController?: AgentObserveController;\n\t/**\n\t * Whether the bundled compact skill and its compact.* host handlers are\n\t * available to the model. Default: the compaction.agentCallable setting.\n\t */\n\tincludeCompactSkill?: boolean;\n\t/**\n\t * Optional host-side controller for the bundled rlm-heartbeat Python skill.\n\t * When omitted, rlm_heartbeat.* host requests are unavailable.\n\t */\n\trlmHeartbeatController?: AgentRlmHeartbeatController;\n\t/**\n\t * Optional MCP integration manager. When present, its mcp.* host requests\n\t * (refresh, begin_login) are exposed to the kernel.\n\t */\n\tmcpManager?: McpManager;\n\t/**\n\t * Override base tools (useful for custom runtimes).\n\t *\n\t * These are synthesized into minimal ToolDefinitions internally so AgentSession can keep\n\t * a definition-first registry even when callers provide plain AgentTool instances.\n\t */\n\tbaseToolsOverride?: Record<string, AgentTool>;\n\textensionRunnerRef?: { current?: ExtensionRunner };\n\tsessionStartEvent?: SessionStartEvent;\n\trlmDepth?: number;\n\trlmMaxDepth?: number;\n\trlmSessionDir?: string;\n\trlmParentNodeId?: string;\n\trlmParentAgent?: string;\n\trlmChildAdmission?: RlmChildAdmission;\n\trlmSubagentCapacity?: RlmSubagentCapacity;\n\trlmRootAdmission?: RlmRootAdmission;\n\tsemanticParentSessionId?: string;\n\tsemanticSpawnedByRequestId?: string;\n\tsubagentRuntimeHost?: SubagentRuntimeHost;\n\tautonomous?: AgentAutonomousConfig;\n\tprewarmIpythonKernel?: boolean;\n\tautoRefineReviewer?: AutoRefineReviewer;\n\t/**\n\t * When true, auto-refine runs synchronously between turns at the\n\t * shouldStopAfterTurn boundary instead of in the background after\n\t * agent_end. Used for print/headless autonomous runs so refinement\n\t * never overlaps the primary model request. Default: false.\n\t */\n\tserializedRefine?: boolean;\n\t/**\n\t * Initial goal to seed at session creation. Only applied when rlmDepth\n\t * is 0 and no persisted thread_goal_state entry exists in the branch.\n\t */\n\tinitialGoal?: { objective: string; tokenBudget?: number };\n}\n\nexport interface ExtensionBindings {\n\tuiContext?: ExtensionUIContext;\n\tcommandContextActions?: ExtensionCommandContextActions;\n\tshutdownHandler?: ShutdownHandler;\n\tonError?: ExtensionErrorListener;\n}\n\nexport interface AutoRefineReviewRequest {\n\treason: AutoRefineReason;\n\tturnsSinceLastReview: number;\n}\n\n/**\n * Discriminated result from a serialized-mode background planning pass.\n * - \"plan\": review approved and planning succeeded; carry the exact plan,\n * options, and abort controller so the boundary can apply directly\n * without a second planning request.\n * - \"skip\": reviewer declined; no refine needed.\n * - \"failure\": review or planning threw; boundary should not retry.\n */\nexport type SerializedBackgroundPlanResult =\n\t| {\n\t\t\tstatus: \"plan\";\n\t\t\tplan: RefinementPlan;\n\t\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean };\n\t\t\tabort: AbortController;\n\t\t\tbranchVersion: number;\n\t }\n\t| { status: \"skip\"; explicit?: boolean }\n\t| { status: \"invalidated\"; branchVersion: number }\n\t| {\n\t\t\tstatus: \"failure\";\n\t\t\texplicit: boolean;\n\t\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean };\n\t\t\tbranchVersion: number;\n\t };\n\nexport type AutoRefineReviewer = (request: AutoRefineReviewRequest, signal?: AbortSignal) => Promise<AutoRefineReview>;\n\nexport interface PromptOptions {\n\texpandPromptTemplates?: boolean;\n\timages?: ImageContent[];\n\tstreamingBehavior?: \"steer\" | \"followUp\";\n\tfollowUpQueueKey?: string;\n\tsource?: InputSource;\n\tpreflightResult?: (success: boolean, queued?: boolean) => void;\n\tqueueIfBusy?: boolean;\n\tresumeIfIdle?: boolean;\n\tinternalPrompt?: boolean;\n\tsuppressAutonomousContinuation?: boolean;\n\tskipInputHandlers?: boolean;\n\tsignal?: AbortSignal;\n\tadmissionCommitted?: () => void;\n\tagentMessageId?: string;\n\tcontent?: (TextContent | ImageContent)[];\n\tcustomMessage?: CustomMessage;\n}\n\ninterface InternalPromptOptions extends PromptOptions {\n\tskipPrePromptWork?: boolean;\n\treturnAfterAccepted?: boolean;\n\tagentMessageId?: string;\n}\n\ntype SubmissionExtensionCommandPolicy = \"execute\" | \"reject\" | \"ignore\";\n\ninterface SubmissionNormalizationPolicy {\n\tparseSessionCommands: boolean;\n\textensionCommands: SubmissionExtensionCommandPolicy;\n\tinputSource?: InputSource;\n\texpandSkills: boolean;\n\texpandPromptTemplates: boolean;\n}\n\ntype NormalizedSubmission =\n\t| {\n\t\t\tkind: \"prompt\";\n\t\t\ttext: string;\n\t\t\timages?: ImageContent[];\n\t\t\tselectedSkillRef?: NativeSkillSourceRef;\n\t\t\tassertSkillCurrent?: () => void;\n\t }\n\t| {\n\t\t\tkind: \"sessionCommand\";\n\t\t\ttext: string;\n\t\t\timages?: ImageContent[];\n\t\t\tcommand: SessionSlashCommand;\n\t }\n\t| { kind: \"extensionCommand\"; completion: Promise<void> }\n\t| { kind: \"handled\" };\n\ninterface NativeSkillSelectionOwner {\n\tmanager: SessionManager;\n\tsessionId: string;\n\tsessionFile: string | undefined;\n\twriter: CapturedSkillSelectionWriter;\n\tinputEpoch?: number;\n}\n\ninterface SkillCommandExpansion {\n\ttext: string;\n\tselectedSkillRef?: NativeSkillSourceRef;\n\tassertSkillCurrent: () => void;\n}\n\ntype PreTurnCompactionTiming = \"beforeModelSelection\" | \"afterModelSelection\" | \"skip\";\ntype RefineBarrierPolicy = \"always\" | \"ifInFlight\" | \"skip\";\n\ninterface CommitPreparationPolicy {\n\tinitialRefineBarrier: RefineBarrierPolicy;\n\tflushPendingBashBeforeValidation: boolean;\n\tvalidateModelAndAuth: boolean;\n\tawaitPendingModelSelection: boolean;\n\tpreTurnCompaction: PreTurnCompactionTiming;\n\tfinalRefineBarrier: RefineBarrierPolicy;\n}\n\ninterface CommitPreparationSteps<TPrepared, TCommitted> {\n\tafterValidation?: () => void;\n\tprepare: () => Promise<TPrepared>;\n\tshouldCommit?: (prepared: TPrepared) => boolean;\n\tbeforeFinalRefineBarrier?: (prepared: TPrepared) => void;\n\tcommit: (prepared: TPrepared, passedFinalRefineBarrier: boolean) => TCommitted;\n}\n\ntype QueuedAgentMessage = UserMessage | CustomMessage;\ntype SessionInputSchedule = \"steer\" | \"followUp\";\n\nexport interface TurnExecutionPolicy {\n\tpreparation: CommitPreparationPolicy;\n\trunBeforeAgentStart: boolean;\n\tnextTurnContextTiming: \"preparation\" | \"commit\" | \"skip\";\n\tpreserveEmptyExtensionPrompt: boolean;\n\tcompletionIncludesRetryChain: boolean;\n}\n\nfunction turnExecutionPoliciesEqual(left: TurnExecutionPolicy, right: TurnExecutionPolicy): boolean {\n\treturn (\n\t\tleft.preparation.initialRefineBarrier === right.preparation.initialRefineBarrier &&\n\t\tleft.preparation.flushPendingBashBeforeValidation === right.preparation.flushPendingBashBeforeValidation &&\n\t\tleft.preparation.validateModelAndAuth === right.preparation.validateModelAndAuth &&\n\t\tleft.preparation.awaitPendingModelSelection === right.preparation.awaitPendingModelSelection &&\n\t\tleft.preparation.preTurnCompaction === right.preparation.preTurnCompaction &&\n\t\tleft.preparation.finalRefineBarrier === right.preparation.finalRefineBarrier &&\n\t\tleft.runBeforeAgentStart === right.runBeforeAgentStart &&\n\t\tleft.nextTurnContextTiming === right.nextTurnContextTiming &&\n\t\tleft.preserveEmptyExtensionPrompt === right.preserveEmptyExtensionPrompt &&\n\t\tleft.completionIncludesRetryChain === right.completionIncludesRetryChain\n\t);\n}\n\ninterface PreparedTurnPayload extends SessionTurnPayload {\n\tsubmitted?: NativeSubmittedInput;\n\tselectedSkillRef?: NativeSkillSourceRef;\n\timages?: ImageContent[];\n\tcontent?: (TextContent | ImageContent)[];\n\tcustomMessage?: CustomMessage;\n\tprepared?: PreparedPromptPreparation;\n\texecutionPolicy: TurnExecutionPolicy;\n\tqueueVisible: boolean;\n\tacceptedAgentMessage: boolean;\n\tacceptedBeforeCompletion: boolean;\n\tcaptureRunMessages?: Set<AgentMessage>;\n\tcancelledDispatchEnded?: boolean;\n}\n\ninterface PreparedCommandPayload extends SessionCommandPayload {\n\tsubmitted?: NativeSubmittedInput;\n\timages?: ImageContent[];\n}\n\ntype QueuedSessionAction = SessionAction<PreparedTurnPayload | PreparedCommandPayload>;\n\ninterface PreparedPromptPreparation {\n\tresult: Awaited<ReturnType<ExtensionRunner[\"emitBeforeAgentStart\"]>>;\n\tbasePromptSnapshot: string;\n}\n\nclass DeferredSessionInputError extends Error {}\nclass StaleGoalContinuationError extends Error {}\n\ninterface GoalContinuationOwner {\n\tmanager: SessionManager;\n\tsessionId: string;\n\tsessionFile: string | undefined;\n\tpumpEpoch: number;\n\tgoal: GoalState;\n\tgoalRevision: number;\n\taccountingStartedAt: number | undefined;\n\tsignal: AbortSignal | undefined;\n\tcheckpointOwner?: CompactionOwner;\n}\n\nfunction oncePreflight(\n\tpreflightResult: ((success: boolean, queued?: boolean) => void) | undefined,\n): (success: boolean, queued?: boolean) => void {\n\tlet settled = false;\n\treturn (success, queued = false) => {\n\t\tif (!settled) {\n\t\t\tsettled = true;\n\t\t\tpreflightResult?.(success, queued);\n\t\t}\n\t};\n}\n\ninterface RestoredPromptInput {\n\ttext: string;\n\tcontent?: (TextContent | ImageContent)[];\n\timages?: ImageContent[];\n\tqueueKey?: string;\n\tagentMessageId?: string;\n\tcustomMessage?: CustomMessage;\n\tprefixMessages?: CustomMessage[];\n}\n\nexport const SESSION_ACTION_RECOVERY_FORMAT_VERSION = 1;\n/** Only snapshots carrying the new native source binding require this current-format discriminator. */\nexport const SESSION_ACTION_SKILL_RECOVERY_FORMAT_VERSION = 2;\n\nexport interface SessionActionRecoveryRecord {\n\tid: string;\n\trole: DeliveryRecord[\"role\"];\n\tmessage: QueuedAgentMessage;\n\townerActionId: string;\n}\n\nexport type SessionActionRecoveryPayload =\n\t| {\n\t\t\tkind: \"turn\";\n\t\t\tsubmitted?: NativeSubmittedInput;\n\t\t\tselectedSkillRef?: NativeSkillSourceRef;\n\t\t\ttext: string;\n\t\t\tpreview?: string;\n\t\t\trecords: SessionActionRecoveryRecord[];\n\t\t\timages?: ImageContent[];\n\t\t\tcontent?: (TextContent | ImageContent)[];\n\t\t\tcustomMessage?: CustomMessage;\n\t\t\texecutionPolicy: TurnExecutionPolicy;\n\t\t\tqueueVisible: boolean;\n\t\t\tacceptedAgentMessage: boolean;\n\t\t\tacceptedBeforeCompletion: boolean;\n\t }\n\t| {\n\t\t\tkind: \"session_command\";\n\t\t\tsubmitted?: NativeSubmittedInput;\n\t\t\ttext: string;\n\t\t\tcommand: SessionSlashCommand;\n\t\t\timages?: ImageContent[];\n\t };\n\nexport interface SessionActionRecoveryAction {\n\tid: string;\n\tsource: InputSource | \"internal\";\n\tdelivery: DeliveryPolicy;\n\twake: WakePolicy;\n\tpayload: SessionActionRecoveryPayload;\n\tqueueKey?: string;\n\tagentMessageId?: string;\n\tsuppressAutonomousContinuation?: boolean;\n}\n\nexport interface SessionActionRecoverySnapshot {\n\tformatVersion: typeof SESSION_ACTION_RECOVERY_FORMAT_VERSION | typeof SESSION_ACTION_SKILL_RECOVERY_FORMAT_VERSION;\n\tactions: SessionActionRecoveryAction[];\n}\n\ntype GoalOperationOrigin = Extract<NativeEntryOrigin, { kind: \"goal_operation\" }>;\ntype GoalOriginContext = Pick<GoalOperationOrigin, \"actor\" | \"actionId\" | \"submittedText\"> & {\n\twriter: NativeEntryWriter;\n};\n\nfunction captureSubmittedInput(\n\ttext: string,\n\tinput: { content?: (TextContent | ImageContent)[]; images?: ImageContent[] } = {},\n): NativeSubmittedInput {\n\treturn structuredClone({ text, content: input.content, images: input.images });\n}\n\nfunction cloneCustomMessage(message: CustomMessage): CustomMessage {\n\treturn {\n\t\t...message,\n\t\tcontent: Array.isArray(message.content) ? message.content.map((block) => ({ ...block })) : message.content,\n\t};\n}\n\nfunction cloneQueuedAgentMessage(message: QueuedAgentMessage): QueuedAgentMessage {\n\tif (message.role === \"custom\") return cloneCustomMessage(message);\n\treturn {\n\t\t...message,\n\t\tcontent: Array.isArray(message.content) ? message.content.map((block) => ({ ...block })) : message.content,\n\t};\n}\n\nfunction primaryDeliveryRecord(action: QueuedSessionAction): DeliveryRecord {\n\tif (action.payload.kind !== \"turn\") throw new Error(`Session action ${action.id} is not a turn`);\n\tconst record = action.payload.records.find((candidate) => candidate.role === \"primary\");\n\tif (!record) throw new Error(`Turn action ${action.id} has no primary delivery record`);\n\treturn record;\n}\n\nfunction normalizeMessageContent(content: string | (TextContent | ImageContent)[]): {\n\ttext: string;\n\timages?: ImageContent[];\n} {\n\tif (typeof content === \"string\") return { text: content };\n\tconst text = content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n\tconst images = content.filter((part): part is ImageContent => part.type === \"image\");\n\treturn { text, ...(images.length > 0 ? { images } : {}) };\n}\n\nfunction isFamilyAgentMessageAction(action: QueuedSessionAction): action is SessionAction<PreparedTurnPayload> {\n\tif (action.payload.kind !== \"turn\") return false;\n\tconst message = primaryDeliveryRecord(action).message;\n\treturn isAgentSessionMessage(message) && message.details.fromRelationship !== undefined;\n}\n\nfunction queuedAgentMessagePreview(action: QueuedSessionAction): string {\n\tconst payload = action.payload;\n\tif (payload.kind === \"session_command\") return payload.text;\n\tif (payload.customMessage && isAgentSessionMessage(payload.customMessage)) {\n\t\treturn `${AGENT_MESSAGE_RECEIVED_PREVIEW_LABEL}: ${payload.customMessage.details.message}`;\n\t}\n\treturn payload.preview ?? payload.text;\n}\n\nfunction visibleSessionActionProjection(actions: readonly QueuedSessionAction[]): readonly QueuedSessionAction[] {\n\treturn actions.filter(\n\t\t(action) =>\n\t\t\taction.payload.kind === \"session_command\" ||\n\t\t\taction.payload.queueVisible ||\n\t\t\taction.payload.acceptedAgentMessage,\n\t);\n}\n\nfunction injectedMessagePreviewLabel(message: CustomMessage): string | undefined {\n\tswitch (message.customType) {\n\t\tcase HEARTBEAT_PROMPT_CUSTOM_TYPE:\n\t\t\treturn HEARTBEAT_PROMPT_PREVIEW_LABEL;\n\t\tcase GOAL_CONTEXT_CUSTOM_TYPE:\n\t\t\treturn GOAL_CONTEXT_PREVIEW_LABEL;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\ninterface AgentMessageDeferred {\n\tpromise: Promise<void>;\n\tresolve: () => void;\n\treject: (error: Error) => void;\n}\n\ninterface AgentMessageOutcome {\n\tdelivery?: AgentMessageDeferred;\n\tcompletion?: AgentMessageDeferred;\n}\n\nfunction createAgentMessageDeferred(): AgentMessageDeferred {\n\tconst deferred = {} as AgentMessageDeferred;\n\tdeferred.promise = new Promise<void>((resolve, reject) => {\n\t\tdeferred.resolve = resolve;\n\t\tdeferred.reject = reject;\n\t});\n\tdeferred.promise.catch(() => undefined);\n\treturn deferred;\n}\n\nclass StaleCompactionOwnerError extends Error {}\n\ninterface CompactionOwner {\n\tmanager: SessionManager;\n\tagent: Agent;\n\tsessionId: string;\n\tsessionFile: string | undefined;\n\tpumpEpoch: number;\n\tisSourceCurrent: () => boolean;\n\trequests: InferenceCoordinator;\n\tsemanticEdges: SemanticEdgeRecorder;\n\textensions: ExtensionRunner;\n\tprovisioner: IpythonKernelProvisioner | undefined;\n\tsignal: AbortSignal | undefined;\n}\n\ninterface CheckpointAction {\n\taction: QueuedSessionAction;\n\tticket: ActionTicket;\n}\n\ninterface CheckpointBoundary {\n\tkind: \"tool\" | \"overflow\" | \"request\";\n\tstate: \"pending\" | \"consumed\";\n}\n\ninterface CheckpointResume {\n\towner: CompactionOwner;\n\tboundary?: CheckpointBoundary;\n\tactions: CheckpointAction[];\n}\n\ninterface ThresholdGoalContinuation extends CheckpointAction {\n\towner: GoalContinuationOwner;\n}\n\ninterface ThresholdAutonomousOwner {\n\tstate: AutonomousRuntimeState;\n\tsnapshot: AutonomousRuntimeState;\n\tcwd: string;\n\tarrivalEpoch: number;\n}\n\ninterface ThresholdAutonomousContinuation extends CheckpointAction {\n\towner: CompactionOwner;\n\tstate: AutonomousRuntimeState;\n\tbefore: AutonomousRuntimeSnapshot;\n\tafter: AutonomousRuntimeState;\n}\n\n/** One-shot settlement for the same captured checkpoint directive; a settled failure is not re-exposed. */\ninterface PostCompactionContinuationSettlement extends AgentMessageDeferred {\n\tresume: CheckpointResume;\n\tsettled: boolean;\n}\n\nfunction createPostCompactionContinuationSettlement(resume: CheckpointResume): PostCompactionContinuationSettlement {\n\treturn { ...createAgentMessageDeferred(), resume, settled: false };\n}\n\nexport interface ModelCycleResult {\n\tmodel: Model<any>;\n\tthinkingLevel: ThinkingLevel;\n\tserviceTier: ServiceTier;\n\tisScoped: boolean;\n}\n\ninterface ModelSelectOptions {\n\twaitForExtensions?: boolean;\n}\n\ninterface ToolDefinitionEntry {\n\tdefinition: ToolDefinition;\n\tsourceInfo: SourceInfo;\n}\n\ntype GoalSlashCommand =\n\t| { kind: \"status\" }\n\t| { kind: \"clear\" }\n\t| { kind: \"pause\" }\n\t| { kind: \"resume\" }\n\t| { kind: \"start\"; objective: string; tokenBudget?: number };\n\ntype AutonomousSlashCommand = { kind: \"status\" } | { kind: \"on\" } | { kind: \"off\" };\n\nimport type { RlmMaxDepthSource, RlmMaxDepthStatus, SetRlmMaxDepthResult } from \"./rlm-max-depth.js\";\nimport {\n\tLocalRlmSubagentCapacity,\n\ttype RlmMaxSubagentsStatus,\n\ttype RlmRootAdmission,\n\ttype RlmSubagentCapacity,\n\ttype RlmSubagentCapacityReservation,\n} from \"./rlm-max-subagents.js\";\n\nexport type { RlmMaxDepthSource, RlmMaxDepthStatus, SetRlmMaxDepthResult } from \"./rlm-max-depth.js\";\n\ninterface PersistedRlmMaxDepthState {\n\tmaxDepth: number;\n}\n\ntype AutonomousRuntimeSnapshot = Pick<\n\tAutonomousRuntimeState,\n\t\"continuationsUsed\" | \"gateAttempts\" | \"lastGateFailure\" | \"lastGateFailureSnapshot\"\n>;\n\ninterface RlmChildRun {\n\tid: string;\n\tprompt: string;\n\tsessionName: string;\n\tsessionDir: string;\n\tmodel: Model<Api>;\n\tstatus: RlmChildAgentStatus;\n\tterminalAssistantOutcome?: Pick<AssistantMessage, \"stopReason\" | \"errorMessage\">;\n\tdurationMs?: number;\n\tanswerPreview?: string;\n\ttoolUseCount: number;\n\tactivity?: RlmChildAgentActivity;\n\terror?: string;\n\tabort: () => void;\n\tpublication: AgentMessageDeferred;\n\t/** Resolves after terminal result publication and detached-run cleanup finish. */\n\tsettlement: AgentMessageDeferred;\n\t/** Child session, once its runtime exists. Used to cancel nested child runs. */\n\tsession?: AgentSession;\n\tsettled: boolean;\n\t/** Do not inject a late terminal notice after the parent session is aborted. */\n\tsuppressTerminalNotice?: boolean;\n\t/** Excluded from future strong barriers after an authoritative cancellation cut. */\n\tabandonedForQuiescence?: boolean;\n\t/** Selector snapshot for an admitted explicit delete. */\n\tdetachedDeletion?: RlmSubagentRegistryEntry;\n\t/** Shared physical runtime cleanup owned by the explicit-delete path. */\n\tdeletionCleanup?: Promise<void>;\n\tdeletionCleanupObserver?: Promise<boolean>;\n\t/** Resolves when a deletion may release its selector reservation. */\n\tdeletionReservation: AgentMessageDeferred;\n\tdeletionCleanupFailed?: boolean;\n\tdeletionRunFinished?: boolean;\n\tdeletionNotice?: Promise<void>;\n\tdeletionNeedsCompletionNotice?: boolean;\n\tcompleteDeletion?: () => Promise<void>;\n\treportDeletionCleanupFailure?: (error: unknown) => Promise<void>;\n\temitUpdate?: () => void;\n\tlastEmittedUpdate?: string;\n\tunsubscribe?: () => void;\n}\n\ninterface RlmChildUsageSource {\n\tsessionId: string;\n\tsessionFile?: string;\n\tentryId: string;\n}\n\nconst RLM_PARENT_USAGE_CUSTOM_TYPE = \"rlm_parent_usage\";\n\ntype RlmChildUsageOrigin = \"spawn_task\" | \"agent_message\" | \"direct_user\";\n\ninterface RetainedRlmChild {\n\tsession: AgentSession;\n\trun?: RlmChildRun;\n}\n\ninterface RlmSubagentModelSelection {\n\tmodel: Model<Api>;\n}\n\nconst KERNEL_STATE_LISTING_TIMEOUT_MS = 5000;\nconst RLM_MAX_DEPTH_STATE_CUSTOM_TYPE = \"rlm_max_depth_state\";\n\nfunction noopRlmChildAbort(): void {}\nfunction noopRlmChildEventUnsubscribe(): void {}\n\nfunction autoRefineInstructions(reason: AutoRefineReason, review: AutoRefineReview): string {\n\tconst detail = review.instructions\n\t\t? `\nReviewer instructions: ${review.instructions}`\n\t\t: \"\";\n\treturn `Automatic refine review triggered by ${reason}. Only create/update/delete local harness entries if there is clear evidence that should help this session continue. Prefer an empty edits array over speculative or one-off memories. Do not promote anything global unless explicitly requested. Reviewer rationale: ${review.rationale}${detail}`;\n}\n\nfunction isNonNegativeInteger(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n\nfunction parseDepth(value: string | undefined, fallback: number, name: string): number {\n\tif (value === undefined || value === \"\") {\n\t\treturn fallback;\n\t}\n\tif (!/^\\d+$/.test(value)) {\n\t\tthrow new Error(`${name} must be a non-negative integer`);\n\t}\n\tconst parsed = Number(value);\n\tif (!isNonNegativeInteger(parsed)) {\n\t\tthrow new Error(`${name} must be a non-negative integer`);\n\t}\n\treturn parsed;\n}\n\nfunction isPersistedRlmMaxDepthState(value: unknown): value is PersistedRlmMaxDepthState {\n\treturn (\n\t\ttypeof value === \"object\" && value !== null && isNonNegativeInteger((value as PersistedRlmMaxDepthState).maxDepth)\n\t);\n}\n\nfunction parseGoalBudgetValue(value: string): number {\n\tif (!/^[1-9]\\d*$/.test(value)) {\n\t\tthrow new Error(\"Goal token budget must be a positive integer.\");\n\t}\n\tconst budget = validateGoalBudget(Number(value));\n\tif (budget === undefined) {\n\t\tthrow new Error(\"Goal token budget must be a positive integer.\");\n\t}\n\treturn budget;\n}\n\nexport function compactRlmText(text: string, maxLength = 160): string {\n\tconst compact = text.replace(/\\s+/g, \" \").trim();\n\tif (compact.length <= maxLength) {\n\t\treturn compact;\n\t}\n\treturn `${compact.slice(0, Math.max(0, maxLength - 3)).trimEnd()}...`;\n}\n\n// Child-agent label: collapse to one line but keep the full prompt — the TUI\n// truncates to the visible width and elides shared prefixes, so capping here\n// would only hide the divergence between near-identical sibling prompts.\nexport function rlmChildLabel(prompt: string): string {\n\treturn prompt.replace(/\\s+/g, \" \").trim() || \"child agent\";\n}\n\nfunction readAssistantText(message: AssistantMessage): string {\n\treturn message.content\n\t\t.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\");\n}\n\nfunction waitForPromiseOrAbort<T>(\n\tpromise: Promise<T>,\n\tsignal: AbortSignal | undefined,\n\tabortMessage: string,\n): Promise<T> {\n\tif (!signal) return promise;\n\tif (signal.aborted) return Promise.reject(new Error(abortMessage));\n\treturn new Promise<T>((resolve, reject) => {\n\t\tconst onAbort = () => {\n\t\t\tcleanup();\n\t\t\treject(new Error(abortMessage));\n\t\t};\n\t\tconst cleanup = () => signal.removeEventListener(\"abort\", onAbort);\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t// Close the listener-registration race before observing the awaited work.\n\t\tif (signal.aborted) return onAbort();\n\t\tpromise.then(\n\t\t\t(value) => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport class AgentSession {\n\treadonly agent: Agent;\n\treadonly sessionManager: SessionManager;\n\treadonly settingsManager: SettingsManager;\n\treadonly requests: InferenceCoordinator;\n\treadonly runtimeServices: SessionRuntimeServices;\n\tprivate readonly _contextCompiler = new CanonicalContextCompiler();\n\tprivate _failedAutomaticCompaction?: {\n\t\tkey: string;\n\t\tsystemPrompt: string;\n\t\ttools: Agent[\"state\"][\"tools\"];\n\t\tsettings: string;\n\t};\n\tprivate _failedThresholdCompaction?: {\n\t\tisCurrent: BoundCompactionSink[\"isCurrent\"];\n\t\tconfiguration: string;\n\t\tsystemPrompt: string;\n\t\ttools: Agent[\"state\"][\"tools\"];\n\t};\n\tprivate readonly _contextEpochsEnabled: boolean;\n\tprivate readonly _initialContextMode: ContextMode;\n\tprivate _contextMode: ContextMode;\n\tprivate _pendingContextModeChanges = 0;\n\tprivate readonly _contextUsageReader = new ContextUsageReader();\n\tprivate _compactionBoundaryCache?: {\n\t\tsessionId: string;\n\t\tsessionFile: string | undefined;\n\t\tentryId: string;\n\t\trevision: string;\n\t\ttimestamp: number;\n\t};\n\tprivate _contextOmissions?: { sessionId: string; sessionFile: string | undefined; ids: Set<string> };\n\tprivate _serviceTierPreference: ServiceTier;\n\n\tprivate _scopedModels: Array<{\n\t\tmodel: Model<any>;\n\t\tthinkingLevel?: ThinkingLevel;\n\t}>;\n\n\tprivate _unsubscribeAgent?: () => void;\n\tprivate _eventListeners: AgentSessionEventListener[] = [];\n\tprivate _lastSessionActionSnapshot: SessionActionSnapshot = {\n\t\tqueuedCount: 0,\n\t\tsteering: [],\n\t\tfollowUps: [],\n\t};\n\tprivate _agentEventQueue: Promise<void> = Promise.resolve();\n\n\t/** Session-owned actions. Items are never fed into Agent.steer/followUp. */\n\tprivate readonly _actionStore = new ActionStore<QueuedSessionAction>();\n\tprivate _sessionInputPump: Promise<void> = Promise.resolve();\n\tprivate _sessionInputPumpRequested = false;\n\t// Invalidates preparation when a branch pause starts and finishes before its next await resumes.\n\tprivate _sessionInputPumpEpoch = 0;\n\tprivate _sessionInputArrivalEpoch = 0;\n\t// Persists abort/restart suspension after the initiating call returns.\n\tprivate _sessionInputPumpSuspended = false;\n\tprivate _sessionInputSuspendedForUpdateRestart = false;\n\t// Branch mutation pause leases can overlap and must all release before dispatch resumes.\n\tprivate readonly _queuedWorkPauses = new Set<symbol>();\n\tprivate readonly _sessionInputAdmissionPauses = new Set<symbol>();\n\tprivate readonly _durableRlmTerminalNoticeActionIds = new Set<string>();\n\tprivate _sessionActionCommitTail: Promise<void> = Promise.resolve();\n\tprivate _sessionActionCommitOwner: symbol | undefined;\n\tprivate _pendingSessionActionFenceWaiters = 0;\n\tprivate readonly _sessionActionCommitContext = new AsyncLocalStorage<symbol>();\n\tprivate readonly _sessionActionCommitDisposeAbortController = new AbortController();\n\t// Checkpoint, handoff, and activity waiters share lifecycle-edge notifications to avoid polling.\n\tprivate readonly _sessionInputCheckpointWaiters = new Set<() => void>();\n\tprivate _pendingNextTurnMessages: CustomMessage[] = [];\n\n\tprivate _goalState: GoalState = emptyGoalState();\n\tprivate _goalStateRevision = 0;\n\tprivate _goalAccountingStartedAt: number | undefined = undefined;\n\tprivate _goalContinuationAwaitsRlmWork = false;\n\tprivate _goalAccountedAssistantMessages = new WeakSet<AssistantMessage>();\n\tprivate _goalAbortInProgress = false;\n\tprivate _autonomousState: AutonomousRuntimeState;\n\tprivate _autonomousContinuationSuppressionDepth = 0;\n\tprivate _autonomousContinuationSuppressedMessages = new WeakSet<AgentMessage>();\n\tprivate readonly _invocationOutputLimits: AgentOutputLimits;\n\tprivate _invocationSuppressedAutonomousContinuation = false;\n\tprivate _refreshInvocationOutput?: (message: AgentMessage) => void;\n\tprivate _invocationOutputUpdateTail?: Promise<void>;\n\tprivate _invocationOutputRefused = false;\n\n\tprivate _compactionAbortController: AbortController | undefined = undefined;\n\tprivate _autoCompactionAbortController: AbortController | undefined = undefined;\n\tprivate _compactionOperation: Promise<void> | undefined = undefined;\n\tprivate _compactionSetupFailure: CompactionCommittedError | undefined;\n\t/** One recovery attempt per overflow; \"reported\" dedups the failure notice. */\n\tprivate _overflowRecovery: \"idle\" | \"attempted\" | \"reported\" = \"idle\";\n\tprivate _invocationCompactionOwner: CompactionOwner | undefined;\n\tprivate _pendingCheckpoint: CheckpointResume | undefined;\n\tprivate _pendingRequestedCompaction: { customInstructions?: string; owner: CompactionOwner } | undefined;\n\tprivate _pendingRequestedRefine: { instructions?: string; global?: boolean } | undefined;\n\n\tprivate _branchSummaryAbortController: AbortController | undefined = undefined;\n\tprivate _branchSummaryOperation: Promise<void> | undefined = undefined;\n\n\tprivate _retryAbortController: AbortController | undefined = undefined;\n\tprivate _retryAttempt = 0;\n\tprivate _retryPromise: Promise<void> | undefined = undefined;\n\tprivate _retryResolve: (() => void) | undefined = undefined;\n\tprivate _agentMessageClearEpoch = 0;\n\tprivate _agentMessageOutcomes = new Map<string, AgentMessageOutcome>();\n\tprivate _lateIpythonSentAgentMessages = new Map<string, KernelSentAgentMessage[]>();\n\t/** Outcome disclosures whose session-file append failed; retained for context rebuilds. */\n\tprivate readonly _unpersistedOutcomes: CustomMessage[] = [];\n\n\tprivate _bashAbortControllers = new Set<AbortController>();\n\tprivate _userBashRunning = false;\n\tprivate _userBashAbortRequested = false;\n\tprivate _pendingBashMessages: BashExecutionMessage[] = [];\n\n\tprivate _extensionRunner!: ExtensionRunner;\n\tprivate _execEnvProvider?: () => Record<string, string | undefined> | undefined;\n\tprivate _turnIndex = 0;\n\tprivate _modelSelectEmitQueue: Promise<void> = Promise.resolve();\n\tprivate _modelSelectEmitQueueIdle = true;\n\tprivate _modelSelectEmitContext = new AsyncLocalStorage<boolean>();\n\n\tprivate _resourceLoader: ResourceLoader;\n\tprivate _customTools: ToolDefinition[];\n\tprivate _acpMcpTools: ToolDefinition[] = [];\n\tprivate _baseToolDefinitions: Map<string, ToolDefinition> = new Map();\n\tprivate _cwd: string;\n\tprivate _agentDir?: string;\n\tprivate _extensionRunnerRef?: { current?: ExtensionRunner };\n\tprivate _initialActiveToolNames?: string[];\n\tprivate _allowedToolNames?: Set<string>;\n\tprivate _includeGoals: boolean;\n\tprivate _includeCompactSkill: boolean;\n\tprivate _rlmHeartbeatController?: AgentRlmHeartbeatController;\n\tprivate _agentMessageController?: AgentSessionMessageController;\n\tprivate _agentObserveController?: AgentObserveController;\n\tprivate _mcpManager?: McpManager;\n\tprivate _baseToolsOverride?: Record<string, AgentTool>;\n\tprivate _sessionStartEvent: SessionStartEvent;\n\tprivate _extensionUIContext?: ExtensionUIContext;\n\tprivate _extensionCommandContextActions?: ExtensionCommandContextActions;\n\tprivate _extensionShutdownHandler?: ShutdownHandler;\n\tprivate _extensionErrorListener?: ExtensionErrorListener;\n\tprivate _extensionErrorUnsubscriber?: () => void;\n\tprivate _disposed = false;\n\tprivate readonly _disposeCallbacks = new Set<() => void | Promise<void>>();\n\tprivate _disposeCallbacksPromise?: Promise<void>;\n\t// Set at the start of async teardown so a child finishing mid-disposeAsync doesn't\n\t// re-populate the retained map after it's been cleared.\n\tprivate _disposing = false;\n\tprivate _disposeAsyncPromise?: Promise<void>;\n\tprivate _ipythonKernelProvisioner?: IpythonKernelProvisioner;\n\t/** Artifact dir backing the current provisioner's kernel snapshot, if any. */\n\tprivate _ipythonKernelSnapshotDir?: string;\n\t/** True once the runtime has been built once; later builds are in-process rebuilds (/reload). */\n\tprivate _ipythonRuntimeBuilt = false;\n\tprivate readonly _prewarmIpythonKernel: boolean;\n\tprivate _rlmDepth: number;\n\tprivate readonly _configuredRlmMaxDepth: number | undefined;\n\tprivate _rlmMaxDepth: number;\n\tprivate _rlmMaxDepthSource: RlmMaxDepthSource;\n\tprivate _rlmSessionDir?: string;\n\tprivate readonly _semanticEdges: SemanticEdgeRecorder;\n\tprivate _rlmParentNodeId?: string;\n\tprivate _rlmParentAgent?: string;\n\tprivate _repliedToParentSinceTask: boolean | undefined;\n\tprivate _parentReplyCount = 0;\n\tprivate _subagentRuntimeHost?: SubagentRuntimeHost;\n\tprivate readonly _rlmChildAdmissions = new Set<RlmChildAdmission & { cancel(reason: string): boolean }>();\n\tprivate _rlmSubagentCapacity: RlmSubagentCapacity;\n\tprivate _rlmParentAdmission?: RlmChildAdmission;\n\tprivate readonly _rlmRootAdmission?: RlmRootAdmission;\n\tprivate _rlmResidentDisposalComplete = false;\n\tprivate _releaseRlmResidentCapacity?: () => Promise<void>;\n\tprivate _activeRlmChildRuns = new Map<string, RlmChildRun>();\n\tprivate _unsettledRlmChildRuns = new Set<RlmChildRun>();\n\tprivate _abandonedRlmQuiescenceChildIds = new Set<string>();\n\tprivate _rlmQuiescenceWaitAborts = new Set<AbortController>();\n\tprivate _pendingRlmSubagentSessionNames = new Set<string>();\n\t// Inline mode keeps finished child sessions so the inspector can still read them;\n\t// the daemon does the same by leaving the child session resident in its registry.\n\tprivate _rlmChildSessions = new Map<string, RetainedRlmChild>();\n\tprivate _deletedRlmChildIds = new Set<string>();\n\t// Failed explicit deletes stay hidden from listings but retain their original\n\t// selector so a later delete can retry cleanup without orphaning the runtime.\n\tprivate _rlmChildCleanupFailures = new Map<string, RlmSubagentRegistryEntry>();\n\tprivate _deletingRlmChildren = new Map<\n\t\tstring,\n\t\t{\n\t\t\tsubagent: RlmSubagentRegistryEntry;\n\t\t\tpromise: Promise<RlmDeleteSubagentResult>;\n\t\t}\n\t>();\n\t// Kept alive for retained children so nested updates (e.g. a grandchild cancel)\n\t// still forward to root; torn down when the retained child is disposed.\n\tprivate _rlmChildUnsubscribes = new Map<string, () => void>();\n\tprivate _rlmChildUsageSources = new Map<string, RlmChildUsageSource>();\n\tprivate _rlmParentUsageAttribution?: (usage: Usage, origin: RlmChildUsageOrigin) => Promise<void>;\n\t/** Latest recap for this session, written by the daemon summarizer; read by a parent to label its child snapshots. */\n\tprivate _currentRecap?: string;\n\tprivate readonly _initialGoal: AgentSessionConfig[\"initialGoal\"];\n\tprivate _initialization: Promise<void> | undefined;\n\tprivate _goalResumeOperation: Promise<void> | undefined;\n\tprivate readonly _rlmRunTasks = new Set<Promise<void>>();\n\tprivate readonly _childUsageWrites = new Set<Promise<void>>();\n\tprivate readonly _assistantEntryIds = new WeakMap<\n\t\tAssistantMessage,\n\t\t{ sessionId: string; sessionFile: string | undefined; entryId: string }\n\t>();\n\n\tprivate _modelRegistry: ModelRegistry;\n\n\tprivate _toolRegistry: Map<string, AgentTool> = new Map();\n\tprivate _nativeRecoveryTools = new WeakMap<AgentTool, AgentTool[\"execute\"]>();\n\tprivate _nativeRecoveryCursors = new NativeRecoveryCursorStore();\n\tprivate _nativeRecoveryCursorSource?: string;\n\tprivate _nativeRecoveryProducer = new AsyncLocalStorage<{ used: boolean; skillOwner?: NativeSkillSelectionOwner }>();\n\tprivate _toolDefinitions: Map<string, ToolDefinitionEntry> = new Map();\n\tprivate _toolPromptSnippets: Map<string, string> = new Map();\n\tprivate _toolPromptGuidelines: Map<string, string[]> = new Map();\n\n\tprivate _baseSystemPrompt = \"\";\n\tprivate _baseSystemPromptOptions!: BuildSystemPromptOptions;\n\tprivate _assistantTurnsSinceAutoRefine = 0;\n\tprivate _lastAutoRefineReviewAt = 0;\n\tprivate _lastAutoRefineEvidence?: Awaited<ReturnType<AgentSession[\"_autoRefineEvidence\"]>>;\n\tprivate _autoRefineInProgress = false;\n\tprivate _autoRefineAdmissionClosed = false;\n\tprivate readonly _autoRefineOperations = new Set<Promise<void>>();\n\tprivate readonly _scheduledAutoRefineTimers = new Set<ReturnType<typeof setTimeout>>();\n\tprivate _compactAutoRefinePending = false;\n\tprivate _turnIntervalAutoRefinePending = false;\n\tprivate _postCompactionContinuationScheduled = false;\n\tprivate _postCompactionContinuationSettlement: PostCompactionContinuationSettlement | undefined;\n\tprivate _postCompactionContinuations: ThresholdAutonomousContinuation[] = [];\n\tprivate _queuedAutonomousThresholdContinuations = new WeakMap<AssistantMessage, ThresholdAutonomousContinuation>();\n\tprivate _pendingThresholdCompactionAutonomousContinuations: ThresholdAutonomousContinuation[] = [];\n\tprivate _queuedGoalThresholdContinuation: ThresholdGoalContinuation | undefined;\n\tprivate _pendingAutoRefineReview: { reason: AutoRefineReason; review: AutoRefineReview } | undefined;\n\tprivate _autoRefineBranchVersion = 0;\n\tprivate _autoRefineReviewAbort?: AbortController;\n\tprivate _refineAbortController?: AbortController;\n\tprivate readonly _autoRefineReviewer?: AutoRefineReviewer;\n\tprivate readonly _serializedRefine: boolean;\n\tprivate _refineInFlight?: Promise<void>;\n\tprivate _refinePlanInFlight?: Promise<void>;\n\tprivate _serializedPlanInFlight?: Promise<SerializedBackgroundPlanResult | undefined>;\n\tprivate _serializedPlanClaim?: Promise<void>;\n\tprivate _serializedExplicitRefineOptions?: {\n\t\tinstructions?: string;\n\t\tglobal?: boolean;\n\t};\n\n\tconstructor(config: AgentSessionConfig) {\n\t\tthis._rlmRootAdmission = config.rlmRootAdmission;\n\t\tthis._rlmRootAdmission?.bind(this);\n\t\tthis._rlmSubagentCapacity =\n\t\t\tconfig.rlmChildAdmission?.parent._rlmSubagentCapacity ??\n\t\t\tconfig.rlmSubagentCapacity ??\n\t\t\tnew LocalRlmSubagentCapacity(config.settingsManager);\n\t\tthis._rlmParentAdmission = config.rlmChildAdmission;\n\t\tthis._rlmParentAdmission?.bind(this);\n\t\tthis.agent = config.agent;\n\t\tthis.sessionManager = config.sessionManager;\n\t\tthis._invocationOutputLimits = {\n\t\t\t...(config.invocationOutputLimits ?? config.settingsManager.getInvocationOutputLimits()),\n\t\t};\n\t\tif (\n\t\t\tthis._invocationOutputLimits &&\n\t\t\t(!Number.isSafeInteger(this._invocationOutputLimits.maxMessages) ||\n\t\t\t\tthis._invocationOutputLimits.maxMessages < 1 ||\n\t\t\t\t!Number.isSafeInteger(this._invocationOutputLimits.maxSourceBytes) ||\n\t\t\t\tthis._invocationOutputLimits.maxSourceBytes < 1)\n\t\t)\n\t\t\tthrow new Error(\"Invalid invocation output limits\");\n\t\tthis.agent.bindOutputOwner(() => {\n\t\t\tthis._invocationOutputRefused = false;\n\t\t\tif (!this.sessionManager.supportsCapturedHistoryReads()) return undefined;\n\t\t\tlet registeredUpdate: ((message: AgentMessage) => void) | undefined;\n\t\t\treturn {\n\t\t\t\tlimits: { ...this._invocationOutputLimits },\n\t\t\t\tbindUpdates: (refresh) => {\n\t\t\t\t\tconst update = (message: AgentMessage) => {\n\t\t\t\t\t\tif (!refresh(message)) this._invocationOutputRefused = true;\n\t\t\t\t\t};\n\t\t\t\t\tregisteredUpdate = update;\n\t\t\t\t\tthis._invocationOutputUpdateTail = undefined;\n\t\t\t\t\tthis._refreshInvocationOutput = update;\n\t\t\t\t\treturn () => {\n\t\t\t\t\t\tif (this._refreshInvocationOutput === update) this._refreshInvocationOutput = undefined;\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\tsettleUpdates: async () => {\n\t\t\t\t\t// One fixed accepted boundary; do not wait for future child lifetimes or a later event tail.\n\t\t\t\t\tconst lateUpdate = this._invocationOutputUpdateTail;\n\t\t\t\t\tthis._invocationOutputUpdateTail = undefined;\n\t\t\t\t\tconst childWrites = [...this._childUsageWrites];\n\t\t\t\t\tif (this._refreshInvocationOutput === registeredUpdate) this._refreshInvocationOutput = undefined;\n\t\t\t\t\tconst settled = await Promise.allSettled([...(lateUpdate ? [lateUpdate] : []), ...childWrites]);\n\t\t\t\t\tconst errors = settled.flatMap((result) => (result.status === \"rejected\" ? [result.reason] : []));\n\t\t\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Accepted invocation output updates failed\");\n\t\t\t\t},\n\t\t\t\tsnapshot: (message, maxSourceBytes) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst json = stringifyBoundedJson(message, maxSourceBytes);\n\t\t\t\t\t\treturn { message: JSON.parse(json) as AgentMessage, sourceBytes: Buffer.byteLength(json) };\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (error instanceof Error && error.message === \"JSON byte limit exceeded\") return undefined;\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t\tthis.agent.bindInitializationOwner(() => this.initialize());\n\t\tthis._initialContextMode = config.contextMode ?? config.settingsManager.getContextMode();\n\t\tif (this._initialContextMode !== \"on\" && this._initialContextMode !== \"off\")\n\t\t\tthrow new Error(\"context.mode must be on or off\");\n\t\tthis._contextMode = this._initialContextMode;\n\t\tthis._contextEpochsEnabled = config.requestTokenBudget !== undefined;\n\t\tconst contextEpochsEnabled = this._contextEpochsEnabled;\n\t\tthis.agent.bindContextOwner(async () => {\n\t\t\tawait this.initialize();\n\t\t\tawait this._goalResumeOperation;\n\t\t\tawait this._waitForAgentEventsBeforeContext();\n\t\t\tawait this._waitForChildUsageWrites();\n\t\t\tconst assertHarnessSourceCurrent = await this._appendHarnessSnapshotIfChanged();\n\t\t\tawait this.sessionManager.flushNow();\n\t\t\tassertHarnessSourceCurrent();\n\t\t\t// In-memory sessions have no canonical archive. This is an explicit mode, not an index-error fallback.\n\t\t\tif (!this.sessionManager.isPersisted()) {\n\t\t\t\tif (!this._compactionSetupFailure) return { messages: this.agent.state.messages, adoptMessages: true };\n\t\t\t\tconst rebuilt = await readSessionBootstrap(\n\t\t\t\t\tthis.sessionManager,\n\t\t\t\t\tthis.settingsManager.getCanonicalContextLimits(),\n\t\t\t\t);\n\t\t\t\tthis._compactionSetupFailure = undefined;\n\t\t\t\treturn { messages: rebuilt.context.messages, adoptMessages: true };\n\t\t\t}\n\t\t\tconst limits = this.settingsManager.getCanonicalContextLimits();\n\t\t\tconst outcomes = structuredClone(this._unpersistedOutcomes);\n\t\t\tif (\n\t\t\t\tthis._contextOmissions?.sessionId !== this.sessionId ||\n\t\t\t\tthis._contextOmissions?.sessionFile !== this.sessionFile\n\t\t\t)\n\t\t\t\tthis._contextOmissions = undefined;\n\t\t\tconst controls = this._contextOmissions;\n\t\t\tconst omitted = new Set(controls?.ids);\n\t\t\tconst epochManager = this.sessionManager;\n\t\t\tconst resource = this._captureKernelResource();\n\t\t\tconst compaction = epochManager.bindCompactionSink({\n\t\t\t\tmaxEntries: limits.maxMessages,\n\t\t\t\tmaxSourceBytes: limits.maxSourceBytes,\n\t\t\t});\n\t\t\tlet captured: InferenceCoordinator;\n\t\t\ttry {\n\t\t\t\tcaptured = this.requests.capture(compaction);\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tawait compaction.release();\n\t\t\t\t} catch (cleanupError) {\n\t\t\t\t\tthrow new AggregateError([error, cleanupError], \"Canonical context capture and release failed\");\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst messages = await captured.readHistory(async (view) => {\n\t\t\t\t\tconst sameSource =\n\t\t\t\t\t\tcontrols?.sessionId === view.source.sessionId && controls?.sessionFile === view.source.sessionFile;\n\t\t\t\t\tconst result = await this._contextCompiler.compile(\n\t\t\t\t\t\tview,\n\t\t\t\t\t\tlimits,\n\t\t\t\t\t\tsameSource ? omitted : undefined,\n\t\t\t\t\t\t{},\n\t\t\t\t\t\tresource,\n\t\t\t\t\t\tthis._initialContextMode,\n\t\t\t\t\t\t// This MAIN owner binds public admission below, independently of optional token budgets.\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t\tif (sameSource && this._contextOmissions === controls) {\n\t\t\t\t\t\t// Only prune this captured set. A newer control or source switch must survive this read.\n\t\t\t\t\t\tfor (const id of omitted) if (!this._contextCompiler.hasActiveEntry(id)) controls.ids.delete(id);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t});\n\t\t\t\t// Failed persistence outcomes are transient UI/request facts, never canonical history authority.\n\t\t\t\tthis._mergeUnpersistedOutcomes(messages, outcomes);\n\t\t\t\tif (messages.length > limits.maxMessages) throw new Error(\"Canonical context message budget exceeded\");\n\t\t\t\tconst epochContext = getCanonicalEpochContext(messages);\n\t\t\t\tif (epochContext) this._contextMode = epochContext.mode;\n\t\t\t\tconst unbudgetedPublic =\n\t\t\t\t\t!contextEpochsEnabled &&\n\t\t\t\t\tBoolean(\n\t\t\t\t\t\tepochContext?.toolContinuations?.length ||\n\t\t\t\t\t\t\tepochContext?.taskFrameRebased ||\n\t\t\t\t\t\t\tepochContext?.checkpoint ||\n\t\t\t\t\t\t\tgetCanonicalViewSelectionSource(messages)?.recoveryContractRequested,\n\t\t\t\t\t);\n\t\t\t\tconst nativeSkills = Boolean(contextEpochsEnabled || epochContext?.checkpoint || unbudgetedPublic);\n\t\t\t\tconst skillPolicy = nativeSkills ? (this._nativeRecoveryEnabled() ? \"enabled\" : \"unavailable\") : undefined;\n\t\t\t\tif (this._baseSystemPromptOptions.nativeSkillSelection !== skillPolicy) {\n\t\t\t\t\tconst previousBase = this._baseSystemPrompt;\n\t\t\t\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames(), nativeSkills);\n\t\t\t\t\tthis.agent.state.systemPrompt = this._refreshExtensionSystemPrompt(\n\t\t\t\t\t\tthis.agent.state.systemPrompt,\n\t\t\t\t\t\tpreviousBase,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tepochContext?.resourceRevision !== undefined &&\n\t\t\t\t\tgetCanonicalViewUnits(messages)?.length !== messages.length\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Current resource view requires tracked canonical context\");\n\t\t\t\tif (\n\t\t\t\t\t(epochContext?.checkpoint || unbudgetedPublic) &&\n\t\t\t\t\tgetCanonicalViewUnits(messages)?.length !== messages.length\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Committed context epoch cannot admit untracked transient messages\");\n\t\t\t\tif (\n\t\t\t\t\tepochContext &&\n\t\t\t\t\t(contextEpochsEnabled || epochContext.checkpoint || unbudgetedPublic) &&\n\t\t\t\t\tgetCanonicalViewUnits(messages)?.length === messages.length\n\t\t\t\t) {\n\t\t\t\t\tlet committed = epochContext.checkpoint;\n\t\t\t\t\tlet committedEntry = epochContext.checkpointEntry;\n\t\t\t\t\tconst fixed =\n\t\t\t\t\t\tepochContext.mode === \"off\" ||\n\t\t\t\t\t\t(committed?.policyOnly === true && !contextEpochsEnabled && !unbudgetedPublic);\n\t\t\t\t\tlet requestContract = fixed ? retainedContextRequestContract(committed) : undefined;\n\t\t\t\t\tconst nativeTail = messages.some(\n\t\t\t\t\t\t(message) =>\n\t\t\t\t\t\t\tmessage.role === \"toolResult\" ||\n\t\t\t\t\t\t\t(message.role === \"assistant\" &&\n\t\t\t\t\t\t\t\tmessage.content.some((part) => part.type !== \"text\" || part.textSignature !== undefined)),\n\t\t\t\t\t);\n\t\t\t\t\tlet accepted: string | undefined;\n\t\t\t\t\tlet acceptedBody: string | undefined;\n\t\t\t\t\tlet acceptedResponseIdentity: string | undefined;\n\t\t\t\t\tlet acceptedReplayContract: ContextReplayContract | undefined;\n\t\t\t\t\tlet acknowledged: CompactionCommit | undefined;\n\t\t\t\t\tconst commitFailure = (cause: unknown) => {\n\t\t\t\t\t\tif (!acknowledged) return cause;\n\t\t\t\t\t\tconst error = new CompactionCommittedError(acknowledged.entryId, acknowledged.result, cause);\n\t\t\t\t\t\tthis._compactionSetupFailure = error;\n\t\t\t\t\t\treturn error;\n\t\t\t\t\t};\n\t\t\t\t\tcaptured.bindRequestViewBoundary(\n\t\t\t\t\t\tmessages,\n\t\t\t\t\t\tasync (candidate) => {\n\t\t\t\t\t\t\tif (fixed) throw new Error(\"Context selection is disabled while context.mode is off\");\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tepochContext.toolContinuations?.length &&\n\t\t\t\t\t\t\t\t(!candidate.publicMessages ||\n\t\t\t\t\t\t\t\t\tJSON.stringify(getCanonicalEpochContext(candidate.publicMessages)?.toolContinuations) !==\n\t\t\t\t\t\t\t\t\t\tJSON.stringify(epochContext.toolContinuations) ||\n\t\t\t\t\t\t\t\t\tcandidate.projection.pendingPublicMessageGroups?.length)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tthrow new Error(\"Tool continuation requires its exact public candidate before epoch ACK\");\n\t\t\t\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\t\t\t\tlet representation: string;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\trepresentation = contextEpochRepresentation(\n\t\t\t\t\t\t\t\t\tcandidate.request,\n\t\t\t\t\t\t\t\t\tcandidate.assessment,\n\t\t\t\t\t\t\t\t\tlimits.maxSourceBytes,\n\t\t\t\t\t\t\t\t\tunbudgetedPublic,\n\t\t\t\t\t\t\t\t\tcandidate.responseItemIdentity,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\terror instanceof UnsupportedContextEpochConfigurationError &&\n\t\t\t\t\t\t\t\t\t!contextEpochsEnabled &&\n\t\t\t\t\t\t\t\t\t!candidate.assessment &&\n\t\t\t\t\t\t\t\t\t!committed &&\n\t\t\t\t\t\t\t\t\t!acknowledged &&\n\t\t\t\t\t\t\t\t\t!epochContext.taskFrameRebased &&\n\t\t\t\t\t\t\t\t\t!epochContext.selectedSkills?.length &&\n\t\t\t\t\t\t\t\t\t!epochContext.toolContinuations?.length &&\n\t\t\t\t\t\t\t\t\t!candidate.publicMessages\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tconst source = getCanonicalViewSelectionSource(messages)!;\n\t\t\t\t\t\t\t\t\tconst selected = new Set(candidate.selectedUnitIds);\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\tsource.recoveryContractRequested &&\n\t\t\t\t\t\t\t\t\t\t!source.requiresEpoch &&\n\t\t\t\t\t\t\t\t\t\t!source.pendingPublicMessageGroups?.length &&\n\t\t\t\t\t\t\t\t\t\tthis.sessionManager === epochManager &&\n\t\t\t\t\t\t\t\t\t\tcompaction.isCurrent() &&\n\t\t\t\t\t\t\t\t\t\tJSON.stringify(candidate.source) === JSON.stringify(source.source) &&\n\t\t\t\t\t\t\t\t\t\tcandidate.selectedUnitIds.length === source.units.length &&\n\t\t\t\t\t\t\t\t\t\tselected.size === source.units.length &&\n\t\t\t\t\t\t\t\t\t\tsource.units.every((unit) => selected.has(unit.id))\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t// Optional capture only. Keep the unchanged full-native offer; grant no epoch or omission.\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst replayContract =\n\t\t\t\t\t\t\t\t\"replayContract\" in candidate.projection &&\n\t\t\t\t\t\t\t\tcandidate.projection.replayContract === \"message-groups\"\n\t\t\t\t\t\t\t\t\t? \"message-groups\"\n\t\t\t\t\t\t\t\t\t: \"complete-context\";\n\t\t\t\t\t\t\tconst publicWindow =\n\t\t\t\t\t\t\t\t\"publicWindow\" in candidate.projection && candidate.projection.publicWindow === true;\n\t\t\t\t\t\t\tconst selection = JSON.stringify([\n\t\t\t\t\t\t\t\trepresentation,\n\t\t\t\t\t\t\t\treplayContract,\n\t\t\t\t\t\t\t\tpublicWindow,\n\t\t\t\t\t\t\t\tcandidate.publicMessages !== undefined,\n\t\t\t\t\t\t\t\tcandidate.selectedUnitIds,\n\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\tacceptedResponseIdentity = candidate.responseItemIdentity;\n\t\t\t\t\t\t\tif (accepted !== undefined) {\n\t\t\t\t\t\t\t\tif (accepted !== selection)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Captured epoch request selection changed after acceptance\");\n\t\t\t\t\t\t\t\treturn committedEntry;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Stable request settings do not cover recovery added after the committed source.\n\t\t\t\t\t\t\tconst recoverySourceSequence = committed?.source.sourceSequence ?? -1;\n\t\t\t\t\t\t\tconst hasUncoveredRecovery = getCanonicalViewUnits(messages)!.some((unit, index) => {\n\t\t\t\t\t\t\t\tconst reference = epochContext.references[index];\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\tunit.kind === \"recovery\" && (!reference || reference.ref.sequence > recoverySourceSequence)\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!candidate.publicMessages &&\n\t\t\t\t\t\t\t\t!hasUncoveredRecovery &&\n\t\t\t\t\t\t\t\tcommitted?.representation === representation &&\n\t\t\t\t\t\t\t\tcommitted.replayContract === replayContract &&\n\t\t\t\t\t\t\t\t(committed.publicWindow === true) === publicWindow &&\n\t\t\t\t\t\t\t\tcommitted.taskFrame?.material === epochContext.taskFrame?.material &&\n\t\t\t\t\t\t\t\tcommitted.resourceRevision === epochContext.resourceRevision &&\n\t\t\t\t\t\t\t\tsameSelectedSkills(committed.selectedSkills, epochContext.selectedSkills) &&\n\t\t\t\t\t\t\t\tcandidate.selectedUnitIds.length === messages.length\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\taccepted = selection;\n\t\t\t\t\t\t\t\tacceptedBody = candidate.request.body;\n\t\t\t\t\t\t\t\treturn committedEntry;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst prepared = prepareCanonicalEpoch(\n\t\t\t\t\t\t\t\tcandidate.publicMessages ?? messages,\n\t\t\t\t\t\t\t\tcandidate.selectedUnitIds,\n\t\t\t\t\t\t\t\trepresentation,\n\t\t\t\t\t\t\t\tlimits.maxSourceBytes,\n\t\t\t\t\t\t\t\treplayContract,\n\t\t\t\t\t\t\t\tpublicWindow,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (JSON.stringify(prepared.checkpoint.source) !== JSON.stringify(candidate.source))\n\t\t\t\t\t\t\t\tthrow new Error(\"Context epoch candidate does not match its captured source\");\n\t\t\t\t\t\t\tconst tokensBefore = candidate.originalAssessment?.estimatedInputTokens ?? null;\n\t\t\t\t\t\t\tconst result: CompactionResult = {\n\t\t\t\t\t\t\t\tsummary: \"\",\n\t\t\t\t\t\t\t\tfirstKeptEntryId: prepared.checkpoint.literalTailId,\n\t\t\t\t\t\t\t\ttokensBefore,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t// This is the sole commit. A resolved append is already canonical even if adoption fails.\n\t\t\t\t\t\t\tconst entryId = await compaction[appendContextEpoch](prepared.checkpoint, tokensBefore);\n\t\t\t\t\t\t\tacknowledged = { entryId, result };\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\t\t\t\t\tif (this.sessionManager !== epochManager || !compaction.isCurrent())\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Context epoch source changed before adoption\");\n\t\t\t\t\t\t\t\tthis.agent.state.messages = prepared.messages;\n\t\t\t\t\t\t\t\tcommitted = prepared.checkpoint;\n\t\t\t\t\t\t\t\tcommittedEntry = { sessionId: epochContext.source.sessionId, entryId };\n\t\t\t\t\t\t\t\taccepted = selection;\n\t\t\t\t\t\t\t\tacceptedBody = candidate.request.body;\n\t\t\t\t\t\t\t\treturn committedEntry;\n\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\tthrow commitFailure(cause);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t(request, assessment) => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\t\t\t\t\tif (!sameSelectedSkills(committed?.selectedSkills, epochContext.selectedSkills))\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Selected skill versions require a committed epoch boundary\");\n\t\t\t\t\t\t\t\tif (fixed) {\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t(requestContract ||\n\t\t\t\t\t\t\t\t\t\t\tcommitted?.pendingRequestContract ||\n\t\t\t\t\t\t\t\t\t\t\tnativeTail ||\n\t\t\t\t\t\t\t\t\t\t\tacceptedBody !== undefined) &&\n\t\t\t\t\t\t\t\t\t\t(acceptedBody === undefined || request.body !== acceptedBody)\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed context requires a compatible final provider projection\");\n\t\t\t\t\t\t\t\t\tif (requestContract) {\n\t\t\t\t\t\t\t\t\t\tif (!acceptedReplayContract)\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed context has no accepted replay projection\");\n\t\t\t\t\t\t\t\t\t\tassertContextRequestContract(requestContract, request, acceptedReplayContract);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (epochContext.taskFrameRebased && acceptedBody === undefined)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Task frame rebase requires a committed epoch boundary\");\n\t\t\t\t\t\t\t\tif (!committed) return;\n\t\t\t\t\t\t\t\tif (acceptedBody === undefined || request.body !== acceptedBody)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Committed context epoch requires a compatible final provider projection\");\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\tcontextEpochRepresentation(\n\t\t\t\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t\t\t\t\tassessment,\n\t\t\t\t\t\t\t\t\t\tlimits.maxSourceBytes,\n\t\t\t\t\t\t\t\t\t\tunbudgetedPublic,\n\t\t\t\t\t\t\t\t\t\tacceptedResponseIdentity,\n\t\t\t\t\t\t\t\t\t) !== committed.representation\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Context epoch representation changed without a committed boundary\");\n\t\t\t\t\t\t\t\tif (committed.resourceRevision !== epochContext.resourceRevision)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Context epoch resource revision requires a committed boundary\");\n\t\t\t\t\t\t\t\tif (committed.taskFrame?.material !== epochContext.taskFrame?.material)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Context epoch task revision requires a committed boundary\");\n\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\tthrow commitFailure(cause);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfixed\n\t\t\t\t\t\t\t? async (request, projection) => {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\t\t\t\t\t\t\tif (!requestContract && nativeTail)\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Retained native context has no accepted request contract\");\n\t\t\t\t\t\t\t\t\t\tconst replayContract = projection.replayContract ?? \"complete-context\";\n\t\t\t\t\t\t\t\t\t\tconst skillChange = !sameSelectedSkills(\n\t\t\t\t\t\t\t\t\t\t\tcommitted?.selectedSkills,\n\t\t\t\t\t\t\t\t\t\t\tepochContext.selectedSkills,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\tskillChange &&\n\t\t\t\t\t\t\t\t\t\t\tcommitted?.selectedSkills?.some(\n\t\t\t\t\t\t\t\t\t\t\t\t(skill) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t!sameSelectedSkills(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[skill],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tepochContext.selectedSkills?.filter((item) => item.name === skill.name),\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed context cannot replace a selected skill version\");\n\t\t\t\t\t\t\t\t\t\tif ((!requestContract && committed?.pendingRequestContract) || skillChange) {\n\t\t\t\t\t\t\t\t\t\t\t// Existing policy-only ACK: bind first selections, without changing fixed views or mode.\n\t\t\t\t\t\t\t\t\t\t\tconst base =\n\t\t\t\t\t\t\t\t\t\t\t\tcommitted ??\n\t\t\t\t\t\t\t\t\t\t\t\tprepareContextModeEpoch(messages, epochContext.mode, limits.maxSourceBytes)\n\t\t\t\t\t\t\t\t\t\t\t\t\t.checkpoint;\n\t\t\t\t\t\t\t\t\t\t\tif (base.version !== 5)\n\t\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed skill selection requires its policy checkpoint\");\n\t\t\t\t\t\t\t\t\t\t\tconst nextContract =\n\t\t\t\t\t\t\t\t\t\t\t\trequestContract ?? contextRequestContract(request, replayContract);\n\t\t\t\t\t\t\t\t\t\t\tconst checkpoint = snapshotContextEpoch(\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t...base,\n\t\t\t\t\t\t\t\t\t\t\t\t\trenderer: epochContext.selectedSkills?.length\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? CONTEXT_SKILL_EPOCH_RENDERER\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: base.renderer,\n\t\t\t\t\t\t\t\t\t\t\t\t\t...(epochContext.selectedSkills?.length\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? { selectedSkills: epochContext.selectedSkills }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t\t\t\t\t\tsource: epochContext.source,\n\t\t\t\t\t\t\t\t\t\t\t\t\trequestContract: nextContract,\n\t\t\t\t\t\t\t\t\t\t\t\t\tpendingRequestContract: undefined,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\tlimits.maxSourceBytes,\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\tconst entryId = await compaction[appendContextEpoch](checkpoint, null);\n\t\t\t\t\t\t\t\t\t\t\tacknowledged = {\n\t\t\t\t\t\t\t\t\t\t\t\tentryId,\n\t\t\t\t\t\t\t\t\t\t\t\tresult: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsummary: \"\",\n\t\t\t\t\t\t\t\t\t\t\t\t\tfirstKeptEntryId: checkpoint.literalTailId,\n\t\t\t\t\t\t\t\t\t\t\t\t\ttokensBefore: null,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\tcommitted = checkpoint;\n\t\t\t\t\t\t\t\t\t\t\tcommittedEntry = { sessionId: epochContext.source.sessionId, entryId };\n\t\t\t\t\t\t\t\t\t\t\trequestContract = nextContract;\n\t\t\t\t\t\t\t\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\t\t\t\t\t\t\t\tif (this.sessionManager !== epochManager || !compaction.isCurrent())\n\t\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Context contract source changed before acceptance\");\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (!sameSelectedSkills(committed?.selectedSkills, epochContext.selectedSkills))\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed context selected skill versions changed after acceptance\");\n\t\t\t\t\t\t\t\t\t\tif (requestContract)\n\t\t\t\t\t\t\t\t\t\t\tassertContextRequestContract(requestContract, request, replayContract);\n\t\t\t\t\t\t\t\t\t\tif (acceptedBody !== undefined && request.body !== acceptedBody)\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed context changed after acceptance\");\n\t\t\t\t\t\t\t\t\t\tacceptedBody = request.body;\n\t\t\t\t\t\t\t\t\t\tacceptedReplayContract = replayContract;\n\t\t\t\t\t\t\t\t\t\treturn committedEntry;\n\t\t\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\t\t\tthrow commitFailure(cause);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tcompaction.isCurrent,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis._compactionSetupFailure = undefined;\n\t\t\t\treturn { messages, adoptMessages: true, streamContext: captured, release: () => captured.dispose() };\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tawait captured.dispose();\n\t\t\t\t} catch (cleanupError) {\n\t\t\t\t\tthrow new AggregateError([error, cleanupError], \"Canonical context build and release failed\");\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\t\tthis.agent.bindRequestPreparationRecoveryOwner(async (error, signal) => {\n\t\t\tif (\n\t\t\t\t!(error instanceof PublicContextBudgetError) ||\n\t\t\t\t!this.settingsManager.getCompactionSettings().enabled ||\n\t\t\t\t!this._contextOptimizationAllowed()\n\t\t\t)\n\t\t\t\treturn false;\n\t\t\tconst invocation = this._invocationCompactionOwner;\n\t\t\tif (!invocation || invocation.signal !== signal) return false;\n\t\t\tconst owner = { ...invocation, pumpEpoch: this._sessionInputPumpEpoch };\n\t\t\tif (\n\t\t\t\t!this._isCompactionOwnerCurrent(owner) ||\n\t\t\t\t!error.source.persistent ||\n\t\t\t\terror.source.sessionId !== owner.sessionId ||\n\t\t\t\terror.source.sessionFile !== owner.sessionFile ||\n\t\t\t\t!(error.isSourceCurrent?.() ?? error.source.leafId === owner.manager.getLeafId())\n\t\t\t)\n\t\t\t\treturn false;\n\t\t\t// Rebase this captured frame before paying for a summary. The replacement still\n\t\t\t// needs the normal full provider projection and epoch ACK before MAIN can send.\n\t\t\tif (error.taskFrameRebaseAvailable) {\n\t\t\t\tthis._contextCompiler.requestTaskFrameRebase();\n\t\t\t\treturn \"reprepare\";\n\t\t\t}\n\t\t\tif (error.mandatoryAssessment?.status === \"over-budget\") return false;\n\t\t\t// The loop released its unsent inference and captured projection before this handoff.\n\t\t\t// Continue in-place only after the real summary ACK and canonical owner adoption.\n\t\t\tconst key = error.getCompactionKey();\n\t\t\tconst current = {\n\t\t\t\tkey: key ?? \"\",\n\t\t\t\tsystemPrompt: this.agent.state.systemPrompt,\n\t\t\t\ttools: this.agent.state.tools,\n\t\t\t\tsettings: JSON.stringify(this.settingsManager.getCompactionSettings()),\n\t\t\t};\n\t\t\tconst failed = this._failedAutomaticCompaction;\n\t\t\tif (\n\t\t\t\tkey &&\n\t\t\t\tfailed &&\n\t\t\t\tfailed.key === key &&\n\t\t\t\tfailed.systemPrompt === current.systemPrompt &&\n\t\t\t\tfailed.tools === current.tools &&\n\t\t\t\tfailed.settings === current.settings\n\t\t\t)\n\t\t\t\treturn false;\n\t\t\tthis._failedAutomaticCompaction = undefined;\n\t\t\tlet succeeded = false;\n\t\t\ttry {\n\t\t\t\tsucceeded = await this._runAutoCompaction(\"threshold\", false, owner, true, error);\n\t\t\t\treturn succeeded;\n\t\t\t} finally {\n\t\t\t\tif (!succeeded && key && this._isCompactionSourceOwnerCurrent(owner))\n\t\t\t\t\tthis._failedAutomaticCompaction = current;\n\t\t\t}\n\t\t});\n\t\tthis.agent.bindProviderFailureRecoveryOwner({\n\t\t\trecover: (message, signal) => this._handleRetryableError(message, signal),\n\t\t\tsettle: () => {\n\t\t\t\t// A request-budget rejection can bypass agent_end. Always release its retry owner.\n\t\t\t\tif (this._retryAttempt > 0) {\n\t\t\t\t\tthis._emit({\n\t\t\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tattempt: this._retryAttempt,\n\t\t\t\t\t\tfinalError: this.agent.state.errorMessage,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis._retryAttempt = 0;\n\t\t\t\tthis._resolveRetry();\n\t\t\t},\n\t\t});\n\t\tthis.agent.bindToolExecutionOwner({\n\t\t\tonToolInvocationStarting: async (invocation, _signal, tool, execute, assistantMessage) => {\n\t\t\t\t// Capture this invocation's original source generation before either wait.\n\t\t\t\tconst manager = this.sessionManager;\n\t\t\t\tconst sessionId = manager.getSessionId();\n\t\t\t\tconst sessionFile = manager.getSessionFile();\n\t\t\t\tconst writer = manager[bindNativeEntryWriter]();\n\t\t\t\tconst selected = this._toolRegistry.get(tool.name) === tool && tool.execute === execute;\n\t\t\t\tconst qualified = selected && manager.isPersisted();\n\t\t\t\tconst skillOwner = qualified\n\t\t\t\t\t? { manager, sessionId, sessionFile, writer: writer.captureSkillSelection() }\n\t\t\t\t\t: undefined;\n\t\t\t\tawait this.initialize();\n\t\t\t\tawait this._agentEventQueue;\n\t\t\t\tif (this.sessionManager !== manager)\n\t\t\t\t\tthrow new Error(\"Tool execution owner changed before intent admission\");\n\t\t\t\tconst assistant = assistantMessage ? this._assistantEntryIds.get(assistantMessage) : undefined;\n\t\t\t\tif (qualified && (!assistant || assistant.sessionId !== sessionId || assistant.sessionFile !== sessionFile))\n\t\t\t\t\tthrow new Error(\"Tool intent does not match its original native assistant source\");\n\t\t\t\tconst intentWrite = writer.captureToolInvocation(qualified ? assistant : undefined);\n\t\t\t\tconst exchangeWrite = qualified ? writer.captureToolExchange(invocation.executionId) : undefined;\n\t\t\t\t// Recovery qualification still requires the selected genuine recovery producer.\n\t\t\t\tconst recoveryWrite =\n\t\t\t\t\tthis._nativeRecoveryTools.get(tool) === execute\n\t\t\t\t\t\t? writer.captureRecoveryExchange(invocation.executionId)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tawait intentWrite(invocation);\n\t\t\t\tif (!recoveryWrite && !exchangeWrite) return;\n\t\t\t\tconst producer = { used: false, skillOwner };\n\t\t\t\tconst owner: BoundToolExecution = {\n\t\t\t\t\trun: (run) => (recoveryWrite ? this._nativeRecoveryProducer.run(producer, run) : run()),\n\t\t\t\t\tfinalize: async (exchange) => {\n\t\t\t\t\t\tif (producer.used && recoveryWrite) await recoveryWrite(exchange);\n\t\t\t\t\t\telse if (exchangeWrite) await exchangeWrite(exchange);\n\t\t\t\t\t\telse await manager.appendToolExchange(exchange);\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\treturn owner;\n\t\t\t},\n\t\t\tonToolExchangeFinalized: async (exchange) => {\n\t\t\t\tawait this.sessionManager.appendToolExchange(exchange);\n\t\t\t},\n\t\t});\n\t\tthis.settingsManager = config.settingsManager;\n\t\tthis._serviceTierPreference = config.serviceTierPreference ?? config.agent.state.serviceTier;\n\t\tthis._scopedModels = config.scopedModels ?? [];\n\t\tthis._resourceLoader = config.resourceLoader;\n\t\tthis._customTools = config.customTools ?? [];\n\t\tthis._cwd = config.cwd;\n\t\tthis._agentDir = config.agentDir;\n\t\tthis._modelRegistry = config.modelRegistry;\n\t\tthis._extensionRunnerRef = config.extensionRunnerRef;\n\t\tthis._initialActiveToolNames = config.initialActiveToolNames;\n\t\tthis._allowedToolNames = config.allowedToolNames ? new Set(config.allowedToolNames) : undefined;\n\t\tthis._includeGoals = config.includeGoals ?? true;\n\t\tthis._includeCompactSkill = config.includeCompactSkill ?? this.settingsManager.getCompactionAgentCallable();\n\t\tthis._rlmHeartbeatController = config.rlmHeartbeatController;\n\t\tthis._agentMessageController = config.agentMessageController;\n\t\tthis._agentObserveController = config.agentObserveController;\n\t\tthis._mcpManager = config.mcpManager;\n\t\tthis._baseToolsOverride = config.baseToolsOverride;\n\t\tthis._sessionStartEvent = config.sessionStartEvent ?? { type: \"session_start\", reason: \"startup\" };\n\t\tconst headerRlmDepth = this.sessionManager.getHeader()?.rlmDepth;\n\t\tthis._rlmDepth =\n\t\t\tconfig.rlmDepth ??\n\t\t\t(isNonNegativeInteger(headerRlmDepth)\n\t\t\t\t? headerRlmDepth\n\t\t\t\t: parseDepth(process.env.BASE_CONTEXT_RLM_DEPTH, 0, \"BASE_CONTEXT_RLM_DEPTH\"));\n\t\tthis._configuredRlmMaxDepth = config.rlmMaxDepth;\n\t\tif (this._configuredRlmMaxDepth !== undefined && !isNonNegativeInteger(this._configuredRlmMaxDepth)) {\n\t\t\tthrow new Error(\"rlmMaxDepth must be a non-negative integer\");\n\t\t}\n\t\t// Persistent controls are restored before constructing the runtime in initialize().\n\t\tconst resolvedRlmMaxDepth = this.sessionManager.isPersisted()\n\t\t\t? { maxDepth: 2, source: \"default\" as const }\n\t\t\t: this._resolveRlmMaxDepth(this._loadPersistedRlmMaxDepthState());\n\t\tthis._rlmMaxDepth = resolvedRlmMaxDepth.maxDepth;\n\t\tthis._rlmMaxDepthSource = resolvedRlmMaxDepth.source;\n\t\tthis._prewarmIpythonKernel = (config.prewarmIpythonKernel ?? false) && this._rlmDepth === 0;\n\t\tthis._autoRefineReviewer = config.autoRefineReviewer;\n\t\tthis._serializedRefine = config.serializedRefine ?? false;\n\t\tthis._rlmSessionDir = config.rlmSessionDir;\n\t\tthis._rlmParentNodeId = config.rlmParentNodeId;\n\t\tthis._rlmParentAgent = config.rlmParentAgent;\n\t\tthis._semanticEdges = new SemanticEdgeRecorder({\n\t\t\tledgerPath: semanticEdgeLedgerPath({\n\t\t\t\trlmSessionDir: this._rlmSessionDir,\n\t\t\t\tsessionArtifactDir: this.sessionManager.getSessionArtifactDir(),\n\t\t\t}),\n\t\t\tsessionId: this.sessionManager.getSessionId(),\n\t\t\tparentSessionId: config.semanticParentSessionId,\n\t\t\tspawnedByRequestId: config.semanticSpawnedByRequestId,\n\t\t});\n\t\tthis.requests = new InferenceCoordinator(\n\t\t\t() => this.sessionManager.bindRequestSink(),\n\t\t\t() => ({ parentSessionId: config.semanticParentSessionId }),\n\t\t\tconfig.requestTokenBudget,\n\t\t);\n\t\tthis.requests.setProviderRecoveryPolicy(() => ({\n\t\t\tenabled: this.settingsManager.getRetryEnabled(),\n\t\t\tbaseDelayMs: this.settingsManager.getRetrySettings().baseDelayMs,\n\t\t\tmaxRetryDelayMs: this.settingsManager.getProviderRetrySettings().maxRetryDelayMs || 60_000,\n\t\t}));\n\t\tthis.runtimeServices = { requests: this.requests };\n\t\tthis.requests.onActivityChange(() => this._notifySessionInputCheckpointChange());\n\t\tthis.agent.bindStreamOwner((streamFn) =>\n\t\t\twrapStreamFnWithSemanticEdges(\n\t\t\t\tthis.requests.bindStream(streamFn, {\n\t\t\t\t\tpurpose: this._rlmDepth > 0 ? \"child\" : \"main\",\n\t\t\t\t\tparentOperationId: config.semanticSpawnedByRequestId,\n\t\t\t\t}),\n\t\t\t\tthis._semanticEdges,\n\t\t\t),\n\t\t);\n\t\t// A resumed child may have replied before this process started; false would\n\t\t// claim knowledge that is not present in the session transcript.\n\t\tthis._repliedToParentSinceTask =\n\t\t\tthis._rlmDepth > 0 &&\n\t\t\t(this.sessionManager.isPersisted() ||\n\t\t\t\tthis.sessionManager.getBranch().some((entry) => entry.type === \"message\"))\n\t\t\t\t? undefined\n\t\t\t\t: false;\n\t\tthis._subagentRuntimeHost = config.subagentRuntimeHost;\n\t\tthis._autonomousState = createAutonomousRuntimeState(config.autonomous, {\n\t\t\tcwd: this._cwd,\n\t\t});\n\t\tthis._goalState = this.sessionManager.isPersisted() ? emptyGoalState() : this._loadPersistedGoalState();\n\t\tthis._initialGoal = config.initialGoal ? { ...config.initialGoal } : undefined;\n\t\tthis._restoreLateIpythonSentAgentMessages();\n\t\tif (this._goalState.status === \"active\") {\n\t\t\tthis._goalAccountingStartedAt = Date.now();\n\t\t}\n\n\t\tthis._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);\n\t\tthis._installAgentToolHooks();\n\t\tthis._installAgentTurnHook();\n\t\tthis._installAgentContinuationHook();\n\n\t\tif (!this.sessionManager.isPersisted()) {\n\t\t\tthis._buildRuntime({\n\t\t\t\tactiveToolNames: this._initialActiveToolNames,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async _waitForChildUsageWrites(): Promise<void> {\n\t\twhile (this._childUsageWrites.size > 0) await Promise.all([...this._childUsageWrites]);\n\t}\n\n\t/** Finish native bootstrap persistence before publishing this session. */\n\tinitialize(): Promise<void> {\n\t\tif (this._disposing || this._disposed)\n\t\t\treturn Promise.reject(new Error(\"Cannot initialize a disposing or disposed session.\"));\n\t\tthis._initialization ??= this._initialize();\n\t\treturn this._initialization;\n\t}\n\n\tprivate async _initialize(): Promise<void> {\n\t\tthis._rlmParentAdmission?.assertCurrent();\n\t\tthis._contextMode = await this._readContextMode();\n\t\tconst freshContextContract = this.sessionManager.canSeedContextModeContract();\n\t\tlet goalSeedable = false;\n\t\tif (this.sessionManager.isPersisted()) {\n\t\t\tconst bootstrap = await this._readRuntimeBootstrap();\n\t\t\tthis._goalState = bootstrap.goalState;\n\t\t\tthis._goalAccountingStartedAt = this._goalState.status === \"active\" ? Date.now() : undefined;\n\t\t\tgoalSeedable = bootstrap.goalSeedable;\n\t\t\tconst resolved = this._resolveRlmMaxDepth(bootstrap.rlmMaxDepth);\n\t\t\tthis._rlmMaxDepth = resolved.maxDepth;\n\t\t\tthis._rlmMaxDepthSource = resolved.source;\n\t\t\tthis._repliedToParentSinceTask = this._rlmDepth > 0 && bootstrap.hasBranchMessage ? undefined : false;\n\t\t\tthis._buildRuntime({\n\t\t\t\tactiveToolNames: this._initialActiveToolNames,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t\tif (\n\t\t\t\tthis._goalState.status === \"active\" &&\n\t\t\t\tthis._includeGoals &&\n\t\t\t\t!this.getActiveToolNames().includes(\"ipython\")\n\t\t\t) {\n\t\t\t\tthis.setActiveToolsByName([...this.getActiveToolNames(), \"ipython\"]);\n\t\t\t\tthis._prewarmIpythonIfNeeded();\n\t\t\t}\n\t\t} else if (this._rlmDepth === 0 && this._initialGoal) {\n\t\t\tgoalSeedable = this._isBranchSeedable();\n\t\t}\n\t\tif (this._rlmDepth === 0 && this._initialGoal && goalSeedable) {\n\t\t\tconst goal = await this._startGoal(this._initialGoal.objective, this._initialGoal.tokenBudget);\n\t\t\tthis._pendingNextTurnMessages.push(createGoalContextMessage(goal, \"continuation\"));\n\t\t\tthis._ensureGoalRuntimeActive();\n\t\t}\n\t\tawait this.sessionManager.flushNow();\n\t\tif (this._contextMode === \"off\") await this._writeContextMode(\"off\", freshContextContract);\n\t}\n\n\t/** Accepted canonical policy. Settings are only the creation default. */\n\tget contextMode(): ContextMode {\n\t\treturn this._contextMode;\n\t}\n\n\tprivate _contextOptimizationAllowed(): boolean {\n\t\treturn this._contextMode === \"on\" && this._pendingContextModeChanges === 0;\n\t}\n\n\tprivate _assertContextOptimizationAllowed(): void {\n\t\tif (!this._contextOptimizationAllowed())\n\t\t\tthrow new Error(\"Context optimization is disabled; explicitly re-enable context.mode first\");\n\t}\n\n\tprivate _retainContextOptimization<T>(operation: Promise<T>): Promise<T> {\n\t\tconst retained = operation.then(() => undefined);\n\t\tthis._autoRefineOperations.add(retained);\n\t\tvoid retained.finally(() => this._autoRefineOperations.delete(retained)).catch(() => undefined);\n\t\treturn operation;\n\t}\n\n\tprivate _readContextMode(): Promise<ContextMode> {\n\t\tif (!this.sessionManager.isPersisted()) return Promise.resolve(this._initialContextMode);\n\t\tconst { maxSourceBytes } = this.settingsManager.getCanonicalContextLimits();\n\t\treturn this.sessionManager.readBranchHistory((history) =>\n\t\t\treadCanonicalContextMode(history.branchContext, maxSourceBytes, this._initialContextMode),\n\t\t);\n\t}\n\n\t/** External session control; never await the current action's own pump or tool turn. */\n\tasync setContextMode(mode: ContextMode): Promise<void> {\n\t\tif (mode !== \"on\" && mode !== \"off\") throw new Error(\"context.mode must be on or off\");\n\t\tif (this._sessionActionCommitContext.getStore() !== undefined)\n\t\t\tthrow new Error(\"Context mode changes require external session control\");\n\t\tthis._pendingContextModeChanges++;\n\t\ttry {\n\t\t\tawait this.initialize();\n\t\t\twhile (true) {\n\t\t\t\tawait this._drainAcceptedRefinement();\n\t\t\t\tawait Promise.all([this._compactionOperation, this._branchSummaryOperation]);\n\t\t\t\tawait this.waitForIdle();\n\t\t\t\tconst fence = await this._acquireSessionActionCommitFence();\n\t\t\t\ttry {\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis.isStreaming ||\n\t\t\t\t\t\tthis.unfinishedActionCount !== 0 ||\n\t\t\t\t\t\tthis._compactionOperation ||\n\t\t\t\t\t\tthis._branchSummaryOperation ||\n\t\t\t\t\t\tthis._refineInFlight ||\n\t\t\t\t\t\tthis._refinePlanInFlight ||\n\t\t\t\t\t\tthis._serializedPlanInFlight\n\t\t\t\t\t)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tawait this._sessionActionCommitContext.run(fence.owner, () => this._writeContextMode(mode));\n\t\t\t\t\treturn;\n\t\t\t\t} finally {\n\t\t\t\t\tfence.release();\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\t// Restore only the reversible barrier. EOF/disposal remains permanently closed.\n\t\t\tthis._pendingContextModeChanges--;\n\t\t}\n\t}\n\n\t/** Called during unpublished initialization or while holding the existing session action fence. */\n\tprivate async _writeContextMode(mode: ContextMode, freshContextContract = false): Promise<void> {\n\t\tconst manager = this.sessionManager;\n\t\tconst limits = this.settingsManager.getCanonicalContextLimits();\n\t\tconst resource = this._captureKernelResource();\n\t\tconst compaction = manager.bindCompactionSink({\n\t\t\tmaxEntries: limits.maxMessages,\n\t\t\tmaxSourceBytes: limits.maxSourceBytes,\n\t\t});\n\t\tconst captured = this.requests.capture(compaction);\n\t\tlet committed: CompactionCommit | undefined;\n\t\tlet failure: unknown;\n\t\tlet primaryCause: unknown;\n\t\ttry {\n\t\t\tconst messages = await captured.readHistory((view) =>\n\t\t\t\tthis._contextCompiler.compile(view, limits, undefined, {}, resource, this._initialContextMode),\n\t\t\t);\n\t\t\tconst context = getCanonicalEpochContext(messages)!;\n\t\t\tif (\n\t\t\t\tcontextEpochMode(context.checkpoint, this._initialContextMode) === mode &&\n\t\t\t\t(context.checkpoint !== undefined || mode === \"on\")\n\t\t\t) {\n\t\t\t\tthis._contextMode = mode;\n\t\t\t} else {\n\t\t\t\tconst prepared = prepareContextModeEpoch(messages, mode, limits.maxSourceBytes, freshContextContract);\n\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\tconst entryId = await compaction[appendContextEpoch](prepared.checkpoint, null);\n\t\t\t\tcommitted = {\n\t\t\t\t\tentryId,\n\t\t\t\t\tresult: { summary: \"\", firstKeptEntryId: prepared.checkpoint.literalTailId, tokensBefore: null },\n\t\t\t\t};\n\t\t\t\t// ACK is authoritative even if later setup or release fails.\n\t\t\t\tthis._contextMode = mode;\n\t\t\t\tif (this.sessionManager !== manager || !compaction.isCurrent())\n\t\t\t\t\tthrow new Error(\"Context mode source changed before adoption\");\n\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\tthis.agent.state.messages = prepared.messages;\n\t\t\t}\n\t\t} catch (cause) {\n\t\t\tprimaryCause = cause;\n\t\t\tfailure = committed ? new CompactionCommittedError(committed.entryId, committed.result, cause) : cause;\n\t\t\tif (committed) this._compactionSetupFailure = failure as CompactionCommittedError;\n\t\t}\n\t\ttry {\n\t\t\tawait captured.dispose();\n\t\t} catch (cause) {\n\t\t\tif (failure !== undefined) {\n\t\t\t\tif (cause !== primaryCause)\n\t\t\t\t\tfailure = new AggregateError([failure, cause], \"Context mode transition and release failed\", {\n\t\t\t\t\t\tcause: failure,\n\t\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tfailure = committed ? new CompactionCommittedError(committed.entryId, committed.result, cause) : cause;\n\t\t\t\tif (committed) this._compactionSetupFailure = failure as CompactionCommittedError;\n\t\t\t}\n\t\t}\n\t\tif (failure !== undefined) throw failure;\n\t}\n\n\t/** Refreshes MCP provider registrations without rebuilding the session runtime. */\n\trefreshMcpProviders(): void {\n\t\tthis._mcpManager?.refresh();\n\t}\n\n\t/**\n\t * Set the RLM heartbeat controller after construction. Used by\n\t * print/headless mode to attach an in-process heartbeat scheduler\n\t * when the session is created outside the daemon.\n\t */\n\tsetRlmHeartbeatController(controller: AgentRlmHeartbeatController): void {\n\t\tif (this._rlmHeartbeatController === controller) {\n\t\t\treturn;\n\t\t}\n\t\tthis._rlmHeartbeatController = controller;\n\t\tthis._buildRuntime({\n\t\t\tactiveToolNames: this.getActiveToolNames(),\n\t\t\tincludeAllExtensionTools: true,\n\t\t});\n\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t}\n\n\treplaceAcpMcpServers(servers: readonly AcpMcpServerConfig[], ownerId: string): void {\n\t\tif (this.isStreaming) throw new Error(\"Cannot replace ACP MCP servers while the agent is running\");\n\t\tif (!this._mcpManager) {\n\t\t\tif (servers.length > 0) throw new Error(\"MCP is unavailable in this session\");\n\t\t\treturn;\n\t\t}\n\t\tif (servers.length > 0 && !this._ipythonKernelProvisioner) {\n\t\t\tthrow new Error(\"ACP MCP servers require the built-in cpython tool\");\n\t\t}\n\t\tthis._assertAcpMcpToolNamesAvailable(acpMcpToolNames(servers));\n\t\tif (!this._mcpManager.replaceAcpServers(servers, ownerId)) return;\n\t\tthis._rebuildRuntimeForAcpMcpServers();\n\t}\n\n\tasync releaseAcpMcpServers(ownerId: string, serverNames: readonly string[]): Promise<void> {\n\t\tif (!this._mcpManager?.canReleaseAcpServers(ownerId)) return;\n\t\tif (this._mcpManager.replaceAcpServers([], ownerId)) {\n\t\t\tconst removedToolNames = new Set(this._acpMcpTools.map((tool) => tool.name));\n\t\t\tconst activeToolNames = this.getActiveToolNames().filter((name) => !removedToolNames.has(name));\n\t\t\tfor (const name of removedToolNames) this._allowedToolNames?.delete(name);\n\t\t\tthis._acpMcpTools = [];\n\t\t\tthis._refreshToolRegistry({ activeToolNames, includeAllExtensionTools: true });\n\t\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t\t}\n\t\tconst names = [...new Set(serverNames)];\n\t\tif (names.length === 0) return;\n\n\t\tconst inputPause = this.acquireSessionInputPause();\n\t\ttry {\n\t\t\t// Do not rebuild or kill the notebook. Wait for the current turn, then ask\n\t\t\t// the kernel-owned MCP registry to close only these cached transports.\n\t\t\tawait this.agent.waitForIdle();\n\t\t\tawait this._agentEventQueue;\n\t\t\tconst manager = this._ipythonKernelProvisioner?.manager;\n\t\t\tif (!manager?.isRunning) return;\n\t\t\tconst code = [\n\t\t\t\t\"import importlib as _prime_importlib\",\n\t\t\t\t'_prime_mcp = _prime_importlib.import_module(\"rlm.mcp\")',\n\t\t\t\t`_prime_mcp_names = ${JSON.stringify(names)}`,\n\t\t\t\t\"_prime_mcp_errors = []\",\n\t\t\t\t\"for _prime_mcp_name in _prime_mcp_names:\",\n\t\t\t\t\" try:\",\n\t\t\t\t\" await _prime_mcp.reload(_prime_mcp_name)\",\n\t\t\t\t\" except BaseException as _prime_mcp_error:\",\n\t\t\t\t\" _prime_mcp_errors.append(_prime_mcp_error)\",\n\t\t\t\t\"if _prime_mcp_errors:\",\n\t\t\t\t\" raise _prime_mcp_errors[0]\",\n\t\t\t\t\"del _prime_mcp, _prime_importlib, _prime_mcp_names, _prime_mcp_errors, _prime_mcp_name\",\n\t\t\t].join(\"\\n\");\n\t\t\tconst result = await manager.execute(code);\n\t\t\tif (result.status !== \"ok\") {\n\t\t\t\tthrow new Error(`Failed to close ACP MCP kernel transports: ${result.stderr || \"kernel error\"}`);\n\t\t\t}\n\t\t} finally {\n\t\t\tinputPause.release();\n\t\t}\n\t}\n\n\tprivate _assertAcpMcpToolNamesAvailable(names: readonly string[]): void {\n\t\tconst occupiedNames = new Set([\n\t\t\t...this._baseToolDefinitions.keys(),\n\t\t\t...this._customTools.map((tool) => tool.name),\n\t\t\t...this._extensionRunner.getAllRegisteredTools().map((tool) => tool.definition.name),\n\t\t]);\n\t\tfor (const name of names) {\n\t\t\tif (occupiedNames.has(name)) {\n\t\t\t\tthrow new Error(`ACP MCP tool name conflicts with an existing tool: ${name}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _rebuildRuntimeForAcpMcpServers(): void {\n\t\tconst previousToolNames = new Set(this._acpMcpTools.map((tool) => tool.name));\n\t\tconst nextToolNames = acpMcpToolNames(this._mcpManager?.getAcpServers() ?? []);\n\t\tthis._assertAcpMcpToolNamesAvailable(nextToolNames);\n\t\tconst activeToolNames = this.getActiveToolNames().filter((name) => !previousToolNames.has(name));\n\t\tactiveToolNames.push(...nextToolNames);\n\t\tthis._buildRuntime({\n\t\t\tactiveToolNames,\n\t\t\tincludeAllExtensionTools: true,\n\t\t});\n\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t}\n\n\tget modelRegistry(): ModelRegistry {\n\t\treturn this._modelRegistry;\n\t}\n\n\tsetSubagentRuntimeHost(host?: SubagentRuntimeHost): void {\n\t\tthis._subagentRuntimeHost = host;\n\t}\n\n\tprivate async _getRequiredRequestAuth(model: Model<any>): Promise<{\n\t\tapiKey: string;\n\t\theaders?: Record<string, string>;\n\t}> {\n\t\tconst result = await this._modelRegistry.getApiKeyAndHeaders(model);\n\t\tif (!result.ok) {\n\t\t\tif (result.error.startsWith(\"No API key found\")) {\n\t\t\t\tthrow new Error(formatNoApiKeyFoundMessage(model.provider));\n\t\t\t}\n\t\t\tthrow new Error(result.error);\n\t\t}\n\t\tif (result.apiKey) {\n\t\t\treturn { apiKey: result.apiKey, headers: result.headers };\n\t\t}\n\n\t\tconst isOAuth = this._modelRegistry.isUsingOAuth(model);\n\t\tif (isOAuth) {\n\t\t\tthrow new Error(formatAuthenticationFailedMessage(model.provider));\n\t\t}\n\t\tthrow new Error(formatNoApiKeyFoundMessage(model.provider));\n\t}\n\n\t/**\n\t * Install tool hooks once on the Agent instance.\n\t *\n\t * The callbacks read `this._extensionRunner` at execution time, so extension reload swaps in the\n\t * new runner without reinstalling hooks. Extension-specific tool wrappers are still used to adapt\n\t * registered tool execution to the extension context. Tool call and tool result interception now\n\t * happens here instead of in wrappers.\n\t */\n\tprivate _installAgentToolHooks(): void {\n\t\tthis.agent.beforeToolCall = async ({ toolCall, args }) => {\n\t\t\tconst runner = this._extensionRunner;\n\t\t\tif (!runner.hasHandlers(\"tool_call\")) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tawait this._agentEventQueue;\n\n\t\t\ttry {\n\t\t\t\treturn await runner.emitToolCall({\n\t\t\t\t\ttype: \"tool_call\",\n\t\t\t\t\ttoolName: toolCall.name,\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\tinput: args as Record<string, unknown>,\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Extension failed, blocking execution: ${String(err)}`);\n\t\t\t}\n\t\t};\n\n\t\tthis.agent.afterToolCall = async ({ toolCall, args, result, isError }) => {\n\t\t\tconst runner = this._extensionRunner;\n\t\t\tif (!runner.hasHandlers(\"tool_result\")) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst hookResult = await runner.emitToolResult({\n\t\t\t\ttype: \"tool_result\",\n\t\t\t\ttoolName: toolCall.name,\n\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\tinput: args as Record<string, unknown>,\n\t\t\t\tcontent: result.content,\n\t\t\t\tdetails: result.details,\n\t\t\t\tisError,\n\t\t\t});\n\n\t\t\tif (!hookResult) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: hookResult.content,\n\t\t\t\tdetails: hookResult.details,\n\t\t\t\tisError: hookResult.isError ?? isError,\n\t\t\t};\n\t\t};\n\t}\n\n\tprivate _installAgentContinuationHook(): void {\n\t\tthis.agent.getContinuationMessages = (context, signal) => this._getContinuationMessages(context, signal);\n\t\tthis.agent.getContinuationOutcome = (context, signal) => this._getContinuationOutcome(context, signal);\n\t}\n\n\tprivate _installAgentTurnHook(): void {\n\t\tthis.agent.shouldStopBeforeTurn = () => this._shouldStopBeforeTurn();\n\t\tthis.agent.shouldStopAfterTurn = (context) => this._shouldStopAfterTurn(context);\n\t\tthis.agent.getTurnOutcome = (context, signal) => this._getTurnOutcome(context, signal);\n\t}\n\n\tprivate _emit(event: AgentSessionEvent): void {\n\t\tfor (const l of this._eventListeners) {\n\t\t\ttry {\n\t\t\t\tl(event);\n\t\t\t} catch {\n\t\t\t\t// A failing observer must not prevent other subscribers from\n\t\t\t\t// receiving lifecycle and persistence events.\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _emitQueueUpdate(): void {\n\t\tconst actions = this.getSessionActionSnapshot();\n\t\tif (JSON.stringify(actions) === JSON.stringify(this._lastSessionActionSnapshot)) return;\n\t\tthis._lastSessionActionSnapshot = actions;\n\t\tthis._emit({ type: \"session_action_update\", actions });\n\t}\n\n\tprivate _restoreLateIpythonSentAgentMessages(): void {\n\t\tthis._lateIpythonSentAgentMessages.clear();\n\t\t// Native restored outputs come from the compiler; pending outputs use captured relation reads.\n\t\tif (this.sessionManager.supportsCapturedHistoryReads()) return;\n\t\tfor (const entry of this.sessionManager.getBranch()) {\n\t\t\tif (entry.type !== \"custom\" || entry.customType !== IPYTHON_SENT_AGENT_MESSAGE_CUSTOM_ENTRY) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst persisted = parsePersistedIpythonSentAgentMessage(entry.data);\n\t\t\tif (persisted) {\n\t\t\t\tthis._rememberLateIpythonSentAgentMessage(persisted.toolCallId, persisted.message);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _rememberLateIpythonSentAgentMessage(toolCallId: string, message: KernelSentAgentMessage): boolean {\n\t\tconst messages = this._lateIpythonSentAgentMessages.get(toolCallId) ?? [];\n\t\tconst isNew = !messages.some((entry) => entry.id === message.id);\n\t\tif (isNew) {\n\t\t\tmessages.push(message);\n\t\t\tthis._lateIpythonSentAgentMessages.set(toolCallId, messages);\n\t\t}\n\t\tfor (let index = this.agent.state.messages.length - 1; index >= 0; index -= 1) {\n\t\t\tif (appendSentAgentMessageToToolResult(this.agent.state.messages[index], toolCallId, message)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn isNew;\n\t}\n\n\tprivate _applyLateIpythonSentAgentMessages(message: AgentMessage): void {\n\t\tif (message.role !== \"toolResult\" || message.toolName !== \"ipython\") {\n\t\t\treturn;\n\t\t}\n\t\tfor (const sentMessage of this._lateIpythonSentAgentMessages.get(message.toolCallId) ?? []) {\n\t\t\tappendSentAgentMessageToToolResult(message, message.toolCallId, sentMessage);\n\t\t}\n\t}\n\n\tprivate async _applyCanonicalIpythonSentAgentMessages(message: AgentMessage): Promise<void> {\n\t\tif (message.role !== \"toolResult\" || message.toolName !== \"ipython\") return;\n\t\tconst toolCallId = message.toolCallId;\n\t\tconst refreshOutput = this._refreshInvocationOutput;\n\t\tconst limits = { ...this.settingsManager.getCanonicalContextLimits() };\n\t\tconst sentMessages = await this.sessionManager.readSourceHistory(async (history) => {\n\t\t\tconst messages: KernelSentAgentMessage[] = [];\n\t\t\tlet cursor: IpythonSentMessagesCursor | undefined;\n\t\t\tlet sourceBytes = 0;\n\t\t\tdo {\n\t\t\t\tconst page = await history.ipythonSentMessages(toolCallId, { cursor });\n\t\t\t\tfor (const ref of page.refs) {\n\t\t\t\t\tsourceBytes += ref.locator.length;\n\t\t\t\t\tif (sourceBytes > limits.maxSourceBytes || messages.length >= limits.maxMessages)\n\t\t\t\t\t\tthrow new Error(\"IPython sent-message history budget exceeded\");\n\t\t\t\t\tconst hydrated = await history.hydrateEntry(ref.entryId, limits.maxSourceBytes);\n\t\t\t\t\tconst sent =\n\t\t\t\t\t\thydrated?.entry.type === \"custom\"\n\t\t\t\t\t\t\t? parsePersistedIpythonSentAgentMessage(hydrated.entry.data)\n\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\tif (!sent || sent.toolCallId !== toolCallId)\n\t\t\t\t\t\tthrow new Error(\"IPython sent-message source is unavailable\");\n\t\t\t\t\tmessages.push(sent.message);\n\t\t\t\t}\n\t\t\t\tcursor = page.nextCursor ?? undefined;\n\t\t\t} while (cursor);\n\t\t\treturn messages;\n\t\t});\n\t\tfor (const sent of sentMessages) appendSentAgentMessageToToolResult(message, toolCallId, sent);\n\t\trefreshOutput?.(message);\n\t}\n\n\tprivate _recordLateIpythonSentAgentMessage(toolCallId: string, message: KernelSentAgentMessage): void {\n\t\tconst refreshOutput = this._refreshInvocationOutput;\n\t\tconst record = async () => {\n\t\t\tif (this._disposed) return;\n\t\t\tif (this.sessionManager.supportsCapturedHistoryReads()) {\n\t\t\t\tconst sessionId = this.sessionId;\n\t\t\t\tconst sessionFile = this.sessionFile;\n\t\t\t\tconst captured = structuredClone(message);\n\t\t\t\tconst result = await this.sessionManager.appendIpythonSentAgentMessage({ toolCallId, message: captured });\n\t\t\t\tif (!result.appended || sessionId !== this.sessionId || sessionFile !== this.sessionFile) return;\n\t\t\t\tfor (let index = this.agent.state.messages.length - 1; index >= 0; index--) {\n\t\t\t\t\tif (appendSentAgentMessageToToolResult(this.agent.state.messages[index], toolCallId, captured)) {\n\t\t\t\t\t\trefreshOutput?.(this.agent.state.messages[index]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis._emit({ type: \"ipython_sent_agent_message\", toolCallId, message: captured });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!this._rememberLateIpythonSentAgentMessage(toolCallId, message)) return;\n\t\t\tawait this.sessionManager.appendCustomEntry(IPYTHON_SENT_AGENT_MESSAGE_CUSTOM_ENTRY, { toolCallId, message });\n\t\t\tthis._emit({ type: \"ipython_sent_agent_message\", toolCallId, message });\n\t\t};\n\t\tthis._agentEventQueue = this._agentEventQueue.then(record, record);\n\t\tif (refreshOutput) this._invocationOutputUpdateTail = this._agentEventQueue;\n\t\tvoid this._agentEventQueue.catch((error) => this._surfaceSessionInputError(error));\n\t}\n\n\tprivate _emitGoalUpdate(): void {\n\t\tthis._emit({ type: \"goal_update\", goal: this.goalState });\n\t}\n\n\tprivate _loadPersistedRlmMaxDepthState(): PersistedRlmMaxDepthState | undefined {\n\t\tconst branch = this.sessionManager.getBranch();\n\t\tfor (let i = branch.length - 1; i >= 0; i--) {\n\t\t\tconst entry = branch[i];\n\t\t\tif (\n\t\t\t\tentry.type === \"custom\" &&\n\t\t\t\tentry.customType === RLM_MAX_DEPTH_STATE_CUSTOM_TYPE &&\n\t\t\t\tisPersistedRlmMaxDepthState(entry.data)\n\t\t\t) {\n\t\t\t\treturn entry.data;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _resolveRlmMaxDepth(persisted: PersistedRlmMaxDepthState | undefined): {\n\t\tmaxDepth: number;\n\t\tsource: RlmMaxDepthSource;\n\t} {\n\t\tif (persisted) {\n\t\t\treturn { maxDepth: persisted.maxDepth, source: \"chat\" };\n\t\t}\n\t\tif (this._configuredRlmMaxDepth !== undefined) {\n\t\t\treturn { maxDepth: this._configuredRlmMaxDepth, source: \"inherited\" };\n\t\t}\n\t\tconst global = this.settingsManager.getRlmMaxDepth();\n\t\tif (global !== undefined && isNonNegativeInteger(global)) {\n\t\t\treturn { maxDepth: global, source: \"global\" };\n\t\t}\n\t\tconst env = process.env.BASE_CONTEXT_RLM_MAX_DEPTH;\n\t\tif (env !== undefined && env !== \"\") {\n\t\t\treturn { maxDepth: parseDepth(env, 1, \"BASE_CONTEXT_RLM_MAX_DEPTH\"), source: \"env\" };\n\t\t}\n\t\treturn { maxDepth: 2, source: \"default\" };\n\t}\n\n\tprivate async _readRuntimeBootstrap(): Promise<{\n\t\tgoalState: GoalState;\n\t\tgoalSeedable: boolean;\n\t\trlmMaxDepth: PersistedRlmMaxDepthState | undefined;\n\t\thasBranchMessage: boolean;\n\t}> {\n\t\tconst { maxSourceBytes } = this.settingsManager.getCanonicalContextLimits();\n\t\treturn this.sessionManager.readBranchHistory(async (view) => {\n\t\t\tconst bootstrap = await view.branchBootstrap();\n\t\t\tlet remaining = maxSourceBytes;\n\t\t\tlet goalState = emptyGoalState();\n\t\t\tif (bootstrap.goalState) {\n\t\t\t\tif (bootstrap.goalState.locator.length > remaining)\n\t\t\t\t\tthrow new Error(\"Runtime bootstrap source byte budget exceeded\");\n\t\t\t\tconst hydrated = await view.hydrateEntry(bootstrap.goalState.id, remaining);\n\t\t\t\tremaining -= bootstrap.goalState.locator.length;\n\t\t\t\tif (\n\t\t\t\t\t!hydrated ||\n\t\t\t\t\thydrated.source.retention === \"retained-import\" ||\n\t\t\t\t\thydrated.entry.type !== \"custom\" ||\n\t\t\t\t\thydrated.entry.customType !== GOAL_STATE_CUSTOM_TYPE ||\n\t\t\t\t\t!isPersistedGoalState(hydrated.entry.data)\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Bootstrap goal source is unavailable or ineligible\");\n\t\t\t\tgoalState = normalizeGoalState(hydrated.entry.data);\n\t\t\t}\n\t\t\tlet rlmMaxDepth: PersistedRlmMaxDepthState | undefined;\n\t\t\tif (bootstrap.rlmMaxDepth) {\n\t\t\t\tif (bootstrap.rlmMaxDepth.locator.length > remaining)\n\t\t\t\t\tthrow new Error(\"Runtime bootstrap source byte budget exceeded\");\n\t\t\t\tconst hydrated = await view.hydrateEntry(bootstrap.rlmMaxDepth.id, remaining);\n\t\t\t\tif (\n\t\t\t\t\t!hydrated ||\n\t\t\t\t\thydrated.entry.type !== \"custom\" ||\n\t\t\t\t\thydrated.entry.customType !== RLM_MAX_DEPTH_STATE_CUSTOM_TYPE ||\n\t\t\t\t\t!isPersistedRlmMaxDepthState(hydrated.entry.data)\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Bootstrap RLM depth source is unavailable or ineligible\");\n\t\t\t\trlmMaxDepth = hydrated.entry.data;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tgoalState,\n\t\t\t\tgoalSeedable: bootstrap.goalSeedable,\n\t\t\t\trlmMaxDepth,\n\t\t\t\thasBranchMessage: bootstrap.hasBranchMessage,\n\t\t\t};\n\t\t});\n\t}\n\n\tprivate _loadPersistedGoalState(): GoalState {\n\t\tconst branch = this.sessionManager.getBranch();\n\t\tfor (let i = branch.length - 1; i >= 0; i--) {\n\t\t\tconst entry = branch[i];\n\t\t\tif (\n\t\t\t\tentry.type === \"custom\" &&\n\t\t\t\tentry.customType === GOAL_STATE_CUSTOM_TYPE &&\n\t\t\t\tthis.sessionManager.getEntryRetention(entry.id) !== \"retained-import\" &&\n\t\t\t\tisPersistedGoalState(entry.data)\n\t\t\t) {\n\t\t\t\treturn normalizeGoalState(entry.data);\n\t\t\t}\n\t\t}\n\t\treturn emptyGoalState();\n\t}\n\n\t/**\n\t * Whether the session branch is seedable for an initial goal. Returns true\n\t * only when the branch contains exclusively bootstrap entry types\n\t * (model_change, thinking_level_change, service_tier_change) and no\n\t * thread_goal_state custom entry. Any message, custom entry, or persisted\n\t * goal (including cleared/complete/error) means the session has been used\n\t * and should not be reseeded.\n\t */\n\tprivate _isBranchSeedable(): boolean {\n\t\tconst branch = this.sessionManager.getBranch();\n\t\tfor (const entry of branch) {\n\t\t\tswitch (entry.type) {\n\t\t\t\tcase \"model_change\":\n\t\t\t\tcase \"thinking_level_change\":\n\t\t\t\tcase \"service_tier_change\":\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"custom\":\n\t\t\t\t\tif (entry.customType === GOAL_STATE_CUSTOM_TYPE) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate async _reloadBranchRuntimeState(): Promise<void> {\n\t\tthis._contextMode = await this._readContextMode();\n\t\tconst bootstrap = this.sessionManager.isPersisted()\n\t\t\t? await this._readRuntimeBootstrap()\n\t\t\t: { goalState: this._loadPersistedGoalState(), rlmMaxDepth: this._loadPersistedRlmMaxDepthState() };\n\t\tthis._goalState = bootstrap.goalState;\n\t\tthis._goalAccountingStartedAt = this._goalState.status === \"active\" ? Date.now() : undefined;\n\t\tthis._emitGoalUpdate();\n\t\tconst previousMaxDepth = this._rlmMaxDepth;\n\t\tconst resolved = this._resolveRlmMaxDepth(bootstrap.rlmMaxDepth);\n\t\tthis._rlmMaxDepth = resolved.maxDepth;\n\t\tthis._rlmMaxDepthSource = resolved.source;\n\t\tif (resolved.maxDepth !== previousMaxDepth) {\n\t\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t\t}\n\t}\n\n\tprivate _captureGoalContinuationOwner(signal?: AbortSignal): GoalContinuationOwner {\n\t\tconst manager = this.sessionManager;\n\t\treturn {\n\t\t\tmanager,\n\t\t\tsessionId: manager.getSessionId(),\n\t\t\tsessionFile: manager.getSessionFile(),\n\t\t\tpumpEpoch: this._sessionInputPumpEpoch,\n\t\t\tgoal: this._goalState,\n\t\t\tgoalRevision: this._goalStateRevision,\n\t\t\taccountingStartedAt: this._goalAccountingStartedAt,\n\t\t\tsignal,\n\t\t};\n\t}\n\n\tprivate _isGoalContinuationOwnerCurrent(owner: GoalContinuationOwner): boolean {\n\t\treturn (\n\t\t\t!owner.signal?.aborted &&\n\t\t\t(!owner.checkpointOwner || this._isCompactionOwnerCurrent(owner.checkpointOwner)) &&\n\t\t\t!this._disposed &&\n\t\t\t!this._disposing &&\n\t\t\tthis.sessionManager === owner.manager &&\n\t\t\towner.manager.getSessionId() === owner.sessionId &&\n\t\t\towner.manager.getSessionFile() === owner.sessionFile &&\n\t\t\tthis._sessionInputPumpEpoch === (owner.checkpointOwner?.pumpEpoch ?? owner.pumpEpoch) &&\n\t\t\tthis._goalStateRevision === owner.goalRevision &&\n\t\t\tthis._goalState === owner.goal &&\n\t\t\tthis._goalAccountingStartedAt === owner.accountingStartedAt\n\t\t);\n\t}\n\n\tprivate _assertGoalContinuationOwner(owner: GoalContinuationOwner): void {\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) {\n\t\t\tthrow new StaleGoalContinuationError(\"Goal continuation owner changed\");\n\t\t}\n\t}\n\n\tprivate _stoppedContinuationOutcome(signal?: AbortSignal): AgentContinuationOutcome {\n\t\treturn { kind: signal?.aborted || this._disposed || this._disposing ? \"cancelled\" : \"finish\" };\n\t}\n\n\tprivate async _persistGoalState(\n\t\tgoal: GoalState,\n\t\tnativeGoalWrite?: CapturedNativeGoalWrite,\n\t\tcontinuationOwner?: GoalContinuationOwner,\n\t): Promise<void> {\n\t\tconst manager = continuationOwner?.manager ?? this.sessionManager;\n\t\tif (continuationOwner) this._assertGoalContinuationOwner(continuationOwner);\n\t\tif (nativeGoalWrite) await nativeGoalWrite(goal);\n\t\telse await manager.appendCustomEntry(GOAL_STATE_CUSTOM_TYPE, goal);\n\t\t// Accepted writes stay on their source. Do not admit a flush on a replacement after the ACK.\n\t\tif (continuationOwner) this._assertGoalContinuationOwner(continuationOwner);\n\t\t// Force flush so the goal state is durable before the first assistant response.\n\t\tawait manager.flushNow();\n\t}\n\n\tprivate async _setGoalState(\n\t\tnext: GoalState,\n\t\toptions: {\n\t\t\tpersist?: boolean;\n\t\t\tnativeGoalWrite?: CapturedNativeGoalWrite;\n\t\t\tcontinuationOwner?: GoalContinuationOwner;\n\t\t} = {},\n\t): Promise<GoalState> {\n\t\tconst owner = options.continuationOwner;\n\t\tif (owner) this._assertGoalContinuationOwner(owner);\n\t\t// A newer goal write invalidates a continuation before that write's awaited publication.\n\t\tthis._goalStateRevision++;\n\t\tif (owner) owner.goalRevision = this._goalStateRevision;\n\t\tconst normalized = normalizeGoalState({\n\t\t\t...next,\n\t\t\tupdatedAt: Date.now(),\n\t\t});\n\t\tif (options.persist !== false) {\n\t\t\tawait this._persistGoalState(normalized, options.nativeGoalWrite, owner);\n\t\t}\n\t\tif (owner) this._assertGoalContinuationOwner(owner);\n\t\tthis._goalState = normalized;\n\t\tif (normalized.status === \"active\") {\n\t\t\tthis._goalAccountingStartedAt ??= Date.now();\n\t\t} else {\n\t\t\tthis._goalAccountingStartedAt = undefined;\n\t\t}\n\t\tif (owner) {\n\t\t\towner.goal = normalized;\n\t\t\towner.accountingStartedAt = this._goalAccountingStartedAt;\n\t\t}\n\t\tthis._emitGoalUpdate();\n\t\treturn normalized;\n\t}\n\n\tprivate _goalWithCurrentWallClock(now = Date.now()): GoalState {\n\t\tif (this._goalState.status !== \"active\" || !this._goalAccountingStartedAt) {\n\t\t\treturn this._goalState;\n\t\t}\n\t\tconst elapsedSeconds = Math.floor((now - this._goalAccountingStartedAt) / 1000);\n\t\tif (elapsedSeconds <= 0) {\n\t\t\treturn this._goalState;\n\t\t}\n\t\treturn {\n\t\t\t...this._goalState,\n\t\t\ttimeUsedSeconds: this._goalState.timeUsedSeconds + elapsedSeconds,\n\t\t};\n\t}\n\n\tprivate _goalWithAccountedWallClock(): GoalState {\n\t\tconst now = Date.now();\n\t\tconst goal = this._goalWithCurrentWallClock(now);\n\t\tif (goal !== this._goalState) {\n\t\t\tthis._goalAccountingStartedAt = now;\n\t\t}\n\t\treturn goal;\n\t}\n\n\tprivate _cancelSessionActions(\n\t\tpredicate: (action: QueuedSessionAction) => boolean,\n\t\terror: Error,\n\t\tcandidates = this._actionStore.clearableActions(),\n\t): QueuedSessionAction[] {\n\t\tconst matching = candidates.filter(predicate);\n\t\tconst previousStates = new Map(matching.map((action) => [action.id, action.lifecycle.state]));\n\t\tconst preparing = this._actionStore\n\t\t\t.activeActions()\n\t\t\t.filter(\n\t\t\t\t(action): action is SessionAction<PreparedTurnPayload> =>\n\t\t\t\t\taction.payload.kind === \"turn\" && action.lifecycle.state === \"preparing\",\n\t\t\t);\n\t\tconst previousAnchor = preparing.at(-1);\n\t\tconst actions = this._actionStore.remove(predicate, candidates);\n\t\tconst restorableMessages: CustomMessage[] = [];\n\t\tconst removed = new Set(actions);\n\t\tif (previousAnchor && removed.has(previousAnchor)) {\n\t\t\tfor (const action of preparing) {\n\t\t\t\tif (!removed.has(action)) action.payload.prepared = undefined;\n\t\t\t}\n\t\t}\n\t\tfor (const action of actions) {\n\t\t\tconst ticket = this._actionStore.ticketFor(action);\n\t\t\tif (\n\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t(action.payload.acceptedAgentMessage ||\n\t\t\t\t\t!action.payload.queueVisible ||\n\t\t\t\t\tpreviousStates.get(action.id) !== \"queued\")\n\t\t\t) {\n\t\t\t\tticket.rejectDelivered(error);\n\t\t\t} else {\n\t\t\t\tticket.settleDelivered({ status: \"not_applicable\" });\n\t\t\t}\n\t\t\tticket.settleCompleted(error);\n\t\t\tconst dispatched = previousStates.get(action.id) === \"committing\" && action.payload.kind === \"turn\";\n\t\t\tif (action.payload.kind === \"turn\") {\n\t\t\t\tconst payload = action.payload;\n\t\t\t\tconst restorable = payload.records\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(record): record is DeliveryRecord & { message: CustomMessage } =>\n\t\t\t\t\t\t\t(record.role === \"next_turn\" || (payload.acceptedAgentMessage && record.role === \"prefix\")) &&\n\t\t\t\t\t\t\trecord.message.role === \"custom\" &&\n\t\t\t\t\t\t\t!record.durable,\n\t\t\t\t\t)\n\t\t\t\t\t.map((record) => cloneCustomMessage(record.message));\n\t\t\t\trestorableMessages.push(...restorable);\n\t\t\t\tif (dispatched) {\n\t\t\t\t\tpayload.captureRunMessages = new Set(payload.records.map((record) => record.message));\n\t\t\t\t\tthis.agent.state.messages = this.agent.state.messages.filter(\n\t\t\t\t\t\t(message) => !payload.captureRunMessages?.has(message),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!dispatched) {\n\t\t\t\tthis._actionStore.releaseTerminal(action);\n\t\t\t}\n\t\t}\n\t\tthis._pendingNextTurnMessages.unshift(...restorableMessages);\n\t\tif (actions.length > 0) this._notifySessionInputCheckpointChange();\n\t\treturn actions;\n\t}\n\n\tprivate _clearQueuedGoalContexts(): void {\n\t\tthis._goalContinuationAwaitsRlmWork = false;\n\t\tthis._pendingNextTurnMessages = this._pendingNextTurnMessages.filter(\n\t\t\t(message) => message.customType !== GOAL_CONTEXT_CUSTOM_TYPE,\n\t\t);\n\t\tthis.agent.removeQueuedMessages(\n\t\t\t(message) => message.role === \"custom\" && message.customType === GOAL_CONTEXT_CUSTOM_TYPE,\n\t\t);\n\t\tthis._cancelSessionActions(\n\t\t\t(action) =>\n\t\t\t\taction.payload.kind === \"turn\" && action.payload.customMessage?.customType === GOAL_CONTEXT_CUSTOM_TYPE,\n\t\t\tnew Error(\"Queued goal context was cleared before delivery.\"),\n\t\t);\n\t\tthis._emitQueueUpdate();\n\t}\n\n\tprivate async _startGoal(\n\t\tobjectiveText: string,\n\t\ttokenBudget: number | undefined,\n\t\tnativeGoalWrite?: CapturedNativeGoalWrite,\n\t): Promise<GoalState> {\n\t\tconst objective = validateGoalObjective(objectiveText);\n\t\tconst budget = validateGoalBudget(tokenBudget);\n\t\tconst now = Date.now();\n\t\tconst goal: GoalState = {\n\t\t\tactive: true,\n\t\t\tstatus: \"active\",\n\t\t\tgoalId: randomUUID(),\n\t\t\tobjective,\n\t\t\ttokenBudget: budget,\n\t\t\ttokensUsed: 0,\n\t\t\ttimeUsedSeconds: 0,\n\t\t\tcontinuationsUsed: 0,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t};\n\t\tthis._goalAccountingStartedAt = now;\n\t\tthis._goalContinuationAwaitsRlmWork = false;\n\t\treturn this._setGoalState(goal, { nativeGoalWrite });\n\t}\n\n\tprivate async _clearGoal(nativeGoalWrite?: CapturedNativeGoalWrite): Promise<void> {\n\t\tthis._clearQueuedGoalContexts();\n\t\tawait this._setGoalState(emptyGoalState(), { nativeGoalWrite });\n\t}\n\n\tprivate async _pauseGoal(reason = \"Paused by user\", nativeGoalWrite?: CapturedNativeGoalWrite): Promise<void> {\n\t\tthis._clearQueuedGoalContexts();\n\t\tif (this._goalState.status !== \"active\") {\n\t\t\tthis._emitGoalUpdate();\n\t\t\treturn;\n\t\t}\n\t\tconst goal = this._goalWithAccountedWallClock();\n\t\tawait this._setGoalState(\n\t\t\t{\n\t\t\t\t...goal,\n\t\t\t\tactive: false,\n\t\t\t\tstatus: \"paused\",\n\t\t\t\tlastReason: reason,\n\t\t\t\tlastError: undefined,\n\t\t\t},\n\t\t\t{ nativeGoalWrite },\n\t\t);\n\t}\n\n\tprivate async _resumeGoal(nativeGoalWrite?: CapturedNativeGoalWrite): Promise<void> {\n\t\tif (!this._goalState.objective) {\n\t\t\tthis._emitGoalUpdate();\n\t\t\treturn;\n\t\t}\n\t\tif (this._goalState.status !== \"paused\" && this._goalState.status !== \"budget_limited\") {\n\t\t\tthis._emitGoalUpdate();\n\t\t\treturn;\n\t\t}\n\t\tconst exhausted =\n\t\t\tthis._goalState.tokenBudget !== undefined && this._goalState.tokensUsed >= this._goalState.tokenBudget;\n\t\tconst nextStatus: GoalStatus = exhausted ? \"budget_limited\" : \"active\";\n\t\tawait this._setGoalState(\n\t\t\t{\n\t\t\t\t...this._goalState,\n\t\t\t\tactive: nextStatus === \"active\",\n\t\t\t\tstatus: nextStatus,\n\t\t\t\tlastReason: exhausted ? \"Goal token budget already reached\" : undefined,\n\t\t\t\tlastError: undefined,\n\t\t\t},\n\t\t\t{ nativeGoalWrite },\n\t\t);\n\t\tif (nextStatus === \"active\") {\n\t\t\tawait this._runOrQueueGoalContext(\"continuation\");\n\t\t}\n\t}\n\n\tprivate async _finishGoalWithError(errorMessage: string, continuationOwner?: GoalContinuationOwner): Promise<void> {\n\t\tif (continuationOwner) this._assertGoalContinuationOwner(continuationOwner);\n\t\tif (!this._goalState.objective || this._goalState.status !== \"active\") {\n\t\t\treturn;\n\t\t}\n\t\tconst goal = this._goalWithAccountedWallClock();\n\t\tif (continuationOwner) continuationOwner.accountingStartedAt = this._goalAccountingStartedAt;\n\t\tawait this._setGoalState(\n\t\t\t{\n\t\t\t\t...goal,\n\t\t\t\tactive: false,\n\t\t\t\tstatus: \"error\",\n\t\t\t\tlastReason: errorMessage,\n\t\t\t\tlastError: errorMessage,\n\t\t\t},\n\t\t\t{ continuationOwner },\n\t\t);\n\t}\n\n\tprivate async _finishGoalForTerminalAssistantMessage(\n\t\tmessage: AssistantMessage,\n\t\tcontinuationOwner?: GoalContinuationOwner,\n\t): Promise<void> {\n\t\tif (continuationOwner) this._assertGoalContinuationOwner(continuationOwner);\n\t\tif (this._goalState.status !== \"active\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (message.stopReason === \"aborted\") {\n\t\t\tthis._goalAbortInProgress = false;\n\t\t\treturn;\n\t\t}\n\n\t\tif (message.stopReason === \"error\") {\n\t\t\tif (this._goalAbortInProgress) {\n\t\t\t\tthis._goalAbortInProgress = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this._finishGoalWithError(message.errorMessage || \"Assistant response failed\", continuationOwner);\n\t\t}\n\t}\n\n\tprivate async _stopGoalContinuationForTerminalMessage(\n\t\tmessage: AssistantMessage,\n\t\tcontinuationOwner?: GoalContinuationOwner,\n\t): Promise<boolean> {\n\t\tif (message.stopReason !== \"error\" && message.stopReason !== \"aborted\") {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tawait this._finishGoalForTerminalAssistantMessage(message, continuationOwner);\n\t\t} catch {\n\t\t\t// Goal hooks must not reject; listener failures should not crash the agent loop.\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate _parseGoalSlashCommand(text: string): GoalSlashCommand | undefined {\n\t\tconst command = parseSessionSlashCommand(text);\n\t\tif (command?.name !== \"goal\") return undefined;\n\n\t\tconst rest = command.args;\n\t\tconst normalized = rest.toLowerCase();\n\t\tif (!rest || normalized === \"status\") {\n\t\t\treturn { kind: \"status\" };\n\t\t}\n\t\tif (normalized === \"clear\" || normalized === \"stop\") {\n\t\t\treturn { kind: \"clear\" };\n\t\t}\n\t\tif (normalized === \"pause\") {\n\t\t\treturn { kind: \"pause\" };\n\t\t}\n\t\tif (normalized === \"resume\") {\n\t\t\treturn { kind: \"resume\" };\n\t\t}\n\n\t\tlet tokenBudget: number | undefined;\n\t\tlet objective = rest;\n\t\tconst firstToken = rest.split(/\\s+/, 1)[0] ?? \"\";\n\t\tif (\n\t\t\tfirstToken === \"--budget\" ||\n\t\t\tfirstToken === \"--token-budget\" ||\n\t\t\tfirstToken.startsWith(\"--budget=\") ||\n\t\t\tfirstToken.startsWith(\"--token-budget=\")\n\t\t) {\n\t\t\tlet valueText: string;\n\t\t\tif (firstToken === \"--budget\" || firstToken === \"--token-budget\") {\n\t\t\t\tconst withoutFlag = rest.slice(firstToken.length).trimStart();\n\t\t\t\tconst nextSpace = withoutFlag.search(/\\s/);\n\t\t\t\tif (nextSpace < 0) {\n\t\t\t\t\tthrow new Error(\"Usage: /goal [--budget <tokens>] <objective>\");\n\t\t\t\t}\n\t\t\t\tvalueText = withoutFlag.slice(0, nextSpace);\n\t\t\t\tobjective = withoutFlag.slice(nextSpace + 1).trim();\n\t\t\t} else {\n\t\t\t\tconst separator = firstToken.indexOf(\"=\");\n\t\t\t\tvalueText = firstToken.slice(separator + 1);\n\t\t\t\tobjective = rest.slice(firstToken.length).trim();\n\t\t\t}\n\t\t\ttokenBudget = parseGoalBudgetValue(valueText);\n\t\t}\n\n\t\treturn {\n\t\t\tkind: \"start\",\n\t\t\tobjective: validateGoalObjective(objective),\n\t\t\ttokenBudget,\n\t\t};\n\t}\n\n\tprivate _parseAutonomousSlashCommand(text: string): AutonomousSlashCommand | undefined {\n\t\tconst command = parseSessionSlashCommand(text);\n\t\tif (command?.name !== \"autonomous\") return undefined;\n\t\tconst rest = command.args.toLowerCase();\n\t\tif (!rest || rest === \"status\") {\n\t\t\treturn { kind: \"status\" };\n\t\t}\n\t\tif (rest === \"on\" || rest === \"enable\" || rest === \"enabled\") {\n\t\t\treturn { kind: \"on\" };\n\t\t}\n\t\tif (rest === \"off\" || rest === \"disable\" || rest === \"disabled\") {\n\t\t\treturn { kind: \"off\" };\n\t\t}\n\t\tthrow new Error(\"Usage: /autonomous [on|off|status]\");\n\t}\n\n\tprivate _formatAutonomousStatus(): string {\n\t\tconst status = this.getAutonomousStatus();\n\t\tconst state = status.enabled ? \"on\" : \"off\";\n\t\treturn `Autonomous mode: ${state}. Continuations: ${status.continuationsUsed}/${status.limits.maxContinuations}. Turns: ${status.turnsUsed}/${status.limits.maxTurns}. Tokens: ${status.tokensUsed}/${status.limits.maxTokens}.`;\n\t}\n\n\tprivate async _emitAutonomousStatus(): Promise<void> {\n\t\tconst message = {\n\t\t\trole: \"custom\" as const,\n\t\t\tcustomType: \"autonomous_status\",\n\t\t\tcontent: this._formatAutonomousStatus(),\n\t\t\tdisplay: true,\n\t\t\tdetails: this.getAutonomousStatus(),\n\t\t\ttimestamp: Date.now(),\n\t\t} satisfies CustomMessage<AgentAutonomousStatus>;\n\t\tawait this.sessionManager.appendCustomMessageEntry(\n\t\t\tmessage.customType,\n\t\t\tmessage.content,\n\t\t\tmessage.display,\n\t\t\tmessage.details,\n\t\t);\n\t\tthis.agent.state.messages.push(message);\n\t\tthis._emit({ type: \"message_start\", message });\n\t\tthis._emit({ type: \"message_end\", message });\n\t}\n\n\tprivate async _handleAutonomousSlashCommand(text: string): Promise<boolean> {\n\t\tconst command = this._parseAutonomousSlashCommand(text);\n\t\tif (!command) {\n\t\t\treturn false;\n\t\t}\n\t\tif (command.kind === \"on\") {\n\t\t\tsetAutonomousEnabled(this._autonomousState, true, { cwd: this._cwd });\n\t\t} else if (command.kind === \"off\") {\n\t\t\tsetAutonomousEnabled(this._autonomousState, false);\n\t\t\tthis._clearQueuedAutonomousContinuations();\n\t\t}\n\t\tawait this._emitAutonomousStatus();\n\t\treturn true;\n\t}\n\n\tprivate _appendBeforeAgentStartMessages(\n\t\tmessages: AgentMessage[],\n\t\tresult: Awaited<ReturnType<ExtensionRunner[\"emitBeforeAgentStart\"]>>,\n\t): void {\n\t\tif (!result?.messages) return;\n\t\tfor (const message of result.messages) {\n\t\t\tmessages.push({\n\t\t\t\trole: \"custom\",\n\t\t\t\tcustomType: message.customType,\n\t\t\t\tcontent: message.content,\n\t\t\t\tdisplay: message.display,\n\t\t\t\tdetails: message.details,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async _validateCanStartAgentRun(): Promise<void> {\n\t\tif (!this.model) {\n\t\t\tthrow new Error(formatNoModelSelectedMessage());\n\t\t}\n\t\tif (!this._modelRegistry.hasConfiguredAuth(this.model)) {\n\t\t\tconst isOAuth = this._modelRegistry.isUsingOAuth(this.model);\n\t\t\tif (isOAuth) {\n\t\t\t\tthrow new Error(formatAuthenticationFailedMessage(this.model.provider));\n\t\t\t}\n\t\t\tthrow new Error(formatNoApiKeyFoundMessage(this.model.provider));\n\t\t}\n\t}\n\n\t/**\n\t * Goals are pursued through the kernel goal skill, so the only tool the\n\t * model needs is ipython. Force-activate it (including into a live\n\t * continuation context) so the model can always reach `goal.complete()`.\n\t */\n\tprivate _ensureGoalRuntimeActive(context?: AgentContext): void {\n\t\tif (!this._includeGoals) {\n\t\t\tthrow new Error(\"Goals are disabled. Enable goals before using /goal.\");\n\t\t}\n\t\tconst ipythonTool = this._toolRegistry.get(\"ipython\");\n\t\tif (!ipythonTool) {\n\t\t\tthrow new Error(\"Goals require the ipython tool, which is not available in this session.\");\n\t\t}\n\t\tconst activeToolNames = new Set(this.getActiveToolNames());\n\t\tif (!activeToolNames.has(\"ipython\")) {\n\t\t\tactiveToolNames.add(\"ipython\");\n\t\t\tthis.setActiveToolsByName([...activeToolNames]);\n\t\t}\n\t\tif (context) {\n\t\t\tconst contextTools = [...(context.tools ?? [])];\n\t\t\tif (!contextTools.some((tool) => tool.name === \"ipython\")) {\n\t\t\t\tcontextTools.push(ipythonTool);\n\t\t\t\tcontext.tools = contextTools;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _scheduleGoalContinuationAfterRlmWork(): void {\n\t\tif (this._goalResumeOperation || !this._goalContinuationAwaitsRlmWork) return;\n\t\tconst operation = this._resumeGoalContinuationAfterRlmWork();\n\t\tthis._goalResumeOperation = operation;\n\t\tvoid operation\n\t\t\t.finally(() => {\n\t\t\t\tif (this._goalResumeOperation === operation) this._goalResumeOperation = undefined;\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t})\n\t\t\t.catch((error) => this._surfaceSessionInputError(error));\n\t}\n\n\tprivate async _resumeGoalContinuationAfterRlmWork(): Promise<void> {\n\t\tif (!this._goalContinuationAwaitsRlmWork) return;\n\t\tif (this._disposed || this._disposing || this._hasUnsettledRlmQuiescenceWork()) return;\n\t\tif (this._goalState.status !== \"active\" || !this._goalState.objective) {\n\t\t\tthis._goalContinuationAwaitsRlmWork = false;\n\t\t\treturn;\n\t\t}\n\t\t// Keep the deferral while admission is paused or the pump is suspended\n\t\t// (post-abort); the pause release and resumeQueuedWork retry.\n\t\tif (this._sessionInputAdmissionPauses.size > 0 || this._sessionInputPumpSuspended) return;\n\t\tconst owner = this._captureGoalContinuationOwner();\n\t\tconst goalBeforeResume = owner.goal;\n\t\ttry {\n\t\t\tthis._ensureGoalRuntimeActive();\n\t\t\tawait this._setGoalState(\n\t\t\t\t{\n\t\t\t\t\t...owner.goal,\n\t\t\t\t\tcontinuationsUsed: owner.goal.continuationsUsed + 1,\n\t\t\t\t\tlastReason: undefined,\n\t\t\t\t\tlastError: undefined,\n\t\t\t\t},\n\t\t\t\t{ continuationOwner: owner },\n\t\t\t);\n\t\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return;\n\t\t\tconst message = createGoalContextMessage(owner.goal, \"continuation\");\n\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\t// No front: a settling child's terminal notice must be read first.\n\t\t\tthis._admitSessionInput(\n\t\t\t\tthis._createPreparedTurnAction(\"followUp\", normalized.text, normalized.images, {\n\t\t\t\t\tmessage,\n\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tthis._goalContinuationAwaitsRlmWork = false;\n\t\t} catch {\n\t\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return;\n\t\t\t// Compensate only on the unchanged owner; an accepted old write is not rolled back on a new goal.\n\t\t\ttry {\n\t\t\t\tawait this._setGoalState(goalBeforeResume, { continuationOwner: owner });\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof StaleGoalContinuationError)) throw error;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _runOrQueueGoalContext(kind: \"continuation\" | \"objective_updated\", images?: ImageContent[]): void {\n\t\tif (!this._goalState.objective) return;\n\t\tthis._ensureGoalRuntimeActive();\n\t\tconst message = createGoalContextMessage(this._goalState, kind, images);\n\t\tconst normalized = normalizeMessageContent(message.content);\n\t\tconst action = this._createPreparedTurnAction(\"followUp\", normalized.text, normalized.images, {\n\t\t\tmessage,\n\t\t\tresumeIfIdle: true,\n\t\t});\n\t\tthis._admitSessionInput(action, { front: true, wake: false });\n\t}\n\n\tprivate async _handleGoalSlashCommand(\n\t\ttext: string,\n\t\timages: ImageContent[] | undefined,\n\t\tcontext?: GoalOriginContext,\n\t): Promise<boolean> {\n\t\tconst command = this._parseGoalSlashCommand(text);\n\t\tif (!command) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst previousGoalId = this._goalState.goalId;\n\t\tconst replacementOperation = this._goalState.objective ? \"revise\" : \"create\";\n\t\tconst origin = (operation: GoalOperationOrigin[\"operation\"]): CapturedNativeGoalWrite | undefined => {\n\t\t\tif (!context) return undefined;\n\t\t\tconst { writer, ...captured } = context;\n\t\t\treturn writer.captureGoalOperation({\n\t\t\t\tversion: 1,\n\t\t\t\tkind: \"goal_operation\",\n\t\t\t\t...captured,\n\t\t\t\toperation,\n\t\t\t\tpreviousGoalId,\n\t\t\t});\n\t\t};\n\n\t\tif (command.kind === \"status\") {\n\t\t\tthis._emitGoalUpdate();\n\t\t\treturn true;\n\t\t}\n\n\t\tif (command.kind === \"clear\") {\n\t\t\tawait this._clearGoal(origin(\"clear\"));\n\t\t\treturn true;\n\t\t}\n\n\t\tif (command.kind === \"pause\") {\n\t\t\tawait this._pauseGoal(undefined, origin(\"pause\"));\n\t\t\treturn true;\n\t\t}\n\n\t\tif (command.kind === \"resume\") {\n\t\t\tawait this._resumeGoal(origin(\"resume\"));\n\t\t\treturn true;\n\t\t}\n\n\t\tconst previousWasActive = this._goalState.status === \"active\";\n\t\tconst nativeGoalWrite = origin(replacementOperation);\n\t\tif (!this.isStreaming) {\n\t\t\tawait this._validateCanStartAgentRun();\n\t\t}\n\t\tthis._ensureGoalRuntimeActive();\n\t\tthis._clearQueuedGoalContexts();\n\t\tawait this._startGoal(command.objective, command.tokenBudget, nativeGoalWrite);\n\t\tawait this._runOrQueueGoalContext(previousWasActive ? \"objective_updated\" : \"continuation\", images);\n\t\treturn true;\n\t}\n\n\tprivate async _accountGoalUsageForAssistantMessage(\n\t\tmessage: AssistantMessage,\n\t\towner?: GoalContinuationOwner,\n\t): Promise<boolean> {\n\t\tif (owner) this._assertGoalContinuationOwner(owner);\n\t\tif (!this._goalState.objective) {\n\t\t\treturn false;\n\t\t}\n\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\treturn false;\n\t\t}\n\t\tif (this._goalAccountedAssistantMessages.has(message)) {\n\t\t\treturn false;\n\t\t}\n\t\t// Usage is attributed at the assistant message's message_end, which fires\n\t\t// before that turn's ipython cell runs. goal.complete() only arrives later\n\t\t// over the kernel host bridge, so the completing turn is always accounted\n\t\t// while the goal is still active. Only count turns spent pursuing the goal;\n\t\t// post-completion turns (e.g. a closing summary) must not be attributed.\n\t\tif (this._goalState.status !== \"active\") {\n\t\t\treturn false;\n\t\t}\n\t\tthis._goalAccountedAssistantMessages.add(message);\n\t\tconst tokenDelta = goalTokenDeltaForUsage(message.usage);\n\t\tconst goal = this._goalWithAccountedWallClock();\n\t\tif (owner) owner.accountingStartedAt = this._goalAccountingStartedAt;\n\t\tconst nextGoal: GoalState = {\n\t\t\t...goal,\n\t\t\ttokensUsed: goal.tokensUsed + tokenDelta,\n\t\t};\n\t\tconst budgetReached = nextGoal.tokenBudget !== undefined && nextGoal.tokensUsed >= nextGoal.tokenBudget;\n\t\tif (!budgetReached) {\n\t\t\tawait this._setGoalState(nextGoal, { continuationOwner: owner });\n\t\t\treturn false;\n\t\t}\n\t\tawait this._setGoalState(\n\t\t\t{\n\t\t\t\t...nextGoal,\n\t\t\t\tactive: false,\n\t\t\t\tstatus: \"budget_limited\",\n\t\t\t\tlastReason: `Reached ${nextGoal.tokenBudget} token goal budget`,\n\t\t\t\tlastError: undefined,\n\t\t\t},\n\t\t\t{ continuationOwner: owner },\n\t\t);\n\t\treturn true;\n\t}\n\n\tprivate get _steeringStopPending(): boolean {\n\t\treturn (\n\t\t\tthis._actionStore.queuedActions(\"next_turn_boundary\").length > 0 ||\n\t\t\tthis._actionStore\n\t\t\t\t.activeActions(\"next_turn_boundary\")\n\t\t\t\t.some(\n\t\t\t\t\t(action) =>\n\t\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\t\t(action.lifecycle.state === \"selected\" || action.lifecycle.state === \"preparing\"),\n\t\t\t\t)\n\t\t);\n\t}\n\n\tprivate _shouldStopBeforeTurn(): boolean {\n\t\treturn this._steeringStopPending;\n\t}\n\n\tprivate _captureCompactionOwner(signal?: AbortSignal): CompactionOwner {\n\t\tconst manager = this.sessionManager;\n\t\treturn {\n\t\t\tmanager,\n\t\t\tagent: this.agent,\n\t\t\tsessionId: manager.getSessionId(),\n\t\t\tsessionFile: manager.getSessionFile(),\n\t\t\tpumpEpoch: this._sessionInputPumpEpoch,\n\t\t\tisSourceCurrent: manager.captureCompactionSourceOwner(),\n\t\t\trequests: this.requests,\n\t\t\tsemanticEdges: this._semanticEdges,\n\t\t\textensions: this._extensionRunner,\n\t\t\tprovisioner: this._ipythonKernelProvisioner,\n\t\t\tsignal,\n\t\t};\n\t}\n\n\tprivate _isCompactionSourceOwnerCurrent(owner: CompactionOwner): boolean {\n\t\treturn (\n\t\t\tthis.sessionManager === owner.manager &&\n\t\t\tthis.agent === owner.agent &&\n\t\t\towner.manager.getSessionId() === owner.sessionId &&\n\t\t\towner.manager.getSessionFile() === owner.sessionFile &&\n\t\t\towner.isSourceCurrent() &&\n\t\t\tthis.requests === owner.requests &&\n\t\t\tthis._semanticEdges === owner.semanticEdges &&\n\t\t\tthis._extensionRunner === owner.extensions &&\n\t\t\tthis._ipythonKernelProvisioner === owner.provisioner\n\t\t);\n\t}\n\n\tprivate _isCompactionOwnerCurrent(owner: CompactionOwner): boolean {\n\t\treturn (\n\t\t\t!this._disposed &&\n\t\t\t!this._disposing &&\n\t\t\t!owner.signal?.aborted &&\n\t\t\tthis._isCompactionSourceOwnerCurrent(owner) &&\n\t\t\tthis._sessionInputPumpEpoch === owner.pumpEpoch\n\t\t);\n\t}\n\n\tprivate _assertCompactionSourceOwner(owner: CompactionOwner): void {\n\t\tif (!this._isCompactionSourceOwnerCurrent(owner))\n\t\t\tthrow new StaleCompactionOwnerError(\"Compaction source owner changed\");\n\t}\n\n\tprivate _assertCompactionOwner(owner: CompactionOwner): void {\n\t\tif (!this._isCompactionOwnerCurrent(owner)) throw new StaleCompactionOwnerError(\"Compaction owner changed\");\n\t}\n\n\tprivate _checkpointActionPending({ action }: CheckpointAction): boolean {\n\t\treturn (\n\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t!primaryDeliveryRecord(action).started &&\n\t\t\t(action.lifecycle.state === \"queued\" ||\n\t\t\t\taction.lifecycle.state === \"selected\" ||\n\t\t\t\taction.lifecycle.state === \"preparing\" ||\n\t\t\t\taction.lifecycle.state === \"committing\")\n\t\t);\n\t}\n\n\tprivate _captureCheckpointResume(owner: CompactionOwner, boundary?: CheckpointBoundary): CheckpointResume {\n\t\tconst actions = this._actionStore\n\t\t\t.unfinishedActions()\n\t\t\t.filter((action) => action.payload.kind === \"turn\" && !primaryDeliveryRecord(action).started)\n\t\t\t.map((action) => ({ action, ticket: this._actionStore.ticketFor(action).ticket }));\n\t\treturn { owner, boundary, actions };\n\t}\n\n\tprivate _checkpointHasResume(resume: CheckpointResume): boolean {\n\t\treturn (\n\t\t\tresume.boundary?.state === \"pending\" || resume.actions.some((action) => this._checkpointActionPending(action))\n\t\t);\n\t}\n\n\tprivate async _shouldStopAfterTurn(context: ShouldStopAfterTurnContext): Promise<boolean> {\n\t\t// The legacy direct adapter has no finalized-batch decision. The installed native hook does.\n\t\tconst last = this.agent.state.messages.at(-1);\n\t\treturn (\n\t\t\t(await this._getTurnOutcome({ ...context, hasMoreToolCalls: !!last && last.role !== \"assistant\" })).kind !==\n\t\t\t\"proceed\"\n\t\t);\n\t}\n\n\tprivate async _getTurnOutcome(context: GetTurnOutcomeContext, signal?: AbortSignal): Promise<AgentTurnOutcome> {\n\t\tconst sourceOwner = signal ? this._invocationCompactionOwner : this._captureCompactionOwner();\n\t\tif (\n\t\t\t!sourceOwner ||\n\t\t\tsignal?.aborted ||\n\t\t\t(signal && sourceOwner.signal !== signal) ||\n\t\t\t!this._isCompactionSourceOwnerCurrent(sourceOwner)\n\t\t)\n\t\t\treturn { kind: \"cancelled\" };\n\t\t// This is a new turn-boundary admission. Its source predicate still belongs to the original invocation.\n\t\tconst owner = { ...sourceOwner, pumpEpoch: this._sessionInputPumpEpoch };\n\t\tconst requested = this._pendingRequestedCompaction;\n\t\tconst mayCheckpoint =\n\t\t\tthis._contextOptimizationAllowed() ||\n\t\t\t(requested !== undefined && this._isCompactionOwnerCurrent(requested.owner));\n\t\tconst preparing = mayCheckpoint\n\t\t\t? this._captureCheckpointResume(\n\t\t\t\t\towner,\n\t\t\t\t\tcontext.hasMoreToolCalls ? { kind: \"tool\", state: \"pending\" } : undefined,\n\t\t\t\t)\n\t\t\t: undefined;\n\t\tif (preparing) this._pendingCheckpoint = preparing;\n\t\tconst current = () =>\n\t\t\tpreparing\n\t\t\t\t? this._isCompactionOwnerCurrent(owner)\n\t\t\t\t: !signal?.aborted && !this._disposed && !this._disposing && this._isCompactionSourceOwnerCurrent(owner);\n\t\tconst goalOwner = { ...this._captureGoalContinuationOwner(signal), checkpointOwner: owner };\n\t\tconst autonomousOwner = this._captureThresholdAutonomousOwner();\n\t\ttry {\n\t\t\tif (await this._stopGoalContinuationForTerminalMessage(context.message, goalOwner)) return { kind: \"finish\" };\n\t\t\tif (!current()) return { kind: \"cancelled\" };\n\t\t\ttry {\n\t\t\t\tif (await this._accountGoalUsageForAssistantMessage(context.message, goalOwner)) {\n\t\t\t\t\tthis._assertGoalContinuationOwner(goalOwner);\n\t\t\t\t\tconst message = createGoalContextMessage(goalOwner.goal, \"budget_limit\");\n\t\t\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\t\t\tthis._admitSessionInput(\n\t\t\t\t\t\tthis._createPreparedTurnAction(\"steer\", normalized.text, normalized.images, {\n\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ordinary accounting retains its non-rejection policy; it cannot publish on a replacement.\n\t\t\t}\n\t\t\tif (!current()) return { kind: \"cancelled\" };\n\t\t\t// Keep mandatory serialized refinement before threshold and steering, without self-waiting for idle.\n\t\t\tif (this._serializedRefine) {\n\t\t\t\tawait this._agentEventQueue;\n\t\t\t\tif (!current()) return { kind: \"cancelled\" };\n\t\t\t\tawait this._runSerializedRefineCheckpoint();\n\t\t\t}\n\t\t\tif (!current()) return { kind: \"cancelled\" };\n\t\t\ttry {\n\t\t\t\tif (\n\t\t\t\t\tpreparing &&\n\t\t\t\t\t(await this._shouldStopForThresholdCompaction(context, owner, goalOwner, autonomousOwner))\n\t\t\t\t) {\n\t\t\t\t\tconst resume = this._pendingCheckpoint;\n\t\t\t\t\treturn { kind: resume && this._checkpointHasResume(resume) ? \"checkpoint_then_continue\" : \"finish\" };\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof StaleCompactionOwnerError)) throw error;\n\t\t\t\treturn { kind: \"cancelled\" };\n\t\t\t}\n\t\t\tif (!current()) return { kind: \"cancelled\" };\n\t\t\treturn { kind: this._steeringStopPending ? \"finish\" : \"proceed\" };\n\t\t} finally {\n\t\t\t// Only an actual checkpoint decision replaces this preparing reference.\n\t\t\tif (preparing && this._pendingCheckpoint === preparing) this._pendingCheckpoint = undefined;\n\t\t}\n\t}\n\n\tprivate async _shouldStopForThresholdCompaction(\n\t\tcontext: GetTurnOutcomeContext,\n\t\towner: CompactionOwner,\n\t\tgoalOwner: GoalContinuationOwner,\n\t\tautonomousOwner: ThresholdAutonomousOwner,\n\t): Promise<boolean> {\n\t\tconst pending = this._pendingRequestedCompaction;\n\t\tif (pending && !this._isCompactionOwnerCurrent(pending.owner)) {\n\t\t\tif (this._pendingRequestedCompaction === pending) this._pendingRequestedCompaction = undefined;\n\t\t}\n\t\tconst requested = pending !== undefined && this._pendingRequestedCompaction === pending;\n\t\tif (!requested && !(await this._thresholdCompactionNeeded(context, owner, goalOwner, autonomousOwner)))\n\t\t\treturn false;\n\t\tif (!this._isCompactionOwnerCurrent(owner)) return false;\n\t\tthis._pendingCheckpoint = this._captureCheckpointResume(\n\t\t\towner,\n\t\t\tcontext.hasMoreToolCalls ? { kind: \"tool\", state: \"pending\" } : undefined,\n\t\t);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Serialized-mode auto-refine checkpoint called from _shouldStopAfterTurn.\n\t * Runs the review, planning, and application phases inline between turns\n\t * at the quiescent shouldStopAfterTurn boundary. This path NEVER calls\n\t * _maybeAutoRefine, _runApprovedRefine, public refine(), agent.abort(),\n\t * or agent.waitForIdle — all of which would deadlock or defer because\n\t * the agent loop still owns activeRun at this point. Instead it calls\n\t * _reviewAutoRefine, _planRefine, and _applyRefine directly with proper\n\t * in-flight guards and counter resets.\n\t */\n\tprivate async _runSerializedRefineCheckpoint(): Promise<void> {\n\t\tif (this._compactionSetupFailure) return;\n\t\tif (this._disposed || this._disposing) {\n\t\t\treturn;\n\t\t}\n\n\t\t// 1. Await any background plan that was started at message_end\n\t\t// (either for a pending refine.run or for interval-triggered\n\t\t// auto-refine). This must be checked BEFORE the pending and\n\t\t// interval checks because background planning may have consumed\n\t\t// the pending request at message_end.\n\t\tconst branchVersion = this._autoRefineBranchVersion;\n\t\tconst bgConsumption = await this._consumeSerializedBackgroundPlan(async (bgResult) => {\n\t\t\tif (this._disposed || this._disposing) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (bgResult?.status === \"plan\") {\n\t\t\t\tif (bgResult.branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\t\tif (!this._pendingRequestedRefine) {\n\t\t\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Apply the EXACT background plan directly via _applyRefine\n\t\t\t\t\t// (no second _planRefine call).\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this._applySerializedPlan(bgResult);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthis._emitRefineFailed(error);\n\t\t\t\t\t}\n\t\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t\tif (!this._pendingRequestedRefine) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (bgResult?.status === \"skip\") {\n\t\t\t\t// Reviewer declined or an extension skipped during background planning.\n\t\t\t\t// Reset exactly once. Never retry the interval review; only fall through for a separate pending refine.run.\n\t\t\t\tif (bgResult.explicit) {\n\t\t\t\t\tthis._emitRefineFailed(new RefineSkippedError(\"Refinement skipped by extension\"));\n\t\t\t\t}\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\tif (!this._pendingRequestedRefine) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (bgResult?.status === \"failure\") {\n\t\t\t\t// Background review or planning failure stamps cooldown without a synchronous retry.\n\t\t\t\t// A separately queued refine.run may still be serviced below.\n\t\t\t\tif (branchVersion === this._autoRefineBranchVersion) {\n\t\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t}\n\t\t\t\t// Re-queue an explicit refine.run whose background plan failed,\n\t\t\t\t// but only when branchVersion is still current and no newer\n\t\t\t\t// pending request has arrived since the background plan consumed\n\t\t\t\t// the original one. A newer request retains priority; interval\n\t\t\t\t// failures keep existing no-retry cooldown semantics.\n\t\t\t\tif (\n\t\t\t\t\tbgResult.explicit &&\n\t\t\t\t\tbgResult.branchVersion === this._autoRefineBranchVersion &&\n\t\t\t\t\t!this._pendingRequestedRefine\n\t\t\t\t) {\n\t\t\t\t\tthis._pendingRequestedRefine = bgResult.options;\n\t\t\t\t}\n\t\t\t\tif (!this._pendingRequestedRefine) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (bgResult?.status === \"invalidated\" && !this._pendingRequestedRefine) {\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tawait this._runSerializedRefineCheckpointAfterBackground(branchVersion);\n\t\t\treturn true;\n\t\t});\n\t\tif (this._disposed || this._disposing || bgConsumption !== \"none\") {\n\t\t\treturn;\n\t\t}\n\t\tawait this._runSerializedRefineCheckpointAfterBackground(branchVersion);\n\t}\n\n\tprivate async _runSerializedRefineCheckpointAfterBackground(branchVersion: number): Promise<void> {\n\t\tif (this._compactionSetupFailure) return;\n\t\t// No background result, or a refine.run arrived while the background result was\n\t\t// in flight. Fall through so an explicit pending request is serviced at this boundary.\n\n\t\t// 2. Agent-callable refine.run requests that were NOT consumed by\n\t\t// background planning (e.g. interval not reached at message_end,\n\t\t// or cooldown was active). Service them synchronously.\n\t\tconst pending = this._pendingRequestedRefine;\n\t\tif (pending) {\n\t\t\tthis._pendingRequestedRefine = undefined;\n\t\t\ttry {\n\t\t\t\tawait this._runSerializedRefine(pending);\n\t\t\t} catch (error) {\n\t\t\t\tthis._emitRefineFailed(error);\n\t\t\t}\n\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\treturn;\n\t\t}\n\n\t\t// 3. Post-compaction auto-refine. Serialized sessions defer the\n\t\t// compaction trigger to this boundary instead of entering the interactive\n\t\t// path, which waits for agent idle and can never run inside a tool loop.\n\t\tif (!this._newAutoRefineAllowed()) {\n\t\t\tthis._compactAutoRefinePending = false;\n\t\t\treturn;\n\t\t}\n\t\tconst settings = this.settingsManager.getAutoRefineSettings();\n\t\tif (!settings.enabled) {\n\t\t\tthis._compactAutoRefinePending = false;\n\t\t\treturn;\n\t\t}\n\t\tif (this._compactAutoRefinePending) {\n\t\t\tif (!settings.compact) {\n\t\t\t\tthis._compactAutoRefinePending = false;\n\t\t\t} else {\n\t\t\t\tconst nowMs = Date.now();\n\t\t\t\tconst underCooldown =\n\t\t\t\t\tthis._lastAutoRefineReviewAt > 0 && nowMs - this._lastAutoRefineReviewAt < settings.cooldownMs;\n\t\t\t\tif (underCooldown) {\n\t\t\t\t\t// Preserve the compact trigger for a later boundary, matching the\n\t\t\t\t\t// interactive path's pending behavior while the cooldown is active.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis._compactAutoRefinePending = false;\n\t\t\t\tawait this._runSerializedAutoRefineReview(\"compact\", branchVersion);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// 4. Interval-triggered auto-refine (no background plan was started).\n\t\tif (this._assistantTurnsSinceAutoRefine < settings.turnInterval) {\n\t\t\treturn;\n\t\t}\n\t\tconst nowMs = Date.now();\n\t\tconst underCooldown =\n\t\t\tthis._lastAutoRefineReviewAt > 0 && nowMs - this._lastAutoRefineReviewAt < settings.cooldownMs;\n\t\tif (underCooldown) {\n\t\t\treturn;\n\t\t}\n\t\tawait this._runSerializedAutoRefineReview(\"turn_interval\", branchVersion);\n\t}\n\n\tprivate async _runSerializedAutoRefineReview(\n\t\treason: \"compact\" | \"turn_interval\",\n\t\tbranchVersion: number,\n\t): Promise<void> {\n\t\tif (!this._newAutoRefineAllowed()) return;\n\t\tconst reviewAbort = new AbortController();\n\t\tthis._autoRefineReviewAbort = reviewAbort;\n\t\tthis._autoRefineInProgress = true;\n\t\ttry {\n\t\t\tconst review = await this._reviewAutoRefine(\n\t\t\t\t{ reason, turnsSinceLastReview: this._assistantTurnsSinceAutoRefine },\n\t\t\t\treviewAbort.signal,\n\t\t\t);\n\t\t\tif (\n\t\t\t\t!this._newAutoRefineAllowed() ||\n\t\t\t\tthis._disposed ||\n\t\t\t\tthis._disposing ||\n\t\t\t\tbranchVersion !== this._autoRefineBranchVersion\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!review.shouldRefine) {\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this._runSerializedRefine({ instructions: autoRefineInstructions(reason, review) }, \"auto\");\n\t\t\tif (this._disposed || this._disposing || branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t} catch (error) {\n\t\t\tif (branchVersion === this._autoRefineBranchVersion) {\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t// An extension skip is an intentional non-round, not a failure.\n\t\t\t\tif (error instanceof RefineSkippedError) {\n\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t} else {\n\t\t\t\t\tthis._emitRefineFailed(error);\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tif (this._autoRefineReviewAbort === reviewAbort) {\n\t\t\t\tthis._autoRefineReviewAbort = undefined;\n\t\t\t}\n\t\t\tthis._autoRefineInProgress = false;\n\t\t}\n\t}\n\n\t/**\n\t * Claim and process the serialized background plan if one is in flight.\n\t * A concurrent caller waits for the claim holder's full processing callback\n\t * instead of resuming as soon as planning settles.\n\t */\n\tprivate async _consumeSerializedBackgroundPlan(\n\t\tconsume: (result: SerializedBackgroundPlanResult | undefined) => Promise<boolean>,\n\t): Promise<\"none\" | \"waited\" | \"continue\" | \"stop\"> {\n\t\tif (this._serializedPlanClaim) {\n\t\t\tawait this._serializedPlanClaim.catch(() => undefined);\n\t\t\treturn \"waited\";\n\t\t}\n\t\tconst planInFlight = this._serializedPlanInFlight;\n\t\tif (!planInFlight) {\n\t\t\treturn \"none\";\n\t\t}\n\n\t\tlet releaseClaim: () => void = () => {};\n\t\tconst claim = new Promise<void>((resolve) => {\n\t\t\treleaseClaim = resolve;\n\t\t});\n\t\tthis._serializedPlanClaim = claim;\n\t\ttry {\n\t\t\tconst result = await planInFlight.catch(() => undefined);\n\t\t\tif (this._serializedPlanInFlight === planInFlight) {\n\t\t\t\tthis._serializedPlanInFlight = undefined;\n\t\t\t\tthis._serializedExplicitRefineOptions = undefined;\n\t\t\t}\n\t\t\treturn (await consume(result)) ? \"stop\" : \"continue\";\n\t\t} finally {\n\t\t\treleaseClaim();\n\t\t\tif (this._serializedPlanClaim === claim) {\n\t\t\t\tthis._serializedPlanClaim = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Apply an exact background plan directly via _applyRefine without\n\t * calling _planRefine again. Sets _refineInFlight for safety.\n\t */\n\tprivate async _applySerializedPlan(\n\t\tbgResult: Extract<SerializedBackgroundPlanResult, { status: \"plan\" }>,\n\t): Promise<void> {\n\t\tlet resolveApplySettled: () => void = () => {};\n\t\tconst applySettled = new Promise<void>((resolve) => {\n\t\t\tresolveApplySettled = resolve;\n\t\t});\n\t\tthis._refineInFlight = applySettled;\n\t\ttry {\n\t\t\tawait this._applyRefine(bgResult.plan, bgResult.options, bgResult.abort);\n\t\t} finally {\n\t\t\tresolveApplySettled();\n\t\t\tif (this._refineInFlight === applySettled) {\n\t\t\t\tthis._refineInFlight = undefined;\n\t\t\t}\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\tthis._scheduleSessionInputPump();\n\t\t}\n\t}\n\n\t/**\n\t * Start background refinement planning at assistant message_end, while\n\t * tools are still executing. The plan (if any) is awaited at the\n\t * shouldStopAfterTurn boundary before applying. Planning overlaps tool\n\t * execution only — never another model request.\n\t */\n\tprivate _maybeStartSerializedBackgroundPlan(): void {\n\t\tif (!this._serializedRefine || this._disposed || this._disposing) {\n\t\t\treturn;\n\t\t}\n\t\t// Don't start if a plan is already in flight.\n\t\tif (this._serializedPlanInFlight || this._refineInFlight || this._refinePlanInFlight) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Start background planning for a pending agent-callable\n\t\t// refine.run request, so its plan is ready at the shouldStopAfterTurn\n\t\t// boundary. The pending request is consumed (cleared) here so the\n\t\t// boundary doesn't re-plan it. Explicit refine.run skips the review gate.\n\t\tconst pending = this._pendingRequestedRefine;\n\t\tif (pending) {\n\t\t\tthis._pendingRequestedRefine = undefined;\n\t\t\tthis._serializedExplicitRefineOptions = pending;\n\t\t\tconst refineAbort = new AbortController();\n\t\t\tthis._refineAbortController = refineAbort;\n\t\t\tconst branchVersion = this._autoRefineBranchVersion;\n\t\t\tthis._serializedPlanInFlight = this._runBackgroundPlan(pending, refineAbort, branchVersion, true);\n\t\t\treturn;\n\t\t}\n\n\t\t// Interval-triggered auto-refine background planning.\n\t\tif (!this._newAutoRefineAllowed()) {\n\t\t\treturn;\n\t\t}\n\t\tconst settings = this.settingsManager.getAutoRefineSettings();\n\t\tif (!settings.enabled) {\n\t\t\treturn;\n\t\t}\n\t\tif (this._assistantTurnsSinceAutoRefine < settings.turnInterval) {\n\t\t\treturn;\n\t\t}\n\t\tconst nowMs = Date.now();\n\t\tconst underCooldown =\n\t\t\tthis._lastAutoRefineReviewAt > 0 && nowMs - this._lastAutoRefineReviewAt < settings.cooldownMs;\n\t\tif (underCooldown) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst refineAbort = new AbortController();\n\t\tthis._refineAbortController = refineAbort;\n\t\tconst branchVersion = this._autoRefineBranchVersion;\n\t\t// Pass empty options — _runBackgroundPlan derives instructions from\n\t\t// the review result for interval-triggered auto-refine.\n\t\tthis._serializedPlanInFlight = this._runBackgroundPlan({}, refineAbort, branchVersion);\n\t}\n\n\t/**\n\t * Shared background planning coroutine. Runs review + planRefine and\n\t * returns a discriminated result so the boundary can distinguish\n\t * reviewer-declined (\"skip\") from failure (\"failure\") from a ready\n\t * plan (\"plan\") and apply that exact plan without re-planning.\n\t */\n\tprivate async _runBackgroundPlan(\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean },\n\t\trefineAbort: AbortController,\n\t\tbranchVersion: number,\n\t\tskipReview = false,\n\t): Promise<SerializedBackgroundPlanResult | undefined> {\n\t\ttry {\n\t\t\tlet planOptions = options;\n\t\t\tif (!skipReview) {\n\t\t\t\t// Interval-triggered: run the review gate first, then derive\n\t\t\t\t// instructions from the review result (not prepopulated).\n\t\t\t\tconst review = await this._reviewAutoRefine(\n\t\t\t\t\t{\n\t\t\t\t\t\treason: \"turn_interval\",\n\t\t\t\t\t\tturnsSinceLastReview: this._assistantTurnsSinceAutoRefine,\n\t\t\t\t\t},\n\t\t\t\t\trefineAbort.signal,\n\t\t\t\t);\n\t\t\t\tif (this._disposed || this._disposing || branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\t\treturn { status: \"invalidated\", branchVersion };\n\t\t\t\t}\n\t\t\t\tif (!review.shouldRefine) {\n\t\t\t\t\treturn { status: \"skip\" };\n\t\t\t\t}\n\t\t\t\tif (!this._newAutoRefineAllowed()) return { status: \"skip\" };\n\t\t\t\tplanOptions = {\n\t\t\t\t\tinstructions: autoRefineInstructions(\"turn_interval\", review),\n\t\t\t\t};\n\t\t\t}\n\t\t\t// For explicit refine.run (skipReview=true), plan directly with\n\t\t\t// the user-provided options — no auto-review gate.\n\t\t\tconst plan = await this._planRefine(planOptions, refineAbort.signal, skipReview ? \"manual\" : \"auto\");\n\t\t\tif (this._disposed || this._disposing || branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\treturn { status: \"invalidated\", branchVersion };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tstatus: \"plan\",\n\t\t\t\tplan,\n\t\t\t\toptions: planOptions,\n\t\t\t\tabort: refineAbort,\n\t\t\t\tbranchVersion,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (this._disposed || this._disposing || branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\treturn { status: \"invalidated\", branchVersion };\n\t\t\t}\n\t\t\tif (error instanceof RefineSkippedError) {\n\t\t\t\treturn { status: \"skip\", explicit: skipReview };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tstatus: \"failure\",\n\t\t\t\texplicit: skipReview,\n\t\t\t\toptions,\n\t\t\t\tbranchVersion,\n\t\t\t};\n\t\t} finally {\n\t\t\tif (this._refineAbortController === refineAbort) {\n\t\t\t\tthis._refineAbortController = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Direct serialized plan+apply. Calls _planRefine and _applyRefine with\n\t * proper in-flight guards but NEVER agent.waitForIdle or agent.abort.\n\t * The caller (shouldStopAfterTurn) is already at the quiescent boundary,\n\t * so the agent is between turns and _applyRefine's disconnect/reconnect\n\t * is safe.\n\t */\n\tprivate async _runSerializedRefine(\n\t\toptions: {\n\t\t\tinstructions?: string;\n\t\t\trollbackId?: string;\n\t\t\tglobal?: boolean;\n\t\t},\n\t\ttrigger: \"manual\" | \"auto\" = \"manual\",\n\t): Promise<void> {\n\t\tif (this._disposed || this._disposing) {\n\t\t\treturn;\n\t\t}\n\t\t// Guard: serialize against concurrent _runSerializedRefine calls.\n\t\t// _serializedPlanInFlight covers background planning; _refineInFlight\n\t\t// covers the apply phase. Both must be settled before starting a new\n\t\t// plan+apply cycle.\n\t\twhile (this._serializedPlanInFlight || this._refineInFlight || this._refinePlanInFlight) {\n\t\t\tif (this._serializedPlanInFlight) {\n\t\t\t\tawait this._consumeSerializedBackgroundPlan(async () => false);\n\t\t\t} else if (this._refineInFlight) {\n\t\t\t\tawait this._refineInFlight;\n\t\t\t} else {\n\t\t\t\tawait this._refinePlanInFlight;\n\t\t\t}\n\t\t}\n\t\tif (this._disposed || this._disposing) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst refineAbort = new AbortController();\n\t\tthis._refineAbortController = refineAbort;\n\n\t\tconst planRun = this._planRefine(options, refineAbort.signal, trigger);\n\t\tconst planSettled = planRun.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\tthis._refinePlanInFlight = planSettled;\n\t\tlet plan: RefinementPlan;\n\t\ttry {\n\t\t\tplan = await planRun;\n\t\t} catch (error) {\n\t\t\tif (this._refineAbortController === refineAbort) {\n\t\t\t\tthis._refineAbortController = undefined;\n\t\t\t}\n\t\t\tthis._scheduleSessionInputPump();\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tif (this._refinePlanInFlight === planSettled) {\n\t\t\t\tthis._refinePlanInFlight = undefined;\n\t\t\t}\n\t\t}\n\n\t\tif (this._disposed || refineAbort.signal.aborted) {\n\t\t\tif (this._refineAbortController === refineAbort) {\n\t\t\t\tthis._refineAbortController = undefined;\n\t\t\t}\n\t\t\tthis._scheduleSessionInputPump();\n\t\t\treturn;\n\t\t}\n\n\t\t// Do NOT call agent.waitForIdle() — we are at the quiescent boundary\n\t\t// already (shouldStopAfterTurn). _applyRefine handles disconnect/reconnect internally.\n\t\tlet resolveApplySettled: () => void = () => {};\n\t\tconst applySettled = new Promise<void>((resolve) => {\n\t\t\tresolveApplySettled = resolve;\n\t\t});\n\t\tthis._refineInFlight = applySettled;\n\t\ttry {\n\t\t\tawait this._applyRefine(plan, options, refineAbort);\n\t\t} finally {\n\t\t\tresolveApplySettled();\n\t\t\tif (this._refineInFlight === applySettled) {\n\t\t\t\tthis._refineInFlight = undefined;\n\t\t\t}\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\tthis._scheduleSessionInputPump();\n\t\t}\n\t}\n\n\tprivate async _getLatestCompactionTimestamp(owner?: CompactionOwner): Promise<number | undefined> {\n\t\tif (owner) this._assertCompactionOwner(owner);\n\t\tconst manager = owner?.manager ?? this.sessionManager;\n\t\tif (!manager.isPersisted()) {\n\t\t\tconst entry = getLatestCompactionEntry(manager.getBranch());\n\t\t\treturn entry ? new Date(entry.timestamp).getTime() : undefined;\n\t\t}\n\t\tconst { maxSourceBytes } = this.settingsManager.getCanonicalContextLimits();\n\t\treturn manager.readBranchHistory(async (view) => {\n\t\t\tconst ref = (await view.branchBootstrap()).latestCompaction;\n\t\t\tif (owner) this._assertCompactionOwner(owner);\n\t\t\tif (!ref) {\n\t\t\t\tthis._compactionBoundaryCache = undefined;\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (ref.locator.length > maxSourceBytes) throw new Error(\"Compaction bootstrap source byte budget exceeded\");\n\t\t\tconst cached = this._compactionBoundaryCache;\n\t\t\tif (\n\t\t\t\tcached &&\n\t\t\t\tcached.sessionId === view.source.sessionId &&\n\t\t\t\tcached.sessionFile === view.source.sessionFile &&\n\t\t\t\tcached.entryId === ref.id &&\n\t\t\t\tcached.revision === ref.revision\n\t\t\t)\n\t\t\t\treturn cached.timestamp;\n\t\t\tconst hydrated = await view.hydrateEntry(ref.id, maxSourceBytes);\n\t\t\tif (!hydrated || hydrated.entry.type !== \"compaction\")\n\t\t\t\tthrow new Error(\"Compaction bootstrap source is unavailable\");\n\t\t\tconst timestamp = new Date(hydrated.entry.timestamp).getTime();\n\t\t\tif (owner) this._assertCompactionOwner(owner);\n\t\t\tthis._compactionBoundaryCache = {\n\t\t\t\tsessionId: view.source.sessionId,\n\t\t\t\tsessionFile: view.source.sessionFile,\n\t\t\t\tentryId: ref.id,\n\t\t\t\trevision: ref.revision,\n\t\t\t\ttimestamp,\n\t\t\t};\n\t\t\treturn timestamp;\n\t\t});\n\t}\n\n\tprivate _thresholdCompactionConfiguration(): string {\n\t\treturn JSON.stringify({\n\t\t\tmodel: this.model,\n\t\t\tthinkingLevel: this.thinkingLevel,\n\t\t\tsettings: this.settingsManager.getCompactionSettings(),\n\t\t});\n\t}\n\n\tprivate _hasFailedThresholdCompaction(): boolean {\n\t\tconst failed = this._failedThresholdCompaction;\n\t\tif (!failed) return false;\n\t\tif (\n\t\t\tfailed.isCurrent() &&\n\t\t\tfailed.configuration === this._thresholdCompactionConfiguration() &&\n\t\t\tfailed.systemPrompt === this.agent.state.systemPrompt &&\n\t\t\tfailed.tools === this.agent.state.tools\n\t\t)\n\t\t\treturn true;\n\t\tthis._failedThresholdCompaction = undefined;\n\t\treturn false;\n\t}\n\n\tprivate async _thresholdCompactionNeeded(\n\t\tcontext: ShouldStopAfterTurnContext,\n\t\towner = this._captureCompactionOwner(),\n\t\tgoalOwner: GoalContinuationOwner = {\n\t\t\t...this._captureGoalContinuationOwner(owner.signal),\n\t\t\tcheckpointOwner: owner,\n\t\t},\n\t\tautonomousOwner = this._captureThresholdAutonomousOwner(),\n\t): Promise<boolean> {\n\t\tif (!this._isCompactionOwnerCurrent(owner) || !this._contextOptimizationAllowed()) return false;\n\t\tconst settings = this.settingsManager.getCompactionSettings();\n\t\tif (!settings.enabled) return false;\n\t\tconst contextWindow = this.model?.contextWindow ?? 0;\n\t\tconst compactionTimestamp = await this._getLatestCompactionTimestamp(owner);\n\t\tif (!this._isCompactionOwnerCurrent(owner) || !this._contextOptimizationAllowed()) return false;\n\t\tif (compactionTimestamp !== undefined && context.message.timestamp <= compactionTimestamp) return false;\n\t\tconst contextTokens = this._getThresholdContextTokens(context.message, compactionTimestamp);\n\t\tif (\n\t\t\tcontextTokens === undefined ||\n\t\t\t!shouldCompact(\n\t\t\t\tcontextTokens,\n\t\t\t\tcontextWindow,\n\t\t\t\tsettings,\n\t\t\t\testimateFixedCompactionTokens(this.systemPrompt, this.agent.state.tools, this.messages),\n\t\t\t)\n\t\t)\n\t\t\treturn false;\n\t\tif (this._hasFailedThresholdCompaction()) return false;\n\t\t// Keep the existing threshold-specific goal winner; do not import W74's natural wait policy here.\n\t\tif (!this._isGoalContinuationOwnerCurrent(goalOwner)) return true;\n\t\tif (!(await this._queueGoalContinuationForThresholdCompaction(context.message, goalOwner))) {\n\t\t\tif (!this._isGoalContinuationOwnerCurrent(goalOwner))\n\t\t\t\treturn this._isCompactionOwnerCurrent(owner) && this._contextOptimizationAllowed();\n\t\t\tif (!this._contextOptimizationAllowed()) return false;\n\t\t\tawait this._queueAutonomousContinuationForThresholdCompaction(context.message, owner, autonomousOwner);\n\t\t}\n\t\treturn this._isCompactionOwnerCurrent(owner) && this._contextOptimizationAllowed();\n\t}\n\n\tprivate _captureThresholdAutonomousOwner(): ThresholdAutonomousOwner {\n\t\treturn {\n\t\t\tstate: this._autonomousState,\n\t\t\tsnapshot: structuredClone(this._autonomousState),\n\t\t\tcwd: this._cwd,\n\t\t\tarrivalEpoch: this._sessionInputArrivalEpoch,\n\t\t};\n\t}\n\n\tprivate _snapshotAutonomousRuntimeState(state = this._autonomousState): AutonomousRuntimeSnapshot {\n\t\treturn {\n\t\t\tcontinuationsUsed: state.continuationsUsed,\n\t\t\tgateAttempts: { ...state.gateAttempts },\n\t\t\tlastGateFailure: state.lastGateFailure ? { ...state.lastGateFailure } : undefined,\n\t\t\tlastGateFailureSnapshot: state.lastGateFailureSnapshot ? { ...state.lastGateFailureSnapshot } : undefined,\n\t\t};\n\t}\n\n\tprivate _restoreAutonomousRuntimeSnapshot(snapshot: AutonomousRuntimeSnapshot): void {\n\t\tthis._autonomousState.continuationsUsed = snapshot.continuationsUsed;\n\t\tthis._autonomousState.gateAttempts = { ...snapshot.gateAttempts };\n\t\tthis._autonomousState.lastGateFailure = snapshot.lastGateFailure ? { ...snapshot.lastGateFailure } : undefined;\n\t\tthis._autonomousState.lastGateFailureSnapshot = snapshot.lastGateFailureSnapshot\n\t\t\t? { ...snapshot.lastGateFailureSnapshot }\n\t\t\t: undefined;\n\t}\n\n\tprivate async _queueAutonomousContinuationForThresholdCompaction(\n\t\tmessage: AssistantMessage,\n\t\towner = this._captureCompactionOwner(this.agent.signal),\n\t\tcapture = this._captureThresholdAutonomousOwner(),\n\t): Promise<CheckpointAction | undefined> {\n\t\tif (!this._isCompactionOwnerCurrent(owner) || !this._contextOptimizationAllowed()) return undefined;\n\t\tconst queued = this._queuedAutonomousThresholdContinuations.get(message);\n\t\tif (queued && this._checkpointActionPending(queued)) return queued;\n\t\tconst { state, snapshot: original, arrivalEpoch, cwd } = capture;\n\t\tconst before = this._snapshotAutonomousRuntimeState(original);\n\t\tconst candidate = structuredClone(original);\n\t\tconst current = () =>\n\t\t\tthis._isCompactionOwnerCurrent(owner) && this._autonomousState === state && isDeepStrictEqual(state, original);\n\t\tif (!current()) return undefined;\n\t\tlet messageToQueue: UserMessage | undefined;\n\t\ttry {\n\t\t\tmessageToQueue = await nextAutonomousContinuation(candidate, message, { cwd, signal: owner.signal });\n\t\t} catch (error) {\n\t\t\tif (current()) this._restoreAutonomousRuntimeSnapshot(candidate);\n\t\t\tthrow error; // Preserve the actual command/orphan owner's primary failure even after replacement.\n\t\t}\n\t\tif (!current() || !this._contextOptimizationAllowed()) return undefined;\n\t\tif (messageToQueue && this._sessionInputArrivalEpoch !== arrivalEpoch) return undefined;\n\t\tthis._restoreAutonomousRuntimeSnapshot(candidate);\n\t\tif (!messageToQueue) return undefined;\n\t\tconst normalized = normalizeMessageContent(messageToQueue.content);\n\t\tconst action = this._createPreparedTurnAction(\"followUp\", normalized.text, normalized.images, {\n\t\t\tmessage: messageToQueue,\n\t\t});\n\t\tconst admitted = this._admitSessionInput(action);\n\t\tif (!admitted.accepted || !admitted.ticket) {\n\t\t\tthis._restoreAutonomousRuntimeSnapshot(before);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst continuation: ThresholdAutonomousContinuation = {\n\t\t\taction,\n\t\t\tticket: admitted.ticket,\n\t\t\towner,\n\t\t\tstate,\n\t\t\tbefore,\n\t\t\tafter: structuredClone(state),\n\t\t};\n\t\tthis._queuedAutonomousThresholdContinuations.set(message, continuation);\n\t\tthis._postCompactionContinuations.push(continuation);\n\t\tthis._pendingThresholdCompactionAutonomousContinuations.push(continuation);\n\t\treturn continuation;\n\t}\n\n\tprivate async _queueGoalContinuationForThresholdCompaction(\n\t\tmessage: AssistantMessage,\n\t\towner: GoalContinuationOwner = {\n\t\t\t...this._captureGoalContinuationOwner(this.agent.signal),\n\t\t\tcheckpointOwner: this._captureCompactionOwner(this.agent.signal),\n\t\t},\n\t): Promise<CheckpointAction | undefined> {\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner) || !this._contextOptimizationAllowed()) return undefined;\n\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") return undefined;\n\t\tif (owner.goal.status !== \"active\" || !owner.goal.objective) return undefined;\n\t\tconst queued = this._queuedGoalThresholdContinuation;\n\t\tif (queued && this._checkpointActionPending(queued)) return queued;\n\t\tconst before = owner.goal;\n\t\tlet counted = false;\n\t\ttry {\n\t\t\tthis._ensureGoalRuntimeActive();\n\t\t\tawait this._setGoalState(\n\t\t\t\t{\n\t\t\t\t\t...before,\n\t\t\t\t\tcontinuationsUsed: before.continuationsUsed + 1,\n\t\t\t\t\tlastReason: undefined,\n\t\t\t\t\tlastError: undefined,\n\t\t\t\t},\n\t\t\t\t{ continuationOwner: owner },\n\t\t\t);\n\t\t\tcounted = true;\n\t\t\tthis._assertGoalContinuationOwner(owner);\n\t\t\tif (!this._contextOptimizationAllowed()) {\n\t\t\t\tawait this._setGoalState(before, { continuationOwner: owner });\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst messageToQueue = createGoalContextMessage(owner.goal, \"continuation\");\n\t\t\tconst normalized = normalizeMessageContent(messageToQueue.content);\n\t\t\tconst action = this._createPreparedTurnAction(\"followUp\", normalized.text, normalized.images, {\n\t\t\t\tmessage: messageToQueue,\n\t\t\t});\n\t\t\tconst admitted = this._admitSessionInput(action);\n\t\t\tif (!admitted.accepted || !admitted.ticket) {\n\t\t\t\tawait this._setGoalState(before, { continuationOwner: owner });\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst continuation = { action, ticket: admitted.ticket, owner };\n\t\t\tthis._queuedGoalThresholdContinuation = continuation;\n\t\t\treturn continuation;\n\t\t} catch {\n\t\t\tif (counted && this._isGoalContinuationOwnerCurrent(owner)) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this._setGoalState(before, { continuationOwner: owner });\n\t\t\t\t} catch {\n\t\t\t\t\t/* Keep the existing non-rejection policy. */\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async _clearQueuedGoalContinuationAfterCancelledThresholdCompaction(\n\t\tcontinuation: ThresholdGoalContinuation | undefined,\n\t): Promise<void> {\n\t\tif (\n\t\t\t!continuation ||\n\t\t\t!continuation.owner.checkpointOwner ||\n\t\t\t!this._isCompactionSourceOwnerCurrent(continuation.owner.checkpointOwner) ||\n\t\t\t!this._checkpointActionPending(continuation)\n\t\t)\n\t\t\treturn;\n\t\tconst cancelled = this._cancelSessionActions(\n\t\t\t(action) => action === continuation.action,\n\t\t\tnew Error(\"Queued goal continuation was cleared before delivery.\"),\n\t\t);\n\t\tif (this._queuedGoalThresholdContinuation === continuation) this._queuedGoalThresholdContinuation = undefined;\n\t\tif (\n\t\t\t!cancelled.includes(continuation.action) ||\n\t\t\tprimaryDeliveryRecord(continuation.action).durable ||\n\t\t\t!this._isGoalContinuationOwnerCurrent(continuation.owner)\n\t\t)\n\t\t\treturn;\n\t\tconst owner = continuation.owner;\n\t\tawait this._setGoalState(\n\t\t\t{ ...owner.goal, continuationsUsed: owner.goal.continuationsUsed - 1 },\n\t\t\t{ continuationOwner: owner },\n\t\t);\n\t\tthis._emitQueueUpdate();\n\t}\n\n\tprivate _clearQueuedAutonomousContinuations(\n\t\toptions: { restoreAutonomousState?: boolean; continuations?: ThresholdAutonomousContinuation[] } = {},\n\t): void {\n\t\tconst continuations = options.continuations ?? [...this._postCompactionContinuations];\n\t\tconst current = continuations.filter(\n\t\t\t(continuation) =>\n\t\t\t\tthis._isCompactionSourceOwnerCurrent(continuation.owner) && this._checkpointActionPending(continuation),\n\t\t);\n\t\tconst actions = new Set(current.map((continuation) => continuation.action));\n\t\tconst cancelled = this._cancelSessionActions(\n\t\t\t(action) => actions.has(action),\n\t\t\tnew Error(\"Queued autonomous continuation was cleared before delivery.\"),\n\t\t);\n\t\tif (options.restoreAutonomousState) {\n\t\t\tconst continuation = current.find(\n\t\t\t\t(candidate) =>\n\t\t\t\t\tthis._isCompactionOwnerCurrent(candidate.owner) &&\n\t\t\t\t\tcancelled.includes(candidate.action) &&\n\t\t\t\t\t!primaryDeliveryRecord(candidate.action).durable &&\n\t\t\t\t\tthis._autonomousState === candidate.state &&\n\t\t\t\t\tisDeepStrictEqual(candidate.state, candidate.after),\n\t\t\t);\n\t\t\tif (continuation) this._restoreAutonomousRuntimeSnapshot(continuation.before);\n\t\t}\n\t\tthis._postCompactionContinuations = this._postCompactionContinuations.filter(\n\t\t\t(item) => !continuations.includes(item),\n\t\t);\n\t\tthis._pendingThresholdCompactionAutonomousContinuations =\n\t\t\tthis._pendingThresholdCompactionAutonomousContinuations.filter((item) => !continuations.includes(item));\n\t\tif (cancelled.length > 0) this._emitQueueUpdate();\n\t\tif (\n\t\t\t!this.agent.hasQueuedMessages() &&\n\t\t\tthis.unfinishedActionCount === 0 &&\n\t\t\tthis._postCompactionContinuationSettlement?.resume.boundary?.state !== \"pending\"\n\t\t)\n\t\t\tthis._cancelPostCompactionContinue();\n\t}\n\n\tprivate _clearQueuedAutonomousContinuationsAfterSkippedThresholdCompaction(\n\t\tshouldContinueAfterThreshold: boolean,\n\t\tcontinuations: ThresholdAutonomousContinuation[],\n\t): void {\n\t\tif (shouldContinueAfterThreshold)\n\t\t\tthis._clearQueuedAutonomousContinuations({ restoreAutonomousState: true, continuations });\n\t}\n\n\t/**\n\t * Handle a goal.* request from the Python kernel host bridge (the bundled\n\t * goal skill). All goal state stays host-side; the kernel only sees the\n\t * serialized snake_case response.\n\t */\n\tasync handleGoalHostRequest(type: string, payload: Record<string, unknown> = {}): Promise<GoalHostResponse> {\n\t\tif (!this._includeGoals) {\n\t\t\tthrow new Error(\"goals are disabled in this session\");\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase \"goal.get\":\n\t\t\t\treturn goalHostResponse(this.goalState, false);\n\t\t\tcase \"goal.create\": {\n\t\t\t\tif (typeof payload.objective !== \"string\") {\n\t\t\t\t\tthrow new Error(\"goal.create objective must be a string\");\n\t\t\t\t}\n\t\t\t\tif (payload.token_budget !== undefined && typeof payload.token_budget !== \"number\") {\n\t\t\t\t\tthrow new Error(\"goal.create token_budget must be an integer when provided\");\n\t\t\t\t}\n\t\t\t\treturn goalHostResponse(await this._createGoalFromHost(payload.objective, payload.token_budget), false);\n\t\t\t}\n\t\t\tcase \"goal.complete\":\n\t\t\t\treturn goalHostResponse(await this._completeGoalFromHost(), true);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown goal request type \"${type}\"`);\n\t\t}\n\t}\n\n\t/**\n\t * Handle a compact.* request from the kernel host bridge. Compaction would\n\t * abort the run executing the requesting cell, so compact.run only schedules\n\t * it; _checkCompaction consumes the request at the turn boundary.\n\t */\n\tasync handleCompactHostRequest(\n\t\ttype: string,\n\t\tpayload: Record<string, unknown> = {},\n\t): Promise<Record<string, unknown>> {\n\t\tif (type === \"compact.run\") this._assertContextOptimizationAllowed();\n\t\tif (!this._includeCompactSkill) {\n\t\t\tthrow new Error(\"the compact skill is disabled in this session\");\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase \"compact.status\": {\n\t\t\t\tconst scheduled = this._pendingRequestedCompaction !== undefined;\n\t\t\t\tconst usage = await this.getContextUsage();\n\t\t\t\treturn {\n\t\t\t\t\ttokens: usage?.tokens ?? null,\n\t\t\t\t\tcontext_window: usage?.contextWindow ?? null,\n\t\t\t\t\tpercent: usage?.percent ?? null,\n\t\t\t\t\tscheduled,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"compact.run\": {\n\t\t\t\tconst instructions = payload.instructions;\n\t\t\t\tif (instructions !== undefined && typeof instructions !== \"string\") {\n\t\t\t\t\tthrow new Error(\"compact.run instructions must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tif (!this.isStreaming) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tscheduled: false,\n\t\t\t\t\t\treason: \"no active turn; compaction can only be requested while a turn is running\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst settings = { ...this.settingsManager.getCompactionSettings() };\n\t\t\t\tconst sourceOwner = this._invocationCompactionOwner ?? this._captureCompactionOwner(this.agent.signal);\n\t\t\t\tconst owner = { ...sourceOwner, pumpEpoch: this._sessionInputPumpEpoch };\n\t\t\t\tthis._assertCompactionOwner(owner);\n\t\t\t\tconst compaction = owner.manager.bindCompactionSink();\n\t\t\t\tconst captured = owner.requests.capture(compaction);\n\t\t\t\tlet branch: SessionEntry[];\n\t\t\t\tlet preparation: CompactionPreparation | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tbranch = await compaction.readBranch();\n\t\t\t\t\tthis._assertCompactionOwner(owner);\n\t\t\t\t\tpreparation = this.isStreaming\n\t\t\t\t\t\t? (await this._prepareCapturedCompaction(branch, settings, captured, compaction, owner)).preparation\n\t\t\t\t\t\t: undefined;\n\t\t\t\t} catch (error) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait captured.dispose();\n\t\t\t\t\t} catch (cleanupError) {\n\t\t\t\t\t\tthrow new AggregateError([error, cleanupError], \"Compaction preparation and release failed\", {\n\t\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tawait captured.dispose();\n\t\t\t\tthis._assertCompactionOwner(owner);\n\t\t\t\tif (!this.isStreaming)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tscheduled: false,\n\t\t\t\t\t\treason: \"no active turn; compaction can only be requested while a turn is running\",\n\t\t\t\t\t};\n\t\t\t\tif (!preparation) {\n\t\t\t\t\tconst lastEntry = branch.at(-1);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tscheduled: false,\n\t\t\t\t\t\treason: lastEntry?.type === \"compaction\" ? \"already compacted\" : \"session is too short to compact\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthis._assertContextOptimizationAllowed();\n\t\t\t\tthis._pendingRequestedCompaction = { customInstructions: instructions, owner };\n\t\t\t\treturn {\n\t\t\t\t\tscheduled: true,\n\t\t\t\t\tnote: \"Compaction runs when the current turn ends; you resume automatically afterwards. Continue working normally.\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown compact request type \"${type}\"`);\n\t\t}\n\t}\n\n\t/**\n\t * Handle a refine.* request from the kernel host bridge. Like compact,\n\t * refinement waits for the current turn to become idle before applying\n\t * changes, so refine.run only schedules it; _consumePendingRequestedRefine\n\t * fires it at the turn boundary. This prevents a deadlock that would occur\n\t * if refine() awaited agent idle from within the active tool call.\n\t */\n\thandleRefineHostRequest(type: string, payload: Record<string, unknown> = {}): Record<string, unknown> {\n\t\tif (type === \"refine.run\") this._assertContextOptimizationAllowed();\n\t\tswitch (type) {\n\t\t\tcase \"refine.status\": {\n\t\t\t\treturn {\n\t\t\t\t\tpending: this._pendingRequestedRefine !== undefined,\n\t\t\t\t\tin_flight:\n\t\t\t\t\t\tthis._refineInFlight !== undefined ||\n\t\t\t\t\t\tthis._refinePlanInFlight !== undefined ||\n\t\t\t\t\t\tthis._serializedPlanInFlight !== undefined,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"refine.run\": {\n\t\t\t\tconst instructions = payload.instructions;\n\t\t\t\tif (instructions !== undefined && typeof instructions !== \"string\") {\n\t\t\t\t\tthrow new Error(\"refine.run instructions must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tconst globalFlag = payload.global;\n\t\t\t\tif (globalFlag !== undefined && typeof globalFlag !== \"boolean\") {\n\t\t\t\t\tthrow new Error(\"refine.run global must be a boolean when provided\");\n\t\t\t\t}\n\t\t\t\tif (!this.isStreaming) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tscheduled: false,\n\t\t\t\t\t\treason: \"no active turn; refine can only be requested while a turn is running\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst previous = this._pendingRequestedRefine ?? this._serializedExplicitRefineOptions;\n\t\t\t\tthis._pendingRequestedRefine = {\n\t\t\t\t\tinstructions: instructions ?? previous?.instructions,\n\t\t\t\t\tglobal: globalFlag ?? previous?.global,\n\t\t\t\t};\n\t\t\t\t// In serialized mode, kick off background planning immediately\n\t\t\t\t// (the primary response ended at message_end, tools are active).\n\t\t\t\t// This lets planning overlap tool execution rather than waiting\n\t\t\t\t// for the shouldStopAfterTurn boundary.\n\t\t\t\tif (this._serializedRefine) {\n\t\t\t\t\tif (this._serializedPlanInFlight) {\n\t\t\t\t\t\tthis._autoRefineBranchVersion++;\n\t\t\t\t\t\tif (this._refineAbortController) {\n\t\t\t\t\t\t\tthis._refineAbortController.abort();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis._serializedPlanInFlight = Promise.resolve({\n\t\t\t\t\t\t\t\tstatus: \"invalidated\",\n\t\t\t\t\t\t\t\tbranchVersion: this._autoRefineBranchVersion,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!this._invocationOutputRefused) this._maybeStartSerializedBackgroundPlan();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tscheduled: true,\n\t\t\t\t\tnote: \"Refinement runs when the current turn ends; fresh harness advice is added to the next request and you resume automatically. Continue working normally.\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown refine request type \"${type}\"`);\n\t\t}\n\t}\n\n\t/**\n\t * Handle an rlm_heartbeat.* request from the bundled rlm-heartbeat skill.\n\t * These heartbeats are internal to this active session and never read or\n\t * mutate the user-level /heartbeat.\n\t */\n\thandleRlmHeartbeatHostRequest(type: string, payload: Record<string, unknown> = {}): Record<string, unknown> {\n\t\tconst controller = this._rlmHeartbeatController;\n\t\tif (!controller) {\n\t\t\tthrow new Error(\"RLM heartbeat skill is not available in this session\");\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase \"rlm_heartbeat.list\": {\n\t\t\t\tconst includeInactive = payload.include_inactive === true || payload.includeInactive === true;\n\t\t\t\treturn {\n\t\t\t\t\theartbeats: controller\n\t\t\t\t\t\t.listRlmHeartbeats({ includeInactive })\n\t\t\t\t\t\t.map((heartbeat) => rlmHeartbeatHostResponse(heartbeat)),\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"rlm_heartbeat.create\": {\n\t\t\t\tif (typeof payload.instruction !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.create instruction must be a string\");\n\t\t\t\t}\n\t\t\t\tif (payload.interval !== undefined && typeof payload.interval !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.create interval must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tif (payload.label !== undefined && typeof payload.label !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.create label must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tconst deliveryMode = normalizeHeartbeatDeliveryMode(payload.delivery_mode ?? payload.deliveryMode);\n\t\t\t\treturn {\n\t\t\t\t\theartbeat: rlmHeartbeatHostResponse(\n\t\t\t\t\t\tcontroller.createRlmHeartbeat({\n\t\t\t\t\t\t\tinstruction: payload.instruction,\n\t\t\t\t\t\t\tinterval: payload.interval,\n\t\t\t\t\t\t\tlabel: payload.label,\n\t\t\t\t\t\t\tdeliveryMode,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"rlm_heartbeat.update\": {\n\t\t\t\tif (typeof payload.id !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.update id must be a string\");\n\t\t\t\t}\n\t\t\t\tif (payload.instruction !== undefined && typeof payload.instruction !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.update instruction must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tif (payload.interval !== undefined && typeof payload.interval !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.update interval must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tif (payload.label !== undefined && typeof payload.label !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.update label must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tif (payload.status !== undefined && !isRlmHeartbeatStatusUpdate(payload.status)) {\n\t\t\t\t\tthrow new Error('rlm_heartbeat.update status must be \"pause\" or \"resume\" when provided');\n\t\t\t\t}\n\t\t\t\tconst rawDeliveryMode = payload.delivery_mode ?? payload.deliveryMode;\n\t\t\t\tconst deliveryMode = normalizeHeartbeatDeliveryMode(rawDeliveryMode);\n\t\t\t\tif (\n\t\t\t\t\tpayload.instruction === undefined &&\n\t\t\t\t\tpayload.interval === undefined &&\n\t\t\t\t\tpayload.label === undefined &&\n\t\t\t\t\tpayload.status === undefined &&\n\t\t\t\t\trawDeliveryMode === undefined\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.update requires at least one field to update\");\n\t\t\t\t}\n\t\t\t\tconst heartbeat = controller.updateRlmHeartbeat({\n\t\t\t\t\tid: payload.id,\n\t\t\t\t\tinstruction: payload.instruction,\n\t\t\t\t\tinterval: payload.interval,\n\t\t\t\t\tlabel: payload.label,\n\t\t\t\t\tstatus: payload.status,\n\t\t\t\t\tdeliveryMode,\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\theartbeat: heartbeat ? rlmHeartbeatHostResponse(heartbeat) : null,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"rlm_heartbeat.delete\": {\n\t\t\t\tif (typeof payload.id !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.delete id must be a string\");\n\t\t\t\t}\n\t\t\t\tconst heartbeat = controller.deleteRlmHeartbeat(payload.id);\n\t\t\t\treturn {\n\t\t\t\t\theartbeat: heartbeat ? rlmHeartbeatHostResponse(heartbeat) : null,\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown RLM heartbeat request type \"${type}\"`);\n\t\t}\n\t}\n\n\thandleAgentMessageHostRequest(\n\t\ttype: string,\n\t\tpayload: Record<string, unknown> = {},\n\t):\n\t\t| Promise<AgentSessionMessageListResult | AgentSessionMessageReceipt | AgentFamilyRosterResult>\n\t\t| AgentSessionMessageListResult\n\t\t| AgentFamilyRosterResult {\n\t\tif (!this._agentMessageController) {\n\t\t\tthrow new Error(\"agent messaging is not available in this session\");\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase \"agent_message.list_agents\":\n\t\t\t\tif (!this._agentMessageController.roster)\n\t\t\t\t\tthrow new Error(\"agent family roster is not available in this session\");\n\t\t\t\treturn this._agentMessageController.roster();\n\t\t\tcase \"agent_message.send_result\": {\n\t\t\t\tif (typeof payload.target !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_message.send_result target must be a string\");\n\t\t\t\t}\n\t\t\t\tif (typeof payload.summary !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_message.send_result summary must be a string\");\n\t\t\t\t}\n\t\t\t\tif (typeof payload.findings !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_message.send_result findings must be a string\");\n\t\t\t\t}\n\t\t\t\treturn this._agentMessageController.sendAgentMessage({\n\t\t\t\t\ttarget: assertDirectAgentMessageTarget(payload.target),\n\t\t\t\t\tmessage: payload.summary,\n\t\t\t\t\tfindings: payload.findings,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcase \"agent_message.send\": {\n\t\t\t\tif (typeof payload.target !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_message.send target must be a string\");\n\t\t\t\t}\n\t\t\t\tif (typeof payload.message !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_message.send message must be a string\");\n\t\t\t\t}\n\t\t\t\treturn this._agentMessageController.sendAgentMessage({\n\t\t\t\t\ttarget: assertDirectAgentMessageTarget(payload.target),\n\t\t\t\t\tmessage: normalizeAgentSessionMessage(payload.message),\n\t\t\t\t});\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown agent message request type \"${type}\"`);\n\t\t}\n\t}\n\n\thandleAgentObserveHostRequest(\n\t\ttype: string,\n\t\tpayload: Record<string, unknown> = {},\n\t):\n\t\t| AgentObserveListResult\n\t\t| AgentObserveAgentSnapshot\n\t\t| AgentObserveRecentMessagesResult\n\t\t| Promise<AgentObserveListResult | AgentObserveAgentSnapshot | AgentObserveRecentMessagesResult> {\n\t\tconst controller = this._agentObserveController;\n\t\tif (!controller) {\n\t\t\tthrow new Error(\"agent observation is not available in this session\");\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase \"agent_observe.list\":\n\t\t\t\treturn controller.listAgents();\n\t\t\tcase \"agent_observe.get\": {\n\t\t\t\tif (typeof payload.target !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_observe.get target must be a string\");\n\t\t\t\t}\n\t\t\t\treturn controller.getAgent(payload.target);\n\t\t\t}\n\t\t\tcase \"agent_observe.recent\": {\n\t\t\t\tif (typeof payload.target !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_observe.recent target must be a string\");\n\t\t\t\t}\n\t\t\t\treturn controller.recentMessages({\n\t\t\t\t\ttarget: payload.target,\n\t\t\t\t\tlimit: normalizeObserveLimit(payload.limit as number | undefined),\n\t\t\t\t\tmaxChars: normalizeObserveMaxChars((payload.max_chars ?? payload.maxChars) as number | undefined),\n\t\t\t\t});\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown agent observe request type \"${type}\"`);\n\t\t}\n\t}\n\n\tprivate async _createGoalFromHost(objective: string, tokenBudget: number | undefined): Promise<GoalState> {\n\t\tswitch (this._goalState.status) {\n\t\t\tcase \"active\":\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"cannot create a new goal because this thread already has an active goal; run `await goal.complete()` when it is achieved, or ask the user to clear it with /goal clear\",\n\t\t\t\t);\n\t\t\tcase \"paused\":\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"cannot create a new goal because a paused goal exists; ask the user to resume it with /goal resume or clear it with /goal clear\",\n\t\t\t\t);\n\t\t\tcase \"budget_limited\":\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"cannot create a new goal because a budget-limited goal exists; ask the user to resume it with /goal resume or clear it with /goal clear\",\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\t// idle, or a terminal record (complete / error): nothing pending, start fresh.\n\t\t\t\treturn this._startGoal(\n\t\t\t\t\tobjective,\n\t\t\t\t\ttokenBudget,\n\t\t\t\t\tthis.sessionManager[bindNativeEntryWriter]().captureGoalOperation({\n\t\t\t\t\t\tversion: 1,\n\t\t\t\t\t\tkind: \"goal_operation\",\n\t\t\t\t\t\toperation: \"create\",\n\t\t\t\t\t\tactor: \"runtime\",\n\t\t\t\t\t\tsubmittedText: objective,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t}\n\t}\n\n\tprivate async _completeGoalFromHost(): Promise<GoalState> {\n\t\tif (!this._goalState.objective || this._goalState.status === \"idle\") {\n\t\t\tthrow new Error(\"cannot complete goal because this thread has no goal\");\n\t\t}\n\t\tconst goal = this._goalWithAccountedWallClock();\n\t\t// A turn can cross the budget and complete the goal at once: accounting\n\t\t// runs at message_end, before the completing ipython cell executes, so a\n\t\t// budget-limit context may already be steered. It is stale now — drop it.\n\t\tthis._clearQueuedGoalContexts();\n\t\treturn this._setGoalState(\n\t\t\t{\n\t\t\t\t...goal,\n\t\t\t\tactive: false,\n\t\t\t\tstatus: \"complete\",\n\t\t\t\tlastReason: \"Goal achieved\",\n\t\t\t\tlastError: undefined,\n\t\t\t},\n\t\t\t{\n\t\t\t\tnativeGoalWrite: this.sessionManager[bindNativeEntryWriter]().captureGoalOperation({\n\t\t\t\t\tversion: 1,\n\t\t\t\t\tkind: \"goal_operation\",\n\t\t\t\t\toperation: \"complete\",\n\t\t\t\t\tactor: \"runtime\",\n\t\t\t\t\tpreviousGoalId: goal.goalId,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\t}\n\n\tprivate _getGoalContinuationMessages(\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal?: AbortSignal,\n\t): Promise<AgentMessage[]>;\n\tprivate _getGoalContinuationMessages(\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal: AbortSignal | undefined,\n\t\towner: GoalContinuationOwner,\n\t): Promise<AgentContinuationOutcome>;\n\tprivate _getGoalContinuationMessages(\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal?: AbortSignal,\n\t\towner?: GoalContinuationOwner,\n\t): Promise<AgentMessage[] | AgentContinuationOutcome> {\n\t\tconst outcome = this._getGoalContinuationOutcome(context, owner ?? this._captureGoalContinuationOwner(signal));\n\t\treturn owner ? outcome : outcome.then((value) => (value.kind === \"continue\" ? value.messages : []));\n\t}\n\n\tprivate async _getGoalContinuationOutcome(\n\t\tcontext: GetContinuationMessagesContext,\n\t\towner: GoalContinuationOwner,\n\t): Promise<AgentContinuationOutcome> {\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(owner.signal);\n\t\tif (await this._stopGoalContinuationForTerminalMessage(context.message, owner)) {\n\t\t\treturn this._stoppedContinuationOutcome(owner.signal);\n\t\t}\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(owner.signal);\n\t\tif (this._goalState.status !== \"active\" || !this._goalState.objective) {\n\t\t\treturn { kind: \"finish\" };\n\t\t}\n\t\t// Delegating and ending the turn is correct behavior; retain the existing wakeup owner.\n\t\tif (this._hasUnsettledRlmQuiescenceWork()) {\n\t\t\tthis._goalContinuationAwaitsRlmWork = true;\n\t\t\treturn { kind: \"wait_for_owned_work\" };\n\t\t}\n\t\tthis._goalContinuationAwaitsRlmWork = false;\n\t\ttry {\n\t\t\tthis._ensureGoalRuntimeActive(context.context);\n\t\t\tconst nextGoal = {\n\t\t\t\t...owner.goal,\n\t\t\t\tcontinuationsUsed: owner.goal.continuationsUsed + 1,\n\t\t\t\tlastReason: undefined,\n\t\t\t\tlastError: undefined,\n\t\t\t};\n\t\t\tawait this._setGoalState(nextGoal, { continuationOwner: owner });\n\t\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(owner.signal);\n\t\t\treturn { kind: \"continue\", messages: [createGoalContextMessage(owner.goal, \"continuation\")] };\n\t\t} catch (error) {\n\t\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(owner.signal);\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\ttry {\n\t\t\t\tawait this._finishGoalWithError(message, owner);\n\t\t\t} catch {\n\t\t\t\t// Preserve the goal hook's existing non-rejection policy, without finishing a replacement goal.\n\t\t\t}\n\t\t\treturn this._stoppedContinuationOutcome(owner.signal);\n\t\t}\n\t}\n\n\tprivate async _getContinuationMessages(\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal?: AbortSignal,\n\t): Promise<AgentMessage[]> {\n\t\t// Keep direct callers of the original Agent callback; the real loop uses the typed owner only.\n\t\tconst outcome = await this._getContinuationOutcome(context, signal);\n\t\treturn outcome.kind === \"continue\" ? outcome.messages : [];\n\t}\n\n\tprivate async _getContinuationOutcome(\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal?: AbortSignal,\n\t): Promise<AgentContinuationOutcome> {\n\t\tif (signal?.aborted || this._disposed || this._disposing) return this._stoppedContinuationOutcome(signal);\n\t\tif (this.queuedActionCount > 0) return { kind: \"finish\" };\n\t\tconst owner = this._captureGoalContinuationOwner(signal);\n\t\tconst arrivalEpoch = this._sessionInputArrivalEpoch;\n\t\tconst goalSnapshot = owner.goal;\n\t\tconst goalAccountingStartedAt = owner.accountingStartedAt;\n\t\tconst autonomousState = this._autonomousState;\n\t\tconst autonomousSnapshot = structuredClone(autonomousState);\n\t\tconst cwd = this._cwd;\n\t\tconst autonomousOwnerIsCurrent = () =>\n\t\t\tthis._autonomousState === autonomousState && isDeepStrictEqual(autonomousState, autonomousSnapshot);\n\t\tconst goalOutcome = await this._getGoalContinuationMessages(context, signal, owner);\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(signal);\n\t\tif (goalOutcome.kind === \"continue\") {\n\t\t\tif (this._sessionInputArrivalEpoch !== arrivalEpoch) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this._setGoalState(goalSnapshot, { continuationOwner: owner });\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof StaleGoalContinuationError) return this._stoppedContinuationOutcome(signal);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(signal);\n\t\t\t\tthis._goalAccountingStartedAt = goalAccountingStartedAt;\n\t\t\t\treturn { kind: \"finish\" };\n\t\t\t}\n\t\t\treturn goalOutcome;\n\t\t}\n\t\tconst noContinuation = (): AgentContinuationOutcome =>\n\t\t\tgoalOutcome.kind === \"wait_for_owned_work\" && this._goalContinuationAwaitsRlmWork\n\t\t\t\t? { kind: \"wait_for_owned_work\" }\n\t\t\t\t: { kind: \"finish\" };\n\t\tif (\n\t\t\tthis._autonomousContinuationSuppressionDepth > 0 ||\n\t\t\t(owner.manager.supportsCapturedHistoryReads()\n\t\t\t\t? this._invocationSuppressedAutonomousContinuation\n\t\t\t\t: context.newMessages.some((message) => this._autonomousContinuationSuppressedMessages.has(message)))\n\t\t) {\n\t\t\treturn noContinuation();\n\t\t}\n\t\tif (!autonomousOwnerIsCurrent()) return { kind: \"finish\" };\n\t\t// Gate work may await. It must not mutate a new run's counters or failure state while it waits.\n\t\tconst candidate = structuredClone(autonomousSnapshot);\n\t\tlet autonomousMessage: AgentMessage | undefined;\n\t\ttry {\n\t\t\tautonomousMessage = await nextAutonomousContinuation(candidate, context.message, { cwd, signal });\n\t\t} catch (error) {\n\t\t\tif (this._isGoalContinuationOwnerCurrent(owner) && autonomousOwnerIsCurrent()) {\n\t\t\t\tthis._restoreAutonomousRuntimeSnapshot(candidate);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(signal);\n\t\tif (!autonomousOwnerIsCurrent()) return { kind: \"finish\" };\n\t\tif (autonomousMessage && this._sessionInputArrivalEpoch !== arrivalEpoch) return { kind: \"finish\" };\n\t\tthis._restoreAutonomousRuntimeSnapshot(candidate);\n\t\t// Preserve the current policy winner: a goal deferral does not override autonomous continuation.\n\t\treturn autonomousMessage ? { kind: \"continue\", messages: [autonomousMessage] } : noContinuation();\n\t}\n\n\tprivate _lastAssistantMessage: AssistantMessage | undefined = undefined;\n\n\tprivate _agentMessageOutcome(agentMessageId: string): AgentMessageOutcome {\n\t\tlet outcome = this._agentMessageOutcomes.get(agentMessageId);\n\t\tif (!outcome) {\n\t\t\toutcome = {};\n\t\t\tthis._agentMessageOutcomes.set(agentMessageId, outcome);\n\t\t}\n\t\treturn outcome;\n\t}\n\n\t/**\n\t * Register a delivery waiter before submitting the prompt. Delivery outcomes are not retained\n\t * for late lookup, so callers that register after admission may wait for a future use of the id.\n\t */\n\twaitForAgentMessagePromptDelivery(agentMessageId: string): Promise<void> {\n\t\tconst outcome = this._agentMessageOutcome(agentMessageId);\n\t\toutcome.delivery ??= createAgentMessageDeferred();\n\t\treturn outcome.delivery.promise;\n\t}\n\n\tprivate _settleAgentMessage(\n\t\tagentMessageId: string | undefined,\n\t\tleg: \"delivery\" | \"completion\",\n\t\terror?: Error,\n\t): void {\n\t\tif (agentMessageId === undefined) return;\n\t\tconst outcome = this._agentMessageOutcomes.get(agentMessageId);\n\t\tif (!outcome) return;\n\t\tconst deferred = outcome[leg];\n\t\tif (!deferred) return;\n\t\toutcome[leg] = undefined;\n\t\tif (!outcome.delivery && !outcome.completion) {\n\t\t\tthis._agentMessageOutcomes.delete(agentMessageId);\n\t\t}\n\t\tif (error) deferred.reject(error);\n\t\telse deferred.resolve();\n\t}\n\n\tprivate _rejectAgentMessage(agentMessageId: string | undefined, error: Error): void {\n\t\tif (agentMessageId === undefined) return;\n\t\tthis._settleAgentMessage(agentMessageId, \"delivery\", error);\n\t\tthis._settleAgentMessage(agentMessageId, \"completion\", error);\n\t}\n\n\tprivate _rejectQueuedAgentMessageDeliveries(deliveryError: Error, completionError = deliveryError): void {\n\t\tfor (const action of this._actionStore.unfinishedActions()) {\n\t\t\tthis._settleAgentMessage(action.agentMessageId, \"delivery\", deliveryError);\n\t\t\tthis._settleAgentMessage(action.agentMessageId, \"completion\", completionError);\n\t\t}\n\t}\n\n\tprivate _capturingCancelledAction(message: AgentMessage): QueuedSessionAction | undefined {\n\t\treturn this._actionStore\n\t\t\t.ownedActions()\n\t\t\t.find(\n\t\t\t\t(action) =>\n\t\t\t\t\taction.lifecycle.state === \"cancelled\" &&\n\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\taction.payload.captureRunMessages?.has(message) === true,\n\t\t\t);\n\t}\n\n\tprivate _hasCancelledDispatchCapture(): boolean {\n\t\treturn this._actionStore\n\t\t\t.ownedActions()\n\t\t\t.some(\n\t\t\t\t(action) =>\n\t\t\t\t\taction.lifecycle.state === \"cancelled\" &&\n\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\taction.payload.captureRunMessages !== undefined,\n\t\t\t);\n\t}\n\n\tprivate _captureInputOrigin(message: UserMessage | CustomMessage): CapturedNativeMessageWrite | undefined {\n\t\tconst actions = this._actionStore.actionsForMessage(message);\n\t\tif (actions.length !== 1) return undefined;\n\t\tconst action = actions[0];\n\t\tif (action.payload.kind !== \"turn\") return undefined;\n\t\tconst record = action.payload.records.find((record) => record.message === message);\n\t\tif (!record) return undefined;\n\t\treturn this.sessionManager[bindNativeEntryWriter]().captureMessage({\n\t\t\tversion: 1,\n\t\t\tkind: \"input\",\n\t\t\tactionId: action.id,\n\t\t\trecordId: record.id,\n\t\t\tinputSource: action.payload.acceptedAgentMessage ? \"internal\" : action.source,\n\t\t\trecordRole: record.role,\n\t\t\t...(record.role === \"primary\" && action.payload.submitted ? { submitted: action.payload.submitted } : {}),\n\t\t\t...(record.role === \"primary\" && action.payload.selectedSkillRef\n\t\t\t\t? { selectedSkillRef: action.payload.selectedSkillRef }\n\t\t\t\t: {}),\n\t\t});\n\t}\n\n\tprivate async _waitForAgentEventsBeforeContext(): Promise<void> {\n\t\ttry {\n\t\t\tawait this._agentEventQueue;\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof CompactionCommittedError) || error !== this._compactionSetupFailure) throw error;\n\t\t}\n\t}\n\n\tprivate _handleAgentEvent = (event: AgentEvent): void | Promise<void> => {\n\t\tif (event.type === \"agent_end\" && event.refusal) this._invocationOutputRefused = true;\n\t\tif (event.type === \"agent_start\") {\n\t\t\t// Native input waits for its delivery ticket. Direct/generic Agent runs have actually started here.\n\t\t\tif (\n\t\t\t\t!this._actionStore\n\t\t\t\t\t.activeActions()\n\t\t\t\t\t.some((action) => action.payload.kind === \"turn\" && action.lifecycle.state === \"committing\")\n\t\t\t) {\n\t\t\t\tfor (const resume of [this._pendingCheckpoint, this._postCompactionContinuationSettlement?.resume]) {\n\t\t\t\t\tif (resume?.boundary && this._isCompactionOwnerCurrent(resume.owner)) resume.boundary.state = \"consumed\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._invocationSuppressedAutonomousContinuation = false;\n\t\t\tthis._invocationCompactionOwner = this._captureCompactionOwner(this.agent.signal);\n\t\t}\n\t\tif (\n\t\t\t(event.type === \"message_start\" || event.type === \"message_end\") &&\n\t\t\tthis._autonomousContinuationSuppressedMessages.has(event.message)\n\t\t) {\n\t\t\tthis._invocationSuppressedAutonomousContinuation = true;\n\t\t}\n\t\tconst nativeMessageWrite =\n\t\t\tevent.type === \"message_end\" && (event.message.role === \"user\" || event.message.role === \"custom\")\n\t\t\t\t? this._captureInputOrigin(event.message)\n\t\t\t\t: undefined;\n\t\tif (event.type === \"message_start\" || event.type === \"message_end\") {\n\t\t\tfor (const action of this._actionStore.ownedActions()) {\n\t\t\t\tif (\n\t\t\t\t\taction.payload.kind !== \"turn\" ||\n\t\t\t\t\t!action.payload.captureRunMessages ||\n\t\t\t\t\taction.payload.cancelledDispatchEnded\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst primary = primaryDeliveryRecord(action);\n\t\t\t\tif (event.message === primary.message || primary.started) {\n\t\t\t\t\taction.payload.captureRunMessages.add(event.message);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (event.type === \"agent_end\") {\n\t\t\tconst captured = new Set<AgentMessage>();\n\t\t\tfor (const action of this._actionStore.ownedActions()) {\n\t\t\t\tif (action.payload.kind === \"turn\" && action.payload.captureRunMessages) {\n\t\t\t\t\tfor (const message of action.payload.captureRunMessages) captured.add(message);\n\t\t\t\t\taction.payload.cancelledDispatchEnded = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (captured.size > 0) {\n\t\t\t\tthis.agent.state.messages = this.agent.state.messages.filter((message) => !captured.has(message));\n\t\t\t}\n\t\t}\n\t\tif (event.type === \"message_start\" && (event.message.role === \"user\" || event.message.role === \"custom\")) {\n\t\t\tfor (const action of this._actionStore.actionsForMessage(event.message)) {\n\t\t\t\tconst record =\n\t\t\t\t\taction.payload.kind === \"turn\"\n\t\t\t\t\t\t? action.payload.records.find((candidate) => candidate.message === event.message)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (record) record.started = true;\n\t\t\t}\n\t\t}\n\t\tif (event.type === \"message_end\" && event.message.role === \"assistant\") {\n\t\t\t// Native result settlement precedes message publication. Keep auth failure\n\t\t\t// ownership independent of later message replacement, cancellation, or retry cleanup.\n\t\t\tconst source = takeNativeInferenceAuthSource(event.message);\n\t\t\tif (source && this._isConcreteProviderAuthFailure(event.message)) this._markProviderAuthStale(source);\n\t\t}\n\t\tconst compactionOwner = event.type === \"agent_end\" ? this._invocationCompactionOwner : undefined;\n\t\tconst job = this._agentEventQueue.then(\n\t\t\t() => this._processAgentEvent(event, nativeMessageWrite, compactionOwner),\n\t\t\t() => this._processAgentEvent(event, nativeMessageWrite, compactionOwner),\n\t\t);\n\t\tthis._agentEventQueue = job;\n\t\tjob.catch(() => {});\n\t\t// Ordinary extension contexts already expose request-only abort, not command waitForIdle.\n\t\t// Join THIS accepted message job, never a later mutable tail from inside that job.\n\t\tif (\n\t\t\tthis.sessionManager.supportsCapturedHistoryReads() &&\n\t\t\t(event.type === \"message_end\" || (event.type === \"agent_end\" && event.refusal))\n\t\t)\n\t\t\treturn job;\n\t};\n\n\tprivate _findLastAssistantInMessages(messages: AgentMessage[]): AssistantMessage | undefined {\n\t\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\t\tconst message = messages[i];\n\t\t\tif (message.role === \"assistant\") {\n\t\t\t\treturn message as AssistantMessage;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _addLoginGuidanceToAuthError(event: AgentEvent): void {\n\t\tconst message =\n\t\t\tevent.type === \"message_end\" && event.message.role === \"assistant\"\n\t\t\t\t? (event.message as AssistantMessage)\n\t\t\t\t: event.type === \"agent_end\" && !event.refusal\n\t\t\t\t\t? this._findLastAssistantInMessages(event.messages)\n\t\t\t\t\t: undefined;\n\t\tif (!message || message.stopReason !== \"error\" || !message.errorMessage) {\n\t\t\treturn;\n\t\t}\n\t\tif (!isLikelyAuthenticationError(message.errorMessage)) {\n\t\t\treturn;\n\t\t}\n\t\tmessage.errorMessage = addLoginGuidanceToAuthError(message.errorMessage);\n\t}\n\n\tprivate async _processAgentEvent(\n\t\tevent: AgentEvent,\n\t\tnativeMessageWrite?: CapturedNativeMessageWrite,\n\t\tcompactionOwner?: CompactionOwner,\n\t): Promise<void> {\n\t\tlet clearedDispatchEnded = false;\n\t\tif ((event.type === \"message_start\" || event.type === \"message_end\") && event.message.role === \"toolResult\") {\n\t\t\tif (this.sessionManager.supportsCapturedHistoryReads())\n\t\t\t\tawait this._applyCanonicalIpythonSentAgentMessages(event.message);\n\t\t\telse this._applyLateIpythonSentAgentMessages(event.message);\n\t\t}\n\t\tif (event.type === \"message_start\" || event.type === \"message_end\") {\n\t\t\tconst cleared = this._capturingCancelledAction(event.message);\n\t\t\tif (cleared?.payload.kind === \"turn\" && cleared.payload.captureRunMessages) {\n\t\t\t\tconst captured = cleared.payload.captureRunMessages;\n\t\t\t\tthis.agent.state.messages = this.agent.state.messages.filter((message) => !captured.has(message));\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif (event.type === \"agent_end\") {\n\t\t\tconst cleared = this._actionStore\n\t\t\t\t.ownedActions()\n\t\t\t\t.filter(\n\t\t\t\t\t(action) =>\n\t\t\t\t\t\taction.lifecycle.state === \"cancelled\" &&\n\t\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\t\taction.payload.captureRunMessages !== undefined,\n\t\t\t\t);\n\t\t\tif (cleared.length > 0) {\n\t\t\t\tclearedDispatchEnded = true;\n\t\t\t\tconst removed = new Set(\n\t\t\t\t\tcleared.flatMap((action) =>\n\t\t\t\t\t\taction.payload.kind === \"turn\" ? [...(action.payload.captureRunMessages ?? [])] : [],\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tthis.agent.state.messages = this.agent.state.messages.filter((message) => !removed.has(message));\n\t\t\t\t(this.agent.state as { errorMessage?: string }).errorMessage = undefined;\n\t\t\t\tthis._lastAssistantMessage = undefined;\n\t\t\t\tfor (const action of cleared) this._actionStore.releaseTerminal(action);\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\tthis._resolveRetry();\n\t\t\t}\n\t\t}\n\n\t\tif (event.type === \"agent_end\" && event.refusal) {\n\t\t\t// Primary delivery ACKs remain delivered. Only this invocation's completion has failed.\n\t\t\tthis._lastAssistantMessage = undefined;\n\t\t\tthis._clearQueuedGoalContexts();\n\t\t\tthis._clearQueuedAutonomousContinuations();\n\t\t\tif (this._retryAttempt > 0) {\n\t\t\t\tthis._emit({\n\t\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tattempt: this._retryAttempt,\n\t\t\t\t\tfinalError: new AgentOutputLimitError(event.refusal).message,\n\t\t\t\t});\n\t\t\t\tthis._retryAttempt = 0;\n\t\t\t}\n\t\t\tthis._resolveRetry();\n\t\t\tawait this._emitExtensionEvent(event);\n\t\t\tthis._emit(event);\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.type === \"message_start\" && startsAgentRun(event.message)) {\n\t\t\tthis._overflowRecovery = \"idle\";\n\t\t}\n\n\t\tif (\n\t\t\tthis.sessionManager.supportsCapturedHistoryReads() &&\n\t\t\tevent.type === \"message_end\" &&\n\t\t\tevent.message.role === \"assistant\"\n\t\t) {\n\t\t\t// Preserve budget progress while a message_end transformer waits. The same subject WeakSet\n\t\t\t// deduplicates the post-message and post-turn calls; goal state is published only after its ACK.\n\t\t\t// Do not run serialized refinement/compaction or stop mandatory tools at this point.\n\t\t\tif ((await this._accountGoalUsageForAssistantMessage(event.message)) && !this._invocationOutputRefused) {\n\t\t\t\tconst message = createGoalContextMessage(this._goalState, \"budget_limit\");\n\t\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\t\tawait this._queuePreparedPrompt(\"steer\", normalized.text, normalized.images, {\n\t\t\t\t\tmessage,\n\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait this._emitExtensionEvent(event);\n\t\tif (event.type === \"message_start\" || event.type === \"message_end\") {\n\t\t\tconst cleared = this._capturingCancelledAction(event.message);\n\t\t\tif (cleared?.payload.kind === \"turn\" && cleared.payload.captureRunMessages) {\n\t\t\t\tconst captured = cleared.payload.captureRunMessages;\n\t\t\t\tthis.agent.state.messages = this.agent.state.messages.filter((message) => !captured.has(message));\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis._addLoginGuidanceToAuthError(event);\n\n\t\tif (event.type !== \"message_end\") this._emit(event);\n\n\t\tif (event.type === \"message_end\") {\n\t\t\tif (event.message.role === \"custom\") {\n\t\t\t\tif (nativeMessageWrite) await nativeMessageWrite(event.message);\n\t\t\t\telse\n\t\t\t\t\tawait this.sessionManager.appendCustomMessageEntry(\n\t\t\t\t\t\tevent.message.customType,\n\t\t\t\t\t\tevent.message.content,\n\t\t\t\t\t\tevent.message.display,\n\t\t\t\t\t\tevent.message.details,\n\t\t\t\t\t);\n\t\t\t} else if (\n\t\t\t\tevent.message.role === \"user\" ||\n\t\t\t\tevent.message.role === \"assistant\" ||\n\t\t\t\tevent.message.role === \"toolResult\"\n\t\t\t) {\n\t\t\t\tconst manager = this.sessionManager;\n\t\t\t\tconst sessionId = manager.getSessionId();\n\t\t\t\tconst sessionFile = manager.getSessionFile();\n\t\t\t\tconst nativeOutput =\n\t\t\t\t\t!nativeMessageWrite && event.message.role === \"assistant\"\n\t\t\t\t\t\t? this.requests.appendMainOutput(event.message, manager)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst entryId = nativeMessageWrite\n\t\t\t\t\t? await nativeMessageWrite(event.message)\n\t\t\t\t\t: ((nativeOutput ? await nativeOutput : undefined) ?? (await manager.appendMessage(event.message)));\n\t\t\t\tif (event.message.role === \"assistant\")\n\t\t\t\t\tthis._assistantEntryIds.set(event.message, { sessionId, sessionFile, entryId });\n\t\t\t}\n\t\t\tif (event.message.role === \"user\" || event.message.role === \"custom\") {\n\t\t\t\tfor (const action of this._actionStore.actionsForMessage(event.message)) {\n\t\t\t\t\tconst record =\n\t\t\t\t\t\taction.payload.kind === \"turn\"\n\t\t\t\t\t\t\t? action.payload.records.find((candidate) => candidate.message === event.message)\n\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\tif (record) record.durable = true;\n\t\t\t\t\tif (record?.role === \"primary\") {\n\t\t\t\t\t\tthis._actionStore.ticketFor(action).settleDelivered({ status: \"delivered\" });\n\t\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"delivery\");\n\t\t\t\t\t\tif (action.lifecycle.state === \"committing\") {\n\t\t\t\t\t\t\ttransitionSessionAction(action, { state: \"running\", execution: \"agent_turn\" });\n\t\t\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._emit(event);\n\n\t\t\tif (event.message.role === \"assistant\") {\n\t\t\t\tthis._lastAssistantMessage = event.message;\n\n\t\t\t\tconst assistantMsg = event.message as AssistantMessage;\n\t\t\t\tif (assistantMsg.stopReason !== \"error\") {\n\t\t\t\t\taddAutonomousUsage(this._autonomousState, assistantMsg.usage);\n\t\t\t\t}\n\t\t\t\tif (assistantMsg.stopReason !== \"error\" && assistantMsg.stopReason !== \"aborted\") {\n\t\t\t\t\tthis._assistantTurnsSinceAutoRefine++;\n\t\t\t\t\t// In serialized mode, kick off background refinement planning\n\t\t\t\t\t// immediately after the primary stream finishes, while tools\n\t\t\t\t\t// are still executing. The plan is awaited at shouldStopAfterTurn\n\t\t\t\t\t// before applying, so planning overlaps tools only — never another\n\t\t\t\t\t// model request.\n\t\t\t\t\tthis._maybeStartSerializedBackgroundPlan();\n\t\t\t\t}\n\t\t\t\tif (assistantMsg.stopReason !== \"error\") {\n\t\t\t\t\tthis._overflowRecovery = \"idle\";\n\t\t\t\t}\n\n\t\t\t\t// Reset retry counter immediately on successful assistant response\n\t\t\t\t// This prevents accumulation across multiple LLM calls within a turn\n\t\t\t\tif (\n\t\t\t\t\tassistantMsg.stopReason !== \"error\" &&\n\t\t\t\t\tassistantMsg.stopReason !== \"aborted\" &&\n\t\t\t\t\tthis._retryAttempt > 0\n\t\t\t\t) {\n\t\t\t\t\tthis._emit({\n\t\t\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tattempt: this._retryAttempt,\n\t\t\t\t\t});\n\t\t\t\t\tthis._retryAttempt = 0;\n\t\t\t\t}\n\t\t\t\tif ((await this._accountGoalUsageForAssistantMessage(assistantMsg)) && !this._invocationOutputRefused) {\n\t\t\t\t\tconst message = createGoalContextMessage(this._goalState, \"budget_limit\");\n\t\t\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\t\t\tawait this._queuePreparedPrompt(\"steer\", normalized.text, normalized.images, {\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (clearedDispatchEnded) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.type === \"agent_end\") {\n\t\t\tconst msg =\n\t\t\t\tthis._lastAssistantMessage ??\n\t\t\t\t(this._retryPromise ? this._findLastAssistantInMessages(event.messages) : undefined);\n\t\t\tthis._lastAssistantMessage = undefined;\n\t\t\tif (!msg) {\n\t\t\t\tthis._resolveRetry();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst compactionWillRetry = await this._checkCompaction(msg, true, true, compactionOwner);\n\t\t\tif (compactionWillRetry && this._retryAttempt > 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._finishActiveRetryWithFailure(msg);\n\t\t\tthis._resolveRetry();\n\t\t\tif (!compactionWillRetry) {\n\t\t\t\tawait this._finishGoalForTerminalAssistantMessage(msg);\n\t\t\t\t// In serialized mode, agent-callable refine.run is serviced\n\t\t\t\t// at the shouldStopAfterTurn boundary, not here at agent_end.\n\t\t\t\tif (!this._serializedRefine) {\n\t\t\t\t\tconst consumedRequestedRefine = this._consumePendingRequestedRefine();\n\t\t\t\t\tif (!consumedRequestedRefine) {\n\t\t\t\t\t\tthis._scheduleAutoRefineAfterAgentEnd();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _resolveRetry(): void {\n\t\tthis._semanticEdges.clearTurnRetry();\n\t\tthis.requests.clearTurnRetry();\n\t\tif (this._retryResolve) {\n\t\t\tthis._retryResolve();\n\t\t\tthis._retryResolve = undefined;\n\t\t\tthis._retryPromise = undefined;\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\tthis._scheduleSessionInputPump();\n\t\t}\n\t}\n\n\tprivate _findLastAssistantMessage(): AssistantMessage | undefined {\n\t\tconst messages = this.agent.state.messages;\n\t\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\t\tconst msg = messages[i];\n\t\t\tif (msg.role === \"assistant\") {\n\t\t\t\treturn msg as AssistantMessage;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _replaceMessageInPlace(target: AgentMessage, replacement: AgentMessage): void {\n\t\t// Agent-core stores the finalized message object in its state before emitting message_end.\n\t\t// SessionManager persistence happens later in _processAgentEvent() with event.message.\n\t\t// Mutating this object in place keeps agent state, later turn/agent events, listeners,\n\t\t// and the eventual SessionManager.appendMessage(event.message) persistence in sync.\n\t\tif (target === replacement) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst targetRecord = target as unknown as Record<string, unknown>;\n\t\tfor (const key of Object.keys(targetRecord)) {\n\t\t\tdelete targetRecord[key];\n\t\t}\n\t\tObject.assign(targetRecord, replacement);\n\t}\n\n\tprivate async _emitExtensionEvent(event: AgentEvent): Promise<void> {\n\t\t// Failed native initialization can emit a lifecycle error before extensions exist.\n\t\tif (!this._extensionRunner) return;\n\t\tif (event.type === \"agent_start\") {\n\t\t\tthis._turnIndex = 0;\n\t\t\tawait this.sessionManager.recordGitStateIfChanged();\n\t\t\tawait this._extensionRunner.emit({ type: \"agent_start\" });\n\t\t} else if (event.type === \"agent_end\") {\n\t\t\t// Also capture at end of turn so commits made during the run (e.g. via a bash tool) land.\n\t\t\tawait this.sessionManager.recordGitStateIfChanged();\n\t\t\tawait this._extensionRunner.emit(event);\n\t\t} else if (event.type === \"turn_start\") {\n\t\t\tconst extensionEvent: TurnStartEvent = {\n\t\t\t\ttype: \"turn_start\",\n\t\t\t\tturnIndex: this._turnIndex,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t} else if (event.type === \"turn_end\") {\n\t\t\tconst extensionEvent: TurnEndEvent = {\n\t\t\t\ttype: \"turn_end\",\n\t\t\t\tturnIndex: this._turnIndex,\n\t\t\t\tmessage: event.message,\n\t\t\t\ttoolResults: event.toolResults,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t\tthis._turnIndex++;\n\t\t} else if (event.type === \"message_start\") {\n\t\t\tconst extensionEvent: MessageStartEvent = {\n\t\t\t\ttype: \"message_start\",\n\t\t\t\tmessage: event.message,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t} else if (event.type === \"message_update\") {\n\t\t\tconst extensionEvent: MessageUpdateEvent = {\n\t\t\t\ttype: \"message_update\",\n\t\t\t\tmessage: event.message,\n\t\t\t\tassistantMessageEvent: event.assistantMessageEvent,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t} else if (event.type === \"message_end\") {\n\t\t\tconst extensionEvent: MessageEndEvent = {\n\t\t\t\ttype: \"message_end\",\n\t\t\t\tmessage: event.message,\n\t\t\t};\n\t\t\tconst replacement = await this._extensionRunner.emitMessageEnd(extensionEvent);\n\t\t\tif (replacement) {\n\t\t\t\tthis._replaceMessageInPlace(event.message, replacement);\n\t\t\t}\n\t\t} else if (event.type === \"tool_execution_start\") {\n\t\t\tconst extensionEvent: ToolExecutionStartEvent = {\n\t\t\t\ttype: \"tool_execution_start\",\n\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\ttoolName: event.toolName,\n\t\t\t\targs: event.args,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t} else if (event.type === \"tool_execution_update\") {\n\t\t\tconst extensionEvent: ToolExecutionUpdateEvent = {\n\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\ttoolName: event.toolName,\n\t\t\t\targs: event.args,\n\t\t\t\tpartialResult: event.partialResult,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t} else if (event.type === \"tool_execution_end\") {\n\t\t\tconst extensionEvent: ToolExecutionEndEvent = {\n\t\t\t\ttype: \"tool_execution_end\",\n\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\ttoolName: event.toolName,\n\t\t\t\tresult: event.result,\n\t\t\t\tisError: event.isError,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t}\n\t}\n\n\t/**\n\t * Subscribe to agent events.\n\t * Session persistence is handled internally (saves messages on message_end).\n\t * Multiple listeners can be added. Returns unsubscribe function for this listener.\n\t */\n\tsubscribe(listener: AgentSessionEventListener): () => void {\n\t\tthis._eventListeners.push(listener);\n\n\t\treturn () => {\n\t\t\tconst index = this._eventListeners.indexOf(listener);\n\t\t\tif (index !== -1) {\n\t\t\t\tthis._eventListeners.splice(index, 1);\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Temporarily disconnect from agent events.\n\t * User listeners are preserved and will receive events again after resubscribe().\n\t * Used internally during operations that need to pause event processing.\n\t */\n\tprivate _disconnectFromAgent(): void {\n\t\tif (this._unsubscribeAgent) {\n\t\t\tthis._unsubscribeAgent();\n\t\t\tthis._unsubscribeAgent = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Reconnect to agent events after _disconnectFromAgent().\n\t * Preserves all existing listeners.\n\t */\n\tprivate _reconnectToAgent(): void {\n\t\tif (this._unsubscribeAgent) return; // Already connected\n\t\tthis._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);\n\t}\n\n\t/**\n\t * Remove all listeners and disconnect from agent.\n\t * Call this when completely done with the session.\n\t */\n\t/** Stop new opportunistic refinement without cancelling accepted calls or explicit queued requests. */\n\tcloseAutoRefineAdmission(): void {\n\t\tif (this._autoRefineAdmissionClosed) return;\n\t\tthis._autoRefineAdmissionClosed = true;\n\t\tfor (const timer of this._scheduledAutoRefineTimers) clearTimeout(timer);\n\t\tthis._scheduledAutoRefineTimers.clear();\n\t\tthis._discardPendingAutoRefine();\n\t}\n\n\t/**\n\t * Async teardown for graceful quit/switch: await the Python kernel's dispose\n\t * (which flushes a final namespace snapshot) before the synchronous dispose, so\n\t * the latest state reaches disk instead of racing process exit.\n\t */\n\tasync disposeAsync(options?: { kernelSnapshot?: boolean }): Promise<void> {\n\t\tthis._failedAutomaticCompaction = undefined;\n\t\tthis._failedThresholdCompaction = undefined;\n\t\tthis._contextCompiler.clear();\n\t\tthis._nativeRecoveryCursors.clear();\n\t\tfor (const admission of this._rlmChildAdmissions) admission.cancel(\"Parent session disposed\");\n\t\tif (this._disposeAsyncPromise) return this._disposeAsyncPromise;\n\t\tthis.closeAutoRefineAdmission();\n\t\tconst kernelSnapshot = options?.kernelSnapshot ?? true;\n\t\tthis._disposeAsyncPromise = (async () => {\n\t\t\tconst errors: unknown[] = [];\n\t\t\ttry {\n\t\t\t\tif (!this._disposed) await this._drainPendingRefinementForDisposal();\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t\tthis._disposing = true;\n\t\t\tthis._sessionActionCommitDisposeAbortController.abort();\n\t\t\ttry {\n\t\t\t\tawait this._disposeAsyncOnce(kernelSnapshot);\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session disposal failed\");\n\t\t\tthis._rlmResidentDisposalComplete = true;\n\t\t\tawait this._releaseRlmResidentCapacity?.();\n\t\t\tawait this._rlmRootAdmission?.release();\n\t\t})();\n\t\treturn this._disposeAsyncPromise;\n\t}\n\n\t/** Drain accepted refinement and explicit queued requests; never start an opportunistic review or plan. */\n\tprivate async _drainPendingRefinementForDisposal(): Promise<void> {\n\t\tthis.closeAutoRefineAdmission();\n\t\tawait this._drainAcceptedRefinement();\n\t}\n\n\tprivate async _drainAcceptedRefinement(): Promise<void> {\n\t\tconst errors: unknown[] = [];\n\t\tconst drain = async () => {\n\t\t\tfor (const timer of this._scheduledAutoRefineTimers) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tthis._scheduledAutoRefineTimers.clear();\n\t\t\tconst settled = await Promise.allSettled([...this._autoRefineOperations]);\n\t\t\tfor (const result of settled) if (result.status === \"rejected\") errors.push(result.reason);\n\t\t\tfor (const timer of this._scheduledAutoRefineTimers) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tthis._scheduledAutoRefineTimers.clear();\n\t\t\t// Wait for in-flight refinement (including serialized background plan) to settle.\n\t\t\twhile (this._refineInFlight || this._refinePlanInFlight || this._serializedPlanInFlight) {\n\t\t\t\tif (this._refineInFlight) {\n\t\t\t\t\tawait this._refineInFlight;\n\t\t\t\t} else if (this._refinePlanInFlight) {\n\t\t\t\t\tawait this._refinePlanInFlight;\n\t\t\t\t} else if (this._serializedPlanInFlight) {\n\t\t\t\t\t// Await the background plan and apply a ready \"plan\" result before teardown.\n\t\t\t\t\tawait this._consumeSerializedBackgroundPlan(async (bgResult) => {\n\t\t\t\t\t\tif (bgResult?.status === \"plan\" && bgResult.branchVersion === this._autoRefineBranchVersion) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tawait this._applySerializedPlan(bgResult);\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\terrors.push(error);\n\t\t\t\t\t\t\t\tthis._emitRefineFailed(error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Preserve completion bookkeeping for the accepted refinement.\n\t\t\t\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// A failed background plan keeps its recorded failure; disposal never recreates it for retry.\n\t\t\t\t\t\tif (bgResult?.status === \"skip\" && bgResult.explicit) {\n\t\t\t\t\t\t\tthis._emitRefineFailed(new RefineSkippedError(\"Refinement skipped by extension\"));\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Preserve completed background-round bookkeeping without retrying.\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tbgResult?.status === \"skip\" ||\n\t\t\t\t\t\t\tbgResult?.status === \"failure\" ||\n\t\t\t\t\t\t\tbgResult?.status === \"invalidated\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tawait new Promise<void>((resolve) => setTimeout(resolve, 0));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this._compactionSetupFailure) return;\n\t\t\t// Drain an agent-callable refine.run request that was scheduled but\n\t\t\t// not yet consumed. Use the direct serialized path (no waitForIdle)\n\t\t\t// since the agent may still own activeRun at the final agent_end.\n\t\t\tif (this._pendingRequestedRefine) {\n\t\t\t\tconst pending = this._pendingRequestedRefine;\n\t\t\t\tthis._pendingRequestedRefine = undefined;\n\t\t\t\ttry {\n\t\t\t\t\tawait this._runSerializedRefine(pending);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t}\n\t\t\t\t// Preserve completion bookkeeping for the accepted explicit request.\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t}\n\t\t};\n\t\ttry {\n\t\t\tawait drain();\n\t\t} catch (error) {\n\t\t\terrors.push(error);\n\t\t}\n\t\tconst distinct = [...new Set(errors)];\n\t\tif (distinct.length === 1) throw distinct[0];\n\t\tif (distinct.length > 1) throw new AggregateError(distinct, \"Session refinement drain failed\");\n\t}\n\n\tprivate async _disposeAsyncOnce(kernelSnapshot: boolean): Promise<void> {\n\t\tconst admissions = [...this._rlmChildAdmissions];\n\t\tconst errors: unknown[] = [];\n\t\tconst drain = async (operation: () => unknown | Promise<unknown>): Promise<void> => {\n\t\t\ttry {\n\t\t\t\tawait operation();\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t};\n\t\ttry {\n\t\t\tawait drain(() => this.requests.stopAdmission());\n\t\t\tawait drain(() => this.requestAbort());\n\t\t\tfor (const run of [...this._activeRlmChildRuns.values()]) {\n\t\t\t\tawait drain(() => this._cancelRlmChildRun(run, \"Parent session disposed\"));\n\t\t\t}\n\t\t\tawait drain(() => this.requests.waitForIdle());\n\t\t\t// Initialization reports errors through its own promise, like an active Agent run.\n\t\t\t// Join it before disposing any runtime resources it may still be constructing.\n\t\t\tif (this._initialization) await Promise.allSettled([this._initialization]);\n\t\t\t// Includes native children constructed but not yet published by their factories.\n\t\t\tfor (const admission of admissions) {\n\t\t\t\tif (admission.session) await drain(() => admission.session?.disposeAsync());\n\t\t\t}\n\t\t\tfor (const run of [...this._activeRlmChildRuns.values()]) {\n\t\t\t\tconst childSession = run.session;\n\t\t\t\tif (!childSession) continue;\n\t\t\t\trun.suppressTerminalNotice = true;\n\t\t\t\tif (run.detachedDeletion && run.deletionCleanupObserver) {\n\t\t\t\t\tawait drain(() => run.deletionCleanupObserver);\n\t\t\t\t} else if (run.detachedDeletion && run.deletionCleanup) {\n\t\t\t\t\tawait drain(() => run.deletionCleanup);\n\t\t\t\t} else {\n\t\t\t\t\tawait drain(() => childSession.disposeAsync());\n\t\t\t\t}\n\t\t\t\tif (run.detachedDeletion && !run.settled) await drain(() => this._finishRlmRunDeletion(run));\n\t\t\t}\n\t\t\tfor (const unsubscribe of this._rlmChildUnsubscribes.values()) await drain(unsubscribe);\n\t\t\tthis._rlmChildUnsubscribes.clear();\n\t\t\tfor (const { session } of this._rlmChildSessions.values()) await drain(() => session.disposeAsync());\n\t\t\tthis._rlmChildSessions.clear();\n\t\t\tthis._rlmChildUsageSources.clear();\n\t\t\tthis._rlmChildCleanupFailures.clear();\n\t\t\tthis._deletedRlmChildIds.clear();\n\t\t\t// Stop kernel-backed tools before waiting for their terminal agent events.\n\t\t\tawait drain(() => this._ipythonKernelProvisioner?.dispose({ snapshot: kernelSnapshot }));\n\t\t\twhile (this._rlmRunTasks.size > 0) {\n\t\t\t\tfor (const task of [...this._rlmRunTasks]) await drain(() => task);\n\t\t\t}\n\t\t\tfor (const admission of admissions) {\n\t\t\t\tawait drain(() => admission.settlement);\n\t\t\t\tif (admission.session) await drain(() => admission.session?.disposeAsync());\n\t\t\t}\n\t\t\tawait drain(() => this.agent.waitForIdle());\n\t\t\tawait drain(() => this._compactionOperation);\n\t\t\tawait drain(() => this._branchSummaryOperation);\n\t\t\tawait drain(() => this._agentEventQueue);\n\t\t\tawait drain(() => this._goalResumeOperation);\n\t\t\tawait drain(() => this._waitForChildUsageWrites());\n\t\t\tawait drain(() => this.dispose());\n\t\t} catch (error) {\n\t\t\terrors.push(error);\n\t\t} finally {\n\t\t\tawait drain(() => this._startDisposeCallbacks());\n\t\t\tawait drain(() => this.sessionManager.close());\n\t\t}\n\t\tif (errors.length === 1) throw errors[0];\n\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session disposal failed\");\n\t}\n\n\tprivate _startDisposeCallbacks(): Promise<void> {\n\t\tif (this._disposeCallbacksPromise) return this._disposeCallbacksPromise;\n\t\tconst pending: Promise<void>[] = [];\n\t\tfor (const callback of this._disposeCallbacks) {\n\t\t\ttry {\n\t\t\t\tconst result = callback();\n\t\t\t\tif (result) pending.push(result);\n\t\t\t} catch (error) {\n\t\t\t\tpending.push(Promise.reject(error));\n\t\t\t}\n\t\t}\n\t\tthis._disposeCallbacks.clear();\n\t\tthis._disposeCallbacksPromise = Promise.allSettled(pending).then((results) => {\n\t\t\tconst errors = results.flatMap((result) => (result.status === \"rejected\" ? [result.reason] : []));\n\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session disposal callbacks failed\");\n\t\t});\n\t\treturn this._disposeCallbacksPromise;\n\t}\n\n\tdispose(): void {\n\t\tthis._failedAutomaticCompaction = undefined;\n\t\tthis._failedThresholdCompaction = undefined;\n\t\tthis._contextCompiler.clear();\n\t\tthis._nativeRecoveryCursors.clear();\n\t\tif (this._disposed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.requests.stopAdmission();\n\t\tthis._disposed = true;\n\t\tfor (const run of this._unsettledRlmChildRuns) run.suppressTerminalNotice = true;\n\t\tfor (const controller of this._rlmQuiescenceWaitAborts) controller.abort();\n\t\tthis._sessionActionCommitDisposeAbortController.abort();\n\t\ttry {\n\t\t\t// Invalidate scheduled timers and abort any in-flight review so a late\n\t\t\t// resolution cannot write harness state or re-subscribe handlers.\n\t\t\tthis._autoRefineReviewAbort?.abort();\n\t\t\tthis._refineAbortController?.abort();\n\t\t\tfor (const timer of this._scheduledAutoRefineTimers) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tthis._scheduledAutoRefineTimers.clear();\n\t\t\tthis._serializedPlanInFlight = undefined;\n\t\t\tthis._serializedExplicitRefineOptions = undefined;\n\t\t\tthis._pendingRequestedRefine = undefined;\n\t\t\tthis._discardPendingAutoRefine({ cancelPostCompactionContinue: true });\n\t\t\tthis._autoRefineBranchVersion++;\n\t\t\tthis._cancelActiveRlmChildRuns(\"Parent session disposed\");\n\t\t\tfor (const unsubscribe of this._rlmChildUnsubscribes.values()) {\n\t\t\t\tunsubscribe();\n\t\t\t}\n\t\t\tthis._rlmChildUnsubscribes.clear();\n\t\t\tfor (const { session } of this._rlmChildSessions.values()) {\n\t\t\t\tsession.dispose();\n\t\t\t}\n\t\t\tthis._rlmChildSessions.clear();\n\t\t\tthis._rlmChildUsageSources.clear();\n\t\t\tthis._rlmChildCleanupFailures.clear();\n\t\t\tthis._deletedRlmChildIds.clear();\n\t\t\tthis._pendingNextTurnMessages = [];\n\t\t\tconst deliveryError = new Error(\"Session disposed before prompt delivery.\");\n\t\t\tconst completionError = new Error(\"Session disposed before prompt completion.\");\n\t\t\tthis._rejectQueuedAgentMessageDeliveries(deliveryError, completionError);\n\t\t\tfor (const [agentMessageId, outcome] of this._agentMessageOutcomes) {\n\t\t\t\tif (outcome.delivery) this._settleAgentMessage(agentMessageId, \"delivery\", deliveryError);\n\t\t\t\tif (outcome.completion) this._settleAgentMessage(agentMessageId, \"completion\", completionError);\n\t\t\t}\n\t\t\tthis._cancelSessionActions(() => true, deliveryError);\n\t\t\tthis.agent.clearAllQueues();\n\t\t\tthis._extensionRunner?.invalidate(\n\t\t\t\t\"This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().\",\n\t\t\t);\n\t\t\tthis._disconnectFromAgent();\n\t\t\tthis._eventListeners = [];\n\t\t\tcleanupSessionResources(this.sessionId);\n\t\t} finally {\n\t\t\t// The synchronous surface cannot report late errors; disposeAsync joins this same promise.\n\t\t\tvoid this._startDisposeCallbacks().catch(() => undefined);\n\t\t}\n\t}\n\n\tregisterDisposeCallback(callback: () => void | Promise<void>): void {\n\t\tif (this._disposed) {\n\t\t\ttry {\n\t\t\t\tconst result = callback();\n\t\t\t\tif (result) void result.catch(() => undefined);\n\t\t\t} catch {\n\t\t\t\t// Late registration follows the same best-effort disposal contract.\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis._disposeCallbacks.add(callback);\n\t}\n\n\tget state(): AgentState {\n\t\treturn this.agent.state;\n\t}\n\n\tget model(): Model<any> | undefined {\n\t\treturn this.agent.state.model;\n\t}\n\n\tget thinkingLevel(): ThinkingLevel {\n\t\treturn this.agent.state.thinkingLevel;\n\t}\n\n\tget serviceTier(): ServiceTier {\n\t\treturn this.agent.state.serviceTier;\n\t}\n\n\tget isStreaming(): boolean {\n\t\treturn this.agent.state.isStreaming;\n\t}\n\n\tget systemPrompt(): string {\n\t\treturn this.agent.state.systemPrompt;\n\t}\n\n\tget retryAttempt(): number {\n\t\treturn this._retryAttempt;\n\t}\n\n\tgetActiveToolNames(): string[] {\n\t\treturn this.agent.state.tools.map((t) => t.name);\n\t}\n\n\tgetAllTools(): ToolInfo[] {\n\t\treturn Array.from(this._toolDefinitions.values()).map(({ definition, sourceInfo }) => ({\n\t\t\tname: definition.name,\n\t\t\tdescription: definition.description,\n\t\t\tparameters: definition.parameters,\n\t\t\tsourceInfo,\n\t\t}));\n\t}\n\n\tgetToolDefinition(name: string): ToolDefinition | undefined {\n\t\treturn this._toolDefinitions.get(name)?.definition;\n\t}\n\n\tsetActiveToolsByName(toolNames: string[]): void {\n\t\tconst tools: AgentTool[] = [];\n\t\tconst validToolNames: string[] = [];\n\t\tconst seenToolNames = new Set<string>();\n\t\tfor (const name of toolNames) {\n\t\t\tif (seenToolNames.has(name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst tool = this._toolRegistry.get(name);\n\t\t\tif (tool) {\n\t\t\t\tseenToolNames.add(name);\n\t\t\t\ttools.push(tool);\n\t\t\t\tvalidToolNames.push(name);\n\t\t\t}\n\t\t}\n\t\tthis.agent.state.tools = tools;\n\n\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(validToolNames);\n\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t}\n\n\tget isCompacting(): boolean {\n\t\treturn (\n\t\t\tthis._autoCompactionAbortController !== undefined ||\n\t\t\tthis._compactionAbortController !== undefined ||\n\t\t\tthis._branchSummaryAbortController !== undefined\n\t\t);\n\t}\n\n\t/** Active working context; use captured history readers for the complete source. */\n\tget messages(): AgentMessage[] {\n\t\treturn this.agent.state.messages;\n\t}\n\n\tasync buildSessionContext(): Promise<SessionContext> {\n\t\tif (!this.sessionManager.isPersisted()) {\n\t\t\tconst context = this.sessionManager.buildSessionContext();\n\t\t\tfor (const message of context.messages) this._applyLateIpythonSentAgentMessages(message);\n\t\t\tthis._mergeUnpersistedOutcomes(context.messages);\n\t\t\treturn context;\n\t\t}\n\t\tconst limits = this.settingsManager.getCanonicalContextLimits();\n\t\tconst outcomes = structuredClone(this._unpersistedOutcomes);\n\t\tconst { context } = await readSessionBootstrap(this.sessionManager, limits, {\n\t\t\tinitialContextMode: this._initialContextMode,\n\t\t\tpurpose: \"read\",\n\t\t});\n\t\tthis._mergeUnpersistedOutcomes(context.messages, outcomes);\n\t\tif (context.messages.length > limits.maxMessages) throw new Error(\"Canonical context message budget exceeded\");\n\t\treturn context;\n\t}\n\n\tprivate _mergeUnpersistedOutcomes(\n\t\tmessages: AgentMessage[],\n\t\toutcomes: readonly CustomMessage[] = this._unpersistedOutcomes,\n\t): void {\n\t\tfor (const outcome of outcomes) {\n\t\t\tlet insertAt = messages.length;\n\t\t\twhile (insertAt > 0 && messages[insertAt - 1]!.timestamp > outcome.timestamp) {\n\t\t\t\tinsertAt -= 1;\n\t\t\t}\n\t\t\tmessages.splice(insertAt, 0, outcome);\n\t\t}\n\t}\n\n\tget steeringMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.agent.steeringMode;\n\t}\n\n\tget followUpMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.agent.followUpMode;\n\t}\n\n\tget sessionFile(): string | undefined {\n\t\treturn this.sessionManager.getSessionFile();\n\t}\n\n\tget sessionId(): string {\n\t\treturn this.sessionManager.getSessionId();\n\t}\n\n\tget rlmDepth(): number {\n\t\treturn this._rlmDepth;\n\t}\n\n\tget semanticEdges(): SemanticEdgeRecorder {\n\t\treturn this._semanticEdges;\n\t}\n\n\tget rlmMaxDepth(): number {\n\t\treturn this._rlmMaxDepth;\n\t}\n\n\tget sessionName(): string | undefined {\n\t\treturn this.sessionManager.getSessionName();\n\t}\n\n\tget goalState(): GoalState {\n\t\treturn { ...this._goalWithCurrentWallClock() };\n\t}\n\n\tgetAutonomousStatus(): AgentAutonomousStatus {\n\t\treturn autonomousStatus(this._autonomousState);\n\t}\n\n\trecordHostAutonomousContinuation(): void {\n\t\taddAutonomousContinuation(this._autonomousState);\n\t}\n\n\tasync refreshAutonomousGates(): Promise<void> {\n\t\tawait refreshAutonomousQualityGates(this._autonomousState, {\n\t\t\tcwd: this._cwd,\n\t\t});\n\t}\n\n\tprivate async _runWithAutonomousContinuationSuppressed<T>(fn: () => Promise<T>): Promise<T> {\n\t\tthis._autonomousContinuationSuppressionDepth++;\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} finally {\n\t\t\tthis._autonomousContinuationSuppressionDepth--;\n\t\t}\n\t}\n\n\tprivate _markAutonomousContinuationSuppressed(message: AgentMessage): void {\n\t\tthis._autonomousContinuationSuppressedMessages.add(message);\n\t}\n\n\tget scopedModels(): ReadonlyArray<{\n\t\tmodel: Model<any>;\n\t\tthinkingLevel?: ThinkingLevel;\n\t}> {\n\t\treturn this._scopedModels;\n\t}\n\n\tsetScopedModels(scopedModels: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>): void {\n\t\tthis._scopedModels = scopedModels;\n\t}\n\n\tget promptTemplates(): ReadonlyArray<PromptTemplate> {\n\t\treturn this._resourceLoader.getPrompts().prompts;\n\t}\n\n\tprivate _normalizePromptSnippet(text: string | undefined): string | undefined {\n\t\tif (!text) return undefined;\n\t\tconst oneLine = text\n\t\t\t.replace(/[\\r\\n]+/g, \" \")\n\t\t\t.replace(/\\s+/g, \" \")\n\t\t\t.trim();\n\t\treturn oneLine.length > 0 ? oneLine : undefined;\n\t}\n\n\tprivate _normalizePromptGuidelines(guidelines: string[] | undefined): string[] {\n\t\tif (!guidelines || guidelines.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst unique = new Set<string>();\n\t\tfor (const guideline of guidelines) {\n\t\t\tconst normalized = guideline.trim();\n\t\t\tif (normalized.length > 0) {\n\t\t\t\tunique.add(normalized);\n\t\t\t}\n\t\t}\n\t\treturn Array.from(unique);\n\t}\n\n\tprivate _rebuildSystemPrompt(\n\t\ttoolNames: string[],\n\t\tnativeEpoch = this.sessionManager.isPersisted() && this._contextEpochsEnabled,\n\t\toperation = this._baseSystemPromptOptions?.errorFixSelection?.operation,\n\t): string {\n\t\tconst validToolNames = toolNames.filter((name) => this._toolRegistry.has(name));\n\t\tconst toolSnippets: Record<string, string> = {};\n\t\tconst promptGuidelines: string[] = [];\n\t\tfor (const name of validToolNames) {\n\t\t\tconst snippet = this._toolPromptSnippets.get(name);\n\t\t\tif (snippet) {\n\t\t\t\ttoolSnippets[name] = snippet;\n\t\t\t}\n\n\t\t\tconst toolGuidelines = this._toolPromptGuidelines.get(name);\n\t\t\tif (toolGuidelines) {\n\t\t\t\tpromptGuidelines.push(...toolGuidelines);\n\t\t\t}\n\t\t}\n\n\t\tconst loaderSystemPrompt = this._resourceLoader.getSystemPrompt();\n\t\tconst loaderAppendSystemPrompt = this._resourceLoader.getAppendSystemPrompt();\n\t\tconst appendSystemPrompt =\n\t\t\tloaderAppendSystemPrompt.length > 0 ? loaderAppendSystemPrompt.join(\"\\n\\n\") : undefined;\n\t\tconst loadedSkills = this._modelVisibleSkills();\n\t\tconst loadedContextFiles = this._resourceLoader.getAgentsFiles().agentsFiles;\n\n\t\tthis._baseSystemPromptOptions = {\n\t\t\tcwd: this._cwd,\n\t\t\tskills: loadedSkills,\n\t\t\tnativeSkillSelection: nativeEpoch ? (this._nativeRecoveryEnabled() ? \"enabled\" : \"unavailable\") : undefined,\n\t\t\tcontextFiles: loadedContextFiles,\n\t\t\tcustomPrompt: loaderSystemPrompt,\n\t\t\tappendSystemPrompt,\n\t\t\tmessagesPath: this.sessionManager.getSessionFile(),\n\t\t\tselectedTools: validToolNames,\n\t\t\ttoolSnippets,\n\t\t\tpromptGuidelines,\n\t\t\tallowRecursion: this._rlmDepth < this._rlmMaxDepth,\n\t\t\trlmDepth: this._rlmDepth,\n\t\t\trlmParentAgent: this._rlmParentAgent,\n\t\t\tharnessState: this._loadMergedHarnessState(),\n\t\t\tharnessSection: \"instructions\",\n\t\t\terrorFixSelection: {\n\t\t\t\tenabled: this.settingsManager.getLearningEnabled(),\n\t\t\t\ttools: validToolNames,\n\t\t\t\toperation,\n\t\t\t\tgoal: this._goalState.objective,\n\t\t\t\tenvironment: { cwd: this._cwd, platform: process.platform },\n\t\t\t\tcountTokens: conservativeTextTokenCost,\n\t\t\t},\n\t\t\tgenericMcpServers: this._mcpManager?.getEnabledPersistentGenericServers(),\n\t\t};\n\t\treturn buildSystemPrompt(this._baseSystemPromptOptions);\n\t}\n\n\t/** Read only snapshot candidates in the active literal tail and accepted epoch recipes. */\n\tprivate async _readHarnessSnapshot(view: SessionHistoryReadView): Promise<string | undefined> {\n\t\tconst { maxMessages, maxSourceBytes } = this.settingsManager.getCanonicalContextLimits();\n\t\tconst refs: ContextRef[] = [];\n\t\tlet summary: ContextRef | null = null;\n\t\tlet cursor: ContextManifestCursor | undefined;\n\t\tlet count = 0;\n\t\tlet bytes = 0;\n\t\tdo {\n\t\t\tconst page = await view.contextManifest({ cursor, limit: 128 });\n\t\t\tif (page.selection !== \"known\") throw new Error(`Harness snapshot context selection is ${page.selection}`);\n\t\t\tsummary = page.summaryRef;\n\t\t\tcount += page.refs.length;\n\t\t\tif (count + (summary ? 1 : 0) > maxMessages)\n\t\t\t\tthrow new Error(\"Harness snapshot context message budget exceeded\");\n\t\t\trefs.push(...page.refs.filter((ref) => ref.kind === \"custom_message\"));\n\t\t\tcursor = page.nextCursor ?? undefined;\n\t\t} while (cursor);\n\t\tconst read = async (ref: ContextRef, source = view): Promise<SessionEntry> => {\n\t\t\tbytes += ref.locator.length;\n\t\t\tif (bytes > maxSourceBytes) throw new Error(\"Harness snapshot source byte budget exceeded\");\n\t\t\tconst metadata = await source.get(ref.entryId);\n\t\t\tif (!metadata || metadata.revision !== ref.revision) throw new Error(\"Harness snapshot source is unavailable\");\n\t\t\tconst hydrated = await hydrateCapturedHistoryEntry(metadata, ref.locator.length, source.readPayload);\n\t\t\tif (!hydrated) throw new Error(\"Harness snapshot payload is unavailable\");\n\t\t\treturn hydrated.entry;\n\t\t};\n\t\tconst content = (entry: SessionEntry) =>\n\t\t\tentry.type === \"custom_message\" &&\n\t\t\tentry.customType === HARNESS_SNAPSHOT_CUSTOM_TYPE &&\n\t\t\ttypeof entry.content === \"string\"\n\t\t\t\t? entry.content\n\t\t\t\t: undefined;\n\t\tfor (const ref of refs.reverse()) {\n\t\t\tconst snapshot = content(await read(ref));\n\t\t\tif (snapshot !== undefined) return snapshot;\n\t\t}\n\t\tif (!summary) return;\n\t\tconst entry = await read(summary);\n\t\tif (\n\t\t\tentry.type !== \"compaction\" ||\n\t\t\tsummary.qualification !== \"native-context-epoch\" ||\n\t\t\tsummary.retention === \"retained-import\"\n\t\t)\n\t\t\treturn;\n\t\tconst checkpoint = readContextEpoch(entry.details, maxSourceBytes);\n\t\tif (!checkpoint) return;\n\t\tif (count + checkpoint.views.length > maxMessages)\n\t\t\tthrow new Error(\"Harness snapshot context message budget exceeded\");\n\t\tfor (const pinned of [...checkpoint.views].reverse()) {\n\t\t\tif (pinned.ref.kind !== \"custom_message\") continue;\n\t\t\tif (!view.atSnapshot) throw new Error(\"Harness snapshot epoch requires its captured source\");\n\t\t\tconst snapshot = content(await read(pinned.ref, await view.atSnapshot(pinned.source)));\n\t\t\tif (snapshot !== undefined) return snapshot;\n\t\t}\n\t}\n\n\t/** Persist mutable advice before the request owner captures its source and epoch ACK boundary. */\n\tprivate async _appendHarnessSnapshotIfChanged(): Promise<() => void> {\n\t\tconst manager = this.sessionManager;\n\t\tlet leafId = manager.getLeafId();\n\t\tconst sourceIsCurrent = manager.captureCompactionSourceOwner();\n\t\tconst assertCurrent = () => {\n\t\t\tif (this._disposed || this.sessionManager !== manager || !sourceIsCurrent() || manager.getLeafId() !== leafId)\n\t\t\t\tthrow new Error(\"Harness snapshot source changed before request ownership\");\n\t\t};\n\t\tlet previous: CustomMessage[\"content\"] | undefined;\n\t\tif (manager.isPersisted()) {\n\t\t\tprevious = await manager.readBranchHistory((view) => this._readHarnessSnapshot(view.branchContext));\n\t\t} else {\n\t\t\tconst snapshot = manager\n\t\t\t\t.buildSessionContext()\n\t\t\t\t.messages.reverse()\n\t\t\t\t.find((message) => message.role === \"custom\" && message.customType === HARNESS_SNAPSHOT_CUSTOM_TYPE);\n\t\t\tif (snapshot?.role === \"custom\") previous = snapshot.content;\n\t\t}\n\t\tassertCurrent();\n\t\tconst options = this._baseSystemPromptOptions;\n\t\tconst tools = options.selectedTools ?? [];\n\t\tconst hasIpython = tools.includes(\"ipython\");\n\t\tconst content = formatHarnessStateForPrompt(this._loadMergedHarnessState(), {\n\t\t\tsection: \"entries\",\n\t\t\tincludeIpythonExamples: hasIpython,\n\t\t\tincludeShellExamples: tools.includes(\"bash\"),\n\t\t\terrorFixSelection: options.errorFixSelection\n\t\t\t\t? { ...options.errorFixSelection, enabled: this.settingsManager.getLearningEnabled() }\n\t\t\t\t: undefined,\n\t\t});\n\t\tif (previous === content) return assertCurrent;\n\t\tconst entryId = await manager.appendCustomMessageEntryWithRollback(HARNESS_SNAPSHOT_CUSTOM_TYPE, content, false);\n\t\tif (this._disposed || this.sessionManager !== manager || !sourceIsCurrent() || manager.getLeafId() !== entryId)\n\t\t\tthrow new Error(\"Harness snapshot source changed during append\");\n\t\tif (!manager.isPersisted())\n\t\t\tthis.agent.state.messages.push({\n\t\t\t\trole: \"custom\",\n\t\t\t\tcustomType: HARNESS_SNAPSHOT_CUSTOM_TYPE,\n\t\t\t\tcontent,\n\t\t\t\tdisplay: false,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t});\n\t\tleafId = entryId;\n\t\treturn assertCurrent;\n\t}\n\n\tprivate _refreshExtensionSystemPrompt(extensionPrompt: string, baseSnapshot: string): string {\n\t\tif (this._baseSystemPrompt === baseSnapshot) {\n\t\t\treturn extensionPrompt;\n\t\t}\n\t\tif (!extensionPrompt.includes(baseSnapshot)) {\n\t\t\treturn extensionPrompt;\n\t\t}\n\t\treturn extensionPrompt.replace(baseSnapshot, () => this._baseSystemPrompt);\n\t}\n\n\tprivate _finishSubmissionNormalization(\n\t\ttext: string,\n\t\timages: ImageContent[] | undefined,\n\t\tpolicy: SubmissionNormalizationPolicy,\n\t\tskillOwner?: NativeSkillSelectionOwner,\n\t): NormalizedSubmission | Promise<NormalizedSubmission> {\n\t\tconst finish = (expanded: string | SkillCommandExpansion): NormalizedSubmission => {\n\t\t\tconst value = typeof expanded === \"string\" ? { text: expanded } : expanded;\n\t\t\treturn {\n\t\t\t\t...value,\n\t\t\t\tkind: \"prompt\",\n\t\t\t\timages,\n\t\t\t\ttext: policy.expandPromptTemplates\n\t\t\t\t\t? expandPromptTemplate(value.text, [...this.promptTemplates])\n\t\t\t\t\t: value.text,\n\t\t\t};\n\t\t};\n\t\tconst expanded = policy.expandSkills ? this._expandSkillCommand(text, skillOwner) : text;\n\t\treturn expanded instanceof Promise ? expanded.then(finish) : finish(expanded);\n\t}\n\n\tprivate _normalizeSubmission(\n\t\ttext: string,\n\t\timages: ImageContent[] | undefined,\n\t\tpolicy: SubmissionNormalizationPolicy,\n\t): NormalizedSubmission | Promise<NormalizedSubmission> {\n\t\tif (policy.parseSessionCommands) {\n\t\t\tconst command = parseSessionSlashCommand(text);\n\t\t\tif (command) return { kind: \"sessionCommand\", text, images, command };\n\t\t}\n\n\t\tif (text.startsWith(\"/\")) {\n\t\t\tif (policy.extensionCommands === \"execute\") {\n\t\t\t\tconst completion = this._executeExtensionCommand(text);\n\t\t\t\tif (completion) return { kind: \"extensionCommand\", completion };\n\t\t\t} else if (policy.extensionCommands === \"reject\") {\n\t\t\t\tthis._throwIfExtensionCommand(text);\n\t\t\t}\n\t\t}\n\n\t\tconst skillOwner = policy.expandSkills ? this._captureSkillSelectionOwner() : undefined;\n\t\tif (policy.inputSource !== undefined && this._extensionRunner.hasHandlers(\"input\")) {\n\t\t\treturn this._extensionRunner.emitInput(text, images, policy.inputSource).then((result) => {\n\t\t\t\tif (result.action === \"handled\") return { kind: \"handled\" };\n\t\t\t\tif (result.action === \"transform\") {\n\t\t\t\t\treturn this._finishSubmissionNormalization(result.text, result.images ?? images, policy, skillOwner);\n\t\t\t\t}\n\t\t\t\treturn this._finishSubmissionNormalization(text, images, policy, skillOwner);\n\t\t\t});\n\t\t}\n\n\t\treturn this._finishSubmissionNormalization(text, images, policy, skillOwner);\n\t}\n\n\tprivate async _runPreTurnCompaction(): Promise<void> {\n\t\tconst lastAssistant = this._findLastAssistantMessage();\n\t\tif (lastAssistant) await this._checkCompaction(lastAssistant, false, false, undefined, true);\n\t}\n\n\tprivate async _prepareForCommit<TPrepared, TCommitted>(\n\t\tpolicy: CommitPreparationPolicy,\n\t\tsteps: CommitPreparationSteps<TPrepared, TCommitted>,\n\t): Promise<TCommitted | undefined> {\n\t\tif (\n\t\t\tpolicy.initialRefineBarrier === \"always\" ||\n\t\t\t(policy.initialRefineBarrier === \"ifInFlight\" && this._refineInFlight)\n\t\t) {\n\t\t\tawait this._waitForRefineIdle();\n\t\t}\n\t\tif (policy.flushPendingBashBeforeValidation) await this._flushPendingBashMessages();\n\t\tif (policy.validateModelAndAuth) await this._validateCanStartAgentRun();\n\t\tsteps.afterValidation?.();\n\t\tif (!policy.flushPendingBashBeforeValidation) await this._flushPendingBashMessages();\n\n\t\tif (policy.preTurnCompaction === \"beforeModelSelection\") await this._runPreTurnCompaction();\n\t\tif (policy.awaitPendingModelSelection) {\n\t\t\tconst pendingModelSelectEmit = this._pendingModelSelectEmit();\n\t\t\tif (pendingModelSelectEmit) await pendingModelSelectEmit;\n\t\t}\n\t\tif (policy.preTurnCompaction === \"afterModelSelection\") await this._runPreTurnCompaction();\n\n\t\tconst prepared = await steps.prepare();\n\t\tif (steps.shouldCommit && !steps.shouldCommit(prepared)) return undefined;\n\t\tsteps.beforeFinalRefineBarrier?.(prepared);\n\t\tlet passedFinalRefineBarrier = false;\n\t\tif (\n\t\t\tpolicy.finalRefineBarrier === \"always\" ||\n\t\t\t(policy.finalRefineBarrier === \"ifInFlight\" && this._refineInFlight)\n\t\t) {\n\t\t\tawait this._waitForRefineIdle();\n\t\t\tpassedFinalRefineBarrier = true;\n\t\t}\n\t\treturn steps.commit(prepared, passedFinalRefineBarrier);\n\t}\n\n\tprivate _applyPreparedSystemPrompt(\n\t\tpreparation: PreparedPromptPreparation | undefined,\n\t\tpreserveEmptyExtensionPrompt: boolean,\n\t): void {\n\t\tconst extensionPrompt = preparation?.result?.systemPrompt;\n\t\tconst hasExtensionPrompt = preserveEmptyExtensionPrompt\n\t\t\t? extensionPrompt !== undefined\n\t\t\t: Boolean(extensionPrompt);\n\t\tthis.agent.state.systemPrompt =\n\t\t\thasExtensionPrompt && extensionPrompt !== undefined && preparation !== undefined\n\t\t\t\t? this._refreshExtensionSystemPrompt(extensionPrompt, preparation.basePromptSnapshot)\n\t\t\t\t: this._baseSystemPrompt;\n\t}\n\n\tprivate _canStartSessionActionImmediately(): boolean {\n\t\treturn (\n\t\t\t!this.isStreaming &&\n\t\t\t!this.isCompacting &&\n\t\t\t!this.isRetrying &&\n\t\t\t!this.isBashRunning &&\n\t\t\t!this._sessionInputPumpSuspended &&\n\t\t\tthis._queuedWorkPauses.size === 0 &&\n\t\t\t!this._disposed &&\n\t\t\t!this._disposing\n\t\t);\n\t}\n\n\t/**\n\t * Send a prompt to the agent.\n\t * - Handles extension commands (registered via pi.registerCommand) immediately, even during streaming\n\t * - Expands file-based prompt templates by default\n\t * - During streaming, queues via steer() or followUp() based on streamingBehavior option\n\t * - Validates model and API key before sending (when not streaming)\n\t * @throws Error if streaming and no streamingBehavior specified\n\t * @throws Error if no model selected or no API key available (when not streaming)\n\t */\n\tasync prompt(text: string, options?: PromptOptions): Promise<void> {\n\t\treturn this._prompt(text, options);\n\t}\n\n\tasync promptUntilAccepted(text: string, options?: PromptOptions): Promise<void> {\n\t\treturn this._prompt(text, { ...options, returnAfterAccepted: true });\n\t}\n\n\tasync promptAndWait(text: string, options?: PromptOptions): Promise<void> {\n\t\tconst agentMessageId = options?.agentMessageId ?? `prompt-wait:${randomUUID()}`;\n\t\tif (this._agentMessageOutcomes.get(agentMessageId)?.completion) {\n\t\t\tthrow new Error(`Prompt completion id is already in use: ${agentMessageId}`);\n\t\t}\n\t\tconst outcome = this._agentMessageOutcome(agentMessageId);\n\t\toutcome.completion = createAgentMessageDeferred();\n\t\tconst completion = outcome.completion.promise;\n\t\tconst signal = options?.signal;\n\t\tlet cancelQueuedPrompt: (() => void) | undefined;\n\t\ttry {\n\t\t\tawait this.promptUntilAccepted(text, { ...options, agentMessageId });\n\t\t\tif (signal) {\n\t\t\t\tcancelQueuedPrompt = () => {\n\t\t\t\t\tconst error = new Error(\"Prompt was cancelled before it started.\");\n\t\t\t\t\tconst cancelled = this._cancelSessionActions(\n\t\t\t\t\t\t(action) => action.agentMessageId === agentMessageId && action.payload.kind === \"turn\",\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t\tif (cancelled.length > 0) {\n\t\t\t\t\t\tthis._settleAgentMessage(agentMessageId, \"completion\", error);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", cancelQueuedPrompt, { once: true });\n\t\t\t\tif (signal.aborted) cancelQueuedPrompt();\n\t\t\t}\n\t\t\tawait completion;\n\t\t} catch (error) {\n\t\t\tthis._settleAgentMessage(agentMessageId, \"completion\", this._asError(error));\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tif (signal && cancelQueuedPrompt) {\n\t\t\t\tsignal.removeEventListener(\"abort\", cancelQueuedPrompt);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync acceptAgentMessagePrompt(text: string, options?: PromptOptions): Promise<void> {\n\t\tconst customMessage =\n\t\t\toptions?.customMessage && isAgentSessionMessage(options.customMessage) ? options.customMessage : undefined;\n\t\tconst clearEpoch = this._agentMessageClearEpoch;\n\t\tconst admissionCommitted = () => {\n\t\t\toptions?.admissionCommitted?.();\n\t\t\tif (clearEpoch !== this._agentMessageClearEpoch) {\n\t\t\t\tthrow new Error(\"Agent message was cleared before admission\");\n\t\t\t}\n\t\t};\n\t\tif (\n\t\t\tthis._sessionInputPumpSuspended &&\n\t\t\tthis._isBusyForSessionInput(\"preflight\") &&\n\t\t\toptions?.queueIfBusy === true &&\n\t\t\toptions.streamingBehavior\n\t\t) {\n\t\t\tadmissionCommitted();\n\t\t\tconst queued = await this.queueAgentMessagePrompt(text, options.streamingBehavior, customMessage);\n\t\t\toptions.preflightResult?.(queued, queued);\n\t\t\treturn;\n\t\t}\n\t\tawait this._prompt(text, {\n\t\t\t...options,\n\t\t\tresumeIfIdle: false,\n\t\t\texpandPromptTemplates: false,\n\t\t\tskipInputHandlers: true,\n\t\t\tskipPrePromptWork: true,\n\t\t\treturnAfterAccepted: true,\n\t\t\tagentMessageId: options?.agentMessageId ?? customMessage?.details.id ?? parseAgentSessionMessagePromptId(text),\n\t\t\tcustomMessage,\n\t\t\tadmissionCommitted,\n\t\t});\n\t\tif (customMessage?.details.fromRelationship === \"parent\") this._repliedToParentSinceTask = false;\n\t}\n\n\tasync queueAgentMessagePrompt(\n\t\ttext: string,\n\t\tstreamingBehavior: \"steer\" | \"followUp\",\n\t\tcustomMessage?: AgentSessionMessage,\n\t): Promise<boolean> {\n\t\tconst agentMessageId = customMessage?.details.id ?? parseAgentSessionMessagePromptId(text);\n\t\tif (streamingBehavior === \"steer\") {\n\t\t\tawait this._queuePreparedPrompt(\"steer\", text, undefined, {\n\t\t\t\tagentMessageId,\n\t\t\t\tmessage: customMessage,\n\t\t\t});\n\t\t\tif (customMessage?.details.fromRelationship === \"parent\") this._repliedToParentSinceTask = false;\n\t\t\treturn true;\n\t\t}\n\t\tconst queued = await this._queuePreparedPrompt(\"followUp\", text, undefined, {\n\t\t\tagentMessageId,\n\t\t\tmessage: customMessage,\n\t\t});\n\t\tif (queued && customMessage?.details.fromRelationship === \"parent\") this._repliedToParentSinceTask = false;\n\t\treturn queued;\n\t}\n\n\tasync promptHeartbeat(job: AgentCronJob, options?: PromptOptions): Promise<void> {\n\t\tconst message = createHeartbeatPromptMessage(job);\n\t\tawait this._promptInjectedMessage(job.prompt, message, {\n\t\t\t...options,\n\t\t\tfollowUpQueueKey: options?.followUpQueueKey ?? `heartbeat:${job.id}`,\n\t\t\tresumeIfIdle: true,\n\t\t});\n\t}\n\n\tprivate _isRlmTerminalNotice(message: CustomMessage): boolean {\n\t\treturn (\n\t\t\tmessage.customType === RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE ||\n\t\t\tmessage.customType === RLM_CHILD_FAILURE_CUSTOM_TYPE\n\t\t);\n\t}\n\n\tprivate _assertRlmTerminalNotice(message: CustomMessage): void {\n\t\tif (!this._isRlmTerminalNotice(message)) {\n\t\t\tthrow new Error(\"Deferred terminal admission only accepts RLM child terminal notices.\");\n\t\t}\n\t}\n\n\tprivate _isRlmTerminalNoticeAction(action: QueuedSessionAction): boolean {\n\t\tif (action.payload.kind !== \"turn\") return false;\n\t\tconst message = primaryDeliveryRecord(action).message;\n\t\treturn message.role === \"custom\" && this._isRlmTerminalNotice(message);\n\t}\n\n\tprivate _hasDeferredRlmTerminalNotices(): boolean {\n\t\treturn this._pendingNextTurnMessages.some((message) => this._isRlmTerminalNotice(message));\n\t}\n\n\tprivate _enqueueRlmTerminalNoticeAction(message: CustomMessage): void {\n\t\tthis._assertRlmTerminalNotice(message);\n\t\tconst action = this._createPreparedTurnAction(\"followUp\", message.content as string, undefined, {\n\t\t\tmessage,\n\t\t\tsuppressAutonomousContinuation: true,\n\t\t\tresumeIfIdle: false,\n\t\t\tsource: \"internal\",\n\t\t\texecutionPolicy: this._turnExecutionPolicy(\"injected\"),\n\t\t\tqueueVisible: false,\n\t\t});\n\t\tthis._durableRlmTerminalNoticeActionIds.add(action.id);\n\t\ttry {\n\t\t\tconst result = this._admitSessionInput(action, { wake: false });\n\t\t\tif (!result.accepted) throw new Error(\"RLM child terminal notice was not admitted.\");\n\t\t} catch (error) {\n\t\t\tthis._durableRlmTerminalNoticeActionIds.delete(action.id);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate _flushDeferredRlmTerminalNotices(): void {\n\t\tif (\n\t\t\tthis._sessionInputAdmissionPauses.size > 0 ||\n\t\t\tthis._sessionInputPumpSuspended ||\n\t\t\tthis._queuedWorkPauses.size > 0 ||\n\t\t\tthis._disposed ||\n\t\t\tthis._disposing\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\twhile (true) {\n\t\t\tconst index = this._pendingNextTurnMessages.findIndex((message) => this._isRlmTerminalNotice(message));\n\t\t\tif (index < 0) break;\n\t\t\tconst message = this._pendingNextTurnMessages[index];\n\t\t\ttry {\n\t\t\t\tthis._enqueueRlmTerminalNoticeAction(message);\n\t\t\t} catch {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._pendingNextTurnMessages.splice(index, 1);\n\t\t}\n\t\tthis._scheduleSessionInputPump();\n\t}\n\n\tprivate async _acquireRlmTerminalNoticeRetentionFence(): Promise<{ owner: symbol; release(): void } | undefined> {\n\t\tconst disposeSignal = this._sessionActionCommitDisposeAbortController.signal;\n\t\twhile (!this._disposed && !this._disposing && !disposeSignal.aborted) {\n\t\t\tif (this._queuedWorkPauses.size > 0) {\n\t\t\t\tlet wake = () => {};\n\t\t\t\tconst pauseReleased = new Promise<void>((resolve) => {\n\t\t\t\t\twake = resolve;\n\t\t\t\t\tthis._sessionInputCheckpointWaiters.add(resolve);\n\t\t\t\t});\n\t\t\t\ttry {\n\t\t\t\t\tawait waitForPromiseOrAbort(pauseReleased, disposeSignal, \"Terminal notice retention cancelled\");\n\t\t\t\t} catch {\n\t\t\t\t\treturn undefined;\n\t\t\t\t} finally {\n\t\t\t\t\tthis._sessionInputCheckpointWaiters.delete(wake);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet fence: { owner: symbol; release(): void };\n\t\t\ttry {\n\t\t\t\tfence = await this._acquireSessionActionCommitFence(disposeSignal);\n\t\t\t} catch {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (this._queuedWorkPauses.size === 0 && !this._disposed && !this._disposing) return fence;\n\t\t\tfence.release();\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate async _deferRlmTerminalNotice(message: CustomMessage): Promise<void> {\n\t\tthis._assertRlmTerminalNotice(message);\n\t\tconst fence = await this._acquireRlmTerminalNoticeRetentionFence();\n\t\tif (!fence) return;\n\t\ttry {\n\t\t\tif (this._disposed || this._disposing) return;\n\t\t\tthis._pendingNextTurnMessages.push(cloneCustomMessage(message));\n\t\t\tthis._flushDeferredRlmTerminalNotices();\n\t\t} finally {\n\t\t\tfence.release();\n\t\t}\n\t}\n\n\tprivate _demoteRlmTerminalNoticeActions(): void {\n\t\tconst actions = this._actionStore\n\t\t\t.clearableActions()\n\t\t\t.filter((action) => this._durableRlmTerminalNoticeActionIds.has(action.id));\n\t\tif (actions.length === 0) return;\n\t\tfor (const action of actions) {\n\t\t\tif (!this._isRlmTerminalNoticeAction(action)) continue;\n\t\t\tconst message = primaryDeliveryRecord(action).message;\n\t\t\tif (message.role === \"custom\") this._pendingNextTurnMessages.push(cloneCustomMessage(message));\n\t\t}\n\t\tconst ids = new Set(actions.map((action) => action.id));\n\t\tthis._cancelSessionActions(\n\t\t\t(action) => ids.has(action.id),\n\t\t\tnew Error(\"RLM child terminal notice deferred across session input suspension.\"),\n\t\t\tactions,\n\t\t);\n\t\tfor (const id of ids) this._durableRlmTerminalNoticeActionIds.delete(id);\n\t}\n\n\tprivate async _promptInjectedMessage(\n\t\ttext: string,\n\t\tmessage: CustomMessage,\n\t\toptions?: InternalPromptOptions & { executionPolicy?: TurnExecutionPolicy },\n\t): Promise<void> {\n\t\tif (!this.isStreaming && options?.resumeIfIdle) this._resumeSessionInputAdmission();\n\t\tconst admissionEpoch = this._sessionInputPumpEpoch;\n\t\tconst admissionFence = await this._acquireDirectTurnAdmissionFence(options?.signal).catch((error: unknown) => {\n\t\t\tthrowIfPromptAdmissionCancelled(options?.signal);\n\t\t\tthrow error;\n\t\t});\n\t\tconst reportPreflight = oncePreflight(options?.preflightResult);\n\t\ttry {\n\t\t\tthrowIfPromptAdmissionCancelled(options?.signal);\n\t\t\tif (admissionEpoch !== this._sessionInputPumpEpoch) {\n\t\t\t\tthrow new Error(\"Injected session input was invalidated before admission\");\n\t\t\t}\n\t\t\toptions?.admissionCommitted?.();\n\t\t\tconst queueForStreaming = this.isStreaming;\n\t\t\tconst queueForBusy = options?.queueIfBusy === true && this._isBusyForSessionInput(\"preflight\");\n\t\t\tconst visibleQueued = queueForStreaming || queueForBusy;\n\t\t\tif (visibleQueued && !options?.streamingBehavior) {\n\t\t\t\tconst stateDescription = queueForStreaming ? \"Agent is already processing\" : \"Agent has queued work\";\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${stateDescription}. Specify streamingBehavior ('steer' or 'followUp') to queue the message.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst schedule = options?.streamingBehavior ?? \"followUp\";\n\t\t\tconst prefixMessages = visibleQueued ? this._takePendingNextTurnMessages() : undefined;\n\t\t\tconst action = this._createPreparedTurnAction(schedule, text, undefined, {\n\t\t\t\tmessage,\n\t\t\t\tprefixMessages,\n\t\t\t\tqueueKey: options?.followUpQueueKey,\n\t\t\t\tpreviewLabel: injectedMessagePreviewLabel(message),\n\t\t\t\tsuppressAutonomousContinuation: options?.suppressAutonomousContinuation,\n\t\t\t\tresumeIfIdle:\n\t\t\t\t\t!visibleQueued ||\n\t\t\t\t\toptions?.resumeIfIdle ||\n\t\t\t\t\t(options?.queueIfBusy === true && canSelectSessionAction(this._runtimeActivity())),\n\t\t\t\tsource: options?.source ?? \"internal\",\n\t\t\t\texecutionPolicy:\n\t\t\t\t\toptions?.executionPolicy ??\n\t\t\t\t\t(visibleQueued ? this._turnExecutionPolicy(\"queued\") : this._turnExecutionPolicy(\"injected\")),\n\t\t\t\tqueueVisible: visibleQueued,\n\t\t\t});\n\t\t\tconst result = this._admitSessionInput(action, {\n\t\t\t\timmediatelyEligible: !visibleQueued,\n\t\t\t});\n\t\t\tadmissionFence.release();\n\t\t\tif (!result.accepted || !result.ticket) {\n\t\t\t\tif (prefixMessages) this._pendingNextTurnMessages.unshift(...prefixMessages);\n\t\t\t\treportPreflight(false, false);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (result.disposition === \"queued\") {\n\t\t\t\treportPreflight(true, true);\n\t\t\t} else {\n\t\t\t\tvoid result.ticket.delivered.then(\n\t\t\t\t\t() => reportPreflight(true),\n\t\t\t\t\t() => reportPreflight(false),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (options?.returnAfterAccepted) {\n\t\t\t\tif (result.disposition === \"starts_when_admitted\") await result.ticket.delivered;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (visibleQueued) return;\n\t\t\tawait result.ticket.completed;\n\t\t} catch (error) {\n\t\t\treportPreflight(false);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tadmissionFence.release();\n\t\t}\n\t}\n\n\tprivate async _prompt(text: string, options?: InternalPromptOptions): Promise<void> {\n\t\tconst submitted = captureSubmittedInput(text, options);\n\t\tconst isInternalPrompt = options?.internalPrompt === true;\n\t\tconst acceptedAgentMessage = options?.skipPrePromptWork === true && options.returnAfterAccepted === true;\n\t\tconst inputSource = isInternalPrompt ? \"internal\" : (options?.source ?? \"interactive\");\n\t\tconst resumeSuspendedInput = options?.resumeIfIdle !== false;\n\t\tif (!this.isStreaming) {\n\t\t\tif (resumeSuspendedInput) this._resumeSessionInputAdmission();\n\t\t\tthis._assertSessionActionAdmissionAvailable();\n\t\t}\n\t\tconst admissionEpoch = this._sessionInputPumpEpoch;\n\t\tconst commitFence = this.isStreaming\n\t\t\t? undefined\n\t\t\t: await this._acquireDirectTurnAdmissionFence(options?.signal).catch((error: unknown) => {\n\t\t\t\t\tthrowIfPromptAdmissionCancelled(options?.signal);\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\t\tconst reportPreflight = oncePreflight(options?.preflightResult);\n\t\tconst run = async () => {\n\t\t\ttry {\n\t\t\t\tthrowIfPromptAdmissionCancelled(options?.signal);\n\t\t\t\tif (!resumeSuspendedInput && admissionEpoch !== this._sessionInputPumpEpoch) {\n\t\t\t\t\tthrow new Error(\"Session input was invalidated before admission\");\n\t\t\t\t}\n\t\t\t\toptions?.admissionCommitted?.();\n\t\t\t\tconst expandPromptTemplates = isInternalPrompt ? false : (options?.expandPromptTemplates ?? true);\n\t\t\t\tconst normalizationResult = this._normalizeSubmission(text, options?.images, {\n\t\t\t\t\tparseSessionCommands: !isInternalPrompt && !options?.skipPrePromptWork,\n\t\t\t\t\textensionCommands: expandPromptTemplates ? \"execute\" : \"ignore\",\n\t\t\t\t\tinputSource:\n\t\t\t\t\t\t!isInternalPrompt && !options?.skipInputHandlers && inputSource !== \"internal\"\n\t\t\t\t\t\t\t? inputSource\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\texpandSkills: expandPromptTemplates,\n\t\t\t\t\texpandPromptTemplates,\n\t\t\t\t});\n\t\t\t\tconst normalized = normalizationResult instanceof Promise ? await normalizationResult : normalizationResult;\n\t\t\t\t// Async input handlers ran between the admission check above and\n\t\t\t\t// admission itself; re-check so content invalidated during that\n\t\t\t\t// await (e.g. a cron job cancelled or updated) is not admitted.\n\t\t\t\tif (normalizationResult instanceof Promise) options?.admissionCommitted?.();\n\t\t\t\tif (normalized.kind === \"extensionCommand\") {\n\t\t\t\t\tcommitFence?.release();\n\t\t\t\t\treportPreflight(true);\n\t\t\t\t\tvoid normalized.completion.then(\n\t\t\t\t\t\t() => this._settleAgentMessage(options?.agentMessageId, \"completion\"),\n\t\t\t\t\t\t(error) => this._settleAgentMessage(options?.agentMessageId, \"completion\", error),\n\t\t\t\t\t);\n\t\t\t\t\tvoid normalized.completion.catch(() => undefined);\n\t\t\t\t\tif (!options?.returnAfterAccepted) await normalized.completion.catch(() => undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (normalized.kind === \"handled\") {\n\t\t\t\t\tcommitFence?.release();\n\t\t\t\t\treportPreflight(true);\n\t\t\t\t\tthis._settleAgentMessage(options?.agentMessageId, \"completion\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst pendingOwnedWork = this._actionStore.unfinishedActions().length > 0;\n\t\t\t\tconst wasRuntimeBusy = this.isStreaming || this.isCompacting || this.isRetrying || this.isBashRunning;\n\t\t\t\tconst wasBusy = wasRuntimeBusy || pendingOwnedWork;\n\t\t\t\tif (normalized.kind === \"sessionCommand\") {\n\t\t\t\t\tconst schedule = options?.streamingBehavior ?? (this.isStreaming ? \"steer\" : \"followUp\");\n\t\t\t\t\tconst action = this._createSessionCommandAction(\n\t\t\t\t\t\tnormalized.text,\n\t\t\t\t\t\tnormalized.command,\n\t\t\t\t\t\tnormalized.images,\n\t\t\t\t\t\tschedule,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tagentMessageId: options?.agentMessageId,\n\t\t\t\t\t\t\tsource: inputSource,\n\t\t\t\t\t\t\tsubmitted,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tconst result = this._admitSessionInput(action, {\n\t\t\t\t\t\timmediatelyEligible: !wasBusy && this._canStartSessionActionImmediately(),\n\t\t\t\t\t});\n\t\t\t\t\tcommitFence?.release();\n\t\t\t\t\treportPreflight(result.accepted, result.disposition === \"queued\");\n\t\t\t\t\tif (!result.accepted || !result.ticket) return;\n\t\t\t\t\tif (options?.returnAfterAccepted) {\n\t\t\t\t\t\tif (result.disposition === \"starts_when_admitted\") await result.ticket.delivered;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (result.disposition === \"queued\") return;\n\t\t\t\t\tawait this.waitForSessionInputIdle();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tnormalized.assertSkillCurrent?.();\n\t\t\t\tconst queueForStreaming = this.isStreaming;\n\t\t\t\tconst queueForBusy = options?.queueIfBusy === true && this._isBusyForSessionInput(\"preflight\");\n\t\t\t\tconst visibleQueued = queueForStreaming || queueForBusy;\n\t\t\t\tif (visibleQueued && !options?.streamingBehavior) {\n\t\t\t\t\tconst stateDescription = queueForStreaming ? \"Agent is already processing\" : \"Agent has queued work\";\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`${stateDescription}. Specify streamingBehavior ('steer' or 'followUp') to queue the message.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst schedule = options?.streamingBehavior ?? \"followUp\";\n\t\t\t\tconst prefixMessages = visibleQueued ? this._takePendingNextTurnMessages() : undefined;\n\t\t\t\tconst content = options?.content\n\t\t\t\t\t? options.content.map((block) => ({ ...block }))\n\t\t\t\t\t: this._buildPromptContent(normalized.text, normalized.images);\n\t\t\t\tconst suppliedMessage = options?.customMessage;\n\t\t\t\tconst primaryMessage = suppliedMessage\n\t\t\t\t\t? visibleQueued\n\t\t\t\t\t\t? suppliedMessage\n\t\t\t\t\t\t: cloneCustomMessage(suppliedMessage)\n\t\t\t\t\t: ({\n\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\tcontent: content.map((block) => ({ ...block })),\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t} satisfies UserMessage);\n\t\t\t\tconst action = this._createPreparedTurnAction(schedule, normalized.text, normalized.images, {\n\t\t\t\t\tselectedSkillRef: normalized.selectedSkillRef,\n\t\t\t\t\tagentMessageId: options?.agentMessageId,\n\t\t\t\t\tqueueKey: options?.followUpQueueKey,\n\t\t\t\t\tcontent,\n\t\t\t\t\tmessage: primaryMessage,\n\t\t\t\t\tprefixMessages,\n\t\t\t\t\tsuppressAutonomousContinuation: options?.suppressAutonomousContinuation,\n\t\t\t\t\tresumeIfIdle:\n\t\t\t\t\t\t!visibleQueued ||\n\t\t\t\t\t\toptions?.resumeIfIdle ||\n\t\t\t\t\t\t(options?.queueIfBusy === true && canSelectSessionAction(this._runtimeActivity())),\n\t\t\t\t\tsource: inputSource,\n\t\t\t\t\tsubmitted,\n\t\t\t\t\texecutionPolicy: visibleQueued\n\t\t\t\t\t\t? this._turnExecutionPolicy(\"queued\")\n\t\t\t\t\t\t: this._turnExecutionPolicy(\"directPrompt\", {\n\t\t\t\t\t\t\t\treturnAfterAccepted: options?.returnAfterAccepted,\n\t\t\t\t\t\t\t\tskipPrePromptWork: options?.skipPrePromptWork,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\tqueueVisible: visibleQueued,\n\t\t\t\t\tacceptedAgentMessage,\n\t\t\t\t\tacceptedBeforeCompletion: options?.returnAfterAccepted === true,\n\t\t\t\t});\n\t\t\t\tif (action.suppressAutonomousContinuation) {\n\t\t\t\t\tthis._markAutonomousContinuationSuppressed(primaryDeliveryRecord(action).message);\n\t\t\t\t}\n\t\t\t\tconst result = this._admitSessionInput(action, {\n\t\t\t\t\timmediatelyEligible: !visibleQueued && this._canStartSessionActionImmediately(),\n\t\t\t\t});\n\t\t\t\tcommitFence?.release();\n\t\t\t\tif (!result.accepted || !result.ticket) {\n\t\t\t\t\tif (prefixMessages) this._pendingNextTurnMessages.unshift(...prefixMessages);\n\t\t\t\t\treportPreflight(false, false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (result.disposition === \"queued\") {\n\t\t\t\t\treportPreflight(true, true);\n\t\t\t\t} else {\n\t\t\t\t\tvoid result.ticket.delivered.then(\n\t\t\t\t\t\t() => reportPreflight(true),\n\t\t\t\t\t\t() => reportPreflight(false),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst deferralObserver =\n\t\t\t\t\tacceptedAgentMessage &&\n\t\t\t\t\toptions?.queueIfBusy === true &&\n\t\t\t\t\t!options.streamingBehavior &&\n\t\t\t\t\tresult.disposition === \"starts_when_admitted\"\n\t\t\t\t\t\t? this._observeSessionActionDeferral(action)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (acceptedAgentMessage && !queueForStreaming && !queueForBusy && !options?.streamingBehavior) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst outcome = deferralObserver\n\t\t\t\t\t\t\t? await Promise.race([\n\t\t\t\t\t\t\t\t\tresult.ticket.delivered.then(() => \"delivered\" as const),\n\t\t\t\t\t\t\t\t\tdeferralObserver.deferred.then(() => \"deferred\" as const),\n\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t: await result.ticket.delivered.then(() => \"delivered\" as const);\n\t\t\t\t\t\tif (outcome === \"deferred\" && !options?.streamingBehavior) {\n\t\t\t\t\t\t\tconst error = new Error(\n\t\t\t\t\t\t\t\t\"Agent became busy before prompt delivery. Specify streamingBehavior ('steer' or 'followUp') to queue the message.\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tthis._rejectAgentMessage(action.agentMessageId, error);\n\t\t\t\t\t\t\tthis._cancelSessionActions((candidate) => candidate === action, error);\n\t\t\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tdeferralObserver?.stop();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (options?.returnAfterAccepted) {\n\t\t\t\t\tif (result.disposition === \"starts_when_admitted\" || (acceptedAgentMessage && !visibleQueued)) {\n\t\t\t\t\t\tawait result.ticket.delivered;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (visibleQueued) return;\n\t\t\t\tawait result.ticket.completed;\n\t\t\t\tawait this.waitForSessionInputIdle();\n\t\t\t} catch (error) {\n\t\t\t\treportPreflight(false);\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\tcommitFence?.release();\n\t\t\t}\n\t\t};\n\t\treturn commitFence ? this._sessionActionCommitContext.run(commitFence.owner, run) : run();\n\t}\n\n\tprivate _executeExtensionCommand(text: string): Promise<void> | undefined {\n\t\tconst parsed = parseSlashCommand(text);\n\t\tif (!parsed) return undefined;\n\t\tconst commandName = parsed.name;\n\t\tconst args = parsed.args;\n\n\t\tconst command = this._extensionRunner.getCommand(commandName);\n\t\tif (!command) return undefined;\n\t\tconst context = this._extensionRunner.createCommandContext();\n\t\treturn Promise.resolve()\n\t\t\t.then(() => command.handler(args, context))\n\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconst commandError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\tthis._extensionRunner.emitError({\n\t\t\t\t\textensionPath: `command:${commandName}`,\n\t\t\t\t\tevent: \"command\",\n\t\t\t\t\terror: commandError.message,\n\t\t\t\t});\n\t\t\t\tthrow commandError;\n\t\t\t});\n\t}\n\n\t/**\n\t * Expand skill commands (/skill:name args) to their full content.\n\t * Returns the expanded text, or the original text if not a skill command or skill not found.\n\t * Emits errors via extension runner and rejects if the selected file cannot be read completely.\n\t */\n\tprivate _expandSkillCommand(\n\t\ttext: string,\n\t\towner?: NativeSkillSelectionOwner,\n\t): string | Promise<string | SkillCommandExpansion> {\n\t\tif (!text.startsWith(\"/skill:\")) return text;\n\t\tconst parsed = parseSlashCommand(text);\n\t\tif (!parsed?.name.startsWith(\"skill:\")) return text;\n\t\tconst skillName = parsed.name.slice(\"skill:\".length);\n\t\tconst skill = this.resourceLoader.getSkills().skills.find((item) => item.name === skillName);\n\t\tif (!skill) return text;\n\t\tconst skillPath = skill.filePath;\n\t\tconst render = (capture: SelectedSkillCapture, ref?: string): string => {\n\t\t\tconst block = selectedSkillBlock(capture, ref);\n\t\t\treturn parsed.args ? `${block}\\n\\n${parsed.args}` : block;\n\t\t};\n\t\tconst failure = (error: unknown): never => {\n\t\t\tthis._extensionRunner.emitError({\n\t\t\t\textensionPath: skillPath,\n\t\t\t\tevent: \"skill_expansion\",\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t});\n\t\t\tthrow error;\n\t\t};\n\t\ttry {\n\t\t\tif (owner)\n\t\t\t\treturn this._selectNativeSkill(skill, owner, false)\n\t\t\t\t\t.then((selected) => {\n\t\t\t\t\t\tconst assertSkillCurrent = () => this._assertSkillSelectionOwner(owner);\n\t\t\t\t\t\tassertSkillCurrent();\n\t\t\t\t\t\treturn selected\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\ttext: render(selected.capture, selected.ref),\n\t\t\t\t\t\t\t\t\tselectedSkillRef: { ...selected.source },\n\t\t\t\t\t\t\t\t\tassertSkillCurrent,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: { text: render(captureSelectedSkill(captureSkillDescriptor(skill))), assertSkillCurrent };\n\t\t\t\t\t})\n\t\t\t\t\t.catch(failure);\n\t\t\treturn render(captureSelectedSkill(captureSkillDescriptor(skill)));\n\t\t} catch (error) {\n\t\t\treturn failure(error);\n\t\t}\n\t}\n\n\t/**\n\t * Queue a steering message while the agent is running.\n\t * Delivered after the current assistant turn finishes executing its tool calls,\n\t * before the next LLM call.\n\t * Expands skill commands and prompt templates. Errors on extension commands.\n\t * @param images Optional image attachments to include with the message\n\t * @throws Error if text is an extension command\n\t */\n\tasync steer(\n\t\ttext: string,\n\t\timages?: ImageContent[],\n\t\toptions: {\n\t\t\tqueueKey?: string;\n\t\t\tagentMessageId?: string;\n\t\t\tresumeIfIdle?: boolean;\n\t\t} = {},\n\t): Promise<void> {\n\t\tconst submitted = captureSubmittedInput(text, { images });\n\t\tconst manager = this.sessionManager;\n\t\tconst sessionId = manager.getSessionId();\n\t\tconst sessionFile = manager.getSessionFile();\n\t\tconst inputEpoch = this._sessionInputPumpEpoch;\n\t\tconst normalization = this._normalizeSubmission(text, images, {\n\t\t\tparseSessionCommands: false,\n\t\t\textensionCommands: \"reject\",\n\t\t\texpandSkills: true,\n\t\t\texpandPromptTemplates: true,\n\t\t});\n\t\tconst normalized = normalization instanceof Promise ? await normalization : normalization;\n\t\tif (\n\t\t\tnormalization instanceof Promise &&\n\t\t\t(this.sessionManager !== manager ||\n\t\t\t\tsessionId !== manager.getSessionId() ||\n\t\t\t\tsessionFile !== manager.getSessionFile() ||\n\t\t\t\tinputEpoch !== this._sessionInputPumpEpoch)\n\t\t)\n\t\t\tthrow new Error(\"Queued prompt normalization owner changed\");\n\t\tif (normalized.kind !== \"prompt\") {\n\t\t\tthrow new Error(\"Queued prompt normalization did not produce a prompt\");\n\t\t}\n\n\t\tnormalized.assertSkillCurrent?.();\n\t\tawait this._queuePreparedPrompt(\"steer\", normalized.text, normalized.images, {\n\t\t\tsubmitted,\n\t\t\tselectedSkillRef: normalized.selectedSkillRef,\n\t\t\tqueueKey: options.queueKey,\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t\tresumeIfIdle: options.resumeIfIdle,\n\t\t});\n\t}\n\n\t/**\n\t * Queue a follow-up message to be processed after the agent finishes.\n\t * Delivered only when agent has no more tool calls or steering messages.\n\t * Expands skill commands and prompt templates. Errors on extension commands.\n\t * @param images Optional image attachments to include with the message\n\t * @throws Error if text is an extension command\n\t */\n\tasync followUp(\n\t\ttext: string,\n\t\timages?: ImageContent[],\n\t\toptions: {\n\t\t\tqueueKey?: string;\n\t\t\tagentMessageId?: string;\n\t\t\tresumeIfIdle?: boolean;\n\t\t} = {},\n\t): Promise<boolean> {\n\t\tconst submitted = captureSubmittedInput(text, { images });\n\t\tconst manager = this.sessionManager;\n\t\tconst sessionId = manager.getSessionId();\n\t\tconst sessionFile = manager.getSessionFile();\n\t\tconst inputEpoch = this._sessionInputPumpEpoch;\n\t\tconst normalization = this._normalizeSubmission(text, images, {\n\t\t\tparseSessionCommands: false,\n\t\t\textensionCommands: \"reject\",\n\t\t\texpandSkills: true,\n\t\t\texpandPromptTemplates: true,\n\t\t});\n\t\tconst normalized = normalization instanceof Promise ? await normalization : normalization;\n\t\tif (\n\t\t\tnormalization instanceof Promise &&\n\t\t\t(this.sessionManager !== manager ||\n\t\t\t\tsessionId !== manager.getSessionId() ||\n\t\t\t\tsessionFile !== manager.getSessionFile() ||\n\t\t\t\tinputEpoch !== this._sessionInputPumpEpoch)\n\t\t)\n\t\t\tthrow new Error(\"Queued prompt normalization owner changed\");\n\t\tif (normalized.kind !== \"prompt\") {\n\t\t\tthrow new Error(\"Queued prompt normalization did not produce a prompt\");\n\t\t}\n\n\t\tnormalized.assertSkillCurrent?.();\n\t\treturn this._queuePreparedPrompt(\"followUp\", normalized.text, normalized.images, {\n\t\t\tsubmitted,\n\t\t\tselectedSkillRef: normalized.selectedSkillRef,\n\t\t\tqueueKey: options.queueKey,\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t\tresumeIfIdle: options.resumeIfIdle,\n\t\t});\n\t}\n\n\tasync restoreSessionActions(snapshot: SessionActionRecoverySnapshot): Promise<number> {\n\t\tif (\n\t\t\t(snapshot.formatVersion !== SESSION_ACTION_RECOVERY_FORMAT_VERSION &&\n\t\t\t\tsnapshot.formatVersion !== SESSION_ACTION_SKILL_RECOVERY_FORMAT_VERSION) ||\n\t\t\t(snapshot.formatVersion === SESSION_ACTION_RECOVERY_FORMAT_VERSION &&\n\t\t\t\tsnapshot.actions.some((action) => action.payload.kind === \"turn\" && action.payload.selectedSkillRef))\n\t\t) {\n\t\t\tthrow new Error(`Unsupported session action recovery format version: ${snapshot.formatVersion}`);\n\t\t}\n\t\tconst actionIds = new Set(this._actionStore.ownedActions().map((action) => action.id));\n\t\tconst actions = snapshot.actions.map((recovered): QueuedSessionAction => {\n\t\t\tif (actionIds.has(recovered.id)) throw new Error(`Duplicate session action id: ${recovered.id}`);\n\t\t\tactionIds.add(recovered.id);\n\t\t\tif (\n\t\t\t\trecovered.payload.kind === \"turn\" &&\n\t\t\t\trecovered.payload.records.some((record) => record.ownerActionId !== recovered.id)\n\t\t\t) {\n\t\t\t\tthrow new Error(`Session action ${recovered.id} has invalid delivery correlation`);\n\t\t\t}\n\t\t\tconst payload: PreparedTurnPayload | PreparedCommandPayload =\n\t\t\t\trecovered.payload.kind === \"turn\"\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tkind: \"turn\",\n\t\t\t\t\t\t\ttext: recovered.payload.text,\n\t\t\t\t\t\t\t...(recovered.payload.selectedSkillRef\n\t\t\t\t\t\t\t\t? { selectedSkillRef: { ...recovered.payload.selectedSkillRef } }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(recovered.payload.submitted\n\t\t\t\t\t\t\t\t? { submitted: structuredClone(recovered.payload.submitted) }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(recovered.payload.preview ? { preview: recovered.payload.preview } : {}),\n\t\t\t\t\t\t\trecords: recovered.payload.records.map((record) => ({\n\t\t\t\t\t\t\t\tid: record.id,\n\t\t\t\t\t\t\t\trole: record.role,\n\t\t\t\t\t\t\t\tmessage: cloneQueuedAgentMessage(record.message),\n\t\t\t\t\t\t\t\tstarted: false,\n\t\t\t\t\t\t\t\tdurable: false,\n\t\t\t\t\t\t\t\townerActionId: record.ownerActionId,\n\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t...(recovered.payload.images\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\timages: recovered.payload.images.map((image) => ({\n\t\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(recovered.payload.content\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tcontent: recovered.payload.content.map((block) => ({\n\t\t\t\t\t\t\t\t\t\t\t...block,\n\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(recovered.payload.customMessage\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tcustomMessage: cloneCustomMessage(recovered.payload.customMessage),\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\texecutionPolicy: {\n\t\t\t\t\t\t\t\t...recovered.payload.executionPolicy,\n\t\t\t\t\t\t\t\tpreparation: {\n\t\t\t\t\t\t\t\t\t...recovered.payload.executionPolicy.preparation,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tqueueVisible: recovered.payload.queueVisible,\n\t\t\t\t\t\t\tacceptedAgentMessage: recovered.payload.acceptedAgentMessage,\n\t\t\t\t\t\t\tacceptedBeforeCompletion: recovered.payload.acceptedBeforeCompletion,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tkind: \"session_command\",\n\t\t\t\t\t\t\ttext: recovered.payload.text,\n\t\t\t\t\t\t\t...(recovered.payload.submitted\n\t\t\t\t\t\t\t\t? { submitted: structuredClone(recovered.payload.submitted) }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\tcommand: { ...recovered.payload.command },\n\t\t\t\t\t\t\t...(recovered.payload.images\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\timages: recovered.payload.images.map((image) => ({\n\t\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t};\n\t\t\treturn {\n\t\t\t\tid: recovered.id,\n\t\t\t\tsource: recovered.source,\n\t\t\t\tdelivery: recovered.delivery,\n\t\t\t\twake: recovered.wake,\n\t\t\t\tpayload,\n\t\t\t\tlifecycle: { state: \"queued\" },\n\t\t\t\t...(recovered.queueKey ? { queueKey: recovered.queueKey } : {}),\n\t\t\t\t...(recovered.agentMessageId ? { agentMessageId: recovered.agentMessageId } : {}),\n\t\t\t\t...(recovered.suppressAutonomousContinuation ? { suppressAutonomousContinuation: true } : {}),\n\t\t\t};\n\t\t});\n\t\tfor (const action of actions) {\n\t\t\tconst durableTerminalNotice = this._isRlmTerminalNoticeAction(action);\n\t\t\tif (durableTerminalNotice) this._durableRlmTerminalNoticeActionIds.add(action.id);\n\t\t\ttry {\n\t\t\t\tthis._admitSessionInput(action, { restore: true });\n\t\t\t} catch (error) {\n\t\t\t\tif (durableTerminalNotice) this._durableRlmTerminalNoticeActionIds.delete(action.id);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\treturn actions.length;\n\t}\n\n\tprivate _restoreSessionCommand(\n\t\ttext: string,\n\t\tcustomMessage: CustomMessage | undefined,\n\t\timages: ImageContent[] | undefined,\n\t\tschedule: SessionInputSchedule,\n\t\tagentMessageId: string | undefined,\n\t): boolean | undefined {\n\t\tif (!isSessionSlashCommandMessage(customMessage) || text !== customMessage.details.command.text) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this._admitSessionInput(\n\t\t\tthis._createSessionCommandAction(text, customMessage.details.command, images, schedule, {\n\t\t\t\tagentMessageId,\n\t\t\t\tsource: \"internal\",\n\t\t\t}),\n\t\t\t{ restore: true },\n\t\t).accepted;\n\t}\n\n\tprivate _restorePromptInput(schedule: SessionInputSchedule, snapshot: RestoredPromptInput): Promise<boolean> {\n\t\treturn this._queuePreparedPrompt(schedule, snapshot.text, snapshot.images, {\n\t\t\tqueueKey: snapshot.queueKey,\n\t\t\tagentMessageId: snapshot.agentMessageId,\n\t\t\tcontent: snapshot.content,\n\t\t\tmessage: snapshot.customMessage,\n\t\t\tprefixMessages: snapshot.prefixMessages,\n\t\t\tsource: \"internal\",\n\t\t});\n\t}\n\n\tasync restoreSteeringMessage(\n\t\ttext: string,\n\t\timages?: ImageContent[],\n\t\toptions: {\n\t\t\tqueueKey?: string;\n\t\t\tagentMessageId?: string;\n\t\t\tcontent?: (TextContent | ImageContent)[];\n\t\t\tcustomMessage?: CustomMessage;\n\t\t\tprefixMessages?: CustomMessage[];\n\t\t} = {},\n\t): Promise<void> {\n\t\tif (\n\t\t\tthis._restoreSessionCommand(text, options.customMessage, images, \"steer\", options.agentMessageId) !== undefined\n\t\t)\n\t\t\treturn;\n\n\t\tawait this._restorePromptInput(\"steer\", {\n\t\t\ttext,\n\t\t\timages,\n\t\t\tqueueKey: options.queueKey,\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t\tcontent: options.content,\n\t\t\tcustomMessage: options.customMessage,\n\t\t\tprefixMessages: options.prefixMessages,\n\t\t});\n\t}\n\n\tasync restoreFollowUpMessage(\n\t\ttext: string,\n\t\timages?: ImageContent[],\n\t\toptions: {\n\t\t\tqueueKey?: string;\n\t\t\tagentMessageId?: string;\n\t\t\tcontent?: (TextContent | ImageContent)[];\n\t\t\tcustomMessage?: CustomMessage;\n\t\t\tprefixMessages?: CustomMessage[];\n\t\t} = {},\n\t): Promise<boolean> {\n\t\tconst restoredCommand = this._restoreSessionCommand(\n\t\t\ttext,\n\t\t\toptions.customMessage,\n\t\t\timages,\n\t\t\t\"followUp\",\n\t\t\toptions.agentMessageId,\n\t\t);\n\t\tif (restoredCommand !== undefined) return restoredCommand;\n\n\t\treturn this._restorePromptInput(\"followUp\", {\n\t\t\ttext,\n\t\t\timages,\n\t\t\tqueueKey: options.queueKey,\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t\tcontent: options.content,\n\t\t\tcustomMessage: options.customMessage,\n\t\t\tprefixMessages: options.prefixMessages,\n\t\t});\n\t}\n\n\tprivate _buildPromptContent(text: string, images?: ImageContent[]): (TextContent | ImageContent)[] {\n\t\tconst content: (TextContent | ImageContent)[] = [];\n\t\tcontent.push({ type: \"text\", text });\n\t\tif (images) content.push(...images);\n\t\treturn content;\n\t}\n\n\tprivate _takePendingNextTurnMessages(): CustomMessage[] {\n\t\tconst messages = this._pendingNextTurnMessages;\n\t\tthis._pendingNextTurnMessages = [];\n\t\treturn messages;\n\t}\n\n\tprivate _deliveryPolicy(schedule: SessionInputSchedule): DeliveryPolicy {\n\t\treturn schedule === \"steer\" ? \"next_turn_boundary\" : \"when_run_idle\";\n\t}\n\n\tprivate _createDeliveryRecord(\n\t\tactionId: string,\n\t\trole: DeliveryRecord[\"role\"],\n\t\tmessage: QueuedAgentMessage,\n\t): DeliveryRecord {\n\t\treturn {\n\t\t\tid: randomUUID(),\n\t\t\trole,\n\t\t\tmessage,\n\t\t\tstarted: false,\n\t\t\tdurable: false,\n\t\t\townerActionId: actionId,\n\t\t};\n\t}\n\n\tprivate _turnExecutionPolicy(\n\t\tkind: \"queued\" | \"directPrompt\" | \"injected\" | \"customTrigger\",\n\t\toptions: {\n\t\t\treturnAfterAccepted?: boolean;\n\t\t\tskipPrePromptWork?: boolean;\n\t\t} = {},\n\t): TurnExecutionPolicy {\n\t\tif (kind === \"queued\") {\n\t\t\treturn {\n\t\t\t\tpreparation: {\n\t\t\t\t\tinitialRefineBarrier: \"skip\",\n\t\t\t\t\tflushPendingBashBeforeValidation: false,\n\t\t\t\t\tvalidateModelAndAuth: true,\n\t\t\t\t\tawaitPendingModelSelection: true,\n\t\t\t\t\tpreTurnCompaction: \"beforeModelSelection\",\n\t\t\t\t\tfinalRefineBarrier: \"always\",\n\t\t\t\t},\n\t\t\t\trunBeforeAgentStart: true,\n\t\t\t\tnextTurnContextTiming: \"commit\",\n\t\t\t\tpreserveEmptyExtensionPrompt: true,\n\t\t\t\tcompletionIncludesRetryChain: true,\n\t\t\t};\n\t\t}\n\t\tif (kind === \"directPrompt\") {\n\t\t\treturn {\n\t\t\t\tpreparation: {\n\t\t\t\t\tinitialRefineBarrier: options.returnAfterAccepted ? \"skip\" : \"always\",\n\t\t\t\t\tflushPendingBashBeforeValidation: true,\n\t\t\t\t\tvalidateModelAndAuth: true,\n\t\t\t\t\tawaitPendingModelSelection: true,\n\t\t\t\t\tpreTurnCompaction: options.skipPrePromptWork ? \"skip\" : \"afterModelSelection\",\n\t\t\t\t\tfinalRefineBarrier: \"ifInFlight\",\n\t\t\t\t},\n\t\t\t\trunBeforeAgentStart: !options.skipPrePromptWork,\n\t\t\t\tnextTurnContextTiming: \"preparation\",\n\t\t\t\tpreserveEmptyExtensionPrompt: false,\n\t\t\t\tcompletionIncludesRetryChain: true,\n\t\t\t};\n\t\t}\n\t\tif (kind === \"injected\") {\n\t\t\treturn {\n\t\t\t\tpreparation: {\n\t\t\t\t\tinitialRefineBarrier: \"always\",\n\t\t\t\t\tflushPendingBashBeforeValidation: true,\n\t\t\t\t\tvalidateModelAndAuth: true,\n\t\t\t\t\tawaitPendingModelSelection: true,\n\t\t\t\t\tpreTurnCompaction: \"beforeModelSelection\",\n\t\t\t\t\tfinalRefineBarrier: \"ifInFlight\",\n\t\t\t\t},\n\t\t\t\trunBeforeAgentStart: true,\n\t\t\t\tnextTurnContextTiming: \"preparation\",\n\t\t\t\tpreserveEmptyExtensionPrompt: true,\n\t\t\t\tcompletionIncludesRetryChain: true,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tpreparation: {\n\t\t\t\tinitialRefineBarrier: \"always\",\n\t\t\t\tflushPendingBashBeforeValidation: false,\n\t\t\t\tvalidateModelAndAuth: false,\n\t\t\t\tawaitPendingModelSelection: false,\n\t\t\t\tpreTurnCompaction: \"skip\",\n\t\t\t\tfinalRefineBarrier: \"skip\",\n\t\t\t},\n\t\t\trunBeforeAgentStart: false,\n\t\t\tnextTurnContextTiming: \"skip\",\n\t\t\tpreserveEmptyExtensionPrompt: false,\n\t\t\tcompletionIncludesRetryChain: false,\n\t\t};\n\t}\n\n\tprivate _createPreparedTurnAction(\n\t\tschedule: SessionInputSchedule,\n\t\ttext: string,\n\t\timages: ImageContent[] | undefined,\n\t\toptions: {\n\t\t\tagentMessageId?: string;\n\t\t\tqueueKey?: string;\n\t\t\tsubmitted?: NativeSubmittedInput;\n\t\t\tselectedSkillRef?: NativeSkillSourceRef;\n\t\t\tcontent?: (TextContent | ImageContent)[];\n\t\t\tmessage?: QueuedAgentMessage;\n\t\t\tprefixMessages?: CustomMessage[];\n\t\t\tpreviewLabel?: string;\n\t\t\tsuppressAutonomousContinuation?: boolean;\n\t\t\tresumeIfIdle?: boolean;\n\t\t\tsource?: InputSource | \"internal\";\n\t\t\texecutionPolicy?: TurnExecutionPolicy;\n\t\t\tqueueVisible?: boolean;\n\t\t\tacceptedAgentMessage?: boolean;\n\t\t\tacceptedBeforeCompletion?: boolean;\n\t\t},\n\t): QueuedSessionAction {\n\t\tconst id = randomUUID();\n\t\tconst content = options.content ?? this._buildPromptContent(text, images);\n\t\tconst message =\n\t\t\toptions.message ??\n\t\t\t({\n\t\t\t\trole: \"user\",\n\t\t\t\tcontent: content.map((block) => ({ ...block })),\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t} satisfies UserMessage);\n\t\tconst prefixMessages = options.prefixMessages?.map((prefix) => cloneCustomMessage(prefix)) ?? [];\n\t\tconst preview = options.previewLabel ? `${options.previewLabel}: ${text}` : undefined;\n\t\tconst payload: PreparedTurnPayload = {\n\t\t\tkind: \"turn\",\n\t\t\tsubmitted: options.submitted,\n\t\t\tselectedSkillRef: options.selectedSkillRef ? { ...options.selectedSkillRef } : undefined,\n\t\t\ttext,\n\t\t\trecords: [\n\t\t\t\t...prefixMessages.map((prefix) => this._createDeliveryRecord(id, \"prefix\", prefix)),\n\t\t\t\tthis._createDeliveryRecord(id, \"primary\", message),\n\t\t\t],\n\t\t\tpreview,\n\t\t\timages: images?.map((image) => ({ ...image })),\n\t\t\tcontent: content.map((block) => ({ ...block })),\n\t\t\tcustomMessage: options.message?.role === \"custom\" ? cloneCustomMessage(options.message) : undefined,\n\t\t\texecutionPolicy: options.executionPolicy ?? this._turnExecutionPolicy(\"queued\"),\n\t\t\tqueueVisible: options.queueVisible ?? true,\n\t\t\tacceptedAgentMessage: options.acceptedAgentMessage ?? false,\n\t\t\tacceptedBeforeCompletion: options.acceptedBeforeCompletion ?? false,\n\t\t};\n\t\treturn {\n\t\t\tid,\n\t\t\tsource: options.source ?? \"internal\",\n\t\t\tdelivery: this._deliveryPolicy(schedule),\n\t\t\twake:\n\t\t\t\toptions.resumeIfIdle === true\n\t\t\t\t\t? \"immediate\"\n\t\t\t\t\t: schedule === \"steer\"\n\t\t\t\t\t\t? \"on_lower_boundary\"\n\t\t\t\t\t\t: \"external_resume\",\n\t\t\tpayload,\n\t\t\tlifecycle: { state: \"queued\" },\n\t\t\tqueueKey: options.queueKey,\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t\tsuppressAutonomousContinuation: options.suppressAutonomousContinuation,\n\t\t};\n\t}\n\n\tprivate _createSessionCommandAction(\n\t\ttext: string,\n\t\tcommand: SessionSlashCommand,\n\t\timages: ImageContent[] | undefined,\n\t\tschedule: SessionInputSchedule,\n\t\toptions: {\n\t\t\tagentMessageId?: string;\n\t\t\tsubmitted?: NativeSubmittedInput;\n\t\t\tsource?: InputSource | \"internal\";\n\t\t} = {},\n\t): QueuedSessionAction {\n\t\treturn {\n\t\t\tid: randomUUID(),\n\t\t\tsource: options.source ?? \"internal\",\n\t\t\tdelivery: this._deliveryPolicy(schedule),\n\t\t\twake: \"immediate\",\n\t\t\tpayload: { kind: \"session_command\", submitted: options.submitted, text, command, images },\n\t\t\tlifecycle: { state: \"queued\" },\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t};\n\t}\n\n\tprivate _coalescedFollowUpOwner(action: QueuedSessionAction): QueuedSessionAction | undefined {\n\t\tif (action.delivery !== \"when_run_idle\" || action.payload.kind !== \"turn\" || !action.queueKey) return undefined;\n\t\treturn this._actionStore\n\t\t\t.unfinishedActions()\n\t\t\t.find(\n\t\t\t\t(candidate) =>\n\t\t\t\t\tcandidate.queueKey === action.queueKey &&\n\t\t\t\t\t(candidate.lifecycle.state === \"queued\" ||\n\t\t\t\t\t\tcandidate.lifecycle.state === \"selected\" ||\n\t\t\t\t\t\tcandidate.lifecycle.state === \"preparing\"),\n\t\t\t);\n\t}\n\n\tprivate _assertSessionActionAdmissionAvailable(): void {\n\t\tif (this._disposed || this._disposing) {\n\t\t\tthrow new Error(\"Cannot admit a session action because the session is disposing or disposed.\");\n\t\t}\n\t\tif (this._sessionInputAdmissionPauses.size > 0) {\n\t\t\tthrow new Error(\"Cannot admit a session action while session input admission is paused.\");\n\t\t}\n\t\tif (this._sessionInputPumpSuspended) {\n\t\t\tthrow new Error(\"Cannot admit a session action while queued session input is suspended.\");\n\t\t}\n\t}\n\n\tprivate _admitSessionInput(\n\t\taction: QueuedSessionAction,\n\t\toptions: {\n\t\t\trestore?: boolean;\n\t\t\tfront?: boolean;\n\t\t\twake?: boolean;\n\t\t\timmediatelyEligible?: boolean;\n\t\t} = {},\n\t): {\n\t\taccepted: boolean;\n\t\tdisposition: \"starts_when_admitted\" | \"queued\";\n\t\tticket?: ActionTicket;\n\t} {\n\t\tif (this._disposed || this._disposing) {\n\t\t\tthrow new Error(\"Cannot admit a session action because the session is disposing or disposed.\");\n\t\t}\n\t\tif (this._sessionInputAdmissionPauses.size > 0) {\n\t\t\tthrow new Error(\"Cannot admit a session action while session input admission is paused.\");\n\t\t}\n\t\tif (\n\t\t\toptions.restore !== true &&\n\t\t\taction.payload.kind === \"turn\" &&\n\t\t\tisAgentSessionMessage(primaryDeliveryRecord(action).message)\n\t\t) {\n\t\t\tassertAgentMessageQueueCapacity(\n\t\t\t\tthis._actionStore.unfinishedActions().length,\n\t\t\t\tDEFAULT_AGENT_MESSAGE_MAX_PENDING_PER_SESSION,\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\t!options.restore &&\n\t\t\taction.payload.kind === \"session_command\" &&\n\t\t\t(action.payload.command.name === \"compact\" || action.payload.command.name === \"refine\")\n\t\t)\n\t\t\tthis._assertContextOptimizationAllowed();\n\t\tconst coalescedOwner = options.restore ? undefined : this._coalescedFollowUpOwner(action);\n\t\tif (coalescedOwner) {\n\t\t\tif (action.agentMessageId !== coalescedOwner.agentMessageId) {\n\t\t\t\tthis._rejectAgentMessage(\n\t\t\t\t\taction.agentMessageId,\n\t\t\t\t\tnew Error(\"Prompt was not queued because an equivalent follow-up is already pending.\"),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn { accepted: false, disposition: \"queued\" };\n\t\t}\n\t\tconst canStartImmediately =\n\t\t\toptions.immediatelyEligible === true &&\n\t\t\t(this._actionStore.unfinishedActions().length === 0 || options.front === true);\n\t\tif (options.front) this._actionStore.enqueueFront(action);\n\t\telse this._actionStore.enqueue(action);\n\t\tlet disposition: \"starts_when_admitted\" | \"queued\" = \"queued\";\n\t\tif (canStartImmediately && this._actionStore.selectFirst() === action) disposition = \"starts_when_admitted\";\n\t\tconst controller = this._actionStore.ticketFor(action);\n\t\tcontroller.settleAccepted({\n\t\t\tstatus: \"accepted\",\n\t\t\tactionId: action.id,\n\t\t\tdisposition,\n\t\t});\n\t\tthis._sessionInputArrivalEpoch++;\n\t\tthis._emitQueueUpdate();\n\t\tif (\n\t\t\t!options.restore &&\n\t\t\toptions.wake !== false &&\n\t\t\t(disposition === \"starts_when_admitted\" ||\n\t\t\t\t(action.delivery === \"next_turn_boundary\" && this.isStreaming) ||\n\t\t\t\taction.payload.kind === \"session_command\" ||\n\t\t\t\taction.wake === \"immediate\")\n\t\t) {\n\t\t\tif (action.payload.kind === \"turn\" && action.wake === \"immediate\") {\n\t\t\t\tthis._resumeSessionInputAdmission();\n\t\t\t}\n\t\t\tthis._scheduleSessionInputPump();\n\t\t}\n\t\treturn { accepted: true, disposition, ticket: controller.ticket };\n\t}\n\n\tprivate async _queuePreparedPrompt(\n\t\tschedule: SessionInputSchedule,\n\t\ttext: string,\n\t\timages?: ImageContent[],\n\t\toptions: {\n\t\t\tagentMessageId?: string;\n\t\t\tqueueKey?: string;\n\t\t\tsubmitted?: NativeSubmittedInput;\n\t\t\tselectedSkillRef?: NativeSkillSourceRef;\n\t\t\tcontent?: (TextContent | ImageContent)[];\n\t\t\tmessage?: QueuedAgentMessage;\n\t\t\tprefixMessages?: CustomMessage[];\n\t\t\tpreviewLabel?: string;\n\t\t\tsuppressAutonomousContinuation?: boolean;\n\t\t\tresumeIfIdle?: boolean;\n\t\t\tsource?: InputSource | \"internal\";\n\t\t} = {},\n\t): Promise<boolean> {\n\t\tconst action = this._createPreparedTurnAction(schedule, text, images, options);\n\t\tif (action.suppressAutonomousContinuation) {\n\t\t\tthis._markAutonomousContinuationSuppressed(primaryDeliveryRecord(action).message);\n\t\t}\n\t\treturn this._admitSessionInput(action).accepted;\n\t}\n\n\tprivate _runtimeActivity(): RuntimeActivity {\n\t\treturn {\n\t\t\tlowerAgentRun: this.isStreaming,\n\t\t\tcompaction: this.isCompacting,\n\t\t\tretry: this.isRetrying,\n\t\t\tbash: this.isBashRunning,\n\t\t\trefinementApply: this._refineInFlight !== undefined,\n\t\t\tbranchMutation: this._branchSummaryOperation !== undefined,\n\t\t\tschedulerPauseCount: this._queuedWorkPauses.size + (this._sessionInputPumpSuspended ? 1 : 0),\n\t\t\tdisposing: this._disposed || this._disposing,\n\t\t};\n\t}\n\n\tprivate _hasSelectableSessionInput(): boolean {\n\t\treturn (\n\t\t\tthis._actionStore.queuedActions().length > 0 ||\n\t\t\tthis._actionStore.activeActions().some((action) => action.lifecycle.state === \"selected\")\n\t\t);\n\t}\n\n\tget hasPendingSessionWork(): boolean {\n\t\treturn this._actionStore.unfinishedActions().some((action) => {\n\t\t\tconst state = action.lifecycle.state;\n\t\t\treturn (\n\t\t\t\tstate === \"queued\" ||\n\t\t\t\tstate === \"selected\" ||\n\t\t\t\tstate === \"preparing\" ||\n\t\t\t\t(state === \"committing\" && action.payload.kind === \"turn\" && !primaryDeliveryRecord(action).durable)\n\t\t\t);\n\t\t});\n\t}\n\n\tget hasPendingAdmissionWaiters(): boolean {\n\t\treturn (\n\t\t\tthis._sessionActionCommitOwner !== undefined ||\n\t\t\tthis._pendingSessionActionFenceWaiters > 0 ||\n\t\t\tthis._sessionInputCheckpointWaiters.size > 0\n\t\t);\n\t}\n\n\tprivate _scheduleSessionInputPump(): void {\n\t\tif (this._sessionInputPumpSuspended || this._queuedWorkPauses.size > 0) return;\n\t\tif (this._disposed || this._disposing || this._sessionInputPumpRequested || !this._hasSelectableSessionInput()) {\n\t\t\treturn;\n\t\t}\n\t\tthis._sessionInputPumpRequested = true;\n\t\tconst epoch = this._sessionInputPumpEpoch;\n\t\tconst pump = async () => {\n\t\t\tthis._sessionInputPumpRequested = false;\n\t\t\tawait this._pumpSessionInputs(epoch);\n\t\t};\n\t\tthis._sessionInputPump = this._sessionInputPump.then(pump, pump);\n\t\tthis._sessionInputPump.catch(() => {});\n\t}\n\n\tprivate async _pumpSessionInputs(epoch: number): Promise<void> {\n\t\tlet blocked = false;\n\t\ttry {\n\t\t\twhile (!this._disposed && !this._disposing && this._hasSelectableSessionInput()) {\n\t\t\t\tawait this.agent.waitForIdle();\n\t\t\t\tconst preselected = this._actionStore\n\t\t\t\t\t.activeActions()\n\t\t\t\t\t.find((action) => action.lifecycle.state === \"selected\");\n\t\t\t\tif (epoch !== this._sessionInputPumpEpoch) {\n\t\t\t\t\tif (preselected) {\n\t\t\t\t\t\tthis._actionStore.rollback(preselected);\n\t\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!this._hasCancelledDispatchCapture()) await this._waitForAgentEventsBeforeContext();\n\t\t\t\tif (!preselected || preselected.payload.kind === \"session_command\") await this._waitForRefineIdle();\n\t\t\t\tconst activity = this._runtimeActivity();\n\t\t\t\tconst canSelectPreselectedTurn =\n\t\t\t\t\tpreselected?.payload.kind === \"turn\" && canSelectSessionAction({ ...activity, refinementApply: false });\n\t\t\t\tif (\n\t\t\t\t\tthis._isSessionInputHandoffDeferred(epoch) ||\n\t\t\t\t\t(!canSelectPreselectedTurn && !canSelectSessionAction(activity))\n\t\t\t\t) {\n\t\t\t\t\tblocked = true;\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst first = preselected ?? this._actionStore.selectFirst();\n\t\t\t\tif (!first) return;\n\t\t\t\tif (first.payload.kind === \"session_command\") {\n\t\t\t\t\tawait this._executeSelectedSessionCommand(first, epoch);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst mode = first.delivery === \"next_turn_boundary\" ? this.steeringMode : this.followUpMode;\n\t\t\t\tconst actions: QueuedSessionAction[] = [first];\n\t\t\t\twhile (!preselected && mode === \"all\") {\n\t\t\t\t\tconst next = this._actionStore.queuedActions(first.delivery)[0];\n\t\t\t\t\tif (\n\t\t\t\t\t\t!next ||\n\t\t\t\t\t\tnext.payload.kind !== \"turn\" ||\n\t\t\t\t\t\t!turnExecutionPoliciesEqual(first.payload.executionPolicy, next.payload.executionPolicy)\n\t\t\t\t\t) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tthis._actionStore.selectFirst();\n\t\t\t\t\tactions.push(next);\n\t\t\t\t}\n\t\t\t\tif (epoch !== this._sessionInputPumpEpoch) {\n\t\t\t\t\tfor (const action of actions) this._actionStore.rollback(action);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const action of actions) transitionSessionAction(action, { state: \"preparing\" });\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\ttry {\n\t\t\t\t\tawait this._startPreparedTurnActions(actions, epoch);\n\t\t\t\t\tfor (const action of actions) {\n\t\t\t\t\t\tif (action.lifecycle.state === \"committing\") {\n\t\t\t\t\t\t\tconst primary = primaryDeliveryRecord(action);\n\t\t\t\t\t\t\tif (primary.durable) {\n\t\t\t\t\t\t\t\ttransitionSessionAction(action, {\n\t\t\t\t\t\t\t\t\tstate: \"running\",\n\t\t\t\t\t\t\t\t\texecution: \"agent_turn\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (action.lifecycle.state === \"running\") {\n\t\t\t\t\t\t\ttransitionSessionAction(action, { state: \"completed\" });\n\t\t\t\t\t\t\tthis._actionStore.ticketFor(action).settleCompleted();\n\t\t\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"completion\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst transcript = this.agent.state.messages;\n\t\t\t\t\tconst undelivered: QueuedSessionAction[] = [];\n\t\t\t\t\tfor (const action of actions) {\n\t\t\t\t\t\tif (action.payload.kind !== \"turn\" || action.lifecycle.state === \"cancelled\") continue;\n\t\t\t\t\t\taction.payload.records = action.payload.records.filter((record) => {\n\t\t\t\t\t\t\tif (record.role === \"prefix\") return !record.durable;\n\t\t\t\t\t\t\tif (record.role === \"next_turn\") return record.durable;\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (!primaryDeliveryRecord(action).durable) undelivered.push(action);\n\t\t\t\t\t}\n\t\t\t\t\tif (this._isDeferredSessionInputError(error, epoch)) {\n\t\t\t\t\t\tfor (const action of undelivered) {\n\t\t\t\t\t\t\tif (action.lifecycle.state === \"committing\") {\n\t\t\t\t\t\t\t\tthis._actionStore.rollback(action, {\n\t\t\t\t\t\t\t\t\tdispatchSettled: true,\n\t\t\t\t\t\t\t\t\ttranscript,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else if (action.lifecycle.state === \"preparing\" || action.lifecycle.state === \"selected\") {\n\t\t\t\t\t\t\t\tthis._actionStore.rollback(action);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (undelivered.length > 0) this._emitQueueUpdate();\n\t\t\t\t\t\tblocked = epoch !== this._sessionInputPumpEpoch || this._isBusyForSessionInput(\"pump\");\n\t\t\t\t\t\tif (blocked) return;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst terminalError = this._asError(error);\n\t\t\t\t\tfor (const action of actions) {\n\t\t\t\t\t\tif (action.lifecycle.state === \"cancelled\") continue;\n\t\t\t\t\t\tif (action.lifecycle.state !== \"completed\" && action.lifecycle.state !== \"failed\") {\n\t\t\t\t\t\t\ttransitionSessionAction(action, {\n\t\t\t\t\t\t\t\tstate: \"failed\",\n\t\t\t\t\t\t\t\terror: terminalError,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst ticket = this._actionStore.ticketFor(action);\n\t\t\t\t\t\tif (undelivered.includes(action)) {\n\t\t\t\t\t\t\tticket.rejectDelivered(terminalError);\n\t\t\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"delivery\", terminalError);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"completion\", terminalError);\n\t\t\t\t\t\tticket.settleCompleted(terminalError);\n\t\t\t\t\t}\n\t\t\t\t\tif (actions.some((action) => action.payload.kind !== \"turn\" || action.payload.queueVisible)) {\n\t\t\t\t\t\tthis._surfaceSessionInputError(error);\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\tfor (const action of actions) {\n\t\t\t\t\t\tconst retainedCancelledDispatch =\n\t\t\t\t\t\t\taction.lifecycle.state === \"cancelled\" &&\n\t\t\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\t\t\taction.payload.captureRunMessages !== undefined;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!retainedCancelledDispatch &&\n\t\t\t\t\t\t\t(action.lifecycle.state === \"completed\" ||\n\t\t\t\t\t\t\t\taction.lifecycle.state === \"failed\" ||\n\t\t\t\t\t\t\t\taction.lifecycle.state === \"cancelled\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis._durableRlmTerminalNoticeActionIds.delete(action.id);\n\t\t\t\t\t\t\tthis._actionStore.releaseTerminal(action);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t}\n\t\t\t\tif (epoch !== this._sessionInputPumpEpoch || blocked) return;\n\t\t\t}\n\t\t} finally {\n\t\t\tif (!blocked && epoch === this._sessionInputPumpEpoch && this._hasSelectableSessionInput()) {\n\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async _executeSelectedSessionCommand(action: QueuedSessionAction, epoch: number): Promise<void> {\n\t\tif (action.payload.kind !== \"session_command\") throw new Error(\"Expected a selected session command\");\n\t\tconst input = action.payload;\n\t\tconst commitFence = await this._acquireSessionActionCommitFence();\n\t\ttry {\n\t\t\tawait this._sessionActionCommitContext.run(commitFence.owner, async () => {\n\t\t\t\tconst isCancelled = () => action.lifecycle.state === \"cancelled\";\n\t\t\t\tif (isCancelled()) return;\n\t\t\t\tawait this._waitForRefineIdle();\n\t\t\t\tif (isCancelled()) return;\n\t\t\t\tif (this._isSessionInputHandoffDeferred(epoch) || !canSelectSessionAction(this._runtimeActivity())) {\n\t\t\t\t\tthis._actionStore.rollback(action);\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttransitionSessionAction(action, {\n\t\t\t\t\tstate: \"running\",\n\t\t\t\t\texecution: \"session_command\",\n\t\t\t\t});\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\ttry {\n\t\t\t\t\tawait this._appendDurableSessionCommandMessage(input.text, input.command, false);\n\t\t\t\t\tthis._actionStore.ticketFor(action).settleDelivered({ status: \"not_applicable\" });\n\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"delivery\");\n\t\t\t\t\tawait this._executeQueuedSessionCommand(action);\n\t\t\t\t\ttransitionSessionAction(action, { state: \"completed\" });\n\t\t\t\t\tthis._actionStore.ticketFor(action).settleCompleted();\n\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"completion\");\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst commandError = this._asError(error);\n\t\t\t\t\ttransitionSessionAction(action, {\n\t\t\t\t\t\tstate: \"failed\",\n\t\t\t\t\t\terror: commandError,\n\t\t\t\t\t});\n\t\t\t\t\tconst ticket = this._actionStore.ticketFor(action);\n\t\t\t\t\tticket.rejectDelivered(commandError);\n\t\t\t\t\tticket.settleCompleted(commandError);\n\t\t\t\t\tthis._rejectAgentMessage(action.agentMessageId, commandError);\n\t\t\t\t} finally {\n\t\t\t\t\tthis._actionStore.releaseTerminal(action);\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t}\n\t\t\t});\n\t\t} finally {\n\t\t\tcommitFence.release();\n\t\t}\n\t}\n\n\tprivate _isBusyForSessionInput(point: \"preflight\" | \"pump\"): boolean {\n\t\tconst externalBusy = this.isCompacting || this.isRetrying || this.isBashRunning;\n\t\tif (point === \"pump\") {\n\t\t\treturn (\n\t\t\t\texternalBusy ||\n\t\t\t\tthis._disposed ||\n\t\t\t\tthis._disposing ||\n\t\t\t\tthis._sessionInputPumpSuspended ||\n\t\t\t\tthis._queuedWorkPauses.size > 0 ||\n\t\t\t\tthis._branchSummaryOperation !== undefined\n\t\t\t);\n\t\t}\n\t\treturn externalBusy || this._actionStore.unfinishedActions().length > 0;\n\t}\n\n\tprivate _isSessionInputHandoffDeferred(epoch: number): boolean {\n\t\treturn epoch !== this._sessionInputPumpEpoch || this._isBusyForSessionInput(\"pump\");\n\t}\n\n\tprivate _asError(error: unknown): Error {\n\t\treturn error instanceof Error ? error : new Error(String(error));\n\t}\n\n\tprivate _isDeferredSessionInputError(error: unknown, epoch: number): boolean {\n\t\tif (primaryCommittedCompactionError(error)) return false;\n\t\tif (error instanceof DeferredSessionInputError) return true;\n\t\tif (epoch !== this._sessionInputPumpEpoch) return true;\n\t\tif (this._isBusyForSessionInput(\"pump\")) {\n\t\t\tthis._surfaceSessionInputError(error);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate _surfaceSessionInputError(error: unknown): void {\n\t\tconst normalized = this._asError(error);\n\t\ttry {\n\t\t\tthis._extensionRunner.emitError({\n\t\t\t\textensionPath: \"<session-input>\",\n\t\t\t\tevent: \"session_input\",\n\t\t\t\terror: normalized.message,\n\t\t\t\tstack: normalized.stack,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Best-effort: a throwing error listener must not break the pump's requeue path.\n\t\t}\n\t}\n\n\tprivate async _startPreparedTurnActions(actions: QueuedSessionAction[], epoch: number): Promise<void> {\n\t\tlet nextTurnMessages: CustomMessage[] = [];\n\t\tconst activeTurns = () =>\n\t\t\tactions.filter(\n\t\t\t\t(action): action is SessionAction<PreparedTurnPayload> =>\n\t\t\t\t\taction.payload.kind === \"turn\" && action.lifecycle.state === \"preparing\",\n\t\t\t);\n\t\tconst firstTurn = activeTurns()[0];\n\t\tif (!firstTurn) return;\n\t\tconst executionPolicy = firstTurn.payload.executionPolicy;\n\t\tconst restoreNextTurnContext = () => {\n\t\t\tthis._pendingNextTurnMessages.unshift(...nextTurnMessages);\n\t\t\tnextTurnMessages = [];\n\t\t};\n\t\ttry {\n\t\t\tconst preparedTurn = await this._prepareForCommit(executionPolicy.preparation, {\n\t\t\t\tafterValidation: () => {\n\t\t\t\t\tif (this._isSessionInputHandoffDeferred(epoch)) {\n\t\t\t\t\t\tthrow new DeferredSessionInputError(\"Session input paused before preflight\");\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tprepare: async () => {\n\t\t\t\t\tif (executionPolicy.nextTurnContextTiming === \"preparation\") {\n\t\t\t\t\t\tnextTurnMessages = this._takePendingNextTurnMessages();\n\t\t\t\t\t}\n\t\t\t\t\tif (!executionPolicy.runBeforeAgentStart) return undefined;\n\t\t\t\t\twhile (activeTurns().some((action) => action.payload.prepared === undefined)) {\n\t\t\t\t\t\tif (this._isSessionInputHandoffDeferred(epoch)) {\n\t\t\t\t\t\t\tthrow new DeferredSessionInputError(\"Session input paused before preparation\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst preparationAction = activeTurns().at(-1);\n\t\t\t\t\t\tif (!preparationAction) return undefined;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.settingsManager.getLearningEnabled() ||\n\t\t\t\t\t\t\tthis._baseSystemPromptOptions.errorFixSelection?.enabled\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Capture advice for this task before extensions and provider preparation.\n\t\t\t\t\t\t\t// Tool continuations keep the same prompt until the next task boundary.\n\t\t\t\t\t\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(\n\t\t\t\t\t\t\t\tthis.getActiveToolNames(),\n\t\t\t\t\t\t\t\tthis._baseSystemPromptOptions.nativeSkillSelection !== undefined,\n\t\t\t\t\t\t\t\tpreparationAction.payload.text,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst basePromptSnapshot = this._baseSystemPrompt;\n\t\t\t\t\t\tconst result = await this._extensionRunner.emitBeforeAgentStart(\n\t\t\t\t\t\t\tpreparationAction.payload.text,\n\t\t\t\t\t\t\tpreparationAction.payload.images,\n\t\t\t\t\t\t\tbasePromptSnapshot,\n\t\t\t\t\t\t\tthis._baseSystemPromptOptions,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (activeTurns().at(-1) !== preparationAction) continue;\n\t\t\t\t\t\tconst prepared = { result, basePromptSnapshot };\n\t\t\t\t\t\tfor (const action of activeTurns()) action.payload.prepared = prepared;\n\t\t\t\t\t}\n\t\t\t\t\tif (this._isSessionInputHandoffDeferred(epoch)) {\n\t\t\t\t\t\tthrow new DeferredSessionInputError(\"Session input paused before handoff\");\n\t\t\t\t\t}\n\t\t\t\t\treturn activeTurns()[0]?.payload.prepared;\n\t\t\t\t},\n\t\t\t\tshouldCommit: () => activeTurns().length > 0,\n\t\t\t\tcommit: (prepared) => {\n\t\t\t\t\tif (this._isSessionInputHandoffDeferred(epoch)) {\n\t\t\t\t\t\tthrow new DeferredSessionInputError(\"Session input paused before handoff\");\n\t\t\t\t\t}\n\t\t\t\t\tconst turns = activeTurns();\n\t\t\t\t\tif (turns.length === 0) return undefined;\n\t\t\t\t\treturn { prepared, turns };\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (!preparedTurn) {\n\t\t\t\trestoreNextTurnContext();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst { prepared } = preparedTurn;\n\t\t\tlet { turns } = preparedTurn;\n\t\t\tconst commitFence = await this._acquireSessionActionCommitFence();\n\t\t\tlet promptPromise: Promise<void>;\n\t\t\ttry {\n\t\t\t\tpromptPromise = this._sessionActionCommitContext.run(commitFence.owner, () => {\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis._isSessionInputHandoffDeferred(epoch) ||\n\t\t\t\t\t\tthis.isStreaming ||\n\t\t\t\t\t\tturns.some((action) => action.lifecycle.state !== \"preparing\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new DeferredSessionInputError(\"Agent became active before session input handoff\");\n\t\t\t\t\t}\n\t\t\t\t\t// Deliver the pending family updates together, including arrivals during preparation.\n\t\t\t\t\t// Keep user/control actions and delivery lanes as boundaries; retain every action's ticket.\n\t\t\t\t\tif (turns.every(isFamilyAgentMessageAction)) {\n\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\tconst next = this._actionStore.queuedActions()[0];\n\t\t\t\t\t\t\tif (!next || next.delivery !== turns[0].delivery || !isFamilyAgentMessageAction(next)) break;\n\t\t\t\t\t\t\tthis._actionStore.selectFirst();\n\t\t\t\t\t\t\ttransitionSessionAction(next, { state: \"preparing\" });\n\t\t\t\t\t\t\tactions.push(next);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tturns = activeTurns();\n\t\t\t\t\t}\n\t\t\t\t\tif (executionPolicy.nextTurnContextTiming === \"commit\") {\n\t\t\t\t\t\tnextTurnMessages = this._takePendingNextTurnMessages();\n\t\t\t\t\t}\n\t\t\t\t\tconst contextRecords = nextTurnMessages.map((message) =>\n\t\t\t\t\t\tthis._createDeliveryRecord(turns[0].id, \"next_turn\", message),\n\t\t\t\t\t);\n\t\t\t\t\tconst firstPrimaryIndex = turns[0].payload.records.indexOf(primaryDeliveryRecord(turns[0]));\n\t\t\t\t\tturns[0].payload.records.splice(firstPrimaryIndex, 0, ...contextRecords);\n\t\t\t\t\tconst preparedMessages: AgentMessage[] = turns.flatMap((action) =>\n\t\t\t\t\t\taction.payload.records.map((record) => record.message),\n\t\t\t\t\t);\n\t\t\t\t\tfor (const action of turns) {\n\t\t\t\t\t\tif (action.suppressAutonomousContinuation) {\n\t\t\t\t\t\t\tthis._markAutonomousContinuationSuppressed(primaryDeliveryRecord(action).message);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (executionPolicy.runBeforeAgentStart) {\n\t\t\t\t\t\tthis._appendBeforeAgentStartMessages(preparedMessages, prepared?.result);\n\t\t\t\t\t\tthis._applyPreparedSystemPrompt(prepared, executionPolicy.preserveEmptyExtensionPrompt);\n\t\t\t\t\t} else if (executionPolicy.nextTurnContextTiming !== \"skip\") {\n\t\t\t\t\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t\t\t\t\t}\n\t\t\t\t\tconst checkpointBoundary =\n\t\t\t\t\t\tthis._postCompactionContinuationSettlement?.resume.boundary ?? this._pendingCheckpoint?.boundary;\n\t\t\t\t\tfor (const action of turns) {\n\t\t\t\t\t\ttransitionSessionAction(action, { state: \"committing\" });\n\t\t\t\t\t\tif (checkpointBoundary?.state === \"pending\") {\n\t\t\t\t\t\t\tvoid this._actionStore.ticketFor(action).ticket.delivered.then(\n\t\t\t\t\t\t\t\t(delivery) => {\n\t\t\t\t\t\t\t\t\tif (delivery.status === \"delivered\") checkpointBoundary.state = \"consumed\";\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t() => {},\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t\treturn turns.some((action) => action.suppressAutonomousContinuation)\n\t\t\t\t\t\t? this._runWithAutonomousContinuationSuppressed(() => this.agent.prompt(preparedMessages))\n\t\t\t\t\t\t: this.agent.prompt(preparedMessages);\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tcommitFence.release();\n\t\t\t}\n\t\t\tawait promptPromise;\n\t\t\tif (executionPolicy.completionIncludesRetryChain) await this.waitForRetry();\n\t\t\tif (!this._hasCancelledDispatchCapture()) await this._agentEventQueue;\n\t\t\tif (turns.some((action) => action.lifecycle.state !== \"cancelled\" && !primaryDeliveryRecord(action).durable)) {\n\t\t\t\tthrow new Error(\"Session input dispatch settled without durable delivery\");\n\t\t\t}\n\t\t\tthis._forgetConsumedPostCompactionContinuations(turns);\n\t\t} catch (error) {\n\t\t\tconst delivered = new Set(this.agent.state.messages);\n\t\t\tthis._pendingNextTurnMessages.unshift(...nextTurnMessages.filter((message) => !delivered.has(message)));\n\t\t\tfor (const action of actions) {\n\t\t\t\tif (action.payload.kind === \"turn\") {\n\t\t\t\t\taction.payload.records = action.payload.records.filter((record) => record.role !== \"next_turn\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async _executeQueuedSessionCommand(action: QueuedSessionAction): Promise<void> {\n\t\tif (action.payload.kind !== \"session_command\") throw new Error(\"Expected a session command action\");\n\t\tconst input = action.payload;\n\t\ttry {\n\t\t\tlet resultText: string | undefined;\n\t\t\tlet displayResult = true;\n\t\t\tswitch (input.command.name) {\n\t\t\t\tcase \"compact\":\n\t\t\t\t\tawait this._compactAccepted(input.command.args || undefined, {\n\t\t\t\t\t\tskipAbort: true,\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"refine\": {\n\t\t\t\t\tlet result: RefinementResult;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst options = parseRefineCommandOptions(input.command.args);\n\t\t\t\t\t\tresult = await this._refineAccepted(options, { skipAbort: true });\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t// Only a failure of the refinement itself is a refine failure; a later\n\t\t\t\t\t\t// result-row persist error must not report a completed refinement as failed.\n\t\t\t\t\t\tthis._emitRefineFailed(this._asError(error));\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t\tconst applied = result.appliedEdits.filter((edit) => edit.applied).length;\n\t\t\t\t\tresultText = `Refined continual harness state: ${applied} edit${applied === 1 ? \"\" : \"s\"} applied.`;\n\t\t\t\t\tdisplayResult = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"goal\": {\n\t\t\t\t\tconst goalOrigin: GoalOriginContext = {\n\t\t\t\t\t\twriter: this.sessionManager[bindNativeEntryWriter](),\n\t\t\t\t\t\tactor: action.source,\n\t\t\t\t\t\tactionId: action.id,\n\t\t\t\t\t\tsubmittedText: input.submitted?.text,\n\t\t\t\t\t};\n\t\t\t\t\tawait this._handleGoalSlashCommand(input.text, input.images, goalOrigin);\n\t\t\t\t\tresultText = this._goalState.objective\n\t\t\t\t\t\t? `Goal ${this._goalState.status}: ${this._goalState.objective}`\n\t\t\t\t\t\t: \"No active goal.\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"autonomous\":\n\t\t\t\t\tawait this._handleAutonomousSlashCommand(input.text);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (resultText) {\n\t\t\t\tawait this._appendDurableSessionCommandMessage(resultText, input.command, true, false, displayResult);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (error instanceof CompactionSkippedError) return;\n\t\t\tconst commandError = error instanceof Error ? error : new Error(String(error));\n\t\t\ttry {\n\t\t\t\tawait this._appendDurableSessionCommandMessage(\n\t\t\t\t\t`Command failed: ${commandError.message}`,\n\t\t\t\t\tinput.command,\n\t\t\t\t\ttrue,\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} catch {\n\t\t\t\t// The result row is also the command-correlated UI settle edge.\n\t\t\t\tconst message = createSessionSlashCommandResultMessage(`Command failed: ${commandError.message}`, {\n\t\t\t\t\tcommand: input.command,\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tseverity: \"error\",\n\t\t\t\t\terror: commandError.message,\n\t\t\t\t});\n\t\t\t\tthis._emit({ type: \"message_start\", message });\n\t\t\t\tthis._emit({ type: \"message_end\", message });\n\t\t\t}\n\t\t\tthrow commandError;\n\t\t}\n\t}\n\n\tprivate async _appendDurableSessionCommandMessage(\n\t\tcontent: string,\n\t\tcommand: SessionSlashCommand,\n\t\tisResult: boolean,\n\t\tisError = false,\n\t\tdisplay = true,\n\t): Promise<void> {\n\t\tconst message: CustomMessage = isResult\n\t\t\t? createSessionSlashCommandResultMessage(\n\t\t\t\t\tcontent,\n\t\t\t\t\t{\n\t\t\t\t\t\tcommand,\n\t\t\t\t\t\tsuccess: !isError,\n\t\t\t\t\t\tseverity: isError ? \"error\" : \"info\",\n\t\t\t\t\t\t...(isError ? { error: content.replace(/^Command failed:\\s*/, \"\") } : {}),\n\t\t\t\t\t},\n\t\t\t\t\tdisplay,\n\t\t\t\t)\n\t\t\t: createSessionSlashCommandMessage(command);\n\t\t// Persist before touching live state so a failed write cannot leave an\n\t\t// unsaved leaf that the next entry would silently parent onto.\n\t\tawait this.sessionManager.appendCustomMessageEntryWithRollback(\n\t\t\tmessage.customType,\n\t\t\tmessage.content,\n\t\t\tmessage.display,\n\t\t\tmessage.details,\n\t\t);\n\t\tthis.agent.state.messages.push(message);\n\t\tthis._emit({ type: \"message_start\", message });\n\t\tthis._emit({ type: \"message_end\", message });\n\t}\n\n\tprivate _throwIfExtensionCommand(text: string): void {\n\t\tconst commandName = parseSlashCommand(text)?.name ?? \"\";\n\t\tconst command = this._extensionRunner.getCommand(commandName);\n\n\t\tif (command) {\n\t\t\tthrow new Error(\n\t\t\t\t`Extension command \"/${commandName}\" cannot be queued. Use prompt() or execute the command when not streaming.`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Send a custom message to the session. Creates a CustomMessageEntry.\n\t *\n\t * Handles three cases:\n\t * - Streaming: queues message, processed when loop pulls from queue\n\t * - Not streaming + triggerTurn: appends to state/session, starts new turn\n\t * - Not streaming + no trigger: appends to state/session, no turn\n\t *\n\t * @param message Custom message with customType, content, display, details\n\t * @param options.triggerTurn If true and not streaming, triggers a new LLM turn\n\t * @param options.deliverAs Delivery mode: \"steer\", \"followUp\", or \"nextTurn\"\n\t */\n\tasync sendCustomMessage<T = unknown>(\n\t\tmessage: Pick<CustomMessage<T>, \"customType\" | \"content\" | \"display\" | \"details\">,\n\t\toptions?: {\n\t\t\ttriggerTurn?: boolean;\n\t\t\tdeliverAs?: \"steer\" | \"followUp\" | \"nextTurn\";\n\t\t},\n\t): Promise<void> {\n\t\tconst appMessage = {\n\t\t\trole: \"custom\" as const,\n\t\t\tcustomType: message.customType,\n\t\t\tcontent: message.content,\n\t\t\tdisplay: message.display,\n\t\t\tdetails: message.details,\n\t\t\ttimestamp: Date.now(),\n\t\t} satisfies CustomMessage<T>;\n\t\tif (options?.deliverAs === \"nextTurn\") {\n\t\t\tthis._pendingNextTurnMessages.push(appMessage);\n\t\t} else if (this.isStreaming) {\n\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\tif (options?.deliverAs === \"followUp\") {\n\t\t\t\tawait this._queuePreparedPrompt(\"followUp\", normalized.text, normalized.images, {\n\t\t\t\t\tmessage: appMessage,\n\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tawait this._queuePreparedPrompt(\"steer\", normalized.text, normalized.images, {\n\t\t\t\t\tmessage: appMessage,\n\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (options?.triggerTurn) {\n\t\t\tif (!this._sessionInputSuspendedForUpdateRestart) this._resumeSessionInputAdmission();\n\t\t\tconst admissionFence = await this._acquireDirectTurnAdmissionFence();\n\t\t\ttry {\n\t\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\t\tconst immediatelyEligible = this._canStartSessionActionImmediately();\n\t\t\t\tconst action = this._createPreparedTurnAction(\"followUp\", normalized.text, normalized.images, {\n\t\t\t\t\tmessage: appMessage,\n\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t\texecutionPolicy: this._turnExecutionPolicy(\"customTrigger\"),\n\t\t\t\t\tqueueVisible: false,\n\t\t\t\t});\n\t\t\t\tconst result = this._admitSessionInput(action, { immediatelyEligible });\n\t\t\t\tadmissionFence.release();\n\t\t\t\tif (!result.ticket) return;\n\t\t\t\tawait result.ticket.completed;\n\t\t\t} finally {\n\t\t\t\tadmissionFence.release();\n\t\t\t}\n\t\t} else {\n\t\t\tawait this.sessionManager.appendCustomMessageEntry(\n\t\t\t\tmessage.customType,\n\t\t\t\tmessage.content,\n\t\t\t\tmessage.display,\n\t\t\t\tmessage.details,\n\t\t\t);\n\t\t\tthis.agent.state.messages.push(appMessage);\n\t\t\tthis._emit({ type: \"message_start\", message: appMessage });\n\t\t\tthis._emit({ type: \"message_end\", message: appMessage });\n\t\t}\n\t}\n\n\t/**\n\t * Send a user message to the agent. Always triggers a turn.\n\t * When the agent is streaming, use deliverAs to specify how to queue the message.\n\t *\n\t * @param content User message content (string or content array)\n\t * @param options.deliverAs Delivery mode when streaming: \"steer\" or \"followUp\"\n\t */\n\tasync sendUserMessage(\n\t\tcontent: string | (TextContent | ImageContent)[],\n\t\toptions?: { deliverAs?: \"steer\" | \"followUp\" },\n\t): Promise<void> {\n\t\tlet text: string;\n\t\tlet images: ImageContent[] | undefined;\n\n\t\tif (typeof content === \"string\") {\n\t\t\ttext = content;\n\t\t} else {\n\t\t\tconst textParts: string[] = [];\n\t\t\timages = [];\n\t\t\tfor (const part of content) {\n\t\t\t\tif (part.type === \"text\") {\n\t\t\t\t\ttextParts.push(part.text);\n\t\t\t\t} else {\n\t\t\t\t\timages.push(part);\n\t\t\t\t}\n\t\t\t}\n\t\t\ttext = textParts.join(\"\\n\");\n\t\t\tif (images.length === 0) images = undefined;\n\t\t}\n\n\t\tawait this._prompt(text, {\n\t\t\texpandPromptTemplates: false,\n\t\t\tstreamingBehavior: options?.deliverAs,\n\t\t\timages,\n\t\t\tsource: \"extension\",\n\t\t\tresumeIfIdle: true,\n\t\t});\n\t}\n\n\tclearQueue(): { steering: string[]; followUp: string[] } {\n\t\tconst clearable = this._actionStore\n\t\t\t.clearableActions()\n\t\t\t.filter((action) => action.payload.kind === \"session_command\" || action.payload.queueVisible);\n\t\tif (clearable.some((action) => action.payload.kind === \"turn\" && action.lifecycle.state === \"preparing\")) {\n\t\t\tthis._sessionInputPumpEpoch++;\n\t\t}\n\t\tconst steering = clearable\n\t\t\t.filter((action) => action.delivery === \"next_turn_boundary\")\n\t\t\t.map((action) => action.payload.text);\n\t\tconst followUp = clearable\n\t\t\t.filter((action) => action.delivery === \"when_run_idle\")\n\t\t\t.map((action) => action.payload.text);\n\t\tconst promptError = new Error(\"Queued prompt was cleared before delivery.\");\n\t\tconst agentMessageError = new Error(\"Queued agent message was cleared before delivery.\");\n\t\tfor (const action of clearable) {\n\t\t\tconst error =\n\t\t\t\taction.payload.kind === \"turn\" && action.lifecycle.state === \"preparing\" ? promptError : agentMessageError;\n\t\t\tthis._settleAgentMessage(action.agentMessageId, \"delivery\", error);\n\t\t\tthis._settleAgentMessage(action.agentMessageId, \"completion\", error);\n\t\t}\n\t\tconst clearableIds = new Set(clearable.map((action) => action.id));\n\t\tthis._cancelSessionActions((action) => clearableIds.has(action.id), agentMessageError);\n\t\tthis.agent.clearAllQueues();\n\t\tthis._emitQueueUpdate();\n\t\treturn { steering, followUp };\n\t}\n\n\tprivate _invalidateQueuedPromptPreparation(): void {\n\t\tfor (const action of this._actionStore.clearableActions()) {\n\t\t\tif (action.payload.kind === \"turn\") action.payload.prepared = undefined;\n\t\t}\n\t}\n\n\tclearQueuedAgentMessages(): { steering: string[]; followUp: string[] } {\n\t\tthis._agentMessageClearEpoch++;\n\t\treturn this.clearQueuedUserMessagesMatching(isAgentSessionMessagePrompt);\n\t}\n\n\tclearQueuedUserMessagesMatching(predicate: (text: string) => boolean): { steering: string[]; followUp: string[] } {\n\t\tconst ownedActions = this._actionStore.ownedActions();\n\t\tconst dispatchedTurnCount = ownedActions.filter(\n\t\t\t(action) =>\n\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t(action.lifecycle.state === \"committing\" || action.lifecycle.state === \"running\"),\n\t\t).length;\n\t\tconst matching = ownedActions.filter(\n\t\t\t(action) =>\n\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\taction.agentMessageId !== undefined &&\n\t\t\t\tpredicate(action.payload.text) &&\n\t\t\t\t(action.lifecycle.state === \"queued\" ||\n\t\t\t\t\taction.lifecycle.state === \"selected\" ||\n\t\t\t\t\taction.lifecycle.state === \"preparing\" ||\n\t\t\t\t\t(action.lifecycle.state === \"committing\" &&\n\t\t\t\t\t\tdispatchedTurnCount === 1 &&\n\t\t\t\t\t\t!primaryDeliveryRecord(action).started)),\n\t\t);\n\t\tif (matching.length === 0) return { steering: [], followUp: [] };\n\t\tconst removedTexts = (delivery: DeliveryPolicy) =>\n\t\t\t[\n\t\t\t\t...matching.filter((action) => action.delivery === delivery && action.lifecycle.state === \"queued\"),\n\t\t\t\t...matching.filter((action) => action.delivery === delivery && action.lifecycle.state !== \"queued\"),\n\t\t\t].map((action) => action.payload.text);\n\t\tconst removedSteering = removedTexts(\"next_turn_boundary\");\n\t\tconst removedFollowUp = removedTexts(\"when_run_idle\");\n\t\tconst acceptedError = new Error(\"Accepted agent message was cleared before delivery.\");\n\t\tconst queuedError = new Error(\"Queued agent message was cleared before delivery.\");\n\t\tfor (const action of matching) {\n\t\t\tconst error =\n\t\t\t\taction.payload.kind === \"turn\" && action.payload.acceptedAgentMessage ? acceptedError : queuedError;\n\t\t\tthis._rejectAgentMessage(action.agentMessageId, error);\n\t\t}\n\t\tfor (const [accepted, error] of [\n\t\t\t[true, acceptedError],\n\t\t\t[false, queuedError],\n\t\t] as const) {\n\t\t\tconst ids = new Set(\n\t\t\t\tmatching\n\t\t\t\t\t.filter((action) => action.payload.kind === \"turn\" && action.payload.acceptedAgentMessage === accepted)\n\t\t\t\t\t.map((action) => action.id),\n\t\t\t);\n\t\t\tif (ids.size > 0) this._cancelSessionActions((action) => ids.has(action.id), error, matching);\n\t\t}\n\t\tif (\n\t\t\tmatching.some(\n\t\t\t\t(action) =>\n\t\t\t\t\taction.lifecycle.state === \"cancelled\" &&\n\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\taction.payload.captureRunMessages,\n\t\t\t)\n\t\t) {\n\t\t\tthis.agent.abort();\n\t\t}\n\t\tthis._emitQueueUpdate();\n\t\treturn { steering: removedSteering, followUp: removedFollowUp };\n\t}\n\n\t/**\n\t * Mutate a single visible queued message, addressed by its position in the same\n\t * projection the session-action snapshot publishes. expectedText must match the\n\t * item's current preview so clients never edit a shifted queue by accident.\n\t */\n\tmutateQueuedMessage(\n\t\tlane: QueuedMessageLane,\n\t\tindex: number,\n\t\texpectedText: string,\n\t\tmutation: QueuedMessageMutation,\n\t): QueuedMessageMutationStatus {\n\t\tconst policy = queuedMessageLaneDeliveryPolicy(lane);\n\t\tconst projection = visibleSessionActionProjection(this._actionStore.queuedActions(policy));\n\t\tconst item = projection[index];\n\t\tif (!item || queuedAgentMessagePreview(item) !== expectedText) return \"rejected\";\n\t\tif (mutation.type === \"delete\") {\n\t\t\tconst error = new Error(\"Queued prompt was deleted before delivery.\");\n\t\t\tthis._rejectAgentMessage(item.agentMessageId, error);\n\t\t\tthis._cancelSessionActions((candidate) => candidate === item, error);\n\t\t\tthis._emitQueueUpdate();\n\t\t\tthis.resumeQueuedWork();\n\t\t\treturn \"applied\";\n\t\t}\n\t\tif (mutation.type === \"move\") {\n\t\t\tconst neighbor = projection[index + mutation.direction];\n\t\t\tif (!neighbor) return \"rejected\";\n\t\t\tthis._actionStore.swapQueued(item, neighbor);\n\t\t\tthis._emitQueueUpdate();\n\t\t\treturn \"applied\";\n\t\t}\n\t\tif (\n\t\t\titem.payload.kind === \"turn\" &&\n\t\t\t(item.payload.acceptedAgentMessage ||\n\t\t\t\titem.payload.records.some((record) => record.role === \"primary\" && record.message.role !== \"user\"))\n\t\t) {\n\t\t\treturn \"rejected\";\n\t\t}\n\t\tconst images = mutation.images?.map((image) => ({ ...image }));\n\t\tif (item.payload.kind === \"session_command\") {\n\t\t\tconst command = parseSessionSlashCommand(mutation.text);\n\t\t\tif (!command) return \"invalid\";\n\t\t\titem.payload.text = mutation.text;\n\t\t\titem.payload.command = command;\n\t\t\tif (mutation.images !== undefined) item.payload.images = images?.length ? images : undefined;\n\t\t} else {\n\t\t\titem.payload.text = mutation.text;\n\t\t\titem.payload.selectedSkillRef = undefined;\n\t\t\tconst text = { type: \"text\" as const, text: mutation.text };\n\t\t\tif (mutation.images !== undefined) {\n\t\t\t\titem.payload.images = images?.length ? images : undefined;\n\t\t\t\titem.payload.content = [text, ...(images?.map((image) => ({ ...image })) ?? [])];\n\t\t\t} else if (item.payload.content) {\n\t\t\t\titem.payload.content = [text, ...item.payload.content.filter((block) => block.type !== \"text\")];\n\t\t\t}\n\t\t\titem.payload.preview = undefined;\n\t\t\titem.payload.prepared = undefined;\n\t\t\tfor (const record of item.payload.records) {\n\t\t\t\tif (record.role === \"primary\" && record.message.role === \"user\") {\n\t\t\t\t\trecord.message.content = item.payload.content?.map((block) => ({ ...block })) ?? mutation.text;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (item.payload.submitted) {\n\t\t\tconst previous = item.payload.submitted;\n\t\t\tconst content = previous.content\n\t\t\t\t? [\n\t\t\t\t\t\t{ type: \"text\" as const, text: mutation.text },\n\t\t\t\t\t\t...(mutation.images ?? previous.content.filter((block) => block.type !== \"text\")),\n\t\t\t\t\t]\n\t\t\t\t: undefined;\n\t\t\titem.payload.submitted = captureSubmittedInput(mutation.text, {\n\t\t\t\tcontent,\n\t\t\t\timages: mutation.images ?? previous.images,\n\t\t\t});\n\t\t}\n\t\tconst targetPolicy = queuedMessageLaneDeliveryPolicy(mutation.lane);\n\t\tif (targetPolicy !== policy) {\n\t\t\titem.queueKey = undefined;\n\t\t\titem.wake = mutation.lane === \"steering\" ? \"on_lower_boundary\" : \"external_resume\";\n\t\t\tthis._actionStore.moveQueued(item, targetPolicy, this._actionStore.queuedActions(targetPolicy).length);\n\t\t}\n\t\tthis.resumeQueuedWork();\n\t\tthis._emitQueueUpdate();\n\t\treturn \"applied\";\n\t}\n\n\tget queuedActionCount(): number {\n\t\treturn visibleSessionActionProjection(this._actionStore.queuedActions()).length;\n\t}\n\n\tget unfinishedActionCount(): number {\n\t\treturn this._actionStore.unfinishedActions().length;\n\t}\n\n\tget isQueuedWorkSuspended(): boolean {\n\t\treturn this._sessionInputPumpSuspended;\n\t}\n\n\tget isSessionActive(): boolean {\n\t\treturn (\n\t\t\tthis.requests.hasPending ||\n\t\t\tthis._goalResumeOperation !== undefined ||\n\t\t\tthis.isStreaming ||\n\t\t\tthis.isCompacting ||\n\t\t\tthis.isRetrying ||\n\t\t\tthis.isBashRunning ||\n\t\t\tthis._refineInFlight !== undefined ||\n\t\t\tthis._branchSummaryOperation !== undefined ||\n\t\t\tthis._postCompactionContinuationSettlement !== undefined ||\n\t\t\tthis.unfinishedActionCount > 0\n\t\t);\n\t}\n\n\tgetSessionActionSnapshot(): SessionActionSnapshot {\n\t\tconst steering = visibleSessionActionProjection(this._actionStore.queuedActions(\"next_turn_boundary\")).map(\n\t\t\tqueuedAgentMessagePreview,\n\t\t);\n\t\tconst followUps = visibleSessionActionProjection(this._actionStore.queuedActions(\"when_run_idle\")).map(\n\t\t\tqueuedAgentMessagePreview,\n\t\t);\n\t\tconst active = visibleSessionActionProjection(this._actionStore.activeActions())[0];\n\t\tconst activeState = active?.lifecycle.state;\n\t\tconst phase =\n\t\t\tactiveState === \"selected\"\n\t\t\t\t? \"preparing\"\n\t\t\t\t: activeState === \"preparing\" || activeState === \"committing\" || activeState === \"running\"\n\t\t\t\t\t? activeState\n\t\t\t\t\t: undefined;\n\t\treturn {\n\t\t\tqueuedCount: steering.length + followUps.length,\n\t\t\tsteering,\n\t\t\tfollowUps,\n\t\t\t...(active && phase\n\t\t\t\t? {\n\t\t\t\t\t\tactive: {\n\t\t\t\t\t\t\tkind: active.payload.kind,\n\t\t\t\t\t\t\tphase,\n\t\t\t\t\t\t\tlabel: compactRlmText(active.payload.text),\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t};\n\t}\n\n\tgetSteeringMessages(): readonly string[] {\n\t\treturn visibleSessionActionProjection(this._actionStore.queuedActions(\"next_turn_boundary\")).map(\n\t\t\t(action) => action.payload.text,\n\t\t);\n\t}\n\n\tgetSteeringMessagePreviews(): readonly string[] {\n\t\treturn visibleSessionActionProjection(this._actionStore.queuedActions(\"next_turn_boundary\")).map(\n\t\t\tqueuedAgentMessagePreview,\n\t\t);\n\t}\n\n\tgetFollowUpMessages(): readonly string[] {\n\t\treturn visibleSessionActionProjection(this._actionStore.queuedActions(\"when_run_idle\")).map(\n\t\t\t(action) => action.payload.text,\n\t\t);\n\t}\n\n\tgetFollowUpMessagePreviews(): readonly string[] {\n\t\treturn visibleSessionActionProjection(this._actionStore.queuedActions(\"when_run_idle\")).map(\n\t\t\tqueuedAgentMessagePreview,\n\t\t);\n\t}\n\n\tgetSessionActionRecoverySnapshot(): SessionActionRecoverySnapshot {\n\t\tconst actions = this._actionStore.snapshotActions();\n\t\treturn {\n\t\t\tformatVersion: actions.some((action) => action.payload.kind === \"turn\" && action.payload.selectedSkillRef)\n\t\t\t\t? SESSION_ACTION_SKILL_RECOVERY_FORMAT_VERSION\n\t\t\t\t: SESSION_ACTION_RECOVERY_FORMAT_VERSION,\n\t\t\tactions: actions.map((action) => ({\n\t\t\t\tid: action.id,\n\t\t\t\tsource: action.source,\n\t\t\t\tdelivery: action.delivery,\n\t\t\t\twake: action.wake,\n\t\t\t\t...(action.queueKey ? { queueKey: action.queueKey } : {}),\n\t\t\t\t...(action.agentMessageId ? { agentMessageId: action.agentMessageId } : {}),\n\t\t\t\t...(action.suppressAutonomousContinuation ? { suppressAutonomousContinuation: true } : {}),\n\t\t\t\tpayload:\n\t\t\t\t\taction.payload.kind === \"turn\"\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tkind: \"turn\",\n\t\t\t\t\t\t\t\ttext: action.payload.text,\n\t\t\t\t\t\t\t\t...(action.payload.selectedSkillRef\n\t\t\t\t\t\t\t\t\t? { selectedSkillRef: { ...action.payload.selectedSkillRef } }\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t...(action.payload.submitted ? { submitted: structuredClone(action.payload.submitted) } : {}),\n\t\t\t\t\t\t\t\t...(action.payload.preview ? { preview: action.payload.preview } : {}),\n\t\t\t\t\t\t\t\trecords: action.payload.records.map((record) => ({\n\t\t\t\t\t\t\t\t\tid: record.id,\n\t\t\t\t\t\t\t\t\trole: record.role,\n\t\t\t\t\t\t\t\t\tmessage: cloneQueuedAgentMessage(record.message),\n\t\t\t\t\t\t\t\t\townerActionId: record.ownerActionId,\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t...(action.payload.images\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\timages: action.payload.images.map((image) => ({\n\t\t\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t...(action.payload.content\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\tcontent: action.payload.content.map((block) => ({\n\t\t\t\t\t\t\t\t\t\t\t\t...block,\n\t\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t...(action.payload.customMessage\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\tcustomMessage: cloneCustomMessage(action.payload.customMessage),\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\texecutionPolicy: {\n\t\t\t\t\t\t\t\t\t...action.payload.executionPolicy,\n\t\t\t\t\t\t\t\t\tpreparation: {\n\t\t\t\t\t\t\t\t\t\t...action.payload.executionPolicy.preparation,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tqueueVisible: action.payload.queueVisible,\n\t\t\t\t\t\t\t\tacceptedAgentMessage: action.payload.acceptedAgentMessage,\n\t\t\t\t\t\t\t\tacceptedBeforeCompletion: action.payload.acceptedBeforeCompletion,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tkind: \"session_command\",\n\t\t\t\t\t\t\t\ttext: action.payload.text,\n\t\t\t\t\t\t\t\t...(action.payload.submitted ? { submitted: structuredClone(action.payload.submitted) } : {}),\n\t\t\t\t\t\t\t\tcommand: { ...action.payload.command },\n\t\t\t\t\t\t\t\t...(action.payload.images\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\timages: action.payload.images.map((image) => ({\n\t\t\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t},\n\t\t\t})),\n\t\t};\n\t}\n\n\tprivate _notifySessionInputCheckpointChange(): void {\n\t\tconst waiters = [...this._sessionInputCheckpointWaiters];\n\t\tthis._sessionInputCheckpointWaiters.clear();\n\t\tfor (const resolve of waiters) resolve();\n\t}\n\n\tprivate _waitForSessionActivityChange(signal: AbortSignal): Promise<void> {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst finish = () => {\n\t\t\t\tthis._sessionInputCheckpointWaiters.delete(finish);\n\t\t\t\tsignal.removeEventListener(\"abort\", finish);\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tthis._sessionInputCheckpointWaiters.add(finish);\n\t\t\tsignal.addEventListener(\"abort\", finish, { once: true });\n\t\t\tif (signal.aborted) finish();\n\t\t});\n\t}\n\n\tprivate _observeSessionActionDeferral(action: QueuedSessionAction): {\n\t\tdeferred: Promise<void>;\n\t\tstop(): void;\n\t} {\n\t\tlet resolveDeferral = () => {};\n\t\tconst deferred = new Promise<void>((resolve) => {\n\t\t\tresolveDeferral = resolve;\n\t\t});\n\t\tconst check = () => {\n\t\t\tif (action.lifecycle.state === \"queued\") resolveDeferral();\n\t\t\telse this._sessionInputCheckpointWaiters.add(check);\n\t\t};\n\t\tthis._sessionInputCheckpointWaiters.add(check);\n\t\treturn {\n\t\t\tdeferred,\n\t\t\tstop: () => this._sessionInputCheckpointWaiters.delete(check),\n\t\t};\n\t}\n\n\tasync waitForSessionInputCheckpoint(signal?: AbortSignal): Promise<void> {\n\t\tconst blocksCheckpoint = () =>\n\t\t\tthis._actionStore.activeActions().some((action) => {\n\t\t\t\tif (action.payload.kind === \"session_command\") {\n\t\t\t\t\treturn action.lifecycle.state === \"selected\" || action.lifecycle.state === \"running\";\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\taction.lifecycle.state === \"selected\" ||\n\t\t\t\t\taction.lifecycle.state === \"preparing\" ||\n\t\t\t\t\t(action.lifecycle.state === \"committing\" && !primaryDeliveryRecord(action).durable)\n\t\t\t\t);\n\t\t\t});\n\t\twhile (true) {\n\t\t\twhile (blocksCheckpoint()) {\n\t\t\t\tif (signal?.aborted) throw new Error(\"Update restart preparation cancelled\");\n\t\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\t\tconst onChange = () => {\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t};\n\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new Error(\"Update restart preparation cancelled\"));\n\t\t\t\t\t};\n\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\tthis._sessionInputCheckpointWaiters.delete(onChange);\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t};\n\t\t\t\t\tthis._sessionInputCheckpointWaiters.add(onChange);\n\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\tif (signal?.aborted) onAbort();\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst commitFence = await this._acquireSessionActionCommitFence(signal);\n\t\t\ttry {\n\t\t\t\tif (blocksCheckpoint()) continue;\n\t\t\t\tif (signal?.aborted) throw new Error(\"Update restart preparation cancelled\");\n\t\t\t\tawait waitForPromiseOrAbort(this._agentEventQueue, signal, \"Update restart preparation cancelled\");\n\t\t\t\tif (signal?.aborted) throw new Error(\"Update restart preparation cancelled\");\n\t\t\t\tawait this.sessionManager.flushNow();\n\t\t\t\treturn;\n\t\t\t} finally {\n\t\t\t\tcommitFence.release();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _advanceCheckpointPauseEpoch(): void {\n\t\t// A pause invalidates preparations, not already owned checkpoint work. Keep its original source predicate.\n\t\tconst owners = [\n\t\t\tthis._pendingRequestedCompaction?.owner,\n\t\t\tthis._pendingCheckpoint?.owner,\n\t\t\tthis._postCompactionContinuationSettlement?.resume.owner,\n\t\t].filter((owner): owner is CompactionOwner => owner !== undefined && this._isCompactionOwnerCurrent(owner));\n\t\tthis._sessionInputPumpEpoch++;\n\t\tfor (const owner of owners) owner.pumpEpoch = this._sessionInputPumpEpoch;\n\t}\n\n\tacquireSessionInputPause(): { release(): void } {\n\t\tconst token = Symbol(\"session-input-admission-pause\");\n\t\tthis._sessionInputAdmissionPauses.add(token);\n\t\tthis._sessionInputPumpRequested = false;\n\t\tthis._advanceCheckpointPauseEpoch();\n\t\tlet released = false;\n\t\treturn {\n\t\t\trelease: () => {\n\t\t\t\tif (released) return;\n\t\t\t\treleased = true;\n\t\t\t\tthis._sessionInputAdmissionPauses.delete(token);\n\t\t\t\tthis._advanceCheckpointPauseEpoch();\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\tthis._flushDeferredRlmTerminalNotices();\n\t\t\t\tthis._scheduleGoalContinuationAfterRlmWork();\n\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t},\n\t\t};\n\t}\n\n\tacquireQueuedWorkPause(): { release(): void } {\n\t\tconst token = Symbol(\"queued-work-pause\");\n\t\tthis._queuedWorkPauses.add(token);\n\t\tthis._sessionInputPumpRequested = false;\n\t\tthis._advanceCheckpointPauseEpoch();\n\t\tlet released = false;\n\t\treturn {\n\t\t\trelease: () => {\n\t\t\t\tif (released) return;\n\t\t\t\treleased = true;\n\t\t\t\tthis._queuedWorkPauses.delete(token);\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\tthis._flushDeferredRlmTerminalNotices();\n\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate async _acquireDirectTurnAdmissionFence(signal?: AbortSignal): Promise<{ owner: symbol; release(): void }> {\n\t\tconst inheritedOwner = this._sessionActionCommitContext.getStore();\n\t\tif (inheritedOwner !== undefined && inheritedOwner === this._sessionActionCommitOwner) {\n\t\t\tthis._assertSessionActionAdmissionAvailable();\n\t\t\treturn this._acquireSessionActionCommitFence(signal);\n\t\t}\n\t\tconst disposeSignal = this._sessionActionCommitDisposeAbortController.signal;\n\t\tconst waitSignal = signal ? AbortSignal.any([signal, disposeSignal]) : disposeSignal;\n\t\twhile (true) {\n\t\t\tthis._assertSessionActionAdmissionAvailable();\n\t\t\tif (this._queuedWorkPauses.size > 0) {\n\t\t\t\tlet wake = () => {};\n\t\t\t\tconst pauseReleased = new Promise<void>((resolve) => {\n\t\t\t\t\twake = resolve;\n\t\t\t\t\tthis._sessionInputCheckpointWaiters.add(resolve);\n\t\t\t\t});\n\t\t\t\ttry {\n\t\t\t\t\tawait waitForPromiseOrAbort(pauseReleased, waitSignal, \"Update restart preparation cancelled\");\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (disposeSignal.aborted) {\n\t\t\t\t\t\tthrow new Error(\"Cannot admit a session action because the session is disposing or disposed.\");\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t} finally {\n\t\t\t\t\tthis._sessionInputCheckpointWaiters.delete(wake);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst fence = await this._acquireSessionActionCommitFence(signal);\n\t\t\ttry {\n\t\t\t\tif (this._queuedWorkPauses.size === 0) {\n\t\t\t\t\tthis._assertSessionActionAdmissionAvailable();\n\t\t\t\t\treturn fence;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tfence.release();\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tfence.release();\n\t\t}\n\t}\n\n\tprivate async _acquireSessionActionCommitFence(signal?: AbortSignal): Promise<{ owner: symbol; release(): void }> {\n\t\tconst inheritedOwner = this._sessionActionCommitContext.getStore();\n\t\tif (inheritedOwner !== undefined && inheritedOwner === this._sessionActionCommitOwner) {\n\t\t\treturn { owner: inheritedOwner, release: () => {} };\n\t\t}\n\t\tconst previous = this._sessionActionCommitTail;\n\t\tlet resolve = () => {};\n\t\tthis._sessionActionCommitTail = new Promise<void>((release) => {\n\t\t\tresolve = release;\n\t\t});\n\t\tconst disposeSignal = this._sessionActionCommitDisposeAbortController.signal;\n\t\tconst waitSignal = signal ? AbortSignal.any([signal, disposeSignal]) : disposeSignal;\n\t\tthis._pendingSessionActionFenceWaiters++;\n\t\ttry {\n\t\t\tawait waitForPromiseOrAbort(previous, waitSignal, \"Update restart preparation cancelled\");\n\t\t} catch (error) {\n\t\t\tthis._pendingSessionActionFenceWaiters--;\n\t\t\t// A cancelled waiter remains in the FIFO chain until its predecessor releases.\n\t\t\tvoid previous.then(resolve, resolve);\n\t\t\tif (disposeSignal.aborted) {\n\t\t\t\tthrow new Error(\"Cannot admit a session action because the session is disposing or disposed.\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tconst owner = Symbol(\"session-action-commit\");\n\t\tthis._sessionActionCommitOwner = owner;\n\t\tthis._pendingSessionActionFenceWaiters--;\n\t\tlet released = false;\n\t\treturn {\n\t\t\towner,\n\t\t\trelease: () => {\n\t\t\t\tif (released) return;\n\t\t\t\treleased = true;\n\t\t\t\tif (this._sessionActionCommitOwner === owner) this._sessionActionCommitOwner = undefined;\n\t\t\t\tresolve();\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate _resumeSessionInputAdmission(): void {\n\t\tif (!this._sessionInputPumpSuspended) return;\n\t\tthis._sessionInputPumpSuspended = false;\n\t\tthis._sessionInputSuspendedForUpdateRestart = false;\n\t\tthis._sessionInputPumpEpoch++;\n\t\tthis._notifySessionInputCheckpointChange();\n\t\tthis._flushDeferredRlmTerminalNotices();\n\t}\n\n\t/** Resume the scheduler after requestAbort/abortForUpdateRestart suspended it; owned pause leases are unaffected. */\n\tresumeQueuedWork(): boolean {\n\t\tthis._resumeSessionInputAdmission();\n\t\tthis._scheduleGoalContinuationAfterRlmWork();\n\t\tthis._scheduleSessionInputPump();\n\t\treturn this._hasSelectableSessionInput();\n\t}\n\n\tasync waitForSessionInputIdle(): Promise<void> {\n\t\twhile (true) {\n\t\t\tconst pump = this._sessionInputPump;\n\t\t\tawait pump;\n\t\t\tif (pump === this._sessionInputPump && !this._sessionInputPumpRequested) return;\n\t\t}\n\t}\n\n\tasync waitForIdle(): Promise<void> {\n\t\tawait this._waitForIdleOrSettlement();\n\t}\n\n\t/**\n\t * {@link waitForIdle} loop; with a settlement, returns once that settlement is\n\t * superseded so a cancelled post-compaction runner cannot keep a checkpoint\n\t * waiter registered (a leaked waiter holds hasPendingAdmissionWaiters true and\n\t * blocks daemon passivation).\n\t */\n\tprivate async _waitForIdleOrSettlement(settlement?: PostCompactionContinuationSettlement): Promise<void> {\n\t\tconst owner = settlement?.resume.owner;\n\t\tconst current = () => !owner || this._isCompactionOwnerCurrent(owner);\n\t\twhile (current() && (settlement === undefined || this._postCompactionContinuationSettlement === settlement)) {\n\t\t\tif (this._actionStore.queuedActions().length > 0) {\n\t\t\t\t// A blocked pump must wait for a checkpoint change, not spin in\n\t\t\t\t// microtasks and starve the IO that clears its busy state.\n\t\t\t\tif (this._isBusyForSessionInput(\"pump\") || (settlement && this._sessionInputAdmissionPauses.size > 0)) {\n\t\t\t\t\tlet wake = () => {};\n\t\t\t\t\tconst changed = new Promise<void>((resolve) => {\n\t\t\t\t\t\twake = resolve;\n\t\t\t\t\t\tthis._sessionInputCheckpointWaiters.add(resolve);\n\t\t\t\t\t});\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait (settlement ? Promise.race([changed, settlement.promise]) : changed);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tthis._sessionInputCheckpointWaiters.delete(wake);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t}\n\t\t\tconst pump = this._sessionInputPump;\n\t\t\tawait pump;\n\t\t\tif (!current()) return;\n\t\t\tawait (owner?.agent ?? this.agent).waitForIdle();\n\t\t\tif (!current()) return;\n\t\t\tconst agentEventQueue = this._agentEventQueue;\n\t\t\tawait agentEventQueue;\n\t\t\tif (!current()) return;\n\t\t\tconst goalResumeOperation = this._goalResumeOperation;\n\t\t\tawait goalResumeOperation;\n\t\t\tif (!current()) return;\n\t\t\tconst requestSettlement = (owner?.requests ?? this.requests).waitForIdle();\n\t\t\tawait (settlement ? Promise.race([requestSettlement, settlement.promise]) : requestSettlement);\n\t\t\tif (!current() || (settlement && this._postCompactionContinuationSettlement !== settlement)) return;\n\t\t\tif (\n\t\t\t\tpump === this._sessionInputPump &&\n\t\t\t\tagentEventQueue === this._agentEventQueue &&\n\t\t\t\tthis._goalResumeOperation === undefined &&\n\t\t\t\t!this._sessionInputPumpRequested &&\n\t\t\t\t!this.agent.state.isStreaming &&\n\t\t\t\t!this.requests.hasPending &&\n\t\t\t\tthis.unfinishedActionCount === 0\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Waits out any owned post-compaction continuation and rejects when one cannot start; {@link waitForIdle} never rejects. */\n\tasync waitForHeadlessIdle(): Promise<void> {\n\t\twhile (true) {\n\t\t\tawait this.waitForIdle();\n\t\t\tconst postCompactionContinuation = this._postCompactionContinuationSettlement?.promise;\n\t\t\tif (!postCompactionContinuation) return;\n\t\t\tawait postCompactionContinuation;\n\t\t}\n\t}\n\n\tgetPendingNextTurnMessageSnapshots(): readonly CustomMessage[] {\n\t\tconst messages = this._pendingNextTurnMessages.map((message) => cloneCustomMessage(message));\n\t\tfor (const action of this._actionStore.unfinishedActions()) {\n\t\t\tif (\n\t\t\t\taction.payload.kind !== \"turn\" ||\n\t\t\t\t!action.payload.acceptedAgentMessage ||\n\t\t\t\t!primaryDeliveryRecord(action).started\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmessages.push(\n\t\t\t\t...action.payload.records\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(record): record is DeliveryRecord & { message: CustomMessage } =>\n\t\t\t\t\t\t\t(record.role === \"next_turn\" || record.role === \"prefix\") &&\n\t\t\t\t\t\t\trecord.message.role === \"custom\" &&\n\t\t\t\t\t\t\t!record.durable,\n\t\t\t\t\t)\n\t\t\t\t\t.map((record) => cloneCustomMessage(record.message)),\n\t\t\t);\n\t\t}\n\t\treturn messages;\n\t}\n\n\trestorePendingNextTurnMessages(messages: readonly CustomMessage[]): void {\n\t\tthis._pendingNextTurnMessages.push(...messages.map((message) => cloneCustomMessage(message)));\n\t\tthis._flushDeferredRlmTerminalNotices();\n\t}\n\n\tremoveQueuedFollowUp(queueKey: string): boolean {\n\t\tconst matching = this._actionStore\n\t\t\t.clearableActions()\n\t\t\t.filter((action) => action.payload.kind === \"turn\" && action.queueKey === queueKey);\n\t\tif (matching.length === 0) return false;\n\t\tconst error = new Error(\"Queued agent message was cleared before delivery.\");\n\t\tfor (const action of matching) this._rejectAgentMessage(action.agentMessageId, error);\n\t\tconst ids = new Set(matching.map((action) => action.id));\n\t\tthis._cancelSessionActions((action) => ids.has(action.id), error);\n\t\tthis._emitQueueUpdate();\n\t\treturn true;\n\t}\n\n\tget resourceLoader(): ResourceLoader {\n\t\treturn this._resourceLoader;\n\t}\n\n\trequestAbort(): void {\n\t\tfor (const run of [...this._unsettledRlmChildRuns]) {\n\t\t\tif (run.status === \"cancelled\") this._abandonRlmRunForQuiescence(run);\n\t\t}\n\t\tfor (const controller of this._rlmQuiescenceWaitAborts) controller.abort();\n\t\tthis._sessionInputPumpRequested = false;\n\t\tthis._sessionInputPumpEpoch++;\n\t\tthis._sessionInputPumpSuspended = true;\n\t\tthis._sessionInputSuspendedForUpdateRestart = false;\n\t\tthis._demoteRlmTerminalNoticeActions();\n\t\tthis._cancelSessionActions(\n\t\t\t(action) =>\n\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t!action.payload.queueVisible &&\n\t\t\t\t!this._durableRlmTerminalNoticeActionIds.has(action.id),\n\t\t\tnew Error(\"Prompt aborted before delivery.\"),\n\t\t);\n\t\tthis._cancelPostCompactionContinue();\n\t\tthis.abortRetry();\n\t\tthis.abortCompaction();\n\t\tthis.abortBranchSummary();\n\t\tthis.abortBash();\n\t\tthis._pendingRequestedRefine = undefined;\n\t\tthis._autoRefineBranchVersion++;\n\t\tthis._autoRefineReviewAbort?.abort();\n\t\tthis._refineAbortController?.abort();\n\t\tthis.agent.abort();\n\t}\n\n\tasync abort(): Promise<void> {\n\t\tconst compactionOperation = this._compactionOperation;\n\t\tconst branchSummaryOperation = this._branchSummaryOperation;\n\t\tthis.requestAbort();\n\t\tthis._cancelActiveRlmChildRuns(\"Parent session aborted\");\n\t\tthis._goalAbortInProgress = this._goalState.status === \"active\";\n\t\ttry {\n\t\t\tawait Promise.allSettled([\n\t\t\t\tthis.agent.waitForIdle(),\n\t\t\t\tthis._agentEventQueue,\n\t\t\t\t...(compactionOperation ? [compactionOperation] : []),\n\t\t\t\t...(branchSummaryOperation ? [branchSummaryOperation] : []),\n\t\t\t]);\n\t\t} finally {\n\t\t\tthis._goalAbortInProgress = false;\n\t\t}\n\t}\n\n\tabortForUpdateRestart(): void {\n\t\t// Cancel scheduled pumps and suspend new ones: queued inputs must survive\n\t\t// into the restart manifest instead of starting a turn during teardown.\n\t\tthis._sessionInputPumpRequested = false;\n\t\tthis._sessionInputPumpEpoch++;\n\t\tthis._sessionInputPumpSuspended = true;\n\t\tthis._sessionInputSuspendedForUpdateRestart = true;\n\t\tthis._cancelPostCompactionContinue();\n\t\tthis.abortRetry();\n\t\tfor (const controller of this._rlmQuiescenceWaitAborts) controller.abort();\n\t\tthis._cancelActiveRlmChildRuns(\"Parent session aborted for update restart\");\n\t\tthis._goalAbortInProgress = this._goalState.status === \"active\";\n\t\tthis.agent.abort();\n\t\tif (this._goalAbortInProgress) {\n\t\t\tvoid this.agent\n\t\t\t\t.waitForIdle()\n\t\t\t\t.then(() => this._agentEventQueue)\n\t\t\t\t.catch(() => undefined)\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis._goalAbortInProgress = false;\n\t\t\t\t});\n\t\t}\n\t}\n\n\tprivate async _emitModelSelect(\n\t\tnextModel: Model<any>,\n\t\tpreviousModel: Model<any> | undefined,\n\t\tsource: \"set\" | \"cycle\" | \"restore\",\n\t): Promise<void> {\n\t\tif (modelsAreEqual(previousModel, nextModel)) return;\n\t\tawait this._extensionRunner.emit({\n\t\t\ttype: \"model_select\",\n\t\t\tmodel: nextModel,\n\t\t\tpreviousModel,\n\t\t\tsource,\n\t\t});\n\t}\n\n\tprivate _queueModelSelectEmit(\n\t\tnextModel: Model<any>,\n\t\tpreviousModel: Model<any> | undefined,\n\t\tsource: \"set\" | \"cycle\" | \"restore\",\n\t): Promise<void> {\n\t\tconst emit = () =>\n\t\t\tthis._modelSelectEmitContext.run(true, () => this._emitModelSelect(nextModel, previousModel, source));\n\t\tthis._modelSelectEmitQueueIdle = false;\n\t\tconst promise = this._modelSelectEmitQueue.then(emit, emit);\n\t\tconst queued = promise.catch(() => {});\n\t\tthis._modelSelectEmitQueue = queued;\n\t\tvoid queued.finally(() => {\n\t\t\tif (this._modelSelectEmitQueue === queued) {\n\t\t\t\tthis._modelSelectEmitQueueIdle = true;\n\t\t\t}\n\t\t});\n\t\treturn promise;\n\t}\n\n\tasync setModel(model: Model<any>, options: ModelSelectOptions = {}): Promise<void> {\n\t\tmodel = { ...model, cost: { ...model.cost } };\n\t\tconst sourceId = this.sessionManager.getSessionId();\n\t\tconst sourceFile = this.sessionManager.getSessionFile();\n\t\tconst previousModel = this.model;\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch();\n\t\tconst serviceTier = this._getServiceTierForModelSwitch();\n\t\tif (!this._modelRegistry.hasConfiguredAuth(model)) {\n\t\t\tthrow new Error(`No API key for ${model.provider}/${model.id}`);\n\t\t}\n\t\tif (!(await this._modelRegistry.canUseModel(model))) {\n\t\t\tthrow new Error(`Model \"${model.provider}/${model.id}\" is not available with the configured authentication.`);\n\t\t}\n\n\t\tif (this.sessionManager.getSessionId() !== sourceId || this.sessionManager.getSessionFile() !== sourceFile) {\n\t\t\tthrow new Error(\"Session source changed during model selection\");\n\t\t}\n\t\tawait this.sessionManager.appendModelChange(model.provider, model.id);\n\t\tthis.agent.state.model = model;\n\t\tthis.settingsManager.setDefaultModelAndProvider(model.provider, model.id);\n\n\t\tawait this.setThinkingLevel(thinkingLevel);\n\t\tthis._clampServiceTierForModel(serviceTier);\n\n\t\tconst emitPromise = this._queueModelSelectEmit(model, previousModel, \"set\");\n\t\tif (this._shouldWaitForModelSelectEmit(options)) {\n\t\t\tawait emitPromise;\n\t\t} else {\n\t\t\tthis._trackModelSelectEmitError(emitPromise);\n\t\t}\n\t}\n\n\tprivate _trackModelSelectEmitError(emitPromise: Promise<void>): void {\n\t\tvoid emitPromise.catch((error) => {\n\t\t\tthis._extensionRunner.emitError({\n\t\t\t\textensionPath: \"<internal>\",\n\t\t\t\tevent: \"model_select\",\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate _shouldWaitForModelSelectEmit(options: ModelSelectOptions): boolean {\n\t\treturn options.waitForExtensions !== false && !this._modelSelectEmitContext.getStore();\n\t}\n\n\tprivate _pendingModelSelectEmit(): Promise<void> | undefined {\n\t\tif (!this._modelSelectEmitContext.getStore() && !this._modelSelectEmitQueueIdle) {\n\t\t\treturn this._modelSelectEmitQueue;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tasync cycleModel(\n\t\tdirection: \"forward\" | \"backward\" = \"forward\",\n\t\toptions: ModelSelectOptions = {},\n\t): Promise<ModelCycleResult | undefined> {\n\t\tif (this._scopedModels.length > 0) {\n\t\t\treturn this._cycleScopedModel(direction, options);\n\t\t}\n\t\treturn this._cycleAvailableModel(direction, options);\n\t}\n\n\tprivate async _cycleScopedModel(\n\t\tdirection: \"forward\" | \"backward\",\n\t\toptions: ModelSelectOptions,\n\t): Promise<ModelCycleResult | undefined> {\n\t\tconst availableModels = await this._modelRegistry.refreshAvailableModels();\n\t\tconst scopedModels = this._scopedModels.filter((scoped) =>\n\t\t\tavailableModels.some((model) => modelsAreEqual(model, scoped.model)),\n\t\t);\n\t\tif (scopedModels.length <= 1) return undefined;\n\n\t\tconst currentModel = this.model;\n\t\tlet currentIndex = scopedModels.findIndex((sm) => modelsAreEqual(sm.model, currentModel));\n\n\t\tif (currentIndex === -1) currentIndex = 0;\n\t\tconst len = scopedModels.length;\n\t\tconst nextIndex = direction === \"forward\" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;\n\t\tconst next = scopedModels[nextIndex];\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch(next.thinkingLevel);\n\t\tconst serviceTier = this._getServiceTierForModelSwitch();\n\n\t\tawait this.sessionManager.appendModelChange(next.model.provider, next.model.id);\n\t\tthis.agent.state.model = next.model;\n\t\tthis.settingsManager.setDefaultModelAndProvider(next.model.provider, next.model.id);\n\n\t\tawait this.setThinkingLevel(thinkingLevel);\n\t\tthis._clampServiceTierForModel(serviceTier);\n\n\t\tconst emitPromise = this._queueModelSelectEmit(next.model, currentModel, \"cycle\");\n\t\tif (this._shouldWaitForModelSelectEmit(options)) {\n\t\t\tawait emitPromise;\n\t\t} else {\n\t\t\tthis._trackModelSelectEmitError(emitPromise);\n\t\t}\n\n\t\treturn {\n\t\t\tmodel: next.model,\n\t\t\tthinkingLevel: this.thinkingLevel,\n\t\t\tserviceTier: this.serviceTier,\n\t\t\tisScoped: true,\n\t\t};\n\t}\n\n\tprivate async _cycleAvailableModel(\n\t\tdirection: \"forward\" | \"backward\",\n\t\toptions: ModelSelectOptions,\n\t): Promise<ModelCycleResult | undefined> {\n\t\tconst availableModels = await this._modelRegistry.refreshAvailableModels();\n\t\tif (availableModels.length <= 1) return undefined;\n\n\t\tconst currentModel = this.model;\n\t\tlet currentIndex = availableModels.findIndex((m) => modelsAreEqual(m, currentModel));\n\n\t\tif (currentIndex === -1) currentIndex = 0;\n\t\tconst len = availableModels.length;\n\t\tconst nextIndex = direction === \"forward\" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;\n\t\tconst nextModel = availableModels[nextIndex];\n\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch();\n\t\tconst serviceTier = this._getServiceTierForModelSwitch();\n\t\tawait this.sessionManager.appendModelChange(nextModel.provider, nextModel.id);\n\t\tthis.agent.state.model = nextModel;\n\t\tthis.settingsManager.setDefaultModelAndProvider(nextModel.provider, nextModel.id);\n\n\t\tawait this.setThinkingLevel(thinkingLevel);\n\t\tthis._clampServiceTierForModel(serviceTier);\n\n\t\tconst emitPromise = this._queueModelSelectEmit(nextModel, currentModel, \"cycle\");\n\t\tif (this._shouldWaitForModelSelectEmit(options)) {\n\t\t\tawait emitPromise;\n\t\t} else {\n\t\t\tthis._trackModelSelectEmitError(emitPromise);\n\t\t}\n\n\t\treturn {\n\t\t\tmodel: nextModel,\n\t\t\tthinkingLevel: this.thinkingLevel,\n\t\t\tserviceTier: this.serviceTier,\n\t\t\tisScoped: false,\n\t\t};\n\t}\n\n\tasync setThinkingLevel(level: ThinkingLevel): Promise<void> {\n\t\tconst availableLevels = this.getAvailableThinkingLevels();\n\t\tconst effectiveLevel = availableLevels.includes(level) ? level : this._clampThinkingLevel(level, availableLevels);\n\n\t\tconst previousLevel = this.agent.state.thinkingLevel;\n\t\tconst isChanging = effectiveLevel !== previousLevel;\n\n\t\tif (isChanging) {\n\t\t\tawait this.sessionManager.appendThinkingLevelChange(effectiveLevel);\n\t\t\tthis.agent.state.thinkingLevel = effectiveLevel;\n\t\t\tif (this.supportsThinking() || effectiveLevel !== \"off\") {\n\t\t\t\tthis.settingsManager.setDefaultThinkingLevel(effectiveLevel);\n\t\t\t}\n\t\t\tthis._emit({ type: \"thinking_level_changed\", level: effectiveLevel });\n\t\t\tawait this._extensionRunner.emit({\n\t\t\t\ttype: \"thinking_level_select\",\n\t\t\t\tlevel: effectiveLevel,\n\t\t\t\tpreviousLevel,\n\t\t\t});\n\t\t}\n\t}\n\n\tasync setServiceTier(serviceTier: ServiceTier): Promise<void> {\n\t\tconst effectiveServiceTier = this._getEffectiveServiceTier(serviceTier);\n\t\tconst preferenceChanged = effectiveServiceTier !== this._serviceTierPreference;\n\t\tconst effectiveTierChanged = effectiveServiceTier !== this.agent.state.serviceTier;\n\t\tif (!preferenceChanged && !effectiveTierChanged) {\n\t\t\treturn;\n\t\t}\n\t\tif (preferenceChanged) {\n\t\t\tawait this.sessionManager.appendServiceTierChange(effectiveServiceTier);\n\t\t\tthis._serviceTierPreference = effectiveServiceTier;\n\t\t\tif (this.model && supportsFastMode(this.model)) {\n\t\t\t\tthis.settingsManager.setDefaultServiceTier(effectiveServiceTier);\n\t\t\t}\n\t\t}\n\t\tif (effectiveTierChanged) {\n\t\t\tthis.agent.state.serviceTier = effectiveServiceTier;\n\t\t\tthis._emit({\n\t\t\t\ttype: \"service_tier_changed\",\n\t\t\t\tserviceTier: effectiveServiceTier,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate _getEffectiveServiceTier(serviceTier: ServiceTier): ServiceTier {\n\t\treturn serviceTier === \"priority\" && (!this.model || !supportsFastMode(this.model)) ? \"default\" : serviceTier;\n\t}\n\n\tprivate _getServiceTierForModelSwitch(): ServiceTier {\n\t\treturn this._serviceTierPreference;\n\t}\n\n\tprivate _clampServiceTierForModel(serviceTier: ServiceTier = this.serviceTier): void {\n\t\tconst effectiveServiceTier = this._getEffectiveServiceTier(serviceTier);\n\t\tif (effectiveServiceTier === this.agent.state.serviceTier) {\n\t\t\treturn;\n\t\t}\n\t\tthis.agent.state.serviceTier = effectiveServiceTier;\n\t\tthis._emit({\n\t\t\ttype: \"service_tier_changed\",\n\t\t\tserviceTier: effectiveServiceTier,\n\t\t});\n\t}\n\n\tasync cycleThinkingLevel(): Promise<ThinkingLevel | undefined> {\n\t\tif (!this.supportsThinking()) return undefined;\n\n\t\tconst levels = this.getAvailableThinkingLevels();\n\t\tconst currentIndex = levels.indexOf(this.thinkingLevel);\n\t\tconst nextIndex = (currentIndex + 1) % levels.length;\n\t\tconst nextLevel = levels[nextIndex];\n\n\t\tawait this.setThinkingLevel(nextLevel);\n\t\treturn nextLevel;\n\t}\n\n\tgetAvailableThinkingLevels(): ThinkingLevel[] {\n\t\tif (!this.model) return THINKING_LEVELS;\n\t\treturn getSupportedThinkingLevels(this.model) as ThinkingLevel[];\n\t}\n\n\tsupportsThinking(): boolean {\n\t\treturn !!this.model?.reasoning;\n\t}\n\n\tprivate _getThinkingLevelForModelSwitch(explicitLevel?: ThinkingLevel): ThinkingLevel {\n\t\tif (explicitLevel !== undefined) {\n\t\t\treturn explicitLevel;\n\t\t}\n\t\tif (!this.supportsThinking()) {\n\t\t\treturn this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t\t}\n\t\treturn this.thinkingLevel;\n\t}\n\n\tprivate _clampThinkingLevel(level: ThinkingLevel, _availableLevels: ThinkingLevel[]): ThinkingLevel {\n\t\treturn this.model ? (clampThinkingLevel(this.model, level) as ThinkingLevel) : \"off\";\n\t}\n\n\tprivate _captureKernelResource(): OwnedResourceCapture {\n\t\tconst provisioner = this._ipythonKernelProvisioner;\n\t\tconst captured = provisioner ? captureOwnedKernelState.call(provisioner) : undefined;\n\t\treturn Object.freeze({\n\t\t\tenabled: this._contextEpochsEnabled,\n\t\t\tsnapshot:\n\t\t\t\tcaptured?.snapshot ??\n\t\t\t\tObject.freeze({\n\t\t\t\t\tsource: \"unobserved\" as const,\n\t\t\t\t\towner: null,\n\t\t\t\t\tgeneration: null,\n\t\t\t\t\tstate: \"unobserved\" as const,\n\t\t\t\t}),\n\t\t\tisCurrent: () => this._ipythonKernelProvisioner === provisioner && (captured?.isCurrent() ?? true),\n\t\t});\n\t}\n\n\tprivate async _syncKernelStateAfterCompaction(owner = this._captureCompactionOwner()): Promise<void> {\n\t\tthis._assertCompactionOwner(owner);\n\t\tconst provisioner = owner.provisioner;\n\t\tif (!provisioner?.hasRunningKernel) return;\n\t\tconst pruned = await provisioner.pruneOversizedVariables().catch(() => null);\n\t\tthis._assertCompactionOwner(owner);\n\t\tconst abort = new AbortController();\n\t\tconst timer = setTimeout(() => abort.abort(), KERNEL_STATE_LISTING_TIMEOUT_MS);\n\t\tif (typeof timer === \"object\" && \"unref\" in timer) timer.unref();\n\t\tlet names: string[] | null;\n\t\ttry {\n\t\t\tnames = await provisioner.listNamespaceNames(abort.signal).catch(() => null);\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t\tthis._assertCompactionOwner(owner);\n\t\tif (names === null && !provisioner.hasRunningKernel) return;\n\t\tconst detail =\n\t\t\tnames === null\n\t\t\t\t? \"\"\n\t\t\t\t: names.length > 0\n\t\t\t\t\t? ` These names are still defined: ${names.join(\", \")}.`\n\t\t\t\t\t: \" You have not defined any names yet.\";\n\t\tconst prunedDetail =\n\t\t\tpruned && pruned.length > 0\n\t\t\t\t? ` Variables above the per-variable snapshot limit were removed: ${pruned.join(\", \")}.`\n\t\t\t\t: \"\";\n\t\tconst content = [\n\t\t\t\"<ipython_state>\",\n\t\t\t`Your Python kernel persisted through compaction; its remaining variables, imports, and helpers are still available.${prunedDetail}${detail}`,\n\t\t\t\"</ipython_state>\",\n\t\t].join(\"\\n\");\n\t\tconst message = {\n\t\t\trole: \"custom\" as const,\n\t\t\tcustomType: \"ipython_state\",\n\t\t\tcontent,\n\t\t\tdisplay: false,\n\t\t\ttimestamp: Date.now(),\n\t\t} satisfies CustomMessage;\n\t\tawait owner.manager.appendCustomMessageEntry(message.customType, message.content, message.display, undefined);\n\t\tthis._assertCompactionOwner(owner);\n\t\tconst messages = owner.agent.state.messages;\n\t\tconst last = messages[messages.length - 1];\n\t\tconst insertBeforeError = last?.role === \"assistant\" && (last as AssistantMessage).stopReason === \"error\";\n\t\tif (insertBeforeError) {\n\t\t\tmessages.splice(messages.length - 1, 0, message);\n\t\t} else {\n\t\t\tmessages.push(message);\n\t\t}\n\t\tthis._emit({ type: \"message_start\", message });\n\t\tthis._emit({ type: \"message_end\", message });\n\t}\n\n\tprivate _onIpythonStateRestored(result: RestoreResult): void {\n\t\tconst lines = [\"<ipython_state_restored>\"];\n\t\tif (result.restored.length > 0) {\n\t\t\tlines.push(\n\t\t\t\t`Your Python kernel state was revived from your previous session. These names are available again: ${result.restored.join(\", \")}.`,\n\t\t\t);\n\t\t} else {\n\t\t\tlines.push(\n\t\t\t\t\"Your previous Python kernel state could not be revived; the kernel is starting fresh, so re-create any variables, imports, or loaded data you need.\",\n\t\t\t);\n\t\t}\n\t\tif (result.failed.length > 0) {\n\t\t\tlines.push(\n\t\t\t\t`These could not be restored and must be recreated if needed: ${result.failed.map((f) => f.name).join(\", \")}.`,\n\t\t\t);\n\t\t}\n\t\tlines.push(\"</ipython_state_restored>\");\n\t\tvoid this.sendCustomMessage(\n\t\t\t{\n\t\t\t\tcustomType: IPYTHON_STATE_RESTORED_CUSTOM_TYPE,\n\t\t\t\tcontent: lines.join(\"\\n\"),\n\t\t\t\tdisplay: true,\n\t\t\t\tdetails: { restored: result.restored.length > 0 },\n\t\t\t},\n\t\t\t{ deliverAs: \"nextTurn\" },\n\t\t).catch(() => {});\n\t}\n\n\tsetSteeringMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.agent.steeringMode = mode;\n\t\tthis.settingsManager.setSteeringMode(mode);\n\t}\n\n\tsetFollowUpMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.agent.followUpMode = mode;\n\t\tthis.settingsManager.setFollowUpMode(mode);\n\t}\n\n\tasync compact(customInstructions?: string, options: { skipAbort?: boolean } = {}): Promise<CompactionResult> {\n\t\tthis._assertContextOptimizationAllowed();\n\t\treturn this._retainContextOptimization(this._compactAccepted(customInstructions, options));\n\t}\n\n\tprivate _resolveCompactionModel(): { model: Model<Api>; thinkingLevel: ThinkingLevel } | undefined {\n\t\tconst selection = this.settingsManager.getCompactionModel();\n\t\tif (selection === undefined) {\n\t\t\tconst model = this.model;\n\t\t\treturn model ? { model: { ...model, cost: { ...model.cost } }, thinkingLevel: this.thinkingLevel } : undefined;\n\t\t}\n\t\tif (\n\t\t\t!selection ||\n\t\t\ttypeof selection !== \"object\" ||\n\t\t\tArray.isArray(selection) ||\n\t\t\ttypeof selection.provider !== \"string\" ||\n\t\t\t!selection.provider.trim() ||\n\t\t\ttypeof selection.modelId !== \"string\" ||\n\t\t\t!selection.modelId.trim() ||\n\t\t\ttypeof selection.thinkingLevel !== \"string\"\n\t\t)\n\t\t\tthrow new Error(\"Invalid compaction.model; expected provider, modelId, and thinkingLevel\");\n\t\tconst model = this._modelRegistry.find(selection.provider, selection.modelId);\n\t\tif (!model) throw new Error(`Unknown compaction.model ${selection.provider}/${selection.modelId}`);\n\t\tif (!getSupportedThinkingLevels(model).includes(selection.thinkingLevel))\n\t\t\tthrow new Error(\n\t\t\t\t`compaction.model thinkingLevel ${selection.thinkingLevel} is not supported by ${selection.provider}/${selection.modelId}`,\n\t\t\t);\n\t\treturn { model: structuredClone(model), thinkingLevel: selection.thinkingLevel };\n\t}\n\n\tprivate async _compactAccepted(\n\t\tcustomInstructions?: string,\n\t\toptions: { skipAbort?: boolean } = {},\n\t): Promise<CompactionResult> {\n\t\tif (this._compactionSetupFailure) throw this._compactionSetupFailure;\n\t\tif (options.skipAbort && this.isStreaming) {\n\t\t\tthrow new Error(\"Cannot compact without aborting while the agent is running.\");\n\t\t}\n\t\tconst sourceOwner = this._captureCompactionOwner();\n\t\tconst consumedRequest = this._pendingRequestedCompaction;\n\t\tconst requestedWasCurrent =\n\t\t\tconsumedRequest !== undefined && this._isCompactionOwnerCurrent(consumedRequest.owner);\n\t\tconst savedResume = this._postCompactionContinuationScheduled\n\t\t\t? this._postCompactionContinuationSettlement?.resume\n\t\t\t: undefined;\n\t\tconst carryResume = savedResume !== undefined && this._isCompactionOwnerCurrent(savedResume.owner);\n\t\tthis._disconnectFromAgent();\n\t\t// Only this operation's own abort advances its control epoch. Do not adopt an epoch after the wait.\n\t\tconst originalOwner = carryResume ? savedResume.owner : requestedWasCurrent ? consumedRequest.owner : sourceOwner;\n\t\tconst owner = {\n\t\t\t...originalOwner,\n\t\t\tsignal: undefined,\n\t\t\tpumpEpoch: sourceOwner.pumpEpoch + (options.skipAbort ? 0 : 1),\n\t\t};\n\t\tif (!options.skipAbort) await this.abort();\n\t\tif (!this._isCompactionOwnerCurrent(owner)) {\n\t\t\tif (this._isCompactionSourceOwnerCurrent(owner)) this._reconnectToAgent();\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t}\n\t\tconst resume = carryResume ? { ...savedResume, owner } : undefined;\n\t\tconst checkpoint = resume ?? { owner, actions: [] };\n\t\tthis._pendingCheckpoint = checkpoint;\n\t\tif (requestedWasCurrent && this._pendingRequestedCompaction === consumedRequest) {\n\t\t\tconsumedRequest.owner = { ...consumedRequest.owner, pumpEpoch: owner.pumpEpoch, signal: undefined };\n\t\t}\n\t\tlet didCompact = false;\n\t\tlet requests: InferenceCoordinator | undefined;\n\t\tlet compaction: BoundCompactionSink | undefined;\n\t\tlet committed: CompactionCommit | undefined;\n\t\tlet failure: unknown;\n\t\tconst abort = new AbortController();\n\t\tthis._compactionAbortController = abort;\n\t\tlet resolveCompactionOperation: () => void = () => {};\n\t\tconst compactionOperation = new Promise<void>((resolve) => {\n\t\t\tresolveCompactionOperation = resolve;\n\t\t});\n\t\tthis._compactionOperation = compactionOperation;\n\t\tthis._emit({\n\t\t\ttype: \"compaction_start\",\n\t\t\treason: \"manual\",\n\t\t\tcustomInstructions,\n\t\t});\n\n\t\ttry {\n\t\t\tconst selected = this._resolveCompactionModel();\n\t\t\tif (!selected) {\n\t\t\t\tthrow new Error(formatNoModelSelectedMessage());\n\t\t\t}\n\n\t\t\tconst { model, thinkingLevel } = selected;\n\t\t\tconst settings = { ...this.settingsManager.getCompactionSettings() };\n\t\t\tconst semanticEdges = owner.semanticEdges;\n\t\t\tcompaction = owner.manager.bindCompactionSink();\n\t\t\trequests = owner.requests.capture(compaction);\n\t\t\tconst pathEntries = await compaction.readBranch();\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tconst { apiKey, headers } = await this._getRequiredRequestAuth(model);\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tcommitted = await this._performCompaction({\n\t\t\t\tmodel,\n\t\t\t\tthinkingLevel,\n\t\t\t\tpathEntries,\n\t\t\t\tsettings,\n\t\t\t\trequests,\n\t\t\t\tcompaction,\n\t\t\t\tsemanticEdges,\n\t\t\t\towner,\n\t\t\t\tapiKey,\n\t\t\t\theaders,\n\t\t\t\tcustomInstructions,\n\t\t\t\tsignal: abort.signal,\n\t\t\t\tallowShortSession: true,\n\t\t\t});\n\n\t\t\tconst result = committed.result;\n\t\t\tawait this._releaseCompactionCapture(requests, compaction, undefined, owner);\n\t\t\trequests = undefined;\n\t\t\tcompaction = undefined;\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tthis._emit({\n\t\t\t\ttype: \"compaction_end\",\n\t\t\t\treason: \"manual\",\n\t\t\t\tresult,\n\t\t\t\taborted: false,\n\t\t\t\twillRetry: false,\n\t\t\t\tcustomInstructions,\n\t\t\t});\n\t\t\tdidCompact = true;\n\t\t\t// A manual compaction satisfies any pending model request; on failure the\n\t\t\t// request stays scheduled for the next turn boundary.\n\t\t\tif (this._pendingRequestedCompaction === consumedRequest) this._pendingRequestedCompaction = undefined;\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tconst primaryCommit = primaryCommittedCompactionError(error);\n\t\t\tconst knownCommit = primaryCommit ?? committed;\n\t\t\tfailure =\n\t\t\t\tknownCommit && !(error instanceof CompactionCommittedError)\n\t\t\t\t\t? new CompactionCommittedError(knownCommit.entryId, knownCommit.result, error)\n\t\t\t\t\t: error;\n\t\t\tif (failure instanceof CompactionCommittedError) {\n\t\t\t\tif (this._pendingRequestedCompaction === consumedRequest) this._pendingRequestedCompaction = undefined;\n\t\t\t\tthis._reportCommittedCompactionFailure(failure, \"manual\", customInstructions, owner);\n\t\t\t\tthrow failure;\n\t\t\t}\n\t\t\tif (!this._isCompactionSourceOwnerCurrent(owner)) throw error;\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tconst aborted = message === \"Compaction cancelled\" || (error instanceof Error && error.name === \"AbortError\");\n\t\t\tconst skipped = error instanceof CompactionSkippedError;\n\t\t\tthis._emit({\n\t\t\t\ttype: \"compaction_end\",\n\t\t\t\treason: \"manual\",\n\t\t\t\tresult: undefined,\n\t\t\t\taborted,\n\t\t\t\twillRetry: false,\n\t\t\t\terrorMessage: aborted ? undefined : skipped ? message : `Compaction failed: ${message}`,\n\t\t\t\terrorSeverity: skipped ? \"warning\" : \"error\",\n\t\t\t\tcustomInstructions,\n\t\t\t});\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait this._releaseCompactionCapture(requests, compaction, failure, owner);\n\t\t\t} finally {\n\t\t\t\tif (this._pendingCheckpoint === checkpoint) this._pendingCheckpoint = undefined;\n\t\t\t\tif (this._compactionAbortController === abort) this._compactionAbortController = undefined;\n\t\t\t\tif (this._isCompactionSourceOwnerCurrent(owner)) this._reconnectToAgent();\n\t\t\t\tif (this._compactionOperation === compactionOperation) {\n\t\t\t\t\tthis._compactionOperation = undefined;\n\t\t\t\t}\n\t\t\t\tresolveCompactionOperation();\n\t\t\t\tif (this._isCompactionOwnerCurrent(owner)) {\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t\t}\n\t\t\t\tif (didCompact && this._isCompactionOwnerCurrent(owner)) {\n\t\t\t\t\tthis._discardPendingAutoRefine({ cancelPostCompactionContinue: true });\n\t\t\t\t\tif (resume) {\n\t\t\t\t\t\tthis._schedulePostCompactionContinue(resume);\n\t\t\t\t\t}\n\t\t\t\t\t// Queued agent or session-owned inputs resume the loop; defer refine\n\t\t\t\t\t// behind them instead of interleaving it before their turns.\n\t\t\t\t\tthis._scheduleAutoRefineAfterCompaction(\n\t\t\t\t\t\tresume !== undefined || this.agent.hasQueuedMessages() || this.unfinishedActionCount > 0,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** A private compiled context keeps extension summary edits separate from retained source recipes. */\n\tprivate async _prepareCapturedCompaction(\n\t\tpathEntries: SessionEntry[],\n\t\tsettings: ReturnType<SettingsManager[\"getCompactionSettings\"]>,\n\t\trequests: InferenceCoordinator,\n\t\tcompaction: BoundCompactionSink,\n\t\towner = this._captureCompactionOwner(),\n\t\tallowShortSession = false,\n\t\tbudgetPressure = false,\n\t\tcapacity?: PublicContextBudgetError,\n\t): Promise<{\n\t\tpreparation: CompactionPreparation | undefined;\n\t\tmessages?: readonly AgentMessage[];\n\t\tresource?: OwnedResourceCapture;\n\t\tmaxSourceBytes: number;\n\t}> {\n\t\tthis._assertCompactionOwner(owner);\n\t\tconst limits = this.settingsManager.getCanonicalContextLimits();\n\t\tconst resource = this._captureKernelResource();\n\t\tconst source = await compaction.source;\n\t\tthis._assertCompactionOwner(owner);\n\t\tif (!source.persistent)\n\t\t\treturn {\n\t\t\t\tpreparation: prepareCompaction(pathEntries, settings, allowShortSession),\n\t\t\t\tmaxSourceBytes: limits.maxSourceBytes,\n\t\t\t};\n\t\treturn requests.readHistory(async (view) => {\n\t\t\tconst messages = await new CanonicalContextCompiler().compile(\n\t\t\t\tview,\n\t\t\t\tlimits,\n\t\t\t\tundefined,\n\t\t\t\t{},\n\t\t\t\tresource,\n\t\t\t\tthis._initialContextMode,\n\t\t\t\tfalse,\n\t\t\t\t\"read\",\n\t\t\t);\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tconst context = getCanonicalEpochContext(messages)!;\n\t\t\tif (context.checkpoint?.includeSummary && pathEntries.at(-1)?.type === \"compaction\")\n\t\t\t\treturn { preparation: undefined, maxSourceBytes: limits.maxSourceBytes };\n\t\t\tconst authorization = getRecoveryCompactionAuthorization(capacity);\n\t\t\tconst boundary = canonicalRecoveryBoundary(messages, authorization);\n\t\t\tconst preparation =\n\t\t\t\tbudgetPressure || context.checkpoint || boundary\n\t\t\t\t\t? prepareViewCompaction(\n\t\t\t\t\t\t\tmessages,\n\t\t\t\t\t\t\tcontext.references.map((ref) => ref?.ref.entryId),\n\t\t\t\t\t\t\tpathEntries,\n\t\t\t\t\t\t\tsettings,\n\t\t\t\t\t\t\tboundary,\n\t\t\t\t\t\t\tallowShortSession,\n\t\t\t\t\t\t\tbudgetPressure,\n\t\t\t\t\t\t)\n\t\t\t\t\t: prepareCompaction(pathEntries, settings, allowShortSession);\n\t\t\t// Refuse unsupported public data or open groups before starting the summary model call.\n\t\t\tif (preparation)\n\t\t\t\tprepareRecoveryCompaction(messages, preparation.firstKeptEntryId, limits.maxSourceBytes, authorization);\n\t\t\treturn {\n\t\t\t\tpreparation,\n\t\t\t\tmessages,\n\t\t\t\tresource: context.resourceRevision !== undefined ? resource : undefined,\n\t\t\t\tmaxSourceBytes: limits.maxSourceBytes,\n\t\t\t};\n\t\t});\n\t}\n\n\t/**\n\t * Shared compaction core behind /compact, auto-compaction, and the compact\n\t * skill. Throws CompactionSkippedError when there is nothing to compact and\n\t * Error(\"Compaction cancelled\") on abort or extension cancel.\n\t */\n\tprivate async _performCompaction(options: {\n\t\tmodel: Model<any>;\n\t\tapiKey: string;\n\t\theaders?: Record<string, string>;\n\t\tcustomInstructions?: string;\n\t\tsignal: AbortSignal;\n\t\tthinkingLevel: ThinkingLevel;\n\t\trequests: InferenceCoordinator;\n\t\tcompaction: BoundCompactionSink;\n\t\tsemanticEdges: SemanticEdgeRecorder;\n\t\towner?: CompactionOwner;\n\t\tpathEntries: Awaited<ReturnType<SessionManager[\"readBranch\"]>>;\n\t\tsettings: ReturnType<SettingsManager[\"getCompactionSettings\"]>;\n\t\tallowShortSession?: boolean;\n\t\tbudgetPressure?: boolean;\n\t\tcapacity?: PublicContextBudgetError;\n\t}): Promise<CompactionCommit> {\n\t\tconst {\n\t\t\tmodel,\n\t\t\tapiKey,\n\t\t\theaders,\n\t\t\tcustomInstructions,\n\t\t\tsignal,\n\t\t\tthinkingLevel,\n\t\t\trequests,\n\t\t\tcompaction,\n\t\t\tsemanticEdges,\n\t\t\tpathEntries,\n\t\t\tsettings,\n\t\t\towner = this._captureCompactionOwner(),\n\t\t\tallowShortSession = false,\n\t\t\tbudgetPressure = false,\n\t\t} = options;\n\n\t\tconst prepared = await this._prepareCapturedCompaction(\n\t\t\tpathEntries,\n\t\t\tsettings,\n\t\t\trequests,\n\t\t\tcompaction,\n\t\t\towner,\n\t\t\tallowShortSession,\n\t\t\tbudgetPressure,\n\t\t\toptions.capacity,\n\t\t);\n\t\tthis._assertCompactionOwner(owner);\n\t\tif (prepared.resource) assertResourceCurrent(prepared.resource);\n\t\tconst preparation = prepared.preparation;\n\t\tif (!preparation) {\n\t\t\tconst lastEntry = pathEntries[pathEntries.length - 1];\n\t\t\tif (lastEntry?.type === \"compaction\") {\n\t\t\t\tthrow new CompactionSkippedError(\"Already compacted\");\n\t\t\t}\n\t\t\tthrow new CompactionSkippedError(\"Session is too short to compact — try again once it grows\");\n\t\t}\n\n\t\tlet extensionCompaction: CompactionResult | undefined;\n\t\tlet nativeCompaction: CompactionResult | undefined;\n\t\tlet fromExtension = false;\n\n\t\tconst semanticCompaction = semanticEdges.beginCompaction();\n\t\tlet committed: CompactionCommit | undefined;\n\t\tconst uncommittedSlices: string[] = [];\n\t\tlet compactionSettled = false;\n\t\tlet summary: string;\n\t\tlet firstKeptEntryId: string;\n\t\tlet tokensBefore: number | null;\n\t\tlet details: CompactionResult[\"details\"];\n\t\tlet usage: CompactionResult[\"usage\"];\n\t\tlet savedCompactionId: string;\n\t\ttry {\n\t\t\tif (owner.extensions.hasHandlers(\"session_before_compact\")) {\n\t\t\t\tconst result = (await owner.extensions.emit({\n\t\t\t\t\ttype: \"session_before_compact\",\n\t\t\t\t\tpreparation,\n\t\t\t\t\tbranchEntries: pathEntries,\n\t\t\t\t\tcustomInstructions,\n\t\t\t\t\tsignal,\n\t\t\t\t})) as SessionBeforeCompactResult | undefined;\n\n\t\t\t\tthis._assertCompactionOwner(owner);\n\t\t\t\tif (result?.cancel) {\n\t\t\t\t\tthrow new Error(\"Compaction cancelled\");\n\t\t\t\t}\n\n\t\t\t\tif (result?.compaction) {\n\t\t\t\t\textensionCompaction = result.compaction;\n\t\t\t\t\tfromExtension = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (extensionCompaction) {\n\t\t\t\t({ summary, firstKeptEntryId, tokensBefore, details, usage } = extensionCompaction);\n\t\t\t} else {\n\t\t\t\t// Each summary wire call gets its own request ID: split turns send two\n\t\t\t\t// different bodies, and one Idempotency-Key must never cover both. A slice\n\t\t\t\t// that succeeds on the wire stays uncommitted until the compaction itself\n\t\t\t\t// commits: a racing sibling's failure (or an abort) must leave no committed\n\t\t\t\t// summary request for the next turn's continuation edge to attach to.\n\t\t\t\tconst summaryCall = async <T>(\n\t\t\t\t\tcall: (callHeaders: Record<string, string> | undefined) => Promise<T>,\n\t\t\t\t): Promise<T> => {\n\t\t\t\t\tconst requestId = semanticEdges.startCompactionRequest(semanticCompaction.compactionId);\n\t\t\t\t\tif (requestId === undefined) {\n\t\t\t\t\t\treturn call(headers);\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await call({ ...headers, ...modelRequestHeaders(requestId) });\n\t\t\t\t\t\t// A slice resolving after a sibling's rejection already settled the\n\t\t\t\t\t\t// compaction would push into a drained list and stay in-flight forever.\n\t\t\t\t\t\tif (compactionSettled) {\n\t\t\t\t\t\t\tsemanticEdges.failRequest(requestId);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tuncommittedSlices.push(requestId);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tsemanticEdges.failRequest(requestId);\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tconst summaryRequests = requests[captureNativeCompactionRequests]();\n\t\t\t\tlet summaryFailure: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tnativeCompaction = await compact(\n\t\t\t\t\t\tpreparation,\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tapiKey,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tcustomInstructions,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\tthinkingLevel,\n\t\t\t\t\t\tsummaryCall,\n\t\t\t\t\t\tsummaryRequests,\n\t\t\t\t\t\toptions.capacity\n\t\t\t\t\t\t\t? (wrapper) =>\n\t\t\t\t\t\t\t\t\toptions.capacity!.remainingSummaryTokens(\n\t\t\t\t\t\t\t\t\t\tnew Set(\n\t\t\t\t\t\t\t\t\t\t\tpathEntries\n\t\t\t\t\t\t\t\t\t\t\t\t.slice(pathEntries.findIndex((entry) => entry.id === preparation.firstKeptEntryId))\n\t\t\t\t\t\t\t\t\t\t\t\t.map((entry) => entry.id),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\twrapper,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t);\n\t\t\t\t\t({ summary, firstKeptEntryId, tokensBefore, details, usage } = nativeCompaction);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tsummaryFailure = error;\n\t\t\t\t\tthrow error;\n\t\t\t\t} finally {\n\t\t\t\t\tawait this._releaseCompactionCapture(summaryRequests, undefined, summaryFailure, owner);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (signal.aborted) {\n\t\t\t\tthrow new Error(\"Compaction cancelled\");\n\t\t\t}\n\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tconst result: CompactionResult = JSON.parse(\n\t\t\t\tJSON.stringify({ summary, firstKeptEntryId, tokensBefore, details }),\n\t\t\t);\n\t\t\tconst recovery = prepared.messages\n\t\t\t\t? prepareRecoveryCompaction(\n\t\t\t\t\t\tprepared.messages,\n\t\t\t\t\t\tfirstKeptEntryId,\n\t\t\t\t\t\tprepared.maxSourceBytes,\n\t\t\t\t\t\tgetRecoveryCompactionAuthorization(options.capacity),\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\t\tif (prepared.resource) assertResourceCurrent(prepared.resource);\n\t\t\tif (recovery) {\n\t\t\t\tif (\n\t\t\t\t\tresult.details !== undefined &&\n\t\t\t\t\t(!result.details || typeof result.details !== \"object\" || Array.isArray(result.details))\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Recovery compaction details require an object\");\n\t\t\t\tconst recoveryDetails = { ...result.details, [CONTEXT_EPOCH_DETAIL]: recovery };\n\t\t\t\tresult.details = recoveryDetails;\n\t\t\t\tsavedCompactionId = await compaction[appendContextEpoch](\n\t\t\t\t\trecovery,\n\t\t\t\t\ttokensBefore,\n\t\t\t\t\t{\n\t\t\t\t\t\tsummary,\n\t\t\t\t\t\tdetails: recoveryDetails,\n\t\t\t\t\t\tfromHook: fromExtension,\n\t\t\t\t\t\tcustomInstructions,\n\t\t\t\t\t\tusage,\n\t\t\t\t\t},\n\t\t\t\t\tnativeCompaction,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tsavedCompactionId = await compaction.appendCompaction(\n\t\t\t\t\tsummary,\n\t\t\t\t\tfirstKeptEntryId,\n\t\t\t\t\ttokensBefore,\n\t\t\t\t\tresult.details,\n\t\t\t\t\tfromExtension,\n\t\t\t\t\tcustomInstructions,\n\t\t\t\t\tusage,\n\t\t\t\t\tnativeCompaction,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Only the canonical append ACK commits summary slices and advances the semantic epoch.\n\t\t\tcommitted = { entryId: savedCompactionId, result };\n\t\t\tcompactionSettled = true;\n\t\t\tfor (const requestId of uncommittedSlices.splice(0)) {\n\t\t\t\tsemanticEdges.finishRequest(requestId);\n\t\t\t}\n\t\t\tsemanticEdges.finishCompaction(semanticCompaction.compactionId, \"completed\");\n\t\t\tif (prepared.resource) assertResourceCurrent(prepared.resource);\n\t\t} catch (error) {\n\t\t\tcompactionSettled = true;\n\t\t\tif (committed) throw new CompactionCommittedError(committed.entryId, committed.result, error);\n\t\t\tfor (const requestId of uncommittedSlices.splice(0)) {\n\t\t\t\tsemanticEdges.failRequest(requestId);\n\t\t\t}\n\t\t\tconst cancelled =\n\t\t\t\terror instanceof Error && (error.name === \"AbortError\" || error.message === \"Compaction cancelled\");\n\t\t\tsemanticEdges.finishCompaction(semanticCompaction.compactionId, cancelled ? \"cancelled\" : \"failed\");\n\t\t\tthrow error;\n\t\t}\n\t\ttry {\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tconst bootstrap = await readSessionBootstrap(owner.manager, this.settingsManager.getCanonicalContextLimits(), {\n\t\t\t\tpurpose: \"read\",\n\t\t\t\tinitialContextMode: this._initialContextMode,\n\t\t\t});\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\towner.agent.state.messages = bootstrap.context.messages;\n\t\t\tthis._contextOmissions = undefined;\n\t\t\tthis._mergeUnpersistedOutcomes(owner.agent.state.messages);\n\t\t\tthis._restoreLateIpythonSentAgentMessages();\n\n\t\t\tconst savedCompactionEntry = await owner.manager.readEntry(savedCompactionId);\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tif (savedCompactionEntry?.type === \"compaction\") {\n\t\t\t\tawait owner.extensions.emit({\n\t\t\t\t\ttype: \"session_compact\",\n\t\t\t\t\tcompactionEntry: savedCompactionEntry,\n\t\t\t\t\tfromExtension,\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tif (!prepared.resource) await this._syncKernelStateAfterCompaction(owner);\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tawait this._reapDeletedRlmSubagentRuntimesAfterCompaction();\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t} catch (error) {\n\t\t\tthrow new CompactionCommittedError(committed!.entryId, committed!.result, error);\n\t\t}\n\t\treturn committed!;\n\t}\n\n\tprivate _reportCommittedCompactionFailure(\n\t\terror: CompactionCommittedError,\n\t\treason: CompactionReason,\n\t\tcustomInstructions?: string,\n\t\towner?: CompactionOwner,\n\t): void {\n\t\tif (owner && !this._isCompactionSourceOwnerCurrent(owner)) return;\n\t\tthis._compactionSetupFailure = error;\n\t\tthis._sessionInputPumpRequested = false;\n\t\tthis._sessionInputPumpEpoch++;\n\t\tthis._sessionInputPumpSuspended = true;\n\t\tthis._settlePostCompactionContinue(error);\n\t\tthis._discardPendingAutoRefine({ cancelPostCompactionContinue: true });\n\t\tthis._autoRefineBranchVersion++;\n\t\tthis._resolveRetry();\n\t\tthis._emit({\n\t\t\ttype: \"compaction_end\",\n\t\t\treason,\n\t\t\tresult: error.result,\n\t\t\taborted: false,\n\t\t\twillRetry: false,\n\t\t\terrorMessage: error.message,\n\t\t\terrorSeverity: \"error\",\n\t\t\tcustomInstructions,\n\t\t});\n\t}\n\n\tprivate async _releaseCompactionCapture(\n\t\trequests: InferenceCoordinator | undefined,\n\t\tcompaction: BoundCompactionSink | undefined,\n\t\tfailure: unknown,\n\t\towner?: CompactionOwner,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tif (requests) await requests.dispose();\n\t\t\telse await compaction?.release();\n\t\t} catch (cleanupError) {\n\t\t\tif (failure instanceof CompactionCommittedError) {\n\t\t\t\tif (cleanupError === failure || cleanupError === failure.cause) throw failure;\n\t\t\t\tconst combined = new CompactionCommittedError(\n\t\t\t\t\tfailure.entryId,\n\t\t\t\t\tfailure.result,\n\t\t\t\t\tnew AggregateError([failure.cause, cleanupError], \"Compaction setup and source release failed\"),\n\t\t\t\t);\n\t\t\t\tif ((!owner || this._isCompactionSourceOwnerCurrent(owner)) && this._compactionSetupFailure === failure)\n\t\t\t\t\tthis._compactionSetupFailure = combined;\n\t\t\t\tthrow combined;\n\t\t\t}\n\t\t\tif (failure !== undefined && failure !== cleanupError)\n\t\t\t\tthrow new AggregateError([failure, cleanupError], \"Compaction and source release failed\");\n\t\t\tthrow cleanupError;\n\t\t}\n\t}\n\n\tprivate async _reapDeletedRlmSubagentRuntimesAfterCompaction(): Promise<void> {\n\t\tconst childIds = [...this._rlmChildCleanupFailures.keys()].filter(\n\t\t\t(childId) => !this._activeRlmChildRuns.get(childId)?.detachedDeletion,\n\t\t);\n\t\tawait Promise.allSettled(childIds.map((childId) => this.deleteRlmSubagent(childId)));\n\t}\n\n\tabortCompaction(): void {\n\t\tthis._compactionAbortController?.abort();\n\t\tthis._autoCompactionAbortController?.abort();\n\t}\n\n\tprivate _localHarnessStateDir(): string | undefined {\n\t\treturn (\n\t\t\tgetLocalHarnessStateDir(this.sessionManager.getSessionArtifactDir()) ??\n\t\t\t(this._rlmSessionDir ? getLocalHarnessStateDir(this._rlmSessionDir) : undefined)\n\t\t);\n\t}\n\n\tprivate _autoRefineAllowedForSession(): boolean {\n\t\treturn this._rlmDepth === 0 && this._localHarnessStateDir() !== undefined;\n\t}\n\n\tprivate _newAutoRefineAllowed(): boolean {\n\t\treturn (\n\t\t\tthis._contextOptimizationAllowed() && !this._autoRefineAdmissionClosed && this._autoRefineAllowedForSession()\n\t\t);\n\t}\n\n\tprivate _settlePostCompactionContinue(error?: Error): void {\n\t\tif (!error && this._postCompactionContinuationScheduled) return;\n\t\tif (error) this._postCompactionContinuationScheduled = false;\n\t\tconst settlement = this._postCompactionContinuationSettlement;\n\t\tif (!settlement || settlement.settled) return;\n\t\tsettlement.settled = true;\n\t\tthis._postCompactionContinuationSettlement = undefined;\n\t\tif (error) settlement.reject(error);\n\t\telse settlement.resolve();\n\t\tthis._notifySessionInputCheckpointChange();\n\t}\n\n\tprivate _cancelPostCompactionContinue(): void {\n\t\tthis._postCompactionContinuationScheduled = false;\n\t\tthis._settlePostCompactionContinue();\n\t}\n\n\tprivate _discardPendingAutoRefine(options: { cancelPostCompactionContinue?: boolean } = {}): void {\n\t\tthis._compactAutoRefinePending = false;\n\t\tthis._turnIntervalAutoRefinePending = false;\n\t\tthis._pendingAutoRefineReview = undefined;\n\t\tif (options.cancelPostCompactionContinue) {\n\t\t\tthis._cancelPostCompactionContinue();\n\t\t}\n\t}\n\n\tprivate async _invalidatePendingAutoRefineForBranchChange(): Promise<void> {\n\t\tthis._autoRefineReviewAbort?.abort();\n\t\tthis._discardPendingAutoRefine({ cancelPostCompactionContinue: true });\n\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t// Increment branch version BEFORE aborting/awaiting the serialized plan.\n\t\t// This invalidates the plan's branchVersion check at the boundary\n\t\t// so even if the plan completes, the boundary will reject it\n\t\t// (bgResult.branchVersion !== this._autoRefineBranchVersion).\n\t\tthis._autoRefineBranchVersion++;\n\t\t// Abort the in-flight refine/bplan controller so any pending\n\t\t// _planRefine or _reviewAutoRefine call settles via signal abort\n\t\t// rather than hanging forever.\n\t\tthis._refineAbortController?.abort();\n\t\tif (this._serializedPlanInFlight) {\n\t\t\tawait this._consumeSerializedBackgroundPlan(async () => false);\n\t\t}\n\t\twhile (this._refinePlanInFlight) {\n\t\t\tawait this._refinePlanInFlight;\n\t\t}\n\t\tawait this._waitForRefineIdle();\n\t}\n\n\t/**\n\t * Consume a refine request that was scheduled by the agent-callable refine\n\t * skill (refine.run). Fire-and-forget: the refine() method handles its own\n\t * background planning, idle wait, application, and error recovery. Called\n\t * at the turn boundary after compaction checks and before auto-refine\n\t * scheduling so the manual request takes priority.\n\t */\n\tprivate _emitRefineFailed(error: unknown): void {\n\t\tthis._emit({\n\t\t\ttype: \"refine_failed\",\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t});\n\t}\n\n\tprivate _consumePendingRequestedRefine(): boolean {\n\t\tconst pending = this._pendingRequestedRefine;\n\t\tif (!pending) return false;\n\t\tthis._pendingRequestedRefine = undefined;\n\t\tvoid this.refine(pending).catch((error) => this._emitRefineFailed(error));\n\t\treturn true;\n\t}\n\n\tprivate _scheduleAutoRefineAfterAgentEnd(): void {\n\t\tif (this._compactionSetupFailure) return;\n\t\tif (!this._newAutoRefineAllowed()) {\n\t\t\treturn;\n\t\t}\n\t\tif (this._pendingAutoRefineReview) {\n\t\t\tthis._scheduleAutoRefine(this._pendingAutoRefineReview.reason);\n\t\t\treturn;\n\t\t}\n\t\tif (this._compactAutoRefinePending) {\n\t\t\tif (this._postCompactionContinuationScheduled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._scheduleAutoRefine(\"compact\");\n\t\t\treturn;\n\t\t}\n\n\t\tthis._scheduleAutoRefine(\"turn_interval\");\n\t}\n\n\tprivate _scheduleAutoRefineAfterCompaction(willContinueAfterCompaction: boolean): void {\n\t\tif (!this._newAutoRefineAllowed()) {\n\t\t\treturn;\n\t\t}\n\t\tif (this._serializedRefine) {\n\t\t\t// Serialized sessions must service compaction-triggered refinement at\n\t\t\t// shouldStopAfterTurn, never through the interactive path.\n\t\t\tthis._compactAutoRefinePending = true;\n\t\t\treturn;\n\t\t}\n\t\tif (willContinueAfterCompaction) {\n\t\t\tthis._compactAutoRefinePending = true;\n\t\t\treturn;\n\t\t}\n\n\t\tthis._scheduleAutoRefine(\"compact\");\n\t}\n\n\tprivate _schedulePostCompactionContinue(resume: CheckpointResume): void {\n\t\tif (!this._isCompactionOwnerCurrent(resume.owner)) return;\n\t\tconst previous = this._postCompactionContinuationSettlement;\n\t\tif (previous && !this._isCompactionOwnerCurrent(previous.resume.owner)) this._cancelPostCompactionContinue();\n\t\tif (!this._postCompactionContinuationSettlement || this._postCompactionContinuationSettlement.settled) {\n\t\t\tthis._postCompactionContinuationSettlement = createPostCompactionContinuationSettlement(resume);\n\t\t}\n\t\tconst settlement = this._postCompactionContinuationSettlement;\n\t\tsettlement.resume = resume;\n\t\tif (this._postCompactionContinuationScheduled) return;\n\t\tthis._postCompactionContinuationScheduled = true;\n\t\tvoid this._runScheduledPostCompactionContinue(settlement)\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (this._postCompactionContinuationSettlement === settlement)\n\t\t\t\t\tthis._settlePostCompactionContinue(this._asError(error));\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (this._postCompactionContinuationSettlement === settlement) this._settlePostCompactionContinue();\n\t\t\t});\n\t}\n\n\tprivate async _waitForQueuedWorkResume(settlement: PostCompactionContinuationSettlement): Promise<void> {\n\t\tconst resume = settlement.resume;\n\t\twhile (\n\t\t\t(this._queuedWorkPauses.size > 0 || this._sessionInputAdmissionPauses.size > 0) &&\n\t\t\tthis._postCompactionContinuationSettlement === settlement &&\n\t\t\tsettlement.resume === resume &&\n\t\t\tthis._isCompactionOwnerCurrent(resume.owner)\n\t\t) {\n\t\t\tlet resume = () => {};\n\t\t\tconst resumed = new Promise<void>((resolve) => {\n\t\t\t\tresume = resolve;\n\t\t\t\tthis._sessionInputCheckpointWaiters.add(resolve);\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tawait Promise.race([resumed, settlement.promise]);\n\t\t\t} finally {\n\t\t\t\tthis._sessionInputCheckpointWaiters.delete(resume);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async _runScheduledPostCompactionContinue(settlement: PostCompactionContinuationSettlement): Promise<void> {\n\t\twhile (this._postCompactionContinuationScheduled && this._postCompactionContinuationSettlement === settlement) {\n\t\t\tconst resume = settlement.resume;\n\t\t\tconst owner = resume.owner;\n\t\t\tconst current = () =>\n\t\t\t\tthis._postCompactionContinuationSettlement === settlement &&\n\t\t\t\tsettlement.resume === resume &&\n\t\t\t\tthis._isCompactionOwnerCurrent(owner);\n\t\t\tif (!current()) {\n\t\t\t\tthis._cancelPostCompactionContinue();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait owner.agent.waitForIdle();\n\t\t\tif (!current()) continue;\n\t\t\tawait this.waitForRetry();\n\t\t\tif (!current()) continue;\n\t\t\tconst refine = this._refineInFlight;\n\t\t\tif (refine) await refine;\n\t\t\tif (!current()) continue;\n\t\t\tawait this._waitForQueuedWorkResume(settlement);\n\t\t\tif (!current()) continue;\n\t\t\tconst compactionOperation = this._compactionOperation;\n\t\t\tif (compactionOperation) {\n\t\t\t\tawait Promise.race([compactionOperation, settlement.promise]);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst commitFence = await this._acquireSessionActionCommitFence();\n\t\t\tlet continuation: Promise<void> | undefined;\n\t\t\tlet waitForSessionInput = false;\n\t\t\ttry {\n\t\t\t\tif (!current()) continue;\n\t\t\t\tawait owner.agent.waitForIdle();\n\t\t\t\tif (!current()) continue;\n\t\t\t\tif (\n\t\t\t\t\tthis._queuedWorkPauses.size > 0 ||\n\t\t\t\t\tthis._sessionInputAdmissionPauses.size > 0 ||\n\t\t\t\t\tthis._compactionOperation ||\n\t\t\t\t\tthis._refineInFlight\n\t\t\t\t)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (this.unfinishedActionCount > 0 || this._sessionInputPumpRequested) {\n\t\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t\t\twaitForSessionInput = true;\n\t\t\t\t} else {\n\t\t\t\t\t// A released row is not a receipt. The retained ticket settles delivery and completion separately.\n\t\t\t\t\tfor (const { action, ticket } of resume.actions) {\n\t\t\t\t\t\tif (action.lifecycle.state === \"cancelled\") continue;\n\t\t\t\t\t\tif (action.lifecycle.state !== \"completed\" && action.lifecycle.state !== \"failed\") {\n\t\t\t\t\t\t\tthrow new Error(`Checkpoint action ${ticket.id} has not settled`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait ticket.completed;\n\t\t\t\t\t\tconst delivered = await ticket.delivered;\n\t\t\t\t\t\tif (delivered.status !== \"delivered\")\n\t\t\t\t\t\t\tthrow new Error(`Checkpoint action ${ticket.id} was not delivered`);\n\t\t\t\t\t\tif (!current()) break;\n\t\t\t\t\t}\n\t\t\t\t\tif (!current()) continue;\n\t\t\t\t\tif (this.hasPendingSessionWork || this._sessionInputPumpRequested) continue;\n\t\t\t\t\tthis._postCompactionContinuationScheduled = false;\n\t\t\t\t\tif (resume.boundary?.state === \"pending\" || owner.agent.hasQueuedMessages()) {\n\t\t\t\t\t\tcontinuation = owner.agent.continue();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._scheduleAutoRefineAfterAgentEnd();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tcommitFence.release();\n\t\t\t}\n\t\t\tif (waitForSessionInput) {\n\t\t\t\tawait this._waitForIdleOrSettlement(settlement);\n\t\t\t\tcontinue; // The input dispatch, not queue removal, consumes the old boundary.\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait continuation;\n\t\t\t\treturn;\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof AgentContinueError && error.code === \"busy\") {\n\t\t\t\t\tif (current()) this._postCompactionContinuationScheduled = true;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// A valid directive must not rely on a stale-tail/nothing-to-continue error to decide completion.\n\t\t\t\tif (this._postCompactionContinuationSettlement === settlement)\n\t\t\t\t\tthis._settlePostCompactionContinue(this._asError(error));\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _forgetConsumedPostCompactionContinuations(actions: QueuedSessionAction[]): void {\n\t\tthis._postCompactionContinuations = this._postCompactionContinuations.filter(\n\t\t\t(continuation) => !actions.includes(continuation.action) || this._checkpointActionPending(continuation),\n\t\t);\n\t}\n\n\tprivate _shouldSkipAutoRefineForActiveAgent(): boolean {\n\t\treturn this.isStreaming || this.isCompacting;\n\t}\n\n\tprivate _scheduleDeferredAutoRefineIfIdle(): void {\n\t\tif (this._autoRefineInProgress || this._shouldSkipAutoRefineForActiveAgent() || this._pendingAutoRefineReview) {\n\t\t\treturn;\n\t\t}\n\t\tif (this._turnIntervalAutoRefinePending) {\n\t\t\tthis._turnIntervalAutoRefinePending = false;\n\t\t\tthis._scheduleAutoRefine(\"turn_interval\");\n\t\t}\n\t}\n\n\tprivate _scheduleAutoRefine(reason: AutoRefineReason, branchVersion = this._autoRefineBranchVersion): void {\n\t\tif (this._compactionSetupFailure || !this._newAutoRefineAllowed()) return;\n\t\tconst timer = setTimeout(() => {\n\t\t\tthis._scheduledAutoRefineTimers.delete(timer);\n\t\t\tif (branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst operation = this._maybeAutoRefine(reason);\n\t\t\tthis._autoRefineOperations.add(operation);\n\t\t\tvoid operation.finally(() => this._autoRefineOperations.delete(operation)).catch(() => undefined);\n\t\t}, 0);\n\t\tthis._scheduledAutoRefineTimers.add(timer);\n\t}\n\n\tprivate async _maybeAutoRefine(reason: AutoRefineReason): Promise<void> {\n\t\tif (this._compactionSetupFailure) return;\n\t\tif (this._disposed || this._disposing) {\n\t\t\tthis._discardPendingAutoRefine();\n\t\t\treturn;\n\t\t}\n\t\tif (!this._newAutoRefineAllowed()) {\n\t\t\tthis._discardPendingAutoRefine();\n\t\t\treturn;\n\t\t}\n\n\t\tconst settings = this.settingsManager.getAutoRefineSettings();\n\t\tif (!settings.enabled) {\n\t\t\tthis._discardPendingAutoRefine();\n\t\t\treturn;\n\t\t}\n\t\tif (this._autoRefineInProgress || this._shouldSkipAutoRefineForActiveAgent()) {\n\t\t\tif (reason === \"compact\") {\n\t\t\t\tthis._compactAutoRefinePending = true;\n\t\t\t} else {\n\t\t\t\tthis._turnIntervalAutoRefinePending = true;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst nowMs = Date.now();\n\t\tconst underCooldown =\n\t\t\tthis._lastAutoRefineReviewAt > 0 && nowMs - this._lastAutoRefineReviewAt < settings.cooldownMs;\n\n\t\tconst pendingReview = this._pendingAutoRefineReview;\n\t\tif (pendingReview) {\n\t\t\t// A failed refine stamps the cooldown; keep the pending review for later.\n\t\t\tif (underCooldown) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this._runApprovedRefine(pendingReview.reason, pendingReview.review);\n\t\t\treturn;\n\t\t}\n\n\t\tif (reason === \"compact\" && !settings.compact) {\n\t\t\tthis._compactAutoRefinePending = false;\n\t\t\treason = \"turn_interval\";\n\t\t}\n\t\tif (reason === \"turn_interval\" && this._assistantTurnsSinceAutoRefine < settings.turnInterval) {\n\t\t\treturn;\n\t\t}\n\t\tif (underCooldown) {\n\t\t\tif (reason === \"compact\") {\n\t\t\t\tthis._compactAutoRefinePending = true;\n\t\t\t} else {\n\t\t\t\tthis._turnIntervalAutoRefinePending = true;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (reason === \"turn_interval\") {\n\t\t\tthis._turnIntervalAutoRefinePending = false;\n\t\t}\n\t\tif (!this.model) {\n\t\t\tif (reason === \"compact\") {\n\t\t\t\tthis._compactAutoRefinePending = true;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis._autoRefineInProgress = true;\n\t\tconst turnsSinceLastReview = this._assistantTurnsSinceAutoRefine;\n\t\tconst branchVersion = this._autoRefineBranchVersion;\n\t\tconst reviewAbort = new AbortController();\n\t\tthis._autoRefineReviewAbort = reviewAbort;\n\t\tlet approvedReview: AutoRefineReview | undefined;\n\t\ttry {\n\t\t\tconst review = await this._reviewAutoRefine({ reason, turnsSinceLastReview }, reviewAbort.signal);\n\t\t\tif (\n\t\t\t\t!this._newAutoRefineAllowed() ||\n\t\t\t\tthis._disposed ||\n\t\t\t\tthis._disposing ||\n\t\t\t\tbranchVersion !== this._autoRefineBranchVersion\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!review.shouldRefine) {\n\t\t\t\tconst preserveTurnIntervalReview =\n\t\t\t\t\treason === \"compact\" && this._assistantTurnsSinceAutoRefine >= settings.turnInterval;\n\t\t\t\tif (preserveTurnIntervalReview) {\n\t\t\t\t\tthis._turnIntervalAutoRefinePending = true;\n\t\t\t\t} else {\n\t\t\t\t\tthis._lastAutoRefineReviewAt = nowMs;\n\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t}\n\t\t\t\tif (reason === \"compact\") {\n\t\t\t\t\tthis._compactAutoRefinePending = false;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this._shouldSkipAutoRefineForActiveAgent()) {\n\t\t\t\tthis._pendingAutoRefineReview = { reason, review };\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tapprovedReview = review;\n\t\t} catch {\n\t\t\t// Failed review: stamp the cooldown so a persistent failure (bad auth,\n\t\t\t// unparseable output) doesn't retry a full review on every agent end.\n\t\t\tif (branchVersion === this._autoRefineBranchVersion) {\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t}\n\t\t} finally {\n\t\t\tif (this._autoRefineReviewAbort === reviewAbort) {\n\t\t\t\tthis._autoRefineReviewAbort = undefined;\n\t\t\t}\n\t\t\tthis._autoRefineInProgress = false;\n\t\t\t// When a refine follows, _runApprovedRefine schedules the deferred pass.\n\t\t\tif (!approvedReview) {\n\t\t\t\tthis._scheduleDeferredAutoRefineIfIdle();\n\t\t\t}\n\t\t}\n\t\tif (approvedReview) {\n\t\t\tawait this._runApprovedRefine(reason, approvedReview);\n\t\t}\n\t}\n\n\tprivate async _runApprovedRefine(reason: AutoRefineReason, review: AutoRefineReview): Promise<void> {\n\t\tif (this._compactionSetupFailure || !this._newAutoRefineAllowed()) return;\n\t\tthis._autoRefineInProgress = true;\n\t\ttry {\n\t\t\tawait this.refine({ instructions: autoRefineInstructions(reason, review) }, { trigger: \"auto\" });\n\t\t\tthis._pendingAutoRefineReview = undefined;\n\t\t\tthis._turnIntervalAutoRefinePending = false;\n\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\tif (reason === \"compact\") {\n\t\t\t\tthis._compactAutoRefinePending = false;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Consume this exact automatic proposal after failure. New evidence can\n\t\t\t// request a new review; manual /refine remains independent.\n\t\t\tthis._pendingAutoRefineReview = undefined;\n\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\tif (error instanceof RefineSkippedError) {\n\t\t\t\t// A skipped round is consumed like a reviewer decline, not retained for retry.\n\t\t\t\tthis._pendingAutoRefineReview = undefined;\n\t\t\t\tthis._turnIntervalAutoRefinePending = false;\n\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\tif (reason === \"compact\") this._compactAutoRefinePending = false;\n\t\t\t}\n\t\t} finally {\n\t\t\tthis._autoRefineInProgress = false;\n\t\t\tthis._scheduleDeferredAutoRefineIfIdle();\n\t\t}\n\t}\n\n\tprivate _resolveRefinementModel():\n\t\t| { model: NonNullable<AgentSession[\"model\"]>; thinkingLevel: ThinkingLevel; explicit: boolean }\n\t\t| undefined {\n\t\tconst selection = this.settingsManager.getAutoRefineModel();\n\t\tif (selection === undefined) {\n\t\t\tconst model = this.model;\n\t\t\treturn model\n\t\t\t\t? { model: { ...model, cost: { ...model.cost } }, thinkingLevel: this.thinkingLevel, explicit: false }\n\t\t\t\t: undefined;\n\t\t}\n\t\tif (\n\t\t\t!selection ||\n\t\t\ttypeof selection !== \"object\" ||\n\t\t\tArray.isArray(selection) ||\n\t\t\ttypeof selection.provider !== \"string\" ||\n\t\t\t!selection.provider.trim() ||\n\t\t\ttypeof selection.modelId !== \"string\" ||\n\t\t\t!selection.modelId.trim() ||\n\t\t\ttypeof selection.thinkingLevel !== \"string\"\n\t\t)\n\t\t\tthrow new Error(\"Invalid autoRefine.model; expected provider, modelId, and thinkingLevel\");\n\t\tconst model = this._modelRegistry.find(selection.provider, selection.modelId);\n\t\tif (!model) throw new Error(`Unknown autoRefine.model ${selection.provider}/${selection.modelId}`);\n\t\tif (!getSupportedThinkingLevels(model).includes(selection.thinkingLevel))\n\t\t\tthrow new Error(\n\t\t\t\t`autoRefine.model thinkingLevel ${selection.thinkingLevel} is not supported by ${selection.provider}/${selection.modelId}`,\n\t\t\t);\n\t\treturn { model: { ...model, cost: { ...model.cost } }, thinkingLevel: selection.thinkingLevel, explicit: true };\n\t}\n\n\tprivate async _autoRefineEvidence(harnessState: HarnessState) {\n\t\tconst manager = this.sessionManager;\n\t\tconst goalEvidence = ({ active, status, goalId, objective, tokenBudget, lastError }: GoalState) => ({\n\t\t\tactive,\n\t\t\tstatus,\n\t\t\tgoalId,\n\t\t\tobjective,\n\t\t\ttokenBudget,\n\t\t\tlastError,\n\t\t});\n\t\tconst frontier = manager.supportsCapturedHistoryReads()\n\t\t\t? await manager.readBranchHistory(async (history) => {\n\t\t\t\t\tconst goal = (await history.branchBootstrap()).goalState;\n\t\t\t\t\tconst limits = this.settingsManager.getCanonicalContextLimits();\n\t\t\t\t\tlet goalState = emptyGoalState();\n\t\t\t\t\tif (goal) {\n\t\t\t\t\t\tconst hydrated = await history.hydrateEntry(goal.id, limits.maxSourceBytes);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!hydrated ||\n\t\t\t\t\t\t\thydrated.source.retention === \"retained-import\" ||\n\t\t\t\t\t\t\thydrated.entry.type !== \"custom\" ||\n\t\t\t\t\t\t\thydrated.entry.customType !== GOAL_STATE_CUSTOM_TYPE ||\n\t\t\t\t\t\t\t!isPersistedGoalState(hydrated.entry.data)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthrow new RefineSkippedError(\"Automatic refinement goal source is unavailable or ineligible\");\n\t\t\t\t\t\tgoalState = normalizeGoalState(hydrated.entry.data);\n\t\t\t\t\t}\n\t\t\t\t\tlet id = history.source.leafId;\n\t\t\t\t\tconst maxEntries = limits.maxMessages;\n\t\t\t\t\tfor (let scanned = 0; scanned < maxEntries; scanned++) {\n\t\t\t\t\t\tconst entry = id ? await history.get(id) : undefined;\n\t\t\t\t\t\tif (id && !entry) throw new RefineSkippedError(\"Automatic refinement task frontier is unavailable\");\n\t\t\t\t\t\tconst message = entry?.kind === \"message\" ? entry : undefined;\n\t\t\t\t\t\tif (message || !entry)\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tsessionId: history.source.sessionId,\n\t\t\t\t\t\t\t\tsessionFile: history.source.sessionFile,\n\t\t\t\t\t\t\t\tmessage: message ? ([message.id, message.revision] as const) : undefined,\n\t\t\t\t\t\t\t\tgoal: goalEvidence(goalState),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\tid = entry.parentId;\n\t\t\t\t\t}\n\t\t\t\t\tthrow new RefineSkippedError(\"Automatic refinement task frontier exceeds the context read limit\");\n\t\t\t\t})\n\t\t\t: (() => {\n\t\t\t\t\tconst branch = manager.getBranch().slice().reverse();\n\t\t\t\t\tconst message = branch.find((entry) => entry.type === \"message\");\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsessionId: manager.getSessionId(),\n\t\t\t\t\t\tsessionFile: manager.getSessionFile(),\n\t\t\t\t\t\tmessage: message ? ([message.id, message.timestamp] as const) : undefined,\n\t\t\t\t\t\tgoal: goalEvidence(this._loadPersistedGoalState()),\n\t\t\t\t\t};\n\t\t\t\t})();\n\t\treturn {\n\t\t\t...frontier,\n\t\t\tsystemPrompt: this.agent.state.systemPrompt,\n\t\t\tmodel: JSON.stringify([this.model?.provider, this.model?.id, this.settingsManager.getAutoRefineModel()]),\n\t\t\tharnessEntries: Object.fromEntries(\n\t\t\t\tObject.entries(harnessState.entries).map(([kind, entries]) => [\n\t\t\t\t\tkind,\n\t\t\t\t\tObject.fromEntries(\n\t\t\t\t\t\tObject.entries(entries).map(\n\t\t\t\t\t\t\t([id, { version: _version, created_at: _created, updated_at: _updated, ...entry }]) => [id, entry],\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t]),\n\t\t\t),\n\t\t};\n\t}\n\n\tprivate async _reviewAutoRefine(context: AutoRefineReviewRequest, signal?: AbortSignal): Promise<AutoRefineReview> {\n\t\tconst harnessState = this._loadMergedHarnessState();\n\t\tconst evidence = await this._autoRefineEvidence(harnessState);\n\t\tsignal?.throwIfAborted();\n\t\tif (isDeepStrictEqual(evidence, this._lastAutoRefineEvidence))\n\t\t\treturn { shouldRefine: false, rationale: \"No new task evidence since the previous automatic review.\" };\n\t\t// Reserve before any inference wait. Equivalent running, declined or failed\n\t\t// automatic reviews do not buy another call; explicit /refine stays independent.\n\t\tthis._lastAutoRefineEvidence = evidence;\n\t\tif (this._autoRefineReviewer) return this._autoRefineReviewer(context, signal);\n\t\tconst selected = this._resolveRefinementModel();\n\t\tif (!selected) return { shouldRefine: false, rationale: \"No model selected.\" };\n\t\tconst { model, thinkingLevel, explicit } = selected;\n\t\tconst messages = structuredClone(this.agent.state.messages);\n\t\tconst reviewContext = { ...context };\n\t\tconst requests = this.requests[captureNativeReviewerRequests]();\n\t\ttry {\n\t\t\tconst history = await this._loadRefinementHistory();\n\t\t\tconst { apiKey, headers } = await this._getRequiredRequestAuth(model);\n\t\t\treturn await reviewAutoRefine(\n\t\t\t\tmessages,\n\t\t\t\tharnessState,\n\t\t\t\thistory,\n\t\t\t\tmodel,\n\t\t\t\tapiKey,\n\t\t\t\treviewContext,\n\t\t\t\theaders,\n\t\t\t\tsignal,\n\t\t\t\tthinkingLevel,\n\t\t\t\trequests,\n\t\t\t\texplicit,\n\t\t\t);\n\t\t} finally {\n\t\t\tawait requests.dispose();\n\t\t}\n\t}\n\n\t/** Merge existing session/global memory with the selected project's workspace memory. */\n\tprivate _loadMergedHarnessState(): HarnessState {\n\t\tconst localHarnessStateDir = this._localHarnessStateDir();\n\t\treturn mergeHarnessStates(\n\t\t\tloadHarnessState(getGlobalHarnessStateDir(), \"global\"),\n\t\t\tlocalHarnessStateDir ? loadHarnessState(localHarnessStateDir, \"local\") : undefined,\n\t\t\tloadHarnessState(getWorkspaceHarnessStateDir(this._cwd), \"workspace\"),\n\t\t);\n\t}\n\n\tprivate async _loadRefinementHistory(): Promise<RefinementResult[]> {\n\t\tconst limits: SessionHistoryReadLimits = {\n\t\t\tmaxEntries: 16_384,\n\t\t\tmaxSourceBytes: 64 * 1024 * 1024,\n\t\t};\n\t\tconst residentEntries = this.sessionManager.supportsCapturedHistoryReads()\n\t\t\t? undefined\n\t\t\t: this.sessionManager.materializeResidentHistory(limits).entries;\n\t\tconst globalHistory = loadGlobalRefinementHistory(getGlobalHarnessStateDir(), limits);\n\t\tconst sessionHistory = (async () => {\n\t\t\tif (residentEntries !== undefined) return residentEntries;\n\t\t\treturn this.sessionManager.readSourceHistory(async (history) => {\n\t\t\t\tconst entries: SessionEntry[] = [];\n\t\t\t\tlet sourceBytes = 0;\n\t\t\t\tlet after = 0;\n\t\t\t\tfor (;;) {\n\t\t\t\t\tconst page = await history.page(after, 128);\n\t\t\t\t\tif (page.indexedThrough < history.source.sourceSequence)\n\t\t\t\t\t\tthrow new Error(\"Captured refinement history has incomplete index coverage\");\n\t\t\t\t\tfor (const reference of page.events) {\n\t\t\t\t\t\tif (reference.kind !== \"custom\") continue;\n\t\t\t\t\t\t// Refinement consumes custom records, not archived conversation or request bodies.\n\t\t\t\t\t\tif (entries.length >= limits.maxEntries) throw new Error(\"Refinement history entry budget exceeded\");\n\t\t\t\t\t\tif (sourceBytes + reference.locator.length > limits.maxSourceBytes)\n\t\t\t\t\t\t\tthrow new Error(\"Refinement history source byte budget exceeded\");\n\t\t\t\t\t\tconst hydrated = await hydrateCapturedHistoryEntry(\n\t\t\t\t\t\t\treference,\n\t\t\t\t\t\t\tlimits.maxSourceBytes - sourceBytes,\n\t\t\t\t\t\t\thistory.readPayload,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tentries.push(hydrated.entry);\n\t\t\t\t\t\tsourceBytes += reference.locator.length;\n\t\t\t\t\t}\n\t\t\t\t\tif (page.nextAfter === null) return entries;\n\t\t\t\t\tafter = page.nextAfter;\n\t\t\t\t}\n\t\t\t});\n\t\t})();\n\t\tconst [globalResult, sessionResult] = await Promise.allSettled([globalHistory, sessionHistory]);\n\t\tif (globalResult.status === \"rejected\") {\n\t\t\tif (sessionResult.status === \"rejected\") {\n\t\t\t\tthrow new AggregateError([globalResult.reason, sessionResult.reason], \"Refinement history reads failed\");\n\t\t\t}\n\t\t\tthrow globalResult.reason;\n\t\t}\n\t\tif (sessionResult.status === \"rejected\") throw sessionResult.reason;\n\t\treturn mergeRefinementHistory(\n\t\t\tglobalResult.value,\n\t\t\tgetRefinementHistory(sessionResult.value.filter((entry) => entry.type === \"custom\")),\n\t\t);\n\t}\n\n\t/**\n\t * Refine editable continual harness state: prompt notes, memory, skills, and subagent specs.\n\t * The base system prompt is intentionally not editable through this path.\n\t *\n\t * Planning runs in the background and does NOT block turn entry points\n\t * (`_waitForRefineIdle` only waits for `_refineInFlight`). Only the fast\n\t * application phase (disk I/O + in-memory mutation) blocks turn entry points.\n\t */\n\tasync refine(\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean } = {},\n\t\tinternal: { skipAbort?: boolean; trigger?: \"manual\" | \"auto\" } = {},\n\t): Promise<RefinementResult> {\n\t\tthis._assertContextOptimizationAllowed();\n\t\treturn this._retainContextOptimization(this._refineAccepted(options, internal));\n\t}\n\n\tprivate async _refineAccepted(\n\t\toptions: {\n\t\t\tinstructions?: string;\n\t\t\trollbackId?: string;\n\t\t\tglobal?: boolean;\n\t\t} = {},\n\t\tinternal: { skipAbort?: boolean; trigger?: \"manual\" | \"auto\" } = {},\n\t): Promise<RefinementResult> {\n\t\t// Queued /refine executes from the session-input pump between turns;\n\t\t// refine never aborts the agent (planning is backgrounded and the apply\n\t\t// phase waits for quiescence), so skipAbort only asserts the pump's\n\t\t// idle invariant instead of changing abort behavior.\n\t\tif (internal.skipAbort && this.isStreaming) {\n\t\t\tthrow new Error(\"Cannot refine without aborting while the agent is running.\");\n\t\t}\n\t\t// Wait for any existing refine (both planning and application) before\n\t\t// starting a new run. This serializes concurrent /refine calls so two\n\t\t// planning phases cannot race into concurrent _applyRefine calls that\n\t\t// overwrite harness state.\n\t\twhile (this._refineInFlight || this._refinePlanInFlight || this._serializedPlanInFlight) {\n\t\t\tif (this._refineInFlight) {\n\t\t\t\tawait this._refineInFlight;\n\t\t\t} else if (this._refinePlanInFlight) {\n\t\t\t\tawait this._refinePlanInFlight;\n\t\t\t} else {\n\t\t\t\t// A serialized background plan is in flight (started during an\n\t\t\t\t// active turn at message_end). Wait for planning and for the active\n\t\t\t\t// turn to settle so its normal checkpoint can consume the plan.\n\t\t\t\tconst serializedPlanInFlight = this._serializedPlanInFlight;\n\t\t\t\tawait serializedPlanInFlight;\n\t\t\t\tif (this._refineInFlight || this._refinePlanInFlight) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tawait this.agent.waitForIdle();\n\t\t\t\t// Aborted turns skip shouldStopAfterTurn. Drop their settled plan\n\t\t\t\t// after idle so a later public refine cannot spin on it forever.\n\t\t\t\tif (this._serializedPlanInFlight === serializedPlanInFlight) {\n\t\t\t\t\tthis._serializedPlanInFlight = undefined;\n\t\t\t\t\tthis._serializedExplicitRefineOptions = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst refineAbort = new AbortController();\n\t\tthis._refineAbortController = refineAbort;\n\n\t\tconst planRun = this._planRefine(options, refineAbort.signal, internal.trigger ?? \"manual\");\n\t\tconst planSettled = planRun.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\tthis._refinePlanInFlight = planSettled;\n\t\tlet plan: RefinementPlan;\n\t\ttry {\n\t\t\tplan = await planRun;\n\t\t} catch (e) {\n\t\t\tif (this._refineAbortController === refineAbort) {\n\t\t\t\tthis._refineAbortController = undefined;\n\t\t\t}\n\t\t\tthis._scheduleSessionInputPump();\n\t\t\tthrow e;\n\t\t} finally {\n\t\t\tif (this._refinePlanInFlight === planSettled) {\n\t\t\t\tthis._refinePlanInFlight = undefined;\n\t\t\t}\n\t\t}\n\n\t\t// Block new turns before waiting for the current turn to finish. One shared\n\t\t// settled promise covers the full transition and apply critical section.\n\t\tlet resolveApplySettled: () => void = () => {};\n\t\tconst applySettled = new Promise<void>((resolve) => {\n\t\t\tresolveApplySettled = resolve;\n\t\t});\n\t\tthis._refineInFlight = applySettled;\n\t\ttry {\n\t\t\t// Wait for the session to become quiescent before applying. Planning is\n\t\t\t// allowed to overlap active user work, but application must not disconnect\n\t\t\t// event handling until that work and its queued events have completed.\n\t\t\tawait this.agent.waitForIdle();\n\t\t\twhile (true) {\n\t\t\t\tconst eventQueue = this._agentEventQueue;\n\t\t\t\tconst compactionOp = this._compactionOperation;\n\t\t\t\tconst branchSummaryOp = this._branchSummaryOperation;\n\t\t\t\tawait Promise.allSettled([\n\t\t\t\t\teventQueue,\n\t\t\t\t\t...(compactionOp ? [compactionOp] : []),\n\t\t\t\t\t...(branchSummaryOp ? [branchSummaryOp] : []),\n\t\t\t\t]);\n\t\t\t\tif (\n\t\t\t\t\teventQueue === this._agentEventQueue &&\n\t\t\t\t\tcompactionOp === this._compactionOperation &&\n\t\t\t\t\tbranchSummaryOp === this._branchSummaryOperation\n\t\t\t\t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this._disposed || refineAbort.signal.aborted) {\n\t\t\t\tthrow new Error(\"Refinement cancelled because the session was disposed.\");\n\t\t\t}\n\t\t\treturn await this._applyRefine(plan, options, refineAbort);\n\t\t} finally {\n\t\t\tresolveApplySettled();\n\t\t\tif (this._refineInFlight === applySettled) {\n\t\t\t\tthis._refineInFlight = undefined;\n\t\t\t}\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\tthis._scheduleSessionInputPump();\n\t\t}\n\t}\n\n\t/**\n\t * Block a new agent turn until any in-flight refine application phase has\n\t * reattached event handling; otherwise the turn's messages are never\n\t * persisted or rendered.\n\t *\n\t * The idle-wait and application phase (`_refineInFlight`) block here. The\n\t * background planning phase (`_refinePlanInFlight`) does NOT block turns.\n\t * Refine failures surface to the refine caller, not here.\n\t */\n\tprivate async _waitForRefineIdle(): Promise<void> {\n\t\twhile (this._refineInFlight) {\n\t\t\tawait this._refineInFlight;\n\t\t}\n\t}\n\n\t/**\n\t * Background planning phase: runs the LLM planning call via `planRefinement`.\n\t * Does not disconnect from or abort the agent. Returns the plan without\n\t * applying anything.\n\t */\n\tprivate async _planRefine(\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean },\n\t\tsignal: AbortSignal,\n\t\ttrigger: \"manual\" | \"auto\" = \"manual\",\n\t): Promise<RefinementPlan> {\n\t\tif (this._disposed) {\n\t\t\tthrow new Error(\"Cannot refine a disposed session.\");\n\t\t}\n\n\t\tconst selected = this._resolveRefinementModel();\n\t\tif (!selected) throw new Error(formatNoModelSelectedMessage());\n\t\tconst { model, thinkingLevel, explicit } = selected;\n\t\tconst messages = structuredClone(this.agent.state.messages);\n\t\tconst requestOptions = { ...options };\n\t\tconst globalHarnessStateDir = getGlobalHarnessStateDir();\n\t\tconst localHarnessStateDir = this._localHarnessStateDir();\n\t\tconst requestedScope = requestOptions.global ? \"global\" : \"local\";\n\t\tif (!requestOptions.rollbackId && requestedScope === \"local\" && !localHarnessStateDir) {\n\t\t\tthrow new Error(\"Local harness refinement requires a persisted session; use global refinement instead.\");\n\t\t}\n\t\tconst globalPlanningState = loadHarnessState(globalHarnessStateDir, \"global\");\n\t\tconst localPlanningState = localHarnessStateDir ? loadHarnessState(localHarnessStateDir, \"local\") : undefined;\n\t\tconst planningState =\n\t\t\trequestedScope === \"global\"\n\t\t\t\t? globalPlanningState\n\t\t\t\t: mergeHarnessStates(globalPlanningState, localPlanningState);\n\t\tconst plannerManager = this.sessionManager;\n\t\tconst requests = this.requests[captureNativePlannerRequests](plannerManager.bindRequestSink());\n\t\ttry {\n\t\t\tconst history = await this._loadRefinementHistory();\n\t\t\tconst rollbackTarget = requestOptions.rollbackId\n\t\t\t\t? history.find((item) => item.id === requestOptions.rollbackId)\n\t\t\t\t: undefined;\n\t\t\tlet baselineScope = rollbackTarget\n\t\t\t\t? (inferRefinementResultScope(rollbackTarget) ?? requestedScope)\n\t\t\t\t: requestedScope;\n\t\t\tlet baselineHarnessStateDir = baselineScope === \"global\" ? globalHarnessStateDir : localHarnessStateDir;\n\t\t\tif (rollbackTarget?.harnessStatePath) {\n\t\t\t\tbaselineHarnessStateDir = dirname(rollbackTarget.harnessStatePath);\n\t\t\t\tbaselineScope = resolve(baselineHarnessStateDir) === resolve(globalHarnessStateDir) ? \"global\" : \"local\";\n\t\t\t}\n\t\t\tif (!baselineHarnessStateDir) {\n\t\t\t\tthrow new Error(\"Local harness refinement requires a persisted session; use global refinement instead.\");\n\t\t\t}\n\t\t\tconst baselineState = rollbackTarget\n\t\t\t\t? loadHarnessState(baselineHarnessStateDir, baselineScope)\n\t\t\t\t: baselineScope === \"global\"\n\t\t\t\t\t? globalPlanningState\n\t\t\t\t\t: localPlanningState!;\n\t\t\tconst { apiKey, headers } = await this._getRequiredRequestAuth(model);\n\t\t\tif (!requestOptions.rollbackId && this._extensionRunner.hasHandlers(\"session_before_refine\")) {\n\t\t\t\tconst result = (await this._extensionRunner.emit({\n\t\t\t\t\ttype: \"session_before_refine\",\n\t\t\t\t\tpreparation: {\n\t\t\t\t\t\ttrigger,\n\t\t\t\t\t\tinstructions: requestOptions.instructions,\n\t\t\t\t\t\tscope: requestedScope,\n\t\t\t\t\t\tplanningState,\n\t\t\t\t\t\thistory,\n\t\t\t\t\t\tconversationText: serializeConversation(convertToLlm(messages)).slice(-80_000),\n\t\t\t\t\t},\n\t\t\t\t\tsignal,\n\t\t\t\t})) as SessionBeforeRefineResult | undefined;\n\t\t\t\tif (this._disposed || signal.aborted) {\n\t\t\t\t\tthrow new Error(\"Refinement cancelled because the session was disposed.\");\n\t\t\t\t}\n\t\t\t\tif (result?.skip) {\n\t\t\t\t\tthrow new RefineSkippedError(\"Refinement skipped by extension\");\n\t\t\t\t}\n\t\t\t\tif (result?.proposal !== undefined) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproposal: normalizeRefinementProposal(result.proposal),\n\t\t\t\t\t\tid: generateRefinementId(),\n\t\t\t\t\t\tbaselineState,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst plan = await planRefinement(\n\t\t\t\tmessages,\n\t\t\t\tplanningState,\n\t\t\t\thistory,\n\t\t\t\tmodel,\n\t\t\t\tapiKey,\n\t\t\t\trequestOptions,\n\t\t\t\theaders,\n\t\t\t\tsignal,\n\t\t\t\tthinkingLevel,\n\t\t\t\trequests,\n\t\t\t\texplicit,\n\t\t\t);\n\t\t\tif (this._disposed || signal.aborted) {\n\t\t\t\tthrow new Error(\"Refinement cancelled because the session was disposed.\");\n\t\t\t}\n\t\t\treturn withRefinementBaseline(plan, baselineState);\n\t\t} finally {\n\t\t\tawait requests.dispose();\n\t\t}\n\t}\n\n\tprivate async _recordRefinementOutcome(result: RefinementResult): Promise<void> {\n\t\tconst message = createRefinementOutcomeMessage(result);\n\t\ttry {\n\t\t\tawait this.sessionManager.appendCustomMessageEntryWithRollback(\n\t\t\t\tmessage.customType,\n\t\t\t\tmessage.content,\n\t\t\t\tmessage.display,\n\t\t\t\tmessage.details,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\t// Retain the already-applied effect, but do not publish a saved outcome.\n\t\t\tthis._unpersistedOutcomes.push(message);\n\t\t\tthrow error;\n\t\t}\n\t\tthis.agent.state.messages.push(message);\n\t\tthis._emit({ type: \"message_start\", message });\n\t\tthis._emit({ type: \"message_end\", message });\n\t}\n\n\t/**\n\t * Synchronous application phase: disconnects from the agent, aborts any\n\t * in-flight agent run, applies the refinement plan to disk and memory, then\n\t * reconnects. This is the only phase that blocks turn entry points.\n\t */\n\tprivate async _applyRefine(\n\t\tplan: RefinementPlan,\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean },\n\t\trefineAbort: AbortController,\n\t): Promise<RefinementResult> {\n\t\tif (this._disposed) {\n\t\t\tthrow new Error(\"Cannot refine a disposed session.\");\n\t\t}\n\t\t// The caller has already set _refineInFlight and waited for agent idle.\n\t\t// Disconnect only for the brief apply + save + reconnect critical section.\n\t\toptions = { ...options };\n\t\tthis._disconnectFromAgent();\n\n\t\ttry {\n\t\t\tconst globalHarnessStateDir = getGlobalHarnessStateDir();\n\t\t\tconst localHarnessStateDir = this._localHarnessStateDir();\n\t\t\tconst requestedScope = options.global ? \"global\" : \"local\";\n\t\t\tconst history = await this._loadRefinementHistory();\n\t\t\tconst rollbackTarget = options.rollbackId ? history.find((item) => item.id === options.rollbackId) : undefined;\n\t\t\tlet targetScope = plan.rollbackScope ?? requestedScope;\n\t\t\tlet targetHarnessStateDir = targetScope === \"global\" ? globalHarnessStateDir : localHarnessStateDir;\n\t\t\tif (targetScope === \"local\" && rollbackTarget?.harnessStatePath) {\n\t\t\t\tif (!existsSync(rollbackTarget.harnessStatePath)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Local refinement ${rollbackTarget.id} state file not found: ${rollbackTarget.harnessStatePath}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\ttargetHarnessStateDir = dirname(rollbackTarget.harnessStatePath);\n\t\t\t\t// Legacy records predate scope fields and default to \"local\" but may point\n\t\t\t\t// at the global store; honor the recorded path so its entries stay global.\n\t\t\t\tif (resolve(targetHarnessStateDir) === resolve(globalHarnessStateDir)) {\n\t\t\t\t\ttargetScope = \"global\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!targetHarnessStateDir) {\n\t\t\t\tthrow new Error(\"Local harness refinement requires a persisted session; use global refinement instead.\");\n\t\t\t}\n\t\t\t// Re-read the target state immediately before applying so concurrent kernel\n\t\t\t// (`rlm.harness`) writes during the LLM pass are not clobbered.\n\t\t\tconst state = loadHarnessState(targetHarnessStateDir, targetScope);\n\t\t\tconst proposal = prepareRefinementApplication(plan, state, options, targetScope);\n\t\t\tif (this._disposed || refineAbort.signal.aborted) {\n\t\t\t\tthrow new Error(\"Refinement cancelled because the session was disposed.\");\n\t\t\t}\n\t\t\tconst result = applyRefinementProposal(state, proposal, {\n\t\t\t\tid: plan.id,\n\t\t\t\trollbackOf: plan.rollbackOf,\n\t\t\t\tscope: targetScope,\n\t\t\t\tbaselineState: plan.baselineState,\n\t\t\t});\n\t\t\tresult.harnessStatePath = saveHarnessState(targetHarnessStateDir, state);\n\t\t\tif (targetScope === \"global\") {\n\t\t\t\tawait appendGlobalRefinement(globalHarnessStateDir, result);\n\t\t\t}\n\t\t\tlet refinementAuditAppendError: { error: unknown } | undefined;\n\t\t\ttry {\n\t\t\t\tconst manager = this.sessionManager;\n\t\t\t\tconst write = takeNativePlannerRequestWrite(result);\n\t\t\t\tconst pending = write?.(manager);\n\t\t\t\tif ((pending ? await pending : undefined) === undefined) {\n\t\t\t\t\tawait manager.appendCustomEntry(\"prime-agent.refinement\", result);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\trefinementAuditAppendError = { error };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait this._recordRefinementOutcome(result);\n\t\t\t} catch (error) {\n\t\t\t\tif (!refinementAuditAppendError) throw error;\n\t\t\t}\n\t\t\tif (refinementAuditAppendError) throw refinementAuditAppendError.error;\n\t\t\t// Keep extension-facing state fresh, but do not rewrite the cached system prefix.\n\t\t\tthis._baseSystemPromptOptions = {\n\t\t\t\t...this._baseSystemPromptOptions,\n\t\t\t\tharnessState: this._loadMergedHarnessState(),\n\t\t\t};\n\t\t\t// The next owned request appends the new advice before capturing its source.\n\t\t\ttry {\n\t\t\t\tthis._emit({ type: \"refine_complete\", result });\n\t\t\t} catch {\n\t\t\t\t// Listener failures must not flip a successful refinement into\n\t\t\t\t// a reported failure — the refinement is already persisted.\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait this._extensionRunner.emit({\n\t\t\t\t\ttype: \"refine_complete\",\n\t\t\t\t\tid: result.id,\n\t\t\t\t\tsummary: result.summary,\n\t\t\t\t\tappliedEdits: result.appliedEdits.filter((edit) => edit.applied).length,\n\t\t\t\t\tscope: result.scope ?? \"local\",\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\t// Extension emit failures must not flip a successful refinement\n\t\t\t\t// into a reported failure — the refinement is already persisted.\n\t\t\t}\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (this._refineAbortController === refineAbort) {\n\t\t\t\tthis._refineAbortController = undefined;\n\t\t\t}\n\t\t\tif (!this._disposed) {\n\t\t\t\tthis._reconnectToAgent();\n\t\t\t}\n\t\t}\n\t}\n\n\tabortBranchSummary(): void {\n\t\tthis._branchSummaryAbortController?.abort();\n\t}\n\n\t/**\n\t * Check if compaction is needed and run it.\n\t * Called after agent_end and before prompt submission.\n\t *\n\t * Two cases:\n\t * 1. Overflow: LLM returned context overflow error, remove error message from agent state, compact, auto-retry\n\t * 2. Threshold: Context over threshold, compact, and continue only for stopped in-progress loops or queued messages\n\t *\n\t * @param assistantMessage The assistant message to check\n\t * @param skipAbortedCheck If false, include aborted messages (for pre-prompt check). Default: true\n\t */\n\tprivate _getThresholdContextTokens(\n\t\tassistantMessage: AssistantMessage,\n\t\tcompactionTimestamp: number | undefined,\n\t): number | undefined {\n\t\tconst messages = this.agent.state.messages;\n\t\tconst estimate = estimateContextTokens(messages);\n\t\tif (estimate.lastUsageIndex !== null) {\n\t\t\t// Verify the usage source is post-compaction. Kept pre-compaction messages\n\t\t\t// have stale usage reflecting the old (larger) context and would falsely\n\t\t\t// trigger compaction right after one just finished.\n\t\t\tconst usageMsg = messages[estimate.lastUsageIndex];\n\t\t\tif (\n\t\t\t\tcompactionTimestamp !== undefined &&\n\t\t\t\tusageMsg.role === \"assistant\" &&\n\t\t\t\t(usageMsg as AssistantMessage).timestamp <= compactionTimestamp\n\t\t\t) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn estimate.tokens;\n\t\t}\n\t\tif (assistantMessage.stopReason === \"error\") return undefined;\n\t\treturn calculateContextTokens(assistantMessage.usage);\n\t}\n\n\tprivate async _checkCompaction(\n\t\tassistantMessage: AssistantMessage,\n\t\tskipAbortedCheck = true,\n\t\tqueueAutonomousContinuation = true,\n\t\tinvocationOwner?: CompactionOwner,\n\t\tbeforeNextTurn = false,\n\t): Promise<boolean> {\n\t\tif (this._compactionSetupFailure) return false;\n\t\tif (invocationOwner && !this._isCompactionSourceOwnerCurrent(invocationOwner)) return false;\n\t\tconst owner =\n\t\t\tthis._pendingCheckpoint?.owner ??\n\t\t\t(invocationOwner\n\t\t\t\t? { ...invocationOwner, pumpEpoch: this._sessionInputPumpEpoch }\n\t\t\t\t: this._captureCompactionOwner());\n\t\tif (!this._isCompactionSourceOwnerCurrent(owner)) return false;\n\t\tif (assistantMessage.stopReason !== \"aborted\" && !this._isCompactionOwnerCurrent(owner)) return false;\n\t\tconst goalOwner = { ...this._captureGoalContinuationOwner(owner.signal), checkpointOwner: owner };\n\t\tconst autonomousOwner = this._captureThresholdAutonomousOwner();\n\t\tconst pending = this._pendingRequestedCompaction;\n\t\tif (pending && !this._isCompactionOwnerCurrent(pending.owner)) this._pendingRequestedCompaction = undefined;\n\t\tif (!this._contextOptimizationAllowed() && this._pendingRequestedCompaction === undefined) return false;\n\t\t// An abort drops any compaction the model requested this turn, even on the\n\t\t// pre-prompt path (skipAbortedCheck=false) which continues to threshold checks.\n\t\tif (assistantMessage.stopReason === \"aborted\") {\n\t\t\tthis._pendingRequestedCompaction = undefined;\n\t\t\tthis._pendingCheckpoint = undefined;\n\t\t\t// An abort also drops any pending explicit refine.run request: the\n\t\t\t// turn that would service it (non-serialized: _consumePendingRequestedRefine\n\t\t\t// at agent_end; serialized: the shouldStopAfterTurn checkpoint) never\n\t\t\t// runs for an aborted turn, so a stale request would leak into the\n\t\t\t// next turn or checkpoint.\n\t\t\tthis._pendingRequestedRefine = undefined;\n\t\t\tif (this._serializedPlanInFlight) {\n\t\t\t\tconst serializedPlanInFlight = this._serializedPlanInFlight;\n\t\t\t\tthis._autoRefineBranchVersion++;\n\t\t\t\tthis._refineAbortController?.abort();\n\t\t\t\tawait serializedPlanInFlight.catch(() => undefined);\n\t\t\t\tif (this._serializedPlanInFlight === serializedPlanInFlight) {\n\t\t\t\t\tthis._serializedPlanInFlight = undefined;\n\t\t\t\t\tthis._serializedExplicitRefineOptions = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (skipAbortedCheck) return false;\n\t\t}\n\n\t\tconst settings = this.settingsManager.getCompactionSettings();\n\t\tconst contextWindow = this.model?.contextWindow ?? 0;\n\n\t\t// Skip overflow check if the message came from a different model.\n\t\t// This handles the case where user switched from a smaller-context model (e.g. opus)\n\t\t// to a larger-context model (e.g. codex) - the overflow error from the old model\n\t\t// shouldn't trigger compaction for the new model.\n\t\tconst sameModel =\n\t\t\tthis.model && assistantMessage.provider === this.model.provider && assistantMessage.model === this.model.id;\n\n\t\t// Skip overflow/threshold checks if this assistant message is older than the\n\t\t// latest compaction boundary. This prevents a stale pre-compaction usage/error\n\t\t// from retriggering compaction on the first prompt after compaction.\n\t\tlet compactionTimestamp: number | undefined;\n\t\ttry {\n\t\t\tcompactionTimestamp = await this._getLatestCompactionTimestamp(owner);\n\t\t} catch (error) {\n\t\t\t// A manual checkpoint can supersede this optional check after agent_end was emitted.\n\t\t\tif (error instanceof StaleCompactionOwnerError && !this._isCompactionOwnerCurrent(owner)) return false;\n\t\t\tthrow error;\n\t\t}\n\t\tif (!this._isCompactionOwnerCurrent(owner)) return false;\n\t\tlet assistantIsFromBeforeCompaction =\n\t\t\tcompactionTimestamp !== undefined && assistantMessage.timestamp <= compactionTimestamp;\n\t\tconst assistantEntryId = this._findAssistantEntryIdForMessage(assistantMessage);\n\t\tif (assistantEntryId && owner.manager.supportsCapturedHistoryReads()) {\n\t\t\tconst ordered = await owner.manager.readBranchHistory(async (history) => {\n\t\t\t\tconst assistant = await history.get(assistantEntryId);\n\t\t\t\tconst boundary = (await history.branchBootstrap()).latestCompaction;\n\t\t\t\treturn assistant && boundary ? assistant.sequence <= boundary.sequence : undefined;\n\t\t\t});\n\t\t\tif (!this._isCompactionOwnerCurrent(owner)) return false;\n\t\t\t// Provider messages are timestamped before request preparation, which may\n\t\t\t// commit an epoch. Canonical append order, not that start time, owns staleness.\n\t\t\tif (ordered !== undefined) assistantIsFromBeforeCompaction = ordered;\n\t\t}\n\n\t\t// Case 1: Overflow - takes priority over a pending model request so the error\n\t\t// strip + retry still happen; the compaction it runs consumes the request.\n\t\tif (\n\t\t\t!assistantIsFromBeforeCompaction &&\n\t\t\t(settings.enabled || this._pendingRequestedCompaction !== undefined) &&\n\t\t\tsameModel &&\n\t\t\tisContextOverflow(assistantMessage, contextWindow)\n\t\t) {\n\t\t\tif (this._overflowRecovery !== \"idle\") {\n\t\t\t\tif (this._overflowRecovery === \"attempted\") {\n\t\t\t\t\tthis._overflowRecovery = \"reported\";\n\t\t\t\t\tawait this._endCompactionUnsuccessfully(\n\t\t\t\t\t\t\"overflow\",\n\t\t\t\t\t\t\"failed\",\n\t\t\t\t\t\t\"Context overflow recovery failed after one compact-and-retry attempt. Try reducing context or switching to a larger-context model.\",\n\t\t\t\t\t\t{ owner },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis._overflowRecovery = \"attempted\";\n\t\t\t// Remove the error message from agent state (it IS saved to session for history,\n\t\t\t// but we don't want it in context for the retry)\n\t\t\tconst messages = this.agent.state.messages;\n\t\t\tif (messages.length > 0 && messages[messages.length - 1].role === \"assistant\") {\n\t\t\t\tthis._removeLastAssistantFromContext();\n\t\t\t}\n\t\t\treturn await this._runAutoCompaction(\"overflow\", true, owner, false, undefined, beforeNextTurn);\n\t\t}\n\n\t\tif (this._pendingRequestedCompaction !== undefined) {\n\t\t\treturn await this._runAutoCompaction(\"requested\", false, owner);\n\t\t}\n\n\t\tif (!this._contextOptimizationAllowed() || !settings.enabled || assistantIsFromBeforeCompaction) return false;\n\t\t// A native turn already made its typed decision. Do not synthesize a new policy winner at agent_end.\n\t\tif (invocationOwner && !this._pendingCheckpoint) return false;\n\n\t\t// Case 3: Threshold - context is getting large.\n\t\t// Use the full-session estimate so messages appended after the last successful\n\t\t// assistant usage are included, matching the /usage context display.\n\t\tconst contextTokens = this._getThresholdContextTokens(assistantMessage, compactionTimestamp);\n\t\tif (contextTokens === undefined) return false;\n\t\tif (\n\t\t\tshouldCompact(\n\t\t\t\tcontextTokens,\n\t\t\t\tcontextWindow,\n\t\t\t\tsettings,\n\t\t\t\testimateFixedCompactionTokens(this.systemPrompt, this.agent.state.tools, this.messages),\n\t\t\t)\n\t\t) {\n\t\t\tif (this._hasFailedThresholdCompaction()) return false;\n\t\t\tif (!this._pendingCheckpoint && queueAutonomousContinuation) {\n\t\t\t\tif (\n\t\t\t\t\t!(await this._queueGoalContinuationForThresholdCompaction(assistantMessage, goalOwner)) &&\n\t\t\t\t\tthis._isGoalContinuationOwnerCurrent(goalOwner)\n\t\t\t\t) {\n\t\t\t\t\tawait this._queueAutonomousContinuationForThresholdCompaction(assistantMessage, owner, autonomousOwner);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!this._isCompactionOwnerCurrent(owner) || !this._contextOptimizationAllowed()) return false;\n\t\t\treturn await this._runAutoCompaction(\"threshold\", false, owner, false, undefined, beforeNextTurn);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Internal: Run automatic (threshold/overflow) or model-requested compaction\n\t * with events.\n\t */\n\tprivate async _endCompactionUnsuccessfully(\n\t\treason: CompactionOutcomeReason,\n\t\toutcome: CompactionOutcome,\n\t\tmessage: string,\n\t\toptions: {\n\t\t\taborted?: boolean;\n\t\t\terrorSeverity?: \"warning\" | \"error\";\n\t\t\tcustomInstructions?: string;\n\t\t\towner?: CompactionOwner;\n\t\t} = {},\n\t): Promise<void> {\n\t\tconst owner = options.owner ?? this._captureCompactionOwner();\n\t\tawait this._persistCompactionOutcome(reason, outcome, message, owner);\n\t\tthis._assertCompactionSourceOwner(owner);\n\t\tthis._emit({\n\t\t\ttype: \"compaction_end\",\n\t\t\treason,\n\t\t\tresult: undefined,\n\t\t\taborted: options.aborted ?? false,\n\t\t\twillRetry: false,\n\t\t\t// Aborts are user-initiated; they carry no error message on the event.\n\t\t\terrorMessage: options.aborted ? undefined : message,\n\t\t\terrorSeverity: options.errorSeverity,\n\t\t\tcustomInstructions: options.customInstructions,\n\t\t});\n\t}\n\n\tprivate async _persistCompactionOutcome(\n\t\treason: CompactionOutcomeReason,\n\t\toutcome: CompactionOutcome,\n\t\tmessage: string,\n\t\towner = this._captureCompactionOwner(),\n\t): Promise<void> {\n\t\tthis._assertCompactionSourceOwner(owner);\n\t\tlet outcomeMessage = createCompactionOutcomeMessage(message, {\n\t\t\treason,\n\t\t\toutcome,\n\t\t});\n\t\ttry {\n\t\t\tawait owner.manager.appendCustomMessageEntryWithRollback(\n\t\t\t\toutcomeMessage.customType,\n\t\t\t\toutcomeMessage.content,\n\t\t\t\toutcomeMessage.display,\n\t\t\t\toutcomeMessage.details,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (!this._isCompactionSourceOwnerCurrent(owner)) throw error;\n\t\t\tconst persistenceError = error instanceof Error ? error.message : String(error);\n\t\t\toutcomeMessage = createCompactionOutcomeMessage(\n\t\t\t\t`${message}\\n\\nThis compaction outcome could not be saved to session history: ${persistenceError}`,\n\t\t\t\t{ reason, outcome },\n\t\t\t);\n\t\t\t// Not in the session file, so context rebuilds would drop the disclosure.\n\t\t\tthis._unpersistedOutcomes.push(outcomeMessage);\n\t\t}\n\t\tthis._assertCompactionSourceOwner(owner);\n\t\towner.agent.state.messages.push(outcomeMessage);\n\t\tthis._emit({ type: \"message_start\", message: outcomeMessage });\n\t\tthis._emit({ type: \"message_end\", message: outcomeMessage });\n\t}\n\n\tprivate async _runAutoCompaction(\n\t\treason: \"overflow\" | \"threshold\" | \"requested\",\n\t\twillRetry: boolean,\n\t\tcapturedOwner?: CompactionOwner,\n\t\tresumeInPlace = false,\n\t\tcapacity?: PublicContextBudgetError,\n\t\tbeforeNextTurn = false,\n\t): Promise<boolean> {\n\t\tconst checkpoint = this._pendingCheckpoint;\n\t\tconst pending = this._pendingRequestedCompaction;\n\t\tconst owner = checkpoint?.owner ?? pending?.owner ?? capturedOwner ?? this._captureCompactionOwner();\n\t\tif (!this._isCompactionOwnerCurrent(owner)) return false;\n\t\tif (reason === \"threshold\" && !this._contextOptimizationAllowed()) return false;\n\t\tif (checkpoint && !this._isCompactionOwnerCurrent(checkpoint.owner)) return false;\n\t\tif (pending && !this._isCompactionOwnerCurrent(pending.owner)) return false;\n\t\tthis._pendingRequestedCompaction = undefined;\n\t\tconst customInstructions = pending?.customInstructions;\n\t\tconst resume = resumeInPlace\n\t\t\t? this._captureCheckpointResume(owner, { kind: \"request\", state: \"pending\" })\n\t\t\t: reason === \"overflow\"\n\t\t\t\t? this._captureCheckpointResume(owner, { kind: \"overflow\", state: \"pending\" })\n\t\t\t\t: (checkpoint ?? this._captureCheckpointResume(owner));\n\t\tthis._pendingCheckpoint = resume;\n\t\tconst shouldContinueAfterCompaction = this._checkpointHasResume(resume);\n\t\tconst queuedAutonomousContinuationsForThisCompaction =\n\t\t\treason === \"threshold\" && shouldContinueAfterCompaction\n\t\t\t\t? this._pendingThresholdCompactionAutonomousContinuations.splice(0)\n\t\t\t\t: [];\n\t\tconst queuedGoalContinuationForThisCompaction =\n\t\t\treason === \"threshold\" && shouldContinueAfterCompaction ? this._queuedGoalThresholdContinuation : undefined;\n\t\tconst resumeAfterFailure = () => {\n\t\t\tif (\n\t\t\t\t!resumeInPlace &&\n\t\t\t\t(reason === \"requested\" || reason === \"threshold\") &&\n\t\t\t\tthis._isCompactionOwnerCurrent(owner) &&\n\t\t\t\t(this._checkpointHasResume(resume) || owner.agent.hasQueuedMessages() || this.hasPendingSessionWork)\n\t\t\t) {\n\t\t\t\tthis._schedulePostCompactionContinue(resume);\n\t\t\t}\n\t\t};\n\n\t\tthis._emit({ type: \"compaction_start\", reason, customInstructions });\n\t\tconst abort = new AbortController();\n\t\tthis._autoCompactionAbortController = abort;\n\t\tlet resolveCompactionOperation: () => void = () => {};\n\t\tconst compactionOperation = new Promise<void>((resolve) => {\n\t\t\tresolveCompactionOperation = resolve;\n\t\t});\n\t\tthis._compactionOperation = compactionOperation;\n\t\tlet requests: InferenceCoordinator | undefined;\n\t\tlet compaction: BoundCompactionSink | undefined;\n\t\tlet committed: CompactionCommit | undefined;\n\t\tlet failure: unknown;\n\t\tconst thresholdConfiguration =\n\t\t\treason === \"threshold\" && !resumeInPlace\n\t\t\t\t? {\n\t\t\t\t\t\tconfiguration: this._thresholdCompactionConfiguration(),\n\t\t\t\t\t\tsystemPrompt: this.agent.state.systemPrompt,\n\t\t\t\t\t\ttools: this.agent.state.tools,\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\t\tconst rememberThresholdFailure = () => {\n\t\t\tif (\n\t\t\t\tthresholdConfiguration &&\n\t\t\t\t!abort.signal.aborted &&\n\t\t\t\tthis._isCompactionOwnerCurrent(owner) &&\n\t\t\t\tcompaction?.isCurrent()\n\t\t\t) {\n\t\t\t\tthis._failedThresholdCompaction = { ...thresholdConfiguration, isCurrent: compaction.isCurrent };\n\t\t\t}\n\t\t};\n\t\ttry {\n\t\t\tconst selected = this._resolveCompactionModel();\n\t\t\tconst model = selected?.model;\n\t\t\tconst thinkingLevel = selected?.thinkingLevel ?? this.thinkingLevel;\n\t\t\tconst settings = { ...this.settingsManager.getCompactionSettings() };\n\t\t\tconst semanticEdges = owner.semanticEdges;\n\t\t\tcompaction = owner.manager.bindCompactionSink();\n\t\t\trequests = owner.requests.capture(compaction);\n\t\t\tconst pathEntries = await compaction.readBranch();\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tconst authResult = model ? await this._modelRegistry.getApiKeyAndHeaders(model) : undefined;\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tif (!model || !authResult || !authResult.ok || !authResult.apiKey) {\n\t\t\t\tconst detail =\n\t\t\t\t\t!model || !authResult\n\t\t\t\t\t\t? \"no model is selected\"\n\t\t\t\t\t\t: authResult.ok\n\t\t\t\t\t\t\t? \"no API key is available\"\n\t\t\t\t\t\t\t: authResult.error;\n\t\t\t\tawait this._endCompactionUnsuccessfully(reason, \"failed\", `Compaction failed: ${detail}`, { owner });\n\t\t\t\tthis._clearQueuedAutonomousContinuationsAfterSkippedThresholdCompaction(\n\t\t\t\t\treason === \"threshold\" && shouldContinueAfterCompaction,\n\t\t\t\t\tqueuedAutonomousContinuationsForThisCompaction,\n\t\t\t\t);\n\t\t\t\trememberThresholdFailure();\n\t\t\t\tresumeAfterFailure();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tcommitted = await this._performCompaction({\n\t\t\t\tmodel,\n\t\t\t\tthinkingLevel,\n\t\t\t\tpathEntries,\n\t\t\t\tsettings,\n\t\t\t\trequests,\n\t\t\t\tcompaction,\n\t\t\t\tsemanticEdges,\n\t\t\t\towner,\n\t\t\t\tapiKey: authResult.apiKey,\n\t\t\t\theaders: authResult.headers,\n\t\t\t\tcustomInstructions,\n\t\t\t\tsignal: abort.signal,\n\t\t\t\t// Only confirmed public-budget recovery resumes within the same invocation.\n\t\t\t\tbudgetPressure: resumeInPlace,\n\t\t\t\tcapacity,\n\t\t\t});\n\t\t\tconst result = committed.result;\n\t\t\t// Release this captured source before arming success. A later release failure still carries the ACK.\n\t\t\tawait this._releaseCompactionCapture(requests, compaction, undefined, owner);\n\t\t\trequests = undefined;\n\t\t\tcompaction = undefined;\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tthis._emit({ type: \"compaction_end\", reason, result, aborted: false, willRetry, customInstructions });\n\t\t\tconst hasQueuedWork = owner.agent.hasQueuedMessages() || this.hasPendingSessionWork;\n\t\t\tconst willContinue = willRetry || this._checkpointHasResume(resume) || hasQueuedWork;\n\t\t\tif (willRetry) {\n\t\t\t\tconst messages = owner.agent.state.messages;\n\t\t\t\tconst last = messages[messages.length - 1];\n\t\t\t\tif (last?.role === \"assistant\" && last.stopReason === \"error\") this._removeLastAssistantFromContext();\n\t\t\t}\n\t\t\tif (willContinue && !resumeInPlace) this._schedulePostCompactionContinue(resume);\n\t\t\tthis._scheduleAutoRefineAfterCompaction(willContinue);\n\t\t\t// The unsent request remains in its original invocation; do not queue a new action.\n\t\t\treturn resumeInPlace || willRetry; // Other callers retain the existing overflow retry contract.\n\t\t} catch (error) {\n\t\t\tconst primaryCommit = primaryCommittedCompactionError(error);\n\t\t\tconst knownCommit = primaryCommit ?? committed;\n\t\t\tfailure =\n\t\t\t\tknownCommit && !(error instanceof CompactionCommittedError)\n\t\t\t\t\t? new CompactionCommittedError(knownCommit.entryId, knownCommit.result, error)\n\t\t\t\t\t: error;\n\t\t\tif (failure instanceof CompactionCommittedError) {\n\t\t\t\tthis._reportCommittedCompactionFailure(failure, reason, customInstructions, owner);\n\t\t\t\tthrow failure;\n\t\t\t}\n\t\t\tif (!this._isCompactionSourceOwnerCurrent(owner)) throw failure;\n\t\t\tthis._clearQueuedAutonomousContinuationsAfterSkippedThresholdCompaction(\n\t\t\t\treason === \"threshold\" && shouldContinueAfterCompaction,\n\t\t\t\tqueuedAutonomousContinuationsForThisCompaction,\n\t\t\t);\n\t\t\tif (beforeNextTurn && error instanceof MissingRecoveryReplayContractError) {\n\t\t\t\t// Let the imminent MAIN obtain its own actual projection/ACK. This was not a recovery attempt.\n\t\t\t\tif (reason === \"overflow\") this._overflowRecovery = \"idle\";\n\t\t\t\tawait this._endCompactionUnsuccessfully(\n\t\t\t\t\treason,\n\t\t\t\t\t\"skipped\",\n\t\t\t\t\t\"Compaction deferred until the next native request establishes recovery replay coverage.\",\n\t\t\t\t\t{ errorSeverity: \"warning\", customInstructions, owner },\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"compaction failed\";\n\t\t\tconst aborted =\n\t\t\t\terrorMessage === \"Compaction cancelled\" ||\n\t\t\t\t(error instanceof Error && error.name === \"AbortError\") ||\n\t\t\t\tabort.signal.aborted;\n\t\t\tif (aborted) {\n\t\t\t\tawait this._clearQueuedGoalContinuationAfterCancelledThresholdCompaction(\n\t\t\t\t\tqueuedGoalContinuationForThisCompaction,\n\t\t\t\t);\n\t\t\t\tawait this._endCompactionUnsuccessfully(\n\t\t\t\t\treason,\n\t\t\t\t\t\"cancelled\",\n\t\t\t\t\t`${reason === \"requested\" ? \"Requested c\" : \"C\"}ompaction cancelled`,\n\t\t\t\t\t{ aborted: true, customInstructions, owner },\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (error instanceof CompactionSkippedError) {\n\t\t\t\tawait this._endCompactionUnsuccessfully(\n\t\t\t\t\treason,\n\t\t\t\t\t\"skipped\",\n\t\t\t\t\treason === \"requested\"\n\t\t\t\t\t\t? `Requested compaction skipped: ${errorMessage}`\n\t\t\t\t\t\t: `Auto-compaction skipped: ${errorMessage}`,\n\t\t\t\t\t{ errorSeverity: \"warning\", customInstructions, owner },\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait this._endCompactionUnsuccessfully(\n\t\t\t\t\treason,\n\t\t\t\t\t\"failed\",\n\t\t\t\t\treason === \"overflow\"\n\t\t\t\t\t\t? `Context overflow recovery failed: ${errorMessage}`\n\t\t\t\t\t\t: reason === \"requested\"\n\t\t\t\t\t\t\t? `Requested compaction failed: ${errorMessage}`\n\t\t\t\t\t\t\t: `Auto-compaction failed: ${errorMessage}`,\n\t\t\t\t\t{ customInstructions, owner },\n\t\t\t\t);\n\t\t\t}\n\t\t\trememberThresholdFailure();\n\t\t\tresumeAfterFailure();\n\t\t\treturn false;\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait this._releaseCompactionCapture(requests, compaction, failure, owner);\n\t\t\t} finally {\n\t\t\t\tif (this._pendingCheckpoint === resume) this._pendingCheckpoint = undefined;\n\t\t\t\tif (this._autoCompactionAbortController === abort) this._autoCompactionAbortController = undefined;\n\t\t\t\tif (this._compactionOperation === compactionOperation) this._compactionOperation = undefined;\n\t\t\t\tresolveCompactionOperation();\n\t\t\t\tif (this._isCompactionOwnerCurrent(owner)) {\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tsetAutoCompactionEnabled(enabled: boolean): void {\n\t\tthis.settingsManager.setCompactionEnabled(enabled);\n\t}\n\n\tget autoCompactionEnabled(): boolean {\n\t\treturn this.settingsManager.getCompactionEnabled();\n\t}\n\n\t/**\n\t * Set the provider for extra env vars merged over process.env in extension\n\t * pi.exec() subprocesses. The function is read at exec time, so a host (e.g.\n\t * the daemon) can update the underlying value per attach without rebinding.\n\t */\n\tsetExecEnvProvider(provider: (() => Record<string, string | undefined> | undefined) | undefined): void {\n\t\tthis._execEnvProvider = provider;\n\t\tconst extensions = this._resourceLoader.getExtensions();\n\t\textensions.runtime.getExecEnv = provider;\n\t}\n\n\tasync bindExtensions(bindings: ExtensionBindings): Promise<void> {\n\t\tif (bindings.uiContext !== undefined) {\n\t\t\tthis._extensionUIContext = bindings.uiContext;\n\t\t}\n\t\tif (bindings.commandContextActions !== undefined) {\n\t\t\tthis._extensionCommandContextActions = bindings.commandContextActions;\n\t\t}\n\t\tif (bindings.shutdownHandler !== undefined) {\n\t\t\tthis._extensionShutdownHandler = bindings.shutdownHandler;\n\t\t}\n\t\tif (bindings.onError !== undefined) {\n\t\t\tthis._extensionErrorListener = bindings.onError;\n\t\t}\n\n\t\tthis._applyExtensionBindings(this._extensionRunner);\n\t\tawait this._extensionRunner.emit(this._sessionStartEvent);\n\t\tawait this.extendResourcesFromExtensions(this._sessionStartEvent.reason === \"reload\" ? \"reload\" : \"startup\");\n\t}\n\n\tprivate async extendResourcesFromExtensions(reason: \"startup\" | \"reload\"): Promise<void> {\n\t\tif (!this._extensionRunner.hasHandlers(\"resources_discover\")) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { skillPaths, promptPaths, themePaths } = await this._extensionRunner.emitResourcesDiscover(\n\t\t\tthis._cwd,\n\t\t\treason,\n\t\t);\n\n\t\tif (skillPaths.length === 0 && promptPaths.length === 0 && themePaths.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst extensionPaths: ResourceExtensionPaths = {\n\t\t\tskillPaths: this.buildExtensionResourcePaths(skillPaths),\n\t\t\tpromptPaths: this.buildExtensionResourcePaths(promptPaths),\n\t\t\tthemePaths: this.buildExtensionResourcePaths(themePaths),\n\t\t};\n\n\t\tthis._resourceLoader.extendResources(extensionPaths);\n\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t}\n\n\tprivate buildExtensionResourcePaths(entries: Array<{ path: string; extensionPath: string }>): Array<{\n\t\tpath: string;\n\t\tmetadata: {\n\t\t\tsource: string;\n\t\t\tscope: \"temporary\";\n\t\t\torigin: \"top-level\";\n\t\t\tbaseDir?: string;\n\t\t};\n\t}> {\n\t\treturn entries.map((entry) => {\n\t\t\tconst source = this.getExtensionSourceLabel(entry.extensionPath);\n\t\t\tconst baseDir = entry.extensionPath.startsWith(\"<\") ? undefined : dirname(entry.extensionPath);\n\t\t\treturn {\n\t\t\t\tpath: entry.path,\n\t\t\t\tmetadata: {\n\t\t\t\t\tsource,\n\t\t\t\t\tscope: \"temporary\",\n\t\t\t\t\torigin: \"top-level\",\n\t\t\t\t\tbaseDir,\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t}\n\n\tprivate getExtensionSourceLabel(extensionPath: string): string {\n\t\tif (extensionPath.startsWith(\"<\")) {\n\t\t\treturn `extension:${extensionPath.replace(/[<>]/g, \"\")}`;\n\t\t}\n\t\tconst base = basename(extensionPath);\n\t\tconst name = base.replace(/\\.(ts|js)$/, \"\");\n\t\treturn `extension:${name}`;\n\t}\n\n\tprivate _applyExtensionBindings(runner: ExtensionRunner): void {\n\t\trunner.setUIContext(this._extensionUIContext);\n\t\trunner.bindCommandContext(this._extensionCommandContextActions);\n\n\t\tthis._extensionErrorUnsubscriber?.();\n\t\tthis._extensionErrorUnsubscriber = this._extensionErrorListener\n\t\t\t? runner.onError(this._extensionErrorListener)\n\t\t\t: undefined;\n\t}\n\n\tprivate _refreshCurrentModelFromRegistry(): void {\n\t\tconst currentModel = this.model;\n\t\tif (!currentModel) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst refreshedModel = this._modelRegistry.find(currentModel.provider, currentModel.id);\n\t\tif (!refreshedModel || refreshedModel === currentModel) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.agent.state.model = refreshedModel;\n\t}\n\n\tprivate _bindExtensionCore(runner: ExtensionRunner): void {\n\t\tconst getCommands = (): SlashCommandInfo[] => {\n\t\t\tconst extensionCommands: SlashCommandInfo[] = runner.getRegisteredCommands().map((command) => ({\n\t\t\t\tname: command.invocationName,\n\t\t\t\tdescription: command.description,\n\t\t\t\tsource: \"extension\",\n\t\t\t\tsourceInfo: command.sourceInfo,\n\t\t\t}));\n\n\t\t\tconst templates: SlashCommandInfo[] = this.promptTemplates.map((template) => ({\n\t\t\t\tname: template.name,\n\t\t\t\tdescription: template.description,\n\t\t\t\tsource: \"prompt\",\n\t\t\t\tsourceInfo: template.sourceInfo,\n\t\t\t}));\n\n\t\t\tconst skills: SlashCommandInfo[] = this._resourceLoader.getSkills().skills.map((skill) => ({\n\t\t\t\tname: `skill:${skill.name}`,\n\t\t\t\tdescription: skill.description,\n\t\t\t\tsource: \"skill\",\n\t\t\t\tsourceInfo: skill.sourceInfo,\n\t\t\t}));\n\n\t\t\treturn [...extensionCommands, ...templates, ...skills];\n\t\t};\n\n\t\trunner.bindCore(\n\t\t\t{\n\t\t\t\tsendMessage: async (message, options) => {\n\t\t\t\t\tawait this.sendCustomMessage(message, options).catch((err) => {\n\t\t\t\t\t\trunner.emitError({\n\t\t\t\t\t\t\textensionPath: \"<runtime>\",\n\t\t\t\t\t\t\tevent: \"send_message\",\n\t\t\t\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tsendUserMessage: async (content, options) => {\n\t\t\t\t\tawait this.sendUserMessage(content, options).catch((err) => {\n\t\t\t\t\t\trunner.emitError({\n\t\t\t\t\t\t\textensionPath: \"<runtime>\",\n\t\t\t\t\t\t\tevent: \"send_user_message\",\n\t\t\t\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tappendEntry: async (customType, data) => {\n\t\t\t\t\tawait this.sessionManager.appendCustomEntry(customType, data);\n\t\t\t\t},\n\t\t\t\tsetSessionName: async (name) => {\n\t\t\t\t\tif (this._agentMessageController?.setSessionName) {\n\t\t\t\t\t\tawait this._agentMessageController.setSessionName(name);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setSessionName(name);\n\t\t\t\t},\n\t\t\t\tgetSessionName: () => {\n\t\t\t\t\treturn this.sessionManager.getSessionName();\n\t\t\t\t},\n\t\t\t\tsetLabel: async (entryId, label) => {\n\t\t\t\t\tawait this.sessionManager.appendLabelChange(entryId, label);\n\t\t\t\t},\n\t\t\t\tgetActiveTools: () => this.getActiveToolNames(),\n\t\t\t\tgetAllTools: () => this.getAllTools(),\n\t\t\t\tsetActiveTools: (toolNames) => this.setActiveToolsByName(toolNames),\n\t\t\t\trefreshTools: () => this._refreshToolRegistry(),\n\t\t\t\tgetCommands,\n\t\t\t\tsetModel: async (model) => {\n\t\t\t\t\tif (!this.modelRegistry.hasConfiguredAuth(model)) return false;\n\t\t\t\t\tawait this.setModel(model);\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t\tgetThinkingLevel: () => this.thinkingLevel,\n\t\t\t\tsetThinkingLevel: (level) => this.setThinkingLevel(level),\n\t\t\t},\n\t\t\t{\n\t\t\t\tgetModel: () => this.model,\n\t\t\t\tisIdle: () => !this.isStreaming,\n\t\t\t\tgetSignal: () => this.agent.signal,\n\t\t\t\tabort: () => this.abort(),\n\t\t\t\thasPendingMessages: () => this.queuedActionCount > 0,\n\t\t\t\tshutdown: () => {\n\t\t\t\t\tthis._extensionShutdownHandler?.();\n\t\t\t\t},\n\t\t\t\tgetContextUsage: () => this.getContextUsage(),\n\t\t\t\tcompact: (options) => {\n\t\t\t\t\tvoid (async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst result = await this.compact(options?.customInstructions);\n\t\t\t\t\t\t\toptions?.onComplete?.(result);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\t\t\toptions?.onError?.(err);\n\t\t\t\t\t\t}\n\t\t\t\t\t})();\n\t\t\t\t},\n\t\t\t\tgetSystemPrompt: () => this.systemPrompt,\n\t\t\t},\n\t\t\t{\n\t\t\t\tregisterProvider: (name, config) => {\n\t\t\t\t\tthis._modelRegistry.registerProvider(name, config);\n\t\t\t\t\tthis._refreshCurrentModelFromRegistry();\n\t\t\t\t},\n\t\t\t\tunregisterProvider: (name) => {\n\t\t\t\t\tthis._modelRegistry.unregisterProvider(name);\n\t\t\t\t\tthis._refreshCurrentModelFromRegistry();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n\n\tprivate _refreshToolRegistry(options?: { activeToolNames?: string[]; includeAllExtensionTools?: boolean }): void {\n\t\tconst previousRegistryNames = new Set(this._toolRegistry.keys());\n\t\tconst previousActiveToolNames = this.getActiveToolNames();\n\t\tconst allowedToolNames = this._allowedToolNames;\n\t\tconst registeredTools = this._extensionRunner.getAllRegisteredTools();\n\t\tconst sdkToolEntry = (definition: ToolDefinition) => ({\n\t\t\tdefinition,\n\t\t\tsourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, {\n\t\t\t\tsource: \"sdk\" as const,\n\t\t\t}),\n\t\t});\n\t\tconst allCustomTools = [\n\t\t\t...registeredTools,\n\t\t\t...this._customTools.map(sdkToolEntry),\n\t\t\t...this._acpMcpTools.map(sdkToolEntry),\n\t\t];\n\t\tconst isAllowedTool = (name: string): boolean => !allowedToolNames || allowedToolNames.has(name);\n\t\tconst allowedCustomTools = allCustomTools.filter((tool) => isAllowedTool(tool.definition.name));\n\t\tconst definitionRegistry = new Map<string, ToolDefinitionEntry>(\n\t\t\tArray.from(this._baseToolDefinitions.entries())\n\t\t\t\t.filter(([name]) => isAllowedTool(name))\n\t\t\t\t.map(([name, definition]) => [\n\t\t\t\t\tname,\n\t\t\t\t\t{\n\t\t\t\t\t\tdefinition,\n\t\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${name}>`, {\n\t\t\t\t\t\t\tsource: \"builtin\",\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t]),\n\t\t);\n\t\tfor (const tool of allowedCustomTools) {\n\t\t\tdefinitionRegistry.set(tool.definition.name, {\n\t\t\t\tdefinition: tool.definition,\n\t\t\t\tsourceInfo: tool.sourceInfo,\n\t\t\t});\n\t\t}\n\t\tthis._toolDefinitions = definitionRegistry;\n\t\tthis._toolPromptSnippets = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst snippet = this._normalizePromptSnippet(definition.promptSnippet);\n\t\t\t\t\treturn snippet ? ([definition.name, snippet] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string] => entry !== undefined),\n\t\t);\n\t\tthis._toolPromptGuidelines = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst guidelines = this._normalizePromptGuidelines(definition.promptGuidelines);\n\t\t\t\t\treturn guidelines.length > 0 ? ([definition.name, guidelines] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string[]] => entry !== undefined),\n\t\t);\n\t\tconst runner = this._extensionRunner;\n\t\tconst wrappedExtensionTools = wrapRegisteredTools(allowedCustomTools, runner);\n\t\t// Resolve the runner at call time so a rebuild/reload rebinds built-in tools to the\n\t\t// live runner instead of wedging them on the invalidated one's stale-ctx guard.\n\t\tconst wrappedBuiltInTools = wrapRegisteredTools(\n\t\t\tArray.from(this._baseToolDefinitions.values())\n\t\t\t\t.filter((definition) => isAllowedTool(definition.name))\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${definition.name}>`, { source: \"builtin\" }),\n\t\t\t\t})),\n\t\t\t() => this._extensionRunner,\n\t\t);\n\n\t\t// Only these actual built-in wrappers can establish a recovery execution scope.\n\t\t// Same-name custom tools and baseToolsOverride never enter this identity table.\n\t\tif (!this._baseToolsOverride) {\n\t\t\tfor (const tool of wrappedBuiltInTools) {\n\t\t\t\tif (tool.name === \"prime_context\" || tool.name === \"ipython\")\n\t\t\t\t\tthis._nativeRecoveryTools.set(tool, tool.execute);\n\t\t\t}\n\t\t}\n\t\tconst toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));\n\t\tfor (const tool of wrappedExtensionTools as AgentTool[]) {\n\t\t\ttoolRegistry.set(tool.name, tool);\n\t\t}\n\t\tthis._toolRegistry = toolRegistry;\n\n\t\tconst nextActiveToolNames = (\n\t\t\toptions?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames]\n\t\t).filter((name) => isAllowedTool(name));\n\n\t\tif (allowedToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (allowedToolNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (options?.includeAllExtensionTools) {\n\t\t\tfor (const tool of wrappedExtensionTools) {\n\t\t\t\tnextActiveToolNames.push(tool.name);\n\t\t\t}\n\t\t} else if (!options?.activeToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!previousRegistryNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.setActiveToolsByName([...new Set(nextActiveToolNames)]);\n\t}\n\n\tprivate _buildRuntime(options: {\n\t\tactiveToolNames?: string[];\n\t\tflagValues?: Map<string, boolean | string>;\n\t\tincludeAllExtensionTools?: boolean;\n\t}): void {\n\t\tconst pythonSkills = getPythonSkillRuntimeInfo(this._modelVisibleSkills());\n\t\tlet configuredBaseToolDefinitions: Record<string, ToolDefinition>;\n\t\tif (this._baseToolsOverride) {\n\t\t\tconfiguredBaseToolDefinitions = Object.fromEntries(\n\t\t\t\tObject.entries(this._baseToolsOverride).map(([name, tool]) => [\n\t\t\t\t\tname,\n\t\t\t\t\tcreateToolDefinitionFromAgentTool(tool),\n\t\t\t\t]),\n\t\t\t);\n\t\t} else {\n\t\t\t// Rebuilding (e.g. /reload) replaces the provisioner; drop the previous\n\t\t\t// kernel so the session never holds two live kernels. Gate the new kernel's\n\t\t\t// startup on the old one's dispose (which flushes a final snapshot), so a\n\t\t\t// reload can't restore from a snapshot the old kernel is still writing.\n\t\t\tconst previousDispose = this._ipythonKernelProvisioner?.dispose();\n\t\t\tthis._ipythonKernelSnapshotDir = this.sessionManager.getSessionArtifactDir();\n\t\t\t// Only surface the \"revived from your previous session\" notice on the first\n\t\t\t// build (a genuine resume). A later rebuild (/reload) restores state silently\n\t\t\t// for continuity — the conversation is unchanged, so there's nothing to flag.\n\t\t\tconst notifyRestore = !this._ipythonRuntimeBuilt;\n\t\t\tthis._ipythonKernelProvisioner = new IpythonKernelProvisioner(this._cwd, {\n\t\t\t\tenv: this._rlmKernelEnv(),\n\t\t\t\tcommandPrefix: this.settingsManager.getShellCommandPrefix(),\n\t\t\t\tshellPath: this.settingsManager.getShellPath(),\n\t\t\t\tsessionId: this.sessionId,\n\t\t\t\thostHandlers: this._createKernelHostHandlers(),\n\t\t\t\tpythonSkills,\n\t\t\t\tsnapshotDir: this._ipythonKernelSnapshotDir,\n\t\t\t\treadyGate: previousDispose,\n\t\t\t\tonRestore: notifyRestore ? (result) => this._onIpythonStateRestored(result) : undefined,\n\t\t\t});\n\t\t\tconfiguredBaseToolDefinitions = createAllToolDefinitions(this._cwd, {\n\t\t\t\tprime_context: { recover: (input, signal) => this.recoverNativeHistory(input, signal) },\n\t\t\t\tipython: {\n\t\t\t\t\tcaptureNativeRecoveryScope: () => {\n\t\t\t\t\t\tconst producer = this._nativeRecoveryProducer.getStore();\n\t\t\t\t\t\treturn producer ? (run) => this._nativeRecoveryProducer.run(producer, run) : undefined;\n\t\t\t\t\t},\n\t\t\t\t\tprovisioner: this._ipythonKernelProvisioner,\n\t\t\t\t\tcommandPrefix: this.settingsManager.getShellCommandPrefix(),\n\t\t\t\t\tshellPath: this.settingsManager.getShellPath(),\n\t\t\t\t\tonLateSentAgentMessage: (toolCallId, message) =>\n\t\t\t\t\t\tthis._recordLateIpythonSentAgentMessage(toolCallId, message),\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tthis._baseToolDefinitions = new Map(\n\t\t\tObject.entries(configuredBaseToolDefinitions).map(([name, tool]) => [name, tool as ToolDefinition]),\n\t\t);\n\n\t\tconst extensionsResult = this._resourceLoader.getExtensions();\n\t\tif (options.flagValues) {\n\t\t\tfor (const [name, value] of options.flagValues) {\n\t\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\t}\n\t\t}\n\t\t// Re-apply on (re)build so the provider survives /reload. Guarded: the\n\t\t// runtime object can be shared across sessions from one ResourceLoader\n\t\t// (RLM children), so a provider-less session must not wipe the owner's.\n\t\tif (this._execEnvProvider) {\n\t\t\textensionsResult.runtime.getExecEnv = this._execEnvProvider;\n\t\t}\n\n\t\tthis._extensionRunner = new ExtensionRunner(\n\t\t\textensionsResult.extensions,\n\t\t\textensionsResult.runtime,\n\t\t\tthis._cwd,\n\t\t\tthis.sessionManager,\n\t\t\tthis._modelRegistry,\n\t\t);\n\t\tif (this._extensionRunnerRef) {\n\t\t\tthis._extensionRunnerRef.current = this._extensionRunner;\n\t\t}\n\t\tthis._bindExtensionCore(this._extensionRunner);\n\t\tthis._applyExtensionBindings(this._extensionRunner);\n\n\t\tconst previousAcpMcpToolNames = new Set(this._acpMcpTools.map((tool) => tool.name));\n\t\tconst acpServers = this._mcpManager?.getAcpServers() ?? [];\n\t\tif (acpServers.length > 0 && !this._ipythonKernelProvisioner) {\n\t\t\tthrow new Error(\"ACP MCP servers require the built-in cpython tool\");\n\t\t}\n\t\tconst acpMcpTools = this._ipythonKernelProvisioner\n\t\t\t? createAcpMcpToolDefinitions(acpServers, this._ipythonKernelProvisioner)\n\t\t\t: [];\n\t\tthis._assertAcpMcpToolNamesAvailable(acpMcpTools.map((tool) => tool.name));\n\t\tfor (const name of previousAcpMcpToolNames) this._allowedToolNames?.delete(name);\n\t\tfor (const tool of acpMcpTools) this._allowedToolNames?.add(tool.name);\n\t\tthis._acpMcpTools = acpMcpTools;\n\n\t\tconst defaultActiveToolNames = this._baseToolsOverride\n\t\t\t? Object.keys(this._baseToolsOverride)\n\t\t\t: [\"ipython\", \"prime_context\"];\n\t\tconst baseActiveToolNames = [...(options.activeToolNames ?? defaultActiveToolNames)];\n\t\tif (this._goalState.status === \"active\" && this._includeGoals) {\n\t\t\t// An active goal needs ipython so the model can reach the goal skill.\n\t\t\tbaseActiveToolNames.push(\"ipython\");\n\t\t}\n\t\tthis._refreshToolRegistry({\n\t\t\tactiveToolNames: [...new Set(baseActiveToolNames)],\n\t\t\tincludeAllExtensionTools: options.includeAllExtensionTools,\n\t\t});\n\n\t\tthis._prewarmIpythonIfNeeded();\n\n\t\t// Subsequent builds are in-process rebuilds (/reload), not a fresh resume.\n\t\tthis._ipythonRuntimeBuilt = true;\n\t}\n\n\tprivate _prewarmIpythonIfNeeded(): void {\n\t\t// Also used when an asynchronously restored goal enables ipython after construction.\n\t\tconst hasSnapshot =\n\t\t\t!!this._ipythonKernelSnapshotDir && existsSync(snapshotPathIn(this._ipythonKernelSnapshotDir));\n\t\tif ((this._prewarmIpythonKernel || hasSnapshot) && this.getActiveToolNames().includes(\"ipython\")) {\n\t\t\tthis._ipythonKernelProvisioner?.prewarm();\n\t\t}\n\t}\n\n\t/**\n\t * Skills exposed to the model (system prompt + kernel). The bundled goal\n\t * and compact skills are withheld when disabled for this session.\n\t */\n\tprivate _modelVisibleSkills(): Skill[] {\n\t\tlet skills = this._resourceLoader.getSkills().skills;\n\t\tif (!this._includeGoals) {\n\t\t\tskills = skills.filter((skill) => skill.name !== GOAL_SKILL_NAME);\n\t\t}\n\t\tif (!this._includeCompactSkill) {\n\t\t\tskills = skills.filter((skill) => skill.name !== COMPACT_SKILL_NAME);\n\t\t}\n\t\tif (!this._autoRefineAllowedForSession()) {\n\t\t\tskills = skills.filter((skill) => skill.name !== REFINE_SKILL_NAME);\n\t\t}\n\t\tif (!this._agentMessageController) {\n\t\t\tskills = skills.filter((skill) => skill.name !== AGENT_MESSAGE_SKILL_NAME);\n\t\t}\n\t\tif (!this._agentObserveController) {\n\t\t\tskills = skills.filter((skill) => skill.name !== AGENT_OBSERVE_SKILL_NAME);\n\t\t}\n\t\tif (!this._agentObserveController || !this._rlmHeartbeatController) {\n\t\t\tskills = skills.filter((skill) => skill.name !== ORCHESTRATION_HEARTBEAT_SKILL_NAME);\n\t\t}\n\t\treturn skills;\n\t}\n\n\tprivate _nativeRecoveryEnabled(): boolean {\n\t\tconst nativeDefinition = this._baseToolDefinitions.get(\"prime_context\");\n\t\treturn (\n\t\t\t!this._baseToolsOverride &&\n\t\t\tnativeDefinition !== undefined &&\n\t\t\tthis._toolDefinitions.get(\"prime_context\")?.definition === nativeDefinition &&\n\t\t\tthis.getActiveToolNames().includes(\"prime_context\") &&\n\t\t\t(!this._allowedToolNames || this._allowedToolNames.has(\"prime_context\"))\n\t\t);\n\t}\n\n\tprivate _captureSkillSelectionOwner(): NativeSkillSelectionOwner | undefined {\n\t\tconst manager = this.sessionManager;\n\t\treturn manager.isPersisted()\n\t\t\t? {\n\t\t\t\t\tmanager,\n\t\t\t\t\tsessionId: manager.getSessionId(),\n\t\t\t\t\tsessionFile: manager.getSessionFile(),\n\t\t\t\t\twriter: manager[bindNativeEntryWriter]().captureSkillSelection(),\n\t\t\t\t\tinputEpoch: this._sessionInputPumpEpoch,\n\t\t\t\t}\n\t\t\t: undefined;\n\t}\n\n\tprivate _assertSkillSelectionOwner(owner: NativeSkillSelectionOwner): void {\n\t\towner.writer.assertCurrent();\n\t\tif (\n\t\t\tthis.sessionManager !== owner.manager ||\n\t\t\towner.sessionId !== owner.manager.getSessionId() ||\n\t\t\towner.sessionFile !== owner.manager.getSessionFile() ||\n\t\t\t(owner.inputEpoch !== undefined && owner.inputEpoch !== this._sessionInputPumpEpoch)\n\t\t)\n\t\t\tthrow new Error(\"Skill selection owner changed\");\n\t}\n\n\tprivate async _selectNativeSkill(\n\t\tskill: Skill,\n\t\towner: NativeSkillSelectionOwner,\n\t\tmodelInvocation: boolean,\n\t\tsignal?: AbortSignal,\n\t): Promise<\n\t\t| { ref: string; capture: SelectedSkillCapture; source: NativeSkillSourceRef; assertCurrent: () => void }\n\t\t| undefined\n\t> {\n\t\tconst assertCurrent = () => {\n\t\t\tsignal?.throwIfAborted();\n\t\t\tthis._assertSkillSelectionOwner(owner);\n\t\t\tif (modelInvocation && !this._nativeRecoveryEnabled())\n\t\t\t\tthrow new Error(\"Native skill selection is not authorized\");\n\t\t};\n\t\tassertCurrent();\n\t\tconst descriptor = captureSkillDescriptor(skill);\n\t\tconst result = (ref: string, capture: SelectedSkillCapture) => ({\n\t\t\tref,\n\t\t\tcapture,\n\t\t\tassertCurrent,\n\t\t\tsource: { sessionId: owner.sessionId, sessionFile: owner.sessionFile, entryId: ref },\n\t\t});\n\t\tconst state = await owner.manager.readBranchHistory((history) =>\n\t\t\treadSkillSelection(history.branchContext, descriptor.name, this.settingsManager.getCanonicalContextLimits()),\n\t\t);\n\t\tassertCurrent();\n\t\tif (!this._contextEpochsEnabled && !state.checkpoint) return;\n\t\tconst fixed =\n\t\t\tcontextEpochMode(state.checkpoint, this._initialContextMode) === \"off\" ||\n\t\t\t(state.checkpoint?.policyOnly === true && !this._contextEpochsEnabled);\n\t\t// A new file capture is eligible only after an actual accepted epoch boundary.\n\t\t// Off/fixed reads keep the retained version; no file read is a policy/epoch ACK.\n\t\tconst sameSource =\n\t\t\t!state.capture || selectedSkillIdentity(state.capture.descriptor) === selectedSkillIdentity(descriptor);\n\t\tif (state.reference && !sameSource && fixed)\n\t\t\tthrow new Error(\"Fixed context cannot substitute a different effective skill source\");\n\t\tif (\n\t\t\tstate.reference &&\n\t\t\tstate.capture &&\n\t\t\tsameSource &&\n\t\t\t(state.pending ||\n\t\t\t\tfixed ||\n\t\t\t\tJSON.stringify(state.reference.view.source) === JSON.stringify(state.checkpoint?.source))\n\t\t)\n\t\t\treturn result(state.reference.view.ref.entryId, state.capture);\n\t\tconst capture = captureSelectedSkill(descriptor);\n\t\tconst ref = await owner.writer.append(capture, modelInvocation ? \"model\" : \"command\");\n\t\tassertCurrent(); // A completed source append is not rolled back on cancellation or owner change.\n\t\treturn result(ref, capture);\n\t}\n\n\t/** Read only the server-owned branch captured for this operation (including a batch). */\n\tasync recoverNativeHistory(\n\t\tinput: NativeRecoveryInput,\n\t\tsignal?: AbortSignal,\n\t\tmaxBytes = DEFAULT_NATIVE_RECOVERY_LIMITS.maxBytes,\n\t): Promise<NativeRecoveryResponse> {\n\t\tsignal?.throwIfAborted();\n\t\tconst request = parseNativeRecoveryInput(input);\n\t\tconst responseBytes = Math.min(maxBytes, DEFAULT_NATIVE_RECOVERY_LIMITS.maxBytes, request.maxBytes ?? Infinity);\n\t\tif (!this._nativeRecoveryEnabled()) {\n\t\t\treturn createNativeRecoveryRefusal(\"not_authorized\", \"native_recovery_not_enabled\", responseBytes);\n\t\t}\n\t\t// Only the real authorized reader can latch this private admitted execution.\n\t\t// A replacement method/result or descriptive JSON cannot set the producer bit.\n\t\tconst producer = this._nativeRecoveryProducer.getStore();\n\t\tif (producer) producer.used = true;\n\t\tif (request.action === \"skill\") {\n\t\t\tif (!producer?.skillOwner)\n\t\t\t\treturn createNativeRecoveryRefusal(\n\t\t\t\t\t\"not_authorized\",\n\t\t\t\t\t\"native_skill_selection_owner_required\",\n\t\t\t\t\tresponseBytes,\n\t\t\t\t);\n\t\t\tconst skill = this._modelVisibleSkills().find(\n\t\t\t\t(item) => item.name === request.name && !item.disableModelInvocation,\n\t\t\t);\n\t\t\tif (!skill) return createNativeRecoveryRefusal(\"not_authorized\", \"skill_not_model_visible\", responseBytes);\n\t\t\tconst selected = await this._selectNativeSkill(skill, producer.skillOwner, true, signal);\n\t\t\tif (!selected)\n\t\t\t\treturn createNativeRecoveryRefusal(\"unavailable\", \"native_skill_epoch_not_enabled\", responseBytes);\n\t\t\tselected.assertCurrent();\n\t\t\treturn producer.skillOwner.manager.readBranchHistory((history) =>\n\t\t\t\trecoverCapturedHistory(\n\t\t\t\t\thistory.branchContext,\n\t\t\t\t\t{ action: \"read\", ref: selected.ref, maxBytes: responseBytes },\n\t\t\t\t\t{ ...DEFAULT_NATIVE_RECOVERY_LIMITS, maxBytes: responseBytes },\n\t\t\t\t\tsignal,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\t// readBranchHistory captures synchronously and preserves ordered read/release errors.\n\t\t// Never accept a caller's owner/path/frontier or turn a failed read into evidence of absence.\n\t\ttry {\n\t\t\tconst manager = producer?.skillOwner?.manager ?? this.sessionManager;\n\t\t\tproducer?.skillOwner?.writer.assertCurrent();\n\t\t\tif (this.sessionManager !== manager) throw new Error(\"Native recovery source changed\");\n\t\t\tconst cursorSource = JSON.stringify([manager.getSessionId(), manager.getSessionFile()]);\n\t\t\tif (this._nativeRecoveryCursorSource !== cursorSource) {\n\t\t\t\tthis._nativeRecoveryCursors.clear();\n\t\t\t\tthis._nativeRecoveryCursorSource = cursorSource;\n\t\t\t}\n\t\t\treturn await manager.readBranchHistory((history) =>\n\t\t\t\trecoverCapturedHistory(\n\t\t\t\t\thistory.branchContext,\n\t\t\t\t\trequest,\n\t\t\t\t\t{ ...DEFAULT_NATIVE_RECOVERY_LIMITS, maxBytes: responseBytes },\n\t\t\t\t\tsignal,\n\t\t\t\t\tthis._nativeRecoveryCursors,\n\t\t\t\t),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tsignal?.throwIfAborted();\n\t\t\tif (error instanceof NativeRecoveryBudgetRefusal) throw error;\n\t\t\treturn createNativeRecoveryRefusal(\"unavailable\", \"captured_history_unavailable\", responseBytes);\n\t\t}\n\t}\n\n\tprivate _createKernelHostHandlers(): HostRequestHandlers {\n\t\tconst handlers: HostRequestHandlers = {\n\t\t\tprime_context: async (payload, context) => {\n\t\t\t\tif (!context?.nativeRecovery) {\n\t\t\t\t\treturn { ...createNativeRecoveryRefusal(\"not_authorized\", \"active_cell_required\") };\n\t\t\t\t}\n\t\t\t\tconst input = parseNativeRecoveryInput(payload.request);\n\t\t\t\treturn { ...(await this.recoverNativeHistory(input, context.signal, context.nativeRecovery.maxBytes)) };\n\t\t\t},\n\t\t\t\"rlm.run\": createRlmRunHostHandler(async ({ prompt, kwargs, cellSourceCode }) => ({\n\t\t\t\t...(await this.runRlmChild(prompt, kwargs, cellSourceCode)),\n\t\t\t})),\n\t\t\t\"rlm.find_models\": createRlmFindModelsHostHandler((query, limit) => this.findRlmModels(query, limit)),\n\t\t\t\"rlm.list_subagents\": createRlmListSubagentsHostHandler(() => this.listRlmSubagents()),\n\t\t\t\"rlm.delete_subagent\": createRlmDeleteSubagentHostHandler((target) => this.deleteRlmSubagent(target)),\n\t\t\t\"model.info\": async () => ({\n\t\t\t\tid: this.model?.id ?? null,\n\t\t\t\tprovider: this.model?.provider ?? null,\n\t\t\t\tinput: this.model?.input ?? [],\n\t\t\t}),\n\t\t};\n\t\tif (this._includeGoals) {\n\t\t\tfor (const type of [\"goal.get\", \"goal.create\", \"goal.complete\"]) {\n\t\t\t\thandlers[type] = async (payload) => this.handleGoalHostRequest(type, payload);\n\t\t\t}\n\t\t}\n\t\tif (this._includeCompactSkill) {\n\t\t\tfor (const type of [\"compact.run\", \"compact.status\"]) {\n\t\t\t\thandlers[type] = async (payload) => this.handleCompactHostRequest(type, payload);\n\t\t\t}\n\t\t}\n\t\tif (this._autoRefineAllowedForSession()) {\n\t\t\tfor (const type of [\"refine.run\", \"refine.status\"]) {\n\t\t\t\thandlers[type] = async (payload) => this.handleRefineHostRequest(type, payload);\n\t\t\t}\n\t\t}\n\t\tif (this._rlmHeartbeatController) {\n\t\t\tfor (const type of [\n\t\t\t\t\"rlm_heartbeat.list\",\n\t\t\t\t\"rlm_heartbeat.create\",\n\t\t\t\t\"rlm_heartbeat.update\",\n\t\t\t\t\"rlm_heartbeat.delete\",\n\t\t\t]) {\n\t\t\t\thandlers[type] = async (payload) => this.handleRlmHeartbeatHostRequest(type, payload);\n\t\t\t}\n\t\t}\n\t\tconst visibleKernelSkillNames = new Set(\n\t\t\tthis._modelVisibleSkills()\n\t\t\t\t.filter((skill) => !skill.disableModelInvocation)\n\t\t\t\t.map((skill) => skill.name),\n\t\t);\n\t\tif (this._agentMessageController && visibleKernelSkillNames.has(AGENT_MESSAGE_SKILL_NAME)) {\n\t\t\tObject.assign(\n\t\t\t\thandlers,\n\t\t\t\tcreateAgentMessageHostHandlers({\n\t\t\t\t\troster: async () =>\n\t\t\t\t\t\t(await this.handleAgentMessageHostRequest(\"agent_message.list_agents\")) as AgentFamilyRosterResult,\n\t\t\t\t\tawaitPendingChildPublication: (selector) => this._awaitPendingRlmChildPublication(selector),\n\t\t\t\t\tsendAgentMessage: async (input) => {\n\t\t\t\t\t\tconst receipt = (await (input.findings === undefined\n\t\t\t\t\t\t\t? this.handleAgentMessageHostRequest(\"agent_message.send\", {\n\t\t\t\t\t\t\t\t\ttarget: input.target,\n\t\t\t\t\t\t\t\t\tmessage: input.message,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t: this.handleAgentMessageHostRequest(\"agent_message.send_result\", {\n\t\t\t\t\t\t\t\t\ttarget: input.target,\n\t\t\t\t\t\t\t\t\tsummary: input.message,\n\t\t\t\t\t\t\t\t\tfindings: input.findings,\n\t\t\t\t\t\t\t\t}))) as AgentSessionMessageReceipt;\n\t\t\t\t\t\tif (this._rlmDepth > 0) {\n\t\t\t\t\t\t\tlet addressedParent = input.receiverRole === \"parent\";\n\t\t\t\t\t\t\tif (input.receiverRole === undefined && this._agentMessageController?.roster) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst roster = await this._agentMessageController.roster();\n\t\t\t\t\t\t\t\t\taddressedParent = roster.entries.some(\n\t\t\t\t\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\t\t\t\t\tentry.relationship === \"parent\" &&\n\t\t\t\t\t\t\t\t\t\t\t(entry.id === input.target || entry.name === input.target),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\taddressedParent = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (addressedParent) {\n\t\t\t\t\t\t\t\tthis._repliedToParentSinceTask = true;\n\t\t\t\t\t\t\t\tthis._parentReplyCount += 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn receipt;\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tif (this._agentObserveController) {\n\t\t\tObject.assign(\n\t\t\t\thandlers,\n\t\t\t\tcreateAgentObserveHostHandlers({\n\t\t\t\t\tlistAgents: () => this.handleAgentObserveHostRequest(\"agent_observe.list\") as AgentObserveListResult,\n\t\t\t\t\tgetAgent: (target) =>\n\t\t\t\t\t\tthis.handleAgentObserveHostRequest(\"agent_observe.get\", {\n\t\t\t\t\t\t\ttarget,\n\t\t\t\t\t\t}) as AgentObserveAgentSnapshot,\n\t\t\t\t\trecentMessages: (input) =>\n\t\t\t\t\t\tthis.handleAgentObserveHostRequest(\"agent_observe.recent\", {\n\t\t\t\t\t\t\ttarget: input.target,\n\t\t\t\t\t\t\tlimit: input.limit,\n\t\t\t\t\t\t\tmax_chars: input.maxChars,\n\t\t\t\t\t\t}) as AgentObserveRecentMessagesResult,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tif (this._mcpManager) {\n\t\t\tObject.assign(handlers, this._mcpManager.hostHandlers());\n\t\t}\n\t\treturn handlers;\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tconst previousFlagValues = this._extensionRunner.getFlagValues();\n\t\tawait emitSessionShutdownEvent(this._extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason: \"reload\",\n\t\t});\n\t\tawait this.settingsManager.reload();\n\t\t// Re-read auth.json: a login saved by the client process (daemon mode) must be\n\t\t// visible here so MCP skill gating sees the new credentials.\n\t\tthis._modelRegistry.authStorage.reload();\n\t\tresetApiProviders();\n\t\tthis._mcpManager?.refresh();\n\t\tawait this._resourceLoader.reload();\n\t\tthis._buildRuntime({\n\t\t\tactiveToolNames: this.getActiveToolNames(),\n\t\t\tflagValues: previousFlagValues,\n\t\t\tincludeAllExtensionTools: true,\n\t\t});\n\n\t\tconst hasBindings =\n\t\t\tthis._extensionUIContext ||\n\t\t\tthis._extensionCommandContextActions ||\n\t\t\tthis._extensionShutdownHandler ||\n\t\t\tthis._extensionErrorListener;\n\t\tif (hasBindings) {\n\t\t\tawait this._extensionRunner.emit({\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"reload\",\n\t\t\t});\n\t\t\tawait this.extendResourcesFromExtensions(\"reload\");\n\t\t}\n\t}\n\n\tprivate _rlmKernelEnv(): Record<string, string> {\n\t\t// Kernel env is provisioning-time only: BASE_CONTEXT_RLM_MAX_DEPTH may be stale in an already-running kernel;\n\t\t// the TypeScript-side spawn check remains authoritative.\n\t\tconst env: Record<string, string> = {\n\t\t\tBASE_CONTEXT_RLM_DEPTH: String(this._rlmDepth),\n\t\t\tBASE_CONTEXT_RLM_MAX_DEPTH: String(this._rlmMaxDepth),\n\t\t\tBASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR: getGlobalHarnessStateDir(),\n\t\t\tBASE_CONTEXT_WORKSPACE_HARNESS_STATE_DIR: getWorkspaceHarnessStateDir(this._cwd),\n\t\t};\n\t\tconst rlmSessionDir = this._ensureRlmSessionDir();\n\t\tif (rlmSessionDir) {\n\t\t\tenv.BASE_CONTEXT_KERNEL_SESSION_DIR = rlmSessionDir;\n\t\t\t// Keep kernel writes and host reads (system prompt, review, /refine) on\n\t\t\t// the same local harness path. Subagents prefer their own artifact dir;\n\t\t\t// ephemeral sessions fall back to the RLM session dir once it exists.\n\t\t\tenv.BASE_CONTEXT_HARNESS_STATE_DIR = this._localHarnessStateDir() ?? getLocalHarnessStateDir(rlmSessionDir)!;\n\t\t}\n\t\tthis._addWebsearchKeyEnv(env);\n\t\treturn env;\n\t}\n\n\tprivate _addWebsearchKeyEnv(env: Record<string, string>): void {\n\t\tif (this._agentDir) {\n\t\t\tenv.BASE_CONTEXT_HOME = this._agentDir;\n\t\t}\n\n\t\tif (process.env[SERPER_ENV_VAR]?.trim()) {\n\t\t\treturn;\n\t\t}\n\t\t// Inject only when a websearch skill (bundled or custom) is actually loaded,\n\t\t// so the key isn't exposed to kernels that can't use it.\n\t\tif (!this._resourceLoader.getSkills().skills.some((skill) => skill.name === WEBSEARCH_SKILL_NAME)) {\n\t\t\treturn;\n\t\t}\n\t\tconst cred = this._modelRegistry.authStorage.get(SERPER_CREDENTIAL_ID);\n\t\tif (cred?.type !== \"api_key\") {\n\t\t\treturn;\n\t\t}\n\t\tconst resolved = resolveConfigValue(cred.key)?.trim();\n\t\tif (resolved) {\n\t\t\tenv[SERPER_ENV_VAR] = resolved;\n\t\t}\n\t}\n\n\t// Undefined when there's no persistent artifact dir (e.g. the viewer client):\n\t// don't mkdtemp here, since this runs on every kernel build but a viewer never\n\t// does RLM work. The temp dir is created lazily in _createChildRlmSessionDir.\n\tprivate _ensureRlmSessionDir(): string | undefined {\n\t\tif (this._rlmSessionDir) {\n\t\t\tmkdirSync(this._rlmSessionDir, { recursive: true });\n\t\t\treturn this._rlmSessionDir;\n\t\t}\n\n\t\tconst sessionArtifactDir = this.sessionManager.getSessionArtifactDir();\n\t\tif (sessionArtifactDir) {\n\t\t\tmkdirSync(sessionArtifactDir, { recursive: true });\n\t\t\tthis._rlmSessionDir = sessionArtifactDir;\n\t\t\treturn sessionArtifactDir;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tprivate _createChildRlmSessionDir(): string {\n\t\tconst parentDir = this._ensureRlmSessionDir() ?? this._createEphemeralRlmSessionDir();\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\tconst childDir = join(parentDir, `sub-${randomUUID().slice(0, 8)}`);\n\t\t\ttry {\n\t\t\t\tmkdirSync(childDir);\n\t\t\t\treturn childDir;\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof Error && \"code\" in error && error.code === \"EEXIST\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tthrow new Error(\"Unable to create unique RLM child session directory\");\n\t}\n\n\tprivate _createEphemeralRlmSessionDir(): string {\n\t\tthis._rlmSessionDir = mkdtempSync(join(tmpdir(), `${PRODUCT.command}-rlm-`));\n\t\treturn this._rlmSessionDir;\n\t}\n\n\t_contextTokensForCurrentMessages(): number | undefined {\n\t\tconst last = this._findLastAssistantMessage();\n\t\treturn last ? calculateContextTokens(last.usage) : undefined;\n\t}\n\n\tsetCurrentRecap(recap: string | undefined): void {\n\t\tif (this._currentRecap === recap) return;\n\t\tthis._currentRecap = recap;\n\t\tthis._emit({ type: \"recap_update\", recap });\n\t}\n\n\tget repliedToParentSinceTask(): boolean | undefined {\n\t\treturn this._repliedToParentSinceTask;\n\t}\n\n\tgetCurrentRecap(): string | undefined {\n\t\treturn this._currentRecap;\n\t}\n\n\tprivate _removeLastAssistantFromContext(): void {\n\t\tconst messages = this.agent.state.messages;\n\t\tconst message = messages.at(-1);\n\t\tif (message?.role !== \"assistant\") return;\n\t\tif (this.sessionManager.isPersisted()) {\n\t\t\tconst entryId = this._findAssistantEntryIdForMessage(message);\n\t\t\tif (!entryId) throw new Error(\"Cannot identify the acknowledged assistant response removed by retry control\");\n\t\t\tif (\n\t\t\t\tthis._contextOmissions?.sessionId !== this.sessionId ||\n\t\t\t\tthis._contextOmissions?.sessionFile !== this.sessionFile\n\t\t\t)\n\t\t\t\tthis._contextOmissions = { sessionId: this.sessionId, sessionFile: this.sessionFile, ids: new Set() };\n\t\t\tthis._contextOmissions.ids.add(entryId);\n\t\t}\n\t\tthis.agent.state.messages = messages.slice(0, -1);\n\t}\n\n\tprivate _findAssistantEntryIdForMessage(message: AssistantMessage): string | undefined {\n\t\tconst source = this._assistantEntryIds.get(message) ?? getCanonicalMessageSource(message);\n\t\tif (source)\n\t\t\treturn source.sessionId === this.sessionId && source.sessionFile === this.sessionFile\n\t\t\t\t? source.entryId\n\t\t\t\t: undefined;\n\t\tif (this.sessionManager.isPersisted()) return undefined;\n\t\treturn this.sessionManager.getEntries().find((entry) => entry.type === \"message\" && entry.message === message)\n\t\t\t?.id;\n\t}\n\n\tget hasRlmParentAdmission(): boolean {\n\t\treturn this._releaseRlmResidentCapacity !== undefined;\n\t}\n\n\t/** Reserve before setup awaits. Capacity remains owned until real cleanup completes. */\n\tasync reserveRlmChildAdmission(): Promise<RlmChildAdmission> {\n\t\tif (this._disposed || this._disposing || this._disposeAsyncPromise) {\n\t\t\tthrow new Error(\"Cannot spawn a subagent after its parent was disposed\");\n\t\t}\n\t\tconst controller = new AbortController();\n\t\tconst settlement = createAgentMessageDeferred();\n\t\tlet child: AgentSession | undefined;\n\t\tlet settled = false;\n\t\tlet factoryClaimed = false;\n\t\tlet unboundCleanupComplete = true;\n\t\tlet capacity: RlmSubagentCapacityReservation | undefined;\n\t\tlet capacityRelease: Promise<void> | undefined;\n\t\tconst release = async () => {\n\t\t\tif (!settled || (child ? !child._rlmResidentDisposalComplete : !unboundCleanupComplete)) return;\n\t\t\tif (capacity) {\n\t\t\t\tcapacityRelease ??= capacity.release();\n\t\t\t\tawait capacityRelease;\n\t\t\t}\n\t\t\tthis._rlmChildAdmissions.delete(admission);\n\t\t\tif (child?._releaseRlmResidentCapacity === release) child._releaseRlmResidentCapacity = undefined;\n\t\t\tif (child?._rlmParentAdmission === admission) child._rlmParentAdmission = undefined;\n\t\t};\n\t\tconst admission: RlmChildAdmission & { cancel(reason: string): boolean } = {\n\t\t\tparent: this,\n\t\t\tget session() {\n\t\t\t\treturn child;\n\t\t\t},\n\t\t\tsettlement: settlement.promise,\n\t\t\tget pending() {\n\t\t\t\treturn !settled;\n\t\t\t},\n\t\t\tassertCurrent: () => {\n\t\t\t\tcontroller.signal.throwIfAborted();\n\t\t\t\tif (\n\t\t\t\t\tthis._disposed ||\n\t\t\t\t\tthis._disposing ||\n\t\t\t\t\tthis._disposeAsyncPromise ||\n\t\t\t\t\t!this._rlmChildAdmissions.has(admission)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\"RLM child admission is no longer current\");\n\t\t\t\t}\n\t\t\t},\n\t\t\tbind: (session) => {\n\t\t\t\tif (!this._rlmChildAdmissions.has(admission)) throw new Error(\"RLM child admission is no longer current\");\n\t\t\t\tif (\n\t\t\t\t\t(child && child !== session) ||\n\t\t\t\t\t(session._releaseRlmResidentCapacity && session._releaseRlmResidentCapacity !== release)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\"RLM child already belongs to another resident admission\");\n\t\t\t\t}\n\t\t\t\tchild = session;\n\t\t\t\tsession._rlmParentAdmission = admission;\n\t\t\t\tsession._rlmSubagentCapacity = this._rlmSubagentCapacity;\n\t\t\t\tsession._releaseRlmResidentCapacity = release;\n\t\t\t},\n\t\t\tbeginSetup: () => {\n\t\t\t\tif (settled || child) throw new Error(\"RLM child admission already started a child\");\n\t\t\t\tunboundCleanupComplete = false;\n\t\t\t},\n\t\t\tclaimFactory: () => {\n\t\t\t\tif (factoryClaimed) throw new Error(\"RLM child admission already started a factory\");\n\t\t\t\tadmission.beginSetup();\n\t\t\t\tfactoryClaimed = true;\n\t\t\t},\n\t\t\tconfirmUnboundCleanup: async () => {\n\t\t\t\tunboundCleanupComplete = true;\n\t\t\t\tawait release();\n\t\t\t},\n\t\t\tsettle: async () => {\n\t\t\t\tsettled = true;\n\t\t\t\ttry {\n\t\t\t\t\tawait release();\n\t\t\t\t} finally {\n\t\t\t\t\tsettlement.resolve();\n\t\t\t\t}\n\t\t\t},\n\t\t\tcancel: (reason) => {\n\t\t\t\tif (settled || controller.signal.aborted) return false;\n\t\t\t\tcontroller.abort(new Error(reason));\n\t\t\t\tvoid child?.abort();\n\t\t\t\treturn true;\n\t\t\t},\n\t\t};\n\t\tthis._rlmChildAdmissions.add(admission);\n\t\ttry {\n\t\t\tcapacity = await this._rlmSubagentCapacity.reserve();\n\t\t\tadmission.assertCurrent();\n\t\t\treturn admission;\n\t\t} catch (error) {\n\t\t\tawait admission.settle();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate _createRlmSubagentRuntimeOptions(options: {\n\t\tadmission: RlmChildAdmission;\n\t\tid: string;\n\t\tprompt: string;\n\t\tsessionName: string;\n\t\tspawnCode?: string;\n\t\tsessionDir: string;\n\t\tmodel: Model<any>;\n\t\tthinkingLevel?: ThinkingLevel;\n\t\tspawnedByRequestId?: string;\n\t}): CreateRlmSubagentRuntimeOptions & { admission: RlmChildAdmission } {\n\t\tconst requestTokenBudget = this.requests.getRequestTokenBudgetOptions();\n\t\treturn {\n\t\t\tparentSession: this,\n\t\t\tcontextMode: this.contextMode,\n\t\t\t...(requestTokenBudget === undefined ? {} : { requestTokenBudget }),\n\t\t\tadmission: options.admission,\n\t\t\tid: options.id,\n\t\t\tprompt: options.prompt,\n\t\t\tsessionName: options.sessionName,\n\t\t\tspawnCode: options.spawnCode,\n\t\t\tsessionDir: options.sessionDir,\n\t\t\tmodel: options.model,\n\t\t\tthinkingLevel:\n\t\t\t\toptions.thinkingLevel ?? (clampThinkingLevel(options.model, this.thinkingLevel) as ThinkingLevel),\n\t\t\tserviceTier:\n\t\t\t\tthis.serviceTier === \"priority\" && !supportsFastMode(options.model) ? \"default\" : this.serviceTier,\n\t\t\tscopedModels: [...this._scopedModels],\n\t\t\tactiveToolNames: this.getActiveToolNames(),\n\t\t\tallowedToolNames: this._allowedToolNames ? [...this._allowedToolNames] : undefined,\n\t\t\tcustomTools: [...this._customTools],\n\t\t\tincludeGoals: this._includeGoals,\n\t\t\tincludeCompactSkill: this._includeCompactSkill,\n\t\t\trlmDepth: this._rlmDepth + 1,\n\t\t\trlmMaxDepth: this._rlmMaxDepth,\n\t\t\trlmParentNodeId: options.id,\n\t\t\tspawnedByRequestId: options.spawnedByRequestId,\n\t\t};\n\t}\n\n\tprivate async _createRlmSubagentRuntime(\n\t\toptions: CreateRlmSubagentRuntimeOptions & { admission: RlmChildAdmission },\n\t): Promise<RlmSubagentRuntime> {\n\t\toptions.admission.assertCurrent();\n\t\toptions.admission.beginSetup();\n\t\tif (this._subagentRuntimeHost) {\n\t\t\treturn await this._subagentRuntimeHost.createRlmSubagentRuntime(options);\n\t\t}\n\n\t\treturn this._createInlineRlmSubagentRuntime(options);\n\t}\n\n\tprivate async _createInlineRlmSubagentRuntime(\n\t\toptions: CreateRlmSubagentRuntimeOptions & { admission: RlmChildAdmission },\n\t): Promise<RlmSubagentRuntime> {\n\t\toptions.admission.claimFactory();\n\t\tconst parentSessionFile = options.parentSession.sessionFile;\n\t\tconst parentSessionId = options.parentSession.sessionId;\n\t\tconst parentAgent = options.parentSession.sessionName ?? parentSessionId;\n\t\tconst childSessionManager = await SessionManager.create(this._cwd, options.sessionDir, {\n\t\t\tparentSession: parentSessionFile,\n\t\t\trlmDepth: options.rlmDepth,\n\t\t});\n\t\tlet child: AgentSession | undefined;\n\t\ttry {\n\t\t\toptions.admission.assertCurrent();\n\t\t\tawait childSessionManager.appendModelChange(options.model.provider, options.model.id);\n\t\t\tawait childSessionManager.appendThinkingLevelChange(options.thinkingLevel);\n\t\t\tawait childSessionManager.appendServiceTierChange(options.serviceTier);\n\n\t\t\tconst childAgent = new Agent({\n\t\t\t\tinitialState: {\n\t\t\t\t\tsystemPrompt: \"\",\n\t\t\t\t\tmodel: options.model,\n\t\t\t\t\tthinkingLevel: options.thinkingLevel,\n\t\t\t\t\tserviceTier: options.serviceTier,\n\t\t\t\t\ttools: [],\n\t\t\t\t},\n\t\t\t\tconvertToLlm: this.agent.convertToLlm,\n\t\t\t\ttransformContext: this.agent.transformContext,\n\t\t\t\tstreamFn: this.agent.streamFn,\n\t\t\t\tgetApiKey: this.agent.getApiKey,\n\t\t\t\tonPayload: this.agent.onPayload,\n\t\t\t\tonResponse: this.agent.onResponse,\n\t\t\t\tsteeringMode: this.settingsManager.getSteeringMode(),\n\t\t\t\tfollowUpMode: this.settingsManager.getFollowUpMode(),\n\t\t\t\tsessionId: childSessionManager.getSessionId(),\n\t\t\t\tthinkingBudgets: this.settingsManager.getThinkingBudgets(),\n\t\t\t\ttransport: this.settingsManager.getTransport(),\n\t\t\t\tmaxRetryDelayMs: this.settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\t\t\ttoolExecution: this.agent.toolExecution,\n\t\t\t});\n\n\t\t\tchild = new AgentSession({\n\t\t\t\tagent: childAgent,\n\t\t\t\trequestTokenBudget: options.requestTokenBudget,\n\t\t\t\tcontextMode: options.contextMode,\n\t\t\t\tsessionManager: childSessionManager,\n\t\t\t\tsettingsManager: this.settingsManager,\n\t\t\t\tcwd: this._cwd,\n\t\t\t\tagentDir: this._agentDir,\n\t\t\t\tscopedModels: options.scopedModels,\n\t\t\t\tresourceLoader: this._resourceLoader,\n\t\t\t\tcustomTools: options.customTools,\n\t\t\t\tmodelRegistry: this._modelRegistry,\n\t\t\t\tinitialActiveToolNames: options.activeToolNames,\n\t\t\t\tallowedToolNames: options.allowedToolNames,\n\t\t\t\tincludeGoals: options.includeGoals,\n\t\t\t\tincludeCompactSkill: options.includeCompactSkill,\n\t\t\t\trlmDepth: options.rlmDepth,\n\t\t\t\trlmMaxDepth: options.rlmMaxDepth,\n\t\t\t\trlmSessionDir: options.sessionDir,\n\t\t\t\trlmParentNodeId: options.rlmParentNodeId,\n\t\t\t\trlmParentAgent: parentAgent,\n\t\t\t\trlmChildAdmission: options.admission,\n\t\t\t\tsemanticParentSessionId: parentSessionId,\n\t\t\t\tsemanticSpawnedByRequestId: options.spawnedByRequestId,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"startup\" },\n\t\t\t});\n\t\t\tawait child.initialize();\n\t\t\tif (child.sessionName !== options.sessionName) {\n\t\t\t\tawait child.setSessionName(options.sessionName);\n\t\t\t}\n\t\t\toptions.onSessionPublished?.(child);\n\n\t\t\treturn { session: child };\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tconst failedChild = child ?? options.admission.session;\n\t\t\t\tif (failedChild) await failedChild.disposeAsync();\n\t\t\t\telse {\n\t\t\t\t\tawait childSessionManager.close();\n\t\t\t\t\tawait options.admission.confirmUnboundCleanup();\n\t\t\t\t}\n\t\t\t} catch (cleanupError) {\n\t\t\t\tif (cleanupError === error || (error instanceof AggregateError && error.errors.includes(cleanupError)))\n\t\t\t\t\tthrow error;\n\t\t\t\tthrow new AggregateError([error, cleanupError], \"RLM startup and cleanup failed\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate _abandonRlmRunForQuiescence(run: RlmChildRun): void {\n\t\trun.suppressTerminalNotice = true;\n\t\trun.abandonedForQuiescence = true;\n\t\tthis._abandonedRlmQuiescenceChildIds.add(run.id);\n\t\tthis._unsettledRlmChildRuns.delete(run);\n\t\trun.settlement.resolve();\n\t\tthis._scheduleGoalContinuationAfterRlmWork();\n\t}\n\n\tprivate _cancelActiveRlmChildRuns(reason: string): void {\n\t\tfor (const admission of this._rlmChildAdmissions) admission.cancel(reason);\n\t\tfor (const run of this._activeRlmChildRuns.values()) {\n\t\t\tthis._cancelRlmChildRun(run, reason);\n\t\t}\n\t}\n\n\tprivate _cancelRlmChildRun(run: RlmChildRun, reason: string): boolean {\n\t\tif (run.status !== \"running\" && run.status !== \"queued\") {\n\t\t\treturn false;\n\t\t}\n\t\trun.status = \"cancelled\";\n\t\tif (this._sessionInputPumpSuspended) this._abandonRlmRunForQuiescence(run);\n\t\trun.error = reason;\n\t\trun.publication.reject(new Error(reason));\n\t\trun.abort();\n\t\t// Surface the cancellation immediately; the run's own terminal update is\n\t\t// delayed indefinitely when the child is stuck mid-stream, which is\n\t\t// exactly when users reach for the kill.\n\t\trun.emitUpdate?.();\n\t\treturn true;\n\t}\n\n\tgetRlmChildRunStatus(childId: string): RlmChildAgentStatus | undefined {\n\t\treturn this._activeRlmChildRuns.get(childId)?.status;\n\t}\n\n\tprivate async _currentActiveSessionId(): Promise<string | undefined> {\n\t\ttry {\n\t\t\treturn (await this._agentMessageController?.listAgents())?.current?.activeSessionId;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async _awaitPendingRlmChildPublication(selector: string): Promise<string | undefined> {\n\t\tconst run = [...this._activeRlmChildRuns.values()].find(\n\t\t\t(candidate) =>\n\t\t\t\t(candidate.status === \"queued\" || candidate.status === \"running\" || candidate.status === \"done\") &&\n\t\t\t\t!candidate.detachedDeletion &&\n\t\t\t\t(candidate.id === selector || candidate.sessionName === selector),\n\t\t);\n\t\tif (!run) return undefined;\n\t\tawait run.publication.promise;\n\t\treturn run.session?.sessionId;\n\t}\n\n\tasync listRlmSubagents(): Promise<RlmListSubagentsResult> {\n\t\treturn this._buildRlmSubagentList(await this._agentMessageController?.listAgents());\n\t}\n\n\tprivate _buildRlmSubagentList(listedAgents?: AgentSessionMessageListResult): RlmListSubagentsResult {\n\t\tconst daemonChildren = new Map<string, AgentSessionMessageAgentSummary>();\n\t\tconst parentActiveSessionId = listedAgents?.current?.activeSessionId;\n\t\tif (parentActiveSessionId) {\n\t\t\tfor (const agent of listedAgents.agents) {\n\t\t\t\tif (\n\t\t\t\t\tagent.runtimeKind === \"subagent\" &&\n\t\t\t\t\tagent.parentActiveSessionId === parentActiveSessionId &&\n\t\t\t\t\tagent.rlmChildId\n\t\t\t\t) {\n\t\t\t\t\tdaemonChildren.set(agent.rlmChildId, agent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst subagents: RlmListSubagentsResult[\"subagents\"] = [];\n\t\tconst recorded = new Set<string>();\n\t\tfor (const run of this._activeRlmChildRuns.values()) {\n\t\t\tif (this._deletingRlmChildren.has(run.id) || run.detachedDeletion || run.status === \"cancelled\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst daemonChild = daemonChildren.get(run.id);\n\t\t\tsubagents.push({\n\t\t\t\trlm_child_id: run.id,\n\t\t\t\tactive_session_id: daemonChild?.activeSessionId ?? null,\n\t\t\t\tsession_id: daemonChild?.sessionId ?? run.session?.sessionId ?? null,\n\t\t\t\tsession_name: daemonChild?.sessionName ?? run.session?.sessionName ?? run.sessionName,\n\t\t\t\tsession_dir: run.sessionDir,\n\t\t\t\tstatus: run.status === \"done\" ? \"completed\" : run.status === \"error\" ? \"error\" : \"running\",\n\t\t\t});\n\t\t\trecorded.add(run.id);\n\t\t}\n\t\tfor (const [childId, { session: childSession }] of this._rlmChildSessions) {\n\t\t\tif (\n\t\t\t\tthis._deletingRlmChildren.has(childId) ||\n\t\t\t\trecorded.has(childId) ||\n\t\t\t\tthis._rlmChildCleanupFailures.has(childId)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst daemonChild = daemonChildren.get(childId);\n\t\t\tconst sessionDir = childSession._rlmSessionDir;\n\t\t\tif (!sessionDir) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tsubagents.push({\n\t\t\t\trlm_child_id: childId,\n\t\t\t\tactive_session_id: daemonChild?.activeSessionId ?? null,\n\t\t\t\tsession_id: daemonChild?.sessionId ?? childSession.sessionId,\n\t\t\t\tsession_name:\n\t\t\t\t\tdaemonChild?.sessionName ?? childSession.sessionName ?? createDefaultRlmSubagentSessionName(\"\", childId),\n\t\t\t\tsession_dir: sessionDir,\n\t\t\t\tstatus: \"completed\",\n\t\t\t});\n\t\t\trecorded.add(childId);\n\t\t}\n\t\tfor (const [childId, daemonChild] of daemonChildren) {\n\t\t\tif (\n\t\t\t\trecorded.has(childId) ||\n\t\t\t\tthis._deletingRlmChildren.has(childId) ||\n\t\t\t\tthis._deletedRlmChildIds.has(childId) ||\n\t\t\t\tthis._rlmChildCleanupFailures.has(childId) ||\n\t\t\t\t!daemonChild.sessionDir\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tsubagents.push({\n\t\t\t\trlm_child_id: childId,\n\t\t\t\tactive_session_id: daemonChild.activeSessionId,\n\t\t\t\tsession_id: daemonChild.sessionId,\n\t\t\t\tsession_name: daemonChild.sessionName ?? createDefaultRlmSubagentSessionName(\"\", childId),\n\t\t\t\tsession_dir: daemonChild.sessionDir,\n\t\t\t\tstatus: daemonChild.rlmChildRegistryStatus === \"completed\" ? \"completed\" : \"error\",\n\t\t\t});\n\t\t}\n\t\treturn { subagents };\n\t}\n\n\tprivate _rlmSubagentMatchesTarget(entry: RlmSubagentRegistryEntry, target: string): boolean {\n\t\treturn (\n\t\t\tentry.rlm_child_id === target ||\n\t\t\tentry.active_session_id === target ||\n\t\t\tentry.session_id === target ||\n\t\t\tentry.session_name === target\n\t\t);\n\t}\n\n\tprivate async _resolveDirectRlmSubagent(target: string): Promise<RlmSubagentRegistryEntry> {\n\t\tconst candidates = [...(await this.listRlmSubagents()).subagents, ...this._rlmChildCleanupFailures.values()];\n\t\tconst matches = candidates.filter((entry) => this._rlmSubagentMatchesTarget(entry, target));\n\t\tif (matches.length === 0) {\n\t\t\tthrow new Error(`No direct RLM subagent matches \"${target}\" in the current parent session`);\n\t\t}\n\t\tif (matches.length > 1) {\n\t\t\tthrow new Error(`RLM subagent selector \"${target}\" is ambiguous in the current parent session`);\n\t\t}\n\t\treturn matches[0]!;\n\t}\n\n\tasync deleteInactiveRlmSubagent(\n\t\tchildId: string,\n\t\tisExternallyRunning: () => boolean = () => false,\n\t): Promise<\"deleted\" | \"not_found\" | \"running\"> {\n\t\tfor (const owner of this._rlmSubtreeSessions()) {\n\t\t\tconst isRunning = (): boolean => {\n\t\t\t\tconst status = owner._activeRlmChildRuns.get(childId)?.status;\n\t\t\t\treturn status === \"queued\" || status === \"running\" || isExternallyRunning();\n\t\t\t};\n\t\t\tif (isRunning()) {\n\t\t\t\treturn \"running\";\n\t\t\t}\n\t\t\tconst subagent = [\n\t\t\t\t...(await owner.listRlmSubagents()).subagents,\n\t\t\t\t...owner._rlmChildCleanupFailures.values(),\n\t\t\t].find((entry) => entry.rlm_child_id === childId);\n\t\t\tif (!subagent) continue;\n\t\t\tif (isRunning()) {\n\t\t\t\treturn \"running\";\n\t\t\t}\n\t\t\tconst result = await owner._trackRlmSubagentDeletion(subagent, () => {\n\t\t\t\tif (isRunning()) {\n\t\t\t\t\treturn Promise.resolve({ subagent, outcome: \"skipped_running\" });\n\t\t\t\t}\n\t\t\t\treturn owner._deleteResolvedRlmSubagent(subagent);\n\t\t\t});\n\t\t\treturn result.outcome === \"skipped_running\" ? \"running\" : \"deleted\";\n\t\t}\n\t\treturn \"not_found\";\n\t}\n\n\tasync deleteRlmSubagent(target: string): Promise<RlmDeleteSubagentResult> {\n\t\tconst inFlight = [...this._deletingRlmChildren.values()].filter(({ subagent }) =>\n\t\t\tthis._rlmSubagentMatchesTarget(subagent, target),\n\t\t);\n\t\tif (inFlight.length > 1) {\n\t\t\tthrow new Error(`RLM subagent selector \"${target}\" is ambiguous in the current parent session`);\n\t\t}\n\n\t\t// Running and retained children can be reserved synchronously. This keeps\n\t\t// them hidden immediately while the async daemon listing checks for a\n\t\t// conflicting passive selector.\n\t\tconst localMatches = [\n\t\t\t...this._buildRlmSubagentList().subagents,\n\t\t\t...this._rlmChildCleanupFailures.values(),\n\t\t].filter((entry) => this._rlmSubagentMatchesTarget(entry, target));\n\t\tconst matchingChildIds = new Set([\n\t\t\t...inFlight.map(({ subagent }) => subagent.rlm_child_id),\n\t\t\t...localMatches.map((subagent) => subagent.rlm_child_id),\n\t\t]);\n\t\tif (matchingChildIds.size > 1 || localMatches.length > 1) {\n\t\t\tthrow new Error(`RLM subagent selector \"${target}\" is ambiguous in the current parent session`);\n\t\t}\n\t\tif (inFlight[0]) {\n\t\t\treturn inFlight[0].promise;\n\t\t}\n\t\tif (localMatches[0]) {\n\t\t\tconst subagent = localMatches[0];\n\t\t\treturn this._trackRlmSubagentDeletion(subagent, async () => {\n\t\t\t\tconst listedAgents = await this._agentMessageController?.listAgents();\n\t\t\t\tconst listedSubagents = this._buildRlmSubagentList(listedAgents).subagents;\n\t\t\t\tconst passiveMatches = listedSubagents.filter(\n\t\t\t\t\t(entry) => entry.rlm_child_id !== subagent.rlm_child_id && this._rlmSubagentMatchesTarget(entry, target),\n\t\t\t\t);\n\t\t\t\tif (passiveMatches.length > 0) {\n\t\t\t\t\tthrow new Error(`RLM subagent selector \"${target}\" is ambiguous in the current parent session`);\n\t\t\t\t}\n\t\t\t\tconst parentActiveSessionId = listedAgents?.current?.activeSessionId;\n\t\t\t\tconst daemonChild = listedAgents?.agents.find(\n\t\t\t\t\t(agent) =>\n\t\t\t\t\t\tagent.rlmChildId === subagent.rlm_child_id && agent.parentActiveSessionId === parentActiveSessionId,\n\t\t\t\t);\n\t\t\t\tconst resolvedSubagent = daemonChild\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...subagent,\n\t\t\t\t\t\t\tactive_session_id: daemonChild.activeSessionId,\n\t\t\t\t\t\t\tsession_id: daemonChild.sessionId,\n\t\t\t\t\t\t\tsession_name: daemonChild.sessionName ?? subagent.session_name,\n\t\t\t\t\t\t}\n\t\t\t\t\t: subagent;\n\t\t\t\treturn this._deleteResolvedRlmSubagent(resolvedSubagent);\n\t\t\t});\n\t\t}\n\n\t\tconst directMatches = [\n\t\t\t...(await this.listRlmSubagents()).subagents,\n\t\t\t...this._rlmChildCleanupFailures.values(),\n\t\t].filter((entry) => this._rlmSubagentMatchesTarget(entry, target));\n\t\tconst directChildIds = new Set(directMatches.map((subagent) => subagent.rlm_child_id));\n\t\tif (directChildIds.size > 1) {\n\t\t\tthrow new Error(`RLM subagent selector \"${target}\" is ambiguous in the current parent session`);\n\t\t}\n\t\tconst subagent = directMatches[0] ?? (await this._resolveDirectRlmSubagent(target));\n\t\treturn this._trackRlmSubagentDeletion(subagent, () => this._deleteResolvedRlmSubagent(subagent));\n\t}\n\n\tprivate async _trackRlmSubagentDeletion(\n\t\tsubagent: RlmSubagentRegistryEntry,\n\t\tstartDeletion: () => Promise<RlmDeleteSubagentResult>,\n\t): Promise<RlmDeleteSubagentResult> {\n\t\tconst existing = this._deletingRlmChildren.get(subagent.rlm_child_id);\n\t\tif (existing) return existing.promise;\n\t\tconst deletion = Promise.resolve().then(startDeletion);\n\t\tthis._deletingRlmChildren.set(subagent.rlm_child_id, {\n\t\t\tsubagent,\n\t\t\tpromise: deletion,\n\t\t});\n\t\ttry {\n\t\t\treturn await deletion;\n\t\t} finally {\n\t\t\tconst clearReservation = () => {\n\t\t\t\tif (this._deletingRlmChildren.get(subagent.rlm_child_id)?.promise === deletion) {\n\t\t\t\t\tthis._deletingRlmChildren.delete(subagent.rlm_child_id);\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst run = this._activeRlmChildRuns.get(subagent.rlm_child_id);\n\t\t\tif (run?.detachedDeletion) {\n\t\t\t\t// Keep every selector reserved until the run settles, or until a failed\n\t\t\t\t// cleanup is exposed for an explicit retry. Repeated deletes before that\n\t\t\t\t// boundary return the same accepted result.\n\t\t\t\tvoid run.deletionReservation.promise.then(clearReservation, clearReservation);\n\t\t\t} else {\n\t\t\t\tclearReservation();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _deleteRlmSubagentSession(childId: string, session?: AgentSession): Promise<void> {\n\t\tif (this._subagentRuntimeHost) {\n\t\t\treturn this._subagentRuntimeHost.deleteRlmSubagentRuntime(childId, session);\n\t\t}\n\t\treturn session?.disposeAsync() ?? Promise.resolve();\n\t}\n\n\tprivate _ensureRlmRunDeletionCleanup(run: RlmChildRun, session: AgentSession): Promise<void> {\n\t\tif (run.deletionCleanup) return run.deletionCleanup;\n\t\tconst cleanup = Promise.resolve().then(() => this._deleteRlmSubagentSession(run.id, session));\n\t\trun.deletionCleanup = cleanup;\n\t\t// Deletion admission is intentionally nonblocking. The detached run owner\n\t\t// joins this exact promise before settlement and records any failure.\n\t\tvoid cleanup.catch(() => undefined);\n\t\treturn cleanup;\n\t}\n\n\tprivate async _recordRlmRunDeletionCleanupFailure(\n\t\trun: RlmChildRun,\n\t\tsubagent: RlmSubagentRegistryEntry,\n\t\tsession: AgentSession,\n\t\terror: unknown,\n\t): Promise<void> {\n\t\tif (this._disposed || this._disposing) {\n\t\t\trun.suppressTerminalNotice = true;\n\t\t\tawait session.disposeAsync().catch(() => undefined);\n\t\t\tif (!run.settled) await this._finishRlmRunDeletion(run);\n\t\t\treturn;\n\t\t}\n\t\trun.deletionCleanup = undefined;\n\t\trun.deletionCleanupObserver = undefined;\n\t\trun.deletionCleanupFailed = true;\n\t\trun.session = session;\n\t\tthis._rlmChildCleanupFailures.set(run.id, subagent);\n\t\t// Make retry admission available before waking the parent model with the\n\t\t// retry-required notice.\n\t\trun.deletionReservation.resolve();\n\t\tawait Promise.resolve();\n\t\tawait run.reportDeletionCleanupFailure?.(error);\n\t}\n\n\tprivate async _finishRlmRunDeletion(run: RlmChildRun): Promise<void> {\n\t\tawait run.completeDeletion?.();\n\t\tif (this._activeRlmChildRuns.get(run.id) === run) {\n\t\t\tthis._removeRlmSubagentTracking(run.id, run);\n\t\t}\n\t\trun.settled = true;\n\t\trun.settlement.resolve();\n\t\trun.deletionReservation.resolve();\n\t\tthis._unsettledRlmChildRuns.delete(run);\n\t\tthis._scheduleGoalContinuationAfterRlmWork();\n\t}\n\n\tprivate _observeRlmRunDeletionCleanup(\n\t\trun: RlmChildRun,\n\t\tsubagent: RlmSubagentRegistryEntry,\n\t\tsession: AgentSession,\n\t\tcleanup: Promise<void>,\n\t): Promise<boolean> {\n\t\tif (run.deletionCleanupObserver) return run.deletionCleanupObserver;\n\t\tconst observer = cleanup.then(\n\t\t\t() => true,\n\t\t\tasync (error) => {\n\t\t\t\tawait this._recordRlmRunDeletionCleanupFailure(run, subagent, session, error);\n\t\t\t\treturn false;\n\t\t\t},\n\t\t);\n\t\trun.deletionCleanupObserver = observer;\n\t\tvoid observer.catch(() => undefined);\n\t\treturn observer;\n\t}\n\n\tprivate _continueFinishedRlmRunDeletion(\n\t\trun: RlmChildRun,\n\t\tsubagent: RlmSubagentRegistryEntry,\n\t\tsession: AgentSession,\n\t): void {\n\t\tconst cleanup = this._ensureRlmRunDeletionCleanup(run, session);\n\t\tconst observer = this._observeRlmRunDeletionCleanup(run, subagent, session, cleanup);\n\t\tif (!run.deletionRunFinished) return;\n\t\tvoid observer\n\t\t\t.then(async (cleanupSucceeded) => {\n\t\t\t\tif (cleanupSucceeded) await this._finishRlmRunDeletion(run);\n\t\t\t})\n\t\t\t.catch(() => undefined);\n\t}\n\n\tprivate _removeRlmSubagentTracking(childId: string, run?: RlmChildRun): void {\n\t\trun?.unsubscribe?.();\n\t\tthis._rlmChildUnsubscribes.get(childId)?.();\n\t\tthis._rlmChildUnsubscribes.delete(childId);\n\t\tthis._rlmChildSessions.delete(childId);\n\t\tthis._rlmChildUsageSources.delete(childId);\n\t\tthis._rlmChildCleanupFailures.delete(childId);\n\t\tthis._abandonedRlmQuiescenceChildIds.delete(childId);\n\t\tif (!run || this._activeRlmChildRuns.get(childId) === run) {\n\t\t\tthis._activeRlmChildRuns.delete(childId);\n\t\t}\n\t\tif (run) {\n\t\t\trun.abort = noopRlmChildAbort;\n\t\t\trun.unsubscribe = undefined;\n\t\t\trun.session = undefined;\n\t\t}\n\t}\n\n\tprivate _emitRlmSubagentRemoval(subagent: RlmSubagentRegistryEntry): void {\n\t\tthis._emit({\n\t\t\ttype: \"rlm_child_update\",\n\t\t\tchild: {\n\t\t\t\tid: subagent.rlm_child_id,\n\t\t\t\tparentId: this._rlmParentNodeId,\n\t\t\t\tactiveSessionId: subagent.active_session_id ?? undefined,\n\t\t\t\tsessionName: subagent.session_name,\n\t\t\t\tlabel: subagent.session_name,\n\t\t\t\tstatus: \"cancelled\",\n\t\t\t\tsessionDir: subagent.session_dir,\n\t\t\t\terror: \"Deleted by parent orchestrator\",\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate async _deleteResolvedRlmSubagent(subagent: RlmSubagentRegistryEntry): Promise<RlmDeleteSubagentResult> {\n\t\tconst childId = subagent.rlm_child_id;\n\t\tconst run = this._activeRlmChildRuns.get(childId);\n\t\tif (run) {\n\t\t\tif (run.deletionCleanupFailed) {\n\t\t\t\t// Reset retry coordination only after selector preflight reaches the\n\t\t\t\t// resolved child. A failed preflight must leave the prior retry boundary\n\t\t\t\t// intact so a later call can acquire it.\n\t\t\t\trun.deletionCleanupFailed = false;\n\t\t\t\trun.deletionReservation = createAgentMessageDeferred();\n\t\t\t}\n\t\t\t// The detached task remains the sole lifecycle owner. Mark deletion before\n\t\t\t// cancellation so its catch/finally path cannot race a normal release or\n\t\t\t// terminal notice against the physical delete.\n\t\t\trun.detachedDeletion = subagent;\n\t\t\tif (this._cancelRlmChildRun(run, \"Deleted by parent orchestrator\")) {\n\t\t\t\trun.deletionNeedsCompletionNotice = true;\n\t\t\t} else {\n\t\t\t\tthis._emitRlmSubagentRemoval(subagent);\n\t\t\t}\n\t\t\tconst liveSession = run.session;\n\t\t\tif (run.status === \"error\" && !liveSession && run.settled) {\n\t\t\t\tthis._deletedRlmChildIds.add(childId);\n\t\t\t\tthis._removeRlmSubagentTracking(childId, run);\n\t\t\t\treturn { subagent };\n\t\t\t}\n\t\t\tif (liveSession && run.settled) {\n\t\t\t\trun.deletionRunFinished = true;\n\t\t\t\trun.settlement = createAgentMessageDeferred();\n\t\t\t\trun.settled = false;\n\t\t\t\tthis._unsettledRlmChildRuns.add(run);\n\t\t\t}\n\t\t\tif (liveSession) this._continueFinishedRlmRunDeletion(run, subagent, liveSession);\n\n\t\t\t// Return once deletion is accepted. The run stays hidden but unsettled until\n\t\t\t// abort-insensitive model/tool work unwinds and the shared cleanup finishes.\n\t\t\tthis._deletedRlmChildIds.add(childId);\n\t\t\treturn { subagent };\n\t\t}\n\n\t\tthis._emitRlmSubagentRemoval(subagent);\n\t\tconst retained = this._rlmChildSessions.get(childId)?.session;\n\t\ttry {\n\t\t\tawait this._deleteRlmSubagentSession(childId, retained);\n\t\t} catch (error) {\n\t\t\tif (this._disposed || this._disposing) {\n\t\t\t\tthis._removeRlmSubagentTracking(childId);\n\t\t\t\tvoid retained?.disposeAsync().catch(() => undefined);\n\t\t\t} else {\n\t\t\t\tthis._rlmChildCleanupFailures.set(childId, subagent);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tthis._deletedRlmChildIds.add(childId);\n\t\tthis._removeRlmSubagentTracking(childId);\n\t\treturn { subagent };\n\t}\n\n\tprivate async _restoreRlmChildUsageSource(childId: string, child: AgentSession): Promise<void> {\n\t\tif (this._rlmChildUsageSources.has(childId)) return;\n\t\tconst readSource = (entry: SessionEntry): RlmChildUsageSource | undefined => {\n\t\t\tif (entry.type !== \"custom\" || entry.customType !== RLM_PARENT_USAGE_CUSTOM_TYPE) return;\n\t\t\tconst data = entry.data as Partial<RlmChildUsageSource> | undefined;\n\t\t\tif (\n\t\t\t\t!data ||\n\t\t\t\tdata.sessionId !== this.sessionId ||\n\t\t\t\tdata.sessionFile !== this.sessionFile ||\n\t\t\t\ttypeof data.entryId !== \"string\"\n\t\t\t)\n\t\t\t\treturn;\n\t\t\treturn { sessionId: data.sessionId, sessionFile: data.sessionFile, entryId: data.entryId };\n\t\t};\n\t\tconst source = child.sessionManager.supportsCapturedHistoryReads()\n\t\t\t? await child.sessionManager.readBranchHistory(async (history) => {\n\t\t\t\t\tlet after = 0;\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\tconst page = await history.page(after, 64);\n\t\t\t\t\t\tfor (const ref of page.events) {\n\t\t\t\t\t\t\tif (ref.kind !== \"custom\" || ref.locator.length > 16 * 1024) continue;\n\t\t\t\t\t\t\tconst record = await history.hydrateEntry(ref.id, 16 * 1024);\n\t\t\t\t\t\t\tconst source = record && readSource(record.entry);\n\t\t\t\t\t\t\tif (source) return source;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (page.nextAfter === null) return;\n\t\t\t\t\t\tafter = page.nextAfter;\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t: child.sessionManager\n\t\t\t\t\t.getBranch()\n\t\t\t\t\t.map(readSource)\n\t\t\t\t\t.find((source) => source !== undefined);\n\t\tif (!source || source.sessionId !== this.sessionId || source.sessionFile !== this.sessionFile) return;\n\t\tconst target = await this.sessionManager.readEntry(source.entryId);\n\t\tif (target?.type !== \"message\" || target.message.role !== \"assistant\") return;\n\t\tif (source.sessionId !== this.sessionId || source.sessionFile !== this.sessionFile) return;\n\t\tthis._rlmChildUsageSources.set(childId, source);\n\t}\n\n\tprivate _subscribeRlmChildEvents(\n\t\tchildId: string,\n\t\tchild: AgentSession,\n\t\trun?: RlmChildRun,\n\t\tonUsageWrite?: (write: Promise<void>) => void,\n\t): () => void {\n\t\tlet runningToolCount = 0;\n\t\tconst emitChildUpdate = () => {\n\t\t\tif (run) run.emitUpdate?.();\n\t\t\telse this._emit({ type: \"rlm_child_update\", child: this._rlmChildSnapshotForSession(childId, child) });\n\t\t};\n\t\tconst attributeUsage = (usage: Usage, origin: RlmChildUsageOrigin): Promise<void> => {\n\t\t\tconst source = this._rlmChildUsageSources.get(childId);\n\t\t\tif (!source || source.sessionId !== this.sessionId || source.sessionFile !== this.sessionFile)\n\t\t\t\treturn Promise.resolve();\n\t\t\tconst delta = structuredClone(usage);\n\t\t\tconst target = this.messages.find(\n\t\t\t\t(message): message is AssistantMessage =>\n\t\t\t\t\tmessage.role === \"assistant\" && this._findAssistantEntryIdForMessage(message) === source.entryId,\n\t\t\t);\n\t\t\tconst refreshOutput = this._refreshInvocationOutput;\n\t\t\tconst forwardUsage = this._rlmParentUsageAttribution;\n\t\t\tconst write = this.sessionManager\n\t\t\t\t.appendChildUsageAttributionWithAggregate(source.entryId, delta, undefined, origin)\n\t\t\t\t.then(async ({ aggregateUsage }) => {\n\t\t\t\t\tif (target) {\n\t\t\t\t\t\ttarget.usage = structuredClone(aggregateUsage);\n\t\t\t\t\t\trefreshOutput?.(target);\n\t\t\t\t\t}\n\t\t\t\t\t// Ancestors receive only this newly acknowledged delta, never the aggregate again.\n\t\t\t\t\tawait forwardUsage?.(delta, origin);\n\t\t\t\t});\n\t\t\tthis._childUsageWrites.add(write);\n\t\t\tonUsageWrite?.(write);\n\t\t\tvoid write.then(\n\t\t\t\t() => this._childUsageWrites.delete(write),\n\t\t\t\t(error) => {\n\t\t\t\t\tthis._childUsageWrites.delete(write);\n\t\t\t\t\tif (run) run.error = `Child usage attribution was not acknowledged: ${this._asError(error).message}`;\n\t\t\t\t\tthis._surfaceSessionInputError(error);\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn write;\n\t\t};\n\t\tchild._rlmParentUsageAttribution = attributeUsage;\n\t\tconst unsubscribe = child.subscribe((event) => {\n\t\t\tif (event.type === \"rlm_child_update\") {\n\t\t\t\tthis._emit(event);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (event.type === \"agent_start\") {\n\t\t\t\tif (run) run.activity = { kind: \"waiting\" };\n\t\t\t\temitChildUpdate();\n\t\t\t} else if (event.type === \"agent_end\") {\n\t\t\t\tif (run) run.activity = undefined;\n\t\t\t\temitChildUpdate();\n\t\t\t} else if (event.type === \"message_end\" && event.message.role === \"assistant\") {\n\t\t\t\tconst assistant = event.message;\n\t\t\t\tif (run) {\n\t\t\t\t\trun.terminalAssistantOutcome = {\n\t\t\t\t\t\tstopReason: assistant.stopReason,\n\t\t\t\t\t\terrorMessage: assistant.errorMessage,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst update = () => {\n\t\t\t\t\tconst text = compactRlmText(readAssistantText(assistant));\n\t\t\t\t\tif (run && text) run.answerPreview = text;\n\t\t\t\t\temitChildUpdate();\n\t\t\t\t};\n\t\t\t\tif (assistant.stopReason !== \"error\" && assistant.stopReason !== \"aborted\") {\n\t\t\t\t\tconst messages = child.messages;\n\t\t\t\t\tconst precedingPrompt = messages\n\t\t\t\t\t\t.slice(0, messages.lastIndexOf(assistant))\n\t\t\t\t\t\t.reverse()\n\t\t\t\t\t\t.find(\n\t\t\t\t\t\t\t(message) =>\n\t\t\t\t\t\t\t\tmessage.role === \"user\" ||\n\t\t\t\t\t\t\t\t(message.role === \"custom\" && message.customType !== HARNESS_SNAPSHOT_CUSTOM_TYPE),\n\t\t\t\t\t\t);\n\t\t\t\t\tconst origin =\n\t\t\t\t\t\tprecedingPrompt?.role === \"custom\" && isAgentSessionMessage(precedingPrompt)\n\t\t\t\t\t\t\t? precedingPrompt.details.id.startsWith(\"spawn:\")\n\t\t\t\t\t\t\t\t? \"spawn_task\"\n\t\t\t\t\t\t\t\t: \"agent_message\"\n\t\t\t\t\t\t\t: \"direct_user\";\n\t\t\t\t\tvoid attributeUsage(assistant.usage, origin).then(update, () => {});\n\t\t\t\t} else update();\n\t\t\t} else if (event.type === \"message_start\" || event.type === \"message_update\") {\n\t\t\t\tif (event.message.role === \"assistant\") {\n\t\t\t\t\tif (run) {\n\t\t\t\t\t\tconst text = compactRlmText(readAssistantText(event.message));\n\t\t\t\t\t\tif (text) run.answerPreview = text;\n\t\t\t\t\t\trun.activity = { kind: \"writing\" };\n\t\t\t\t\t}\n\t\t\t\t\temitChildUpdate();\n\t\t\t\t}\n\t\t\t} else if (event.type === \"tool_execution_start\") {\n\t\t\t\tif (run) {\n\t\t\t\t\trun.toolUseCount++;\n\t\t\t\t\trunningToolCount++;\n\t\t\t\t\trun.activity = { kind: \"executing\", toolName: event.toolName };\n\t\t\t\t}\n\t\t\t\temitChildUpdate();\n\t\t\t} else if (event.type === \"tool_execution_end\") {\n\t\t\t\tif (run) {\n\t\t\t\t\trunningToolCount = Math.max(0, runningToolCount - 1);\n\t\t\t\t\tif (runningToolCount === 0) run.activity = { kind: \"waiting\" };\n\t\t\t\t}\n\t\t\t\temitChildUpdate();\n\t\t\t} else if (event.type === \"session_info_changed\" || event.type === \"recap_update\") emitChildUpdate();\n\t\t});\n\t\treturn () => {\n\t\t\tunsubscribe();\n\t\t\tif (child._rlmParentUsageAttribution === attributeUsage) child._rlmParentUsageAttribution = undefined;\n\t\t};\n\t}\n\n\t/**\n\t * Retain a finished child session for the parent lifetime so inspectors and\n\t * daemon-hosted agent messaging can keep addressing it. Returns false (and disposes\n\t * the child) when the parent is already tearing down, so the caller can drop the\n\t * matching event forwarder too.\n\t */\n\tasync registerRlmChildSession(childId: string, session: AgentSession, unsubscribe?: () => void): Promise<boolean> {\n\t\t// A child can finish concurrently while the parent is (or has) torn down; don't\n\t\t// resurrect the map (it would never be disposed), just drop the child now.\n\t\tif (this._deletingRlmChildren.has(childId) || this._deletedRlmChildIds.has(childId)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (this._subagentRuntimeHost?.completeRlmSubagentRuntime?.(childId, session) === false) {\n\t\t\treturn false;\n\t\t}\n\t\tif (this._disposed || this._disposing) {\n\t\t\tawait session.disposeAsync();\n\t\t\treturn false;\n\t\t}\n\t\tif (!session._rlmResidentDisposalComplete) {\n\t\t\tif (session._rlmParentAdmission?.parent === this) session._rlmParentAdmission.bind(session);\n\t\t\telse {\n\t\t\t\tconst admission = await this.reserveRlmChildAdmission();\n\t\t\t\ttry {\n\t\t\t\t\tadmission.bind(session);\n\t\t\t\t} finally {\n\t\t\t\t\tawait admission.settle();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tawait this._restoreRlmChildUsageSource(childId, session);\n\t\tif (this._disposed || this._disposing) {\n\t\t\tawait session.disposeAsync();\n\t\t\treturn false;\n\t\t}\n\t\tif (this._deletingRlmChildren.has(childId) || this._deletedRlmChildIds.has(childId)) return false;\n\t\tconst retained = this._rlmChildSessions.get(childId);\n\t\tconst run = this._activeRlmChildRuns.get(childId);\n\t\tif (!run?.unsubscribe && (retained?.session !== session || !this._rlmChildUnsubscribes.has(childId))) {\n\t\t\tthis._rlmChildUnsubscribes.get(childId)?.();\n\t\t\tconst ownedUnsubscribe = this._subscribeRlmChildEvents(childId, session);\n\t\t\tthis._rlmChildUnsubscribes.set(childId, () => {\n\t\t\t\townedUnsubscribe();\n\t\t\t\tunsubscribe?.();\n\t\t\t});\n\t\t}\n\t\tthis._rlmChildSessions.set(childId, { session, run });\n\t\treturn true;\n\t}\n\n\treleaseRlmChildSession(childId: string, session: AgentSession): (() => void) | false {\n\t\tconst run = this._activeRlmChildRuns.get(childId);\n\t\tif (run?.session === session && run.status === \"done\") {\n\t\t\tconst unsubscribe = run.unsubscribe ?? noopRlmChildEventUnsubscribe;\n\t\t\treturn () => {\n\t\t\t\tif (run.unsubscribe === unsubscribe) run.unsubscribe = undefined;\n\t\t\t\tif (this._activeRlmChildRuns.get(childId) === run) this._activeRlmChildRuns.delete(childId);\n\t\t\t\tunsubscribe();\n\t\t\t};\n\t\t}\n\t\tif (this._rlmChildSessions.get(childId)?.session !== session) return false;\n\t\tconst unsubscribe = this._rlmChildUnsubscribes.get(childId) ?? noopRlmChildEventUnsubscribe;\n\t\treturn () => {\n\t\t\tif (\n\t\t\t\tthis._rlmChildSessions.get(childId)?.session === session &&\n\t\t\t\tthis._rlmChildUnsubscribes.get(childId) === unsubscribe\n\t\t\t) {\n\t\t\t\tthis._rlmChildUnsubscribes.delete(childId);\n\t\t\t\tthis._rlmChildSessions.delete(childId);\n\t\t\t}\n\t\t\tunsubscribe();\n\t\t};\n\t}\n\n\tprivate _rlmChildSnapshotForRun(\n\t\trun: RlmChildRun,\n\t\tchild = run.session ?? this._rlmChildSessions.get(run.id)?.session,\n\t): RlmChildAgentSnapshot {\n\t\tconst model = child?.model ?? run.model;\n\t\treturn {\n\t\t\tid: run.id,\n\t\t\tparentId: this._rlmParentNodeId,\n\t\t\tsessionName: child?.sessionName ?? run.sessionName,\n\t\t\tmodel: `${model.provider}/${model.id}`,\n\t\t\tlabel: rlmChildLabel(run.prompt),\n\t\t\tstatus: run.status,\n\t\t\tdurationMs: run.durationMs,\n\t\t\tanswerPreview: run.answerPreview,\n\t\t\ttoolUseCount: run.toolUseCount > 0 ? run.toolUseCount : undefined,\n\t\t\ttokenCount: child?._contextTokensForCurrentMessages(),\n\t\t\trecap: child?.getCurrentRecap(),\n\t\t\tsessionDir: run.sessionDir,\n\t\t\tactivity: run.activity,\n\t\t\trepliedSinceTask: child?._repliedToParentSinceTask,\n\t\t\terror: run.error,\n\t\t};\n\t}\n\n\tprivate _rlmChildSnapshotForSession(childId: string, child: AgentSession): RlmChildAgentSnapshot {\n\t\tlet answerPreview: string | undefined;\n\t\tlet toolUseCount = 0;\n\t\tconst messages =\n\t\t\tchild.state.streamingMessage?.role === \"assistant\"\n\t\t\t\t? [...child.messages, child.state.streamingMessage]\n\t\t\t\t: child.messages;\n\t\tfor (const message of messages) {\n\t\t\tif (message.role !== \"assistant\") continue;\n\t\t\tconst text = compactRlmText(readAssistantText(message));\n\t\t\tif (text) answerPreview = text;\n\t\t\ttoolUseCount += message.content.filter((block) => block.type === \"toolCall\").length;\n\t\t}\n\t\treturn {\n\t\t\tid: childId,\n\t\t\tparentId: this._rlmParentNodeId,\n\t\t\tsessionName: child.sessionName,\n\t\t\tmodel: child.model ? `${child.model.provider}/${child.model.id}` : undefined,\n\t\t\tlabel: child.sessionName ?? \"child agent\",\n\t\t\tstatus: \"done\",\n\t\t\tanswerPreview,\n\t\t\ttoolUseCount: toolUseCount > 0 ? toolUseCount : undefined,\n\t\t\ttokenCount: child._contextTokensForCurrentMessages(),\n\t\t\trecap: child.getCurrentRecap(),\n\t\t\tsessionDir: child._rlmSessionDir ?? child.sessionManager.getSessionDir(),\n\t\t\t// No run exists (e.g. a child rehydrated after daemon recovery), so live\n\t\t\t// session state is the only source for in-flight follow-up work. Mirror\n\t\t\t// the run projection's convention: status stays \"done\" (the recorded task\n\t\t\t// finished) and current work surfaces through activity.\n\t\t\tactivity: child.isSessionActive ? { kind: child.isStreaming ? \"writing\" : \"waiting\" } : undefined,\n\t\t\trepliedSinceTask: child._repliedToParentSinceTask,\n\t\t};\n\t}\n\n\tprivate _isUnboundTerminalRlmChildRun(run: RlmChildRun): boolean {\n\t\tif (run.session !== undefined || this._rlmChildSessions.has(run.id)) return false;\n\t\treturn run.status === \"done\" || run.status === \"error\" || run.status === \"cancelled\";\n\t}\n\n\t/** Live recursive child roster from lifecycle state, including nested work under retained parents. */\n\tgetRlmChildSnapshots(): RlmChildAgentSnapshot[] {\n\t\tconst snapshots: RlmChildAgentSnapshot[] = [];\n\t\tconst recorded = new Set<string>();\n\t\tconst traversed = new Set<string>();\n\t\tfor (const run of this._activeRlmChildRuns.values()) {\n\t\t\tconst hidden =\n\t\t\t\trun.detachedDeletion ||\n\t\t\t\tthis._deletingRlmChildren.has(run.id) ||\n\t\t\t\tthis._deletedRlmChildIds.has(run.id) ||\n\t\t\t\tthis._isUnboundTerminalRlmChildRun(run);\n\t\t\tconst child = run.session;\n\t\t\tif (!hidden) {\n\t\t\t\tsnapshots.push(this._rlmChildSnapshotForRun(run));\n\t\t\t\trecorded.add(run.id);\n\t\t\t}\n\t\t\tif (child) {\n\t\t\t\ttraversed.add(run.id);\n\t\t\t\tsnapshots.push(...child.getRlmChildSnapshots());\n\t\t\t}\n\t\t}\n\t\tfor (const [childId, { session: child, run }] of this._rlmChildSessions) {\n\t\t\tif (recorded.has(childId) || traversed.has(childId)) continue;\n\t\t\tconst hidden = this._deletingRlmChildren.has(childId) || this._deletedRlmChildIds.has(childId);\n\t\t\tif (!hidden) {\n\t\t\t\tconst snapshot = run\n\t\t\t\t\t? this._rlmChildSnapshotForRun(run, child)\n\t\t\t\t\t: this._rlmChildSnapshotForSession(childId, child);\n\t\t\t\tsnapshots.push({\n\t\t\t\t\t...snapshot,\n\t\t\t\t\tstatus: this._rlmChildCleanupFailures.has(childId) ? \"cancelled\" : snapshot.status,\n\t\t\t\t});\n\t\t\t}\n\t\t\tsnapshots.push(...child.getRlmChildSnapshots());\n\t\t}\n\t\treturn snapshots;\n\t}\n\n\t/** True when any direct or nested subagent is still running or queued. */\n\thasRunningRlmChildren(): boolean {\n\t\tfor (const session of this._rlmSubtreeSessions()) {\n\t\t\tfor (const admission of session._rlmChildAdmissions) if (admission.pending) return true;\n\t\t\tfor (const run of session._activeRlmChildRuns.values()) {\n\t\t\t\tif (run.status === \"running\" || run.status === \"queued\") {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate _rlmChildSessionSnapshot(): AgentSession[] {\n\t\tconst sessions = new Set<AgentSession>();\n\t\tfor (const [childId, { session }] of this._rlmChildSessions) {\n\t\t\tif (!this._abandonedRlmQuiescenceChildIds.has(childId)) sessions.add(session);\n\t\t}\n\t\tfor (const run of this._activeRlmChildRuns.values()) {\n\t\t\tif (run.session && !run.abandonedForQuiescence) sessions.add(run.session);\n\t\t}\n\t\treturn [...sessions];\n\t}\n\n\tprivate _hasUnsettledRlmQuiescenceWork(): boolean {\n\t\tif (this.requests.hasPending || this._childUsageWrites.size > 0) return true;\n\t\tif (this._hasDeferredRlmTerminalNotices()) return true;\n\t\tif ([...this._unsettledRlmChildRuns].some((run) => !run.settled)) return true;\n\t\treturn this._rlmChildSessionSnapshot().some(\n\t\t\t(child) => child.isSessionActive || child._hasUnsettledRlmQuiescenceWork(),\n\t\t);\n\t}\n\n\t/**\n\t * Wait for every admitted descendant run to publish its terminal parent\n\t * message and for the resulting parent turns to drain. Re-snapshotting after\n\t * each drain includes descendants spawned while earlier results were consumed.\n\t */\n\tasync waitForRlmQuiescence(externalSignal?: AbortSignal): Promise<void> {\n\t\tconst cancellation = new AbortController();\n\t\tconst cancelFromParent = () => cancellation.abort();\n\t\tif (externalSignal?.aborted) cancellation.abort();\n\t\telse externalSignal?.addEventListener(\"abort\", cancelFromParent, { once: true });\n\t\tthis._rlmQuiescenceWaitAborts.add(cancellation);\n\t\tlet rejectCancelled = (_error: Error) => {};\n\t\tconst cancelled = new Promise<never>((_resolve, reject) => {\n\t\t\trejectCancelled = reject;\n\t\t});\n\t\tconst onCancelled = () => rejectCancelled(new Error(\"RLM quiescence wait cancelled\"));\n\t\tcancellation.signal.addEventListener(\"abort\", onCancelled, { once: true });\n\t\tif (cancellation.signal.aborted) onCancelled();\n\t\tconst wait = <T>(operation: Promise<T>): Promise<T> => Promise.race([operation, cancelled]);\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tawait wait(this.waitForHeadlessIdle());\n\t\t\t\t// Strong RLM quiescence also owns work that interactive waitForIdle ignores.\n\t\t\t\tif (this.isSessionActive || this._hasDeferredRlmTerminalNotices()) {\n\t\t\t\t\tawait wait(this._waitForSessionActivityChange(cancellation.signal));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst unsettledRuns = [...this._unsettledRlmChildRuns].filter((run) => !run.settled);\n\t\t\t\tconst childSessions = this._rlmChildSessionSnapshot();\n\t\t\t\tif (unsettledRuns.length === 0 && !this._hasUnsettledRlmQuiescenceWork()) return;\n\t\t\t\tawait wait(\n\t\t\t\t\tPromise.all([\n\t\t\t\t\t\t...unsettledRuns.map((run) => run.settlement.promise),\n\t\t\t\t\t\t...this._childUsageWrites,\n\t\t\t\t\t\t...childSessions.map((child) => child.waitForRlmQuiescence(cancellation.signal)),\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\t\t// Always loop through the self-active/deferred checks again. Work may\n\t\t\t\t// start at the child-settlement boundary.\n\t\t\t}\n\t\t} finally {\n\t\t\t// A local descendant error must cancel sibling recursive waits owned by\n\t\t\t// this barrier before their propagation listeners are removed.\n\t\t\tcancellation.abort();\n\t\t\texternalSignal?.removeEventListener(\"abort\", cancelFromParent);\n\t\t\tcancellation.signal.removeEventListener(\"abort\", onCancelled);\n\t\t\tthis._rlmQuiescenceWaitAborts.delete(cancellation);\n\t\t}\n\t}\n\n\t// Inline (non-daemon) mode only; daemon clients attach to the child session directly.\n\tgetRlmChildSession(childId: string): AgentSession | undefined {\n\t\tfor (const session of this._rlmSubtreeSessions()) {\n\t\t\tconst direct =\n\t\t\t\tsession._activeRlmChildRuns.get(childId)?.session ?? session._rlmChildSessions.get(childId)?.session;\n\t\t\tif (direct) {\n\t\t\t\treturn direct;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Cancel a single RLM child run by id, searching nested child sessions.\n\t *\n\t * @returns true when a live run was cancelled or its unsettled terminal notice\n\t * was suppressed; false when the id is unknown or the run already settled.\n\t */\n\tcancelRlmChildRun(childId: string, reason = \"Cancelled by user\"): boolean {\n\t\tfor (const session of this._rlmSubtreeSessions()) {\n\t\t\tconst run = session._activeRlmChildRuns.get(childId);\n\t\t\tif (run) {\n\t\t\t\tif (run.status !== \"running\" && run.status !== \"queued\" && !run.settled) {\n\t\t\t\t\tif (session._sessionInputPumpSuspended) session._abandonRlmRunForQuiescence(run);\n\t\t\t\t\telse run.suppressTerminalNotice = true;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// The abort cascade never reaches running work retained under a settled descendant.\n\t\t\t\tconst cancelled = session._cancelRlmChildRun(run, reason);\n\t\t\t\tconst descendantsCancelled = run.session?.cancelRunningRlmDescendants(reason) ?? false;\n\t\t\t\tif (cancelled || descendantsCancelled) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// A fruitless match keeps walking: child ids are only mkdir-unique among\n\t\t\t// siblings, so a colliding live run elsewhere must stay reachable.\n\t\t\tif (session._rlmChildSessions.get(childId)?.session.cancelRunningRlmDescendants(reason)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t// A done child sits in BOTH maps until passivation; the visited set keeps that dual membership from doubling the walk.\n\tprivate *_rlmSubtreeSessions(): Generator<AgentSession> {\n\t\tconst visited = new Set<AgentSession>([this]);\n\t\tconst stack: AgentSession[] = [this];\n\t\twhile (stack.length > 0) {\n\t\t\tconst session = stack.pop()!;\n\t\t\tyield session;\n\t\t\tfor (const run of session._activeRlmChildRuns.values()) {\n\t\t\t\tif (run.session && !visited.has(run.session)) {\n\t\t\t\t\tvisited.add(run.session);\n\t\t\t\t\tstack.push(run.session);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const { session: retained } of session._rlmChildSessions.values()) {\n\t\t\t\tif (!visited.has(retained)) {\n\t\t\t\t\tvisited.add(retained);\n\t\t\t\t\tstack.push(retained);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Cancel every running or queued run in this session's subtree. */\n\tcancelRunningRlmDescendants(reason = \"Cancelled by user\"): boolean {\n\t\tlet cancelled = false;\n\t\tfor (const session of this._rlmSubtreeSessions()) {\n\t\t\tfor (const admission of session._rlmChildAdmissions) if (admission.cancel(reason)) cancelled = true;\n\t\t\tfor (const run of session._activeRlmChildRuns.values()) {\n\t\t\t\tif (session._cancelRlmChildRun(run, reason)) cancelled = true;\n\t\t\t}\n\t\t}\n\t\treturn cancelled;\n\t}\n\n\tprivate async _assertRlmSubagentSessionNameAvailable(name: string, ignorePendingReservation = false): Promise<void> {\n\t\tconst depth = this._rlmDepth + 1;\n\t\tif (!ignorePendingReservation && this._pendingRlmSubagentSessionNames.has(name)) {\n\t\t\tthrow new Error(formatAgentSessionNameUnavailable(name, depth));\n\t\t}\n\t\tconst localConflict =\n\t\t\t[...this._activeRlmChildRuns.values()].some(\n\t\t\t\t(run) => run.session?.sessionName === name || (!run.session && run.sessionName === name),\n\t\t\t) ||\n\t\t\t[...this._rlmChildSessions.values()].some(({ session }) => session.sessionName === name) ||\n\t\t\t[...this._rlmChildCleanupFailures.values()].some((entry) => entry.session_name === name);\n\t\tif (localConflict) {\n\t\t\tthrow new Error(formatAgentSessionNameUnavailable(name, depth));\n\t\t}\n\t\tconst controller = this._agentMessageController;\n\t\tif (!controller) return;\n\t\tconst input = {\n\t\t\tname,\n\t\t\tdepth,\n\t\t\tparentSessionId: this.sessionId,\n\t\t\tparentSessionPath: this.sessionFile,\n\t\t};\n\t\tif (controller.assertSessionNameAvailable) {\n\t\t\tawait controller.assertSessionNameAvailable(input);\n\t\t\treturn;\n\t\t}\n\t\tconst listed = await controller.listAgents();\n\t\tconst catalog = listed.agents.map(\n\t\t\t(agent): AgentFamilyCatalogEntry => ({\n\t\t\t\tid: agent.sessionId,\n\t\t\t\t...(agent.sessionName ? { name: agent.sessionName } : {}),\n\t\t\t\tdepth: agent.rlmDepth ?? 0,\n\t\t\t\tstatus: agent.status ?? \"idle\",\n\t\t\t\t...(agent.parentSessionId ? { parentSessionId: agent.parentSessionId } : {}),\n\t\t\t\t...(agent.parentSessionPath ? { parentSessionPath: agent.parentSessionPath } : {}),\n\t\t\t\t...(agent.sessionPath ? { sessionPath: agent.sessionPath } : {}),\n\t\t\t}),\n\t\t);\n\t\tassertAgentSessionNameAvailable(catalog, input);\n\t}\n\n\tprivate async _authenticatedRlmModels(): Promise<Model<Api>[]> {\n\t\treturn (await this._modelRegistry.getExecutableModels()).filter((model) => {\n\t\t\tconst status = this._modelRegistry.getProviderAuthStatus(model.provider);\n\t\t\treturn status.source !== \"stale\" && status.label !== \"expired\";\n\t\t});\n\t}\n\n\tasync findRlmModels(query: string, limit: number): Promise<RlmFindModelsResult> {\n\t\treturn {\n\t\t\tmodels: findRlmModelMatches(query, await this._authenticatedRlmModels(), limit),\n\t\t};\n\t}\n\n\tprivate async _resolveRlmSubagentModel(reference: string | undefined): Promise<RlmSubagentModelSelection> {\n\t\tconst parentModel = this.model;\n\t\tif (!parentModel) {\n\t\t\tthrow new Error(formatNoModelSelectedMessage());\n\t\t}\n\t\tif (!reference) {\n\t\t\treturn { model: parentModel };\n\t\t}\n\n\t\tconst normalizedReference = reference.toLowerCase();\n\t\tif (`${parentModel.provider}/${parentModel.id}`.toLowerCase() === normalizedReference) {\n\t\t\treturn { model: parentModel };\n\t\t}\n\t\tconst model = (await this._authenticatedRlmModels()).find(\n\t\t\t(candidate) => `${candidate.provider}/${candidate.id}`.toLowerCase() === normalizedReference,\n\t\t);\n\t\tif (!model) {\n\t\t\tthrow new Error(`Requested subagent model \"${reference}\" is unavailable, unauthenticated, or expired`);\n\t\t}\n\n\t\tconst auth = await this._modelRegistry.getApiKeyAndHeaders(model);\n\t\tif (!auth.ok) {\n\t\t\tthrow new Error(`Requested subagent model \"${reference}\" failed authentication preflight`);\n\t\t}\n\t\treturn { model };\n\t}\n\n\tprivate async _startRlmChildRun(\n\t\tprompt: string,\n\t\tadmission: RlmChildAdmission,\n\t\tkwargs: Record<string, unknown> = {},\n\t\tspawnCode?: string,\n\t): Promise<RlmSpawnHandle> {\n\t\t// Snapshot before any await: the spawning request is the turn whose tool call is\n\t\t// executing now. A spawn arriving outside an active run (a detached kernel task\n\t\t// firing while the parent is idle) has no such turn; an absent edge beats a wrong one.\n\t\tconst spawnedByRequestId = this.isStreaming ? this._semanticEdges.lastTurnRequestId : undefined;\n\t\tconst parentAssistantForUsage = this._findLastAssistantMessage();\n\t\tconst parentEntryId = parentAssistantForUsage && this._findAssistantEntryIdForMessage(parentAssistantForUsage);\n\t\tconst usageSource: RlmChildUsageSource | undefined = parentEntryId\n\t\t\t? {\n\t\t\t\t\tsessionId: this.sessionId,\n\t\t\t\t\tsessionFile: this.sessionFile,\n\t\t\t\t\tentryId: parentEntryId,\n\t\t\t\t}\n\t\t\t: undefined;\n\t\tconst { name: rawName, model: rawModel, thinking: rawThinking, ...unsupported } = kwargs;\n\t\tconst unsupportedKwargs = Object.keys(unsupported);\n\t\tif (unsupportedKwargs.length > 0) {\n\t\t\tthrow new Error(`Unsupported rlm.run kwargs: ${unsupportedKwargs.sort().join(\", \")}`);\n\t\t}\n\t\tconst requestedSessionName = normalizeRequestedRlmSubagentSessionName(rawName);\n\t\tconst requestedModel = normalizeRequestedRlmSubagentModel(rawModel);\n\t\tconst requestedThinkingLevel = normalizeRequestedRlmSubagentThinkingLevel(rawThinking);\n\t\tif (requestedSessionName) assertDirectAgentMessageTarget(requestedSessionName);\n\t\tif (this._rlmDepth >= this._rlmMaxDepth) {\n\t\t\tthrow new Error(\n\t\t\t\t`RLM recursion depth limit reached (BASE_CONTEXT_RLM_DEPTH=${this._rlmDepth}, BASE_CONTEXT_RLM_MAX_DEPTH=${this._rlmMaxDepth})`,\n\t\t\t);\n\t\t}\n\t\tif (requestedSessionName) {\n\t\t\tif (this._pendingRlmSubagentSessionNames.has(requestedSessionName)) {\n\t\t\t\tthrow new Error(formatAgentSessionNameUnavailable(requestedSessionName, this._rlmDepth + 1));\n\t\t\t}\n\t\t\tthis._pendingRlmSubagentSessionNames.add(requestedSessionName);\n\t\t}\n\t\tlet modelSelection: RlmSubagentModelSelection;\n\t\ttry {\n\t\t\tif (requestedSessionName) await this._assertRlmSubagentSessionNameAvailable(requestedSessionName, true);\n\t\t\tmodelSelection = await this._resolveRlmSubagentModel(requestedModel);\n\t\t} finally {\n\t\t\tif (requestedSessionName) this._pendingRlmSubagentSessionNames.delete(requestedSessionName);\n\t\t}\n\t\tadmission.assertCurrent();\n\t\tif (requestedThinkingLevel !== undefined) {\n\t\t\tconst supported = getSupportedThinkingLevels(modelSelection.model) as ThinkingLevel[];\n\t\t\tif (!supported.includes(requestedThinkingLevel)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Requested thinking level \"${requestedThinkingLevel}\" is not supported by model \"${modelSelection.model.provider}/${modelSelection.model.id}\"; supported levels: ${supported.join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (this._disposed || this._disposing) throw new Error(\"Cannot spawn a subagent after its parent was disposed\");\n\n\t\tconst childSessionDir = this._createChildRlmSessionDir();\n\t\tconst childNodeId = basename(childSessionDir);\n\t\tconst sessionName = requestedSessionName ?? createDefaultRlmSubagentSessionName(prompt, childNodeId);\n\t\tif (!requestedSessionName) await this._assertRlmSubagentSessionNameAvailable(sessionName);\n\t\tadmission.assertCurrent();\n\t\tconst startedAt = Date.now();\n\t\tlet childSession: AgentSession | undefined;\n\t\tlet usageSettlement: Promise<void> = Promise.resolve();\n\t\tconst run: RlmChildRun = {\n\t\t\tid: childNodeId,\n\t\t\tprompt,\n\t\t\tsessionName,\n\t\t\tsessionDir: childSessionDir,\n\t\t\tmodel: modelSelection.model,\n\t\t\tstatus: \"queued\",\n\t\t\ttoolUseCount: 0,\n\t\t\tsettled: false,\n\t\t\tabort: noopRlmChildAbort,\n\t\t\tpublication: createAgentMessageDeferred(),\n\t\t\tsettlement: createAgentMessageDeferred(),\n\t\t\tdeletionReservation: createAgentMessageDeferred(),\n\t\t};\n\t\tconst throwIfCancelled = () => {\n\t\t\tif (run.status === \"cancelled\") throw new Error(run.error ?? \"RLM child cancelled\");\n\t\t};\n\t\tthis._activeRlmChildRuns.set(run.id, run);\n\t\tif (usageSource) this._rlmChildUsageSources.set(run.id, usageSource);\n\t\tthis._unsettledRlmChildRuns.add(run);\n\t\tconst emitChildUpdate = () => {\n\t\t\tconst child = this._rlmChildSnapshotForRun(run);\n\t\t\tconst serialized = JSON.stringify(child);\n\t\t\tif (serialized === run.lastEmittedUpdate) return;\n\t\t\trun.lastEmittedUpdate = serialized;\n\t\t\tthis._emit({ type: \"rlm_child_update\", child });\n\t\t};\n\t\trun.emitUpdate = emitChildUpdate;\n\t\temitChildUpdate();\n\n\t\tconst publishChildSession = (child: AgentSession) => {\n\t\t\tchildSession = child;\n\t\t\tif (this._activeRlmChildRuns.get(run.id) !== run) return;\n\t\t\trun.session = child;\n\t\t\trun.abort = () => void child.abort();\n\t\t\trun.publication.resolve();\n\t\t\t// Cancellation may have been admitted while runtime construction was\n\t\t\t// blocked and run.abort was still a no-op.\n\t\t\tif (run.status === \"cancelled\") run.abort();\n\t\t};\n\t\tconst subagentOptions: CreateRlmSubagentRuntimeOptions & { admission: RlmChildAdmission } = {\n\t\t\t...this._createRlmSubagentRuntimeOptions({\n\t\t\t\tadmission,\n\t\t\t\tid: childNodeId,\n\t\t\t\tprompt,\n\t\t\t\tsessionName,\n\t\t\t\tspawnCode,\n\t\t\t\tsessionDir: childSessionDir,\n\t\t\t\tmodel: modelSelection.model,\n\t\t\t\tthinkingLevel: requestedThinkingLevel,\n\t\t\t\tspawnedByRequestId,\n\t\t\t}),\n\t\t\tonSessionPublished: publishChildSession,\n\t\t};\n\n\t\tconst deliverTerminalMessageToParent = async (message: CustomMessage): Promise<void> => {\n\t\t\t// Synthesized lifecycle notices always use the parent's private durable\n\t\t\t// path. Explicit child replies continue through agent_message separately.\n\t\t\tawait this._deferRlmTerminalNotice(message);\n\t\t};\n\n\t\trun.completeDeletion = () => {\n\t\t\tif (!run.deletionNeedsCompletionNotice || run.suppressTerminalNotice || this._disposed || this._disposing) {\n\t\t\t\treturn Promise.resolve();\n\t\t\t}\n\t\t\tif (run.deletionNotice) return run.deletionNotice;\n\t\t\tconst notice = deliverTerminalMessageToParent(\n\t\t\t\tcreateRlmChildTerminalNoticeMessage({\n\t\t\t\t\tkind: \"cancelled\",\n\t\t\t\t\tchildId: run.id,\n\t\t\t\t\tsessionName,\n\t\t\t\t\treason: run.error ?? \"Deleted by parent orchestrator\",\n\t\t\t\t}),\n\t\t\t);\n\t\t\trun.deletionNotice = notice;\n\t\t\treturn notice;\n\t\t};\n\n\t\trun.reportDeletionCleanupFailure = (error) => {\n\t\t\tif (run.suppressTerminalNotice || this._disposed || this._disposing) return Promise.resolve();\n\t\t\tconst cleanupError = error instanceof Error ? error.message : String(error);\n\t\t\treturn deliverTerminalMessageToParent(\n\t\t\t\tcreateRlmChildFailureMessage({\n\t\t\t\t\tchildId: run.id,\n\t\t\t\t\tsessionName,\n\t\t\t\t\terror: `Deletion cleanup failed; retry rlm.delete_subagent(\"${run.id}\") before completion: ${cleanupError}`,\n\t\t\t\t}),\n\t\t\t);\n\t\t};\n\n\t\t// Runtime startup and the task run are deliberately detached. The public\n\t\t// spawn resolves at admission, while this task owns live tracking, usage,\n\t\t// retention, cancellation, and late-startup cleanup.\n\t\tconst task = (async () => {\n\t\t\tlet childRuntime: RlmSubagentRuntime | undefined;\n\t\t\ttry {\n\t\t\t\ttry {\n\t\t\t\t\tchildRuntime = await this._createRlmSubagentRuntime(subagentOptions);\n\t\t\t\t\tadmission.bind(childRuntime.session);\n\t\t\t\t} finally {\n\t\t\t\t\tawait admission.settle();\n\t\t\t\t}\n\t\t\t\tadmission.assertCurrent();\n\t\t\t\tconst child = childRuntime.session;\n\t\t\t\tif (run.status === \"cancelled\") throw new Error(run.error ?? \"RLM child cancelled\");\n\t\t\t\tif (child.sessionName !== sessionName) await child.setSessionName(sessionName);\n\t\t\t\tpublishChildSession(child);\n\t\t\t\tthrowIfCancelled();\n\t\t\t\trun.status = \"running\";\n\t\t\t\temitChildUpdate();\n\t\t\t\tif (usageSource) {\n\t\t\t\t\tawait child.sessionManager.appendCustomEntry(RLM_PARENT_USAGE_CUSTOM_TYPE, usageSource);\n\t\t\t\t}\n\t\t\t\tconst unsubscribeChildEvents = this._subscribeRlmChildEvents(run.id, child, run, (write) => {\n\t\t\t\t\tusageSettlement = Promise.all([usageSettlement, write]).then(() => undefined);\n\t\t\t\t\tvoid usageSettlement.catch(() => undefined);\n\t\t\t\t});\n\t\t\t\trun.unsubscribe = unsubscribeChildEvents;\n\t\t\t\tconst content = `[task from parent]\\n\\n${prompt}`;\n\t\t\t\tconst spawnMessage: AgentSessionMessage = {\n\t\t\t\t\trole: \"custom\",\n\t\t\t\t\tcustomType: AGENT_MESSAGE_CUSTOM_TYPE,\n\t\t\t\t\tcontent,\n\t\t\t\t\tdisplay: true,\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tid: `spawn:${run.id}`,\n\t\t\t\t\t\tmessage: prompt,\n\t\t\t\t\t\tfrom: {\n\t\t\t\t\t\t\tsessionId: this.sessionId,\n\t\t\t\t\t\t\tsessionName: this.sessionName,\n\t\t\t\t\t\t\tactiveSessionId: await this._currentActiveSessionId(),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfromRelationship: \"parent\",\n\t\t\t\t\t},\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t};\n\t\t\t\tthrowIfCancelled();\n\t\t\t\tconst parentReplyCountBeforeRun = child._parentReplyCount;\n\t\t\t\tawait child.promptAndWait(content, {\n\t\t\t\t\texpandPromptTemplates: false,\n\t\t\t\t\tsource: \"extension\",\n\t\t\t\t\tcustomMessage: spawnMessage,\n\t\t\t\t});\n\t\t\t\t// promptAndWait can resolve after a provider error or abort. Only outcomes\n\t\t\t\t// emitted during this run count; a recovered intermediate error is not terminal.\n\t\t\t\tconst terminal = run.terminalAssistantOutcome;\n\t\t\t\tif (terminal?.stopReason === \"aborted\") {\n\t\t\t\t\trun.status = \"cancelled\";\n\t\t\t\t\trun.error ??= terminal.errorMessage || \"RLM child aborted\";\n\t\t\t\t}\n\t\t\t\tthrowIfCancelled();\n\t\t\t\tif (terminal?.stopReason === \"error\")\n\t\t\t\t\tthrow new Error(terminal.errorMessage || \"RLM child inference failed\");\n\t\t\t\tawait child.waitForRlmQuiescence();\n\t\t\t\tawait usageSettlement;\n\t\t\t\tthrowIfCancelled();\n\t\t\t\tif (run.error) throw new Error(run.error);\n\t\t\t\trun.status = \"done\";\n\t\t\t\t// Only successful completions return; the edge lands on the parent's next commit.\n\t\t\t\tconst childLastCommitted = child.semanticEdges.lastCommittedRequestId;\n\t\t\t\tif (childLastCommitted !== undefined) {\n\t\t\t\t\tthis._semanticEdges.recordChildReturned(child.sessionId, childLastCommitted);\n\t\t\t\t}\n\t\t\t\trun.durationMs = Date.now() - startedAt;\n\t\t\t\trun.activity = undefined;\n\t\t\t\temitChildUpdate();\n\t\t\t\tif (\n\t\t\t\t\t!run.detachedDeletion &&\n\t\t\t\t\t!run.suppressTerminalNotice &&\n\t\t\t\t\tchild._parentReplyCount === parentReplyCountBeforeRun\n\t\t\t\t) {\n\t\t\t\t\tconst lastAssistantText = child.getLastAssistantText();\n\t\t\t\t\tawait deliverTerminalMessageToParent(\n\t\t\t\t\t\tcreateRlmChildTerminalNoticeMessage({\n\t\t\t\t\t\t\tkind: \"completed_without_reply\",\n\t\t\t\t\t\t\tchildId: run.id,\n\t\t\t\t\t\t\tsessionName,\n\t\t\t\t\t\t\tlastAssistantTextPreview: lastAssistantText ? compactRlmText(lastAssistantText) : undefined,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!(await this.registerRlmChildSession(run.id, child)) && !run.detachedDeletion) {\n\t\t\t\t\tif (childRuntime && this._subagentRuntimeHost?.releaseRlmSubagentRuntime) {\n\t\t\t\t\t\tawait this._subagentRuntimeHost\n\t\t\t\t\t\t\t.releaseRlmSubagentRuntime(childRuntime, subagentOptions, \"error\")\n\t\t\t\t\t\t\t.catch(() => void child.disposeAsync().catch(() => undefined));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait child.disposeAsync().catch(() => undefined);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconst runError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\trun.publication.reject(runError);\n\t\t\t\t// A native constructor can fail before publication, but still owns a real child.\n\t\t\t\tif (!childSession && admission.session) {\n\t\t\t\t\tchildSession = admission.session;\n\t\t\t\t\trun.session = childSession;\n\t\t\t\t}\n\t\t\t\tif (run.status !== \"cancelled\") {\n\t\t\t\t\trun.status = \"error\";\n\t\t\t\t\trun.error = runError.message;\n\t\t\t\t}\n\t\t\t\t// A failed child still returns an error outcome the parent consumes;\n\t\t\t\t// cancelled runs and zero-commit children return nothing.\n\t\t\t\tconst failedChild = childSession ?? childRuntime?.session;\n\t\t\t\tconst failedLastCommitted = failedChild?.semanticEdges.lastCommittedRequestId;\n\t\t\t\tif (run.status === \"error\" && failedChild && failedLastCommitted !== undefined) {\n\t\t\t\t\tthis._semanticEdges.recordChildReturned(failedChild.sessionId, failedLastCommitted);\n\t\t\t\t}\n\t\t\t\trun.durationMs = Date.now() - startedAt;\n\t\t\t\trun.activity = undefined;\n\t\t\t\tif (run.status === \"error\" && childSession === undefined) {\n\t\t\t\t\t// A pre-bind failure leaves no row: \"cancelled\" is the wire's removal signal.\n\t\t\t\t\tthis._emit({\n\t\t\t\t\t\ttype: \"rlm_child_update\",\n\t\t\t\t\t\tchild: { ...this._rlmChildSnapshotForRun(run), status: \"cancelled\" },\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\temitChildUpdate();\n\t\t\t\t}\n\t\t\t\tif (!run.detachedDeletion && !run.suppressTerminalNotice) {\n\t\t\t\t\tif (run.status === \"error\") {\n\t\t\t\t\t\tawait deliverTerminalMessageToParent(\n\t\t\t\t\t\t\tcreateRlmChildFailureMessage({\n\t\t\t\t\t\t\t\tchildId: run.id,\n\t\t\t\t\t\t\t\tsessionName,\n\t\t\t\t\t\t\t\terror: run.error ?? \"unknown error\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (run.status === \"cancelled\") {\n\t\t\t\t\t\tawait deliverTerminalMessageToParent(\n\t\t\t\t\t\t\tcreateRlmChildTerminalNoticeMessage({\n\t\t\t\t\t\t\t\tkind: \"cancelled\",\n\t\t\t\t\t\t\t\tchildId: run.id,\n\t\t\t\t\t\t\t\tsessionName,\n\t\t\t\t\t\t\t\treason: run.error,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!run.detachedDeletion && childSession && this._subagentRuntimeHost?.releaseRlmSubagentRuntime) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this._subagentRuntimeHost.releaseRlmSubagentRuntime(\n\t\t\t\t\t\t\tchildRuntime ?? { session: childSession },\n\t\t\t\t\t\t\tsubagentOptions,\n\t\t\t\t\t\t\trun.status === \"cancelled\" ? \"cancelled\" : \"error\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (run.status === \"cancelled\" && !this._disposed && !this._disposing) {\n\t\t\t\t\t\t\tthis._deletedRlmChildIds.add(run.id);\n\t\t\t\t\t\t\tthis._removeRlmSubagentTracking(run.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tawait childSession?.disposeAsync().catch(() => undefined);\n\t\t\t\t\t}\n\t\t\t\t} else if (!run.detachedDeletion) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (childRuntime && this._subagentRuntimeHost) {\n\t\t\t\t\t\t\tawait this._subagentRuntimeHost.deleteRlmSubagentRuntime(run.id, childRuntime.session);\n\t\t\t\t\t\t} else if (childSession) {\n\t\t\t\t\t\t\tawait childSession.disposeAsync();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (run.status === \"cancelled\" && !this._disposed && !this._disposing) {\n\t\t\t\t\t\t\tthis._deletedRlmChildIds.add(run.id);\n\t\t\t\t\t\t\tthis._removeRlmSubagentTracking(run.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// A failed best-effort retry remains available through the retained cleanup maps.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tawait usageSettlement.catch((error) => this._surfaceSessionInputError(error));\n\t\t\t\tif (run.detachedDeletion) {\n\t\t\t\t\trun.deletionRunFinished = true;\n\t\t\t\t\tif (!run.settled) {\n\t\t\t\t\t\tlet cleanupSucceeded = !run.deletionCleanupFailed;\n\t\t\t\t\t\tif (childRuntime && cleanupSucceeded) {\n\t\t\t\t\t\t\tconst cleanup =\n\t\t\t\t\t\t\t\trun.deletionCleanup ?? this._ensureRlmRunDeletionCleanup(run, childRuntime.session);\n\t\t\t\t\t\t\tcleanupSucceeded = await this._observeRlmRunDeletionCleanup(\n\t\t\t\t\t\t\t\trun,\n\t\t\t\t\t\t\t\trun.detachedDeletion,\n\t\t\t\t\t\t\t\tchildRuntime.session,\n\t\t\t\t\t\t\t\tcleanup,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (cleanupSucceeded) await this._finishRlmRunDeletion(run);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (this._activeRlmChildRuns.get(run.id) === run) {\n\t\t\t\t\t\tif (this._rlmChildSessions.has(run.id)) {\n\t\t\t\t\t\t\tthis._activeRlmChildRuns.delete(run.id);\n\t\t\t\t\t\t\tif (run.unsubscribe) this._rlmChildUnsubscribes.set(run.id, run.unsubscribe);\n\t\t\t\t\t\t\trun.abort = noopRlmChildAbort;\n\t\t\t\t\t\t\trun.unsubscribe = undefined;\n\t\t\t\t\t\t\trun.session = undefined;\n\t\t\t\t\t\t} else if (run.status !== \"error\") {\n\t\t\t\t\t\t\tthis._removeRlmSubagentTracking(run.id, run);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\trun.unsubscribe?.();\n\t\t\t\t\t\t\trun.abort = noopRlmChildAbort;\n\t\t\t\t\t\t\trun.unsubscribe = undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\trun.settled = true;\n\t\t\t\t\trun.settlement.resolve();\n\t\t\t\t\tthis._unsettledRlmChildRuns.delete(run);\n\t\t\t\t\tthis._scheduleGoalContinuationAfterRlmWork();\n\t\t\t\t}\n\t\t\t}\n\t\t})();\n\t\tthis._rlmRunTasks.add(task);\n\t\tvoid task.then(\n\t\t\t() => this._rlmRunTasks.delete(task),\n\t\t\t(error) => {\n\t\t\t\tthis._rlmRunTasks.delete(task);\n\t\t\t\tthis._surfaceSessionInputError(error);\n\t\t\t},\n\t\t);\n\n\t\treturn {\n\t\t\trlm_child_id: childNodeId,\n\t\t\tname: sessionName,\n\t\t\tsession_dir: childSessionDir,\n\t\t\tmodel: `${modelSelection.model.provider}/${modelSelection.model.id}`,\n\t\t};\n\t}\n\n\tasync runRlmChild(\n\t\tprompt: string,\n\t\tkwargs: Record<string, unknown> = {},\n\t\tspawnCode?: string,\n\t): Promise<RlmSpawnHandle> {\n\t\tconst admission = await this.reserveRlmChildAdmission();\n\t\tconst start = this._startRlmChildRun(prompt, admission, kwargs, spawnCode);\n\t\t// Join pre-runtime name/model work during disposal as well as the detached task.\n\t\tconst pending = start.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\tthis._rlmRunTasks.add(pending);\n\t\ttry {\n\t\t\treturn await start;\n\t\t} catch (error) {\n\t\t\tawait admission.settle();\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis._rlmRunTasks.delete(pending);\n\t\t}\n\t}\n\n\tprivate _isRetryableError(message: AssistantMessage): boolean {\n\t\treturn isTransientProviderFailure(message) && !isContextOverflow(message, this.model?.contextWindow ?? 0);\n\t}\n\n\tprivate _getProviderStreamFailureDetails(message: AssistantMessage): Record<string, unknown> | undefined {\n\t\tconst failure = message.diagnostics?.find((diagnostic) => diagnostic.type === \"provider_stream_failure\");\n\t\tconst details = failure?.details;\n\t\tif (!details || typeof details !== \"object\") {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn details;\n\t}\n\n\tprivate _getProviderStreamFailureAuthStatus(message: AssistantMessage): number | undefined {\n\t\tconst details = this._getProviderStreamFailureDetails(message);\n\t\tif (!details) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst kind = details.kind;\n\t\tif (kind !== \"auth\") {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst status = details.status;\n\t\tif (typeof status === \"number\") {\n\t\t\treturn status;\n\t\t}\n\t\tif (typeof status === \"string\") {\n\t\t\tconst parsed = Number(status);\n\t\t\treturn Number.isInteger(parsed) ? parsed : undefined;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _isConcreteProviderAuthFailure(message: AssistantMessage): boolean {\n\t\tif (message.stopReason !== \"error\" || !message.errorMessage) return false;\n\n\t\tconst structuredStatus = this._getProviderStreamFailureAuthStatus(message);\n\t\tif (structuredStatus === 401 || structuredStatus === 403) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (/\\b(?:401|403)\\b/.test(message.errorMessage) && /\\bstatus code\\b/i.test(message.errorMessage)) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn (\n\t\t\t/\\b(?:401|403)\\b/.test(message.errorMessage) &&\n\t\t\t/auth|unauthori[sz]ed|forbidden|api.?key|token|credential/i.test(message.errorMessage)\n\t\t);\n\t}\n\n\tprivate _markProviderAuthStale(source: AuthSourceToken): void {\n\t\tif (this._modelRegistry.markProviderAuthSourceStale(source)) {\n\t\t\tthis._emit({ type: \"auth_stale\", provider: source.provider, sourceTokens: [source] });\n\t\t}\n\t}\n\n\tprivate _finishActiveRetryWithFailure(message: AssistantMessage): void {\n\t\tif (this._retryAttempt === 0) {\n\t\t\treturn;\n\t\t}\n\t\tthis._emit({\n\t\t\ttype: \"auto_retry_end\",\n\t\t\tsuccess: false,\n\t\t\tattempt: this._retryAttempt,\n\t\t\tfinalError: message.errorMessage,\n\t\t});\n\t\tthis._retryAttempt = 0;\n\t}\n\n\tprivate async _handleRetryableError(message: AssistantMessage, signal?: AbortSignal): Promise<boolean> {\n\t\tconst settings = this.settingsManager.getRetrySettings();\n\t\tif (!settings.enabled || signal?.aborted || !this._isRetryableError(message)) return false;\n\n\t\t// Join native message persistence before omitting its acknowledged assistant ID.\n\t\tawait this._waitForAgentEventsBeforeContext();\n\t\tif (signal?.aborted) return false;\n\t\tthis._removeLastAssistantFromContext();\n\t\tif (!this._retryPromise) {\n\t\t\tthis._retryPromise = new Promise((resolve) => {\n\t\t\t\tthis._retryResolve = resolve;\n\t\t\t});\n\t\t}\n\t\tthis._retryAttempt++;\n\t\tconst delayMs = Math.min(\n\t\t\tthis.settingsManager.getProviderRetrySettings().maxRetryDelayMs || 60_000,\n\t\t\tsettings.baseDelayMs * 2 ** Math.min(this._retryAttempt - 1, 32),\n\t\t);\n\t\t// Payload hooks forfeit reuse. Otherwise retain the failed operation's existing identity.\n\t\tif (!this._extensionRunner.hasHandlers(\"before_provider_request\")) {\n\t\t\tthis._semanticEdges.prepareTurnRetry();\n\t\t\tthis.requests.prepareTurnRetry();\n\t\t}\n\t\tconst controller = new AbortController();\n\t\tthis._retryAbortController = controller;\n\t\tconst retrySignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;\n\t\tthis._emit({\n\t\t\ttype: \"auto_retry_start\",\n\t\t\tattempt: this._retryAttempt,\n\t\t\tdelayMs,\n\t\t\terrorMessage: message.errorMessage || \"Provider request failed\",\n\t\t});\n\t\ttry {\n\t\t\tawait sleep(delayMs, retrySignal);\n\t\t} catch (error) {\n\t\t\tif (!retrySignal.aborted) throw error;\n\t\t\treturn false;\n\t\t} finally {\n\t\t\tthis._retryAbortController = undefined;\n\t\t}\n\t\treturn this.settingsManager.getRetryEnabled() && !retrySignal.aborted;\n\t}\n\n\tabortRetry(): void {\n\t\tif (this._retryPromise) this.agent.abort();\n\t\tif (this._retryAbortController) {\n\t\t\tthis._retryAbortController.abort();\n\t\t\treturn;\n\t\t}\n\t\tif (this._retryAttempt > 0) {\n\t\t\tthis._autoCompactionAbortController?.abort();\n\t\t\tthis._cancelPostCompactionContinue();\n\t\t\tthis._emit({\n\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\tsuccess: false,\n\t\t\t\tattempt: this._retryAttempt,\n\t\t\t\tfinalError: \"Retry cancelled\",\n\t\t\t});\n\t\t\tthis._retryAttempt = 0;\n\t\t}\n\t\tthis._resolveRetry();\n\t}\n\n\tprivate async waitForRetry(): Promise<void> {\n\t\tif (!this._retryPromise) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait this._retryPromise;\n\t\tawait this.agent.waitForIdle();\n\t}\n\n\tget isRetrying(): boolean {\n\t\treturn this._retryPromise !== undefined;\n\t}\n\n\tget hasAcceptedPromptInFlight(): boolean {\n\t\treturn this._actionStore\n\t\t\t.unfinishedActions()\n\t\t\t.some(\n\t\t\t\t(action) =>\n\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\t!action.payload.queueVisible &&\n\t\t\t\t\taction.payload.acceptedBeforeCompletion,\n\t\t\t);\n\t}\n\n\tget autoRetryEnabled(): boolean {\n\t\treturn this.settingsManager.getRetryEnabled();\n\t}\n\n\tsetAutoRetryEnabled(enabled: boolean): void {\n\t\tthis.settingsManager.setRetryEnabled(enabled);\n\t}\n\n\t/**\n\t * Execute a bash command.\n\t * Adds result to agent context and session.\n\t * @param command The bash command to execute\n\t * @param onChunk Optional streaming callback for output\n\t * @param options.excludeFromContext If true, command output won't be sent to LLM (!! prefix)\n\t * @param options.operations Custom BashOperations for remote execution\n\t */\n\tasync executeBash(\n\t\tcommand: string,\n\t\tonChunk?: (chunk: string) => void,\n\t\toptions?: {\n\t\t\texcludeFromContext?: boolean;\n\t\t\toperations?: BashOperations;\n\t\t\ttransient?: boolean;\n\t\t},\n\t): Promise<BashResult> {\n\t\t// Each invocation owns its controller so abortBash reaches every in-flight command.\n\t\tconst abortController = new AbortController();\n\t\tthis._bashAbortControllers.add(abortController);\n\n\t\tconst prefix = this.settingsManager.getShellCommandPrefix();\n\t\tconst shellPath = this.settingsManager.getShellPath();\n\t\tconst resolvedCommand = prefix ? `${prefix}\\n${command}` : command;\n\n\t\ttry {\n\t\t\tconst result = await executeBashWithOperations(\n\t\t\t\tresolvedCommand,\n\t\t\t\tthis.sessionManager.getCwd(),\n\t\t\t\toptions?.operations ?? createLocalBashOperations({ shellPath }),\n\t\t\t\t{\n\t\t\t\t\tonChunk,\n\t\t\t\t\tsignal: abortController.signal,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!options?.transient) {\n\t\t\t\tawait this.recordBashResult(command, result, options);\n\t\t\t}\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tthis._bashAbortControllers.delete(abortController);\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t}\n\t}\n\n\t/**\n\t * Run a user-initiated bash command (! / !! prefix), emitting bash_start,\n\t * bash_output, and bash_end session events so any attached client can render\n\t * streaming output. Extensions can intercept execution via the user_bash event.\n\t * Execution failures are reported through bash_end rather than a rejected promise;\n\t * only the already-running guard and extension dispatch errors reject.\n\t * @param command The bash command to execute\n\t * @param options.excludeFromContext If true, command output won't be sent to LLM (!! prefix)\n\t */\n\tasync runUserBash(\n\t\tcommand: string,\n\t\toptions?: {\n\t\t\texcludeFromContext?: boolean;\n\t\t\ttransient?: boolean;\n\t\t\trunId?: string;\n\t\t},\n\t): Promise<void> {\n\t\tif (this.isBashRunning) {\n\t\t\tthrow new Error(\"A bash command is already running\");\n\t\t}\n\t\t// Claim the bash slot synchronously: isBashRunning is otherwise false until\n\t\t// executeBash installs its abort controller, which would let a second command\n\t\t// slip through during the user_bash extension dispatch below.\n\t\tthis._userBashRunning = true;\n\t\tthis._userBashAbortRequested = false;\n\t\t// Echoed on bash_start/bash_end so the requesting client can tell its own\n\t\t// run apart from other clients' runs broadcast on the same session.\n\t\tconst identity = {\n\t\t\t...(options?.transient ? { transient: true } : {}),\n\t\t\t...(options?.runId !== undefined ? { runId: options.runId } : {}),\n\t\t};\n\t\tlet end: UserBashEndDetails;\n\t\ttry {\n\t\t\tend = await this.runUserBashLocked(\n\t\t\t\tcommand,\n\t\t\t\toptions?.excludeFromContext ?? false,\n\t\t\t\toptions?.transient ?? false,\n\t\t\t\tidentity,\n\t\t\t);\n\t\t} finally {\n\t\t\tthis._userBashRunning = false;\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t}\n\t\t// Emitted after the slot is released so clients never observe a bash_end\n\t\t// while the session still rejects new commands as already running.\n\t\tthis._emit({ type: \"bash_end\", ...end, ...identity });\n\t\tvoid this._drainQueuedMessagesAfterBash().catch(() => undefined);\n\t}\n\n\tprivate async _drainQueuedMessagesAfterBash(): Promise<void> {\n\t\tawait this.agent.waitForIdle();\n\t\tthis._scheduleSessionInputPump();\n\t}\n\n\tprivate async runUserBashLocked(\n\t\tcommand: string,\n\t\texcludeFromContext: boolean,\n\t\ttransient: boolean,\n\t\tidentity: { transient?: boolean; runId?: string },\n\t): Promise<UserBashEndDetails> {\n\t\tconst eventResult = await this._extensionRunner.emitUserBash({\n\t\t\ttype: \"user_bash\",\n\t\t\tcommand,\n\t\t\texcludeFromContext,\n\t\t\tcwd: this.sessionManager.getCwd(),\n\t\t});\n\n\t\t// Transient runs (side-conversation bash) live only in their pane: they\n\t\t// are never recorded, so reloads and rebuilds cannot resurface them.\n\t\tconst record = transient\n\t\t\t? () => {}\n\t\t\t: (result: BashResult) => this.recordBashResult(command, result, { excludeFromContext });\n\n\t\tthis._emit({\n\t\t\ttype: \"bash_start\",\n\t\t\tcommand,\n\t\t\texcludeFromContext,\n\t\t\t...identity,\n\t\t});\n\t\ttry {\n\t\t\t// If an extension returned a full result, surface it without executing\n\t\t\tif (eventResult?.result) {\n\t\t\t\tconst result = eventResult.result;\n\t\t\t\tif (result.output) {\n\t\t\t\t\tthis._emit({ type: \"bash_output\", chunk: result.output });\n\t\t\t\t}\n\t\t\t\tawait record(result);\n\t\t\t\treturn {\n\t\t\t\t\texitCode: result.exitCode,\n\t\t\t\t\tcancelled: result.cancelled,\n\t\t\t\t\ttruncated: result.truncated,\n\t\t\t\t\tfullOutputPath: result.fullOutputPath,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// An abort that arrived before the process spawned (during extension\n\t\t\t// dispatch) has no abort controller to act on; honor it here instead.\n\t\t\tif (this._userBashAbortRequested) {\n\t\t\t\tawait record({\n\t\t\t\t\toutput: \"\",\n\t\t\t\t\texitCode: undefined,\n\t\t\t\t\tcancelled: true,\n\t\t\t\t\ttruncated: false,\n\t\t\t\t});\n\t\t\t\treturn { exitCode: undefined, cancelled: true, truncated: false };\n\t\t\t}\n\n\t\t\tconst result = await this.executeBash(command, (chunk) => this._emit({ type: \"bash_output\", chunk }), {\n\t\t\t\texcludeFromContext,\n\t\t\t\toperations: eventResult?.operations,\n\t\t\t\ttransient,\n\t\t\t});\n\t\t\treturn {\n\t\t\t\texitCode: result.exitCode,\n\t\t\t\tcancelled: result.cancelled,\n\t\t\t\ttruncated: result.truncated,\n\t\t\t\tfullOutputPath: result.fullOutputPath,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\t// Persist the failure like every other outcome so replayed transcripts\n\t\t\t// and the LLM context reflect that the command did not run.\n\t\t\tawait record({\n\t\t\t\toutput: `bash failed: ${errorMessage}`,\n\t\t\t\texitCode: undefined,\n\t\t\t\tcancelled: false,\n\t\t\t\ttruncated: false,\n\t\t\t});\n\t\t\treturn {\n\t\t\t\texitCode: undefined,\n\t\t\t\tcancelled: false,\n\t\t\t\ttruncated: false,\n\t\t\t\terrorMessage,\n\t\t\t};\n\t\t}\n\t}\n\n\tasync recordBashResult(\n\t\tcommand: string,\n\t\tresult: BashResult,\n\t\toptions?: { excludeFromContext?: boolean },\n\t): Promise<void> {\n\t\tconst bashMessage: BashExecutionMessage = {\n\t\t\trole: \"bashExecution\",\n\t\t\tcommand,\n\t\t\toutput: result.output,\n\t\t\texitCode: result.exitCode,\n\t\t\tcancelled: result.cancelled,\n\t\t\ttruncated: result.truncated,\n\t\t\tfullOutputPath: result.fullOutputPath,\n\t\t\ttimestamp: Date.now(),\n\t\t\texcludeFromContext: options?.excludeFromContext,\n\t\t};\n\n\t\t// If agent is streaming, defer adding to avoid breaking tool_use/tool_result ordering\n\t\tif (this.isStreaming) {\n\t\t\tthis._pendingBashMessages.push(bashMessage);\n\t\t} else {\n\t\t\tawait this.sessionManager.appendMessage(bashMessage);\n\t\t\tthis.agent.state.messages.push(bashMessage);\n\t\t}\n\t}\n\n\t/**\n\t * Cancel running bash command.\n\t */\n\tabortBash(): void {\n\t\t// A user bash command may not have spawned yet (extension dispatch in\n\t\t// progress); flag the request so runUserBash cancels before executing.\n\t\t// runUserBash clears the flag at each start, so a stale flag is harmless.\n\t\tif (this._userBashRunning) {\n\t\t\tthis._userBashAbortRequested = true;\n\t\t}\n\t\tfor (const controller of this._bashAbortControllers) {\n\t\t\tcontroller.abort();\n\t\t}\n\t}\n\n\tget isBashRunning(): boolean {\n\t\treturn this._bashAbortControllers.size > 0 || this._userBashRunning;\n\t}\n\n\t/** Whether there are pending bash messages waiting to be flushed */\n\tget hasPendingBashMessages(): boolean {\n\t\treturn this._pendingBashMessages.length > 0;\n\t}\n\n\t/**\n\t * Flush pending bash messages to agent state and session.\n\t * Called after agent turn completes to maintain proper message ordering.\n\t */\n\tprivate async _flushPendingBashMessages(): Promise<void> {\n\t\tif (this._pendingBashMessages.length === 0) return;\n\n\t\twhile (this._pendingBashMessages.length > 0) {\n\t\t\tconst bashMessage = this._pendingBashMessages[0]!;\n\t\t\tawait this.sessionManager.appendMessage(bashMessage);\n\t\t\tthis._pendingBashMessages.shift();\n\t\t\tthis.agent.state.messages.push(bashMessage);\n\t\t}\n\t}\n\n\tgetRlmMaxSubagentsStatus(): Promise<RlmMaxSubagentsStatus> {\n\t\treturn this._rlmSubagentCapacity.getStatus();\n\t}\n\n\tsetRlmMaxSubagents(maxSubagents: number): Promise<RlmMaxSubagentsStatus> {\n\t\treturn this._rlmSubagentCapacity.setMaxSubagents(maxSubagents);\n\t}\n\n\tgetRlmMaxDepthStatus(): RlmMaxDepthStatus {\n\t\treturn { maxDepth: this._rlmMaxDepth, source: this._rlmMaxDepthSource };\n\t}\n\n\tasync setRlmMaxDepth(maxDepth: number, options: { global?: boolean } = {}): Promise<SetRlmMaxDepthResult> {\n\t\tif (!isNonNegativeInteger(maxDepth)) {\n\t\t\tthrow new Error(\"RLM max depth must be a non-negative integer.\");\n\t\t}\n\n\t\tawait this.sessionManager.appendCustomEntryWithRollback(RLM_MAX_DEPTH_STATE_CUSTOM_TYPE, { maxDepth });\n\t\tthis._rlmMaxDepth = maxDepth;\n\t\tthis._rlmMaxDepthSource = \"chat\";\n\t\tconst oldBase = this._baseSystemPrompt;\n\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\tthis.agent.state.systemPrompt = this._refreshExtensionSystemPrompt(this.agent.state.systemPrompt, oldBase);\n\n\t\tlet globalError: string | undefined;\n\t\tif (options.global) {\n\t\t\tawait this.settingsManager.flush();\n\t\t\tconst staleErrors = this.settingsManager.drainErrors(\"global\");\n\t\t\tfor (const { error } of staleErrors) {\n\t\t\t\tconsole.warn(`Warning: Earlier global settings write failed: ${error.message}`);\n\t\t\t}\n\t\t\tthis.settingsManager.setRlmMaxDepth(maxDepth);\n\t\t\tawait this.settingsManager.flush();\n\t\t\tconst errors = this.settingsManager.drainErrors(\"global\");\n\t\t\tglobalError = errors.map(({ error }) => error.message).join(\"; \") || undefined;\n\t\t}\n\n\t\treturn {\n\t\t\t...this.getRlmMaxDepthStatus(),\n\t\t\tglobalSaved: options.global === true && globalError === undefined,\n\t\t\t...(globalError ? { globalError } : {}),\n\t\t};\n\t}\n\n\tasync setSessionName(name: string): Promise<void> {\n\t\tawait this.sessionManager.appendSessionInfo(name);\n\t\tthis._emit({\n\t\t\ttype: \"session_info_changed\",\n\t\t\tname: this.sessionManager.getSessionName(),\n\t\t});\n\t}\n\n\t/**\n\t * Navigate to a different node in the session tree.\n\t * Unlike fork() which creates a new session file, this stays in the same file.\n\t *\n\t * @param targetId The entry ID to navigate to\n\t * @param options.summarize Whether user wants to summarize abandoned branch\n\t * @param options.customInstructions Custom instructions for summarizer\n\t * @param options.replaceInstructions If true, customInstructions replaces the default prompt\n\t * @param options.label Label to attach to the branch summary entry\n\t * @returns Result with editorText (if user message) and cancelled status\n\t */\n\tprivate _branchNavigationQueue: Promise<void> = Promise.resolve();\n\n\tasync navigateTree(\n\t\ttargetId: string,\n\t\toptions: {\n\t\t\tsummarize?: boolean;\n\t\t\tcustomInstructions?: string;\n\t\t\treplaceInstructions?: boolean;\n\t\t\tlabel?: string;\n\t\t} = {},\n\t): Promise<{\n\t\teditorText?: string;\n\t\tcancelled: boolean;\n\t\taborted?: boolean;\n\t\tsummaryEntry?: BranchSummaryEntry;\n\t}> {\n\t\toptions = { ...options };\n\t\tconst previous = this._branchNavigationQueue;\n\t\tlet release = () => {};\n\t\tthis._branchNavigationQueue = new Promise<void>((resolve) => {\n\t\t\trelease = resolve;\n\t\t});\n\t\tawait previous;\n\t\ttry {\n\t\t\treturn await this._navigateTree(targetId, options);\n\t\t} finally {\n\t\t\trelease();\n\t\t}\n\t}\n\n\tprivate _resolveBranchSummaryModel(): { model: Model<Api>; thinkingLevel: ThinkingLevel } | undefined {\n\t\tconst selection = this.settingsManager.getBranchSummaryModel();\n\t\tif (selection === undefined) return undefined;\n\t\tif (\n\t\t\t!selection ||\n\t\t\ttypeof selection !== \"object\" ||\n\t\t\tArray.isArray(selection) ||\n\t\t\ttypeof selection.provider !== \"string\" ||\n\t\t\t!selection.provider.trim() ||\n\t\t\ttypeof selection.modelId !== \"string\" ||\n\t\t\t!selection.modelId.trim() ||\n\t\t\ttypeof selection.thinkingLevel !== \"string\"\n\t\t)\n\t\t\tthrow new Error(\"Invalid branchSummary.model; expected provider, modelId, and thinkingLevel\");\n\t\tconst model = this._modelRegistry.find(selection.provider, selection.modelId);\n\t\tif (!model) throw new Error(`Unknown branchSummary.model ${selection.provider}/${selection.modelId}`);\n\t\tif (!getSupportedThinkingLevels(model).includes(selection.thinkingLevel))\n\t\t\tthrow new Error(\n\t\t\t\t`branchSummary.model thinkingLevel ${selection.thinkingLevel} is not supported by ${selection.provider}/${selection.modelId}`,\n\t\t\t);\n\t\treturn { model: structuredClone(model), thinkingLevel: selection.thinkingLevel };\n\t}\n\n\tprivate async _navigateTree(\n\t\ttargetId: string,\n\t\toptions: {\n\t\t\tsummarize?: boolean;\n\t\t\tcustomInstructions?: string;\n\t\t\treplaceInstructions?: boolean;\n\t\t\tlabel?: string;\n\t\t} = {},\n\t): Promise<{\n\t\teditorText?: string;\n\t\tcancelled: boolean;\n\t\taborted?: boolean;\n\t\tsummaryEntry?: BranchSummaryEntry;\n\t}> {\n\t\tconst summarySelection = options.summarize ? this._resolveBranchSummaryModel() : undefined;\n\t\tif (options.summarize && !summarySelection && !this.model) {\n\t\t\tthrow new Error(\"No model available for summarization\");\n\t\t}\n\n\t\toptions = { ...options };\n\t\tconst queuedWorkPause = this.acquireQueuedWorkPause();\n\t\tlet commitFence: { owner: symbol; release(): void } | undefined;\n\t\ttry {\n\t\t\tconst targetSource = { sessionId: this.sessionId, sessionFile: this.sessionFile };\n\t\t\tconst targetEntry = await this.sessionManager.readEntry(targetId);\n\t\t\tif (targetSource.sessionId !== this.sessionId || targetSource.sessionFile !== this.sessionFile)\n\t\t\t\tthrow new Error(\"Session source changed during branch navigation\");\n\t\t\tif (this._disposing || this._disposed) throw new Error(\"Cannot navigate a disposing or disposed session.\");\n\t\t\tif (!targetEntry) throw new Error(`Entry ${targetId} not found`);\n\t\t\t// Branch navigation and turn dispatch mutate the same transcript leaf.\n\t\t\tcommitFence = await this._acquireSessionActionCommitFence();\n\t\t\treturn await this._sessionActionCommitContext.run(commitFence.owner, async () => {\n\t\t\t\tawait this.agent.waitForIdle();\n\t\t\t\tawait this._agentEventQueue;\n\t\t\t\tif (targetSource.sessionId !== this.sessionId || targetSource.sessionFile !== this.sessionFile)\n\t\t\t\t\tthrow new Error(\"Session source changed during branch navigation\");\n\t\t\t\treturn this._navigateTreeUnderPause(targetId, targetEntry, options, summarySelection);\n\t\t\t});\n\t\t} finally {\n\t\t\tqueuedWorkPause.release();\n\t\t\tcommitFence?.release();\n\t\t}\n\t}\n\n\tprivate async _navigateTreeUnderPause(\n\t\ttargetId: string,\n\t\ttargetEntry: NonNullable<Awaited<ReturnType<SessionManager[\"readEntry\"]>>>,\n\t\toptions: {\n\t\t\tsummarize?: boolean;\n\t\t\tcustomInstructions?: string;\n\t\t\treplaceInstructions?: boolean;\n\t\t\tlabel?: string;\n\t\t},\n\t\tsummarySelection: { model: Model<Api>; thinkingLevel: ThinkingLevel } | undefined,\n\t): Promise<{\n\t\teditorText?: string;\n\t\tcancelled: boolean;\n\t\taborted?: boolean;\n\t\tsummaryEntry?: BranchSummaryEntry;\n\t}> {\n\t\tconst oldLeafId = this.sessionManager.getLeafId();\n\n\t\t// No-op if already at target after admitted work has settled.\n\t\tif (targetId === oldLeafId) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\t// Do not switch branches while /refine has detached event handling and is\n\t\t// about to persist harness/session entries for the current branch.\n\t\tawait this._invalidatePendingAutoRefineForBranchChange();\n\t\tif (this._disposing || this._disposed) throw new Error(\"Cannot navigate a disposing or disposed session.\");\n\n\t\tthis._branchSummaryAbortController = new AbortController();\n\t\tlet resolveBranchSummaryOperation: () => void = () => {};\n\t\tconst branchSummaryOperation = new Promise<void>((resolve) => {\n\t\t\tresolveBranchSummaryOperation = resolve;\n\t\t});\n\t\tthis._branchSummaryOperation = branchSummaryOperation;\n\n\t\ttry {\n\t\t\tconst initialSource = { sessionId: this.sessionId, sessionFile: this.sessionFile };\n\t\t\tconst captured = await this.sessionManager.readBranches([oldLeafId, targetId]);\n\t\t\tconst source = captured.source ?? initialSource;\n\t\t\tconst assertSource = () => {\n\t\t\t\tif (source.sessionId !== this.sessionId || source.sessionFile !== this.sessionFile)\n\t\t\t\t\tthrow new Error(\"Session source changed during branch navigation\");\n\t\t\t};\n\t\t\tassertSource();\n\t\t\tif (this._branchSummaryAbortController.signal.aborted) return { cancelled: true, aborted: true };\n\t\t\tconst [oldPath, targetPath] = captured.branches;\n\t\t\tif (!oldPath || !targetPath) throw new Error(\"Captured navigation paths are unavailable\");\n\t\t\tconst { entries: entriesToSummarize, commonAncestorId } = collectEntriesForBranchSummary(oldPath, targetPath);\n\n\t\t\tlet customInstructions = options.customInstructions;\n\t\t\tlet replaceInstructions = options.replaceInstructions;\n\t\t\tlet label = options.label;\n\n\t\t\tconst preparation: TreePreparation = {\n\t\t\t\ttargetId,\n\t\t\t\toldLeafId,\n\t\t\t\tcommonAncestorId,\n\t\t\t\tentriesToSummarize,\n\t\t\t\tuserWantsSummary: options.summarize ?? false,\n\t\t\t\tcustomInstructions,\n\t\t\t\treplaceInstructions,\n\t\t\t\tlabel,\n\t\t\t};\n\n\t\t\tlet extensionSummary: { summary: string; details?: unknown } | undefined;\n\t\t\tlet fromExtension = false;\n\n\t\t\tif (this._extensionRunner.hasHandlers(\"session_before_tree\")) {\n\t\t\t\tconst result = (await this._extensionRunner.emit({\n\t\t\t\t\ttype: \"session_before_tree\",\n\t\t\t\t\tpreparation,\n\t\t\t\t\tsignal: this._branchSummaryAbortController.signal,\n\t\t\t\t})) as SessionBeforeTreeResult | undefined;\n\n\t\t\t\tif (result?.cancel) {\n\t\t\t\t\treturn { cancelled: true };\n\t\t\t\t}\n\n\t\t\t\tif (result?.summary && options.summarize) {\n\t\t\t\t\textensionSummary = result.summary;\n\t\t\t\t\tfromExtension = true;\n\t\t\t\t}\n\n\t\t\t\tif (result?.customInstructions !== undefined) {\n\t\t\t\t\tcustomInstructions = result.customInstructions;\n\t\t\t\t}\n\t\t\t\tif (result?.replaceInstructions !== undefined) {\n\t\t\t\t\treplaceInstructions = result.replaceInstructions;\n\t\t\t\t}\n\t\t\t\tif (result?.label !== undefined) {\n\t\t\t\t\tlabel = result.label;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tassertSource();\n\t\t\tlet summaryText: string | undefined;\n\t\t\tlet nativeBranchSummary: BranchSummaryResult | undefined;\n\t\t\tlet summaryDetails: unknown;\n\t\t\tlet summaryUsage: Usage | undefined;\n\t\t\tif (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {\n\t\t\t\tconst selectedModel = summarySelection?.model ?? this.model!;\n\t\t\t\tconst model = { ...selectedModel, cost: { ...selectedModel.cost } };\n\t\t\t\tconst branchSummarySettings = { ...this.settingsManager.getBranchSummarySettings() };\n\t\t\t\tconst summaryEntries = structuredClone(entriesToSummarize);\n\t\t\t\tconst summaryManager = this.sessionManager;\n\t\t\t\tconst requests = this.requests[captureNativeBranchRequests](summaryManager.bindRequestSink());\n\t\t\t\ttry {\n\t\t\t\t\tconst { apiKey, headers } = await this._getRequiredRequestAuth(model);\n\t\t\t\t\tconst result = await generateBranchSummary(summaryEntries, {\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t...(summarySelection === undefined ? {} : { thinkingLevel: summarySelection.thinkingLevel }),\n\t\t\t\t\t\tapiKey,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tsignal: this._branchSummaryAbortController.signal,\n\t\t\t\t\t\tcustomInstructions,\n\t\t\t\t\t\treplaceInstructions,\n\t\t\t\t\t\treserveTokens: branchSummarySettings.reserveTokens,\n\t\t\t\t\t\trequests,\n\t\t\t\t\t});\n\t\t\t\t\tif (result.aborted) {\n\t\t\t\t\t\treturn { cancelled: true, aborted: true };\n\t\t\t\t\t}\n\t\t\t\t\tif (result.error) {\n\t\t\t\t\t\tthrow new Error(result.error);\n\t\t\t\t\t}\n\t\t\t\t\tnativeBranchSummary = result;\n\t\t\t\t\tsummaryText = result.summary;\n\t\t\t\t\tsummaryUsage = result.usage;\n\t\t\t\t\tsummaryDetails = {\n\t\t\t\t\t\treadFiles: result.readFiles || [],\n\t\t\t\t\t\tmodifiedFiles: result.modifiedFiles || [],\n\t\t\t\t\t};\n\t\t\t\t} finally {\n\t\t\t\t\tawait requests.dispose();\n\t\t\t\t}\n\t\t\t} else if (extensionSummary) {\n\t\t\t\tsummaryText = extensionSummary.summary;\n\t\t\t\tsummaryDetails = extensionSummary.details;\n\t\t\t}\n\n\t\t\tlet newLeafId: string | null;\n\t\t\tlet editorText: string | undefined;\n\n\t\t\tif (targetEntry.type === \"message\" && targetEntry.message.role === \"user\") {\n\t\t\t\tnewLeafId = targetEntry.parentId;\n\t\t\t\teditorText = this._extractUserMessageText(targetEntry.message.content);\n\t\t\t} else if (targetEntry.type === \"custom_message\") {\n\t\t\t\tnewLeafId = targetEntry.parentId;\n\t\t\t\teditorText =\n\t\t\t\t\ttypeof targetEntry.content === \"string\"\n\t\t\t\t\t\t? targetEntry.content\n\t\t\t\t\t\t: targetEntry.content\n\t\t\t\t\t\t\t\t.filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n\t\t\t\t\t\t\t\t.map((c) => c.text)\n\t\t\t\t\t\t\t\t.join(\"\");\n\t\t\t} else {\n\t\t\t\tnewLeafId = targetId;\n\t\t\t}\n\n\t\t\tawait this.sessionManager.flushNow();\n\t\t\tassertSource();\n\t\t\tlet summaryEntry: BranchSummaryEntry | undefined;\n\t\t\tif (summaryText) {\n\t\t\t\tconst manager = this.sessionManager;\n\t\t\t\tconst write = !fromExtension ? takeNativeBranchSummaryWrite(nativeBranchSummary, summaryText) : undefined;\n\t\t\t\tconst pending = write?.(manager, newLeafId, summaryText, summaryDetails, summaryUsage);\n\t\t\t\tconst summaryId =\n\t\t\t\t\t(pending ? await pending : undefined) ??\n\t\t\t\t\t(await manager.branchWithSummary(newLeafId, summaryText, summaryDetails, fromExtension, summaryUsage));\n\t\t\t\tsummaryEntry = (await this.sessionManager.readEntry(summaryId)) as BranchSummaryEntry;\n\n\t\t\t\tif (label) {\n\t\t\t\t\tawait this.sessionManager.appendLabelChange(summaryId, label);\n\t\t\t\t}\n\t\t\t} else if (newLeafId === null) {\n\t\t\t\tawait this.sessionManager.branchTo(null);\n\t\t\t} else {\n\t\t\t\tawait this.sessionManager.branchTo(newLeafId);\n\t\t\t}\n\n\t\t\tif (label && !summaryText) {\n\t\t\t\tawait this.sessionManager.appendLabelChange(targetId, label);\n\t\t\t}\n\n\t\t\tconst { context: sessionContext } = await readSessionBootstrap(\n\t\t\t\tthis.sessionManager,\n\t\t\t\tthis.settingsManager.getCanonicalContextLimits(),\n\t\t\t\t{ purpose: \"read\", initialContextMode: this._initialContextMode },\n\t\t\t);\n\t\t\tthis.agent.state.messages = sessionContext.messages;\n\t\t\tthis._contextOmissions = undefined;\n\t\t\tthis._mergeUnpersistedOutcomes(this.agent.state.messages);\n\t\t\tthis._restoreLateIpythonSentAgentMessages();\n\t\t\tawait this._reloadBranchRuntimeState();\n\t\t\tthis._invalidateQueuedPromptPreparation();\n\n\t\t\tawait this._extensionRunner.emit({\n\t\t\t\ttype: \"session_tree\",\n\t\t\t\tnewLeafId: this.sessionManager.getLeafId(),\n\t\t\t\toldLeafId,\n\t\t\t\tsummaryEntry,\n\t\t\t\tfromExtension: summaryText ? fromExtension : undefined,\n\t\t\t});\n\n\t\t\treturn { editorText, cancelled: false, summaryEntry };\n\t\t} finally {\n\t\t\tthis._branchSummaryAbortController = undefined;\n\t\t\tif (this._branchSummaryOperation === branchSummaryOperation) {\n\t\t\t\tthis._branchSummaryOperation = undefined;\n\t\t\t}\n\t\t\tresolveBranchSummaryOperation();\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t}\n\t}\n\n\tgetUserMessagesForForking(): Promise<Array<{ entryId: string; text: string }>> {\n\t\treturn readUserMessagesForForking(this.sessionManager);\n\t}\n\n\tprivate _extractUserMessageText(content: string | Array<{ type: string; text?: string }>): string {\n\t\tif (typeof content === \"string\") return content;\n\t\tif (Array.isArray(content)) {\n\t\t\treturn content\n\t\t\t\t.filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n\t\t\t\t.map((c) => c.text)\n\t\t\t\t.join(\"\");\n\t\t}\n\t\treturn \"\";\n\t}\n\n\tasync getSessionStats(): Promise<SessionStats> {\n\t\tconst state = this.state;\n\t\tconst userMessages = state.messages.filter((m) => m.role === \"user\").length;\n\t\tconst assistantMessages = state.messages.filter((m) => m.role === \"assistant\").length;\n\t\tconst toolResults = state.messages.filter((m) => m.role === \"toolResult\").length;\n\n\t\tlet toolCalls = 0;\n\t\tlet totalInput = 0;\n\t\tlet totalOutput = 0;\n\t\tlet totalCacheRead = 0;\n\t\tlet totalCacheWrite = 0;\n\t\tlet totalCost = 0;\n\n\t\tfor (const message of state.messages) {\n\t\t\tif (message.role === \"assistant\") {\n\t\t\t\tconst assistantMsg = message as AssistantMessage;\n\t\t\t\ttoolCalls += assistantMsg.content.filter((c) => c.type === \"toolCall\").length;\n\t\t\t\ttotalInput += assistantMsg.usage.input;\n\t\t\t\ttotalOutput += assistantMsg.usage.output;\n\t\t\t\ttotalCacheRead += assistantMsg.usage.cacheRead;\n\t\t\t\ttotalCacheWrite += assistantMsg.usage.cacheWrite;\n\t\t\t\ttotalCost += assistantMsg.usage.cost.total;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsessionFile: this.sessionFile,\n\t\t\tsessionId: this.sessionId,\n\t\t\tuserMessages,\n\t\t\tassistantMessages,\n\t\t\ttoolCalls,\n\t\t\ttoolResults,\n\t\t\ttotalMessages: state.messages.length,\n\t\t\ttokens: {\n\t\t\t\tinput: totalInput,\n\t\t\t\toutput: totalOutput,\n\t\t\t\tcacheRead: totalCacheRead,\n\t\t\t\tcacheWrite: totalCacheWrite,\n\t\t\t\ttotal: totalInput + totalOutput + totalCacheRead + totalCacheWrite,\n\t\t\t},\n\t\t\tcost: totalCost,\n\t\t\tcontextUsage: await this.getContextUsage(),\n\t\t};\n\t}\n\n\tasync getContextUsage(): Promise<ContextUsage | undefined> {\n\t\tconst model = this.model;\n\t\tif (!model) return undefined;\n\t\tconst contextWindow = model.contextWindow ?? 0;\n\t\tif (contextWindow <= 0) return undefined;\n\n\t\t// Capture the working-view estimate before the source read can yield.\n\t\tconst estimate = estimateContextTokens(this.messages);\n\t\tconst { maxSourceBytes } = this.settingsManager.getCanonicalContextLimits();\n\t\tif (!(await this._contextUsageReader.hasPostCompactionUsage(this.sessionManager, maxSourceBytes)))\n\t\t\treturn { tokens: null, contextWindow, percent: null };\n\t\treturn {\n\t\t\ttokens: estimate.tokens,\n\t\t\tcontextWindow,\n\t\t\tpercent: (estimate.tokens / contextWindow) * 100,\n\t\t};\n\t}\n\n\tprivate _rlmSessionDirForReading(): string | undefined {\n\t\treturn this._rlmSessionDir ?? this.sessionManager.getSessionArtifactDir();\n\t}\n\n\tprivate _contextWindowResolver(): ContextWindowResolver {\n\t\treturn (provider, modelId) => this._modelRegistry.find(provider, modelId)?.contextWindow;\n\t}\n\n\t// Whole-source own spend, identical to the catalog reduction at passivation.\n\tasync getOwnUsageSummary(): Promise<SessionUsageSummary | undefined> {\n\t\tif (!this.sessionManager.supportsCapturedHistoryReads()) {\n\t\t\tconst entries = this.sessionManager.getEntries();\n\t\t\treturn sessionUsageSummaryFrom(computeOwnAndTotalUsage(entries, entries).ownUsage);\n\t\t}\n\t\treturn this.sessionManager.readOwnUsageSummary();\n\t}\n\n\t/**\n\t * Build the agent context overview for /context: this session as the root\n\t * plus one node per RLM sub-agent, recursively. Running children are read\n\t * from their live sessions; completed children from their persisted session\n\t * dirs, so the tree survives child disposal and session resume.\n\t */\n\tasync getContextTree(limits: Partial<ContextTreeRequestLimits> = {}): Promise<ContextTreeNode> {\n\t\treturn this._getContextTree(new ContextTreeRequest(limits));\n\t}\n\n\tprivate async _getContextTree(\n\t\trequest: ContextTreeRequest,\n\t\tidentity?: Pick<ContextTreeNode, \"id\" | \"label\" | \"status\">,\n\t): Promise<ContextTreeNode> {\n\t\t// Live descendants enter synchronously before any queued native/disk reduction.\n\t\t// Their parent already admitted the run identity and one node slot.\n\t\tif (!identity) request.admitNode();\n\t\tconst model = this.model;\n\t\tconst rootNode = {\n\t\t\t...(identity ?? { id: \"root\", label: this.sessionName ?? \"main agent\", status: \"active\" as const }),\n\t\t\tmodel: model ? { provider: model.provider, id: model.id } : undefined,\n\t\t};\n\t\trequest.retainMetadata(identity ? { model: rootNode.model } : rootNode);\n\t\tconst contextWindow = model?.contextWindow ?? 0;\n\t\tconst estimate = model && !(contextWindow <= 0) ? estimateContextTokens(this.messages) : undefined;\n\t\tconst availabilityBytes = estimate ? this.settingsManager.getCanonicalContextLimits().maxSourceBytes : undefined;\n\t\tconst resolveContextWindow = this._contextWindowResolver();\n\t\tconst rlmSessionDir = this._rlmSessionDirForReading();\n\t\tconst residentUsage = this.sessionManager.supportsCapturedHistoryReads()\n\t\t\t? undefined\n\t\t\t: readResidentContextTreeUsage(this.sessionManager, request.limits, availabilityBytes);\n\t\tif (residentUsage) request.retainMetadata(residentUsage);\n\t\tconst usageRead = residentUsage\n\t\t\t? Promise.resolve(residentUsage)\n\t\t\t: readContextTreeUsage(this.sessionManager, request.limits, request, availabilityBytes);\n\t\tconst children: Promise<ContextTreeNode | undefined>[] = [];\n\t\tconst skipIds = new Set<string>();\n\t\tlet diskChildren: Promise<ContextTreeNode[]> = Promise.resolve([]);\n\t\ttry {\n\t\t\t// Admit while iterating: do not first clone an unbounded run Map.\n\t\t\tfor (const run of this._activeRlmChildRuns.values()) {\n\t\t\t\trequest.admitNode();\n\t\t\t\tconst childIdentity = { id: run.id, label: rlmChildLabel(run.prompt), status: run.status };\n\t\t\t\trequest.retainMetadata(childIdentity);\n\t\t\t\tskipIds.add(childIdentity.id);\n\t\t\t\tconst child = run.session;\n\t\t\t\tchildren.push(\n\t\t\t\t\tchild\n\t\t\t\t\t\t? child._getContextTree(request, childIdentity)\n\t\t\t\t\t\t: loadContextTreeChildFromDisk(run.sessionDir, resolveContextWindow, request, childIdentity),\n\t\t\t\t);\n\t\t\t}\n\t\t\tdiskChildren = loadContextTreeChildrenFromDisk(rlmSessionDir, resolveContextWindow, skipIds, request);\n\t\t} catch (error) {\n\t\t\t// Admission failure does not abandon any earlier captured/accepted read.\n\t\t\tchildren.push(Promise.reject(error));\n\t\t}\n\t\tconst results = await Promise.allSettled([usageRead, ...children, diskChildren]);\n\t\tconst errors = results.flatMap((result) => (result.status === \"rejected\" ? [result.reason] : []));\n\t\tif (errors.length === 1) throw errors[0];\n\t\tif (errors.length > 1) throw new AggregateError(errors, \"Context tree reads failed\");\n\t\tconst usage = (results[0] as PromiseFulfilledResult<Awaited<typeof usageRead>>).value;\n\t\tif (!usage) throw new Error(\"Context tree usage source is unavailable\");\n\t\tconst contextUsage = estimate\n\t\t\t? usage.hasPostCompactionUsage\n\t\t\t\t? { tokens: estimate.tokens, contextWindow, percent: (estimate.tokens / contextWindow) * 100 }\n\t\t\t\t: { tokens: null, contextWindow, percent: null }\n\t\t\t: undefined;\n\t\tconst usageMetadata = {\n\t\t\townUsage: usage.ownUsage,\n\t\t\ttotalUsage: usage.totalUsage,\n\t\t\t...(usage.ownRequestUsage ? { ownRequestUsage: usage.ownRequestUsage } : {}),\n\t\t\tcontextUsage,\n\t\t};\n\t\trequest.retainMetadata({ contextUsage });\n\t\treturn {\n\t\t\t...rootNode,\n\t\t\t...usageMetadata,\n\t\t\tchildren: [\n\t\t\t\t...results.slice(1, children.length + 1).flatMap((result) => {\n\t\t\t\t\tconst node = (result as PromiseFulfilledResult<ContextTreeNode | undefined>).value;\n\t\t\t\t\treturn node ? [node] : [];\n\t\t\t\t}),\n\t\t\t\t...(results[children.length + 1] as PromiseFulfilledResult<ContextTreeNode[]>).value,\n\t\t\t],\n\t\t};\n\t}\n\n\t/**\n\t * Export session to HTML.\n\t * @param outputPath Optional output path (defaults to session directory)\n\t * @returns Path to exported file\n\t */\n\tasync exportToHtml(outputPath?: string): Promise<string> {\n\t\tconst themeName = this.settingsManager.getTheme();\n\t\tconst sourceId = this.sessionManager.getSessionId();\n\t\tconst sourceFile = this.sessionManager.getSessionFile();\n\t\tawait this.initialize();\n\t\tawait this._agentEventQueue;\n\t\tawait this._goalResumeOperation;\n\t\tawait this._waitForChildUsageWrites();\n\t\tawait this.sessionManager.flushNow();\n\t\tif (this.sessionManager.getSessionId() !== sourceId || this.sessionManager.getSessionFile() !== sourceFile) {\n\t\t\tthrow new Error(\"Session source changed during export\");\n\t\t}\n\n\t\tconst toolRenderer: ToolHtmlRenderer = createToolHtmlRenderer({\n\t\t\tgetToolDefinition: (name) => this.getToolDefinition(name),\n\t\t\ttheme,\n\t\t\tcwd: this.sessionManager.getCwd(),\n\t\t});\n\n\t\treturn await exportSessionToHtml(this.sessionManager, this.state, {\n\t\t\toutputPath,\n\t\t\tthemeName,\n\t\t\ttoolRenderer,\n\t\t});\n\t}\n\n\t/**\n\t * Export the current session branch to a JSONL file.\n\t * Writes the session header followed by all entries on the current branch path.\n\t * @param outputPath Target file path. If omitted, generates a timestamped file in cwd.\n\t * @returns The resolved output file path.\n\t */\n\tasync exportToJsonl(outputPath?: string): Promise<string> {\n\t\tconst filePath = resolve(outputPath ?? `session-${new Date().toISOString().replace(/[:.]/g, \"-\")}.jsonl`);\n\t\tconst sourceId = this.sessionManager.getSessionId();\n\t\tconst sourceFile = this.sessionManager.getSessionFile();\n\t\tawait this.initialize();\n\t\tawait this._agentEventQueue;\n\t\tawait this._goalResumeOperation;\n\t\tawait this._waitForChildUsageWrites();\n\t\tawait this.sessionManager.flushNow();\n\t\tif (this.sessionManager.getSessionId() !== sourceId || this.sessionManager.getSessionFile() !== sourceFile) {\n\t\t\tthrow new Error(\"Session source changed during export\");\n\t\t}\n\t\treturn exportSessionBranchToJsonl(this.sessionManager, filePath);\n\t}\n\n\t/**\n\t * Get text content of last assistant message.\n\t * Useful for /copy command.\n\t * @returns Text content, or undefined if no assistant message exists\n\t */\n\tgetLastAssistantText(): string | undefined {\n\t\tconst lastAssistant = this.messages\n\t\t\t.slice()\n\t\t\t.reverse()\n\t\t\t.find((m) => {\n\t\t\t\tif (m.role !== \"assistant\") return false;\n\t\t\t\tconst msg = m as AssistantMessage;\n\t\t\t\t// Skip aborted messages with no content\n\t\t\t\tif (msg.stopReason === \"aborted\" && msg.content.length === 0) return false;\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\tif (!lastAssistant) return undefined;\n\n\t\tlet text = \"\";\n\t\tfor (const content of (lastAssistant as AssistantMessage).content) {\n\t\t\tif (content.type === \"text\") {\n\t\t\t\ttext += content.text;\n\t\t\t}\n\t\t}\n\n\t\treturn text.trim() || undefined;\n\t}\n\n\t// =========================================================================\n\t// Extension System\n\t// =========================================================================\n\n\tcreateReplacedSessionContext(): ReplacedSessionContext {\n\t\tconst context = Object.defineProperties(\n\t\t\t{},\n\t\t\tObject.getOwnPropertyDescriptors(this._extensionRunner.createCommandContext()),\n\t\t) as ReplacedSessionContext;\n\t\tcontext.sendMessage = (message, options) => this.sendCustomMessage(message, options);\n\t\tcontext.sendUserMessage = (content, options) => this.sendUserMessage(content, options);\n\t\treturn context;\n\t}\n\n\thasExtensionHandlers(eventType: string): boolean {\n\t\treturn this._extensionRunner.hasHandlers(eventType);\n\t}\n\n\tget extensionRunner(): ExtensionRunner {\n\t\treturn this._extensionRunner;\n\t}\n}\n\nfunction isRlmHeartbeatStatusUpdate(value: unknown): value is AgentRlmHeartbeatStatusUpdate {\n\treturn value === \"pause\" || value === \"resume\";\n}\n\nfunction rlmHeartbeatHostResponse(job: AgentCronJob): Record<string, unknown> {\n\treturn {\n\t\tid: job.id,\n\t\tstatus: job.status,\n\t\tlabel: job.label ?? null,\n\t\tdelivery_mode: job.deliveryMode ?? \"steer\",\n\t\tinstruction: job.prompt,\n\t\tschedule: job.schedule,\n\t\tcreated_at: job.createdAt,\n\t\tupdated_at: job.updatedAt,\n\t\tnext_run_at: job.nextRunAt ?? null,\n\t\tlast_run_at: job.lastRunAt ?? null,\n\t\tlast_error: job.lastError ?? null,\n\t\trun_count: job.runCount,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-session.d.ts","sourceRoot":"","sources":["../../src/core/agent-session.ts"],"names":[],"mappings":"AAMA,OAAO,EACN,KAAK,EAIL,KAAK,UAAU,EACf,KAAK,YAAY,EAEjB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,SAAS,EAMd,KAAK,aAAa,EAClB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAGX,YAAY,EACZ,KAAK,EACL,yBAAyB,EACzB,WAAW,EACX,WAAW,EAEX,WAAW,EACX,MAAM,+BAA+B,CAAC;AAgBvC,OAAO,EAKN,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EAExB,KAAK,6BAA6B,EAClC,KAAK,6BAA6B,EAClC,KAAK,0BAA0B,EAY/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEN,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,gCAAgC,EAKrC,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EACN,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAU1B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,UAAU,EAA6B,MAAM,oBAAoB,CAAC;AAehF,OAAO,EAIN,KAAK,gBAAgB,EAYrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAKN,KAAK,WAAW,EAShB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,KAAK,eAAe,EAEpB,KAAK,wBAAwB,EAO7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,2BAA2B,EAAiC,MAAM,gBAAgB,CAAC;AAK/G,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,8BAA8B,EACnC,KAAK,sBAAsB,EAC3B,eAAe,EACf,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAIhB,KAAK,sBAAsB,EAI3B,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,cAAc,EAInB,KAAK,QAAQ,EAKb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAON,KAAK,gBAAgB,EACrB,KAAK,SAAS,EAQd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAKN,oBAAoB,EACpB,KAAK,sBAAsB,EAE3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAuB,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAErF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAIN,KAAK,aAAa,EAgBlB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EAmBrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAKrB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAA0B,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEnF,OAAO,EAWN,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EAGnB,KAAK,mBAAmB,EACxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAIN,KAAK,oBAAoB,EAMzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAKN,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAG3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAEN,oBAAoB,EAGpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAIN,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAIhC,KAAK,qBAAqB,EAI1B,KAAK,UAAU,EACf,MAAM,2BAA2B,CAAC;AAQnC,OAAO,EAMN,KAAK,oBAAoB,EACzB,MAAM,2BAA2B,CAAC;AAQnC,OAAO,EAEN,KAAK,kBAAkB,EAEvB,KAAK,cAAc,EAEnB,cAAc,EACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,EAIN,KAAK,mBAAmB,EAExB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAE,KAAK,cAAc,EAA6B,MAAM,iBAAiB,CAAC;AAIjF,OAAO,EAAE,KAAK,mBAAmB,EAA2B,MAAM,YAAY,CAAC;AAM/E,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,KAAK,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE3E,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC;AAExF,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,mBAAmB,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,CAAC;AAEjF,MAAM,MAAM,iBAAiB,GAC1B,UAAU,GACV;IACA,IAAI,EAAE,4BAA4B,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,sBAAsB,CAAC;CAC/B,GACD;IAAE,IAAI,EAAE,uBAAuB,CAAC;IAAC,OAAO,EAAE,qBAAqB,CAAA;CAAE,GACjE;IACA,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,gBAAgB,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC3B,GACD;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,wBAAwB,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,GAC1D;IACA,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IACpC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC3B,GACD;IACA,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACpB,GACD;IACA,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACnB,GACD;IACA,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;CACzC,GACD;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,qBAAqB,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GACxC;IACA,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CACd,GACD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtC;IACA,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CACd,GACD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5C,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAU3E,qBAAa,sBAAuB,SAAQ,KAAK;CAAG;AAOpD,+EAA+E;AAC/E,qBAAa,wBAAyB,SAAQ,KAAK;IAEjD,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,MAAM,EAAE,gBAAgB;IAFlC,YACU,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,gBAAgB,EACjC,KAAK,EAAE,OAAO,EAOd;CACD;AAOD,gFAAgF;AAChF,qBAAa,kBAAmB,SAAQ,KAAK;CAAG;AAEhD,MAAM,WAAW,kBAAkB;IAClC,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;IAC/C,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,gGAAgG;IAChG,sBAAsB,CAAC,EAAE,iBAAiB,CAAC;IAC3C,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,qBAAqB,CAAC,EAAE,WAAW,CAAC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,aAAa,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;IAC3E,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;IAC/B,aAAa,EAAE,aAAa,CAAC;IAC7B,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sBAAsB,CAAC,EAAE,6BAA6B,CAAC;IACvD,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAChD;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,2BAA2B,CAAC;IACrD;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC9C,kBAAkB,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,eAAe,CAAA;KAAE,CAAC;IACnD,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1D;AAED,MAAM,WAAW,iBAAiB;IACjC,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,qBAAqB,CAAC,EAAE,8BAA8B,CAAC;IACvD,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,OAAO,CAAC,EAAE,sBAAsB,CAAC;CACjC;AAED,MAAM,WAAW,uBAAuB;IACvC,MAAM,EAAE,gBAAgB,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,8BAA8B,GACvC;IACA,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC1E,KAAK,EAAE,eAAe,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACrB,GACD;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAChD;IACA,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC1E,aAAa,EAAE,MAAM,CAAC;CACrB,CAAC;AAEL,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,uBAAuB,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAEvH,MAAM,WAAW,aAAa;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACzC,aAAa,CAAC,EAAE,aAAa,CAAC;CAC9B;AAiDD,KAAK,uBAAuB,GAAG,sBAAsB,GAAG,qBAAqB,GAAG,MAAM,CAAC;AACvF,KAAK,mBAAmB,GAAG,QAAQ,GAAG,YAAY,GAAG,MAAM,CAAC;AAE5D,UAAU,uBAAuB;IAChC,oBAAoB,EAAE,mBAAmB,CAAC;IAC1C,gCAAgC,EAAE,OAAO,CAAC;IAC1C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,0BAA0B,EAAE,OAAO,CAAC;IACpC,iBAAiB,EAAE,uBAAuB,CAAC;IAC3C,kBAAkB,EAAE,mBAAmB,CAAC;CACxC;AAUD,KAAK,kBAAkB,GAAG,WAAW,GAAG,aAAa,CAAC;AAGtD,MAAM,WAAW,mBAAmB;IACnC,WAAW,EAAE,uBAAuB,CAAC;IACrC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,qBAAqB,EAAE,aAAa,GAAG,QAAQ,GAAG,MAAM,CAAC;IACzD,4BAA4B,EAAE,OAAO,CAAC;IACtC,4BAA4B,EAAE,OAAO,CAAC;CACtC;AAiFD,eAAO,MAAM,sCAAsC,IAAI,CAAC;AACxD,uGAAuG;AACvG,eAAO,MAAM,4CAA4C,IAAI,CAAC;AAE9D,MAAM,WAAW,2BAA2B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,4BAA4B,GACrC;IACA,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,2BAA2B,EAAE,CAAC;IACvC,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACzC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,eAAe,EAAE,mBAAmB,CAAC;IACrC,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,wBAAwB,EAAE,OAAO,CAAC;CACjC,GACD;IACA,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,mBAAmB,CAAC;IAC7B,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;CACvB,CAAC;AAEL,MAAM,WAAW,2BAA2B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,WAAW,GAAG,UAAU,CAAC;IACjC,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,4BAA4B,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8BAA8B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED,MAAM,WAAW,6BAA6B;IAC7C,aAAa,EAAE,OAAO,sCAAsC,GAAG,OAAO,4CAA4C,CAAC;IACnH,OAAO,EAAE,2BAA2B,EAAE,CAAC;CACvC;AAqKD,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,UAAU,kBAAkB;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAgBD,OAAO,KAAK,EAAqB,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACrG,OAAO,EAEN,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAExB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAyHrG,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAMpE;AAKD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAsCD,qBAAa,YAAY;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,sBAAsB,CAAC;IACjD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkC;IACnE,OAAO,CAAC,0BAA0B,CAAC,CAKjC;IACF,OAAO,CAAC,0BAA0B,CAAC,CAKjC;IACF,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAU;IAChD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAc;IAClD,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,0BAA0B,CAAK;IACvC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA4B;IAChE,OAAO,CAAC,wBAAwB,CAAC,CAM/B;IACF,OAAO,CAAC,iBAAiB,CAAC,CAA2E;IACrG,OAAO,CAAC,sBAAsB,CAAc;IAE5C,OAAO,CAAC,aAAa,CAGlB;IAEH,OAAO,CAAC,iBAAiB,CAAC,CAAa;IACvC,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,0BAA0B,CAIhC;IACF,OAAO,CAAC,gBAAgB,CAAoC;IAE5D,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0C;IACvE,OAAO,CAAC,iBAAiB,CAAoC;IAC7D,OAAO,CAAC,0BAA0B,CAAS;IAE3C,OAAO,CAAC,sBAAsB,CAAK;IACnC,OAAO,CAAC,yBAAyB,CAAK;IAEtC,OAAO,CAAC,0BAA0B,CAAS;IAC3C,OAAO,CAAC,sCAAsC,CAAS;IAEvD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IACvD,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAqB;IAClE,OAAO,CAAC,QAAQ,CAAC,kCAAkC,CAAqB;IACxE,OAAO,CAAC,wBAAwB,CAAoC;IACpE,OAAO,CAAC,yBAAyB,CAAqB;IACtD,OAAO,CAAC,iCAAiC,CAAK;IAC9C,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAmC;IAC/E,OAAO,CAAC,QAAQ,CAAC,0CAA0C,CAAyB;IAEpF,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAyB;IACxE,OAAO,CAAC,wBAAwB,CAAuB;IAEvD,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,wBAAwB,CAAiC;IACjE,OAAO,CAAC,8BAA8B,CAAS;IAC/C,OAAO,CAAC,+BAA+B,CAAmC;IAC1E,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,uCAAuC,CAAK;IACpD,OAAO,CAAC,yCAAyC,CAA+B;IAChF,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAoB;IAC5D,OAAO,CAAC,2CAA2C,CAAS;IAC5D,OAAO,CAAC,wBAAwB,CAAC,CAAkC;IACnE,OAAO,CAAC,2BAA2B,CAAC,CAAgB;IACpD,OAAO,CAAC,wBAAwB,CAAS;IAEzC,OAAO,CAAC,0BAA0B,CAA0C;IAC5E,OAAO,CAAC,8BAA8B,CAA0C;IAChF,OAAO,CAAC,oBAAoB,CAAwC;IACpE,OAAO,CAAC,uBAAuB,CAAuC;IACtE,+EAA+E;IAC/E,OAAO,CAAC,iBAAiB,CAA6C;IACtE,OAAO,CAAC,0BAA0B,CAA8B;IAChE,OAAO,CAAC,kBAAkB,CAA+B;IACzD,OAAO,CAAC,2BAA2B,CAAsE;IACzG,OAAO,CAAC,uBAAuB,CAA0D;IAEzF,OAAO,CAAC,6BAA6B,CAA0C;IAC/E,OAAO,CAAC,uBAAuB,CAAwC;IAEvE,OAAO,CAAC,qBAAqB,CAA0C;IACvE,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,uBAAuB,CAAK;IACpC,OAAO,CAAC,qBAAqB,CAA0C;IACvE,OAAO,CAAC,6BAA6B,CAA+C;IACpF,2FAA2F;IAC3F,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAuB;IAE5D,OAAO,CAAC,qBAAqB,CAA8B;IAC3D,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,oBAAoB,CAA8B;IAE1D,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,gBAAgB,CAAC,CAAuD;IAChF,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,qBAAqB,CAAoC;IACjE,OAAO,CAAC,yBAAyB,CAAQ;IACzC,OAAO,CAAC,uBAAuB,CAAoC;IAEnE,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,oBAAoB,CAA0C;IACtE,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,mBAAmB,CAAC,CAAgC;IAC5D,OAAO,CAAC,uBAAuB,CAAC,CAAW;IAC3C,OAAO,CAAC,iBAAiB,CAAC,CAAc;IACxC,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,oBAAoB,CAAU;IACtC,OAAO,CAAC,uBAAuB,CAAC,CAA8B;IAC9D,OAAO,CAAC,uBAAuB,CAAC,CAAgC;IAChE,OAAO,CAAC,uBAAuB,CAAC,CAAyB;IACzD,OAAO,CAAC,WAAW,CAAC,CAAa;IACjC,OAAO,CAAC,kBAAkB,CAAC,CAA4B;IACvD,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,mBAAmB,CAAC,CAAqB;IACjD,OAAO,CAAC,+BAA+B,CAAC,CAAiC;IACzE,OAAO,CAAC,yBAAyB,CAAC,CAAkB;IACpD,OAAO,CAAC,uBAAuB,CAAC,CAAyB;IACzD,OAAO,CAAC,2BAA2B,CAAC,CAAa;IACjD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyC;IAC3E,OAAO,CAAC,wBAAwB,CAAC,CAAgB;IAGjD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,oBAAoB,CAAC,CAAgB;IAC7C,OAAO,CAAC,yBAAyB,CAAC,CAA2B;IAC7D,8EAA8E;IAC9E,OAAO,CAAC,yBAAyB,CAAC,CAAS;IAC3C,iGAAiG;IACjG,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAU;IAChD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAqB;IAC5D,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuB;IACtD,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,yBAAyB,CAAsB;IACvD,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAC,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsE;IAC1G,OAAO,CAAC,oBAAoB,CAAsB;IAClD,OAAO,CAAC,mBAAmB,CAAC,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAmB;IACtD,OAAO,CAAC,4BAA4B,CAAS;IAC7C,OAAO,CAAC,2BAA2B,CAAC,CAAsB;IAC1D,OAAO,CAAC,mBAAmB,CAAkC;IAC7D,OAAO,CAAC,sBAAsB,CAA0B;IACxD,OAAO,CAAC,+BAA+B,CAAqB;IAC5D,OAAO,CAAC,wBAAwB,CAA8B;IAC9D,OAAO,CAAC,+BAA+B,CAAqB;IAG5D,OAAO,CAAC,iBAAiB,CAAuC;IAChE,OAAO,CAAC,mBAAmB,CAAqB;IAGhD,OAAO,CAAC,wBAAwB,CAA+C;IAC/E,OAAO,CAAC,oBAAoB,CAMxB;IAGJ,OAAO,CAAC,qBAAqB,CAAiC;IAC9D,OAAO,CAAC,qBAAqB,CAA0C;IACvE,OAAO,CAAC,0BAA0B,CAAC,CAA+D;IAClG,sHAAsH;IACtH,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoC;IACjE,OAAO,CAAC,eAAe,CAA4B;IACnD,OAAO,CAAC,oBAAoB,CAA4B;IACxD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA4B;IACzD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA4B;IAC9D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAG/B;IAEJ,OAAO,CAAC,cAAc,CAAgB;IAEtC,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,oBAAoB,CAAkD;IAC9E,OAAO,CAAC,sBAAsB,CAAmC;IACjE,OAAO,CAAC,2BAA2B,CAAC,CAAS;IAC7C,OAAO,CAAC,uBAAuB,CAAsF;IACrH,OAAO,CAAC,gBAAgB,CAA+C;IACvE,OAAO,CAAC,mBAAmB,CAAkC;IAC7D,OAAO,CAAC,qBAAqB,CAAoC;IAEjE,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,wBAAwB,CAA4B;IAC5D,OAAO,CAAC,8BAA8B,CAAK;IAC3C,OAAO,CAAC,uBAAuB,CAAK;IACpC,OAAO,CAAC,uBAAuB,CAAC,CAA2D;IAC3F,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,0BAA0B,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA4B;IAClE,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAA4C;IACvF,OAAO,CAAC,yBAAyB,CAAS;IAC1C,OAAO,CAAC,8BAA8B,CAAS;IAC/C,OAAO,CAAC,oCAAoC,CAAS;IACrD,OAAO,CAAC,qCAAqC,CAAmD;IAChG,OAAO,CAAC,4BAA4B,CAAyC;IAC7E,OAAO,CAAC,uCAAuC,CAAoE;IACnH,OAAO,CAAC,kDAAkD,CAAyC;IACnG,OAAO,CAAC,gCAAgC,CAAwC;IAChF,OAAO,CAAC,wBAAwB,CAAqE;IACrG,OAAO,CAAC,wBAAwB,CAAK;IACrC,OAAO,CAAC,sBAAsB,CAAC,CAAkB;IACjD,OAAO,CAAC,sBAAsB,CAAC,CAAkB;IACjD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAqB;IAC1D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IAC5C,OAAO,CAAC,eAAe,CAAC,CAAgB;IACxC,OAAO,CAAC,mBAAmB,CAAC,CAAgB;IAC5C,OAAO,CAAC,uBAAuB,CAAC,CAAsD;IACtF,OAAO,CAAC,oBAAoB,CAAC,CAAgB;IAC7C,OAAO,CAAC,gCAAgC,CAAC,CAGvC;IAEF,YAAY,MAAM,EAAE,kBAAkB,EA+pBrC;YAEa,wBAAwB;IAItC,0EAA0E;IAC1E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAK1B;YAEa,WAAW;IAsCzB,yEAAyE;IACzE,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,iCAAiC;IAKzC,OAAO,CAAC,0BAA0B;IAOlC,OAAO,CAAC,gBAAgB;IAQxB,wFAAwF;IAClF,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCrD;YAGa,iBAAiB;IA0D/B,mFAAmF;IACnF,mBAAmB,IAAI,IAAI,CAE1B;IAED;;;;OAIG;IACH,yBAAyB,CAAC,UAAU,EAAE,2BAA2B,GAAG,IAAI,CAWvE;IAED,oBAAoB,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAYlF;IAEK,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CzF;IAED,OAAO,CAAC,+BAA+B;IAavC,OAAO,CAAC,+BAA+B;IAcvC,IAAI,aAAa,IAAI,aAAa,CAEjC;IAED,sBAAsB,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAEvD;YAEa,uBAAuB;IAsBrC;;;;;;;OAOG;IACH,OAAO,CAAC,sBAAsB;IAoD9B,OAAO,CAAC,6BAA6B;IAKrC,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,KAAK;IAWb,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,oCAAoC;IAe5C,OAAO,CAAC,oCAAoC;IAe5C,OAAO,CAAC,kCAAkC;YAS5B,uCAAuC;IAgCrD,OAAO,CAAC,kCAAkC;IA4B1C,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,8BAA8B;IAetC,OAAO,CAAC,mBAAmB;YAqBb,qBAAqB;IAiDnC,OAAO,CAAC,uBAAuB;IAgB/B;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;YAoBX,yBAAyB;IAkBvC,OAAO,CAAC,6BAA6B;IAcrC,OAAO,CAAC,+BAA+B;IAgBvC,OAAO,CAAC,4BAA4B;IAMpC,OAAO,CAAC,2BAA2B;YAIrB,iBAAiB;YAejB,aAAa;IAmC3B,OAAO,CAAC,yBAAyB;IAcjC,OAAO,CAAC,2BAA2B;IASnC,OAAO,CAAC,qBAAqB;IA+D7B,OAAO,CAAC,wBAAwB;YAgBlB,UAAU;YAyBV,UAAU;YAKV,UAAU;YAmBV,WAAW;YA2BX,oBAAoB;YAmBpB,sCAAsC;YAuBtC,uCAAuC;IAerD,OAAO,CAAC,sBAAsB;IAoD9B,OAAO,CAAC,4BAA4B;IAgBpC,OAAO,CAAC,uBAAuB;YAMjB,qBAAqB;YAoBrB,6BAA6B;IAe3C,OAAO,CAAC,+BAA+B;YAiBzB,yBAAyB;IAavC;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAsBhC,OAAO,CAAC,qCAAqC;YAY/B,mCAAmC;IA6CjD,OAAO,CAAC,sBAAsB;YAYhB,uBAAuB;YAwDvB,oCAAoC;IAgDlD,OAAO,KAAK,oBAAoB,GAW/B;IAED,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,+BAA+B;IAcvC,OAAO,CAAC,yBAAyB;IAUjC,OAAO,CAAC,4BAA4B;IAKpC,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,wBAAwB;IAQhC,OAAO,CAAC,oBAAoB;YAMd,oBAAoB;YASpB,eAAe;YA8Ef,iCAAiC;YA+BjC,8BAA8B;YA2F9B,6CAA6C;YAgE7C,8BAA8B;YAuD9B,gCAAgC;YAoChC,oBAAoB;IAoBlC;;;;;OAKG;IACH,OAAO,CAAC,mCAAmC;YAwD7B,kBAAkB;YAqElB,oBAAoB;YA+EpB,6BAA6B;IAyC3C,OAAO,CAAC,iCAAiC;IAQzC,OAAO,CAAC,6BAA6B;YAcvB,0BAA0B;IAuCxC,OAAO,CAAC,gCAAgC;IASxC,OAAO,CAAC,+BAA+B;IASvC,OAAO,CAAC,iCAAiC;YAS3B,kDAAkD;YAgDlD,4CAA4C;YAwD5C,6DAA6D;IA6B3E,OAAO,CAAC,mCAAmC;IAsC3C,OAAO,CAAC,kEAAkE;IAQ1E;;;;OAIG;IACG,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAqB1G;IAED;;;;OAIG;IACG,wBAAwB,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA2ElC;IAED;;;;;;OAMG;IACH,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA2DpG;IAED;;;;OAIG;IACH,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuF1G;IAED,6BAA6B,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAEnC,OAAO,CAAC,6BAA6B,GAAG,0BAA0B,GAAG,uBAAuB,CAAC,GAC7F,6BAA6B,GAC7B,uBAAuB,CAwCzB;IAED,6BAA6B,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAEnC,sBAAsB,GACtB,yBAAyB,GACzB,gCAAgC,GAChC,OAAO,CAAC,sBAAsB,GAAG,yBAAyB,GAAG,gCAAgC,CAAC,CA2BhG;YAEa,mBAAmB;YA8BnB,qBAAqB;IA6BnC,OAAO,CAAC,4BAA4B;YAkBtB,2BAA2B;YAyC3B,wBAAwB;YASxB,uBAAuB;IA+DrC,OAAO,CAAC,qBAAqB,CAA2C;IAExE,OAAO,CAAC,oBAAoB;IAS5B;;;OAGG;IACH,iCAAiC,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvE;IAED,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,mCAAmC;IAO3C,OAAO,CAAC,yBAAyB;IAWjC,OAAO,CAAC,4BAA4B;IAWpC,OAAO,CAAC,mBAAmB;YAqBb,gCAAgC;IAQ9C,OAAO,CAAC,iBAAiB,CAiFvB;IAEF,OAAO,CAAC,4BAA4B;IAUpC,OAAO,CAAC,4BAA4B;YAgBtB,kBAAkB;IAmOhC,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,yBAAyB;IAWjC,OAAO,CAAC,sBAAsB;YAgBhB,mBAAmB;IA8EjC;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CASzD;IAED;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAO5B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAKzB;;;OAGG;IACH,uGAAuG;IACvG,wBAAwB,IAAI,IAAI,CAM/B;IAED;;;;OAIG;IACG,YAAY,CAAC,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BxE;YAGa,kCAAkC;YAKlC,wBAAwB;YA+ExB,iBAAiB;IAsE/B,OAAO,CAAC,sBAAsB;IAoB9B,OAAO,IAAI,IAAI,CA2Dd;IAED,uBAAuB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAWlE;IAED,IAAI,KAAK,IAAI,UAAU,CAEtB;IAED,IAAI,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAElC;IAED,IAAI,aAAa,IAAI,aAAa,CAEjC;IAED,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,kBAAkB,IAAI,MAAM,EAAE,CAE7B;IAED,WAAW,IAAI,QAAQ,EAAE,CAOxB;IAED,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE1D;IAED,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAmB9C;IAED,IAAI,YAAY,IAAI,OAAO,CAM1B;IAED,oFAAoF;IACpF,IAAI,QAAQ,IAAI,YAAY,EAAE,CAE7B;IAEK,mBAAmB,IAAI,OAAO,CAAC,cAAc,CAAC,CAgBnD;IAED,OAAO,CAAC,yBAAyB;IAajC,IAAI,YAAY,IAAI,KAAK,GAAG,eAAe,CAE1C;IAED,IAAI,YAAY,IAAI,KAAK,GAAG,eAAe,CAE1C;IAED,IAAI,WAAW,IAAI,MAAM,GAAG,SAAS,CAEpC;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,aAAa,IAAI,oBAAoB,CAExC;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,IAAI,MAAM,GAAG,SAAS,CAEpC;IAED,IAAI,SAAS,IAAI,SAAS,CAEzB;IAED,mBAAmB,IAAI,qBAAqB,CAE3C;IAED,gCAAgC,IAAI,IAAI,CAEvC;IAEK,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAI5C;YAEa,wCAAwC;IAStD,OAAO,CAAC,qCAAqC;IAI7C,IAAI,YAAY,IAAI,aAAa,CAAC;QACjC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAClB,aAAa,CAAC,EAAE,aAAa,CAAC;KAC9B,CAAC,CAED;IAED,eAAe,CAAC,YAAY,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,aAAa,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC,GAAG,IAAI,CAE/F;IAED,IAAI,eAAe,IAAI,aAAa,CAAC,cAAc,CAAC,CAEnD;IAED,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,0BAA0B;IAelC,OAAO,CAAC,oBAAoB;YAyDd,oBAAoB;YAyDpB,+BAA+B;IA8C7C,OAAO,CAAC,6BAA6B;IAUrC,OAAO,CAAC,8BAA8B;IAqBtC,OAAO,CAAC,oBAAoB;YAiCd,qBAAqB;YAKrB,iBAAiB;IAoC/B,OAAO,CAAC,0BAA0B;IAclC,OAAO,CAAC,iCAAiC;IAazC;;;;;;;;OAQG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE;IAEK,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9E;IAEK,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCxE;IAEK,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCnF;IAEK,uBAAuB,CAC5B,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,OAAO,GAAG,UAAU,EACvC,aAAa,CAAC,EAAE,mBAAmB,GACjC,OAAO,CAAC,OAAO,CAAC,CAgBlB;IAEK,eAAe,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAO/E;IAED,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,wBAAwB;IAMhC,OAAO,CAAC,0BAA0B;IAMlC,OAAO,CAAC,8BAA8B;IAItC,OAAO,CAAC,+BAA+B;IAoBvC,OAAO,CAAC,gCAAgC;YAwB1B,uCAAuC;YA8BvC,uBAAuB;IAarC,OAAO,CAAC,+BAA+B;YAmBzB,sBAAsB;YA4EtB,OAAO;IA+MrB,OAAO,CAAC,wBAAwB;IAuBhC;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IA4C3B;;;;;;;OAOG;IACG,KAAK,CACV,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,YAAY,EAAE,EACvB,OAAO,GAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,YAAY,CAAC,EAAE,OAAO,CAAC;KAClB,GACJ,OAAO,CAAC,IAAI,CAAC,CAiCf;IAED;;;;;;OAMG;IACG,QAAQ,CACb,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,YAAY,EAAE,EACvB,OAAO,GAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,YAAY,CAAC,EAAE,OAAO,CAAC;KAClB,GACJ,OAAO,CAAC,OAAO,CAAC,CAiClB;IAEK,qBAAqB,CAAC,QAAQ,EAAE,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CA0GpF;IAED,OAAO,CAAC,sBAAsB;IAmB9B,OAAO,CAAC,mBAAmB;IAWrB,sBAAsB,CAC3B,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,YAAY,EAAE,EACvB,OAAO,GAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;QACzC,aAAa,CAAC,EAAE,aAAa,CAAC;QAC9B,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;KAC5B,GACJ,OAAO,CAAC,IAAI,CAAC,CAef;IAEK,sBAAsB,CAC3B,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,YAAY,EAAE,EACvB,OAAO,GAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;QACzC,aAAa,CAAC,EAAE,aAAa,CAAC;QAC9B,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;KAC5B,GACJ,OAAO,CAAC,OAAO,CAAC,CAmBlB;IAED,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,4BAA4B;IAMpC,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,oBAAoB;IAuE5B,OAAO,CAAC,yBAAyB;IAqEjC,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,sCAAsC;IAY9C,OAAO,CAAC,kBAAkB;YA4EZ,oBAAoB;IAyBlC,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,0BAA0B;IAOlC,IAAI,qBAAqB,IAAI,OAAO,CAUnC;IAED,IAAI,0BAA0B,IAAI,OAAO,CAMxC;IAED,OAAO,CAAC,yBAAyB;YAenB,kBAAkB;YAuJlB,8BAA8B;IAmD5C,OAAO,CAAC,sBAAsB;IAe9B,OAAO,CAAC,8BAA8B;IAItC,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,4BAA4B;IAWpC,OAAO,CAAC,yBAAyB;YAcnB,yBAAyB;YAkKzB,4BAA4B;YAyE5B,mCAAmC;IAgCjD,OAAO,CAAC,wBAAwB;IAWhC;;;;;;;;;;;OAWG;IACG,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAClC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC,EACjF,OAAO,CAAC,EAAE;QACT,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;KAC9C,GACC,OAAO,CAAC,IAAI,CAAC,CAsDf;IAED;;;;;;OAMG;IACG,eAAe,CACpB,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,EAChD,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAA;KAAE,GAC5C,OAAO,CAAC,IAAI,CAAC,CA2Bf;IAED,UAAU,IAAI;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CA0BvD;IAED,OAAO,CAAC,kCAAkC;IAM1C,wBAAwB,IAAI;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAGrE;IAED,+BAA+B,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAyDhH;IAED;;;;OAIG;IACH,mBAAmB,CAClB,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,qBAAqB,GAC7B,2BAA2B,CA0E7B;IAED,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,IAAI,qBAAqB,IAAI,MAAM,CAElC;IAED,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAED,IAAI,eAAe,IAAI,OAAO,CAa7B;IAED,wBAAwB,IAAI,qBAAqB,CA6BhD;IAED,mBAAmB,IAAI,SAAS,MAAM,EAAE,CAIvC;IAED,0BAA0B,IAAI,SAAS,MAAM,EAAE,CAI9C;IAED,mBAAmB,IAAI,SAAS,MAAM,EAAE,CAIvC;IAED,0BAA0B,IAAI,SAAS,MAAM,EAAE,CAI9C;IAED,gCAAgC,IAAI,6BAA6B,CA0EhE;IAED,OAAO,CAAC,mCAAmC;IAM3C,OAAO,CAAC,6BAA6B;IAarC,OAAO,CAAC,6BAA6B;IAmB/B,6BAA6B,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA6CvE;IAED,OAAO,CAAC,4BAA4B;IAWpC,wBAAwB,IAAI;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE,CAkB9C;IAED,sBAAsB,IAAI;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE,CAgB5C;YAEa,gCAAgC;YA0ChC,gCAAgC;IAuC9C,OAAO,CAAC,4BAA4B;IASpC,qHAAqH;IACrH,gBAAgB,IAAI,OAAO,CAK1B;IAEK,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM7C;IAEK,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAEjC;YAQa,wBAAwB;IAkDtC,6HAA6H;IACvH,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAOzC;IAED,kCAAkC,IAAI,SAAS,aAAa,EAAE,CAsB7D;IAED,8BAA8B,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAGvE;IAED,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAW9C;IAED,IAAI,cAAc,IAAI,cAAc,CAEnC;IAED,YAAY,IAAI,IAAI,CA2BnB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAgB3B;IAED,qBAAqB,IAAI,IAAI,CAsB5B;YAEa,gBAAgB;IAc9B,OAAO,CAAC,qBAAqB;IAmBvB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BjF;IAED,OAAO,CAAC,0BAA0B;IAWlC,OAAO,CAAC,6BAA6B;IAIrC,OAAO,CAAC,uBAAuB;IAOzB,UAAU,CACf,SAAS,GAAE,SAAS,GAAG,UAAsB,EAC7C,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAKvC;YAEa,iBAAiB;YA0CjB,oBAAoB;IAuC5B,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB1D;IAEK,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB5D;IAED,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,6BAA6B;IAIrC,OAAO,CAAC,yBAAyB;IAY3B,kBAAkB,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAU7D;IAED,0BAA0B,IAAI,aAAa,EAAE,CAG5C;IAED,gBAAgB,IAAI,OAAO,CAE1B;IAED,OAAO,CAAC,+BAA+B;IAUvC,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,sBAAsB;YAiBhB,+BAA+B;IAqD7C,OAAO,CAAC,uBAAuB;IA4B/B,eAAe,CAAC,IAAI,EAAE,KAAK,GAAG,eAAe,GAAG,IAAI,CAGnD;IAED,eAAe,CAAC,IAAI,EAAE,KAAK,GAAG,eAAe,GAAG,IAAI,CAGnD;IAEK,OAAO,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAG3G;IAED,OAAO,CAAC,uBAAuB;YA0BjB,gBAAgB;YAgKhB,0BAA0B;YAuE1B,kBAAkB;IA8PhC,OAAO,CAAC,iCAAiC;YA2B3B,yBAAyB;YA2BzB,8CAA8C;IAO5D,eAAe,IAAI,IAAI,CAGtB;IAED,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,4BAA4B;IAIpC,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,6BAA6B;IAYrC,OAAO,CAAC,6BAA6B;IAKrC,OAAO,CAAC,yBAAyB;YASnB,2CAA2C;IAsBzD;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,8BAA8B;IAQtC,OAAO,CAAC,gCAAgC;IAoBxC,OAAO,CAAC,kCAAkC;IAkB1C,OAAO,CAAC,+BAA+B;YAqBzB,wBAAwB;YAqBxB,mCAAmC;IAyFjD,OAAO,CAAC,0CAA0C;IAMlD,OAAO,CAAC,mCAAmC;IAI3C,OAAO,CAAC,iCAAiC;IAUzC,OAAO,CAAC,mBAAmB;YAcb,gBAAgB;YAuHhB,kBAAkB;IA8BhC,OAAO,CAAC,uBAAuB;YA8BjB,mBAAmB;YAuEnB,iBAAiB;IAqC/B,yFAAyF;IACzF,OAAO,CAAC,uBAAuB;YASjB,sBAAsB;IAoDpC;;;;;;;OAOG;IACG,MAAM,CACX,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,EAC9E,QAAQ,GAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;KAAO,GACjE,OAAO,CAAC,gBAAgB,CAAC,CAG3B;YAEa,eAAe;YAuHf,kBAAkB;YAWlB,WAAW;YAmGX,wBAAwB;YAwBxB,YAAY;IA0G1B,kBAAkB,IAAI,IAAI,CAEzB;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,0BAA0B;YAwBpB,gBAAgB;YAyJhB,4BAA4B;YA2B5B,yBAAyB;YAkCzB,kBAAkB;IA0NhC,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE/C;IAED,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,QAAQ,EAAE,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC,GAAG,SAAS,GAAG,IAAI,CAIrG;IAEK,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB/D;YAEa,6BAA6B;IAyB3C,OAAO,CAAC,2BAA2B;IAwBnC,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,uBAAuB;IAU/B,OAAO,CAAC,gCAAgC;IAcxC,OAAO,CAAC,kBAAkB;IAiH1B,OAAO,CAAC,oBAAoB;IA2G5B,OAAO,CAAC,aAAa;IAkHrB,OAAO,CAAC,uBAAuB;IAS/B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAuB3B,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,2BAA2B;IAanC,OAAO,CAAC,0BAA0B;YAWpB,kBAAkB;IAoDhC,yFAAyF;IACnF,oBAAoB,CACzB,KAAK,EAAE,mBAAmB,EAC1B,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,SAA0C,GAChD,OAAO,CAAC,sBAAsB,CAAC,CA4DjC;IAED,OAAO,CAAC,yBAAyB;IAqH3B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CA+B5B;IAED,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,mBAAmB;IA0B3B,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,6BAA6B;IAKrC,gCAAgC,IAAI,MAAM,GAAG,SAAS,CAGrD;IAED,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAI/C;IAED,IAAI,wBAAwB,IAAI,OAAO,GAAG,SAAS,CAElD;IAED,eAAe,IAAI,MAAM,GAAG,SAAS,CAEpC;IAED,OAAO,CAAC,+BAA+B;IAiBvC,OAAO,CAAC,+BAA+B;IAWvC,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAED,wFAAwF;IAClF,wBAAwB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CA4F3D;IAED,OAAO,CAAC,gCAAgC;YAwC1B,yBAAyB;YAYzB,+BAA+B;IA2F7C,OAAO,CAAC,2BAA2B;IASnC,OAAO,CAAC,yBAAyB;IAOjC,OAAO,CAAC,kBAAkB;IAgB1B,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAErE;YAEa,uBAAuB;YAQvB,gCAAgC;IAYxC,gBAAgB,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAExD;IAED,OAAO,CAAC,qBAAqB;IA8E7B,OAAO,CAAC,yBAAyB;YASnB,yBAAyB;IAYjC,yBAAyB,CAC9B,OAAO,EAAE,MAAM,EACf,mBAAmB,GAAE,MAAM,OAAqB,GAC9C,OAAO,CAAC,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC,CA0B9C;IAEK,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA+DxE;YAEa,yBAAyB;IA+BvC,OAAO,CAAC,yBAAyB;IAOjC,OAAO,CAAC,4BAA4B;YAUtB,mCAAmC;YAwBnC,qBAAqB;IAYnC,OAAO,CAAC,6BAA6B;IAmBrC,OAAO,CAAC,+BAA+B;IAevC,OAAO,CAAC,0BAA0B;IAkBlC,OAAO,CAAC,uBAAuB;YAgBjB,0BAA0B;YA0D1B,2BAA2B;IAwCzC,OAAO,CAAC,wBAAwB;IAqHhC;;;;;OAKG;IACG,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CA0ChH;IAED,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,KAAK,CAsBnF;IAED,OAAO,CAAC,uBAAuB;IAwB/B,OAAO,CAAC,2BAA2B;IAkCnC,OAAO,CAAC,6BAA6B;IAKrC,sGAAsG;IACtG,oBAAoB,IAAI,qBAAqB,EAAE,CAmC9C;IAED,0EAA0E;IAC1E,qBAAqB,IAAI,OAAO,CAU/B;IAED,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,8BAA8B;IAStC;;;;OAIG;IACG,oBAAoB,CAAC,cAAc,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CtE;IAGD,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAS5D;IAED;;;;;OAKG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAsB,GAAG,OAAO,CAuBxE;IAGD,OAAO,CAAE,mBAAmB;IAqB5B,oEAAoE;IACpE,2BAA2B,CAAC,MAAM,SAAsB,GAAG,OAAO,CASjE;YAEa,sCAAsC;YAyCtC,uBAAuB;IAO/B,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAI9E;YAEa,wBAAwB;YA2BxB,iBAAiB;IAwYzB,WAAW,CAChB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,SAAS,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CAiBzB;IAED,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,gCAAgC;IASxC,OAAO,CAAC,mCAAmC;IAsB3C,OAAO,CAAC,8BAA8B;IAkBtC,OAAO,CAAC,sBAAsB;IAM9B,OAAO,CAAC,6BAA6B;YAavB,qBAAqB;IA2CnC,UAAU,IAAI,IAAI,CAkBjB;YAEa,YAAY;IAS1B,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,IAAI,yBAAyB,IAAI,OAAO,CASvC;IAED,IAAI,gBAAgB,IAAI,OAAO,CAE9B;IAED,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE1C;IAED;;;;;;;OAOG;IACG,WAAW,CAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,OAAO,CAAC,EAAE;QACT,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,UAAU,CAAC,EAAE,cAAc,CAAC;QAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;KACpB,GACC,OAAO,CAAC,UAAU,CAAC,CA4BrB;IAED;;;;;;;;OAQG;IACG,WAAW,CAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACT,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;KACf,GACC,OAAO,CAAC,IAAI,CAAC,CA+Bf;YAEa,6BAA6B;YAK7B,iBAAiB;IAmFzB,gBAAgB,CACrB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,UAAU,EAClB,OAAO,CAAC,EAAE;QAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;KAAE,GACxC,OAAO,CAAC,IAAI,CAAC,CAoBf;IAED;;OAEG;IACH,SAAS,IAAI,IAAI,CAUhB;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,oEAAoE;IACpE,IAAI,sBAAsB,IAAI,OAAO,CAEpC;YAMa,yBAAyB;IAWvC,wBAAwB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAEzD;IAED,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAEvE;IAED,oBAAoB,IAAI,iBAAiB,CAExC;IAEK,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA8BxG;IAEK,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhD;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,sBAAsB,CAAoC;IAE5D,YAAY,CACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;QACR,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;KACV,GACJ,OAAO,CAAC;QACV,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,YAAY,CAAC,EAAE,kBAAkB,CAAC;KAClC,CAAC,CAaD;IAED,OAAO,CAAC,0BAA0B;YAuBpB,aAAa;YA4Cb,uBAAuB;IAuNrC,yBAAyB,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAE7E;IAED,OAAO,CAAC,uBAAuB;IAWzB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CA2C7C;IAEK,eAAe,IAAI,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAgBzD;IAED,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,sBAAsB;IAKxB,kBAAkB,IAAI,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAMnE;IAED;;;;;OAKG;IACG,cAAc,CAAC,MAAM,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAE7F;YAEa,eAAe;IA8E7B;;;;OAIG;IACG,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBvD;IAED;;;;;OAKG;IACG,aAAa,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAaxD;IAED;;;;OAIG;IACH,oBAAoB,IAAI,MAAM,GAAG,SAAS,CAsBzC;IAMD,4BAA4B,IAAI,sBAAsB,CAQrD;IAED,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/C;IAED,IAAI,eAAe,IAAI,eAAe,CAErC;CACD","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { randomUUID } from \"node:crypto\";\nimport { existsSync, mkdirSync, mkdtempSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport {\n\tAgent,\n\ttype AgentContext,\n\ttype AgentContinuationOutcome,\n\tAgentContinueError,\n\ttype AgentEvent,\n\ttype AgentMessage,\n\tAgentOutputLimitError,\n\ttype AgentOutputLimits,\n\ttype AgentState,\n\ttype AgentTool,\n\ttype AgentTurnOutcome,\n\ttype BoundToolExecution,\n\ttype GetContinuationMessagesContext,\n\ttype GetTurnOutcomeContext,\n\ttype ShouldStopAfterTurnContext,\n\ttype ThinkingLevel,\n} from \"@ponythewhite/base-context-agent\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tImageContent,\n\tModel,\n\tRequestTokenBudgetOptions,\n\tServiceTier,\n\tTextContent,\n\tUsage,\n\tUserMessage,\n} from \"@ponythewhite/base-context-ai\";\nimport {\n\tclampThinkingLevel,\n\tcleanupSessionResources,\n\tconservativeTextTokenCost,\n\tgetSupportedThinkingLevels,\n\tisContextOverflow,\n\tisTransientProviderFailure,\n\tmodelsAreEqual,\n\tresetApiProviders,\n\tsupportsFastMode,\n} from \"@ponythewhite/base-context-ai\";\nimport { theme } from \"../modes/interactive/theme/theme.js\";\nimport { PRODUCT } from \"../product-identity.js\";\n\nimport { sleep } from \"../utils/sleep.js\";\nimport {\n\tAGENT_MESSAGE_CUSTOM_TYPE,\n\tAGENT_MESSAGE_RECEIVED_PREVIEW_LABEL,\n\tAGENT_MESSAGE_SKILL_NAME,\n\ttype AgentFamilyCatalogEntry,\n\ttype AgentFamilyRosterResult,\n\ttype AgentSessionMessage,\n\ttype AgentSessionMessageAgentSummary,\n\ttype AgentSessionMessageController,\n\ttype AgentSessionMessageListResult,\n\ttype AgentSessionMessageReceipt,\n\tassertAgentMessageQueueCapacity,\n\tassertAgentSessionNameAvailable,\n\tassertDirectAgentMessageTarget,\n\tcreateAgentMessageHostHandlers,\n\tDEFAULT_AGENT_MESSAGE_MAX_PENDING_PER_SESSION,\n\tformatAgentSessionNameUnavailable,\n\tisAgentSessionMessage,\n\tisAgentSessionMessagePrompt,\n\tnormalizeAgentSessionMessage,\n\tparseAgentSessionMessagePromptId,\n\tstartsAgentRun,\n} from \"./agent-messages.js\";\nimport {\n\tAGENT_OBSERVE_SKILL_NAME,\n\ttype AgentObserveAgentSnapshot,\n\ttype AgentObserveController,\n\ttype AgentObserveListResult,\n\ttype AgentObserveRecentMessagesResult,\n\tcreateAgentObserveHostHandlers,\n\tnormalizeObserveLimit,\n\tnormalizeObserveMaxChars,\n\tORCHESTRATION_HEARTBEAT_SKILL_NAME,\n} from \"./agent-observe.js\";\nimport {\n\taddLoginGuidanceToAuthError,\n\tformatAuthenticationFailedMessage,\n\tformatNoApiKeyFoundMessage,\n\tformatNoModelSelectedMessage,\n\tisLikelyAuthenticationError,\n} from \"./auth-guidance.js\";\nimport type { AuthSourceToken } from \"./auth-storage.js\";\nimport {\n\ttype AgentAutonomousConfig,\n\ttype AgentAutonomousStatus,\n\ttype AutonomousRuntimeState,\n\taddAutonomousContinuation,\n\taddAutonomousUsage,\n\tautonomousRunLimitReason,\n\tautonomousStatus,\n\tcreateAutonomousRuntimeState,\n\tnextAutonomousContinuation,\n\trefreshAutonomousQualityGates,\n\tsetAutonomousEnabled,\n} from \"./autonomous.js\";\nimport { type BashResult, executeBashWithOperations } from \"./bash-executor.js\";\nimport { stringifyBoundedJson } from \"./bounded-json.js\";\nimport {\n\tCanonicalContextCompiler,\n\tcanonicalRecoveryBoundary,\n\tgetCanonicalEpochContext,\n\tgetCanonicalMessageSource,\n\tgetCanonicalViewSelectionSource,\n\tgetCanonicalViewUnits,\n\tMissingRecoveryReplayContractError,\n\tprepareCanonicalEpoch,\n\tprepareContextModeEpoch,\n\tprepareRecoveryCompaction,\n\treadCanonicalContextMode,\n} from \"./canonical-context.js\";\nimport {\n\ttype BranchSummaryResult,\n\tCOMPACT_SKILL_NAME,\n\ttype CompactionPreparation,\n\ttype CompactionResult,\n\tcalculateContextTokens,\n\tcollectEntriesForBranchSummary,\n\tcompact,\n\testimateContextTokens,\n\testimateFixedCompactionTokens,\n\tgenerateBranchSummary,\n\tprepareCompaction,\n\tprepareViewCompaction,\n\tserializeConversation,\n\tshouldCompact,\n\ttakeNativeBranchSummaryWrite,\n} from \"./compaction/index.js\";\nimport {\n\tappendContextEpoch,\n\tassertContextRequestContract,\n\tCONTEXT_EPOCH_DETAIL,\n\tCONTEXT_SKILL_EPOCH_RENDERER,\n\ttype ContextMode,\n\ttype ContextReplayContract,\n\tcontextEpochMode,\n\tcontextEpochRepresentation,\n\tcontextRequestContract,\n\treadContextEpoch,\n\tretainedContextRequestContract,\n\tsnapshotContextEpoch,\n\tUnsupportedContextEpochConfigurationError,\n} from \"./context-epoch.js\";\nimport {\n\ttype ContextTreeNode,\n\tContextTreeRequest,\n\ttype ContextTreeRequestLimits,\n\ttype ContextWindowResolver,\n\tcomputeOwnAndTotalUsage,\n\tloadContextTreeChildFromDisk,\n\tloadContextTreeChildrenFromDisk,\n\treadContextTreeUsage,\n\treadResidentContextTreeUsage,\n} from \"./context-tree.js\";\nimport type { AgentCronJob, AgentRlmHeartbeatController, AgentRlmHeartbeatStatusUpdate } from \"./cron-jobs.js\";\nimport { normalizeHeartbeatDeliveryMode } from \"./cron-jobs.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport { exportSessionToHtml, type ToolHtmlRenderer } from \"./export-html/index.js\";\nimport { createToolHtmlRenderer } from \"./export-html/tool-renderer.js\";\nimport {\n\ttype ContextUsage,\n\ttype ExtensionCommandContextActions,\n\ttype ExtensionErrorListener,\n\tExtensionRunner,\n\ttype ExtensionUIContext,\n\ttype InputSource,\n\ttype MessageEndEvent,\n\ttype MessageStartEvent,\n\ttype MessageUpdateEvent,\n\ttype ReplacedSessionContext,\n\ttype SessionBeforeCompactResult,\n\ttype SessionBeforeRefineResult,\n\ttype SessionBeforeTreeResult,\n\ttype SessionStartEvent,\n\ttype ShutdownHandler,\n\ttype ToolDefinition,\n\ttype ToolExecutionEndEvent,\n\ttype ToolExecutionStartEvent,\n\ttype ToolExecutionUpdateEvent,\n\ttype ToolInfo,\n\ttype TreePreparation,\n\ttype TurnEndEvent,\n\ttype TurnStartEvent,\n\twrapRegisteredTools,\n} from \"./extensions/index.js\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.js\";\nimport {\n\tcreateGoalContextMessage,\n\temptyGoalState,\n\tGOAL_CONTEXT_CUSTOM_TYPE,\n\tGOAL_CONTEXT_PREVIEW_LABEL,\n\tGOAL_SKILL_NAME,\n\tGOAL_STATE_CUSTOM_TYPE,\n\ttype GoalHostResponse,\n\ttype GoalState,\n\ttype GoalStatus,\n\tgoalHostResponse,\n\tgoalTokenDeltaForUsage,\n\tisPersistedGoalState,\n\tnormalizeGoalState,\n\tvalidateGoalBudget,\n\tvalidateGoalObjective,\n} from \"./goals.js\";\nimport type { ContextManifestCursor, ContextRef, IpythonSentMessagesCursor } from \"./history-index.js\";\nimport {\n\tcaptureNativeBranchRequests,\n\tcaptureNativeCompactionRequests,\n\tcaptureNativePlannerRequests,\n\tcaptureNativeReviewerRequests,\n\tInferenceCoordinator,\n\ttype SessionRuntimeServices,\n\ttakeNativeInferenceAuthSource,\n} from \"./inference-coordinator.js\";\nimport type { HostRequestHandlers, KernelSentAgentMessage } from \"./kernel/index.js\";\nimport { type RestoreResult, snapshotPathIn } from \"./kernel/state-snapshot.js\";\nimport type { AcpMcpServerConfig } from \"./mcp/acp-mcp-types.js\";\nimport type { McpManager } from \"./mcp/mcp-manager.js\";\nimport {\n\ttype BashExecutionMessage,\n\ttype CompactionOutcome,\n\ttype CompactionOutcomeReason,\n\ttype CustomMessage,\n\tconvertToLlm,\n\tcreateCompactionOutcomeMessage,\n\tcreateHeartbeatPromptMessage,\n\tcreateRefinementOutcomeMessage,\n\tcreateRlmChildFailureMessage,\n\tcreateRlmChildTerminalNoticeMessage,\n\tcreateSessionSlashCommandMessage,\n\tcreateSessionSlashCommandResultMessage,\n\tHARNESS_SNAPSHOT_CUSTOM_TYPE,\n\tHEARTBEAT_PROMPT_CUSTOM_TYPE,\n\tHEARTBEAT_PROMPT_PREVIEW_LABEL,\n\tIPYTHON_STATE_RESTORED_CUSTOM_TYPE,\n\tisSessionSlashCommandMessage,\n\tRLM_CHILD_FAILURE_CUSTOM_TYPE,\n\tRLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE,\n} from \"./messages.js\";\nimport type { ModelRegistry } from \"./model-registry.js\";\nimport { throwIfPromptAdmissionCancelled } from \"./prompt-admission.js\";\nimport { expandPromptTemplate, type PromptTemplate } from \"./prompt-templates.js\";\nimport {\n\ttype AutoRefineReason,\n\ttype AutoRefineReview,\n\tappendGlobalRefinement,\n\tapplyRefinementProposal,\n\tformatHarnessStateForPrompt,\n\tgenerateRefinementId,\n\tgetGlobalHarnessStateDir,\n\tgetLocalHarnessStateDir,\n\tgetRefinementHistory,\n\tgetWorkspaceHarnessStateDir,\n\ttype HarnessState,\n\tinferRefinementResultScope,\n\tloadGlobalRefinementHistory,\n\tloadHarnessState,\n\tmergeHarnessStates,\n\tmergeRefinementHistory,\n\tnormalizeRefinementProposal,\n\tplanRefinement,\n\tprepareRefinementApplication,\n\tREFINE_SKILL_NAME,\n\ttype RefinementPlan,\n\ttype RefinementResult,\n\treviewAutoRefine,\n\tsaveHarnessState,\n\ttakeNativePlannerRequestWrite,\n\twithRefinementBaseline,\n} from \"./refinement/index.js\";\nimport { getRecoveryCompactionAuthorization, PublicContextBudgetError } from \"./request-view-selection.js\";\nimport { resolveConfigValue } from \"./resolve-config-value.js\";\nimport type { ResourceExtensionPaths, ResourceLoader } from \"./resource-loader.js\";\nimport { assertResourceCurrent, type OwnedResourceCapture } from \"./resource-view.js\";\nimport {\n\ttype CreateRlmSubagentRuntimeOptions,\n\tcreateDefaultRlmSubagentSessionName,\n\tcreateRlmDeleteSubagentHostHandler,\n\tcreateRlmFindModelsHostHandler,\n\tcreateRlmListSubagentsHostHandler,\n\tcreateRlmRunHostHandler,\n\tfindRlmModelMatches,\n\tnormalizeRequestedRlmSubagentModel,\n\tnormalizeRequestedRlmSubagentSessionName,\n\tnormalizeRequestedRlmSubagentThinkingLevel,\n\ttype RlmChildAdmission,\n\ttype RlmDeleteSubagentResult,\n\ttype RlmFindModelsResult,\n\ttype RlmListSubagentsResult,\n\ttype RlmSpawnHandle,\n\ttype RlmSubagentRegistryEntry,\n\ttype RlmSubagentRuntime,\n\ttype SubagentRuntimeHost,\n} from \"./rlm-runtime.js\";\nimport {\n\ttype CapturedSkillSelectionWriter,\n\tcaptureSelectedSkill,\n\tcaptureSkillDescriptor,\n\ttype NativeSkillSourceRef,\n\treadSkillSelection,\n\ttype SelectedSkillCapture,\n\tsameSelectedSkills,\n\tselectedSkillBlock,\n\tselectedSkillIdentity,\n} from \"./selected-skills.js\";\nimport {\n\tcreateNativeRecoveryRefusal,\n\tDEFAULT_NATIVE_RECOVERY_LIMITS,\n\tNativeRecoveryBudgetRefusal,\n\tNativeRecoveryCursorStore,\n\ttype NativeRecoveryInput,\n\ttype NativeRecoveryResponse,\n\tparseNativeRecoveryInput,\n\trecoverCapturedHistory,\n} from \"./selective-recovery.js\";\nimport {\n\tmodelRequestHeaders,\n\tSemanticEdgeRecorder,\n\tsemanticEdgeLedgerPath,\n\twrapStreamFnWithSemanticEdges,\n} from \"./semantic-edges.js\";\nimport {\n\tActionStore,\n\ttype ActionTicket,\n\tcanSelectSessionAction,\n\ttype DeliveryPolicy,\n\ttype DeliveryRecord,\n\ttype QueuedMessageLane,\n\ttype QueuedMessageMutation,\n\ttype QueuedMessageMutationStatus,\n\tqueuedMessageLaneDeliveryPolicy,\n\ttype RuntimeActivity,\n\ttype SessionAction,\n\ttype SessionActionSnapshot,\n\ttype SessionCommandPayload,\n\ttype SessionTurnPayload,\n\ttransitionSessionAction,\n\ttype WakePolicy,\n} from \"./session-action-store.js\";\nimport { readSessionBootstrap } from \"./session-bootstrap.js\";\nimport {\n\tappendSentAgentMessageToToolResult,\n\tIPYTHON_SENT_AGENT_MESSAGE_CUSTOM_ENTRY,\n\tparsePersistedIpythonSentAgentMessage,\n} from \"./session-context-updates.js\";\nimport { ContextUsageReader } from \"./session-context-usage.js\";\nimport {\n\tbindNativeEntryWriter,\n\ttype CapturedNativeGoalWrite,\n\ttype CapturedNativeMessageWrite,\n\ttype NativeEntryOrigin,\n\ttype NativeEntryWriter,\n\ttype NativeSubmittedInput,\n} from \"./session-entry-origin.js\";\nimport { readUserMessagesForForking } from \"./session-fork-messages.js\";\nimport {\n\thydrateCapturedHistoryEntry,\n\ttype SessionHistoryReadLimits,\n\ttype SessionHistoryReadView,\n} from \"./session-history-index.js\";\nimport { exportSessionBranchToJsonl } from \"./session-jsonl-export.js\";\nimport {\n\ttype BoundCompactionSink,\n\ttype BranchSummaryEntry,\n\tgetLatestCompactionEntry,\n\ttype SessionContext,\n\ttype SessionEntry,\n\tSessionManager,\n} from \"./session-manager.js\";\nimport type { SessionStats } from \"./session-stats.js\";\nimport type { SettingsManager } from \"./settings-manager.js\";\nimport { getPythonSkillRuntimeInfo, type Skill } from \"./skills.js\";\n\nimport {\n\tparseRefineCommandOptions,\n\tparseSessionSlashCommand,\n\tparseSlashCommand,\n\ttype SessionSlashCommand,\n\ttype SlashCommandInfo,\n} from \"./slash-commands.js\";\nimport { createSyntheticSourceInfo, type SourceInfo } from \"./source-info.js\";\nimport { type BuildSystemPromptOptions, buildSystemPrompt } from \"./system-prompt.js\";\nimport { THINKING_LEVELS } from \"./thinking-levels.js\";\nimport { acpMcpToolNames, createAcpMcpToolDefinitions } from \"./tools/acp-mcp.js\";\nimport { type BashOperations, createLocalBashOperations } from \"./tools/bash.js\";\nimport { createAllToolDefinitions } from \"./tools/index.js\";\nimport { IpythonKernelProvisioner } from \"./tools/ipython.js\";\nimport { createToolDefinitionFromAgentTool } from \"./tools/tool-definition-wrapper.js\";\nimport { type SessionUsageSummary, sessionUsageSummaryFrom } from \"./usage.js\";\nimport { SERPER_CREDENTIAL_ID, SERPER_ENV_VAR, WEBSEARCH_SKILL_NAME } from \"./websearch-credential.js\";\n\n// The native owner reads its actual provisioner, not a replaceable public reader method.\nconst captureOwnedKernelState = IpythonKernelProvisioner.prototype.captureKernelState;\n\nexport type { GoalState, GoalStatus } from \"./goals.js\";\nexport type { SessionStats } from \"./session-stats.js\";\nexport { type ParsedSkillBlock, parseSkillBlock } from \"./skill-blocks.js\";\n\nexport type RlmChildAgentStatus = \"queued\" | \"running\" | \"done\" | \"error\" | \"cancelled\";\n\nexport interface RlmChildAgentActivity {\n\tkind: \"waiting\" | \"writing\" | \"executing\";\n\ttoolName?: string;\n}\n\nexport interface RlmChildAgentSnapshot {\n\tid: string;\n\tparentId?: string;\n\tactiveSessionId?: string;\n\tsessionName?: string;\n\tmodel?: string;\n\tlabel: string;\n\tstatus: RlmChildAgentStatus;\n\tdurationMs?: number;\n\tanswerPreview?: string;\n\ttoolUseCount?: number;\n\ttokenCount?: number;\n\trecap?: string;\n\tsessionDir: string;\n\tactivity?: RlmChildAgentActivity;\n\trepliedSinceTask?: boolean;\n\terror?: string;\n}\n\nexport type CompactionReason = \"manual\" | \"threshold\" | \"overflow\" | \"requested\";\n\nexport type AgentSessionEvent =\n\t| AgentEvent\n\t| {\n\t\t\ttype: \"ipython_sent_agent_message\";\n\t\t\ttoolCallId: string;\n\t\t\tmessage: KernelSentAgentMessage;\n\t }\n\t| { type: \"session_action_update\"; actions: SessionActionSnapshot }\n\t| {\n\t\t\ttype: \"compaction_start\";\n\t\t\treason: CompactionReason;\n\t\t\tcustomInstructions?: string;\n\t }\n\t| { type: \"session_info_changed\"; name: string | undefined }\n\t| { type: \"thinking_level_changed\"; level: ThinkingLevel }\n\t| { type: \"service_tier_changed\"; serviceTier: ServiceTier }\n\t| {\n\t\t\ttype: \"compaction_end\";\n\t\t\treason: CompactionReason;\n\t\t\tresult: CompactionResult | undefined;\n\t\t\taborted: boolean;\n\t\t\twillRetry: boolean;\n\t\t\terrorMessage?: string;\n\t\t\terrorSeverity?: \"warning\" | \"error\";\n\t\t\tcustomInstructions?: string;\n\t }\n\t| {\n\t\t\ttype: \"auto_retry_start\";\n\t\t\tattempt: number;\n\t\t\tmaxAttempts?: number;\n\t\t\tdelayMs: number;\n\t\t\terrorMessage: string;\n\t }\n\t| {\n\t\t\ttype: \"auto_retry_end\";\n\t\t\tsuccess: boolean;\n\t\t\tattempt: number;\n\t\t\tfinalError?: string;\n\t }\n\t| {\n\t\t\ttype: \"auth_stale\";\n\t\t\tprovider: string;\n\t\t\tsourceTokens?: readonly AuthSourceToken[];\n\t }\n\t| { type: \"rlm_child_update\"; child: RlmChildAgentSnapshot }\n\t| { type: \"recap_update\"; recap: string | undefined }\n\t| { type: \"goal_update\"; goal: GoalState }\n\t| {\n\t\t\ttype: \"bash_start\";\n\t\t\tcommand: string;\n\t\t\texcludeFromContext: boolean;\n\t\t\ttransient?: boolean;\n\t\t\trunId?: string;\n\t }\n\t| { type: \"bash_output\"; chunk: string }\n\t| {\n\t\t\ttype: \"bash_end\";\n\t\t\texitCode: number | undefined;\n\t\t\tcancelled: boolean;\n\t\t\ttruncated: boolean;\n\t\t\tfullOutputPath?: string;\n\t\t\terrorMessage?: string;\n\t\t\ttransient?: boolean;\n\t\t\trunId?: string;\n\t }\n\t| { type: \"refine_complete\"; result: RefinementResult }\n\t| { type: \"refine_failed\"; error: string };\n\nexport type AgentSessionEventListener = (event: AgentSessionEvent) => void;\n\ntype UserBashEndDetails = {\n\texitCode: number | undefined;\n\tcancelled: boolean;\n\ttruncated: boolean;\n\tfullOutputPath?: string;\n\terrorMessage?: string;\n};\n\nexport class CompactionSkippedError extends Error {}\n\ninterface CompactionCommit {\n\tentryId: string;\n\tresult: CompactionResult;\n}\n\n/** The canonical compaction is already ACKed; only subsequent setup failed. */\nexport class CompactionCommittedError extends Error {\n\tconstructor(\n\t\treadonly entryId: string,\n\t\treadonly result: CompactionResult,\n\t\tcause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Compaction ${entryId} committed, but setup failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\t{ cause },\n\t\t);\n\t\tthis.name = \"CompactionCommittedError\";\n\t}\n}\n\nfunction primaryCommittedCompactionError(error: unknown): CompactionCommittedError | undefined {\n\twhile (error instanceof AggregateError) error = error.errors[0];\n\treturn error instanceof CompactionCommittedError ? error : undefined;\n}\n\n/** Thrown when a session_before_refine extension skips the refinement round. */\nexport class RefineSkippedError extends Error {}\n\nexport interface AgentSessionConfig {\n\t/** Explicit request budget profiles; absent preserves control behavior. */\n\trequestTokenBudget?: RequestTokenBudgetOptions;\n\tcontextMode?: ContextMode;\n\t/** Override native invocationOutput settings; complete finalized values or explicit refusal. */\n\tinvocationOutputLimits?: AgentOutputLimits;\n\tagent: Agent;\n\tsessionManager: SessionManager;\n\tsettingsManager: SettingsManager;\n\tserviceTierPreference?: ServiceTier;\n\tcwd: string;\n\tagentDir?: string;\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\tresourceLoader: ResourceLoader;\n\tcustomTools?: ToolDefinition[];\n\tmodelRegistry: ModelRegistry;\n\tinitialActiveToolNames?: string[];\n\tallowedToolNames?: string[];\n\t/**\n\t * Whether the built-in long-running goals feature is available: the bundled\n\t * goal skill in the Python kernel, its goal.* host handlers, and /goal.\n\t * Default: true.\n\t */\n\tincludeGoals?: boolean;\n\tagentMessageController?: AgentSessionMessageController;\n\tagentObserveController?: AgentObserveController;\n\t/**\n\t * Whether the bundled compact skill and its compact.* host handlers are\n\t * available to the model. Default: the compaction.agentCallable setting.\n\t */\n\tincludeCompactSkill?: boolean;\n\t/**\n\t * Optional host-side controller for the bundled rlm-heartbeat Python skill.\n\t * When omitted, rlm_heartbeat.* host requests are unavailable.\n\t */\n\trlmHeartbeatController?: AgentRlmHeartbeatController;\n\t/**\n\t * Optional MCP integration manager. When present, its mcp.* host requests\n\t * (refresh, begin_login) are exposed to the kernel.\n\t */\n\tmcpManager?: McpManager;\n\t/**\n\t * Override base tools (useful for custom runtimes).\n\t *\n\t * These are synthesized into minimal ToolDefinitions internally so AgentSession can keep\n\t * a definition-first registry even when callers provide plain AgentTool instances.\n\t */\n\tbaseToolsOverride?: Record<string, AgentTool>;\n\textensionRunnerRef?: { current?: ExtensionRunner };\n\tsessionStartEvent?: SessionStartEvent;\n\trlmDepth?: number;\n\trlmMaxDepth?: number;\n\trlmSessionDir?: string;\n\trlmParentNodeId?: string;\n\trlmParentAgent?: string;\n\trlmChildAdmission?: RlmChildAdmission;\n\trlmSubagentCapacity?: RlmSubagentCapacity;\n\trlmRootAdmission?: RlmRootAdmission;\n\tsemanticParentSessionId?: string;\n\tsemanticSpawnedByRequestId?: string;\n\tsubagentRuntimeHost?: SubagentRuntimeHost;\n\tautonomous?: AgentAutonomousConfig;\n\tprewarmIpythonKernel?: boolean;\n\tautoRefineReviewer?: AutoRefineReviewer;\n\t/**\n\t * When true, auto-refine runs synchronously between turns at the\n\t * shouldStopAfterTurn boundary instead of in the background after\n\t * agent_end. Used for print/headless autonomous runs so refinement\n\t * never overlaps the primary model request. Default: false.\n\t */\n\tserializedRefine?: boolean;\n\t/**\n\t * Initial goal to seed at session creation. Only applied when rlmDepth\n\t * is 0 and no persisted thread_goal_state entry exists in the branch.\n\t */\n\tinitialGoal?: { objective: string; tokenBudget?: number };\n}\n\nexport interface ExtensionBindings {\n\tuiContext?: ExtensionUIContext;\n\tcommandContextActions?: ExtensionCommandContextActions;\n\tshutdownHandler?: ShutdownHandler;\n\tonError?: ExtensionErrorListener;\n}\n\nexport interface AutoRefineReviewRequest {\n\treason: AutoRefineReason;\n\tturnsSinceLastReview: number;\n}\n\n/**\n * Discriminated result from a serialized-mode background planning pass.\n * - \"plan\": review approved and planning succeeded; carry the exact plan,\n * options, and abort controller so the boundary can apply directly\n * without a second planning request.\n * - \"skip\": reviewer declined; no refine needed.\n * - \"failure\": review or planning threw; boundary should not retry.\n */\nexport type SerializedBackgroundPlanResult =\n\t| {\n\t\t\tstatus: \"plan\";\n\t\t\tplan: RefinementPlan;\n\t\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean };\n\t\t\tabort: AbortController;\n\t\t\tbranchVersion: number;\n\t }\n\t| { status: \"skip\"; explicit?: boolean }\n\t| { status: \"invalidated\"; branchVersion: number }\n\t| {\n\t\t\tstatus: \"failure\";\n\t\t\texplicit: boolean;\n\t\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean };\n\t\t\tbranchVersion: number;\n\t };\n\nexport type AutoRefineReviewer = (request: AutoRefineReviewRequest, signal?: AbortSignal) => Promise<AutoRefineReview>;\n\nexport interface PromptOptions {\n\texpandPromptTemplates?: boolean;\n\timages?: ImageContent[];\n\tstreamingBehavior?: \"steer\" | \"followUp\";\n\tfollowUpQueueKey?: string;\n\tsource?: InputSource;\n\tpreflightResult?: (success: boolean, queued?: boolean) => void;\n\tqueueIfBusy?: boolean;\n\tresumeIfIdle?: boolean;\n\tinternalPrompt?: boolean;\n\tsuppressAutonomousContinuation?: boolean;\n\tskipInputHandlers?: boolean;\n\tsignal?: AbortSignal;\n\tadmissionCommitted?: () => void;\n\tagentMessageId?: string;\n\tcontent?: (TextContent | ImageContent)[];\n\tcustomMessage?: CustomMessage;\n}\n\ninterface InternalPromptOptions extends PromptOptions {\n\tskipPrePromptWork?: boolean;\n\treturnAfterAccepted?: boolean;\n\tagentMessageId?: string;\n}\n\ntype SubmissionExtensionCommandPolicy = \"execute\" | \"reject\" | \"ignore\";\n\ninterface SubmissionNormalizationPolicy {\n\tparseSessionCommands: boolean;\n\textensionCommands: SubmissionExtensionCommandPolicy;\n\tinputSource?: InputSource;\n\texpandSkills: boolean;\n\texpandPromptTemplates: boolean;\n}\n\ntype NormalizedSubmission =\n\t| {\n\t\t\tkind: \"prompt\";\n\t\t\ttext: string;\n\t\t\timages?: ImageContent[];\n\t\t\tselectedSkillRef?: NativeSkillSourceRef;\n\t\t\tassertSkillCurrent?: () => void;\n\t }\n\t| {\n\t\t\tkind: \"sessionCommand\";\n\t\t\ttext: string;\n\t\t\timages?: ImageContent[];\n\t\t\tcommand: SessionSlashCommand;\n\t }\n\t| { kind: \"extensionCommand\"; completion: Promise<void> }\n\t| { kind: \"handled\" };\n\ninterface NativeSkillSelectionOwner {\n\tmanager: SessionManager;\n\tsessionId: string;\n\tsessionFile: string | undefined;\n\twriter: CapturedSkillSelectionWriter;\n\tinputEpoch?: number;\n}\n\ninterface SkillCommandExpansion {\n\ttext: string;\n\tselectedSkillRef?: NativeSkillSourceRef;\n\tassertSkillCurrent: () => void;\n}\n\ntype PreTurnCompactionTiming = \"beforeModelSelection\" | \"afterModelSelection\" | \"skip\";\ntype RefineBarrierPolicy = \"always\" | \"ifInFlight\" | \"skip\";\n\ninterface CommitPreparationPolicy {\n\tinitialRefineBarrier: RefineBarrierPolicy;\n\tflushPendingBashBeforeValidation: boolean;\n\tvalidateModelAndAuth: boolean;\n\tawaitPendingModelSelection: boolean;\n\tpreTurnCompaction: PreTurnCompactionTiming;\n\tfinalRefineBarrier: RefineBarrierPolicy;\n}\n\ninterface CommitPreparationSteps<TPrepared, TCommitted> {\n\tafterValidation?: () => void;\n\tprepare: () => Promise<TPrepared>;\n\tshouldCommit?: (prepared: TPrepared) => boolean;\n\tbeforeFinalRefineBarrier?: (prepared: TPrepared) => void;\n\tcommit: (prepared: TPrepared, passedFinalRefineBarrier: boolean) => TCommitted;\n}\n\ntype QueuedAgentMessage = UserMessage | CustomMessage;\ntype SessionInputSchedule = \"steer\" | \"followUp\";\n\nexport interface TurnExecutionPolicy {\n\tpreparation: CommitPreparationPolicy;\n\trunBeforeAgentStart: boolean;\n\tnextTurnContextTiming: \"preparation\" | \"commit\" | \"skip\";\n\tpreserveEmptyExtensionPrompt: boolean;\n\tcompletionIncludesRetryChain: boolean;\n}\n\nfunction turnExecutionPoliciesEqual(left: TurnExecutionPolicy, right: TurnExecutionPolicy): boolean {\n\treturn (\n\t\tleft.preparation.initialRefineBarrier === right.preparation.initialRefineBarrier &&\n\t\tleft.preparation.flushPendingBashBeforeValidation === right.preparation.flushPendingBashBeforeValidation &&\n\t\tleft.preparation.validateModelAndAuth === right.preparation.validateModelAndAuth &&\n\t\tleft.preparation.awaitPendingModelSelection === right.preparation.awaitPendingModelSelection &&\n\t\tleft.preparation.preTurnCompaction === right.preparation.preTurnCompaction &&\n\t\tleft.preparation.finalRefineBarrier === right.preparation.finalRefineBarrier &&\n\t\tleft.runBeforeAgentStart === right.runBeforeAgentStart &&\n\t\tleft.nextTurnContextTiming === right.nextTurnContextTiming &&\n\t\tleft.preserveEmptyExtensionPrompt === right.preserveEmptyExtensionPrompt &&\n\t\tleft.completionIncludesRetryChain === right.completionIncludesRetryChain\n\t);\n}\n\ninterface PreparedTurnPayload extends SessionTurnPayload {\n\tsubmitted?: NativeSubmittedInput;\n\tselectedSkillRef?: NativeSkillSourceRef;\n\timages?: ImageContent[];\n\tcontent?: (TextContent | ImageContent)[];\n\tcustomMessage?: CustomMessage;\n\tprepared?: PreparedPromptPreparation;\n\texecutionPolicy: TurnExecutionPolicy;\n\tqueueVisible: boolean;\n\tacceptedAgentMessage: boolean;\n\tacceptedBeforeCompletion: boolean;\n\tcaptureRunMessages?: Set<AgentMessage>;\n\tcancelledDispatchEnded?: boolean;\n}\n\ninterface PreparedCommandPayload extends SessionCommandPayload {\n\tsubmitted?: NativeSubmittedInput;\n\timages?: ImageContent[];\n}\n\ntype QueuedSessionAction = SessionAction<PreparedTurnPayload | PreparedCommandPayload>;\n\ninterface PreparedPromptPreparation {\n\tresult: Awaited<ReturnType<ExtensionRunner[\"emitBeforeAgentStart\"]>>;\n\tbasePromptSnapshot: string;\n}\n\nclass DeferredSessionInputError extends Error {}\nclass StaleGoalContinuationError extends Error {}\n\ninterface GoalContinuationOwner {\n\tmanager: SessionManager;\n\tsessionId: string;\n\tsessionFile: string | undefined;\n\tpumpEpoch: number;\n\tgoal: GoalState;\n\tgoalRevision: number;\n\taccountingStartedAt: number | undefined;\n\tsignal: AbortSignal | undefined;\n\tcheckpointOwner?: CompactionOwner;\n}\n\nfunction oncePreflight(\n\tpreflightResult: ((success: boolean, queued?: boolean) => void) | undefined,\n): (success: boolean, queued?: boolean) => void {\n\tlet settled = false;\n\treturn (success, queued = false) => {\n\t\tif (!settled) {\n\t\t\tsettled = true;\n\t\t\tpreflightResult?.(success, queued);\n\t\t}\n\t};\n}\n\ninterface RestoredPromptInput {\n\ttext: string;\n\tcontent?: (TextContent | ImageContent)[];\n\timages?: ImageContent[];\n\tqueueKey?: string;\n\tagentMessageId?: string;\n\tcustomMessage?: CustomMessage;\n\tprefixMessages?: CustomMessage[];\n}\n\nexport const SESSION_ACTION_RECOVERY_FORMAT_VERSION = 1;\n/** Only snapshots carrying the new native source binding require this current-format discriminator. */\nexport const SESSION_ACTION_SKILL_RECOVERY_FORMAT_VERSION = 2;\n\nexport interface SessionActionRecoveryRecord {\n\tid: string;\n\trole: DeliveryRecord[\"role\"];\n\tmessage: QueuedAgentMessage;\n\townerActionId: string;\n}\n\nexport type SessionActionRecoveryPayload =\n\t| {\n\t\t\tkind: \"turn\";\n\t\t\tsubmitted?: NativeSubmittedInput;\n\t\t\tselectedSkillRef?: NativeSkillSourceRef;\n\t\t\ttext: string;\n\t\t\tpreview?: string;\n\t\t\trecords: SessionActionRecoveryRecord[];\n\t\t\timages?: ImageContent[];\n\t\t\tcontent?: (TextContent | ImageContent)[];\n\t\t\tcustomMessage?: CustomMessage;\n\t\t\texecutionPolicy: TurnExecutionPolicy;\n\t\t\tqueueVisible: boolean;\n\t\t\tacceptedAgentMessage: boolean;\n\t\t\tacceptedBeforeCompletion: boolean;\n\t }\n\t| {\n\t\t\tkind: \"session_command\";\n\t\t\tsubmitted?: NativeSubmittedInput;\n\t\t\ttext: string;\n\t\t\tcommand: SessionSlashCommand;\n\t\t\timages?: ImageContent[];\n\t };\n\nexport interface SessionActionRecoveryAction {\n\tid: string;\n\tsource: InputSource | \"internal\";\n\tdelivery: DeliveryPolicy;\n\twake: WakePolicy;\n\tpayload: SessionActionRecoveryPayload;\n\tqueueKey?: string;\n\tagentMessageId?: string;\n\tsuppressAutonomousContinuation?: boolean;\n}\n\nexport interface SessionActionRecoverySnapshot {\n\tformatVersion: typeof SESSION_ACTION_RECOVERY_FORMAT_VERSION | typeof SESSION_ACTION_SKILL_RECOVERY_FORMAT_VERSION;\n\tactions: SessionActionRecoveryAction[];\n}\n\ntype GoalOperationOrigin = Extract<NativeEntryOrigin, { kind: \"goal_operation\" }>;\ntype GoalOriginContext = Pick<GoalOperationOrigin, \"actor\" | \"actionId\" | \"submittedText\"> & {\n\twriter: NativeEntryWriter;\n};\n\nfunction captureSubmittedInput(\n\ttext: string,\n\tinput: { content?: (TextContent | ImageContent)[]; images?: ImageContent[] } = {},\n): NativeSubmittedInput {\n\treturn structuredClone({ text, content: input.content, images: input.images });\n}\n\nfunction cloneCustomMessage(message: CustomMessage): CustomMessage {\n\treturn {\n\t\t...message,\n\t\tcontent: Array.isArray(message.content) ? message.content.map((block) => ({ ...block })) : message.content,\n\t};\n}\n\nfunction cloneQueuedAgentMessage(message: QueuedAgentMessage): QueuedAgentMessage {\n\tif (message.role === \"custom\") return cloneCustomMessage(message);\n\treturn {\n\t\t...message,\n\t\tcontent: Array.isArray(message.content) ? message.content.map((block) => ({ ...block })) : message.content,\n\t};\n}\n\nfunction primaryDeliveryRecord(action: QueuedSessionAction): DeliveryRecord {\n\tif (action.payload.kind !== \"turn\") throw new Error(`Session action ${action.id} is not a turn`);\n\tconst record = action.payload.records.find((candidate) => candidate.role === \"primary\");\n\tif (!record) throw new Error(`Turn action ${action.id} has no primary delivery record`);\n\treturn record;\n}\n\nfunction normalizeMessageContent(content: string | (TextContent | ImageContent)[]): {\n\ttext: string;\n\timages?: ImageContent[];\n} {\n\tif (typeof content === \"string\") return { text: content };\n\tconst text = content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n\tconst images = content.filter((part): part is ImageContent => part.type === \"image\");\n\treturn { text, ...(images.length > 0 ? { images } : {}) };\n}\n\nfunction isFamilyAgentMessageAction(action: QueuedSessionAction): action is SessionAction<PreparedTurnPayload> {\n\tif (action.payload.kind !== \"turn\") return false;\n\tconst message = primaryDeliveryRecord(action).message;\n\treturn isAgentSessionMessage(message) && message.details.fromRelationship !== undefined;\n}\n\nfunction queuedAgentMessagePreview(action: QueuedSessionAction): string {\n\tconst payload = action.payload;\n\tif (payload.kind === \"session_command\") return payload.text;\n\tif (payload.customMessage && isAgentSessionMessage(payload.customMessage)) {\n\t\treturn `${AGENT_MESSAGE_RECEIVED_PREVIEW_LABEL}: ${payload.customMessage.details.message}`;\n\t}\n\treturn payload.preview ?? payload.text;\n}\n\nfunction visibleSessionActionProjection(actions: readonly QueuedSessionAction[]): readonly QueuedSessionAction[] {\n\treturn actions.filter(\n\t\t(action) =>\n\t\t\taction.payload.kind === \"session_command\" ||\n\t\t\taction.payload.queueVisible ||\n\t\t\taction.payload.acceptedAgentMessage,\n\t);\n}\n\nfunction injectedMessagePreviewLabel(message: CustomMessage): string | undefined {\n\tswitch (message.customType) {\n\t\tcase HEARTBEAT_PROMPT_CUSTOM_TYPE:\n\t\t\treturn HEARTBEAT_PROMPT_PREVIEW_LABEL;\n\t\tcase GOAL_CONTEXT_CUSTOM_TYPE:\n\t\t\treturn GOAL_CONTEXT_PREVIEW_LABEL;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\ninterface AgentMessageDeferred {\n\tpromise: Promise<void>;\n\tresolve: () => void;\n\treject: (error: Error) => void;\n}\n\ninterface AgentMessageOutcome {\n\tdelivery?: AgentMessageDeferred;\n\tcompletion?: AgentMessageDeferred;\n}\n\nfunction createAgentMessageDeferred(): AgentMessageDeferred {\n\tconst deferred = {} as AgentMessageDeferred;\n\tdeferred.promise = new Promise<void>((resolve, reject) => {\n\t\tdeferred.resolve = resolve;\n\t\tdeferred.reject = reject;\n\t});\n\tdeferred.promise.catch(() => undefined);\n\treturn deferred;\n}\n\nclass StaleCompactionOwnerError extends Error {}\n\ninterface CompactionOwner {\n\tmanager: SessionManager;\n\tagent: Agent;\n\tsessionId: string;\n\tsessionFile: string | undefined;\n\tpumpEpoch: number;\n\tisSourceCurrent: () => boolean;\n\trequests: InferenceCoordinator;\n\tsemanticEdges: SemanticEdgeRecorder;\n\textensions: ExtensionRunner;\n\tprovisioner: IpythonKernelProvisioner | undefined;\n\tsignal: AbortSignal | undefined;\n}\n\ninterface CheckpointAction {\n\taction: QueuedSessionAction;\n\tticket: ActionTicket;\n}\n\ninterface CheckpointBoundary {\n\tkind: \"tool\" | \"overflow\" | \"request\";\n\tstate: \"pending\" | \"consumed\";\n}\n\ninterface CheckpointResume {\n\towner: CompactionOwner;\n\tboundary?: CheckpointBoundary;\n\tactions: CheckpointAction[];\n}\n\ninterface ThresholdGoalContinuation extends CheckpointAction {\n\towner: GoalContinuationOwner;\n}\n\ninterface ThresholdAutonomousOwner {\n\tstate: AutonomousRuntimeState;\n\tsnapshot: AutonomousRuntimeState;\n\tcwd: string;\n\tarrivalEpoch: number;\n}\n\ninterface ThresholdAutonomousContinuation extends CheckpointAction {\n\towner: CompactionOwner;\n\tstate: AutonomousRuntimeState;\n\tbefore: AutonomousRuntimeSnapshot;\n\tafter: AutonomousRuntimeState;\n}\n\n/** One-shot settlement for the same captured checkpoint directive; a settled failure is not re-exposed. */\ninterface PostCompactionContinuationSettlement extends AgentMessageDeferred {\n\tresume: CheckpointResume;\n\tsettled: boolean;\n}\n\nfunction createPostCompactionContinuationSettlement(resume: CheckpointResume): PostCompactionContinuationSettlement {\n\treturn { ...createAgentMessageDeferred(), resume, settled: false };\n}\n\nexport interface ModelCycleResult {\n\tmodel: Model<any>;\n\tthinkingLevel: ThinkingLevel;\n\tserviceTier: ServiceTier;\n\tisScoped: boolean;\n}\n\ninterface ModelSelectOptions {\n\twaitForExtensions?: boolean;\n}\n\ninterface ToolDefinitionEntry {\n\tdefinition: ToolDefinition;\n\tsourceInfo: SourceInfo;\n}\n\ntype GoalSlashCommand =\n\t| { kind: \"status\" }\n\t| { kind: \"clear\" }\n\t| { kind: \"pause\" }\n\t| { kind: \"resume\" }\n\t| { kind: \"start\"; objective: string; tokenBudget?: number };\n\ntype AutonomousSlashCommand = { kind: \"status\" } | { kind: \"on\" } | { kind: \"off\" };\n\nimport type { RlmMaxDepthSource, RlmMaxDepthStatus, SetRlmMaxDepthResult } from \"./rlm-max-depth.js\";\nimport {\n\tLocalRlmSubagentCapacity,\n\ttype RlmMaxSubagentsStatus,\n\ttype RlmRootAdmission,\n\ttype RlmSubagentCapacity,\n\ttype RlmSubagentCapacityReservation,\n} from \"./rlm-max-subagents.js\";\n\nexport type { RlmMaxDepthSource, RlmMaxDepthStatus, SetRlmMaxDepthResult } from \"./rlm-max-depth.js\";\n\ninterface PersistedRlmMaxDepthState {\n\tmaxDepth: number;\n}\n\ntype AutonomousRuntimeSnapshot = Pick<\n\tAutonomousRuntimeState,\n\t\"continuationsUsed\" | \"gateAttempts\" | \"lastGateFailure\" | \"lastGateFailureSnapshot\"\n>;\n\ninterface RlmChildRun {\n\tid: string;\n\tprompt: string;\n\tsessionName: string;\n\tsessionDir: string;\n\tmodel: Model<Api>;\n\tstatus: RlmChildAgentStatus;\n\tterminalAssistantOutcome?: Pick<AssistantMessage, \"stopReason\" | \"errorMessage\">;\n\tdurationMs?: number;\n\tanswerPreview?: string;\n\ttoolUseCount: number;\n\tactivity?: RlmChildAgentActivity;\n\terror?: string;\n\tabort: () => void;\n\tpublication: AgentMessageDeferred;\n\t/** Resolves after terminal result publication and detached-run cleanup finish. */\n\tsettlement: AgentMessageDeferred;\n\t/** Child session, once its runtime exists. Used to cancel nested child runs. */\n\tsession?: AgentSession;\n\tsettled: boolean;\n\t/** Do not inject a late terminal notice after the parent session is aborted. */\n\tsuppressTerminalNotice?: boolean;\n\t/** Excluded from future strong barriers after an authoritative cancellation cut. */\n\tabandonedForQuiescence?: boolean;\n\t/** Selector snapshot for an admitted explicit delete. */\n\tdetachedDeletion?: RlmSubagentRegistryEntry;\n\t/** Shared physical runtime cleanup owned by the explicit-delete path. */\n\tdeletionCleanup?: Promise<void>;\n\tdeletionCleanupObserver?: Promise<boolean>;\n\t/** Resolves when a deletion may release its selector reservation. */\n\tdeletionReservation: AgentMessageDeferred;\n\tdeletionCleanupFailed?: boolean;\n\tdeletionRunFinished?: boolean;\n\tdeletionNotice?: Promise<void>;\n\tdeletionNeedsCompletionNotice?: boolean;\n\tcompleteDeletion?: () => Promise<void>;\n\treportDeletionCleanupFailure?: (error: unknown) => Promise<void>;\n\temitUpdate?: () => void;\n\tlastEmittedUpdate?: string;\n\tunsubscribe?: () => void;\n}\n\ninterface RlmChildUsageSource {\n\tsessionId: string;\n\tsessionFile?: string;\n\tentryId: string;\n}\n\nconst RLM_PARENT_USAGE_CUSTOM_TYPE = \"rlm_parent_usage\";\n\ntype RlmChildUsageOrigin = \"spawn_task\" | \"agent_message\" | \"direct_user\";\n\ninterface RetainedRlmChild {\n\tsession: AgentSession;\n\trun?: RlmChildRun;\n}\n\ninterface RlmSubagentModelSelection {\n\tmodel: Model<Api>;\n}\n\nconst KERNEL_STATE_LISTING_TIMEOUT_MS = 5000;\nconst RLM_MAX_DEPTH_STATE_CUSTOM_TYPE = \"rlm_max_depth_state\";\n\nfunction noopRlmChildAbort(): void {}\nfunction noopRlmChildEventUnsubscribe(): void {}\n\nfunction autoRefineInstructions(reason: AutoRefineReason, review: AutoRefineReview): string {\n\tconst detail = review.instructions\n\t\t? `\nReviewer instructions: ${review.instructions}`\n\t\t: \"\";\n\treturn `Automatic refine review triggered by ${reason}. Only create/update/delete local harness entries if there is clear evidence that should help this session continue. Prefer an empty edits array over speculative or one-off memories. Do not promote anything global unless explicitly requested. Reviewer rationale: ${review.rationale}${detail}`;\n}\n\nfunction isNonNegativeInteger(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n\nfunction parseDepth(value: string | undefined, fallback: number, name: string): number {\n\tif (value === undefined || value === \"\") {\n\t\treturn fallback;\n\t}\n\tif (!/^\\d+$/.test(value)) {\n\t\tthrow new Error(`${name} must be a non-negative integer`);\n\t}\n\tconst parsed = Number(value);\n\tif (!isNonNegativeInteger(parsed)) {\n\t\tthrow new Error(`${name} must be a non-negative integer`);\n\t}\n\treturn parsed;\n}\n\nfunction isPersistedRlmMaxDepthState(value: unknown): value is PersistedRlmMaxDepthState {\n\treturn (\n\t\ttypeof value === \"object\" && value !== null && isNonNegativeInteger((value as PersistedRlmMaxDepthState).maxDepth)\n\t);\n}\n\nfunction parseGoalBudgetValue(value: string): number {\n\tif (!/^[1-9]\\d*$/.test(value)) {\n\t\tthrow new Error(\"Goal token budget must be a positive integer.\");\n\t}\n\tconst budget = validateGoalBudget(Number(value));\n\tif (budget === undefined) {\n\t\tthrow new Error(\"Goal token budget must be a positive integer.\");\n\t}\n\treturn budget;\n}\n\nexport function compactRlmText(text: string, maxLength = 160): string {\n\tconst compact = text.replace(/\\s+/g, \" \").trim();\n\tif (compact.length <= maxLength) {\n\t\treturn compact;\n\t}\n\treturn `${compact.slice(0, Math.max(0, maxLength - 3)).trimEnd()}...`;\n}\n\n// Child-agent label: collapse to one line but keep the full prompt — the TUI\n// truncates to the visible width and elides shared prefixes, so capping here\n// would only hide the divergence between near-identical sibling prompts.\nexport function rlmChildLabel(prompt: string): string {\n\treturn prompt.replace(/\\s+/g, \" \").trim() || \"child agent\";\n}\n\nfunction readAssistantText(message: AssistantMessage): string {\n\treturn message.content\n\t\t.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\");\n}\n\nfunction waitForPromiseOrAbort<T>(\n\tpromise: Promise<T>,\n\tsignal: AbortSignal | undefined,\n\tabortMessage: string,\n): Promise<T> {\n\tif (!signal) return promise;\n\tif (signal.aborted) return Promise.reject(new Error(abortMessage));\n\treturn new Promise<T>((resolve, reject) => {\n\t\tconst onAbort = () => {\n\t\t\tcleanup();\n\t\t\treject(new Error(abortMessage));\n\t\t};\n\t\tconst cleanup = () => signal.removeEventListener(\"abort\", onAbort);\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t// Close the listener-registration race before observing the awaited work.\n\t\tif (signal.aborted) return onAbort();\n\t\tpromise.then(\n\t\t\t(value) => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport class AgentSession {\n\treadonly agent: Agent;\n\treadonly sessionManager: SessionManager;\n\treadonly settingsManager: SettingsManager;\n\treadonly requests: InferenceCoordinator;\n\treadonly runtimeServices: SessionRuntimeServices;\n\tprivate readonly _contextCompiler = new CanonicalContextCompiler();\n\tprivate _failedAutomaticCompaction?: {\n\t\tkey: string;\n\t\tsystemPrompt: string;\n\t\ttools: Agent[\"state\"][\"tools\"];\n\t\tsettings: string;\n\t};\n\tprivate _failedThresholdCompaction?: {\n\t\tisCurrent: BoundCompactionSink[\"isCurrent\"];\n\t\tconfiguration: string;\n\t\tsystemPrompt: string;\n\t\ttools: Agent[\"state\"][\"tools\"];\n\t};\n\tprivate readonly _contextEpochsEnabled: boolean;\n\tprivate readonly _initialContextMode: ContextMode;\n\tprivate _contextMode: ContextMode;\n\tprivate _pendingContextModeChanges = 0;\n\tprivate readonly _contextUsageReader = new ContextUsageReader();\n\tprivate _compactionBoundaryCache?: {\n\t\tsessionId: string;\n\t\tsessionFile: string | undefined;\n\t\tentryId: string;\n\t\trevision: string;\n\t\ttimestamp: number;\n\t};\n\tprivate _contextOmissions?: { sessionId: string; sessionFile: string | undefined; ids: Set<string> };\n\tprivate _serviceTierPreference: ServiceTier;\n\n\tprivate _scopedModels: Array<{\n\t\tmodel: Model<any>;\n\t\tthinkingLevel?: ThinkingLevel;\n\t}>;\n\n\tprivate _unsubscribeAgent?: () => void;\n\tprivate _eventListeners: AgentSessionEventListener[] = [];\n\tprivate _lastSessionActionSnapshot: SessionActionSnapshot = {\n\t\tqueuedCount: 0,\n\t\tsteering: [],\n\t\tfollowUps: [],\n\t};\n\tprivate _agentEventQueue: Promise<void> = Promise.resolve();\n\n\t/** Session-owned actions. Items are never fed into Agent.steer/followUp. */\n\tprivate readonly _actionStore = new ActionStore<QueuedSessionAction>();\n\tprivate _sessionInputPump: Promise<void> = Promise.resolve();\n\tprivate _sessionInputPumpRequested = false;\n\t// Invalidates preparation when a branch pause starts and finishes before its next await resumes.\n\tprivate _sessionInputPumpEpoch = 0;\n\tprivate _sessionInputArrivalEpoch = 0;\n\t// Persists abort/restart suspension after the initiating call returns.\n\tprivate _sessionInputPumpSuspended = false;\n\tprivate _sessionInputSuspendedForUpdateRestart = false;\n\t// Branch mutation pause leases can overlap and must all release before dispatch resumes.\n\tprivate readonly _queuedWorkPauses = new Set<symbol>();\n\tprivate readonly _sessionInputAdmissionPauses = new Set<symbol>();\n\tprivate readonly _durableRlmTerminalNoticeActionIds = new Set<string>();\n\tprivate _sessionActionCommitTail: Promise<void> = Promise.resolve();\n\tprivate _sessionActionCommitOwner: symbol | undefined;\n\tprivate _pendingSessionActionFenceWaiters = 0;\n\tprivate readonly _sessionActionCommitContext = new AsyncLocalStorage<symbol>();\n\tprivate readonly _sessionActionCommitDisposeAbortController = new AbortController();\n\t// Checkpoint, handoff, and activity waiters share lifecycle-edge notifications to avoid polling.\n\tprivate readonly _sessionInputCheckpointWaiters = new Set<() => void>();\n\tprivate _pendingNextTurnMessages: CustomMessage[] = [];\n\n\tprivate _goalState: GoalState = emptyGoalState();\n\tprivate _goalStateRevision = 0;\n\tprivate _goalAccountingStartedAt: number | undefined = undefined;\n\tprivate _goalContinuationAwaitsRlmWork = false;\n\tprivate _goalAccountedAssistantMessages = new WeakSet<AssistantMessage>();\n\tprivate _goalAbortInProgress = false;\n\tprivate _autonomousState: AutonomousRuntimeState;\n\tprivate _autonomousContinuationSuppressionDepth = 0;\n\tprivate _autonomousContinuationSuppressedMessages = new WeakSet<AgentMessage>();\n\tprivate readonly _invocationOutputLimits: AgentOutputLimits;\n\tprivate _invocationSuppressedAutonomousContinuation = false;\n\tprivate _refreshInvocationOutput?: (message: AgentMessage) => void;\n\tprivate _invocationOutputUpdateTail?: Promise<void>;\n\tprivate _invocationOutputRefused = false;\n\n\tprivate _compactionAbortController: AbortController | undefined = undefined;\n\tprivate _autoCompactionAbortController: AbortController | undefined = undefined;\n\tprivate _compactionOperation: Promise<void> | undefined = undefined;\n\tprivate _compactionSetupFailure: CompactionCommittedError | undefined;\n\t/** One recovery attempt per overflow; \"reported\" dedups the failure notice. */\n\tprivate _overflowRecovery: \"idle\" | \"attempted\" | \"reported\" = \"idle\";\n\tprivate _invocationCompactionOwner: CompactionOwner | undefined;\n\tprivate _pendingCheckpoint: CheckpointResume | undefined;\n\tprivate _pendingRequestedCompaction: { customInstructions?: string; owner: CompactionOwner } | undefined;\n\tprivate _pendingRequestedRefine: { instructions?: string; global?: boolean } | undefined;\n\n\tprivate _branchSummaryAbortController: AbortController | undefined = undefined;\n\tprivate _branchSummaryOperation: Promise<void> | undefined = undefined;\n\n\tprivate _retryAbortController: AbortController | undefined = undefined;\n\tprivate _retryAttempt = 0;\n\tprivate _retryPromise: Promise<void> | undefined = undefined;\n\tprivate _retryResolve: (() => void) | undefined = undefined;\n\tprivate _agentMessageClearEpoch = 0;\n\tprivate _agentMessageOutcomes = new Map<string, AgentMessageOutcome>();\n\tprivate _lateIpythonSentAgentMessages = new Map<string, KernelSentAgentMessage[]>();\n\t/** Outcome disclosures whose session-file append failed; retained for context rebuilds. */\n\tprivate readonly _unpersistedOutcomes: CustomMessage[] = [];\n\n\tprivate _bashAbortControllers = new Set<AbortController>();\n\tprivate _userBashRunning = false;\n\tprivate _userBashAbortRequested = false;\n\tprivate _pendingBashMessages: BashExecutionMessage[] = [];\n\n\tprivate _extensionRunner!: ExtensionRunner;\n\tprivate _execEnvProvider?: () => Record<string, string | undefined> | undefined;\n\tprivate _turnIndex = 0;\n\tprivate _modelSelectEmitQueue: Promise<void> = Promise.resolve();\n\tprivate _modelSelectEmitQueueIdle = true;\n\tprivate _modelSelectEmitContext = new AsyncLocalStorage<boolean>();\n\n\tprivate _resourceLoader: ResourceLoader;\n\tprivate _customTools: ToolDefinition[];\n\tprivate _acpMcpTools: ToolDefinition[] = [];\n\tprivate _baseToolDefinitions: Map<string, ToolDefinition> = new Map();\n\tprivate _cwd: string;\n\tprivate _agentDir?: string;\n\tprivate _extensionRunnerRef?: { current?: ExtensionRunner };\n\tprivate _initialActiveToolNames?: string[];\n\tprivate _allowedToolNames?: Set<string>;\n\tprivate _includeGoals: boolean;\n\tprivate _includeCompactSkill: boolean;\n\tprivate _rlmHeartbeatController?: AgentRlmHeartbeatController;\n\tprivate _agentMessageController?: AgentSessionMessageController;\n\tprivate _agentObserveController?: AgentObserveController;\n\tprivate _mcpManager?: McpManager;\n\tprivate _baseToolsOverride?: Record<string, AgentTool>;\n\tprivate _sessionStartEvent: SessionStartEvent;\n\tprivate _extensionUIContext?: ExtensionUIContext;\n\tprivate _extensionCommandContextActions?: ExtensionCommandContextActions;\n\tprivate _extensionShutdownHandler?: ShutdownHandler;\n\tprivate _extensionErrorListener?: ExtensionErrorListener;\n\tprivate _extensionErrorUnsubscriber?: () => void;\n\tprivate _disposed = false;\n\tprivate readonly _disposeCallbacks = new Set<() => void | Promise<void>>();\n\tprivate _disposeCallbacksPromise?: Promise<void>;\n\t// Set at the start of async teardown so a child finishing mid-disposeAsync doesn't\n\t// re-populate the retained map after it's been cleared.\n\tprivate _disposing = false;\n\tprivate _disposeAsyncPromise?: Promise<void>;\n\tprivate _ipythonKernelProvisioner?: IpythonKernelProvisioner;\n\t/** Artifact dir backing the current provisioner's kernel snapshot, if any. */\n\tprivate _ipythonKernelSnapshotDir?: string;\n\t/** True once the runtime has been built once; later builds are in-process rebuilds (/reload). */\n\tprivate _ipythonRuntimeBuilt = false;\n\tprivate readonly _prewarmIpythonKernel: boolean;\n\tprivate _rlmDepth: number;\n\tprivate readonly _configuredRlmMaxDepth: number | undefined;\n\tprivate _rlmMaxDepth: number;\n\tprivate _rlmMaxDepthSource: RlmMaxDepthSource;\n\tprivate _rlmSessionDir?: string;\n\tprivate readonly _semanticEdges: SemanticEdgeRecorder;\n\tprivate _rlmParentNodeId?: string;\n\tprivate _rlmParentAgent?: string;\n\tprivate _repliedToParentSinceTask: boolean | undefined;\n\tprivate _parentReplyCount = 0;\n\tprivate _subagentRuntimeHost?: SubagentRuntimeHost;\n\tprivate readonly _rlmChildAdmissions = new Set<RlmChildAdmission & { cancel(reason: string): boolean }>();\n\tprivate _rlmSubagentCapacity: RlmSubagentCapacity;\n\tprivate _rlmParentAdmission?: RlmChildAdmission;\n\tprivate readonly _rlmRootAdmission?: RlmRootAdmission;\n\tprivate _rlmResidentDisposalComplete = false;\n\tprivate _releaseRlmResidentCapacity?: () => Promise<void>;\n\tprivate _activeRlmChildRuns = new Map<string, RlmChildRun>();\n\tprivate _unsettledRlmChildRuns = new Set<RlmChildRun>();\n\tprivate _abandonedRlmQuiescenceChildIds = new Set<string>();\n\tprivate _rlmQuiescenceWaitAborts = new Set<AbortController>();\n\tprivate _pendingRlmSubagentSessionNames = new Set<string>();\n\t// Inline mode keeps finished child sessions so the inspector can still read them;\n\t// the daemon does the same by leaving the child session resident in its registry.\n\tprivate _rlmChildSessions = new Map<string, RetainedRlmChild>();\n\tprivate _deletedRlmChildIds = new Set<string>();\n\t// Failed explicit deletes stay hidden from listings but retain their original\n\t// selector so a later delete can retry cleanup without orphaning the runtime.\n\tprivate _rlmChildCleanupFailures = new Map<string, RlmSubagentRegistryEntry>();\n\tprivate _deletingRlmChildren = new Map<\n\t\tstring,\n\t\t{\n\t\t\tsubagent: RlmSubagentRegistryEntry;\n\t\t\tpromise: Promise<RlmDeleteSubagentResult>;\n\t\t}\n\t>();\n\t// Kept alive for retained children so nested updates (e.g. a grandchild cancel)\n\t// still forward to root; torn down when the retained child is disposed.\n\tprivate _rlmChildUnsubscribes = new Map<string, () => void>();\n\tprivate _rlmChildUsageSources = new Map<string, RlmChildUsageSource>();\n\tprivate _rlmParentUsageAttribution?: (usage: Usage, origin: RlmChildUsageOrigin) => Promise<void>;\n\t/** Latest recap for this session, written by the daemon summarizer; read by a parent to label its child snapshots. */\n\tprivate _currentRecap?: string;\n\tprivate readonly _initialGoal: AgentSessionConfig[\"initialGoal\"];\n\tprivate _initialization: Promise<void> | undefined;\n\tprivate _goalResumeOperation: Promise<void> | undefined;\n\tprivate readonly _rlmRunTasks = new Set<Promise<void>>();\n\tprivate readonly _childUsageWrites = new Set<Promise<void>>();\n\tprivate readonly _assistantEntryIds = new WeakMap<\n\t\tAssistantMessage,\n\t\t{ sessionId: string; sessionFile: string | undefined; entryId: string }\n\t>();\n\n\tprivate _modelRegistry: ModelRegistry;\n\n\tprivate _toolRegistry: Map<string, AgentTool> = new Map();\n\tprivate _nativeRecoveryTools = new WeakMap<AgentTool, AgentTool[\"execute\"]>();\n\tprivate _nativeRecoveryCursors = new NativeRecoveryCursorStore();\n\tprivate _nativeRecoveryCursorSource?: string;\n\tprivate _nativeRecoveryProducer = new AsyncLocalStorage<{ used: boolean; skillOwner?: NativeSkillSelectionOwner }>();\n\tprivate _toolDefinitions: Map<string, ToolDefinitionEntry> = new Map();\n\tprivate _toolPromptSnippets: Map<string, string> = new Map();\n\tprivate _toolPromptGuidelines: Map<string, string[]> = new Map();\n\n\tprivate _baseSystemPrompt = \"\";\n\tprivate _baseSystemPromptOptions!: BuildSystemPromptOptions;\n\tprivate _assistantTurnsSinceAutoRefine = 0;\n\tprivate _lastAutoRefineReviewAt = 0;\n\tprivate _lastAutoRefineEvidence?: Awaited<ReturnType<AgentSession[\"_autoRefineEvidence\"]>>;\n\tprivate _autoRefineInProgress = false;\n\tprivate _autoRefineAdmissionClosed = false;\n\tprivate readonly _autoRefineOperations = new Set<Promise<void>>();\n\tprivate readonly _scheduledAutoRefineTimers = new Set<ReturnType<typeof setTimeout>>();\n\tprivate _compactAutoRefinePending = false;\n\tprivate _turnIntervalAutoRefinePending = false;\n\tprivate _postCompactionContinuationScheduled = false;\n\tprivate _postCompactionContinuationSettlement: PostCompactionContinuationSettlement | undefined;\n\tprivate _postCompactionContinuations: ThresholdAutonomousContinuation[] = [];\n\tprivate _queuedAutonomousThresholdContinuations = new WeakMap<AssistantMessage, ThresholdAutonomousContinuation>();\n\tprivate _pendingThresholdCompactionAutonomousContinuations: ThresholdAutonomousContinuation[] = [];\n\tprivate _queuedGoalThresholdContinuation: ThresholdGoalContinuation | undefined;\n\tprivate _pendingAutoRefineReview: { reason: AutoRefineReason; review: AutoRefineReview } | undefined;\n\tprivate _autoRefineBranchVersion = 0;\n\tprivate _autoRefineReviewAbort?: AbortController;\n\tprivate _refineAbortController?: AbortController;\n\tprivate readonly _autoRefineReviewer?: AutoRefineReviewer;\n\tprivate readonly _serializedRefine: boolean;\n\tprivate _refineInFlight?: Promise<void>;\n\tprivate _refinePlanInFlight?: Promise<void>;\n\tprivate _serializedPlanInFlight?: Promise<SerializedBackgroundPlanResult | undefined>;\n\tprivate _serializedPlanClaim?: Promise<void>;\n\tprivate _serializedExplicitRefineOptions?: {\n\t\tinstructions?: string;\n\t\tglobal?: boolean;\n\t};\n\n\tconstructor(config: AgentSessionConfig) {\n\t\tthis._rlmRootAdmission = config.rlmRootAdmission;\n\t\tthis._rlmRootAdmission?.bind(this);\n\t\tthis._rlmSubagentCapacity =\n\t\t\tconfig.rlmChildAdmission?.parent._rlmSubagentCapacity ??\n\t\t\tconfig.rlmSubagentCapacity ??\n\t\t\tnew LocalRlmSubagentCapacity(config.settingsManager);\n\t\tthis._rlmParentAdmission = config.rlmChildAdmission;\n\t\tthis._rlmParentAdmission?.bind(this);\n\t\tthis.agent = config.agent;\n\t\tthis.sessionManager = config.sessionManager;\n\t\tthis._invocationOutputLimits = {\n\t\t\t...(config.invocationOutputLimits ?? config.settingsManager.getInvocationOutputLimits()),\n\t\t};\n\t\tif (\n\t\t\tthis._invocationOutputLimits &&\n\t\t\t(!Number.isSafeInteger(this._invocationOutputLimits.maxMessages) ||\n\t\t\t\tthis._invocationOutputLimits.maxMessages < 1 ||\n\t\t\t\t!Number.isSafeInteger(this._invocationOutputLimits.maxSourceBytes) ||\n\t\t\t\tthis._invocationOutputLimits.maxSourceBytes < 1)\n\t\t)\n\t\t\tthrow new Error(\"Invalid invocation output limits\");\n\t\tthis.agent.bindOutputOwner(() => {\n\t\t\tthis._invocationOutputRefused = false;\n\t\t\tif (!this.sessionManager.supportsCapturedHistoryReads()) return undefined;\n\t\t\tlet registeredUpdate: ((message: AgentMessage) => void) | undefined;\n\t\t\treturn {\n\t\t\t\tlimits: { ...this._invocationOutputLimits },\n\t\t\t\tbindUpdates: (refresh) => {\n\t\t\t\t\tconst update = (message: AgentMessage) => {\n\t\t\t\t\t\tif (!refresh(message)) this._invocationOutputRefused = true;\n\t\t\t\t\t};\n\t\t\t\t\tregisteredUpdate = update;\n\t\t\t\t\tthis._invocationOutputUpdateTail = undefined;\n\t\t\t\t\tthis._refreshInvocationOutput = update;\n\t\t\t\t\treturn () => {\n\t\t\t\t\t\tif (this._refreshInvocationOutput === update) this._refreshInvocationOutput = undefined;\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\tsettleUpdates: async () => {\n\t\t\t\t\t// One fixed accepted boundary; do not wait for future child lifetimes or a later event tail.\n\t\t\t\t\tconst lateUpdate = this._invocationOutputUpdateTail;\n\t\t\t\t\tthis._invocationOutputUpdateTail = undefined;\n\t\t\t\t\tconst childWrites = [...this._childUsageWrites];\n\t\t\t\t\tif (this._refreshInvocationOutput === registeredUpdate) this._refreshInvocationOutput = undefined;\n\t\t\t\t\tconst settled = await Promise.allSettled([...(lateUpdate ? [lateUpdate] : []), ...childWrites]);\n\t\t\t\t\tconst errors = settled.flatMap((result) => (result.status === \"rejected\" ? [result.reason] : []));\n\t\t\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Accepted invocation output updates failed\");\n\t\t\t\t},\n\t\t\t\tsnapshot: (message, maxSourceBytes) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst json = stringifyBoundedJson(message, maxSourceBytes);\n\t\t\t\t\t\treturn { message: JSON.parse(json) as AgentMessage, sourceBytes: Buffer.byteLength(json) };\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (error instanceof Error && error.message === \"JSON byte limit exceeded\") return undefined;\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t\tthis.agent.bindInitializationOwner(() => this.initialize());\n\t\tthis._initialContextMode = config.contextMode ?? config.settingsManager.getContextMode();\n\t\tif (this._initialContextMode !== \"on\" && this._initialContextMode !== \"off\")\n\t\t\tthrow new Error(\"context.mode must be on or off\");\n\t\tthis._contextMode = this._initialContextMode;\n\t\tthis._contextEpochsEnabled = config.requestTokenBudget !== undefined;\n\t\tconst contextEpochsEnabled = this._contextEpochsEnabled;\n\t\tthis.agent.bindContextOwner(async () => {\n\t\t\tawait this.initialize();\n\t\t\tawait this._goalResumeOperation;\n\t\t\tawait this._waitForAgentEventsBeforeContext();\n\t\t\tawait this._waitForChildUsageWrites();\n\t\t\tconst assertHarnessSourceCurrent = await this._appendHarnessSnapshotIfChanged();\n\t\t\tawait this.sessionManager.flushNow();\n\t\t\tassertHarnessSourceCurrent();\n\t\t\t// In-memory sessions have no canonical archive. This is an explicit mode, not an index-error fallback.\n\t\t\tif (!this.sessionManager.isPersisted()) {\n\t\t\t\tif (!this._compactionSetupFailure) return { messages: this.agent.state.messages, adoptMessages: true };\n\t\t\t\tconst rebuilt = await readSessionBootstrap(\n\t\t\t\t\tthis.sessionManager,\n\t\t\t\t\tthis.settingsManager.getCanonicalContextLimits(),\n\t\t\t\t);\n\t\t\t\tthis._compactionSetupFailure = undefined;\n\t\t\t\treturn { messages: rebuilt.context.messages, adoptMessages: true };\n\t\t\t}\n\t\t\tconst limits = this.settingsManager.getCanonicalContextLimits();\n\t\t\tconst outcomes = structuredClone(this._unpersistedOutcomes);\n\t\t\tif (\n\t\t\t\tthis._contextOmissions?.sessionId !== this.sessionId ||\n\t\t\t\tthis._contextOmissions?.sessionFile !== this.sessionFile\n\t\t\t)\n\t\t\t\tthis._contextOmissions = undefined;\n\t\t\tconst controls = this._contextOmissions;\n\t\t\tconst omitted = new Set(controls?.ids);\n\t\t\tconst epochManager = this.sessionManager;\n\t\t\tconst resource = this._captureKernelResource();\n\t\t\tconst compaction = epochManager.bindCompactionSink({\n\t\t\t\tmaxEntries: limits.maxMessages,\n\t\t\t\tmaxSourceBytes: limits.maxSourceBytes,\n\t\t\t});\n\t\t\tlet captured: InferenceCoordinator;\n\t\t\ttry {\n\t\t\t\tcaptured = this.requests.capture(compaction);\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tawait compaction.release();\n\t\t\t\t} catch (cleanupError) {\n\t\t\t\t\tthrow new AggregateError([error, cleanupError], \"Canonical context capture and release failed\");\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst messages = await captured.readHistory(async (view) => {\n\t\t\t\t\tconst sameSource =\n\t\t\t\t\t\tcontrols?.sessionId === view.source.sessionId && controls?.sessionFile === view.source.sessionFile;\n\t\t\t\t\tconst result = await this._contextCompiler.compile(\n\t\t\t\t\t\tview,\n\t\t\t\t\t\tlimits,\n\t\t\t\t\t\tsameSource ? omitted : undefined,\n\t\t\t\t\t\t{},\n\t\t\t\t\t\tresource,\n\t\t\t\t\t\tthis._initialContextMode,\n\t\t\t\t\t\t// This MAIN owner binds public admission below, independently of optional token budgets.\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t\tif (sameSource && this._contextOmissions === controls) {\n\t\t\t\t\t\t// Only prune this captured set. A newer control or source switch must survive this read.\n\t\t\t\t\t\tfor (const id of omitted) if (!this._contextCompiler.hasActiveEntry(id)) controls.ids.delete(id);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t});\n\t\t\t\t// Failed persistence outcomes are transient UI/request facts, never canonical history authority.\n\t\t\t\tthis._mergeUnpersistedOutcomes(messages, outcomes);\n\t\t\t\tif (messages.length > limits.maxMessages) throw new Error(\"Canonical context message budget exceeded\");\n\t\t\t\tconst epochContext = getCanonicalEpochContext(messages);\n\t\t\t\tif (epochContext) this._contextMode = epochContext.mode;\n\t\t\t\tconst unbudgetedPublic =\n\t\t\t\t\t!contextEpochsEnabled &&\n\t\t\t\t\tBoolean(\n\t\t\t\t\t\tepochContext?.toolContinuations?.length ||\n\t\t\t\t\t\t\tepochContext?.taskFrameRebased ||\n\t\t\t\t\t\t\tepochContext?.checkpoint ||\n\t\t\t\t\t\t\tgetCanonicalViewSelectionSource(messages)?.recoveryContractRequested,\n\t\t\t\t\t);\n\t\t\t\tconst nativeSkills = Boolean(contextEpochsEnabled || epochContext?.checkpoint || unbudgetedPublic);\n\t\t\t\tconst skillPolicy = nativeSkills ? (this._nativeRecoveryEnabled() ? \"enabled\" : \"unavailable\") : undefined;\n\t\t\t\tif (this._baseSystemPromptOptions.nativeSkillSelection !== skillPolicy) {\n\t\t\t\t\tconst previousBase = this._baseSystemPrompt;\n\t\t\t\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames(), nativeSkills);\n\t\t\t\t\tthis.agent.state.systemPrompt = this._refreshExtensionSystemPrompt(\n\t\t\t\t\t\tthis.agent.state.systemPrompt,\n\t\t\t\t\t\tpreviousBase,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tepochContext?.resourceRevision !== undefined &&\n\t\t\t\t\tgetCanonicalViewUnits(messages)?.length !== messages.length\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Current resource view requires tracked canonical context\");\n\t\t\t\tif (\n\t\t\t\t\t(epochContext?.checkpoint || unbudgetedPublic) &&\n\t\t\t\t\tgetCanonicalViewUnits(messages)?.length !== messages.length\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Committed context epoch cannot admit untracked transient messages\");\n\t\t\t\tif (\n\t\t\t\t\tepochContext &&\n\t\t\t\t\t(contextEpochsEnabled || epochContext.checkpoint || unbudgetedPublic) &&\n\t\t\t\t\tgetCanonicalViewUnits(messages)?.length === messages.length\n\t\t\t\t) {\n\t\t\t\t\tlet committed = epochContext.checkpoint;\n\t\t\t\t\tlet committedEntry = epochContext.checkpointEntry;\n\t\t\t\t\tconst fixed =\n\t\t\t\t\t\tepochContext.mode === \"off\" ||\n\t\t\t\t\t\t(committed?.policyOnly === true && !contextEpochsEnabled && !unbudgetedPublic);\n\t\t\t\t\tlet requestContract = fixed ? retainedContextRequestContract(committed) : undefined;\n\t\t\t\t\tconst nativeTail = messages.some(\n\t\t\t\t\t\t(message) =>\n\t\t\t\t\t\t\tmessage.role === \"toolResult\" ||\n\t\t\t\t\t\t\t(message.role === \"assistant\" &&\n\t\t\t\t\t\t\t\tmessage.content.some((part) => part.type !== \"text\" || part.textSignature !== undefined)),\n\t\t\t\t\t);\n\t\t\t\t\tlet accepted: string | undefined;\n\t\t\t\t\tlet acceptedBody: string | undefined;\n\t\t\t\t\tlet acceptedResponseIdentity: string | undefined;\n\t\t\t\t\tlet acceptedReplayContract: ContextReplayContract | undefined;\n\t\t\t\t\tlet acknowledged: CompactionCommit | undefined;\n\t\t\t\t\tconst commitFailure = (cause: unknown) => {\n\t\t\t\t\t\tif (!acknowledged) return cause;\n\t\t\t\t\t\tconst error = new CompactionCommittedError(acknowledged.entryId, acknowledged.result, cause);\n\t\t\t\t\t\tthis._compactionSetupFailure = error;\n\t\t\t\t\t\treturn error;\n\t\t\t\t\t};\n\t\t\t\t\tcaptured.bindRequestViewBoundary(\n\t\t\t\t\t\tmessages,\n\t\t\t\t\t\tasync (candidate) => {\n\t\t\t\t\t\t\tif (fixed) throw new Error(\"Context selection is disabled while context.mode is off\");\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tepochContext.toolContinuations?.length &&\n\t\t\t\t\t\t\t\t(!candidate.publicMessages ||\n\t\t\t\t\t\t\t\t\tJSON.stringify(getCanonicalEpochContext(candidate.publicMessages)?.toolContinuations) !==\n\t\t\t\t\t\t\t\t\t\tJSON.stringify(epochContext.toolContinuations) ||\n\t\t\t\t\t\t\t\t\tcandidate.projection.pendingPublicMessageGroups?.length)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tthrow new Error(\"Tool continuation requires its exact public candidate before epoch ACK\");\n\t\t\t\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\t\t\t\tlet representation: string;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\trepresentation = contextEpochRepresentation(\n\t\t\t\t\t\t\t\t\tcandidate.request,\n\t\t\t\t\t\t\t\t\tcandidate.assessment,\n\t\t\t\t\t\t\t\t\tlimits.maxSourceBytes,\n\t\t\t\t\t\t\t\t\tunbudgetedPublic,\n\t\t\t\t\t\t\t\t\tcandidate.responseItemIdentity,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\terror instanceof UnsupportedContextEpochConfigurationError &&\n\t\t\t\t\t\t\t\t\t!contextEpochsEnabled &&\n\t\t\t\t\t\t\t\t\t!candidate.assessment &&\n\t\t\t\t\t\t\t\t\t!committed &&\n\t\t\t\t\t\t\t\t\t!acknowledged &&\n\t\t\t\t\t\t\t\t\t!epochContext.taskFrameRebased &&\n\t\t\t\t\t\t\t\t\t!epochContext.selectedSkills?.length &&\n\t\t\t\t\t\t\t\t\t!epochContext.toolContinuations?.length &&\n\t\t\t\t\t\t\t\t\t!candidate.publicMessages\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tconst source = getCanonicalViewSelectionSource(messages)!;\n\t\t\t\t\t\t\t\t\tconst selected = new Set(candidate.selectedUnitIds);\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\tsource.recoveryContractRequested &&\n\t\t\t\t\t\t\t\t\t\t!source.requiresEpoch &&\n\t\t\t\t\t\t\t\t\t\t!source.pendingPublicMessageGroups?.length &&\n\t\t\t\t\t\t\t\t\t\tthis.sessionManager === epochManager &&\n\t\t\t\t\t\t\t\t\t\tcompaction.isCurrent() &&\n\t\t\t\t\t\t\t\t\t\tJSON.stringify(candidate.source) === JSON.stringify(source.source) &&\n\t\t\t\t\t\t\t\t\t\tcandidate.selectedUnitIds.length === source.units.length &&\n\t\t\t\t\t\t\t\t\t\tselected.size === source.units.length &&\n\t\t\t\t\t\t\t\t\t\tsource.units.every((unit) => selected.has(unit.id))\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t// Optional capture only. Keep the unchanged full-native offer; grant no epoch or omission.\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst replayContract =\n\t\t\t\t\t\t\t\t\"replayContract\" in candidate.projection &&\n\t\t\t\t\t\t\t\tcandidate.projection.replayContract === \"message-groups\"\n\t\t\t\t\t\t\t\t\t? \"message-groups\"\n\t\t\t\t\t\t\t\t\t: \"complete-context\";\n\t\t\t\t\t\t\tconst publicWindow =\n\t\t\t\t\t\t\t\t\"publicWindow\" in candidate.projection && candidate.projection.publicWindow === true;\n\t\t\t\t\t\t\tconst selection = JSON.stringify([\n\t\t\t\t\t\t\t\trepresentation,\n\t\t\t\t\t\t\t\treplayContract,\n\t\t\t\t\t\t\t\tpublicWindow,\n\t\t\t\t\t\t\t\tcandidate.publicMessages !== undefined,\n\t\t\t\t\t\t\t\tcandidate.selectedUnitIds,\n\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\tacceptedResponseIdentity = candidate.responseItemIdentity;\n\t\t\t\t\t\t\tif (accepted !== undefined) {\n\t\t\t\t\t\t\t\tif (accepted !== selection)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Captured epoch request selection changed after acceptance\");\n\t\t\t\t\t\t\t\treturn committedEntry;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Stable request settings do not cover recovery added after the committed source.\n\t\t\t\t\t\t\tconst recoverySourceSequence = committed?.source.sourceSequence ?? -1;\n\t\t\t\t\t\t\tconst hasUncoveredRecovery = getCanonicalViewUnits(messages)!.some((unit, index) => {\n\t\t\t\t\t\t\t\tconst reference = epochContext.references[index];\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\tunit.kind === \"recovery\" && (!reference || reference.ref.sequence > recoverySourceSequence)\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!candidate.publicMessages &&\n\t\t\t\t\t\t\t\t!hasUncoveredRecovery &&\n\t\t\t\t\t\t\t\tcommitted?.representation === representation &&\n\t\t\t\t\t\t\t\tcommitted.replayContract === replayContract &&\n\t\t\t\t\t\t\t\t(committed.publicWindow === true) === publicWindow &&\n\t\t\t\t\t\t\t\tcommitted.taskFrame?.material === epochContext.taskFrame?.material &&\n\t\t\t\t\t\t\t\tcommitted.resourceRevision === epochContext.resourceRevision &&\n\t\t\t\t\t\t\t\tsameSelectedSkills(committed.selectedSkills, epochContext.selectedSkills) &&\n\t\t\t\t\t\t\t\tcandidate.selectedUnitIds.length === messages.length\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\taccepted = selection;\n\t\t\t\t\t\t\t\tacceptedBody = candidate.request.body;\n\t\t\t\t\t\t\t\treturn committedEntry;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst prepared = prepareCanonicalEpoch(\n\t\t\t\t\t\t\t\tcandidate.publicMessages ?? messages,\n\t\t\t\t\t\t\t\tcandidate.selectedUnitIds,\n\t\t\t\t\t\t\t\trepresentation,\n\t\t\t\t\t\t\t\tlimits.maxSourceBytes,\n\t\t\t\t\t\t\t\treplayContract,\n\t\t\t\t\t\t\t\tpublicWindow,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (JSON.stringify(prepared.checkpoint.source) !== JSON.stringify(candidate.source))\n\t\t\t\t\t\t\t\tthrow new Error(\"Context epoch candidate does not match its captured source\");\n\t\t\t\t\t\t\tconst tokensBefore = candidate.originalAssessment?.estimatedInputTokens ?? null;\n\t\t\t\t\t\t\tconst result: CompactionResult = {\n\t\t\t\t\t\t\t\tsummary: \"\",\n\t\t\t\t\t\t\t\tfirstKeptEntryId: prepared.checkpoint.literalTailId,\n\t\t\t\t\t\t\t\ttokensBefore,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t// This is the sole commit. A resolved append is already canonical even if adoption fails.\n\t\t\t\t\t\t\tconst entryId = await compaction[appendContextEpoch](prepared.checkpoint, tokensBefore);\n\t\t\t\t\t\t\tacknowledged = { entryId, result };\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\t\t\t\t\tif (this.sessionManager !== epochManager || !compaction.isCurrent())\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Context epoch source changed before adoption\");\n\t\t\t\t\t\t\t\tthis.agent.state.messages = prepared.messages;\n\t\t\t\t\t\t\t\tcommitted = prepared.checkpoint;\n\t\t\t\t\t\t\t\tcommittedEntry = { sessionId: epochContext.source.sessionId, entryId };\n\t\t\t\t\t\t\t\taccepted = selection;\n\t\t\t\t\t\t\t\tacceptedBody = candidate.request.body;\n\t\t\t\t\t\t\t\treturn committedEntry;\n\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\tthrow commitFailure(cause);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t(request, assessment) => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\t\t\t\t\tif (!sameSelectedSkills(committed?.selectedSkills, epochContext.selectedSkills))\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Selected skill versions require a committed epoch boundary\");\n\t\t\t\t\t\t\t\tif (fixed) {\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t(requestContract ||\n\t\t\t\t\t\t\t\t\t\t\tcommitted?.pendingRequestContract ||\n\t\t\t\t\t\t\t\t\t\t\tnativeTail ||\n\t\t\t\t\t\t\t\t\t\t\tacceptedBody !== undefined) &&\n\t\t\t\t\t\t\t\t\t\t(acceptedBody === undefined || request.body !== acceptedBody)\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed context requires a compatible final provider projection\");\n\t\t\t\t\t\t\t\t\tif (requestContract) {\n\t\t\t\t\t\t\t\t\t\tif (!acceptedReplayContract)\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed context has no accepted replay projection\");\n\t\t\t\t\t\t\t\t\t\tassertContextRequestContract(requestContract, request, acceptedReplayContract);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (epochContext.taskFrameRebased && acceptedBody === undefined)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Task frame rebase requires a committed epoch boundary\");\n\t\t\t\t\t\t\t\tif (!committed) return;\n\t\t\t\t\t\t\t\tif (acceptedBody === undefined || request.body !== acceptedBody)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Committed context epoch requires a compatible final provider projection\");\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\tcontextEpochRepresentation(\n\t\t\t\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t\t\t\t\tassessment,\n\t\t\t\t\t\t\t\t\t\tlimits.maxSourceBytes,\n\t\t\t\t\t\t\t\t\t\tunbudgetedPublic,\n\t\t\t\t\t\t\t\t\t\tacceptedResponseIdentity,\n\t\t\t\t\t\t\t\t\t) !== committed.representation\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Context epoch representation changed without a committed boundary\");\n\t\t\t\t\t\t\t\tif (committed.resourceRevision !== epochContext.resourceRevision)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Context epoch resource revision requires a committed boundary\");\n\t\t\t\t\t\t\t\tif (committed.taskFrame?.material !== epochContext.taskFrame?.material)\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Context epoch task revision requires a committed boundary\");\n\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\tthrow commitFailure(cause);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfixed\n\t\t\t\t\t\t\t? async (request, projection) => {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\t\t\t\t\t\t\tif (!requestContract && nativeTail)\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Retained native context has no accepted request contract\");\n\t\t\t\t\t\t\t\t\t\tconst replayContract = projection.replayContract ?? \"complete-context\";\n\t\t\t\t\t\t\t\t\t\tconst skillChange = !sameSelectedSkills(\n\t\t\t\t\t\t\t\t\t\t\tcommitted?.selectedSkills,\n\t\t\t\t\t\t\t\t\t\t\tepochContext.selectedSkills,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\tskillChange &&\n\t\t\t\t\t\t\t\t\t\t\tcommitted?.selectedSkills?.some(\n\t\t\t\t\t\t\t\t\t\t\t\t(skill) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t!sameSelectedSkills(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[skill],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tepochContext.selectedSkills?.filter((item) => item.name === skill.name),\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed context cannot replace a selected skill version\");\n\t\t\t\t\t\t\t\t\t\tif ((!requestContract && committed?.pendingRequestContract) || skillChange) {\n\t\t\t\t\t\t\t\t\t\t\t// Existing policy-only ACK: bind first selections, without changing fixed views or mode.\n\t\t\t\t\t\t\t\t\t\t\tconst base =\n\t\t\t\t\t\t\t\t\t\t\t\tcommitted ??\n\t\t\t\t\t\t\t\t\t\t\t\tprepareContextModeEpoch(messages, epochContext.mode, limits.maxSourceBytes)\n\t\t\t\t\t\t\t\t\t\t\t\t\t.checkpoint;\n\t\t\t\t\t\t\t\t\t\t\tif (base.version !== 5)\n\t\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed skill selection requires its policy checkpoint\");\n\t\t\t\t\t\t\t\t\t\t\tconst nextContract =\n\t\t\t\t\t\t\t\t\t\t\t\trequestContract ?? contextRequestContract(request, replayContract);\n\t\t\t\t\t\t\t\t\t\t\tconst checkpoint = snapshotContextEpoch(\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t...base,\n\t\t\t\t\t\t\t\t\t\t\t\t\trenderer: epochContext.selectedSkills?.length\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? CONTEXT_SKILL_EPOCH_RENDERER\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: base.renderer,\n\t\t\t\t\t\t\t\t\t\t\t\t\t...(epochContext.selectedSkills?.length\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? { selectedSkills: epochContext.selectedSkills }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t\t\t\t\t\tsource: epochContext.source,\n\t\t\t\t\t\t\t\t\t\t\t\t\trequestContract: nextContract,\n\t\t\t\t\t\t\t\t\t\t\t\t\tpendingRequestContract: undefined,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\tlimits.maxSourceBytes,\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\tconst entryId = await compaction[appendContextEpoch](checkpoint, null);\n\t\t\t\t\t\t\t\t\t\t\tacknowledged = {\n\t\t\t\t\t\t\t\t\t\t\t\tentryId,\n\t\t\t\t\t\t\t\t\t\t\t\tresult: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsummary: \"\",\n\t\t\t\t\t\t\t\t\t\t\t\t\tfirstKeptEntryId: checkpoint.literalTailId,\n\t\t\t\t\t\t\t\t\t\t\t\t\ttokensBefore: null,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\tcommitted = checkpoint;\n\t\t\t\t\t\t\t\t\t\t\tcommittedEntry = { sessionId: epochContext.source.sessionId, entryId };\n\t\t\t\t\t\t\t\t\t\t\trequestContract = nextContract;\n\t\t\t\t\t\t\t\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\t\t\t\t\t\t\t\tif (this.sessionManager !== epochManager || !compaction.isCurrent())\n\t\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Context contract source changed before acceptance\");\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (!sameSelectedSkills(committed?.selectedSkills, epochContext.selectedSkills))\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed context selected skill versions changed after acceptance\");\n\t\t\t\t\t\t\t\t\t\tif (requestContract)\n\t\t\t\t\t\t\t\t\t\t\tassertContextRequestContract(requestContract, request, replayContract);\n\t\t\t\t\t\t\t\t\t\tif (acceptedBody !== undefined && request.body !== acceptedBody)\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Fixed context changed after acceptance\");\n\t\t\t\t\t\t\t\t\t\tacceptedBody = request.body;\n\t\t\t\t\t\t\t\t\t\tacceptedReplayContract = replayContract;\n\t\t\t\t\t\t\t\t\t\treturn committedEntry;\n\t\t\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\t\t\tthrow commitFailure(cause);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tcompaction.isCurrent,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis._compactionSetupFailure = undefined;\n\t\t\t\treturn { messages, adoptMessages: true, streamContext: captured, release: () => captured.dispose() };\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tawait captured.dispose();\n\t\t\t\t} catch (cleanupError) {\n\t\t\t\t\tthrow new AggregateError([error, cleanupError], \"Canonical context build and release failed\");\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\t\tthis.agent.bindRequestPreparationRecoveryOwner(async (error, signal) => {\n\t\t\tif (\n\t\t\t\t!(error instanceof PublicContextBudgetError) ||\n\t\t\t\t!this.settingsManager.getCompactionSettings().enabled ||\n\t\t\t\t!this._contextOptimizationAllowed()\n\t\t\t)\n\t\t\t\treturn false;\n\t\t\tconst invocation = this._invocationCompactionOwner;\n\t\t\tif (!invocation || invocation.signal !== signal) return false;\n\t\t\tconst owner = { ...invocation, pumpEpoch: this._sessionInputPumpEpoch };\n\t\t\tif (\n\t\t\t\t!this._isCompactionOwnerCurrent(owner) ||\n\t\t\t\t!error.source.persistent ||\n\t\t\t\terror.source.sessionId !== owner.sessionId ||\n\t\t\t\terror.source.sessionFile !== owner.sessionFile ||\n\t\t\t\t!(error.isSourceCurrent?.() ?? error.source.leafId === owner.manager.getLeafId())\n\t\t\t)\n\t\t\t\treturn false;\n\t\t\t// Rebase this captured frame before paying for a summary. The replacement still\n\t\t\t// needs the normal full provider projection and epoch ACK before MAIN can send.\n\t\t\tif (error.taskFrameRebaseAvailable) {\n\t\t\t\tthis._contextCompiler.requestTaskFrameRebase();\n\t\t\t\treturn \"reprepare\";\n\t\t\t}\n\t\t\tif (error.mandatoryAssessment?.status === \"over-budget\") return false;\n\t\t\t// The loop released its unsent inference and captured projection before this handoff.\n\t\t\t// Continue in-place only after the real summary ACK and canonical owner adoption.\n\t\t\tconst key = error.getCompactionKey();\n\t\t\tconst current = {\n\t\t\t\tkey: key ?? \"\",\n\t\t\t\tsystemPrompt: this.agent.state.systemPrompt,\n\t\t\t\ttools: this.agent.state.tools,\n\t\t\t\tsettings: JSON.stringify(this.settingsManager.getCompactionSettings()),\n\t\t\t};\n\t\t\tconst failed = this._failedAutomaticCompaction;\n\t\t\tif (\n\t\t\t\tkey &&\n\t\t\t\tfailed &&\n\t\t\t\tfailed.key === key &&\n\t\t\t\tfailed.systemPrompt === current.systemPrompt &&\n\t\t\t\tfailed.tools === current.tools &&\n\t\t\t\tfailed.settings === current.settings\n\t\t\t)\n\t\t\t\treturn false;\n\t\t\tthis._failedAutomaticCompaction = undefined;\n\t\t\tlet succeeded = false;\n\t\t\ttry {\n\t\t\t\tsucceeded = await this._runAutoCompaction(\"threshold\", false, owner, true, error);\n\t\t\t\treturn succeeded;\n\t\t\t} finally {\n\t\t\t\tif (!succeeded && key && this._isCompactionSourceOwnerCurrent(owner))\n\t\t\t\t\tthis._failedAutomaticCompaction = current;\n\t\t\t}\n\t\t});\n\t\tthis.agent.bindProviderFailureRecoveryOwner({\n\t\t\trecover: (message, signal) => this._handleRetryableError(message, signal),\n\t\t\tsettle: () => {\n\t\t\t\t// A request-budget rejection can bypass agent_end. Always release its retry owner.\n\t\t\t\tif (this._retryAttempt > 0) {\n\t\t\t\t\tthis._emit({\n\t\t\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tattempt: this._retryAttempt,\n\t\t\t\t\t\tfinalError: this.agent.state.errorMessage,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis._retryAttempt = 0;\n\t\t\t\tthis._resolveRetry();\n\t\t\t},\n\t\t});\n\t\tthis.agent.bindToolExecutionOwner({\n\t\t\tonToolInvocationStarting: async (invocation, _signal, tool, execute, assistantMessage) => {\n\t\t\t\t// Capture this invocation's original source generation before either wait.\n\t\t\t\tconst manager = this.sessionManager;\n\t\t\t\tconst sessionId = manager.getSessionId();\n\t\t\t\tconst sessionFile = manager.getSessionFile();\n\t\t\t\tconst writer = manager[bindNativeEntryWriter]();\n\t\t\t\tconst selected = this._toolRegistry.get(tool.name) === tool && tool.execute === execute;\n\t\t\t\tconst qualified = selected && manager.isPersisted();\n\t\t\t\tconst skillOwner = qualified\n\t\t\t\t\t? { manager, sessionId, sessionFile, writer: writer.captureSkillSelection() }\n\t\t\t\t\t: undefined;\n\t\t\t\tawait this.initialize();\n\t\t\t\tawait this._agentEventQueue;\n\t\t\t\tif (this.sessionManager !== manager)\n\t\t\t\t\tthrow new Error(\"Tool execution owner changed before intent admission\");\n\t\t\t\tconst assistant = assistantMessage ? this._assistantEntryIds.get(assistantMessage) : undefined;\n\t\t\t\tif (qualified && (!assistant || assistant.sessionId !== sessionId || assistant.sessionFile !== sessionFile))\n\t\t\t\t\tthrow new Error(\"Tool intent does not match its original native assistant source\");\n\t\t\t\tconst intentWrite = writer.captureToolInvocation(qualified ? assistant : undefined);\n\t\t\t\tconst exchangeWrite = qualified ? writer.captureToolExchange(invocation.executionId) : undefined;\n\t\t\t\t// Recovery qualification still requires the selected genuine recovery producer.\n\t\t\t\tconst recoveryWrite =\n\t\t\t\t\tthis._nativeRecoveryTools.get(tool) === execute\n\t\t\t\t\t\t? writer.captureRecoveryExchange(invocation.executionId)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tawait intentWrite(invocation);\n\t\t\t\tif (!recoveryWrite && !exchangeWrite) return;\n\t\t\t\tconst producer = { used: false, skillOwner };\n\t\t\t\tconst owner: BoundToolExecution = {\n\t\t\t\t\trun: (run) => (recoveryWrite ? this._nativeRecoveryProducer.run(producer, run) : run()),\n\t\t\t\t\tfinalize: async (exchange) => {\n\t\t\t\t\t\tif (producer.used && recoveryWrite) await recoveryWrite(exchange);\n\t\t\t\t\t\telse if (exchangeWrite) await exchangeWrite(exchange);\n\t\t\t\t\t\telse await manager.appendToolExchange(exchange);\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\treturn owner;\n\t\t\t},\n\t\t\tonToolExchangeFinalized: async (exchange) => {\n\t\t\t\tawait this.sessionManager.appendToolExchange(exchange);\n\t\t\t},\n\t\t});\n\t\tthis.settingsManager = config.settingsManager;\n\t\tthis._serviceTierPreference = config.serviceTierPreference ?? config.agent.state.serviceTier;\n\t\tthis._scopedModels = config.scopedModels ?? [];\n\t\tthis._resourceLoader = config.resourceLoader;\n\t\tthis._customTools = config.customTools ?? [];\n\t\tthis._cwd = config.cwd;\n\t\tthis._agentDir = config.agentDir;\n\t\tthis._modelRegistry = config.modelRegistry;\n\t\tthis._extensionRunnerRef = config.extensionRunnerRef;\n\t\tthis._initialActiveToolNames = config.initialActiveToolNames;\n\t\tthis._allowedToolNames = config.allowedToolNames ? new Set(config.allowedToolNames) : undefined;\n\t\tthis._includeGoals = config.includeGoals ?? true;\n\t\tthis._includeCompactSkill = config.includeCompactSkill ?? this.settingsManager.getCompactionAgentCallable();\n\t\tthis._rlmHeartbeatController = config.rlmHeartbeatController;\n\t\tthis._agentMessageController = config.agentMessageController;\n\t\tthis._agentObserveController = config.agentObserveController;\n\t\tthis._mcpManager = config.mcpManager;\n\t\tthis._baseToolsOverride = config.baseToolsOverride;\n\t\tthis._sessionStartEvent = config.sessionStartEvent ?? { type: \"session_start\", reason: \"startup\" };\n\t\tconst headerRlmDepth = this.sessionManager.getHeader()?.rlmDepth;\n\t\tthis._rlmDepth =\n\t\t\tconfig.rlmDepth ??\n\t\t\t(isNonNegativeInteger(headerRlmDepth)\n\t\t\t\t? headerRlmDepth\n\t\t\t\t: parseDepth(process.env.BASE_CONTEXT_RLM_DEPTH, 0, \"BASE_CONTEXT_RLM_DEPTH\"));\n\t\tthis._configuredRlmMaxDepth = config.rlmMaxDepth;\n\t\tif (this._configuredRlmMaxDepth !== undefined && !isNonNegativeInteger(this._configuredRlmMaxDepth)) {\n\t\t\tthrow new Error(\"rlmMaxDepth must be a non-negative integer\");\n\t\t}\n\t\t// Persistent controls are restored before constructing the runtime in initialize().\n\t\tconst resolvedRlmMaxDepth = this.sessionManager.isPersisted()\n\t\t\t? { maxDepth: 2, source: \"default\" as const }\n\t\t\t: this._resolveRlmMaxDepth(this._loadPersistedRlmMaxDepthState());\n\t\tthis._rlmMaxDepth = resolvedRlmMaxDepth.maxDepth;\n\t\tthis._rlmMaxDepthSource = resolvedRlmMaxDepth.source;\n\t\tthis._prewarmIpythonKernel = (config.prewarmIpythonKernel ?? false) && this._rlmDepth === 0;\n\t\tthis._autoRefineReviewer = config.autoRefineReviewer;\n\t\tthis._serializedRefine = config.serializedRefine ?? false;\n\t\tthis._rlmSessionDir = config.rlmSessionDir;\n\t\tthis._rlmParentNodeId = config.rlmParentNodeId;\n\t\tthis._rlmParentAgent = config.rlmParentAgent;\n\t\tthis._semanticEdges = new SemanticEdgeRecorder({\n\t\t\tledgerPath: semanticEdgeLedgerPath({\n\t\t\t\trlmSessionDir: this._rlmSessionDir,\n\t\t\t\tsessionArtifactDir: this.sessionManager.getSessionArtifactDir(),\n\t\t\t}),\n\t\t\tsessionId: this.sessionManager.getSessionId(),\n\t\t\tparentSessionId: config.semanticParentSessionId,\n\t\t\tspawnedByRequestId: config.semanticSpawnedByRequestId,\n\t\t});\n\t\tthis.requests = new InferenceCoordinator(\n\t\t\t() => this.sessionManager.bindRequestSink(),\n\t\t\t() => ({ parentSessionId: config.semanticParentSessionId }),\n\t\t\tconfig.requestTokenBudget,\n\t\t);\n\t\tthis.requests.setProviderRecoveryPolicy(() => ({\n\t\t\tenabled: this.settingsManager.getRetryEnabled(),\n\t\t\tbaseDelayMs: this.settingsManager.getRetrySettings().baseDelayMs,\n\t\t\tmaxRetryDelayMs: this.settingsManager.getProviderRetrySettings().maxRetryDelayMs || 60_000,\n\t\t}));\n\t\tthis.runtimeServices = { requests: this.requests };\n\t\tthis.requests.onActivityChange(() => this._notifySessionInputCheckpointChange());\n\t\tthis.agent.bindStreamOwner((streamFn) =>\n\t\t\twrapStreamFnWithSemanticEdges(\n\t\t\t\tthis.requests.bindStream(streamFn, {\n\t\t\t\t\tpurpose: this._rlmDepth > 0 ? \"child\" : \"main\",\n\t\t\t\t\tparentOperationId: config.semanticSpawnedByRequestId,\n\t\t\t\t}),\n\t\t\t\tthis._semanticEdges,\n\t\t\t),\n\t\t);\n\t\t// A resumed child may have replied before this process started; false would\n\t\t// claim knowledge that is not present in the session transcript.\n\t\tthis._repliedToParentSinceTask =\n\t\t\tthis._rlmDepth > 0 &&\n\t\t\t(this.sessionManager.isPersisted() ||\n\t\t\t\tthis.sessionManager.getBranch().some((entry) => entry.type === \"message\"))\n\t\t\t\t? undefined\n\t\t\t\t: false;\n\t\tthis._subagentRuntimeHost = config.subagentRuntimeHost;\n\t\tthis._autonomousState = createAutonomousRuntimeState(config.autonomous, {\n\t\t\tcwd: this._cwd,\n\t\t});\n\t\tthis._goalState = this.sessionManager.isPersisted() ? emptyGoalState() : this._loadPersistedGoalState();\n\t\tthis._initialGoal = config.initialGoal ? { ...config.initialGoal } : undefined;\n\t\tthis._restoreLateIpythonSentAgentMessages();\n\t\tif (this._goalState.status === \"active\") {\n\t\t\tthis._goalAccountingStartedAt = Date.now();\n\t\t}\n\n\t\tthis._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);\n\t\tthis._installAgentToolHooks();\n\t\tthis._installAgentTurnHook();\n\t\tthis._installAgentContinuationHook();\n\n\t\tif (!this.sessionManager.isPersisted()) {\n\t\t\tthis._buildRuntime({\n\t\t\t\tactiveToolNames: this._initialActiveToolNames,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async _waitForChildUsageWrites(): Promise<void> {\n\t\twhile (this._childUsageWrites.size > 0) await Promise.all([...this._childUsageWrites]);\n\t}\n\n\t/** Finish native bootstrap persistence before publishing this session. */\n\tinitialize(): Promise<void> {\n\t\tif (this._disposing || this._disposed)\n\t\t\treturn Promise.reject(new Error(\"Cannot initialize a disposing or disposed session.\"));\n\t\tthis._initialization ??= this._initialize();\n\t\treturn this._initialization;\n\t}\n\n\tprivate async _initialize(): Promise<void> {\n\t\tthis._rlmParentAdmission?.assertCurrent();\n\t\tthis._contextMode = await this._readContextMode();\n\t\tconst freshContextContract = this.sessionManager.canSeedContextModeContract();\n\t\tlet goalSeedable = false;\n\t\tif (this.sessionManager.isPersisted()) {\n\t\t\tconst bootstrap = await this._readRuntimeBootstrap();\n\t\t\tthis._goalState = bootstrap.goalState;\n\t\t\tthis._goalAccountingStartedAt = this._goalState.status === \"active\" ? Date.now() : undefined;\n\t\t\tgoalSeedable = bootstrap.goalSeedable;\n\t\t\tconst resolved = this._resolveRlmMaxDepth(bootstrap.rlmMaxDepth);\n\t\t\tthis._rlmMaxDepth = resolved.maxDepth;\n\t\t\tthis._rlmMaxDepthSource = resolved.source;\n\t\t\tthis._repliedToParentSinceTask = this._rlmDepth > 0 && bootstrap.hasBranchMessage ? undefined : false;\n\t\t\tthis._buildRuntime({\n\t\t\t\tactiveToolNames: this._initialActiveToolNames,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t\tif (\n\t\t\t\tthis._goalState.status === \"active\" &&\n\t\t\t\tthis._includeGoals &&\n\t\t\t\t!this.getActiveToolNames().includes(\"ipython\")\n\t\t\t) {\n\t\t\t\tthis.setActiveToolsByName([...this.getActiveToolNames(), \"ipython\"]);\n\t\t\t\tthis._prewarmIpythonIfNeeded();\n\t\t\t}\n\t\t} else if (this._rlmDepth === 0 && this._initialGoal) {\n\t\t\tgoalSeedable = this._isBranchSeedable();\n\t\t}\n\t\tif (this._rlmDepth === 0 && this._initialGoal && goalSeedable) {\n\t\t\tconst goal = await this._startGoal(this._initialGoal.objective, this._initialGoal.tokenBudget);\n\t\t\tthis._pendingNextTurnMessages.push(createGoalContextMessage(goal, \"continuation\"));\n\t\t\tthis._ensureGoalRuntimeActive();\n\t\t}\n\t\tawait this.sessionManager.flushNow();\n\t\tif (this._contextMode === \"off\") await this._writeContextMode(\"off\", freshContextContract);\n\t}\n\n\t/** Accepted canonical policy. Settings are only the creation default. */\n\tget contextMode(): ContextMode {\n\t\treturn this._contextMode;\n\t}\n\n\tprivate _contextOptimizationAllowed(): boolean {\n\t\treturn this._contextMode === \"on\" && this._pendingContextModeChanges === 0;\n\t}\n\n\tprivate _assertContextOptimizationAllowed(): void {\n\t\tif (!this._contextOptimizationAllowed())\n\t\t\tthrow new Error(\"Context optimization is disabled; explicitly re-enable context.mode first\");\n\t}\n\n\tprivate _retainContextOptimization<T>(operation: Promise<T>): Promise<T> {\n\t\tconst retained = operation.then(() => undefined);\n\t\tthis._autoRefineOperations.add(retained);\n\t\tvoid retained.finally(() => this._autoRefineOperations.delete(retained)).catch(() => undefined);\n\t\treturn operation;\n\t}\n\n\tprivate _readContextMode(): Promise<ContextMode> {\n\t\tif (!this.sessionManager.isPersisted()) return Promise.resolve(this._initialContextMode);\n\t\tconst { maxSourceBytes } = this.settingsManager.getCanonicalContextLimits();\n\t\treturn this.sessionManager.readBranchHistory((history) =>\n\t\t\treadCanonicalContextMode(history.branchContext, maxSourceBytes, this._initialContextMode),\n\t\t);\n\t}\n\n\t/** External session control; never await the current action's own pump or tool turn. */\n\tasync setContextMode(mode: ContextMode): Promise<void> {\n\t\tif (mode !== \"on\" && mode !== \"off\") throw new Error(\"context.mode must be on or off\");\n\t\tif (this._sessionActionCommitContext.getStore() !== undefined)\n\t\t\tthrow new Error(\"Context mode changes require external session control\");\n\t\tthis._pendingContextModeChanges++;\n\t\ttry {\n\t\t\tawait this.initialize();\n\t\t\twhile (true) {\n\t\t\t\tawait this._drainAcceptedRefinement();\n\t\t\t\tawait Promise.all([this._compactionOperation, this._branchSummaryOperation]);\n\t\t\t\tawait this.waitForIdle();\n\t\t\t\tconst fence = await this._acquireSessionActionCommitFence();\n\t\t\t\ttry {\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis.isStreaming ||\n\t\t\t\t\t\tthis.unfinishedActionCount !== 0 ||\n\t\t\t\t\t\tthis._compactionOperation ||\n\t\t\t\t\t\tthis._branchSummaryOperation ||\n\t\t\t\t\t\tthis._refineInFlight ||\n\t\t\t\t\t\tthis._refinePlanInFlight ||\n\t\t\t\t\t\tthis._serializedPlanInFlight\n\t\t\t\t\t)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tawait this._sessionActionCommitContext.run(fence.owner, () => this._writeContextMode(mode));\n\t\t\t\t\treturn;\n\t\t\t\t} finally {\n\t\t\t\t\tfence.release();\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\t// Restore only the reversible barrier. EOF/disposal remains permanently closed.\n\t\t\tthis._pendingContextModeChanges--;\n\t\t}\n\t}\n\n\t/** Called during unpublished initialization or while holding the existing session action fence. */\n\tprivate async _writeContextMode(mode: ContextMode, freshContextContract = false): Promise<void> {\n\t\tconst manager = this.sessionManager;\n\t\tconst limits = this.settingsManager.getCanonicalContextLimits();\n\t\tconst resource = this._captureKernelResource();\n\t\tconst compaction = manager.bindCompactionSink({\n\t\t\tmaxEntries: limits.maxMessages,\n\t\t\tmaxSourceBytes: limits.maxSourceBytes,\n\t\t});\n\t\tconst captured = this.requests.capture(compaction);\n\t\tlet committed: CompactionCommit | undefined;\n\t\tlet failure: unknown;\n\t\tlet primaryCause: unknown;\n\t\ttry {\n\t\t\tconst messages = await captured.readHistory((view) =>\n\t\t\t\tthis._contextCompiler.compile(view, limits, undefined, {}, resource, this._initialContextMode),\n\t\t\t);\n\t\t\tconst context = getCanonicalEpochContext(messages)!;\n\t\t\tif (\n\t\t\t\tcontextEpochMode(context.checkpoint, this._initialContextMode) === mode &&\n\t\t\t\t(context.checkpoint !== undefined || mode === \"on\")\n\t\t\t) {\n\t\t\t\tthis._contextMode = mode;\n\t\t\t} else {\n\t\t\t\tconst prepared = prepareContextModeEpoch(messages, mode, limits.maxSourceBytes, freshContextContract);\n\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\tconst entryId = await compaction[appendContextEpoch](prepared.checkpoint, null);\n\t\t\t\tcommitted = {\n\t\t\t\t\tentryId,\n\t\t\t\t\tresult: { summary: \"\", firstKeptEntryId: prepared.checkpoint.literalTailId, tokensBefore: null },\n\t\t\t\t};\n\t\t\t\t// ACK is authoritative even if later setup or release fails.\n\t\t\t\tthis._contextMode = mode;\n\t\t\t\tif (this.sessionManager !== manager || !compaction.isCurrent())\n\t\t\t\t\tthrow new Error(\"Context mode source changed before adoption\");\n\t\t\t\tassertResourceCurrent(resource);\n\t\t\t\tthis.agent.state.messages = prepared.messages;\n\t\t\t}\n\t\t} catch (cause) {\n\t\t\tprimaryCause = cause;\n\t\t\tfailure = committed ? new CompactionCommittedError(committed.entryId, committed.result, cause) : cause;\n\t\t\tif (committed) this._compactionSetupFailure = failure as CompactionCommittedError;\n\t\t}\n\t\ttry {\n\t\t\tawait captured.dispose();\n\t\t} catch (cause) {\n\t\t\tif (failure !== undefined) {\n\t\t\t\tif (cause !== primaryCause)\n\t\t\t\t\tfailure = new AggregateError([failure, cause], \"Context mode transition and release failed\", {\n\t\t\t\t\t\tcause: failure,\n\t\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tfailure = committed ? new CompactionCommittedError(committed.entryId, committed.result, cause) : cause;\n\t\t\t\tif (committed) this._compactionSetupFailure = failure as CompactionCommittedError;\n\t\t\t}\n\t\t}\n\t\tif (failure !== undefined) throw failure;\n\t}\n\n\t/** Refreshes MCP provider registrations without rebuilding the session runtime. */\n\trefreshMcpProviders(): void {\n\t\tthis._mcpManager?.refresh();\n\t}\n\n\t/**\n\t * Set the RLM heartbeat controller after construction. Used by\n\t * print/headless mode to attach an in-process heartbeat scheduler\n\t * when the session is created outside the daemon.\n\t */\n\tsetRlmHeartbeatController(controller: AgentRlmHeartbeatController): void {\n\t\tif (this._rlmHeartbeatController === controller) {\n\t\t\treturn;\n\t\t}\n\t\tthis._rlmHeartbeatController = controller;\n\t\tthis._buildRuntime({\n\t\t\tactiveToolNames: this.getActiveToolNames(),\n\t\t\tincludeAllExtensionTools: true,\n\t\t});\n\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t}\n\n\treplaceAcpMcpServers(servers: readonly AcpMcpServerConfig[], ownerId: string): void {\n\t\tif (this.isStreaming) throw new Error(\"Cannot replace ACP MCP servers while the agent is running\");\n\t\tif (!this._mcpManager) {\n\t\t\tif (servers.length > 0) throw new Error(\"MCP is unavailable in this session\");\n\t\t\treturn;\n\t\t}\n\t\tif (servers.length > 0 && !this._ipythonKernelProvisioner) {\n\t\t\tthrow new Error(\"ACP MCP servers require the built-in cpython tool\");\n\t\t}\n\t\tthis._assertAcpMcpToolNamesAvailable(acpMcpToolNames(servers));\n\t\tif (!this._mcpManager.replaceAcpServers(servers, ownerId)) return;\n\t\tthis._rebuildRuntimeForAcpMcpServers();\n\t}\n\n\tasync releaseAcpMcpServers(ownerId: string, serverNames: readonly string[]): Promise<void> {\n\t\tif (!this._mcpManager?.canReleaseAcpServers(ownerId)) return;\n\t\tif (this._mcpManager.replaceAcpServers([], ownerId)) {\n\t\t\tconst removedToolNames = new Set(this._acpMcpTools.map((tool) => tool.name));\n\t\t\tconst activeToolNames = this.getActiveToolNames().filter((name) => !removedToolNames.has(name));\n\t\t\tfor (const name of removedToolNames) this._allowedToolNames?.delete(name);\n\t\t\tthis._acpMcpTools = [];\n\t\t\tthis._refreshToolRegistry({ activeToolNames, includeAllExtensionTools: true });\n\t\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t\t}\n\t\tconst names = [...new Set(serverNames)];\n\t\tif (names.length === 0) return;\n\n\t\tconst inputPause = this.acquireSessionInputPause();\n\t\ttry {\n\t\t\t// Do not rebuild or kill the notebook. Wait for the current turn, then ask\n\t\t\t// the kernel-owned MCP registry to close only these cached transports.\n\t\t\tawait this.agent.waitForIdle();\n\t\t\tawait this._agentEventQueue;\n\t\t\tconst manager = this._ipythonKernelProvisioner?.manager;\n\t\t\tif (!manager?.isRunning) return;\n\t\t\tconst code = [\n\t\t\t\t\"import importlib as _prime_importlib\",\n\t\t\t\t'_prime_mcp = _prime_importlib.import_module(\"rlm.mcp\")',\n\t\t\t\t`_prime_mcp_names = ${JSON.stringify(names)}`,\n\t\t\t\t\"_prime_mcp_errors = []\",\n\t\t\t\t\"for _prime_mcp_name in _prime_mcp_names:\",\n\t\t\t\t\" try:\",\n\t\t\t\t\" await _prime_mcp.reload(_prime_mcp_name)\",\n\t\t\t\t\" except BaseException as _prime_mcp_error:\",\n\t\t\t\t\" _prime_mcp_errors.append(_prime_mcp_error)\",\n\t\t\t\t\"if _prime_mcp_errors:\",\n\t\t\t\t\" raise _prime_mcp_errors[0]\",\n\t\t\t\t\"del _prime_mcp, _prime_importlib, _prime_mcp_names, _prime_mcp_errors, _prime_mcp_name\",\n\t\t\t].join(\"\\n\");\n\t\t\tconst result = await manager.execute(code);\n\t\t\tif (result.status !== \"ok\") {\n\t\t\t\tthrow new Error(`Failed to close ACP MCP kernel transports: ${result.stderr || \"kernel error\"}`);\n\t\t\t}\n\t\t} finally {\n\t\t\tinputPause.release();\n\t\t}\n\t}\n\n\tprivate _assertAcpMcpToolNamesAvailable(names: readonly string[]): void {\n\t\tconst occupiedNames = new Set([\n\t\t\t...this._baseToolDefinitions.keys(),\n\t\t\t...this._customTools.map((tool) => tool.name),\n\t\t\t...this._extensionRunner.getAllRegisteredTools().map((tool) => tool.definition.name),\n\t\t]);\n\t\tfor (const name of names) {\n\t\t\tif (occupiedNames.has(name)) {\n\t\t\t\tthrow new Error(`ACP MCP tool name conflicts with an existing tool: ${name}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _rebuildRuntimeForAcpMcpServers(): void {\n\t\tconst previousToolNames = new Set(this._acpMcpTools.map((tool) => tool.name));\n\t\tconst nextToolNames = acpMcpToolNames(this._mcpManager?.getAcpServers() ?? []);\n\t\tthis._assertAcpMcpToolNamesAvailable(nextToolNames);\n\t\tconst activeToolNames = this.getActiveToolNames().filter((name) => !previousToolNames.has(name));\n\t\tactiveToolNames.push(...nextToolNames);\n\t\tthis._buildRuntime({\n\t\t\tactiveToolNames,\n\t\t\tincludeAllExtensionTools: true,\n\t\t});\n\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t}\n\n\tget modelRegistry(): ModelRegistry {\n\t\treturn this._modelRegistry;\n\t}\n\n\tsetSubagentRuntimeHost(host?: SubagentRuntimeHost): void {\n\t\tthis._subagentRuntimeHost = host;\n\t}\n\n\tprivate async _getRequiredRequestAuth(model: Model<any>): Promise<{\n\t\tapiKey: string;\n\t\theaders?: Record<string, string>;\n\t}> {\n\t\tconst result = await this._modelRegistry.getApiKeyAndHeaders(model);\n\t\tif (!result.ok) {\n\t\t\tif (result.error.startsWith(\"No API key found\")) {\n\t\t\t\tthrow new Error(formatNoApiKeyFoundMessage(model.provider));\n\t\t\t}\n\t\t\tthrow new Error(result.error);\n\t\t}\n\t\tif (result.apiKey) {\n\t\t\treturn { apiKey: result.apiKey, headers: result.headers };\n\t\t}\n\n\t\tconst isOAuth = this._modelRegistry.isUsingOAuth(model);\n\t\tif (isOAuth) {\n\t\t\tthrow new Error(formatAuthenticationFailedMessage(model.provider));\n\t\t}\n\t\tthrow new Error(formatNoApiKeyFoundMessage(model.provider));\n\t}\n\n\t/**\n\t * Install tool hooks once on the Agent instance.\n\t *\n\t * The callbacks read `this._extensionRunner` at execution time, so extension reload swaps in the\n\t * new runner without reinstalling hooks. Extension-specific tool wrappers are still used to adapt\n\t * registered tool execution to the extension context. Tool call and tool result interception now\n\t * happens here instead of in wrappers.\n\t */\n\tprivate _installAgentToolHooks(): void {\n\t\tthis.agent.beforeToolCall = async ({ toolCall, args }) => {\n\t\t\tconst runner = this._extensionRunner;\n\t\t\tif (!runner.hasHandlers(\"tool_call\")) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tawait this._agentEventQueue;\n\n\t\t\ttry {\n\t\t\t\treturn await runner.emitToolCall({\n\t\t\t\t\ttype: \"tool_call\",\n\t\t\t\t\ttoolName: toolCall.name,\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\tinput: args as Record<string, unknown>,\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Extension failed, blocking execution: ${String(err)}`);\n\t\t\t}\n\t\t};\n\n\t\tthis.agent.afterToolCall = async ({ toolCall, args, result, isError }) => {\n\t\t\tconst runner = this._extensionRunner;\n\t\t\tif (!runner.hasHandlers(\"tool_result\")) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst hookResult = await runner.emitToolResult({\n\t\t\t\ttype: \"tool_result\",\n\t\t\t\ttoolName: toolCall.name,\n\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\tinput: args as Record<string, unknown>,\n\t\t\t\tcontent: result.content,\n\t\t\t\tdetails: result.details,\n\t\t\t\tisError,\n\t\t\t});\n\n\t\t\tif (!hookResult) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: hookResult.content,\n\t\t\t\tdetails: hookResult.details,\n\t\t\t\tisError: hookResult.isError ?? isError,\n\t\t\t};\n\t\t};\n\t}\n\n\tprivate _installAgentContinuationHook(): void {\n\t\tthis.agent.getContinuationMessages = (context, signal) => this._getContinuationMessages(context, signal);\n\t\tthis.agent.getContinuationOutcome = (context, signal) => this._getContinuationOutcome(context, signal);\n\t}\n\n\tprivate _installAgentTurnHook(): void {\n\t\tthis.agent.shouldStopBeforeTurn = () => this._shouldStopBeforeTurn();\n\t\tthis.agent.shouldStopAfterTurn = (context) => this._shouldStopAfterTurn(context);\n\t\tthis.agent.getTurnOutcome = (context, signal) => this._getTurnOutcome(context, signal);\n\t}\n\n\tprivate _emit(event: AgentSessionEvent): void {\n\t\tfor (const l of this._eventListeners) {\n\t\t\ttry {\n\t\t\t\tl(event);\n\t\t\t} catch {\n\t\t\t\t// A failing observer must not prevent other subscribers from\n\t\t\t\t// receiving lifecycle and persistence events.\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _emitQueueUpdate(): void {\n\t\tconst actions = this.getSessionActionSnapshot();\n\t\tif (JSON.stringify(actions) === JSON.stringify(this._lastSessionActionSnapshot)) return;\n\t\tthis._lastSessionActionSnapshot = actions;\n\t\tthis._emit({ type: \"session_action_update\", actions });\n\t}\n\n\tprivate _restoreLateIpythonSentAgentMessages(): void {\n\t\tthis._lateIpythonSentAgentMessages.clear();\n\t\t// Native restored outputs come from the compiler; pending outputs use captured relation reads.\n\t\tif (this.sessionManager.supportsCapturedHistoryReads()) return;\n\t\tfor (const entry of this.sessionManager.getBranch()) {\n\t\t\tif (entry.type !== \"custom\" || entry.customType !== IPYTHON_SENT_AGENT_MESSAGE_CUSTOM_ENTRY) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst persisted = parsePersistedIpythonSentAgentMessage(entry.data);\n\t\t\tif (persisted) {\n\t\t\t\tthis._rememberLateIpythonSentAgentMessage(persisted.toolCallId, persisted.message);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _rememberLateIpythonSentAgentMessage(toolCallId: string, message: KernelSentAgentMessage): boolean {\n\t\tconst messages = this._lateIpythonSentAgentMessages.get(toolCallId) ?? [];\n\t\tconst isNew = !messages.some((entry) => entry.id === message.id);\n\t\tif (isNew) {\n\t\t\tmessages.push(message);\n\t\t\tthis._lateIpythonSentAgentMessages.set(toolCallId, messages);\n\t\t}\n\t\tfor (let index = this.agent.state.messages.length - 1; index >= 0; index -= 1) {\n\t\t\tif (appendSentAgentMessageToToolResult(this.agent.state.messages[index], toolCallId, message)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn isNew;\n\t}\n\n\tprivate _applyLateIpythonSentAgentMessages(message: AgentMessage): void {\n\t\tif (message.role !== \"toolResult\" || message.toolName !== \"ipython\") {\n\t\t\treturn;\n\t\t}\n\t\tfor (const sentMessage of this._lateIpythonSentAgentMessages.get(message.toolCallId) ?? []) {\n\t\t\tappendSentAgentMessageToToolResult(message, message.toolCallId, sentMessage);\n\t\t}\n\t}\n\n\tprivate async _applyCanonicalIpythonSentAgentMessages(message: AgentMessage): Promise<void> {\n\t\tif (message.role !== \"toolResult\" || message.toolName !== \"ipython\") return;\n\t\tconst toolCallId = message.toolCallId;\n\t\tconst refreshOutput = this._refreshInvocationOutput;\n\t\tconst limits = { ...this.settingsManager.getCanonicalContextLimits() };\n\t\tconst sentMessages = await this.sessionManager.readSourceHistory(async (history) => {\n\t\t\tconst messages: KernelSentAgentMessage[] = [];\n\t\t\tlet cursor: IpythonSentMessagesCursor | undefined;\n\t\t\tlet sourceBytes = 0;\n\t\t\tdo {\n\t\t\t\tconst page = await history.ipythonSentMessages(toolCallId, { cursor });\n\t\t\t\tfor (const ref of page.refs) {\n\t\t\t\t\tsourceBytes += ref.locator.length;\n\t\t\t\t\tif (sourceBytes > limits.maxSourceBytes || messages.length >= limits.maxMessages)\n\t\t\t\t\t\tthrow new Error(\"IPython sent-message history budget exceeded\");\n\t\t\t\t\tconst hydrated = await history.hydrateEntry(ref.entryId, limits.maxSourceBytes);\n\t\t\t\t\tconst sent =\n\t\t\t\t\t\thydrated?.entry.type === \"custom\"\n\t\t\t\t\t\t\t? parsePersistedIpythonSentAgentMessage(hydrated.entry.data)\n\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\tif (!sent || sent.toolCallId !== toolCallId)\n\t\t\t\t\t\tthrow new Error(\"IPython sent-message source is unavailable\");\n\t\t\t\t\tmessages.push(sent.message);\n\t\t\t\t}\n\t\t\t\tcursor = page.nextCursor ?? undefined;\n\t\t\t} while (cursor);\n\t\t\treturn messages;\n\t\t});\n\t\tfor (const sent of sentMessages) appendSentAgentMessageToToolResult(message, toolCallId, sent);\n\t\trefreshOutput?.(message);\n\t}\n\n\tprivate _recordLateIpythonSentAgentMessage(toolCallId: string, message: KernelSentAgentMessage): void {\n\t\tconst refreshOutput = this._refreshInvocationOutput;\n\t\tconst record = async () => {\n\t\t\tif (this._disposed) return;\n\t\t\tif (this.sessionManager.supportsCapturedHistoryReads()) {\n\t\t\t\tconst sessionId = this.sessionId;\n\t\t\t\tconst sessionFile = this.sessionFile;\n\t\t\t\tconst captured = structuredClone(message);\n\t\t\t\tconst result = await this.sessionManager.appendIpythonSentAgentMessage({ toolCallId, message: captured });\n\t\t\t\tif (!result.appended || sessionId !== this.sessionId || sessionFile !== this.sessionFile) return;\n\t\t\t\tfor (let index = this.agent.state.messages.length - 1; index >= 0; index--) {\n\t\t\t\t\tif (appendSentAgentMessageToToolResult(this.agent.state.messages[index], toolCallId, captured)) {\n\t\t\t\t\t\trefreshOutput?.(this.agent.state.messages[index]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis._emit({ type: \"ipython_sent_agent_message\", toolCallId, message: captured });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!this._rememberLateIpythonSentAgentMessage(toolCallId, message)) return;\n\t\t\tawait this.sessionManager.appendCustomEntry(IPYTHON_SENT_AGENT_MESSAGE_CUSTOM_ENTRY, { toolCallId, message });\n\t\t\tthis._emit({ type: \"ipython_sent_agent_message\", toolCallId, message });\n\t\t};\n\t\tthis._agentEventQueue = this._agentEventQueue.then(record, record);\n\t\tif (refreshOutput) this._invocationOutputUpdateTail = this._agentEventQueue;\n\t\tvoid this._agentEventQueue.catch((error) => this._surfaceSessionInputError(error));\n\t}\n\n\tprivate _emitGoalUpdate(): void {\n\t\tthis._emit({ type: \"goal_update\", goal: this.goalState });\n\t}\n\n\tprivate _loadPersistedRlmMaxDepthState(): PersistedRlmMaxDepthState | undefined {\n\t\tconst branch = this.sessionManager.getBranch();\n\t\tfor (let i = branch.length - 1; i >= 0; i--) {\n\t\t\tconst entry = branch[i];\n\t\t\tif (\n\t\t\t\tentry.type === \"custom\" &&\n\t\t\t\tentry.customType === RLM_MAX_DEPTH_STATE_CUSTOM_TYPE &&\n\t\t\t\tisPersistedRlmMaxDepthState(entry.data)\n\t\t\t) {\n\t\t\t\treturn entry.data;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _resolveRlmMaxDepth(persisted: PersistedRlmMaxDepthState | undefined): {\n\t\tmaxDepth: number;\n\t\tsource: RlmMaxDepthSource;\n\t} {\n\t\tif (persisted) {\n\t\t\treturn { maxDepth: persisted.maxDepth, source: \"chat\" };\n\t\t}\n\t\tif (this._configuredRlmMaxDepth !== undefined) {\n\t\t\treturn { maxDepth: this._configuredRlmMaxDepth, source: \"inherited\" };\n\t\t}\n\t\tconst global = this.settingsManager.getRlmMaxDepth();\n\t\tif (global !== undefined && isNonNegativeInteger(global)) {\n\t\t\treturn { maxDepth: global, source: \"global\" };\n\t\t}\n\t\tconst env = process.env.BASE_CONTEXT_RLM_MAX_DEPTH;\n\t\tif (env !== undefined && env !== \"\") {\n\t\t\treturn { maxDepth: parseDepth(env, 1, \"BASE_CONTEXT_RLM_MAX_DEPTH\"), source: \"env\" };\n\t\t}\n\t\treturn { maxDepth: 2, source: \"default\" };\n\t}\n\n\tprivate async _readRuntimeBootstrap(): Promise<{\n\t\tgoalState: GoalState;\n\t\tgoalSeedable: boolean;\n\t\trlmMaxDepth: PersistedRlmMaxDepthState | undefined;\n\t\thasBranchMessage: boolean;\n\t}> {\n\t\tconst { maxSourceBytes } = this.settingsManager.getCanonicalContextLimits();\n\t\treturn this.sessionManager.readBranchHistory(async (view) => {\n\t\t\tconst bootstrap = await view.branchBootstrap();\n\t\t\tlet remaining = maxSourceBytes;\n\t\t\tlet goalState = emptyGoalState();\n\t\t\tif (bootstrap.goalState) {\n\t\t\t\tif (bootstrap.goalState.locator.length > remaining)\n\t\t\t\t\tthrow new Error(\"Runtime bootstrap source byte budget exceeded\");\n\t\t\t\tconst hydrated = await view.hydrateEntry(bootstrap.goalState.id, remaining);\n\t\t\t\tremaining -= bootstrap.goalState.locator.length;\n\t\t\t\tif (\n\t\t\t\t\t!hydrated ||\n\t\t\t\t\thydrated.source.retention === \"retained-import\" ||\n\t\t\t\t\thydrated.entry.type !== \"custom\" ||\n\t\t\t\t\thydrated.entry.customType !== GOAL_STATE_CUSTOM_TYPE ||\n\t\t\t\t\t!isPersistedGoalState(hydrated.entry.data)\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Bootstrap goal source is unavailable or ineligible\");\n\t\t\t\tgoalState = normalizeGoalState(hydrated.entry.data);\n\t\t\t}\n\t\t\tlet rlmMaxDepth: PersistedRlmMaxDepthState | undefined;\n\t\t\tif (bootstrap.rlmMaxDepth) {\n\t\t\t\tif (bootstrap.rlmMaxDepth.locator.length > remaining)\n\t\t\t\t\tthrow new Error(\"Runtime bootstrap source byte budget exceeded\");\n\t\t\t\tconst hydrated = await view.hydrateEntry(bootstrap.rlmMaxDepth.id, remaining);\n\t\t\t\tif (\n\t\t\t\t\t!hydrated ||\n\t\t\t\t\thydrated.entry.type !== \"custom\" ||\n\t\t\t\t\thydrated.entry.customType !== RLM_MAX_DEPTH_STATE_CUSTOM_TYPE ||\n\t\t\t\t\t!isPersistedRlmMaxDepthState(hydrated.entry.data)\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Bootstrap RLM depth source is unavailable or ineligible\");\n\t\t\t\trlmMaxDepth = hydrated.entry.data;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tgoalState,\n\t\t\t\tgoalSeedable: bootstrap.goalSeedable,\n\t\t\t\trlmMaxDepth,\n\t\t\t\thasBranchMessage: bootstrap.hasBranchMessage,\n\t\t\t};\n\t\t});\n\t}\n\n\tprivate _loadPersistedGoalState(): GoalState {\n\t\tconst branch = this.sessionManager.getBranch();\n\t\tfor (let i = branch.length - 1; i >= 0; i--) {\n\t\t\tconst entry = branch[i];\n\t\t\tif (\n\t\t\t\tentry.type === \"custom\" &&\n\t\t\t\tentry.customType === GOAL_STATE_CUSTOM_TYPE &&\n\t\t\t\tthis.sessionManager.getEntryRetention(entry.id) !== \"retained-import\" &&\n\t\t\t\tisPersistedGoalState(entry.data)\n\t\t\t) {\n\t\t\t\treturn normalizeGoalState(entry.data);\n\t\t\t}\n\t\t}\n\t\treturn emptyGoalState();\n\t}\n\n\t/**\n\t * Whether the session branch is seedable for an initial goal. Returns true\n\t * only when the branch contains exclusively bootstrap entry types\n\t * (model_change, thinking_level_change, service_tier_change) and no\n\t * thread_goal_state custom entry. Any message, custom entry, or persisted\n\t * goal (including cleared/complete/error) means the session has been used\n\t * and should not be reseeded.\n\t */\n\tprivate _isBranchSeedable(): boolean {\n\t\tconst branch = this.sessionManager.getBranch();\n\t\tfor (const entry of branch) {\n\t\t\tswitch (entry.type) {\n\t\t\t\tcase \"model_change\":\n\t\t\t\tcase \"thinking_level_change\":\n\t\t\t\tcase \"service_tier_change\":\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"custom\":\n\t\t\t\t\tif (entry.customType === GOAL_STATE_CUSTOM_TYPE) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate async _reloadBranchRuntimeState(): Promise<void> {\n\t\tthis._contextMode = await this._readContextMode();\n\t\tconst bootstrap = this.sessionManager.isPersisted()\n\t\t\t? await this._readRuntimeBootstrap()\n\t\t\t: { goalState: this._loadPersistedGoalState(), rlmMaxDepth: this._loadPersistedRlmMaxDepthState() };\n\t\tthis._goalState = bootstrap.goalState;\n\t\tthis._goalAccountingStartedAt = this._goalState.status === \"active\" ? Date.now() : undefined;\n\t\tthis._emitGoalUpdate();\n\t\tconst previousMaxDepth = this._rlmMaxDepth;\n\t\tconst resolved = this._resolveRlmMaxDepth(bootstrap.rlmMaxDepth);\n\t\tthis._rlmMaxDepth = resolved.maxDepth;\n\t\tthis._rlmMaxDepthSource = resolved.source;\n\t\tif (resolved.maxDepth !== previousMaxDepth) {\n\t\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t\t}\n\t}\n\n\tprivate _captureGoalContinuationOwner(signal?: AbortSignal): GoalContinuationOwner {\n\t\tconst manager = this.sessionManager;\n\t\treturn {\n\t\t\tmanager,\n\t\t\tsessionId: manager.getSessionId(),\n\t\t\tsessionFile: manager.getSessionFile(),\n\t\t\tpumpEpoch: this._sessionInputPumpEpoch,\n\t\t\tgoal: this._goalState,\n\t\t\tgoalRevision: this._goalStateRevision,\n\t\t\taccountingStartedAt: this._goalAccountingStartedAt,\n\t\t\tsignal,\n\t\t};\n\t}\n\n\tprivate _isGoalContinuationOwnerCurrent(owner: GoalContinuationOwner): boolean {\n\t\treturn (\n\t\t\t!owner.signal?.aborted &&\n\t\t\t(!owner.checkpointOwner || this._isCompactionOwnerCurrent(owner.checkpointOwner)) &&\n\t\t\t!this._disposed &&\n\t\t\t!this._disposing &&\n\t\t\tthis.sessionManager === owner.manager &&\n\t\t\towner.manager.getSessionId() === owner.sessionId &&\n\t\t\towner.manager.getSessionFile() === owner.sessionFile &&\n\t\t\tthis._sessionInputPumpEpoch === (owner.checkpointOwner?.pumpEpoch ?? owner.pumpEpoch) &&\n\t\t\tthis._goalStateRevision === owner.goalRevision &&\n\t\t\tthis._goalState === owner.goal &&\n\t\t\tthis._goalAccountingStartedAt === owner.accountingStartedAt\n\t\t);\n\t}\n\n\tprivate _assertGoalContinuationOwner(owner: GoalContinuationOwner): void {\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) {\n\t\t\tthrow new StaleGoalContinuationError(\"Goal continuation owner changed\");\n\t\t}\n\t}\n\n\tprivate _stoppedContinuationOutcome(signal?: AbortSignal): AgentContinuationOutcome {\n\t\treturn { kind: signal?.aborted || this._disposed || this._disposing ? \"cancelled\" : \"finish\" };\n\t}\n\n\tprivate async _persistGoalState(\n\t\tgoal: GoalState,\n\t\tnativeGoalWrite?: CapturedNativeGoalWrite,\n\t\tcontinuationOwner?: GoalContinuationOwner,\n\t): Promise<void> {\n\t\tconst manager = continuationOwner?.manager ?? this.sessionManager;\n\t\tif (continuationOwner) this._assertGoalContinuationOwner(continuationOwner);\n\t\tif (nativeGoalWrite) await nativeGoalWrite(goal);\n\t\telse await manager.appendCustomEntry(GOAL_STATE_CUSTOM_TYPE, goal);\n\t\t// Accepted writes stay on their source. Do not admit a flush on a replacement after the ACK.\n\t\tif (continuationOwner) this._assertGoalContinuationOwner(continuationOwner);\n\t\t// Force flush so the goal state is durable before the first assistant response.\n\t\tawait manager.flushNow();\n\t}\n\n\tprivate async _setGoalState(\n\t\tnext: GoalState,\n\t\toptions: {\n\t\t\tpersist?: boolean;\n\t\t\tnativeGoalWrite?: CapturedNativeGoalWrite;\n\t\t\tcontinuationOwner?: GoalContinuationOwner;\n\t\t} = {},\n\t): Promise<GoalState> {\n\t\tconst owner = options.continuationOwner;\n\t\tif (owner) this._assertGoalContinuationOwner(owner);\n\t\t// A newer goal write invalidates a continuation before that write's awaited publication.\n\t\tthis._goalStateRevision++;\n\t\tif (owner) owner.goalRevision = this._goalStateRevision;\n\t\tconst normalized = normalizeGoalState({\n\t\t\t...next,\n\t\t\tupdatedAt: Date.now(),\n\t\t});\n\t\tif (options.persist !== false) {\n\t\t\tawait this._persistGoalState(normalized, options.nativeGoalWrite, owner);\n\t\t}\n\t\tif (owner) this._assertGoalContinuationOwner(owner);\n\t\tthis._goalState = normalized;\n\t\tif (normalized.status === \"active\") {\n\t\t\tthis._goalAccountingStartedAt ??= Date.now();\n\t\t} else {\n\t\t\tthis._goalAccountingStartedAt = undefined;\n\t\t}\n\t\tif (owner) {\n\t\t\towner.goal = normalized;\n\t\t\towner.accountingStartedAt = this._goalAccountingStartedAt;\n\t\t}\n\t\tthis._emitGoalUpdate();\n\t\treturn normalized;\n\t}\n\n\tprivate _goalWithCurrentWallClock(now = Date.now()): GoalState {\n\t\tif (this._goalState.status !== \"active\" || !this._goalAccountingStartedAt) {\n\t\t\treturn this._goalState;\n\t\t}\n\t\tconst elapsedSeconds = Math.floor((now - this._goalAccountingStartedAt) / 1000);\n\t\tif (elapsedSeconds <= 0) {\n\t\t\treturn this._goalState;\n\t\t}\n\t\treturn {\n\t\t\t...this._goalState,\n\t\t\ttimeUsedSeconds: this._goalState.timeUsedSeconds + elapsedSeconds,\n\t\t};\n\t}\n\n\tprivate _goalWithAccountedWallClock(): GoalState {\n\t\tconst now = Date.now();\n\t\tconst goal = this._goalWithCurrentWallClock(now);\n\t\tif (goal !== this._goalState) {\n\t\t\tthis._goalAccountingStartedAt = now;\n\t\t}\n\t\treturn goal;\n\t}\n\n\tprivate _cancelSessionActions(\n\t\tpredicate: (action: QueuedSessionAction) => boolean,\n\t\terror: Error,\n\t\tcandidates = this._actionStore.clearableActions(),\n\t): QueuedSessionAction[] {\n\t\tconst matching = candidates.filter(predicate);\n\t\tconst previousStates = new Map(matching.map((action) => [action.id, action.lifecycle.state]));\n\t\tconst preparing = this._actionStore\n\t\t\t.activeActions()\n\t\t\t.filter(\n\t\t\t\t(action): action is SessionAction<PreparedTurnPayload> =>\n\t\t\t\t\taction.payload.kind === \"turn\" && action.lifecycle.state === \"preparing\",\n\t\t\t);\n\t\tconst previousAnchor = preparing.at(-1);\n\t\tconst actions = this._actionStore.remove(predicate, candidates);\n\t\tconst restorableMessages: CustomMessage[] = [];\n\t\tconst removed = new Set(actions);\n\t\tif (previousAnchor && removed.has(previousAnchor)) {\n\t\t\tfor (const action of preparing) {\n\t\t\t\tif (!removed.has(action)) action.payload.prepared = undefined;\n\t\t\t}\n\t\t}\n\t\tfor (const action of actions) {\n\t\t\tconst ticket = this._actionStore.ticketFor(action);\n\t\t\tif (\n\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t(action.payload.acceptedAgentMessage ||\n\t\t\t\t\t!action.payload.queueVisible ||\n\t\t\t\t\tpreviousStates.get(action.id) !== \"queued\")\n\t\t\t) {\n\t\t\t\tticket.rejectDelivered(error);\n\t\t\t} else {\n\t\t\t\tticket.settleDelivered({ status: \"not_applicable\" });\n\t\t\t}\n\t\t\tticket.settleCompleted(error);\n\t\t\tconst dispatched = previousStates.get(action.id) === \"committing\" && action.payload.kind === \"turn\";\n\t\t\tif (action.payload.kind === \"turn\") {\n\t\t\t\tconst payload = action.payload;\n\t\t\t\tconst restorable = payload.records\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(record): record is DeliveryRecord & { message: CustomMessage } =>\n\t\t\t\t\t\t\t(record.role === \"next_turn\" || (payload.acceptedAgentMessage && record.role === \"prefix\")) &&\n\t\t\t\t\t\t\trecord.message.role === \"custom\" &&\n\t\t\t\t\t\t\t!record.durable,\n\t\t\t\t\t)\n\t\t\t\t\t.map((record) => cloneCustomMessage(record.message));\n\t\t\t\trestorableMessages.push(...restorable);\n\t\t\t\tif (dispatched) {\n\t\t\t\t\tpayload.captureRunMessages = new Set(payload.records.map((record) => record.message));\n\t\t\t\t\tthis.agent.state.messages = this.agent.state.messages.filter(\n\t\t\t\t\t\t(message) => !payload.captureRunMessages?.has(message),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!dispatched) {\n\t\t\t\tthis._actionStore.releaseTerminal(action);\n\t\t\t}\n\t\t}\n\t\tthis._pendingNextTurnMessages.unshift(...restorableMessages);\n\t\tif (actions.length > 0) this._notifySessionInputCheckpointChange();\n\t\treturn actions;\n\t}\n\n\tprivate _clearQueuedGoalContexts(): void {\n\t\tthis._goalContinuationAwaitsRlmWork = false;\n\t\tthis._pendingNextTurnMessages = this._pendingNextTurnMessages.filter(\n\t\t\t(message) => message.customType !== GOAL_CONTEXT_CUSTOM_TYPE,\n\t\t);\n\t\tthis.agent.removeQueuedMessages(\n\t\t\t(message) => message.role === \"custom\" && message.customType === GOAL_CONTEXT_CUSTOM_TYPE,\n\t\t);\n\t\tthis._cancelSessionActions(\n\t\t\t(action) =>\n\t\t\t\taction.payload.kind === \"turn\" && action.payload.customMessage?.customType === GOAL_CONTEXT_CUSTOM_TYPE,\n\t\t\tnew Error(\"Queued goal context was cleared before delivery.\"),\n\t\t);\n\t\tthis._emitQueueUpdate();\n\t}\n\n\tprivate async _startGoal(\n\t\tobjectiveText: string,\n\t\ttokenBudget: number | undefined,\n\t\tnativeGoalWrite?: CapturedNativeGoalWrite,\n\t): Promise<GoalState> {\n\t\tconst objective = validateGoalObjective(objectiveText);\n\t\tconst budget = validateGoalBudget(tokenBudget);\n\t\tconst now = Date.now();\n\t\tconst goal: GoalState = {\n\t\t\tactive: true,\n\t\t\tstatus: \"active\",\n\t\t\tgoalId: randomUUID(),\n\t\t\tobjective,\n\t\t\ttokenBudget: budget,\n\t\t\ttokensUsed: 0,\n\t\t\ttimeUsedSeconds: 0,\n\t\t\tcontinuationsUsed: 0,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t};\n\t\tthis._goalAccountingStartedAt = now;\n\t\tthis._goalContinuationAwaitsRlmWork = false;\n\t\treturn this._setGoalState(goal, { nativeGoalWrite });\n\t}\n\n\tprivate async _clearGoal(nativeGoalWrite?: CapturedNativeGoalWrite): Promise<void> {\n\t\tthis._clearQueuedGoalContexts();\n\t\tawait this._setGoalState(emptyGoalState(), { nativeGoalWrite });\n\t}\n\n\tprivate async _pauseGoal(reason = \"Paused by user\", nativeGoalWrite?: CapturedNativeGoalWrite): Promise<void> {\n\t\tthis._clearQueuedGoalContexts();\n\t\tif (this._goalState.status !== \"active\") {\n\t\t\tthis._emitGoalUpdate();\n\t\t\treturn;\n\t\t}\n\t\tconst goal = this._goalWithAccountedWallClock();\n\t\tawait this._setGoalState(\n\t\t\t{\n\t\t\t\t...goal,\n\t\t\t\tactive: false,\n\t\t\t\tstatus: \"paused\",\n\t\t\t\tlastReason: reason,\n\t\t\t\tlastError: undefined,\n\t\t\t},\n\t\t\t{ nativeGoalWrite },\n\t\t);\n\t}\n\n\tprivate async _resumeGoal(nativeGoalWrite?: CapturedNativeGoalWrite): Promise<void> {\n\t\tif (!this._goalState.objective) {\n\t\t\tthis._emitGoalUpdate();\n\t\t\treturn;\n\t\t}\n\t\tif (this._goalState.status !== \"paused\" && this._goalState.status !== \"budget_limited\") {\n\t\t\tthis._emitGoalUpdate();\n\t\t\treturn;\n\t\t}\n\t\tconst exhausted =\n\t\t\tthis._goalState.tokenBudget !== undefined && this._goalState.tokensUsed >= this._goalState.tokenBudget;\n\t\tconst nextStatus: GoalStatus = exhausted ? \"budget_limited\" : \"active\";\n\t\tawait this._setGoalState(\n\t\t\t{\n\t\t\t\t...this._goalState,\n\t\t\t\tactive: nextStatus === \"active\",\n\t\t\t\tstatus: nextStatus,\n\t\t\t\tlastReason: exhausted ? \"Goal token budget already reached\" : undefined,\n\t\t\t\tlastError: undefined,\n\t\t\t},\n\t\t\t{ nativeGoalWrite },\n\t\t);\n\t\tif (nextStatus === \"active\") {\n\t\t\tawait this._runOrQueueGoalContext(\"continuation\");\n\t\t}\n\t}\n\n\tprivate async _finishGoalWithError(errorMessage: string, continuationOwner?: GoalContinuationOwner): Promise<void> {\n\t\tif (continuationOwner) this._assertGoalContinuationOwner(continuationOwner);\n\t\tif (!this._goalState.objective || this._goalState.status !== \"active\") {\n\t\t\treturn;\n\t\t}\n\t\tconst goal = this._goalWithAccountedWallClock();\n\t\tif (continuationOwner) continuationOwner.accountingStartedAt = this._goalAccountingStartedAt;\n\t\tawait this._setGoalState(\n\t\t\t{\n\t\t\t\t...goal,\n\t\t\t\tactive: false,\n\t\t\t\tstatus: \"error\",\n\t\t\t\tlastReason: errorMessage,\n\t\t\t\tlastError: errorMessage,\n\t\t\t},\n\t\t\t{ continuationOwner },\n\t\t);\n\t}\n\n\tprivate async _finishGoalForTerminalAssistantMessage(\n\t\tmessage: AssistantMessage,\n\t\tcontinuationOwner?: GoalContinuationOwner,\n\t): Promise<void> {\n\t\tif (continuationOwner) this._assertGoalContinuationOwner(continuationOwner);\n\t\tif (this._goalState.status !== \"active\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (message.stopReason === \"aborted\") {\n\t\t\tthis._goalAbortInProgress = false;\n\t\t\treturn;\n\t\t}\n\n\t\tif (message.stopReason === \"error\") {\n\t\t\tif (this._goalAbortInProgress) {\n\t\t\t\tthis._goalAbortInProgress = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this._finishGoalWithError(message.errorMessage || \"Assistant response failed\", continuationOwner);\n\t\t}\n\t}\n\n\tprivate async _stopGoalContinuationForTerminalMessage(\n\t\tmessage: AssistantMessage,\n\t\tcontinuationOwner?: GoalContinuationOwner,\n\t): Promise<boolean> {\n\t\tif (message.stopReason !== \"error\" && message.stopReason !== \"aborted\") {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tawait this._finishGoalForTerminalAssistantMessage(message, continuationOwner);\n\t\t} catch {\n\t\t\t// Goal hooks must not reject; listener failures should not crash the agent loop.\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate _parseGoalSlashCommand(text: string): GoalSlashCommand | undefined {\n\t\tconst command = parseSessionSlashCommand(text);\n\t\tif (command?.name !== \"goal\") return undefined;\n\n\t\tconst rest = command.args;\n\t\tconst normalized = rest.toLowerCase();\n\t\tif (!rest || normalized === \"status\") {\n\t\t\treturn { kind: \"status\" };\n\t\t}\n\t\tif (normalized === \"clear\" || normalized === \"stop\") {\n\t\t\treturn { kind: \"clear\" };\n\t\t}\n\t\tif (normalized === \"pause\") {\n\t\t\treturn { kind: \"pause\" };\n\t\t}\n\t\tif (normalized === \"resume\") {\n\t\t\treturn { kind: \"resume\" };\n\t\t}\n\n\t\tlet tokenBudget: number | undefined;\n\t\tlet objective = rest;\n\t\tconst firstToken = rest.split(/\\s+/, 1)[0] ?? \"\";\n\t\tif (\n\t\t\tfirstToken === \"--budget\" ||\n\t\t\tfirstToken === \"--token-budget\" ||\n\t\t\tfirstToken.startsWith(\"--budget=\") ||\n\t\t\tfirstToken.startsWith(\"--token-budget=\")\n\t\t) {\n\t\t\tlet valueText: string;\n\t\t\tif (firstToken === \"--budget\" || firstToken === \"--token-budget\") {\n\t\t\t\tconst withoutFlag = rest.slice(firstToken.length).trimStart();\n\t\t\t\tconst nextSpace = withoutFlag.search(/\\s/);\n\t\t\t\tif (nextSpace < 0) {\n\t\t\t\t\tthrow new Error(\"Usage: /goal [--budget <tokens>] <objective>\");\n\t\t\t\t}\n\t\t\t\tvalueText = withoutFlag.slice(0, nextSpace);\n\t\t\t\tobjective = withoutFlag.slice(nextSpace + 1).trim();\n\t\t\t} else {\n\t\t\t\tconst separator = firstToken.indexOf(\"=\");\n\t\t\t\tvalueText = firstToken.slice(separator + 1);\n\t\t\t\tobjective = rest.slice(firstToken.length).trim();\n\t\t\t}\n\t\t\ttokenBudget = parseGoalBudgetValue(valueText);\n\t\t}\n\n\t\treturn {\n\t\t\tkind: \"start\",\n\t\t\tobjective: validateGoalObjective(objective),\n\t\t\ttokenBudget,\n\t\t};\n\t}\n\n\tprivate _parseAutonomousSlashCommand(text: string): AutonomousSlashCommand | undefined {\n\t\tconst command = parseSessionSlashCommand(text);\n\t\tif (command?.name !== \"autonomous\") return undefined;\n\t\tconst rest = command.args.toLowerCase();\n\t\tif (!rest || rest === \"status\") {\n\t\t\treturn { kind: \"status\" };\n\t\t}\n\t\tif (rest === \"on\" || rest === \"enable\" || rest === \"enabled\") {\n\t\t\treturn { kind: \"on\" };\n\t\t}\n\t\tif (rest === \"off\" || rest === \"disable\" || rest === \"disabled\") {\n\t\t\treturn { kind: \"off\" };\n\t\t}\n\t\tthrow new Error(\"Usage: /autonomous [on|off|status]\");\n\t}\n\n\tprivate _formatAutonomousStatus(): string {\n\t\tconst status = this.getAutonomousStatus();\n\t\tconst state = status.enabled ? \"on\" : \"off\";\n\t\treturn `Autonomous mode: ${state}. Continuations: ${status.continuationsUsed}/${status.limits.maxContinuations}. Turns: ${status.turnsUsed}/${status.limits.maxTurns}. Tokens: ${status.tokensUsed}/${status.limits.maxTokens}.`;\n\t}\n\n\tprivate async _emitAutonomousStatus(): Promise<void> {\n\t\tconst message = {\n\t\t\trole: \"custom\" as const,\n\t\t\tcustomType: \"autonomous_status\",\n\t\t\tcontent: this._formatAutonomousStatus(),\n\t\t\tdisplay: true,\n\t\t\tdetails: this.getAutonomousStatus(),\n\t\t\ttimestamp: Date.now(),\n\t\t} satisfies CustomMessage<AgentAutonomousStatus>;\n\t\tawait this.sessionManager.appendCustomMessageEntry(\n\t\t\tmessage.customType,\n\t\t\tmessage.content,\n\t\t\tmessage.display,\n\t\t\tmessage.details,\n\t\t);\n\t\tthis.agent.state.messages.push(message);\n\t\tthis._emit({ type: \"message_start\", message });\n\t\tthis._emit({ type: \"message_end\", message });\n\t}\n\n\tprivate async _handleAutonomousSlashCommand(text: string): Promise<boolean> {\n\t\tconst command = this._parseAutonomousSlashCommand(text);\n\t\tif (!command) {\n\t\t\treturn false;\n\t\t}\n\t\tif (command.kind === \"on\") {\n\t\t\tsetAutonomousEnabled(this._autonomousState, true, { cwd: this._cwd });\n\t\t} else if (command.kind === \"off\") {\n\t\t\tsetAutonomousEnabled(this._autonomousState, false);\n\t\t\tthis._clearQueuedAutonomousContinuations();\n\t\t}\n\t\tawait this._emitAutonomousStatus();\n\t\treturn true;\n\t}\n\n\tprivate _appendBeforeAgentStartMessages(\n\t\tmessages: AgentMessage[],\n\t\tresult: Awaited<ReturnType<ExtensionRunner[\"emitBeforeAgentStart\"]>>,\n\t): void {\n\t\tif (!result?.messages) return;\n\t\tfor (const message of result.messages) {\n\t\t\tmessages.push({\n\t\t\t\trole: \"custom\",\n\t\t\t\tcustomType: message.customType,\n\t\t\t\tcontent: message.content,\n\t\t\t\tdisplay: message.display,\n\t\t\t\tdetails: message.details,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async _validateCanStartAgentRun(): Promise<void> {\n\t\tif (!this.model) {\n\t\t\tthrow new Error(formatNoModelSelectedMessage());\n\t\t}\n\t\tif (!this._modelRegistry.hasConfiguredAuth(this.model)) {\n\t\t\tconst isOAuth = this._modelRegistry.isUsingOAuth(this.model);\n\t\t\tif (isOAuth) {\n\t\t\t\tthrow new Error(formatAuthenticationFailedMessage(this.model.provider));\n\t\t\t}\n\t\t\tthrow new Error(formatNoApiKeyFoundMessage(this.model.provider));\n\t\t}\n\t}\n\n\t/**\n\t * Goals are pursued through the kernel goal skill, so the only tool the\n\t * model needs is ipython. Force-activate it (including into a live\n\t * continuation context) so the model can always reach `goal.complete()`.\n\t */\n\tprivate _ensureGoalRuntimeActive(context?: AgentContext): void {\n\t\tif (!this._includeGoals) {\n\t\t\tthrow new Error(\"Goals are disabled. Enable goals before using /goal.\");\n\t\t}\n\t\tconst ipythonTool = this._toolRegistry.get(\"ipython\");\n\t\tif (!ipythonTool) {\n\t\t\tthrow new Error(\"Goals require the ipython tool, which is not available in this session.\");\n\t\t}\n\t\tconst activeToolNames = new Set(this.getActiveToolNames());\n\t\tif (!activeToolNames.has(\"ipython\")) {\n\t\t\tactiveToolNames.add(\"ipython\");\n\t\t\tthis.setActiveToolsByName([...activeToolNames]);\n\t\t}\n\t\tif (context) {\n\t\t\tconst contextTools = [...(context.tools ?? [])];\n\t\t\tif (!contextTools.some((tool) => tool.name === \"ipython\")) {\n\t\t\t\tcontextTools.push(ipythonTool);\n\t\t\t\tcontext.tools = contextTools;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _scheduleGoalContinuationAfterRlmWork(): void {\n\t\tif (this._goalResumeOperation || !this._goalContinuationAwaitsRlmWork) return;\n\t\tconst operation = this._resumeGoalContinuationAfterRlmWork();\n\t\tthis._goalResumeOperation = operation;\n\t\tvoid operation\n\t\t\t.finally(() => {\n\t\t\t\tif (this._goalResumeOperation === operation) this._goalResumeOperation = undefined;\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t})\n\t\t\t.catch((error) => this._surfaceSessionInputError(error));\n\t}\n\n\tprivate async _resumeGoalContinuationAfterRlmWork(): Promise<void> {\n\t\tif (!this._goalContinuationAwaitsRlmWork) return;\n\t\tif (this._disposed || this._disposing || this._hasUnsettledRlmQuiescenceWork()) return;\n\t\tif (this._goalState.status !== \"active\" || !this._goalState.objective) {\n\t\t\tthis._goalContinuationAwaitsRlmWork = false;\n\t\t\treturn;\n\t\t}\n\t\t// Keep the deferral while admission is paused or the pump is suspended\n\t\t// (post-abort); the pause release and resumeQueuedWork retry.\n\t\tif (this._sessionInputAdmissionPauses.size > 0 || this._sessionInputPumpSuspended) return;\n\t\tconst owner = this._captureGoalContinuationOwner();\n\t\tconst goalBeforeResume = owner.goal;\n\t\ttry {\n\t\t\tthis._ensureGoalRuntimeActive();\n\t\t\tawait this._setGoalState(\n\t\t\t\t{\n\t\t\t\t\t...owner.goal,\n\t\t\t\t\tcontinuationsUsed: owner.goal.continuationsUsed + 1,\n\t\t\t\t\tlastReason: undefined,\n\t\t\t\t\tlastError: undefined,\n\t\t\t\t},\n\t\t\t\t{ continuationOwner: owner },\n\t\t\t);\n\t\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return;\n\t\t\tconst message = createGoalContextMessage(owner.goal, \"continuation\");\n\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\t// No front: a settling child's terminal notice must be read first.\n\t\t\tthis._admitSessionInput(\n\t\t\t\tthis._createPreparedTurnAction(\"followUp\", normalized.text, normalized.images, {\n\t\t\t\t\tmessage,\n\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tthis._goalContinuationAwaitsRlmWork = false;\n\t\t} catch {\n\t\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return;\n\t\t\t// Compensate only on the unchanged owner; an accepted old write is not rolled back on a new goal.\n\t\t\ttry {\n\t\t\t\tawait this._setGoalState(goalBeforeResume, { continuationOwner: owner });\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof StaleGoalContinuationError)) throw error;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _runOrQueueGoalContext(kind: \"continuation\" | \"objective_updated\", images?: ImageContent[]): void {\n\t\tif (!this._goalState.objective) return;\n\t\tthis._ensureGoalRuntimeActive();\n\t\tconst message = createGoalContextMessage(this._goalState, kind, images);\n\t\tconst normalized = normalizeMessageContent(message.content);\n\t\tconst action = this._createPreparedTurnAction(\"followUp\", normalized.text, normalized.images, {\n\t\t\tmessage,\n\t\t\tresumeIfIdle: true,\n\t\t});\n\t\tthis._admitSessionInput(action, { front: true, wake: false });\n\t}\n\n\tprivate async _handleGoalSlashCommand(\n\t\ttext: string,\n\t\timages: ImageContent[] | undefined,\n\t\tcontext?: GoalOriginContext,\n\t): Promise<boolean> {\n\t\tconst command = this._parseGoalSlashCommand(text);\n\t\tif (!command) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst previousGoalId = this._goalState.goalId;\n\t\tconst replacementOperation = this._goalState.objective ? \"revise\" : \"create\";\n\t\tconst origin = (operation: GoalOperationOrigin[\"operation\"]): CapturedNativeGoalWrite | undefined => {\n\t\t\tif (!context) return undefined;\n\t\t\tconst { writer, ...captured } = context;\n\t\t\treturn writer.captureGoalOperation({\n\t\t\t\tversion: 1,\n\t\t\t\tkind: \"goal_operation\",\n\t\t\t\t...captured,\n\t\t\t\toperation,\n\t\t\t\tpreviousGoalId,\n\t\t\t});\n\t\t};\n\n\t\tif (command.kind === \"status\") {\n\t\t\tthis._emitGoalUpdate();\n\t\t\treturn true;\n\t\t}\n\n\t\tif (command.kind === \"clear\") {\n\t\t\tawait this._clearGoal(origin(\"clear\"));\n\t\t\treturn true;\n\t\t}\n\n\t\tif (command.kind === \"pause\") {\n\t\t\tawait this._pauseGoal(undefined, origin(\"pause\"));\n\t\t\treturn true;\n\t\t}\n\n\t\tif (command.kind === \"resume\") {\n\t\t\tawait this._resumeGoal(origin(\"resume\"));\n\t\t\treturn true;\n\t\t}\n\n\t\tconst previousWasActive = this._goalState.status === \"active\";\n\t\tconst nativeGoalWrite = origin(replacementOperation);\n\t\tif (!this.isStreaming) {\n\t\t\tawait this._validateCanStartAgentRun();\n\t\t}\n\t\tthis._ensureGoalRuntimeActive();\n\t\tthis._clearQueuedGoalContexts();\n\t\tawait this._startGoal(command.objective, command.tokenBudget, nativeGoalWrite);\n\t\tawait this._runOrQueueGoalContext(previousWasActive ? \"objective_updated\" : \"continuation\", images);\n\t\treturn true;\n\t}\n\n\tprivate async _accountGoalUsageForAssistantMessage(\n\t\tmessage: AssistantMessage,\n\t\towner?: GoalContinuationOwner,\n\t): Promise<boolean> {\n\t\tif (owner) this._assertGoalContinuationOwner(owner);\n\t\tif (!this._goalState.objective) {\n\t\t\treturn false;\n\t\t}\n\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\treturn false;\n\t\t}\n\t\tif (this._goalAccountedAssistantMessages.has(message)) {\n\t\t\treturn false;\n\t\t}\n\t\t// Usage is attributed at the assistant message's message_end, which fires\n\t\t// before that turn's ipython cell runs. goal.complete() only arrives later\n\t\t// over the kernel host bridge, so the completing turn is always accounted\n\t\t// while the goal is still active. Only count turns spent pursuing the goal;\n\t\t// post-completion turns (e.g. a closing summary) must not be attributed.\n\t\tif (this._goalState.status !== \"active\") {\n\t\t\treturn false;\n\t\t}\n\t\tthis._goalAccountedAssistantMessages.add(message);\n\t\tconst tokenDelta = goalTokenDeltaForUsage(message.usage);\n\t\tconst goal = this._goalWithAccountedWallClock();\n\t\tif (owner) owner.accountingStartedAt = this._goalAccountingStartedAt;\n\t\tconst nextGoal: GoalState = {\n\t\t\t...goal,\n\t\t\ttokensUsed: goal.tokensUsed + tokenDelta,\n\t\t};\n\t\tconst budgetReached = nextGoal.tokenBudget !== undefined && nextGoal.tokensUsed >= nextGoal.tokenBudget;\n\t\tif (!budgetReached) {\n\t\t\tawait this._setGoalState(nextGoal, { continuationOwner: owner });\n\t\t\treturn false;\n\t\t}\n\t\tawait this._setGoalState(\n\t\t\t{\n\t\t\t\t...nextGoal,\n\t\t\t\tactive: false,\n\t\t\t\tstatus: \"budget_limited\",\n\t\t\t\tlastReason: `Reached ${nextGoal.tokenBudget} token goal budget`,\n\t\t\t\tlastError: undefined,\n\t\t\t},\n\t\t\t{ continuationOwner: owner },\n\t\t);\n\t\treturn true;\n\t}\n\n\tprivate get _steeringStopPending(): boolean {\n\t\treturn (\n\t\t\tthis._actionStore.queuedActions(\"next_turn_boundary\").length > 0 ||\n\t\t\tthis._actionStore\n\t\t\t\t.activeActions(\"next_turn_boundary\")\n\t\t\t\t.some(\n\t\t\t\t\t(action) =>\n\t\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\t\t(action.lifecycle.state === \"selected\" || action.lifecycle.state === \"preparing\"),\n\t\t\t\t)\n\t\t);\n\t}\n\n\tprivate _shouldStopBeforeTurn(): boolean {\n\t\treturn this._steeringStopPending;\n\t}\n\n\tprivate _captureCompactionOwner(signal?: AbortSignal): CompactionOwner {\n\t\tconst manager = this.sessionManager;\n\t\treturn {\n\t\t\tmanager,\n\t\t\tagent: this.agent,\n\t\t\tsessionId: manager.getSessionId(),\n\t\t\tsessionFile: manager.getSessionFile(),\n\t\t\tpumpEpoch: this._sessionInputPumpEpoch,\n\t\t\tisSourceCurrent: manager.captureCompactionSourceOwner(),\n\t\t\trequests: this.requests,\n\t\t\tsemanticEdges: this._semanticEdges,\n\t\t\textensions: this._extensionRunner,\n\t\t\tprovisioner: this._ipythonKernelProvisioner,\n\t\t\tsignal,\n\t\t};\n\t}\n\n\tprivate _isCompactionSourceOwnerCurrent(owner: CompactionOwner): boolean {\n\t\treturn (\n\t\t\tthis.sessionManager === owner.manager &&\n\t\t\tthis.agent === owner.agent &&\n\t\t\towner.manager.getSessionId() === owner.sessionId &&\n\t\t\towner.manager.getSessionFile() === owner.sessionFile &&\n\t\t\towner.isSourceCurrent() &&\n\t\t\tthis.requests === owner.requests &&\n\t\t\tthis._semanticEdges === owner.semanticEdges &&\n\t\t\tthis._extensionRunner === owner.extensions &&\n\t\t\tthis._ipythonKernelProvisioner === owner.provisioner\n\t\t);\n\t}\n\n\tprivate _isCompactionOwnerCurrent(owner: CompactionOwner): boolean {\n\t\treturn (\n\t\t\t!this._disposed &&\n\t\t\t!this._disposing &&\n\t\t\t!owner.signal?.aborted &&\n\t\t\tthis._isCompactionSourceOwnerCurrent(owner) &&\n\t\t\tthis._sessionInputPumpEpoch === owner.pumpEpoch\n\t\t);\n\t}\n\n\tprivate _assertCompactionSourceOwner(owner: CompactionOwner): void {\n\t\tif (!this._isCompactionSourceOwnerCurrent(owner))\n\t\t\tthrow new StaleCompactionOwnerError(\"Compaction source owner changed\");\n\t}\n\n\tprivate _assertCompactionOwner(owner: CompactionOwner): void {\n\t\tif (!this._isCompactionOwnerCurrent(owner)) throw new StaleCompactionOwnerError(\"Compaction owner changed\");\n\t}\n\n\tprivate _checkpointActionPending({ action }: CheckpointAction): boolean {\n\t\treturn (\n\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t!primaryDeliveryRecord(action).started &&\n\t\t\t(action.lifecycle.state === \"queued\" ||\n\t\t\t\taction.lifecycle.state === \"selected\" ||\n\t\t\t\taction.lifecycle.state === \"preparing\" ||\n\t\t\t\taction.lifecycle.state === \"committing\")\n\t\t);\n\t}\n\n\tprivate _captureCheckpointResume(owner: CompactionOwner, boundary?: CheckpointBoundary): CheckpointResume {\n\t\tconst actions = this._actionStore\n\t\t\t.unfinishedActions()\n\t\t\t.filter((action) => action.payload.kind === \"turn\" && !primaryDeliveryRecord(action).started)\n\t\t\t.map((action) => ({ action, ticket: this._actionStore.ticketFor(action).ticket }));\n\t\treturn { owner, boundary, actions };\n\t}\n\n\tprivate _checkpointHasResume(resume: CheckpointResume): boolean {\n\t\treturn (\n\t\t\tresume.boundary?.state === \"pending\" || resume.actions.some((action) => this._checkpointActionPending(action))\n\t\t);\n\t}\n\n\tprivate async _shouldStopAfterTurn(context: ShouldStopAfterTurnContext): Promise<boolean> {\n\t\t// The legacy direct adapter has no finalized-batch decision. The installed native hook does.\n\t\tconst last = this.agent.state.messages.at(-1);\n\t\treturn (\n\t\t\t(await this._getTurnOutcome({ ...context, hasMoreToolCalls: !!last && last.role !== \"assistant\" })).kind !==\n\t\t\t\"proceed\"\n\t\t);\n\t}\n\n\tprivate async _getTurnOutcome(context: GetTurnOutcomeContext, signal?: AbortSignal): Promise<AgentTurnOutcome> {\n\t\t// Usage is recorded by message_end. Join it before admitting another native tool turn.\n\t\tif (this._autonomousState.enabled) await this._agentEventQueue;\n\t\tconst sourceOwner = signal ? this._invocationCompactionOwner : this._captureCompactionOwner();\n\t\tif (\n\t\t\t!sourceOwner ||\n\t\t\tsignal?.aborted ||\n\t\t\t(signal && sourceOwner.signal !== signal) ||\n\t\t\t!this._isCompactionSourceOwnerCurrent(sourceOwner)\n\t\t)\n\t\t\treturn { kind: \"cancelled\" };\n\t\t// This is a new turn-boundary admission. Its source predicate still belongs to the original invocation.\n\t\tconst owner = { ...sourceOwner, pumpEpoch: this._sessionInputPumpEpoch };\n\t\tconst requested = this._pendingRequestedCompaction;\n\t\tconst mayCheckpoint =\n\t\t\tthis._contextOptimizationAllowed() ||\n\t\t\t(requested !== undefined && this._isCompactionOwnerCurrent(requested.owner));\n\t\tconst preparing = mayCheckpoint\n\t\t\t? this._captureCheckpointResume(\n\t\t\t\t\towner,\n\t\t\t\t\tcontext.hasMoreToolCalls ? { kind: \"tool\", state: \"pending\" } : undefined,\n\t\t\t\t)\n\t\t\t: undefined;\n\t\tif (preparing) this._pendingCheckpoint = preparing;\n\t\tconst current = () =>\n\t\t\tpreparing\n\t\t\t\t? this._isCompactionOwnerCurrent(owner)\n\t\t\t\t: !signal?.aborted && !this._disposed && !this._disposing && this._isCompactionSourceOwnerCurrent(owner);\n\t\tconst goalOwner = { ...this._captureGoalContinuationOwner(signal), checkpointOwner: owner };\n\t\tconst autonomousOwner = this._captureThresholdAutonomousOwner();\n\t\ttry {\n\t\t\tif (await this._stopGoalContinuationForTerminalMessage(context.message, goalOwner)) return { kind: \"finish\" };\n\t\t\tif (!current()) return { kind: \"cancelled\" };\n\t\t\tif (this._autonomousState.enabled && autonomousRunLimitReason(this._autonomousState))\n\t\t\t\treturn { kind: \"finish\" };\n\t\t\ttry {\n\t\t\t\tif (await this._accountGoalUsageForAssistantMessage(context.message, goalOwner)) {\n\t\t\t\t\tthis._assertGoalContinuationOwner(goalOwner);\n\t\t\t\t\tconst message = createGoalContextMessage(goalOwner.goal, \"budget_limit\");\n\t\t\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\t\t\tthis._admitSessionInput(\n\t\t\t\t\t\tthis._createPreparedTurnAction(\"steer\", normalized.text, normalized.images, {\n\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ordinary accounting retains its non-rejection policy; it cannot publish on a replacement.\n\t\t\t}\n\t\t\tif (!current()) return { kind: \"cancelled\" };\n\t\t\t// Keep mandatory serialized refinement before threshold and steering, without self-waiting for idle.\n\t\t\tif (this._serializedRefine) {\n\t\t\t\tawait this._agentEventQueue;\n\t\t\t\tif (!current()) return { kind: \"cancelled\" };\n\t\t\t\tawait this._runSerializedRefineCheckpoint();\n\t\t\t}\n\t\t\tif (!current()) return { kind: \"cancelled\" };\n\t\t\ttry {\n\t\t\t\tif (\n\t\t\t\t\tpreparing &&\n\t\t\t\t\t(await this._shouldStopForThresholdCompaction(context, owner, goalOwner, autonomousOwner))\n\t\t\t\t) {\n\t\t\t\t\tconst resume = this._pendingCheckpoint;\n\t\t\t\t\treturn { kind: resume && this._checkpointHasResume(resume) ? \"checkpoint_then_continue\" : \"finish\" };\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof StaleCompactionOwnerError)) throw error;\n\t\t\t\treturn { kind: \"cancelled\" };\n\t\t\t}\n\t\t\tif (!current()) return { kind: \"cancelled\" };\n\t\t\treturn { kind: this._steeringStopPending ? \"finish\" : \"proceed\" };\n\t\t} finally {\n\t\t\t// Only an actual checkpoint decision replaces this preparing reference.\n\t\t\tif (preparing && this._pendingCheckpoint === preparing) this._pendingCheckpoint = undefined;\n\t\t}\n\t}\n\n\tprivate async _shouldStopForThresholdCompaction(\n\t\tcontext: GetTurnOutcomeContext,\n\t\towner: CompactionOwner,\n\t\tgoalOwner: GoalContinuationOwner,\n\t\tautonomousOwner: ThresholdAutonomousOwner,\n\t): Promise<boolean> {\n\t\tconst pending = this._pendingRequestedCompaction;\n\t\tif (pending && !this._isCompactionOwnerCurrent(pending.owner)) {\n\t\t\tif (this._pendingRequestedCompaction === pending) this._pendingRequestedCompaction = undefined;\n\t\t}\n\t\tconst requested = pending !== undefined && this._pendingRequestedCompaction === pending;\n\t\tif (!requested && !(await this._thresholdCompactionNeeded(context, owner, goalOwner, autonomousOwner)))\n\t\t\treturn false;\n\t\tif (!this._isCompactionOwnerCurrent(owner)) return false;\n\t\tthis._pendingCheckpoint = this._captureCheckpointResume(\n\t\t\towner,\n\t\t\tcontext.hasMoreToolCalls ? { kind: \"tool\", state: \"pending\" } : undefined,\n\t\t);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Serialized-mode auto-refine checkpoint called from _shouldStopAfterTurn.\n\t * Runs the review, planning, and application phases inline between turns\n\t * at the quiescent shouldStopAfterTurn boundary. This path NEVER calls\n\t * _maybeAutoRefine, _runApprovedRefine, public refine(), agent.abort(),\n\t * or agent.waitForIdle — all of which would deadlock or defer because\n\t * the agent loop still owns activeRun at this point. Instead it calls\n\t * _reviewAutoRefine, _planRefine, and _applyRefine directly with proper\n\t * in-flight guards and counter resets.\n\t */\n\tprivate async _runSerializedRefineCheckpoint(): Promise<void> {\n\t\tif (this._compactionSetupFailure) return;\n\t\tif (this._disposed || this._disposing) {\n\t\t\treturn;\n\t\t}\n\n\t\t// 1. Await any background plan that was started at message_end\n\t\t// (either for a pending refine.run or for interval-triggered\n\t\t// auto-refine). This must be checked BEFORE the pending and\n\t\t// interval checks because background planning may have consumed\n\t\t// the pending request at message_end.\n\t\tconst branchVersion = this._autoRefineBranchVersion;\n\t\tconst bgConsumption = await this._consumeSerializedBackgroundPlan(async (bgResult) => {\n\t\t\tif (this._disposed || this._disposing) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (bgResult?.status === \"plan\") {\n\t\t\t\tif (bgResult.branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\t\tif (!this._pendingRequestedRefine) {\n\t\t\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Apply the EXACT background plan directly via _applyRefine\n\t\t\t\t\t// (no second _planRefine call).\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this._applySerializedPlan(bgResult);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthis._emitRefineFailed(error);\n\t\t\t\t\t}\n\t\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t\tif (!this._pendingRequestedRefine) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (bgResult?.status === \"skip\") {\n\t\t\t\t// Reviewer declined or an extension skipped during background planning.\n\t\t\t\t// Reset exactly once. Never retry the interval review; only fall through for a separate pending refine.run.\n\t\t\t\tif (bgResult.explicit) {\n\t\t\t\t\tthis._emitRefineFailed(new RefineSkippedError(\"Refinement skipped by extension\"));\n\t\t\t\t}\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\tif (!this._pendingRequestedRefine) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (bgResult?.status === \"failure\") {\n\t\t\t\t// Background review or planning failure stamps cooldown without a synchronous retry.\n\t\t\t\t// A separately queued refine.run may still be serviced below.\n\t\t\t\tif (branchVersion === this._autoRefineBranchVersion) {\n\t\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t}\n\t\t\t\t// Re-queue an explicit refine.run whose background plan failed,\n\t\t\t\t// but only when branchVersion is still current and no newer\n\t\t\t\t// pending request has arrived since the background plan consumed\n\t\t\t\t// the original one. A newer request retains priority; interval\n\t\t\t\t// failures keep existing no-retry cooldown semantics.\n\t\t\t\tif (\n\t\t\t\t\tbgResult.explicit &&\n\t\t\t\t\tbgResult.branchVersion === this._autoRefineBranchVersion &&\n\t\t\t\t\t!this._pendingRequestedRefine\n\t\t\t\t) {\n\t\t\t\t\tthis._pendingRequestedRefine = bgResult.options;\n\t\t\t\t}\n\t\t\t\tif (!this._pendingRequestedRefine) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (bgResult?.status === \"invalidated\" && !this._pendingRequestedRefine) {\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tawait this._runSerializedRefineCheckpointAfterBackground(branchVersion);\n\t\t\treturn true;\n\t\t});\n\t\tif (this._disposed || this._disposing || bgConsumption !== \"none\") {\n\t\t\treturn;\n\t\t}\n\t\tawait this._runSerializedRefineCheckpointAfterBackground(branchVersion);\n\t}\n\n\tprivate async _runSerializedRefineCheckpointAfterBackground(branchVersion: number): Promise<void> {\n\t\tif (this._compactionSetupFailure) return;\n\t\t// No background result, or a refine.run arrived while the background result was\n\t\t// in flight. Fall through so an explicit pending request is serviced at this boundary.\n\n\t\t// 2. Agent-callable refine.run requests that were NOT consumed by\n\t\t// background planning (e.g. interval not reached at message_end,\n\t\t// or cooldown was active). Service them synchronously.\n\t\tconst pending = this._pendingRequestedRefine;\n\t\tif (pending) {\n\t\t\tthis._pendingRequestedRefine = undefined;\n\t\t\ttry {\n\t\t\t\tawait this._runSerializedRefine(pending);\n\t\t\t} catch (error) {\n\t\t\t\tthis._emitRefineFailed(error);\n\t\t\t}\n\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\treturn;\n\t\t}\n\n\t\t// 3. Post-compaction auto-refine. Serialized sessions defer the\n\t\t// compaction trigger to this boundary instead of entering the interactive\n\t\t// path, which waits for agent idle and can never run inside a tool loop.\n\t\tif (!this._newAutoRefineAllowed()) {\n\t\t\tthis._compactAutoRefinePending = false;\n\t\t\treturn;\n\t\t}\n\t\tconst settings = this.settingsManager.getAutoRefineSettings();\n\t\tif (!settings.enabled) {\n\t\t\tthis._compactAutoRefinePending = false;\n\t\t\treturn;\n\t\t}\n\t\tif (this._compactAutoRefinePending) {\n\t\t\tif (!settings.compact) {\n\t\t\t\tthis._compactAutoRefinePending = false;\n\t\t\t} else {\n\t\t\t\tconst nowMs = Date.now();\n\t\t\t\tconst underCooldown =\n\t\t\t\t\tthis._lastAutoRefineReviewAt > 0 && nowMs - this._lastAutoRefineReviewAt < settings.cooldownMs;\n\t\t\t\tif (underCooldown) {\n\t\t\t\t\t// Preserve the compact trigger for a later boundary, matching the\n\t\t\t\t\t// interactive path's pending behavior while the cooldown is active.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis._compactAutoRefinePending = false;\n\t\t\t\tawait this._runSerializedAutoRefineReview(\"compact\", branchVersion);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// 4. Interval-triggered auto-refine (no background plan was started).\n\t\tif (this._assistantTurnsSinceAutoRefine < settings.turnInterval) {\n\t\t\treturn;\n\t\t}\n\t\tconst nowMs = Date.now();\n\t\tconst underCooldown =\n\t\t\tthis._lastAutoRefineReviewAt > 0 && nowMs - this._lastAutoRefineReviewAt < settings.cooldownMs;\n\t\tif (underCooldown) {\n\t\t\treturn;\n\t\t}\n\t\tawait this._runSerializedAutoRefineReview(\"turn_interval\", branchVersion);\n\t}\n\n\tprivate async _runSerializedAutoRefineReview(\n\t\treason: \"compact\" | \"turn_interval\",\n\t\tbranchVersion: number,\n\t): Promise<void> {\n\t\tif (!this._newAutoRefineAllowed()) return;\n\t\tconst reviewAbort = new AbortController();\n\t\tthis._autoRefineReviewAbort = reviewAbort;\n\t\tthis._autoRefineInProgress = true;\n\t\ttry {\n\t\t\tconst review = await this._reviewAutoRefine(\n\t\t\t\t{ reason, turnsSinceLastReview: this._assistantTurnsSinceAutoRefine },\n\t\t\t\treviewAbort.signal,\n\t\t\t);\n\t\t\tif (\n\t\t\t\t!this._newAutoRefineAllowed() ||\n\t\t\t\tthis._disposed ||\n\t\t\t\tthis._disposing ||\n\t\t\t\tbranchVersion !== this._autoRefineBranchVersion\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!review.shouldRefine) {\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this._runSerializedRefine({ instructions: autoRefineInstructions(reason, review) }, \"auto\");\n\t\t\tif (this._disposed || this._disposing || branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t} catch (error) {\n\t\t\tif (branchVersion === this._autoRefineBranchVersion) {\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t// An extension skip is an intentional non-round, not a failure.\n\t\t\t\tif (error instanceof RefineSkippedError) {\n\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t} else {\n\t\t\t\t\tthis._emitRefineFailed(error);\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tif (this._autoRefineReviewAbort === reviewAbort) {\n\t\t\t\tthis._autoRefineReviewAbort = undefined;\n\t\t\t}\n\t\t\tthis._autoRefineInProgress = false;\n\t\t}\n\t}\n\n\t/**\n\t * Claim and process the serialized background plan if one is in flight.\n\t * A concurrent caller waits for the claim holder's full processing callback\n\t * instead of resuming as soon as planning settles.\n\t */\n\tprivate async _consumeSerializedBackgroundPlan(\n\t\tconsume: (result: SerializedBackgroundPlanResult | undefined) => Promise<boolean>,\n\t): Promise<\"none\" | \"waited\" | \"continue\" | \"stop\"> {\n\t\tif (this._serializedPlanClaim) {\n\t\t\tawait this._serializedPlanClaim.catch(() => undefined);\n\t\t\treturn \"waited\";\n\t\t}\n\t\tconst planInFlight = this._serializedPlanInFlight;\n\t\tif (!planInFlight) {\n\t\t\treturn \"none\";\n\t\t}\n\n\t\tlet releaseClaim: () => void = () => {};\n\t\tconst claim = new Promise<void>((resolve) => {\n\t\t\treleaseClaim = resolve;\n\t\t});\n\t\tthis._serializedPlanClaim = claim;\n\t\ttry {\n\t\t\tconst result = await planInFlight.catch(() => undefined);\n\t\t\tif (this._serializedPlanInFlight === planInFlight) {\n\t\t\t\tthis._serializedPlanInFlight = undefined;\n\t\t\t\tthis._serializedExplicitRefineOptions = undefined;\n\t\t\t}\n\t\t\treturn (await consume(result)) ? \"stop\" : \"continue\";\n\t\t} finally {\n\t\t\treleaseClaim();\n\t\t\tif (this._serializedPlanClaim === claim) {\n\t\t\t\tthis._serializedPlanClaim = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Apply an exact background plan directly via _applyRefine without\n\t * calling _planRefine again. Sets _refineInFlight for safety.\n\t */\n\tprivate async _applySerializedPlan(\n\t\tbgResult: Extract<SerializedBackgroundPlanResult, { status: \"plan\" }>,\n\t): Promise<void> {\n\t\tlet resolveApplySettled: () => void = () => {};\n\t\tconst applySettled = new Promise<void>((resolve) => {\n\t\t\tresolveApplySettled = resolve;\n\t\t});\n\t\tthis._refineInFlight = applySettled;\n\t\ttry {\n\t\t\tawait this._applyRefine(bgResult.plan, bgResult.options, bgResult.abort);\n\t\t} finally {\n\t\t\tresolveApplySettled();\n\t\t\tif (this._refineInFlight === applySettled) {\n\t\t\t\tthis._refineInFlight = undefined;\n\t\t\t}\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\tthis._scheduleSessionInputPump();\n\t\t}\n\t}\n\n\t/**\n\t * Start background refinement planning at assistant message_end, while\n\t * tools are still executing. The plan (if any) is awaited at the\n\t * shouldStopAfterTurn boundary before applying. Planning overlaps tool\n\t * execution only — never another model request.\n\t */\n\tprivate _maybeStartSerializedBackgroundPlan(): void {\n\t\tif (!this._serializedRefine || this._disposed || this._disposing) {\n\t\t\treturn;\n\t\t}\n\t\t// Don't start if a plan is already in flight.\n\t\tif (this._serializedPlanInFlight || this._refineInFlight || this._refinePlanInFlight) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Start background planning for a pending agent-callable\n\t\t// refine.run request, so its plan is ready at the shouldStopAfterTurn\n\t\t// boundary. The pending request is consumed (cleared) here so the\n\t\t// boundary doesn't re-plan it. Explicit refine.run skips the review gate.\n\t\tconst pending = this._pendingRequestedRefine;\n\t\tif (pending) {\n\t\t\tthis._pendingRequestedRefine = undefined;\n\t\t\tthis._serializedExplicitRefineOptions = pending;\n\t\t\tconst refineAbort = new AbortController();\n\t\t\tthis._refineAbortController = refineAbort;\n\t\t\tconst branchVersion = this._autoRefineBranchVersion;\n\t\t\tthis._serializedPlanInFlight = this._runBackgroundPlan(pending, refineAbort, branchVersion, true);\n\t\t\treturn;\n\t\t}\n\n\t\t// Interval-triggered auto-refine background planning.\n\t\tif (!this._newAutoRefineAllowed()) {\n\t\t\treturn;\n\t\t}\n\t\tconst settings = this.settingsManager.getAutoRefineSettings();\n\t\tif (!settings.enabled) {\n\t\t\treturn;\n\t\t}\n\t\tif (this._assistantTurnsSinceAutoRefine < settings.turnInterval) {\n\t\t\treturn;\n\t\t}\n\t\tconst nowMs = Date.now();\n\t\tconst underCooldown =\n\t\t\tthis._lastAutoRefineReviewAt > 0 && nowMs - this._lastAutoRefineReviewAt < settings.cooldownMs;\n\t\tif (underCooldown) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst refineAbort = new AbortController();\n\t\tthis._refineAbortController = refineAbort;\n\t\tconst branchVersion = this._autoRefineBranchVersion;\n\t\t// Pass empty options — _runBackgroundPlan derives instructions from\n\t\t// the review result for interval-triggered auto-refine.\n\t\tthis._serializedPlanInFlight = this._runBackgroundPlan({}, refineAbort, branchVersion);\n\t}\n\n\t/**\n\t * Shared background planning coroutine. Runs review + planRefine and\n\t * returns a discriminated result so the boundary can distinguish\n\t * reviewer-declined (\"skip\") from failure (\"failure\") from a ready\n\t * plan (\"plan\") and apply that exact plan without re-planning.\n\t */\n\tprivate async _runBackgroundPlan(\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean },\n\t\trefineAbort: AbortController,\n\t\tbranchVersion: number,\n\t\tskipReview = false,\n\t): Promise<SerializedBackgroundPlanResult | undefined> {\n\t\ttry {\n\t\t\tlet planOptions = options;\n\t\t\tif (!skipReview) {\n\t\t\t\t// Interval-triggered: run the review gate first, then derive\n\t\t\t\t// instructions from the review result (not prepopulated).\n\t\t\t\tconst review = await this._reviewAutoRefine(\n\t\t\t\t\t{\n\t\t\t\t\t\treason: \"turn_interval\",\n\t\t\t\t\t\tturnsSinceLastReview: this._assistantTurnsSinceAutoRefine,\n\t\t\t\t\t},\n\t\t\t\t\trefineAbort.signal,\n\t\t\t\t);\n\t\t\t\tif (this._disposed || this._disposing || branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\t\treturn { status: \"invalidated\", branchVersion };\n\t\t\t\t}\n\t\t\t\tif (!review.shouldRefine) {\n\t\t\t\t\treturn { status: \"skip\" };\n\t\t\t\t}\n\t\t\t\tif (!this._newAutoRefineAllowed()) return { status: \"skip\" };\n\t\t\t\tplanOptions = {\n\t\t\t\t\tinstructions: autoRefineInstructions(\"turn_interval\", review),\n\t\t\t\t};\n\t\t\t}\n\t\t\t// For explicit refine.run (skipReview=true), plan directly with\n\t\t\t// the user-provided options — no auto-review gate.\n\t\t\tconst plan = await this._planRefine(planOptions, refineAbort.signal, skipReview ? \"manual\" : \"auto\");\n\t\t\tif (this._disposed || this._disposing || branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\treturn { status: \"invalidated\", branchVersion };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tstatus: \"plan\",\n\t\t\t\tplan,\n\t\t\t\toptions: planOptions,\n\t\t\t\tabort: refineAbort,\n\t\t\t\tbranchVersion,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (this._disposed || this._disposing || branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\treturn { status: \"invalidated\", branchVersion };\n\t\t\t}\n\t\t\tif (error instanceof RefineSkippedError) {\n\t\t\t\treturn { status: \"skip\", explicit: skipReview };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tstatus: \"failure\",\n\t\t\t\texplicit: skipReview,\n\t\t\t\toptions,\n\t\t\t\tbranchVersion,\n\t\t\t};\n\t\t} finally {\n\t\t\tif (this._refineAbortController === refineAbort) {\n\t\t\t\tthis._refineAbortController = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Direct serialized plan+apply. Calls _planRefine and _applyRefine with\n\t * proper in-flight guards but NEVER agent.waitForIdle or agent.abort.\n\t * The caller (shouldStopAfterTurn) is already at the quiescent boundary,\n\t * so the agent is between turns and _applyRefine's disconnect/reconnect\n\t * is safe.\n\t */\n\tprivate async _runSerializedRefine(\n\t\toptions: {\n\t\t\tinstructions?: string;\n\t\t\trollbackId?: string;\n\t\t\tglobal?: boolean;\n\t\t},\n\t\ttrigger: \"manual\" | \"auto\" = \"manual\",\n\t): Promise<void> {\n\t\tif (this._disposed || this._disposing) {\n\t\t\treturn;\n\t\t}\n\t\t// Guard: serialize against concurrent _runSerializedRefine calls.\n\t\t// _serializedPlanInFlight covers background planning; _refineInFlight\n\t\t// covers the apply phase. Both must be settled before starting a new\n\t\t// plan+apply cycle.\n\t\twhile (this._serializedPlanInFlight || this._refineInFlight || this._refinePlanInFlight) {\n\t\t\tif (this._serializedPlanInFlight) {\n\t\t\t\tawait this._consumeSerializedBackgroundPlan(async () => false);\n\t\t\t} else if (this._refineInFlight) {\n\t\t\t\tawait this._refineInFlight;\n\t\t\t} else {\n\t\t\t\tawait this._refinePlanInFlight;\n\t\t\t}\n\t\t}\n\t\tif (this._disposed || this._disposing) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst refineAbort = new AbortController();\n\t\tthis._refineAbortController = refineAbort;\n\n\t\tconst planRun = this._planRefine(options, refineAbort.signal, trigger);\n\t\tconst planSettled = planRun.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\tthis._refinePlanInFlight = planSettled;\n\t\tlet plan: RefinementPlan;\n\t\ttry {\n\t\t\tplan = await planRun;\n\t\t} catch (error) {\n\t\t\tif (this._refineAbortController === refineAbort) {\n\t\t\t\tthis._refineAbortController = undefined;\n\t\t\t}\n\t\t\tthis._scheduleSessionInputPump();\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tif (this._refinePlanInFlight === planSettled) {\n\t\t\t\tthis._refinePlanInFlight = undefined;\n\t\t\t}\n\t\t}\n\n\t\tif (this._disposed || refineAbort.signal.aborted) {\n\t\t\tif (this._refineAbortController === refineAbort) {\n\t\t\t\tthis._refineAbortController = undefined;\n\t\t\t}\n\t\t\tthis._scheduleSessionInputPump();\n\t\t\treturn;\n\t\t}\n\n\t\t// Do NOT call agent.waitForIdle() — we are at the quiescent boundary\n\t\t// already (shouldStopAfterTurn). _applyRefine handles disconnect/reconnect internally.\n\t\tlet resolveApplySettled: () => void = () => {};\n\t\tconst applySettled = new Promise<void>((resolve) => {\n\t\t\tresolveApplySettled = resolve;\n\t\t});\n\t\tthis._refineInFlight = applySettled;\n\t\ttry {\n\t\t\tawait this._applyRefine(plan, options, refineAbort);\n\t\t} finally {\n\t\t\tresolveApplySettled();\n\t\t\tif (this._refineInFlight === applySettled) {\n\t\t\t\tthis._refineInFlight = undefined;\n\t\t\t}\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\tthis._scheduleSessionInputPump();\n\t\t}\n\t}\n\n\tprivate async _getLatestCompactionTimestamp(owner?: CompactionOwner): Promise<number | undefined> {\n\t\tif (owner) this._assertCompactionOwner(owner);\n\t\tconst manager = owner?.manager ?? this.sessionManager;\n\t\tif (!manager.isPersisted()) {\n\t\t\tconst entry = getLatestCompactionEntry(manager.getBranch());\n\t\t\treturn entry ? new Date(entry.timestamp).getTime() : undefined;\n\t\t}\n\t\tconst { maxSourceBytes } = this.settingsManager.getCanonicalContextLimits();\n\t\treturn manager.readBranchHistory(async (view) => {\n\t\t\tconst ref = (await view.branchBootstrap()).latestCompaction;\n\t\t\tif (owner) this._assertCompactionOwner(owner);\n\t\t\tif (!ref) {\n\t\t\t\tthis._compactionBoundaryCache = undefined;\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (ref.locator.length > maxSourceBytes) throw new Error(\"Compaction bootstrap source byte budget exceeded\");\n\t\t\tconst cached = this._compactionBoundaryCache;\n\t\t\tif (\n\t\t\t\tcached &&\n\t\t\t\tcached.sessionId === view.source.sessionId &&\n\t\t\t\tcached.sessionFile === view.source.sessionFile &&\n\t\t\t\tcached.entryId === ref.id &&\n\t\t\t\tcached.revision === ref.revision\n\t\t\t)\n\t\t\t\treturn cached.timestamp;\n\t\t\tconst hydrated = await view.hydrateEntry(ref.id, maxSourceBytes);\n\t\t\tif (!hydrated || hydrated.entry.type !== \"compaction\")\n\t\t\t\tthrow new Error(\"Compaction bootstrap source is unavailable\");\n\t\t\tconst timestamp = new Date(hydrated.entry.timestamp).getTime();\n\t\t\tif (owner) this._assertCompactionOwner(owner);\n\t\t\tthis._compactionBoundaryCache = {\n\t\t\t\tsessionId: view.source.sessionId,\n\t\t\t\tsessionFile: view.source.sessionFile,\n\t\t\t\tentryId: ref.id,\n\t\t\t\trevision: ref.revision,\n\t\t\t\ttimestamp,\n\t\t\t};\n\t\t\treturn timestamp;\n\t\t});\n\t}\n\n\tprivate _thresholdCompactionConfiguration(): string {\n\t\treturn JSON.stringify({\n\t\t\tmodel: this.model,\n\t\t\tthinkingLevel: this.thinkingLevel,\n\t\t\tsettings: this.settingsManager.getCompactionSettings(),\n\t\t});\n\t}\n\n\tprivate _hasFailedThresholdCompaction(): boolean {\n\t\tconst failed = this._failedThresholdCompaction;\n\t\tif (!failed) return false;\n\t\tif (\n\t\t\tfailed.isCurrent() &&\n\t\t\tfailed.configuration === this._thresholdCompactionConfiguration() &&\n\t\t\tfailed.systemPrompt === this.agent.state.systemPrompt &&\n\t\t\tfailed.tools === this.agent.state.tools\n\t\t)\n\t\t\treturn true;\n\t\tthis._failedThresholdCompaction = undefined;\n\t\treturn false;\n\t}\n\n\tprivate async _thresholdCompactionNeeded(\n\t\tcontext: ShouldStopAfterTurnContext,\n\t\towner = this._captureCompactionOwner(),\n\t\tgoalOwner: GoalContinuationOwner = {\n\t\t\t...this._captureGoalContinuationOwner(owner.signal),\n\t\t\tcheckpointOwner: owner,\n\t\t},\n\t\tautonomousOwner = this._captureThresholdAutonomousOwner(),\n\t): Promise<boolean> {\n\t\tif (!this._isCompactionOwnerCurrent(owner) || !this._contextOptimizationAllowed()) return false;\n\t\tconst settings = this.settingsManager.getCompactionSettings();\n\t\tif (!settings.enabled) return false;\n\t\tconst contextWindow = this.model?.contextWindow ?? 0;\n\t\tconst compactionTimestamp = await this._getLatestCompactionTimestamp(owner);\n\t\tif (!this._isCompactionOwnerCurrent(owner) || !this._contextOptimizationAllowed()) return false;\n\t\tif (compactionTimestamp !== undefined && context.message.timestamp <= compactionTimestamp) return false;\n\t\tconst contextTokens = this._getThresholdContextTokens(context.message, compactionTimestamp);\n\t\tif (\n\t\t\tcontextTokens === undefined ||\n\t\t\t!shouldCompact(\n\t\t\t\tcontextTokens,\n\t\t\t\tcontextWindow,\n\t\t\t\tsettings,\n\t\t\t\testimateFixedCompactionTokens(this.systemPrompt, this.agent.state.tools, this.messages),\n\t\t\t)\n\t\t)\n\t\t\treturn false;\n\t\tif (this._hasFailedThresholdCompaction()) return false;\n\t\t// Keep the existing threshold-specific goal winner; do not import W74's natural wait policy here.\n\t\tif (!this._isGoalContinuationOwnerCurrent(goalOwner)) return true;\n\t\tif (!(await this._queueGoalContinuationForThresholdCompaction(context.message, goalOwner))) {\n\t\t\tif (!this._isGoalContinuationOwnerCurrent(goalOwner))\n\t\t\t\treturn this._isCompactionOwnerCurrent(owner) && this._contextOptimizationAllowed();\n\t\t\tif (!this._contextOptimizationAllowed()) return false;\n\t\t\tawait this._queueAutonomousContinuationForThresholdCompaction(context.message, owner, autonomousOwner);\n\t\t}\n\t\treturn this._isCompactionOwnerCurrent(owner) && this._contextOptimizationAllowed();\n\t}\n\n\tprivate _captureThresholdAutonomousOwner(): ThresholdAutonomousOwner {\n\t\treturn {\n\t\t\tstate: this._autonomousState,\n\t\t\tsnapshot: structuredClone(this._autonomousState),\n\t\t\tcwd: this._cwd,\n\t\t\tarrivalEpoch: this._sessionInputArrivalEpoch,\n\t\t};\n\t}\n\n\tprivate _snapshotAutonomousRuntimeState(state = this._autonomousState): AutonomousRuntimeSnapshot {\n\t\treturn {\n\t\t\tcontinuationsUsed: state.continuationsUsed,\n\t\t\tgateAttempts: { ...state.gateAttempts },\n\t\t\tlastGateFailure: state.lastGateFailure ? { ...state.lastGateFailure } : undefined,\n\t\t\tlastGateFailureSnapshot: state.lastGateFailureSnapshot ? { ...state.lastGateFailureSnapshot } : undefined,\n\t\t};\n\t}\n\n\tprivate _restoreAutonomousRuntimeSnapshot(snapshot: AutonomousRuntimeSnapshot): void {\n\t\tthis._autonomousState.continuationsUsed = snapshot.continuationsUsed;\n\t\tthis._autonomousState.gateAttempts = { ...snapshot.gateAttempts };\n\t\tthis._autonomousState.lastGateFailure = snapshot.lastGateFailure ? { ...snapshot.lastGateFailure } : undefined;\n\t\tthis._autonomousState.lastGateFailureSnapshot = snapshot.lastGateFailureSnapshot\n\t\t\t? { ...snapshot.lastGateFailureSnapshot }\n\t\t\t: undefined;\n\t}\n\n\tprivate async _queueAutonomousContinuationForThresholdCompaction(\n\t\tmessage: AssistantMessage,\n\t\towner = this._captureCompactionOwner(this.agent.signal),\n\t\tcapture = this._captureThresholdAutonomousOwner(),\n\t): Promise<CheckpointAction | undefined> {\n\t\tif (!this._isCompactionOwnerCurrent(owner) || !this._contextOptimizationAllowed()) return undefined;\n\t\tconst queued = this._queuedAutonomousThresholdContinuations.get(message);\n\t\tif (queued && this._checkpointActionPending(queued)) return queued;\n\t\tconst { state, snapshot: original, arrivalEpoch, cwd } = capture;\n\t\tconst before = this._snapshotAutonomousRuntimeState(original);\n\t\tconst candidate = structuredClone(original);\n\t\tconst current = () =>\n\t\t\tthis._isCompactionOwnerCurrent(owner) && this._autonomousState === state && isDeepStrictEqual(state, original);\n\t\tif (!current()) return undefined;\n\t\tlet messageToQueue: UserMessage | undefined;\n\t\ttry {\n\t\t\tmessageToQueue = await nextAutonomousContinuation(candidate, message, { cwd, signal: owner.signal });\n\t\t} catch (error) {\n\t\t\tif (current()) this._restoreAutonomousRuntimeSnapshot(candidate);\n\t\t\tthrow error; // Preserve the actual command/orphan owner's primary failure even after replacement.\n\t\t}\n\t\tif (!current() || !this._contextOptimizationAllowed()) return undefined;\n\t\tif (messageToQueue && this._sessionInputArrivalEpoch !== arrivalEpoch) return undefined;\n\t\tthis._restoreAutonomousRuntimeSnapshot(candidate);\n\t\tif (!messageToQueue) return undefined;\n\t\tconst normalized = normalizeMessageContent(messageToQueue.content);\n\t\tconst action = this._createPreparedTurnAction(\"followUp\", normalized.text, normalized.images, {\n\t\t\tmessage: messageToQueue,\n\t\t});\n\t\tconst admitted = this._admitSessionInput(action);\n\t\tif (!admitted.accepted || !admitted.ticket) {\n\t\t\tthis._restoreAutonomousRuntimeSnapshot(before);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst continuation: ThresholdAutonomousContinuation = {\n\t\t\taction,\n\t\t\tticket: admitted.ticket,\n\t\t\towner,\n\t\t\tstate,\n\t\t\tbefore,\n\t\t\tafter: structuredClone(state),\n\t\t};\n\t\tthis._queuedAutonomousThresholdContinuations.set(message, continuation);\n\t\tthis._postCompactionContinuations.push(continuation);\n\t\tthis._pendingThresholdCompactionAutonomousContinuations.push(continuation);\n\t\treturn continuation;\n\t}\n\n\tprivate async _queueGoalContinuationForThresholdCompaction(\n\t\tmessage: AssistantMessage,\n\t\towner: GoalContinuationOwner = {\n\t\t\t...this._captureGoalContinuationOwner(this.agent.signal),\n\t\t\tcheckpointOwner: this._captureCompactionOwner(this.agent.signal),\n\t\t},\n\t): Promise<CheckpointAction | undefined> {\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner) || !this._contextOptimizationAllowed()) return undefined;\n\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") return undefined;\n\t\tif (owner.goal.status !== \"active\" || !owner.goal.objective) return undefined;\n\t\tconst queued = this._queuedGoalThresholdContinuation;\n\t\tif (queued && this._checkpointActionPending(queued)) return queued;\n\t\tconst before = owner.goal;\n\t\tlet counted = false;\n\t\ttry {\n\t\t\tthis._ensureGoalRuntimeActive();\n\t\t\tawait this._setGoalState(\n\t\t\t\t{\n\t\t\t\t\t...before,\n\t\t\t\t\tcontinuationsUsed: before.continuationsUsed + 1,\n\t\t\t\t\tlastReason: undefined,\n\t\t\t\t\tlastError: undefined,\n\t\t\t\t},\n\t\t\t\t{ continuationOwner: owner },\n\t\t\t);\n\t\t\tcounted = true;\n\t\t\tthis._assertGoalContinuationOwner(owner);\n\t\t\tif (!this._contextOptimizationAllowed()) {\n\t\t\t\tawait this._setGoalState(before, { continuationOwner: owner });\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst messageToQueue = createGoalContextMessage(owner.goal, \"continuation\");\n\t\t\tconst normalized = normalizeMessageContent(messageToQueue.content);\n\t\t\tconst action = this._createPreparedTurnAction(\"followUp\", normalized.text, normalized.images, {\n\t\t\t\tmessage: messageToQueue,\n\t\t\t});\n\t\t\tconst admitted = this._admitSessionInput(action);\n\t\t\tif (!admitted.accepted || !admitted.ticket) {\n\t\t\t\tawait this._setGoalState(before, { continuationOwner: owner });\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst continuation = { action, ticket: admitted.ticket, owner };\n\t\t\tthis._queuedGoalThresholdContinuation = continuation;\n\t\t\treturn continuation;\n\t\t} catch {\n\t\t\tif (counted && this._isGoalContinuationOwnerCurrent(owner)) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this._setGoalState(before, { continuationOwner: owner });\n\t\t\t\t} catch {\n\t\t\t\t\t/* Keep the existing non-rejection policy. */\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async _clearQueuedGoalContinuationAfterCancelledThresholdCompaction(\n\t\tcontinuation: ThresholdGoalContinuation | undefined,\n\t): Promise<void> {\n\t\tif (\n\t\t\t!continuation ||\n\t\t\t!continuation.owner.checkpointOwner ||\n\t\t\t!this._isCompactionSourceOwnerCurrent(continuation.owner.checkpointOwner) ||\n\t\t\t!this._checkpointActionPending(continuation)\n\t\t)\n\t\t\treturn;\n\t\tconst cancelled = this._cancelSessionActions(\n\t\t\t(action) => action === continuation.action,\n\t\t\tnew Error(\"Queued goal continuation was cleared before delivery.\"),\n\t\t);\n\t\tif (this._queuedGoalThresholdContinuation === continuation) this._queuedGoalThresholdContinuation = undefined;\n\t\tif (\n\t\t\t!cancelled.includes(continuation.action) ||\n\t\t\tprimaryDeliveryRecord(continuation.action).durable ||\n\t\t\t!this._isGoalContinuationOwnerCurrent(continuation.owner)\n\t\t)\n\t\t\treturn;\n\t\tconst owner = continuation.owner;\n\t\tawait this._setGoalState(\n\t\t\t{ ...owner.goal, continuationsUsed: owner.goal.continuationsUsed - 1 },\n\t\t\t{ continuationOwner: owner },\n\t\t);\n\t\tthis._emitQueueUpdate();\n\t}\n\n\tprivate _clearQueuedAutonomousContinuations(\n\t\toptions: { restoreAutonomousState?: boolean; continuations?: ThresholdAutonomousContinuation[] } = {},\n\t): void {\n\t\tconst continuations = options.continuations ?? [...this._postCompactionContinuations];\n\t\tconst current = continuations.filter(\n\t\t\t(continuation) =>\n\t\t\t\tthis._isCompactionSourceOwnerCurrent(continuation.owner) && this._checkpointActionPending(continuation),\n\t\t);\n\t\tconst actions = new Set(current.map((continuation) => continuation.action));\n\t\tconst cancelled = this._cancelSessionActions(\n\t\t\t(action) => actions.has(action),\n\t\t\tnew Error(\"Queued autonomous continuation was cleared before delivery.\"),\n\t\t);\n\t\tif (options.restoreAutonomousState) {\n\t\t\tconst continuation = current.find(\n\t\t\t\t(candidate) =>\n\t\t\t\t\tthis._isCompactionOwnerCurrent(candidate.owner) &&\n\t\t\t\t\tcancelled.includes(candidate.action) &&\n\t\t\t\t\t!primaryDeliveryRecord(candidate.action).durable &&\n\t\t\t\t\tthis._autonomousState === candidate.state &&\n\t\t\t\t\tisDeepStrictEqual(candidate.state, candidate.after),\n\t\t\t);\n\t\t\tif (continuation) this._restoreAutonomousRuntimeSnapshot(continuation.before);\n\t\t}\n\t\tthis._postCompactionContinuations = this._postCompactionContinuations.filter(\n\t\t\t(item) => !continuations.includes(item),\n\t\t);\n\t\tthis._pendingThresholdCompactionAutonomousContinuations =\n\t\t\tthis._pendingThresholdCompactionAutonomousContinuations.filter((item) => !continuations.includes(item));\n\t\tif (cancelled.length > 0) this._emitQueueUpdate();\n\t\tif (\n\t\t\t!this.agent.hasQueuedMessages() &&\n\t\t\tthis.unfinishedActionCount === 0 &&\n\t\t\tthis._postCompactionContinuationSettlement?.resume.boundary?.state !== \"pending\"\n\t\t)\n\t\t\tthis._cancelPostCompactionContinue();\n\t}\n\n\tprivate _clearQueuedAutonomousContinuationsAfterSkippedThresholdCompaction(\n\t\tshouldContinueAfterThreshold: boolean,\n\t\tcontinuations: ThresholdAutonomousContinuation[],\n\t): void {\n\t\tif (shouldContinueAfterThreshold)\n\t\t\tthis._clearQueuedAutonomousContinuations({ restoreAutonomousState: true, continuations });\n\t}\n\n\t/**\n\t * Handle a goal.* request from the Python kernel host bridge (the bundled\n\t * goal skill). All goal state stays host-side; the kernel only sees the\n\t * serialized snake_case response.\n\t */\n\tasync handleGoalHostRequest(type: string, payload: Record<string, unknown> = {}): Promise<GoalHostResponse> {\n\t\tif (!this._includeGoals) {\n\t\t\tthrow new Error(\"goals are disabled in this session\");\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase \"goal.get\":\n\t\t\t\treturn goalHostResponse(this.goalState, false);\n\t\t\tcase \"goal.create\": {\n\t\t\t\tif (typeof payload.objective !== \"string\") {\n\t\t\t\t\tthrow new Error(\"goal.create objective must be a string\");\n\t\t\t\t}\n\t\t\t\tif (payload.token_budget !== undefined && typeof payload.token_budget !== \"number\") {\n\t\t\t\t\tthrow new Error(\"goal.create token_budget must be an integer when provided\");\n\t\t\t\t}\n\t\t\t\treturn goalHostResponse(await this._createGoalFromHost(payload.objective, payload.token_budget), false);\n\t\t\t}\n\t\t\tcase \"goal.complete\":\n\t\t\t\treturn goalHostResponse(await this._completeGoalFromHost(), true);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown goal request type \"${type}\"`);\n\t\t}\n\t}\n\n\t/**\n\t * Handle a compact.* request from the kernel host bridge. Compaction would\n\t * abort the run executing the requesting cell, so compact.run only schedules\n\t * it; _checkCompaction consumes the request at the turn boundary.\n\t */\n\tasync handleCompactHostRequest(\n\t\ttype: string,\n\t\tpayload: Record<string, unknown> = {},\n\t): Promise<Record<string, unknown>> {\n\t\tif (type === \"compact.run\") this._assertContextOptimizationAllowed();\n\t\tif (!this._includeCompactSkill) {\n\t\t\tthrow new Error(\"the compact skill is disabled in this session\");\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase \"compact.status\": {\n\t\t\t\tconst scheduled = this._pendingRequestedCompaction !== undefined;\n\t\t\t\tconst usage = await this.getContextUsage();\n\t\t\t\treturn {\n\t\t\t\t\ttokens: usage?.tokens ?? null,\n\t\t\t\t\tcontext_window: usage?.contextWindow ?? null,\n\t\t\t\t\tpercent: usage?.percent ?? null,\n\t\t\t\t\tscheduled,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"compact.run\": {\n\t\t\t\tconst instructions = payload.instructions;\n\t\t\t\tif (instructions !== undefined && typeof instructions !== \"string\") {\n\t\t\t\t\tthrow new Error(\"compact.run instructions must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tif (!this.isStreaming) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tscheduled: false,\n\t\t\t\t\t\treason: \"no active turn; compaction can only be requested while a turn is running\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst settings = { ...this.settingsManager.getCompactionSettings() };\n\t\t\t\tconst sourceOwner = this._invocationCompactionOwner ?? this._captureCompactionOwner(this.agent.signal);\n\t\t\t\tconst owner = { ...sourceOwner, pumpEpoch: this._sessionInputPumpEpoch };\n\t\t\t\tthis._assertCompactionOwner(owner);\n\t\t\t\tconst compaction = owner.manager.bindCompactionSink();\n\t\t\t\tconst captured = owner.requests.capture(compaction);\n\t\t\t\tlet branch: SessionEntry[];\n\t\t\t\tlet preparation: CompactionPreparation | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tbranch = await compaction.readBranch();\n\t\t\t\t\tthis._assertCompactionOwner(owner);\n\t\t\t\t\tpreparation = this.isStreaming\n\t\t\t\t\t\t? (await this._prepareCapturedCompaction(branch, settings, captured, compaction, owner)).preparation\n\t\t\t\t\t\t: undefined;\n\t\t\t\t} catch (error) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait captured.dispose();\n\t\t\t\t\t} catch (cleanupError) {\n\t\t\t\t\t\tthrow new AggregateError([error, cleanupError], \"Compaction preparation and release failed\", {\n\t\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tawait captured.dispose();\n\t\t\t\tthis._assertCompactionOwner(owner);\n\t\t\t\tif (!this.isStreaming)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tscheduled: false,\n\t\t\t\t\t\treason: \"no active turn; compaction can only be requested while a turn is running\",\n\t\t\t\t\t};\n\t\t\t\tif (!preparation) {\n\t\t\t\t\tconst lastEntry = branch.at(-1);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tscheduled: false,\n\t\t\t\t\t\treason: lastEntry?.type === \"compaction\" ? \"already compacted\" : \"session is too short to compact\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthis._assertContextOptimizationAllowed();\n\t\t\t\tthis._pendingRequestedCompaction = { customInstructions: instructions, owner };\n\t\t\t\treturn {\n\t\t\t\t\tscheduled: true,\n\t\t\t\t\tnote: \"Compaction runs when the current turn ends; you resume automatically afterwards. Continue working normally.\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown compact request type \"${type}\"`);\n\t\t}\n\t}\n\n\t/**\n\t * Handle a refine.* request from the kernel host bridge. Like compact,\n\t * refinement waits for the current turn to become idle before applying\n\t * changes, so refine.run only schedules it; _consumePendingRequestedRefine\n\t * fires it at the turn boundary. This prevents a deadlock that would occur\n\t * if refine() awaited agent idle from within the active tool call.\n\t */\n\thandleRefineHostRequest(type: string, payload: Record<string, unknown> = {}): Record<string, unknown> {\n\t\tif (type === \"refine.run\") this._assertContextOptimizationAllowed();\n\t\tswitch (type) {\n\t\t\tcase \"refine.status\": {\n\t\t\t\treturn {\n\t\t\t\t\tpending: this._pendingRequestedRefine !== undefined,\n\t\t\t\t\tin_flight:\n\t\t\t\t\t\tthis._refineInFlight !== undefined ||\n\t\t\t\t\t\tthis._refinePlanInFlight !== undefined ||\n\t\t\t\t\t\tthis._serializedPlanInFlight !== undefined,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"refine.run\": {\n\t\t\t\tconst instructions = payload.instructions;\n\t\t\t\tif (instructions !== undefined && typeof instructions !== \"string\") {\n\t\t\t\t\tthrow new Error(\"refine.run instructions must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tconst globalFlag = payload.global;\n\t\t\t\tif (globalFlag !== undefined && typeof globalFlag !== \"boolean\") {\n\t\t\t\t\tthrow new Error(\"refine.run global must be a boolean when provided\");\n\t\t\t\t}\n\t\t\t\tif (!this.isStreaming) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tscheduled: false,\n\t\t\t\t\t\treason: \"no active turn; refine can only be requested while a turn is running\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst previous = this._pendingRequestedRefine ?? this._serializedExplicitRefineOptions;\n\t\t\t\tthis._pendingRequestedRefine = {\n\t\t\t\t\tinstructions: instructions ?? previous?.instructions,\n\t\t\t\t\tglobal: globalFlag ?? previous?.global,\n\t\t\t\t};\n\t\t\t\t// In serialized mode, kick off background planning immediately\n\t\t\t\t// (the primary response ended at message_end, tools are active).\n\t\t\t\t// This lets planning overlap tool execution rather than waiting\n\t\t\t\t// for the shouldStopAfterTurn boundary.\n\t\t\t\tif (this._serializedRefine) {\n\t\t\t\t\tif (this._serializedPlanInFlight) {\n\t\t\t\t\t\tthis._autoRefineBranchVersion++;\n\t\t\t\t\t\tif (this._refineAbortController) {\n\t\t\t\t\t\t\tthis._refineAbortController.abort();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis._serializedPlanInFlight = Promise.resolve({\n\t\t\t\t\t\t\t\tstatus: \"invalidated\",\n\t\t\t\t\t\t\t\tbranchVersion: this._autoRefineBranchVersion,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!this._invocationOutputRefused) this._maybeStartSerializedBackgroundPlan();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tscheduled: true,\n\t\t\t\t\tnote: \"Refinement runs when the current turn ends; fresh harness advice is added to the next request and you resume automatically. Continue working normally.\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown refine request type \"${type}\"`);\n\t\t}\n\t}\n\n\t/**\n\t * Handle an rlm_heartbeat.* request from the bundled rlm-heartbeat skill.\n\t * These heartbeats are internal to this active session and never read or\n\t * mutate the user-level /heartbeat.\n\t */\n\thandleRlmHeartbeatHostRequest(type: string, payload: Record<string, unknown> = {}): Record<string, unknown> {\n\t\tconst controller = this._rlmHeartbeatController;\n\t\tif (!controller) {\n\t\t\tthrow new Error(\"RLM heartbeat skill is not available in this session\");\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase \"rlm_heartbeat.list\": {\n\t\t\t\tconst includeInactive = payload.include_inactive === true || payload.includeInactive === true;\n\t\t\t\treturn {\n\t\t\t\t\theartbeats: controller\n\t\t\t\t\t\t.listRlmHeartbeats({ includeInactive })\n\t\t\t\t\t\t.map((heartbeat) => rlmHeartbeatHostResponse(heartbeat)),\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"rlm_heartbeat.create\": {\n\t\t\t\tif (typeof payload.instruction !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.create instruction must be a string\");\n\t\t\t\t}\n\t\t\t\tif (payload.interval !== undefined && typeof payload.interval !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.create interval must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tif (payload.label !== undefined && typeof payload.label !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.create label must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tconst deliveryMode = normalizeHeartbeatDeliveryMode(payload.delivery_mode ?? payload.deliveryMode);\n\t\t\t\treturn {\n\t\t\t\t\theartbeat: rlmHeartbeatHostResponse(\n\t\t\t\t\t\tcontroller.createRlmHeartbeat({\n\t\t\t\t\t\t\tinstruction: payload.instruction,\n\t\t\t\t\t\t\tinterval: payload.interval,\n\t\t\t\t\t\t\tlabel: payload.label,\n\t\t\t\t\t\t\tdeliveryMode,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"rlm_heartbeat.update\": {\n\t\t\t\tif (typeof payload.id !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.update id must be a string\");\n\t\t\t\t}\n\t\t\t\tif (payload.instruction !== undefined && typeof payload.instruction !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.update instruction must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tif (payload.interval !== undefined && typeof payload.interval !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.update interval must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tif (payload.label !== undefined && typeof payload.label !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.update label must be a string when provided\");\n\t\t\t\t}\n\t\t\t\tif (payload.status !== undefined && !isRlmHeartbeatStatusUpdate(payload.status)) {\n\t\t\t\t\tthrow new Error('rlm_heartbeat.update status must be \"pause\" or \"resume\" when provided');\n\t\t\t\t}\n\t\t\t\tconst rawDeliveryMode = payload.delivery_mode ?? payload.deliveryMode;\n\t\t\t\tconst deliveryMode = normalizeHeartbeatDeliveryMode(rawDeliveryMode);\n\t\t\t\tif (\n\t\t\t\t\tpayload.instruction === undefined &&\n\t\t\t\t\tpayload.interval === undefined &&\n\t\t\t\t\tpayload.label === undefined &&\n\t\t\t\t\tpayload.status === undefined &&\n\t\t\t\t\trawDeliveryMode === undefined\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.update requires at least one field to update\");\n\t\t\t\t}\n\t\t\t\tconst heartbeat = controller.updateRlmHeartbeat({\n\t\t\t\t\tid: payload.id,\n\t\t\t\t\tinstruction: payload.instruction,\n\t\t\t\t\tinterval: payload.interval,\n\t\t\t\t\tlabel: payload.label,\n\t\t\t\t\tstatus: payload.status,\n\t\t\t\t\tdeliveryMode,\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\theartbeat: heartbeat ? rlmHeartbeatHostResponse(heartbeat) : null,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"rlm_heartbeat.delete\": {\n\t\t\t\tif (typeof payload.id !== \"string\") {\n\t\t\t\t\tthrow new Error(\"rlm_heartbeat.delete id must be a string\");\n\t\t\t\t}\n\t\t\t\tconst heartbeat = controller.deleteRlmHeartbeat(payload.id);\n\t\t\t\treturn {\n\t\t\t\t\theartbeat: heartbeat ? rlmHeartbeatHostResponse(heartbeat) : null,\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown RLM heartbeat request type \"${type}\"`);\n\t\t}\n\t}\n\n\thandleAgentMessageHostRequest(\n\t\ttype: string,\n\t\tpayload: Record<string, unknown> = {},\n\t):\n\t\t| Promise<AgentSessionMessageListResult | AgentSessionMessageReceipt | AgentFamilyRosterResult>\n\t\t| AgentSessionMessageListResult\n\t\t| AgentFamilyRosterResult {\n\t\tif (!this._agentMessageController) {\n\t\t\tthrow new Error(\"agent messaging is not available in this session\");\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase \"agent_message.list_agents\":\n\t\t\t\tif (!this._agentMessageController.roster)\n\t\t\t\t\tthrow new Error(\"agent family roster is not available in this session\");\n\t\t\t\treturn this._agentMessageController.roster();\n\t\t\tcase \"agent_message.send_result\": {\n\t\t\t\tif (typeof payload.target !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_message.send_result target must be a string\");\n\t\t\t\t}\n\t\t\t\tif (typeof payload.summary !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_message.send_result summary must be a string\");\n\t\t\t\t}\n\t\t\t\tif (typeof payload.findings !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_message.send_result findings must be a string\");\n\t\t\t\t}\n\t\t\t\treturn this._agentMessageController.sendAgentMessage({\n\t\t\t\t\ttarget: assertDirectAgentMessageTarget(payload.target),\n\t\t\t\t\tmessage: payload.summary,\n\t\t\t\t\tfindings: payload.findings,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcase \"agent_message.send\": {\n\t\t\t\tif (typeof payload.target !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_message.send target must be a string\");\n\t\t\t\t}\n\t\t\t\tif (typeof payload.message !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_message.send message must be a string\");\n\t\t\t\t}\n\t\t\t\treturn this._agentMessageController.sendAgentMessage({\n\t\t\t\t\ttarget: assertDirectAgentMessageTarget(payload.target),\n\t\t\t\t\tmessage: normalizeAgentSessionMessage(payload.message),\n\t\t\t\t});\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown agent message request type \"${type}\"`);\n\t\t}\n\t}\n\n\thandleAgentObserveHostRequest(\n\t\ttype: string,\n\t\tpayload: Record<string, unknown> = {},\n\t):\n\t\t| AgentObserveListResult\n\t\t| AgentObserveAgentSnapshot\n\t\t| AgentObserveRecentMessagesResult\n\t\t| Promise<AgentObserveListResult | AgentObserveAgentSnapshot | AgentObserveRecentMessagesResult> {\n\t\tconst controller = this._agentObserveController;\n\t\tif (!controller) {\n\t\t\tthrow new Error(\"agent observation is not available in this session\");\n\t\t}\n\t\tswitch (type) {\n\t\t\tcase \"agent_observe.list\":\n\t\t\t\treturn controller.listAgents();\n\t\t\tcase \"agent_observe.get\": {\n\t\t\t\tif (typeof payload.target !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_observe.get target must be a string\");\n\t\t\t\t}\n\t\t\t\treturn controller.getAgent(payload.target);\n\t\t\t}\n\t\t\tcase \"agent_observe.recent\": {\n\t\t\t\tif (typeof payload.target !== \"string\") {\n\t\t\t\t\tthrow new Error(\"agent_observe.recent target must be a string\");\n\t\t\t\t}\n\t\t\t\treturn controller.recentMessages({\n\t\t\t\t\ttarget: payload.target,\n\t\t\t\t\tlimit: normalizeObserveLimit(payload.limit as number | undefined),\n\t\t\t\t\tmaxChars: normalizeObserveMaxChars((payload.max_chars ?? payload.maxChars) as number | undefined),\n\t\t\t\t});\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`unknown agent observe request type \"${type}\"`);\n\t\t}\n\t}\n\n\tprivate async _createGoalFromHost(objective: string, tokenBudget: number | undefined): Promise<GoalState> {\n\t\tswitch (this._goalState.status) {\n\t\t\tcase \"active\":\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"cannot create a new goal because this thread already has an active goal; run `await goal.complete()` when it is achieved, or ask the user to clear it with /goal clear\",\n\t\t\t\t);\n\t\t\tcase \"paused\":\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"cannot create a new goal because a paused goal exists; ask the user to resume it with /goal resume or clear it with /goal clear\",\n\t\t\t\t);\n\t\t\tcase \"budget_limited\":\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"cannot create a new goal because a budget-limited goal exists; ask the user to resume it with /goal resume or clear it with /goal clear\",\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\t// idle, or a terminal record (complete / error): nothing pending, start fresh.\n\t\t\t\treturn this._startGoal(\n\t\t\t\t\tobjective,\n\t\t\t\t\ttokenBudget,\n\t\t\t\t\tthis.sessionManager[bindNativeEntryWriter]().captureGoalOperation({\n\t\t\t\t\t\tversion: 1,\n\t\t\t\t\t\tkind: \"goal_operation\",\n\t\t\t\t\t\toperation: \"create\",\n\t\t\t\t\t\tactor: \"runtime\",\n\t\t\t\t\t\tsubmittedText: objective,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t}\n\t}\n\n\tprivate async _completeGoalFromHost(): Promise<GoalState> {\n\t\tif (!this._goalState.objective || this._goalState.status === \"idle\") {\n\t\t\tthrow new Error(\"cannot complete goal because this thread has no goal\");\n\t\t}\n\t\tconst goal = this._goalWithAccountedWallClock();\n\t\t// A turn can cross the budget and complete the goal at once: accounting\n\t\t// runs at message_end, before the completing ipython cell executes, so a\n\t\t// budget-limit context may already be steered. It is stale now — drop it.\n\t\tthis._clearQueuedGoalContexts();\n\t\treturn this._setGoalState(\n\t\t\t{\n\t\t\t\t...goal,\n\t\t\t\tactive: false,\n\t\t\t\tstatus: \"complete\",\n\t\t\t\tlastReason: \"Goal achieved\",\n\t\t\t\tlastError: undefined,\n\t\t\t},\n\t\t\t{\n\t\t\t\tnativeGoalWrite: this.sessionManager[bindNativeEntryWriter]().captureGoalOperation({\n\t\t\t\t\tversion: 1,\n\t\t\t\t\tkind: \"goal_operation\",\n\t\t\t\t\toperation: \"complete\",\n\t\t\t\t\tactor: \"runtime\",\n\t\t\t\t\tpreviousGoalId: goal.goalId,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\t}\n\n\tprivate _getGoalContinuationMessages(\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal?: AbortSignal,\n\t): Promise<AgentMessage[]>;\n\tprivate _getGoalContinuationMessages(\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal: AbortSignal | undefined,\n\t\towner: GoalContinuationOwner,\n\t): Promise<AgentContinuationOutcome>;\n\tprivate _getGoalContinuationMessages(\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal?: AbortSignal,\n\t\towner?: GoalContinuationOwner,\n\t): Promise<AgentMessage[] | AgentContinuationOutcome> {\n\t\tconst outcome = this._getGoalContinuationOutcome(context, owner ?? this._captureGoalContinuationOwner(signal));\n\t\treturn owner ? outcome : outcome.then((value) => (value.kind === \"continue\" ? value.messages : []));\n\t}\n\n\tprivate async _getGoalContinuationOutcome(\n\t\tcontext: GetContinuationMessagesContext,\n\t\towner: GoalContinuationOwner,\n\t): Promise<AgentContinuationOutcome> {\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(owner.signal);\n\t\tif (await this._stopGoalContinuationForTerminalMessage(context.message, owner)) {\n\t\t\treturn this._stoppedContinuationOutcome(owner.signal);\n\t\t}\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(owner.signal);\n\t\tif (this._goalState.status !== \"active\" || !this._goalState.objective) {\n\t\t\treturn { kind: \"finish\" };\n\t\t}\n\t\t// Delegating and ending the turn is correct behavior; retain the existing wakeup owner.\n\t\tif (this._hasUnsettledRlmQuiescenceWork()) {\n\t\t\tthis._goalContinuationAwaitsRlmWork = true;\n\t\t\treturn { kind: \"wait_for_owned_work\" };\n\t\t}\n\t\tthis._goalContinuationAwaitsRlmWork = false;\n\t\ttry {\n\t\t\tthis._ensureGoalRuntimeActive(context.context);\n\t\t\tconst nextGoal = {\n\t\t\t\t...owner.goal,\n\t\t\t\tcontinuationsUsed: owner.goal.continuationsUsed + 1,\n\t\t\t\tlastReason: undefined,\n\t\t\t\tlastError: undefined,\n\t\t\t};\n\t\t\tawait this._setGoalState(nextGoal, { continuationOwner: owner });\n\t\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(owner.signal);\n\t\t\treturn { kind: \"continue\", messages: [createGoalContextMessage(owner.goal, \"continuation\")] };\n\t\t} catch (error) {\n\t\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(owner.signal);\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\ttry {\n\t\t\t\tawait this._finishGoalWithError(message, owner);\n\t\t\t} catch {\n\t\t\t\t// Preserve the goal hook's existing non-rejection policy, without finishing a replacement goal.\n\t\t\t}\n\t\t\treturn this._stoppedContinuationOutcome(owner.signal);\n\t\t}\n\t}\n\n\tprivate async _getContinuationMessages(\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal?: AbortSignal,\n\t): Promise<AgentMessage[]> {\n\t\t// Keep direct callers of the original Agent callback; the real loop uses the typed owner only.\n\t\tconst outcome = await this._getContinuationOutcome(context, signal);\n\t\treturn outcome.kind === \"continue\" ? outcome.messages : [];\n\t}\n\n\tprivate async _getContinuationOutcome(\n\t\tcontext: GetContinuationMessagesContext,\n\t\tsignal?: AbortSignal,\n\t): Promise<AgentContinuationOutcome> {\n\t\tif (signal?.aborted || this._disposed || this._disposing) return this._stoppedContinuationOutcome(signal);\n\t\tif (this.queuedActionCount > 0) return { kind: \"finish\" };\n\t\tconst owner = this._captureGoalContinuationOwner(signal);\n\t\tconst arrivalEpoch = this._sessionInputArrivalEpoch;\n\t\tconst goalSnapshot = owner.goal;\n\t\tconst goalAccountingStartedAt = owner.accountingStartedAt;\n\t\tconst autonomousState = this._autonomousState;\n\t\tconst autonomousSnapshot = structuredClone(autonomousState);\n\t\tconst cwd = this._cwd;\n\t\tconst autonomousOwnerIsCurrent = () =>\n\t\t\tthis._autonomousState === autonomousState && isDeepStrictEqual(autonomousState, autonomousSnapshot);\n\t\tconst goalOutcome = await this._getGoalContinuationMessages(context, signal, owner);\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(signal);\n\t\tif (goalOutcome.kind === \"continue\") {\n\t\t\tif (this._sessionInputArrivalEpoch !== arrivalEpoch) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this._setGoalState(goalSnapshot, { continuationOwner: owner });\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof StaleGoalContinuationError) return this._stoppedContinuationOutcome(signal);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(signal);\n\t\t\t\tthis._goalAccountingStartedAt = goalAccountingStartedAt;\n\t\t\t\treturn { kind: \"finish\" };\n\t\t\t}\n\t\t\treturn goalOutcome;\n\t\t}\n\t\tconst noContinuation = (): AgentContinuationOutcome =>\n\t\t\tgoalOutcome.kind === \"wait_for_owned_work\" && this._goalContinuationAwaitsRlmWork\n\t\t\t\t? { kind: \"wait_for_owned_work\" }\n\t\t\t\t: { kind: \"finish\" };\n\t\tif (\n\t\t\tthis._autonomousContinuationSuppressionDepth > 0 ||\n\t\t\t(owner.manager.supportsCapturedHistoryReads()\n\t\t\t\t? this._invocationSuppressedAutonomousContinuation\n\t\t\t\t: context.newMessages.some((message) => this._autonomousContinuationSuppressedMessages.has(message)))\n\t\t) {\n\t\t\treturn noContinuation();\n\t\t}\n\t\tif (!autonomousOwnerIsCurrent()) return { kind: \"finish\" };\n\t\t// Gate work may await. It must not mutate a new run's counters or failure state while it waits.\n\t\tconst candidate = structuredClone(autonomousSnapshot);\n\t\tlet autonomousMessage: AgentMessage | undefined;\n\t\ttry {\n\t\t\tautonomousMessage = await nextAutonomousContinuation(candidate, context.message, { cwd, signal });\n\t\t} catch (error) {\n\t\t\tif (this._isGoalContinuationOwnerCurrent(owner) && autonomousOwnerIsCurrent()) {\n\t\t\t\tthis._restoreAutonomousRuntimeSnapshot(candidate);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tif (!this._isGoalContinuationOwnerCurrent(owner)) return this._stoppedContinuationOutcome(signal);\n\t\tif (!autonomousOwnerIsCurrent()) return { kind: \"finish\" };\n\t\tif (autonomousMessage && this._sessionInputArrivalEpoch !== arrivalEpoch) return { kind: \"finish\" };\n\t\tthis._restoreAutonomousRuntimeSnapshot(candidate);\n\t\t// Preserve the current policy winner: a goal deferral does not override autonomous continuation.\n\t\treturn autonomousMessage ? { kind: \"continue\", messages: [autonomousMessage] } : noContinuation();\n\t}\n\n\tprivate _lastAssistantMessage: AssistantMessage | undefined = undefined;\n\n\tprivate _agentMessageOutcome(agentMessageId: string): AgentMessageOutcome {\n\t\tlet outcome = this._agentMessageOutcomes.get(agentMessageId);\n\t\tif (!outcome) {\n\t\t\toutcome = {};\n\t\t\tthis._agentMessageOutcomes.set(agentMessageId, outcome);\n\t\t}\n\t\treturn outcome;\n\t}\n\n\t/**\n\t * Register a delivery waiter before submitting the prompt. Delivery outcomes are not retained\n\t * for late lookup, so callers that register after admission may wait for a future use of the id.\n\t */\n\twaitForAgentMessagePromptDelivery(agentMessageId: string): Promise<void> {\n\t\tconst outcome = this._agentMessageOutcome(agentMessageId);\n\t\toutcome.delivery ??= createAgentMessageDeferred();\n\t\treturn outcome.delivery.promise;\n\t}\n\n\tprivate _settleAgentMessage(\n\t\tagentMessageId: string | undefined,\n\t\tleg: \"delivery\" | \"completion\",\n\t\terror?: Error,\n\t): void {\n\t\tif (agentMessageId === undefined) return;\n\t\tconst outcome = this._agentMessageOutcomes.get(agentMessageId);\n\t\tif (!outcome) return;\n\t\tconst deferred = outcome[leg];\n\t\tif (!deferred) return;\n\t\toutcome[leg] = undefined;\n\t\tif (!outcome.delivery && !outcome.completion) {\n\t\t\tthis._agentMessageOutcomes.delete(agentMessageId);\n\t\t}\n\t\tif (error) deferred.reject(error);\n\t\telse deferred.resolve();\n\t}\n\n\tprivate _rejectAgentMessage(agentMessageId: string | undefined, error: Error): void {\n\t\tif (agentMessageId === undefined) return;\n\t\tthis._settleAgentMessage(agentMessageId, \"delivery\", error);\n\t\tthis._settleAgentMessage(agentMessageId, \"completion\", error);\n\t}\n\n\tprivate _rejectQueuedAgentMessageDeliveries(deliveryError: Error, completionError = deliveryError): void {\n\t\tfor (const action of this._actionStore.unfinishedActions()) {\n\t\t\tthis._settleAgentMessage(action.agentMessageId, \"delivery\", deliveryError);\n\t\t\tthis._settleAgentMessage(action.agentMessageId, \"completion\", completionError);\n\t\t}\n\t}\n\n\tprivate _capturingCancelledAction(message: AgentMessage): QueuedSessionAction | undefined {\n\t\treturn this._actionStore\n\t\t\t.ownedActions()\n\t\t\t.find(\n\t\t\t\t(action) =>\n\t\t\t\t\taction.lifecycle.state === \"cancelled\" &&\n\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\taction.payload.captureRunMessages?.has(message) === true,\n\t\t\t);\n\t}\n\n\tprivate _hasCancelledDispatchCapture(): boolean {\n\t\treturn this._actionStore\n\t\t\t.ownedActions()\n\t\t\t.some(\n\t\t\t\t(action) =>\n\t\t\t\t\taction.lifecycle.state === \"cancelled\" &&\n\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\taction.payload.captureRunMessages !== undefined,\n\t\t\t);\n\t}\n\n\tprivate _captureInputOrigin(message: UserMessage | CustomMessage): CapturedNativeMessageWrite | undefined {\n\t\tconst actions = this._actionStore.actionsForMessage(message);\n\t\tif (actions.length !== 1) return undefined;\n\t\tconst action = actions[0];\n\t\tif (action.payload.kind !== \"turn\") return undefined;\n\t\tconst record = action.payload.records.find((record) => record.message === message);\n\t\tif (!record) return undefined;\n\t\treturn this.sessionManager[bindNativeEntryWriter]().captureMessage({\n\t\t\tversion: 1,\n\t\t\tkind: \"input\",\n\t\t\tactionId: action.id,\n\t\t\trecordId: record.id,\n\t\t\tinputSource: action.payload.acceptedAgentMessage ? \"internal\" : action.source,\n\t\t\trecordRole: record.role,\n\t\t\t...(record.role === \"primary\" && action.payload.submitted ? { submitted: action.payload.submitted } : {}),\n\t\t\t...(record.role === \"primary\" && action.payload.selectedSkillRef\n\t\t\t\t? { selectedSkillRef: action.payload.selectedSkillRef }\n\t\t\t\t: {}),\n\t\t});\n\t}\n\n\tprivate async _waitForAgentEventsBeforeContext(): Promise<void> {\n\t\ttry {\n\t\t\tawait this._agentEventQueue;\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof CompactionCommittedError) || error !== this._compactionSetupFailure) throw error;\n\t\t}\n\t}\n\n\tprivate _handleAgentEvent = (event: AgentEvent): void | Promise<void> => {\n\t\tif (event.type === \"agent_end\" && event.refusal) this._invocationOutputRefused = true;\n\t\tif (event.type === \"agent_start\") {\n\t\t\t// Native input waits for its delivery ticket. Direct/generic Agent runs have actually started here.\n\t\t\tif (\n\t\t\t\t!this._actionStore\n\t\t\t\t\t.activeActions()\n\t\t\t\t\t.some((action) => action.payload.kind === \"turn\" && action.lifecycle.state === \"committing\")\n\t\t\t) {\n\t\t\t\tfor (const resume of [this._pendingCheckpoint, this._postCompactionContinuationSettlement?.resume]) {\n\t\t\t\t\tif (resume?.boundary && this._isCompactionOwnerCurrent(resume.owner)) resume.boundary.state = \"consumed\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._invocationSuppressedAutonomousContinuation = false;\n\t\t\tthis._invocationCompactionOwner = this._captureCompactionOwner(this.agent.signal);\n\t\t}\n\t\tif (\n\t\t\t(event.type === \"message_start\" || event.type === \"message_end\") &&\n\t\t\tthis._autonomousContinuationSuppressedMessages.has(event.message)\n\t\t) {\n\t\t\tthis._invocationSuppressedAutonomousContinuation = true;\n\t\t}\n\t\tconst nativeMessageWrite =\n\t\t\tevent.type === \"message_end\" && (event.message.role === \"user\" || event.message.role === \"custom\")\n\t\t\t\t? this._captureInputOrigin(event.message)\n\t\t\t\t: undefined;\n\t\tif (event.type === \"message_start\" || event.type === \"message_end\") {\n\t\t\tfor (const action of this._actionStore.ownedActions()) {\n\t\t\t\tif (\n\t\t\t\t\taction.payload.kind !== \"turn\" ||\n\t\t\t\t\t!action.payload.captureRunMessages ||\n\t\t\t\t\taction.payload.cancelledDispatchEnded\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst primary = primaryDeliveryRecord(action);\n\t\t\t\tif (event.message === primary.message || primary.started) {\n\t\t\t\t\taction.payload.captureRunMessages.add(event.message);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (event.type === \"agent_end\") {\n\t\t\tconst captured = new Set<AgentMessage>();\n\t\t\tfor (const action of this._actionStore.ownedActions()) {\n\t\t\t\tif (action.payload.kind === \"turn\" && action.payload.captureRunMessages) {\n\t\t\t\t\tfor (const message of action.payload.captureRunMessages) captured.add(message);\n\t\t\t\t\taction.payload.cancelledDispatchEnded = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (captured.size > 0) {\n\t\t\t\tthis.agent.state.messages = this.agent.state.messages.filter((message) => !captured.has(message));\n\t\t\t}\n\t\t}\n\t\tif (event.type === \"message_start\" && (event.message.role === \"user\" || event.message.role === \"custom\")) {\n\t\t\tfor (const action of this._actionStore.actionsForMessage(event.message)) {\n\t\t\t\tconst record =\n\t\t\t\t\taction.payload.kind === \"turn\"\n\t\t\t\t\t\t? action.payload.records.find((candidate) => candidate.message === event.message)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (record) record.started = true;\n\t\t\t}\n\t\t}\n\t\tif (event.type === \"message_end\" && event.message.role === \"assistant\") {\n\t\t\t// Native result settlement precedes message publication. Keep auth failure\n\t\t\t// ownership independent of later message replacement, cancellation, or retry cleanup.\n\t\t\tconst source = takeNativeInferenceAuthSource(event.message);\n\t\t\tif (source && this._isConcreteProviderAuthFailure(event.message)) this._markProviderAuthStale(source);\n\t\t}\n\t\tconst compactionOwner = event.type === \"agent_end\" ? this._invocationCompactionOwner : undefined;\n\t\tconst job = this._agentEventQueue.then(\n\t\t\t() => this._processAgentEvent(event, nativeMessageWrite, compactionOwner),\n\t\t\t() => this._processAgentEvent(event, nativeMessageWrite, compactionOwner),\n\t\t);\n\t\tthis._agentEventQueue = job;\n\t\tjob.catch(() => {});\n\t\t// Ordinary extension contexts already expose request-only abort, not command waitForIdle.\n\t\t// Join THIS accepted message job, never a later mutable tail from inside that job.\n\t\tif (\n\t\t\tthis.sessionManager.supportsCapturedHistoryReads() &&\n\t\t\t(event.type === \"message_end\" || (event.type === \"agent_end\" && event.refusal))\n\t\t)\n\t\t\treturn job;\n\t};\n\n\tprivate _findLastAssistantInMessages(messages: AgentMessage[]): AssistantMessage | undefined {\n\t\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\t\tconst message = messages[i];\n\t\t\tif (message.role === \"assistant\") {\n\t\t\t\treturn message as AssistantMessage;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _addLoginGuidanceToAuthError(event: AgentEvent): void {\n\t\tconst message =\n\t\t\tevent.type === \"message_end\" && event.message.role === \"assistant\"\n\t\t\t\t? (event.message as AssistantMessage)\n\t\t\t\t: event.type === \"agent_end\" && !event.refusal\n\t\t\t\t\t? this._findLastAssistantInMessages(event.messages)\n\t\t\t\t\t: undefined;\n\t\tif (!message || message.stopReason !== \"error\" || !message.errorMessage) {\n\t\t\treturn;\n\t\t}\n\t\tif (!isLikelyAuthenticationError(message.errorMessage)) {\n\t\t\treturn;\n\t\t}\n\t\tmessage.errorMessage = addLoginGuidanceToAuthError(message.errorMessage);\n\t}\n\n\tprivate async _processAgentEvent(\n\t\tevent: AgentEvent,\n\t\tnativeMessageWrite?: CapturedNativeMessageWrite,\n\t\tcompactionOwner?: CompactionOwner,\n\t): Promise<void> {\n\t\tlet clearedDispatchEnded = false;\n\t\tif ((event.type === \"message_start\" || event.type === \"message_end\") && event.message.role === \"toolResult\") {\n\t\t\tif (this.sessionManager.supportsCapturedHistoryReads())\n\t\t\t\tawait this._applyCanonicalIpythonSentAgentMessages(event.message);\n\t\t\telse this._applyLateIpythonSentAgentMessages(event.message);\n\t\t}\n\t\tif (event.type === \"message_start\" || event.type === \"message_end\") {\n\t\t\tconst cleared = this._capturingCancelledAction(event.message);\n\t\t\tif (cleared?.payload.kind === \"turn\" && cleared.payload.captureRunMessages) {\n\t\t\t\tconst captured = cleared.payload.captureRunMessages;\n\t\t\t\tthis.agent.state.messages = this.agent.state.messages.filter((message) => !captured.has(message));\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif (event.type === \"agent_end\") {\n\t\t\tconst cleared = this._actionStore\n\t\t\t\t.ownedActions()\n\t\t\t\t.filter(\n\t\t\t\t\t(action) =>\n\t\t\t\t\t\taction.lifecycle.state === \"cancelled\" &&\n\t\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\t\taction.payload.captureRunMessages !== undefined,\n\t\t\t\t);\n\t\t\tif (cleared.length > 0) {\n\t\t\t\tclearedDispatchEnded = true;\n\t\t\t\tconst removed = new Set(\n\t\t\t\t\tcleared.flatMap((action) =>\n\t\t\t\t\t\taction.payload.kind === \"turn\" ? [...(action.payload.captureRunMessages ?? [])] : [],\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tthis.agent.state.messages = this.agent.state.messages.filter((message) => !removed.has(message));\n\t\t\t\t(this.agent.state as { errorMessage?: string }).errorMessage = undefined;\n\t\t\t\tthis._lastAssistantMessage = undefined;\n\t\t\t\tfor (const action of cleared) this._actionStore.releaseTerminal(action);\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\tthis._resolveRetry();\n\t\t\t}\n\t\t}\n\n\t\tif (event.type === \"agent_end\" && event.refusal) {\n\t\t\t// Primary delivery ACKs remain delivered. Only this invocation's completion has failed.\n\t\t\tthis._lastAssistantMessage = undefined;\n\t\t\tthis._clearQueuedGoalContexts();\n\t\t\tthis._clearQueuedAutonomousContinuations();\n\t\t\tif (this._retryAttempt > 0) {\n\t\t\t\tthis._emit({\n\t\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tattempt: this._retryAttempt,\n\t\t\t\t\tfinalError: new AgentOutputLimitError(event.refusal).message,\n\t\t\t\t});\n\t\t\t\tthis._retryAttempt = 0;\n\t\t\t}\n\t\t\tthis._resolveRetry();\n\t\t\tawait this._emitExtensionEvent(event);\n\t\t\tthis._emit(event);\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.type === \"message_start\" && startsAgentRun(event.message)) {\n\t\t\tthis._overflowRecovery = \"idle\";\n\t\t}\n\n\t\tif (\n\t\t\tthis.sessionManager.supportsCapturedHistoryReads() &&\n\t\t\tevent.type === \"message_end\" &&\n\t\t\tevent.message.role === \"assistant\"\n\t\t) {\n\t\t\t// Preserve budget progress while a message_end transformer waits. The same subject WeakSet\n\t\t\t// deduplicates the post-message and post-turn calls; goal state is published only after its ACK.\n\t\t\t// Do not run serialized refinement/compaction or stop mandatory tools at this point.\n\t\t\tif ((await this._accountGoalUsageForAssistantMessage(event.message)) && !this._invocationOutputRefused) {\n\t\t\t\tconst message = createGoalContextMessage(this._goalState, \"budget_limit\");\n\t\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\t\tawait this._queuePreparedPrompt(\"steer\", normalized.text, normalized.images, {\n\t\t\t\t\tmessage,\n\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait this._emitExtensionEvent(event);\n\t\tif (event.type === \"message_start\" || event.type === \"message_end\") {\n\t\t\tconst cleared = this._capturingCancelledAction(event.message);\n\t\t\tif (cleared?.payload.kind === \"turn\" && cleared.payload.captureRunMessages) {\n\t\t\t\tconst captured = cleared.payload.captureRunMessages;\n\t\t\t\tthis.agent.state.messages = this.agent.state.messages.filter((message) => !captured.has(message));\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis._addLoginGuidanceToAuthError(event);\n\n\t\tif (event.type !== \"message_end\") this._emit(event);\n\n\t\tif (event.type === \"message_end\") {\n\t\t\tif (event.message.role === \"custom\") {\n\t\t\t\tif (nativeMessageWrite) await nativeMessageWrite(event.message);\n\t\t\t\telse\n\t\t\t\t\tawait this.sessionManager.appendCustomMessageEntry(\n\t\t\t\t\t\tevent.message.customType,\n\t\t\t\t\t\tevent.message.content,\n\t\t\t\t\t\tevent.message.display,\n\t\t\t\t\t\tevent.message.details,\n\t\t\t\t\t);\n\t\t\t} else if (\n\t\t\t\tevent.message.role === \"user\" ||\n\t\t\t\tevent.message.role === \"assistant\" ||\n\t\t\t\tevent.message.role === \"toolResult\"\n\t\t\t) {\n\t\t\t\tconst manager = this.sessionManager;\n\t\t\t\tconst sessionId = manager.getSessionId();\n\t\t\t\tconst sessionFile = manager.getSessionFile();\n\t\t\t\tconst nativeOutput =\n\t\t\t\t\t!nativeMessageWrite && event.message.role === \"assistant\"\n\t\t\t\t\t\t? this.requests.appendMainOutput(event.message, manager)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst entryId = nativeMessageWrite\n\t\t\t\t\t? await nativeMessageWrite(event.message)\n\t\t\t\t\t: ((nativeOutput ? await nativeOutput : undefined) ?? (await manager.appendMessage(event.message)));\n\t\t\t\tif (event.message.role === \"assistant\")\n\t\t\t\t\tthis._assistantEntryIds.set(event.message, { sessionId, sessionFile, entryId });\n\t\t\t}\n\t\t\tif (event.message.role === \"user\" || event.message.role === \"custom\") {\n\t\t\t\tfor (const action of this._actionStore.actionsForMessage(event.message)) {\n\t\t\t\t\tconst record =\n\t\t\t\t\t\taction.payload.kind === \"turn\"\n\t\t\t\t\t\t\t? action.payload.records.find((candidate) => candidate.message === event.message)\n\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\tif (record) record.durable = true;\n\t\t\t\t\tif (record?.role === \"primary\") {\n\t\t\t\t\t\tthis._actionStore.ticketFor(action).settleDelivered({ status: \"delivered\" });\n\t\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"delivery\");\n\t\t\t\t\t\tif (action.lifecycle.state === \"committing\") {\n\t\t\t\t\t\t\ttransitionSessionAction(action, { state: \"running\", execution: \"agent_turn\" });\n\t\t\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._emit(event);\n\n\t\t\tif (event.message.role === \"assistant\") {\n\t\t\t\tthis._lastAssistantMessage = event.message;\n\n\t\t\t\tconst assistantMsg = event.message as AssistantMessage;\n\t\t\t\tif (assistantMsg.stopReason !== \"error\") {\n\t\t\t\t\taddAutonomousUsage(this._autonomousState, assistantMsg.usage);\n\t\t\t\t}\n\t\t\t\tif (assistantMsg.stopReason !== \"error\" && assistantMsg.stopReason !== \"aborted\") {\n\t\t\t\t\tthis._assistantTurnsSinceAutoRefine++;\n\t\t\t\t\t// In serialized mode, kick off background refinement planning\n\t\t\t\t\t// immediately after the primary stream finishes, while tools\n\t\t\t\t\t// are still executing. The plan is awaited at shouldStopAfterTurn\n\t\t\t\t\t// before applying, so planning overlaps tools only — never another\n\t\t\t\t\t// model request.\n\t\t\t\t\tthis._maybeStartSerializedBackgroundPlan();\n\t\t\t\t}\n\t\t\t\tif (assistantMsg.stopReason !== \"error\") {\n\t\t\t\t\tthis._overflowRecovery = \"idle\";\n\t\t\t\t}\n\n\t\t\t\t// Reset retry counter immediately on successful assistant response\n\t\t\t\t// This prevents accumulation across multiple LLM calls within a turn\n\t\t\t\tif (\n\t\t\t\t\tassistantMsg.stopReason !== \"error\" &&\n\t\t\t\t\tassistantMsg.stopReason !== \"aborted\" &&\n\t\t\t\t\tthis._retryAttempt > 0\n\t\t\t\t) {\n\t\t\t\t\tthis._emit({\n\t\t\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tattempt: this._retryAttempt,\n\t\t\t\t\t});\n\t\t\t\t\tthis._retryAttempt = 0;\n\t\t\t\t}\n\t\t\t\tif ((await this._accountGoalUsageForAssistantMessage(assistantMsg)) && !this._invocationOutputRefused) {\n\t\t\t\t\tconst message = createGoalContextMessage(this._goalState, \"budget_limit\");\n\t\t\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\t\t\tawait this._queuePreparedPrompt(\"steer\", normalized.text, normalized.images, {\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (clearedDispatchEnded) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.type === \"agent_end\") {\n\t\t\tconst msg =\n\t\t\t\tthis._lastAssistantMessage ??\n\t\t\t\t(this._retryPromise ? this._findLastAssistantInMessages(event.messages) : undefined);\n\t\t\tthis._lastAssistantMessage = undefined;\n\t\t\tif (!msg) {\n\t\t\t\tthis._resolveRetry();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst compactionWillRetry = await this._checkCompaction(msg, true, true, compactionOwner);\n\t\t\tif (compactionWillRetry && this._retryAttempt > 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._finishActiveRetryWithFailure(msg);\n\t\t\tthis._resolveRetry();\n\t\t\tif (!compactionWillRetry) {\n\t\t\t\tawait this._finishGoalForTerminalAssistantMessage(msg);\n\t\t\t\t// In serialized mode, agent-callable refine.run is serviced\n\t\t\t\t// at the shouldStopAfterTurn boundary, not here at agent_end.\n\t\t\t\tif (!this._serializedRefine) {\n\t\t\t\t\tconst consumedRequestedRefine = this._consumePendingRequestedRefine();\n\t\t\t\t\tif (!consumedRequestedRefine) {\n\t\t\t\t\t\tthis._scheduleAutoRefineAfterAgentEnd();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _resolveRetry(): void {\n\t\tthis._semanticEdges.clearTurnRetry();\n\t\tthis.requests.clearTurnRetry();\n\t\tif (this._retryResolve) {\n\t\t\tthis._retryResolve();\n\t\t\tthis._retryResolve = undefined;\n\t\t\tthis._retryPromise = undefined;\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\tthis._scheduleSessionInputPump();\n\t\t}\n\t}\n\n\tprivate _findLastAssistantMessage(): AssistantMessage | undefined {\n\t\tconst messages = this.agent.state.messages;\n\t\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\t\tconst msg = messages[i];\n\t\t\tif (msg.role === \"assistant\") {\n\t\t\t\treturn msg as AssistantMessage;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _replaceMessageInPlace(target: AgentMessage, replacement: AgentMessage): void {\n\t\t// Agent-core stores the finalized message object in its state before emitting message_end.\n\t\t// SessionManager persistence happens later in _processAgentEvent() with event.message.\n\t\t// Mutating this object in place keeps agent state, later turn/agent events, listeners,\n\t\t// and the eventual SessionManager.appendMessage(event.message) persistence in sync.\n\t\tif (target === replacement) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst targetRecord = target as unknown as Record<string, unknown>;\n\t\tfor (const key of Object.keys(targetRecord)) {\n\t\t\tdelete targetRecord[key];\n\t\t}\n\t\tObject.assign(targetRecord, replacement);\n\t}\n\n\tprivate async _emitExtensionEvent(event: AgentEvent): Promise<void> {\n\t\t// Failed native initialization can emit a lifecycle error before extensions exist.\n\t\tif (!this._extensionRunner) return;\n\t\tif (event.type === \"agent_start\") {\n\t\t\tthis._turnIndex = 0;\n\t\t\tawait this.sessionManager.recordGitStateIfChanged();\n\t\t\tawait this._extensionRunner.emit({ type: \"agent_start\" });\n\t\t} else if (event.type === \"agent_end\") {\n\t\t\t// Also capture at end of turn so commits made during the run (e.g. via a bash tool) land.\n\t\t\tawait this.sessionManager.recordGitStateIfChanged();\n\t\t\tawait this._extensionRunner.emit(event);\n\t\t} else if (event.type === \"turn_start\") {\n\t\t\tconst extensionEvent: TurnStartEvent = {\n\t\t\t\ttype: \"turn_start\",\n\t\t\t\tturnIndex: this._turnIndex,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t} else if (event.type === \"turn_end\") {\n\t\t\tconst extensionEvent: TurnEndEvent = {\n\t\t\t\ttype: \"turn_end\",\n\t\t\t\tturnIndex: this._turnIndex,\n\t\t\t\tmessage: event.message,\n\t\t\t\ttoolResults: event.toolResults,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t\tthis._turnIndex++;\n\t\t} else if (event.type === \"message_start\") {\n\t\t\tconst extensionEvent: MessageStartEvent = {\n\t\t\t\ttype: \"message_start\",\n\t\t\t\tmessage: event.message,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t} else if (event.type === \"message_update\") {\n\t\t\tconst extensionEvent: MessageUpdateEvent = {\n\t\t\t\ttype: \"message_update\",\n\t\t\t\tmessage: event.message,\n\t\t\t\tassistantMessageEvent: event.assistantMessageEvent,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t} else if (event.type === \"message_end\") {\n\t\t\tconst extensionEvent: MessageEndEvent = {\n\t\t\t\ttype: \"message_end\",\n\t\t\t\tmessage: event.message,\n\t\t\t};\n\t\t\tconst replacement = await this._extensionRunner.emitMessageEnd(extensionEvent);\n\t\t\tif (replacement) {\n\t\t\t\tthis._replaceMessageInPlace(event.message, replacement);\n\t\t\t}\n\t\t} else if (event.type === \"tool_execution_start\") {\n\t\t\tconst extensionEvent: ToolExecutionStartEvent = {\n\t\t\t\ttype: \"tool_execution_start\",\n\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\ttoolName: event.toolName,\n\t\t\t\targs: event.args,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t} else if (event.type === \"tool_execution_update\") {\n\t\t\tconst extensionEvent: ToolExecutionUpdateEvent = {\n\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\ttoolName: event.toolName,\n\t\t\t\targs: event.args,\n\t\t\t\tpartialResult: event.partialResult,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t} else if (event.type === \"tool_execution_end\") {\n\t\t\tconst extensionEvent: ToolExecutionEndEvent = {\n\t\t\t\ttype: \"tool_execution_end\",\n\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\ttoolName: event.toolName,\n\t\t\t\tresult: event.result,\n\t\t\t\tisError: event.isError,\n\t\t\t};\n\t\t\tawait this._extensionRunner.emit(extensionEvent);\n\t\t}\n\t}\n\n\t/**\n\t * Subscribe to agent events.\n\t * Session persistence is handled internally (saves messages on message_end).\n\t * Multiple listeners can be added. Returns unsubscribe function for this listener.\n\t */\n\tsubscribe(listener: AgentSessionEventListener): () => void {\n\t\tthis._eventListeners.push(listener);\n\n\t\treturn () => {\n\t\t\tconst index = this._eventListeners.indexOf(listener);\n\t\t\tif (index !== -1) {\n\t\t\t\tthis._eventListeners.splice(index, 1);\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Temporarily disconnect from agent events.\n\t * User listeners are preserved and will receive events again after resubscribe().\n\t * Used internally during operations that need to pause event processing.\n\t */\n\tprivate _disconnectFromAgent(): void {\n\t\tif (this._unsubscribeAgent) {\n\t\t\tthis._unsubscribeAgent();\n\t\t\tthis._unsubscribeAgent = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Reconnect to agent events after _disconnectFromAgent().\n\t * Preserves all existing listeners.\n\t */\n\tprivate _reconnectToAgent(): void {\n\t\tif (this._unsubscribeAgent) return; // Already connected\n\t\tthis._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);\n\t}\n\n\t/**\n\t * Remove all listeners and disconnect from agent.\n\t * Call this when completely done with the session.\n\t */\n\t/** Stop new opportunistic refinement without cancelling accepted calls or explicit queued requests. */\n\tcloseAutoRefineAdmission(): void {\n\t\tif (this._autoRefineAdmissionClosed) return;\n\t\tthis._autoRefineAdmissionClosed = true;\n\t\tfor (const timer of this._scheduledAutoRefineTimers) clearTimeout(timer);\n\t\tthis._scheduledAutoRefineTimers.clear();\n\t\tthis._discardPendingAutoRefine();\n\t}\n\n\t/**\n\t * Async teardown for graceful quit/switch: await the Python kernel's dispose\n\t * (which flushes a final namespace snapshot) before the synchronous dispose, so\n\t * the latest state reaches disk instead of racing process exit.\n\t */\n\tasync disposeAsync(options?: { kernelSnapshot?: boolean }): Promise<void> {\n\t\tthis._failedAutomaticCompaction = undefined;\n\t\tthis._failedThresholdCompaction = undefined;\n\t\tthis._contextCompiler.clear();\n\t\tthis._nativeRecoveryCursors.clear();\n\t\tfor (const admission of this._rlmChildAdmissions) admission.cancel(\"Parent session disposed\");\n\t\tif (this._disposeAsyncPromise) return this._disposeAsyncPromise;\n\t\tthis.closeAutoRefineAdmission();\n\t\tconst kernelSnapshot = options?.kernelSnapshot ?? true;\n\t\tthis._disposeAsyncPromise = (async () => {\n\t\t\tconst errors: unknown[] = [];\n\t\t\ttry {\n\t\t\t\tif (!this._disposed) await this._drainPendingRefinementForDisposal();\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t\tthis._disposing = true;\n\t\t\tthis._sessionActionCommitDisposeAbortController.abort();\n\t\t\ttry {\n\t\t\t\tawait this._disposeAsyncOnce(kernelSnapshot);\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session disposal failed\");\n\t\t\tthis._rlmResidentDisposalComplete = true;\n\t\t\tawait this._releaseRlmResidentCapacity?.();\n\t\t\tawait this._rlmRootAdmission?.release();\n\t\t})();\n\t\treturn this._disposeAsyncPromise;\n\t}\n\n\t/** Drain accepted refinement and explicit queued requests; never start an opportunistic review or plan. */\n\tprivate async _drainPendingRefinementForDisposal(): Promise<void> {\n\t\tthis.closeAutoRefineAdmission();\n\t\tawait this._drainAcceptedRefinement();\n\t}\n\n\tprivate async _drainAcceptedRefinement(): Promise<void> {\n\t\tconst errors: unknown[] = [];\n\t\tconst drain = async () => {\n\t\t\tfor (const timer of this._scheduledAutoRefineTimers) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tthis._scheduledAutoRefineTimers.clear();\n\t\t\tconst settled = await Promise.allSettled([...this._autoRefineOperations]);\n\t\t\tfor (const result of settled) if (result.status === \"rejected\") errors.push(result.reason);\n\t\t\tfor (const timer of this._scheduledAutoRefineTimers) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tthis._scheduledAutoRefineTimers.clear();\n\t\t\t// Wait for in-flight refinement (including serialized background plan) to settle.\n\t\t\twhile (this._refineInFlight || this._refinePlanInFlight || this._serializedPlanInFlight) {\n\t\t\t\tif (this._refineInFlight) {\n\t\t\t\t\tawait this._refineInFlight;\n\t\t\t\t} else if (this._refinePlanInFlight) {\n\t\t\t\t\tawait this._refinePlanInFlight;\n\t\t\t\t} else if (this._serializedPlanInFlight) {\n\t\t\t\t\t// Await the background plan and apply a ready \"plan\" result before teardown.\n\t\t\t\t\tawait this._consumeSerializedBackgroundPlan(async (bgResult) => {\n\t\t\t\t\t\tif (bgResult?.status === \"plan\" && bgResult.branchVersion === this._autoRefineBranchVersion) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tawait this._applySerializedPlan(bgResult);\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\terrors.push(error);\n\t\t\t\t\t\t\t\tthis._emitRefineFailed(error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Preserve completion bookkeeping for the accepted refinement.\n\t\t\t\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// A failed background plan keeps its recorded failure; disposal never recreates it for retry.\n\t\t\t\t\t\tif (bgResult?.status === \"skip\" && bgResult.explicit) {\n\t\t\t\t\t\t\tthis._emitRefineFailed(new RefineSkippedError(\"Refinement skipped by extension\"));\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Preserve completed background-round bookkeeping without retrying.\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tbgResult?.status === \"skip\" ||\n\t\t\t\t\t\t\tbgResult?.status === \"failure\" ||\n\t\t\t\t\t\t\tbgResult?.status === \"invalidated\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tawait new Promise<void>((resolve) => setTimeout(resolve, 0));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this._compactionSetupFailure) return;\n\t\t\t// Drain an agent-callable refine.run request that was scheduled but\n\t\t\t// not yet consumed. Use the direct serialized path (no waitForIdle)\n\t\t\t// since the agent may still own activeRun at the final agent_end.\n\t\t\tif (this._pendingRequestedRefine) {\n\t\t\t\tconst pending = this._pendingRequestedRefine;\n\t\t\t\tthis._pendingRequestedRefine = undefined;\n\t\t\t\ttry {\n\t\t\t\t\tawait this._runSerializedRefine(pending);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t}\n\t\t\t\t// Preserve completion bookkeeping for the accepted explicit request.\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t}\n\t\t};\n\t\ttry {\n\t\t\tawait drain();\n\t\t} catch (error) {\n\t\t\terrors.push(error);\n\t\t}\n\t\tconst distinct = [...new Set(errors)];\n\t\tif (distinct.length === 1) throw distinct[0];\n\t\tif (distinct.length > 1) throw new AggregateError(distinct, \"Session refinement drain failed\");\n\t}\n\n\tprivate async _disposeAsyncOnce(kernelSnapshot: boolean): Promise<void> {\n\t\tconst admissions = [...this._rlmChildAdmissions];\n\t\tconst errors: unknown[] = [];\n\t\tconst drain = async (operation: () => unknown | Promise<unknown>): Promise<void> => {\n\t\t\ttry {\n\t\t\t\tawait operation();\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t};\n\t\ttry {\n\t\t\tawait drain(() => this.requests.stopAdmission());\n\t\t\tawait drain(() => this.requestAbort());\n\t\t\tfor (const run of [...this._activeRlmChildRuns.values()]) {\n\t\t\t\tawait drain(() => this._cancelRlmChildRun(run, \"Parent session disposed\"));\n\t\t\t}\n\t\t\tawait drain(() => this.requests.waitForIdle());\n\t\t\t// Initialization reports errors through its own promise, like an active Agent run.\n\t\t\t// Join it before disposing any runtime resources it may still be constructing.\n\t\t\tif (this._initialization) await Promise.allSettled([this._initialization]);\n\t\t\t// Includes native children constructed but not yet published by their factories.\n\t\t\tfor (const admission of admissions) {\n\t\t\t\tif (admission.session) await drain(() => admission.session?.disposeAsync());\n\t\t\t}\n\t\t\tfor (const run of [...this._activeRlmChildRuns.values()]) {\n\t\t\t\tconst childSession = run.session;\n\t\t\t\tif (!childSession) continue;\n\t\t\t\trun.suppressTerminalNotice = true;\n\t\t\t\tif (run.detachedDeletion && run.deletionCleanupObserver) {\n\t\t\t\t\tawait drain(() => run.deletionCleanupObserver);\n\t\t\t\t} else if (run.detachedDeletion && run.deletionCleanup) {\n\t\t\t\t\tawait drain(() => run.deletionCleanup);\n\t\t\t\t} else {\n\t\t\t\t\tawait drain(() => childSession.disposeAsync());\n\t\t\t\t}\n\t\t\t\tif (run.detachedDeletion && !run.settled) await drain(() => this._finishRlmRunDeletion(run));\n\t\t\t}\n\t\t\tfor (const unsubscribe of this._rlmChildUnsubscribes.values()) await drain(unsubscribe);\n\t\t\tthis._rlmChildUnsubscribes.clear();\n\t\t\tfor (const { session } of this._rlmChildSessions.values()) await drain(() => session.disposeAsync());\n\t\t\tthis._rlmChildSessions.clear();\n\t\t\tthis._rlmChildUsageSources.clear();\n\t\t\tthis._rlmChildCleanupFailures.clear();\n\t\t\tthis._deletedRlmChildIds.clear();\n\t\t\t// Stop kernel-backed tools before waiting for their terminal agent events.\n\t\t\tawait drain(() => this._ipythonKernelProvisioner?.dispose({ snapshot: kernelSnapshot }));\n\t\t\twhile (this._rlmRunTasks.size > 0) {\n\t\t\t\tfor (const task of [...this._rlmRunTasks]) await drain(() => task);\n\t\t\t}\n\t\t\tfor (const admission of admissions) {\n\t\t\t\tawait drain(() => admission.settlement);\n\t\t\t\tif (admission.session) await drain(() => admission.session?.disposeAsync());\n\t\t\t}\n\t\t\tawait drain(() => this.agent.waitForIdle());\n\t\t\tawait drain(() => this._compactionOperation);\n\t\t\tawait drain(() => this._branchSummaryOperation);\n\t\t\tawait drain(() => this._agentEventQueue);\n\t\t\tawait drain(() => this._goalResumeOperation);\n\t\t\tawait drain(() => this._waitForChildUsageWrites());\n\t\t\tawait drain(() => this.dispose());\n\t\t} catch (error) {\n\t\t\terrors.push(error);\n\t\t} finally {\n\t\t\tawait drain(() => this._startDisposeCallbacks());\n\t\t\tawait drain(() => this.sessionManager.close());\n\t\t}\n\t\tif (errors.length === 1) throw errors[0];\n\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session disposal failed\");\n\t}\n\n\tprivate _startDisposeCallbacks(): Promise<void> {\n\t\tif (this._disposeCallbacksPromise) return this._disposeCallbacksPromise;\n\t\tconst pending: Promise<void>[] = [];\n\t\tfor (const callback of this._disposeCallbacks) {\n\t\t\ttry {\n\t\t\t\tconst result = callback();\n\t\t\t\tif (result) pending.push(result);\n\t\t\t} catch (error) {\n\t\t\t\tpending.push(Promise.reject(error));\n\t\t\t}\n\t\t}\n\t\tthis._disposeCallbacks.clear();\n\t\tthis._disposeCallbacksPromise = Promise.allSettled(pending).then((results) => {\n\t\t\tconst errors = results.flatMap((result) => (result.status === \"rejected\" ? [result.reason] : []));\n\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Session disposal callbacks failed\");\n\t\t});\n\t\treturn this._disposeCallbacksPromise;\n\t}\n\n\tdispose(): void {\n\t\tthis._failedAutomaticCompaction = undefined;\n\t\tthis._failedThresholdCompaction = undefined;\n\t\tthis._contextCompiler.clear();\n\t\tthis._nativeRecoveryCursors.clear();\n\t\tif (this._disposed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.requests.stopAdmission();\n\t\tthis._disposed = true;\n\t\tfor (const run of this._unsettledRlmChildRuns) run.suppressTerminalNotice = true;\n\t\tfor (const controller of this._rlmQuiescenceWaitAborts) controller.abort();\n\t\tthis._sessionActionCommitDisposeAbortController.abort();\n\t\ttry {\n\t\t\t// Invalidate scheduled timers and abort any in-flight review so a late\n\t\t\t// resolution cannot write harness state or re-subscribe handlers.\n\t\t\tthis._autoRefineReviewAbort?.abort();\n\t\t\tthis._refineAbortController?.abort();\n\t\t\tfor (const timer of this._scheduledAutoRefineTimers) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tthis._scheduledAutoRefineTimers.clear();\n\t\t\tthis._serializedPlanInFlight = undefined;\n\t\t\tthis._serializedExplicitRefineOptions = undefined;\n\t\t\tthis._pendingRequestedRefine = undefined;\n\t\t\tthis._discardPendingAutoRefine({ cancelPostCompactionContinue: true });\n\t\t\tthis._autoRefineBranchVersion++;\n\t\t\tthis._cancelActiveRlmChildRuns(\"Parent session disposed\");\n\t\t\tfor (const unsubscribe of this._rlmChildUnsubscribes.values()) {\n\t\t\t\tunsubscribe();\n\t\t\t}\n\t\t\tthis._rlmChildUnsubscribes.clear();\n\t\t\tfor (const { session } of this._rlmChildSessions.values()) {\n\t\t\t\tsession.dispose();\n\t\t\t}\n\t\t\tthis._rlmChildSessions.clear();\n\t\t\tthis._rlmChildUsageSources.clear();\n\t\t\tthis._rlmChildCleanupFailures.clear();\n\t\t\tthis._deletedRlmChildIds.clear();\n\t\t\tthis._pendingNextTurnMessages = [];\n\t\t\tconst deliveryError = new Error(\"Session disposed before prompt delivery.\");\n\t\t\tconst completionError = new Error(\"Session disposed before prompt completion.\");\n\t\t\tthis._rejectQueuedAgentMessageDeliveries(deliveryError, completionError);\n\t\t\tfor (const [agentMessageId, outcome] of this._agentMessageOutcomes) {\n\t\t\t\tif (outcome.delivery) this._settleAgentMessage(agentMessageId, \"delivery\", deliveryError);\n\t\t\t\tif (outcome.completion) this._settleAgentMessage(agentMessageId, \"completion\", completionError);\n\t\t\t}\n\t\t\tthis._cancelSessionActions(() => true, deliveryError);\n\t\t\tthis.agent.clearAllQueues();\n\t\t\tthis._extensionRunner?.invalidate(\n\t\t\t\t\"This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().\",\n\t\t\t);\n\t\t\tthis._disconnectFromAgent();\n\t\t\tthis._eventListeners = [];\n\t\t\tcleanupSessionResources(this.sessionId);\n\t\t} finally {\n\t\t\t// The synchronous surface cannot report late errors; disposeAsync joins this same promise.\n\t\t\tvoid this._startDisposeCallbacks().catch(() => undefined);\n\t\t}\n\t}\n\n\tregisterDisposeCallback(callback: () => void | Promise<void>): void {\n\t\tif (this._disposed) {\n\t\t\ttry {\n\t\t\t\tconst result = callback();\n\t\t\t\tif (result) void result.catch(() => undefined);\n\t\t\t} catch {\n\t\t\t\t// Late registration follows the same best-effort disposal contract.\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis._disposeCallbacks.add(callback);\n\t}\n\n\tget state(): AgentState {\n\t\treturn this.agent.state;\n\t}\n\n\tget model(): Model<any> | undefined {\n\t\treturn this.agent.state.model;\n\t}\n\n\tget thinkingLevel(): ThinkingLevel {\n\t\treturn this.agent.state.thinkingLevel;\n\t}\n\n\tget serviceTier(): ServiceTier {\n\t\treturn this.agent.state.serviceTier;\n\t}\n\n\tget isStreaming(): boolean {\n\t\treturn this.agent.state.isStreaming;\n\t}\n\n\tget systemPrompt(): string {\n\t\treturn this.agent.state.systemPrompt;\n\t}\n\n\tget retryAttempt(): number {\n\t\treturn this._retryAttempt;\n\t}\n\n\tgetActiveToolNames(): string[] {\n\t\treturn this.agent.state.tools.map((t) => t.name);\n\t}\n\n\tgetAllTools(): ToolInfo[] {\n\t\treturn Array.from(this._toolDefinitions.values()).map(({ definition, sourceInfo }) => ({\n\t\t\tname: definition.name,\n\t\t\tdescription: definition.description,\n\t\t\tparameters: definition.parameters,\n\t\t\tsourceInfo,\n\t\t}));\n\t}\n\n\tgetToolDefinition(name: string): ToolDefinition | undefined {\n\t\treturn this._toolDefinitions.get(name)?.definition;\n\t}\n\n\tsetActiveToolsByName(toolNames: string[]): void {\n\t\tconst tools: AgentTool[] = [];\n\t\tconst validToolNames: string[] = [];\n\t\tconst seenToolNames = new Set<string>();\n\t\tfor (const name of toolNames) {\n\t\t\tif (seenToolNames.has(name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst tool = this._toolRegistry.get(name);\n\t\t\tif (tool) {\n\t\t\t\tseenToolNames.add(name);\n\t\t\t\ttools.push(tool);\n\t\t\t\tvalidToolNames.push(name);\n\t\t\t}\n\t\t}\n\t\tthis.agent.state.tools = tools;\n\n\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(validToolNames);\n\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t}\n\n\tget isCompacting(): boolean {\n\t\treturn (\n\t\t\tthis._autoCompactionAbortController !== undefined ||\n\t\t\tthis._compactionAbortController !== undefined ||\n\t\t\tthis._branchSummaryAbortController !== undefined\n\t\t);\n\t}\n\n\t/** Active working context; use captured history readers for the complete source. */\n\tget messages(): AgentMessage[] {\n\t\treturn this.agent.state.messages;\n\t}\n\n\tasync buildSessionContext(): Promise<SessionContext> {\n\t\tif (!this.sessionManager.isPersisted()) {\n\t\t\tconst context = this.sessionManager.buildSessionContext();\n\t\t\tfor (const message of context.messages) this._applyLateIpythonSentAgentMessages(message);\n\t\t\tthis._mergeUnpersistedOutcomes(context.messages);\n\t\t\treturn context;\n\t\t}\n\t\tconst limits = this.settingsManager.getCanonicalContextLimits();\n\t\tconst outcomes = structuredClone(this._unpersistedOutcomes);\n\t\tconst { context } = await readSessionBootstrap(this.sessionManager, limits, {\n\t\t\tinitialContextMode: this._initialContextMode,\n\t\t\tpurpose: \"read\",\n\t\t});\n\t\tthis._mergeUnpersistedOutcomes(context.messages, outcomes);\n\t\tif (context.messages.length > limits.maxMessages) throw new Error(\"Canonical context message budget exceeded\");\n\t\treturn context;\n\t}\n\n\tprivate _mergeUnpersistedOutcomes(\n\t\tmessages: AgentMessage[],\n\t\toutcomes: readonly CustomMessage[] = this._unpersistedOutcomes,\n\t): void {\n\t\tfor (const outcome of outcomes) {\n\t\t\tlet insertAt = messages.length;\n\t\t\twhile (insertAt > 0 && messages[insertAt - 1]!.timestamp > outcome.timestamp) {\n\t\t\t\tinsertAt -= 1;\n\t\t\t}\n\t\t\tmessages.splice(insertAt, 0, outcome);\n\t\t}\n\t}\n\n\tget steeringMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.agent.steeringMode;\n\t}\n\n\tget followUpMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.agent.followUpMode;\n\t}\n\n\tget sessionFile(): string | undefined {\n\t\treturn this.sessionManager.getSessionFile();\n\t}\n\n\tget sessionId(): string {\n\t\treturn this.sessionManager.getSessionId();\n\t}\n\n\tget rlmDepth(): number {\n\t\treturn this._rlmDepth;\n\t}\n\n\tget semanticEdges(): SemanticEdgeRecorder {\n\t\treturn this._semanticEdges;\n\t}\n\n\tget rlmMaxDepth(): number {\n\t\treturn this._rlmMaxDepth;\n\t}\n\n\tget sessionName(): string | undefined {\n\t\treturn this.sessionManager.getSessionName();\n\t}\n\n\tget goalState(): GoalState {\n\t\treturn { ...this._goalWithCurrentWallClock() };\n\t}\n\n\tgetAutonomousStatus(): AgentAutonomousStatus {\n\t\treturn autonomousStatus(this._autonomousState);\n\t}\n\n\trecordHostAutonomousContinuation(): void {\n\t\taddAutonomousContinuation(this._autonomousState);\n\t}\n\n\tasync refreshAutonomousGates(): Promise<void> {\n\t\tawait refreshAutonomousQualityGates(this._autonomousState, {\n\t\t\tcwd: this._cwd,\n\t\t});\n\t}\n\n\tprivate async _runWithAutonomousContinuationSuppressed<T>(fn: () => Promise<T>): Promise<T> {\n\t\tthis._autonomousContinuationSuppressionDepth++;\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} finally {\n\t\t\tthis._autonomousContinuationSuppressionDepth--;\n\t\t}\n\t}\n\n\tprivate _markAutonomousContinuationSuppressed(message: AgentMessage): void {\n\t\tthis._autonomousContinuationSuppressedMessages.add(message);\n\t}\n\n\tget scopedModels(): ReadonlyArray<{\n\t\tmodel: Model<any>;\n\t\tthinkingLevel?: ThinkingLevel;\n\t}> {\n\t\treturn this._scopedModels;\n\t}\n\n\tsetScopedModels(scopedModels: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>): void {\n\t\tthis._scopedModels = scopedModels;\n\t}\n\n\tget promptTemplates(): ReadonlyArray<PromptTemplate> {\n\t\treturn this._resourceLoader.getPrompts().prompts;\n\t}\n\n\tprivate _normalizePromptSnippet(text: string | undefined): string | undefined {\n\t\tif (!text) return undefined;\n\t\tconst oneLine = text\n\t\t\t.replace(/[\\r\\n]+/g, \" \")\n\t\t\t.replace(/\\s+/g, \" \")\n\t\t\t.trim();\n\t\treturn oneLine.length > 0 ? oneLine : undefined;\n\t}\n\n\tprivate _normalizePromptGuidelines(guidelines: string[] | undefined): string[] {\n\t\tif (!guidelines || guidelines.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst unique = new Set<string>();\n\t\tfor (const guideline of guidelines) {\n\t\t\tconst normalized = guideline.trim();\n\t\t\tif (normalized.length > 0) {\n\t\t\t\tunique.add(normalized);\n\t\t\t}\n\t\t}\n\t\treturn Array.from(unique);\n\t}\n\n\tprivate _rebuildSystemPrompt(\n\t\ttoolNames: string[],\n\t\tnativeEpoch = this.sessionManager.isPersisted() && this._contextEpochsEnabled,\n\t\toperation = this._baseSystemPromptOptions?.errorFixSelection?.operation,\n\t): string {\n\t\tconst validToolNames = toolNames.filter((name) => this._toolRegistry.has(name));\n\t\tconst toolSnippets: Record<string, string> = {};\n\t\tconst promptGuidelines: string[] = [];\n\t\tfor (const name of validToolNames) {\n\t\t\tconst snippet = this._toolPromptSnippets.get(name);\n\t\t\tif (snippet) {\n\t\t\t\ttoolSnippets[name] = snippet;\n\t\t\t}\n\n\t\t\tconst toolGuidelines = this._toolPromptGuidelines.get(name);\n\t\t\tif (toolGuidelines) {\n\t\t\t\tpromptGuidelines.push(...toolGuidelines);\n\t\t\t}\n\t\t}\n\n\t\tconst loaderSystemPrompt = this._resourceLoader.getSystemPrompt();\n\t\tconst loaderAppendSystemPrompt = this._resourceLoader.getAppendSystemPrompt();\n\t\tconst appendSystemPrompt =\n\t\t\tloaderAppendSystemPrompt.length > 0 ? loaderAppendSystemPrompt.join(\"\\n\\n\") : undefined;\n\t\tconst loadedSkills = this._modelVisibleSkills();\n\t\tconst loadedContextFiles = this._resourceLoader.getAgentsFiles().agentsFiles;\n\n\t\tthis._baseSystemPromptOptions = {\n\t\t\tcwd: this._cwd,\n\t\t\tskills: loadedSkills,\n\t\t\tnativeSkillSelection: nativeEpoch ? (this._nativeRecoveryEnabled() ? \"enabled\" : \"unavailable\") : undefined,\n\t\t\tcontextFiles: loadedContextFiles,\n\t\t\tcustomPrompt: loaderSystemPrompt,\n\t\t\tappendSystemPrompt,\n\t\t\tmessagesPath: this.sessionManager.getSessionFile(),\n\t\t\tselectedTools: validToolNames,\n\t\t\ttoolSnippets,\n\t\t\tpromptGuidelines,\n\t\t\tallowRecursion: this._rlmDepth < this._rlmMaxDepth,\n\t\t\trlmDepth: this._rlmDepth,\n\t\t\trlmParentAgent: this._rlmParentAgent,\n\t\t\tharnessState: this._loadMergedHarnessState(),\n\t\t\tharnessSection: \"instructions\",\n\t\t\terrorFixSelection: {\n\t\t\t\tenabled: this.settingsManager.getLearningEnabled(),\n\t\t\t\ttools: validToolNames,\n\t\t\t\toperation,\n\t\t\t\tgoal: this._goalState.objective,\n\t\t\t\tenvironment: { cwd: this._cwd, platform: process.platform },\n\t\t\t\tcountTokens: conservativeTextTokenCost,\n\t\t\t},\n\t\t\tgenericMcpServers: this._mcpManager?.getEnabledPersistentGenericServers(),\n\t\t};\n\t\treturn buildSystemPrompt(this._baseSystemPromptOptions);\n\t}\n\n\t/** Read only snapshot candidates in the active literal tail and accepted epoch recipes. */\n\tprivate async _readHarnessSnapshot(view: SessionHistoryReadView): Promise<string | undefined> {\n\t\tconst { maxMessages, maxSourceBytes } = this.settingsManager.getCanonicalContextLimits();\n\t\tconst refs: ContextRef[] = [];\n\t\tlet summary: ContextRef | null = null;\n\t\tlet cursor: ContextManifestCursor | undefined;\n\t\tlet count = 0;\n\t\tlet bytes = 0;\n\t\tdo {\n\t\t\tconst page = await view.contextManifest({ cursor, limit: 128 });\n\t\t\tif (page.selection !== \"known\") throw new Error(`Harness snapshot context selection is ${page.selection}`);\n\t\t\tsummary = page.summaryRef;\n\t\t\tcount += page.refs.length;\n\t\t\tif (count + (summary ? 1 : 0) > maxMessages)\n\t\t\t\tthrow new Error(\"Harness snapshot context message budget exceeded\");\n\t\t\trefs.push(...page.refs.filter((ref) => ref.kind === \"custom_message\"));\n\t\t\tcursor = page.nextCursor ?? undefined;\n\t\t} while (cursor);\n\t\tconst read = async (ref: ContextRef, source = view): Promise<SessionEntry> => {\n\t\t\tbytes += ref.locator.length;\n\t\t\tif (bytes > maxSourceBytes) throw new Error(\"Harness snapshot source byte budget exceeded\");\n\t\t\tconst metadata = await source.get(ref.entryId);\n\t\t\tif (!metadata || metadata.revision !== ref.revision) throw new Error(\"Harness snapshot source is unavailable\");\n\t\t\tconst hydrated = await hydrateCapturedHistoryEntry(metadata, ref.locator.length, source.readPayload);\n\t\t\tif (!hydrated) throw new Error(\"Harness snapshot payload is unavailable\");\n\t\t\treturn hydrated.entry;\n\t\t};\n\t\tconst content = (entry: SessionEntry) =>\n\t\t\tentry.type === \"custom_message\" &&\n\t\t\tentry.customType === HARNESS_SNAPSHOT_CUSTOM_TYPE &&\n\t\t\ttypeof entry.content === \"string\"\n\t\t\t\t? entry.content\n\t\t\t\t: undefined;\n\t\tfor (const ref of refs.reverse()) {\n\t\t\tconst snapshot = content(await read(ref));\n\t\t\tif (snapshot !== undefined) return snapshot;\n\t\t}\n\t\tif (!summary) return;\n\t\tconst entry = await read(summary);\n\t\tif (\n\t\t\tentry.type !== \"compaction\" ||\n\t\t\tsummary.qualification !== \"native-context-epoch\" ||\n\t\t\tsummary.retention === \"retained-import\"\n\t\t)\n\t\t\treturn;\n\t\tconst checkpoint = readContextEpoch(entry.details, maxSourceBytes);\n\t\tif (!checkpoint) return;\n\t\tif (count + checkpoint.views.length > maxMessages)\n\t\t\tthrow new Error(\"Harness snapshot context message budget exceeded\");\n\t\tfor (const pinned of [...checkpoint.views].reverse()) {\n\t\t\tif (pinned.ref.kind !== \"custom_message\") continue;\n\t\t\tif (!view.atSnapshot) throw new Error(\"Harness snapshot epoch requires its captured source\");\n\t\t\tconst snapshot = content(await read(pinned.ref, await view.atSnapshot(pinned.source)));\n\t\t\tif (snapshot !== undefined) return snapshot;\n\t\t}\n\t}\n\n\t/** Persist mutable advice before the request owner captures its source and epoch ACK boundary. */\n\tprivate async _appendHarnessSnapshotIfChanged(): Promise<() => void> {\n\t\tconst manager = this.sessionManager;\n\t\tlet leafId = manager.getLeafId();\n\t\tconst sourceIsCurrent = manager.captureCompactionSourceOwner();\n\t\tconst assertCurrent = () => {\n\t\t\tif (this._disposed || this.sessionManager !== manager || !sourceIsCurrent() || manager.getLeafId() !== leafId)\n\t\t\t\tthrow new Error(\"Harness snapshot source changed before request ownership\");\n\t\t};\n\t\tlet previous: CustomMessage[\"content\"] | undefined;\n\t\tif (manager.isPersisted()) {\n\t\t\tprevious = await manager.readBranchHistory((view) => this._readHarnessSnapshot(view.branchContext));\n\t\t} else {\n\t\t\tconst snapshot = manager\n\t\t\t\t.buildSessionContext()\n\t\t\t\t.messages.reverse()\n\t\t\t\t.find((message) => message.role === \"custom\" && message.customType === HARNESS_SNAPSHOT_CUSTOM_TYPE);\n\t\t\tif (snapshot?.role === \"custom\") previous = snapshot.content;\n\t\t}\n\t\tassertCurrent();\n\t\tconst options = this._baseSystemPromptOptions;\n\t\tconst tools = options.selectedTools ?? [];\n\t\tconst hasIpython = tools.includes(\"ipython\");\n\t\tconst content = formatHarnessStateForPrompt(this._loadMergedHarnessState(), {\n\t\t\tsection: \"entries\",\n\t\t\tincludeIpythonExamples: hasIpython,\n\t\t\tincludeShellExamples: tools.includes(\"bash\"),\n\t\t\terrorFixSelection: options.errorFixSelection\n\t\t\t\t? { ...options.errorFixSelection, enabled: this.settingsManager.getLearningEnabled() }\n\t\t\t\t: undefined,\n\t\t});\n\t\tif (previous === content) return assertCurrent;\n\t\tconst entryId = await manager.appendCustomMessageEntryWithRollback(HARNESS_SNAPSHOT_CUSTOM_TYPE, content, false);\n\t\tif (this._disposed || this.sessionManager !== manager || !sourceIsCurrent() || manager.getLeafId() !== entryId)\n\t\t\tthrow new Error(\"Harness snapshot source changed during append\");\n\t\tif (!manager.isPersisted())\n\t\t\tthis.agent.state.messages.push({\n\t\t\t\trole: \"custom\",\n\t\t\t\tcustomType: HARNESS_SNAPSHOT_CUSTOM_TYPE,\n\t\t\t\tcontent,\n\t\t\t\tdisplay: false,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t});\n\t\tleafId = entryId;\n\t\treturn assertCurrent;\n\t}\n\n\tprivate _refreshExtensionSystemPrompt(extensionPrompt: string, baseSnapshot: string): string {\n\t\tif (this._baseSystemPrompt === baseSnapshot) {\n\t\t\treturn extensionPrompt;\n\t\t}\n\t\tif (!extensionPrompt.includes(baseSnapshot)) {\n\t\t\treturn extensionPrompt;\n\t\t}\n\t\treturn extensionPrompt.replace(baseSnapshot, () => this._baseSystemPrompt);\n\t}\n\n\tprivate _finishSubmissionNormalization(\n\t\ttext: string,\n\t\timages: ImageContent[] | undefined,\n\t\tpolicy: SubmissionNormalizationPolicy,\n\t\tskillOwner?: NativeSkillSelectionOwner,\n\t): NormalizedSubmission | Promise<NormalizedSubmission> {\n\t\tconst finish = (expanded: string | SkillCommandExpansion): NormalizedSubmission => {\n\t\t\tconst value = typeof expanded === \"string\" ? { text: expanded } : expanded;\n\t\t\treturn {\n\t\t\t\t...value,\n\t\t\t\tkind: \"prompt\",\n\t\t\t\timages,\n\t\t\t\ttext: policy.expandPromptTemplates\n\t\t\t\t\t? expandPromptTemplate(value.text, [...this.promptTemplates])\n\t\t\t\t\t: value.text,\n\t\t\t};\n\t\t};\n\t\tconst expanded = policy.expandSkills ? this._expandSkillCommand(text, skillOwner) : text;\n\t\treturn expanded instanceof Promise ? expanded.then(finish) : finish(expanded);\n\t}\n\n\tprivate _normalizeSubmission(\n\t\ttext: string,\n\t\timages: ImageContent[] | undefined,\n\t\tpolicy: SubmissionNormalizationPolicy,\n\t): NormalizedSubmission | Promise<NormalizedSubmission> {\n\t\tif (policy.parseSessionCommands) {\n\t\t\tconst command = parseSessionSlashCommand(text);\n\t\t\tif (command) return { kind: \"sessionCommand\", text, images, command };\n\t\t}\n\n\t\tif (text.startsWith(\"/\")) {\n\t\t\tif (policy.extensionCommands === \"execute\") {\n\t\t\t\tconst completion = this._executeExtensionCommand(text);\n\t\t\t\tif (completion) return { kind: \"extensionCommand\", completion };\n\t\t\t} else if (policy.extensionCommands === \"reject\") {\n\t\t\t\tthis._throwIfExtensionCommand(text);\n\t\t\t}\n\t\t}\n\n\t\tconst skillOwner = policy.expandSkills ? this._captureSkillSelectionOwner() : undefined;\n\t\tif (policy.inputSource !== undefined && this._extensionRunner.hasHandlers(\"input\")) {\n\t\t\treturn this._extensionRunner.emitInput(text, images, policy.inputSource).then((result) => {\n\t\t\t\tif (result.action === \"handled\") return { kind: \"handled\" };\n\t\t\t\tif (result.action === \"transform\") {\n\t\t\t\t\treturn this._finishSubmissionNormalization(result.text, result.images ?? images, policy, skillOwner);\n\t\t\t\t}\n\t\t\t\treturn this._finishSubmissionNormalization(text, images, policy, skillOwner);\n\t\t\t});\n\t\t}\n\n\t\treturn this._finishSubmissionNormalization(text, images, policy, skillOwner);\n\t}\n\n\tprivate async _runPreTurnCompaction(): Promise<void> {\n\t\tconst lastAssistant = this._findLastAssistantMessage();\n\t\tif (lastAssistant) await this._checkCompaction(lastAssistant, false, false, undefined, true);\n\t}\n\n\tprivate async _prepareForCommit<TPrepared, TCommitted>(\n\t\tpolicy: CommitPreparationPolicy,\n\t\tsteps: CommitPreparationSteps<TPrepared, TCommitted>,\n\t): Promise<TCommitted | undefined> {\n\t\tif (\n\t\t\tpolicy.initialRefineBarrier === \"always\" ||\n\t\t\t(policy.initialRefineBarrier === \"ifInFlight\" && this._refineInFlight)\n\t\t) {\n\t\t\tawait this._waitForRefineIdle();\n\t\t}\n\t\tif (policy.flushPendingBashBeforeValidation) await this._flushPendingBashMessages();\n\t\tif (policy.validateModelAndAuth) await this._validateCanStartAgentRun();\n\t\tsteps.afterValidation?.();\n\t\tif (!policy.flushPendingBashBeforeValidation) await this._flushPendingBashMessages();\n\n\t\tif (policy.preTurnCompaction === \"beforeModelSelection\") await this._runPreTurnCompaction();\n\t\tif (policy.awaitPendingModelSelection) {\n\t\t\tconst pendingModelSelectEmit = this._pendingModelSelectEmit();\n\t\t\tif (pendingModelSelectEmit) await pendingModelSelectEmit;\n\t\t}\n\t\tif (policy.preTurnCompaction === \"afterModelSelection\") await this._runPreTurnCompaction();\n\n\t\tconst prepared = await steps.prepare();\n\t\tif (steps.shouldCommit && !steps.shouldCommit(prepared)) return undefined;\n\t\tsteps.beforeFinalRefineBarrier?.(prepared);\n\t\tlet passedFinalRefineBarrier = false;\n\t\tif (\n\t\t\tpolicy.finalRefineBarrier === \"always\" ||\n\t\t\t(policy.finalRefineBarrier === \"ifInFlight\" && this._refineInFlight)\n\t\t) {\n\t\t\tawait this._waitForRefineIdle();\n\t\t\tpassedFinalRefineBarrier = true;\n\t\t}\n\t\treturn steps.commit(prepared, passedFinalRefineBarrier);\n\t}\n\n\tprivate _applyPreparedSystemPrompt(\n\t\tpreparation: PreparedPromptPreparation | undefined,\n\t\tpreserveEmptyExtensionPrompt: boolean,\n\t): void {\n\t\tconst extensionPrompt = preparation?.result?.systemPrompt;\n\t\tconst hasExtensionPrompt = preserveEmptyExtensionPrompt\n\t\t\t? extensionPrompt !== undefined\n\t\t\t: Boolean(extensionPrompt);\n\t\tthis.agent.state.systemPrompt =\n\t\t\thasExtensionPrompt && extensionPrompt !== undefined && preparation !== undefined\n\t\t\t\t? this._refreshExtensionSystemPrompt(extensionPrompt, preparation.basePromptSnapshot)\n\t\t\t\t: this._baseSystemPrompt;\n\t}\n\n\tprivate _canStartSessionActionImmediately(): boolean {\n\t\treturn (\n\t\t\t!this.isStreaming &&\n\t\t\t!this.isCompacting &&\n\t\t\t!this.isRetrying &&\n\t\t\t!this.isBashRunning &&\n\t\t\t!this._sessionInputPumpSuspended &&\n\t\t\tthis._queuedWorkPauses.size === 0 &&\n\t\t\t!this._disposed &&\n\t\t\t!this._disposing\n\t\t);\n\t}\n\n\t/**\n\t * Send a prompt to the agent.\n\t * - Handles extension commands (registered via pi.registerCommand) immediately, even during streaming\n\t * - Expands file-based prompt templates by default\n\t * - During streaming, queues via steer() or followUp() based on streamingBehavior option\n\t * - Validates model and API key before sending (when not streaming)\n\t * @throws Error if streaming and no streamingBehavior specified\n\t * @throws Error if no model selected or no API key available (when not streaming)\n\t */\n\tasync prompt(text: string, options?: PromptOptions): Promise<void> {\n\t\treturn this._prompt(text, options);\n\t}\n\n\tasync promptUntilAccepted(text: string, options?: PromptOptions): Promise<void> {\n\t\treturn this._prompt(text, { ...options, returnAfterAccepted: true });\n\t}\n\n\tasync promptAndWait(text: string, options?: PromptOptions): Promise<void> {\n\t\tconst agentMessageId = options?.agentMessageId ?? `prompt-wait:${randomUUID()}`;\n\t\tif (this._agentMessageOutcomes.get(agentMessageId)?.completion) {\n\t\t\tthrow new Error(`Prompt completion id is already in use: ${agentMessageId}`);\n\t\t}\n\t\tconst outcome = this._agentMessageOutcome(agentMessageId);\n\t\toutcome.completion = createAgentMessageDeferred();\n\t\tconst completion = outcome.completion.promise;\n\t\tconst signal = options?.signal;\n\t\tlet cancelQueuedPrompt: (() => void) | undefined;\n\t\ttry {\n\t\t\tawait this.promptUntilAccepted(text, { ...options, agentMessageId });\n\t\t\tif (signal) {\n\t\t\t\tcancelQueuedPrompt = () => {\n\t\t\t\t\tconst error = new Error(\"Prompt was cancelled before it started.\");\n\t\t\t\t\tconst cancelled = this._cancelSessionActions(\n\t\t\t\t\t\t(action) => action.agentMessageId === agentMessageId && action.payload.kind === \"turn\",\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t\tif (cancelled.length > 0) {\n\t\t\t\t\t\tthis._settleAgentMessage(agentMessageId, \"completion\", error);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", cancelQueuedPrompt, { once: true });\n\t\t\t\tif (signal.aborted) cancelQueuedPrompt();\n\t\t\t}\n\t\t\tawait completion;\n\t\t} catch (error) {\n\t\t\tthis._settleAgentMessage(agentMessageId, \"completion\", this._asError(error));\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tif (signal && cancelQueuedPrompt) {\n\t\t\t\tsignal.removeEventListener(\"abort\", cancelQueuedPrompt);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync acceptAgentMessagePrompt(text: string, options?: PromptOptions): Promise<void> {\n\t\tconst customMessage =\n\t\t\toptions?.customMessage && isAgentSessionMessage(options.customMessage) ? options.customMessage : undefined;\n\t\tconst clearEpoch = this._agentMessageClearEpoch;\n\t\tconst admissionCommitted = () => {\n\t\t\toptions?.admissionCommitted?.();\n\t\t\tif (clearEpoch !== this._agentMessageClearEpoch) {\n\t\t\t\tthrow new Error(\"Agent message was cleared before admission\");\n\t\t\t}\n\t\t};\n\t\tif (\n\t\t\tthis._sessionInputPumpSuspended &&\n\t\t\tthis._isBusyForSessionInput(\"preflight\") &&\n\t\t\toptions?.queueIfBusy === true &&\n\t\t\toptions.streamingBehavior\n\t\t) {\n\t\t\tadmissionCommitted();\n\t\t\tconst queued = await this.queueAgentMessagePrompt(text, options.streamingBehavior, customMessage);\n\t\t\toptions.preflightResult?.(queued, queued);\n\t\t\treturn;\n\t\t}\n\t\tawait this._prompt(text, {\n\t\t\t...options,\n\t\t\tresumeIfIdle: false,\n\t\t\texpandPromptTemplates: false,\n\t\t\tskipInputHandlers: true,\n\t\t\tskipPrePromptWork: true,\n\t\t\treturnAfterAccepted: true,\n\t\t\tagentMessageId: options?.agentMessageId ?? customMessage?.details.id ?? parseAgentSessionMessagePromptId(text),\n\t\t\tcustomMessage,\n\t\t\tadmissionCommitted,\n\t\t});\n\t\tif (customMessage?.details.fromRelationship === \"parent\") this._repliedToParentSinceTask = false;\n\t}\n\n\tasync queueAgentMessagePrompt(\n\t\ttext: string,\n\t\tstreamingBehavior: \"steer\" | \"followUp\",\n\t\tcustomMessage?: AgentSessionMessage,\n\t): Promise<boolean> {\n\t\tconst agentMessageId = customMessage?.details.id ?? parseAgentSessionMessagePromptId(text);\n\t\tif (streamingBehavior === \"steer\") {\n\t\t\tawait this._queuePreparedPrompt(\"steer\", text, undefined, {\n\t\t\t\tagentMessageId,\n\t\t\t\tmessage: customMessage,\n\t\t\t});\n\t\t\tif (customMessage?.details.fromRelationship === \"parent\") this._repliedToParentSinceTask = false;\n\t\t\treturn true;\n\t\t}\n\t\tconst queued = await this._queuePreparedPrompt(\"followUp\", text, undefined, {\n\t\t\tagentMessageId,\n\t\t\tmessage: customMessage,\n\t\t});\n\t\tif (queued && customMessage?.details.fromRelationship === \"parent\") this._repliedToParentSinceTask = false;\n\t\treturn queued;\n\t}\n\n\tasync promptHeartbeat(job: AgentCronJob, options?: PromptOptions): Promise<void> {\n\t\tconst message = createHeartbeatPromptMessage(job);\n\t\tawait this._promptInjectedMessage(job.prompt, message, {\n\t\t\t...options,\n\t\t\tfollowUpQueueKey: options?.followUpQueueKey ?? `heartbeat:${job.id}`,\n\t\t\tresumeIfIdle: true,\n\t\t});\n\t}\n\n\tprivate _isRlmTerminalNotice(message: CustomMessage): boolean {\n\t\treturn (\n\t\t\tmessage.customType === RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE ||\n\t\t\tmessage.customType === RLM_CHILD_FAILURE_CUSTOM_TYPE\n\t\t);\n\t}\n\n\tprivate _assertRlmTerminalNotice(message: CustomMessage): void {\n\t\tif (!this._isRlmTerminalNotice(message)) {\n\t\t\tthrow new Error(\"Deferred terminal admission only accepts RLM child terminal notices.\");\n\t\t}\n\t}\n\n\tprivate _isRlmTerminalNoticeAction(action: QueuedSessionAction): boolean {\n\t\tif (action.payload.kind !== \"turn\") return false;\n\t\tconst message = primaryDeliveryRecord(action).message;\n\t\treturn message.role === \"custom\" && this._isRlmTerminalNotice(message);\n\t}\n\n\tprivate _hasDeferredRlmTerminalNotices(): boolean {\n\t\treturn this._pendingNextTurnMessages.some((message) => this._isRlmTerminalNotice(message));\n\t}\n\n\tprivate _enqueueRlmTerminalNoticeAction(message: CustomMessage): void {\n\t\tthis._assertRlmTerminalNotice(message);\n\t\tconst action = this._createPreparedTurnAction(\"followUp\", message.content as string, undefined, {\n\t\t\tmessage,\n\t\t\tsuppressAutonomousContinuation: true,\n\t\t\tresumeIfIdle: false,\n\t\t\tsource: \"internal\",\n\t\t\texecutionPolicy: this._turnExecutionPolicy(\"injected\"),\n\t\t\tqueueVisible: false,\n\t\t});\n\t\tthis._durableRlmTerminalNoticeActionIds.add(action.id);\n\t\ttry {\n\t\t\tconst result = this._admitSessionInput(action, { wake: false });\n\t\t\tif (!result.accepted) throw new Error(\"RLM child terminal notice was not admitted.\");\n\t\t} catch (error) {\n\t\t\tthis._durableRlmTerminalNoticeActionIds.delete(action.id);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate _flushDeferredRlmTerminalNotices(): void {\n\t\tif (\n\t\t\tthis._sessionInputAdmissionPauses.size > 0 ||\n\t\t\tthis._sessionInputPumpSuspended ||\n\t\t\tthis._queuedWorkPauses.size > 0 ||\n\t\t\tthis._disposed ||\n\t\t\tthis._disposing\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\twhile (true) {\n\t\t\tconst index = this._pendingNextTurnMessages.findIndex((message) => this._isRlmTerminalNotice(message));\n\t\t\tif (index < 0) break;\n\t\t\tconst message = this._pendingNextTurnMessages[index];\n\t\t\ttry {\n\t\t\t\tthis._enqueueRlmTerminalNoticeAction(message);\n\t\t\t} catch {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._pendingNextTurnMessages.splice(index, 1);\n\t\t}\n\t\tthis._scheduleSessionInputPump();\n\t}\n\n\tprivate async _acquireRlmTerminalNoticeRetentionFence(): Promise<{ owner: symbol; release(): void } | undefined> {\n\t\tconst disposeSignal = this._sessionActionCommitDisposeAbortController.signal;\n\t\twhile (!this._disposed && !this._disposing && !disposeSignal.aborted) {\n\t\t\tif (this._queuedWorkPauses.size > 0) {\n\t\t\t\tlet wake = () => {};\n\t\t\t\tconst pauseReleased = new Promise<void>((resolve) => {\n\t\t\t\t\twake = resolve;\n\t\t\t\t\tthis._sessionInputCheckpointWaiters.add(resolve);\n\t\t\t\t});\n\t\t\t\ttry {\n\t\t\t\t\tawait waitForPromiseOrAbort(pauseReleased, disposeSignal, \"Terminal notice retention cancelled\");\n\t\t\t\t} catch {\n\t\t\t\t\treturn undefined;\n\t\t\t\t} finally {\n\t\t\t\t\tthis._sessionInputCheckpointWaiters.delete(wake);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet fence: { owner: symbol; release(): void };\n\t\t\ttry {\n\t\t\t\tfence = await this._acquireSessionActionCommitFence(disposeSignal);\n\t\t\t} catch {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (this._queuedWorkPauses.size === 0 && !this._disposed && !this._disposing) return fence;\n\t\t\tfence.release();\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate async _deferRlmTerminalNotice(message: CustomMessage): Promise<void> {\n\t\tthis._assertRlmTerminalNotice(message);\n\t\tconst fence = await this._acquireRlmTerminalNoticeRetentionFence();\n\t\tif (!fence) return;\n\t\ttry {\n\t\t\tif (this._disposed || this._disposing) return;\n\t\t\tthis._pendingNextTurnMessages.push(cloneCustomMessage(message));\n\t\t\tthis._flushDeferredRlmTerminalNotices();\n\t\t} finally {\n\t\t\tfence.release();\n\t\t}\n\t}\n\n\tprivate _demoteRlmTerminalNoticeActions(): void {\n\t\tconst actions = this._actionStore\n\t\t\t.clearableActions()\n\t\t\t.filter((action) => this._durableRlmTerminalNoticeActionIds.has(action.id));\n\t\tif (actions.length === 0) return;\n\t\tfor (const action of actions) {\n\t\t\tif (!this._isRlmTerminalNoticeAction(action)) continue;\n\t\t\tconst message = primaryDeliveryRecord(action).message;\n\t\t\tif (message.role === \"custom\") this._pendingNextTurnMessages.push(cloneCustomMessage(message));\n\t\t}\n\t\tconst ids = new Set(actions.map((action) => action.id));\n\t\tthis._cancelSessionActions(\n\t\t\t(action) => ids.has(action.id),\n\t\t\tnew Error(\"RLM child terminal notice deferred across session input suspension.\"),\n\t\t\tactions,\n\t\t);\n\t\tfor (const id of ids) this._durableRlmTerminalNoticeActionIds.delete(id);\n\t}\n\n\tprivate async _promptInjectedMessage(\n\t\ttext: string,\n\t\tmessage: CustomMessage,\n\t\toptions?: InternalPromptOptions & { executionPolicy?: TurnExecutionPolicy },\n\t): Promise<void> {\n\t\tif (!this.isStreaming && options?.resumeIfIdle) this._resumeSessionInputAdmission();\n\t\tconst admissionEpoch = this._sessionInputPumpEpoch;\n\t\tconst admissionFence = await this._acquireDirectTurnAdmissionFence(options?.signal).catch((error: unknown) => {\n\t\t\tthrowIfPromptAdmissionCancelled(options?.signal);\n\t\t\tthrow error;\n\t\t});\n\t\tconst reportPreflight = oncePreflight(options?.preflightResult);\n\t\ttry {\n\t\t\tthrowIfPromptAdmissionCancelled(options?.signal);\n\t\t\tif (admissionEpoch !== this._sessionInputPumpEpoch) {\n\t\t\t\tthrow new Error(\"Injected session input was invalidated before admission\");\n\t\t\t}\n\t\t\toptions?.admissionCommitted?.();\n\t\t\tconst queueForStreaming = this.isStreaming;\n\t\t\tconst queueForBusy = options?.queueIfBusy === true && this._isBusyForSessionInput(\"preflight\");\n\t\t\tconst visibleQueued = queueForStreaming || queueForBusy;\n\t\t\tif (visibleQueued && !options?.streamingBehavior) {\n\t\t\t\tconst stateDescription = queueForStreaming ? \"Agent is already processing\" : \"Agent has queued work\";\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${stateDescription}. Specify streamingBehavior ('steer' or 'followUp') to queue the message.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst schedule = options?.streamingBehavior ?? \"followUp\";\n\t\t\tconst prefixMessages = visibleQueued ? this._takePendingNextTurnMessages() : undefined;\n\t\t\tconst action = this._createPreparedTurnAction(schedule, text, undefined, {\n\t\t\t\tmessage,\n\t\t\t\tprefixMessages,\n\t\t\t\tqueueKey: options?.followUpQueueKey,\n\t\t\t\tpreviewLabel: injectedMessagePreviewLabel(message),\n\t\t\t\tsuppressAutonomousContinuation: options?.suppressAutonomousContinuation,\n\t\t\t\tresumeIfIdle:\n\t\t\t\t\t!visibleQueued ||\n\t\t\t\t\toptions?.resumeIfIdle ||\n\t\t\t\t\t(options?.queueIfBusy === true && canSelectSessionAction(this._runtimeActivity())),\n\t\t\t\tsource: options?.source ?? \"internal\",\n\t\t\t\texecutionPolicy:\n\t\t\t\t\toptions?.executionPolicy ??\n\t\t\t\t\t(visibleQueued ? this._turnExecutionPolicy(\"queued\") : this._turnExecutionPolicy(\"injected\")),\n\t\t\t\tqueueVisible: visibleQueued,\n\t\t\t});\n\t\t\tconst result = this._admitSessionInput(action, {\n\t\t\t\timmediatelyEligible: !visibleQueued,\n\t\t\t});\n\t\t\tadmissionFence.release();\n\t\t\tif (!result.accepted || !result.ticket) {\n\t\t\t\tif (prefixMessages) this._pendingNextTurnMessages.unshift(...prefixMessages);\n\t\t\t\treportPreflight(false, false);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (result.disposition === \"queued\") {\n\t\t\t\treportPreflight(true, true);\n\t\t\t} else {\n\t\t\t\tvoid result.ticket.delivered.then(\n\t\t\t\t\t() => reportPreflight(true),\n\t\t\t\t\t() => reportPreflight(false),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (options?.returnAfterAccepted) {\n\t\t\t\tif (result.disposition === \"starts_when_admitted\") await result.ticket.delivered;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (visibleQueued) return;\n\t\t\tawait result.ticket.completed;\n\t\t} catch (error) {\n\t\t\treportPreflight(false);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tadmissionFence.release();\n\t\t}\n\t}\n\n\tprivate async _prompt(text: string, options?: InternalPromptOptions): Promise<void> {\n\t\tconst submitted = captureSubmittedInput(text, options);\n\t\tconst isInternalPrompt = options?.internalPrompt === true;\n\t\tconst acceptedAgentMessage = options?.skipPrePromptWork === true && options.returnAfterAccepted === true;\n\t\tconst inputSource = isInternalPrompt ? \"internal\" : (options?.source ?? \"interactive\");\n\t\tconst resumeSuspendedInput = options?.resumeIfIdle !== false;\n\t\tif (!this.isStreaming) {\n\t\t\tif (resumeSuspendedInput) this._resumeSessionInputAdmission();\n\t\t\tthis._assertSessionActionAdmissionAvailable();\n\t\t}\n\t\tconst admissionEpoch = this._sessionInputPumpEpoch;\n\t\tconst commitFence = this.isStreaming\n\t\t\t? undefined\n\t\t\t: await this._acquireDirectTurnAdmissionFence(options?.signal).catch((error: unknown) => {\n\t\t\t\t\tthrowIfPromptAdmissionCancelled(options?.signal);\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\t\tconst reportPreflight = oncePreflight(options?.preflightResult);\n\t\tconst run = async () => {\n\t\t\ttry {\n\t\t\t\tthrowIfPromptAdmissionCancelled(options?.signal);\n\t\t\t\tif (!resumeSuspendedInput && admissionEpoch !== this._sessionInputPumpEpoch) {\n\t\t\t\t\tthrow new Error(\"Session input was invalidated before admission\");\n\t\t\t\t}\n\t\t\t\toptions?.admissionCommitted?.();\n\t\t\t\tconst expandPromptTemplates = isInternalPrompt ? false : (options?.expandPromptTemplates ?? true);\n\t\t\t\tconst normalizationResult = this._normalizeSubmission(text, options?.images, {\n\t\t\t\t\tparseSessionCommands: !isInternalPrompt && !options?.skipPrePromptWork,\n\t\t\t\t\textensionCommands: expandPromptTemplates ? \"execute\" : \"ignore\",\n\t\t\t\t\tinputSource:\n\t\t\t\t\t\t!isInternalPrompt && !options?.skipInputHandlers && inputSource !== \"internal\"\n\t\t\t\t\t\t\t? inputSource\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\texpandSkills: expandPromptTemplates,\n\t\t\t\t\texpandPromptTemplates,\n\t\t\t\t});\n\t\t\t\tconst normalized = normalizationResult instanceof Promise ? await normalizationResult : normalizationResult;\n\t\t\t\t// Async input handlers ran between the admission check above and\n\t\t\t\t// admission itself; re-check so content invalidated during that\n\t\t\t\t// await (e.g. a cron job cancelled or updated) is not admitted.\n\t\t\t\tif (normalizationResult instanceof Promise) options?.admissionCommitted?.();\n\t\t\t\tif (normalized.kind === \"extensionCommand\") {\n\t\t\t\t\tcommitFence?.release();\n\t\t\t\t\treportPreflight(true);\n\t\t\t\t\tvoid normalized.completion.then(\n\t\t\t\t\t\t() => this._settleAgentMessage(options?.agentMessageId, \"completion\"),\n\t\t\t\t\t\t(error) => this._settleAgentMessage(options?.agentMessageId, \"completion\", error),\n\t\t\t\t\t);\n\t\t\t\t\tvoid normalized.completion.catch(() => undefined);\n\t\t\t\t\tif (!options?.returnAfterAccepted) await normalized.completion.catch(() => undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (normalized.kind === \"handled\") {\n\t\t\t\t\tcommitFence?.release();\n\t\t\t\t\treportPreflight(true);\n\t\t\t\t\tthis._settleAgentMessage(options?.agentMessageId, \"completion\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst pendingOwnedWork = this._actionStore.unfinishedActions().length > 0;\n\t\t\t\tconst wasRuntimeBusy = this.isStreaming || this.isCompacting || this.isRetrying || this.isBashRunning;\n\t\t\t\tconst wasBusy = wasRuntimeBusy || pendingOwnedWork;\n\t\t\t\tif (normalized.kind === \"sessionCommand\") {\n\t\t\t\t\tconst schedule = options?.streamingBehavior ?? (this.isStreaming ? \"steer\" : \"followUp\");\n\t\t\t\t\tconst action = this._createSessionCommandAction(\n\t\t\t\t\t\tnormalized.text,\n\t\t\t\t\t\tnormalized.command,\n\t\t\t\t\t\tnormalized.images,\n\t\t\t\t\t\tschedule,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tagentMessageId: options?.agentMessageId,\n\t\t\t\t\t\t\tsource: inputSource,\n\t\t\t\t\t\t\tsubmitted,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tconst result = this._admitSessionInput(action, {\n\t\t\t\t\t\timmediatelyEligible: !wasBusy && this._canStartSessionActionImmediately(),\n\t\t\t\t\t});\n\t\t\t\t\tcommitFence?.release();\n\t\t\t\t\treportPreflight(result.accepted, result.disposition === \"queued\");\n\t\t\t\t\tif (!result.accepted || !result.ticket) return;\n\t\t\t\t\tif (options?.returnAfterAccepted) {\n\t\t\t\t\t\tif (result.disposition === \"starts_when_admitted\") await result.ticket.delivered;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (result.disposition === \"queued\") return;\n\t\t\t\t\tawait this.waitForSessionInputIdle();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tnormalized.assertSkillCurrent?.();\n\t\t\t\tconst queueForStreaming = this.isStreaming;\n\t\t\t\tconst queueForBusy = options?.queueIfBusy === true && this._isBusyForSessionInput(\"preflight\");\n\t\t\t\tconst visibleQueued = queueForStreaming || queueForBusy;\n\t\t\t\tif (visibleQueued && !options?.streamingBehavior) {\n\t\t\t\t\tconst stateDescription = queueForStreaming ? \"Agent is already processing\" : \"Agent has queued work\";\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`${stateDescription}. Specify streamingBehavior ('steer' or 'followUp') to queue the message.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst schedule = options?.streamingBehavior ?? \"followUp\";\n\t\t\t\tconst prefixMessages = visibleQueued ? this._takePendingNextTurnMessages() : undefined;\n\t\t\t\tconst content = options?.content\n\t\t\t\t\t? options.content.map((block) => ({ ...block }))\n\t\t\t\t\t: this._buildPromptContent(normalized.text, normalized.images);\n\t\t\t\tconst suppliedMessage = options?.customMessage;\n\t\t\t\tconst primaryMessage = suppliedMessage\n\t\t\t\t\t? visibleQueued\n\t\t\t\t\t\t? suppliedMessage\n\t\t\t\t\t\t: cloneCustomMessage(suppliedMessage)\n\t\t\t\t\t: ({\n\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\tcontent: content.map((block) => ({ ...block })),\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t} satisfies UserMessage);\n\t\t\t\tconst action = this._createPreparedTurnAction(schedule, normalized.text, normalized.images, {\n\t\t\t\t\tselectedSkillRef: normalized.selectedSkillRef,\n\t\t\t\t\tagentMessageId: options?.agentMessageId,\n\t\t\t\t\tqueueKey: options?.followUpQueueKey,\n\t\t\t\t\tcontent,\n\t\t\t\t\tmessage: primaryMessage,\n\t\t\t\t\tprefixMessages,\n\t\t\t\t\tsuppressAutonomousContinuation: options?.suppressAutonomousContinuation,\n\t\t\t\t\tresumeIfIdle:\n\t\t\t\t\t\t!visibleQueued ||\n\t\t\t\t\t\toptions?.resumeIfIdle ||\n\t\t\t\t\t\t(options?.queueIfBusy === true && canSelectSessionAction(this._runtimeActivity())),\n\t\t\t\t\tsource: inputSource,\n\t\t\t\t\tsubmitted,\n\t\t\t\t\texecutionPolicy: visibleQueued\n\t\t\t\t\t\t? this._turnExecutionPolicy(\"queued\")\n\t\t\t\t\t\t: this._turnExecutionPolicy(\"directPrompt\", {\n\t\t\t\t\t\t\t\treturnAfterAccepted: options?.returnAfterAccepted,\n\t\t\t\t\t\t\t\tskipPrePromptWork: options?.skipPrePromptWork,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\tqueueVisible: visibleQueued,\n\t\t\t\t\tacceptedAgentMessage,\n\t\t\t\t\tacceptedBeforeCompletion: options?.returnAfterAccepted === true,\n\t\t\t\t});\n\t\t\t\tif (action.suppressAutonomousContinuation) {\n\t\t\t\t\tthis._markAutonomousContinuationSuppressed(primaryDeliveryRecord(action).message);\n\t\t\t\t}\n\t\t\t\tconst result = this._admitSessionInput(action, {\n\t\t\t\t\timmediatelyEligible: !visibleQueued && this._canStartSessionActionImmediately(),\n\t\t\t\t});\n\t\t\t\tcommitFence?.release();\n\t\t\t\tif (!result.accepted || !result.ticket) {\n\t\t\t\t\tif (prefixMessages) this._pendingNextTurnMessages.unshift(...prefixMessages);\n\t\t\t\t\treportPreflight(false, false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (result.disposition === \"queued\") {\n\t\t\t\t\treportPreflight(true, true);\n\t\t\t\t} else {\n\t\t\t\t\tvoid result.ticket.delivered.then(\n\t\t\t\t\t\t() => reportPreflight(true),\n\t\t\t\t\t\t() => reportPreflight(false),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst deferralObserver =\n\t\t\t\t\tacceptedAgentMessage &&\n\t\t\t\t\toptions?.queueIfBusy === true &&\n\t\t\t\t\t!options.streamingBehavior &&\n\t\t\t\t\tresult.disposition === \"starts_when_admitted\"\n\t\t\t\t\t\t? this._observeSessionActionDeferral(action)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (acceptedAgentMessage && !queueForStreaming && !queueForBusy && !options?.streamingBehavior) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst outcome = deferralObserver\n\t\t\t\t\t\t\t? await Promise.race([\n\t\t\t\t\t\t\t\t\tresult.ticket.delivered.then(() => \"delivered\" as const),\n\t\t\t\t\t\t\t\t\tdeferralObserver.deferred.then(() => \"deferred\" as const),\n\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t: await result.ticket.delivered.then(() => \"delivered\" as const);\n\t\t\t\t\t\tif (outcome === \"deferred\" && !options?.streamingBehavior) {\n\t\t\t\t\t\t\tconst error = new Error(\n\t\t\t\t\t\t\t\t\"Agent became busy before prompt delivery. Specify streamingBehavior ('steer' or 'followUp') to queue the message.\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tthis._rejectAgentMessage(action.agentMessageId, error);\n\t\t\t\t\t\t\tthis._cancelSessionActions((candidate) => candidate === action, error);\n\t\t\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tdeferralObserver?.stop();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (options?.returnAfterAccepted) {\n\t\t\t\t\tif (result.disposition === \"starts_when_admitted\" || (acceptedAgentMessage && !visibleQueued)) {\n\t\t\t\t\t\tawait result.ticket.delivered;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (visibleQueued) return;\n\t\t\t\tawait result.ticket.completed;\n\t\t\t\tawait this.waitForSessionInputIdle();\n\t\t\t} catch (error) {\n\t\t\t\treportPreflight(false);\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\tcommitFence?.release();\n\t\t\t}\n\t\t};\n\t\treturn commitFence ? this._sessionActionCommitContext.run(commitFence.owner, run) : run();\n\t}\n\n\tprivate _executeExtensionCommand(text: string): Promise<void> | undefined {\n\t\tconst parsed = parseSlashCommand(text);\n\t\tif (!parsed) return undefined;\n\t\tconst commandName = parsed.name;\n\t\tconst args = parsed.args;\n\n\t\tconst command = this._extensionRunner.getCommand(commandName);\n\t\tif (!command) return undefined;\n\t\tconst context = this._extensionRunner.createCommandContext();\n\t\treturn Promise.resolve()\n\t\t\t.then(() => command.handler(args, context))\n\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconst commandError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\tthis._extensionRunner.emitError({\n\t\t\t\t\textensionPath: `command:${commandName}`,\n\t\t\t\t\tevent: \"command\",\n\t\t\t\t\terror: commandError.message,\n\t\t\t\t});\n\t\t\t\tthrow commandError;\n\t\t\t});\n\t}\n\n\t/**\n\t * Expand skill commands (/skill:name args) to their full content.\n\t * Returns the expanded text, or the original text if not a skill command or skill not found.\n\t * Emits errors via extension runner and rejects if the selected file cannot be read completely.\n\t */\n\tprivate _expandSkillCommand(\n\t\ttext: string,\n\t\towner?: NativeSkillSelectionOwner,\n\t): string | Promise<string | SkillCommandExpansion> {\n\t\tif (!text.startsWith(\"/skill:\")) return text;\n\t\tconst parsed = parseSlashCommand(text);\n\t\tif (!parsed?.name.startsWith(\"skill:\")) return text;\n\t\tconst skillName = parsed.name.slice(\"skill:\".length);\n\t\tconst skill = this.resourceLoader.getSkills().skills.find((item) => item.name === skillName);\n\t\tif (!skill) return text;\n\t\tconst skillPath = skill.filePath;\n\t\tconst render = (capture: SelectedSkillCapture, ref?: string): string => {\n\t\t\tconst block = selectedSkillBlock(capture, ref);\n\t\t\treturn parsed.args ? `${block}\\n\\n${parsed.args}` : block;\n\t\t};\n\t\tconst failure = (error: unknown): never => {\n\t\t\tthis._extensionRunner.emitError({\n\t\t\t\textensionPath: skillPath,\n\t\t\t\tevent: \"skill_expansion\",\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t});\n\t\t\tthrow error;\n\t\t};\n\t\ttry {\n\t\t\tif (owner)\n\t\t\t\treturn this._selectNativeSkill(skill, owner, false)\n\t\t\t\t\t.then((selected) => {\n\t\t\t\t\t\tconst assertSkillCurrent = () => this._assertSkillSelectionOwner(owner);\n\t\t\t\t\t\tassertSkillCurrent();\n\t\t\t\t\t\treturn selected\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\ttext: render(selected.capture, selected.ref),\n\t\t\t\t\t\t\t\t\tselectedSkillRef: { ...selected.source },\n\t\t\t\t\t\t\t\t\tassertSkillCurrent,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: { text: render(captureSelectedSkill(captureSkillDescriptor(skill))), assertSkillCurrent };\n\t\t\t\t\t})\n\t\t\t\t\t.catch(failure);\n\t\t\treturn render(captureSelectedSkill(captureSkillDescriptor(skill)));\n\t\t} catch (error) {\n\t\t\treturn failure(error);\n\t\t}\n\t}\n\n\t/**\n\t * Queue a steering message while the agent is running.\n\t * Delivered after the current assistant turn finishes executing its tool calls,\n\t * before the next LLM call.\n\t * Expands skill commands and prompt templates. Errors on extension commands.\n\t * @param images Optional image attachments to include with the message\n\t * @throws Error if text is an extension command\n\t */\n\tasync steer(\n\t\ttext: string,\n\t\timages?: ImageContent[],\n\t\toptions: {\n\t\t\tqueueKey?: string;\n\t\t\tagentMessageId?: string;\n\t\t\tresumeIfIdle?: boolean;\n\t\t} = {},\n\t): Promise<void> {\n\t\tconst submitted = captureSubmittedInput(text, { images });\n\t\tconst manager = this.sessionManager;\n\t\tconst sessionId = manager.getSessionId();\n\t\tconst sessionFile = manager.getSessionFile();\n\t\tconst inputEpoch = this._sessionInputPumpEpoch;\n\t\tconst normalization = this._normalizeSubmission(text, images, {\n\t\t\tparseSessionCommands: false,\n\t\t\textensionCommands: \"reject\",\n\t\t\texpandSkills: true,\n\t\t\texpandPromptTemplates: true,\n\t\t});\n\t\tconst normalized = normalization instanceof Promise ? await normalization : normalization;\n\t\tif (\n\t\t\tnormalization instanceof Promise &&\n\t\t\t(this.sessionManager !== manager ||\n\t\t\t\tsessionId !== manager.getSessionId() ||\n\t\t\t\tsessionFile !== manager.getSessionFile() ||\n\t\t\t\tinputEpoch !== this._sessionInputPumpEpoch)\n\t\t)\n\t\t\tthrow new Error(\"Queued prompt normalization owner changed\");\n\t\tif (normalized.kind !== \"prompt\") {\n\t\t\tthrow new Error(\"Queued prompt normalization did not produce a prompt\");\n\t\t}\n\n\t\tnormalized.assertSkillCurrent?.();\n\t\tawait this._queuePreparedPrompt(\"steer\", normalized.text, normalized.images, {\n\t\t\tsubmitted,\n\t\t\tselectedSkillRef: normalized.selectedSkillRef,\n\t\t\tqueueKey: options.queueKey,\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t\tresumeIfIdle: options.resumeIfIdle,\n\t\t});\n\t}\n\n\t/**\n\t * Queue a follow-up message to be processed after the agent finishes.\n\t * Delivered only when agent has no more tool calls or steering messages.\n\t * Expands skill commands and prompt templates. Errors on extension commands.\n\t * @param images Optional image attachments to include with the message\n\t * @throws Error if text is an extension command\n\t */\n\tasync followUp(\n\t\ttext: string,\n\t\timages?: ImageContent[],\n\t\toptions: {\n\t\t\tqueueKey?: string;\n\t\t\tagentMessageId?: string;\n\t\t\tresumeIfIdle?: boolean;\n\t\t} = {},\n\t): Promise<boolean> {\n\t\tconst submitted = captureSubmittedInput(text, { images });\n\t\tconst manager = this.sessionManager;\n\t\tconst sessionId = manager.getSessionId();\n\t\tconst sessionFile = manager.getSessionFile();\n\t\tconst inputEpoch = this._sessionInputPumpEpoch;\n\t\tconst normalization = this._normalizeSubmission(text, images, {\n\t\t\tparseSessionCommands: false,\n\t\t\textensionCommands: \"reject\",\n\t\t\texpandSkills: true,\n\t\t\texpandPromptTemplates: true,\n\t\t});\n\t\tconst normalized = normalization instanceof Promise ? await normalization : normalization;\n\t\tif (\n\t\t\tnormalization instanceof Promise &&\n\t\t\t(this.sessionManager !== manager ||\n\t\t\t\tsessionId !== manager.getSessionId() ||\n\t\t\t\tsessionFile !== manager.getSessionFile() ||\n\t\t\t\tinputEpoch !== this._sessionInputPumpEpoch)\n\t\t)\n\t\t\tthrow new Error(\"Queued prompt normalization owner changed\");\n\t\tif (normalized.kind !== \"prompt\") {\n\t\t\tthrow new Error(\"Queued prompt normalization did not produce a prompt\");\n\t\t}\n\n\t\tnormalized.assertSkillCurrent?.();\n\t\treturn this._queuePreparedPrompt(\"followUp\", normalized.text, normalized.images, {\n\t\t\tsubmitted,\n\t\t\tselectedSkillRef: normalized.selectedSkillRef,\n\t\t\tqueueKey: options.queueKey,\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t\tresumeIfIdle: options.resumeIfIdle,\n\t\t});\n\t}\n\n\tasync restoreSessionActions(snapshot: SessionActionRecoverySnapshot): Promise<number> {\n\t\tif (\n\t\t\t(snapshot.formatVersion !== SESSION_ACTION_RECOVERY_FORMAT_VERSION &&\n\t\t\t\tsnapshot.formatVersion !== SESSION_ACTION_SKILL_RECOVERY_FORMAT_VERSION) ||\n\t\t\t(snapshot.formatVersion === SESSION_ACTION_RECOVERY_FORMAT_VERSION &&\n\t\t\t\tsnapshot.actions.some((action) => action.payload.kind === \"turn\" && action.payload.selectedSkillRef))\n\t\t) {\n\t\t\tthrow new Error(`Unsupported session action recovery format version: ${snapshot.formatVersion}`);\n\t\t}\n\t\tconst actionIds = new Set(this._actionStore.ownedActions().map((action) => action.id));\n\t\tconst actions = snapshot.actions.map((recovered): QueuedSessionAction => {\n\t\t\tif (actionIds.has(recovered.id)) throw new Error(`Duplicate session action id: ${recovered.id}`);\n\t\t\tactionIds.add(recovered.id);\n\t\t\tif (\n\t\t\t\trecovered.payload.kind === \"turn\" &&\n\t\t\t\trecovered.payload.records.some((record) => record.ownerActionId !== recovered.id)\n\t\t\t) {\n\t\t\t\tthrow new Error(`Session action ${recovered.id} has invalid delivery correlation`);\n\t\t\t}\n\t\t\tconst payload: PreparedTurnPayload | PreparedCommandPayload =\n\t\t\t\trecovered.payload.kind === \"turn\"\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tkind: \"turn\",\n\t\t\t\t\t\t\ttext: recovered.payload.text,\n\t\t\t\t\t\t\t...(recovered.payload.selectedSkillRef\n\t\t\t\t\t\t\t\t? { selectedSkillRef: { ...recovered.payload.selectedSkillRef } }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(recovered.payload.submitted\n\t\t\t\t\t\t\t\t? { submitted: structuredClone(recovered.payload.submitted) }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(recovered.payload.preview ? { preview: recovered.payload.preview } : {}),\n\t\t\t\t\t\t\trecords: recovered.payload.records.map((record) => ({\n\t\t\t\t\t\t\t\tid: record.id,\n\t\t\t\t\t\t\t\trole: record.role,\n\t\t\t\t\t\t\t\tmessage: cloneQueuedAgentMessage(record.message),\n\t\t\t\t\t\t\t\tstarted: false,\n\t\t\t\t\t\t\t\tdurable: false,\n\t\t\t\t\t\t\t\townerActionId: record.ownerActionId,\n\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t...(recovered.payload.images\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\timages: recovered.payload.images.map((image) => ({\n\t\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(recovered.payload.content\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tcontent: recovered.payload.content.map((block) => ({\n\t\t\t\t\t\t\t\t\t\t\t...block,\n\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(recovered.payload.customMessage\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tcustomMessage: cloneCustomMessage(recovered.payload.customMessage),\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\texecutionPolicy: {\n\t\t\t\t\t\t\t\t...recovered.payload.executionPolicy,\n\t\t\t\t\t\t\t\tpreparation: {\n\t\t\t\t\t\t\t\t\t...recovered.payload.executionPolicy.preparation,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tqueueVisible: recovered.payload.queueVisible,\n\t\t\t\t\t\t\tacceptedAgentMessage: recovered.payload.acceptedAgentMessage,\n\t\t\t\t\t\t\tacceptedBeforeCompletion: recovered.payload.acceptedBeforeCompletion,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tkind: \"session_command\",\n\t\t\t\t\t\t\ttext: recovered.payload.text,\n\t\t\t\t\t\t\t...(recovered.payload.submitted\n\t\t\t\t\t\t\t\t? { submitted: structuredClone(recovered.payload.submitted) }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\tcommand: { ...recovered.payload.command },\n\t\t\t\t\t\t\t...(recovered.payload.images\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\timages: recovered.payload.images.map((image) => ({\n\t\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t};\n\t\t\treturn {\n\t\t\t\tid: recovered.id,\n\t\t\t\tsource: recovered.source,\n\t\t\t\tdelivery: recovered.delivery,\n\t\t\t\twake: recovered.wake,\n\t\t\t\tpayload,\n\t\t\t\tlifecycle: { state: \"queued\" },\n\t\t\t\t...(recovered.queueKey ? { queueKey: recovered.queueKey } : {}),\n\t\t\t\t...(recovered.agentMessageId ? { agentMessageId: recovered.agentMessageId } : {}),\n\t\t\t\t...(recovered.suppressAutonomousContinuation ? { suppressAutonomousContinuation: true } : {}),\n\t\t\t};\n\t\t});\n\t\tfor (const action of actions) {\n\t\t\tconst durableTerminalNotice = this._isRlmTerminalNoticeAction(action);\n\t\t\tif (durableTerminalNotice) this._durableRlmTerminalNoticeActionIds.add(action.id);\n\t\t\ttry {\n\t\t\t\tthis._admitSessionInput(action, { restore: true });\n\t\t\t} catch (error) {\n\t\t\t\tif (durableTerminalNotice) this._durableRlmTerminalNoticeActionIds.delete(action.id);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\treturn actions.length;\n\t}\n\n\tprivate _restoreSessionCommand(\n\t\ttext: string,\n\t\tcustomMessage: CustomMessage | undefined,\n\t\timages: ImageContent[] | undefined,\n\t\tschedule: SessionInputSchedule,\n\t\tagentMessageId: string | undefined,\n\t): boolean | undefined {\n\t\tif (!isSessionSlashCommandMessage(customMessage) || text !== customMessage.details.command.text) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this._admitSessionInput(\n\t\t\tthis._createSessionCommandAction(text, customMessage.details.command, images, schedule, {\n\t\t\t\tagentMessageId,\n\t\t\t\tsource: \"internal\",\n\t\t\t}),\n\t\t\t{ restore: true },\n\t\t).accepted;\n\t}\n\n\tprivate _restorePromptInput(schedule: SessionInputSchedule, snapshot: RestoredPromptInput): Promise<boolean> {\n\t\treturn this._queuePreparedPrompt(schedule, snapshot.text, snapshot.images, {\n\t\t\tqueueKey: snapshot.queueKey,\n\t\t\tagentMessageId: snapshot.agentMessageId,\n\t\t\tcontent: snapshot.content,\n\t\t\tmessage: snapshot.customMessage,\n\t\t\tprefixMessages: snapshot.prefixMessages,\n\t\t\tsource: \"internal\",\n\t\t});\n\t}\n\n\tasync restoreSteeringMessage(\n\t\ttext: string,\n\t\timages?: ImageContent[],\n\t\toptions: {\n\t\t\tqueueKey?: string;\n\t\t\tagentMessageId?: string;\n\t\t\tcontent?: (TextContent | ImageContent)[];\n\t\t\tcustomMessage?: CustomMessage;\n\t\t\tprefixMessages?: CustomMessage[];\n\t\t} = {},\n\t): Promise<void> {\n\t\tif (\n\t\t\tthis._restoreSessionCommand(text, options.customMessage, images, \"steer\", options.agentMessageId) !== undefined\n\t\t)\n\t\t\treturn;\n\n\t\tawait this._restorePromptInput(\"steer\", {\n\t\t\ttext,\n\t\t\timages,\n\t\t\tqueueKey: options.queueKey,\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t\tcontent: options.content,\n\t\t\tcustomMessage: options.customMessage,\n\t\t\tprefixMessages: options.prefixMessages,\n\t\t});\n\t}\n\n\tasync restoreFollowUpMessage(\n\t\ttext: string,\n\t\timages?: ImageContent[],\n\t\toptions: {\n\t\t\tqueueKey?: string;\n\t\t\tagentMessageId?: string;\n\t\t\tcontent?: (TextContent | ImageContent)[];\n\t\t\tcustomMessage?: CustomMessage;\n\t\t\tprefixMessages?: CustomMessage[];\n\t\t} = {},\n\t): Promise<boolean> {\n\t\tconst restoredCommand = this._restoreSessionCommand(\n\t\t\ttext,\n\t\t\toptions.customMessage,\n\t\t\timages,\n\t\t\t\"followUp\",\n\t\t\toptions.agentMessageId,\n\t\t);\n\t\tif (restoredCommand !== undefined) return restoredCommand;\n\n\t\treturn this._restorePromptInput(\"followUp\", {\n\t\t\ttext,\n\t\t\timages,\n\t\t\tqueueKey: options.queueKey,\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t\tcontent: options.content,\n\t\t\tcustomMessage: options.customMessage,\n\t\t\tprefixMessages: options.prefixMessages,\n\t\t});\n\t}\n\n\tprivate _buildPromptContent(text: string, images?: ImageContent[]): (TextContent | ImageContent)[] {\n\t\tconst content: (TextContent | ImageContent)[] = [];\n\t\tcontent.push({ type: \"text\", text });\n\t\tif (images) content.push(...images);\n\t\treturn content;\n\t}\n\n\tprivate _takePendingNextTurnMessages(): CustomMessage[] {\n\t\tconst messages = this._pendingNextTurnMessages;\n\t\tthis._pendingNextTurnMessages = [];\n\t\treturn messages;\n\t}\n\n\tprivate _deliveryPolicy(schedule: SessionInputSchedule): DeliveryPolicy {\n\t\treturn schedule === \"steer\" ? \"next_turn_boundary\" : \"when_run_idle\";\n\t}\n\n\tprivate _createDeliveryRecord(\n\t\tactionId: string,\n\t\trole: DeliveryRecord[\"role\"],\n\t\tmessage: QueuedAgentMessage,\n\t): DeliveryRecord {\n\t\treturn {\n\t\t\tid: randomUUID(),\n\t\t\trole,\n\t\t\tmessage,\n\t\t\tstarted: false,\n\t\t\tdurable: false,\n\t\t\townerActionId: actionId,\n\t\t};\n\t}\n\n\tprivate _turnExecutionPolicy(\n\t\tkind: \"queued\" | \"directPrompt\" | \"injected\" | \"customTrigger\",\n\t\toptions: {\n\t\t\treturnAfterAccepted?: boolean;\n\t\t\tskipPrePromptWork?: boolean;\n\t\t} = {},\n\t): TurnExecutionPolicy {\n\t\tif (kind === \"queued\") {\n\t\t\treturn {\n\t\t\t\tpreparation: {\n\t\t\t\t\tinitialRefineBarrier: \"skip\",\n\t\t\t\t\tflushPendingBashBeforeValidation: false,\n\t\t\t\t\tvalidateModelAndAuth: true,\n\t\t\t\t\tawaitPendingModelSelection: true,\n\t\t\t\t\tpreTurnCompaction: \"beforeModelSelection\",\n\t\t\t\t\tfinalRefineBarrier: \"always\",\n\t\t\t\t},\n\t\t\t\trunBeforeAgentStart: true,\n\t\t\t\tnextTurnContextTiming: \"commit\",\n\t\t\t\tpreserveEmptyExtensionPrompt: true,\n\t\t\t\tcompletionIncludesRetryChain: true,\n\t\t\t};\n\t\t}\n\t\tif (kind === \"directPrompt\") {\n\t\t\treturn {\n\t\t\t\tpreparation: {\n\t\t\t\t\tinitialRefineBarrier: options.returnAfterAccepted ? \"skip\" : \"always\",\n\t\t\t\t\tflushPendingBashBeforeValidation: true,\n\t\t\t\t\tvalidateModelAndAuth: true,\n\t\t\t\t\tawaitPendingModelSelection: true,\n\t\t\t\t\tpreTurnCompaction: options.skipPrePromptWork ? \"skip\" : \"afterModelSelection\",\n\t\t\t\t\tfinalRefineBarrier: \"ifInFlight\",\n\t\t\t\t},\n\t\t\t\trunBeforeAgentStart: !options.skipPrePromptWork,\n\t\t\t\tnextTurnContextTiming: \"preparation\",\n\t\t\t\tpreserveEmptyExtensionPrompt: false,\n\t\t\t\tcompletionIncludesRetryChain: true,\n\t\t\t};\n\t\t}\n\t\tif (kind === \"injected\") {\n\t\t\treturn {\n\t\t\t\tpreparation: {\n\t\t\t\t\tinitialRefineBarrier: \"always\",\n\t\t\t\t\tflushPendingBashBeforeValidation: true,\n\t\t\t\t\tvalidateModelAndAuth: true,\n\t\t\t\t\tawaitPendingModelSelection: true,\n\t\t\t\t\tpreTurnCompaction: \"beforeModelSelection\",\n\t\t\t\t\tfinalRefineBarrier: \"ifInFlight\",\n\t\t\t\t},\n\t\t\t\trunBeforeAgentStart: true,\n\t\t\t\tnextTurnContextTiming: \"preparation\",\n\t\t\t\tpreserveEmptyExtensionPrompt: true,\n\t\t\t\tcompletionIncludesRetryChain: true,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tpreparation: {\n\t\t\t\tinitialRefineBarrier: \"always\",\n\t\t\t\tflushPendingBashBeforeValidation: false,\n\t\t\t\tvalidateModelAndAuth: false,\n\t\t\t\tawaitPendingModelSelection: false,\n\t\t\t\tpreTurnCompaction: \"skip\",\n\t\t\t\tfinalRefineBarrier: \"skip\",\n\t\t\t},\n\t\t\trunBeforeAgentStart: false,\n\t\t\tnextTurnContextTiming: \"skip\",\n\t\t\tpreserveEmptyExtensionPrompt: false,\n\t\t\tcompletionIncludesRetryChain: false,\n\t\t};\n\t}\n\n\tprivate _createPreparedTurnAction(\n\t\tschedule: SessionInputSchedule,\n\t\ttext: string,\n\t\timages: ImageContent[] | undefined,\n\t\toptions: {\n\t\t\tagentMessageId?: string;\n\t\t\tqueueKey?: string;\n\t\t\tsubmitted?: NativeSubmittedInput;\n\t\t\tselectedSkillRef?: NativeSkillSourceRef;\n\t\t\tcontent?: (TextContent | ImageContent)[];\n\t\t\tmessage?: QueuedAgentMessage;\n\t\t\tprefixMessages?: CustomMessage[];\n\t\t\tpreviewLabel?: string;\n\t\t\tsuppressAutonomousContinuation?: boolean;\n\t\t\tresumeIfIdle?: boolean;\n\t\t\tsource?: InputSource | \"internal\";\n\t\t\texecutionPolicy?: TurnExecutionPolicy;\n\t\t\tqueueVisible?: boolean;\n\t\t\tacceptedAgentMessage?: boolean;\n\t\t\tacceptedBeforeCompletion?: boolean;\n\t\t},\n\t): QueuedSessionAction {\n\t\tconst id = randomUUID();\n\t\tconst content = options.content ?? this._buildPromptContent(text, images);\n\t\tconst message =\n\t\t\toptions.message ??\n\t\t\t({\n\t\t\t\trole: \"user\",\n\t\t\t\tcontent: content.map((block) => ({ ...block })),\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t} satisfies UserMessage);\n\t\tconst prefixMessages = options.prefixMessages?.map((prefix) => cloneCustomMessage(prefix)) ?? [];\n\t\tconst preview = options.previewLabel ? `${options.previewLabel}: ${text}` : undefined;\n\t\tconst payload: PreparedTurnPayload = {\n\t\t\tkind: \"turn\",\n\t\t\tsubmitted: options.submitted,\n\t\t\tselectedSkillRef: options.selectedSkillRef ? { ...options.selectedSkillRef } : undefined,\n\t\t\ttext,\n\t\t\trecords: [\n\t\t\t\t...prefixMessages.map((prefix) => this._createDeliveryRecord(id, \"prefix\", prefix)),\n\t\t\t\tthis._createDeliveryRecord(id, \"primary\", message),\n\t\t\t],\n\t\t\tpreview,\n\t\t\timages: images?.map((image) => ({ ...image })),\n\t\t\tcontent: content.map((block) => ({ ...block })),\n\t\t\tcustomMessage: options.message?.role === \"custom\" ? cloneCustomMessage(options.message) : undefined,\n\t\t\texecutionPolicy: options.executionPolicy ?? this._turnExecutionPolicy(\"queued\"),\n\t\t\tqueueVisible: options.queueVisible ?? true,\n\t\t\tacceptedAgentMessage: options.acceptedAgentMessage ?? false,\n\t\t\tacceptedBeforeCompletion: options.acceptedBeforeCompletion ?? false,\n\t\t};\n\t\treturn {\n\t\t\tid,\n\t\t\tsource: options.source ?? \"internal\",\n\t\t\tdelivery: this._deliveryPolicy(schedule),\n\t\t\twake:\n\t\t\t\toptions.resumeIfIdle === true\n\t\t\t\t\t? \"immediate\"\n\t\t\t\t\t: schedule === \"steer\"\n\t\t\t\t\t\t? \"on_lower_boundary\"\n\t\t\t\t\t\t: \"external_resume\",\n\t\t\tpayload,\n\t\t\tlifecycle: { state: \"queued\" },\n\t\t\tqueueKey: options.queueKey,\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t\tsuppressAutonomousContinuation: options.suppressAutonomousContinuation,\n\t\t};\n\t}\n\n\tprivate _createSessionCommandAction(\n\t\ttext: string,\n\t\tcommand: SessionSlashCommand,\n\t\timages: ImageContent[] | undefined,\n\t\tschedule: SessionInputSchedule,\n\t\toptions: {\n\t\t\tagentMessageId?: string;\n\t\t\tsubmitted?: NativeSubmittedInput;\n\t\t\tsource?: InputSource | \"internal\";\n\t\t} = {},\n\t): QueuedSessionAction {\n\t\treturn {\n\t\t\tid: randomUUID(),\n\t\t\tsource: options.source ?? \"internal\",\n\t\t\tdelivery: this._deliveryPolicy(schedule),\n\t\t\twake: \"immediate\",\n\t\t\tpayload: { kind: \"session_command\", submitted: options.submitted, text, command, images },\n\t\t\tlifecycle: { state: \"queued\" },\n\t\t\tagentMessageId: options.agentMessageId,\n\t\t};\n\t}\n\n\tprivate _coalescedFollowUpOwner(action: QueuedSessionAction): QueuedSessionAction | undefined {\n\t\tif (action.delivery !== \"when_run_idle\" || action.payload.kind !== \"turn\" || !action.queueKey) return undefined;\n\t\treturn this._actionStore\n\t\t\t.unfinishedActions()\n\t\t\t.find(\n\t\t\t\t(candidate) =>\n\t\t\t\t\tcandidate.queueKey === action.queueKey &&\n\t\t\t\t\t(candidate.lifecycle.state === \"queued\" ||\n\t\t\t\t\t\tcandidate.lifecycle.state === \"selected\" ||\n\t\t\t\t\t\tcandidate.lifecycle.state === \"preparing\"),\n\t\t\t);\n\t}\n\n\tprivate _assertSessionActionAdmissionAvailable(): void {\n\t\tif (this._disposed || this._disposing) {\n\t\t\tthrow new Error(\"Cannot admit a session action because the session is disposing or disposed.\");\n\t\t}\n\t\tif (this._sessionInputAdmissionPauses.size > 0) {\n\t\t\tthrow new Error(\"Cannot admit a session action while session input admission is paused.\");\n\t\t}\n\t\tif (this._sessionInputPumpSuspended) {\n\t\t\tthrow new Error(\"Cannot admit a session action while queued session input is suspended.\");\n\t\t}\n\t}\n\n\tprivate _admitSessionInput(\n\t\taction: QueuedSessionAction,\n\t\toptions: {\n\t\t\trestore?: boolean;\n\t\t\tfront?: boolean;\n\t\t\twake?: boolean;\n\t\t\timmediatelyEligible?: boolean;\n\t\t} = {},\n\t): {\n\t\taccepted: boolean;\n\t\tdisposition: \"starts_when_admitted\" | \"queued\";\n\t\tticket?: ActionTicket;\n\t} {\n\t\tif (this._disposed || this._disposing) {\n\t\t\tthrow new Error(\"Cannot admit a session action because the session is disposing or disposed.\");\n\t\t}\n\t\tif (this._sessionInputAdmissionPauses.size > 0) {\n\t\t\tthrow new Error(\"Cannot admit a session action while session input admission is paused.\");\n\t\t}\n\t\tif (\n\t\t\toptions.restore !== true &&\n\t\t\taction.payload.kind === \"turn\" &&\n\t\t\tisAgentSessionMessage(primaryDeliveryRecord(action).message)\n\t\t) {\n\t\t\tassertAgentMessageQueueCapacity(\n\t\t\t\tthis._actionStore.unfinishedActions().length,\n\t\t\t\tDEFAULT_AGENT_MESSAGE_MAX_PENDING_PER_SESSION,\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\t!options.restore &&\n\t\t\taction.payload.kind === \"session_command\" &&\n\t\t\t(action.payload.command.name === \"compact\" || action.payload.command.name === \"refine\")\n\t\t)\n\t\t\tthis._assertContextOptimizationAllowed();\n\t\tconst coalescedOwner = options.restore ? undefined : this._coalescedFollowUpOwner(action);\n\t\tif (coalescedOwner) {\n\t\t\tif (action.agentMessageId !== coalescedOwner.agentMessageId) {\n\t\t\t\tthis._rejectAgentMessage(\n\t\t\t\t\taction.agentMessageId,\n\t\t\t\t\tnew Error(\"Prompt was not queued because an equivalent follow-up is already pending.\"),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn { accepted: false, disposition: \"queued\" };\n\t\t}\n\t\tconst canStartImmediately =\n\t\t\toptions.immediatelyEligible === true &&\n\t\t\t(this._actionStore.unfinishedActions().length === 0 || options.front === true);\n\t\tif (options.front) this._actionStore.enqueueFront(action);\n\t\telse this._actionStore.enqueue(action);\n\t\tlet disposition: \"starts_when_admitted\" | \"queued\" = \"queued\";\n\t\tif (canStartImmediately && this._actionStore.selectFirst() === action) disposition = \"starts_when_admitted\";\n\t\tconst controller = this._actionStore.ticketFor(action);\n\t\tcontroller.settleAccepted({\n\t\t\tstatus: \"accepted\",\n\t\t\tactionId: action.id,\n\t\t\tdisposition,\n\t\t});\n\t\tthis._sessionInputArrivalEpoch++;\n\t\tthis._emitQueueUpdate();\n\t\tif (\n\t\t\t!options.restore &&\n\t\t\toptions.wake !== false &&\n\t\t\t(disposition === \"starts_when_admitted\" ||\n\t\t\t\t(action.delivery === \"next_turn_boundary\" && this.isStreaming) ||\n\t\t\t\taction.payload.kind === \"session_command\" ||\n\t\t\t\taction.wake === \"immediate\")\n\t\t) {\n\t\t\tif (action.payload.kind === \"turn\" && action.wake === \"immediate\") {\n\t\t\t\tthis._resumeSessionInputAdmission();\n\t\t\t}\n\t\t\tthis._scheduleSessionInputPump();\n\t\t}\n\t\treturn { accepted: true, disposition, ticket: controller.ticket };\n\t}\n\n\tprivate async _queuePreparedPrompt(\n\t\tschedule: SessionInputSchedule,\n\t\ttext: string,\n\t\timages?: ImageContent[],\n\t\toptions: {\n\t\t\tagentMessageId?: string;\n\t\t\tqueueKey?: string;\n\t\t\tsubmitted?: NativeSubmittedInput;\n\t\t\tselectedSkillRef?: NativeSkillSourceRef;\n\t\t\tcontent?: (TextContent | ImageContent)[];\n\t\t\tmessage?: QueuedAgentMessage;\n\t\t\tprefixMessages?: CustomMessage[];\n\t\t\tpreviewLabel?: string;\n\t\t\tsuppressAutonomousContinuation?: boolean;\n\t\t\tresumeIfIdle?: boolean;\n\t\t\tsource?: InputSource | \"internal\";\n\t\t} = {},\n\t): Promise<boolean> {\n\t\tconst action = this._createPreparedTurnAction(schedule, text, images, options);\n\t\tif (action.suppressAutonomousContinuation) {\n\t\t\tthis._markAutonomousContinuationSuppressed(primaryDeliveryRecord(action).message);\n\t\t}\n\t\treturn this._admitSessionInput(action).accepted;\n\t}\n\n\tprivate _runtimeActivity(): RuntimeActivity {\n\t\treturn {\n\t\t\tlowerAgentRun: this.isStreaming,\n\t\t\tcompaction: this.isCompacting,\n\t\t\tretry: this.isRetrying,\n\t\t\tbash: this.isBashRunning,\n\t\t\trefinementApply: this._refineInFlight !== undefined,\n\t\t\tbranchMutation: this._branchSummaryOperation !== undefined,\n\t\t\tschedulerPauseCount: this._queuedWorkPauses.size + (this._sessionInputPumpSuspended ? 1 : 0),\n\t\t\tdisposing: this._disposed || this._disposing,\n\t\t};\n\t}\n\n\tprivate _hasSelectableSessionInput(): boolean {\n\t\treturn (\n\t\t\tthis._actionStore.queuedActions().length > 0 ||\n\t\t\tthis._actionStore.activeActions().some((action) => action.lifecycle.state === \"selected\")\n\t\t);\n\t}\n\n\tget hasPendingSessionWork(): boolean {\n\t\treturn this._actionStore.unfinishedActions().some((action) => {\n\t\t\tconst state = action.lifecycle.state;\n\t\t\treturn (\n\t\t\t\tstate === \"queued\" ||\n\t\t\t\tstate === \"selected\" ||\n\t\t\t\tstate === \"preparing\" ||\n\t\t\t\t(state === \"committing\" && action.payload.kind === \"turn\" && !primaryDeliveryRecord(action).durable)\n\t\t\t);\n\t\t});\n\t}\n\n\tget hasPendingAdmissionWaiters(): boolean {\n\t\treturn (\n\t\t\tthis._sessionActionCommitOwner !== undefined ||\n\t\t\tthis._pendingSessionActionFenceWaiters > 0 ||\n\t\t\tthis._sessionInputCheckpointWaiters.size > 0\n\t\t);\n\t}\n\n\tprivate _scheduleSessionInputPump(): void {\n\t\tif (this._sessionInputPumpSuspended || this._queuedWorkPauses.size > 0) return;\n\t\tif (this._disposed || this._disposing || this._sessionInputPumpRequested || !this._hasSelectableSessionInput()) {\n\t\t\treturn;\n\t\t}\n\t\tthis._sessionInputPumpRequested = true;\n\t\tconst epoch = this._sessionInputPumpEpoch;\n\t\tconst pump = async () => {\n\t\t\tthis._sessionInputPumpRequested = false;\n\t\t\tawait this._pumpSessionInputs(epoch);\n\t\t};\n\t\tthis._sessionInputPump = this._sessionInputPump.then(pump, pump);\n\t\tthis._sessionInputPump.catch(() => {});\n\t}\n\n\tprivate async _pumpSessionInputs(epoch: number): Promise<void> {\n\t\tlet blocked = false;\n\t\ttry {\n\t\t\twhile (!this._disposed && !this._disposing && this._hasSelectableSessionInput()) {\n\t\t\t\tawait this.agent.waitForIdle();\n\t\t\t\tconst preselected = this._actionStore\n\t\t\t\t\t.activeActions()\n\t\t\t\t\t.find((action) => action.lifecycle.state === \"selected\");\n\t\t\t\tif (epoch !== this._sessionInputPumpEpoch) {\n\t\t\t\t\tif (preselected) {\n\t\t\t\t\t\tthis._actionStore.rollback(preselected);\n\t\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!this._hasCancelledDispatchCapture()) await this._waitForAgentEventsBeforeContext();\n\t\t\t\tif (!preselected || preselected.payload.kind === \"session_command\") await this._waitForRefineIdle();\n\t\t\t\tconst activity = this._runtimeActivity();\n\t\t\t\tconst canSelectPreselectedTurn =\n\t\t\t\t\tpreselected?.payload.kind === \"turn\" && canSelectSessionAction({ ...activity, refinementApply: false });\n\t\t\t\tif (\n\t\t\t\t\tthis._isSessionInputHandoffDeferred(epoch) ||\n\t\t\t\t\t(!canSelectPreselectedTurn && !canSelectSessionAction(activity))\n\t\t\t\t) {\n\t\t\t\t\tblocked = true;\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst first = preselected ?? this._actionStore.selectFirst();\n\t\t\t\tif (!first) return;\n\t\t\t\tif (first.payload.kind === \"session_command\") {\n\t\t\t\t\tawait this._executeSelectedSessionCommand(first, epoch);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst mode = first.delivery === \"next_turn_boundary\" ? this.steeringMode : this.followUpMode;\n\t\t\t\tconst actions: QueuedSessionAction[] = [first];\n\t\t\t\twhile (!preselected && mode === \"all\") {\n\t\t\t\t\tconst next = this._actionStore.queuedActions(first.delivery)[0];\n\t\t\t\t\tif (\n\t\t\t\t\t\t!next ||\n\t\t\t\t\t\tnext.payload.kind !== \"turn\" ||\n\t\t\t\t\t\t!turnExecutionPoliciesEqual(first.payload.executionPolicy, next.payload.executionPolicy)\n\t\t\t\t\t) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tthis._actionStore.selectFirst();\n\t\t\t\t\tactions.push(next);\n\t\t\t\t}\n\t\t\t\tif (epoch !== this._sessionInputPumpEpoch) {\n\t\t\t\t\tfor (const action of actions) this._actionStore.rollback(action);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const action of actions) transitionSessionAction(action, { state: \"preparing\" });\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\ttry {\n\t\t\t\t\tawait this._startPreparedTurnActions(actions, epoch);\n\t\t\t\t\tfor (const action of actions) {\n\t\t\t\t\t\tif (action.lifecycle.state === \"committing\") {\n\t\t\t\t\t\t\tconst primary = primaryDeliveryRecord(action);\n\t\t\t\t\t\t\tif (primary.durable) {\n\t\t\t\t\t\t\t\ttransitionSessionAction(action, {\n\t\t\t\t\t\t\t\t\tstate: \"running\",\n\t\t\t\t\t\t\t\t\texecution: \"agent_turn\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (action.lifecycle.state === \"running\") {\n\t\t\t\t\t\t\ttransitionSessionAction(action, { state: \"completed\" });\n\t\t\t\t\t\t\tthis._actionStore.ticketFor(action).settleCompleted();\n\t\t\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"completion\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst transcript = this.agent.state.messages;\n\t\t\t\t\tconst undelivered: QueuedSessionAction[] = [];\n\t\t\t\t\tfor (const action of actions) {\n\t\t\t\t\t\tif (action.payload.kind !== \"turn\" || action.lifecycle.state === \"cancelled\") continue;\n\t\t\t\t\t\taction.payload.records = action.payload.records.filter((record) => {\n\t\t\t\t\t\t\tif (record.role === \"prefix\") return !record.durable;\n\t\t\t\t\t\t\tif (record.role === \"next_turn\") return record.durable;\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (!primaryDeliveryRecord(action).durable) undelivered.push(action);\n\t\t\t\t\t}\n\t\t\t\t\tif (this._isDeferredSessionInputError(error, epoch)) {\n\t\t\t\t\t\tfor (const action of undelivered) {\n\t\t\t\t\t\t\tif (action.lifecycle.state === \"committing\") {\n\t\t\t\t\t\t\t\tthis._actionStore.rollback(action, {\n\t\t\t\t\t\t\t\t\tdispatchSettled: true,\n\t\t\t\t\t\t\t\t\ttranscript,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else if (action.lifecycle.state === \"preparing\" || action.lifecycle.state === \"selected\") {\n\t\t\t\t\t\t\t\tthis._actionStore.rollback(action);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (undelivered.length > 0) this._emitQueueUpdate();\n\t\t\t\t\t\tblocked = epoch !== this._sessionInputPumpEpoch || this._isBusyForSessionInput(\"pump\");\n\t\t\t\t\t\tif (blocked) return;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst terminalError = this._asError(error);\n\t\t\t\t\tfor (const action of actions) {\n\t\t\t\t\t\tif (action.lifecycle.state === \"cancelled\") continue;\n\t\t\t\t\t\tif (action.lifecycle.state !== \"completed\" && action.lifecycle.state !== \"failed\") {\n\t\t\t\t\t\t\ttransitionSessionAction(action, {\n\t\t\t\t\t\t\t\tstate: \"failed\",\n\t\t\t\t\t\t\t\terror: terminalError,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst ticket = this._actionStore.ticketFor(action);\n\t\t\t\t\t\tif (undelivered.includes(action)) {\n\t\t\t\t\t\t\tticket.rejectDelivered(terminalError);\n\t\t\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"delivery\", terminalError);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"completion\", terminalError);\n\t\t\t\t\t\tticket.settleCompleted(terminalError);\n\t\t\t\t\t}\n\t\t\t\t\tif (actions.some((action) => action.payload.kind !== \"turn\" || action.payload.queueVisible)) {\n\t\t\t\t\t\tthis._surfaceSessionInputError(error);\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\tfor (const action of actions) {\n\t\t\t\t\t\tconst retainedCancelledDispatch =\n\t\t\t\t\t\t\taction.lifecycle.state === \"cancelled\" &&\n\t\t\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\t\t\taction.payload.captureRunMessages !== undefined;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!retainedCancelledDispatch &&\n\t\t\t\t\t\t\t(action.lifecycle.state === \"completed\" ||\n\t\t\t\t\t\t\t\taction.lifecycle.state === \"failed\" ||\n\t\t\t\t\t\t\t\taction.lifecycle.state === \"cancelled\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis._durableRlmTerminalNoticeActionIds.delete(action.id);\n\t\t\t\t\t\t\tthis._actionStore.releaseTerminal(action);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t}\n\t\t\t\tif (epoch !== this._sessionInputPumpEpoch || blocked) return;\n\t\t\t}\n\t\t} finally {\n\t\t\tif (!blocked && epoch === this._sessionInputPumpEpoch && this._hasSelectableSessionInput()) {\n\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async _executeSelectedSessionCommand(action: QueuedSessionAction, epoch: number): Promise<void> {\n\t\tif (action.payload.kind !== \"session_command\") throw new Error(\"Expected a selected session command\");\n\t\tconst input = action.payload;\n\t\tconst commitFence = await this._acquireSessionActionCommitFence();\n\t\ttry {\n\t\t\tawait this._sessionActionCommitContext.run(commitFence.owner, async () => {\n\t\t\t\tconst isCancelled = () => action.lifecycle.state === \"cancelled\";\n\t\t\t\tif (isCancelled()) return;\n\t\t\t\tawait this._waitForRefineIdle();\n\t\t\t\tif (isCancelled()) return;\n\t\t\t\tif (this._isSessionInputHandoffDeferred(epoch) || !canSelectSessionAction(this._runtimeActivity())) {\n\t\t\t\t\tthis._actionStore.rollback(action);\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttransitionSessionAction(action, {\n\t\t\t\t\tstate: \"running\",\n\t\t\t\t\texecution: \"session_command\",\n\t\t\t\t});\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\ttry {\n\t\t\t\t\tawait this._appendDurableSessionCommandMessage(input.text, input.command, false);\n\t\t\t\t\tthis._actionStore.ticketFor(action).settleDelivered({ status: \"not_applicable\" });\n\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"delivery\");\n\t\t\t\t\tawait this._executeQueuedSessionCommand(action);\n\t\t\t\t\ttransitionSessionAction(action, { state: \"completed\" });\n\t\t\t\t\tthis._actionStore.ticketFor(action).settleCompleted();\n\t\t\t\t\tthis._settleAgentMessage(action.agentMessageId, \"completion\");\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst commandError = this._asError(error);\n\t\t\t\t\ttransitionSessionAction(action, {\n\t\t\t\t\t\tstate: \"failed\",\n\t\t\t\t\t\terror: commandError,\n\t\t\t\t\t});\n\t\t\t\t\tconst ticket = this._actionStore.ticketFor(action);\n\t\t\t\t\tticket.rejectDelivered(commandError);\n\t\t\t\t\tticket.settleCompleted(commandError);\n\t\t\t\t\tthis._rejectAgentMessage(action.agentMessageId, commandError);\n\t\t\t\t} finally {\n\t\t\t\t\tthis._actionStore.releaseTerminal(action);\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t}\n\t\t\t});\n\t\t} finally {\n\t\t\tcommitFence.release();\n\t\t}\n\t}\n\n\tprivate _isBusyForSessionInput(point: \"preflight\" | \"pump\"): boolean {\n\t\tconst externalBusy = this.isCompacting || this.isRetrying || this.isBashRunning;\n\t\tif (point === \"pump\") {\n\t\t\treturn (\n\t\t\t\texternalBusy ||\n\t\t\t\tthis._disposed ||\n\t\t\t\tthis._disposing ||\n\t\t\t\tthis._sessionInputPumpSuspended ||\n\t\t\t\tthis._queuedWorkPauses.size > 0 ||\n\t\t\t\tthis._branchSummaryOperation !== undefined\n\t\t\t);\n\t\t}\n\t\treturn externalBusy || this._actionStore.unfinishedActions().length > 0;\n\t}\n\n\tprivate _isSessionInputHandoffDeferred(epoch: number): boolean {\n\t\treturn epoch !== this._sessionInputPumpEpoch || this._isBusyForSessionInput(\"pump\");\n\t}\n\n\tprivate _asError(error: unknown): Error {\n\t\treturn error instanceof Error ? error : new Error(String(error));\n\t}\n\n\tprivate _isDeferredSessionInputError(error: unknown, epoch: number): boolean {\n\t\tif (primaryCommittedCompactionError(error)) return false;\n\t\tif (error instanceof DeferredSessionInputError) return true;\n\t\tif (epoch !== this._sessionInputPumpEpoch) return true;\n\t\tif (this._isBusyForSessionInput(\"pump\")) {\n\t\t\tthis._surfaceSessionInputError(error);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate _surfaceSessionInputError(error: unknown): void {\n\t\tconst normalized = this._asError(error);\n\t\ttry {\n\t\t\tthis._extensionRunner.emitError({\n\t\t\t\textensionPath: \"<session-input>\",\n\t\t\t\tevent: \"session_input\",\n\t\t\t\terror: normalized.message,\n\t\t\t\tstack: normalized.stack,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Best-effort: a throwing error listener must not break the pump's requeue path.\n\t\t}\n\t}\n\n\tprivate async _startPreparedTurnActions(actions: QueuedSessionAction[], epoch: number): Promise<void> {\n\t\tlet nextTurnMessages: CustomMessage[] = [];\n\t\tconst activeTurns = () =>\n\t\t\tactions.filter(\n\t\t\t\t(action): action is SessionAction<PreparedTurnPayload> =>\n\t\t\t\t\taction.payload.kind === \"turn\" && action.lifecycle.state === \"preparing\",\n\t\t\t);\n\t\tconst firstTurn = activeTurns()[0];\n\t\tif (!firstTurn) return;\n\t\tconst executionPolicy = firstTurn.payload.executionPolicy;\n\t\tconst restoreNextTurnContext = () => {\n\t\t\tthis._pendingNextTurnMessages.unshift(...nextTurnMessages);\n\t\t\tnextTurnMessages = [];\n\t\t};\n\t\ttry {\n\t\t\tconst preparedTurn = await this._prepareForCommit(executionPolicy.preparation, {\n\t\t\t\tafterValidation: () => {\n\t\t\t\t\tif (this._isSessionInputHandoffDeferred(epoch)) {\n\t\t\t\t\t\tthrow new DeferredSessionInputError(\"Session input paused before preflight\");\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tprepare: async () => {\n\t\t\t\t\tif (executionPolicy.nextTurnContextTiming === \"preparation\") {\n\t\t\t\t\t\tnextTurnMessages = this._takePendingNextTurnMessages();\n\t\t\t\t\t}\n\t\t\t\t\tif (!executionPolicy.runBeforeAgentStart) return undefined;\n\t\t\t\t\twhile (activeTurns().some((action) => action.payload.prepared === undefined)) {\n\t\t\t\t\t\tif (this._isSessionInputHandoffDeferred(epoch)) {\n\t\t\t\t\t\t\tthrow new DeferredSessionInputError(\"Session input paused before preparation\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst preparationAction = activeTurns().at(-1);\n\t\t\t\t\t\tif (!preparationAction) return undefined;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.settingsManager.getLearningEnabled() ||\n\t\t\t\t\t\t\tthis._baseSystemPromptOptions.errorFixSelection?.enabled\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Capture advice for this task before extensions and provider preparation.\n\t\t\t\t\t\t\t// Tool continuations keep the same prompt until the next task boundary.\n\t\t\t\t\t\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(\n\t\t\t\t\t\t\t\tthis.getActiveToolNames(),\n\t\t\t\t\t\t\t\tthis._baseSystemPromptOptions.nativeSkillSelection !== undefined,\n\t\t\t\t\t\t\t\tpreparationAction.payload.text,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst basePromptSnapshot = this._baseSystemPrompt;\n\t\t\t\t\t\tconst result = await this._extensionRunner.emitBeforeAgentStart(\n\t\t\t\t\t\t\tpreparationAction.payload.text,\n\t\t\t\t\t\t\tpreparationAction.payload.images,\n\t\t\t\t\t\t\tbasePromptSnapshot,\n\t\t\t\t\t\t\tthis._baseSystemPromptOptions,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (activeTurns().at(-1) !== preparationAction) continue;\n\t\t\t\t\t\tconst prepared = { result, basePromptSnapshot };\n\t\t\t\t\t\tfor (const action of activeTurns()) action.payload.prepared = prepared;\n\t\t\t\t\t}\n\t\t\t\t\tif (this._isSessionInputHandoffDeferred(epoch)) {\n\t\t\t\t\t\tthrow new DeferredSessionInputError(\"Session input paused before handoff\");\n\t\t\t\t\t}\n\t\t\t\t\treturn activeTurns()[0]?.payload.prepared;\n\t\t\t\t},\n\t\t\t\tshouldCommit: () => activeTurns().length > 0,\n\t\t\t\tcommit: (prepared) => {\n\t\t\t\t\tif (this._isSessionInputHandoffDeferred(epoch)) {\n\t\t\t\t\t\tthrow new DeferredSessionInputError(\"Session input paused before handoff\");\n\t\t\t\t\t}\n\t\t\t\t\tconst turns = activeTurns();\n\t\t\t\t\tif (turns.length === 0) return undefined;\n\t\t\t\t\treturn { prepared, turns };\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (!preparedTurn) {\n\t\t\t\trestoreNextTurnContext();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst { prepared } = preparedTurn;\n\t\t\tlet { turns } = preparedTurn;\n\t\t\tconst commitFence = await this._acquireSessionActionCommitFence();\n\t\t\tlet promptPromise: Promise<void>;\n\t\t\ttry {\n\t\t\t\tpromptPromise = this._sessionActionCommitContext.run(commitFence.owner, () => {\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis._isSessionInputHandoffDeferred(epoch) ||\n\t\t\t\t\t\tthis.isStreaming ||\n\t\t\t\t\t\tturns.some((action) => action.lifecycle.state !== \"preparing\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new DeferredSessionInputError(\"Agent became active before session input handoff\");\n\t\t\t\t\t}\n\t\t\t\t\t// Deliver the pending family updates together, including arrivals during preparation.\n\t\t\t\t\t// Keep user/control actions and delivery lanes as boundaries; retain every action's ticket.\n\t\t\t\t\tif (turns.every(isFamilyAgentMessageAction)) {\n\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\tconst next = this._actionStore.queuedActions()[0];\n\t\t\t\t\t\t\tif (!next || next.delivery !== turns[0].delivery || !isFamilyAgentMessageAction(next)) break;\n\t\t\t\t\t\t\tthis._actionStore.selectFirst();\n\t\t\t\t\t\t\ttransitionSessionAction(next, { state: \"preparing\" });\n\t\t\t\t\t\t\tactions.push(next);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tturns = activeTurns();\n\t\t\t\t\t}\n\t\t\t\t\tif (executionPolicy.nextTurnContextTiming === \"commit\") {\n\t\t\t\t\t\tnextTurnMessages = this._takePendingNextTurnMessages();\n\t\t\t\t\t}\n\t\t\t\t\tconst contextRecords = nextTurnMessages.map((message) =>\n\t\t\t\t\t\tthis._createDeliveryRecord(turns[0].id, \"next_turn\", message),\n\t\t\t\t\t);\n\t\t\t\t\tconst firstPrimaryIndex = turns[0].payload.records.indexOf(primaryDeliveryRecord(turns[0]));\n\t\t\t\t\tturns[0].payload.records.splice(firstPrimaryIndex, 0, ...contextRecords);\n\t\t\t\t\tconst preparedMessages: AgentMessage[] = turns.flatMap((action) =>\n\t\t\t\t\t\taction.payload.records.map((record) => record.message),\n\t\t\t\t\t);\n\t\t\t\t\tfor (const action of turns) {\n\t\t\t\t\t\tif (action.suppressAutonomousContinuation) {\n\t\t\t\t\t\t\tthis._markAutonomousContinuationSuppressed(primaryDeliveryRecord(action).message);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (executionPolicy.runBeforeAgentStart) {\n\t\t\t\t\t\tthis._appendBeforeAgentStartMessages(preparedMessages, prepared?.result);\n\t\t\t\t\t\tthis._applyPreparedSystemPrompt(prepared, executionPolicy.preserveEmptyExtensionPrompt);\n\t\t\t\t\t} else if (executionPolicy.nextTurnContextTiming !== \"skip\") {\n\t\t\t\t\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t\t\t\t\t}\n\t\t\t\t\tconst checkpointBoundary =\n\t\t\t\t\t\tthis._postCompactionContinuationSettlement?.resume.boundary ?? this._pendingCheckpoint?.boundary;\n\t\t\t\t\tfor (const action of turns) {\n\t\t\t\t\t\ttransitionSessionAction(action, { state: \"committing\" });\n\t\t\t\t\t\tif (checkpointBoundary?.state === \"pending\") {\n\t\t\t\t\t\t\tvoid this._actionStore.ticketFor(action).ticket.delivered.then(\n\t\t\t\t\t\t\t\t(delivery) => {\n\t\t\t\t\t\t\t\t\tif (delivery.status === \"delivered\") checkpointBoundary.state = \"consumed\";\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t() => {},\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._emitQueueUpdate();\n\t\t\t\t\treturn turns.some((action) => action.suppressAutonomousContinuation)\n\t\t\t\t\t\t? this._runWithAutonomousContinuationSuppressed(() => this.agent.prompt(preparedMessages))\n\t\t\t\t\t\t: this.agent.prompt(preparedMessages);\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tcommitFence.release();\n\t\t\t}\n\t\t\tawait promptPromise;\n\t\t\tif (executionPolicy.completionIncludesRetryChain) await this.waitForRetry();\n\t\t\tif (!this._hasCancelledDispatchCapture()) await this._agentEventQueue;\n\t\t\tif (turns.some((action) => action.lifecycle.state !== \"cancelled\" && !primaryDeliveryRecord(action).durable)) {\n\t\t\t\tthrow new Error(\"Session input dispatch settled without durable delivery\");\n\t\t\t}\n\t\t\tthis._forgetConsumedPostCompactionContinuations(turns);\n\t\t} catch (error) {\n\t\t\tconst delivered = new Set(this.agent.state.messages);\n\t\t\tthis._pendingNextTurnMessages.unshift(...nextTurnMessages.filter((message) => !delivered.has(message)));\n\t\t\tfor (const action of actions) {\n\t\t\t\tif (action.payload.kind === \"turn\") {\n\t\t\t\t\taction.payload.records = action.payload.records.filter((record) => record.role !== \"next_turn\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async _executeQueuedSessionCommand(action: QueuedSessionAction): Promise<void> {\n\t\tif (action.payload.kind !== \"session_command\") throw new Error(\"Expected a session command action\");\n\t\tconst input = action.payload;\n\t\ttry {\n\t\t\tlet resultText: string | undefined;\n\t\t\tlet displayResult = true;\n\t\t\tswitch (input.command.name) {\n\t\t\t\tcase \"compact\":\n\t\t\t\t\tawait this._compactAccepted(input.command.args || undefined, {\n\t\t\t\t\t\tskipAbort: true,\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"refine\": {\n\t\t\t\t\tlet result: RefinementResult;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst options = parseRefineCommandOptions(input.command.args);\n\t\t\t\t\t\tresult = await this._refineAccepted(options, { skipAbort: true });\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t// Only a failure of the refinement itself is a refine failure; a later\n\t\t\t\t\t\t// result-row persist error must not report a completed refinement as failed.\n\t\t\t\t\t\tthis._emitRefineFailed(this._asError(error));\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t\tconst applied = result.appliedEdits.filter((edit) => edit.applied).length;\n\t\t\t\t\tresultText = `Refined continual harness state: ${applied} edit${applied === 1 ? \"\" : \"s\"} applied.`;\n\t\t\t\t\tdisplayResult = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"goal\": {\n\t\t\t\t\tconst goalOrigin: GoalOriginContext = {\n\t\t\t\t\t\twriter: this.sessionManager[bindNativeEntryWriter](),\n\t\t\t\t\t\tactor: action.source,\n\t\t\t\t\t\tactionId: action.id,\n\t\t\t\t\t\tsubmittedText: input.submitted?.text,\n\t\t\t\t\t};\n\t\t\t\t\tawait this._handleGoalSlashCommand(input.text, input.images, goalOrigin);\n\t\t\t\t\tresultText = this._goalState.objective\n\t\t\t\t\t\t? `Goal ${this._goalState.status}: ${this._goalState.objective}`\n\t\t\t\t\t\t: \"No active goal.\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"autonomous\":\n\t\t\t\t\tawait this._handleAutonomousSlashCommand(input.text);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (resultText) {\n\t\t\t\tawait this._appendDurableSessionCommandMessage(resultText, input.command, true, false, displayResult);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (error instanceof CompactionSkippedError) return;\n\t\t\tconst commandError = error instanceof Error ? error : new Error(String(error));\n\t\t\ttry {\n\t\t\t\tawait this._appendDurableSessionCommandMessage(\n\t\t\t\t\t`Command failed: ${commandError.message}`,\n\t\t\t\t\tinput.command,\n\t\t\t\t\ttrue,\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} catch {\n\t\t\t\t// The result row is also the command-correlated UI settle edge.\n\t\t\t\tconst message = createSessionSlashCommandResultMessage(`Command failed: ${commandError.message}`, {\n\t\t\t\t\tcommand: input.command,\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tseverity: \"error\",\n\t\t\t\t\terror: commandError.message,\n\t\t\t\t});\n\t\t\t\tthis._emit({ type: \"message_start\", message });\n\t\t\t\tthis._emit({ type: \"message_end\", message });\n\t\t\t}\n\t\t\tthrow commandError;\n\t\t}\n\t}\n\n\tprivate async _appendDurableSessionCommandMessage(\n\t\tcontent: string,\n\t\tcommand: SessionSlashCommand,\n\t\tisResult: boolean,\n\t\tisError = false,\n\t\tdisplay = true,\n\t): Promise<void> {\n\t\tconst message: CustomMessage = isResult\n\t\t\t? createSessionSlashCommandResultMessage(\n\t\t\t\t\tcontent,\n\t\t\t\t\t{\n\t\t\t\t\t\tcommand,\n\t\t\t\t\t\tsuccess: !isError,\n\t\t\t\t\t\tseverity: isError ? \"error\" : \"info\",\n\t\t\t\t\t\t...(isError ? { error: content.replace(/^Command failed:\\s*/, \"\") } : {}),\n\t\t\t\t\t},\n\t\t\t\t\tdisplay,\n\t\t\t\t)\n\t\t\t: createSessionSlashCommandMessage(command);\n\t\t// Persist before touching live state so a failed write cannot leave an\n\t\t// unsaved leaf that the next entry would silently parent onto.\n\t\tawait this.sessionManager.appendCustomMessageEntryWithRollback(\n\t\t\tmessage.customType,\n\t\t\tmessage.content,\n\t\t\tmessage.display,\n\t\t\tmessage.details,\n\t\t);\n\t\tthis.agent.state.messages.push(message);\n\t\tthis._emit({ type: \"message_start\", message });\n\t\tthis._emit({ type: \"message_end\", message });\n\t}\n\n\tprivate _throwIfExtensionCommand(text: string): void {\n\t\tconst commandName = parseSlashCommand(text)?.name ?? \"\";\n\t\tconst command = this._extensionRunner.getCommand(commandName);\n\n\t\tif (command) {\n\t\t\tthrow new Error(\n\t\t\t\t`Extension command \"/${commandName}\" cannot be queued. Use prompt() or execute the command when not streaming.`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Send a custom message to the session. Creates a CustomMessageEntry.\n\t *\n\t * Handles three cases:\n\t * - Streaming: queues message, processed when loop pulls from queue\n\t * - Not streaming + triggerTurn: appends to state/session, starts new turn\n\t * - Not streaming + no trigger: appends to state/session, no turn\n\t *\n\t * @param message Custom message with customType, content, display, details\n\t * @param options.triggerTurn If true and not streaming, triggers a new LLM turn\n\t * @param options.deliverAs Delivery mode: \"steer\", \"followUp\", or \"nextTurn\"\n\t */\n\tasync sendCustomMessage<T = unknown>(\n\t\tmessage: Pick<CustomMessage<T>, \"customType\" | \"content\" | \"display\" | \"details\">,\n\t\toptions?: {\n\t\t\ttriggerTurn?: boolean;\n\t\t\tdeliverAs?: \"steer\" | \"followUp\" | \"nextTurn\";\n\t\t},\n\t): Promise<void> {\n\t\tconst appMessage = {\n\t\t\trole: \"custom\" as const,\n\t\t\tcustomType: message.customType,\n\t\t\tcontent: message.content,\n\t\t\tdisplay: message.display,\n\t\t\tdetails: message.details,\n\t\t\ttimestamp: Date.now(),\n\t\t} satisfies CustomMessage<T>;\n\t\tif (options?.deliverAs === \"nextTurn\") {\n\t\t\tthis._pendingNextTurnMessages.push(appMessage);\n\t\t} else if (this.isStreaming) {\n\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\tif (options?.deliverAs === \"followUp\") {\n\t\t\t\tawait this._queuePreparedPrompt(\"followUp\", normalized.text, normalized.images, {\n\t\t\t\t\tmessage: appMessage,\n\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tawait this._queuePreparedPrompt(\"steer\", normalized.text, normalized.images, {\n\t\t\t\t\tmessage: appMessage,\n\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (options?.triggerTurn) {\n\t\t\tif (!this._sessionInputSuspendedForUpdateRestart) this._resumeSessionInputAdmission();\n\t\t\tconst admissionFence = await this._acquireDirectTurnAdmissionFence();\n\t\t\ttry {\n\t\t\t\tconst normalized = normalizeMessageContent(message.content);\n\t\t\t\tconst immediatelyEligible = this._canStartSessionActionImmediately();\n\t\t\t\tconst action = this._createPreparedTurnAction(\"followUp\", normalized.text, normalized.images, {\n\t\t\t\t\tmessage: appMessage,\n\t\t\t\t\tresumeIfIdle: true,\n\t\t\t\t\texecutionPolicy: this._turnExecutionPolicy(\"customTrigger\"),\n\t\t\t\t\tqueueVisible: false,\n\t\t\t\t});\n\t\t\t\tconst result = this._admitSessionInput(action, { immediatelyEligible });\n\t\t\t\tadmissionFence.release();\n\t\t\t\tif (!result.ticket) return;\n\t\t\t\tawait result.ticket.completed;\n\t\t\t} finally {\n\t\t\t\tadmissionFence.release();\n\t\t\t}\n\t\t} else {\n\t\t\tawait this.sessionManager.appendCustomMessageEntry(\n\t\t\t\tmessage.customType,\n\t\t\t\tmessage.content,\n\t\t\t\tmessage.display,\n\t\t\t\tmessage.details,\n\t\t\t);\n\t\t\tthis.agent.state.messages.push(appMessage);\n\t\t\tthis._emit({ type: \"message_start\", message: appMessage });\n\t\t\tthis._emit({ type: \"message_end\", message: appMessage });\n\t\t}\n\t}\n\n\t/**\n\t * Send a user message to the agent. Always triggers a turn.\n\t * When the agent is streaming, use deliverAs to specify how to queue the message.\n\t *\n\t * @param content User message content (string or content array)\n\t * @param options.deliverAs Delivery mode when streaming: \"steer\" or \"followUp\"\n\t */\n\tasync sendUserMessage(\n\t\tcontent: string | (TextContent | ImageContent)[],\n\t\toptions?: { deliverAs?: \"steer\" | \"followUp\" },\n\t): Promise<void> {\n\t\tlet text: string;\n\t\tlet images: ImageContent[] | undefined;\n\n\t\tif (typeof content === \"string\") {\n\t\t\ttext = content;\n\t\t} else {\n\t\t\tconst textParts: string[] = [];\n\t\t\timages = [];\n\t\t\tfor (const part of content) {\n\t\t\t\tif (part.type === \"text\") {\n\t\t\t\t\ttextParts.push(part.text);\n\t\t\t\t} else {\n\t\t\t\t\timages.push(part);\n\t\t\t\t}\n\t\t\t}\n\t\t\ttext = textParts.join(\"\\n\");\n\t\t\tif (images.length === 0) images = undefined;\n\t\t}\n\n\t\tawait this._prompt(text, {\n\t\t\texpandPromptTemplates: false,\n\t\t\tstreamingBehavior: options?.deliverAs,\n\t\t\timages,\n\t\t\tsource: \"extension\",\n\t\t\tresumeIfIdle: true,\n\t\t});\n\t}\n\n\tclearQueue(): { steering: string[]; followUp: string[] } {\n\t\tconst clearable = this._actionStore\n\t\t\t.clearableActions()\n\t\t\t.filter((action) => action.payload.kind === \"session_command\" || action.payload.queueVisible);\n\t\tif (clearable.some((action) => action.payload.kind === \"turn\" && action.lifecycle.state === \"preparing\")) {\n\t\t\tthis._sessionInputPumpEpoch++;\n\t\t}\n\t\tconst steering = clearable\n\t\t\t.filter((action) => action.delivery === \"next_turn_boundary\")\n\t\t\t.map((action) => action.payload.text);\n\t\tconst followUp = clearable\n\t\t\t.filter((action) => action.delivery === \"when_run_idle\")\n\t\t\t.map((action) => action.payload.text);\n\t\tconst promptError = new Error(\"Queued prompt was cleared before delivery.\");\n\t\tconst agentMessageError = new Error(\"Queued agent message was cleared before delivery.\");\n\t\tfor (const action of clearable) {\n\t\t\tconst error =\n\t\t\t\taction.payload.kind === \"turn\" && action.lifecycle.state === \"preparing\" ? promptError : agentMessageError;\n\t\t\tthis._settleAgentMessage(action.agentMessageId, \"delivery\", error);\n\t\t\tthis._settleAgentMessage(action.agentMessageId, \"completion\", error);\n\t\t}\n\t\tconst clearableIds = new Set(clearable.map((action) => action.id));\n\t\tthis._cancelSessionActions((action) => clearableIds.has(action.id), agentMessageError);\n\t\tthis.agent.clearAllQueues();\n\t\tthis._emitQueueUpdate();\n\t\treturn { steering, followUp };\n\t}\n\n\tprivate _invalidateQueuedPromptPreparation(): void {\n\t\tfor (const action of this._actionStore.clearableActions()) {\n\t\t\tif (action.payload.kind === \"turn\") action.payload.prepared = undefined;\n\t\t}\n\t}\n\n\tclearQueuedAgentMessages(): { steering: string[]; followUp: string[] } {\n\t\tthis._agentMessageClearEpoch++;\n\t\treturn this.clearQueuedUserMessagesMatching(isAgentSessionMessagePrompt);\n\t}\n\n\tclearQueuedUserMessagesMatching(predicate: (text: string) => boolean): { steering: string[]; followUp: string[] } {\n\t\tconst ownedActions = this._actionStore.ownedActions();\n\t\tconst dispatchedTurnCount = ownedActions.filter(\n\t\t\t(action) =>\n\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t(action.lifecycle.state === \"committing\" || action.lifecycle.state === \"running\"),\n\t\t).length;\n\t\tconst matching = ownedActions.filter(\n\t\t\t(action) =>\n\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\taction.agentMessageId !== undefined &&\n\t\t\t\tpredicate(action.payload.text) &&\n\t\t\t\t(action.lifecycle.state === \"queued\" ||\n\t\t\t\t\taction.lifecycle.state === \"selected\" ||\n\t\t\t\t\taction.lifecycle.state === \"preparing\" ||\n\t\t\t\t\t(action.lifecycle.state === \"committing\" &&\n\t\t\t\t\t\tdispatchedTurnCount === 1 &&\n\t\t\t\t\t\t!primaryDeliveryRecord(action).started)),\n\t\t);\n\t\tif (matching.length === 0) return { steering: [], followUp: [] };\n\t\tconst removedTexts = (delivery: DeliveryPolicy) =>\n\t\t\t[\n\t\t\t\t...matching.filter((action) => action.delivery === delivery && action.lifecycle.state === \"queued\"),\n\t\t\t\t...matching.filter((action) => action.delivery === delivery && action.lifecycle.state !== \"queued\"),\n\t\t\t].map((action) => action.payload.text);\n\t\tconst removedSteering = removedTexts(\"next_turn_boundary\");\n\t\tconst removedFollowUp = removedTexts(\"when_run_idle\");\n\t\tconst acceptedError = new Error(\"Accepted agent message was cleared before delivery.\");\n\t\tconst queuedError = new Error(\"Queued agent message was cleared before delivery.\");\n\t\tfor (const action of matching) {\n\t\t\tconst error =\n\t\t\t\taction.payload.kind === \"turn\" && action.payload.acceptedAgentMessage ? acceptedError : queuedError;\n\t\t\tthis._rejectAgentMessage(action.agentMessageId, error);\n\t\t}\n\t\tfor (const [accepted, error] of [\n\t\t\t[true, acceptedError],\n\t\t\t[false, queuedError],\n\t\t] as const) {\n\t\t\tconst ids = new Set(\n\t\t\t\tmatching\n\t\t\t\t\t.filter((action) => action.payload.kind === \"turn\" && action.payload.acceptedAgentMessage === accepted)\n\t\t\t\t\t.map((action) => action.id),\n\t\t\t);\n\t\t\tif (ids.size > 0) this._cancelSessionActions((action) => ids.has(action.id), error, matching);\n\t\t}\n\t\tif (\n\t\t\tmatching.some(\n\t\t\t\t(action) =>\n\t\t\t\t\taction.lifecycle.state === \"cancelled\" &&\n\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\taction.payload.captureRunMessages,\n\t\t\t)\n\t\t) {\n\t\t\tthis.agent.abort();\n\t\t}\n\t\tthis._emitQueueUpdate();\n\t\treturn { steering: removedSteering, followUp: removedFollowUp };\n\t}\n\n\t/**\n\t * Mutate a single visible queued message, addressed by its position in the same\n\t * projection the session-action snapshot publishes. expectedText must match the\n\t * item's current preview so clients never edit a shifted queue by accident.\n\t */\n\tmutateQueuedMessage(\n\t\tlane: QueuedMessageLane,\n\t\tindex: number,\n\t\texpectedText: string,\n\t\tmutation: QueuedMessageMutation,\n\t): QueuedMessageMutationStatus {\n\t\tconst policy = queuedMessageLaneDeliveryPolicy(lane);\n\t\tconst projection = visibleSessionActionProjection(this._actionStore.queuedActions(policy));\n\t\tconst item = projection[index];\n\t\tif (!item || queuedAgentMessagePreview(item) !== expectedText) return \"rejected\";\n\t\tif (mutation.type === \"delete\") {\n\t\t\tconst error = new Error(\"Queued prompt was deleted before delivery.\");\n\t\t\tthis._rejectAgentMessage(item.agentMessageId, error);\n\t\t\tthis._cancelSessionActions((candidate) => candidate === item, error);\n\t\t\tthis._emitQueueUpdate();\n\t\t\tthis.resumeQueuedWork();\n\t\t\treturn \"applied\";\n\t\t}\n\t\tif (mutation.type === \"move\") {\n\t\t\tconst neighbor = projection[index + mutation.direction];\n\t\t\tif (!neighbor) return \"rejected\";\n\t\t\tthis._actionStore.swapQueued(item, neighbor);\n\t\t\tthis._emitQueueUpdate();\n\t\t\treturn \"applied\";\n\t\t}\n\t\tif (\n\t\t\titem.payload.kind === \"turn\" &&\n\t\t\t(item.payload.acceptedAgentMessage ||\n\t\t\t\titem.payload.records.some((record) => record.role === \"primary\" && record.message.role !== \"user\"))\n\t\t) {\n\t\t\treturn \"rejected\";\n\t\t}\n\t\tconst images = mutation.images?.map((image) => ({ ...image }));\n\t\tif (item.payload.kind === \"session_command\") {\n\t\t\tconst command = parseSessionSlashCommand(mutation.text);\n\t\t\tif (!command) return \"invalid\";\n\t\t\titem.payload.text = mutation.text;\n\t\t\titem.payload.command = command;\n\t\t\tif (mutation.images !== undefined) item.payload.images = images?.length ? images : undefined;\n\t\t} else {\n\t\t\titem.payload.text = mutation.text;\n\t\t\titem.payload.selectedSkillRef = undefined;\n\t\t\tconst text = { type: \"text\" as const, text: mutation.text };\n\t\t\tif (mutation.images !== undefined) {\n\t\t\t\titem.payload.images = images?.length ? images : undefined;\n\t\t\t\titem.payload.content = [text, ...(images?.map((image) => ({ ...image })) ?? [])];\n\t\t\t} else if (item.payload.content) {\n\t\t\t\titem.payload.content = [text, ...item.payload.content.filter((block) => block.type !== \"text\")];\n\t\t\t}\n\t\t\titem.payload.preview = undefined;\n\t\t\titem.payload.prepared = undefined;\n\t\t\tfor (const record of item.payload.records) {\n\t\t\t\tif (record.role === \"primary\" && record.message.role === \"user\") {\n\t\t\t\t\trecord.message.content = item.payload.content?.map((block) => ({ ...block })) ?? mutation.text;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (item.payload.submitted) {\n\t\t\tconst previous = item.payload.submitted;\n\t\t\tconst content = previous.content\n\t\t\t\t? [\n\t\t\t\t\t\t{ type: \"text\" as const, text: mutation.text },\n\t\t\t\t\t\t...(mutation.images ?? previous.content.filter((block) => block.type !== \"text\")),\n\t\t\t\t\t]\n\t\t\t\t: undefined;\n\t\t\titem.payload.submitted = captureSubmittedInput(mutation.text, {\n\t\t\t\tcontent,\n\t\t\t\timages: mutation.images ?? previous.images,\n\t\t\t});\n\t\t}\n\t\tconst targetPolicy = queuedMessageLaneDeliveryPolicy(mutation.lane);\n\t\tif (targetPolicy !== policy) {\n\t\t\titem.queueKey = undefined;\n\t\t\titem.wake = mutation.lane === \"steering\" ? \"on_lower_boundary\" : \"external_resume\";\n\t\t\tthis._actionStore.moveQueued(item, targetPolicy, this._actionStore.queuedActions(targetPolicy).length);\n\t\t}\n\t\tthis.resumeQueuedWork();\n\t\tthis._emitQueueUpdate();\n\t\treturn \"applied\";\n\t}\n\n\tget queuedActionCount(): number {\n\t\treturn visibleSessionActionProjection(this._actionStore.queuedActions()).length;\n\t}\n\n\tget unfinishedActionCount(): number {\n\t\treturn this._actionStore.unfinishedActions().length;\n\t}\n\n\tget isQueuedWorkSuspended(): boolean {\n\t\treturn this._sessionInputPumpSuspended;\n\t}\n\n\tget isSessionActive(): boolean {\n\t\treturn (\n\t\t\tthis.requests.hasPending ||\n\t\t\tthis._goalResumeOperation !== undefined ||\n\t\t\tthis.isStreaming ||\n\t\t\tthis.isCompacting ||\n\t\t\tthis.isRetrying ||\n\t\t\tthis.isBashRunning ||\n\t\t\tthis._refineInFlight !== undefined ||\n\t\t\tthis._branchSummaryOperation !== undefined ||\n\t\t\tthis._postCompactionContinuationSettlement !== undefined ||\n\t\t\tthis.unfinishedActionCount > 0\n\t\t);\n\t}\n\n\tgetSessionActionSnapshot(): SessionActionSnapshot {\n\t\tconst steering = visibleSessionActionProjection(this._actionStore.queuedActions(\"next_turn_boundary\")).map(\n\t\t\tqueuedAgentMessagePreview,\n\t\t);\n\t\tconst followUps = visibleSessionActionProjection(this._actionStore.queuedActions(\"when_run_idle\")).map(\n\t\t\tqueuedAgentMessagePreview,\n\t\t);\n\t\tconst active = visibleSessionActionProjection(this._actionStore.activeActions())[0];\n\t\tconst activeState = active?.lifecycle.state;\n\t\tconst phase =\n\t\t\tactiveState === \"selected\"\n\t\t\t\t? \"preparing\"\n\t\t\t\t: activeState === \"preparing\" || activeState === \"committing\" || activeState === \"running\"\n\t\t\t\t\t? activeState\n\t\t\t\t\t: undefined;\n\t\treturn {\n\t\t\tqueuedCount: steering.length + followUps.length,\n\t\t\tsteering,\n\t\t\tfollowUps,\n\t\t\t...(active && phase\n\t\t\t\t? {\n\t\t\t\t\t\tactive: {\n\t\t\t\t\t\t\tkind: active.payload.kind,\n\t\t\t\t\t\t\tphase,\n\t\t\t\t\t\t\tlabel: compactRlmText(active.payload.text),\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t};\n\t}\n\n\tgetSteeringMessages(): readonly string[] {\n\t\treturn visibleSessionActionProjection(this._actionStore.queuedActions(\"next_turn_boundary\")).map(\n\t\t\t(action) => action.payload.text,\n\t\t);\n\t}\n\n\tgetSteeringMessagePreviews(): readonly string[] {\n\t\treturn visibleSessionActionProjection(this._actionStore.queuedActions(\"next_turn_boundary\")).map(\n\t\t\tqueuedAgentMessagePreview,\n\t\t);\n\t}\n\n\tgetFollowUpMessages(): readonly string[] {\n\t\treturn visibleSessionActionProjection(this._actionStore.queuedActions(\"when_run_idle\")).map(\n\t\t\t(action) => action.payload.text,\n\t\t);\n\t}\n\n\tgetFollowUpMessagePreviews(): readonly string[] {\n\t\treturn visibleSessionActionProjection(this._actionStore.queuedActions(\"when_run_idle\")).map(\n\t\t\tqueuedAgentMessagePreview,\n\t\t);\n\t}\n\n\tgetSessionActionRecoverySnapshot(): SessionActionRecoverySnapshot {\n\t\tconst actions = this._actionStore.snapshotActions();\n\t\treturn {\n\t\t\tformatVersion: actions.some((action) => action.payload.kind === \"turn\" && action.payload.selectedSkillRef)\n\t\t\t\t? SESSION_ACTION_SKILL_RECOVERY_FORMAT_VERSION\n\t\t\t\t: SESSION_ACTION_RECOVERY_FORMAT_VERSION,\n\t\t\tactions: actions.map((action) => ({\n\t\t\t\tid: action.id,\n\t\t\t\tsource: action.source,\n\t\t\t\tdelivery: action.delivery,\n\t\t\t\twake: action.wake,\n\t\t\t\t...(action.queueKey ? { queueKey: action.queueKey } : {}),\n\t\t\t\t...(action.agentMessageId ? { agentMessageId: action.agentMessageId } : {}),\n\t\t\t\t...(action.suppressAutonomousContinuation ? { suppressAutonomousContinuation: true } : {}),\n\t\t\t\tpayload:\n\t\t\t\t\taction.payload.kind === \"turn\"\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tkind: \"turn\",\n\t\t\t\t\t\t\t\ttext: action.payload.text,\n\t\t\t\t\t\t\t\t...(action.payload.selectedSkillRef\n\t\t\t\t\t\t\t\t\t? { selectedSkillRef: { ...action.payload.selectedSkillRef } }\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t...(action.payload.submitted ? { submitted: structuredClone(action.payload.submitted) } : {}),\n\t\t\t\t\t\t\t\t...(action.payload.preview ? { preview: action.payload.preview } : {}),\n\t\t\t\t\t\t\t\trecords: action.payload.records.map((record) => ({\n\t\t\t\t\t\t\t\t\tid: record.id,\n\t\t\t\t\t\t\t\t\trole: record.role,\n\t\t\t\t\t\t\t\t\tmessage: cloneQueuedAgentMessage(record.message),\n\t\t\t\t\t\t\t\t\townerActionId: record.ownerActionId,\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t...(action.payload.images\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\timages: action.payload.images.map((image) => ({\n\t\t\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t...(action.payload.content\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\tcontent: action.payload.content.map((block) => ({\n\t\t\t\t\t\t\t\t\t\t\t\t...block,\n\t\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t...(action.payload.customMessage\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\tcustomMessage: cloneCustomMessage(action.payload.customMessage),\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\texecutionPolicy: {\n\t\t\t\t\t\t\t\t\t...action.payload.executionPolicy,\n\t\t\t\t\t\t\t\t\tpreparation: {\n\t\t\t\t\t\t\t\t\t\t...action.payload.executionPolicy.preparation,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tqueueVisible: action.payload.queueVisible,\n\t\t\t\t\t\t\t\tacceptedAgentMessage: action.payload.acceptedAgentMessage,\n\t\t\t\t\t\t\t\tacceptedBeforeCompletion: action.payload.acceptedBeforeCompletion,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tkind: \"session_command\",\n\t\t\t\t\t\t\t\ttext: action.payload.text,\n\t\t\t\t\t\t\t\t...(action.payload.submitted ? { submitted: structuredClone(action.payload.submitted) } : {}),\n\t\t\t\t\t\t\t\tcommand: { ...action.payload.command },\n\t\t\t\t\t\t\t\t...(action.payload.images\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\timages: action.payload.images.map((image) => ({\n\t\t\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t},\n\t\t\t})),\n\t\t};\n\t}\n\n\tprivate _notifySessionInputCheckpointChange(): void {\n\t\tconst waiters = [...this._sessionInputCheckpointWaiters];\n\t\tthis._sessionInputCheckpointWaiters.clear();\n\t\tfor (const resolve of waiters) resolve();\n\t}\n\n\tprivate _waitForSessionActivityChange(signal: AbortSignal): Promise<void> {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst finish = () => {\n\t\t\t\tthis._sessionInputCheckpointWaiters.delete(finish);\n\t\t\t\tsignal.removeEventListener(\"abort\", finish);\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tthis._sessionInputCheckpointWaiters.add(finish);\n\t\t\tsignal.addEventListener(\"abort\", finish, { once: true });\n\t\t\tif (signal.aborted) finish();\n\t\t});\n\t}\n\n\tprivate _observeSessionActionDeferral(action: QueuedSessionAction): {\n\t\tdeferred: Promise<void>;\n\t\tstop(): void;\n\t} {\n\t\tlet resolveDeferral = () => {};\n\t\tconst deferred = new Promise<void>((resolve) => {\n\t\t\tresolveDeferral = resolve;\n\t\t});\n\t\tconst check = () => {\n\t\t\tif (action.lifecycle.state === \"queued\") resolveDeferral();\n\t\t\telse this._sessionInputCheckpointWaiters.add(check);\n\t\t};\n\t\tthis._sessionInputCheckpointWaiters.add(check);\n\t\treturn {\n\t\t\tdeferred,\n\t\t\tstop: () => this._sessionInputCheckpointWaiters.delete(check),\n\t\t};\n\t}\n\n\tasync waitForSessionInputCheckpoint(signal?: AbortSignal): Promise<void> {\n\t\tconst blocksCheckpoint = () =>\n\t\t\tthis._actionStore.activeActions().some((action) => {\n\t\t\t\tif (action.payload.kind === \"session_command\") {\n\t\t\t\t\treturn action.lifecycle.state === \"selected\" || action.lifecycle.state === \"running\";\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\taction.lifecycle.state === \"selected\" ||\n\t\t\t\t\taction.lifecycle.state === \"preparing\" ||\n\t\t\t\t\t(action.lifecycle.state === \"committing\" && !primaryDeliveryRecord(action).durable)\n\t\t\t\t);\n\t\t\t});\n\t\twhile (true) {\n\t\t\twhile (blocksCheckpoint()) {\n\t\t\t\tif (signal?.aborted) throw new Error(\"Update restart preparation cancelled\");\n\t\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\t\tconst onChange = () => {\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t};\n\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new Error(\"Update restart preparation cancelled\"));\n\t\t\t\t\t};\n\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\tthis._sessionInputCheckpointWaiters.delete(onChange);\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t};\n\t\t\t\t\tthis._sessionInputCheckpointWaiters.add(onChange);\n\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\tif (signal?.aborted) onAbort();\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst commitFence = await this._acquireSessionActionCommitFence(signal);\n\t\t\ttry {\n\t\t\t\tif (blocksCheckpoint()) continue;\n\t\t\t\tif (signal?.aborted) throw new Error(\"Update restart preparation cancelled\");\n\t\t\t\tawait waitForPromiseOrAbort(this._agentEventQueue, signal, \"Update restart preparation cancelled\");\n\t\t\t\tif (signal?.aborted) throw new Error(\"Update restart preparation cancelled\");\n\t\t\t\tawait this.sessionManager.flushNow();\n\t\t\t\treturn;\n\t\t\t} finally {\n\t\t\t\tcommitFence.release();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _advanceCheckpointPauseEpoch(): void {\n\t\t// A pause invalidates preparations, not already owned checkpoint work. Keep its original source predicate.\n\t\tconst owners = [\n\t\t\tthis._pendingRequestedCompaction?.owner,\n\t\t\tthis._pendingCheckpoint?.owner,\n\t\t\tthis._postCompactionContinuationSettlement?.resume.owner,\n\t\t].filter((owner): owner is CompactionOwner => owner !== undefined && this._isCompactionOwnerCurrent(owner));\n\t\tthis._sessionInputPumpEpoch++;\n\t\tfor (const owner of owners) owner.pumpEpoch = this._sessionInputPumpEpoch;\n\t}\n\n\tacquireSessionInputPause(): { release(): void } {\n\t\tconst token = Symbol(\"session-input-admission-pause\");\n\t\tthis._sessionInputAdmissionPauses.add(token);\n\t\tthis._sessionInputPumpRequested = false;\n\t\tthis._advanceCheckpointPauseEpoch();\n\t\tlet released = false;\n\t\treturn {\n\t\t\trelease: () => {\n\t\t\t\tif (released) return;\n\t\t\t\treleased = true;\n\t\t\t\tthis._sessionInputAdmissionPauses.delete(token);\n\t\t\t\tthis._advanceCheckpointPauseEpoch();\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\tthis._flushDeferredRlmTerminalNotices();\n\t\t\t\tthis._scheduleGoalContinuationAfterRlmWork();\n\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t},\n\t\t};\n\t}\n\n\tacquireQueuedWorkPause(): { release(): void } {\n\t\tconst token = Symbol(\"queued-work-pause\");\n\t\tthis._queuedWorkPauses.add(token);\n\t\tthis._sessionInputPumpRequested = false;\n\t\tthis._advanceCheckpointPauseEpoch();\n\t\tlet released = false;\n\t\treturn {\n\t\t\trelease: () => {\n\t\t\t\tif (released) return;\n\t\t\t\treleased = true;\n\t\t\t\tthis._queuedWorkPauses.delete(token);\n\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\tthis._flushDeferredRlmTerminalNotices();\n\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate async _acquireDirectTurnAdmissionFence(signal?: AbortSignal): Promise<{ owner: symbol; release(): void }> {\n\t\tconst inheritedOwner = this._sessionActionCommitContext.getStore();\n\t\tif (inheritedOwner !== undefined && inheritedOwner === this._sessionActionCommitOwner) {\n\t\t\tthis._assertSessionActionAdmissionAvailable();\n\t\t\treturn this._acquireSessionActionCommitFence(signal);\n\t\t}\n\t\tconst disposeSignal = this._sessionActionCommitDisposeAbortController.signal;\n\t\tconst waitSignal = signal ? AbortSignal.any([signal, disposeSignal]) : disposeSignal;\n\t\twhile (true) {\n\t\t\tthis._assertSessionActionAdmissionAvailable();\n\t\t\tif (this._queuedWorkPauses.size > 0) {\n\t\t\t\tlet wake = () => {};\n\t\t\t\tconst pauseReleased = new Promise<void>((resolve) => {\n\t\t\t\t\twake = resolve;\n\t\t\t\t\tthis._sessionInputCheckpointWaiters.add(resolve);\n\t\t\t\t});\n\t\t\t\ttry {\n\t\t\t\t\tawait waitForPromiseOrAbort(pauseReleased, waitSignal, \"Update restart preparation cancelled\");\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (disposeSignal.aborted) {\n\t\t\t\t\t\tthrow new Error(\"Cannot admit a session action because the session is disposing or disposed.\");\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t} finally {\n\t\t\t\t\tthis._sessionInputCheckpointWaiters.delete(wake);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst fence = await this._acquireSessionActionCommitFence(signal);\n\t\t\ttry {\n\t\t\t\tif (this._queuedWorkPauses.size === 0) {\n\t\t\t\t\tthis._assertSessionActionAdmissionAvailable();\n\t\t\t\t\treturn fence;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tfence.release();\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tfence.release();\n\t\t}\n\t}\n\n\tprivate async _acquireSessionActionCommitFence(signal?: AbortSignal): Promise<{ owner: symbol; release(): void }> {\n\t\tconst inheritedOwner = this._sessionActionCommitContext.getStore();\n\t\tif (inheritedOwner !== undefined && inheritedOwner === this._sessionActionCommitOwner) {\n\t\t\treturn { owner: inheritedOwner, release: () => {} };\n\t\t}\n\t\tconst previous = this._sessionActionCommitTail;\n\t\tlet resolve = () => {};\n\t\tthis._sessionActionCommitTail = new Promise<void>((release) => {\n\t\t\tresolve = release;\n\t\t});\n\t\tconst disposeSignal = this._sessionActionCommitDisposeAbortController.signal;\n\t\tconst waitSignal = signal ? AbortSignal.any([signal, disposeSignal]) : disposeSignal;\n\t\tthis._pendingSessionActionFenceWaiters++;\n\t\ttry {\n\t\t\tawait waitForPromiseOrAbort(previous, waitSignal, \"Update restart preparation cancelled\");\n\t\t} catch (error) {\n\t\t\tthis._pendingSessionActionFenceWaiters--;\n\t\t\t// A cancelled waiter remains in the FIFO chain until its predecessor releases.\n\t\t\tvoid previous.then(resolve, resolve);\n\t\t\tif (disposeSignal.aborted) {\n\t\t\t\tthrow new Error(\"Cannot admit a session action because the session is disposing or disposed.\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tconst owner = Symbol(\"session-action-commit\");\n\t\tthis._sessionActionCommitOwner = owner;\n\t\tthis._pendingSessionActionFenceWaiters--;\n\t\tlet released = false;\n\t\treturn {\n\t\t\towner,\n\t\t\trelease: () => {\n\t\t\t\tif (released) return;\n\t\t\t\treleased = true;\n\t\t\t\tif (this._sessionActionCommitOwner === owner) this._sessionActionCommitOwner = undefined;\n\t\t\t\tresolve();\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate _resumeSessionInputAdmission(): void {\n\t\tif (!this._sessionInputPumpSuspended) return;\n\t\tthis._sessionInputPumpSuspended = false;\n\t\tthis._sessionInputSuspendedForUpdateRestart = false;\n\t\tthis._sessionInputPumpEpoch++;\n\t\tthis._notifySessionInputCheckpointChange();\n\t\tthis._flushDeferredRlmTerminalNotices();\n\t}\n\n\t/** Resume the scheduler after requestAbort/abortForUpdateRestart suspended it; owned pause leases are unaffected. */\n\tresumeQueuedWork(): boolean {\n\t\tthis._resumeSessionInputAdmission();\n\t\tthis._scheduleGoalContinuationAfterRlmWork();\n\t\tthis._scheduleSessionInputPump();\n\t\treturn this._hasSelectableSessionInput();\n\t}\n\n\tasync waitForSessionInputIdle(): Promise<void> {\n\t\twhile (true) {\n\t\t\tconst pump = this._sessionInputPump;\n\t\t\tawait pump;\n\t\t\tif (pump === this._sessionInputPump && !this._sessionInputPumpRequested) return;\n\t\t}\n\t}\n\n\tasync waitForIdle(): Promise<void> {\n\t\tawait this._waitForIdleOrSettlement();\n\t}\n\n\t/**\n\t * {@link waitForIdle} loop; with a settlement, returns once that settlement is\n\t * superseded so a cancelled post-compaction runner cannot keep a checkpoint\n\t * waiter registered (a leaked waiter holds hasPendingAdmissionWaiters true and\n\t * blocks daemon passivation).\n\t */\n\tprivate async _waitForIdleOrSettlement(settlement?: PostCompactionContinuationSettlement): Promise<void> {\n\t\tconst owner = settlement?.resume.owner;\n\t\tconst current = () => !owner || this._isCompactionOwnerCurrent(owner);\n\t\twhile (current() && (settlement === undefined || this._postCompactionContinuationSettlement === settlement)) {\n\t\t\tif (this._actionStore.queuedActions().length > 0) {\n\t\t\t\t// A blocked pump must wait for a checkpoint change, not spin in\n\t\t\t\t// microtasks and starve the IO that clears its busy state.\n\t\t\t\tif (this._isBusyForSessionInput(\"pump\") || (settlement && this._sessionInputAdmissionPauses.size > 0)) {\n\t\t\t\t\tlet wake = () => {};\n\t\t\t\t\tconst changed = new Promise<void>((resolve) => {\n\t\t\t\t\t\twake = resolve;\n\t\t\t\t\t\tthis._sessionInputCheckpointWaiters.add(resolve);\n\t\t\t\t\t});\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait (settlement ? Promise.race([changed, settlement.promise]) : changed);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tthis._sessionInputCheckpointWaiters.delete(wake);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t}\n\t\t\tconst pump = this._sessionInputPump;\n\t\t\tawait pump;\n\t\t\tif (!current()) return;\n\t\t\tawait (owner?.agent ?? this.agent).waitForIdle();\n\t\t\tif (!current()) return;\n\t\t\tconst agentEventQueue = this._agentEventQueue;\n\t\t\tawait agentEventQueue;\n\t\t\tif (!current()) return;\n\t\t\tconst goalResumeOperation = this._goalResumeOperation;\n\t\t\tawait goalResumeOperation;\n\t\t\tif (!current()) return;\n\t\t\tconst requestSettlement = (owner?.requests ?? this.requests).waitForIdle();\n\t\t\tawait (settlement ? Promise.race([requestSettlement, settlement.promise]) : requestSettlement);\n\t\t\tif (!current() || (settlement && this._postCompactionContinuationSettlement !== settlement)) return;\n\t\t\tif (\n\t\t\t\tpump === this._sessionInputPump &&\n\t\t\t\tagentEventQueue === this._agentEventQueue &&\n\t\t\t\tthis._goalResumeOperation === undefined &&\n\t\t\t\t!this._sessionInputPumpRequested &&\n\t\t\t\t!this.agent.state.isStreaming &&\n\t\t\t\t!this.requests.hasPending &&\n\t\t\t\tthis.unfinishedActionCount === 0\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Waits out any owned post-compaction continuation and rejects when one cannot start; {@link waitForIdle} never rejects. */\n\tasync waitForHeadlessIdle(): Promise<void> {\n\t\twhile (true) {\n\t\t\tawait this.waitForIdle();\n\t\t\tconst postCompactionContinuation = this._postCompactionContinuationSettlement?.promise;\n\t\t\tif (!postCompactionContinuation) return;\n\t\t\tawait postCompactionContinuation;\n\t\t}\n\t}\n\n\tgetPendingNextTurnMessageSnapshots(): readonly CustomMessage[] {\n\t\tconst messages = this._pendingNextTurnMessages.map((message) => cloneCustomMessage(message));\n\t\tfor (const action of this._actionStore.unfinishedActions()) {\n\t\t\tif (\n\t\t\t\taction.payload.kind !== \"turn\" ||\n\t\t\t\t!action.payload.acceptedAgentMessage ||\n\t\t\t\t!primaryDeliveryRecord(action).started\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmessages.push(\n\t\t\t\t...action.payload.records\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(record): record is DeliveryRecord & { message: CustomMessage } =>\n\t\t\t\t\t\t\t(record.role === \"next_turn\" || record.role === \"prefix\") &&\n\t\t\t\t\t\t\trecord.message.role === \"custom\" &&\n\t\t\t\t\t\t\t!record.durable,\n\t\t\t\t\t)\n\t\t\t\t\t.map((record) => cloneCustomMessage(record.message)),\n\t\t\t);\n\t\t}\n\t\treturn messages;\n\t}\n\n\trestorePendingNextTurnMessages(messages: readonly CustomMessage[]): void {\n\t\tthis._pendingNextTurnMessages.push(...messages.map((message) => cloneCustomMessage(message)));\n\t\tthis._flushDeferredRlmTerminalNotices();\n\t}\n\n\tremoveQueuedFollowUp(queueKey: string): boolean {\n\t\tconst matching = this._actionStore\n\t\t\t.clearableActions()\n\t\t\t.filter((action) => action.payload.kind === \"turn\" && action.queueKey === queueKey);\n\t\tif (matching.length === 0) return false;\n\t\tconst error = new Error(\"Queued agent message was cleared before delivery.\");\n\t\tfor (const action of matching) this._rejectAgentMessage(action.agentMessageId, error);\n\t\tconst ids = new Set(matching.map((action) => action.id));\n\t\tthis._cancelSessionActions((action) => ids.has(action.id), error);\n\t\tthis._emitQueueUpdate();\n\t\treturn true;\n\t}\n\n\tget resourceLoader(): ResourceLoader {\n\t\treturn this._resourceLoader;\n\t}\n\n\trequestAbort(): void {\n\t\tfor (const run of [...this._unsettledRlmChildRuns]) {\n\t\t\tif (run.status === \"cancelled\") this._abandonRlmRunForQuiescence(run);\n\t\t}\n\t\tfor (const controller of this._rlmQuiescenceWaitAborts) controller.abort();\n\t\tthis._sessionInputPumpRequested = false;\n\t\tthis._sessionInputPumpEpoch++;\n\t\tthis._sessionInputPumpSuspended = true;\n\t\tthis._sessionInputSuspendedForUpdateRestart = false;\n\t\tthis._demoteRlmTerminalNoticeActions();\n\t\tthis._cancelSessionActions(\n\t\t\t(action) =>\n\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t!action.payload.queueVisible &&\n\t\t\t\t!this._durableRlmTerminalNoticeActionIds.has(action.id),\n\t\t\tnew Error(\"Prompt aborted before delivery.\"),\n\t\t);\n\t\tthis._cancelPostCompactionContinue();\n\t\tthis.abortRetry();\n\t\tthis.abortCompaction();\n\t\tthis.abortBranchSummary();\n\t\tthis.abortBash();\n\t\tthis._pendingRequestedRefine = undefined;\n\t\tthis._autoRefineBranchVersion++;\n\t\tthis._autoRefineReviewAbort?.abort();\n\t\tthis._refineAbortController?.abort();\n\t\tthis.agent.abort();\n\t}\n\n\tasync abort(): Promise<void> {\n\t\tconst compactionOperation = this._compactionOperation;\n\t\tconst branchSummaryOperation = this._branchSummaryOperation;\n\t\tthis.requestAbort();\n\t\tthis._cancelActiveRlmChildRuns(\"Parent session aborted\");\n\t\tthis._goalAbortInProgress = this._goalState.status === \"active\";\n\t\ttry {\n\t\t\tawait Promise.allSettled([\n\t\t\t\tthis.agent.waitForIdle(),\n\t\t\t\tthis._agentEventQueue,\n\t\t\t\t...(compactionOperation ? [compactionOperation] : []),\n\t\t\t\t...(branchSummaryOperation ? [branchSummaryOperation] : []),\n\t\t\t]);\n\t\t} finally {\n\t\t\tthis._goalAbortInProgress = false;\n\t\t}\n\t}\n\n\tabortForUpdateRestart(): void {\n\t\t// Cancel scheduled pumps and suspend new ones: queued inputs must survive\n\t\t// into the restart manifest instead of starting a turn during teardown.\n\t\tthis._sessionInputPumpRequested = false;\n\t\tthis._sessionInputPumpEpoch++;\n\t\tthis._sessionInputPumpSuspended = true;\n\t\tthis._sessionInputSuspendedForUpdateRestart = true;\n\t\tthis._cancelPostCompactionContinue();\n\t\tthis.abortRetry();\n\t\tfor (const controller of this._rlmQuiescenceWaitAborts) controller.abort();\n\t\tthis._cancelActiveRlmChildRuns(\"Parent session aborted for update restart\");\n\t\tthis._goalAbortInProgress = this._goalState.status === \"active\";\n\t\tthis.agent.abort();\n\t\tif (this._goalAbortInProgress) {\n\t\t\tvoid this.agent\n\t\t\t\t.waitForIdle()\n\t\t\t\t.then(() => this._agentEventQueue)\n\t\t\t\t.catch(() => undefined)\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis._goalAbortInProgress = false;\n\t\t\t\t});\n\t\t}\n\t}\n\n\tprivate async _emitModelSelect(\n\t\tnextModel: Model<any>,\n\t\tpreviousModel: Model<any> | undefined,\n\t\tsource: \"set\" | \"cycle\" | \"restore\",\n\t): Promise<void> {\n\t\tif (modelsAreEqual(previousModel, nextModel)) return;\n\t\tawait this._extensionRunner.emit({\n\t\t\ttype: \"model_select\",\n\t\t\tmodel: nextModel,\n\t\t\tpreviousModel,\n\t\t\tsource,\n\t\t});\n\t}\n\n\tprivate _queueModelSelectEmit(\n\t\tnextModel: Model<any>,\n\t\tpreviousModel: Model<any> | undefined,\n\t\tsource: \"set\" | \"cycle\" | \"restore\",\n\t): Promise<void> {\n\t\tconst emit = () =>\n\t\t\tthis._modelSelectEmitContext.run(true, () => this._emitModelSelect(nextModel, previousModel, source));\n\t\tthis._modelSelectEmitQueueIdle = false;\n\t\tconst promise = this._modelSelectEmitQueue.then(emit, emit);\n\t\tconst queued = promise.catch(() => {});\n\t\tthis._modelSelectEmitQueue = queued;\n\t\tvoid queued.finally(() => {\n\t\t\tif (this._modelSelectEmitQueue === queued) {\n\t\t\t\tthis._modelSelectEmitQueueIdle = true;\n\t\t\t}\n\t\t});\n\t\treturn promise;\n\t}\n\n\tasync setModel(model: Model<any>, options: ModelSelectOptions = {}): Promise<void> {\n\t\tmodel = { ...model, cost: { ...model.cost } };\n\t\tconst sourceId = this.sessionManager.getSessionId();\n\t\tconst sourceFile = this.sessionManager.getSessionFile();\n\t\tconst previousModel = this.model;\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch();\n\t\tconst serviceTier = this._getServiceTierForModelSwitch();\n\t\tif (!this._modelRegistry.hasConfiguredAuth(model)) {\n\t\t\tthrow new Error(`No API key for ${model.provider}/${model.id}`);\n\t\t}\n\t\tif (!(await this._modelRegistry.canUseModel(model))) {\n\t\t\tthrow new Error(`Model \"${model.provider}/${model.id}\" is not available with the configured authentication.`);\n\t\t}\n\n\t\tif (this.sessionManager.getSessionId() !== sourceId || this.sessionManager.getSessionFile() !== sourceFile) {\n\t\t\tthrow new Error(\"Session source changed during model selection\");\n\t\t}\n\t\tawait this.sessionManager.appendModelChange(model.provider, model.id);\n\t\tthis.agent.state.model = model;\n\t\tthis.settingsManager.setDefaultModelAndProvider(model.provider, model.id);\n\n\t\tawait this.setThinkingLevel(thinkingLevel);\n\t\tthis._clampServiceTierForModel(serviceTier);\n\n\t\tconst emitPromise = this._queueModelSelectEmit(model, previousModel, \"set\");\n\t\tif (this._shouldWaitForModelSelectEmit(options)) {\n\t\t\tawait emitPromise;\n\t\t} else {\n\t\t\tthis._trackModelSelectEmitError(emitPromise);\n\t\t}\n\t}\n\n\tprivate _trackModelSelectEmitError(emitPromise: Promise<void>): void {\n\t\tvoid emitPromise.catch((error) => {\n\t\t\tthis._extensionRunner.emitError({\n\t\t\t\textensionPath: \"<internal>\",\n\t\t\t\tevent: \"model_select\",\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate _shouldWaitForModelSelectEmit(options: ModelSelectOptions): boolean {\n\t\treturn options.waitForExtensions !== false && !this._modelSelectEmitContext.getStore();\n\t}\n\n\tprivate _pendingModelSelectEmit(): Promise<void> | undefined {\n\t\tif (!this._modelSelectEmitContext.getStore() && !this._modelSelectEmitQueueIdle) {\n\t\t\treturn this._modelSelectEmitQueue;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tasync cycleModel(\n\t\tdirection: \"forward\" | \"backward\" = \"forward\",\n\t\toptions: ModelSelectOptions = {},\n\t): Promise<ModelCycleResult | undefined> {\n\t\tif (this._scopedModels.length > 0) {\n\t\t\treturn this._cycleScopedModel(direction, options);\n\t\t}\n\t\treturn this._cycleAvailableModel(direction, options);\n\t}\n\n\tprivate async _cycleScopedModel(\n\t\tdirection: \"forward\" | \"backward\",\n\t\toptions: ModelSelectOptions,\n\t): Promise<ModelCycleResult | undefined> {\n\t\tconst availableModels = await this._modelRegistry.refreshAvailableModels();\n\t\tconst scopedModels = this._scopedModels.filter((scoped) =>\n\t\t\tavailableModels.some((model) => modelsAreEqual(model, scoped.model)),\n\t\t);\n\t\tif (scopedModels.length <= 1) return undefined;\n\n\t\tconst currentModel = this.model;\n\t\tlet currentIndex = scopedModels.findIndex((sm) => modelsAreEqual(sm.model, currentModel));\n\n\t\tif (currentIndex === -1) currentIndex = 0;\n\t\tconst len = scopedModels.length;\n\t\tconst nextIndex = direction === \"forward\" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;\n\t\tconst next = scopedModels[nextIndex];\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch(next.thinkingLevel);\n\t\tconst serviceTier = this._getServiceTierForModelSwitch();\n\n\t\tawait this.sessionManager.appendModelChange(next.model.provider, next.model.id);\n\t\tthis.agent.state.model = next.model;\n\t\tthis.settingsManager.setDefaultModelAndProvider(next.model.provider, next.model.id);\n\n\t\tawait this.setThinkingLevel(thinkingLevel);\n\t\tthis._clampServiceTierForModel(serviceTier);\n\n\t\tconst emitPromise = this._queueModelSelectEmit(next.model, currentModel, \"cycle\");\n\t\tif (this._shouldWaitForModelSelectEmit(options)) {\n\t\t\tawait emitPromise;\n\t\t} else {\n\t\t\tthis._trackModelSelectEmitError(emitPromise);\n\t\t}\n\n\t\treturn {\n\t\t\tmodel: next.model,\n\t\t\tthinkingLevel: this.thinkingLevel,\n\t\t\tserviceTier: this.serviceTier,\n\t\t\tisScoped: true,\n\t\t};\n\t}\n\n\tprivate async _cycleAvailableModel(\n\t\tdirection: \"forward\" | \"backward\",\n\t\toptions: ModelSelectOptions,\n\t): Promise<ModelCycleResult | undefined> {\n\t\tconst availableModels = await this._modelRegistry.refreshAvailableModels();\n\t\tif (availableModels.length <= 1) return undefined;\n\n\t\tconst currentModel = this.model;\n\t\tlet currentIndex = availableModels.findIndex((m) => modelsAreEqual(m, currentModel));\n\n\t\tif (currentIndex === -1) currentIndex = 0;\n\t\tconst len = availableModels.length;\n\t\tconst nextIndex = direction === \"forward\" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;\n\t\tconst nextModel = availableModels[nextIndex];\n\n\t\tconst thinkingLevel = this._getThinkingLevelForModelSwitch();\n\t\tconst serviceTier = this._getServiceTierForModelSwitch();\n\t\tawait this.sessionManager.appendModelChange(nextModel.provider, nextModel.id);\n\t\tthis.agent.state.model = nextModel;\n\t\tthis.settingsManager.setDefaultModelAndProvider(nextModel.provider, nextModel.id);\n\n\t\tawait this.setThinkingLevel(thinkingLevel);\n\t\tthis._clampServiceTierForModel(serviceTier);\n\n\t\tconst emitPromise = this._queueModelSelectEmit(nextModel, currentModel, \"cycle\");\n\t\tif (this._shouldWaitForModelSelectEmit(options)) {\n\t\t\tawait emitPromise;\n\t\t} else {\n\t\t\tthis._trackModelSelectEmitError(emitPromise);\n\t\t}\n\n\t\treturn {\n\t\t\tmodel: nextModel,\n\t\t\tthinkingLevel: this.thinkingLevel,\n\t\t\tserviceTier: this.serviceTier,\n\t\t\tisScoped: false,\n\t\t};\n\t}\n\n\tasync setThinkingLevel(level: ThinkingLevel): Promise<void> {\n\t\tconst availableLevels = this.getAvailableThinkingLevels();\n\t\tconst effectiveLevel = availableLevels.includes(level) ? level : this._clampThinkingLevel(level, availableLevels);\n\n\t\tconst previousLevel = this.agent.state.thinkingLevel;\n\t\tconst isChanging = effectiveLevel !== previousLevel;\n\n\t\tif (isChanging) {\n\t\t\tawait this.sessionManager.appendThinkingLevelChange(effectiveLevel);\n\t\t\tthis.agent.state.thinkingLevel = effectiveLevel;\n\t\t\tif (this.supportsThinking() || effectiveLevel !== \"off\") {\n\t\t\t\tthis.settingsManager.setDefaultThinkingLevel(effectiveLevel);\n\t\t\t}\n\t\t\tthis._emit({ type: \"thinking_level_changed\", level: effectiveLevel });\n\t\t\tawait this._extensionRunner.emit({\n\t\t\t\ttype: \"thinking_level_select\",\n\t\t\t\tlevel: effectiveLevel,\n\t\t\t\tpreviousLevel,\n\t\t\t});\n\t\t}\n\t}\n\n\tasync setServiceTier(serviceTier: ServiceTier): Promise<void> {\n\t\tconst effectiveServiceTier = this._getEffectiveServiceTier(serviceTier);\n\t\tconst preferenceChanged = effectiveServiceTier !== this._serviceTierPreference;\n\t\tconst effectiveTierChanged = effectiveServiceTier !== this.agent.state.serviceTier;\n\t\tif (!preferenceChanged && !effectiveTierChanged) {\n\t\t\treturn;\n\t\t}\n\t\tif (preferenceChanged) {\n\t\t\tawait this.sessionManager.appendServiceTierChange(effectiveServiceTier);\n\t\t\tthis._serviceTierPreference = effectiveServiceTier;\n\t\t\tif (this.model && supportsFastMode(this.model)) {\n\t\t\t\tthis.settingsManager.setDefaultServiceTier(effectiveServiceTier);\n\t\t\t}\n\t\t}\n\t\tif (effectiveTierChanged) {\n\t\t\tthis.agent.state.serviceTier = effectiveServiceTier;\n\t\t\tthis._emit({\n\t\t\t\ttype: \"service_tier_changed\",\n\t\t\t\tserviceTier: effectiveServiceTier,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate _getEffectiveServiceTier(serviceTier: ServiceTier): ServiceTier {\n\t\treturn serviceTier === \"priority\" && (!this.model || !supportsFastMode(this.model)) ? \"default\" : serviceTier;\n\t}\n\n\tprivate _getServiceTierForModelSwitch(): ServiceTier {\n\t\treturn this._serviceTierPreference;\n\t}\n\n\tprivate _clampServiceTierForModel(serviceTier: ServiceTier = this.serviceTier): void {\n\t\tconst effectiveServiceTier = this._getEffectiveServiceTier(serviceTier);\n\t\tif (effectiveServiceTier === this.agent.state.serviceTier) {\n\t\t\treturn;\n\t\t}\n\t\tthis.agent.state.serviceTier = effectiveServiceTier;\n\t\tthis._emit({\n\t\t\ttype: \"service_tier_changed\",\n\t\t\tserviceTier: effectiveServiceTier,\n\t\t});\n\t}\n\n\tasync cycleThinkingLevel(): Promise<ThinkingLevel | undefined> {\n\t\tif (!this.supportsThinking()) return undefined;\n\n\t\tconst levels = this.getAvailableThinkingLevels();\n\t\tconst currentIndex = levels.indexOf(this.thinkingLevel);\n\t\tconst nextIndex = (currentIndex + 1) % levels.length;\n\t\tconst nextLevel = levels[nextIndex];\n\n\t\tawait this.setThinkingLevel(nextLevel);\n\t\treturn nextLevel;\n\t}\n\n\tgetAvailableThinkingLevels(): ThinkingLevel[] {\n\t\tif (!this.model) return THINKING_LEVELS;\n\t\treturn getSupportedThinkingLevels(this.model) as ThinkingLevel[];\n\t}\n\n\tsupportsThinking(): boolean {\n\t\treturn !!this.model?.reasoning;\n\t}\n\n\tprivate _getThinkingLevelForModelSwitch(explicitLevel?: ThinkingLevel): ThinkingLevel {\n\t\tif (explicitLevel !== undefined) {\n\t\t\treturn explicitLevel;\n\t\t}\n\t\tif (!this.supportsThinking()) {\n\t\t\treturn this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t\t}\n\t\treturn this.thinkingLevel;\n\t}\n\n\tprivate _clampThinkingLevel(level: ThinkingLevel, _availableLevels: ThinkingLevel[]): ThinkingLevel {\n\t\treturn this.model ? (clampThinkingLevel(this.model, level) as ThinkingLevel) : \"off\";\n\t}\n\n\tprivate _captureKernelResource(): OwnedResourceCapture {\n\t\tconst provisioner = this._ipythonKernelProvisioner;\n\t\tconst captured = provisioner ? captureOwnedKernelState.call(provisioner) : undefined;\n\t\treturn Object.freeze({\n\t\t\tenabled: this._contextEpochsEnabled,\n\t\t\tsnapshot:\n\t\t\t\tcaptured?.snapshot ??\n\t\t\t\tObject.freeze({\n\t\t\t\t\tsource: \"unobserved\" as const,\n\t\t\t\t\towner: null,\n\t\t\t\t\tgeneration: null,\n\t\t\t\t\tstate: \"unobserved\" as const,\n\t\t\t\t}),\n\t\t\tisCurrent: () => this._ipythonKernelProvisioner === provisioner && (captured?.isCurrent() ?? true),\n\t\t});\n\t}\n\n\tprivate async _syncKernelStateAfterCompaction(owner = this._captureCompactionOwner()): Promise<void> {\n\t\tthis._assertCompactionOwner(owner);\n\t\tconst provisioner = owner.provisioner;\n\t\tif (!provisioner?.hasRunningKernel) return;\n\t\tconst pruned = await provisioner.pruneOversizedVariables().catch(() => null);\n\t\tthis._assertCompactionOwner(owner);\n\t\tconst abort = new AbortController();\n\t\tconst timer = setTimeout(() => abort.abort(), KERNEL_STATE_LISTING_TIMEOUT_MS);\n\t\tif (typeof timer === \"object\" && \"unref\" in timer) timer.unref();\n\t\tlet names: string[] | null;\n\t\ttry {\n\t\t\tnames = await provisioner.listNamespaceNames(abort.signal).catch(() => null);\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t\tthis._assertCompactionOwner(owner);\n\t\tif (names === null && !provisioner.hasRunningKernel) return;\n\t\tconst detail =\n\t\t\tnames === null\n\t\t\t\t? \"\"\n\t\t\t\t: names.length > 0\n\t\t\t\t\t? ` These names are still defined: ${names.join(\", \")}.`\n\t\t\t\t\t: \" You have not defined any names yet.\";\n\t\tconst prunedDetail =\n\t\t\tpruned && pruned.length > 0\n\t\t\t\t? ` Variables above the per-variable snapshot limit were removed: ${pruned.join(\", \")}.`\n\t\t\t\t: \"\";\n\t\tconst content = [\n\t\t\t\"<ipython_state>\",\n\t\t\t`Your Python kernel persisted through compaction; its remaining variables, imports, and helpers are still available.${prunedDetail}${detail}`,\n\t\t\t\"</ipython_state>\",\n\t\t].join(\"\\n\");\n\t\tconst message = {\n\t\t\trole: \"custom\" as const,\n\t\t\tcustomType: \"ipython_state\",\n\t\t\tcontent,\n\t\t\tdisplay: false,\n\t\t\ttimestamp: Date.now(),\n\t\t} satisfies CustomMessage;\n\t\tawait owner.manager.appendCustomMessageEntry(message.customType, message.content, message.display, undefined);\n\t\tthis._assertCompactionOwner(owner);\n\t\tconst messages = owner.agent.state.messages;\n\t\tconst last = messages[messages.length - 1];\n\t\tconst insertBeforeError = last?.role === \"assistant\" && (last as AssistantMessage).stopReason === \"error\";\n\t\tif (insertBeforeError) {\n\t\t\tmessages.splice(messages.length - 1, 0, message);\n\t\t} else {\n\t\t\tmessages.push(message);\n\t\t}\n\t\tthis._emit({ type: \"message_start\", message });\n\t\tthis._emit({ type: \"message_end\", message });\n\t}\n\n\tprivate _onIpythonStateRestored(result: RestoreResult): void {\n\t\tconst lines = [\"<ipython_state_restored>\"];\n\t\tif (result.restored.length > 0) {\n\t\t\tlines.push(\n\t\t\t\t`Your Python kernel state was revived from your previous session. These names are available again: ${result.restored.join(\", \")}.`,\n\t\t\t);\n\t\t} else {\n\t\t\tlines.push(\n\t\t\t\t\"Your previous Python kernel state could not be revived; the kernel is starting fresh, so re-create any variables, imports, or loaded data you need.\",\n\t\t\t);\n\t\t}\n\t\tif (result.failed.length > 0) {\n\t\t\tlines.push(\n\t\t\t\t`These could not be restored and must be recreated if needed: ${result.failed.map((f) => f.name).join(\", \")}.`,\n\t\t\t);\n\t\t}\n\t\tlines.push(\"</ipython_state_restored>\");\n\t\tvoid this.sendCustomMessage(\n\t\t\t{\n\t\t\t\tcustomType: IPYTHON_STATE_RESTORED_CUSTOM_TYPE,\n\t\t\t\tcontent: lines.join(\"\\n\"),\n\t\t\t\tdisplay: true,\n\t\t\t\tdetails: { restored: result.restored.length > 0 },\n\t\t\t},\n\t\t\t{ deliverAs: \"nextTurn\" },\n\t\t).catch(() => {});\n\t}\n\n\tsetSteeringMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.agent.steeringMode = mode;\n\t\tthis.settingsManager.setSteeringMode(mode);\n\t}\n\n\tsetFollowUpMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.agent.followUpMode = mode;\n\t\tthis.settingsManager.setFollowUpMode(mode);\n\t}\n\n\tasync compact(customInstructions?: string, options: { skipAbort?: boolean } = {}): Promise<CompactionResult> {\n\t\tthis._assertContextOptimizationAllowed();\n\t\treturn this._retainContextOptimization(this._compactAccepted(customInstructions, options));\n\t}\n\n\tprivate _resolveCompactionModel(): { model: Model<Api>; thinkingLevel: ThinkingLevel } | undefined {\n\t\tconst selection = this.settingsManager.getCompactionModel();\n\t\tif (selection === undefined) {\n\t\t\tconst model = this.model;\n\t\t\treturn model ? { model: { ...model, cost: { ...model.cost } }, thinkingLevel: this.thinkingLevel } : undefined;\n\t\t}\n\t\tif (\n\t\t\t!selection ||\n\t\t\ttypeof selection !== \"object\" ||\n\t\t\tArray.isArray(selection) ||\n\t\t\ttypeof selection.provider !== \"string\" ||\n\t\t\t!selection.provider.trim() ||\n\t\t\ttypeof selection.modelId !== \"string\" ||\n\t\t\t!selection.modelId.trim() ||\n\t\t\ttypeof selection.thinkingLevel !== \"string\"\n\t\t)\n\t\t\tthrow new Error(\"Invalid compaction.model; expected provider, modelId, and thinkingLevel\");\n\t\tconst model = this._modelRegistry.find(selection.provider, selection.modelId);\n\t\tif (!model) throw new Error(`Unknown compaction.model ${selection.provider}/${selection.modelId}`);\n\t\tif (!getSupportedThinkingLevels(model).includes(selection.thinkingLevel))\n\t\t\tthrow new Error(\n\t\t\t\t`compaction.model thinkingLevel ${selection.thinkingLevel} is not supported by ${selection.provider}/${selection.modelId}`,\n\t\t\t);\n\t\treturn { model: structuredClone(model), thinkingLevel: selection.thinkingLevel };\n\t}\n\n\tprivate async _compactAccepted(\n\t\tcustomInstructions?: string,\n\t\toptions: { skipAbort?: boolean } = {},\n\t): Promise<CompactionResult> {\n\t\tif (this._compactionSetupFailure) throw this._compactionSetupFailure;\n\t\tif (options.skipAbort && this.isStreaming) {\n\t\t\tthrow new Error(\"Cannot compact without aborting while the agent is running.\");\n\t\t}\n\t\tconst sourceOwner = this._captureCompactionOwner();\n\t\tconst consumedRequest = this._pendingRequestedCompaction;\n\t\tconst requestedWasCurrent =\n\t\t\tconsumedRequest !== undefined && this._isCompactionOwnerCurrent(consumedRequest.owner);\n\t\tconst savedResume = this._postCompactionContinuationScheduled\n\t\t\t? this._postCompactionContinuationSettlement?.resume\n\t\t\t: undefined;\n\t\tconst carryResume = savedResume !== undefined && this._isCompactionOwnerCurrent(savedResume.owner);\n\t\tthis._disconnectFromAgent();\n\t\t// Only this operation's own abort advances its control epoch. Do not adopt an epoch after the wait.\n\t\tconst originalOwner = carryResume ? savedResume.owner : requestedWasCurrent ? consumedRequest.owner : sourceOwner;\n\t\tconst owner = {\n\t\t\t...originalOwner,\n\t\t\tsignal: undefined,\n\t\t\tpumpEpoch: sourceOwner.pumpEpoch + (options.skipAbort ? 0 : 1),\n\t\t};\n\t\tif (!options.skipAbort) await this.abort();\n\t\tif (!this._isCompactionOwnerCurrent(owner)) {\n\t\t\tif (this._isCompactionSourceOwnerCurrent(owner)) this._reconnectToAgent();\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t}\n\t\tconst resume = carryResume ? { ...savedResume, owner } : undefined;\n\t\tconst checkpoint = resume ?? { owner, actions: [] };\n\t\tthis._pendingCheckpoint = checkpoint;\n\t\tif (requestedWasCurrent && this._pendingRequestedCompaction === consumedRequest) {\n\t\t\tconsumedRequest.owner = { ...consumedRequest.owner, pumpEpoch: owner.pumpEpoch, signal: undefined };\n\t\t}\n\t\tlet didCompact = false;\n\t\tlet requests: InferenceCoordinator | undefined;\n\t\tlet compaction: BoundCompactionSink | undefined;\n\t\tlet committed: CompactionCommit | undefined;\n\t\tlet failure: unknown;\n\t\tconst abort = new AbortController();\n\t\tthis._compactionAbortController = abort;\n\t\tlet resolveCompactionOperation: () => void = () => {};\n\t\tconst compactionOperation = new Promise<void>((resolve) => {\n\t\t\tresolveCompactionOperation = resolve;\n\t\t});\n\t\tthis._compactionOperation = compactionOperation;\n\t\tthis._emit({\n\t\t\ttype: \"compaction_start\",\n\t\t\treason: \"manual\",\n\t\t\tcustomInstructions,\n\t\t});\n\n\t\ttry {\n\t\t\tconst selected = this._resolveCompactionModel();\n\t\t\tif (!selected) {\n\t\t\t\tthrow new Error(formatNoModelSelectedMessage());\n\t\t\t}\n\n\t\t\tconst { model, thinkingLevel } = selected;\n\t\t\tconst settings = { ...this.settingsManager.getCompactionSettings() };\n\t\t\tconst semanticEdges = owner.semanticEdges;\n\t\t\tcompaction = owner.manager.bindCompactionSink();\n\t\t\trequests = owner.requests.capture(compaction);\n\t\t\tconst pathEntries = await compaction.readBranch();\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tconst { apiKey, headers } = await this._getRequiredRequestAuth(model);\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tcommitted = await this._performCompaction({\n\t\t\t\tmodel,\n\t\t\t\tthinkingLevel,\n\t\t\t\tpathEntries,\n\t\t\t\tsettings,\n\t\t\t\trequests,\n\t\t\t\tcompaction,\n\t\t\t\tsemanticEdges,\n\t\t\t\towner,\n\t\t\t\tapiKey,\n\t\t\t\theaders,\n\t\t\t\tcustomInstructions,\n\t\t\t\tsignal: abort.signal,\n\t\t\t\tallowShortSession: true,\n\t\t\t});\n\n\t\t\tconst result = committed.result;\n\t\t\tawait this._releaseCompactionCapture(requests, compaction, undefined, owner);\n\t\t\trequests = undefined;\n\t\t\tcompaction = undefined;\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tthis._emit({\n\t\t\t\ttype: \"compaction_end\",\n\t\t\t\treason: \"manual\",\n\t\t\t\tresult,\n\t\t\t\taborted: false,\n\t\t\t\twillRetry: false,\n\t\t\t\tcustomInstructions,\n\t\t\t});\n\t\t\tdidCompact = true;\n\t\t\t// A manual compaction satisfies any pending model request; on failure the\n\t\t\t// request stays scheduled for the next turn boundary.\n\t\t\tif (this._pendingRequestedCompaction === consumedRequest) this._pendingRequestedCompaction = undefined;\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tconst primaryCommit = primaryCommittedCompactionError(error);\n\t\t\tconst knownCommit = primaryCommit ?? committed;\n\t\t\tfailure =\n\t\t\t\tknownCommit && !(error instanceof CompactionCommittedError)\n\t\t\t\t\t? new CompactionCommittedError(knownCommit.entryId, knownCommit.result, error)\n\t\t\t\t\t: error;\n\t\t\tif (failure instanceof CompactionCommittedError) {\n\t\t\t\tif (this._pendingRequestedCompaction === consumedRequest) this._pendingRequestedCompaction = undefined;\n\t\t\t\tthis._reportCommittedCompactionFailure(failure, \"manual\", customInstructions, owner);\n\t\t\t\tthrow failure;\n\t\t\t}\n\t\t\tif (!this._isCompactionSourceOwnerCurrent(owner)) throw error;\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tconst aborted = message === \"Compaction cancelled\" || (error instanceof Error && error.name === \"AbortError\");\n\t\t\tconst skipped = error instanceof CompactionSkippedError;\n\t\t\tthis._emit({\n\t\t\t\ttype: \"compaction_end\",\n\t\t\t\treason: \"manual\",\n\t\t\t\tresult: undefined,\n\t\t\t\taborted,\n\t\t\t\twillRetry: false,\n\t\t\t\terrorMessage: aborted ? undefined : skipped ? message : `Compaction failed: ${message}`,\n\t\t\t\terrorSeverity: skipped ? \"warning\" : \"error\",\n\t\t\t\tcustomInstructions,\n\t\t\t});\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait this._releaseCompactionCapture(requests, compaction, failure, owner);\n\t\t\t} finally {\n\t\t\t\tif (this._pendingCheckpoint === checkpoint) this._pendingCheckpoint = undefined;\n\t\t\t\tif (this._compactionAbortController === abort) this._compactionAbortController = undefined;\n\t\t\t\tif (this._isCompactionSourceOwnerCurrent(owner)) this._reconnectToAgent();\n\t\t\t\tif (this._compactionOperation === compactionOperation) {\n\t\t\t\t\tthis._compactionOperation = undefined;\n\t\t\t\t}\n\t\t\t\tresolveCompactionOperation();\n\t\t\t\tif (this._isCompactionOwnerCurrent(owner)) {\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t\t}\n\t\t\t\tif (didCompact && this._isCompactionOwnerCurrent(owner)) {\n\t\t\t\t\tthis._discardPendingAutoRefine({ cancelPostCompactionContinue: true });\n\t\t\t\t\tif (resume) {\n\t\t\t\t\t\tthis._schedulePostCompactionContinue(resume);\n\t\t\t\t\t}\n\t\t\t\t\t// Queued agent or session-owned inputs resume the loop; defer refine\n\t\t\t\t\t// behind them instead of interleaving it before their turns.\n\t\t\t\t\tthis._scheduleAutoRefineAfterCompaction(\n\t\t\t\t\t\tresume !== undefined || this.agent.hasQueuedMessages() || this.unfinishedActionCount > 0,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** A private compiled context keeps extension summary edits separate from retained source recipes. */\n\tprivate async _prepareCapturedCompaction(\n\t\tpathEntries: SessionEntry[],\n\t\tsettings: ReturnType<SettingsManager[\"getCompactionSettings\"]>,\n\t\trequests: InferenceCoordinator,\n\t\tcompaction: BoundCompactionSink,\n\t\towner = this._captureCompactionOwner(),\n\t\tallowShortSession = false,\n\t\tbudgetPressure = false,\n\t\tcapacity?: PublicContextBudgetError,\n\t): Promise<{\n\t\tpreparation: CompactionPreparation | undefined;\n\t\tmessages?: readonly AgentMessage[];\n\t\tresource?: OwnedResourceCapture;\n\t\tmaxSourceBytes: number;\n\t}> {\n\t\tthis._assertCompactionOwner(owner);\n\t\tconst limits = this.settingsManager.getCanonicalContextLimits();\n\t\tconst resource = this._captureKernelResource();\n\t\tconst source = await compaction.source;\n\t\tthis._assertCompactionOwner(owner);\n\t\tif (!source.persistent)\n\t\t\treturn {\n\t\t\t\tpreparation: prepareCompaction(pathEntries, settings, allowShortSession),\n\t\t\t\tmaxSourceBytes: limits.maxSourceBytes,\n\t\t\t};\n\t\treturn requests.readHistory(async (view) => {\n\t\t\tconst messages = await new CanonicalContextCompiler().compile(\n\t\t\t\tview,\n\t\t\t\tlimits,\n\t\t\t\tundefined,\n\t\t\t\t{},\n\t\t\t\tresource,\n\t\t\t\tthis._initialContextMode,\n\t\t\t\tfalse,\n\t\t\t\t\"read\",\n\t\t\t);\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tconst context = getCanonicalEpochContext(messages)!;\n\t\t\tif (context.checkpoint?.includeSummary && pathEntries.at(-1)?.type === \"compaction\")\n\t\t\t\treturn { preparation: undefined, maxSourceBytes: limits.maxSourceBytes };\n\t\t\tconst authorization = getRecoveryCompactionAuthorization(capacity);\n\t\t\tconst boundary = canonicalRecoveryBoundary(messages, authorization);\n\t\t\tconst preparation =\n\t\t\t\tbudgetPressure || context.checkpoint || boundary\n\t\t\t\t\t? prepareViewCompaction(\n\t\t\t\t\t\t\tmessages,\n\t\t\t\t\t\t\tcontext.references.map((ref) => ref?.ref.entryId),\n\t\t\t\t\t\t\tpathEntries,\n\t\t\t\t\t\t\tsettings,\n\t\t\t\t\t\t\tboundary,\n\t\t\t\t\t\t\tallowShortSession,\n\t\t\t\t\t\t\tbudgetPressure,\n\t\t\t\t\t\t)\n\t\t\t\t\t: prepareCompaction(pathEntries, settings, allowShortSession);\n\t\t\t// Refuse unsupported public data or open groups before starting the summary model call.\n\t\t\tif (preparation)\n\t\t\t\tprepareRecoveryCompaction(messages, preparation.firstKeptEntryId, limits.maxSourceBytes, authorization);\n\t\t\treturn {\n\t\t\t\tpreparation,\n\t\t\t\tmessages,\n\t\t\t\tresource: context.resourceRevision !== undefined ? resource : undefined,\n\t\t\t\tmaxSourceBytes: limits.maxSourceBytes,\n\t\t\t};\n\t\t});\n\t}\n\n\t/**\n\t * Shared compaction core behind /compact, auto-compaction, and the compact\n\t * skill. Throws CompactionSkippedError when there is nothing to compact and\n\t * Error(\"Compaction cancelled\") on abort or extension cancel.\n\t */\n\tprivate async _performCompaction(options: {\n\t\tmodel: Model<any>;\n\t\tapiKey: string;\n\t\theaders?: Record<string, string>;\n\t\tcustomInstructions?: string;\n\t\tsignal: AbortSignal;\n\t\tthinkingLevel: ThinkingLevel;\n\t\trequests: InferenceCoordinator;\n\t\tcompaction: BoundCompactionSink;\n\t\tsemanticEdges: SemanticEdgeRecorder;\n\t\towner?: CompactionOwner;\n\t\tpathEntries: Awaited<ReturnType<SessionManager[\"readBranch\"]>>;\n\t\tsettings: ReturnType<SettingsManager[\"getCompactionSettings\"]>;\n\t\tallowShortSession?: boolean;\n\t\tbudgetPressure?: boolean;\n\t\tcapacity?: PublicContextBudgetError;\n\t}): Promise<CompactionCommit> {\n\t\tconst {\n\t\t\tmodel,\n\t\t\tapiKey,\n\t\t\theaders,\n\t\t\tcustomInstructions,\n\t\t\tsignal,\n\t\t\tthinkingLevel,\n\t\t\trequests,\n\t\t\tcompaction,\n\t\t\tsemanticEdges,\n\t\t\tpathEntries,\n\t\t\tsettings,\n\t\t\towner = this._captureCompactionOwner(),\n\t\t\tallowShortSession = false,\n\t\t\tbudgetPressure = false,\n\t\t} = options;\n\n\t\tconst prepared = await this._prepareCapturedCompaction(\n\t\t\tpathEntries,\n\t\t\tsettings,\n\t\t\trequests,\n\t\t\tcompaction,\n\t\t\towner,\n\t\t\tallowShortSession,\n\t\t\tbudgetPressure,\n\t\t\toptions.capacity,\n\t\t);\n\t\tthis._assertCompactionOwner(owner);\n\t\tif (prepared.resource) assertResourceCurrent(prepared.resource);\n\t\tconst preparation = prepared.preparation;\n\t\tif (!preparation) {\n\t\t\tconst lastEntry = pathEntries[pathEntries.length - 1];\n\t\t\tif (lastEntry?.type === \"compaction\") {\n\t\t\t\tthrow new CompactionSkippedError(\"Already compacted\");\n\t\t\t}\n\t\t\tthrow new CompactionSkippedError(\"Session is too short to compact — try again once it grows\");\n\t\t}\n\n\t\tlet extensionCompaction: CompactionResult | undefined;\n\t\tlet nativeCompaction: CompactionResult | undefined;\n\t\tlet fromExtension = false;\n\n\t\tconst semanticCompaction = semanticEdges.beginCompaction();\n\t\tlet committed: CompactionCommit | undefined;\n\t\tconst uncommittedSlices: string[] = [];\n\t\tlet compactionSettled = false;\n\t\tlet summary: string;\n\t\tlet firstKeptEntryId: string;\n\t\tlet tokensBefore: number | null;\n\t\tlet details: CompactionResult[\"details\"];\n\t\tlet usage: CompactionResult[\"usage\"];\n\t\tlet savedCompactionId: string;\n\t\ttry {\n\t\t\tif (owner.extensions.hasHandlers(\"session_before_compact\")) {\n\t\t\t\tconst result = (await owner.extensions.emit({\n\t\t\t\t\ttype: \"session_before_compact\",\n\t\t\t\t\tpreparation,\n\t\t\t\t\tbranchEntries: pathEntries,\n\t\t\t\t\tcustomInstructions,\n\t\t\t\t\tsignal,\n\t\t\t\t})) as SessionBeforeCompactResult | undefined;\n\n\t\t\t\tthis._assertCompactionOwner(owner);\n\t\t\t\tif (result?.cancel) {\n\t\t\t\t\tthrow new Error(\"Compaction cancelled\");\n\t\t\t\t}\n\n\t\t\t\tif (result?.compaction) {\n\t\t\t\t\textensionCompaction = result.compaction;\n\t\t\t\t\tfromExtension = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (extensionCompaction) {\n\t\t\t\t({ summary, firstKeptEntryId, tokensBefore, details, usage } = extensionCompaction);\n\t\t\t} else {\n\t\t\t\t// Each summary wire call gets its own request ID: split turns send two\n\t\t\t\t// different bodies, and one Idempotency-Key must never cover both. A slice\n\t\t\t\t// that succeeds on the wire stays uncommitted until the compaction itself\n\t\t\t\t// commits: a racing sibling's failure (or an abort) must leave no committed\n\t\t\t\t// summary request for the next turn's continuation edge to attach to.\n\t\t\t\tconst summaryCall = async <T>(\n\t\t\t\t\tcall: (callHeaders: Record<string, string> | undefined) => Promise<T>,\n\t\t\t\t): Promise<T> => {\n\t\t\t\t\tconst requestId = semanticEdges.startCompactionRequest(semanticCompaction.compactionId);\n\t\t\t\t\tif (requestId === undefined) {\n\t\t\t\t\t\treturn call(headers);\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await call({ ...headers, ...modelRequestHeaders(requestId) });\n\t\t\t\t\t\t// A slice resolving after a sibling's rejection already settled the\n\t\t\t\t\t\t// compaction would push into a drained list and stay in-flight forever.\n\t\t\t\t\t\tif (compactionSettled) {\n\t\t\t\t\t\t\tsemanticEdges.failRequest(requestId);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tuncommittedSlices.push(requestId);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tsemanticEdges.failRequest(requestId);\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tconst summaryRequests = requests[captureNativeCompactionRequests]();\n\t\t\t\tlet summaryFailure: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tnativeCompaction = await compact(\n\t\t\t\t\t\tpreparation,\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tapiKey,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tcustomInstructions,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\tthinkingLevel,\n\t\t\t\t\t\tsummaryCall,\n\t\t\t\t\t\tsummaryRequests,\n\t\t\t\t\t\toptions.capacity\n\t\t\t\t\t\t\t? (wrapper) =>\n\t\t\t\t\t\t\t\t\toptions.capacity!.remainingSummaryTokens(\n\t\t\t\t\t\t\t\t\t\tnew Set(\n\t\t\t\t\t\t\t\t\t\t\tpathEntries\n\t\t\t\t\t\t\t\t\t\t\t\t.slice(pathEntries.findIndex((entry) => entry.id === preparation.firstKeptEntryId))\n\t\t\t\t\t\t\t\t\t\t\t\t.map((entry) => entry.id),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\twrapper,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t);\n\t\t\t\t\t({ summary, firstKeptEntryId, tokensBefore, details, usage } = nativeCompaction);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tsummaryFailure = error;\n\t\t\t\t\tthrow error;\n\t\t\t\t} finally {\n\t\t\t\t\tawait this._releaseCompactionCapture(summaryRequests, undefined, summaryFailure, owner);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (signal.aborted) {\n\t\t\t\tthrow new Error(\"Compaction cancelled\");\n\t\t\t}\n\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tconst result: CompactionResult = JSON.parse(\n\t\t\t\tJSON.stringify({ summary, firstKeptEntryId, tokensBefore, details }),\n\t\t\t);\n\t\t\tconst recovery = prepared.messages\n\t\t\t\t? prepareRecoveryCompaction(\n\t\t\t\t\t\tprepared.messages,\n\t\t\t\t\t\tfirstKeptEntryId,\n\t\t\t\t\t\tprepared.maxSourceBytes,\n\t\t\t\t\t\tgetRecoveryCompactionAuthorization(options.capacity),\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\t\tif (prepared.resource) assertResourceCurrent(prepared.resource);\n\t\t\tif (recovery) {\n\t\t\t\tif (\n\t\t\t\t\tresult.details !== undefined &&\n\t\t\t\t\t(!result.details || typeof result.details !== \"object\" || Array.isArray(result.details))\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Recovery compaction details require an object\");\n\t\t\t\tconst recoveryDetails = { ...result.details, [CONTEXT_EPOCH_DETAIL]: recovery };\n\t\t\t\tresult.details = recoveryDetails;\n\t\t\t\tsavedCompactionId = await compaction[appendContextEpoch](\n\t\t\t\t\trecovery,\n\t\t\t\t\ttokensBefore,\n\t\t\t\t\t{\n\t\t\t\t\t\tsummary,\n\t\t\t\t\t\tdetails: recoveryDetails,\n\t\t\t\t\t\tfromHook: fromExtension,\n\t\t\t\t\t\tcustomInstructions,\n\t\t\t\t\t\tusage,\n\t\t\t\t\t},\n\t\t\t\t\tnativeCompaction,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tsavedCompactionId = await compaction.appendCompaction(\n\t\t\t\t\tsummary,\n\t\t\t\t\tfirstKeptEntryId,\n\t\t\t\t\ttokensBefore,\n\t\t\t\t\tresult.details,\n\t\t\t\t\tfromExtension,\n\t\t\t\t\tcustomInstructions,\n\t\t\t\t\tusage,\n\t\t\t\t\tnativeCompaction,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Only the canonical append ACK commits summary slices and advances the semantic epoch.\n\t\t\tcommitted = { entryId: savedCompactionId, result };\n\t\t\tcompactionSettled = true;\n\t\t\tfor (const requestId of uncommittedSlices.splice(0)) {\n\t\t\t\tsemanticEdges.finishRequest(requestId);\n\t\t\t}\n\t\t\tsemanticEdges.finishCompaction(semanticCompaction.compactionId, \"completed\");\n\t\t\tif (prepared.resource) assertResourceCurrent(prepared.resource);\n\t\t} catch (error) {\n\t\t\tcompactionSettled = true;\n\t\t\tif (committed) throw new CompactionCommittedError(committed.entryId, committed.result, error);\n\t\t\tfor (const requestId of uncommittedSlices.splice(0)) {\n\t\t\t\tsemanticEdges.failRequest(requestId);\n\t\t\t}\n\t\t\tconst cancelled =\n\t\t\t\terror instanceof Error && (error.name === \"AbortError\" || error.message === \"Compaction cancelled\");\n\t\t\tsemanticEdges.finishCompaction(semanticCompaction.compactionId, cancelled ? \"cancelled\" : \"failed\");\n\t\t\tthrow error;\n\t\t}\n\t\ttry {\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tconst bootstrap = await readSessionBootstrap(owner.manager, this.settingsManager.getCanonicalContextLimits(), {\n\t\t\t\tpurpose: \"read\",\n\t\t\t\tinitialContextMode: this._initialContextMode,\n\t\t\t});\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\towner.agent.state.messages = bootstrap.context.messages;\n\t\t\tthis._contextOmissions = undefined;\n\t\t\tthis._mergeUnpersistedOutcomes(owner.agent.state.messages);\n\t\t\tthis._restoreLateIpythonSentAgentMessages();\n\n\t\t\tconst savedCompactionEntry = await owner.manager.readEntry(savedCompactionId);\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tif (savedCompactionEntry?.type === \"compaction\") {\n\t\t\t\tawait owner.extensions.emit({\n\t\t\t\t\ttype: \"session_compact\",\n\t\t\t\t\tcompactionEntry: savedCompactionEntry,\n\t\t\t\t\tfromExtension,\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tif (!prepared.resource) await this._syncKernelStateAfterCompaction(owner);\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tawait this._reapDeletedRlmSubagentRuntimesAfterCompaction();\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t} catch (error) {\n\t\t\tthrow new CompactionCommittedError(committed!.entryId, committed!.result, error);\n\t\t}\n\t\treturn committed!;\n\t}\n\n\tprivate _reportCommittedCompactionFailure(\n\t\terror: CompactionCommittedError,\n\t\treason: CompactionReason,\n\t\tcustomInstructions?: string,\n\t\towner?: CompactionOwner,\n\t): void {\n\t\tif (owner && !this._isCompactionSourceOwnerCurrent(owner)) return;\n\t\tthis._compactionSetupFailure = error;\n\t\tthis._sessionInputPumpRequested = false;\n\t\tthis._sessionInputPumpEpoch++;\n\t\tthis._sessionInputPumpSuspended = true;\n\t\tthis._settlePostCompactionContinue(error);\n\t\tthis._discardPendingAutoRefine({ cancelPostCompactionContinue: true });\n\t\tthis._autoRefineBranchVersion++;\n\t\tthis._resolveRetry();\n\t\tthis._emit({\n\t\t\ttype: \"compaction_end\",\n\t\t\treason,\n\t\t\tresult: error.result,\n\t\t\taborted: false,\n\t\t\twillRetry: false,\n\t\t\terrorMessage: error.message,\n\t\t\terrorSeverity: \"error\",\n\t\t\tcustomInstructions,\n\t\t});\n\t}\n\n\tprivate async _releaseCompactionCapture(\n\t\trequests: InferenceCoordinator | undefined,\n\t\tcompaction: BoundCompactionSink | undefined,\n\t\tfailure: unknown,\n\t\towner?: CompactionOwner,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tif (requests) await requests.dispose();\n\t\t\telse await compaction?.release();\n\t\t} catch (cleanupError) {\n\t\t\tif (failure instanceof CompactionCommittedError) {\n\t\t\t\tif (cleanupError === failure || cleanupError === failure.cause) throw failure;\n\t\t\t\tconst combined = new CompactionCommittedError(\n\t\t\t\t\tfailure.entryId,\n\t\t\t\t\tfailure.result,\n\t\t\t\t\tnew AggregateError([failure.cause, cleanupError], \"Compaction setup and source release failed\"),\n\t\t\t\t);\n\t\t\t\tif ((!owner || this._isCompactionSourceOwnerCurrent(owner)) && this._compactionSetupFailure === failure)\n\t\t\t\t\tthis._compactionSetupFailure = combined;\n\t\t\t\tthrow combined;\n\t\t\t}\n\t\t\tif (failure !== undefined && failure !== cleanupError)\n\t\t\t\tthrow new AggregateError([failure, cleanupError], \"Compaction and source release failed\");\n\t\t\tthrow cleanupError;\n\t\t}\n\t}\n\n\tprivate async _reapDeletedRlmSubagentRuntimesAfterCompaction(): Promise<void> {\n\t\tconst childIds = [...this._rlmChildCleanupFailures.keys()].filter(\n\t\t\t(childId) => !this._activeRlmChildRuns.get(childId)?.detachedDeletion,\n\t\t);\n\t\tawait Promise.allSettled(childIds.map((childId) => this.deleteRlmSubagent(childId)));\n\t}\n\n\tabortCompaction(): void {\n\t\tthis._compactionAbortController?.abort();\n\t\tthis._autoCompactionAbortController?.abort();\n\t}\n\n\tprivate _localHarnessStateDir(): string | undefined {\n\t\treturn (\n\t\t\tgetLocalHarnessStateDir(this.sessionManager.getSessionArtifactDir()) ??\n\t\t\t(this._rlmSessionDir ? getLocalHarnessStateDir(this._rlmSessionDir) : undefined)\n\t\t);\n\t}\n\n\tprivate _autoRefineAllowedForSession(): boolean {\n\t\treturn this._rlmDepth === 0 && this._localHarnessStateDir() !== undefined;\n\t}\n\n\tprivate _newAutoRefineAllowed(): boolean {\n\t\treturn (\n\t\t\tthis._contextOptimizationAllowed() && !this._autoRefineAdmissionClosed && this._autoRefineAllowedForSession()\n\t\t);\n\t}\n\n\tprivate _settlePostCompactionContinue(error?: Error): void {\n\t\tif (!error && this._postCompactionContinuationScheduled) return;\n\t\tif (error) this._postCompactionContinuationScheduled = false;\n\t\tconst settlement = this._postCompactionContinuationSettlement;\n\t\tif (!settlement || settlement.settled) return;\n\t\tsettlement.settled = true;\n\t\tthis._postCompactionContinuationSettlement = undefined;\n\t\tif (error) settlement.reject(error);\n\t\telse settlement.resolve();\n\t\tthis._notifySessionInputCheckpointChange();\n\t}\n\n\tprivate _cancelPostCompactionContinue(): void {\n\t\tthis._postCompactionContinuationScheduled = false;\n\t\tthis._settlePostCompactionContinue();\n\t}\n\n\tprivate _discardPendingAutoRefine(options: { cancelPostCompactionContinue?: boolean } = {}): void {\n\t\tthis._compactAutoRefinePending = false;\n\t\tthis._turnIntervalAutoRefinePending = false;\n\t\tthis._pendingAutoRefineReview = undefined;\n\t\tif (options.cancelPostCompactionContinue) {\n\t\t\tthis._cancelPostCompactionContinue();\n\t\t}\n\t}\n\n\tprivate async _invalidatePendingAutoRefineForBranchChange(): Promise<void> {\n\t\tthis._autoRefineReviewAbort?.abort();\n\t\tthis._discardPendingAutoRefine({ cancelPostCompactionContinue: true });\n\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t// Increment branch version BEFORE aborting/awaiting the serialized plan.\n\t\t// This invalidates the plan's branchVersion check at the boundary\n\t\t// so even if the plan completes, the boundary will reject it\n\t\t// (bgResult.branchVersion !== this._autoRefineBranchVersion).\n\t\tthis._autoRefineBranchVersion++;\n\t\t// Abort the in-flight refine/bplan controller so any pending\n\t\t// _planRefine or _reviewAutoRefine call settles via signal abort\n\t\t// rather than hanging forever.\n\t\tthis._refineAbortController?.abort();\n\t\tif (this._serializedPlanInFlight) {\n\t\t\tawait this._consumeSerializedBackgroundPlan(async () => false);\n\t\t}\n\t\twhile (this._refinePlanInFlight) {\n\t\t\tawait this._refinePlanInFlight;\n\t\t}\n\t\tawait this._waitForRefineIdle();\n\t}\n\n\t/**\n\t * Consume a refine request that was scheduled by the agent-callable refine\n\t * skill (refine.run). Fire-and-forget: the refine() method handles its own\n\t * background planning, idle wait, application, and error recovery. Called\n\t * at the turn boundary after compaction checks and before auto-refine\n\t * scheduling so the manual request takes priority.\n\t */\n\tprivate _emitRefineFailed(error: unknown): void {\n\t\tthis._emit({\n\t\t\ttype: \"refine_failed\",\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t});\n\t}\n\n\tprivate _consumePendingRequestedRefine(): boolean {\n\t\tconst pending = this._pendingRequestedRefine;\n\t\tif (!pending) return false;\n\t\tthis._pendingRequestedRefine = undefined;\n\t\tvoid this.refine(pending).catch((error) => this._emitRefineFailed(error));\n\t\treturn true;\n\t}\n\n\tprivate _scheduleAutoRefineAfterAgentEnd(): void {\n\t\tif (this._compactionSetupFailure) return;\n\t\tif (!this._newAutoRefineAllowed()) {\n\t\t\treturn;\n\t\t}\n\t\tif (this._pendingAutoRefineReview) {\n\t\t\tthis._scheduleAutoRefine(this._pendingAutoRefineReview.reason);\n\t\t\treturn;\n\t\t}\n\t\tif (this._compactAutoRefinePending) {\n\t\t\tif (this._postCompactionContinuationScheduled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._scheduleAutoRefine(\"compact\");\n\t\t\treturn;\n\t\t}\n\n\t\tthis._scheduleAutoRefine(\"turn_interval\");\n\t}\n\n\tprivate _scheduleAutoRefineAfterCompaction(willContinueAfterCompaction: boolean): void {\n\t\tif (!this._newAutoRefineAllowed()) {\n\t\t\treturn;\n\t\t}\n\t\tif (this._serializedRefine) {\n\t\t\t// Serialized sessions must service compaction-triggered refinement at\n\t\t\t// shouldStopAfterTurn, never through the interactive path.\n\t\t\tthis._compactAutoRefinePending = true;\n\t\t\treturn;\n\t\t}\n\t\tif (willContinueAfterCompaction) {\n\t\t\tthis._compactAutoRefinePending = true;\n\t\t\treturn;\n\t\t}\n\n\t\tthis._scheduleAutoRefine(\"compact\");\n\t}\n\n\tprivate _schedulePostCompactionContinue(resume: CheckpointResume): void {\n\t\tif (!this._isCompactionOwnerCurrent(resume.owner)) return;\n\t\tconst previous = this._postCompactionContinuationSettlement;\n\t\tif (previous && !this._isCompactionOwnerCurrent(previous.resume.owner)) this._cancelPostCompactionContinue();\n\t\tif (!this._postCompactionContinuationSettlement || this._postCompactionContinuationSettlement.settled) {\n\t\t\tthis._postCompactionContinuationSettlement = createPostCompactionContinuationSettlement(resume);\n\t\t}\n\t\tconst settlement = this._postCompactionContinuationSettlement;\n\t\tsettlement.resume = resume;\n\t\tif (this._postCompactionContinuationScheduled) return;\n\t\tthis._postCompactionContinuationScheduled = true;\n\t\tvoid this._runScheduledPostCompactionContinue(settlement)\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (this._postCompactionContinuationSettlement === settlement)\n\t\t\t\t\tthis._settlePostCompactionContinue(this._asError(error));\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (this._postCompactionContinuationSettlement === settlement) this._settlePostCompactionContinue();\n\t\t\t});\n\t}\n\n\tprivate async _waitForQueuedWorkResume(settlement: PostCompactionContinuationSettlement): Promise<void> {\n\t\tconst resume = settlement.resume;\n\t\twhile (\n\t\t\t(this._queuedWorkPauses.size > 0 || this._sessionInputAdmissionPauses.size > 0) &&\n\t\t\tthis._postCompactionContinuationSettlement === settlement &&\n\t\t\tsettlement.resume === resume &&\n\t\t\tthis._isCompactionOwnerCurrent(resume.owner)\n\t\t) {\n\t\t\tlet resume = () => {};\n\t\t\tconst resumed = new Promise<void>((resolve) => {\n\t\t\t\tresume = resolve;\n\t\t\t\tthis._sessionInputCheckpointWaiters.add(resolve);\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tawait Promise.race([resumed, settlement.promise]);\n\t\t\t} finally {\n\t\t\t\tthis._sessionInputCheckpointWaiters.delete(resume);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async _runScheduledPostCompactionContinue(settlement: PostCompactionContinuationSettlement): Promise<void> {\n\t\twhile (this._postCompactionContinuationScheduled && this._postCompactionContinuationSettlement === settlement) {\n\t\t\tconst resume = settlement.resume;\n\t\t\tconst owner = resume.owner;\n\t\t\tconst current = () =>\n\t\t\t\tthis._postCompactionContinuationSettlement === settlement &&\n\t\t\t\tsettlement.resume === resume &&\n\t\t\t\tthis._isCompactionOwnerCurrent(owner);\n\t\t\tif (!current()) {\n\t\t\t\tthis._cancelPostCompactionContinue();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait owner.agent.waitForIdle();\n\t\t\tif (!current()) continue;\n\t\t\tawait this.waitForRetry();\n\t\t\tif (!current()) continue;\n\t\t\tconst refine = this._refineInFlight;\n\t\t\tif (refine) await refine;\n\t\t\tif (!current()) continue;\n\t\t\tawait this._waitForQueuedWorkResume(settlement);\n\t\t\tif (!current()) continue;\n\t\t\tconst compactionOperation = this._compactionOperation;\n\t\t\tif (compactionOperation) {\n\t\t\t\tawait Promise.race([compactionOperation, settlement.promise]);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst commitFence = await this._acquireSessionActionCommitFence();\n\t\t\tlet continuation: Promise<void> | undefined;\n\t\t\tlet waitForSessionInput = false;\n\t\t\ttry {\n\t\t\t\tif (!current()) continue;\n\t\t\t\tawait owner.agent.waitForIdle();\n\t\t\t\tif (!current()) continue;\n\t\t\t\tif (\n\t\t\t\t\tthis._queuedWorkPauses.size > 0 ||\n\t\t\t\t\tthis._sessionInputAdmissionPauses.size > 0 ||\n\t\t\t\t\tthis._compactionOperation ||\n\t\t\t\t\tthis._refineInFlight\n\t\t\t\t)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (this.unfinishedActionCount > 0 || this._sessionInputPumpRequested) {\n\t\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t\t\twaitForSessionInput = true;\n\t\t\t\t} else {\n\t\t\t\t\t// A released row is not a receipt. The retained ticket settles delivery and completion separately.\n\t\t\t\t\tfor (const { action, ticket } of resume.actions) {\n\t\t\t\t\t\tif (action.lifecycle.state === \"cancelled\") continue;\n\t\t\t\t\t\tif (action.lifecycle.state !== \"completed\" && action.lifecycle.state !== \"failed\") {\n\t\t\t\t\t\t\tthrow new Error(`Checkpoint action ${ticket.id} has not settled`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait ticket.completed;\n\t\t\t\t\t\tconst delivered = await ticket.delivered;\n\t\t\t\t\t\tif (delivered.status !== \"delivered\")\n\t\t\t\t\t\t\tthrow new Error(`Checkpoint action ${ticket.id} was not delivered`);\n\t\t\t\t\t\tif (!current()) break;\n\t\t\t\t\t}\n\t\t\t\t\tif (!current()) continue;\n\t\t\t\t\tif (this.hasPendingSessionWork || this._sessionInputPumpRequested) continue;\n\t\t\t\t\tthis._postCompactionContinuationScheduled = false;\n\t\t\t\t\tif (resume.boundary?.state === \"pending\" || owner.agent.hasQueuedMessages()) {\n\t\t\t\t\t\tcontinuation = owner.agent.continue();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._scheduleAutoRefineAfterAgentEnd();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tcommitFence.release();\n\t\t\t}\n\t\t\tif (waitForSessionInput) {\n\t\t\t\tawait this._waitForIdleOrSettlement(settlement);\n\t\t\t\tcontinue; // The input dispatch, not queue removal, consumes the old boundary.\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait continuation;\n\t\t\t\treturn;\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof AgentContinueError && error.code === \"busy\") {\n\t\t\t\t\tif (current()) this._postCompactionContinuationScheduled = true;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// A valid directive must not rely on a stale-tail/nothing-to-continue error to decide completion.\n\t\t\t\tif (this._postCompactionContinuationSettlement === settlement)\n\t\t\t\t\tthis._settlePostCompactionContinue(this._asError(error));\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _forgetConsumedPostCompactionContinuations(actions: QueuedSessionAction[]): void {\n\t\tthis._postCompactionContinuations = this._postCompactionContinuations.filter(\n\t\t\t(continuation) => !actions.includes(continuation.action) || this._checkpointActionPending(continuation),\n\t\t);\n\t}\n\n\tprivate _shouldSkipAutoRefineForActiveAgent(): boolean {\n\t\treturn this.isStreaming || this.isCompacting;\n\t}\n\n\tprivate _scheduleDeferredAutoRefineIfIdle(): void {\n\t\tif (this._autoRefineInProgress || this._shouldSkipAutoRefineForActiveAgent() || this._pendingAutoRefineReview) {\n\t\t\treturn;\n\t\t}\n\t\tif (this._turnIntervalAutoRefinePending) {\n\t\t\tthis._turnIntervalAutoRefinePending = false;\n\t\t\tthis._scheduleAutoRefine(\"turn_interval\");\n\t\t}\n\t}\n\n\tprivate _scheduleAutoRefine(reason: AutoRefineReason, branchVersion = this._autoRefineBranchVersion): void {\n\t\tif (this._compactionSetupFailure || !this._newAutoRefineAllowed()) return;\n\t\tconst timer = setTimeout(() => {\n\t\t\tthis._scheduledAutoRefineTimers.delete(timer);\n\t\t\tif (branchVersion !== this._autoRefineBranchVersion) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst operation = this._maybeAutoRefine(reason);\n\t\t\tthis._autoRefineOperations.add(operation);\n\t\t\tvoid operation.finally(() => this._autoRefineOperations.delete(operation)).catch(() => undefined);\n\t\t}, 0);\n\t\tthis._scheduledAutoRefineTimers.add(timer);\n\t}\n\n\tprivate async _maybeAutoRefine(reason: AutoRefineReason): Promise<void> {\n\t\tif (this._compactionSetupFailure) return;\n\t\tif (this._disposed || this._disposing) {\n\t\t\tthis._discardPendingAutoRefine();\n\t\t\treturn;\n\t\t}\n\t\tif (!this._newAutoRefineAllowed()) {\n\t\t\tthis._discardPendingAutoRefine();\n\t\t\treturn;\n\t\t}\n\n\t\tconst settings = this.settingsManager.getAutoRefineSettings();\n\t\tif (!settings.enabled) {\n\t\t\tthis._discardPendingAutoRefine();\n\t\t\treturn;\n\t\t}\n\t\tif (this._autoRefineInProgress || this._shouldSkipAutoRefineForActiveAgent()) {\n\t\t\tif (reason === \"compact\") {\n\t\t\t\tthis._compactAutoRefinePending = true;\n\t\t\t} else {\n\t\t\t\tthis._turnIntervalAutoRefinePending = true;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst nowMs = Date.now();\n\t\tconst underCooldown =\n\t\t\tthis._lastAutoRefineReviewAt > 0 && nowMs - this._lastAutoRefineReviewAt < settings.cooldownMs;\n\n\t\tconst pendingReview = this._pendingAutoRefineReview;\n\t\tif (pendingReview) {\n\t\t\t// A failed refine stamps the cooldown; keep the pending review for later.\n\t\t\tif (underCooldown) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this._runApprovedRefine(pendingReview.reason, pendingReview.review);\n\t\t\treturn;\n\t\t}\n\n\t\tif (reason === \"compact\" && !settings.compact) {\n\t\t\tthis._compactAutoRefinePending = false;\n\t\t\treason = \"turn_interval\";\n\t\t}\n\t\tif (reason === \"turn_interval\" && this._assistantTurnsSinceAutoRefine < settings.turnInterval) {\n\t\t\treturn;\n\t\t}\n\t\tif (underCooldown) {\n\t\t\tif (reason === \"compact\") {\n\t\t\t\tthis._compactAutoRefinePending = true;\n\t\t\t} else {\n\t\t\t\tthis._turnIntervalAutoRefinePending = true;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (reason === \"turn_interval\") {\n\t\t\tthis._turnIntervalAutoRefinePending = false;\n\t\t}\n\t\tif (!this.model) {\n\t\t\tif (reason === \"compact\") {\n\t\t\t\tthis._compactAutoRefinePending = true;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis._autoRefineInProgress = true;\n\t\tconst turnsSinceLastReview = this._assistantTurnsSinceAutoRefine;\n\t\tconst branchVersion = this._autoRefineBranchVersion;\n\t\tconst reviewAbort = new AbortController();\n\t\tthis._autoRefineReviewAbort = reviewAbort;\n\t\tlet approvedReview: AutoRefineReview | undefined;\n\t\ttry {\n\t\t\tconst review = await this._reviewAutoRefine({ reason, turnsSinceLastReview }, reviewAbort.signal);\n\t\t\tif (\n\t\t\t\t!this._newAutoRefineAllowed() ||\n\t\t\t\tthis._disposed ||\n\t\t\t\tthis._disposing ||\n\t\t\t\tbranchVersion !== this._autoRefineBranchVersion\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!review.shouldRefine) {\n\t\t\t\tconst preserveTurnIntervalReview =\n\t\t\t\t\treason === \"compact\" && this._assistantTurnsSinceAutoRefine >= settings.turnInterval;\n\t\t\t\tif (preserveTurnIntervalReview) {\n\t\t\t\t\tthis._turnIntervalAutoRefinePending = true;\n\t\t\t\t} else {\n\t\t\t\t\tthis._lastAutoRefineReviewAt = nowMs;\n\t\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\t}\n\t\t\t\tif (reason === \"compact\") {\n\t\t\t\t\tthis._compactAutoRefinePending = false;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this._shouldSkipAutoRefineForActiveAgent()) {\n\t\t\t\tthis._pendingAutoRefineReview = { reason, review };\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tapprovedReview = review;\n\t\t} catch {\n\t\t\t// Failed review: stamp the cooldown so a persistent failure (bad auth,\n\t\t\t// unparseable output) doesn't retry a full review on every agent end.\n\t\t\tif (branchVersion === this._autoRefineBranchVersion) {\n\t\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\t}\n\t\t} finally {\n\t\t\tif (this._autoRefineReviewAbort === reviewAbort) {\n\t\t\t\tthis._autoRefineReviewAbort = undefined;\n\t\t\t}\n\t\t\tthis._autoRefineInProgress = false;\n\t\t\t// When a refine follows, _runApprovedRefine schedules the deferred pass.\n\t\t\tif (!approvedReview) {\n\t\t\t\tthis._scheduleDeferredAutoRefineIfIdle();\n\t\t\t}\n\t\t}\n\t\tif (approvedReview) {\n\t\t\tawait this._runApprovedRefine(reason, approvedReview);\n\t\t}\n\t}\n\n\tprivate async _runApprovedRefine(reason: AutoRefineReason, review: AutoRefineReview): Promise<void> {\n\t\tif (this._compactionSetupFailure || !this._newAutoRefineAllowed()) return;\n\t\tthis._autoRefineInProgress = true;\n\t\ttry {\n\t\t\tawait this.refine({ instructions: autoRefineInstructions(reason, review) }, { trigger: \"auto\" });\n\t\t\tthis._pendingAutoRefineReview = undefined;\n\t\t\tthis._turnIntervalAutoRefinePending = false;\n\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\tif (reason === \"compact\") {\n\t\t\t\tthis._compactAutoRefinePending = false;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Consume this exact automatic proposal after failure. New evidence can\n\t\t\t// request a new review; manual /refine remains independent.\n\t\t\tthis._pendingAutoRefineReview = undefined;\n\t\t\tthis._lastAutoRefineReviewAt = Date.now();\n\t\t\tif (error instanceof RefineSkippedError) {\n\t\t\t\t// A skipped round is consumed like a reviewer decline, not retained for retry.\n\t\t\t\tthis._pendingAutoRefineReview = undefined;\n\t\t\t\tthis._turnIntervalAutoRefinePending = false;\n\t\t\t\tthis._assistantTurnsSinceAutoRefine = 0;\n\t\t\t\tif (reason === \"compact\") this._compactAutoRefinePending = false;\n\t\t\t}\n\t\t} finally {\n\t\t\tthis._autoRefineInProgress = false;\n\t\t\tthis._scheduleDeferredAutoRefineIfIdle();\n\t\t}\n\t}\n\n\tprivate _resolveRefinementModel():\n\t\t| { model: NonNullable<AgentSession[\"model\"]>; thinkingLevel: ThinkingLevel; explicit: boolean }\n\t\t| undefined {\n\t\tconst selection = this.settingsManager.getAutoRefineModel();\n\t\tif (selection === undefined) {\n\t\t\tconst model = this.model;\n\t\t\treturn model\n\t\t\t\t? { model: { ...model, cost: { ...model.cost } }, thinkingLevel: this.thinkingLevel, explicit: false }\n\t\t\t\t: undefined;\n\t\t}\n\t\tif (\n\t\t\t!selection ||\n\t\t\ttypeof selection !== \"object\" ||\n\t\t\tArray.isArray(selection) ||\n\t\t\ttypeof selection.provider !== \"string\" ||\n\t\t\t!selection.provider.trim() ||\n\t\t\ttypeof selection.modelId !== \"string\" ||\n\t\t\t!selection.modelId.trim() ||\n\t\t\ttypeof selection.thinkingLevel !== \"string\"\n\t\t)\n\t\t\tthrow new Error(\"Invalid autoRefine.model; expected provider, modelId, and thinkingLevel\");\n\t\tconst model = this._modelRegistry.find(selection.provider, selection.modelId);\n\t\tif (!model) throw new Error(`Unknown autoRefine.model ${selection.provider}/${selection.modelId}`);\n\t\tif (!getSupportedThinkingLevels(model).includes(selection.thinkingLevel))\n\t\t\tthrow new Error(\n\t\t\t\t`autoRefine.model thinkingLevel ${selection.thinkingLevel} is not supported by ${selection.provider}/${selection.modelId}`,\n\t\t\t);\n\t\treturn { model: { ...model, cost: { ...model.cost } }, thinkingLevel: selection.thinkingLevel, explicit: true };\n\t}\n\n\tprivate async _autoRefineEvidence(harnessState: HarnessState) {\n\t\tconst manager = this.sessionManager;\n\t\tconst goalEvidence = ({ active, status, goalId, objective, tokenBudget, lastError }: GoalState) => ({\n\t\t\tactive,\n\t\t\tstatus,\n\t\t\tgoalId,\n\t\t\tobjective,\n\t\t\ttokenBudget,\n\t\t\tlastError,\n\t\t});\n\t\tconst frontier = manager.supportsCapturedHistoryReads()\n\t\t\t? await manager.readBranchHistory(async (history) => {\n\t\t\t\t\tconst goal = (await history.branchBootstrap()).goalState;\n\t\t\t\t\tconst limits = this.settingsManager.getCanonicalContextLimits();\n\t\t\t\t\tlet goalState = emptyGoalState();\n\t\t\t\t\tif (goal) {\n\t\t\t\t\t\tconst hydrated = await history.hydrateEntry(goal.id, limits.maxSourceBytes);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!hydrated ||\n\t\t\t\t\t\t\thydrated.source.retention === \"retained-import\" ||\n\t\t\t\t\t\t\thydrated.entry.type !== \"custom\" ||\n\t\t\t\t\t\t\thydrated.entry.customType !== GOAL_STATE_CUSTOM_TYPE ||\n\t\t\t\t\t\t\t!isPersistedGoalState(hydrated.entry.data)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthrow new RefineSkippedError(\"Automatic refinement goal source is unavailable or ineligible\");\n\t\t\t\t\t\tgoalState = normalizeGoalState(hydrated.entry.data);\n\t\t\t\t\t}\n\t\t\t\t\tlet id = history.source.leafId;\n\t\t\t\t\tconst maxEntries = limits.maxMessages;\n\t\t\t\t\tfor (let scanned = 0; scanned < maxEntries; scanned++) {\n\t\t\t\t\t\tconst entry = id ? await history.get(id) : undefined;\n\t\t\t\t\t\tif (id && !entry) throw new RefineSkippedError(\"Automatic refinement task frontier is unavailable\");\n\t\t\t\t\t\tconst message = entry?.kind === \"message\" ? entry : undefined;\n\t\t\t\t\t\tif (message || !entry)\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tsessionId: history.source.sessionId,\n\t\t\t\t\t\t\t\tsessionFile: history.source.sessionFile,\n\t\t\t\t\t\t\t\tmessage: message ? ([message.id, message.revision] as const) : undefined,\n\t\t\t\t\t\t\t\tgoal: goalEvidence(goalState),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\tid = entry.parentId;\n\t\t\t\t\t}\n\t\t\t\t\tthrow new RefineSkippedError(\"Automatic refinement task frontier exceeds the context read limit\");\n\t\t\t\t})\n\t\t\t: (() => {\n\t\t\t\t\tconst branch = manager.getBranch().slice().reverse();\n\t\t\t\t\tconst message = branch.find((entry) => entry.type === \"message\");\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsessionId: manager.getSessionId(),\n\t\t\t\t\t\tsessionFile: manager.getSessionFile(),\n\t\t\t\t\t\tmessage: message ? ([message.id, message.timestamp] as const) : undefined,\n\t\t\t\t\t\tgoal: goalEvidence(this._loadPersistedGoalState()),\n\t\t\t\t\t};\n\t\t\t\t})();\n\t\treturn {\n\t\t\t...frontier,\n\t\t\tsystemPrompt: this.agent.state.systemPrompt,\n\t\t\tmodel: JSON.stringify([this.model?.provider, this.model?.id, this.settingsManager.getAutoRefineModel()]),\n\t\t\tharnessEntries: Object.fromEntries(\n\t\t\t\tObject.entries(harnessState.entries).map(([kind, entries]) => [\n\t\t\t\t\tkind,\n\t\t\t\t\tObject.fromEntries(\n\t\t\t\t\t\tObject.entries(entries).map(\n\t\t\t\t\t\t\t([id, { version: _version, created_at: _created, updated_at: _updated, ...entry }]) => [id, entry],\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t]),\n\t\t\t),\n\t\t};\n\t}\n\n\tprivate async _reviewAutoRefine(context: AutoRefineReviewRequest, signal?: AbortSignal): Promise<AutoRefineReview> {\n\t\tconst harnessState = this._loadMergedHarnessState();\n\t\tconst evidence = await this._autoRefineEvidence(harnessState);\n\t\tsignal?.throwIfAborted();\n\t\tif (isDeepStrictEqual(evidence, this._lastAutoRefineEvidence))\n\t\t\treturn { shouldRefine: false, rationale: \"No new task evidence since the previous automatic review.\" };\n\t\t// Reserve before any inference wait. Equivalent running, declined or failed\n\t\t// automatic reviews do not buy another call; explicit /refine stays independent.\n\t\tthis._lastAutoRefineEvidence = evidence;\n\t\tif (this._autoRefineReviewer) return this._autoRefineReviewer(context, signal);\n\t\tconst selected = this._resolveRefinementModel();\n\t\tif (!selected) return { shouldRefine: false, rationale: \"No model selected.\" };\n\t\tconst { model, thinkingLevel, explicit } = selected;\n\t\tconst messages = structuredClone(this.agent.state.messages);\n\t\tconst reviewContext = { ...context };\n\t\tconst requests = this.requests[captureNativeReviewerRequests]();\n\t\ttry {\n\t\t\tconst history = await this._loadRefinementHistory();\n\t\t\tconst { apiKey, headers } = await this._getRequiredRequestAuth(model);\n\t\t\treturn await reviewAutoRefine(\n\t\t\t\tmessages,\n\t\t\t\tharnessState,\n\t\t\t\thistory,\n\t\t\t\tmodel,\n\t\t\t\tapiKey,\n\t\t\t\treviewContext,\n\t\t\t\theaders,\n\t\t\t\tsignal,\n\t\t\t\tthinkingLevel,\n\t\t\t\trequests,\n\t\t\t\texplicit,\n\t\t\t);\n\t\t} finally {\n\t\t\tawait requests.dispose();\n\t\t}\n\t}\n\n\t/** Merge existing session/global memory with the selected project's workspace memory. */\n\tprivate _loadMergedHarnessState(): HarnessState {\n\t\tconst localHarnessStateDir = this._localHarnessStateDir();\n\t\treturn mergeHarnessStates(\n\t\t\tloadHarnessState(getGlobalHarnessStateDir(), \"global\"),\n\t\t\tlocalHarnessStateDir ? loadHarnessState(localHarnessStateDir, \"local\") : undefined,\n\t\t\tloadHarnessState(getWorkspaceHarnessStateDir(this._cwd), \"workspace\"),\n\t\t);\n\t}\n\n\tprivate async _loadRefinementHistory(): Promise<RefinementResult[]> {\n\t\tconst limits: SessionHistoryReadLimits = {\n\t\t\tmaxEntries: 16_384,\n\t\t\tmaxSourceBytes: 64 * 1024 * 1024,\n\t\t};\n\t\tconst residentEntries = this.sessionManager.supportsCapturedHistoryReads()\n\t\t\t? undefined\n\t\t\t: this.sessionManager.materializeResidentHistory(limits).entries;\n\t\tconst globalHistory = loadGlobalRefinementHistory(getGlobalHarnessStateDir(), limits);\n\t\tconst sessionHistory = (async () => {\n\t\t\tif (residentEntries !== undefined) return residentEntries;\n\t\t\treturn this.sessionManager.readSourceHistory(async (history) => {\n\t\t\t\tconst entries: SessionEntry[] = [];\n\t\t\t\tlet sourceBytes = 0;\n\t\t\t\tlet after = 0;\n\t\t\t\tfor (;;) {\n\t\t\t\t\tconst page = await history.page(after, 128);\n\t\t\t\t\tif (page.indexedThrough < history.source.sourceSequence)\n\t\t\t\t\t\tthrow new Error(\"Captured refinement history has incomplete index coverage\");\n\t\t\t\t\tfor (const reference of page.events) {\n\t\t\t\t\t\tif (reference.kind !== \"custom\") continue;\n\t\t\t\t\t\t// Refinement consumes custom records, not archived conversation or request bodies.\n\t\t\t\t\t\tif (entries.length >= limits.maxEntries) throw new Error(\"Refinement history entry budget exceeded\");\n\t\t\t\t\t\tif (sourceBytes + reference.locator.length > limits.maxSourceBytes)\n\t\t\t\t\t\t\tthrow new Error(\"Refinement history source byte budget exceeded\");\n\t\t\t\t\t\tconst hydrated = await hydrateCapturedHistoryEntry(\n\t\t\t\t\t\t\treference,\n\t\t\t\t\t\t\tlimits.maxSourceBytes - sourceBytes,\n\t\t\t\t\t\t\thistory.readPayload,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tentries.push(hydrated.entry);\n\t\t\t\t\t\tsourceBytes += reference.locator.length;\n\t\t\t\t\t}\n\t\t\t\t\tif (page.nextAfter === null) return entries;\n\t\t\t\t\tafter = page.nextAfter;\n\t\t\t\t}\n\t\t\t});\n\t\t})();\n\t\tconst [globalResult, sessionResult] = await Promise.allSettled([globalHistory, sessionHistory]);\n\t\tif (globalResult.status === \"rejected\") {\n\t\t\tif (sessionResult.status === \"rejected\") {\n\t\t\t\tthrow new AggregateError([globalResult.reason, sessionResult.reason], \"Refinement history reads failed\");\n\t\t\t}\n\t\t\tthrow globalResult.reason;\n\t\t}\n\t\tif (sessionResult.status === \"rejected\") throw sessionResult.reason;\n\t\treturn mergeRefinementHistory(\n\t\t\tglobalResult.value,\n\t\t\tgetRefinementHistory(sessionResult.value.filter((entry) => entry.type === \"custom\")),\n\t\t);\n\t}\n\n\t/**\n\t * Refine editable continual harness state: prompt notes, memory, skills, and subagent specs.\n\t * The base system prompt is intentionally not editable through this path.\n\t *\n\t * Planning runs in the background and does NOT block turn entry points\n\t * (`_waitForRefineIdle` only waits for `_refineInFlight`). Only the fast\n\t * application phase (disk I/O + in-memory mutation) blocks turn entry points.\n\t */\n\tasync refine(\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean } = {},\n\t\tinternal: { skipAbort?: boolean; trigger?: \"manual\" | \"auto\" } = {},\n\t): Promise<RefinementResult> {\n\t\tthis._assertContextOptimizationAllowed();\n\t\treturn this._retainContextOptimization(this._refineAccepted(options, internal));\n\t}\n\n\tprivate async _refineAccepted(\n\t\toptions: {\n\t\t\tinstructions?: string;\n\t\t\trollbackId?: string;\n\t\t\tglobal?: boolean;\n\t\t} = {},\n\t\tinternal: { skipAbort?: boolean; trigger?: \"manual\" | \"auto\" } = {},\n\t): Promise<RefinementResult> {\n\t\t// Queued /refine executes from the session-input pump between turns;\n\t\t// refine never aborts the agent (planning is backgrounded and the apply\n\t\t// phase waits for quiescence), so skipAbort only asserts the pump's\n\t\t// idle invariant instead of changing abort behavior.\n\t\tif (internal.skipAbort && this.isStreaming) {\n\t\t\tthrow new Error(\"Cannot refine without aborting while the agent is running.\");\n\t\t}\n\t\t// Wait for any existing refine (both planning and application) before\n\t\t// starting a new run. This serializes concurrent /refine calls so two\n\t\t// planning phases cannot race into concurrent _applyRefine calls that\n\t\t// overwrite harness state.\n\t\twhile (this._refineInFlight || this._refinePlanInFlight || this._serializedPlanInFlight) {\n\t\t\tif (this._refineInFlight) {\n\t\t\t\tawait this._refineInFlight;\n\t\t\t} else if (this._refinePlanInFlight) {\n\t\t\t\tawait this._refinePlanInFlight;\n\t\t\t} else {\n\t\t\t\t// A serialized background plan is in flight (started during an\n\t\t\t\t// active turn at message_end). Wait for planning and for the active\n\t\t\t\t// turn to settle so its normal checkpoint can consume the plan.\n\t\t\t\tconst serializedPlanInFlight = this._serializedPlanInFlight;\n\t\t\t\tawait serializedPlanInFlight;\n\t\t\t\tif (this._refineInFlight || this._refinePlanInFlight) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tawait this.agent.waitForIdle();\n\t\t\t\t// Aborted turns skip shouldStopAfterTurn. Drop their settled plan\n\t\t\t\t// after idle so a later public refine cannot spin on it forever.\n\t\t\t\tif (this._serializedPlanInFlight === serializedPlanInFlight) {\n\t\t\t\t\tthis._serializedPlanInFlight = undefined;\n\t\t\t\t\tthis._serializedExplicitRefineOptions = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst refineAbort = new AbortController();\n\t\tthis._refineAbortController = refineAbort;\n\n\t\tconst planRun = this._planRefine(options, refineAbort.signal, internal.trigger ?? \"manual\");\n\t\tconst planSettled = planRun.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\tthis._refinePlanInFlight = planSettled;\n\t\tlet plan: RefinementPlan;\n\t\ttry {\n\t\t\tplan = await planRun;\n\t\t} catch (e) {\n\t\t\tif (this._refineAbortController === refineAbort) {\n\t\t\t\tthis._refineAbortController = undefined;\n\t\t\t}\n\t\t\tthis._scheduleSessionInputPump();\n\t\t\tthrow e;\n\t\t} finally {\n\t\t\tif (this._refinePlanInFlight === planSettled) {\n\t\t\t\tthis._refinePlanInFlight = undefined;\n\t\t\t}\n\t\t}\n\n\t\t// Block new turns before waiting for the current turn to finish. One shared\n\t\t// settled promise covers the full transition and apply critical section.\n\t\tlet resolveApplySettled: () => void = () => {};\n\t\tconst applySettled = new Promise<void>((resolve) => {\n\t\t\tresolveApplySettled = resolve;\n\t\t});\n\t\tthis._refineInFlight = applySettled;\n\t\ttry {\n\t\t\t// Wait for the session to become quiescent before applying. Planning is\n\t\t\t// allowed to overlap active user work, but application must not disconnect\n\t\t\t// event handling until that work and its queued events have completed.\n\t\t\tawait this.agent.waitForIdle();\n\t\t\twhile (true) {\n\t\t\t\tconst eventQueue = this._agentEventQueue;\n\t\t\t\tconst compactionOp = this._compactionOperation;\n\t\t\t\tconst branchSummaryOp = this._branchSummaryOperation;\n\t\t\t\tawait Promise.allSettled([\n\t\t\t\t\teventQueue,\n\t\t\t\t\t...(compactionOp ? [compactionOp] : []),\n\t\t\t\t\t...(branchSummaryOp ? [branchSummaryOp] : []),\n\t\t\t\t]);\n\t\t\t\tif (\n\t\t\t\t\teventQueue === this._agentEventQueue &&\n\t\t\t\t\tcompactionOp === this._compactionOperation &&\n\t\t\t\t\tbranchSummaryOp === this._branchSummaryOperation\n\t\t\t\t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this._disposed || refineAbort.signal.aborted) {\n\t\t\t\tthrow new Error(\"Refinement cancelled because the session was disposed.\");\n\t\t\t}\n\t\t\treturn await this._applyRefine(plan, options, refineAbort);\n\t\t} finally {\n\t\t\tresolveApplySettled();\n\t\t\tif (this._refineInFlight === applySettled) {\n\t\t\t\tthis._refineInFlight = undefined;\n\t\t\t}\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\tthis._scheduleSessionInputPump();\n\t\t}\n\t}\n\n\t/**\n\t * Block a new agent turn until any in-flight refine application phase has\n\t * reattached event handling; otherwise the turn's messages are never\n\t * persisted or rendered.\n\t *\n\t * The idle-wait and application phase (`_refineInFlight`) block here. The\n\t * background planning phase (`_refinePlanInFlight`) does NOT block turns.\n\t * Refine failures surface to the refine caller, not here.\n\t */\n\tprivate async _waitForRefineIdle(): Promise<void> {\n\t\twhile (this._refineInFlight) {\n\t\t\tawait this._refineInFlight;\n\t\t}\n\t}\n\n\t/**\n\t * Background planning phase: runs the LLM planning call via `planRefinement`.\n\t * Does not disconnect from or abort the agent. Returns the plan without\n\t * applying anything.\n\t */\n\tprivate async _planRefine(\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean },\n\t\tsignal: AbortSignal,\n\t\ttrigger: \"manual\" | \"auto\" = \"manual\",\n\t): Promise<RefinementPlan> {\n\t\tif (this._disposed) {\n\t\t\tthrow new Error(\"Cannot refine a disposed session.\");\n\t\t}\n\n\t\tconst selected = this._resolveRefinementModel();\n\t\tif (!selected) throw new Error(formatNoModelSelectedMessage());\n\t\tconst { model, thinkingLevel, explicit } = selected;\n\t\tconst messages = structuredClone(this.agent.state.messages);\n\t\tconst requestOptions = { ...options };\n\t\tconst globalHarnessStateDir = getGlobalHarnessStateDir();\n\t\tconst localHarnessStateDir = this._localHarnessStateDir();\n\t\tconst requestedScope = requestOptions.global ? \"global\" : \"local\";\n\t\tif (!requestOptions.rollbackId && requestedScope === \"local\" && !localHarnessStateDir) {\n\t\t\tthrow new Error(\"Local harness refinement requires a persisted session; use global refinement instead.\");\n\t\t}\n\t\tconst globalPlanningState = loadHarnessState(globalHarnessStateDir, \"global\");\n\t\tconst localPlanningState = localHarnessStateDir ? loadHarnessState(localHarnessStateDir, \"local\") : undefined;\n\t\tconst planningState =\n\t\t\trequestedScope === \"global\"\n\t\t\t\t? globalPlanningState\n\t\t\t\t: mergeHarnessStates(globalPlanningState, localPlanningState);\n\t\tconst plannerManager = this.sessionManager;\n\t\tconst requests = this.requests[captureNativePlannerRequests](plannerManager.bindRequestSink());\n\t\ttry {\n\t\t\tconst history = await this._loadRefinementHistory();\n\t\t\tconst rollbackTarget = requestOptions.rollbackId\n\t\t\t\t? history.find((item) => item.id === requestOptions.rollbackId)\n\t\t\t\t: undefined;\n\t\t\tlet baselineScope = rollbackTarget\n\t\t\t\t? (inferRefinementResultScope(rollbackTarget) ?? requestedScope)\n\t\t\t\t: requestedScope;\n\t\t\tlet baselineHarnessStateDir = baselineScope === \"global\" ? globalHarnessStateDir : localHarnessStateDir;\n\t\t\tif (rollbackTarget?.harnessStatePath) {\n\t\t\t\tbaselineHarnessStateDir = dirname(rollbackTarget.harnessStatePath);\n\t\t\t\tbaselineScope = resolve(baselineHarnessStateDir) === resolve(globalHarnessStateDir) ? \"global\" : \"local\";\n\t\t\t}\n\t\t\tif (!baselineHarnessStateDir) {\n\t\t\t\tthrow new Error(\"Local harness refinement requires a persisted session; use global refinement instead.\");\n\t\t\t}\n\t\t\tconst baselineState = rollbackTarget\n\t\t\t\t? loadHarnessState(baselineHarnessStateDir, baselineScope)\n\t\t\t\t: baselineScope === \"global\"\n\t\t\t\t\t? globalPlanningState\n\t\t\t\t\t: localPlanningState!;\n\t\t\tconst { apiKey, headers } = await this._getRequiredRequestAuth(model);\n\t\t\tif (!requestOptions.rollbackId && this._extensionRunner.hasHandlers(\"session_before_refine\")) {\n\t\t\t\tconst result = (await this._extensionRunner.emit({\n\t\t\t\t\ttype: \"session_before_refine\",\n\t\t\t\t\tpreparation: {\n\t\t\t\t\t\ttrigger,\n\t\t\t\t\t\tinstructions: requestOptions.instructions,\n\t\t\t\t\t\tscope: requestedScope,\n\t\t\t\t\t\tplanningState,\n\t\t\t\t\t\thistory,\n\t\t\t\t\t\tconversationText: serializeConversation(convertToLlm(messages)).slice(-80_000),\n\t\t\t\t\t},\n\t\t\t\t\tsignal,\n\t\t\t\t})) as SessionBeforeRefineResult | undefined;\n\t\t\t\tif (this._disposed || signal.aborted) {\n\t\t\t\t\tthrow new Error(\"Refinement cancelled because the session was disposed.\");\n\t\t\t\t}\n\t\t\t\tif (result?.skip) {\n\t\t\t\t\tthrow new RefineSkippedError(\"Refinement skipped by extension\");\n\t\t\t\t}\n\t\t\t\tif (result?.proposal !== undefined) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproposal: normalizeRefinementProposal(result.proposal),\n\t\t\t\t\t\tid: generateRefinementId(),\n\t\t\t\t\t\tbaselineState,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst plan = await planRefinement(\n\t\t\t\tmessages,\n\t\t\t\tplanningState,\n\t\t\t\thistory,\n\t\t\t\tmodel,\n\t\t\t\tapiKey,\n\t\t\t\trequestOptions,\n\t\t\t\theaders,\n\t\t\t\tsignal,\n\t\t\t\tthinkingLevel,\n\t\t\t\trequests,\n\t\t\t\texplicit,\n\t\t\t);\n\t\t\tif (this._disposed || signal.aborted) {\n\t\t\t\tthrow new Error(\"Refinement cancelled because the session was disposed.\");\n\t\t\t}\n\t\t\treturn withRefinementBaseline(plan, baselineState);\n\t\t} finally {\n\t\t\tawait requests.dispose();\n\t\t}\n\t}\n\n\tprivate async _recordRefinementOutcome(result: RefinementResult): Promise<void> {\n\t\tconst message = createRefinementOutcomeMessage(result);\n\t\ttry {\n\t\t\tawait this.sessionManager.appendCustomMessageEntryWithRollback(\n\t\t\t\tmessage.customType,\n\t\t\t\tmessage.content,\n\t\t\t\tmessage.display,\n\t\t\t\tmessage.details,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\t// Retain the already-applied effect, but do not publish a saved outcome.\n\t\t\tthis._unpersistedOutcomes.push(message);\n\t\t\tthrow error;\n\t\t}\n\t\tthis.agent.state.messages.push(message);\n\t\tthis._emit({ type: \"message_start\", message });\n\t\tthis._emit({ type: \"message_end\", message });\n\t}\n\n\t/**\n\t * Synchronous application phase: disconnects from the agent, aborts any\n\t * in-flight agent run, applies the refinement plan to disk and memory, then\n\t * reconnects. This is the only phase that blocks turn entry points.\n\t */\n\tprivate async _applyRefine(\n\t\tplan: RefinementPlan,\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean },\n\t\trefineAbort: AbortController,\n\t): Promise<RefinementResult> {\n\t\tif (this._disposed) {\n\t\t\tthrow new Error(\"Cannot refine a disposed session.\");\n\t\t}\n\t\t// The caller has already set _refineInFlight and waited for agent idle.\n\t\t// Disconnect only for the brief apply + save + reconnect critical section.\n\t\toptions = { ...options };\n\t\tthis._disconnectFromAgent();\n\n\t\ttry {\n\t\t\tconst globalHarnessStateDir = getGlobalHarnessStateDir();\n\t\t\tconst localHarnessStateDir = this._localHarnessStateDir();\n\t\t\tconst requestedScope = options.global ? \"global\" : \"local\";\n\t\t\tconst history = await this._loadRefinementHistory();\n\t\t\tconst rollbackTarget = options.rollbackId ? history.find((item) => item.id === options.rollbackId) : undefined;\n\t\t\tlet targetScope = plan.rollbackScope ?? requestedScope;\n\t\t\tlet targetHarnessStateDir = targetScope === \"global\" ? globalHarnessStateDir : localHarnessStateDir;\n\t\t\tif (targetScope === \"local\" && rollbackTarget?.harnessStatePath) {\n\t\t\t\tif (!existsSync(rollbackTarget.harnessStatePath)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Local refinement ${rollbackTarget.id} state file not found: ${rollbackTarget.harnessStatePath}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\ttargetHarnessStateDir = dirname(rollbackTarget.harnessStatePath);\n\t\t\t\t// Legacy records predate scope fields and default to \"local\" but may point\n\t\t\t\t// at the global store; honor the recorded path so its entries stay global.\n\t\t\t\tif (resolve(targetHarnessStateDir) === resolve(globalHarnessStateDir)) {\n\t\t\t\t\ttargetScope = \"global\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!targetHarnessStateDir) {\n\t\t\t\tthrow new Error(\"Local harness refinement requires a persisted session; use global refinement instead.\");\n\t\t\t}\n\t\t\t// Re-read the target state immediately before applying so concurrent kernel\n\t\t\t// (`rlm.harness`) writes during the LLM pass are not clobbered.\n\t\t\tconst state = loadHarnessState(targetHarnessStateDir, targetScope);\n\t\t\tconst proposal = prepareRefinementApplication(plan, state, options, targetScope);\n\t\t\tif (this._disposed || refineAbort.signal.aborted) {\n\t\t\t\tthrow new Error(\"Refinement cancelled because the session was disposed.\");\n\t\t\t}\n\t\t\tconst result = applyRefinementProposal(state, proposal, {\n\t\t\t\tid: plan.id,\n\t\t\t\trollbackOf: plan.rollbackOf,\n\t\t\t\tscope: targetScope,\n\t\t\t\tbaselineState: plan.baselineState,\n\t\t\t});\n\t\t\tresult.harnessStatePath = saveHarnessState(targetHarnessStateDir, state);\n\t\t\tif (targetScope === \"global\") {\n\t\t\t\tawait appendGlobalRefinement(globalHarnessStateDir, result);\n\t\t\t}\n\t\t\tlet refinementAuditAppendError: { error: unknown } | undefined;\n\t\t\ttry {\n\t\t\t\tconst manager = this.sessionManager;\n\t\t\t\tconst write = takeNativePlannerRequestWrite(result);\n\t\t\t\tconst pending = write?.(manager);\n\t\t\t\tif ((pending ? await pending : undefined) === undefined) {\n\t\t\t\t\tawait manager.appendCustomEntry(\"prime-agent.refinement\", result);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\trefinementAuditAppendError = { error };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait this._recordRefinementOutcome(result);\n\t\t\t} catch (error) {\n\t\t\t\tif (!refinementAuditAppendError) throw error;\n\t\t\t}\n\t\t\tif (refinementAuditAppendError) throw refinementAuditAppendError.error;\n\t\t\t// Keep extension-facing state fresh, but do not rewrite the cached system prefix.\n\t\t\tthis._baseSystemPromptOptions = {\n\t\t\t\t...this._baseSystemPromptOptions,\n\t\t\t\tharnessState: this._loadMergedHarnessState(),\n\t\t\t};\n\t\t\t// The next owned request appends the new advice before capturing its source.\n\t\t\ttry {\n\t\t\t\tthis._emit({ type: \"refine_complete\", result });\n\t\t\t} catch {\n\t\t\t\t// Listener failures must not flip a successful refinement into\n\t\t\t\t// a reported failure — the refinement is already persisted.\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait this._extensionRunner.emit({\n\t\t\t\t\ttype: \"refine_complete\",\n\t\t\t\t\tid: result.id,\n\t\t\t\t\tsummary: result.summary,\n\t\t\t\t\tappliedEdits: result.appliedEdits.filter((edit) => edit.applied).length,\n\t\t\t\t\tscope: result.scope ?? \"local\",\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\t// Extension emit failures must not flip a successful refinement\n\t\t\t\t// into a reported failure — the refinement is already persisted.\n\t\t\t}\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tif (this._refineAbortController === refineAbort) {\n\t\t\t\tthis._refineAbortController = undefined;\n\t\t\t}\n\t\t\tif (!this._disposed) {\n\t\t\t\tthis._reconnectToAgent();\n\t\t\t}\n\t\t}\n\t}\n\n\tabortBranchSummary(): void {\n\t\tthis._branchSummaryAbortController?.abort();\n\t}\n\n\t/**\n\t * Check if compaction is needed and run it.\n\t * Called after agent_end and before prompt submission.\n\t *\n\t * Two cases:\n\t * 1. Overflow: LLM returned context overflow error, remove error message from agent state, compact, auto-retry\n\t * 2. Threshold: Context over threshold, compact, and continue only for stopped in-progress loops or queued messages\n\t *\n\t * @param assistantMessage The assistant message to check\n\t * @param skipAbortedCheck If false, include aborted messages (for pre-prompt check). Default: true\n\t */\n\tprivate _getThresholdContextTokens(\n\t\tassistantMessage: AssistantMessage,\n\t\tcompactionTimestamp: number | undefined,\n\t): number | undefined {\n\t\tconst messages = this.agent.state.messages;\n\t\tconst estimate = estimateContextTokens(messages);\n\t\tif (estimate.lastUsageIndex !== null) {\n\t\t\t// Verify the usage source is post-compaction. Kept pre-compaction messages\n\t\t\t// have stale usage reflecting the old (larger) context and would falsely\n\t\t\t// trigger compaction right after one just finished.\n\t\t\tconst usageMsg = messages[estimate.lastUsageIndex];\n\t\t\tif (\n\t\t\t\tcompactionTimestamp !== undefined &&\n\t\t\t\tusageMsg.role === \"assistant\" &&\n\t\t\t\t(usageMsg as AssistantMessage).timestamp <= compactionTimestamp\n\t\t\t) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn estimate.tokens;\n\t\t}\n\t\tif (assistantMessage.stopReason === \"error\") return undefined;\n\t\treturn calculateContextTokens(assistantMessage.usage);\n\t}\n\n\tprivate async _checkCompaction(\n\t\tassistantMessage: AssistantMessage,\n\t\tskipAbortedCheck = true,\n\t\tqueueAutonomousContinuation = true,\n\t\tinvocationOwner?: CompactionOwner,\n\t\tbeforeNextTurn = false,\n\t): Promise<boolean> {\n\t\tif (this._compactionSetupFailure) return false;\n\t\tif (invocationOwner && !this._isCompactionSourceOwnerCurrent(invocationOwner)) return false;\n\t\tconst owner =\n\t\t\tthis._pendingCheckpoint?.owner ??\n\t\t\t(invocationOwner\n\t\t\t\t? { ...invocationOwner, pumpEpoch: this._sessionInputPumpEpoch }\n\t\t\t\t: this._captureCompactionOwner());\n\t\tif (!this._isCompactionSourceOwnerCurrent(owner)) return false;\n\t\tif (assistantMessage.stopReason !== \"aborted\" && !this._isCompactionOwnerCurrent(owner)) return false;\n\t\tconst goalOwner = { ...this._captureGoalContinuationOwner(owner.signal), checkpointOwner: owner };\n\t\tconst autonomousOwner = this._captureThresholdAutonomousOwner();\n\t\tconst pending = this._pendingRequestedCompaction;\n\t\tif (pending && !this._isCompactionOwnerCurrent(pending.owner)) this._pendingRequestedCompaction = undefined;\n\t\tif (!this._contextOptimizationAllowed() && this._pendingRequestedCompaction === undefined) return false;\n\t\t// An abort drops any compaction the model requested this turn, even on the\n\t\t// pre-prompt path (skipAbortedCheck=false) which continues to threshold checks.\n\t\tif (assistantMessage.stopReason === \"aborted\") {\n\t\t\tthis._pendingRequestedCompaction = undefined;\n\t\t\tthis._pendingCheckpoint = undefined;\n\t\t\t// An abort also drops any pending explicit refine.run request: the\n\t\t\t// turn that would service it (non-serialized: _consumePendingRequestedRefine\n\t\t\t// at agent_end; serialized: the shouldStopAfterTurn checkpoint) never\n\t\t\t// runs for an aborted turn, so a stale request would leak into the\n\t\t\t// next turn or checkpoint.\n\t\t\tthis._pendingRequestedRefine = undefined;\n\t\t\tif (this._serializedPlanInFlight) {\n\t\t\t\tconst serializedPlanInFlight = this._serializedPlanInFlight;\n\t\t\t\tthis._autoRefineBranchVersion++;\n\t\t\t\tthis._refineAbortController?.abort();\n\t\t\t\tawait serializedPlanInFlight.catch(() => undefined);\n\t\t\t\tif (this._serializedPlanInFlight === serializedPlanInFlight) {\n\t\t\t\t\tthis._serializedPlanInFlight = undefined;\n\t\t\t\t\tthis._serializedExplicitRefineOptions = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (skipAbortedCheck) return false;\n\t\t}\n\n\t\tconst settings = this.settingsManager.getCompactionSettings();\n\t\tconst contextWindow = this.model?.contextWindow ?? 0;\n\n\t\t// Skip overflow check if the message came from a different model.\n\t\t// This handles the case where user switched from a smaller-context model (e.g. opus)\n\t\t// to a larger-context model (e.g. codex) - the overflow error from the old model\n\t\t// shouldn't trigger compaction for the new model.\n\t\tconst sameModel =\n\t\t\tthis.model && assistantMessage.provider === this.model.provider && assistantMessage.model === this.model.id;\n\n\t\t// Skip overflow/threshold checks if this assistant message is older than the\n\t\t// latest compaction boundary. This prevents a stale pre-compaction usage/error\n\t\t// from retriggering compaction on the first prompt after compaction.\n\t\tlet compactionTimestamp: number | undefined;\n\t\ttry {\n\t\t\tcompactionTimestamp = await this._getLatestCompactionTimestamp(owner);\n\t\t} catch (error) {\n\t\t\t// A manual checkpoint can supersede this optional check after agent_end was emitted.\n\t\t\tif (error instanceof StaleCompactionOwnerError && !this._isCompactionOwnerCurrent(owner)) return false;\n\t\t\tthrow error;\n\t\t}\n\t\tif (!this._isCompactionOwnerCurrent(owner)) return false;\n\t\tlet assistantIsFromBeforeCompaction =\n\t\t\tcompactionTimestamp !== undefined && assistantMessage.timestamp <= compactionTimestamp;\n\t\tconst assistantEntryId = this._findAssistantEntryIdForMessage(assistantMessage);\n\t\tif (assistantEntryId && owner.manager.supportsCapturedHistoryReads()) {\n\t\t\tconst ordered = await owner.manager.readBranchHistory(async (history) => {\n\t\t\t\tconst assistant = await history.get(assistantEntryId);\n\t\t\t\tconst boundary = (await history.branchBootstrap()).latestCompaction;\n\t\t\t\treturn assistant && boundary ? assistant.sequence <= boundary.sequence : undefined;\n\t\t\t});\n\t\t\tif (!this._isCompactionOwnerCurrent(owner)) return false;\n\t\t\t// Provider messages are timestamped before request preparation, which may\n\t\t\t// commit an epoch. Canonical append order, not that start time, owns staleness.\n\t\t\tif (ordered !== undefined) assistantIsFromBeforeCompaction = ordered;\n\t\t}\n\n\t\t// Case 1: Overflow - takes priority over a pending model request so the error\n\t\t// strip + retry still happen; the compaction it runs consumes the request.\n\t\tif (\n\t\t\t!assistantIsFromBeforeCompaction &&\n\t\t\t(settings.enabled || this._pendingRequestedCompaction !== undefined) &&\n\t\t\tsameModel &&\n\t\t\tisContextOverflow(assistantMessage, contextWindow)\n\t\t) {\n\t\t\tif (this._overflowRecovery !== \"idle\") {\n\t\t\t\tif (this._overflowRecovery === \"attempted\") {\n\t\t\t\t\tthis._overflowRecovery = \"reported\";\n\t\t\t\t\tawait this._endCompactionUnsuccessfully(\n\t\t\t\t\t\t\"overflow\",\n\t\t\t\t\t\t\"failed\",\n\t\t\t\t\t\t\"Context overflow recovery failed after one compact-and-retry attempt. Try reducing context or switching to a larger-context model.\",\n\t\t\t\t\t\t{ owner },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis._overflowRecovery = \"attempted\";\n\t\t\t// Remove the error message from agent state (it IS saved to session for history,\n\t\t\t// but we don't want it in context for the retry)\n\t\t\tconst messages = this.agent.state.messages;\n\t\t\tif (messages.length > 0 && messages[messages.length - 1].role === \"assistant\") {\n\t\t\t\tthis._removeLastAssistantFromContext();\n\t\t\t}\n\t\t\treturn await this._runAutoCompaction(\"overflow\", true, owner, false, undefined, beforeNextTurn);\n\t\t}\n\n\t\tif (this._pendingRequestedCompaction !== undefined) {\n\t\t\treturn await this._runAutoCompaction(\"requested\", false, owner);\n\t\t}\n\n\t\tif (!this._contextOptimizationAllowed() || !settings.enabled || assistantIsFromBeforeCompaction) return false;\n\t\t// A native turn already made its typed decision. Do not synthesize a new policy winner at agent_end.\n\t\tif (invocationOwner && !this._pendingCheckpoint) return false;\n\n\t\t// Case 3: Threshold - context is getting large.\n\t\t// Use the full-session estimate so messages appended after the last successful\n\t\t// assistant usage are included, matching the /usage context display.\n\t\tconst contextTokens = this._getThresholdContextTokens(assistantMessage, compactionTimestamp);\n\t\tif (contextTokens === undefined) return false;\n\t\tif (\n\t\t\tshouldCompact(\n\t\t\t\tcontextTokens,\n\t\t\t\tcontextWindow,\n\t\t\t\tsettings,\n\t\t\t\testimateFixedCompactionTokens(this.systemPrompt, this.agent.state.tools, this.messages),\n\t\t\t)\n\t\t) {\n\t\t\tif (this._hasFailedThresholdCompaction()) return false;\n\t\t\tif (!this._pendingCheckpoint && queueAutonomousContinuation) {\n\t\t\t\tif (\n\t\t\t\t\t!(await this._queueGoalContinuationForThresholdCompaction(assistantMessage, goalOwner)) &&\n\t\t\t\t\tthis._isGoalContinuationOwnerCurrent(goalOwner)\n\t\t\t\t) {\n\t\t\t\t\tawait this._queueAutonomousContinuationForThresholdCompaction(assistantMessage, owner, autonomousOwner);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!this._isCompactionOwnerCurrent(owner) || !this._contextOptimizationAllowed()) return false;\n\t\t\treturn await this._runAutoCompaction(\"threshold\", false, owner, false, undefined, beforeNextTurn);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Internal: Run automatic (threshold/overflow) or model-requested compaction\n\t * with events.\n\t */\n\tprivate async _endCompactionUnsuccessfully(\n\t\treason: CompactionOutcomeReason,\n\t\toutcome: CompactionOutcome,\n\t\tmessage: string,\n\t\toptions: {\n\t\t\taborted?: boolean;\n\t\t\terrorSeverity?: \"warning\" | \"error\";\n\t\t\tcustomInstructions?: string;\n\t\t\towner?: CompactionOwner;\n\t\t} = {},\n\t): Promise<void> {\n\t\tconst owner = options.owner ?? this._captureCompactionOwner();\n\t\tawait this._persistCompactionOutcome(reason, outcome, message, owner);\n\t\tthis._assertCompactionSourceOwner(owner);\n\t\tthis._emit({\n\t\t\ttype: \"compaction_end\",\n\t\t\treason,\n\t\t\tresult: undefined,\n\t\t\taborted: options.aborted ?? false,\n\t\t\twillRetry: false,\n\t\t\t// Aborts are user-initiated; they carry no error message on the event.\n\t\t\terrorMessage: options.aborted ? undefined : message,\n\t\t\terrorSeverity: options.errorSeverity,\n\t\t\tcustomInstructions: options.customInstructions,\n\t\t});\n\t}\n\n\tprivate async _persistCompactionOutcome(\n\t\treason: CompactionOutcomeReason,\n\t\toutcome: CompactionOutcome,\n\t\tmessage: string,\n\t\towner = this._captureCompactionOwner(),\n\t): Promise<void> {\n\t\tthis._assertCompactionSourceOwner(owner);\n\t\tlet outcomeMessage = createCompactionOutcomeMessage(message, {\n\t\t\treason,\n\t\t\toutcome,\n\t\t});\n\t\ttry {\n\t\t\tawait owner.manager.appendCustomMessageEntryWithRollback(\n\t\t\t\toutcomeMessage.customType,\n\t\t\t\toutcomeMessage.content,\n\t\t\t\toutcomeMessage.display,\n\t\t\t\toutcomeMessage.details,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (!this._isCompactionSourceOwnerCurrent(owner)) throw error;\n\t\t\tconst persistenceError = error instanceof Error ? error.message : String(error);\n\t\t\toutcomeMessage = createCompactionOutcomeMessage(\n\t\t\t\t`${message}\\n\\nThis compaction outcome could not be saved to session history: ${persistenceError}`,\n\t\t\t\t{ reason, outcome },\n\t\t\t);\n\t\t\t// Not in the session file, so context rebuilds would drop the disclosure.\n\t\t\tthis._unpersistedOutcomes.push(outcomeMessage);\n\t\t}\n\t\tthis._assertCompactionSourceOwner(owner);\n\t\towner.agent.state.messages.push(outcomeMessage);\n\t\tthis._emit({ type: \"message_start\", message: outcomeMessage });\n\t\tthis._emit({ type: \"message_end\", message: outcomeMessage });\n\t}\n\n\tprivate async _runAutoCompaction(\n\t\treason: \"overflow\" | \"threshold\" | \"requested\",\n\t\twillRetry: boolean,\n\t\tcapturedOwner?: CompactionOwner,\n\t\tresumeInPlace = false,\n\t\tcapacity?: PublicContextBudgetError,\n\t\tbeforeNextTurn = false,\n\t): Promise<boolean> {\n\t\tconst checkpoint = this._pendingCheckpoint;\n\t\tconst pending = this._pendingRequestedCompaction;\n\t\tconst owner = checkpoint?.owner ?? pending?.owner ?? capturedOwner ?? this._captureCompactionOwner();\n\t\tif (!this._isCompactionOwnerCurrent(owner)) return false;\n\t\tif (reason === \"threshold\" && !this._contextOptimizationAllowed()) return false;\n\t\tif (checkpoint && !this._isCompactionOwnerCurrent(checkpoint.owner)) return false;\n\t\tif (pending && !this._isCompactionOwnerCurrent(pending.owner)) return false;\n\t\tthis._pendingRequestedCompaction = undefined;\n\t\tconst customInstructions = pending?.customInstructions;\n\t\tconst resume = resumeInPlace\n\t\t\t? this._captureCheckpointResume(owner, { kind: \"request\", state: \"pending\" })\n\t\t\t: reason === \"overflow\"\n\t\t\t\t? this._captureCheckpointResume(owner, { kind: \"overflow\", state: \"pending\" })\n\t\t\t\t: (checkpoint ?? this._captureCheckpointResume(owner));\n\t\tthis._pendingCheckpoint = resume;\n\t\tconst shouldContinueAfterCompaction = this._checkpointHasResume(resume);\n\t\tconst queuedAutonomousContinuationsForThisCompaction =\n\t\t\treason === \"threshold\" && shouldContinueAfterCompaction\n\t\t\t\t? this._pendingThresholdCompactionAutonomousContinuations.splice(0)\n\t\t\t\t: [];\n\t\tconst queuedGoalContinuationForThisCompaction =\n\t\t\treason === \"threshold\" && shouldContinueAfterCompaction ? this._queuedGoalThresholdContinuation : undefined;\n\t\tconst resumeAfterFailure = () => {\n\t\t\tif (\n\t\t\t\t!resumeInPlace &&\n\t\t\t\t(reason === \"requested\" || reason === \"threshold\") &&\n\t\t\t\tthis._isCompactionOwnerCurrent(owner) &&\n\t\t\t\t(this._checkpointHasResume(resume) || owner.agent.hasQueuedMessages() || this.hasPendingSessionWork)\n\t\t\t) {\n\t\t\t\tthis._schedulePostCompactionContinue(resume);\n\t\t\t}\n\t\t};\n\n\t\tthis._emit({ type: \"compaction_start\", reason, customInstructions });\n\t\tconst abort = new AbortController();\n\t\tthis._autoCompactionAbortController = abort;\n\t\tlet resolveCompactionOperation: () => void = () => {};\n\t\tconst compactionOperation = new Promise<void>((resolve) => {\n\t\t\tresolveCompactionOperation = resolve;\n\t\t});\n\t\tthis._compactionOperation = compactionOperation;\n\t\tlet requests: InferenceCoordinator | undefined;\n\t\tlet compaction: BoundCompactionSink | undefined;\n\t\tlet committed: CompactionCommit | undefined;\n\t\tlet failure: unknown;\n\t\tconst thresholdConfiguration =\n\t\t\treason === \"threshold\" && !resumeInPlace\n\t\t\t\t? {\n\t\t\t\t\t\tconfiguration: this._thresholdCompactionConfiguration(),\n\t\t\t\t\t\tsystemPrompt: this.agent.state.systemPrompt,\n\t\t\t\t\t\ttools: this.agent.state.tools,\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\t\tconst rememberThresholdFailure = () => {\n\t\t\tif (\n\t\t\t\tthresholdConfiguration &&\n\t\t\t\t!abort.signal.aborted &&\n\t\t\t\tthis._isCompactionOwnerCurrent(owner) &&\n\t\t\t\tcompaction?.isCurrent()\n\t\t\t) {\n\t\t\t\tthis._failedThresholdCompaction = { ...thresholdConfiguration, isCurrent: compaction.isCurrent };\n\t\t\t}\n\t\t};\n\t\ttry {\n\t\t\tconst selected = this._resolveCompactionModel();\n\t\t\tconst model = selected?.model;\n\t\t\tconst thinkingLevel = selected?.thinkingLevel ?? this.thinkingLevel;\n\t\t\tconst settings = { ...this.settingsManager.getCompactionSettings() };\n\t\t\tconst semanticEdges = owner.semanticEdges;\n\t\t\tcompaction = owner.manager.bindCompactionSink();\n\t\t\trequests = owner.requests.capture(compaction);\n\t\t\tconst pathEntries = await compaction.readBranch();\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tconst authResult = model ? await this._modelRegistry.getApiKeyAndHeaders(model) : undefined;\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tif (!model || !authResult || !authResult.ok || !authResult.apiKey) {\n\t\t\t\tconst detail =\n\t\t\t\t\t!model || !authResult\n\t\t\t\t\t\t? \"no model is selected\"\n\t\t\t\t\t\t: authResult.ok\n\t\t\t\t\t\t\t? \"no API key is available\"\n\t\t\t\t\t\t\t: authResult.error;\n\t\t\t\tawait this._endCompactionUnsuccessfully(reason, \"failed\", `Compaction failed: ${detail}`, { owner });\n\t\t\t\tthis._clearQueuedAutonomousContinuationsAfterSkippedThresholdCompaction(\n\t\t\t\t\treason === \"threshold\" && shouldContinueAfterCompaction,\n\t\t\t\t\tqueuedAutonomousContinuationsForThisCompaction,\n\t\t\t\t);\n\t\t\t\trememberThresholdFailure();\n\t\t\t\tresumeAfterFailure();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tcommitted = await this._performCompaction({\n\t\t\t\tmodel,\n\t\t\t\tthinkingLevel,\n\t\t\t\tpathEntries,\n\t\t\t\tsettings,\n\t\t\t\trequests,\n\t\t\t\tcompaction,\n\t\t\t\tsemanticEdges,\n\t\t\t\towner,\n\t\t\t\tapiKey: authResult.apiKey,\n\t\t\t\theaders: authResult.headers,\n\t\t\t\tcustomInstructions,\n\t\t\t\tsignal: abort.signal,\n\t\t\t\t// Only confirmed public-budget recovery resumes within the same invocation.\n\t\t\t\tbudgetPressure: resumeInPlace,\n\t\t\t\tcapacity,\n\t\t\t});\n\t\t\tconst result = committed.result;\n\t\t\t// Release this captured source before arming success. A later release failure still carries the ACK.\n\t\t\tawait this._releaseCompactionCapture(requests, compaction, undefined, owner);\n\t\t\trequests = undefined;\n\t\t\tcompaction = undefined;\n\t\t\tthis._assertCompactionOwner(owner);\n\t\t\tthis._emit({ type: \"compaction_end\", reason, result, aborted: false, willRetry, customInstructions });\n\t\t\tconst hasQueuedWork = owner.agent.hasQueuedMessages() || this.hasPendingSessionWork;\n\t\t\tconst willContinue = willRetry || this._checkpointHasResume(resume) || hasQueuedWork;\n\t\t\tif (willRetry) {\n\t\t\t\tconst messages = owner.agent.state.messages;\n\t\t\t\tconst last = messages[messages.length - 1];\n\t\t\t\tif (last?.role === \"assistant\" && last.stopReason === \"error\") this._removeLastAssistantFromContext();\n\t\t\t}\n\t\t\tif (willContinue && !resumeInPlace) this._schedulePostCompactionContinue(resume);\n\t\t\tthis._scheduleAutoRefineAfterCompaction(willContinue);\n\t\t\t// The unsent request remains in its original invocation; do not queue a new action.\n\t\t\treturn resumeInPlace || willRetry; // Other callers retain the existing overflow retry contract.\n\t\t} catch (error) {\n\t\t\tconst primaryCommit = primaryCommittedCompactionError(error);\n\t\t\tconst knownCommit = primaryCommit ?? committed;\n\t\t\tfailure =\n\t\t\t\tknownCommit && !(error instanceof CompactionCommittedError)\n\t\t\t\t\t? new CompactionCommittedError(knownCommit.entryId, knownCommit.result, error)\n\t\t\t\t\t: error;\n\t\t\tif (failure instanceof CompactionCommittedError) {\n\t\t\t\tthis._reportCommittedCompactionFailure(failure, reason, customInstructions, owner);\n\t\t\t\tthrow failure;\n\t\t\t}\n\t\t\tif (!this._isCompactionSourceOwnerCurrent(owner)) throw failure;\n\t\t\tthis._clearQueuedAutonomousContinuationsAfterSkippedThresholdCompaction(\n\t\t\t\treason === \"threshold\" && shouldContinueAfterCompaction,\n\t\t\t\tqueuedAutonomousContinuationsForThisCompaction,\n\t\t\t);\n\t\t\tif (beforeNextTurn && error instanceof MissingRecoveryReplayContractError) {\n\t\t\t\t// Let the imminent MAIN obtain its own actual projection/ACK. This was not a recovery attempt.\n\t\t\t\tif (reason === \"overflow\") this._overflowRecovery = \"idle\";\n\t\t\t\tawait this._endCompactionUnsuccessfully(\n\t\t\t\t\treason,\n\t\t\t\t\t\"skipped\",\n\t\t\t\t\t\"Compaction deferred until the next native request establishes recovery replay coverage.\",\n\t\t\t\t\t{ errorSeverity: \"warning\", customInstructions, owner },\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"compaction failed\";\n\t\t\tconst aborted =\n\t\t\t\terrorMessage === \"Compaction cancelled\" ||\n\t\t\t\t(error instanceof Error && error.name === \"AbortError\") ||\n\t\t\t\tabort.signal.aborted;\n\t\t\tif (aborted) {\n\t\t\t\tawait this._clearQueuedGoalContinuationAfterCancelledThresholdCompaction(\n\t\t\t\t\tqueuedGoalContinuationForThisCompaction,\n\t\t\t\t);\n\t\t\t\tawait this._endCompactionUnsuccessfully(\n\t\t\t\t\treason,\n\t\t\t\t\t\"cancelled\",\n\t\t\t\t\t`${reason === \"requested\" ? \"Requested c\" : \"C\"}ompaction cancelled`,\n\t\t\t\t\t{ aborted: true, customInstructions, owner },\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (error instanceof CompactionSkippedError) {\n\t\t\t\tawait this._endCompactionUnsuccessfully(\n\t\t\t\t\treason,\n\t\t\t\t\t\"skipped\",\n\t\t\t\t\treason === \"requested\"\n\t\t\t\t\t\t? `Requested compaction skipped: ${errorMessage}`\n\t\t\t\t\t\t: `Auto-compaction skipped: ${errorMessage}`,\n\t\t\t\t\t{ errorSeverity: \"warning\", customInstructions, owner },\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait this._endCompactionUnsuccessfully(\n\t\t\t\t\treason,\n\t\t\t\t\t\"failed\",\n\t\t\t\t\treason === \"overflow\"\n\t\t\t\t\t\t? `Context overflow recovery failed: ${errorMessage}`\n\t\t\t\t\t\t: reason === \"requested\"\n\t\t\t\t\t\t\t? `Requested compaction failed: ${errorMessage}`\n\t\t\t\t\t\t\t: `Auto-compaction failed: ${errorMessage}`,\n\t\t\t\t\t{ customInstructions, owner },\n\t\t\t\t);\n\t\t\t}\n\t\t\trememberThresholdFailure();\n\t\t\tresumeAfterFailure();\n\t\t\treturn false;\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tawait this._releaseCompactionCapture(requests, compaction, failure, owner);\n\t\t\t} finally {\n\t\t\t\tif (this._pendingCheckpoint === resume) this._pendingCheckpoint = undefined;\n\t\t\t\tif (this._autoCompactionAbortController === abort) this._autoCompactionAbortController = undefined;\n\t\t\t\tif (this._compactionOperation === compactionOperation) this._compactionOperation = undefined;\n\t\t\t\tresolveCompactionOperation();\n\t\t\t\tif (this._isCompactionOwnerCurrent(owner)) {\n\t\t\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t\t\t\tthis._scheduleSessionInputPump();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tsetAutoCompactionEnabled(enabled: boolean): void {\n\t\tthis.settingsManager.setCompactionEnabled(enabled);\n\t}\n\n\tget autoCompactionEnabled(): boolean {\n\t\treturn this.settingsManager.getCompactionEnabled();\n\t}\n\n\t/**\n\t * Set the provider for extra env vars merged over process.env in extension\n\t * pi.exec() subprocesses. The function is read at exec time, so a host (e.g.\n\t * the daemon) can update the underlying value per attach without rebinding.\n\t */\n\tsetExecEnvProvider(provider: (() => Record<string, string | undefined> | undefined) | undefined): void {\n\t\tthis._execEnvProvider = provider;\n\t\tconst extensions = this._resourceLoader.getExtensions();\n\t\textensions.runtime.getExecEnv = provider;\n\t}\n\n\tasync bindExtensions(bindings: ExtensionBindings): Promise<void> {\n\t\tif (bindings.uiContext !== undefined) {\n\t\t\tthis._extensionUIContext = bindings.uiContext;\n\t\t}\n\t\tif (bindings.commandContextActions !== undefined) {\n\t\t\tthis._extensionCommandContextActions = bindings.commandContextActions;\n\t\t}\n\t\tif (bindings.shutdownHandler !== undefined) {\n\t\t\tthis._extensionShutdownHandler = bindings.shutdownHandler;\n\t\t}\n\t\tif (bindings.onError !== undefined) {\n\t\t\tthis._extensionErrorListener = bindings.onError;\n\t\t}\n\n\t\tthis._applyExtensionBindings(this._extensionRunner);\n\t\tawait this._extensionRunner.emit(this._sessionStartEvent);\n\t\tawait this.extendResourcesFromExtensions(this._sessionStartEvent.reason === \"reload\" ? \"reload\" : \"startup\");\n\t}\n\n\tprivate async extendResourcesFromExtensions(reason: \"startup\" | \"reload\"): Promise<void> {\n\t\tif (!this._extensionRunner.hasHandlers(\"resources_discover\")) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { skillPaths, promptPaths, themePaths } = await this._extensionRunner.emitResourcesDiscover(\n\t\t\tthis._cwd,\n\t\t\treason,\n\t\t);\n\n\t\tif (skillPaths.length === 0 && promptPaths.length === 0 && themePaths.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst extensionPaths: ResourceExtensionPaths = {\n\t\t\tskillPaths: this.buildExtensionResourcePaths(skillPaths),\n\t\t\tpromptPaths: this.buildExtensionResourcePaths(promptPaths),\n\t\t\tthemePaths: this.buildExtensionResourcePaths(themePaths),\n\t\t};\n\n\t\tthis._resourceLoader.extendResources(extensionPaths);\n\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\tthis.agent.state.systemPrompt = this._baseSystemPrompt;\n\t}\n\n\tprivate buildExtensionResourcePaths(entries: Array<{ path: string; extensionPath: string }>): Array<{\n\t\tpath: string;\n\t\tmetadata: {\n\t\t\tsource: string;\n\t\t\tscope: \"temporary\";\n\t\t\torigin: \"top-level\";\n\t\t\tbaseDir?: string;\n\t\t};\n\t}> {\n\t\treturn entries.map((entry) => {\n\t\t\tconst source = this.getExtensionSourceLabel(entry.extensionPath);\n\t\t\tconst baseDir = entry.extensionPath.startsWith(\"<\") ? undefined : dirname(entry.extensionPath);\n\t\t\treturn {\n\t\t\t\tpath: entry.path,\n\t\t\t\tmetadata: {\n\t\t\t\t\tsource,\n\t\t\t\t\tscope: \"temporary\",\n\t\t\t\t\torigin: \"top-level\",\n\t\t\t\t\tbaseDir,\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t}\n\n\tprivate getExtensionSourceLabel(extensionPath: string): string {\n\t\tif (extensionPath.startsWith(\"<\")) {\n\t\t\treturn `extension:${extensionPath.replace(/[<>]/g, \"\")}`;\n\t\t}\n\t\tconst base = basename(extensionPath);\n\t\tconst name = base.replace(/\\.(ts|js)$/, \"\");\n\t\treturn `extension:${name}`;\n\t}\n\n\tprivate _applyExtensionBindings(runner: ExtensionRunner): void {\n\t\trunner.setUIContext(this._extensionUIContext);\n\t\trunner.bindCommandContext(this._extensionCommandContextActions);\n\n\t\tthis._extensionErrorUnsubscriber?.();\n\t\tthis._extensionErrorUnsubscriber = this._extensionErrorListener\n\t\t\t? runner.onError(this._extensionErrorListener)\n\t\t\t: undefined;\n\t}\n\n\tprivate _refreshCurrentModelFromRegistry(): void {\n\t\tconst currentModel = this.model;\n\t\tif (!currentModel) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst refreshedModel = this._modelRegistry.find(currentModel.provider, currentModel.id);\n\t\tif (!refreshedModel || refreshedModel === currentModel) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.agent.state.model = refreshedModel;\n\t}\n\n\tprivate _bindExtensionCore(runner: ExtensionRunner): void {\n\t\tconst getCommands = (): SlashCommandInfo[] => {\n\t\t\tconst extensionCommands: SlashCommandInfo[] = runner.getRegisteredCommands().map((command) => ({\n\t\t\t\tname: command.invocationName,\n\t\t\t\tdescription: command.description,\n\t\t\t\tsource: \"extension\",\n\t\t\t\tsourceInfo: command.sourceInfo,\n\t\t\t}));\n\n\t\t\tconst templates: SlashCommandInfo[] = this.promptTemplates.map((template) => ({\n\t\t\t\tname: template.name,\n\t\t\t\tdescription: template.description,\n\t\t\t\tsource: \"prompt\",\n\t\t\t\tsourceInfo: template.sourceInfo,\n\t\t\t}));\n\n\t\t\tconst skills: SlashCommandInfo[] = this._resourceLoader.getSkills().skills.map((skill) => ({\n\t\t\t\tname: `skill:${skill.name}`,\n\t\t\t\tdescription: skill.description,\n\t\t\t\tsource: \"skill\",\n\t\t\t\tsourceInfo: skill.sourceInfo,\n\t\t\t}));\n\n\t\t\treturn [...extensionCommands, ...templates, ...skills];\n\t\t};\n\n\t\trunner.bindCore(\n\t\t\t{\n\t\t\t\tsendMessage: async (message, options) => {\n\t\t\t\t\tawait this.sendCustomMessage(message, options).catch((err) => {\n\t\t\t\t\t\trunner.emitError({\n\t\t\t\t\t\t\textensionPath: \"<runtime>\",\n\t\t\t\t\t\t\tevent: \"send_message\",\n\t\t\t\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tsendUserMessage: async (content, options) => {\n\t\t\t\t\tawait this.sendUserMessage(content, options).catch((err) => {\n\t\t\t\t\t\trunner.emitError({\n\t\t\t\t\t\t\textensionPath: \"<runtime>\",\n\t\t\t\t\t\t\tevent: \"send_user_message\",\n\t\t\t\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tappendEntry: async (customType, data) => {\n\t\t\t\t\tawait this.sessionManager.appendCustomEntry(customType, data);\n\t\t\t\t},\n\t\t\t\tsetSessionName: async (name) => {\n\t\t\t\t\tif (this._agentMessageController?.setSessionName) {\n\t\t\t\t\t\tawait this._agentMessageController.setSessionName(name);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setSessionName(name);\n\t\t\t\t},\n\t\t\t\tgetSessionName: () => {\n\t\t\t\t\treturn this.sessionManager.getSessionName();\n\t\t\t\t},\n\t\t\t\tsetLabel: async (entryId, label) => {\n\t\t\t\t\tawait this.sessionManager.appendLabelChange(entryId, label);\n\t\t\t\t},\n\t\t\t\tgetActiveTools: () => this.getActiveToolNames(),\n\t\t\t\tgetAllTools: () => this.getAllTools(),\n\t\t\t\tsetActiveTools: (toolNames) => this.setActiveToolsByName(toolNames),\n\t\t\t\trefreshTools: () => this._refreshToolRegistry(),\n\t\t\t\tgetCommands,\n\t\t\t\tsetModel: async (model) => {\n\t\t\t\t\tif (!this.modelRegistry.hasConfiguredAuth(model)) return false;\n\t\t\t\t\tawait this.setModel(model);\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t\tgetThinkingLevel: () => this.thinkingLevel,\n\t\t\t\tsetThinkingLevel: (level) => this.setThinkingLevel(level),\n\t\t\t},\n\t\t\t{\n\t\t\t\tgetModel: () => this.model,\n\t\t\t\tisIdle: () => !this.isStreaming,\n\t\t\t\tgetSignal: () => this.agent.signal,\n\t\t\t\tabort: () => this.abort(),\n\t\t\t\thasPendingMessages: () => this.queuedActionCount > 0,\n\t\t\t\tshutdown: () => {\n\t\t\t\t\tthis._extensionShutdownHandler?.();\n\t\t\t\t},\n\t\t\t\tgetContextUsage: () => this.getContextUsage(),\n\t\t\t\tcompact: (options) => {\n\t\t\t\t\tvoid (async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst result = await this.compact(options?.customInstructions);\n\t\t\t\t\t\t\toptions?.onComplete?.(result);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\t\t\toptions?.onError?.(err);\n\t\t\t\t\t\t}\n\t\t\t\t\t})();\n\t\t\t\t},\n\t\t\t\tgetSystemPrompt: () => this.systemPrompt,\n\t\t\t},\n\t\t\t{\n\t\t\t\tregisterProvider: (name, config) => {\n\t\t\t\t\tthis._modelRegistry.registerProvider(name, config);\n\t\t\t\t\tthis._refreshCurrentModelFromRegistry();\n\t\t\t\t},\n\t\t\t\tunregisterProvider: (name) => {\n\t\t\t\t\tthis._modelRegistry.unregisterProvider(name);\n\t\t\t\t\tthis._refreshCurrentModelFromRegistry();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n\n\tprivate _refreshToolRegistry(options?: { activeToolNames?: string[]; includeAllExtensionTools?: boolean }): void {\n\t\tconst previousRegistryNames = new Set(this._toolRegistry.keys());\n\t\tconst previousActiveToolNames = this.getActiveToolNames();\n\t\tconst allowedToolNames = this._allowedToolNames;\n\t\tconst registeredTools = this._extensionRunner.getAllRegisteredTools();\n\t\tconst sdkToolEntry = (definition: ToolDefinition) => ({\n\t\t\tdefinition,\n\t\t\tsourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, {\n\t\t\t\tsource: \"sdk\" as const,\n\t\t\t}),\n\t\t});\n\t\tconst allCustomTools = [\n\t\t\t...registeredTools,\n\t\t\t...this._customTools.map(sdkToolEntry),\n\t\t\t...this._acpMcpTools.map(sdkToolEntry),\n\t\t];\n\t\tconst isAllowedTool = (name: string): boolean => !allowedToolNames || allowedToolNames.has(name);\n\t\tconst allowedCustomTools = allCustomTools.filter((tool) => isAllowedTool(tool.definition.name));\n\t\tconst definitionRegistry = new Map<string, ToolDefinitionEntry>(\n\t\t\tArray.from(this._baseToolDefinitions.entries())\n\t\t\t\t.filter(([name]) => isAllowedTool(name))\n\t\t\t\t.map(([name, definition]) => [\n\t\t\t\t\tname,\n\t\t\t\t\t{\n\t\t\t\t\t\tdefinition,\n\t\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${name}>`, {\n\t\t\t\t\t\t\tsource: \"builtin\",\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t]),\n\t\t);\n\t\tfor (const tool of allowedCustomTools) {\n\t\t\tdefinitionRegistry.set(tool.definition.name, {\n\t\t\t\tdefinition: tool.definition,\n\t\t\t\tsourceInfo: tool.sourceInfo,\n\t\t\t});\n\t\t}\n\t\tthis._toolDefinitions = definitionRegistry;\n\t\tthis._toolPromptSnippets = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst snippet = this._normalizePromptSnippet(definition.promptSnippet);\n\t\t\t\t\treturn snippet ? ([definition.name, snippet] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string] => entry !== undefined),\n\t\t);\n\t\tthis._toolPromptGuidelines = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst guidelines = this._normalizePromptGuidelines(definition.promptGuidelines);\n\t\t\t\t\treturn guidelines.length > 0 ? ([definition.name, guidelines] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string[]] => entry !== undefined),\n\t\t);\n\t\tconst runner = this._extensionRunner;\n\t\tconst wrappedExtensionTools = wrapRegisteredTools(allowedCustomTools, runner);\n\t\t// Resolve the runner at call time so a rebuild/reload rebinds built-in tools to the\n\t\t// live runner instead of wedging them on the invalidated one's stale-ctx guard.\n\t\tconst wrappedBuiltInTools = wrapRegisteredTools(\n\t\t\tArray.from(this._baseToolDefinitions.values())\n\t\t\t\t.filter((definition) => isAllowedTool(definition.name))\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${definition.name}>`, { source: \"builtin\" }),\n\t\t\t\t})),\n\t\t\t() => this._extensionRunner,\n\t\t);\n\n\t\t// Only these actual built-in wrappers can establish a recovery execution scope.\n\t\t// Same-name custom tools and baseToolsOverride never enter this identity table.\n\t\tif (!this._baseToolsOverride) {\n\t\t\tfor (const tool of wrappedBuiltInTools) {\n\t\t\t\tif (tool.name === \"prime_context\" || tool.name === \"ipython\")\n\t\t\t\t\tthis._nativeRecoveryTools.set(tool, tool.execute);\n\t\t\t}\n\t\t}\n\t\tconst toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));\n\t\tfor (const tool of wrappedExtensionTools as AgentTool[]) {\n\t\t\ttoolRegistry.set(tool.name, tool);\n\t\t}\n\t\tthis._toolRegistry = toolRegistry;\n\n\t\tconst nextActiveToolNames = (\n\t\t\toptions?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames]\n\t\t).filter((name) => isAllowedTool(name));\n\n\t\tif (allowedToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (allowedToolNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (options?.includeAllExtensionTools) {\n\t\t\tfor (const tool of wrappedExtensionTools) {\n\t\t\t\tnextActiveToolNames.push(tool.name);\n\t\t\t}\n\t\t} else if (!options?.activeToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!previousRegistryNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.setActiveToolsByName([...new Set(nextActiveToolNames)]);\n\t}\n\n\tprivate _buildRuntime(options: {\n\t\tactiveToolNames?: string[];\n\t\tflagValues?: Map<string, boolean | string>;\n\t\tincludeAllExtensionTools?: boolean;\n\t}): void {\n\t\tconst pythonSkills = getPythonSkillRuntimeInfo(this._modelVisibleSkills());\n\t\tlet configuredBaseToolDefinitions: Record<string, ToolDefinition>;\n\t\tif (this._baseToolsOverride) {\n\t\t\tconfiguredBaseToolDefinitions = Object.fromEntries(\n\t\t\t\tObject.entries(this._baseToolsOverride).map(([name, tool]) => [\n\t\t\t\t\tname,\n\t\t\t\t\tcreateToolDefinitionFromAgentTool(tool),\n\t\t\t\t]),\n\t\t\t);\n\t\t} else {\n\t\t\t// Rebuilding (e.g. /reload) replaces the provisioner; drop the previous\n\t\t\t// kernel so the session never holds two live kernels. Gate the new kernel's\n\t\t\t// startup on the old one's dispose (which flushes a final snapshot), so a\n\t\t\t// reload can't restore from a snapshot the old kernel is still writing.\n\t\t\tconst previousDispose = this._ipythonKernelProvisioner?.dispose();\n\t\t\tthis._ipythonKernelSnapshotDir = this.sessionManager.getSessionArtifactDir();\n\t\t\t// Only surface the \"revived from your previous session\" notice on the first\n\t\t\t// build (a genuine resume). A later rebuild (/reload) restores state silently\n\t\t\t// for continuity — the conversation is unchanged, so there's nothing to flag.\n\t\t\tconst notifyRestore = !this._ipythonRuntimeBuilt;\n\t\t\tthis._ipythonKernelProvisioner = new IpythonKernelProvisioner(this._cwd, {\n\t\t\t\tenv: this._rlmKernelEnv(),\n\t\t\t\tcommandPrefix: this.settingsManager.getShellCommandPrefix(),\n\t\t\t\tshellPath: this.settingsManager.getShellPath(),\n\t\t\t\tsessionId: this.sessionId,\n\t\t\t\thostHandlers: this._createKernelHostHandlers(),\n\t\t\t\tpythonSkills,\n\t\t\t\tsnapshotDir: this._ipythonKernelSnapshotDir,\n\t\t\t\treadyGate: previousDispose,\n\t\t\t\tonRestore: notifyRestore ? (result) => this._onIpythonStateRestored(result) : undefined,\n\t\t\t});\n\t\t\tconfiguredBaseToolDefinitions = createAllToolDefinitions(this._cwd, {\n\t\t\t\tprime_context: { recover: (input, signal) => this.recoverNativeHistory(input, signal) },\n\t\t\t\tipython: {\n\t\t\t\t\tcaptureNativeRecoveryScope: () => {\n\t\t\t\t\t\tconst producer = this._nativeRecoveryProducer.getStore();\n\t\t\t\t\t\treturn producer ? (run) => this._nativeRecoveryProducer.run(producer, run) : undefined;\n\t\t\t\t\t},\n\t\t\t\t\tprovisioner: this._ipythonKernelProvisioner,\n\t\t\t\t\tcommandPrefix: this.settingsManager.getShellCommandPrefix(),\n\t\t\t\t\tshellPath: this.settingsManager.getShellPath(),\n\t\t\t\t\tonLateSentAgentMessage: (toolCallId, message) =>\n\t\t\t\t\t\tthis._recordLateIpythonSentAgentMessage(toolCallId, message),\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tthis._baseToolDefinitions = new Map(\n\t\t\tObject.entries(configuredBaseToolDefinitions).map(([name, tool]) => [name, tool as ToolDefinition]),\n\t\t);\n\n\t\tconst extensionsResult = this._resourceLoader.getExtensions();\n\t\tif (options.flagValues) {\n\t\t\tfor (const [name, value] of options.flagValues) {\n\t\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\t}\n\t\t}\n\t\t// Re-apply on (re)build so the provider survives /reload. Guarded: the\n\t\t// runtime object can be shared across sessions from one ResourceLoader\n\t\t// (RLM children), so a provider-less session must not wipe the owner's.\n\t\tif (this._execEnvProvider) {\n\t\t\textensionsResult.runtime.getExecEnv = this._execEnvProvider;\n\t\t}\n\n\t\tthis._extensionRunner = new ExtensionRunner(\n\t\t\textensionsResult.extensions,\n\t\t\textensionsResult.runtime,\n\t\t\tthis._cwd,\n\t\t\tthis.sessionManager,\n\t\t\tthis._modelRegistry,\n\t\t);\n\t\tif (this._extensionRunnerRef) {\n\t\t\tthis._extensionRunnerRef.current = this._extensionRunner;\n\t\t}\n\t\tthis._bindExtensionCore(this._extensionRunner);\n\t\tthis._applyExtensionBindings(this._extensionRunner);\n\n\t\tconst previousAcpMcpToolNames = new Set(this._acpMcpTools.map((tool) => tool.name));\n\t\tconst acpServers = this._mcpManager?.getAcpServers() ?? [];\n\t\tif (acpServers.length > 0 && !this._ipythonKernelProvisioner) {\n\t\t\tthrow new Error(\"ACP MCP servers require the built-in cpython tool\");\n\t\t}\n\t\tconst acpMcpTools = this._ipythonKernelProvisioner\n\t\t\t? createAcpMcpToolDefinitions(acpServers, this._ipythonKernelProvisioner)\n\t\t\t: [];\n\t\tthis._assertAcpMcpToolNamesAvailable(acpMcpTools.map((tool) => tool.name));\n\t\tfor (const name of previousAcpMcpToolNames) this._allowedToolNames?.delete(name);\n\t\tfor (const tool of acpMcpTools) this._allowedToolNames?.add(tool.name);\n\t\tthis._acpMcpTools = acpMcpTools;\n\n\t\tconst defaultActiveToolNames = this._baseToolsOverride\n\t\t\t? Object.keys(this._baseToolsOverride)\n\t\t\t: [\"ipython\", \"prime_context\"];\n\t\tconst baseActiveToolNames = [...(options.activeToolNames ?? defaultActiveToolNames)];\n\t\tif (this._goalState.status === \"active\" && this._includeGoals) {\n\t\t\t// An active goal needs ipython so the model can reach the goal skill.\n\t\t\tbaseActiveToolNames.push(\"ipython\");\n\t\t}\n\t\tthis._refreshToolRegistry({\n\t\t\tactiveToolNames: [...new Set(baseActiveToolNames)],\n\t\t\tincludeAllExtensionTools: options.includeAllExtensionTools,\n\t\t});\n\n\t\tthis._prewarmIpythonIfNeeded();\n\n\t\t// Subsequent builds are in-process rebuilds (/reload), not a fresh resume.\n\t\tthis._ipythonRuntimeBuilt = true;\n\t}\n\n\tprivate _prewarmIpythonIfNeeded(): void {\n\t\t// Also used when an asynchronously restored goal enables ipython after construction.\n\t\tconst hasSnapshot =\n\t\t\t!!this._ipythonKernelSnapshotDir && existsSync(snapshotPathIn(this._ipythonKernelSnapshotDir));\n\t\tif ((this._prewarmIpythonKernel || hasSnapshot) && this.getActiveToolNames().includes(\"ipython\")) {\n\t\t\tthis._ipythonKernelProvisioner?.prewarm();\n\t\t}\n\t}\n\n\t/**\n\t * Skills exposed to the model (system prompt + kernel). The bundled goal\n\t * and compact skills are withheld when disabled for this session.\n\t */\n\tprivate _modelVisibleSkills(): Skill[] {\n\t\tlet skills = this._resourceLoader.getSkills().skills;\n\t\tif (!this._includeGoals) {\n\t\t\tskills = skills.filter((skill) => skill.name !== GOAL_SKILL_NAME);\n\t\t}\n\t\tif (!this._includeCompactSkill) {\n\t\t\tskills = skills.filter((skill) => skill.name !== COMPACT_SKILL_NAME);\n\t\t}\n\t\tif (!this._autoRefineAllowedForSession()) {\n\t\t\tskills = skills.filter((skill) => skill.name !== REFINE_SKILL_NAME);\n\t\t}\n\t\tif (!this._agentMessageController) {\n\t\t\tskills = skills.filter((skill) => skill.name !== AGENT_MESSAGE_SKILL_NAME);\n\t\t}\n\t\tif (!this._agentObserveController) {\n\t\t\tskills = skills.filter((skill) => skill.name !== AGENT_OBSERVE_SKILL_NAME);\n\t\t}\n\t\tif (!this._agentObserveController || !this._rlmHeartbeatController) {\n\t\t\tskills = skills.filter((skill) => skill.name !== ORCHESTRATION_HEARTBEAT_SKILL_NAME);\n\t\t}\n\t\treturn skills;\n\t}\n\n\tprivate _nativeRecoveryEnabled(): boolean {\n\t\tconst nativeDefinition = this._baseToolDefinitions.get(\"prime_context\");\n\t\treturn (\n\t\t\t!this._baseToolsOverride &&\n\t\t\tnativeDefinition !== undefined &&\n\t\t\tthis._toolDefinitions.get(\"prime_context\")?.definition === nativeDefinition &&\n\t\t\tthis.getActiveToolNames().includes(\"prime_context\") &&\n\t\t\t(!this._allowedToolNames || this._allowedToolNames.has(\"prime_context\"))\n\t\t);\n\t}\n\n\tprivate _captureSkillSelectionOwner(): NativeSkillSelectionOwner | undefined {\n\t\tconst manager = this.sessionManager;\n\t\treturn manager.isPersisted()\n\t\t\t? {\n\t\t\t\t\tmanager,\n\t\t\t\t\tsessionId: manager.getSessionId(),\n\t\t\t\t\tsessionFile: manager.getSessionFile(),\n\t\t\t\t\twriter: manager[bindNativeEntryWriter]().captureSkillSelection(),\n\t\t\t\t\tinputEpoch: this._sessionInputPumpEpoch,\n\t\t\t\t}\n\t\t\t: undefined;\n\t}\n\n\tprivate _assertSkillSelectionOwner(owner: NativeSkillSelectionOwner): void {\n\t\towner.writer.assertCurrent();\n\t\tif (\n\t\t\tthis.sessionManager !== owner.manager ||\n\t\t\towner.sessionId !== owner.manager.getSessionId() ||\n\t\t\towner.sessionFile !== owner.manager.getSessionFile() ||\n\t\t\t(owner.inputEpoch !== undefined && owner.inputEpoch !== this._sessionInputPumpEpoch)\n\t\t)\n\t\t\tthrow new Error(\"Skill selection owner changed\");\n\t}\n\n\tprivate async _selectNativeSkill(\n\t\tskill: Skill,\n\t\towner: NativeSkillSelectionOwner,\n\t\tmodelInvocation: boolean,\n\t\tsignal?: AbortSignal,\n\t): Promise<\n\t\t| { ref: string; capture: SelectedSkillCapture; source: NativeSkillSourceRef; assertCurrent: () => void }\n\t\t| undefined\n\t> {\n\t\tconst assertCurrent = () => {\n\t\t\tsignal?.throwIfAborted();\n\t\t\tthis._assertSkillSelectionOwner(owner);\n\t\t\tif (modelInvocation && !this._nativeRecoveryEnabled())\n\t\t\t\tthrow new Error(\"Native skill selection is not authorized\");\n\t\t};\n\t\tassertCurrent();\n\t\tconst descriptor = captureSkillDescriptor(skill);\n\t\tconst result = (ref: string, capture: SelectedSkillCapture) => ({\n\t\t\tref,\n\t\t\tcapture,\n\t\t\tassertCurrent,\n\t\t\tsource: { sessionId: owner.sessionId, sessionFile: owner.sessionFile, entryId: ref },\n\t\t});\n\t\tconst state = await owner.manager.readBranchHistory((history) =>\n\t\t\treadSkillSelection(history.branchContext, descriptor.name, this.settingsManager.getCanonicalContextLimits()),\n\t\t);\n\t\tassertCurrent();\n\t\tif (!this._contextEpochsEnabled && !state.checkpoint) return;\n\t\tconst fixed =\n\t\t\tcontextEpochMode(state.checkpoint, this._initialContextMode) === \"off\" ||\n\t\t\t(state.checkpoint?.policyOnly === true && !this._contextEpochsEnabled);\n\t\t// A new file capture is eligible only after an actual accepted epoch boundary.\n\t\t// Off/fixed reads keep the retained version; no file read is a policy/epoch ACK.\n\t\tconst sameSource =\n\t\t\t!state.capture || selectedSkillIdentity(state.capture.descriptor) === selectedSkillIdentity(descriptor);\n\t\tif (state.reference && !sameSource && fixed)\n\t\t\tthrow new Error(\"Fixed context cannot substitute a different effective skill source\");\n\t\tif (\n\t\t\tstate.reference &&\n\t\t\tstate.capture &&\n\t\t\tsameSource &&\n\t\t\t(state.pending ||\n\t\t\t\tfixed ||\n\t\t\t\tJSON.stringify(state.reference.view.source) === JSON.stringify(state.checkpoint?.source))\n\t\t)\n\t\t\treturn result(state.reference.view.ref.entryId, state.capture);\n\t\tconst capture = captureSelectedSkill(descriptor);\n\t\tconst ref = await owner.writer.append(capture, modelInvocation ? \"model\" : \"command\");\n\t\tassertCurrent(); // A completed source append is not rolled back on cancellation or owner change.\n\t\treturn result(ref, capture);\n\t}\n\n\t/** Read only the server-owned branch captured for this operation (including a batch). */\n\tasync recoverNativeHistory(\n\t\tinput: NativeRecoveryInput,\n\t\tsignal?: AbortSignal,\n\t\tmaxBytes = DEFAULT_NATIVE_RECOVERY_LIMITS.maxBytes,\n\t): Promise<NativeRecoveryResponse> {\n\t\tsignal?.throwIfAborted();\n\t\tconst request = parseNativeRecoveryInput(input);\n\t\tconst responseBytes = Math.min(maxBytes, DEFAULT_NATIVE_RECOVERY_LIMITS.maxBytes, request.maxBytes ?? Infinity);\n\t\tif (!this._nativeRecoveryEnabled()) {\n\t\t\treturn createNativeRecoveryRefusal(\"not_authorized\", \"native_recovery_not_enabled\", responseBytes);\n\t\t}\n\t\t// Only the real authorized reader can latch this private admitted execution.\n\t\t// A replacement method/result or descriptive JSON cannot set the producer bit.\n\t\tconst producer = this._nativeRecoveryProducer.getStore();\n\t\tif (producer) producer.used = true;\n\t\tif (request.action === \"skill\") {\n\t\t\tif (!producer?.skillOwner)\n\t\t\t\treturn createNativeRecoveryRefusal(\n\t\t\t\t\t\"not_authorized\",\n\t\t\t\t\t\"native_skill_selection_owner_required\",\n\t\t\t\t\tresponseBytes,\n\t\t\t\t);\n\t\t\tconst skill = this._modelVisibleSkills().find(\n\t\t\t\t(item) => item.name === request.name && !item.disableModelInvocation,\n\t\t\t);\n\t\t\tif (!skill) return createNativeRecoveryRefusal(\"not_authorized\", \"skill_not_model_visible\", responseBytes);\n\t\t\tconst selected = await this._selectNativeSkill(skill, producer.skillOwner, true, signal);\n\t\t\tif (!selected)\n\t\t\t\treturn createNativeRecoveryRefusal(\"unavailable\", \"native_skill_epoch_not_enabled\", responseBytes);\n\t\t\tselected.assertCurrent();\n\t\t\treturn producer.skillOwner.manager.readBranchHistory((history) =>\n\t\t\t\trecoverCapturedHistory(\n\t\t\t\t\thistory.branchContext,\n\t\t\t\t\t{ action: \"read\", ref: selected.ref, maxBytes: responseBytes },\n\t\t\t\t\t{ ...DEFAULT_NATIVE_RECOVERY_LIMITS, maxBytes: responseBytes },\n\t\t\t\t\tsignal,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\t// readBranchHistory captures synchronously and preserves ordered read/release errors.\n\t\t// Never accept a caller's owner/path/frontier or turn a failed read into evidence of absence.\n\t\ttry {\n\t\t\tconst manager = producer?.skillOwner?.manager ?? this.sessionManager;\n\t\t\tproducer?.skillOwner?.writer.assertCurrent();\n\t\t\tif (this.sessionManager !== manager) throw new Error(\"Native recovery source changed\");\n\t\t\tconst cursorSource = JSON.stringify([manager.getSessionId(), manager.getSessionFile()]);\n\t\t\tif (this._nativeRecoveryCursorSource !== cursorSource) {\n\t\t\t\tthis._nativeRecoveryCursors.clear();\n\t\t\t\tthis._nativeRecoveryCursorSource = cursorSource;\n\t\t\t}\n\t\t\treturn await manager.readBranchHistory((history) =>\n\t\t\t\trecoverCapturedHistory(\n\t\t\t\t\thistory.branchContext,\n\t\t\t\t\trequest,\n\t\t\t\t\t{ ...DEFAULT_NATIVE_RECOVERY_LIMITS, maxBytes: responseBytes },\n\t\t\t\t\tsignal,\n\t\t\t\t\tthis._nativeRecoveryCursors,\n\t\t\t\t),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tsignal?.throwIfAborted();\n\t\t\tif (error instanceof NativeRecoveryBudgetRefusal) throw error;\n\t\t\treturn createNativeRecoveryRefusal(\"unavailable\", \"captured_history_unavailable\", responseBytes);\n\t\t}\n\t}\n\n\tprivate _createKernelHostHandlers(): HostRequestHandlers {\n\t\tconst handlers: HostRequestHandlers = {\n\t\t\tprime_context: async (payload, context) => {\n\t\t\t\tif (!context?.nativeRecovery) {\n\t\t\t\t\treturn { ...createNativeRecoveryRefusal(\"not_authorized\", \"active_cell_required\") };\n\t\t\t\t}\n\t\t\t\tconst input = parseNativeRecoveryInput(payload.request);\n\t\t\t\treturn { ...(await this.recoverNativeHistory(input, context.signal, context.nativeRecovery.maxBytes)) };\n\t\t\t},\n\t\t\t\"rlm.run\": createRlmRunHostHandler(async ({ prompt, kwargs, cellSourceCode }) => ({\n\t\t\t\t...(await this.runRlmChild(prompt, kwargs, cellSourceCode)),\n\t\t\t})),\n\t\t\t\"rlm.find_models\": createRlmFindModelsHostHandler((query, limit) => this.findRlmModels(query, limit)),\n\t\t\t\"rlm.list_subagents\": createRlmListSubagentsHostHandler(() => this.listRlmSubagents()),\n\t\t\t\"rlm.delete_subagent\": createRlmDeleteSubagentHostHandler((target) => this.deleteRlmSubagent(target)),\n\t\t\t\"model.info\": async () => ({\n\t\t\t\tid: this.model?.id ?? null,\n\t\t\t\tprovider: this.model?.provider ?? null,\n\t\t\t\tinput: this.model?.input ?? [],\n\t\t\t}),\n\t\t};\n\t\tif (this._includeGoals) {\n\t\t\tfor (const type of [\"goal.get\", \"goal.create\", \"goal.complete\"]) {\n\t\t\t\thandlers[type] = async (payload) => this.handleGoalHostRequest(type, payload);\n\t\t\t}\n\t\t}\n\t\tif (this._includeCompactSkill) {\n\t\t\tfor (const type of [\"compact.run\", \"compact.status\"]) {\n\t\t\t\thandlers[type] = async (payload) => this.handleCompactHostRequest(type, payload);\n\t\t\t}\n\t\t}\n\t\tif (this._autoRefineAllowedForSession()) {\n\t\t\tfor (const type of [\"refine.run\", \"refine.status\"]) {\n\t\t\t\thandlers[type] = async (payload) => this.handleRefineHostRequest(type, payload);\n\t\t\t}\n\t\t}\n\t\tif (this._rlmHeartbeatController) {\n\t\t\tfor (const type of [\n\t\t\t\t\"rlm_heartbeat.list\",\n\t\t\t\t\"rlm_heartbeat.create\",\n\t\t\t\t\"rlm_heartbeat.update\",\n\t\t\t\t\"rlm_heartbeat.delete\",\n\t\t\t]) {\n\t\t\t\thandlers[type] = async (payload) => this.handleRlmHeartbeatHostRequest(type, payload);\n\t\t\t}\n\t\t}\n\t\tconst visibleKernelSkillNames = new Set(\n\t\t\tthis._modelVisibleSkills()\n\t\t\t\t.filter((skill) => !skill.disableModelInvocation)\n\t\t\t\t.map((skill) => skill.name),\n\t\t);\n\t\tif (this._agentMessageController && visibleKernelSkillNames.has(AGENT_MESSAGE_SKILL_NAME)) {\n\t\t\tObject.assign(\n\t\t\t\thandlers,\n\t\t\t\tcreateAgentMessageHostHandlers({\n\t\t\t\t\troster: async () =>\n\t\t\t\t\t\t(await this.handleAgentMessageHostRequest(\"agent_message.list_agents\")) as AgentFamilyRosterResult,\n\t\t\t\t\tawaitPendingChildPublication: (selector) => this._awaitPendingRlmChildPublication(selector),\n\t\t\t\t\tsendAgentMessage: async (input) => {\n\t\t\t\t\t\tconst receipt = (await (input.findings === undefined\n\t\t\t\t\t\t\t? this.handleAgentMessageHostRequest(\"agent_message.send\", {\n\t\t\t\t\t\t\t\t\ttarget: input.target,\n\t\t\t\t\t\t\t\t\tmessage: input.message,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t: this.handleAgentMessageHostRequest(\"agent_message.send_result\", {\n\t\t\t\t\t\t\t\t\ttarget: input.target,\n\t\t\t\t\t\t\t\t\tsummary: input.message,\n\t\t\t\t\t\t\t\t\tfindings: input.findings,\n\t\t\t\t\t\t\t\t}))) as AgentSessionMessageReceipt;\n\t\t\t\t\t\tif (this._rlmDepth > 0) {\n\t\t\t\t\t\t\tlet addressedParent = input.receiverRole === \"parent\";\n\t\t\t\t\t\t\tif (input.receiverRole === undefined && this._agentMessageController?.roster) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst roster = await this._agentMessageController.roster();\n\t\t\t\t\t\t\t\t\taddressedParent = roster.entries.some(\n\t\t\t\t\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\t\t\t\t\tentry.relationship === \"parent\" &&\n\t\t\t\t\t\t\t\t\t\t\t(entry.id === input.target || entry.name === input.target),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\taddressedParent = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (addressedParent) {\n\t\t\t\t\t\t\t\tthis._repliedToParentSinceTask = true;\n\t\t\t\t\t\t\t\tthis._parentReplyCount += 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn receipt;\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tif (this._agentObserveController) {\n\t\t\tObject.assign(\n\t\t\t\thandlers,\n\t\t\t\tcreateAgentObserveHostHandlers({\n\t\t\t\t\tlistAgents: () => this.handleAgentObserveHostRequest(\"agent_observe.list\") as AgentObserveListResult,\n\t\t\t\t\tgetAgent: (target) =>\n\t\t\t\t\t\tthis.handleAgentObserveHostRequest(\"agent_observe.get\", {\n\t\t\t\t\t\t\ttarget,\n\t\t\t\t\t\t}) as AgentObserveAgentSnapshot,\n\t\t\t\t\trecentMessages: (input) =>\n\t\t\t\t\t\tthis.handleAgentObserveHostRequest(\"agent_observe.recent\", {\n\t\t\t\t\t\t\ttarget: input.target,\n\t\t\t\t\t\t\tlimit: input.limit,\n\t\t\t\t\t\t\tmax_chars: input.maxChars,\n\t\t\t\t\t\t}) as AgentObserveRecentMessagesResult,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tif (this._mcpManager) {\n\t\t\tObject.assign(handlers, this._mcpManager.hostHandlers());\n\t\t}\n\t\treturn handlers;\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tconst previousFlagValues = this._extensionRunner.getFlagValues();\n\t\tawait emitSessionShutdownEvent(this._extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason: \"reload\",\n\t\t});\n\t\tawait this.settingsManager.reload();\n\t\t// Re-read auth.json: a login saved by the client process (daemon mode) must be\n\t\t// visible here so MCP skill gating sees the new credentials.\n\t\tthis._modelRegistry.authStorage.reload();\n\t\tresetApiProviders();\n\t\tthis._mcpManager?.refresh();\n\t\tawait this._resourceLoader.reload();\n\t\tthis._buildRuntime({\n\t\t\tactiveToolNames: this.getActiveToolNames(),\n\t\t\tflagValues: previousFlagValues,\n\t\t\tincludeAllExtensionTools: true,\n\t\t});\n\n\t\tconst hasBindings =\n\t\t\tthis._extensionUIContext ||\n\t\t\tthis._extensionCommandContextActions ||\n\t\t\tthis._extensionShutdownHandler ||\n\t\t\tthis._extensionErrorListener;\n\t\tif (hasBindings) {\n\t\t\tawait this._extensionRunner.emit({\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"reload\",\n\t\t\t});\n\t\t\tawait this.extendResourcesFromExtensions(\"reload\");\n\t\t}\n\t}\n\n\tprivate _rlmKernelEnv(): Record<string, string> {\n\t\t// Kernel env is provisioning-time only: BASE_CONTEXT_RLM_MAX_DEPTH may be stale in an already-running kernel;\n\t\t// the TypeScript-side spawn check remains authoritative.\n\t\tconst env: Record<string, string> = {\n\t\t\tBASE_CONTEXT_RLM_DEPTH: String(this._rlmDepth),\n\t\t\tBASE_CONTEXT_RLM_MAX_DEPTH: String(this._rlmMaxDepth),\n\t\t\tBASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR: getGlobalHarnessStateDir(),\n\t\t\tBASE_CONTEXT_WORKSPACE_HARNESS_STATE_DIR: getWorkspaceHarnessStateDir(this._cwd),\n\t\t};\n\t\tconst rlmSessionDir = this._ensureRlmSessionDir();\n\t\tif (rlmSessionDir) {\n\t\t\tenv.BASE_CONTEXT_KERNEL_SESSION_DIR = rlmSessionDir;\n\t\t\t// Keep kernel writes and host reads (system prompt, review, /refine) on\n\t\t\t// the same local harness path. Subagents prefer their own artifact dir;\n\t\t\t// ephemeral sessions fall back to the RLM session dir once it exists.\n\t\t\tenv.BASE_CONTEXT_HARNESS_STATE_DIR = this._localHarnessStateDir() ?? getLocalHarnessStateDir(rlmSessionDir)!;\n\t\t}\n\t\tthis._addWebsearchKeyEnv(env);\n\t\treturn env;\n\t}\n\n\tprivate _addWebsearchKeyEnv(env: Record<string, string>): void {\n\t\tif (this._agentDir) {\n\t\t\tenv.BASE_CONTEXT_HOME = this._agentDir;\n\t\t}\n\n\t\tif (process.env[SERPER_ENV_VAR]?.trim()) {\n\t\t\treturn;\n\t\t}\n\t\t// Inject only when a websearch skill (bundled or custom) is actually loaded,\n\t\t// so the key isn't exposed to kernels that can't use it.\n\t\tif (!this._resourceLoader.getSkills().skills.some((skill) => skill.name === WEBSEARCH_SKILL_NAME)) {\n\t\t\treturn;\n\t\t}\n\t\tconst cred = this._modelRegistry.authStorage.get(SERPER_CREDENTIAL_ID);\n\t\tif (cred?.type !== \"api_key\") {\n\t\t\treturn;\n\t\t}\n\t\tconst resolved = resolveConfigValue(cred.key)?.trim();\n\t\tif (resolved) {\n\t\t\tenv[SERPER_ENV_VAR] = resolved;\n\t\t}\n\t}\n\n\t// Undefined when there's no persistent artifact dir (e.g. the viewer client):\n\t// don't mkdtemp here, since this runs on every kernel build but a viewer never\n\t// does RLM work. The temp dir is created lazily in _createChildRlmSessionDir.\n\tprivate _ensureRlmSessionDir(): string | undefined {\n\t\tif (this._rlmSessionDir) {\n\t\t\tmkdirSync(this._rlmSessionDir, { recursive: true });\n\t\t\treturn this._rlmSessionDir;\n\t\t}\n\n\t\tconst sessionArtifactDir = this.sessionManager.getSessionArtifactDir();\n\t\tif (sessionArtifactDir) {\n\t\t\tmkdirSync(sessionArtifactDir, { recursive: true });\n\t\t\tthis._rlmSessionDir = sessionArtifactDir;\n\t\t\treturn sessionArtifactDir;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tprivate _createChildRlmSessionDir(): string {\n\t\tconst parentDir = this._ensureRlmSessionDir() ?? this._createEphemeralRlmSessionDir();\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\tconst childDir = join(parentDir, `sub-${randomUUID().slice(0, 8)}`);\n\t\t\ttry {\n\t\t\t\tmkdirSync(childDir);\n\t\t\t\treturn childDir;\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof Error && \"code\" in error && error.code === \"EEXIST\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tthrow new Error(\"Unable to create unique RLM child session directory\");\n\t}\n\n\tprivate _createEphemeralRlmSessionDir(): string {\n\t\tthis._rlmSessionDir = mkdtempSync(join(tmpdir(), `${PRODUCT.command}-rlm-`));\n\t\treturn this._rlmSessionDir;\n\t}\n\n\t_contextTokensForCurrentMessages(): number | undefined {\n\t\tconst last = this._findLastAssistantMessage();\n\t\treturn last ? calculateContextTokens(last.usage) : undefined;\n\t}\n\n\tsetCurrentRecap(recap: string | undefined): void {\n\t\tif (this._currentRecap === recap) return;\n\t\tthis._currentRecap = recap;\n\t\tthis._emit({ type: \"recap_update\", recap });\n\t}\n\n\tget repliedToParentSinceTask(): boolean | undefined {\n\t\treturn this._repliedToParentSinceTask;\n\t}\n\n\tgetCurrentRecap(): string | undefined {\n\t\treturn this._currentRecap;\n\t}\n\n\tprivate _removeLastAssistantFromContext(): void {\n\t\tconst messages = this.agent.state.messages;\n\t\tconst message = messages.at(-1);\n\t\tif (message?.role !== \"assistant\") return;\n\t\tif (this.sessionManager.isPersisted()) {\n\t\t\tconst entryId = this._findAssistantEntryIdForMessage(message);\n\t\t\tif (!entryId) throw new Error(\"Cannot identify the acknowledged assistant response removed by retry control\");\n\t\t\tif (\n\t\t\t\tthis._contextOmissions?.sessionId !== this.sessionId ||\n\t\t\t\tthis._contextOmissions?.sessionFile !== this.sessionFile\n\t\t\t)\n\t\t\t\tthis._contextOmissions = { sessionId: this.sessionId, sessionFile: this.sessionFile, ids: new Set() };\n\t\t\tthis._contextOmissions.ids.add(entryId);\n\t\t}\n\t\tthis.agent.state.messages = messages.slice(0, -1);\n\t}\n\n\tprivate _findAssistantEntryIdForMessage(message: AssistantMessage): string | undefined {\n\t\tconst source = this._assistantEntryIds.get(message) ?? getCanonicalMessageSource(message);\n\t\tif (source)\n\t\t\treturn source.sessionId === this.sessionId && source.sessionFile === this.sessionFile\n\t\t\t\t? source.entryId\n\t\t\t\t: undefined;\n\t\tif (this.sessionManager.isPersisted()) return undefined;\n\t\treturn this.sessionManager.getEntries().find((entry) => entry.type === \"message\" && entry.message === message)\n\t\t\t?.id;\n\t}\n\n\tget hasRlmParentAdmission(): boolean {\n\t\treturn this._releaseRlmResidentCapacity !== undefined;\n\t}\n\n\t/** Reserve before setup awaits. Capacity remains owned until real cleanup completes. */\n\tasync reserveRlmChildAdmission(): Promise<RlmChildAdmission> {\n\t\tif (this._disposed || this._disposing || this._disposeAsyncPromise) {\n\t\t\tthrow new Error(\"Cannot spawn a subagent after its parent was disposed\");\n\t\t}\n\t\tconst controller = new AbortController();\n\t\tconst settlement = createAgentMessageDeferred();\n\t\tlet child: AgentSession | undefined;\n\t\tlet settled = false;\n\t\tlet factoryClaimed = false;\n\t\tlet unboundCleanupComplete = true;\n\t\tlet capacity: RlmSubagentCapacityReservation | undefined;\n\t\tlet capacityRelease: Promise<void> | undefined;\n\t\tconst release = async () => {\n\t\t\tif (!settled || (child ? !child._rlmResidentDisposalComplete : !unboundCleanupComplete)) return;\n\t\t\tif (capacity) {\n\t\t\t\tcapacityRelease ??= capacity.release();\n\t\t\t\tawait capacityRelease;\n\t\t\t}\n\t\t\tthis._rlmChildAdmissions.delete(admission);\n\t\t\tif (child?._releaseRlmResidentCapacity === release) child._releaseRlmResidentCapacity = undefined;\n\t\t\tif (child?._rlmParentAdmission === admission) child._rlmParentAdmission = undefined;\n\t\t};\n\t\tconst admission: RlmChildAdmission & { cancel(reason: string): boolean } = {\n\t\t\tparent: this,\n\t\t\tget session() {\n\t\t\t\treturn child;\n\t\t\t},\n\t\t\tsettlement: settlement.promise,\n\t\t\tget pending() {\n\t\t\t\treturn !settled;\n\t\t\t},\n\t\t\tassertCurrent: () => {\n\t\t\t\tcontroller.signal.throwIfAborted();\n\t\t\t\tif (\n\t\t\t\t\tthis._disposed ||\n\t\t\t\t\tthis._disposing ||\n\t\t\t\t\tthis._disposeAsyncPromise ||\n\t\t\t\t\t!this._rlmChildAdmissions.has(admission)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\"RLM child admission is no longer current\");\n\t\t\t\t}\n\t\t\t},\n\t\t\tbind: (session) => {\n\t\t\t\tif (!this._rlmChildAdmissions.has(admission)) throw new Error(\"RLM child admission is no longer current\");\n\t\t\t\tif (\n\t\t\t\t\t(child && child !== session) ||\n\t\t\t\t\t(session._releaseRlmResidentCapacity && session._releaseRlmResidentCapacity !== release)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\"RLM child already belongs to another resident admission\");\n\t\t\t\t}\n\t\t\t\tchild = session;\n\t\t\t\tsession._rlmParentAdmission = admission;\n\t\t\t\tsession._rlmSubagentCapacity = this._rlmSubagentCapacity;\n\t\t\t\tsession._releaseRlmResidentCapacity = release;\n\t\t\t},\n\t\t\tbeginSetup: () => {\n\t\t\t\tif (settled || child) throw new Error(\"RLM child admission already started a child\");\n\t\t\t\tunboundCleanupComplete = false;\n\t\t\t},\n\t\t\tclaimFactory: () => {\n\t\t\t\tif (factoryClaimed) throw new Error(\"RLM child admission already started a factory\");\n\t\t\t\tadmission.beginSetup();\n\t\t\t\tfactoryClaimed = true;\n\t\t\t},\n\t\t\tconfirmUnboundCleanup: async () => {\n\t\t\t\tunboundCleanupComplete = true;\n\t\t\t\tawait release();\n\t\t\t},\n\t\t\tsettle: async () => {\n\t\t\t\tsettled = true;\n\t\t\t\ttry {\n\t\t\t\t\tawait release();\n\t\t\t\t} finally {\n\t\t\t\t\tsettlement.resolve();\n\t\t\t\t}\n\t\t\t},\n\t\t\tcancel: (reason) => {\n\t\t\t\tif (settled || controller.signal.aborted) return false;\n\t\t\t\tcontroller.abort(new Error(reason));\n\t\t\t\tvoid child?.abort();\n\t\t\t\treturn true;\n\t\t\t},\n\t\t};\n\t\tthis._rlmChildAdmissions.add(admission);\n\t\ttry {\n\t\t\tcapacity = await this._rlmSubagentCapacity.reserve();\n\t\t\tadmission.assertCurrent();\n\t\t\treturn admission;\n\t\t} catch (error) {\n\t\t\tawait admission.settle();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate _createRlmSubagentRuntimeOptions(options: {\n\t\tadmission: RlmChildAdmission;\n\t\tid: string;\n\t\tprompt: string;\n\t\tsessionName: string;\n\t\tspawnCode?: string;\n\t\tsessionDir: string;\n\t\tmodel: Model<any>;\n\t\tthinkingLevel?: ThinkingLevel;\n\t\tspawnedByRequestId?: string;\n\t}): CreateRlmSubagentRuntimeOptions & { admission: RlmChildAdmission } {\n\t\tconst requestTokenBudget = this.requests.getRequestTokenBudgetOptions();\n\t\treturn {\n\t\t\tparentSession: this,\n\t\t\tcontextMode: this.contextMode,\n\t\t\t...(requestTokenBudget === undefined ? {} : { requestTokenBudget }),\n\t\t\tadmission: options.admission,\n\t\t\tid: options.id,\n\t\t\tprompt: options.prompt,\n\t\t\tsessionName: options.sessionName,\n\t\t\tspawnCode: options.spawnCode,\n\t\t\tsessionDir: options.sessionDir,\n\t\t\tmodel: options.model,\n\t\t\tthinkingLevel:\n\t\t\t\toptions.thinkingLevel ?? (clampThinkingLevel(options.model, this.thinkingLevel) as ThinkingLevel),\n\t\t\tserviceTier:\n\t\t\t\tthis.serviceTier === \"priority\" && !supportsFastMode(options.model) ? \"default\" : this.serviceTier,\n\t\t\tscopedModels: [...this._scopedModels],\n\t\t\tactiveToolNames: this.getActiveToolNames(),\n\t\t\tallowedToolNames: this._allowedToolNames ? [...this._allowedToolNames] : undefined,\n\t\t\tcustomTools: [...this._customTools],\n\t\t\tincludeGoals: this._includeGoals,\n\t\t\tincludeCompactSkill: this._includeCompactSkill,\n\t\t\trlmDepth: this._rlmDepth + 1,\n\t\t\trlmMaxDepth: this._rlmMaxDepth,\n\t\t\trlmParentNodeId: options.id,\n\t\t\tspawnedByRequestId: options.spawnedByRequestId,\n\t\t};\n\t}\n\n\tprivate async _createRlmSubagentRuntime(\n\t\toptions: CreateRlmSubagentRuntimeOptions & { admission: RlmChildAdmission },\n\t): Promise<RlmSubagentRuntime> {\n\t\toptions.admission.assertCurrent();\n\t\toptions.admission.beginSetup();\n\t\tif (this._subagentRuntimeHost) {\n\t\t\treturn await this._subagentRuntimeHost.createRlmSubagentRuntime(options);\n\t\t}\n\n\t\treturn this._createInlineRlmSubagentRuntime(options);\n\t}\n\n\tprivate async _createInlineRlmSubagentRuntime(\n\t\toptions: CreateRlmSubagentRuntimeOptions & { admission: RlmChildAdmission },\n\t): Promise<RlmSubagentRuntime> {\n\t\toptions.admission.claimFactory();\n\t\tconst parentSessionFile = options.parentSession.sessionFile;\n\t\tconst parentSessionId = options.parentSession.sessionId;\n\t\tconst parentAgent = options.parentSession.sessionName ?? parentSessionId;\n\t\tconst childSessionManager = await SessionManager.create(this._cwd, options.sessionDir, {\n\t\t\tparentSession: parentSessionFile,\n\t\t\trlmDepth: options.rlmDepth,\n\t\t});\n\t\tlet child: AgentSession | undefined;\n\t\ttry {\n\t\t\toptions.admission.assertCurrent();\n\t\t\tawait childSessionManager.appendModelChange(options.model.provider, options.model.id);\n\t\t\tawait childSessionManager.appendThinkingLevelChange(options.thinkingLevel);\n\t\t\tawait childSessionManager.appendServiceTierChange(options.serviceTier);\n\n\t\t\tconst childAgent = new Agent({\n\t\t\t\tinitialState: {\n\t\t\t\t\tsystemPrompt: \"\",\n\t\t\t\t\tmodel: options.model,\n\t\t\t\t\tthinkingLevel: options.thinkingLevel,\n\t\t\t\t\tserviceTier: options.serviceTier,\n\t\t\t\t\ttools: [],\n\t\t\t\t},\n\t\t\t\tconvertToLlm: this.agent.convertToLlm,\n\t\t\t\ttransformContext: this.agent.transformContext,\n\t\t\t\tstreamFn: this.agent.streamFn,\n\t\t\t\tgetApiKey: this.agent.getApiKey,\n\t\t\t\tonPayload: this.agent.onPayload,\n\t\t\t\tonResponse: this.agent.onResponse,\n\t\t\t\tsteeringMode: this.settingsManager.getSteeringMode(),\n\t\t\t\tfollowUpMode: this.settingsManager.getFollowUpMode(),\n\t\t\t\tsessionId: childSessionManager.getSessionId(),\n\t\t\t\tthinkingBudgets: this.settingsManager.getThinkingBudgets(),\n\t\t\t\ttransport: this.settingsManager.getTransport(),\n\t\t\t\tmaxRetryDelayMs: this.settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\t\t\ttoolExecution: this.agent.toolExecution,\n\t\t\t});\n\n\t\t\tchild = new AgentSession({\n\t\t\t\tagent: childAgent,\n\t\t\t\trequestTokenBudget: options.requestTokenBudget,\n\t\t\t\tcontextMode: options.contextMode,\n\t\t\t\tsessionManager: childSessionManager,\n\t\t\t\tsettingsManager: this.settingsManager,\n\t\t\t\tcwd: this._cwd,\n\t\t\t\tagentDir: this._agentDir,\n\t\t\t\tscopedModels: options.scopedModels,\n\t\t\t\tresourceLoader: this._resourceLoader,\n\t\t\t\tcustomTools: options.customTools,\n\t\t\t\tmodelRegistry: this._modelRegistry,\n\t\t\t\tinitialActiveToolNames: options.activeToolNames,\n\t\t\t\tallowedToolNames: options.allowedToolNames,\n\t\t\t\tincludeGoals: options.includeGoals,\n\t\t\t\tincludeCompactSkill: options.includeCompactSkill,\n\t\t\t\trlmDepth: options.rlmDepth,\n\t\t\t\trlmMaxDepth: options.rlmMaxDepth,\n\t\t\t\trlmSessionDir: options.sessionDir,\n\t\t\t\trlmParentNodeId: options.rlmParentNodeId,\n\t\t\t\trlmParentAgent: parentAgent,\n\t\t\t\trlmChildAdmission: options.admission,\n\t\t\t\tsemanticParentSessionId: parentSessionId,\n\t\t\t\tsemanticSpawnedByRequestId: options.spawnedByRequestId,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"startup\" },\n\t\t\t});\n\t\t\tawait child.initialize();\n\t\t\tif (child.sessionName !== options.sessionName) {\n\t\t\t\tawait child.setSessionName(options.sessionName);\n\t\t\t}\n\t\t\toptions.onSessionPublished?.(child);\n\n\t\t\treturn { session: child };\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tconst failedChild = child ?? options.admission.session;\n\t\t\t\tif (failedChild) await failedChild.disposeAsync();\n\t\t\t\telse {\n\t\t\t\t\tawait childSessionManager.close();\n\t\t\t\t\tawait options.admission.confirmUnboundCleanup();\n\t\t\t\t}\n\t\t\t} catch (cleanupError) {\n\t\t\t\tif (cleanupError === error || (error instanceof AggregateError && error.errors.includes(cleanupError)))\n\t\t\t\t\tthrow error;\n\t\t\t\tthrow new AggregateError([error, cleanupError], \"RLM startup and cleanup failed\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate _abandonRlmRunForQuiescence(run: RlmChildRun): void {\n\t\trun.suppressTerminalNotice = true;\n\t\trun.abandonedForQuiescence = true;\n\t\tthis._abandonedRlmQuiescenceChildIds.add(run.id);\n\t\tthis._unsettledRlmChildRuns.delete(run);\n\t\trun.settlement.resolve();\n\t\tthis._scheduleGoalContinuationAfterRlmWork();\n\t}\n\n\tprivate _cancelActiveRlmChildRuns(reason: string): void {\n\t\tfor (const admission of this._rlmChildAdmissions) admission.cancel(reason);\n\t\tfor (const run of this._activeRlmChildRuns.values()) {\n\t\t\tthis._cancelRlmChildRun(run, reason);\n\t\t}\n\t}\n\n\tprivate _cancelRlmChildRun(run: RlmChildRun, reason: string): boolean {\n\t\tif (run.status !== \"running\" && run.status !== \"queued\") {\n\t\t\treturn false;\n\t\t}\n\t\trun.status = \"cancelled\";\n\t\tif (this._sessionInputPumpSuspended) this._abandonRlmRunForQuiescence(run);\n\t\trun.error = reason;\n\t\trun.publication.reject(new Error(reason));\n\t\trun.abort();\n\t\t// Surface the cancellation immediately; the run's own terminal update is\n\t\t// delayed indefinitely when the child is stuck mid-stream, which is\n\t\t// exactly when users reach for the kill.\n\t\trun.emitUpdate?.();\n\t\treturn true;\n\t}\n\n\tgetRlmChildRunStatus(childId: string): RlmChildAgentStatus | undefined {\n\t\treturn this._activeRlmChildRuns.get(childId)?.status;\n\t}\n\n\tprivate async _currentActiveSessionId(): Promise<string | undefined> {\n\t\ttry {\n\t\t\treturn (await this._agentMessageController?.listAgents())?.current?.activeSessionId;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async _awaitPendingRlmChildPublication(selector: string): Promise<string | undefined> {\n\t\tconst run = [...this._activeRlmChildRuns.values()].find(\n\t\t\t(candidate) =>\n\t\t\t\t(candidate.status === \"queued\" || candidate.status === \"running\" || candidate.status === \"done\") &&\n\t\t\t\t!candidate.detachedDeletion &&\n\t\t\t\t(candidate.id === selector || candidate.sessionName === selector),\n\t\t);\n\t\tif (!run) return undefined;\n\t\tawait run.publication.promise;\n\t\treturn run.session?.sessionId;\n\t}\n\n\tasync listRlmSubagents(): Promise<RlmListSubagentsResult> {\n\t\treturn this._buildRlmSubagentList(await this._agentMessageController?.listAgents());\n\t}\n\n\tprivate _buildRlmSubagentList(listedAgents?: AgentSessionMessageListResult): RlmListSubagentsResult {\n\t\tconst daemonChildren = new Map<string, AgentSessionMessageAgentSummary>();\n\t\tconst parentActiveSessionId = listedAgents?.current?.activeSessionId;\n\t\tif (parentActiveSessionId) {\n\t\t\tfor (const agent of listedAgents.agents) {\n\t\t\t\tif (\n\t\t\t\t\tagent.runtimeKind === \"subagent\" &&\n\t\t\t\t\tagent.parentActiveSessionId === parentActiveSessionId &&\n\t\t\t\t\tagent.rlmChildId\n\t\t\t\t) {\n\t\t\t\t\tdaemonChildren.set(agent.rlmChildId, agent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst subagents: RlmListSubagentsResult[\"subagents\"] = [];\n\t\tconst recorded = new Set<string>();\n\t\tfor (const run of this._activeRlmChildRuns.values()) {\n\t\t\tif (this._deletingRlmChildren.has(run.id) || run.detachedDeletion || run.status === \"cancelled\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst daemonChild = daemonChildren.get(run.id);\n\t\t\tsubagents.push({\n\t\t\t\trlm_child_id: run.id,\n\t\t\t\tactive_session_id: daemonChild?.activeSessionId ?? null,\n\t\t\t\tsession_id: daemonChild?.sessionId ?? run.session?.sessionId ?? null,\n\t\t\t\tsession_name: daemonChild?.sessionName ?? run.session?.sessionName ?? run.sessionName,\n\t\t\t\tsession_dir: run.sessionDir,\n\t\t\t\tstatus: run.status === \"done\" ? \"completed\" : run.status === \"error\" ? \"error\" : \"running\",\n\t\t\t});\n\t\t\trecorded.add(run.id);\n\t\t}\n\t\tfor (const [childId, { session: childSession }] of this._rlmChildSessions) {\n\t\t\tif (\n\t\t\t\tthis._deletingRlmChildren.has(childId) ||\n\t\t\t\trecorded.has(childId) ||\n\t\t\t\tthis._rlmChildCleanupFailures.has(childId)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst daemonChild = daemonChildren.get(childId);\n\t\t\tconst sessionDir = childSession._rlmSessionDir;\n\t\t\tif (!sessionDir) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tsubagents.push({\n\t\t\t\trlm_child_id: childId,\n\t\t\t\tactive_session_id: daemonChild?.activeSessionId ?? null,\n\t\t\t\tsession_id: daemonChild?.sessionId ?? childSession.sessionId,\n\t\t\t\tsession_name:\n\t\t\t\t\tdaemonChild?.sessionName ?? childSession.sessionName ?? createDefaultRlmSubagentSessionName(\"\", childId),\n\t\t\t\tsession_dir: sessionDir,\n\t\t\t\tstatus: \"completed\",\n\t\t\t});\n\t\t\trecorded.add(childId);\n\t\t}\n\t\tfor (const [childId, daemonChild] of daemonChildren) {\n\t\t\tif (\n\t\t\t\trecorded.has(childId) ||\n\t\t\t\tthis._deletingRlmChildren.has(childId) ||\n\t\t\t\tthis._deletedRlmChildIds.has(childId) ||\n\t\t\t\tthis._rlmChildCleanupFailures.has(childId) ||\n\t\t\t\t!daemonChild.sessionDir\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tsubagents.push({\n\t\t\t\trlm_child_id: childId,\n\t\t\t\tactive_session_id: daemonChild.activeSessionId,\n\t\t\t\tsession_id: daemonChild.sessionId,\n\t\t\t\tsession_name: daemonChild.sessionName ?? createDefaultRlmSubagentSessionName(\"\", childId),\n\t\t\t\tsession_dir: daemonChild.sessionDir,\n\t\t\t\tstatus: daemonChild.rlmChildRegistryStatus === \"completed\" ? \"completed\" : \"error\",\n\t\t\t});\n\t\t}\n\t\treturn { subagents };\n\t}\n\n\tprivate _rlmSubagentMatchesTarget(entry: RlmSubagentRegistryEntry, target: string): boolean {\n\t\treturn (\n\t\t\tentry.rlm_child_id === target ||\n\t\t\tentry.active_session_id === target ||\n\t\t\tentry.session_id === target ||\n\t\t\tentry.session_name === target\n\t\t);\n\t}\n\n\tprivate async _resolveDirectRlmSubagent(target: string): Promise<RlmSubagentRegistryEntry> {\n\t\tconst candidates = [...(await this.listRlmSubagents()).subagents, ...this._rlmChildCleanupFailures.values()];\n\t\tconst matches = candidates.filter((entry) => this._rlmSubagentMatchesTarget(entry, target));\n\t\tif (matches.length === 0) {\n\t\t\tthrow new Error(`No direct RLM subagent matches \"${target}\" in the current parent session`);\n\t\t}\n\t\tif (matches.length > 1) {\n\t\t\tthrow new Error(`RLM subagent selector \"${target}\" is ambiguous in the current parent session`);\n\t\t}\n\t\treturn matches[0]!;\n\t}\n\n\tasync deleteInactiveRlmSubagent(\n\t\tchildId: string,\n\t\tisExternallyRunning: () => boolean = () => false,\n\t): Promise<\"deleted\" | \"not_found\" | \"running\"> {\n\t\tfor (const owner of this._rlmSubtreeSessions()) {\n\t\t\tconst isRunning = (): boolean => {\n\t\t\t\tconst status = owner._activeRlmChildRuns.get(childId)?.status;\n\t\t\t\treturn status === \"queued\" || status === \"running\" || isExternallyRunning();\n\t\t\t};\n\t\t\tif (isRunning()) {\n\t\t\t\treturn \"running\";\n\t\t\t}\n\t\t\tconst subagent = [\n\t\t\t\t...(await owner.listRlmSubagents()).subagents,\n\t\t\t\t...owner._rlmChildCleanupFailures.values(),\n\t\t\t].find((entry) => entry.rlm_child_id === childId);\n\t\t\tif (!subagent) continue;\n\t\t\tif (isRunning()) {\n\t\t\t\treturn \"running\";\n\t\t\t}\n\t\t\tconst result = await owner._trackRlmSubagentDeletion(subagent, () => {\n\t\t\t\tif (isRunning()) {\n\t\t\t\t\treturn Promise.resolve({ subagent, outcome: \"skipped_running\" });\n\t\t\t\t}\n\t\t\t\treturn owner._deleteResolvedRlmSubagent(subagent);\n\t\t\t});\n\t\t\treturn result.outcome === \"skipped_running\" ? \"running\" : \"deleted\";\n\t\t}\n\t\treturn \"not_found\";\n\t}\n\n\tasync deleteRlmSubagent(target: string): Promise<RlmDeleteSubagentResult> {\n\t\tconst inFlight = [...this._deletingRlmChildren.values()].filter(({ subagent }) =>\n\t\t\tthis._rlmSubagentMatchesTarget(subagent, target),\n\t\t);\n\t\tif (inFlight.length > 1) {\n\t\t\tthrow new Error(`RLM subagent selector \"${target}\" is ambiguous in the current parent session`);\n\t\t}\n\n\t\t// Running and retained children can be reserved synchronously. This keeps\n\t\t// them hidden immediately while the async daemon listing checks for a\n\t\t// conflicting passive selector.\n\t\tconst localMatches = [\n\t\t\t...this._buildRlmSubagentList().subagents,\n\t\t\t...this._rlmChildCleanupFailures.values(),\n\t\t].filter((entry) => this._rlmSubagentMatchesTarget(entry, target));\n\t\tconst matchingChildIds = new Set([\n\t\t\t...inFlight.map(({ subagent }) => subagent.rlm_child_id),\n\t\t\t...localMatches.map((subagent) => subagent.rlm_child_id),\n\t\t]);\n\t\tif (matchingChildIds.size > 1 || localMatches.length > 1) {\n\t\t\tthrow new Error(`RLM subagent selector \"${target}\" is ambiguous in the current parent session`);\n\t\t}\n\t\tif (inFlight[0]) {\n\t\t\treturn inFlight[0].promise;\n\t\t}\n\t\tif (localMatches[0]) {\n\t\t\tconst subagent = localMatches[0];\n\t\t\treturn this._trackRlmSubagentDeletion(subagent, async () => {\n\t\t\t\tconst listedAgents = await this._agentMessageController?.listAgents();\n\t\t\t\tconst listedSubagents = this._buildRlmSubagentList(listedAgents).subagents;\n\t\t\t\tconst passiveMatches = listedSubagents.filter(\n\t\t\t\t\t(entry) => entry.rlm_child_id !== subagent.rlm_child_id && this._rlmSubagentMatchesTarget(entry, target),\n\t\t\t\t);\n\t\t\t\tif (passiveMatches.length > 0) {\n\t\t\t\t\tthrow new Error(`RLM subagent selector \"${target}\" is ambiguous in the current parent session`);\n\t\t\t\t}\n\t\t\t\tconst parentActiveSessionId = listedAgents?.current?.activeSessionId;\n\t\t\t\tconst daemonChild = listedAgents?.agents.find(\n\t\t\t\t\t(agent) =>\n\t\t\t\t\t\tagent.rlmChildId === subagent.rlm_child_id && agent.parentActiveSessionId === parentActiveSessionId,\n\t\t\t\t);\n\t\t\t\tconst resolvedSubagent = daemonChild\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...subagent,\n\t\t\t\t\t\t\tactive_session_id: daemonChild.activeSessionId,\n\t\t\t\t\t\t\tsession_id: daemonChild.sessionId,\n\t\t\t\t\t\t\tsession_name: daemonChild.sessionName ?? subagent.session_name,\n\t\t\t\t\t\t}\n\t\t\t\t\t: subagent;\n\t\t\t\treturn this._deleteResolvedRlmSubagent(resolvedSubagent);\n\t\t\t});\n\t\t}\n\n\t\tconst directMatches = [\n\t\t\t...(await this.listRlmSubagents()).subagents,\n\t\t\t...this._rlmChildCleanupFailures.values(),\n\t\t].filter((entry) => this._rlmSubagentMatchesTarget(entry, target));\n\t\tconst directChildIds = new Set(directMatches.map((subagent) => subagent.rlm_child_id));\n\t\tif (directChildIds.size > 1) {\n\t\t\tthrow new Error(`RLM subagent selector \"${target}\" is ambiguous in the current parent session`);\n\t\t}\n\t\tconst subagent = directMatches[0] ?? (await this._resolveDirectRlmSubagent(target));\n\t\treturn this._trackRlmSubagentDeletion(subagent, () => this._deleteResolvedRlmSubagent(subagent));\n\t}\n\n\tprivate async _trackRlmSubagentDeletion(\n\t\tsubagent: RlmSubagentRegistryEntry,\n\t\tstartDeletion: () => Promise<RlmDeleteSubagentResult>,\n\t): Promise<RlmDeleteSubagentResult> {\n\t\tconst existing = this._deletingRlmChildren.get(subagent.rlm_child_id);\n\t\tif (existing) return existing.promise;\n\t\tconst deletion = Promise.resolve().then(startDeletion);\n\t\tthis._deletingRlmChildren.set(subagent.rlm_child_id, {\n\t\t\tsubagent,\n\t\t\tpromise: deletion,\n\t\t});\n\t\ttry {\n\t\t\treturn await deletion;\n\t\t} finally {\n\t\t\tconst clearReservation = () => {\n\t\t\t\tif (this._deletingRlmChildren.get(subagent.rlm_child_id)?.promise === deletion) {\n\t\t\t\t\tthis._deletingRlmChildren.delete(subagent.rlm_child_id);\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst run = this._activeRlmChildRuns.get(subagent.rlm_child_id);\n\t\t\tif (run?.detachedDeletion) {\n\t\t\t\t// Keep every selector reserved until the run settles, or until a failed\n\t\t\t\t// cleanup is exposed for an explicit retry. Repeated deletes before that\n\t\t\t\t// boundary return the same accepted result.\n\t\t\t\tvoid run.deletionReservation.promise.then(clearReservation, clearReservation);\n\t\t\t} else {\n\t\t\t\tclearReservation();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _deleteRlmSubagentSession(childId: string, session?: AgentSession): Promise<void> {\n\t\tif (this._subagentRuntimeHost) {\n\t\t\treturn this._subagentRuntimeHost.deleteRlmSubagentRuntime(childId, session);\n\t\t}\n\t\treturn session?.disposeAsync() ?? Promise.resolve();\n\t}\n\n\tprivate _ensureRlmRunDeletionCleanup(run: RlmChildRun, session: AgentSession): Promise<void> {\n\t\tif (run.deletionCleanup) return run.deletionCleanup;\n\t\tconst cleanup = Promise.resolve().then(() => this._deleteRlmSubagentSession(run.id, session));\n\t\trun.deletionCleanup = cleanup;\n\t\t// Deletion admission is intentionally nonblocking. The detached run owner\n\t\t// joins this exact promise before settlement and records any failure.\n\t\tvoid cleanup.catch(() => undefined);\n\t\treturn cleanup;\n\t}\n\n\tprivate async _recordRlmRunDeletionCleanupFailure(\n\t\trun: RlmChildRun,\n\t\tsubagent: RlmSubagentRegistryEntry,\n\t\tsession: AgentSession,\n\t\terror: unknown,\n\t): Promise<void> {\n\t\tif (this._disposed || this._disposing) {\n\t\t\trun.suppressTerminalNotice = true;\n\t\t\tawait session.disposeAsync().catch(() => undefined);\n\t\t\tif (!run.settled) await this._finishRlmRunDeletion(run);\n\t\t\treturn;\n\t\t}\n\t\trun.deletionCleanup = undefined;\n\t\trun.deletionCleanupObserver = undefined;\n\t\trun.deletionCleanupFailed = true;\n\t\trun.session = session;\n\t\tthis._rlmChildCleanupFailures.set(run.id, subagent);\n\t\t// Make retry admission available before waking the parent model with the\n\t\t// retry-required notice.\n\t\trun.deletionReservation.resolve();\n\t\tawait Promise.resolve();\n\t\tawait run.reportDeletionCleanupFailure?.(error);\n\t}\n\n\tprivate async _finishRlmRunDeletion(run: RlmChildRun): Promise<void> {\n\t\tawait run.completeDeletion?.();\n\t\tif (this._activeRlmChildRuns.get(run.id) === run) {\n\t\t\tthis._removeRlmSubagentTracking(run.id, run);\n\t\t}\n\t\trun.settled = true;\n\t\trun.settlement.resolve();\n\t\trun.deletionReservation.resolve();\n\t\tthis._unsettledRlmChildRuns.delete(run);\n\t\tthis._scheduleGoalContinuationAfterRlmWork();\n\t}\n\n\tprivate _observeRlmRunDeletionCleanup(\n\t\trun: RlmChildRun,\n\t\tsubagent: RlmSubagentRegistryEntry,\n\t\tsession: AgentSession,\n\t\tcleanup: Promise<void>,\n\t): Promise<boolean> {\n\t\tif (run.deletionCleanupObserver) return run.deletionCleanupObserver;\n\t\tconst observer = cleanup.then(\n\t\t\t() => true,\n\t\t\tasync (error) => {\n\t\t\t\tawait this._recordRlmRunDeletionCleanupFailure(run, subagent, session, error);\n\t\t\t\treturn false;\n\t\t\t},\n\t\t);\n\t\trun.deletionCleanupObserver = observer;\n\t\tvoid observer.catch(() => undefined);\n\t\treturn observer;\n\t}\n\n\tprivate _continueFinishedRlmRunDeletion(\n\t\trun: RlmChildRun,\n\t\tsubagent: RlmSubagentRegistryEntry,\n\t\tsession: AgentSession,\n\t): void {\n\t\tconst cleanup = this._ensureRlmRunDeletionCleanup(run, session);\n\t\tconst observer = this._observeRlmRunDeletionCleanup(run, subagent, session, cleanup);\n\t\tif (!run.deletionRunFinished) return;\n\t\tvoid observer\n\t\t\t.then(async (cleanupSucceeded) => {\n\t\t\t\tif (cleanupSucceeded) await this._finishRlmRunDeletion(run);\n\t\t\t})\n\t\t\t.catch(() => undefined);\n\t}\n\n\tprivate _removeRlmSubagentTracking(childId: string, run?: RlmChildRun): void {\n\t\trun?.unsubscribe?.();\n\t\tthis._rlmChildUnsubscribes.get(childId)?.();\n\t\tthis._rlmChildUnsubscribes.delete(childId);\n\t\tthis._rlmChildSessions.delete(childId);\n\t\tthis._rlmChildUsageSources.delete(childId);\n\t\tthis._rlmChildCleanupFailures.delete(childId);\n\t\tthis._abandonedRlmQuiescenceChildIds.delete(childId);\n\t\tif (!run || this._activeRlmChildRuns.get(childId) === run) {\n\t\t\tthis._activeRlmChildRuns.delete(childId);\n\t\t}\n\t\tif (run) {\n\t\t\trun.abort = noopRlmChildAbort;\n\t\t\trun.unsubscribe = undefined;\n\t\t\trun.session = undefined;\n\t\t}\n\t}\n\n\tprivate _emitRlmSubagentRemoval(subagent: RlmSubagentRegistryEntry): void {\n\t\tthis._emit({\n\t\t\ttype: \"rlm_child_update\",\n\t\t\tchild: {\n\t\t\t\tid: subagent.rlm_child_id,\n\t\t\t\tparentId: this._rlmParentNodeId,\n\t\t\t\tactiveSessionId: subagent.active_session_id ?? undefined,\n\t\t\t\tsessionName: subagent.session_name,\n\t\t\t\tlabel: subagent.session_name,\n\t\t\t\tstatus: \"cancelled\",\n\t\t\t\tsessionDir: subagent.session_dir,\n\t\t\t\terror: \"Deleted by parent orchestrator\",\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate async _deleteResolvedRlmSubagent(subagent: RlmSubagentRegistryEntry): Promise<RlmDeleteSubagentResult> {\n\t\tconst childId = subagent.rlm_child_id;\n\t\tconst run = this._activeRlmChildRuns.get(childId);\n\t\tif (run) {\n\t\t\tif (run.deletionCleanupFailed) {\n\t\t\t\t// Reset retry coordination only after selector preflight reaches the\n\t\t\t\t// resolved child. A failed preflight must leave the prior retry boundary\n\t\t\t\t// intact so a later call can acquire it.\n\t\t\t\trun.deletionCleanupFailed = false;\n\t\t\t\trun.deletionReservation = createAgentMessageDeferred();\n\t\t\t}\n\t\t\t// The detached task remains the sole lifecycle owner. Mark deletion before\n\t\t\t// cancellation so its catch/finally path cannot race a normal release or\n\t\t\t// terminal notice against the physical delete.\n\t\t\trun.detachedDeletion = subagent;\n\t\t\tif (this._cancelRlmChildRun(run, \"Deleted by parent orchestrator\")) {\n\t\t\t\trun.deletionNeedsCompletionNotice = true;\n\t\t\t} else {\n\t\t\t\tthis._emitRlmSubagentRemoval(subagent);\n\t\t\t}\n\t\t\tconst liveSession = run.session;\n\t\t\tif (run.status === \"error\" && !liveSession && run.settled) {\n\t\t\t\tthis._deletedRlmChildIds.add(childId);\n\t\t\t\tthis._removeRlmSubagentTracking(childId, run);\n\t\t\t\treturn { subagent };\n\t\t\t}\n\t\t\tif (liveSession && run.settled) {\n\t\t\t\trun.deletionRunFinished = true;\n\t\t\t\trun.settlement = createAgentMessageDeferred();\n\t\t\t\trun.settled = false;\n\t\t\t\tthis._unsettledRlmChildRuns.add(run);\n\t\t\t}\n\t\t\tif (liveSession) this._continueFinishedRlmRunDeletion(run, subagent, liveSession);\n\n\t\t\t// Return once deletion is accepted. The run stays hidden but unsettled until\n\t\t\t// abort-insensitive model/tool work unwinds and the shared cleanup finishes.\n\t\t\tthis._deletedRlmChildIds.add(childId);\n\t\t\treturn { subagent };\n\t\t}\n\n\t\tthis._emitRlmSubagentRemoval(subagent);\n\t\tconst retained = this._rlmChildSessions.get(childId)?.session;\n\t\ttry {\n\t\t\tawait this._deleteRlmSubagentSession(childId, retained);\n\t\t} catch (error) {\n\t\t\tif (this._disposed || this._disposing) {\n\t\t\t\tthis._removeRlmSubagentTracking(childId);\n\t\t\t\tvoid retained?.disposeAsync().catch(() => undefined);\n\t\t\t} else {\n\t\t\t\tthis._rlmChildCleanupFailures.set(childId, subagent);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tthis._deletedRlmChildIds.add(childId);\n\t\tthis._removeRlmSubagentTracking(childId);\n\t\treturn { subagent };\n\t}\n\n\tprivate async _restoreRlmChildUsageSource(childId: string, child: AgentSession): Promise<void> {\n\t\tif (this._rlmChildUsageSources.has(childId)) return;\n\t\tconst readSource = (entry: SessionEntry): RlmChildUsageSource | undefined => {\n\t\t\tif (entry.type !== \"custom\" || entry.customType !== RLM_PARENT_USAGE_CUSTOM_TYPE) return;\n\t\t\tconst data = entry.data as Partial<RlmChildUsageSource> | undefined;\n\t\t\tif (\n\t\t\t\t!data ||\n\t\t\t\tdata.sessionId !== this.sessionId ||\n\t\t\t\tdata.sessionFile !== this.sessionFile ||\n\t\t\t\ttypeof data.entryId !== \"string\"\n\t\t\t)\n\t\t\t\treturn;\n\t\t\treturn { sessionId: data.sessionId, sessionFile: data.sessionFile, entryId: data.entryId };\n\t\t};\n\t\tconst source = child.sessionManager.supportsCapturedHistoryReads()\n\t\t\t? await child.sessionManager.readBranchHistory(async (history) => {\n\t\t\t\t\tlet after = 0;\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\tconst page = await history.page(after, 64);\n\t\t\t\t\t\tfor (const ref of page.events) {\n\t\t\t\t\t\t\tif (ref.kind !== \"custom\" || ref.locator.length > 16 * 1024) continue;\n\t\t\t\t\t\t\tconst record = await history.hydrateEntry(ref.id, 16 * 1024);\n\t\t\t\t\t\t\tconst source = record && readSource(record.entry);\n\t\t\t\t\t\t\tif (source) return source;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (page.nextAfter === null) return;\n\t\t\t\t\t\tafter = page.nextAfter;\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t: child.sessionManager\n\t\t\t\t\t.getBranch()\n\t\t\t\t\t.map(readSource)\n\t\t\t\t\t.find((source) => source !== undefined);\n\t\tif (!source || source.sessionId !== this.sessionId || source.sessionFile !== this.sessionFile) return;\n\t\tconst target = await this.sessionManager.readEntry(source.entryId);\n\t\tif (target?.type !== \"message\" || target.message.role !== \"assistant\") return;\n\t\tif (source.sessionId !== this.sessionId || source.sessionFile !== this.sessionFile) return;\n\t\tthis._rlmChildUsageSources.set(childId, source);\n\t}\n\n\tprivate _subscribeRlmChildEvents(\n\t\tchildId: string,\n\t\tchild: AgentSession,\n\t\trun?: RlmChildRun,\n\t\tonUsageWrite?: (write: Promise<void>) => void,\n\t): () => void {\n\t\tlet runningToolCount = 0;\n\t\tconst emitChildUpdate = () => {\n\t\t\tif (run) run.emitUpdate?.();\n\t\t\telse this._emit({ type: \"rlm_child_update\", child: this._rlmChildSnapshotForSession(childId, child) });\n\t\t};\n\t\tconst attributeUsage = (usage: Usage, origin: RlmChildUsageOrigin): Promise<void> => {\n\t\t\tconst source = this._rlmChildUsageSources.get(childId);\n\t\t\tif (!source || source.sessionId !== this.sessionId || source.sessionFile !== this.sessionFile)\n\t\t\t\treturn Promise.resolve();\n\t\t\tconst delta = structuredClone(usage);\n\t\t\tconst target = this.messages.find(\n\t\t\t\t(message): message is AssistantMessage =>\n\t\t\t\t\tmessage.role === \"assistant\" && this._findAssistantEntryIdForMessage(message) === source.entryId,\n\t\t\t);\n\t\t\tconst refreshOutput = this._refreshInvocationOutput;\n\t\t\tconst forwardUsage = this._rlmParentUsageAttribution;\n\t\t\tconst write = this.sessionManager\n\t\t\t\t.appendChildUsageAttributionWithAggregate(source.entryId, delta, undefined, origin)\n\t\t\t\t.then(async ({ aggregateUsage }) => {\n\t\t\t\t\tif (target) {\n\t\t\t\t\t\ttarget.usage = structuredClone(aggregateUsage);\n\t\t\t\t\t\trefreshOutput?.(target);\n\t\t\t\t\t}\n\t\t\t\t\t// Ancestors receive only this newly acknowledged delta, never the aggregate again.\n\t\t\t\t\tawait forwardUsage?.(delta, origin);\n\t\t\t\t});\n\t\t\tthis._childUsageWrites.add(write);\n\t\t\tonUsageWrite?.(write);\n\t\t\tvoid write.then(\n\t\t\t\t() => this._childUsageWrites.delete(write),\n\t\t\t\t(error) => {\n\t\t\t\t\tthis._childUsageWrites.delete(write);\n\t\t\t\t\tif (run) run.error = `Child usage attribution was not acknowledged: ${this._asError(error).message}`;\n\t\t\t\t\tthis._surfaceSessionInputError(error);\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn write;\n\t\t};\n\t\tchild._rlmParentUsageAttribution = attributeUsage;\n\t\tconst unsubscribe = child.subscribe((event) => {\n\t\t\tif (event.type === \"rlm_child_update\") {\n\t\t\t\tthis._emit(event);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (event.type === \"agent_start\") {\n\t\t\t\tif (run) run.activity = { kind: \"waiting\" };\n\t\t\t\temitChildUpdate();\n\t\t\t} else if (event.type === \"agent_end\") {\n\t\t\t\tif (run) run.activity = undefined;\n\t\t\t\temitChildUpdate();\n\t\t\t} else if (event.type === \"message_end\" && event.message.role === \"assistant\") {\n\t\t\t\tconst assistant = event.message;\n\t\t\t\tif (run) {\n\t\t\t\t\trun.terminalAssistantOutcome = {\n\t\t\t\t\t\tstopReason: assistant.stopReason,\n\t\t\t\t\t\terrorMessage: assistant.errorMessage,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst update = () => {\n\t\t\t\t\tconst text = compactRlmText(readAssistantText(assistant));\n\t\t\t\t\tif (run && text) run.answerPreview = text;\n\t\t\t\t\temitChildUpdate();\n\t\t\t\t};\n\t\t\t\tif (assistant.stopReason !== \"error\" && assistant.stopReason !== \"aborted\") {\n\t\t\t\t\tconst messages = child.messages;\n\t\t\t\t\tconst precedingPrompt = messages\n\t\t\t\t\t\t.slice(0, messages.lastIndexOf(assistant))\n\t\t\t\t\t\t.reverse()\n\t\t\t\t\t\t.find(\n\t\t\t\t\t\t\t(message) =>\n\t\t\t\t\t\t\t\tmessage.role === \"user\" ||\n\t\t\t\t\t\t\t\t(message.role === \"custom\" && message.customType !== HARNESS_SNAPSHOT_CUSTOM_TYPE),\n\t\t\t\t\t\t);\n\t\t\t\t\tconst origin =\n\t\t\t\t\t\tprecedingPrompt?.role === \"custom\" && isAgentSessionMessage(precedingPrompt)\n\t\t\t\t\t\t\t? precedingPrompt.details.id.startsWith(\"spawn:\")\n\t\t\t\t\t\t\t\t? \"spawn_task\"\n\t\t\t\t\t\t\t\t: \"agent_message\"\n\t\t\t\t\t\t\t: \"direct_user\";\n\t\t\t\t\tvoid attributeUsage(assistant.usage, origin).then(update, () => {});\n\t\t\t\t} else update();\n\t\t\t} else if (event.type === \"message_start\" || event.type === \"message_update\") {\n\t\t\t\tif (event.message.role === \"assistant\") {\n\t\t\t\t\tif (run) {\n\t\t\t\t\t\tconst text = compactRlmText(readAssistantText(event.message));\n\t\t\t\t\t\tif (text) run.answerPreview = text;\n\t\t\t\t\t\trun.activity = { kind: \"writing\" };\n\t\t\t\t\t}\n\t\t\t\t\temitChildUpdate();\n\t\t\t\t}\n\t\t\t} else if (event.type === \"tool_execution_start\") {\n\t\t\t\tif (run) {\n\t\t\t\t\trun.toolUseCount++;\n\t\t\t\t\trunningToolCount++;\n\t\t\t\t\trun.activity = { kind: \"executing\", toolName: event.toolName };\n\t\t\t\t}\n\t\t\t\temitChildUpdate();\n\t\t\t} else if (event.type === \"tool_execution_end\") {\n\t\t\t\tif (run) {\n\t\t\t\t\trunningToolCount = Math.max(0, runningToolCount - 1);\n\t\t\t\t\tif (runningToolCount === 0) run.activity = { kind: \"waiting\" };\n\t\t\t\t}\n\t\t\t\temitChildUpdate();\n\t\t\t} else if (event.type === \"session_info_changed\" || event.type === \"recap_update\") emitChildUpdate();\n\t\t});\n\t\treturn () => {\n\t\t\tunsubscribe();\n\t\t\tif (child._rlmParentUsageAttribution === attributeUsage) child._rlmParentUsageAttribution = undefined;\n\t\t};\n\t}\n\n\t/**\n\t * Retain a finished child session for the parent lifetime so inspectors and\n\t * daemon-hosted agent messaging can keep addressing it. Returns false (and disposes\n\t * the child) when the parent is already tearing down, so the caller can drop the\n\t * matching event forwarder too.\n\t */\n\tasync registerRlmChildSession(childId: string, session: AgentSession, unsubscribe?: () => void): Promise<boolean> {\n\t\t// A child can finish concurrently while the parent is (or has) torn down; don't\n\t\t// resurrect the map (it would never be disposed), just drop the child now.\n\t\tif (this._deletingRlmChildren.has(childId) || this._deletedRlmChildIds.has(childId)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (this._subagentRuntimeHost?.completeRlmSubagentRuntime?.(childId, session) === false) {\n\t\t\treturn false;\n\t\t}\n\t\tif (this._disposed || this._disposing) {\n\t\t\tawait session.disposeAsync();\n\t\t\treturn false;\n\t\t}\n\t\tif (!session._rlmResidentDisposalComplete) {\n\t\t\tif (session._rlmParentAdmission?.parent === this) session._rlmParentAdmission.bind(session);\n\t\t\telse {\n\t\t\t\tconst admission = await this.reserveRlmChildAdmission();\n\t\t\t\ttry {\n\t\t\t\t\tadmission.bind(session);\n\t\t\t\t} finally {\n\t\t\t\t\tawait admission.settle();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tawait this._restoreRlmChildUsageSource(childId, session);\n\t\tif (this._disposed || this._disposing) {\n\t\t\tawait session.disposeAsync();\n\t\t\treturn false;\n\t\t}\n\t\tif (this._deletingRlmChildren.has(childId) || this._deletedRlmChildIds.has(childId)) return false;\n\t\tconst retained = this._rlmChildSessions.get(childId);\n\t\tconst run = this._activeRlmChildRuns.get(childId);\n\t\tif (!run?.unsubscribe && (retained?.session !== session || !this._rlmChildUnsubscribes.has(childId))) {\n\t\t\tthis._rlmChildUnsubscribes.get(childId)?.();\n\t\t\tconst ownedUnsubscribe = this._subscribeRlmChildEvents(childId, session);\n\t\t\tthis._rlmChildUnsubscribes.set(childId, () => {\n\t\t\t\townedUnsubscribe();\n\t\t\t\tunsubscribe?.();\n\t\t\t});\n\t\t}\n\t\tthis._rlmChildSessions.set(childId, { session, run });\n\t\treturn true;\n\t}\n\n\treleaseRlmChildSession(childId: string, session: AgentSession): (() => void) | false {\n\t\tconst run = this._activeRlmChildRuns.get(childId);\n\t\tif (run?.session === session && run.status === \"done\") {\n\t\t\tconst unsubscribe = run.unsubscribe ?? noopRlmChildEventUnsubscribe;\n\t\t\treturn () => {\n\t\t\t\tif (run.unsubscribe === unsubscribe) run.unsubscribe = undefined;\n\t\t\t\tif (this._activeRlmChildRuns.get(childId) === run) this._activeRlmChildRuns.delete(childId);\n\t\t\t\tunsubscribe();\n\t\t\t};\n\t\t}\n\t\tif (this._rlmChildSessions.get(childId)?.session !== session) return false;\n\t\tconst unsubscribe = this._rlmChildUnsubscribes.get(childId) ?? noopRlmChildEventUnsubscribe;\n\t\treturn () => {\n\t\t\tif (\n\t\t\t\tthis._rlmChildSessions.get(childId)?.session === session &&\n\t\t\t\tthis._rlmChildUnsubscribes.get(childId) === unsubscribe\n\t\t\t) {\n\t\t\t\tthis._rlmChildUnsubscribes.delete(childId);\n\t\t\t\tthis._rlmChildSessions.delete(childId);\n\t\t\t}\n\t\t\tunsubscribe();\n\t\t};\n\t}\n\n\tprivate _rlmChildSnapshotForRun(\n\t\trun: RlmChildRun,\n\t\tchild = run.session ?? this._rlmChildSessions.get(run.id)?.session,\n\t): RlmChildAgentSnapshot {\n\t\tconst model = child?.model ?? run.model;\n\t\treturn {\n\t\t\tid: run.id,\n\t\t\tparentId: this._rlmParentNodeId,\n\t\t\tsessionName: child?.sessionName ?? run.sessionName,\n\t\t\tmodel: `${model.provider}/${model.id}`,\n\t\t\tlabel: rlmChildLabel(run.prompt),\n\t\t\tstatus: run.status,\n\t\t\tdurationMs: run.durationMs,\n\t\t\tanswerPreview: run.answerPreview,\n\t\t\ttoolUseCount: run.toolUseCount > 0 ? run.toolUseCount : undefined,\n\t\t\ttokenCount: child?._contextTokensForCurrentMessages(),\n\t\t\trecap: child?.getCurrentRecap(),\n\t\t\tsessionDir: run.sessionDir,\n\t\t\tactivity: run.activity,\n\t\t\trepliedSinceTask: child?._repliedToParentSinceTask,\n\t\t\terror: run.error,\n\t\t};\n\t}\n\n\tprivate _rlmChildSnapshotForSession(childId: string, child: AgentSession): RlmChildAgentSnapshot {\n\t\tlet answerPreview: string | undefined;\n\t\tlet toolUseCount = 0;\n\t\tconst messages =\n\t\t\tchild.state.streamingMessage?.role === \"assistant\"\n\t\t\t\t? [...child.messages, child.state.streamingMessage]\n\t\t\t\t: child.messages;\n\t\tfor (const message of messages) {\n\t\t\tif (message.role !== \"assistant\") continue;\n\t\t\tconst text = compactRlmText(readAssistantText(message));\n\t\t\tif (text) answerPreview = text;\n\t\t\ttoolUseCount += message.content.filter((block) => block.type === \"toolCall\").length;\n\t\t}\n\t\treturn {\n\t\t\tid: childId,\n\t\t\tparentId: this._rlmParentNodeId,\n\t\t\tsessionName: child.sessionName,\n\t\t\tmodel: child.model ? `${child.model.provider}/${child.model.id}` : undefined,\n\t\t\tlabel: child.sessionName ?? \"child agent\",\n\t\t\tstatus: \"done\",\n\t\t\tanswerPreview,\n\t\t\ttoolUseCount: toolUseCount > 0 ? toolUseCount : undefined,\n\t\t\ttokenCount: child._contextTokensForCurrentMessages(),\n\t\t\trecap: child.getCurrentRecap(),\n\t\t\tsessionDir: child._rlmSessionDir ?? child.sessionManager.getSessionDir(),\n\t\t\t// No run exists (e.g. a child rehydrated after daemon recovery), so live\n\t\t\t// session state is the only source for in-flight follow-up work. Mirror\n\t\t\t// the run projection's convention: status stays \"done\" (the recorded task\n\t\t\t// finished) and current work surfaces through activity.\n\t\t\tactivity: child.isSessionActive ? { kind: child.isStreaming ? \"writing\" : \"waiting\" } : undefined,\n\t\t\trepliedSinceTask: child._repliedToParentSinceTask,\n\t\t};\n\t}\n\n\tprivate _isUnboundTerminalRlmChildRun(run: RlmChildRun): boolean {\n\t\tif (run.session !== undefined || this._rlmChildSessions.has(run.id)) return false;\n\t\treturn run.status === \"done\" || run.status === \"error\" || run.status === \"cancelled\";\n\t}\n\n\t/** Live recursive child roster from lifecycle state, including nested work under retained parents. */\n\tgetRlmChildSnapshots(): RlmChildAgentSnapshot[] {\n\t\tconst snapshots: RlmChildAgentSnapshot[] = [];\n\t\tconst recorded = new Set<string>();\n\t\tconst traversed = new Set<string>();\n\t\tfor (const run of this._activeRlmChildRuns.values()) {\n\t\t\tconst hidden =\n\t\t\t\trun.detachedDeletion ||\n\t\t\t\tthis._deletingRlmChildren.has(run.id) ||\n\t\t\t\tthis._deletedRlmChildIds.has(run.id) ||\n\t\t\t\tthis._isUnboundTerminalRlmChildRun(run);\n\t\t\tconst child = run.session;\n\t\t\tif (!hidden) {\n\t\t\t\tsnapshots.push(this._rlmChildSnapshotForRun(run));\n\t\t\t\trecorded.add(run.id);\n\t\t\t}\n\t\t\tif (child) {\n\t\t\t\ttraversed.add(run.id);\n\t\t\t\tsnapshots.push(...child.getRlmChildSnapshots());\n\t\t\t}\n\t\t}\n\t\tfor (const [childId, { session: child, run }] of this._rlmChildSessions) {\n\t\t\tif (recorded.has(childId) || traversed.has(childId)) continue;\n\t\t\tconst hidden = this._deletingRlmChildren.has(childId) || this._deletedRlmChildIds.has(childId);\n\t\t\tif (!hidden) {\n\t\t\t\tconst snapshot = run\n\t\t\t\t\t? this._rlmChildSnapshotForRun(run, child)\n\t\t\t\t\t: this._rlmChildSnapshotForSession(childId, child);\n\t\t\t\tsnapshots.push({\n\t\t\t\t\t...snapshot,\n\t\t\t\t\tstatus: this._rlmChildCleanupFailures.has(childId) ? \"cancelled\" : snapshot.status,\n\t\t\t\t});\n\t\t\t}\n\t\t\tsnapshots.push(...child.getRlmChildSnapshots());\n\t\t}\n\t\treturn snapshots;\n\t}\n\n\t/** True when any direct or nested subagent is still running or queued. */\n\thasRunningRlmChildren(): boolean {\n\t\tfor (const session of this._rlmSubtreeSessions()) {\n\t\t\tfor (const admission of session._rlmChildAdmissions) if (admission.pending) return true;\n\t\t\tfor (const run of session._activeRlmChildRuns.values()) {\n\t\t\t\tif (run.status === \"running\" || run.status === \"queued\") {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate _rlmChildSessionSnapshot(): AgentSession[] {\n\t\tconst sessions = new Set<AgentSession>();\n\t\tfor (const [childId, { session }] of this._rlmChildSessions) {\n\t\t\tif (!this._abandonedRlmQuiescenceChildIds.has(childId)) sessions.add(session);\n\t\t}\n\t\tfor (const run of this._activeRlmChildRuns.values()) {\n\t\t\tif (run.session && !run.abandonedForQuiescence) sessions.add(run.session);\n\t\t}\n\t\treturn [...sessions];\n\t}\n\n\tprivate _hasUnsettledRlmQuiescenceWork(): boolean {\n\t\tif (this.requests.hasPending || this._childUsageWrites.size > 0) return true;\n\t\tif (this._hasDeferredRlmTerminalNotices()) return true;\n\t\tif ([...this._unsettledRlmChildRuns].some((run) => !run.settled)) return true;\n\t\treturn this._rlmChildSessionSnapshot().some(\n\t\t\t(child) => child.isSessionActive || child._hasUnsettledRlmQuiescenceWork(),\n\t\t);\n\t}\n\n\t/**\n\t * Wait for every admitted descendant run to publish its terminal parent\n\t * message and for the resulting parent turns to drain. Re-snapshotting after\n\t * each drain includes descendants spawned while earlier results were consumed.\n\t */\n\tasync waitForRlmQuiescence(externalSignal?: AbortSignal): Promise<void> {\n\t\tconst cancellation = new AbortController();\n\t\tconst cancelFromParent = () => cancellation.abort();\n\t\tif (externalSignal?.aborted) cancellation.abort();\n\t\telse externalSignal?.addEventListener(\"abort\", cancelFromParent, { once: true });\n\t\tthis._rlmQuiescenceWaitAborts.add(cancellation);\n\t\tlet rejectCancelled = (_error: Error) => {};\n\t\tconst cancelled = new Promise<never>((_resolve, reject) => {\n\t\t\trejectCancelled = reject;\n\t\t});\n\t\tconst onCancelled = () => rejectCancelled(new Error(\"RLM quiescence wait cancelled\"));\n\t\tcancellation.signal.addEventListener(\"abort\", onCancelled, { once: true });\n\t\tif (cancellation.signal.aborted) onCancelled();\n\t\tconst wait = <T>(operation: Promise<T>): Promise<T> => Promise.race([operation, cancelled]);\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tawait wait(this.waitForHeadlessIdle());\n\t\t\t\t// Strong RLM quiescence also owns work that interactive waitForIdle ignores.\n\t\t\t\tif (this.isSessionActive || this._hasDeferredRlmTerminalNotices()) {\n\t\t\t\t\tawait wait(this._waitForSessionActivityChange(cancellation.signal));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst unsettledRuns = [...this._unsettledRlmChildRuns].filter((run) => !run.settled);\n\t\t\t\tconst childSessions = this._rlmChildSessionSnapshot();\n\t\t\t\tif (unsettledRuns.length === 0 && !this._hasUnsettledRlmQuiescenceWork()) return;\n\t\t\t\tawait wait(\n\t\t\t\t\tPromise.all([\n\t\t\t\t\t\t...unsettledRuns.map((run) => run.settlement.promise),\n\t\t\t\t\t\t...this._childUsageWrites,\n\t\t\t\t\t\t...childSessions.map((child) => child.waitForRlmQuiescence(cancellation.signal)),\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\t\t// Always loop through the self-active/deferred checks again. Work may\n\t\t\t\t// start at the child-settlement boundary.\n\t\t\t}\n\t\t} finally {\n\t\t\t// A local descendant error must cancel sibling recursive waits owned by\n\t\t\t// this barrier before their propagation listeners are removed.\n\t\t\tcancellation.abort();\n\t\t\texternalSignal?.removeEventListener(\"abort\", cancelFromParent);\n\t\t\tcancellation.signal.removeEventListener(\"abort\", onCancelled);\n\t\t\tthis._rlmQuiescenceWaitAborts.delete(cancellation);\n\t\t}\n\t}\n\n\t// Inline (non-daemon) mode only; daemon clients attach to the child session directly.\n\tgetRlmChildSession(childId: string): AgentSession | undefined {\n\t\tfor (const session of this._rlmSubtreeSessions()) {\n\t\t\tconst direct =\n\t\t\t\tsession._activeRlmChildRuns.get(childId)?.session ?? session._rlmChildSessions.get(childId)?.session;\n\t\t\tif (direct) {\n\t\t\t\treturn direct;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Cancel a single RLM child run by id, searching nested child sessions.\n\t *\n\t * @returns true when a live run was cancelled or its unsettled terminal notice\n\t * was suppressed; false when the id is unknown or the run already settled.\n\t */\n\tcancelRlmChildRun(childId: string, reason = \"Cancelled by user\"): boolean {\n\t\tfor (const session of this._rlmSubtreeSessions()) {\n\t\t\tconst run = session._activeRlmChildRuns.get(childId);\n\t\t\tif (run) {\n\t\t\t\tif (run.status !== \"running\" && run.status !== \"queued\" && !run.settled) {\n\t\t\t\t\tif (session._sessionInputPumpSuspended) session._abandonRlmRunForQuiescence(run);\n\t\t\t\t\telse run.suppressTerminalNotice = true;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// The abort cascade never reaches running work retained under a settled descendant.\n\t\t\t\tconst cancelled = session._cancelRlmChildRun(run, reason);\n\t\t\t\tconst descendantsCancelled = run.session?.cancelRunningRlmDescendants(reason) ?? false;\n\t\t\t\tif (cancelled || descendantsCancelled) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// A fruitless match keeps walking: child ids are only mkdir-unique among\n\t\t\t// siblings, so a colliding live run elsewhere must stay reachable.\n\t\t\tif (session._rlmChildSessions.get(childId)?.session.cancelRunningRlmDescendants(reason)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t// A done child sits in BOTH maps until passivation; the visited set keeps that dual membership from doubling the walk.\n\tprivate *_rlmSubtreeSessions(): Generator<AgentSession> {\n\t\tconst visited = new Set<AgentSession>([this]);\n\t\tconst stack: AgentSession[] = [this];\n\t\twhile (stack.length > 0) {\n\t\t\tconst session = stack.pop()!;\n\t\t\tyield session;\n\t\t\tfor (const run of session._activeRlmChildRuns.values()) {\n\t\t\t\tif (run.session && !visited.has(run.session)) {\n\t\t\t\t\tvisited.add(run.session);\n\t\t\t\t\tstack.push(run.session);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const { session: retained } of session._rlmChildSessions.values()) {\n\t\t\t\tif (!visited.has(retained)) {\n\t\t\t\t\tvisited.add(retained);\n\t\t\t\t\tstack.push(retained);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Cancel every running or queued run in this session's subtree. */\n\tcancelRunningRlmDescendants(reason = \"Cancelled by user\"): boolean {\n\t\tlet cancelled = false;\n\t\tfor (const session of this._rlmSubtreeSessions()) {\n\t\t\tfor (const admission of session._rlmChildAdmissions) if (admission.cancel(reason)) cancelled = true;\n\t\t\tfor (const run of session._activeRlmChildRuns.values()) {\n\t\t\t\tif (session._cancelRlmChildRun(run, reason)) cancelled = true;\n\t\t\t}\n\t\t}\n\t\treturn cancelled;\n\t}\n\n\tprivate async _assertRlmSubagentSessionNameAvailable(name: string, ignorePendingReservation = false): Promise<void> {\n\t\tconst depth = this._rlmDepth + 1;\n\t\tif (!ignorePendingReservation && this._pendingRlmSubagentSessionNames.has(name)) {\n\t\t\tthrow new Error(formatAgentSessionNameUnavailable(name, depth));\n\t\t}\n\t\tconst localConflict =\n\t\t\t[...this._activeRlmChildRuns.values()].some(\n\t\t\t\t(run) => run.session?.sessionName === name || (!run.session && run.sessionName === name),\n\t\t\t) ||\n\t\t\t[...this._rlmChildSessions.values()].some(({ session }) => session.sessionName === name) ||\n\t\t\t[...this._rlmChildCleanupFailures.values()].some((entry) => entry.session_name === name);\n\t\tif (localConflict) {\n\t\t\tthrow new Error(formatAgentSessionNameUnavailable(name, depth));\n\t\t}\n\t\tconst controller = this._agentMessageController;\n\t\tif (!controller) return;\n\t\tconst input = {\n\t\t\tname,\n\t\t\tdepth,\n\t\t\tparentSessionId: this.sessionId,\n\t\t\tparentSessionPath: this.sessionFile,\n\t\t};\n\t\tif (controller.assertSessionNameAvailable) {\n\t\t\tawait controller.assertSessionNameAvailable(input);\n\t\t\treturn;\n\t\t}\n\t\tconst listed = await controller.listAgents();\n\t\tconst catalog = listed.agents.map(\n\t\t\t(agent): AgentFamilyCatalogEntry => ({\n\t\t\t\tid: agent.sessionId,\n\t\t\t\t...(agent.sessionName ? { name: agent.sessionName } : {}),\n\t\t\t\tdepth: agent.rlmDepth ?? 0,\n\t\t\t\tstatus: agent.status ?? \"idle\",\n\t\t\t\t...(agent.parentSessionId ? { parentSessionId: agent.parentSessionId } : {}),\n\t\t\t\t...(agent.parentSessionPath ? { parentSessionPath: agent.parentSessionPath } : {}),\n\t\t\t\t...(agent.sessionPath ? { sessionPath: agent.sessionPath } : {}),\n\t\t\t}),\n\t\t);\n\t\tassertAgentSessionNameAvailable(catalog, input);\n\t}\n\n\tprivate async _authenticatedRlmModels(): Promise<Model<Api>[]> {\n\t\treturn (await this._modelRegistry.getExecutableModels()).filter((model) => {\n\t\t\tconst status = this._modelRegistry.getProviderAuthStatus(model.provider);\n\t\t\treturn status.source !== \"stale\" && status.label !== \"expired\";\n\t\t});\n\t}\n\n\tasync findRlmModels(query: string, limit: number): Promise<RlmFindModelsResult> {\n\t\treturn {\n\t\t\tmodels: findRlmModelMatches(query, await this._authenticatedRlmModels(), limit),\n\t\t};\n\t}\n\n\tprivate async _resolveRlmSubagentModel(reference: string | undefined): Promise<RlmSubagentModelSelection> {\n\t\tconst parentModel = this.model;\n\t\tif (!parentModel) {\n\t\t\tthrow new Error(formatNoModelSelectedMessage());\n\t\t}\n\t\tif (!reference) {\n\t\t\treturn { model: parentModel };\n\t\t}\n\n\t\tconst normalizedReference = reference.toLowerCase();\n\t\tif (`${parentModel.provider}/${parentModel.id}`.toLowerCase() === normalizedReference) {\n\t\t\treturn { model: parentModel };\n\t\t}\n\t\tconst model = (await this._authenticatedRlmModels()).find(\n\t\t\t(candidate) => `${candidate.provider}/${candidate.id}`.toLowerCase() === normalizedReference,\n\t\t);\n\t\tif (!model) {\n\t\t\tthrow new Error(`Requested subagent model \"${reference}\" is unavailable, unauthenticated, or expired`);\n\t\t}\n\n\t\tconst auth = await this._modelRegistry.getApiKeyAndHeaders(model);\n\t\tif (!auth.ok) {\n\t\t\tthrow new Error(`Requested subagent model \"${reference}\" failed authentication preflight`);\n\t\t}\n\t\treturn { model };\n\t}\n\n\tprivate async _startRlmChildRun(\n\t\tprompt: string,\n\t\tadmission: RlmChildAdmission,\n\t\tkwargs: Record<string, unknown> = {},\n\t\tspawnCode?: string,\n\t): Promise<RlmSpawnHandle> {\n\t\t// Snapshot before any await: the spawning request is the turn whose tool call is\n\t\t// executing now. A spawn arriving outside an active run (a detached kernel task\n\t\t// firing while the parent is idle) has no such turn; an absent edge beats a wrong one.\n\t\tconst spawnedByRequestId = this.isStreaming ? this._semanticEdges.lastTurnRequestId : undefined;\n\t\tconst parentAssistantForUsage = this._findLastAssistantMessage();\n\t\tconst parentEntryId = parentAssistantForUsage && this._findAssistantEntryIdForMessage(parentAssistantForUsage);\n\t\tconst usageSource: RlmChildUsageSource | undefined = parentEntryId\n\t\t\t? {\n\t\t\t\t\tsessionId: this.sessionId,\n\t\t\t\t\tsessionFile: this.sessionFile,\n\t\t\t\t\tentryId: parentEntryId,\n\t\t\t\t}\n\t\t\t: undefined;\n\t\tconst { name: rawName, model: rawModel, thinking: rawThinking, ...unsupported } = kwargs;\n\t\tconst unsupportedKwargs = Object.keys(unsupported);\n\t\tif (unsupportedKwargs.length > 0) {\n\t\t\tthrow new Error(`Unsupported rlm.run kwargs: ${unsupportedKwargs.sort().join(\", \")}`);\n\t\t}\n\t\tconst requestedSessionName = normalizeRequestedRlmSubagentSessionName(rawName);\n\t\tconst requestedModel = normalizeRequestedRlmSubagentModel(rawModel);\n\t\tconst requestedThinkingLevel = normalizeRequestedRlmSubagentThinkingLevel(rawThinking);\n\t\tif (requestedSessionName) assertDirectAgentMessageTarget(requestedSessionName);\n\t\tif (this._rlmDepth >= this._rlmMaxDepth) {\n\t\t\tthrow new Error(\n\t\t\t\t`RLM recursion depth limit reached (BASE_CONTEXT_RLM_DEPTH=${this._rlmDepth}, BASE_CONTEXT_RLM_MAX_DEPTH=${this._rlmMaxDepth})`,\n\t\t\t);\n\t\t}\n\t\tif (requestedSessionName) {\n\t\t\tif (this._pendingRlmSubagentSessionNames.has(requestedSessionName)) {\n\t\t\t\tthrow new Error(formatAgentSessionNameUnavailable(requestedSessionName, this._rlmDepth + 1));\n\t\t\t}\n\t\t\tthis._pendingRlmSubagentSessionNames.add(requestedSessionName);\n\t\t}\n\t\tlet modelSelection: RlmSubagentModelSelection;\n\t\ttry {\n\t\t\tif (requestedSessionName) await this._assertRlmSubagentSessionNameAvailable(requestedSessionName, true);\n\t\t\tmodelSelection = await this._resolveRlmSubagentModel(requestedModel);\n\t\t} finally {\n\t\t\tif (requestedSessionName) this._pendingRlmSubagentSessionNames.delete(requestedSessionName);\n\t\t}\n\t\tadmission.assertCurrent();\n\t\tif (requestedThinkingLevel !== undefined) {\n\t\t\tconst supported = getSupportedThinkingLevels(modelSelection.model) as ThinkingLevel[];\n\t\t\tif (!supported.includes(requestedThinkingLevel)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Requested thinking level \"${requestedThinkingLevel}\" is not supported by model \"${modelSelection.model.provider}/${modelSelection.model.id}\"; supported levels: ${supported.join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (this._disposed || this._disposing) throw new Error(\"Cannot spawn a subagent after its parent was disposed\");\n\n\t\tconst childSessionDir = this._createChildRlmSessionDir();\n\t\tconst childNodeId = basename(childSessionDir);\n\t\tconst sessionName = requestedSessionName ?? createDefaultRlmSubagentSessionName(prompt, childNodeId);\n\t\tif (!requestedSessionName) await this._assertRlmSubagentSessionNameAvailable(sessionName);\n\t\tadmission.assertCurrent();\n\t\tconst startedAt = Date.now();\n\t\tlet childSession: AgentSession | undefined;\n\t\tlet usageSettlement: Promise<void> = Promise.resolve();\n\t\tconst run: RlmChildRun = {\n\t\t\tid: childNodeId,\n\t\t\tprompt,\n\t\t\tsessionName,\n\t\t\tsessionDir: childSessionDir,\n\t\t\tmodel: modelSelection.model,\n\t\t\tstatus: \"queued\",\n\t\t\ttoolUseCount: 0,\n\t\t\tsettled: false,\n\t\t\tabort: noopRlmChildAbort,\n\t\t\tpublication: createAgentMessageDeferred(),\n\t\t\tsettlement: createAgentMessageDeferred(),\n\t\t\tdeletionReservation: createAgentMessageDeferred(),\n\t\t};\n\t\tconst throwIfCancelled = () => {\n\t\t\tif (run.status === \"cancelled\") throw new Error(run.error ?? \"RLM child cancelled\");\n\t\t};\n\t\tthis._activeRlmChildRuns.set(run.id, run);\n\t\tif (usageSource) this._rlmChildUsageSources.set(run.id, usageSource);\n\t\tthis._unsettledRlmChildRuns.add(run);\n\t\tconst emitChildUpdate = () => {\n\t\t\tconst child = this._rlmChildSnapshotForRun(run);\n\t\t\tconst serialized = JSON.stringify(child);\n\t\t\tif (serialized === run.lastEmittedUpdate) return;\n\t\t\trun.lastEmittedUpdate = serialized;\n\t\t\tthis._emit({ type: \"rlm_child_update\", child });\n\t\t};\n\t\trun.emitUpdate = emitChildUpdate;\n\t\temitChildUpdate();\n\n\t\tconst publishChildSession = (child: AgentSession) => {\n\t\t\tchildSession = child;\n\t\t\tif (this._activeRlmChildRuns.get(run.id) !== run) return;\n\t\t\trun.session = child;\n\t\t\trun.abort = () => void child.abort();\n\t\t\trun.publication.resolve();\n\t\t\t// Cancellation may have been admitted while runtime construction was\n\t\t\t// blocked and run.abort was still a no-op.\n\t\t\tif (run.status === \"cancelled\") run.abort();\n\t\t};\n\t\tconst subagentOptions: CreateRlmSubagentRuntimeOptions & { admission: RlmChildAdmission } = {\n\t\t\t...this._createRlmSubagentRuntimeOptions({\n\t\t\t\tadmission,\n\t\t\t\tid: childNodeId,\n\t\t\t\tprompt,\n\t\t\t\tsessionName,\n\t\t\t\tspawnCode,\n\t\t\t\tsessionDir: childSessionDir,\n\t\t\t\tmodel: modelSelection.model,\n\t\t\t\tthinkingLevel: requestedThinkingLevel,\n\t\t\t\tspawnedByRequestId,\n\t\t\t}),\n\t\t\tonSessionPublished: publishChildSession,\n\t\t};\n\n\t\tconst deliverTerminalMessageToParent = async (message: CustomMessage): Promise<void> => {\n\t\t\t// Synthesized lifecycle notices always use the parent's private durable\n\t\t\t// path. Explicit child replies continue through agent_message separately.\n\t\t\tawait this._deferRlmTerminalNotice(message);\n\t\t};\n\n\t\trun.completeDeletion = () => {\n\t\t\tif (!run.deletionNeedsCompletionNotice || run.suppressTerminalNotice || this._disposed || this._disposing) {\n\t\t\t\treturn Promise.resolve();\n\t\t\t}\n\t\t\tif (run.deletionNotice) return run.deletionNotice;\n\t\t\tconst notice = deliverTerminalMessageToParent(\n\t\t\t\tcreateRlmChildTerminalNoticeMessage({\n\t\t\t\t\tkind: \"cancelled\",\n\t\t\t\t\tchildId: run.id,\n\t\t\t\t\tsessionName,\n\t\t\t\t\treason: run.error ?? \"Deleted by parent orchestrator\",\n\t\t\t\t}),\n\t\t\t);\n\t\t\trun.deletionNotice = notice;\n\t\t\treturn notice;\n\t\t};\n\n\t\trun.reportDeletionCleanupFailure = (error) => {\n\t\t\tif (run.suppressTerminalNotice || this._disposed || this._disposing) return Promise.resolve();\n\t\t\tconst cleanupError = error instanceof Error ? error.message : String(error);\n\t\t\treturn deliverTerminalMessageToParent(\n\t\t\t\tcreateRlmChildFailureMessage({\n\t\t\t\t\tchildId: run.id,\n\t\t\t\t\tsessionName,\n\t\t\t\t\terror: `Deletion cleanup failed; retry rlm.delete_subagent(\"${run.id}\") before completion: ${cleanupError}`,\n\t\t\t\t}),\n\t\t\t);\n\t\t};\n\n\t\t// Runtime startup and the task run are deliberately detached. The public\n\t\t// spawn resolves at admission, while this task owns live tracking, usage,\n\t\t// retention, cancellation, and late-startup cleanup.\n\t\tconst task = (async () => {\n\t\t\tlet childRuntime: RlmSubagentRuntime | undefined;\n\t\t\ttry {\n\t\t\t\ttry {\n\t\t\t\t\tchildRuntime = await this._createRlmSubagentRuntime(subagentOptions);\n\t\t\t\t\tadmission.bind(childRuntime.session);\n\t\t\t\t} finally {\n\t\t\t\t\tawait admission.settle();\n\t\t\t\t}\n\t\t\t\tadmission.assertCurrent();\n\t\t\t\tconst child = childRuntime.session;\n\t\t\t\tif (run.status === \"cancelled\") throw new Error(run.error ?? \"RLM child cancelled\");\n\t\t\t\tif (child.sessionName !== sessionName) await child.setSessionName(sessionName);\n\t\t\t\tpublishChildSession(child);\n\t\t\t\tthrowIfCancelled();\n\t\t\t\trun.status = \"running\";\n\t\t\t\temitChildUpdate();\n\t\t\t\tif (usageSource) {\n\t\t\t\t\tawait child.sessionManager.appendCustomEntry(RLM_PARENT_USAGE_CUSTOM_TYPE, usageSource);\n\t\t\t\t}\n\t\t\t\tconst unsubscribeChildEvents = this._subscribeRlmChildEvents(run.id, child, run, (write) => {\n\t\t\t\t\tusageSettlement = Promise.all([usageSettlement, write]).then(() => undefined);\n\t\t\t\t\tvoid usageSettlement.catch(() => undefined);\n\t\t\t\t});\n\t\t\t\trun.unsubscribe = unsubscribeChildEvents;\n\t\t\t\tconst content = `[task from parent]\\n\\n${prompt}`;\n\t\t\t\tconst spawnMessage: AgentSessionMessage = {\n\t\t\t\t\trole: \"custom\",\n\t\t\t\t\tcustomType: AGENT_MESSAGE_CUSTOM_TYPE,\n\t\t\t\t\tcontent,\n\t\t\t\t\tdisplay: true,\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tid: `spawn:${run.id}`,\n\t\t\t\t\t\tmessage: prompt,\n\t\t\t\t\t\tfrom: {\n\t\t\t\t\t\t\tsessionId: this.sessionId,\n\t\t\t\t\t\t\tsessionName: this.sessionName,\n\t\t\t\t\t\t\tactiveSessionId: await this._currentActiveSessionId(),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfromRelationship: \"parent\",\n\t\t\t\t\t},\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t};\n\t\t\t\tthrowIfCancelled();\n\t\t\t\tconst parentReplyCountBeforeRun = child._parentReplyCount;\n\t\t\t\tawait child.promptAndWait(content, {\n\t\t\t\t\texpandPromptTemplates: false,\n\t\t\t\t\tsource: \"extension\",\n\t\t\t\t\tcustomMessage: spawnMessage,\n\t\t\t\t});\n\t\t\t\t// promptAndWait can resolve after a provider error or abort. Only outcomes\n\t\t\t\t// emitted during this run count; a recovered intermediate error is not terminal.\n\t\t\t\tconst terminal = run.terminalAssistantOutcome;\n\t\t\t\tif (terminal?.stopReason === \"aborted\") {\n\t\t\t\t\trun.status = \"cancelled\";\n\t\t\t\t\trun.error ??= terminal.errorMessage || \"RLM child aborted\";\n\t\t\t\t}\n\t\t\t\tthrowIfCancelled();\n\t\t\t\tif (terminal?.stopReason === \"error\")\n\t\t\t\t\tthrow new Error(terminal.errorMessage || \"RLM child inference failed\");\n\t\t\t\tawait child.waitForRlmQuiescence();\n\t\t\t\tawait usageSettlement;\n\t\t\t\tthrowIfCancelled();\n\t\t\t\tif (run.error) throw new Error(run.error);\n\t\t\t\trun.status = \"done\";\n\t\t\t\t// Only successful completions return; the edge lands on the parent's next commit.\n\t\t\t\tconst childLastCommitted = child.semanticEdges.lastCommittedRequestId;\n\t\t\t\tif (childLastCommitted !== undefined) {\n\t\t\t\t\tthis._semanticEdges.recordChildReturned(child.sessionId, childLastCommitted);\n\t\t\t\t}\n\t\t\t\trun.durationMs = Date.now() - startedAt;\n\t\t\t\trun.activity = undefined;\n\t\t\t\temitChildUpdate();\n\t\t\t\tif (\n\t\t\t\t\t!run.detachedDeletion &&\n\t\t\t\t\t!run.suppressTerminalNotice &&\n\t\t\t\t\tchild._parentReplyCount === parentReplyCountBeforeRun\n\t\t\t\t) {\n\t\t\t\t\tconst lastAssistantText = child.getLastAssistantText();\n\t\t\t\t\tawait deliverTerminalMessageToParent(\n\t\t\t\t\t\tcreateRlmChildTerminalNoticeMessage({\n\t\t\t\t\t\t\tkind: \"completed_without_reply\",\n\t\t\t\t\t\t\tchildId: run.id,\n\t\t\t\t\t\t\tsessionName,\n\t\t\t\t\t\t\tlastAssistantTextPreview: lastAssistantText ? compactRlmText(lastAssistantText) : undefined,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!(await this.registerRlmChildSession(run.id, child)) && !run.detachedDeletion) {\n\t\t\t\t\tif (childRuntime && this._subagentRuntimeHost?.releaseRlmSubagentRuntime) {\n\t\t\t\t\t\tawait this._subagentRuntimeHost\n\t\t\t\t\t\t\t.releaseRlmSubagentRuntime(childRuntime, subagentOptions, \"error\")\n\t\t\t\t\t\t\t.catch(() => void child.disposeAsync().catch(() => undefined));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait child.disposeAsync().catch(() => undefined);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconst runError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\trun.publication.reject(runError);\n\t\t\t\t// A native constructor can fail before publication, but still owns a real child.\n\t\t\t\tif (!childSession && admission.session) {\n\t\t\t\t\tchildSession = admission.session;\n\t\t\t\t\trun.session = childSession;\n\t\t\t\t}\n\t\t\t\tif (run.status !== \"cancelled\") {\n\t\t\t\t\trun.status = \"error\";\n\t\t\t\t\trun.error = runError.message;\n\t\t\t\t}\n\t\t\t\t// A failed child still returns an error outcome the parent consumes;\n\t\t\t\t// cancelled runs and zero-commit children return nothing.\n\t\t\t\tconst failedChild = childSession ?? childRuntime?.session;\n\t\t\t\tconst failedLastCommitted = failedChild?.semanticEdges.lastCommittedRequestId;\n\t\t\t\tif (run.status === \"error\" && failedChild && failedLastCommitted !== undefined) {\n\t\t\t\t\tthis._semanticEdges.recordChildReturned(failedChild.sessionId, failedLastCommitted);\n\t\t\t\t}\n\t\t\t\trun.durationMs = Date.now() - startedAt;\n\t\t\t\trun.activity = undefined;\n\t\t\t\tif (run.status === \"error\" && childSession === undefined) {\n\t\t\t\t\t// A pre-bind failure leaves no row: \"cancelled\" is the wire's removal signal.\n\t\t\t\t\tthis._emit({\n\t\t\t\t\t\ttype: \"rlm_child_update\",\n\t\t\t\t\t\tchild: { ...this._rlmChildSnapshotForRun(run), status: \"cancelled\" },\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\temitChildUpdate();\n\t\t\t\t}\n\t\t\t\tif (!run.detachedDeletion && !run.suppressTerminalNotice) {\n\t\t\t\t\tif (run.status === \"error\") {\n\t\t\t\t\t\tawait deliverTerminalMessageToParent(\n\t\t\t\t\t\t\tcreateRlmChildFailureMessage({\n\t\t\t\t\t\t\t\tchildId: run.id,\n\t\t\t\t\t\t\t\tsessionName,\n\t\t\t\t\t\t\t\terror: run.error ?? \"unknown error\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (run.status === \"cancelled\") {\n\t\t\t\t\t\tawait deliverTerminalMessageToParent(\n\t\t\t\t\t\t\tcreateRlmChildTerminalNoticeMessage({\n\t\t\t\t\t\t\t\tkind: \"cancelled\",\n\t\t\t\t\t\t\t\tchildId: run.id,\n\t\t\t\t\t\t\t\tsessionName,\n\t\t\t\t\t\t\t\treason: run.error,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!run.detachedDeletion && childSession && this._subagentRuntimeHost?.releaseRlmSubagentRuntime) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this._subagentRuntimeHost.releaseRlmSubagentRuntime(\n\t\t\t\t\t\t\tchildRuntime ?? { session: childSession },\n\t\t\t\t\t\t\tsubagentOptions,\n\t\t\t\t\t\t\trun.status === \"cancelled\" ? \"cancelled\" : \"error\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (run.status === \"cancelled\" && !this._disposed && !this._disposing) {\n\t\t\t\t\t\t\tthis._deletedRlmChildIds.add(run.id);\n\t\t\t\t\t\t\tthis._removeRlmSubagentTracking(run.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tawait childSession?.disposeAsync().catch(() => undefined);\n\t\t\t\t\t}\n\t\t\t\t} else if (!run.detachedDeletion) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (childRuntime && this._subagentRuntimeHost) {\n\t\t\t\t\t\t\tawait this._subagentRuntimeHost.deleteRlmSubagentRuntime(run.id, childRuntime.session);\n\t\t\t\t\t\t} else if (childSession) {\n\t\t\t\t\t\t\tawait childSession.disposeAsync();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (run.status === \"cancelled\" && !this._disposed && !this._disposing) {\n\t\t\t\t\t\t\tthis._deletedRlmChildIds.add(run.id);\n\t\t\t\t\t\t\tthis._removeRlmSubagentTracking(run.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// A failed best-effort retry remains available through the retained cleanup maps.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tawait usageSettlement.catch((error) => this._surfaceSessionInputError(error));\n\t\t\t\tif (run.detachedDeletion) {\n\t\t\t\t\trun.deletionRunFinished = true;\n\t\t\t\t\tif (!run.settled) {\n\t\t\t\t\t\tlet cleanupSucceeded = !run.deletionCleanupFailed;\n\t\t\t\t\t\tif (childRuntime && cleanupSucceeded) {\n\t\t\t\t\t\t\tconst cleanup =\n\t\t\t\t\t\t\t\trun.deletionCleanup ?? this._ensureRlmRunDeletionCleanup(run, childRuntime.session);\n\t\t\t\t\t\t\tcleanupSucceeded = await this._observeRlmRunDeletionCleanup(\n\t\t\t\t\t\t\t\trun,\n\t\t\t\t\t\t\t\trun.detachedDeletion,\n\t\t\t\t\t\t\t\tchildRuntime.session,\n\t\t\t\t\t\t\t\tcleanup,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (cleanupSucceeded) await this._finishRlmRunDeletion(run);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (this._activeRlmChildRuns.get(run.id) === run) {\n\t\t\t\t\t\tif (this._rlmChildSessions.has(run.id)) {\n\t\t\t\t\t\t\tthis._activeRlmChildRuns.delete(run.id);\n\t\t\t\t\t\t\tif (run.unsubscribe) this._rlmChildUnsubscribes.set(run.id, run.unsubscribe);\n\t\t\t\t\t\t\trun.abort = noopRlmChildAbort;\n\t\t\t\t\t\t\trun.unsubscribe = undefined;\n\t\t\t\t\t\t\trun.session = undefined;\n\t\t\t\t\t\t} else if (run.status !== \"error\") {\n\t\t\t\t\t\t\tthis._removeRlmSubagentTracking(run.id, run);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\trun.unsubscribe?.();\n\t\t\t\t\t\t\trun.abort = noopRlmChildAbort;\n\t\t\t\t\t\t\trun.unsubscribe = undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\trun.settled = true;\n\t\t\t\t\trun.settlement.resolve();\n\t\t\t\t\tthis._unsettledRlmChildRuns.delete(run);\n\t\t\t\t\tthis._scheduleGoalContinuationAfterRlmWork();\n\t\t\t\t}\n\t\t\t}\n\t\t})();\n\t\tthis._rlmRunTasks.add(task);\n\t\tvoid task.then(\n\t\t\t() => this._rlmRunTasks.delete(task),\n\t\t\t(error) => {\n\t\t\t\tthis._rlmRunTasks.delete(task);\n\t\t\t\tthis._surfaceSessionInputError(error);\n\t\t\t},\n\t\t);\n\n\t\treturn {\n\t\t\trlm_child_id: childNodeId,\n\t\t\tname: sessionName,\n\t\t\tsession_dir: childSessionDir,\n\t\t\tmodel: `${modelSelection.model.provider}/${modelSelection.model.id}`,\n\t\t};\n\t}\n\n\tasync runRlmChild(\n\t\tprompt: string,\n\t\tkwargs: Record<string, unknown> = {},\n\t\tspawnCode?: string,\n\t): Promise<RlmSpawnHandle> {\n\t\tconst admission = await this.reserveRlmChildAdmission();\n\t\tconst start = this._startRlmChildRun(prompt, admission, kwargs, spawnCode);\n\t\t// Join pre-runtime name/model work during disposal as well as the detached task.\n\t\tconst pending = start.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\tthis._rlmRunTasks.add(pending);\n\t\ttry {\n\t\t\treturn await start;\n\t\t} catch (error) {\n\t\t\tawait admission.settle();\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis._rlmRunTasks.delete(pending);\n\t\t}\n\t}\n\n\tprivate _isRetryableError(message: AssistantMessage): boolean {\n\t\treturn isTransientProviderFailure(message) && !isContextOverflow(message, this.model?.contextWindow ?? 0);\n\t}\n\n\tprivate _getProviderStreamFailureDetails(message: AssistantMessage): Record<string, unknown> | undefined {\n\t\tconst failure = message.diagnostics?.find((diagnostic) => diagnostic.type === \"provider_stream_failure\");\n\t\tconst details = failure?.details;\n\t\tif (!details || typeof details !== \"object\") {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn details;\n\t}\n\n\tprivate _getProviderStreamFailureAuthStatus(message: AssistantMessage): number | undefined {\n\t\tconst details = this._getProviderStreamFailureDetails(message);\n\t\tif (!details) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst kind = details.kind;\n\t\tif (kind !== \"auth\") {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst status = details.status;\n\t\tif (typeof status === \"number\") {\n\t\t\treturn status;\n\t\t}\n\t\tif (typeof status === \"string\") {\n\t\t\tconst parsed = Number(status);\n\t\t\treturn Number.isInteger(parsed) ? parsed : undefined;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate _isConcreteProviderAuthFailure(message: AssistantMessage): boolean {\n\t\tif (message.stopReason !== \"error\" || !message.errorMessage) return false;\n\n\t\tconst structuredStatus = this._getProviderStreamFailureAuthStatus(message);\n\t\tif (structuredStatus === 401 || structuredStatus === 403) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (/\\b(?:401|403)\\b/.test(message.errorMessage) && /\\bstatus code\\b/i.test(message.errorMessage)) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn (\n\t\t\t/\\b(?:401|403)\\b/.test(message.errorMessage) &&\n\t\t\t/auth|unauthori[sz]ed|forbidden|api.?key|token|credential/i.test(message.errorMessage)\n\t\t);\n\t}\n\n\tprivate _markProviderAuthStale(source: AuthSourceToken): void {\n\t\tif (this._modelRegistry.markProviderAuthSourceStale(source)) {\n\t\t\tthis._emit({ type: \"auth_stale\", provider: source.provider, sourceTokens: [source] });\n\t\t}\n\t}\n\n\tprivate _finishActiveRetryWithFailure(message: AssistantMessage): void {\n\t\tif (this._retryAttempt === 0) {\n\t\t\treturn;\n\t\t}\n\t\tthis._emit({\n\t\t\ttype: \"auto_retry_end\",\n\t\t\tsuccess: false,\n\t\t\tattempt: this._retryAttempt,\n\t\t\tfinalError: message.errorMessage,\n\t\t});\n\t\tthis._retryAttempt = 0;\n\t}\n\n\tprivate async _handleRetryableError(message: AssistantMessage, signal?: AbortSignal): Promise<boolean> {\n\t\tconst settings = this.settingsManager.getRetrySettings();\n\t\tif (!settings.enabled || signal?.aborted || !this._isRetryableError(message)) return false;\n\n\t\t// Join native message persistence before omitting its acknowledged assistant ID.\n\t\tawait this._waitForAgentEventsBeforeContext();\n\t\tif (signal?.aborted) return false;\n\t\tthis._removeLastAssistantFromContext();\n\t\tif (!this._retryPromise) {\n\t\t\tthis._retryPromise = new Promise((resolve) => {\n\t\t\t\tthis._retryResolve = resolve;\n\t\t\t});\n\t\t}\n\t\tthis._retryAttempt++;\n\t\tconst delayMs = Math.min(\n\t\t\tthis.settingsManager.getProviderRetrySettings().maxRetryDelayMs || 60_000,\n\t\t\tsettings.baseDelayMs * 2 ** Math.min(this._retryAttempt - 1, 32),\n\t\t);\n\t\t// Payload hooks forfeit reuse. Otherwise retain the failed operation's existing identity.\n\t\tif (!this._extensionRunner.hasHandlers(\"before_provider_request\")) {\n\t\t\tthis._semanticEdges.prepareTurnRetry();\n\t\t\tthis.requests.prepareTurnRetry();\n\t\t}\n\t\tconst controller = new AbortController();\n\t\tthis._retryAbortController = controller;\n\t\tconst retrySignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;\n\t\tthis._emit({\n\t\t\ttype: \"auto_retry_start\",\n\t\t\tattempt: this._retryAttempt,\n\t\t\tdelayMs,\n\t\t\terrorMessage: message.errorMessage || \"Provider request failed\",\n\t\t});\n\t\ttry {\n\t\t\tawait sleep(delayMs, retrySignal);\n\t\t} catch (error) {\n\t\t\tif (!retrySignal.aborted) throw error;\n\t\t\treturn false;\n\t\t} finally {\n\t\t\tthis._retryAbortController = undefined;\n\t\t}\n\t\treturn this.settingsManager.getRetryEnabled() && !retrySignal.aborted;\n\t}\n\n\tabortRetry(): void {\n\t\tif (this._retryPromise) this.agent.abort();\n\t\tif (this._retryAbortController) {\n\t\t\tthis._retryAbortController.abort();\n\t\t\treturn;\n\t\t}\n\t\tif (this._retryAttempt > 0) {\n\t\t\tthis._autoCompactionAbortController?.abort();\n\t\t\tthis._cancelPostCompactionContinue();\n\t\t\tthis._emit({\n\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\tsuccess: false,\n\t\t\t\tattempt: this._retryAttempt,\n\t\t\t\tfinalError: \"Retry cancelled\",\n\t\t\t});\n\t\t\tthis._retryAttempt = 0;\n\t\t}\n\t\tthis._resolveRetry();\n\t}\n\n\tprivate async waitForRetry(): Promise<void> {\n\t\tif (!this._retryPromise) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait this._retryPromise;\n\t\tawait this.agent.waitForIdle();\n\t}\n\n\tget isRetrying(): boolean {\n\t\treturn this._retryPromise !== undefined;\n\t}\n\n\tget hasAcceptedPromptInFlight(): boolean {\n\t\treturn this._actionStore\n\t\t\t.unfinishedActions()\n\t\t\t.some(\n\t\t\t\t(action) =>\n\t\t\t\t\taction.payload.kind === \"turn\" &&\n\t\t\t\t\t!action.payload.queueVisible &&\n\t\t\t\t\taction.payload.acceptedBeforeCompletion,\n\t\t\t);\n\t}\n\n\tget autoRetryEnabled(): boolean {\n\t\treturn this.settingsManager.getRetryEnabled();\n\t}\n\n\tsetAutoRetryEnabled(enabled: boolean): void {\n\t\tthis.settingsManager.setRetryEnabled(enabled);\n\t}\n\n\t/**\n\t * Execute a bash command.\n\t * Adds result to agent context and session.\n\t * @param command The bash command to execute\n\t * @param onChunk Optional streaming callback for output\n\t * @param options.excludeFromContext If true, command output won't be sent to LLM (!! prefix)\n\t * @param options.operations Custom BashOperations for remote execution\n\t */\n\tasync executeBash(\n\t\tcommand: string,\n\t\tonChunk?: (chunk: string) => void,\n\t\toptions?: {\n\t\t\texcludeFromContext?: boolean;\n\t\t\toperations?: BashOperations;\n\t\t\ttransient?: boolean;\n\t\t},\n\t): Promise<BashResult> {\n\t\t// Each invocation owns its controller so abortBash reaches every in-flight command.\n\t\tconst abortController = new AbortController();\n\t\tthis._bashAbortControllers.add(abortController);\n\n\t\tconst prefix = this.settingsManager.getShellCommandPrefix();\n\t\tconst shellPath = this.settingsManager.getShellPath();\n\t\tconst resolvedCommand = prefix ? `${prefix}\\n${command}` : command;\n\n\t\ttry {\n\t\t\tconst result = await executeBashWithOperations(\n\t\t\t\tresolvedCommand,\n\t\t\t\tthis.sessionManager.getCwd(),\n\t\t\t\toptions?.operations ?? createLocalBashOperations({ shellPath }),\n\t\t\t\t{\n\t\t\t\t\tonChunk,\n\t\t\t\t\tsignal: abortController.signal,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!options?.transient) {\n\t\t\t\tawait this.recordBashResult(command, result, options);\n\t\t\t}\n\t\t\treturn result;\n\t\t} finally {\n\t\t\tthis._bashAbortControllers.delete(abortController);\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t}\n\t}\n\n\t/**\n\t * Run a user-initiated bash command (! / !! prefix), emitting bash_start,\n\t * bash_output, and bash_end session events so any attached client can render\n\t * streaming output. Extensions can intercept execution via the user_bash event.\n\t * Execution failures are reported through bash_end rather than a rejected promise;\n\t * only the already-running guard and extension dispatch errors reject.\n\t * @param command The bash command to execute\n\t * @param options.excludeFromContext If true, command output won't be sent to LLM (!! prefix)\n\t */\n\tasync runUserBash(\n\t\tcommand: string,\n\t\toptions?: {\n\t\t\texcludeFromContext?: boolean;\n\t\t\ttransient?: boolean;\n\t\t\trunId?: string;\n\t\t},\n\t): Promise<void> {\n\t\tif (this.isBashRunning) {\n\t\t\tthrow new Error(\"A bash command is already running\");\n\t\t}\n\t\t// Claim the bash slot synchronously: isBashRunning is otherwise false until\n\t\t// executeBash installs its abort controller, which would let a second command\n\t\t// slip through during the user_bash extension dispatch below.\n\t\tthis._userBashRunning = true;\n\t\tthis._userBashAbortRequested = false;\n\t\t// Echoed on bash_start/bash_end so the requesting client can tell its own\n\t\t// run apart from other clients' runs broadcast on the same session.\n\t\tconst identity = {\n\t\t\t...(options?.transient ? { transient: true } : {}),\n\t\t\t...(options?.runId !== undefined ? { runId: options.runId } : {}),\n\t\t};\n\t\tlet end: UserBashEndDetails;\n\t\ttry {\n\t\t\tend = await this.runUserBashLocked(\n\t\t\t\tcommand,\n\t\t\t\toptions?.excludeFromContext ?? false,\n\t\t\t\toptions?.transient ?? false,\n\t\t\t\tidentity,\n\t\t\t);\n\t\t} finally {\n\t\t\tthis._userBashRunning = false;\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t}\n\t\t// Emitted after the slot is released so clients never observe a bash_end\n\t\t// while the session still rejects new commands as already running.\n\t\tthis._emit({ type: \"bash_end\", ...end, ...identity });\n\t\tvoid this._drainQueuedMessagesAfterBash().catch(() => undefined);\n\t}\n\n\tprivate async _drainQueuedMessagesAfterBash(): Promise<void> {\n\t\tawait this.agent.waitForIdle();\n\t\tthis._scheduleSessionInputPump();\n\t}\n\n\tprivate async runUserBashLocked(\n\t\tcommand: string,\n\t\texcludeFromContext: boolean,\n\t\ttransient: boolean,\n\t\tidentity: { transient?: boolean; runId?: string },\n\t): Promise<UserBashEndDetails> {\n\t\tconst eventResult = await this._extensionRunner.emitUserBash({\n\t\t\ttype: \"user_bash\",\n\t\t\tcommand,\n\t\t\texcludeFromContext,\n\t\t\tcwd: this.sessionManager.getCwd(),\n\t\t});\n\n\t\t// Transient runs (side-conversation bash) live only in their pane: they\n\t\t// are never recorded, so reloads and rebuilds cannot resurface them.\n\t\tconst record = transient\n\t\t\t? () => {}\n\t\t\t: (result: BashResult) => this.recordBashResult(command, result, { excludeFromContext });\n\n\t\tthis._emit({\n\t\t\ttype: \"bash_start\",\n\t\t\tcommand,\n\t\t\texcludeFromContext,\n\t\t\t...identity,\n\t\t});\n\t\ttry {\n\t\t\t// If an extension returned a full result, surface it without executing\n\t\t\tif (eventResult?.result) {\n\t\t\t\tconst result = eventResult.result;\n\t\t\t\tif (result.output) {\n\t\t\t\t\tthis._emit({ type: \"bash_output\", chunk: result.output });\n\t\t\t\t}\n\t\t\t\tawait record(result);\n\t\t\t\treturn {\n\t\t\t\t\texitCode: result.exitCode,\n\t\t\t\t\tcancelled: result.cancelled,\n\t\t\t\t\ttruncated: result.truncated,\n\t\t\t\t\tfullOutputPath: result.fullOutputPath,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// An abort that arrived before the process spawned (during extension\n\t\t\t// dispatch) has no abort controller to act on; honor it here instead.\n\t\t\tif (this._userBashAbortRequested) {\n\t\t\t\tawait record({\n\t\t\t\t\toutput: \"\",\n\t\t\t\t\texitCode: undefined,\n\t\t\t\t\tcancelled: true,\n\t\t\t\t\ttruncated: false,\n\t\t\t\t});\n\t\t\t\treturn { exitCode: undefined, cancelled: true, truncated: false };\n\t\t\t}\n\n\t\t\tconst result = await this.executeBash(command, (chunk) => this._emit({ type: \"bash_output\", chunk }), {\n\t\t\t\texcludeFromContext,\n\t\t\t\toperations: eventResult?.operations,\n\t\t\t\ttransient,\n\t\t\t});\n\t\t\treturn {\n\t\t\t\texitCode: result.exitCode,\n\t\t\t\tcancelled: result.cancelled,\n\t\t\t\ttruncated: result.truncated,\n\t\t\t\tfullOutputPath: result.fullOutputPath,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\t// Persist the failure like every other outcome so replayed transcripts\n\t\t\t// and the LLM context reflect that the command did not run.\n\t\t\tawait record({\n\t\t\t\toutput: `bash failed: ${errorMessage}`,\n\t\t\t\texitCode: undefined,\n\t\t\t\tcancelled: false,\n\t\t\t\ttruncated: false,\n\t\t\t});\n\t\t\treturn {\n\t\t\t\texitCode: undefined,\n\t\t\t\tcancelled: false,\n\t\t\t\ttruncated: false,\n\t\t\t\terrorMessage,\n\t\t\t};\n\t\t}\n\t}\n\n\tasync recordBashResult(\n\t\tcommand: string,\n\t\tresult: BashResult,\n\t\toptions?: { excludeFromContext?: boolean },\n\t): Promise<void> {\n\t\tconst bashMessage: BashExecutionMessage = {\n\t\t\trole: \"bashExecution\",\n\t\t\tcommand,\n\t\t\toutput: result.output,\n\t\t\texitCode: result.exitCode,\n\t\t\tcancelled: result.cancelled,\n\t\t\ttruncated: result.truncated,\n\t\t\tfullOutputPath: result.fullOutputPath,\n\t\t\ttimestamp: Date.now(),\n\t\t\texcludeFromContext: options?.excludeFromContext,\n\t\t};\n\n\t\t// If agent is streaming, defer adding to avoid breaking tool_use/tool_result ordering\n\t\tif (this.isStreaming) {\n\t\t\tthis._pendingBashMessages.push(bashMessage);\n\t\t} else {\n\t\t\tawait this.sessionManager.appendMessage(bashMessage);\n\t\t\tthis.agent.state.messages.push(bashMessage);\n\t\t}\n\t}\n\n\t/**\n\t * Cancel running bash command.\n\t */\n\tabortBash(): void {\n\t\t// A user bash command may not have spawned yet (extension dispatch in\n\t\t// progress); flag the request so runUserBash cancels before executing.\n\t\t// runUserBash clears the flag at each start, so a stale flag is harmless.\n\t\tif (this._userBashRunning) {\n\t\t\tthis._userBashAbortRequested = true;\n\t\t}\n\t\tfor (const controller of this._bashAbortControllers) {\n\t\t\tcontroller.abort();\n\t\t}\n\t}\n\n\tget isBashRunning(): boolean {\n\t\treturn this._bashAbortControllers.size > 0 || this._userBashRunning;\n\t}\n\n\t/** Whether there are pending bash messages waiting to be flushed */\n\tget hasPendingBashMessages(): boolean {\n\t\treturn this._pendingBashMessages.length > 0;\n\t}\n\n\t/**\n\t * Flush pending bash messages to agent state and session.\n\t * Called after agent turn completes to maintain proper message ordering.\n\t */\n\tprivate async _flushPendingBashMessages(): Promise<void> {\n\t\tif (this._pendingBashMessages.length === 0) return;\n\n\t\twhile (this._pendingBashMessages.length > 0) {\n\t\t\tconst bashMessage = this._pendingBashMessages[0]!;\n\t\t\tawait this.sessionManager.appendMessage(bashMessage);\n\t\t\tthis._pendingBashMessages.shift();\n\t\t\tthis.agent.state.messages.push(bashMessage);\n\t\t}\n\t}\n\n\tgetRlmMaxSubagentsStatus(): Promise<RlmMaxSubagentsStatus> {\n\t\treturn this._rlmSubagentCapacity.getStatus();\n\t}\n\n\tsetRlmMaxSubagents(maxSubagents: number): Promise<RlmMaxSubagentsStatus> {\n\t\treturn this._rlmSubagentCapacity.setMaxSubagents(maxSubagents);\n\t}\n\n\tgetRlmMaxDepthStatus(): RlmMaxDepthStatus {\n\t\treturn { maxDepth: this._rlmMaxDepth, source: this._rlmMaxDepthSource };\n\t}\n\n\tasync setRlmMaxDepth(maxDepth: number, options: { global?: boolean } = {}): Promise<SetRlmMaxDepthResult> {\n\t\tif (!isNonNegativeInteger(maxDepth)) {\n\t\t\tthrow new Error(\"RLM max depth must be a non-negative integer.\");\n\t\t}\n\n\t\tawait this.sessionManager.appendCustomEntryWithRollback(RLM_MAX_DEPTH_STATE_CUSTOM_TYPE, { maxDepth });\n\t\tthis._rlmMaxDepth = maxDepth;\n\t\tthis._rlmMaxDepthSource = \"chat\";\n\t\tconst oldBase = this._baseSystemPrompt;\n\t\tthis._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());\n\t\tthis.agent.state.systemPrompt = this._refreshExtensionSystemPrompt(this.agent.state.systemPrompt, oldBase);\n\n\t\tlet globalError: string | undefined;\n\t\tif (options.global) {\n\t\t\tawait this.settingsManager.flush();\n\t\t\tconst staleErrors = this.settingsManager.drainErrors(\"global\");\n\t\t\tfor (const { error } of staleErrors) {\n\t\t\t\tconsole.warn(`Warning: Earlier global settings write failed: ${error.message}`);\n\t\t\t}\n\t\t\tthis.settingsManager.setRlmMaxDepth(maxDepth);\n\t\t\tawait this.settingsManager.flush();\n\t\t\tconst errors = this.settingsManager.drainErrors(\"global\");\n\t\t\tglobalError = errors.map(({ error }) => error.message).join(\"; \") || undefined;\n\t\t}\n\n\t\treturn {\n\t\t\t...this.getRlmMaxDepthStatus(),\n\t\t\tglobalSaved: options.global === true && globalError === undefined,\n\t\t\t...(globalError ? { globalError } : {}),\n\t\t};\n\t}\n\n\tasync setSessionName(name: string): Promise<void> {\n\t\tawait this.sessionManager.appendSessionInfo(name);\n\t\tthis._emit({\n\t\t\ttype: \"session_info_changed\",\n\t\t\tname: this.sessionManager.getSessionName(),\n\t\t});\n\t}\n\n\t/**\n\t * Navigate to a different node in the session tree.\n\t * Unlike fork() which creates a new session file, this stays in the same file.\n\t *\n\t * @param targetId The entry ID to navigate to\n\t * @param options.summarize Whether user wants to summarize abandoned branch\n\t * @param options.customInstructions Custom instructions for summarizer\n\t * @param options.replaceInstructions If true, customInstructions replaces the default prompt\n\t * @param options.label Label to attach to the branch summary entry\n\t * @returns Result with editorText (if user message) and cancelled status\n\t */\n\tprivate _branchNavigationQueue: Promise<void> = Promise.resolve();\n\n\tasync navigateTree(\n\t\ttargetId: string,\n\t\toptions: {\n\t\t\tsummarize?: boolean;\n\t\t\tcustomInstructions?: string;\n\t\t\treplaceInstructions?: boolean;\n\t\t\tlabel?: string;\n\t\t} = {},\n\t): Promise<{\n\t\teditorText?: string;\n\t\tcancelled: boolean;\n\t\taborted?: boolean;\n\t\tsummaryEntry?: BranchSummaryEntry;\n\t}> {\n\t\toptions = { ...options };\n\t\tconst previous = this._branchNavigationQueue;\n\t\tlet release = () => {};\n\t\tthis._branchNavigationQueue = new Promise<void>((resolve) => {\n\t\t\trelease = resolve;\n\t\t});\n\t\tawait previous;\n\t\ttry {\n\t\t\treturn await this._navigateTree(targetId, options);\n\t\t} finally {\n\t\t\trelease();\n\t\t}\n\t}\n\n\tprivate _resolveBranchSummaryModel(): { model: Model<Api>; thinkingLevel: ThinkingLevel } | undefined {\n\t\tconst selection = this.settingsManager.getBranchSummaryModel();\n\t\tif (selection === undefined) return undefined;\n\t\tif (\n\t\t\t!selection ||\n\t\t\ttypeof selection !== \"object\" ||\n\t\t\tArray.isArray(selection) ||\n\t\t\ttypeof selection.provider !== \"string\" ||\n\t\t\t!selection.provider.trim() ||\n\t\t\ttypeof selection.modelId !== \"string\" ||\n\t\t\t!selection.modelId.trim() ||\n\t\t\ttypeof selection.thinkingLevel !== \"string\"\n\t\t)\n\t\t\tthrow new Error(\"Invalid branchSummary.model; expected provider, modelId, and thinkingLevel\");\n\t\tconst model = this._modelRegistry.find(selection.provider, selection.modelId);\n\t\tif (!model) throw new Error(`Unknown branchSummary.model ${selection.provider}/${selection.modelId}`);\n\t\tif (!getSupportedThinkingLevels(model).includes(selection.thinkingLevel))\n\t\t\tthrow new Error(\n\t\t\t\t`branchSummary.model thinkingLevel ${selection.thinkingLevel} is not supported by ${selection.provider}/${selection.modelId}`,\n\t\t\t);\n\t\treturn { model: structuredClone(model), thinkingLevel: selection.thinkingLevel };\n\t}\n\n\tprivate async _navigateTree(\n\t\ttargetId: string,\n\t\toptions: {\n\t\t\tsummarize?: boolean;\n\t\t\tcustomInstructions?: string;\n\t\t\treplaceInstructions?: boolean;\n\t\t\tlabel?: string;\n\t\t} = {},\n\t): Promise<{\n\t\teditorText?: string;\n\t\tcancelled: boolean;\n\t\taborted?: boolean;\n\t\tsummaryEntry?: BranchSummaryEntry;\n\t}> {\n\t\tconst summarySelection = options.summarize ? this._resolveBranchSummaryModel() : undefined;\n\t\tif (options.summarize && !summarySelection && !this.model) {\n\t\t\tthrow new Error(\"No model available for summarization\");\n\t\t}\n\n\t\toptions = { ...options };\n\t\tconst queuedWorkPause = this.acquireQueuedWorkPause();\n\t\tlet commitFence: { owner: symbol; release(): void } | undefined;\n\t\ttry {\n\t\t\tconst targetSource = { sessionId: this.sessionId, sessionFile: this.sessionFile };\n\t\t\tconst targetEntry = await this.sessionManager.readEntry(targetId);\n\t\t\tif (targetSource.sessionId !== this.sessionId || targetSource.sessionFile !== this.sessionFile)\n\t\t\t\tthrow new Error(\"Session source changed during branch navigation\");\n\t\t\tif (this._disposing || this._disposed) throw new Error(\"Cannot navigate a disposing or disposed session.\");\n\t\t\tif (!targetEntry) throw new Error(`Entry ${targetId} not found`);\n\t\t\t// Branch navigation and turn dispatch mutate the same transcript leaf.\n\t\t\tcommitFence = await this._acquireSessionActionCommitFence();\n\t\t\treturn await this._sessionActionCommitContext.run(commitFence.owner, async () => {\n\t\t\t\tawait this.agent.waitForIdle();\n\t\t\t\tawait this._agentEventQueue;\n\t\t\t\tif (targetSource.sessionId !== this.sessionId || targetSource.sessionFile !== this.sessionFile)\n\t\t\t\t\tthrow new Error(\"Session source changed during branch navigation\");\n\t\t\t\treturn this._navigateTreeUnderPause(targetId, targetEntry, options, summarySelection);\n\t\t\t});\n\t\t} finally {\n\t\t\tqueuedWorkPause.release();\n\t\t\tcommitFence?.release();\n\t\t}\n\t}\n\n\tprivate async _navigateTreeUnderPause(\n\t\ttargetId: string,\n\t\ttargetEntry: NonNullable<Awaited<ReturnType<SessionManager[\"readEntry\"]>>>,\n\t\toptions: {\n\t\t\tsummarize?: boolean;\n\t\t\tcustomInstructions?: string;\n\t\t\treplaceInstructions?: boolean;\n\t\t\tlabel?: string;\n\t\t},\n\t\tsummarySelection: { model: Model<Api>; thinkingLevel: ThinkingLevel } | undefined,\n\t): Promise<{\n\t\teditorText?: string;\n\t\tcancelled: boolean;\n\t\taborted?: boolean;\n\t\tsummaryEntry?: BranchSummaryEntry;\n\t}> {\n\t\tconst oldLeafId = this.sessionManager.getLeafId();\n\n\t\t// No-op if already at target after admitted work has settled.\n\t\tif (targetId === oldLeafId) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\t// Do not switch branches while /refine has detached event handling and is\n\t\t// about to persist harness/session entries for the current branch.\n\t\tawait this._invalidatePendingAutoRefineForBranchChange();\n\t\tif (this._disposing || this._disposed) throw new Error(\"Cannot navigate a disposing or disposed session.\");\n\n\t\tthis._branchSummaryAbortController = new AbortController();\n\t\tlet resolveBranchSummaryOperation: () => void = () => {};\n\t\tconst branchSummaryOperation = new Promise<void>((resolve) => {\n\t\t\tresolveBranchSummaryOperation = resolve;\n\t\t});\n\t\tthis._branchSummaryOperation = branchSummaryOperation;\n\n\t\ttry {\n\t\t\tconst initialSource = { sessionId: this.sessionId, sessionFile: this.sessionFile };\n\t\t\tconst captured = await this.sessionManager.readBranches([oldLeafId, targetId]);\n\t\t\tconst source = captured.source ?? initialSource;\n\t\t\tconst assertSource = () => {\n\t\t\t\tif (source.sessionId !== this.sessionId || source.sessionFile !== this.sessionFile)\n\t\t\t\t\tthrow new Error(\"Session source changed during branch navigation\");\n\t\t\t};\n\t\t\tassertSource();\n\t\t\tif (this._branchSummaryAbortController.signal.aborted) return { cancelled: true, aborted: true };\n\t\t\tconst [oldPath, targetPath] = captured.branches;\n\t\t\tif (!oldPath || !targetPath) throw new Error(\"Captured navigation paths are unavailable\");\n\t\t\tconst { entries: entriesToSummarize, commonAncestorId } = collectEntriesForBranchSummary(oldPath, targetPath);\n\n\t\t\tlet customInstructions = options.customInstructions;\n\t\t\tlet replaceInstructions = options.replaceInstructions;\n\t\t\tlet label = options.label;\n\n\t\t\tconst preparation: TreePreparation = {\n\t\t\t\ttargetId,\n\t\t\t\toldLeafId,\n\t\t\t\tcommonAncestorId,\n\t\t\t\tentriesToSummarize,\n\t\t\t\tuserWantsSummary: options.summarize ?? false,\n\t\t\t\tcustomInstructions,\n\t\t\t\treplaceInstructions,\n\t\t\t\tlabel,\n\t\t\t};\n\n\t\t\tlet extensionSummary: { summary: string; details?: unknown } | undefined;\n\t\t\tlet fromExtension = false;\n\n\t\t\tif (this._extensionRunner.hasHandlers(\"session_before_tree\")) {\n\t\t\t\tconst result = (await this._extensionRunner.emit({\n\t\t\t\t\ttype: \"session_before_tree\",\n\t\t\t\t\tpreparation,\n\t\t\t\t\tsignal: this._branchSummaryAbortController.signal,\n\t\t\t\t})) as SessionBeforeTreeResult | undefined;\n\n\t\t\t\tif (result?.cancel) {\n\t\t\t\t\treturn { cancelled: true };\n\t\t\t\t}\n\n\t\t\t\tif (result?.summary && options.summarize) {\n\t\t\t\t\textensionSummary = result.summary;\n\t\t\t\t\tfromExtension = true;\n\t\t\t\t}\n\n\t\t\t\tif (result?.customInstructions !== undefined) {\n\t\t\t\t\tcustomInstructions = result.customInstructions;\n\t\t\t\t}\n\t\t\t\tif (result?.replaceInstructions !== undefined) {\n\t\t\t\t\treplaceInstructions = result.replaceInstructions;\n\t\t\t\t}\n\t\t\t\tif (result?.label !== undefined) {\n\t\t\t\t\tlabel = result.label;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tassertSource();\n\t\t\tlet summaryText: string | undefined;\n\t\t\tlet nativeBranchSummary: BranchSummaryResult | undefined;\n\t\t\tlet summaryDetails: unknown;\n\t\t\tlet summaryUsage: Usage | undefined;\n\t\t\tif (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {\n\t\t\t\tconst selectedModel = summarySelection?.model ?? this.model!;\n\t\t\t\tconst model = { ...selectedModel, cost: { ...selectedModel.cost } };\n\t\t\t\tconst branchSummarySettings = { ...this.settingsManager.getBranchSummarySettings() };\n\t\t\t\tconst summaryEntries = structuredClone(entriesToSummarize);\n\t\t\t\tconst summaryManager = this.sessionManager;\n\t\t\t\tconst requests = this.requests[captureNativeBranchRequests](summaryManager.bindRequestSink());\n\t\t\t\ttry {\n\t\t\t\t\tconst { apiKey, headers } = await this._getRequiredRequestAuth(model);\n\t\t\t\t\tconst result = await generateBranchSummary(summaryEntries, {\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t...(summarySelection === undefined ? {} : { thinkingLevel: summarySelection.thinkingLevel }),\n\t\t\t\t\t\tapiKey,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tsignal: this._branchSummaryAbortController.signal,\n\t\t\t\t\t\tcustomInstructions,\n\t\t\t\t\t\treplaceInstructions,\n\t\t\t\t\t\treserveTokens: branchSummarySettings.reserveTokens,\n\t\t\t\t\t\trequests,\n\t\t\t\t\t});\n\t\t\t\t\tif (result.aborted) {\n\t\t\t\t\t\treturn { cancelled: true, aborted: true };\n\t\t\t\t\t}\n\t\t\t\t\tif (result.error) {\n\t\t\t\t\t\tthrow new Error(result.error);\n\t\t\t\t\t}\n\t\t\t\t\tnativeBranchSummary = result;\n\t\t\t\t\tsummaryText = result.summary;\n\t\t\t\t\tsummaryUsage = result.usage;\n\t\t\t\t\tsummaryDetails = {\n\t\t\t\t\t\treadFiles: result.readFiles || [],\n\t\t\t\t\t\tmodifiedFiles: result.modifiedFiles || [],\n\t\t\t\t\t};\n\t\t\t\t} finally {\n\t\t\t\t\tawait requests.dispose();\n\t\t\t\t}\n\t\t\t} else if (extensionSummary) {\n\t\t\t\tsummaryText = extensionSummary.summary;\n\t\t\t\tsummaryDetails = extensionSummary.details;\n\t\t\t}\n\n\t\t\tlet newLeafId: string | null;\n\t\t\tlet editorText: string | undefined;\n\n\t\t\tif (targetEntry.type === \"message\" && targetEntry.message.role === \"user\") {\n\t\t\t\tnewLeafId = targetEntry.parentId;\n\t\t\t\teditorText = this._extractUserMessageText(targetEntry.message.content);\n\t\t\t} else if (targetEntry.type === \"custom_message\") {\n\t\t\t\tnewLeafId = targetEntry.parentId;\n\t\t\t\teditorText =\n\t\t\t\t\ttypeof targetEntry.content === \"string\"\n\t\t\t\t\t\t? targetEntry.content\n\t\t\t\t\t\t: targetEntry.content\n\t\t\t\t\t\t\t\t.filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n\t\t\t\t\t\t\t\t.map((c) => c.text)\n\t\t\t\t\t\t\t\t.join(\"\");\n\t\t\t} else {\n\t\t\t\tnewLeafId = targetId;\n\t\t\t}\n\n\t\t\tawait this.sessionManager.flushNow();\n\t\t\tassertSource();\n\t\t\tlet summaryEntry: BranchSummaryEntry | undefined;\n\t\t\tif (summaryText) {\n\t\t\t\tconst manager = this.sessionManager;\n\t\t\t\tconst write = !fromExtension ? takeNativeBranchSummaryWrite(nativeBranchSummary, summaryText) : undefined;\n\t\t\t\tconst pending = write?.(manager, newLeafId, summaryText, summaryDetails, summaryUsage);\n\t\t\t\tconst summaryId =\n\t\t\t\t\t(pending ? await pending : undefined) ??\n\t\t\t\t\t(await manager.branchWithSummary(newLeafId, summaryText, summaryDetails, fromExtension, summaryUsage));\n\t\t\t\tsummaryEntry = (await this.sessionManager.readEntry(summaryId)) as BranchSummaryEntry;\n\n\t\t\t\tif (label) {\n\t\t\t\t\tawait this.sessionManager.appendLabelChange(summaryId, label);\n\t\t\t\t}\n\t\t\t} else if (newLeafId === null) {\n\t\t\t\tawait this.sessionManager.branchTo(null);\n\t\t\t} else {\n\t\t\t\tawait this.sessionManager.branchTo(newLeafId);\n\t\t\t}\n\n\t\t\tif (label && !summaryText) {\n\t\t\t\tawait this.sessionManager.appendLabelChange(targetId, label);\n\t\t\t}\n\n\t\t\tconst { context: sessionContext } = await readSessionBootstrap(\n\t\t\t\tthis.sessionManager,\n\t\t\t\tthis.settingsManager.getCanonicalContextLimits(),\n\t\t\t\t{ purpose: \"read\", initialContextMode: this._initialContextMode },\n\t\t\t);\n\t\t\tthis.agent.state.messages = sessionContext.messages;\n\t\t\tthis._contextOmissions = undefined;\n\t\t\tthis._mergeUnpersistedOutcomes(this.agent.state.messages);\n\t\t\tthis._restoreLateIpythonSentAgentMessages();\n\t\t\tawait this._reloadBranchRuntimeState();\n\t\t\tthis._invalidateQueuedPromptPreparation();\n\n\t\t\tawait this._extensionRunner.emit({\n\t\t\t\ttype: \"session_tree\",\n\t\t\t\tnewLeafId: this.sessionManager.getLeafId(),\n\t\t\t\toldLeafId,\n\t\t\t\tsummaryEntry,\n\t\t\t\tfromExtension: summaryText ? fromExtension : undefined,\n\t\t\t});\n\n\t\t\treturn { editorText, cancelled: false, summaryEntry };\n\t\t} finally {\n\t\t\tthis._branchSummaryAbortController = undefined;\n\t\t\tif (this._branchSummaryOperation === branchSummaryOperation) {\n\t\t\t\tthis._branchSummaryOperation = undefined;\n\t\t\t}\n\t\t\tresolveBranchSummaryOperation();\n\t\t\tthis._notifySessionInputCheckpointChange();\n\t\t}\n\t}\n\n\tgetUserMessagesForForking(): Promise<Array<{ entryId: string; text: string }>> {\n\t\treturn readUserMessagesForForking(this.sessionManager);\n\t}\n\n\tprivate _extractUserMessageText(content: string | Array<{ type: string; text?: string }>): string {\n\t\tif (typeof content === \"string\") return content;\n\t\tif (Array.isArray(content)) {\n\t\t\treturn content\n\t\t\t\t.filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n\t\t\t\t.map((c) => c.text)\n\t\t\t\t.join(\"\");\n\t\t}\n\t\treturn \"\";\n\t}\n\n\tasync getSessionStats(): Promise<SessionStats> {\n\t\tconst state = this.state;\n\t\tconst userMessages = state.messages.filter((m) => m.role === \"user\").length;\n\t\tconst assistantMessages = state.messages.filter((m) => m.role === \"assistant\").length;\n\t\tconst toolResults = state.messages.filter((m) => m.role === \"toolResult\").length;\n\n\t\tlet toolCalls = 0;\n\t\tlet totalInput = 0;\n\t\tlet totalOutput = 0;\n\t\tlet totalCacheRead = 0;\n\t\tlet totalCacheWrite = 0;\n\t\tlet totalCost = 0;\n\n\t\tfor (const message of state.messages) {\n\t\t\tif (message.role === \"assistant\") {\n\t\t\t\tconst assistantMsg = message as AssistantMessage;\n\t\t\t\ttoolCalls += assistantMsg.content.filter((c) => c.type === \"toolCall\").length;\n\t\t\t\ttotalInput += assistantMsg.usage.input;\n\t\t\t\ttotalOutput += assistantMsg.usage.output;\n\t\t\t\ttotalCacheRead += assistantMsg.usage.cacheRead;\n\t\t\t\ttotalCacheWrite += assistantMsg.usage.cacheWrite;\n\t\t\t\ttotalCost += assistantMsg.usage.cost.total;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsessionFile: this.sessionFile,\n\t\t\tsessionId: this.sessionId,\n\t\t\tuserMessages,\n\t\t\tassistantMessages,\n\t\t\ttoolCalls,\n\t\t\ttoolResults,\n\t\t\ttotalMessages: state.messages.length,\n\t\t\ttokens: {\n\t\t\t\tinput: totalInput,\n\t\t\t\toutput: totalOutput,\n\t\t\t\tcacheRead: totalCacheRead,\n\t\t\t\tcacheWrite: totalCacheWrite,\n\t\t\t\ttotal: totalInput + totalOutput + totalCacheRead + totalCacheWrite,\n\t\t\t},\n\t\t\tcost: totalCost,\n\t\t\tcontextUsage: await this.getContextUsage(),\n\t\t};\n\t}\n\n\tasync getContextUsage(): Promise<ContextUsage | undefined> {\n\t\tconst model = this.model;\n\t\tif (!model) return undefined;\n\t\tconst contextWindow = model.contextWindow ?? 0;\n\t\tif (contextWindow <= 0) return undefined;\n\n\t\t// Capture the working-view estimate before the source read can yield.\n\t\tconst estimate = estimateContextTokens(this.messages);\n\t\tconst { maxSourceBytes } = this.settingsManager.getCanonicalContextLimits();\n\t\tif (!(await this._contextUsageReader.hasPostCompactionUsage(this.sessionManager, maxSourceBytes)))\n\t\t\treturn { tokens: null, contextWindow, percent: null };\n\t\treturn {\n\t\t\ttokens: estimate.tokens,\n\t\t\tcontextWindow,\n\t\t\tpercent: (estimate.tokens / contextWindow) * 100,\n\t\t};\n\t}\n\n\tprivate _rlmSessionDirForReading(): string | undefined {\n\t\treturn this._rlmSessionDir ?? this.sessionManager.getSessionArtifactDir();\n\t}\n\n\tprivate _contextWindowResolver(): ContextWindowResolver {\n\t\treturn (provider, modelId) => this._modelRegistry.find(provider, modelId)?.contextWindow;\n\t}\n\n\t// Whole-source own spend, identical to the catalog reduction at passivation.\n\tasync getOwnUsageSummary(): Promise<SessionUsageSummary | undefined> {\n\t\tif (!this.sessionManager.supportsCapturedHistoryReads()) {\n\t\t\tconst entries = this.sessionManager.getEntries();\n\t\t\treturn sessionUsageSummaryFrom(computeOwnAndTotalUsage(entries, entries).ownUsage);\n\t\t}\n\t\treturn this.sessionManager.readOwnUsageSummary();\n\t}\n\n\t/**\n\t * Build the agent context overview for /context: this session as the root\n\t * plus one node per RLM sub-agent, recursively. Running children are read\n\t * from their live sessions; completed children from their persisted session\n\t * dirs, so the tree survives child disposal and session resume.\n\t */\n\tasync getContextTree(limits: Partial<ContextTreeRequestLimits> = {}): Promise<ContextTreeNode> {\n\t\treturn this._getContextTree(new ContextTreeRequest(limits));\n\t}\n\n\tprivate async _getContextTree(\n\t\trequest: ContextTreeRequest,\n\t\tidentity?: Pick<ContextTreeNode, \"id\" | \"label\" | \"status\">,\n\t): Promise<ContextTreeNode> {\n\t\t// Live descendants enter synchronously before any queued native/disk reduction.\n\t\t// Their parent already admitted the run identity and one node slot.\n\t\tif (!identity) request.admitNode();\n\t\tconst model = this.model;\n\t\tconst rootNode = {\n\t\t\t...(identity ?? { id: \"root\", label: this.sessionName ?? \"main agent\", status: \"active\" as const }),\n\t\t\tmodel: model ? { provider: model.provider, id: model.id } : undefined,\n\t\t};\n\t\trequest.retainMetadata(identity ? { model: rootNode.model } : rootNode);\n\t\tconst contextWindow = model?.contextWindow ?? 0;\n\t\tconst estimate = model && !(contextWindow <= 0) ? estimateContextTokens(this.messages) : undefined;\n\t\tconst availabilityBytes = estimate ? this.settingsManager.getCanonicalContextLimits().maxSourceBytes : undefined;\n\t\tconst resolveContextWindow = this._contextWindowResolver();\n\t\tconst rlmSessionDir = this._rlmSessionDirForReading();\n\t\tconst residentUsage = this.sessionManager.supportsCapturedHistoryReads()\n\t\t\t? undefined\n\t\t\t: readResidentContextTreeUsage(this.sessionManager, request.limits, availabilityBytes);\n\t\tif (residentUsage) request.retainMetadata(residentUsage);\n\t\tconst usageRead = residentUsage\n\t\t\t? Promise.resolve(residentUsage)\n\t\t\t: readContextTreeUsage(this.sessionManager, request.limits, request, availabilityBytes);\n\t\tconst children: Promise<ContextTreeNode | undefined>[] = [];\n\t\tconst skipIds = new Set<string>();\n\t\tlet diskChildren: Promise<ContextTreeNode[]> = Promise.resolve([]);\n\t\ttry {\n\t\t\t// Admit while iterating: do not first clone an unbounded run Map.\n\t\t\tfor (const run of this._activeRlmChildRuns.values()) {\n\t\t\t\trequest.admitNode();\n\t\t\t\tconst childIdentity = { id: run.id, label: rlmChildLabel(run.prompt), status: run.status };\n\t\t\t\trequest.retainMetadata(childIdentity);\n\t\t\t\tskipIds.add(childIdentity.id);\n\t\t\t\tconst child = run.session;\n\t\t\t\tchildren.push(\n\t\t\t\t\tchild\n\t\t\t\t\t\t? child._getContextTree(request, childIdentity)\n\t\t\t\t\t\t: loadContextTreeChildFromDisk(run.sessionDir, resolveContextWindow, request, childIdentity),\n\t\t\t\t);\n\t\t\t}\n\t\t\tdiskChildren = loadContextTreeChildrenFromDisk(rlmSessionDir, resolveContextWindow, skipIds, request);\n\t\t} catch (error) {\n\t\t\t// Admission failure does not abandon any earlier captured/accepted read.\n\t\t\tchildren.push(Promise.reject(error));\n\t\t}\n\t\tconst results = await Promise.allSettled([usageRead, ...children, diskChildren]);\n\t\tconst errors = results.flatMap((result) => (result.status === \"rejected\" ? [result.reason] : []));\n\t\tif (errors.length === 1) throw errors[0];\n\t\tif (errors.length > 1) throw new AggregateError(errors, \"Context tree reads failed\");\n\t\tconst usage = (results[0] as PromiseFulfilledResult<Awaited<typeof usageRead>>).value;\n\t\tif (!usage) throw new Error(\"Context tree usage source is unavailable\");\n\t\tconst contextUsage = estimate\n\t\t\t? usage.hasPostCompactionUsage\n\t\t\t\t? { tokens: estimate.tokens, contextWindow, percent: (estimate.tokens / contextWindow) * 100 }\n\t\t\t\t: { tokens: null, contextWindow, percent: null }\n\t\t\t: undefined;\n\t\tconst usageMetadata = {\n\t\t\townUsage: usage.ownUsage,\n\t\t\ttotalUsage: usage.totalUsage,\n\t\t\t...(usage.ownRequestUsage ? { ownRequestUsage: usage.ownRequestUsage } : {}),\n\t\t\tcontextUsage,\n\t\t};\n\t\trequest.retainMetadata({ contextUsage });\n\t\treturn {\n\t\t\t...rootNode,\n\t\t\t...usageMetadata,\n\t\t\tchildren: [\n\t\t\t\t...results.slice(1, children.length + 1).flatMap((result) => {\n\t\t\t\t\tconst node = (result as PromiseFulfilledResult<ContextTreeNode | undefined>).value;\n\t\t\t\t\treturn node ? [node] : [];\n\t\t\t\t}),\n\t\t\t\t...(results[children.length + 1] as PromiseFulfilledResult<ContextTreeNode[]>).value,\n\t\t\t],\n\t\t};\n\t}\n\n\t/**\n\t * Export session to HTML.\n\t * @param outputPath Optional output path (defaults to session directory)\n\t * @returns Path to exported file\n\t */\n\tasync exportToHtml(outputPath?: string): Promise<string> {\n\t\tconst themeName = this.settingsManager.getTheme();\n\t\tconst sourceId = this.sessionManager.getSessionId();\n\t\tconst sourceFile = this.sessionManager.getSessionFile();\n\t\tawait this.initialize();\n\t\tawait this._agentEventQueue;\n\t\tawait this._goalResumeOperation;\n\t\tawait this._waitForChildUsageWrites();\n\t\tawait this.sessionManager.flushNow();\n\t\tif (this.sessionManager.getSessionId() !== sourceId || this.sessionManager.getSessionFile() !== sourceFile) {\n\t\t\tthrow new Error(\"Session source changed during export\");\n\t\t}\n\n\t\tconst toolRenderer: ToolHtmlRenderer = createToolHtmlRenderer({\n\t\t\tgetToolDefinition: (name) => this.getToolDefinition(name),\n\t\t\ttheme,\n\t\t\tcwd: this.sessionManager.getCwd(),\n\t\t});\n\n\t\treturn await exportSessionToHtml(this.sessionManager, this.state, {\n\t\t\toutputPath,\n\t\t\tthemeName,\n\t\t\ttoolRenderer,\n\t\t});\n\t}\n\n\t/**\n\t * Export the current session branch to a JSONL file.\n\t * Writes the session header followed by all entries on the current branch path.\n\t * @param outputPath Target file path. If omitted, generates a timestamped file in cwd.\n\t * @returns The resolved output file path.\n\t */\n\tasync exportToJsonl(outputPath?: string): Promise<string> {\n\t\tconst filePath = resolve(outputPath ?? `session-${new Date().toISOString().replace(/[:.]/g, \"-\")}.jsonl`);\n\t\tconst sourceId = this.sessionManager.getSessionId();\n\t\tconst sourceFile = this.sessionManager.getSessionFile();\n\t\tawait this.initialize();\n\t\tawait this._agentEventQueue;\n\t\tawait this._goalResumeOperation;\n\t\tawait this._waitForChildUsageWrites();\n\t\tawait this.sessionManager.flushNow();\n\t\tif (this.sessionManager.getSessionId() !== sourceId || this.sessionManager.getSessionFile() !== sourceFile) {\n\t\t\tthrow new Error(\"Session source changed during export\");\n\t\t}\n\t\treturn exportSessionBranchToJsonl(this.sessionManager, filePath);\n\t}\n\n\t/**\n\t * Get text content of last assistant message.\n\t * Useful for /copy command.\n\t * @returns Text content, or undefined if no assistant message exists\n\t */\n\tgetLastAssistantText(): string | undefined {\n\t\tconst lastAssistant = this.messages\n\t\t\t.slice()\n\t\t\t.reverse()\n\t\t\t.find((m) => {\n\t\t\t\tif (m.role !== \"assistant\") return false;\n\t\t\t\tconst msg = m as AssistantMessage;\n\t\t\t\t// Skip aborted messages with no content\n\t\t\t\tif (msg.stopReason === \"aborted\" && msg.content.length === 0) return false;\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\tif (!lastAssistant) return undefined;\n\n\t\tlet text = \"\";\n\t\tfor (const content of (lastAssistant as AssistantMessage).content) {\n\t\t\tif (content.type === \"text\") {\n\t\t\t\ttext += content.text;\n\t\t\t}\n\t\t}\n\n\t\treturn text.trim() || undefined;\n\t}\n\n\t// =========================================================================\n\t// Extension System\n\t// =========================================================================\n\n\tcreateReplacedSessionContext(): ReplacedSessionContext {\n\t\tconst context = Object.defineProperties(\n\t\t\t{},\n\t\t\tObject.getOwnPropertyDescriptors(this._extensionRunner.createCommandContext()),\n\t\t) as ReplacedSessionContext;\n\t\tcontext.sendMessage = (message, options) => this.sendCustomMessage(message, options);\n\t\tcontext.sendUserMessage = (content, options) => this.sendUserMessage(content, options);\n\t\treturn context;\n\t}\n\n\thasExtensionHandlers(eventType: string): boolean {\n\t\treturn this._extensionRunner.hasHandlers(eventType);\n\t}\n\n\tget extensionRunner(): ExtensionRunner {\n\t\treturn this._extensionRunner;\n\t}\n}\n\nfunction isRlmHeartbeatStatusUpdate(value: unknown): value is AgentRlmHeartbeatStatusUpdate {\n\treturn value === \"pause\" || value === \"resume\";\n}\n\nfunction rlmHeartbeatHostResponse(job: AgentCronJob): Record<string, unknown> {\n\treturn {\n\t\tid: job.id,\n\t\tstatus: job.status,\n\t\tlabel: job.label ?? null,\n\t\tdelivery_mode: job.deliveryMode ?? \"steer\",\n\t\tinstruction: job.prompt,\n\t\tschedule: job.schedule,\n\t\tcreated_at: job.createdAt,\n\t\tupdated_at: job.updatedAt,\n\t\tnext_run_at: job.nextRunAt ?? null,\n\t\tlast_run_at: job.lastRunAt ?? null,\n\t\tlast_error: job.lastError ?? null,\n\t\trun_count: job.runCount,\n\t};\n}\n"]}
|