apex-code 0.0.1-alpha.10 → 0.0.1-alpha.11
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 +11 -0
- package/README.md +9 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +24 -5
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +26 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +77 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +7 -0
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/checkpoints/git-checkpoints.d.ts +33 -0
- package/dist/core/checkpoints/git-checkpoints.d.ts.map +1 -0
- package/dist/core/checkpoints/git-checkpoints.js +230 -0
- package/dist/core/checkpoints/git-checkpoints.js.map +1 -0
- package/dist/core/checkpoints/session-checkpoints.d.ts +23 -0
- package/dist/core/checkpoints/session-checkpoints.d.ts.map +1 -0
- package/dist/core/checkpoints/session-checkpoints.js +29 -0
- package/dist/core/checkpoints/session-checkpoints.js.map +1 -0
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +5 -2
- package/dist/core/exec.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +7 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/mcp/config.d.ts +16 -0
- package/dist/core/mcp/config.d.ts.map +1 -0
- package/dist/core/mcp/config.js +152 -0
- package/dist/core/mcp/config.js.map +1 -0
- package/dist/core/mcp/connector.d.ts +10 -0
- package/dist/core/mcp/connector.d.ts.map +1 -0
- package/dist/core/mcp/connector.js +70 -0
- package/dist/core/mcp/connector.js.map +1 -0
- package/dist/core/mcp/contract.d.ts +19 -0
- package/dist/core/mcp/contract.d.ts.map +1 -0
- package/dist/core/mcp/contract.js +89 -0
- package/dist/core/mcp/contract.js.map +1 -0
- package/dist/core/mcp/mcp-tool.d.ts +32 -0
- package/dist/core/mcp/mcp-tool.d.ts.map +1 -0
- package/dist/core/mcp/mcp-tool.js +165 -0
- package/dist/core/mcp/mcp-tool.js.map +1 -0
- package/dist/core/mcp/metadata-cache.d.ts +29 -0
- package/dist/core/mcp/metadata-cache.d.ts.map +1 -0
- package/dist/core/mcp/metadata-cache.js +99 -0
- package/dist/core/mcp/metadata-cache.js.map +1 -0
- package/dist/core/mcp/runtime.d.ts +18 -0
- package/dist/core/mcp/runtime.d.ts.map +1 -0
- package/dist/core/mcp/runtime.js +35 -0
- package/dist/core/mcp/runtime.js.map +1 -0
- package/dist/core/mcp/schema.d.ts +22 -0
- package/dist/core/mcp/schema.d.ts.map +1 -0
- package/dist/core/mcp/schema.js +20 -0
- package/dist/core/mcp/schema.js.map +1 -0
- package/dist/core/mcp/server-manager.d.ts +43 -0
- package/dist/core/mcp/server-manager.d.ts.map +1 -0
- package/dist/core/mcp/server-manager.js +142 -0
- package/dist/core/mcp/server-manager.js.map +1 -0
- package/dist/core/mcp/types.d.ts +98 -0
- package/dist/core/mcp/types.d.ts.map +1 -0
- package/dist/core/mcp/types.js +8 -0
- package/dist/core/mcp/types.js.map +1 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +14 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +13 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +30 -3
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +7 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +3 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/contract-snapshot.d.ts +58 -0
- package/dist/core/tools/contract-snapshot.d.ts.map +1 -0
- package/dist/core/tools/contract-snapshot.js +51 -0
- package/dist/core/tools/contract-snapshot.js.map +1 -0
- package/dist/core/tools/contract.d.ts +4 -2
- package/dist/core/tools/contract.d.ts.map +1 -1
- package/dist/core/tools/contract.js +4 -2
- package/dist/core/tools/contract.js.map +1 -1
- package/dist/core/tools/index.d.ts +9 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +3 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +6 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +29 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +182 -23
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +7 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +20 -0
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +8 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +29 -9
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +12 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +31 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +29 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +88 -4
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +0 -6
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +6 -4
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +2 -0
- package/docs/environment-variables.md +1 -1
- package/examples/extensions/git-checkpoint.ts +24 -36
- package/npm-shrinkwrap.json +176 -28
- package/package.json +10 -8
- package/dist/server/create-harness.d.ts +0 -26
- package/dist/server/create-harness.d.ts.map +0 -1
- package/dist/server/create-harness.js +0 -107
- package/dist/server/create-harness.js.map +0 -1
package/dist/core/sdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple } from \"@earendil-works/pi-ai/compat\";\nimport { Agent, type AgentMessage, setDefaultStreamFn, type ThinkingLevel } from \"apex-code-agent-core\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type AgentSessionConfig } from \"./agent-session.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { createAgentDefinitionResolver } from \"./delegation/agents.ts\";\nimport type { AgentDefinitionResolver, DelegationRuntimeOptions } from \"./delegation/runtime.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { ModelRuntime } from \"./model-runtime.ts\";\nimport { DerivedPermissionRuleStore } from \"./permissions/store.ts\";\nimport { mergeProviderAttributionHeaders } from \"./provider-attribution.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { ApexToolDefinition, Capability, EvidenceSink } from \"./tools/contract.ts\";\nimport {\n\tcreateAllToolDefinitions,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateDelegateToolDefinition,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreatePowerShellTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\n// Preserve the pre-0.81 fallback for extensions that construct Agent instances\n// or invoke low-level agent loops without supplying streamFn. Agent core remains\n// provider-agnostic and does not import pi-ai/compat itself.\nsetDefaultStreamFn(streamSimple);\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.apex-code/agent */\n\tagentDir?: string;\n\n\t/** Canonical model/auth runtime. Defaults to a runtime using agentDir/auth.json and models.json. */\n\tmodelRuntime?: ModelRuntime;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, pi uses the `defaultTools` setting for the initial built-in\n\t * selection when configured. Otherwise it enables the default built-in tools\n\t * (read, bash, edit, write). Extension/custom tools remain enabled unless\n\t * `noTools` changes that default. When provided, only the listed tool names are\n\t * enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/** Authorization configuration for every registered tool call. */\n\tpermissionGate?: AgentSessionConfig[\"permissionGate\"];\n\t/** Optional destination for source-level evidence; defaults to the durable session sink. */\n\tevidenceSink?: EvidenceSink;\n\t/** Optional post-mutation diagnostics injected into `edit`/`write` (LSP.4). */\n\tdiagnosticsOperations?: AgentSessionConfig[\"diagnosticsOperations\"];\n\t/** Optional `lsp` navigation tool transport (LSP.5); registers and activates `lsp` when present. */\n\tlspOperations?: AgentSessionConfig[\"lspOperations\"];\n\twebSearchOperations?: AgentSessionConfig[\"webSearchOperations\"];\n\t/**\n\t * Delegation entry point (roadmap Phase 5, ADR 0008). When set, `delegate`\n\t * executes real child sessions through `resolveAgent`, with the child's\n\t * authority derived from this session's live active tools and permission\n\t * store -- never reconstructed. When omitted, `delegate` stays inert (no agent\n\t * types resolve). Agent discovery is injected here as a caller-supplied\n\t * resolver rather than built in, until Phase 5 task 5.5 lands real\n\t * markdown/frontmatter discovery. Requires `permissionGate` to be set too: a\n\t * child's authority has nothing to derive from otherwise.\n\t */\n\tdelegation?: { resolveAgent?: AgentDefinitionResolver };\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tInlineExtension,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n\tcreatePowerShellTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@earendil-works/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\n/** The most recent assistant text in a completed session -- what a delegated child returns to its parent as its result. */\nfunction extractFinalAssistantText(session: AgentSession): string {\n\tconst messages = session.agent.state.messages;\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst message = messages[i];\n\t\tif (message.role !== \"assistant\") continue;\n\t\tconst text = message.content\n\t\t\t.filter(\n\t\t\t\t(content): content is Extract<AgentMessage, { role: \"assistant\" }>[\"content\"][number] & { type: \"text\" } =>\n\t\t\t\t\tcontent.type === \"text\",\n\t\t\t)\n\t\t\t.map((content) => content.text)\n\t\t\t.join(\"\\n\");\n\t\tif (text) return text;\n\t}\n\treturn \"\";\n}\n\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst modelRuntime = options.modelRuntime ?? (await ModelRuntime.create({ authPath, modelsPath }));\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRuntime.getModel(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRuntime.hasConfiguredAuth(restoredModel.provider)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelThinkingLevels: settingsManager.getAllModelThinkingLevels(),\n\t\t\tmodelRuntime,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to per-model override, then global default\n\tif (thinkingLevel === undefined && model) {\n\t\tconst perModel = settingsManager.getModelThinkingLevel(model.provider, model.id);\n\t\tif (perModel) {\n\t\t\tthinkingLevel = perModel;\n\t\t}\n\t}\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\t// `web_search` and `lsp` join the core four only when configured. Both stay\n\t// registered either way, so an explicit `--tools` selection still reaches them and an\n\t// unconfigured call still explains itself. Activating an unconfigured tool would put a\n\t// name in the prompt that can only ever fail.\n\tconst defaultActiveToolNames: string[] = [\n\t\t...([\"read\", \"bash\", \"edit\", \"write\"] satisfies ToolName[]),\n\t\t...(options.lspOperations ? [\"lsp\"] : []),\n\t\t...(options.webSearchOperations ? ([\"web_search\"] satisfies ToolName[]) : []),\n\t];\n\tconst configuredDefaultToolNames = settingsManager.getDefaultTools();\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames = (\n\t\toptions.tools ?? (options.noTools ? [] : (configuredDefaultToolNames ?? defaultActiveToolNames))\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n\t\t\t// SDKs treat timeout=0 as 0ms (immediate timeout), not \"no timeout\".\n\t\t\t// Use max int32 to effectively disable the timeout.\n\t\t\tconst effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n\t\t\tconst timeoutMs = options?.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs;\n\t\t\tconst websocketConnectTimeoutMs =\n\t\t\t\toptions?.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs();\n\t\t\tconst headerRunner = extensionRunnerRef.current;\n\t\t\treturn modelRuntime.streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\ttimeoutMs,\n\t\t\t\twebsocketConnectTimeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\ttransformHeaders: async (requestHeaders) => {\n\t\t\t\t\tconst headers = mergeProviderAttributionHeaders(\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tsettingsManager,\n\t\t\t\t\t\toptions?.sessionId,\n\t\t\t\t\t\trequestHeaders,\n\t\t\t\t\t);\n\t\t\t\t\treturn headerRunner?.hasHandlers(\"before_provider_headers\")\n\t\t\t\t\t\t? headerRunner.emitBeforeProviderHeaders(headers ?? {})\n\t\t\t\t\t\t: (headers ?? {});\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = existingSession.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\t// Forward ref, mirroring extensionRunnerRef above: the delegation runtime's\n\t// closures are needed to build `customTools` before `session` exists, but they\n\t// must read the *live* session (active tools can change after construction),\n\t// not a snapshot frozen at this point.\n\tconst parentSessionRef: { current?: AgentSession } = {};\n\tconst customTools: ToolDefinition[] = options.customTools ? [...options.customTools] : [];\n\t// A configured permission gate supplies the authority a child must derive, so\n\t// discovery is enabled by default in real sessions. Callers that need fixture\n\t// definitions may still provide an explicit resolver.\n\tconst delegation = options.delegation ?? (options.permissionGate ? {} : undefined);\n\tif (delegation) {\n\t\tconst parentPermissionGate = options.permissionGate;\n\t\tconst resolveAgent =\n\t\t\tdelegation.resolveAgent ??\n\t\t\tcreateAgentDefinitionResolver({\n\t\t\t\tcwd,\n\t\t\t\tagentDir,\n\t\t\t\tisProjectTrusted: () => settingsManager.isProjectTrusted(),\n\t\t\t});\n\t\tconst delegationRuntime: DelegationRuntimeOptions = {\n\t\t\tresolveAgent,\n\t\t\tgetParentCapabilities: () => {\n\t\t\t\tconst capabilities = new Set<Capability>();\n\t\t\t\tfor (const name of parentSessionRef.current?.getActiveToolNames() ?? []) {\n\t\t\t\t\tconst contract = (\n\t\t\t\t\t\tparentSessionRef.current?.getToolDefinition(name) as Partial<ApexToolDefinition> | undefined\n\t\t\t\t\t)?.contract;\n\t\t\t\t\tif (contract) for (const capability of contract.capabilities) capabilities.add(capability);\n\t\t\t\t}\n\t\t\t\treturn capabilities;\n\t\t\t},\n\t\t\tgetToolCapabilities: (toolName) => {\n\t\t\t\t// Prefer the parent's own live registry first (it also covers\n\t\t\t\t// extension/custom tools an agent definition might name), but fall back\n\t\t\t\t// to the canonical built-in registry: \"what capability does tool X\n\t\t\t\t// need\" is a property of the tool itself, independent of whether the\n\t\t\t\t// parent's own session restricted it out of its active/allowed set via\n\t\t\t\t// `tools`/`excludeTools` -- that restriction affects the parent's own\n\t\t\t\t// *authority* (getParentCapabilities, above), not what a named tool is.\n\t\t\t\tconst fromParent = (\n\t\t\t\t\tparentSessionRef.current?.getToolDefinition(toolName) as Partial<ApexToolDefinition> | undefined\n\t\t\t\t)?.contract?.capabilities;\n\t\t\t\tif (fromParent) return fromParent;\n\t\t\t\treturn (createAllToolDefinitions(cwd)[toolName as ToolName] as ApexToolDefinition | undefined)?.contract\n\t\t\t\t\t?.capabilities;\n\t\t\t},\n\t\t\t// Read fresh each call, not captured once: depth is a live property of\n\t\t\t// the (possibly delegated) session this createAgentSession call is\n\t\t\t// building, via the same sessionManager this closure already captures.\n\t\t\tgetDelegationDepth: () => sessionManager.getDelegationDepth(),\n\t\t\tmaxDelegationDepth: settingsManager.getDelegationMaxDepth(),\n\t\t\tgetParentSessionDir: () => sessionManager.getSessionDir(),\n\t\t\tbuildChildSession: async ({ definition, toolNames, depth, sessionId, artifactDir }) => {\n\t\t\t\tif (!parentPermissionGate) {\n\t\t\t\t\tthrow new Error(\"delegate requires a permission gate configured on the parent session (ADR 0008).\");\n\t\t\t\t}\n\t\t\t\tconst childModel =\n\t\t\t\t\t(definition.model && modelRuntime.getAvailableSnapshot().find((m) => m.id === definition.model)) ||\n\t\t\t\t\tmodel;\n\t\t\t\tif (!childModel) {\n\t\t\t\t\tthrow new Error(`Cannot delegate to \"${definition.name}\": no model is available for the child session.`);\n\t\t\t\t}\n\t\t\t\tconst childSessionManager = artifactDir\n\t\t\t\t\t? SessionManager.create(cwd, artifactDir, {\n\t\t\t\t\t\t\tid: sessionId,\n\t\t\t\t\t\t\tparentSession: sessionManager.getSessionId(),\n\t\t\t\t\t\t\tdelegationDepth: depth,\n\t\t\t\t\t\t})\n\t\t\t\t\t: SessionManager.inMemory(cwd, {\n\t\t\t\t\t\t\tparentSession: sessionManager.getSessionId(),\n\t\t\t\t\t\t\tdelegationDepth: depth,\n\t\t\t\t\t\t});\n\t\t\t\tconst derivedStore = new DerivedPermissionRuleStore({ parent: parentPermissionGate.store });\n\t\t\t\tconst { session: childSession } = await createAgentSession({\n\t\t\t\t\tcwd,\n\t\t\t\t\tagentDir,\n\t\t\t\t\tmodel: childModel,\n\t\t\t\t\tmodelRuntime,\n\t\t\t\t\tsettingsManager,\n\t\t\t\t\tsessionManager: childSessionManager,\n\t\t\t\t\tresourceLoader,\n\t\t\t\t\ttools: toolNames,\n\t\t\t\t\t// No responder: a child's `ask` fails closed rather than prompting the\n\t\t\t\t\t// human for a call the human did not make (ADR 0008, \"Who answers a\n\t\t\t\t\t// child's ask\").\n\t\t\t\t\tpermissionGate: { store: derivedStore, getMode: parentPermissionGate.getMode },\n\t\t\t\t\t// A delegated child shares the parent's cwd-bound LSP pool (spec, \"no\n\t\t\t\t\t// multi-root LSP connection and no sharing across cwd-bound service\n\t\t\t\t\t// lifetimes\" -- delegated children are the one sharing exception).\n\t\t\t\t\tdiagnosticsOperations: options.diagnosticsOperations,\n\t\t\t\t\tlspOperations: options.lspOperations,\n\t\t\t\t\t// Shared for the same reason as the LSP pool: the backend was resolved\n\t\t\t\t\t// once (possibly by running a shell command for the key) and a child\n\t\t\t\t\t// that re-resolved nothing would hold a `web_search` that only throws.\n\t\t\t\t\twebSearchOperations: options.webSearchOperations,\n\t\t\t\t\t// Forwarded so a child that itself holds `delegate` can delegate again\n\t\t\t\t\t// (bounded by the depth guard above, read fresh from its own session\n\t\t\t\t\t// header on its next createAgentSession call) -- otherwise recursion\n\t\t\t\t\t// would be silently capped at one level regardless of maxDelegationDepth.\n\t\t\t\t\tdelegation,\n\t\t\t\t});\n\t\t\t\tawait childSession.bindExtensions({});\n\t\t\t\treturn {\n\t\t\t\t\tasync run(task: string) {\n\t\t\t\t\t\tconst prompt = definition.systemPrompt\n\t\t\t\t\t\t\t? `${definition.systemPrompt}\\n\\nTask: ${task}`\n\t\t\t\t\t\t\t: `Task: ${task}`;\n\t\t\t\t\t\tawait childSession.prompt(prompt);\n\t\t\t\t\t\treturn { output: extractFinalAssistantText(childSession) };\n\t\t\t\t\t},\n\t\t\t\t\tdispose() {\n\t\t\t\t\t\tchildSession.dispose();\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t};\n\t\tcustomTools.push(createDelegateToolDefinition(delegationRuntime) as ToolDefinition<any, any>);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools,\n\t\tmodelRuntime,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tpermissionGate: options.permissionGate,\n\t\tevidenceSink: options.evidenceSink,\n\t\tdiagnosticsOperations: options.diagnosticsOperations,\n\t\tlspOperations: options.lspOperations,\n\t\twebSearchOperations: options.webSearchOperations,\n\t});\n\tparentSessionRef.current = session;\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple } from \"@earendil-works/pi-ai/compat\";\nimport { Agent, type AgentMessage, setDefaultStreamFn, type ThinkingLevel } from \"apex-code-agent-core\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type AgentSessionConfig } from \"./agent-session.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { createAgentDefinitionResolver } from \"./delegation/agents.ts\";\nimport type { AgentDefinitionResolver, DelegationRuntimeOptions } from \"./delegation/runtime.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { createMcpRuntime } from \"./mcp/runtime.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { ModelRuntime } from \"./model-runtime.ts\";\nimport { DerivedPermissionRuleStore } from \"./permissions/store.ts\";\nimport { mergeProviderAttributionHeaders } from \"./provider-attribution.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { ApexToolDefinition, Capability, EvidenceSink } from \"./tools/contract.ts\";\nimport {\n\tcreateAllToolDefinitions,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateDelegateToolDefinition,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreatePowerShellTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\n// Preserve the pre-0.81 fallback for extensions that construct Agent instances\n// or invoke low-level agent loops without supplying streamFn. Agent core remains\n// provider-agnostic and does not import pi-ai/compat itself.\nsetDefaultStreamFn(streamSimple);\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.apex-code/agent */\n\tagentDir?: string;\n\n\t/** Canonical model/auth runtime. Defaults to a runtime using agentDir/auth.json and models.json. */\n\tmodelRuntime?: ModelRuntime;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, pi uses the `defaultTools` setting for the initial built-in\n\t * selection when configured. Otherwise it enables the default built-in tools\n\t * (read, bash, edit, write). Extension/custom tools remain enabled unless\n\t * `noTools` changes that default. When provided, only the listed tool names are\n\t * enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/** Authorization configuration for every registered tool call. */\n\tpermissionGate?: AgentSessionConfig[\"permissionGate\"];\n\t/** Optional destination for source-level evidence; defaults to the durable session sink. */\n\tevidenceSink?: EvidenceSink;\n\t/** Optional post-mutation diagnostics injected into `edit`/`write` (LSP.4). */\n\tdiagnosticsOperations?: AgentSessionConfig[\"diagnosticsOperations\"];\n\t/** Optional `lsp` navigation tool transport (LSP.5); registers and activates `lsp` when present. */\n\tlspOperations?: AgentSessionConfig[\"lspOperations\"];\n\twebSearchOperations?: AgentSessionConfig[\"webSearchOperations\"];\n\t/**\n\t * Delegation entry point (roadmap Phase 5, ADR 0008). When set, `delegate`\n\t * executes real child sessions through `resolveAgent`, with the child's\n\t * authority derived from this session's live active tools and permission\n\t * store -- never reconstructed. When omitted, `delegate` stays inert (no agent\n\t * types resolve). Agent discovery is injected here as a caller-supplied\n\t * resolver rather than built in, until Phase 5 task 5.5 lands real\n\t * markdown/frontmatter discovery. Requires `permissionGate` to be set too: a\n\t * child's authority has nothing to derive from otherwise.\n\t */\n\tdelegation?: { resolveAgent?: AgentDefinitionResolver };\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tInlineExtension,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n\tcreatePowerShellTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@earendil-works/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\n/** The most recent assistant text in a completed session -- what a delegated child returns to its parent as its result. */\nfunction extractFinalAssistantText(session: AgentSession): string {\n\tconst messages = session.agent.state.messages;\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst message = messages[i];\n\t\tif (message.role !== \"assistant\") continue;\n\t\tconst text = message.content\n\t\t\t.filter(\n\t\t\t\t(content): content is Extract<AgentMessage, { role: \"assistant\" }>[\"content\"][number] & { type: \"text\" } =>\n\t\t\t\t\tcontent.type === \"text\",\n\t\t\t)\n\t\t\t.map((content) => content.text)\n\t\t\t.join(\"\\n\");\n\t\tif (text) return text;\n\t}\n\treturn \"\";\n}\n\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst modelRuntime = options.modelRuntime ?? (await ModelRuntime.create({ authPath, modelsPath }));\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRuntime.getModel(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRuntime.hasConfiguredAuth(restoredModel.provider)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelThinkingLevels: settingsManager.getAllModelThinkingLevels(),\n\t\t\tmodelRuntime,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to per-model override, then global default\n\tif (thinkingLevel === undefined && model) {\n\t\tconst perModel = settingsManager.getModelThinkingLevel(model.provider, model.id);\n\t\tif (perModel) {\n\t\t\tthinkingLevel = perModel;\n\t\t}\n\t}\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst mcpRuntime = createMcpRuntime(cwd);\n\n\t// `web_search`, `lsp`, and `mcp` join the core four only when configured. All stay\n\t// registered either way, so an explicit `--tools` selection still reaches them and an\n\t// unconfigured call still explains itself. Activating an unconfigured tool would put a\n\t// name in the prompt that can only ever fail.\n\tconst defaultActiveToolNames: string[] = [\n\t\t...([\"read\", \"bash\", \"edit\", \"write\"] satisfies ToolName[]),\n\t\t...(options.lspOperations ? [\"lsp\"] : []),\n\t\t...(options.webSearchOperations ? ([\"web_search\"] satisfies ToolName[]) : []),\n\t\t...(mcpRuntime ? [\"mcp\"] : []),\n\t];\n\tconst configuredDefaultToolNames = settingsManager.getDefaultTools();\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames = (\n\t\toptions.tools ?? (options.noTools ? [] : (configuredDefaultToolNames ?? defaultActiveToolNames))\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n\t\t\t// SDKs treat timeout=0 as 0ms (immediate timeout), not \"no timeout\".\n\t\t\t// Use max int32 to effectively disable the timeout.\n\t\t\tconst effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n\t\t\tconst timeoutMs = options?.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs;\n\t\t\tconst websocketConnectTimeoutMs =\n\t\t\t\toptions?.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs();\n\t\t\tconst headerRunner = extensionRunnerRef.current;\n\t\t\treturn modelRuntime.streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\ttimeoutMs,\n\t\t\t\twebsocketConnectTimeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\ttransformHeaders: async (requestHeaders) => {\n\t\t\t\t\tconst headers = mergeProviderAttributionHeaders(\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tsettingsManager,\n\t\t\t\t\t\toptions?.sessionId,\n\t\t\t\t\t\trequestHeaders,\n\t\t\t\t\t);\n\t\t\t\t\treturn headerRunner?.hasHandlers(\"before_provider_headers\")\n\t\t\t\t\t\t? headerRunner.emitBeforeProviderHeaders(headers ?? {})\n\t\t\t\t\t\t: (headers ?? {});\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = existingSession.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\t// Forward ref, mirroring extensionRunnerRef above: the delegation runtime's\n\t// closures are needed to build `customTools` before `session` exists, but they\n\t// must read the *live* session (active tools can change after construction),\n\t// not a snapshot frozen at this point.\n\tconst parentSessionRef: { current?: AgentSession } = {};\n\tconst customTools: ToolDefinition[] = options.customTools ? [...options.customTools] : [];\n\t// A configured permission gate supplies the authority a child must derive, so\n\t// discovery is enabled by default in real sessions. Callers that need fixture\n\t// definitions may still provide an explicit resolver.\n\tconst delegation = options.delegation ?? (options.permissionGate ? {} : undefined);\n\tif (delegation) {\n\t\tconst parentPermissionGate = options.permissionGate;\n\t\tconst resolveAgent =\n\t\t\tdelegation.resolveAgent ??\n\t\t\tcreateAgentDefinitionResolver({\n\t\t\t\tcwd,\n\t\t\t\tagentDir,\n\t\t\t\tisProjectTrusted: () => settingsManager.isProjectTrusted(),\n\t\t\t});\n\t\tconst delegationRuntime: DelegationRuntimeOptions = {\n\t\t\tresolveAgent,\n\t\t\tgetParentCapabilities: () => {\n\t\t\t\tconst capabilities = new Set<Capability>();\n\t\t\t\tfor (const name of parentSessionRef.current?.getActiveToolNames() ?? []) {\n\t\t\t\t\tconst contract = (\n\t\t\t\t\t\tparentSessionRef.current?.getToolDefinition(name) as Partial<ApexToolDefinition> | undefined\n\t\t\t\t\t)?.contract;\n\t\t\t\t\tif (contract) for (const capability of contract.capabilities) capabilities.add(capability);\n\t\t\t\t}\n\t\t\t\treturn capabilities;\n\t\t\t},\n\t\t\tgetToolCapabilities: (toolName) => {\n\t\t\t\t// Prefer the parent's own live registry first (it also covers\n\t\t\t\t// extension/custom tools an agent definition might name), but fall back\n\t\t\t\t// to the canonical built-in registry: \"what capability does tool X\n\t\t\t\t// need\" is a property of the tool itself, independent of whether the\n\t\t\t\t// parent's own session restricted it out of its active/allowed set via\n\t\t\t\t// `tools`/`excludeTools` -- that restriction affects the parent's own\n\t\t\t\t// *authority* (getParentCapabilities, above), not what a named tool is.\n\t\t\t\tconst fromParent = (\n\t\t\t\t\tparentSessionRef.current?.getToolDefinition(toolName) as Partial<ApexToolDefinition> | undefined\n\t\t\t\t)?.contract?.capabilities;\n\t\t\t\tif (fromParent) return fromParent;\n\t\t\t\treturn (createAllToolDefinitions(cwd)[toolName as ToolName] as ApexToolDefinition | undefined)?.contract\n\t\t\t\t\t?.capabilities;\n\t\t\t},\n\t\t\t// Read fresh each call, not captured once: depth is a live property of\n\t\t\t// the (possibly delegated) session this createAgentSession call is\n\t\t\t// building, via the same sessionManager this closure already captures.\n\t\t\tgetDelegationDepth: () => sessionManager.getDelegationDepth(),\n\t\t\tmaxDelegationDepth: settingsManager.getDelegationMaxDepth(),\n\t\t\tgetParentSessionDir: () => sessionManager.getSessionDir(),\n\t\t\tbuildChildSession: async ({ definition, toolNames, depth, sessionId, artifactDir }) => {\n\t\t\t\tif (!parentPermissionGate) {\n\t\t\t\t\tthrow new Error(\"delegate requires a permission gate configured on the parent session (ADR 0008).\");\n\t\t\t\t}\n\t\t\t\tconst childModel =\n\t\t\t\t\t(definition.model && modelRuntime.getAvailableSnapshot().find((m) => m.id === definition.model)) ||\n\t\t\t\t\tmodel;\n\t\t\t\tif (!childModel) {\n\t\t\t\t\tthrow new Error(`Cannot delegate to \"${definition.name}\": no model is available for the child session.`);\n\t\t\t\t}\n\t\t\t\tconst childSessionManager = artifactDir\n\t\t\t\t\t? SessionManager.create(cwd, artifactDir, {\n\t\t\t\t\t\t\tid: sessionId,\n\t\t\t\t\t\t\tparentSession: sessionManager.getSessionId(),\n\t\t\t\t\t\t\tdelegationDepth: depth,\n\t\t\t\t\t\t})\n\t\t\t\t\t: SessionManager.inMemory(cwd, {\n\t\t\t\t\t\t\tparentSession: sessionManager.getSessionId(),\n\t\t\t\t\t\t\tdelegationDepth: depth,\n\t\t\t\t\t\t});\n\t\t\t\tconst derivedStore = new DerivedPermissionRuleStore({ parent: parentPermissionGate.store });\n\t\t\t\tconst { session: childSession } = await createAgentSession({\n\t\t\t\t\tcwd,\n\t\t\t\t\tagentDir,\n\t\t\t\t\tmodel: childModel,\n\t\t\t\t\tmodelRuntime,\n\t\t\t\t\tsettingsManager,\n\t\t\t\t\tsessionManager: childSessionManager,\n\t\t\t\t\tresourceLoader,\n\t\t\t\t\ttools: toolNames,\n\t\t\t\t\t// No responder: a child's `ask` fails closed rather than prompting the\n\t\t\t\t\t// human for a call the human did not make (ADR 0008, \"Who answers a\n\t\t\t\t\t// child's ask\").\n\t\t\t\t\tpermissionGate: { store: derivedStore, getMode: parentPermissionGate.getMode },\n\t\t\t\t\t// A delegated child shares the parent's cwd-bound LSP pool (spec, \"no\n\t\t\t\t\t// multi-root LSP connection and no sharing across cwd-bound service\n\t\t\t\t\t// lifetimes\" -- delegated children are the one sharing exception).\n\t\t\t\t\tdiagnosticsOperations: options.diagnosticsOperations,\n\t\t\t\t\tlspOperations: options.lspOperations,\n\t\t\t\t\t// Shared for the same reason as the LSP pool: the backend was resolved\n\t\t\t\t\t// once (possibly by running a shell command for the key) and a child\n\t\t\t\t\t// that re-resolved nothing would hold a `web_search` that only throws.\n\t\t\t\t\twebSearchOperations: options.webSearchOperations,\n\t\t\t\t\t// `checkpointSettings` is deliberately *not* forwarded. A child shares the\n\t\t\t\t\t// parent's cwd, so it would write refs under its own session id into the\n\t\t\t\t\t// same repository and interleave them with the parent's. The parent's\n\t\t\t\t\t// per-turn capture already covers everything a child does inside that turn.\n\n\t\t\t\t\t// Forwarded so a child that itself holds `delegate` can delegate again\n\t\t\t\t\t// (bounded by the depth guard above, read fresh from its own session\n\t\t\t\t\t// header on its next createAgentSession call) -- otherwise recursion\n\t\t\t\t\t// would be silently capped at one level regardless of maxDelegationDepth.\n\t\t\t\t\tdelegation,\n\t\t\t\t});\n\t\t\t\tawait childSession.bindExtensions({});\n\t\t\t\treturn {\n\t\t\t\t\tasync run(task: string) {\n\t\t\t\t\t\tconst prompt = definition.systemPrompt\n\t\t\t\t\t\t\t? `${definition.systemPrompt}\\n\\nTask: ${task}`\n\t\t\t\t\t\t\t: `Task: ${task}`;\n\t\t\t\t\t\tawait childSession.prompt(prompt);\n\t\t\t\t\t\treturn { output: extractFinalAssistantText(childSession) };\n\t\t\t\t\t},\n\t\t\t\t\tdispose() {\n\t\t\t\t\t\tchildSession.dispose();\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t};\n\t\tcustomTools.push(createDelegateToolDefinition(delegationRuntime) as ToolDefinition<any, any>);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools,\n\t\tmodelRuntime,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tpermissionGate: options.permissionGate,\n\t\tevidenceSink: options.evidenceSink,\n\t\tdiagnosticsOperations: options.diagnosticsOperations,\n\t\tlspOperations: options.lspOperations,\n\t\twebSearchOperations: options.webSearchOperations,\n\t\tmcpRuntime,\n\t\tcheckpointSettings: settingsManager.getCheckpointSettings(),\n\t});\n\tparentSessionRef.current = session;\n\t// Eager servers connect here rather than on first use, so their tools are in the\n\t// cache before the model's first search. Detached: a slow or broken server delays\n\t// nothing, and `warmEagerServers` already swallows its own failures.\n\tvoid mcpRuntime?.warm();\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
|
package/dist/core/sdk.js
CHANGED
|
@@ -7,6 +7,7 @@ import { AgentSession } from "./agent-session.js";
|
|
|
7
7
|
import { formatNoModelsAvailableMessage } from "./auth-guidance.js";
|
|
8
8
|
import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
|
|
9
9
|
import { createAgentDefinitionResolver } from "./delegation/agents.js";
|
|
10
|
+
import { createMcpRuntime } from "./mcp/runtime.js";
|
|
10
11
|
import { convertToLlm } from "./messages.js";
|
|
11
12
|
import { findInitialModel } from "./model-resolver.js";
|
|
12
13
|
import { ModelRuntime } from "./model-runtime.js";
|
|
@@ -154,7 +155,8 @@ export async function createAgentSession(options = {}) {
|
|
|
154
155
|
else {
|
|
155
156
|
thinkingLevel = clampThinkingLevel(model, thinkingLevel);
|
|
156
157
|
}
|
|
157
|
-
|
|
158
|
+
const mcpRuntime = createMcpRuntime(cwd);
|
|
159
|
+
// `web_search`, `lsp`, and `mcp` join the core four only when configured. All stay
|
|
158
160
|
// registered either way, so an explicit `--tools` selection still reaches them and an
|
|
159
161
|
// unconfigured call still explains itself. Activating an unconfigured tool would put a
|
|
160
162
|
// name in the prompt that can only ever fail.
|
|
@@ -162,6 +164,7 @@ export async function createAgentSession(options = {}) {
|
|
|
162
164
|
...["read", "bash", "edit", "write"],
|
|
163
165
|
...(options.lspOperations ? ["lsp"] : []),
|
|
164
166
|
...(options.webSearchOperations ? ["web_search"] : []),
|
|
167
|
+
...(mcpRuntime ? ["mcp"] : []),
|
|
165
168
|
];
|
|
166
169
|
const configuredDefaultToolNames = settingsManager.getDefaultTools();
|
|
167
170
|
const allowedToolNames = options.tools ?? (options.noTools === "all" ? [] : undefined);
|
|
@@ -368,6 +371,10 @@ export async function createAgentSession(options = {}) {
|
|
|
368
371
|
// once (possibly by running a shell command for the key) and a child
|
|
369
372
|
// that re-resolved nothing would hold a `web_search` that only throws.
|
|
370
373
|
webSearchOperations: options.webSearchOperations,
|
|
374
|
+
// `checkpointSettings` is deliberately *not* forwarded. A child shares the
|
|
375
|
+
// parent's cwd, so it would write refs under its own session id into the
|
|
376
|
+
// same repository and interleave them with the parent's. The parent's
|
|
377
|
+
// per-turn capture already covers everything a child does inside that turn.
|
|
371
378
|
// Forwarded so a child that itself holds `delegate` can delegate again
|
|
372
379
|
// (bounded by the depth guard above, read fresh from its own session
|
|
373
380
|
// header on its next createAgentSession call) -- otherwise recursion
|
|
@@ -410,8 +417,14 @@ export async function createAgentSession(options = {}) {
|
|
|
410
417
|
diagnosticsOperations: options.diagnosticsOperations,
|
|
411
418
|
lspOperations: options.lspOperations,
|
|
412
419
|
webSearchOperations: options.webSearchOperations,
|
|
420
|
+
mcpRuntime,
|
|
421
|
+
checkpointSettings: settingsManager.getCheckpointSettings(),
|
|
413
422
|
});
|
|
414
423
|
parentSessionRef.current = session;
|
|
424
|
+
// Eager servers connect here rather than on first use, so their tools are in the
|
|
425
|
+
// cache before the model's first search. Detached: a slow or broken server delays
|
|
426
|
+
// nothing, and `warmEagerServers` already swallows its own failures.
|
|
427
|
+
void mcpRuntime?.warm();
|
|
415
428
|
const extensionsResult = resourceLoader.getExtensions();
|
|
416
429
|
return {
|
|
417
430
|
session,
|
package/dist/core/sdk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple } from \"@earendil-works/pi-ai/compat\";\nimport { Agent, type AgentMessage, setDefaultStreamFn, type ThinkingLevel } from \"apex-code-agent-core\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type AgentSessionConfig } from \"./agent-session.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { createAgentDefinitionResolver } from \"./delegation/agents.ts\";\nimport type { AgentDefinitionResolver, DelegationRuntimeOptions } from \"./delegation/runtime.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { ModelRuntime } from \"./model-runtime.ts\";\nimport { DerivedPermissionRuleStore } from \"./permissions/store.ts\";\nimport { mergeProviderAttributionHeaders } from \"./provider-attribution.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { ApexToolDefinition, Capability, EvidenceSink } from \"./tools/contract.ts\";\nimport {\n\tcreateAllToolDefinitions,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateDelegateToolDefinition,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreatePowerShellTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\n// Preserve the pre-0.81 fallback for extensions that construct Agent instances\n// or invoke low-level agent loops without supplying streamFn. Agent core remains\n// provider-agnostic and does not import pi-ai/compat itself.\nsetDefaultStreamFn(streamSimple);\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.apex-code/agent */\n\tagentDir?: string;\n\n\t/** Canonical model/auth runtime. Defaults to a runtime using agentDir/auth.json and models.json. */\n\tmodelRuntime?: ModelRuntime;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, pi uses the `defaultTools` setting for the initial built-in\n\t * selection when configured. Otherwise it enables the default built-in tools\n\t * (read, bash, edit, write). Extension/custom tools remain enabled unless\n\t * `noTools` changes that default. When provided, only the listed tool names are\n\t * enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/** Authorization configuration for every registered tool call. */\n\tpermissionGate?: AgentSessionConfig[\"permissionGate\"];\n\t/** Optional destination for source-level evidence; defaults to the durable session sink. */\n\tevidenceSink?: EvidenceSink;\n\t/** Optional post-mutation diagnostics injected into `edit`/`write` (LSP.4). */\n\tdiagnosticsOperations?: AgentSessionConfig[\"diagnosticsOperations\"];\n\t/** Optional `lsp` navigation tool transport (LSP.5); registers and activates `lsp` when present. */\n\tlspOperations?: AgentSessionConfig[\"lspOperations\"];\n\twebSearchOperations?: AgentSessionConfig[\"webSearchOperations\"];\n\t/**\n\t * Delegation entry point (roadmap Phase 5, ADR 0008). When set, `delegate`\n\t * executes real child sessions through `resolveAgent`, with the child's\n\t * authority derived from this session's live active tools and permission\n\t * store -- never reconstructed. When omitted, `delegate` stays inert (no agent\n\t * types resolve). Agent discovery is injected here as a caller-supplied\n\t * resolver rather than built in, until Phase 5 task 5.5 lands real\n\t * markdown/frontmatter discovery. Requires `permissionGate` to be set too: a\n\t * child's authority has nothing to derive from otherwise.\n\t */\n\tdelegation?: { resolveAgent?: AgentDefinitionResolver };\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tInlineExtension,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n\tcreatePowerShellTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@earendil-works/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\n/** The most recent assistant text in a completed session -- what a delegated child returns to its parent as its result. */\nfunction extractFinalAssistantText(session: AgentSession): string {\n\tconst messages = session.agent.state.messages;\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst message = messages[i];\n\t\tif (message.role !== \"assistant\") continue;\n\t\tconst text = message.content\n\t\t\t.filter(\n\t\t\t\t(content): content is Extract<AgentMessage, { role: \"assistant\" }>[\"content\"][number] & { type: \"text\" } =>\n\t\t\t\t\tcontent.type === \"text\",\n\t\t\t)\n\t\t\t.map((content) => content.text)\n\t\t\t.join(\"\\n\");\n\t\tif (text) return text;\n\t}\n\treturn \"\";\n}\n\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst modelRuntime = options.modelRuntime ?? (await ModelRuntime.create({ authPath, modelsPath }));\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRuntime.getModel(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRuntime.hasConfiguredAuth(restoredModel.provider)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelThinkingLevels: settingsManager.getAllModelThinkingLevels(),\n\t\t\tmodelRuntime,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to per-model override, then global default\n\tif (thinkingLevel === undefined && model) {\n\t\tconst perModel = settingsManager.getModelThinkingLevel(model.provider, model.id);\n\t\tif (perModel) {\n\t\t\tthinkingLevel = perModel;\n\t\t}\n\t}\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\t// `web_search` and `lsp` join the core four only when configured. Both stay\n\t// registered either way, so an explicit `--tools` selection still reaches them and an\n\t// unconfigured call still explains itself. Activating an unconfigured tool would put a\n\t// name in the prompt that can only ever fail.\n\tconst defaultActiveToolNames: string[] = [\n\t\t...([\"read\", \"bash\", \"edit\", \"write\"] satisfies ToolName[]),\n\t\t...(options.lspOperations ? [\"lsp\"] : []),\n\t\t...(options.webSearchOperations ? ([\"web_search\"] satisfies ToolName[]) : []),\n\t];\n\tconst configuredDefaultToolNames = settingsManager.getDefaultTools();\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames = (\n\t\toptions.tools ?? (options.noTools ? [] : (configuredDefaultToolNames ?? defaultActiveToolNames))\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n\t\t\t// SDKs treat timeout=0 as 0ms (immediate timeout), not \"no timeout\".\n\t\t\t// Use max int32 to effectively disable the timeout.\n\t\t\tconst effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n\t\t\tconst timeoutMs = options?.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs;\n\t\t\tconst websocketConnectTimeoutMs =\n\t\t\t\toptions?.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs();\n\t\t\tconst headerRunner = extensionRunnerRef.current;\n\t\t\treturn modelRuntime.streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\ttimeoutMs,\n\t\t\t\twebsocketConnectTimeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\ttransformHeaders: async (requestHeaders) => {\n\t\t\t\t\tconst headers = mergeProviderAttributionHeaders(\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tsettingsManager,\n\t\t\t\t\t\toptions?.sessionId,\n\t\t\t\t\t\trequestHeaders,\n\t\t\t\t\t);\n\t\t\t\t\treturn headerRunner?.hasHandlers(\"before_provider_headers\")\n\t\t\t\t\t\t? headerRunner.emitBeforeProviderHeaders(headers ?? {})\n\t\t\t\t\t\t: (headers ?? {});\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = existingSession.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\t// Forward ref, mirroring extensionRunnerRef above: the delegation runtime's\n\t// closures are needed to build `customTools` before `session` exists, but they\n\t// must read the *live* session (active tools can change after construction),\n\t// not a snapshot frozen at this point.\n\tconst parentSessionRef: { current?: AgentSession } = {};\n\tconst customTools: ToolDefinition[] = options.customTools ? [...options.customTools] : [];\n\t// A configured permission gate supplies the authority a child must derive, so\n\t// discovery is enabled by default in real sessions. Callers that need fixture\n\t// definitions may still provide an explicit resolver.\n\tconst delegation = options.delegation ?? (options.permissionGate ? {} : undefined);\n\tif (delegation) {\n\t\tconst parentPermissionGate = options.permissionGate;\n\t\tconst resolveAgent =\n\t\t\tdelegation.resolveAgent ??\n\t\t\tcreateAgentDefinitionResolver({\n\t\t\t\tcwd,\n\t\t\t\tagentDir,\n\t\t\t\tisProjectTrusted: () => settingsManager.isProjectTrusted(),\n\t\t\t});\n\t\tconst delegationRuntime: DelegationRuntimeOptions = {\n\t\t\tresolveAgent,\n\t\t\tgetParentCapabilities: () => {\n\t\t\t\tconst capabilities = new Set<Capability>();\n\t\t\t\tfor (const name of parentSessionRef.current?.getActiveToolNames() ?? []) {\n\t\t\t\t\tconst contract = (\n\t\t\t\t\t\tparentSessionRef.current?.getToolDefinition(name) as Partial<ApexToolDefinition> | undefined\n\t\t\t\t\t)?.contract;\n\t\t\t\t\tif (contract) for (const capability of contract.capabilities) capabilities.add(capability);\n\t\t\t\t}\n\t\t\t\treturn capabilities;\n\t\t\t},\n\t\t\tgetToolCapabilities: (toolName) => {\n\t\t\t\t// Prefer the parent's own live registry first (it also covers\n\t\t\t\t// extension/custom tools an agent definition might name), but fall back\n\t\t\t\t// to the canonical built-in registry: \"what capability does tool X\n\t\t\t\t// need\" is a property of the tool itself, independent of whether the\n\t\t\t\t// parent's own session restricted it out of its active/allowed set via\n\t\t\t\t// `tools`/`excludeTools` -- that restriction affects the parent's own\n\t\t\t\t// *authority* (getParentCapabilities, above), not what a named tool is.\n\t\t\t\tconst fromParent = (\n\t\t\t\t\tparentSessionRef.current?.getToolDefinition(toolName) as Partial<ApexToolDefinition> | undefined\n\t\t\t\t)?.contract?.capabilities;\n\t\t\t\tif (fromParent) return fromParent;\n\t\t\t\treturn (createAllToolDefinitions(cwd)[toolName as ToolName] as ApexToolDefinition | undefined)?.contract\n\t\t\t\t\t?.capabilities;\n\t\t\t},\n\t\t\t// Read fresh each call, not captured once: depth is a live property of\n\t\t\t// the (possibly delegated) session this createAgentSession call is\n\t\t\t// building, via the same sessionManager this closure already captures.\n\t\t\tgetDelegationDepth: () => sessionManager.getDelegationDepth(),\n\t\t\tmaxDelegationDepth: settingsManager.getDelegationMaxDepth(),\n\t\t\tgetParentSessionDir: () => sessionManager.getSessionDir(),\n\t\t\tbuildChildSession: async ({ definition, toolNames, depth, sessionId, artifactDir }) => {\n\t\t\t\tif (!parentPermissionGate) {\n\t\t\t\t\tthrow new Error(\"delegate requires a permission gate configured on the parent session (ADR 0008).\");\n\t\t\t\t}\n\t\t\t\tconst childModel =\n\t\t\t\t\t(definition.model && modelRuntime.getAvailableSnapshot().find((m) => m.id === definition.model)) ||\n\t\t\t\t\tmodel;\n\t\t\t\tif (!childModel) {\n\t\t\t\t\tthrow new Error(`Cannot delegate to \"${definition.name}\": no model is available for the child session.`);\n\t\t\t\t}\n\t\t\t\tconst childSessionManager = artifactDir\n\t\t\t\t\t? SessionManager.create(cwd, artifactDir, {\n\t\t\t\t\t\t\tid: sessionId,\n\t\t\t\t\t\t\tparentSession: sessionManager.getSessionId(),\n\t\t\t\t\t\t\tdelegationDepth: depth,\n\t\t\t\t\t\t})\n\t\t\t\t\t: SessionManager.inMemory(cwd, {\n\t\t\t\t\t\t\tparentSession: sessionManager.getSessionId(),\n\t\t\t\t\t\t\tdelegationDepth: depth,\n\t\t\t\t\t\t});\n\t\t\t\tconst derivedStore = new DerivedPermissionRuleStore({ parent: parentPermissionGate.store });\n\t\t\t\tconst { session: childSession } = await createAgentSession({\n\t\t\t\t\tcwd,\n\t\t\t\t\tagentDir,\n\t\t\t\t\tmodel: childModel,\n\t\t\t\t\tmodelRuntime,\n\t\t\t\t\tsettingsManager,\n\t\t\t\t\tsessionManager: childSessionManager,\n\t\t\t\t\tresourceLoader,\n\t\t\t\t\ttools: toolNames,\n\t\t\t\t\t// No responder: a child's `ask` fails closed rather than prompting the\n\t\t\t\t\t// human for a call the human did not make (ADR 0008, \"Who answers a\n\t\t\t\t\t// child's ask\").\n\t\t\t\t\tpermissionGate: { store: derivedStore, getMode: parentPermissionGate.getMode },\n\t\t\t\t\t// A delegated child shares the parent's cwd-bound LSP pool (spec, \"no\n\t\t\t\t\t// multi-root LSP connection and no sharing across cwd-bound service\n\t\t\t\t\t// lifetimes\" -- delegated children are the one sharing exception).\n\t\t\t\t\tdiagnosticsOperations: options.diagnosticsOperations,\n\t\t\t\t\tlspOperations: options.lspOperations,\n\t\t\t\t\t// Shared for the same reason as the LSP pool: the backend was resolved\n\t\t\t\t\t// once (possibly by running a shell command for the key) and a child\n\t\t\t\t\t// that re-resolved nothing would hold a `web_search` that only throws.\n\t\t\t\t\twebSearchOperations: options.webSearchOperations,\n\t\t\t\t\t// Forwarded so a child that itself holds `delegate` can delegate again\n\t\t\t\t\t// (bounded by the depth guard above, read fresh from its own session\n\t\t\t\t\t// header on its next createAgentSession call) -- otherwise recursion\n\t\t\t\t\t// would be silently capped at one level regardless of maxDelegationDepth.\n\t\t\t\t\tdelegation,\n\t\t\t\t});\n\t\t\t\tawait childSession.bindExtensions({});\n\t\t\t\treturn {\n\t\t\t\t\tasync run(task: string) {\n\t\t\t\t\t\tconst prompt = definition.systemPrompt\n\t\t\t\t\t\t\t? `${definition.systemPrompt}\\n\\nTask: ${task}`\n\t\t\t\t\t\t\t: `Task: ${task}`;\n\t\t\t\t\t\tawait childSession.prompt(prompt);\n\t\t\t\t\t\treturn { output: extractFinalAssistantText(childSession) };\n\t\t\t\t\t},\n\t\t\t\t\tdispose() {\n\t\t\t\t\t\tchildSession.dispose();\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t};\n\t\tcustomTools.push(createDelegateToolDefinition(delegationRuntime) as ToolDefinition<any, any>);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools,\n\t\tmodelRuntime,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tpermissionGate: options.permissionGate,\n\t\tevidenceSink: options.evidenceSink,\n\t\tdiagnosticsOperations: options.diagnosticsOperations,\n\t\tlspOperations: options.lspOperations,\n\t\twebSearchOperations: options.webSearchOperations,\n\t});\n\tparentSessionRef.current = session;\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple } from \"@earendil-works/pi-ai/compat\";\nimport { Agent, type AgentMessage, setDefaultStreamFn, type ThinkingLevel } from \"apex-code-agent-core\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type AgentSessionConfig } from \"./agent-session.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { createAgentDefinitionResolver } from \"./delegation/agents.ts\";\nimport type { AgentDefinitionResolver, DelegationRuntimeOptions } from \"./delegation/runtime.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { createMcpRuntime } from \"./mcp/runtime.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { ModelRuntime } from \"./model-runtime.ts\";\nimport { DerivedPermissionRuleStore } from \"./permissions/store.ts\";\nimport { mergeProviderAttributionHeaders } from \"./provider-attribution.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { ApexToolDefinition, Capability, EvidenceSink } from \"./tools/contract.ts\";\nimport {\n\tcreateAllToolDefinitions,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateDelegateToolDefinition,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreatePowerShellTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\n// Preserve the pre-0.81 fallback for extensions that construct Agent instances\n// or invoke low-level agent loops without supplying streamFn. Agent core remains\n// provider-agnostic and does not import pi-ai/compat itself.\nsetDefaultStreamFn(streamSimple);\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.apex-code/agent */\n\tagentDir?: string;\n\n\t/** Canonical model/auth runtime. Defaults to a runtime using agentDir/auth.json and models.json. */\n\tmodelRuntime?: ModelRuntime;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, pi uses the `defaultTools` setting for the initial built-in\n\t * selection when configured. Otherwise it enables the default built-in tools\n\t * (read, bash, edit, write). Extension/custom tools remain enabled unless\n\t * `noTools` changes that default. When provided, only the listed tool names are\n\t * enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/** Authorization configuration for every registered tool call. */\n\tpermissionGate?: AgentSessionConfig[\"permissionGate\"];\n\t/** Optional destination for source-level evidence; defaults to the durable session sink. */\n\tevidenceSink?: EvidenceSink;\n\t/** Optional post-mutation diagnostics injected into `edit`/`write` (LSP.4). */\n\tdiagnosticsOperations?: AgentSessionConfig[\"diagnosticsOperations\"];\n\t/** Optional `lsp` navigation tool transport (LSP.5); registers and activates `lsp` when present. */\n\tlspOperations?: AgentSessionConfig[\"lspOperations\"];\n\twebSearchOperations?: AgentSessionConfig[\"webSearchOperations\"];\n\t/**\n\t * Delegation entry point (roadmap Phase 5, ADR 0008). When set, `delegate`\n\t * executes real child sessions through `resolveAgent`, with the child's\n\t * authority derived from this session's live active tools and permission\n\t * store -- never reconstructed. When omitted, `delegate` stays inert (no agent\n\t * types resolve). Agent discovery is injected here as a caller-supplied\n\t * resolver rather than built in, until Phase 5 task 5.5 lands real\n\t * markdown/frontmatter discovery. Requires `permissionGate` to be set too: a\n\t * child's authority has nothing to derive from otherwise.\n\t */\n\tdelegation?: { resolveAgent?: AgentDefinitionResolver };\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tInlineExtension,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n\tcreatePowerShellTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@earendil-works/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\n/** The most recent assistant text in a completed session -- what a delegated child returns to its parent as its result. */\nfunction extractFinalAssistantText(session: AgentSession): string {\n\tconst messages = session.agent.state.messages;\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst message = messages[i];\n\t\tif (message.role !== \"assistant\") continue;\n\t\tconst text = message.content\n\t\t\t.filter(\n\t\t\t\t(content): content is Extract<AgentMessage, { role: \"assistant\" }>[\"content\"][number] & { type: \"text\" } =>\n\t\t\t\t\tcontent.type === \"text\",\n\t\t\t)\n\t\t\t.map((content) => content.text)\n\t\t\t.join(\"\\n\");\n\t\tif (text) return text;\n\t}\n\treturn \"\";\n}\n\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst modelRuntime = options.modelRuntime ?? (await ModelRuntime.create({ authPath, modelsPath }));\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRuntime.getModel(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRuntime.hasConfiguredAuth(restoredModel.provider)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelThinkingLevels: settingsManager.getAllModelThinkingLevels(),\n\t\t\tmodelRuntime,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to per-model override, then global default\n\tif (thinkingLevel === undefined && model) {\n\t\tconst perModel = settingsManager.getModelThinkingLevel(model.provider, model.id);\n\t\tif (perModel) {\n\t\t\tthinkingLevel = perModel;\n\t\t}\n\t}\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst mcpRuntime = createMcpRuntime(cwd);\n\n\t// `web_search`, `lsp`, and `mcp` join the core four only when configured. All stay\n\t// registered either way, so an explicit `--tools` selection still reaches them and an\n\t// unconfigured call still explains itself. Activating an unconfigured tool would put a\n\t// name in the prompt that can only ever fail.\n\tconst defaultActiveToolNames: string[] = [\n\t\t...([\"read\", \"bash\", \"edit\", \"write\"] satisfies ToolName[]),\n\t\t...(options.lspOperations ? [\"lsp\"] : []),\n\t\t...(options.webSearchOperations ? ([\"web_search\"] satisfies ToolName[]) : []),\n\t\t...(mcpRuntime ? [\"mcp\"] : []),\n\t];\n\tconst configuredDefaultToolNames = settingsManager.getDefaultTools();\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames = (\n\t\toptions.tools ?? (options.noTools ? [] : (configuredDefaultToolNames ?? defaultActiveToolNames))\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n\t\t\t// SDKs treat timeout=0 as 0ms (immediate timeout), not \"no timeout\".\n\t\t\t// Use max int32 to effectively disable the timeout.\n\t\t\tconst effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n\t\t\tconst timeoutMs = options?.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs;\n\t\t\tconst websocketConnectTimeoutMs =\n\t\t\t\toptions?.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs();\n\t\t\tconst headerRunner = extensionRunnerRef.current;\n\t\t\treturn modelRuntime.streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\ttimeoutMs,\n\t\t\t\twebsocketConnectTimeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\ttransformHeaders: async (requestHeaders) => {\n\t\t\t\t\tconst headers = mergeProviderAttributionHeaders(\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tsettingsManager,\n\t\t\t\t\t\toptions?.sessionId,\n\t\t\t\t\t\trequestHeaders,\n\t\t\t\t\t);\n\t\t\t\t\treturn headerRunner?.hasHandlers(\"before_provider_headers\")\n\t\t\t\t\t\t? headerRunner.emitBeforeProviderHeaders(headers ?? {})\n\t\t\t\t\t\t: (headers ?? {});\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = existingSession.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\t// Forward ref, mirroring extensionRunnerRef above: the delegation runtime's\n\t// closures are needed to build `customTools` before `session` exists, but they\n\t// must read the *live* session (active tools can change after construction),\n\t// not a snapshot frozen at this point.\n\tconst parentSessionRef: { current?: AgentSession } = {};\n\tconst customTools: ToolDefinition[] = options.customTools ? [...options.customTools] : [];\n\t// A configured permission gate supplies the authority a child must derive, so\n\t// discovery is enabled by default in real sessions. Callers that need fixture\n\t// definitions may still provide an explicit resolver.\n\tconst delegation = options.delegation ?? (options.permissionGate ? {} : undefined);\n\tif (delegation) {\n\t\tconst parentPermissionGate = options.permissionGate;\n\t\tconst resolveAgent =\n\t\t\tdelegation.resolveAgent ??\n\t\t\tcreateAgentDefinitionResolver({\n\t\t\t\tcwd,\n\t\t\t\tagentDir,\n\t\t\t\tisProjectTrusted: () => settingsManager.isProjectTrusted(),\n\t\t\t});\n\t\tconst delegationRuntime: DelegationRuntimeOptions = {\n\t\t\tresolveAgent,\n\t\t\tgetParentCapabilities: () => {\n\t\t\t\tconst capabilities = new Set<Capability>();\n\t\t\t\tfor (const name of parentSessionRef.current?.getActiveToolNames() ?? []) {\n\t\t\t\t\tconst contract = (\n\t\t\t\t\t\tparentSessionRef.current?.getToolDefinition(name) as Partial<ApexToolDefinition> | undefined\n\t\t\t\t\t)?.contract;\n\t\t\t\t\tif (contract) for (const capability of contract.capabilities) capabilities.add(capability);\n\t\t\t\t}\n\t\t\t\treturn capabilities;\n\t\t\t},\n\t\t\tgetToolCapabilities: (toolName) => {\n\t\t\t\t// Prefer the parent's own live registry first (it also covers\n\t\t\t\t// extension/custom tools an agent definition might name), but fall back\n\t\t\t\t// to the canonical built-in registry: \"what capability does tool X\n\t\t\t\t// need\" is a property of the tool itself, independent of whether the\n\t\t\t\t// parent's own session restricted it out of its active/allowed set via\n\t\t\t\t// `tools`/`excludeTools` -- that restriction affects the parent's own\n\t\t\t\t// *authority* (getParentCapabilities, above), not what a named tool is.\n\t\t\t\tconst fromParent = (\n\t\t\t\t\tparentSessionRef.current?.getToolDefinition(toolName) as Partial<ApexToolDefinition> | undefined\n\t\t\t\t)?.contract?.capabilities;\n\t\t\t\tif (fromParent) return fromParent;\n\t\t\t\treturn (createAllToolDefinitions(cwd)[toolName as ToolName] as ApexToolDefinition | undefined)?.contract\n\t\t\t\t\t?.capabilities;\n\t\t\t},\n\t\t\t// Read fresh each call, not captured once: depth is a live property of\n\t\t\t// the (possibly delegated) session this createAgentSession call is\n\t\t\t// building, via the same sessionManager this closure already captures.\n\t\t\tgetDelegationDepth: () => sessionManager.getDelegationDepth(),\n\t\t\tmaxDelegationDepth: settingsManager.getDelegationMaxDepth(),\n\t\t\tgetParentSessionDir: () => sessionManager.getSessionDir(),\n\t\t\tbuildChildSession: async ({ definition, toolNames, depth, sessionId, artifactDir }) => {\n\t\t\t\tif (!parentPermissionGate) {\n\t\t\t\t\tthrow new Error(\"delegate requires a permission gate configured on the parent session (ADR 0008).\");\n\t\t\t\t}\n\t\t\t\tconst childModel =\n\t\t\t\t\t(definition.model && modelRuntime.getAvailableSnapshot().find((m) => m.id === definition.model)) ||\n\t\t\t\t\tmodel;\n\t\t\t\tif (!childModel) {\n\t\t\t\t\tthrow new Error(`Cannot delegate to \"${definition.name}\": no model is available for the child session.`);\n\t\t\t\t}\n\t\t\t\tconst childSessionManager = artifactDir\n\t\t\t\t\t? SessionManager.create(cwd, artifactDir, {\n\t\t\t\t\t\t\tid: sessionId,\n\t\t\t\t\t\t\tparentSession: sessionManager.getSessionId(),\n\t\t\t\t\t\t\tdelegationDepth: depth,\n\t\t\t\t\t\t})\n\t\t\t\t\t: SessionManager.inMemory(cwd, {\n\t\t\t\t\t\t\tparentSession: sessionManager.getSessionId(),\n\t\t\t\t\t\t\tdelegationDepth: depth,\n\t\t\t\t\t\t});\n\t\t\t\tconst derivedStore = new DerivedPermissionRuleStore({ parent: parentPermissionGate.store });\n\t\t\t\tconst { session: childSession } = await createAgentSession({\n\t\t\t\t\tcwd,\n\t\t\t\t\tagentDir,\n\t\t\t\t\tmodel: childModel,\n\t\t\t\t\tmodelRuntime,\n\t\t\t\t\tsettingsManager,\n\t\t\t\t\tsessionManager: childSessionManager,\n\t\t\t\t\tresourceLoader,\n\t\t\t\t\ttools: toolNames,\n\t\t\t\t\t// No responder: a child's `ask` fails closed rather than prompting the\n\t\t\t\t\t// human for a call the human did not make (ADR 0008, \"Who answers a\n\t\t\t\t\t// child's ask\").\n\t\t\t\t\tpermissionGate: { store: derivedStore, getMode: parentPermissionGate.getMode },\n\t\t\t\t\t// A delegated child shares the parent's cwd-bound LSP pool (spec, \"no\n\t\t\t\t\t// multi-root LSP connection and no sharing across cwd-bound service\n\t\t\t\t\t// lifetimes\" -- delegated children are the one sharing exception).\n\t\t\t\t\tdiagnosticsOperations: options.diagnosticsOperations,\n\t\t\t\t\tlspOperations: options.lspOperations,\n\t\t\t\t\t// Shared for the same reason as the LSP pool: the backend was resolved\n\t\t\t\t\t// once (possibly by running a shell command for the key) and a child\n\t\t\t\t\t// that re-resolved nothing would hold a `web_search` that only throws.\n\t\t\t\t\twebSearchOperations: options.webSearchOperations,\n\t\t\t\t\t// `checkpointSettings` is deliberately *not* forwarded. A child shares the\n\t\t\t\t\t// parent's cwd, so it would write refs under its own session id into the\n\t\t\t\t\t// same repository and interleave them with the parent's. The parent's\n\t\t\t\t\t// per-turn capture already covers everything a child does inside that turn.\n\n\t\t\t\t\t// Forwarded so a child that itself holds `delegate` can delegate again\n\t\t\t\t\t// (bounded by the depth guard above, read fresh from its own session\n\t\t\t\t\t// header on its next createAgentSession call) -- otherwise recursion\n\t\t\t\t\t// would be silently capped at one level regardless of maxDelegationDepth.\n\t\t\t\t\tdelegation,\n\t\t\t\t});\n\t\t\t\tawait childSession.bindExtensions({});\n\t\t\t\treturn {\n\t\t\t\t\tasync run(task: string) {\n\t\t\t\t\t\tconst prompt = definition.systemPrompt\n\t\t\t\t\t\t\t? `${definition.systemPrompt}\\n\\nTask: ${task}`\n\t\t\t\t\t\t\t: `Task: ${task}`;\n\t\t\t\t\t\tawait childSession.prompt(prompt);\n\t\t\t\t\t\treturn { output: extractFinalAssistantText(childSession) };\n\t\t\t\t\t},\n\t\t\t\t\tdispose() {\n\t\t\t\t\t\tchildSession.dispose();\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t};\n\t\tcustomTools.push(createDelegateToolDefinition(delegationRuntime) as ToolDefinition<any, any>);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools,\n\t\tmodelRuntime,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tpermissionGate: options.permissionGate,\n\t\tevidenceSink: options.evidenceSink,\n\t\tdiagnosticsOperations: options.diagnosticsOperations,\n\t\tlspOperations: options.lspOperations,\n\t\twebSearchOperations: options.webSearchOperations,\n\t\tmcpRuntime,\n\t\tcheckpointSettings: settingsManager.getCheckpointSettings(),\n\t});\n\tparentSessionRef.current = session;\n\t// Eager servers connect here rather than on first use, so their tools are in the\n\t// cache before the model's first search. Detached: a slow or broken server delays\n\t// nothing, and `warmEagerServers` already swallows its own failures.\n\tvoid mcpRuntime?.warm();\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
|
|
@@ -160,7 +160,7 @@ export interface SessionInfo {
|
|
|
160
160
|
firstMessage: string;
|
|
161
161
|
allMessagesText: string;
|
|
162
162
|
}
|
|
163
|
-
export type ReadonlySessionManager = Pick<SessionManager, "getCwd" | "getSessionDir" | "getSessionId" | "getSessionFile" | "getLeafId" | "getLeafEntry" | "getEntry" | "getLabel" | "getBranch" | "buildContextEntries" | "getHeader" | "getEntries" | "getTree" | "getSessionName" | "getEvidenceRecords">;
|
|
163
|
+
export type ReadonlySessionManager = Pick<SessionManager, "getCwd" | "getSessionDir" | "getSessionId" | "getSessionFile" | "getLeafId" | "getLeafEntry" | "getEntry" | "getLabel" | "getBranch" | "buildContextEntries" | "getHeader" | "getEntries" | "getEntriesVersion" | "getTree" | "getSessionName" | "getEvidenceRecords">;
|
|
164
164
|
export declare function assertValidSessionId(id: string): void;
|
|
165
165
|
/** Exported for testing */
|
|
166
166
|
export declare function migrateSessionEntries(entries: FileEntry[]): void;
|
|
@@ -225,6 +225,12 @@ export declare class SessionManager {
|
|
|
225
225
|
private persist;
|
|
226
226
|
private flushed;
|
|
227
227
|
private fileEntries;
|
|
228
|
+
/**
|
|
229
|
+
* Bumped on every change to fileEntries. O(1) staleness check for callers
|
|
230
|
+
* that walk all entries per frame (the footer's usage totals) and would
|
|
231
|
+
* otherwise re-copy the whole list on every render.
|
|
232
|
+
*/
|
|
233
|
+
private entriesVersion;
|
|
228
234
|
private byId;
|
|
229
235
|
private labelsById;
|
|
230
236
|
private labelTimestampsById;
|
|
@@ -323,6 +329,12 @@ export declare class SessionManager {
|
|
|
323
329
|
* change the leaf pointer. Entries cannot be modified or deleted.
|
|
324
330
|
*/
|
|
325
331
|
getEntries(): SessionEntry[];
|
|
332
|
+
/**
|
|
333
|
+
* Monotonic counter bumped on every change to the entry list. Compare
|
|
334
|
+
* across frames to detect new/removed entries without calling
|
|
335
|
+
* getEntries() (which copies the whole list).
|
|
336
|
+
*/
|
|
337
|
+
getEntriesVersion(): number;
|
|
326
338
|
/**
|
|
327
339
|
* Get the session as a tree structure. Returns a shallow defensive copy of all entries.
|
|
328
340
|
* A well-formed session has exactly one root (first entry with parentId === null).
|