@earendil-works/pi-coding-agent 0.99.1 → 0.99.2
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 +40 -0
- package/dist/bundle/chunks/anthropic-messages-UID2PALB.js +6 -0
- package/dist/bundle/chunks/{azure-openai-responses-EN5WOBET.js → azure-openai-responses-TLHNIYZK.js} +1 -1
- package/dist/bundle/chunks/bedrock-converse-stream.js +1 -1
- package/dist/bundle/chunks/{chunk-IMTXZUO7.js → chunk-3KYEVQKX.js} +3 -3
- package/dist/bundle/chunks/{chunk-W2DOMZSC.js → chunk-3LH3ZQKY.js} +1 -1
- package/dist/bundle/chunks/chunk-3NVH2HQH.js +4 -0
- package/dist/bundle/chunks/{chunk-GUORCHFS.js → chunk-3YAHQSW6.js} +23 -20
- package/dist/bundle/chunks/{chunk-LLMKQWZS.js → chunk-45SXDISG.js} +5 -7
- package/dist/bundle/chunks/chunk-6D7LHLKG.js +2 -0
- package/dist/bundle/chunks/{chunk-AXPY26X7.js → chunk-7QSPBJKW.js} +3 -3
- package/dist/bundle/chunks/{chunk-SLDA2X2H.js → chunk-ECRK44UV.js} +1 -1
- package/dist/bundle/chunks/{chunk-PEHWOV5U.js → chunk-G3UZ5FWD.js} +12 -23
- package/dist/bundle/chunks/chunk-LD2P6SFZ.js +2 -0
- package/dist/bundle/chunks/{chunk-J4CWPC4N.js → chunk-OSKPX3Z5.js} +1 -1
- package/dist/bundle/chunks/{chunk-LRS5S6EK.js → chunk-R5J3MOBF.js} +1 -1
- package/dist/bundle/chunks/chunk-VIV3CWXG.js +2 -0
- package/dist/bundle/chunks/{cli-AZXNGIZH.js → cli-ALNBTL3U.js} +6 -4
- package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-XJQQYGGU.js → cloudflare-workers-ai-system-one-NPQN263E.js} +1 -1
- package/dist/bundle/chunks/codemode-worker.js +23 -3
- package/dist/bundle/chunks/{execute-7XXPZAWW.js → execute-RC7W4ML3.js} +26 -6
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/{google-generative-ai-CQAKKJTA.js → google-generative-ai-APTPZOQL.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-AE36YXJU.js → google-vertex-MXCOSOY3.js} +1 -1
- package/dist/bundle/chunks/{llama-cpp-classify-PJJYKPLD.js → llama-cpp-classify-XT44PI3C.js} +1 -1
- package/dist/bundle/chunks/{mistral-conversations-KEYTXJM7.js → mistral-conversations-DKVFNQL6.js} +1 -1
- package/dist/bundle/chunks/{openai-codex-responses-JQTCOVEG.js → openai-codex-responses-3GKGNXC4.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-XW2Q5HVC.js → openai-completions-JXDDPZ23.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-6AXWFL75.js → openai-responses-S7GKCCDG.js} +1 -1
- package/dist/bundle/chunks/{openrouter-images-TPQ4V6OR.js → openrouter-images-ZVXWCSIM.js} +1 -1
- package/dist/bundle/chunks/{runtime-G5WJPRBM.js → runtime-NJPX4ID2.js} +1 -1
- package/dist/bundle/chunks/{typesafe-system-one-E7A4HNJI.js → typesafe-system-one-A4CZTQWZ.js} +1 -1
- package/dist/bundle/chunks/virtual-modules-5UGH4HRZ.js +2 -0
- package/dist/bundle/cli-runtime.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/config.d.ts +5 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +16 -13
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +7 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +14 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +13 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +6 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/mcp-servers.d.ts +28 -7
- package/dist/core/mcp-servers.d.ts.map +1 -1
- package/dist/core/mcp-servers.js +45 -11
- package/dist/core/mcp-servers.js.map +1 -1
- package/dist/core/model-runtime.d.ts +6 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +22 -18
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +4 -9
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js +11 -31
- package/dist/core/tools/renderers/bash.js.map +1 -1
- package/dist/core/virtual-models.d.ts +2 -0
- package/dist/core/virtual-models.d.ts.map +1 -1
- package/dist/core/virtual-models.js +19 -12
- package/dist/core/virtual-models.js.map +1 -1
- package/dist/extensions/codemode/execute.d.ts.map +1 -1
- package/dist/extensions/codemode/execute.js +43 -4
- package/dist/extensions/codemode/execute.js.map +1 -1
- package/dist/extensions/codemode/renderer.d.ts.map +1 -1
- package/dist/extensions/codemode/renderer.js +43 -25
- package/dist/extensions/codemode/renderer.js.map +1 -1
- package/dist/extensions/codemode/tool.d.ts +5 -4
- package/dist/extensions/codemode/tool.d.ts.map +1 -1
- package/dist/extensions/codemode/tool.js +22 -31
- package/dist/extensions/codemode/tool.js.map +1 -1
- package/dist/extensions/codemode/worker.d.ts +1 -1
- package/dist/extensions/codemode/worker.js +1 -1
- package/dist/extensions/codemode/worker.js.map +1 -1
- package/dist/extensions/mcp/cli.d.ts.map +1 -1
- package/dist/extensions/mcp/cli.js +18 -3
- package/dist/extensions/mcp/cli.js.map +1 -1
- package/dist/extensions/mcp/config.d.ts +4 -2
- package/dist/extensions/mcp/config.d.ts.map +1 -1
- package/dist/extensions/mcp/config.js +14 -2
- package/dist/extensions/mcp/config.js.map +1 -1
- package/dist/extensions/mcp/index.d.ts +32 -8
- package/dist/extensions/mcp/index.d.ts.map +1 -1
- package/dist/extensions/mcp/index.js +205 -52
- package/dist/extensions/mcp/index.js.map +1 -1
- package/dist/extensions/mcp/oauth.d.ts +2 -0
- package/dist/extensions/mcp/oauth.d.ts.map +1 -1
- package/dist/extensions/mcp/oauth.js +1 -1
- package/dist/extensions/mcp/oauth.js.map +1 -1
- package/dist/extensions/mcp/runtime.d.ts +2 -0
- package/dist/extensions/mcp/runtime.d.ts.map +1 -1
- package/dist/extensions/mcp/runtime.js +14 -8
- package/dist/extensions/mcp/runtime.js.map +1 -1
- package/dist/extensions/mcp/tools.d.ts +5 -4
- package/dist/extensions/mcp/tools.d.ts.map +1 -1
- package/dist/extensions/mcp/tools.js +33 -15
- package/dist/extensions/mcp/tools.js.map +1 -1
- package/dist/extensions/mcp/ui.d.ts.map +1 -1
- package/dist/extensions/mcp/ui.js +4 -2
- package/dist/extensions/mcp/ui.js.map +1 -1
- package/dist/extensions/tool-search/tool.d.ts +5 -4
- package/dist/extensions/tool-search/tool.d.ts.map +1 -1
- package/dist/extensions/tool-search/tool.js +7 -28
- package/dist/extensions/tool-search/tool.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts +27 -3
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js +39 -6
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/docs/cli.md +3 -3
- package/docs/extensions.md +3 -3
- package/docs/mcp.md +125 -82
- package/docs/providers.md +2 -0
- package/docs/sdk.md +1 -1
- package/docs/settings.md +3 -1
- package/examples/extensions/built-in-tool-renderer.ts +16 -40
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/minimal-mode.ts +24 -96
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/14-codemode-mcp.ts +2 -2
- package/npm-shrinkwrap.json +26 -26
- package/package.json +10 -10
- package/dist/bundle/chunks/anthropic-messages-A6EXUBG6.js +0 -6
- package/dist/bundle/chunks/chunk-GOPCREV2.js +0 -4
- package/dist/bundle/chunks/chunk-HSPCVFST.js +0 -2
- package/dist/bundle/chunks/chunk-XNGRGP62.js +0 -2
- package/dist/bundle/chunks/virtual-modules-CSWRO37N.js +0 -2
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 { Agent, type AgentMessage, setDefaultStreamFn, type ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { ModelsSimpleStreamOptions } from \"@earendil-works/pi-ai\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple } from \"@earendil-works/pi-ai/compat\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { CacheWarmer } from \"./cache-warmer.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.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 { 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 { DEFAULT_TOOL_NAMES, SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport {\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreatePowerShellTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\nimport { getBranchSelection } from \"./virtual-models.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: ~/.pi/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 resolved `defaultTools` setting for the initial\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}\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 */\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// Assistant messages name the physical model that answered, so a virtual selection is only in\n\t// model_change entries.\n\tconst sessionModel = getBranchSelection(sessionManager.getBranch(), (provider, modelId) =>\n\t\tmodelRuntime.getModel(provider, modelId),\n\t);\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && sessionModel) {\n\t\tconst restoredModel = modelRuntime.getModel(sessionModel.provider, sessionModel.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 ${sessionModel.provider}/${sessionModel.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 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 ?? DEFAULT_TOOL_NAMES))\n\t).filter((name) => !excludedToolNameSet?.has(name));\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\tconst cacheWarmer = new CacheWarmer(\n\t\tmodelRuntime,\n\t\tsessionManager,\n\t\t() => settingsManager.getCacheWarmingMode(),\n\t\tasync (event) => extensionRunnerRef.current?.emitCacheWarmingDecision(event) ?? event.action,\n\t);\n\tconst buildRequestOptions = (\n\t\trequestModel: Model<any>,\n\t\toptions: ModelsSimpleStreamOptions = {},\n\t): ModelsSimpleStreamOptions => {\n\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\tconst httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n\t\tconst effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n\t\tconst headerRunner = extensionRunnerRef.current;\n\t\treturn {\n\t\t\t...options,\n\t\t\ttimeoutMs: options.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs,\n\t\t\twebsocketConnectTimeoutMs: options.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs(),\n\t\t\tmaxRetries: options.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\tmaxRetryDelayMs: options.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\ttransformHeaders: async (requestHeaders) => {\n\t\t\t\tconst headers = mergeProviderAttributionHeaders(\n\t\t\t\t\trequestModel,\n\t\t\t\t\tsettingsManager,\n\t\t\t\t\toptions.sessionId,\n\t\t\t\t\trequestHeaders,\n\t\t\t\t);\n\t\t\t\treturn headerRunner?.hasHandlers(\"before_provider_headers\")\n\t\t\t\t\t? headerRunner.emitBeforeProviderHeaders(headers ?? {})\n\t\t\t\t\t: (headers ?? {});\n\t\t\t},\n\t\t};\n\t};\n\t// Warm only requests for the selected model. Requests a virtual selection routed, or that an\n\t// extension redirected, may not be repeated by the next request, so warming them could be wasted.\n\tconst cacheContextIsCurrent = (requestModel: Model<any>) => {\n\t\tconst messages = agent.state.messages;\n\t\treturn () => {\n\t\t\tconst currentModel = agent.state.model;\n\t\t\tconst currentMessages = agent.state.messages;\n\t\t\treturn (\n\t\t\t\tcurrentModel.provider === requestModel.provider &&\n\t\t\t\tcurrentModel.id === requestModel.id &&\n\t\t\t\tmessages.length <= currentMessages.length &&\n\t\t\t\tmessages.every((message, index) => currentMessages[index] === message)\n\t\t\t);\n\t\t};\n\t};\n\tconst transformProviderPayload = async (payload: unknown) => {\n\t\tconst runner = extensionRunnerRef.current;\n\t\tif (!runner?.hasHandlers(\"before_provider_request\")) return payload;\n\t\treturn runner.emitBeforeProviderRequest(payload);\n\t};\n\tconst handleProviderResponse: NonNullable<ModelsSimpleStreamOptions[\"onResponse\"]> = async (response) => {\n\t\tconst runner = extensionRunnerRef.current;\n\t\tif (!runner?.hasHandlers(\"after_provider_response\")) return;\n\t\tawait runner.emit({\n\t\t\ttype: \"after_provider_response\",\n\t\t\tstatus: response.status,\n\t\t\theaders: response.headers,\n\t\t});\n\t};\n\tconst handleProviderStreamEvent: NonNullable<ModelsSimpleStreamOptions[\"onProviderStreamEvent\"]> = async (\n\t\tdata,\n\t\tmodel,\n\t) => {\n\t\tconst runner = extensionRunnerRef.current;\n\t\tif (!runner?.hasHandlers(\"provider_stream_event\")) return;\n\t\tawait runner.emit({\n\t\t\tdata,\n\t\t\ttype: \"provider_stream_event\",\n\t\t\tprovider: model.provider,\n\t\t\tapi: model.api,\n\t\t\tmodel: model.id,\n\t\t});\n\t};\n\n\tconst agent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t\tmessages: existingSession.messages,\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst requestOptions = buildRequestOptions(model, options);\n\t\t\t// Compaction and summaries use their own routing ids; only session requests\n\t\t\t// replace the cache entry, so warming restarts from them. Keep warming while\n\t\t\t// the current transcript still extends the request's prefix. Agent state may\n\t\t\t// shallow-copy the messages array or refresh the model object without changing\n\t\t\t// the provider request, so top-level object identity is not a valid cache key.\n\t\t\tif (options?.sessionId === sessionManager.getSessionId()) {\n\t\t\t\tcacheWarmer.start({ model, context, options: requestOptions }, cacheContextIsCurrent(model));\n\t\t\t}\n\t\t\treturn modelRuntime.streamSimple(model, context, requestOptions);\n\t\t},\n\t\tonPayload: transformProviderPayload,\n\t\tonResponse: handleProviderResponse,\n\t\tonProviderStreamEvent: handleProviderStreamEvent,\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 missing settings metadata for older sessions.\n\tif (hasExistingSession) {\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\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: options.customTools,\n\t\tmodelRuntime,\n\t\tcacheWarmer,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t});\n\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 { Agent, type AgentMessage, setDefaultStreamFn, type ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { ModelsSimpleStreamOptions } from \"@earendil-works/pi-ai\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple } from \"@earendil-works/pi-ai/compat\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { CacheWarmer } from \"./cache-warmer.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.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 { 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 { DEFAULT_TOOL_NAMES, SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport {\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreatePowerShellTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\nimport { getBranchSelection } from \"./virtual-models.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: ~/.pi/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 resolved `defaultTools` setting for the initial\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}\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 */\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// Assistant messages name the physical model that answered, so a virtual selection is only in\n\t// model_change entries.\n\tconst sessionModel = getBranchSelection(sessionManager.getBranch(), (provider, modelId) =>\n\t\tmodelRuntime.getModel(provider, modelId),\n\t);\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && sessionModel) {\n\t\tconst restoredModel = modelRuntime.getModel(sessionModel.provider, sessionModel.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 ${sessionModel.provider}/${sessionModel.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 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 ?? DEFAULT_TOOL_NAMES))\n\t).filter((name) => !excludedToolNameSet?.has(name));\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\tconst cacheWarmer = new CacheWarmer(\n\t\tmodelRuntime,\n\t\tsessionManager,\n\t\t() => settingsManager.getCacheWarmingMode(),\n\t\tasync (event) => extensionRunnerRef.current?.emitCacheWarmingDecision(event) ?? event.action,\n\t);\n\tconst buildRequestOptions = (\n\t\trequestModel: Model<any>,\n\t\toptions: ModelsSimpleStreamOptions = {},\n\t): ModelsSimpleStreamOptions => {\n\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\tconst httpIdleTimeoutMs = settingsManager.getHttpIdleTimeoutMs();\n\t\tconst effectiveTimeoutMs = httpIdleTimeoutMs === 0 ? 2147483647 : httpIdleTimeoutMs;\n\t\tconst headerRunner = extensionRunnerRef.current;\n\t\treturn {\n\t\t\t...options,\n\t\t\ttimeoutMs: options.timeoutMs ?? providerRetrySettings.timeoutMs ?? effectiveTimeoutMs,\n\t\t\twebsocketConnectTimeoutMs: options.websocketConnectTimeoutMs ?? settingsManager.getWebSocketConnectTimeoutMs(),\n\t\t\tmaxRetries: options.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\tmaxRetryDelayMs: options.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\ttransformHeaders: async (requestHeaders) => {\n\t\t\t\tconst headers = mergeProviderAttributionHeaders(\n\t\t\t\t\trequestModel,\n\t\t\t\t\tsettingsManager,\n\t\t\t\t\toptions.sessionId,\n\t\t\t\t\trequestHeaders,\n\t\t\t\t);\n\t\t\t\treturn headerRunner?.hasHandlers(\"before_provider_headers\")\n\t\t\t\t\t? headerRunner.emitBeforeProviderHeaders(headers ?? {})\n\t\t\t\t\t: (headers ?? {});\n\t\t\t},\n\t\t};\n\t};\n\t// Warm only requests for the selected model. Requests a virtual selection routed, or that an\n\t// extension redirected, may not be repeated by the next request, so warming them could be wasted.\n\tconst cacheContextIsCurrent = (requestModel: Model<any>) => {\n\t\tconst messages = agent.state.messages;\n\t\treturn () => {\n\t\t\tconst currentModel = agent.state.model;\n\t\t\tconst currentMessages = agent.state.messages;\n\t\t\treturn (\n\t\t\t\tcurrentModel.provider === requestModel.provider &&\n\t\t\t\tcurrentModel.id === requestModel.id &&\n\t\t\t\tmessages.length <= currentMessages.length &&\n\t\t\t\tmessages.every((message, index) => currentMessages[index] === message)\n\t\t\t);\n\t\t};\n\t};\n\tconst transformProviderPayload = async (payload: unknown) => {\n\t\tconst runner = extensionRunnerRef.current;\n\t\tif (!runner?.hasHandlers(\"before_provider_request\")) return payload;\n\t\treturn runner.emitBeforeProviderRequest(payload);\n\t};\n\tconst handleProviderResponse: NonNullable<ModelsSimpleStreamOptions[\"onResponse\"]> = async (response) => {\n\t\tconst runner = extensionRunnerRef.current;\n\t\tif (!runner?.hasHandlers(\"after_provider_response\")) return;\n\t\tawait runner.emit({\n\t\t\ttype: \"after_provider_response\",\n\t\t\tstatus: response.status,\n\t\t\theaders: response.headers,\n\t\t});\n\t};\n\tconst handleProviderStreamEvent: NonNullable<ModelsSimpleStreamOptions[\"onProviderStreamEvent\"]> = async (\n\t\tdata,\n\t\tmodel,\n\t) => {\n\t\tconst runner = extensionRunnerRef.current;\n\t\tif (!runner?.hasHandlers(\"provider_stream_event\")) return;\n\t\tawait runner.emit({\n\t\t\tdata,\n\t\t\ttype: \"provider_stream_event\",\n\t\t\tprovider: model.provider,\n\t\t\tapi: model.api,\n\t\t\tmodel: model.id,\n\t\t});\n\t};\n\n\tconst agent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t\tmessages: existingSession.messages,\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst requestOptions = buildRequestOptions(model, options);\n\t\t\t// Compaction and summaries use their own routing ids; only session requests\n\t\t\t// replace the cache entry, so warming restarts from them. Keep warming while\n\t\t\t// the current transcript still extends the request's prefix. Agent state may\n\t\t\t// shallow-copy the messages array or refresh the model object without changing\n\t\t\t// the provider request, so top-level object identity is not a valid cache key.\n\t\t\tif (options?.sessionId === sessionManager.getSessionId()) {\n\t\t\t\tcacheWarmer.start({ model, context, options: requestOptions }, cacheContextIsCurrent(model));\n\t\t\t}\n\t\t\treturn modelRuntime.streamSimple(model, context, requestOptions);\n\t\t},\n\t\tonPayload: transformProviderPayload,\n\t\tonResponse: handleProviderResponse,\n\t\tonProviderStreamEvent: handleProviderStreamEvent,\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 missing settings metadata for older sessions.\n\tif (hasExistingSession) {\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\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: options.customTools,\n\t\tmodelRuntime,\n\t\tcacheWarmer,\n\t\tinitialActiveToolNames,\n\t\tusesDefaultTools: options.tools === undefined && !options.noTools,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t});\n\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/renderers/bash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,2BAA2B,CAAC;AAMzF,eAAO,MAAM,uBAAuB,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/renderers/bash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,2BAA2B,CAAC;AAMzF,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAyF3C,uGAAuG;AACvG,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,CAqClH"}
|
|
@@ -5,20 +5,14 @@
|
|
|
5
5
|
* load the execution path or its typebox parameter schema. `bash.ts` spreads these into the shell
|
|
6
6
|
* tool definition, so the tool's public shape is unchanged.
|
|
7
7
|
*/
|
|
8
|
-
import { Container,
|
|
8
|
+
import { Container, Spacer, Text } from "@earendil-works/pi-tui";
|
|
9
9
|
import { keyHint } from "../../../modes/interactive/components/keybinding-hints.js";
|
|
10
|
-
import {
|
|
10
|
+
import { VisualLinePreview } from "../../../modes/interactive/components/visual-truncate.js";
|
|
11
11
|
import { theme } from "../../../modes/interactive/theme/theme.js";
|
|
12
12
|
import { getTextOutput, invalidArgText, str } from "../render-utils.js";
|
|
13
13
|
import { DEFAULT_MAX_BYTES, formatSize } from "../truncate.js";
|
|
14
14
|
const BASH_PREVIEW_LINES = 5;
|
|
15
15
|
export const BASH_UPDATE_THROTTLE_MS = 100;
|
|
16
|
-
class BashResultRenderComponent extends Container {
|
|
17
|
-
state = {
|
|
18
|
-
cachedWidth: undefined,
|
|
19
|
-
cachedLines: undefined,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
16
|
function formatDuration(ms) {
|
|
23
17
|
const seconds = ms / 1000;
|
|
24
18
|
if (seconds < 60)
|
|
@@ -38,7 +32,6 @@ function formatShellCall(args, prompt) {
|
|
|
38
32
|
return theme.fg("toolTitle", theme.bold(`${prompt} ${commandDisplay}`)) + timeoutSuffix;
|
|
39
33
|
}
|
|
40
34
|
function rebuildBashResultRenderComponent(component, result, options, showImages, startedAt, endedAt) {
|
|
41
|
-
const state = component.state;
|
|
42
35
|
component.clear();
|
|
43
36
|
let output = getTextOutput(result, showImages).trim();
|
|
44
37
|
const truncation = result.details?.truncation;
|
|
@@ -58,27 +51,14 @@ function rebuildBashResultRenderComponent(component, result, options, showImages
|
|
|
58
51
|
component.addChild(new Text(`\n${styledOutput}`, 0, 0));
|
|
59
52
|
}
|
|
60
53
|
else {
|
|
61
|
-
component.addChild(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
` ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
|
|
70
|
-
hintLines.push(truncateToWidth(hint, width, "..."));
|
|
71
|
-
}
|
|
72
|
-
state.cachedLines = ["", ...hintLines, ...preview.visualLines];
|
|
73
|
-
state.cachedWidth = width;
|
|
74
|
-
}
|
|
75
|
-
return state.cachedLines;
|
|
76
|
-
},
|
|
77
|
-
invalidate: () => {
|
|
78
|
-
state.cachedWidth = undefined;
|
|
79
|
-
state.cachedLines = undefined;
|
|
80
|
-
},
|
|
81
|
-
});
|
|
54
|
+
component.addChild(new Spacer(1));
|
|
55
|
+
component.addChild(new VisualLinePreview({
|
|
56
|
+
text: styledOutput,
|
|
57
|
+
maxVisualLines: BASH_PREVIEW_LINES,
|
|
58
|
+
keep: "end",
|
|
59
|
+
formatHint: (hidden) => theme.fg("muted", `... (${hidden} earlier lines,`) +
|
|
60
|
+
` ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`,
|
|
61
|
+
}));
|
|
82
62
|
}
|
|
83
63
|
}
|
|
84
64
|
if (truncation?.truncated || fullOutputPath) {
|
|
@@ -127,7 +107,7 @@ export function createShellRenderers(prompt) {
|
|
|
127
107
|
state.interval = undefined;
|
|
128
108
|
}
|
|
129
109
|
}
|
|
130
|
-
const component = context.lastComponent ?? new
|
|
110
|
+
const component = context.lastComponent ?? new Container();
|
|
131
111
|
rebuildBashResultRenderComponent(component, result, options, context.showImages, state.startedAt, state.endedAt);
|
|
132
112
|
component.invalidate();
|
|
133
113
|
return component;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../../src/core/tools/renderers/bash.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Presentation for the shell tools.\n *\n * Renderers live apart from the implementation so a process that only displays tool output does not\n * load the execution path or its typebox parameter schema. `bash.ts` spreads these into the shell\n * tool definition, so the tool's public shape is unchanged.\n */\n\nimport { Container, Text, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { keyHint } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport { truncateToVisualLines } from \"../../../modes/interactive/components/visual-truncate.ts\";\nimport { theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../../extensions/types.ts\";\nimport type { BashToolDetails } from \"../bash.ts\";\nimport { getTextOutput, invalidArgText, str } from \"../render-utils.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize } from \"../truncate.ts\";\n\nconst BASH_PREVIEW_LINES = 5;\nexport const BASH_UPDATE_THROTTLE_MS = 100;\ntype BashResultRenderState = {\n\tcachedWidth: number | undefined;\n\tcachedLines: string[] | undefined;\n};\nclass BashResultRenderComponent extends Container {\n\tstate: BashResultRenderState = {\n\t\tcachedWidth: undefined,\n\t\tcachedLines: undefined,\n\t};\n}\nfunction formatDuration(ms: number): string {\n\tconst seconds = ms / 1000;\n\tif (seconds < 60) return `${seconds.toFixed(1)}s`;\n\n\tconst totalSeconds = Math.floor(seconds);\n\tconst minutes = Math.floor(totalSeconds / 60);\n\tconst remainder = totalSeconds % 60;\n\tif (minutes < 60) return `${minutes}m ${remainder}s`;\n\n\treturn `${Math.floor(minutes / 60)}h ${minutes % 60}m ${remainder}s`;\n}\nfunction formatShellCall(args: { command?: string; timeout?: number } | undefined, prompt: string): string {\n\tconst command = str(args?.command);\n\tconst timeout = args?.timeout as number | undefined;\n\tconst timeoutSuffix = timeout ? theme.fg(\"muted\", ` (timeout ${timeout}s)`) : \"\";\n\tconst commandDisplay = command === null ? invalidArgText(theme) : command ? command : theme.fg(\"toolOutput\", \"...\");\n\treturn theme.fg(\"toolTitle\", theme.bold(`${prompt} ${commandDisplay}`)) + timeoutSuffix;\n}\nfunction rebuildBashResultRenderComponent(\n\tcomponent: BashResultRenderComponent,\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: BashToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\tshowImages: boolean,\n\tstartedAt: number | undefined,\n\tendedAt: number | undefined,\n): void {\n\tconst state = component.state;\n\tcomponent.clear();\n\n\tlet output = getTextOutput(result as any, showImages).trim();\n\tconst truncation = result.details?.truncation;\n\tconst fullOutputPath = result.details?.fullOutputPath;\n\tif (!options.isPartial && truncation?.truncated && fullOutputPath && output.endsWith(\"]\")) {\n\t\tconst footerStart = output.lastIndexOf(\"\\n\\n[\");\n\t\tif (footerStart !== -1 && output.slice(footerStart).includes(fullOutputPath)) {\n\t\t\toutput = output.slice(0, footerStart).trimEnd();\n\t\t}\n\t}\n\n\tif (output) {\n\t\tconst styledOutput = output\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => theme.fg(\"toolOutput\", line))\n\t\t\t.join(\"\\n\");\n\n\t\tif (options.expanded) {\n\t\t\tcomponent.addChild(new Text(`\\n${styledOutput}`, 0, 0));\n\t\t} else {\n\t\t\tcomponent.addChild({\n\t\t\t\trender: (width: number) => {\n\t\t\t\t\t// Cache the complete output: this renders on every frame for every bash result in the transcript.\n\t\t\t\t\tif (state.cachedLines === undefined || state.cachedWidth !== width) {\n\t\t\t\t\t\tconst preview = truncateToVisualLines(styledOutput, BASH_PREVIEW_LINES, width);\n\t\t\t\t\t\tconst hintLines: string[] = [];\n\t\t\t\t\t\tif (preview.skippedCount > 0) {\n\t\t\t\t\t\t\tconst hint =\n\t\t\t\t\t\t\t\ttheme.fg(\"muted\", `... (${preview.skippedCount} earlier lines,`) +\n\t\t\t\t\t\t\t\t` ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`;\n\t\t\t\t\t\t\thintLines.push(truncateToWidth(hint, width, \"...\"));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstate.cachedLines = [\"\", ...hintLines, ...preview.visualLines];\n\t\t\t\t\t\tstate.cachedWidth = width;\n\t\t\t\t\t}\n\t\t\t\t\treturn state.cachedLines;\n\t\t\t\t},\n\t\t\t\tinvalidate: () => {\n\t\t\t\t\tstate.cachedWidth = undefined;\n\t\t\t\t\tstate.cachedLines = undefined;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tif (truncation?.truncated || fullOutputPath) {\n\t\tconst warnings: string[] = [];\n\t\tif (fullOutputPath) {\n\t\t\twarnings.push(`Full output: ${fullOutputPath}`);\n\t\t}\n\t\tif (truncation?.truncated) {\n\t\t\tif (truncation.truncatedBy === \"lines\") {\n\t\t\t\twarnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);\n\t\t\t} else {\n\t\t\t\twarnings.push(\n\t\t\t\t\t`Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tcomponent.addChild(new Text(`\\n${theme.fg(\"warning\", `[${warnings.join(\". \")}]`)}`, 0, 0));\n\t}\n\n\tif (startedAt !== undefined) {\n\t\tconst label = options.isPartial ? \"Elapsed\" : \"Took\";\n\t\tconst endTime = endedAt ?? Date.now();\n\t\tcomponent.addChild(new Text(`\\n${theme.fg(\"muted\", `${label} ${formatDuration(endTime - startedAt)}`)}`, 0, 0));\n\t}\n}\n\n/** Shell renderers are shared by bash and powershell, which differ only in the prompt they display. */\nexport function createShellRenderers(prompt: string): Pick<ToolDefinition<any, any>, \"renderCall\" | \"renderResult\"> {\n\treturn {\n\t\trenderCall(args, _theme, context) {\n\t\t\tconst state = context.state;\n\t\t\tif (context.executionStarted && state.startedAt === undefined) {\n\t\t\t\tstate.startedAt = Date.now();\n\t\t\t\tstate.endedAt = undefined;\n\t\t\t}\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatShellCall(args as { command?: string; timeout?: number } | undefined, prompt));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, _theme, context) {\n\t\t\tconst state = context.state;\n\t\t\tif (state.startedAt !== undefined && options.isPartial && !state.interval) {\n\t\t\t\tstate.interval = setInterval(() => context.invalidate(), 1000);\n\t\t\t}\n\t\t\tif (!options.isPartial || context.isError) {\n\t\t\t\tstate.endedAt ??= Date.now();\n\t\t\t\tif (state.interval) {\n\t\t\t\t\tclearInterval(state.interval);\n\t\t\t\t\tstate.interval = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst component =\n\t\t\t\t(context.lastComponent as BashResultRenderComponent | undefined) ?? new BashResultRenderComponent();\n\t\t\trebuildBashResultRenderComponent(\n\t\t\t\tcomponent,\n\t\t\t\tresult as any,\n\t\t\t\toptions,\n\t\t\t\tcontext.showImages,\n\t\t\t\tstate.startedAt,\n\t\t\t\tstate.endedAt,\n\t\t\t);\n\t\t\tcomponent.invalidate();\n\t\t\treturn component;\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../../src/core/tools/renderers/bash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,2DAA2D,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0DAA0D,CAAC;AAC7F,OAAO,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AAGlE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE/D,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAC3C,SAAS,cAAc,CAAC,EAAU;IACjC,MAAM,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC;IAC1B,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAElD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,YAAY,GAAG,EAAE,CAAC;IACpC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,KAAK,SAAS,GAAG,CAAC;IAErD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,KAAK,OAAO,GAAG,EAAE,KAAK,SAAS,GAAG,CAAC;AACtE,CAAC;AACD,SAAS,eAAe,CAAC,IAAwD,EAAE,MAAc;IAChG,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,EAAE,OAA6B,CAAC;IACpD,MAAM,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjF,MAAM,cAAc,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACpH,OAAO,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,cAAc,EAAE,CAAC,CAAC,GAAG,aAAa,CAAC;AACzF,CAAC;AACD,SAAS,gCAAgC,CACxC,SAAoB,EACpB,MAGC,EACD,OAAgC,EAChC,UAAmB,EACnB,SAA6B,EAC7B,OAA2B;IAE3B,SAAS,CAAC,KAAK,EAAE,CAAC;IAElB,IAAI,MAAM,GAAG,aAAa,CAAC,MAAa,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC;IAC9C,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC;IACtD,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,UAAU,EAAE,SAAS,IAAI,cAAc,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3F,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,WAAW,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAC9E,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;QACjD,CAAC;IACF,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACZ,MAAM,YAAY,GAAG,MAAM;aACzB,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;aAC3C,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACtB,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACP,SAAS,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,SAAS,CAAC,QAAQ,CACjB,IAAI,iBAAiB,CAAC;gBACrB,IAAI,EAAE,YAAY;gBAClB,cAAc,EAAE,kBAAkB;gBAClC,IAAI,EAAE,KAAK;gBACX,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,CACtB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,MAAM,iBAAiB,CAAC;oBAClD,IAAI,OAAO,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE;aACxE,CAAC,CACF,CAAC;QACH,CAAC;IACF,CAAC;IAED,IAAI,UAAU,EAAE,SAAS,IAAI,cAAc,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,IAAI,cAAc,EAAE,CAAC;YACpB,QAAQ,CAAC,IAAI,CAAC,gBAAgB,cAAc,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,UAAU,EAAE,SAAS,EAAE,CAAC;YAC3B,IAAI,UAAU,CAAC,WAAW,KAAK,OAAO,EAAE,CAAC;gBACxC,QAAQ,CAAC,IAAI,CAAC,sBAAsB,UAAU,CAAC,WAAW,OAAO,UAAU,CAAC,UAAU,QAAQ,CAAC,CAAC;YACjG,CAAC;iBAAM,CAAC;gBACP,QAAQ,CAAC,IAAI,CACZ,cAAc,UAAU,CAAC,WAAW,iBAAiB,UAAU,CAAC,UAAU,CAAC,QAAQ,IAAI,iBAAiB,CAAC,SAAS,CAClH,CAAC;YACH,CAAC;QACF,CAAC;QACD,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;QACrD,MAAM,OAAO,GAAG,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,cAAc,CAAC,OAAO,GAAG,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACjH,CAAC;AACF,CAAC;AAED,uGAAuG;AACvG,MAAM,UAAU,oBAAoB,CAAC,MAAc;IAClD,OAAO;QACN,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO;YAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;YAC5B,IAAI,OAAO,CAAC,gBAAgB,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC/D,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC7B,KAAK,CAAC,OAAO,GAAG,SAAS,CAAC;YAC3B,CAAC;YACD,MAAM,IAAI,GAAI,OAAO,CAAC,aAAkC,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/E,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAA0D,EAAE,MAAM,CAAC,CAAC,CAAC;YAClG,OAAO,IAAI,CAAC;QACb,CAAC;QACD,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO;YAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;YAC5B,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC3E,KAAK,CAAC,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,CAAC;YAChE,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAC3C,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC7B,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACpB,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBAC9B,KAAK,CAAC,QAAQ,GAAG,SAAS,CAAC;gBAC5B,CAAC;YACF,CAAC;YACD,MAAM,SAAS,GAAI,OAAO,CAAC,aAAuC,IAAI,IAAI,SAAS,EAAE,CAAC;YACtF,gCAAgC,CAC/B,SAAS,EACT,MAAa,EACb,OAAO,EACP,OAAO,CAAC,UAAU,EAClB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,OAAO,CACb,CAAC;YACF,SAAS,CAAC,UAAU,EAAE,CAAC;YACvB,OAAO,SAAS,CAAC;QAClB,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["/**\n * Presentation for the shell tools.\n *\n * Renderers live apart from the implementation so a process that only displays tool output does not\n * load the execution path or its typebox parameter schema. `bash.ts` spreads these into the shell\n * tool definition, so the tool's public shape is unchanged.\n */\n\nimport { Container, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport { keyHint } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport { VisualLinePreview } from \"../../../modes/interactive/components/visual-truncate.ts\";\nimport { theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../../extensions/types.ts\";\nimport type { BashToolDetails } from \"../bash.ts\";\nimport { getTextOutput, invalidArgText, str } from \"../render-utils.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize } from \"../truncate.ts\";\n\nconst BASH_PREVIEW_LINES = 5;\nexport const BASH_UPDATE_THROTTLE_MS = 100;\nfunction formatDuration(ms: number): string {\n\tconst seconds = ms / 1000;\n\tif (seconds < 60) return `${seconds.toFixed(1)}s`;\n\n\tconst totalSeconds = Math.floor(seconds);\n\tconst minutes = Math.floor(totalSeconds / 60);\n\tconst remainder = totalSeconds % 60;\n\tif (minutes < 60) return `${minutes}m ${remainder}s`;\n\n\treturn `${Math.floor(minutes / 60)}h ${minutes % 60}m ${remainder}s`;\n}\nfunction formatShellCall(args: { command?: string; timeout?: number } | undefined, prompt: string): string {\n\tconst command = str(args?.command);\n\tconst timeout = args?.timeout as number | undefined;\n\tconst timeoutSuffix = timeout ? theme.fg(\"muted\", ` (timeout ${timeout}s)`) : \"\";\n\tconst commandDisplay = command === null ? invalidArgText(theme) : command ? command : theme.fg(\"toolOutput\", \"...\");\n\treturn theme.fg(\"toolTitle\", theme.bold(`${prompt} ${commandDisplay}`)) + timeoutSuffix;\n}\nfunction rebuildBashResultRenderComponent(\n\tcomponent: Container,\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: BashToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\tshowImages: boolean,\n\tstartedAt: number | undefined,\n\tendedAt: number | undefined,\n): void {\n\tcomponent.clear();\n\n\tlet output = getTextOutput(result as any, showImages).trim();\n\tconst truncation = result.details?.truncation;\n\tconst fullOutputPath = result.details?.fullOutputPath;\n\tif (!options.isPartial && truncation?.truncated && fullOutputPath && output.endsWith(\"]\")) {\n\t\tconst footerStart = output.lastIndexOf(\"\\n\\n[\");\n\t\tif (footerStart !== -1 && output.slice(footerStart).includes(fullOutputPath)) {\n\t\t\toutput = output.slice(0, footerStart).trimEnd();\n\t\t}\n\t}\n\n\tif (output) {\n\t\tconst styledOutput = output\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => theme.fg(\"toolOutput\", line))\n\t\t\t.join(\"\\n\");\n\n\t\tif (options.expanded) {\n\t\t\tcomponent.addChild(new Text(`\\n${styledOutput}`, 0, 0));\n\t\t} else {\n\t\t\tcomponent.addChild(new Spacer(1));\n\t\t\tcomponent.addChild(\n\t\t\t\tnew VisualLinePreview({\n\t\t\t\t\ttext: styledOutput,\n\t\t\t\t\tmaxVisualLines: BASH_PREVIEW_LINES,\n\t\t\t\t\tkeep: \"end\",\n\t\t\t\t\tformatHint: (hidden) =>\n\t\t\t\t\t\ttheme.fg(\"muted\", `... (${hidden} earlier lines,`) +\n\t\t\t\t\t\t` ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\tif (truncation?.truncated || fullOutputPath) {\n\t\tconst warnings: string[] = [];\n\t\tif (fullOutputPath) {\n\t\t\twarnings.push(`Full output: ${fullOutputPath}`);\n\t\t}\n\t\tif (truncation?.truncated) {\n\t\t\tif (truncation.truncatedBy === \"lines\") {\n\t\t\t\twarnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);\n\t\t\t} else {\n\t\t\t\twarnings.push(\n\t\t\t\t\t`Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tcomponent.addChild(new Text(`\\n${theme.fg(\"warning\", `[${warnings.join(\". \")}]`)}`, 0, 0));\n\t}\n\n\tif (startedAt !== undefined) {\n\t\tconst label = options.isPartial ? \"Elapsed\" : \"Took\";\n\t\tconst endTime = endedAt ?? Date.now();\n\t\tcomponent.addChild(new Text(`\\n${theme.fg(\"muted\", `${label} ${formatDuration(endTime - startedAt)}`)}`, 0, 0));\n\t}\n}\n\n/** Shell renderers are shared by bash and powershell, which differ only in the prompt they display. */\nexport function createShellRenderers(prompt: string): Pick<ToolDefinition<any, any>, \"renderCall\" | \"renderResult\"> {\n\treturn {\n\t\trenderCall(args, _theme, context) {\n\t\t\tconst state = context.state;\n\t\t\tif (context.executionStarted && state.startedAt === undefined) {\n\t\t\t\tstate.startedAt = Date.now();\n\t\t\t\tstate.endedAt = undefined;\n\t\t\t}\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatShellCall(args as { command?: string; timeout?: number } | undefined, prompt));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, _theme, context) {\n\t\t\tconst state = context.state;\n\t\t\tif (state.startedAt !== undefined && options.isPartial && !state.interval) {\n\t\t\t\tstate.interval = setInterval(() => context.invalidate(), 1000);\n\t\t\t}\n\t\t\tif (!options.isPartial || context.isError) {\n\t\t\t\tstate.endedAt ??= Date.now();\n\t\t\t\tif (state.interval) {\n\t\t\t\t\tclearInterval(state.interval);\n\t\t\t\t\tstate.interval = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\trebuildBashResultRenderComponent(\n\t\t\t\tcomponent,\n\t\t\t\tresult as any,\n\t\t\t\toptions,\n\t\t\t\tcontext.showImages,\n\t\t\t\tstate.startedAt,\n\t\t\t\tstate.endedAt,\n\t\t\t);\n\t\t\tcomponent.invalidate();\n\t\t\treturn component;\n\t\t},\n\t};\n}\n"]}
|
|
@@ -97,6 +97,8 @@ export declare function findLatestResponse(messages: readonly AgentMessage[]): A
|
|
|
97
97
|
* `model_change`, because responses name the physical models it routed to. Otherwise the latest
|
|
98
98
|
* physical response wins, as in sessions without virtual models. A virtual model that is no longer
|
|
99
99
|
* registered does not hold, so the selection falls back to the physical model that answered last.
|
|
100
|
+
*
|
|
101
|
+
* Only the last `model_change` can hold, so this looks up at most one model in the catalog.
|
|
100
102
|
*/
|
|
101
103
|
export declare function getBranchSelection(branch: readonly SessionEntry[], getModel: (provider: string, modelId: string) => Model<Api> | undefined): {
|
|
102
104
|
provider: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtual-models.d.ts","sourceRoot":"","sources":["../../src/core/virtual-models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAEN,KAAK,GAAG,EACR,KAAK,gBAAgB,EAIrB,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,kBAAkB,EACvB,KAAK,QAAQ,EAEb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,eAAe,CAAC;AAE9C,wEAAwE;AACxE,eAAO,MAAM,yBAAyB,2BAA2B,CAAC;AAElE,uDAAuD;AACvD,MAAM,WAAW,qBAAqB,CAAC,MAAM,GAAG,OAAO;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACd;AAID;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE5E,MAAM,WAAW,iBAAiB,CAAC,MAAM,GAAG,OAAO;IAClD,kCAAkC;IAClC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,oEAAoE;IACpE,aAAa,EAAE,kBAAkB,CAAC;IAClC,MAAM,EAAE,gBAAgB,CAAC;IACzB,yFAAyF;IACzF,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,aAAa,CAAC,EAAE,kBAAkB,CAAA;KAAE,CAAC;IACrE;;;OAGG;IACH,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,aAAa,CAAC,EAAE,kBAAkB,CAAC;QAAC,OAAO,EAAE,gBAAgB,CAAA;KAAE,CAAC;IAC9F,qHAAqH;IACrH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,yDAAyD;AACzD,MAAM,WAAW,UAAU,CAAC,MAAM,GAAG,OAAO;IAC3C,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,EAAE,kBAAkB,CAAC;IAClC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB,CAAC,MAAM,GAAG,OAAO;IACvD,0FAA0F;IAC1F,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,cAAc,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC/C;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6HAA6H;IAC7H,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;IAC7B,gGAAgG;IAChG,KAAK,CAAC,OAAO,EAAE,iBAAiB,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;CAC5F;AAED,gHAAgH;AAChH,wBAAgB,cAAc,CAAC,KAAK,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAE9D;AAED,4HAA4H;AAC5H,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,gBAAgB,GAAG,SAAS,CAQlG;AAED
|
|
1
|
+
{"version":3,"file":"virtual-models.d.ts","sourceRoot":"","sources":["../../src/core/virtual-models.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,24 +23,31 @@ export function findLatestResponse(messages) {
|
|
|
23
23
|
* `model_change`, because responses name the physical models it routed to. Otherwise the latest
|
|
24
24
|
* physical response wins, as in sessions without virtual models. A virtual model that is no longer
|
|
25
25
|
* registered does not hold, so the selection falls back to the physical model that answered last.
|
|
26
|
+
*
|
|
27
|
+
* Only the last `model_change` can hold, so this looks up at most one model in the catalog.
|
|
26
28
|
*/
|
|
27
29
|
export function getBranchSelection(branch, getModel) {
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
return model !== undefined && isVirtualModel(model);
|
|
31
|
-
};
|
|
32
|
-
let selection;
|
|
33
|
-
for (const entry of branch) {
|
|
30
|
+
for (let i = branch.length - 1; i >= 0; i--) {
|
|
31
|
+
const entry = branch[i];
|
|
34
32
|
if (entry.type === "model_change") {
|
|
35
|
-
|
|
33
|
+
return { provider: entry.provider, modelId: entry.modelId };
|
|
36
34
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
if (entry.type === "message" && entry.message.role === "assistant" && !isVirtualModel(entry.message)) {
|
|
36
|
+
const response = { provider: entry.message.provider, modelId: entry.message.model };
|
|
37
|
+
const change = findLastModelChange(branch, i);
|
|
38
|
+
const model = change && getModel(change.provider, change.modelId);
|
|
39
|
+
return change && model && isVirtualModel(model) ? change : response;
|
|
41
40
|
}
|
|
42
41
|
}
|
|
43
|
-
return
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
function findLastModelChange(branch, before) {
|
|
45
|
+
for (let i = before - 1; i >= 0; i--) {
|
|
46
|
+
const entry = branch[i];
|
|
47
|
+
if (entry.type === "model_change")
|
|
48
|
+
return { provider: entry.provider, modelId: entry.modelId };
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
44
51
|
}
|
|
45
52
|
/** Latest router state a session branch stores for a virtual model. */
|
|
46
53
|
export function getVirtualModelState(branch, provider, modelId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtual-models.js","sourceRoot":"","sources":["../../src/core/virtual-models.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Virtual models are catalog entries that route each request to a physical model.\n *\n * The selection (`model_change`, `agent.state.model`, `ctx.model`) may name a virtual model.\n * Everything below the routing step only sees physical models: providers stream them and\n * assistant messages record them. A virtual model never reaches a provider.\n *\n * Virtual models belong to a provider id but are not provider models. `ModelRuntime` keeps them\n * separately and adds them to the provider's catalog with `withVirtualModels()`, so any provider,\n * including one with physical models, can list several virtual models.\n */\nimport type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport {\n\ttype AnyModel,\n\ttype Api,\n\ttype AssistantMessage,\n\ttype AssistantMessageEventStream,\n\tisModelType,\n\tlazyStream,\n\ttype Message,\n\ttype Model,\n\ttype ModelThinkingLevel,\n\ttype Provider,\n\ttype ThinkingLevelMap,\n} from \"@earendil-works/pi-ai\";\nimport type { SessionEntry } from \"./session-manager.ts\";\n\n/** API id of virtual catalog entries. Requests for it fail unless routed first. */\nexport const VIRTUAL_MODEL_API = \"pi-virtual\";\n\n/** Custom entry type that stores router state on the session branch. */\nexport const VIRTUAL_MODEL_STATE_ENTRY = \"pi.virtual-model-state\";\n\n/** Data of a `pi.virtual-model-state` custom entry. */\nexport interface VirtualModelStateData<TState = unknown> {\n\tprovider: string;\n\tmodelId: string;\n\tstate: TState;\n}\n\nconst THINKING_LEVELS: readonly ModelThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"];\n\n/**\n * Why a request is being routed.\n * - `user`: first request after a message the user wrote (prompt, steering, or follow-up)\n * - `continuation`: any other request in the agent loop, e.g. after tool results or extension messages\n * - `retry`: automatic retry after a failed request, including after compaction for a context overflow\n * - `direct`: a request outside the agent loop, e.g. a compaction summary or an extension call\n */\nexport type ModelRouteReason = \"user\" | \"continuation\" | \"retry\" | \"direct\";\n\nexport interface ModelRouteRequest<TState = unknown> {\n\t/** The selected virtual model. */\n\tmodel: Model<Api>;\n\t/** The selected thinking level. Its meaning is up to the router. */\n\tthinkingLevel: ModelThinkingLevel;\n\treason: ModelRouteReason;\n\t/** Physical model and thinking level of the latest successful response in `messages`. */\n\tprevious?: { model: Model<Api>; thinkingLevel?: ModelThinkingLevel };\n\t/**\n\t * For `retry`: the failed request, which `messages` no longer contains. `message` carries its\n\t * `stopReason` and `errorMessage`. Absent when the router itself failed.\n\t */\n\tfailed?: { model: Model<Api>; thinkingLevel?: ModelThinkingLevel; message: AssistantMessage };\n\t/** Router state last returned on this session branch. Undefined before the first state and for `direct` requests. */\n\tstate?: TState;\n\t/** Conversation for this request, including system messages. */\n\tmessages: readonly Message[];\n\tsignal?: AbortSignal;\n}\n\n/** Physical model and thinking level for one request. */\nexport interface ModelRoute<TState = unknown> {\n\tmodel: Model<Api>;\n\tthinkingLevel: ModelThinkingLevel;\n\t/**\n\t * New router state, stored on the session branch unless it is `request.state` itself. Return\n\t * `request.state` or undefined to keep the current state. Must be JSON-serializable. Ignored for\n\t * `direct` requests.\n\t */\n\tstate?: TState;\n}\n\nexport interface VirtualModelDefinition<TState = unknown> {\n\t/** Provider the virtual model is listed under. May be a provider with physical models. */\n\tprovider: string;\n\t/** Model id. Must not be the id of a physical model of `provider`. */\n\tid: string;\n\tname: string;\n\t/** Thinking levels offered for selection. Defaults to `[\"off\"]`. */\n\tthinkingLevels?: readonly ModelThinkingLevel[];\n\t/**\n\t * Limits shown before the first response. Afterwards, Pi uses the limits of the physical model\n\t * that answered. Unset limits are unknown (0).\n\t */\n\tcontextWindow?: number;\n\tmaxTokens?: number;\n\t/** Input types accepted for selection. Defaults to text and images; routed models without image support get placeholders. */\n\tinput?: (\"text\" | \"image\")[];\n\t/** Pick the physical model, which must have credentials, and thinking level for one request. */\n\troute(request: ModelRouteRequest<TState>): ModelRoute<TState> | Promise<ModelRoute<TState>>;\n}\n\n/** Whether a model or message names a virtual model. Failed routing leaves the virtual model on its message. */\nexport function isVirtualModel(model: { api: string }): boolean {\n\treturn model.api === VIRTUAL_MODEL_API;\n}\n\n/** Latest successful response. Its model is physical: failed or aborted requests, including failed routing, are skipped. */\nexport function findLatestResponse(messages: readonly AgentMessage[]): AssistantMessage | undefined {\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst message = messages[i];\n\t\tif (message.role === \"assistant\" && message.stopReason !== \"error\" && message.stopReason !== \"aborted\") {\n\t\t\treturn message;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * The model selection a session branch records. A virtual `model_change` holds until the next\n * `model_change`, because responses name the physical models it routed to. Otherwise the latest\n * physical response wins, as in sessions without virtual models. A virtual model that is no longer\n * registered does not hold, so the selection falls back to the physical model that answered last.\n */\nexport function getBranchSelection(\n\tbranch: readonly SessionEntry[],\n\tgetModel: (provider: string, modelId: string) => Model<Api> | undefined,\n): { provider: string; modelId: string } | undefined {\n\tconst isVirtual = (provider: string, modelId: string) => {\n\t\tconst model = getModel(provider, modelId);\n\t\treturn model !== undefined && isVirtualModel(model);\n\t};\n\tlet selection: { provider: string; modelId: string } | undefined;\n\tfor (const entry of branch) {\n\t\tif (entry.type === \"model_change\") {\n\t\t\tselection = { provider: entry.provider, modelId: entry.modelId };\n\t\t} else if (entry.type === \"message\" && entry.message.role === \"assistant\" && !isVirtualModel(entry.message)) {\n\t\t\tif (!selection || !isVirtual(selection.provider, selection.modelId)) {\n\t\t\t\tselection = { provider: entry.message.provider, modelId: entry.message.model };\n\t\t\t}\n\t\t}\n\t}\n\treturn selection;\n}\n\n/** Latest router state a session branch stores for a virtual model. */\nexport function getVirtualModelState(branch: readonly SessionEntry[], provider: string, modelId: string): unknown {\n\tfor (let i = branch.length - 1; i >= 0; i--) {\n\t\tconst entry = branch[i];\n\t\tif (entry.type !== \"custom\" || entry.customType !== VIRTUAL_MODEL_STATE_ENTRY) continue;\n\t\tconst data = entry.data as VirtualModelStateData | undefined;\n\t\tif (data?.provider === provider && data.modelId === modelId) return data.state;\n\t}\n\treturn undefined;\n}\n\n/** Build the catalog entry of a virtual model. */\nexport function createVirtualModel(definition: Omit<VirtualModelDefinition, \"route\">): Model<Api> {\n\tconst levels = definition.thinkingLevels ?? [\"off\"];\n\tconst thinkingLevelMap: ThinkingLevelMap = {};\n\tfor (const level of THINKING_LEVELS) thinkingLevelMap[level] = levels.includes(level) ? level : null;\n\treturn {\n\t\tid: definition.id,\n\t\tname: definition.name,\n\t\tapi: VIRTUAL_MODEL_API,\n\t\tprovider: definition.provider,\n\t\tbaseUrl: \"\",\n\t\treasoning: levels.some((level) => level !== \"off\"),\n\t\tthinkingLevelMap,\n\t\tinput: definition.input ?? [\"text\", \"image\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: definition.contextWindow ?? 0,\n\t\tmaxTokens: definition.maxTokens ?? 0,\n\t};\n}\n\n/** Stream for a virtual model that was not routed, e.g. `stream()` with API-specific options. */\nfunction unroutedStream(model: Model<Api>): AssistantMessageEventStream {\n\treturn lazyStream(model, async () => {\n\t\tthrow new Error(`Virtual model ${model.provider}/${model.id} must be routed before streaming`);\n\t});\n}\n\n/**\n * Add virtual models to a provider's catalog. Without a provider, the result is a keyless provider\n * that only lists the virtual models. A virtual model hides a physical chat model with the same id,\n * which a catalog refresh can add after registration. Availability follows the provider's auth.\n */\nexport function withVirtualModels(\n\tproviderId: string,\n\tprovider: Provider | undefined,\n\tvirtualModels: readonly Model<Api>[],\n): Provider {\n\tif (!provider) {\n\t\treturn {\n\t\t\tid: providerId,\n\t\t\tname: providerId,\n\t\t\tauth: { apiKey: { name: \"Virtual model\", resolve: async () => ({ auth: {}, source: \"virtual\" }) } },\n\t\t\tgetModels: () => virtualModels,\n\t\t\tstream: unroutedStream,\n\t\t\tstreamSimple: unroutedStream,\n\t\t};\n\t}\n\tconst ids = new Set(virtualModels.map((model) => model.id));\n\tconst physical = <TModel extends AnyModel>(models: readonly TModel[]) =>\n\t\tmodels.filter((model) => !isVirtualModel(model) && !(isModelType(model, \"chat\") && ids.has(model.id)));\n\tconst virtual = <TModel extends AnyModel>(models: readonly TModel[]) =>\n\t\tmodels.filter((model) => isVirtualModel(model));\n\tconst { filterModels, filterAllModels } = provider;\n\treturn {\n\t\t...provider,\n\t\tgetModels: () => [...physical(provider.getModels()), ...virtualModels],\n\t\tgetAllModels: () => [...physical(provider.getAllModels?.() ?? provider.getModels()), ...virtualModels],\n\t\tfilterModels: (models, credential) => {\n\t\t\tconst real = physical(models);\n\t\t\treturn [...(filterModels?.(real, credential) ?? real), ...virtual(models)];\n\t\t},\n\t\tfilterAllModels:\n\t\t\tfilterAllModels &&\n\t\t\t((models, credential) => [...filterAllModels(physical(models), credential), ...virtual(models)]),\n\t\tstream: (model, context, options) =>\n\t\t\tisVirtualModel(model) ? unroutedStream(model) : provider.stream(model, context, options),\n\t\tstreamSimple: (model, context, options) =>\n\t\t\tisVirtualModel(model) ? unroutedStream(model) : provider.streamSimple(model, context, options),\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"virtual-models.js","sourceRoot":"","sources":["../../src/core/virtual-models.ts"],"names":[],"mappings":"AAYA,OAAO,EAKN,WAAW,EACX,UAAU,GAMV,MAAM,uBAAuB,CAAC;AAG/B,mFAAmF;AACnF,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAE9C,wEAAwE;AACxE,MAAM,CAAC,MAAM,yBAAyB,GAAG,wBAAwB,CAAC;AASlE,MAAM,eAAe,GAAkC,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AA+DnH,gHAAgH;AAChH,MAAM,UAAU,cAAc,CAAC,KAAsB;IACpD,OAAO,KAAK,CAAC,GAAG,KAAK,iBAAiB,CAAC;AACxC,CAAC;AAED,4HAA4H;AAC5H,MAAM,UAAU,kBAAkB,CAAC,QAAiC;IACnE,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,UAAU,KAAK,OAAO,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACxG,OAAO,OAAO,CAAC;QAChB,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CACjC,MAA+B,EAC/B,QAAuE;IAEvE,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACnC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAC7D,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACtG,MAAM,QAAQ,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACpF,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;YAClE,OAAO,MAAM,IAAI,KAAK,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;QACrE,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,mBAAmB,CAC3B,MAA+B,EAC/B,MAAc;IAEd,KAAK,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;YAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAChG,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,oBAAoB,CAAC,MAA+B,EAAE,QAAgB,EAAE,OAAe;IACtG,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,yBAAyB;YAAE,SAAS;QACxF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAyC,CAAC;QAC7D,IAAI,IAAI,EAAE,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;IAChF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,kBAAkB,CAAC,UAAiD;IACnF,MAAM,MAAM,GAAG,UAAU,CAAC,cAAc,IAAI,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,gBAAgB,GAAqB,EAAE,CAAC;IAC9C,KAAK,MAAM,KAAK,IAAI,eAAe;QAAE,gBAAgB,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACrG,OAAO;QACN,EAAE,EAAE,UAAU,CAAC,EAAE;QACjB,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,GAAG,EAAE,iBAAiB;QACtB,QAAQ,EAAE,UAAU,CAAC,QAAQ;QAC7B,OAAO,EAAE,EAAE;QACX,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC;QAClD,gBAAgB;QAChB,KAAK,EAAE,UAAU,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;QAC5C,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;QAC1D,aAAa,EAAE,UAAU,CAAC,aAAa,IAAI,CAAC;QAC5C,SAAS,EAAE,UAAU,CAAC,SAAS,IAAI,CAAC;KACpC,CAAC;AACH,CAAC;AAED,iGAAiG;AACjG,SAAS,cAAc,CAAC,KAAiB;IACxC,OAAO,UAAU,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QACnC,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,kCAAkC,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAChC,UAAkB,EAClB,QAA8B,EAC9B,aAAoC;IAEpC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO;YACN,EAAE,EAAE,UAAU;YACd,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE;YACnG,SAAS,EAAE,GAAG,EAAE,CAAC,aAAa;YAC9B,MAAM,EAAE,cAAc;YACtB,YAAY,EAAE,cAAc;SAC5B,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,CAA0B,MAAyB,EAAE,EAAE,CACvE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACxG,MAAM,OAAO,GAAG,CAA0B,MAAyB,EAAE,EAAE,CACtE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;IACjD,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,QAAQ,CAAC;IACnD,OAAO;QACN,GAAG,QAAQ;QACX,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,GAAG,aAAa,CAAC;QACtE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,GAAG,aAAa,CAAC;QACtG,YAAY,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE;YACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5E,CAAC;QACD,eAAe,EACd,eAAe;YACf,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,GAAG,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACjG,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CACnC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC;QACzF,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CACzC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC;KAC/F,CAAC;AACH,CAAC","sourcesContent":["/**\n * Virtual models are catalog entries that route each request to a physical model.\n *\n * The selection (`model_change`, `agent.state.model`, `ctx.model`) may name a virtual model.\n * Everything below the routing step only sees physical models: providers stream them and\n * assistant messages record them. A virtual model never reaches a provider.\n *\n * Virtual models belong to a provider id but are not provider models. `ModelRuntime` keeps them\n * separately and adds them to the provider's catalog with `withVirtualModels()`, so any provider,\n * including one with physical models, can list several virtual models.\n */\nimport type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport {\n\ttype AnyModel,\n\ttype Api,\n\ttype AssistantMessage,\n\ttype AssistantMessageEventStream,\n\tisModelType,\n\tlazyStream,\n\ttype Message,\n\ttype Model,\n\ttype ModelThinkingLevel,\n\ttype Provider,\n\ttype ThinkingLevelMap,\n} from \"@earendil-works/pi-ai\";\nimport type { SessionEntry } from \"./session-manager.ts\";\n\n/** API id of virtual catalog entries. Requests for it fail unless routed first. */\nexport const VIRTUAL_MODEL_API = \"pi-virtual\";\n\n/** Custom entry type that stores router state on the session branch. */\nexport const VIRTUAL_MODEL_STATE_ENTRY = \"pi.virtual-model-state\";\n\n/** Data of a `pi.virtual-model-state` custom entry. */\nexport interface VirtualModelStateData<TState = unknown> {\n\tprovider: string;\n\tmodelId: string;\n\tstate: TState;\n}\n\nconst THINKING_LEVELS: readonly ModelThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"];\n\n/**\n * Why a request is being routed.\n * - `user`: first request after a message the user wrote (prompt, steering, or follow-up)\n * - `continuation`: any other request in the agent loop, e.g. after tool results or extension messages\n * - `retry`: automatic retry after a failed request, including after compaction for a context overflow\n * - `direct`: a request outside the agent loop, e.g. a compaction summary or an extension call\n */\nexport type ModelRouteReason = \"user\" | \"continuation\" | \"retry\" | \"direct\";\n\nexport interface ModelRouteRequest<TState = unknown> {\n\t/** The selected virtual model. */\n\tmodel: Model<Api>;\n\t/** The selected thinking level. Its meaning is up to the router. */\n\tthinkingLevel: ModelThinkingLevel;\n\treason: ModelRouteReason;\n\t/** Physical model and thinking level of the latest successful response in `messages`. */\n\tprevious?: { model: Model<Api>; thinkingLevel?: ModelThinkingLevel };\n\t/**\n\t * For `retry`: the failed request, which `messages` no longer contains. `message` carries its\n\t * `stopReason` and `errorMessage`. Absent when the router itself failed.\n\t */\n\tfailed?: { model: Model<Api>; thinkingLevel?: ModelThinkingLevel; message: AssistantMessage };\n\t/** Router state last returned on this session branch. Undefined before the first state and for `direct` requests. */\n\tstate?: TState;\n\t/** Conversation for this request, including system messages. */\n\tmessages: readonly Message[];\n\tsignal?: AbortSignal;\n}\n\n/** Physical model and thinking level for one request. */\nexport interface ModelRoute<TState = unknown> {\n\tmodel: Model<Api>;\n\tthinkingLevel: ModelThinkingLevel;\n\t/**\n\t * New router state, stored on the session branch unless it is `request.state` itself. Return\n\t * `request.state` or undefined to keep the current state. Must be JSON-serializable. Ignored for\n\t * `direct` requests.\n\t */\n\tstate?: TState;\n}\n\nexport interface VirtualModelDefinition<TState = unknown> {\n\t/** Provider the virtual model is listed under. May be a provider with physical models. */\n\tprovider: string;\n\t/** Model id. Must not be the id of a physical model of `provider`. */\n\tid: string;\n\tname: string;\n\t/** Thinking levels offered for selection. Defaults to `[\"off\"]`. */\n\tthinkingLevels?: readonly ModelThinkingLevel[];\n\t/**\n\t * Limits shown before the first response. Afterwards, Pi uses the limits of the physical model\n\t * that answered. Unset limits are unknown (0).\n\t */\n\tcontextWindow?: number;\n\tmaxTokens?: number;\n\t/** Input types accepted for selection. Defaults to text and images; routed models without image support get placeholders. */\n\tinput?: (\"text\" | \"image\")[];\n\t/** Pick the physical model, which must have credentials, and thinking level for one request. */\n\troute(request: ModelRouteRequest<TState>): ModelRoute<TState> | Promise<ModelRoute<TState>>;\n}\n\n/** Whether a model or message names a virtual model. Failed routing leaves the virtual model on its message. */\nexport function isVirtualModel(model: { api: string }): boolean {\n\treturn model.api === VIRTUAL_MODEL_API;\n}\n\n/** Latest successful response. Its model is physical: failed or aborted requests, including failed routing, are skipped. */\nexport function findLatestResponse(messages: readonly AgentMessage[]): AssistantMessage | undefined {\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst message = messages[i];\n\t\tif (message.role === \"assistant\" && message.stopReason !== \"error\" && message.stopReason !== \"aborted\") {\n\t\t\treturn message;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * The model selection a session branch records. A virtual `model_change` holds until the next\n * `model_change`, because responses name the physical models it routed to. Otherwise the latest\n * physical response wins, as in sessions without virtual models. A virtual model that is no longer\n * registered does not hold, so the selection falls back to the physical model that answered last.\n *\n * Only the last `model_change` can hold, so this looks up at most one model in the catalog.\n */\nexport function getBranchSelection(\n\tbranch: readonly SessionEntry[],\n\tgetModel: (provider: string, modelId: string) => Model<Api> | undefined,\n): { provider: string; modelId: string } | undefined {\n\tfor (let i = branch.length - 1; i >= 0; i--) {\n\t\tconst entry = branch[i];\n\t\tif (entry.type === \"model_change\") {\n\t\t\treturn { provider: entry.provider, modelId: entry.modelId };\n\t\t}\n\t\tif (entry.type === \"message\" && entry.message.role === \"assistant\" && !isVirtualModel(entry.message)) {\n\t\t\tconst response = { provider: entry.message.provider, modelId: entry.message.model };\n\t\t\tconst change = findLastModelChange(branch, i);\n\t\t\tconst model = change && getModel(change.provider, change.modelId);\n\t\t\treturn change && model && isVirtualModel(model) ? change : response;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction findLastModelChange(\n\tbranch: readonly SessionEntry[],\n\tbefore: number,\n): { provider: string; modelId: string } | undefined {\n\tfor (let i = before - 1; i >= 0; i--) {\n\t\tconst entry = branch[i];\n\t\tif (entry.type === \"model_change\") return { provider: entry.provider, modelId: entry.modelId };\n\t}\n\treturn undefined;\n}\n\n/** Latest router state a session branch stores for a virtual model. */\nexport function getVirtualModelState(branch: readonly SessionEntry[], provider: string, modelId: string): unknown {\n\tfor (let i = branch.length - 1; i >= 0; i--) {\n\t\tconst entry = branch[i];\n\t\tif (entry.type !== \"custom\" || entry.customType !== VIRTUAL_MODEL_STATE_ENTRY) continue;\n\t\tconst data = entry.data as VirtualModelStateData | undefined;\n\t\tif (data?.provider === provider && data.modelId === modelId) return data.state;\n\t}\n\treturn undefined;\n}\n\n/** Build the catalog entry of a virtual model. */\nexport function createVirtualModel(definition: Omit<VirtualModelDefinition, \"route\">): Model<Api> {\n\tconst levels = definition.thinkingLevels ?? [\"off\"];\n\tconst thinkingLevelMap: ThinkingLevelMap = {};\n\tfor (const level of THINKING_LEVELS) thinkingLevelMap[level] = levels.includes(level) ? level : null;\n\treturn {\n\t\tid: definition.id,\n\t\tname: definition.name,\n\t\tapi: VIRTUAL_MODEL_API,\n\t\tprovider: definition.provider,\n\t\tbaseUrl: \"\",\n\t\treasoning: levels.some((level) => level !== \"off\"),\n\t\tthinkingLevelMap,\n\t\tinput: definition.input ?? [\"text\", \"image\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: definition.contextWindow ?? 0,\n\t\tmaxTokens: definition.maxTokens ?? 0,\n\t};\n}\n\n/** Stream for a virtual model that was not routed, e.g. `stream()` with API-specific options. */\nfunction unroutedStream(model: Model<Api>): AssistantMessageEventStream {\n\treturn lazyStream(model, async () => {\n\t\tthrow new Error(`Virtual model ${model.provider}/${model.id} must be routed before streaming`);\n\t});\n}\n\n/**\n * Add virtual models to a provider's catalog. Without a provider, the result is a keyless provider\n * that only lists the virtual models. A virtual model hides a physical chat model with the same id,\n * which a catalog refresh can add after registration. Availability follows the provider's auth.\n */\nexport function withVirtualModels(\n\tproviderId: string,\n\tprovider: Provider | undefined,\n\tvirtualModels: readonly Model<Api>[],\n): Provider {\n\tif (!provider) {\n\t\treturn {\n\t\t\tid: providerId,\n\t\t\tname: providerId,\n\t\t\tauth: { apiKey: { name: \"Virtual model\", resolve: async () => ({ auth: {}, source: \"virtual\" }) } },\n\t\t\tgetModels: () => virtualModels,\n\t\t\tstream: unroutedStream,\n\t\t\tstreamSimple: unroutedStream,\n\t\t};\n\t}\n\tconst ids = new Set(virtualModels.map((model) => model.id));\n\tconst physical = <TModel extends AnyModel>(models: readonly TModel[]) =>\n\t\tmodels.filter((model) => !isVirtualModel(model) && !(isModelType(model, \"chat\") && ids.has(model.id)));\n\tconst virtual = <TModel extends AnyModel>(models: readonly TModel[]) =>\n\t\tmodels.filter((model) => isVirtualModel(model));\n\tconst { filterModels, filterAllModels } = provider;\n\treturn {\n\t\t...provider,\n\t\tgetModels: () => [...physical(provider.getModels()), ...virtualModels],\n\t\tgetAllModels: () => [...physical(provider.getAllModels?.() ?? provider.getModels()), ...virtualModels],\n\t\tfilterModels: (models, credential) => {\n\t\t\tconst real = physical(models);\n\t\t\treturn [...(filterModels?.(real, credential) ?? real), ...virtual(models)];\n\t\t},\n\t\tfilterAllModels:\n\t\t\tfilterAllModels &&\n\t\t\t((models, credential) => [...filterAllModels(physical(models), credential), ...virtual(models)]),\n\t\tstream: (model, context, options) =>\n\t\t\tisVirtualModel(model) ? unroutedStream(model) : provider.stream(model, context, options),\n\t\tstreamSimple: (model, context, options) =>\n\t\t\tisVirtualModel(model) ? unroutedStream(model) : provider.streamSimple(model, context, options),\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/extensions/codemode/execute.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAmC,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAYtG,OAAO,KAAK,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/extensions/codemode/execute.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAmC,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAYtG,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,gCAAgC,CAAC;AAC1F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAGlE,OAAO,EAKN,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EAIxB,MAAM,WAAW,CAAC;AA+EnB,6FAA6F;AAC7F,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAU1F;AAsFD;;;GAGG;AACH,wBAAsB,eAAe,CACpC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,EAC9E,GAAG,EAAE,oBAAoB,GAAG,SAAS,EACrC,OAAO,GAAE,mBAAwB,GAC/B,OAAO,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC,CAgG/C"}
|
|
@@ -7,7 +7,7 @@ import { writeFile } from "node:fs/promises";
|
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { CodemodeSandbox, loadQuickJSWasm, parseCodemodeSource, renderToolSample, toCodemodeIdentifier, } from "@earendil-works/pi-codemode";
|
|
10
|
-
import {
|
|
10
|
+
import { getCodemodeWorkerSpecifier, getQuickJSWasmPath } from "../../config.js";
|
|
11
11
|
import { combineUsage } from "../../core/usage-totals.js";
|
|
12
12
|
import { Bm25Ranker, createToolSearchDocument, DEFAULT_TOOL_SEARCH_LIMIT } from "../tool-search/tool.js";
|
|
13
13
|
import { CODEMODE_STORE_ENTRY_TYPE, getCodemodeCallableTools, MODEL_GLOBAL_DECLARATIONS, toCodemodeDeclaration, } from "./tool.js";
|
|
@@ -237,7 +237,7 @@ export async function executeCodemode(toolCallId, input, signal, onUpdate, ctx,
|
|
|
237
237
|
timeoutMs: sourceOptions.timeoutMs ?? Number.POSITIVE_INFINITY,
|
|
238
238
|
memoryLimitBytes: CODEMODE_MEMORY_LIMIT_BYTES,
|
|
239
239
|
wasm: loadQuickJSWasm(getQuickJSWasmPath()),
|
|
240
|
-
workerUrl:
|
|
240
|
+
workerUrl: getCodemodeWorkerSpecifier(),
|
|
241
241
|
});
|
|
242
242
|
let result;
|
|
243
243
|
try {
|
|
@@ -278,7 +278,20 @@ export async function executeCodemode(toolCallId, input, signal, onUpdate, ctx,
|
|
|
278
278
|
...(result.ok ? {} : { isError: true }),
|
|
279
279
|
};
|
|
280
280
|
}
|
|
281
|
-
/**
|
|
281
|
+
/**
|
|
282
|
+
* Whether `query` names the namespace: its name, its script identifier (`mcp__dev-radius` is
|
|
283
|
+
* `mcp__dev_radius`), or the part after its last `__` in either form (`dev-radius`, `dev_radius`).
|
|
284
|
+
*/
|
|
285
|
+
function isNamespaceName(namespace, query) {
|
|
286
|
+
const id = toCodemodeIdentifier(namespace);
|
|
287
|
+
const queryId = toCodemodeIdentifier(query);
|
|
288
|
+
const suffix = (name) => (name.includes("__") ? name.slice(name.lastIndexOf("__") + 2) : undefined);
|
|
289
|
+
return namespace === query || id === queryId || suffix(namespace) === query || suffix(id) === queryId;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* `searchTools()`, `describeTool()`, and `describeNamespace()`: ranked search and lookup over the
|
|
293
|
+
* script's nested tools and their namespaces.
|
|
294
|
+
*/
|
|
282
295
|
function createDiscoveryGlobals(tools, samples, options) {
|
|
283
296
|
const ranker = new Bm25Ranker();
|
|
284
297
|
const entry = (name) => ({ name: toCodemodeIdentifier(name), description: samples.get(name) ?? "" });
|
|
@@ -300,7 +313,7 @@ function createDiscoveryGlobals(tools, samples, options) {
|
|
|
300
313
|
}
|
|
301
314
|
const documents = tools.flatMap((tool) => {
|
|
302
315
|
const toolNamespace = options.getToolNamespace?.(tool.name);
|
|
303
|
-
if (namespace && toolNamespace
|
|
316
|
+
if (namespace && (!toolNamespace || !isNamespaceName(toolNamespace.name, namespace)))
|
|
304
317
|
return [];
|
|
305
318
|
return [createToolSearchDocument(tool, toolNamespace)];
|
|
306
319
|
});
|
|
@@ -318,6 +331,32 @@ function createDiscoveryGlobals(tools, samples, options) {
|
|
|
318
331
|
return tool ? samples.get(tool.name) : undefined;
|
|
319
332
|
},
|
|
320
333
|
},
|
|
334
|
+
{
|
|
335
|
+
name: "describeNamespace",
|
|
336
|
+
spread: true,
|
|
337
|
+
execute: (args) => {
|
|
338
|
+
const [name] = args;
|
|
339
|
+
if (typeof name !== "string")
|
|
340
|
+
throw new Error("describeNamespace() expects a namespace name");
|
|
341
|
+
let namespace;
|
|
342
|
+
const names = [];
|
|
343
|
+
for (const tool of tools) {
|
|
344
|
+
const toolNamespace = options.getToolNamespace?.(tool.name);
|
|
345
|
+
if (!toolNamespace || !isNamespaceName(toolNamespace.name, name))
|
|
346
|
+
continue;
|
|
347
|
+
namespace ??= toolNamespace;
|
|
348
|
+
names.push(toCodemodeIdentifier(tool.name));
|
|
349
|
+
}
|
|
350
|
+
if (!namespace)
|
|
351
|
+
return undefined;
|
|
352
|
+
return {
|
|
353
|
+
name: namespace.name,
|
|
354
|
+
...(namespace.description ? { description: namespace.description } : {}),
|
|
355
|
+
...(namespace.instructions ? { instructions: namespace.instructions } : {}),
|
|
356
|
+
tools: names,
|
|
357
|
+
};
|
|
358
|
+
},
|
|
359
|
+
},
|
|
321
360
|
];
|
|
322
361
|
}
|
|
323
362
|
/**
|