@code-yeongyu/senpi 2026.8.11 → 2026.8.12
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 +185 -0
- package/dist/brand-dir-migration.d.ts +28 -0
- package/dist/brand-dir-migration.d.ts.map +1 -0
- package/dist/brand-dir-migration.js +77 -0
- package/dist/brand-dir-migration.js.map +1 -0
- package/dist/cli/grok-neo-gate.d.ts +0 -8
- package/dist/cli/grok-neo-gate.d.ts.map +1 -1
- package/dist/cli/grok-neo-gate.js +4 -2
- package/dist/cli/grok-neo-gate.js.map +1 -1
- package/dist/cli-main.d.ts +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli-main.js +4 -0
- package/dist/cli-main.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +27 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +41 -9
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +8 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +73 -11
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/brand.d.ts +79 -0
- package/dist/core/brand.d.ts.map +1 -0
- package/dist/core/brand.js +141 -0
- package/dist/core/brand.js.map +1 -0
- package/dist/core/dynamic-prompt/identity.d.ts.map +1 -1
- package/dist/core/dynamic-prompt/identity.js +2 -1
- package/dist/core/dynamic-prompt/identity.js.map +1 -1
- package/dist/core/event-bus.d.ts +5 -0
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +1 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +2 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/builtin/btw/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/btw/index.js +7 -2
- package/dist/core/extensions/builtin/btw/index.js.map +1 -1
- package/dist/core/extensions/builtin/btw/side-query.d.ts +2 -0
- package/dist/core/extensions/builtin/btw/side-query.d.ts.map +1 -1
- package/dist/core/extensions/builtin/btw/side-query.js +39 -2
- package/dist/core/extensions/builtin/btw/side-query.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/availability.d.ts +2 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/availability.d.ts.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/availability.js +24 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/availability.js.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts +4 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/index.js +5 -2
- package/dist/core/extensions/builtin/claude-sdk-oauth/index.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts +6 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js +16 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.js +10 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts +1 -0
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +1 -1
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.js +2 -1
- package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
- package/dist/core/extensions/builtin/config-reload/generated-shim-filter.d.ts.map +1 -1
- package/dist/core/extensions/builtin/config-reload/generated-shim-filter.js +4 -4
- package/dist/core/extensions/builtin/config-reload/generated-shim-filter.js.map +1 -1
- package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/index.js +5 -0
- package/dist/core/extensions/builtin/goal/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +2 -2
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +3 -3
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.js +6 -0
- package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/store.d.ts +3 -2
- package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/store.js +128 -101
- package/dist/core/extensions/builtin/goal/store.js.map +1 -1
- package/dist/core/extensions/builtin/goal/transitions.js +2 -1
- package/dist/core/extensions/builtin/goal/transitions.js.map +1 -1
- package/dist/core/extensions/builtin/help/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/help/index.js +3 -2
- package/dist/core/extensions/builtin/help/index.js.map +1 -1
- package/dist/core/extensions/builtin/imagegen/auth.d.ts +45 -0
- package/dist/core/extensions/builtin/imagegen/auth.d.ts.map +1 -0
- package/dist/core/extensions/builtin/imagegen/auth.js +137 -0
- package/dist/core/extensions/builtin/imagegen/auth.js.map +1 -0
- package/dist/core/extensions/builtin/imagegen/index.d.ts +5 -0
- package/dist/core/extensions/builtin/imagegen/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/imagegen/index.js +46 -0
- package/dist/core/extensions/builtin/imagegen/index.js.map +1 -0
- package/dist/core/extensions/builtin/imagegen/paths.d.ts +26 -0
- package/dist/core/extensions/builtin/imagegen/paths.d.ts.map +1 -0
- package/dist/core/extensions/builtin/imagegen/paths.js +52 -0
- package/dist/core/extensions/builtin/imagegen/paths.js.map +1 -0
- package/dist/core/extensions/builtin/imagegen/skill/SKILL.md +67 -0
- package/dist/core/extensions/builtin/imagegen/state.d.ts +26 -0
- package/dist/core/extensions/builtin/imagegen/state.d.ts.map +1 -0
- package/dist/core/extensions/builtin/imagegen/state.js +35 -0
- package/dist/core/extensions/builtin/imagegen/state.js.map +1 -0
- package/dist/core/extensions/builtin/imagegen/tool.d.ts +31 -0
- package/dist/core/extensions/builtin/imagegen/tool.d.ts.map +1 -0
- package/dist/core/extensions/builtin/imagegen/tool.js +174 -0
- package/dist/core/extensions/builtin/imagegen/tool.js.map +1 -0
- package/dist/core/extensions/builtin/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/index.js +9 -1
- package/dist/core/extensions/builtin/index.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/control-inventory.d.ts +14 -0
- package/dist/core/extensions/builtin/mcp/control-inventory.d.ts.map +1 -0
- package/dist/core/extensions/builtin/mcp/control-inventory.js +22 -0
- package/dist/core/extensions/builtin/mcp/control-inventory.js.map +1 -0
- package/dist/core/extensions/builtin/mcp/expose/native-search.d.ts +2 -44
- package/dist/core/extensions/builtin/mcp/expose/native-search.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/native-search.js +3 -97
- package/dist/core/extensions/builtin/mcp/expose/native-search.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/proxy.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/proxy.js +15 -4
- package/dist/core/extensions/builtin/mcp/expose/proxy.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/session.d.ts +2 -1
- package/dist/core/extensions/builtin/mcp/expose/session.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/session.js +2 -2
- package/dist/core/extensions/builtin/mcp/expose/session.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/tier-b.d.ts +13 -11
- package/dist/core/extensions/builtin/mcp/expose/tier-b.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/tier-b.js +58 -59
- package/dist/core/extensions/builtin/mcp/expose/tier-b.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/index.js +28 -36
- package/dist/core/extensions/builtin/mcp/index.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/service-register.d.ts +2 -1
- package/dist/core/extensions/builtin/mcp/service-register.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/service-register.js +2 -2
- package/dist/core/extensions/builtin/mcp/service-register.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/service-types.d.ts +4 -0
- package/dist/core/extensions/builtin/mcp/service-types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/service-types.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/service.d.ts +6 -11
- package/dist/core/extensions/builtin/mcp/service.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/service.js +79 -41
- package/dist/core/extensions/builtin/mcp/service.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/wrap.d.ts +2 -0
- package/dist/core/extensions/builtin/mcp/wrap.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/wrap.js +3 -0
- package/dist/core/extensions/builtin/mcp/wrap.js.map +1 -1
- package/dist/core/extensions/builtin/openai-image-gen/externalize.d.ts +27 -0
- package/dist/core/extensions/builtin/openai-image-gen/externalize.d.ts.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/externalize.js +133 -0
- package/dist/core/extensions/builtin/openai-image-gen/externalize.js.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/gate.d.ts +21 -0
- package/dist/core/extensions/builtin/openai-image-gen/gate.d.ts.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/gate.js +63 -0
- package/dist/core/extensions/builtin/openai-image-gen/gate.js.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/index.d.ts +14 -0
- package/dist/core/extensions/builtin/openai-image-gen/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/index.js +77 -0
- package/dist/core/extensions/builtin/openai-image-gen/index.js.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/inject.d.ts +15 -0
- package/dist/core/extensions/builtin/openai-image-gen/inject.d.ts.map +1 -0
- package/dist/core/extensions/builtin/openai-image-gen/inject.js +42 -0
- package/dist/core/extensions/builtin/openai-image-gen/inject.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.5.js +6 -5
- package/dist/core/extensions/builtin/prompt-preset/grok-4.5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.js +8 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/notify.d.ts +3 -1
- package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/notify.js +4 -1
- package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
- package/dist/core/extensions/builtin/tool-search/engine/bm25.d.ts +22 -0
- package/dist/core/extensions/builtin/tool-search/engine/bm25.d.ts.map +1 -0
- package/dist/core/extensions/builtin/{mcp/expose → tool-search/engine}/bm25.js +16 -31
- package/dist/core/extensions/builtin/tool-search/engine/bm25.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/engine/document.d.ts +14 -0
- package/dist/core/extensions/builtin/tool-search/engine/document.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/engine/document.js +2 -0
- package/dist/core/extensions/builtin/tool-search/engine/document.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/engine/marker.d.ts +55 -0
- package/dist/core/extensions/builtin/tool-search/engine/marker.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/engine/marker.js +189 -0
- package/dist/core/extensions/builtin/tool-search/engine/marker.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/index.d.ts +7 -0
- package/dist/core/extensions/builtin/tool-search/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/index.js +71 -0
- package/dist/core/extensions/builtin/tool-search/index.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/native-search.d.ts +52 -0
- package/dist/core/extensions/builtin/tool-search/native-search.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/native-search.js +116 -0
- package/dist/core/extensions/builtin/tool-search/native-search.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/service.d.ts +38 -0
- package/dist/core/extensions/builtin/tool-search/service.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/service.js +200 -0
- package/dist/core/extensions/builtin/tool-search/service.js.map +1 -0
- package/dist/core/extensions/builtin/tool-search/tool.d.ts +21 -0
- package/dist/core/extensions/builtin/tool-search/tool.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-search/tool.js +95 -0
- package/dist/core/extensions/builtin/tool-search/tool.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +31 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +28 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +61 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +11 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/generated-shim-banner.d.ts +15 -0
- package/dist/core/generated-shim-banner.d.ts.map +1 -0
- package/dist/core/generated-shim-banner.js +26 -0
- package/dist/core/generated-shim-banner.js.map +1 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +7 -3
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +2 -1
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/provider-composer.d.ts +10 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +9 -0
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +21 -10
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/session-log.d.ts.map +1 -1
- package/dist/core/session-log.js +4 -2
- package/dist/core/session-log.js.map +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +3 -2
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js +2 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts +0 -4
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +2 -1
- package/dist/core/timings.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inspector-policy.d.ts.map +1 -1
- package/dist/inspector-policy.js +2 -1
- package/dist/inspector-policy.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +5 -4
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -0
- package/dist/migrations.js.map +1 -1
- package/dist/modes/index.d.ts +2 -2
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts +2 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +10 -4
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +6 -5
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/cli-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/cli-tips.js +2 -1
- package/dist/modes/interactive/tips/catalog/cli-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/ethos-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/ethos-tips.js +4 -3
- package/dist/modes/interactive/tips/catalog/ethos-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/model-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/model-tips.js +2 -1
- package/dist/modes/interactive/tips/catalog/model-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/session-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/session-tips.js +2 -1
- package/dist/modes/interactive/tips/catalog/session-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/settings-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/settings-tips.js +3 -2
- package/dist/modes/interactive/tips/catalog/settings-tips.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/workspace-tips.d.ts.map +1 -1
- package/dist/modes/interactive/tips/catalog/workspace-tips.js +4 -3
- package/dist/modes/interactive/tips/catalog/workspace-tips.js.map +1 -1
- package/dist/modes/provider-native-rendering.d.ts.map +1 -1
- package/dist/modes/provider-native-rendering.js +33 -0
- package/dist/modes/provider-native-rendering.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +148 -5
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/custom-capability.d.ts +1 -0
- package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
- package/dist/modes/rpc/custom-capability.js +1 -0
- package/dist/modes/rpc/custom-capability.js.map +1 -1
- package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +4 -1
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +5 -2
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +10 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +2 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +47 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-binding.d.ts +2 -1
- package/dist/modes/rpc/session-binding.d.ts.map +1 -1
- package/dist/modes/rpc/session-binding.js +3 -2
- package/dist/modes/rpc/session-binding.js.map +1 -1
- package/dist/modes/rpc/session-command-router.d.ts +2 -1
- package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
- package/dist/modes/rpc/session-command-router.js +3 -2
- package/dist/modes/rpc/session-command-router.js.map +1 -1
- package/dist/nearest-parent-config.d.ts +6 -1
- package/dist/nearest-parent-config.d.ts.map +1 -1
- package/dist/nearest-parent-config.js +18 -2
- package/dist/nearest-parent-config.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +13 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.js +2 -0
- package/dist/rpc-entry.js.map +1 -1
- package/dist/self-update-bootstrap.d.ts.map +1 -1
- package/dist/self-update-bootstrap.js +6 -0
- package/dist/self-update-bootstrap.js.map +1 -1
- package/dist/senpi +3 -2
- package/dist/utils/pi-user-agent.d.ts +1 -1
- package/dist/utils/pi-user-agent.d.ts.map +1 -1
- package/dist/utils/pi-user-agent.js +4 -3
- package/dist/utils/pi-user-agent.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +2 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +3 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +37 -6
- package/dist/utils/version-check.js.map +1 -1
- package/dist/valid-cwd.d.ts +2 -0
- package/dist/valid-cwd.d.ts.map +1 -0
- package/dist/valid-cwd.js +14 -0
- package/dist/valid-cwd.js.map +1 -0
- package/docs/environment-variables.md +8 -1
- package/docs/extensions.md +93 -13
- package/docs/mcp.md +2 -0
- package/docs/providers.md +2 -2
- package/docs/rpc.md +126 -0
- package/docs/skills.md +8 -0
- package/examples/extensions/searchable-tools.ts +49 -0
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +77 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/kernel.ts +14 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/kernel.ts +14 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/runtime-asset.ts +31 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +5 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +4 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +2 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +9 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +4 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +7 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js +222 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.js +10 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +113 -4
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.d.ts +5 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/openai-codex.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +10 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +47 -0
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +47 -0
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.js +36 -13
- package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.js +18 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.js +16 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +7 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/wire-identity.d.ts +14 -0
- package/node_modules/@earendil-works/pi-ai/dist/wire-identity.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/wire-identity.js +24 -0
- package/node_modules/@earendil-works/pi-ai/dist/wire-identity.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js +11 -3
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +9 -9
- package/dist/core/extensions/builtin/mcp/expose/bm25.d.ts +0 -30
- package/dist/core/extensions/builtin/mcp/expose/bm25.d.ts.map +0 -1
- package/dist/core/extensions/builtin/mcp/expose/bm25.js.map +0 -1
- package/dist/core/extensions/builtin/mcp/expose/lazy-activate.d.ts +0 -15
- package/dist/core/extensions/builtin/mcp/expose/lazy-activate.d.ts.map +0 -1
- package/dist/core/extensions/builtin/mcp/expose/lazy-activate.js +0 -33
- package/dist/core/extensions/builtin/mcp/expose/lazy-activate.js.map +0 -1
- package/dist/core/extensions/builtin/mcp/expose/tool-search.d.ts +0 -43
- package/dist/core/extensions/builtin/mcp/expose/tool-search.d.ts.map +0 -1
- package/dist/core/extensions/builtin/mcp/expose/tool-search.js +0 -125
- package/dist/core/extensions/builtin/mcp/expose/tool-search.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAEhF,OAAO,EAAE,gCAAgC,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AACpG,OAAO,EAAE,oBAAoB,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACvG,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAExE,MAAM,UAAU,yBAAyB,CAAC,OAA0B;IACnE,OAAO,CAAC,EAAgB,EAAQ,EAAE;QACjC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAExB,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;YACtC,OAAO,CAAC,YAAY,EAAE,CAAC;YACvB,OAAO,CAAC,yBAAyB,CAAC,GAAG,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,OAAO,CAAC,yBAAyB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,yBAAyB,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC3E,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,OAAO,CAAC,iBAAiB,CAAC,GAAG,EAAE;YAC9B,IAAI,cAAc;gBAAE,OAAO;YAC3B,cAAc,GAAG,IAAI,CAAC;YACtB,EAAE,CAAC,YAAY,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,IAAI,gCAAgC,CAAC;YAC1D,OAAO,EAAE,GAAG,EAAE;gBACb,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;gBAC5C,OAAO,OAAO;qBACZ,UAAU,EAAE;qBACZ,IAAI,CACJ,CAAC,GAAG,EAAE,EAAE,CACP,CAAC,GAAG,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBACrD,CAAC,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,4BAA4B,EAAE,CAAC,CACzD,CAAC;YACJ,CAAC;YACD,UAAU,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE;YACtC,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC3B,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;gBAC3E,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;YACxG,CAAC;YACD,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE;gBACtB,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;gBAC9E,IAAI,GAAG,EAAE,MAAM,KAAK,KAAK;oBAAE,OAAO,4BAA4B,EAAE,CAAC;gBACjE,OAAO,GAAG,EAAE,MAAM,KAAK,WAAW,IAAI,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3E,CAAC;YACD,cAAc,EAAE,qBAAqB;SACrC,CAAC,CAAC;QACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAClH,EAAE,CAAC,EAAE,CAAC,yBAAyB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7F,CAAC,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB;IACxB,IAAI,CAAC;QACJ,mBAAmB,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAAgB;IAC3D,MAAM,OAAO,GAAG;QACf,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE;QACnC,cAAc,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE;QACzC,cAAc,EAAE,CAAC,KAAwB,EAAE,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;KAC3E,CAAC;IACF,MAAM,YAAY,GAAG,gBAAgB,EAAE,CAAC;IACxC,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9F,IAAI,YAAY;QAAE,8BAA8B,CAAC,OAAO,CAAC,CAAC;IAC1D,OAAO,yBAAyB,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC","sourcesContent":["import { bindToProviderScope } from \"@earendil-works/pi-ai/node/provider-scope\";\nimport type { ExtensionAPI, ExtensionFactory } from \"../../types.ts\";\nimport { AnthropicNativeToolSearchAdapter, isMcpNativeToolSearchEnabled } from \"./native-search.ts\";\nimport { getToolSearchService, installScopedToolSearchService, ToolSearchService } from \"./service.ts\";\nimport { createToolSearchTool, TOOL_SEARCH_TOOL_NAME } from \"./tool.ts\";\n\nexport function createToolSearchExtension(service: ToolSearchService): ExtensionFactory {\n\treturn (pi: ExtensionAPI): void => {\n\t\tservice.bindRuntime(pi);\n\n\t\tpi.on(\"session_start\", (_event, ctx) => {\n\t\t\tservice.beginSession();\n\t\t\tservice.maybeRehydrateFromHistory(ctx.sessionManager.getEntries());\n\t\t});\n\t\tpi.on(\"context\", (event) => {\n\t\t\tservice.maybeRehydrateFromHistory(event.messages);\n\t\t});\n\t\tpi.registerLazyToolActivator((toolName) => service.activateTool(toolName));\n\t\tlet toolRegistered = false;\n\t\tservice.bindToolRegistrar(() => {\n\t\t\tif (toolRegistered) return;\n\t\t\ttoolRegistered = true;\n\t\t\tpi.registerTool(createToolSearchTool(service));\n\t\t});\n\n\t\tconst nativeAdapter = new AnthropicNativeToolSearchAdapter({\n\t\t\tenabled: () => {\n\t\t\t\tconst active = new Set(pi.getActiveTools());\n\t\t\t\treturn service\n\t\t\t\t\t.getCatalog()\n\t\t\t\t\t.some(\n\t\t\t\t\t\t(doc) =>\n\t\t\t\t\t\t\t(doc.source === \"extension\" && !active.has(doc.name)) ||\n\t\t\t\t\t\t\t(doc.source === \"mcp\" && isMcpNativeToolSearchEnabled()),\n\t\t\t\t\t);\n\t\t\t},\n\t\t\tgetCatalog: () => service.getCatalog(),\n\t\t\tgetToolDefinition: (name) => {\n\t\t\t\tconst tool = pi.getAllTools().find((candidate) => candidate.name === name);\n\t\t\t\treturn tool === undefined ? undefined : { description: tool.description, parameters: tool.parameters };\n\t\t\t},\n\t\t\tisDeferrable: (name) => {\n\t\t\t\tconst doc = service.getCatalog().find((candidate) => candidate.name === name);\n\t\t\t\tif (doc?.source === \"mcp\") return isMcpNativeToolSearchEnabled();\n\t\t\t\treturn doc?.source === \"extension\" && !pi.getActiveTools().includes(name);\n\t\t\t},\n\t\t\tsearchToolName: TOOL_SEARCH_TOOL_NAME,\n\t\t});\n\t\tpi.on(\"before_provider_request\", (event, ctx) => nativeAdapter.applyBeforeRequest(ctx.model?.api, event.payload));\n\t\tpi.on(\"after_provider_response\", (event) => nativeAdapter.noteResponseStatus(event.status));\n\t};\n}\n\nfunction hasProviderScope(): boolean {\n\ttry {\n\t\tbindToProviderScope(() => undefined);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport default function toolSearchExtension(pi: ExtensionAPI): void | Promise<void> {\n\tconst runtime = {\n\t\tgetAllTools: () => pi.getAllTools(),\n\t\tgetActiveTools: () => pi.getActiveTools(),\n\t\tsetActiveTools: (names: readonly string[]) => pi.setActiveTools([...names]),\n\t};\n\tconst sessionOwned = hasProviderScope();\n\tconst service = sessionOwned ? new ToolSearchService(runtime) : getToolSearchService(runtime);\n\tif (sessionOwned) installScopedToolSearchService(service);\n\treturn createToolSearchExtension(service)(pi);\n}\n\nexport { getToolSearchService, ToolSearchService } from \"./service.ts\";\nexport { createToolSearchTool, TOOL_SEARCH_TOOL_NAME } from \"./tool.ts\";\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ToolSearchDocument } from "./engine/document.ts";
|
|
2
|
+
export declare const ANTHROPIC_TOOL_SEARCH_TYPE = "tool_search_tool_bm25_20251119";
|
|
3
|
+
export declare const ANTHROPIC_TOOL_SEARCH_NAME = "tool_search";
|
|
4
|
+
/** Anthropic caps a request at 10k tools; beyond that native search is invalid. */
|
|
5
|
+
export declare const ANTHROPIC_MAX_TOOLS = 10000;
|
|
6
|
+
type McpNativeToolSearchGate = () => boolean;
|
|
7
|
+
/** Bind the MCP-owned user setting without moving MCP configuration into the shared builtin. */
|
|
8
|
+
export declare function installMcpNativeToolSearchGate(gate: McpNativeToolSearchGate): void;
|
|
9
|
+
export declare function isMcpNativeToolSearchEnabled(): boolean;
|
|
10
|
+
export interface NativeToolDefinition {
|
|
11
|
+
readonly description?: string;
|
|
12
|
+
readonly parameters?: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface AnthropicNativeInjectionConfig {
|
|
15
|
+
/** Never defer this tool (our custom tool_search), and it is non-deferrable. */
|
|
16
|
+
readonly searchToolName?: string;
|
|
17
|
+
/** True only for catalog tools eligible for native deferral in this request. */
|
|
18
|
+
readonly isDeferrable: (toolName: string) => boolean;
|
|
19
|
+
/** Current searchable catalog. Omit when only transforming resident tools. */
|
|
20
|
+
readonly getCatalog?: () => readonly ToolSearchDocument[];
|
|
21
|
+
/** Resolve the winning registered definition used to inject inactive schemas. */
|
|
22
|
+
readonly getToolDefinition?: (toolName: string) => NativeToolDefinition | undefined;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Pure payload transform. Injects eligible inactive catalog schemas, adds exactly
|
|
26
|
+
* one native search tool, and enforces Anthropic's HARD RULES: never defer the
|
|
27
|
+
* local search tool, never combine defer_loading with cache_control, keep at
|
|
28
|
+
* least one non-deferred tool, and skip entirely above the 10k tool cap.
|
|
29
|
+
*/
|
|
30
|
+
export declare function addAnthropicNativeToolSearch(api: string | undefined, payload: unknown, config: AnthropicNativeInjectionConfig): unknown;
|
|
31
|
+
/** `tool_reference` blocks emitted inside a tool_result so the API expands the referenced tools. */
|
|
32
|
+
export declare function buildToolReferenceBlocks(names: readonly string[]): {
|
|
33
|
+
type: "tool_reference";
|
|
34
|
+
name: string;
|
|
35
|
+
}[];
|
|
36
|
+
export interface AnthropicNativeAdapterDeps extends AnthropicNativeInjectionConfig {
|
|
37
|
+
/** Resolved provider/config gate. */
|
|
38
|
+
enabled(): boolean;
|
|
39
|
+
/** Invoked once when a 400 forces the local-search fallback. */
|
|
40
|
+
onFallback?(reason: string): void;
|
|
41
|
+
}
|
|
42
|
+
/** Session-scoped request injector with permanent 400 fallback for the session. */
|
|
43
|
+
export declare class AnthropicNativeToolSearchAdapter {
|
|
44
|
+
#private;
|
|
45
|
+
constructor(deps: AnthropicNativeAdapterDeps);
|
|
46
|
+
applyBeforeRequest(api: string | undefined, payload: unknown): unknown;
|
|
47
|
+
noteResponseStatus(status: number): void;
|
|
48
|
+
get disabled(): boolean;
|
|
49
|
+
get fallbackReason(): string | null;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=native-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-search.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/native-search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAM/D,eAAO,MAAM,0BAA0B,mCAAmC,CAAC;AAC3E,eAAO,MAAM,0BAA0B,gBAAgB,CAAC;AACxD,mFAAmF;AACnF,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC,KAAK,uBAAuB,GAAG,MAAM,OAAO,CAAC;AAK7C,gGAAgG;AAChG,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,CAGlF;AAED,wBAAgB,4BAA4B,IAAI,OAAO,CAEtD;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,8BAA8B;IAC9C,gFAAgF;IAChF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,gFAAgF;IAChF,QAAQ,CAAC,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,SAAS,kBAAkB,EAAE,CAAC;IAC1D,iFAAiF;IACjF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,oBAAoB,GAAG,SAAS,CAAC;CACpF;AAMD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC3C,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,8BAA8B,GACpC,OAAO,CAYT;AAkCD,oGAAoG;AACpG,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAE7G;AAED,MAAM,WAAW,0BAA2B,SAAQ,8BAA8B;IACjF,qCAAqC;IACrC,OAAO,IAAI,OAAO,CAAC;IACnB,gEAAgE;IAChE,UAAU,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,mFAAmF;AACnF,qBAAa,gCAAgC;;IAM5C,YAAY,IAAI,EAAE,0BAA0B,EAE3C;IAED,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAMrE;IAED,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAMvC;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,cAAc,IAAI,MAAM,GAAG,IAAI,CAElC;CACD"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
// Anthropic Messages supports native BM25 tool search through request payload
|
|
3
|
+
// injection alone. OpenAI native client-mode search remains intentionally out of
|
|
4
|
+
// scope because it requires a provider-layer seam.
|
|
5
|
+
export const ANTHROPIC_TOOL_SEARCH_TYPE = "tool_search_tool_bm25_20251119";
|
|
6
|
+
export const ANTHROPIC_TOOL_SEARCH_NAME = "tool_search";
|
|
7
|
+
/** Anthropic caps a request at 10k tools; beyond that native search is invalid. */
|
|
8
|
+
export const ANTHROPIC_MAX_TOOLS = 10000;
|
|
9
|
+
const scopedMcpNativeToolSearchGate = new AsyncLocalStorage();
|
|
10
|
+
let mcpNativeToolSearchGate = () => false;
|
|
11
|
+
/** Bind the MCP-owned user setting without moving MCP configuration into the shared builtin. */
|
|
12
|
+
export function installMcpNativeToolSearchGate(gate) {
|
|
13
|
+
mcpNativeToolSearchGate = gate;
|
|
14
|
+
scopedMcpNativeToolSearchGate.enterWith(gate);
|
|
15
|
+
}
|
|
16
|
+
export function isMcpNativeToolSearchEnabled() {
|
|
17
|
+
return (scopedMcpNativeToolSearchGate.getStore() ?? mcpNativeToolSearchGate)();
|
|
18
|
+
}
|
|
19
|
+
function isRecord(value) {
|
|
20
|
+
return typeof value === "object" && value !== null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Pure payload transform. Injects eligible inactive catalog schemas, adds exactly
|
|
24
|
+
* one native search tool, and enforces Anthropic's HARD RULES: never defer the
|
|
25
|
+
* local search tool, never combine defer_loading with cache_control, keep at
|
|
26
|
+
* least one non-deferred tool, and skip entirely above the 10k tool cap.
|
|
27
|
+
*/
|
|
28
|
+
export function addAnthropicNativeToolSearch(api, payload, config) {
|
|
29
|
+
if (api !== "anthropic-messages" || !isRecord(payload))
|
|
30
|
+
return payload;
|
|
31
|
+
const tools = Array.isArray(payload.tools) ? payload.tools : [];
|
|
32
|
+
const injected = injectInactiveCatalogTools(tools, config);
|
|
33
|
+
if (injected.length > ANTHROPIC_MAX_TOOLS)
|
|
34
|
+
return payload;
|
|
35
|
+
const deferred = injected.map((tool) => maybeDefer(tool, config));
|
|
36
|
+
const hasSearchTool = deferred.some((tool) => isRecord(tool) && tool.type === ANTHROPIC_TOOL_SEARCH_TYPE);
|
|
37
|
+
const nextTools = hasSearchTool
|
|
38
|
+
? deferred
|
|
39
|
+
: [...deferred, { type: ANTHROPIC_TOOL_SEARCH_TYPE, name: ANTHROPIC_TOOL_SEARCH_NAME }];
|
|
40
|
+
if (nextTools.length > ANTHROPIC_MAX_TOOLS)
|
|
41
|
+
return payload;
|
|
42
|
+
return { ...payload, tools: nextTools };
|
|
43
|
+
}
|
|
44
|
+
function injectInactiveCatalogTools(tools, config) {
|
|
45
|
+
const catalog = config.getCatalog?.() ?? [];
|
|
46
|
+
const residentNames = new Set(tools.flatMap((tool) => (isRecord(tool) && typeof tool.name === "string" ? [tool.name] : [])));
|
|
47
|
+
const injected = [...tools];
|
|
48
|
+
for (const doc of catalog) {
|
|
49
|
+
if (doc.name === config.searchToolName || residentNames.has(doc.name) || !config.isDeferrable(doc.name))
|
|
50
|
+
continue;
|
|
51
|
+
const definition = config.getToolDefinition?.(doc.name);
|
|
52
|
+
if (definition?.parameters === undefined)
|
|
53
|
+
continue;
|
|
54
|
+
injected.push({
|
|
55
|
+
name: doc.name,
|
|
56
|
+
description: definition.description ?? doc.description ?? doc.label,
|
|
57
|
+
input_schema: definition.parameters,
|
|
58
|
+
defer_loading: true,
|
|
59
|
+
});
|
|
60
|
+
residentNames.add(doc.name);
|
|
61
|
+
}
|
|
62
|
+
return injected;
|
|
63
|
+
}
|
|
64
|
+
function maybeDefer(tool, config) {
|
|
65
|
+
if (!isRecord(tool))
|
|
66
|
+
return tool;
|
|
67
|
+
const name = typeof tool.name === "string" ? tool.name : undefined;
|
|
68
|
+
if (name === undefined)
|
|
69
|
+
return tool;
|
|
70
|
+
if (name === config.searchToolName)
|
|
71
|
+
return tool;
|
|
72
|
+
if (!config.isDeferrable(name))
|
|
73
|
+
return tool;
|
|
74
|
+
if ("cache_control" in tool)
|
|
75
|
+
return tool;
|
|
76
|
+
if (tool.defer_loading === true)
|
|
77
|
+
return tool;
|
|
78
|
+
return { ...tool, defer_loading: true };
|
|
79
|
+
}
|
|
80
|
+
/** `tool_reference` blocks emitted inside a tool_result so the API expands the referenced tools. */
|
|
81
|
+
export function buildToolReferenceBlocks(names) {
|
|
82
|
+
return names.map((name) => ({ type: "tool_reference", name }));
|
|
83
|
+
}
|
|
84
|
+
/** Session-scoped request injector with permanent 400 fallback for the session. */
|
|
85
|
+
export class AnthropicNativeToolSearchAdapter {
|
|
86
|
+
#disabled = false;
|
|
87
|
+
#injectedLastRequest = false;
|
|
88
|
+
#fallbackReason = null;
|
|
89
|
+
#deps;
|
|
90
|
+
constructor(deps) {
|
|
91
|
+
this.#deps = deps;
|
|
92
|
+
}
|
|
93
|
+
applyBeforeRequest(api, payload) {
|
|
94
|
+
this.#injectedLastRequest = false;
|
|
95
|
+
if (this.#disabled || !this.#deps.enabled())
|
|
96
|
+
return payload;
|
|
97
|
+
const next = addAnthropicNativeToolSearch(api, payload, this.#deps);
|
|
98
|
+
this.#injectedLastRequest = next !== payload;
|
|
99
|
+
return next;
|
|
100
|
+
}
|
|
101
|
+
noteResponseStatus(status) {
|
|
102
|
+
if (status !== 400 || !this.#injectedLastRequest || this.#disabled)
|
|
103
|
+
return;
|
|
104
|
+
this.#disabled = true;
|
|
105
|
+
this.#fallbackReason =
|
|
106
|
+
"Anthropic returned 400 for native tool-search; disabled it and fell back to local tool_search for this session.";
|
|
107
|
+
this.#deps.onFallback?.(this.#fallbackReason);
|
|
108
|
+
}
|
|
109
|
+
get disabled() {
|
|
110
|
+
return this.#disabled;
|
|
111
|
+
}
|
|
112
|
+
get fallbackReason() {
|
|
113
|
+
return this.#fallbackReason;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=native-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-search.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/native-search.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { ToolSearchDocument } from \"./engine/document.ts\";\n\n// Anthropic Messages supports native BM25 tool search through request payload\n// injection alone. OpenAI native client-mode search remains intentionally out of\n// scope because it requires a provider-layer seam.\n\nexport const ANTHROPIC_TOOL_SEARCH_TYPE = \"tool_search_tool_bm25_20251119\";\nexport const ANTHROPIC_TOOL_SEARCH_NAME = \"tool_search\";\n/** Anthropic caps a request at 10k tools; beyond that native search is invalid. */\nexport const ANTHROPIC_MAX_TOOLS = 10000;\n\ntype McpNativeToolSearchGate = () => boolean;\n\nconst scopedMcpNativeToolSearchGate = new AsyncLocalStorage<McpNativeToolSearchGate>();\nlet mcpNativeToolSearchGate: McpNativeToolSearchGate = () => false;\n\n/** Bind the MCP-owned user setting without moving MCP configuration into the shared builtin. */\nexport function installMcpNativeToolSearchGate(gate: McpNativeToolSearchGate): void {\n\tmcpNativeToolSearchGate = gate;\n\tscopedMcpNativeToolSearchGate.enterWith(gate);\n}\n\nexport function isMcpNativeToolSearchEnabled(): boolean {\n\treturn (scopedMcpNativeToolSearchGate.getStore() ?? mcpNativeToolSearchGate)();\n}\n\nexport interface NativeToolDefinition {\n\treadonly description?: string;\n\treadonly parameters?: unknown;\n}\n\nexport interface AnthropicNativeInjectionConfig {\n\t/** Never defer this tool (our custom tool_search), and it is non-deferrable. */\n\treadonly searchToolName?: string;\n\t/** True only for catalog tools eligible for native deferral in this request. */\n\treadonly isDeferrable: (toolName: string) => boolean;\n\t/** Current searchable catalog. Omit when only transforming resident tools. */\n\treadonly getCatalog?: () => readonly ToolSearchDocument[];\n\t/** Resolve the winning registered definition used to inject inactive schemas. */\n\treadonly getToolDefinition?: (toolName: string) => NativeToolDefinition | undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\n/**\n * Pure payload transform. Injects eligible inactive catalog schemas, adds exactly\n * one native search tool, and enforces Anthropic's HARD RULES: never defer the\n * local search tool, never combine defer_loading with cache_control, keep at\n * least one non-deferred tool, and skip entirely above the 10k tool cap.\n */\nexport function addAnthropicNativeToolSearch(\n\tapi: string | undefined,\n\tpayload: unknown,\n\tconfig: AnthropicNativeInjectionConfig,\n): unknown {\n\tif (api !== \"anthropic-messages\" || !isRecord(payload)) return payload;\n\tconst tools = Array.isArray(payload.tools) ? payload.tools : [];\n\tconst injected = injectInactiveCatalogTools(tools, config);\n\tif (injected.length > ANTHROPIC_MAX_TOOLS) return payload;\n\tconst deferred = injected.map((tool) => maybeDefer(tool, config));\n\tconst hasSearchTool = deferred.some((tool) => isRecord(tool) && tool.type === ANTHROPIC_TOOL_SEARCH_TYPE);\n\tconst nextTools = hasSearchTool\n\t\t? deferred\n\t\t: [...deferred, { type: ANTHROPIC_TOOL_SEARCH_TYPE, name: ANTHROPIC_TOOL_SEARCH_NAME }];\n\tif (nextTools.length > ANTHROPIC_MAX_TOOLS) return payload;\n\treturn { ...payload, tools: nextTools };\n}\n\nfunction injectInactiveCatalogTools(tools: readonly unknown[], config: AnthropicNativeInjectionConfig): unknown[] {\n\tconst catalog = config.getCatalog?.() ?? [];\n\tconst residentNames = new Set(\n\t\ttools.flatMap((tool) => (isRecord(tool) && typeof tool.name === \"string\" ? [tool.name] : [])),\n\t);\n\tconst injected: unknown[] = [...tools];\n\tfor (const doc of catalog) {\n\t\tif (doc.name === config.searchToolName || residentNames.has(doc.name) || !config.isDeferrable(doc.name)) continue;\n\t\tconst definition = config.getToolDefinition?.(doc.name);\n\t\tif (definition?.parameters === undefined) continue;\n\t\tinjected.push({\n\t\t\tname: doc.name,\n\t\t\tdescription: definition.description ?? doc.description ?? doc.label,\n\t\t\tinput_schema: definition.parameters,\n\t\t\tdefer_loading: true,\n\t\t});\n\t\tresidentNames.add(doc.name);\n\t}\n\treturn injected;\n}\n\nfunction maybeDefer(tool: unknown, config: AnthropicNativeInjectionConfig): unknown {\n\tif (!isRecord(tool)) return tool;\n\tconst name = typeof tool.name === \"string\" ? tool.name : undefined;\n\tif (name === undefined) return tool;\n\tif (name === config.searchToolName) return tool;\n\tif (!config.isDeferrable(name)) return tool;\n\tif (\"cache_control\" in tool) return tool;\n\tif (tool.defer_loading === true) return tool;\n\treturn { ...tool, defer_loading: true };\n}\n\n/** `tool_reference` blocks emitted inside a tool_result so the API expands the referenced tools. */\nexport function buildToolReferenceBlocks(names: readonly string[]): { type: \"tool_reference\"; name: string }[] {\n\treturn names.map((name) => ({ type: \"tool_reference\", name }));\n}\n\nexport interface AnthropicNativeAdapterDeps extends AnthropicNativeInjectionConfig {\n\t/** Resolved provider/config gate. */\n\tenabled(): boolean;\n\t/** Invoked once when a 400 forces the local-search fallback. */\n\tonFallback?(reason: string): void;\n}\n\n/** Session-scoped request injector with permanent 400 fallback for the session. */\nexport class AnthropicNativeToolSearchAdapter {\n\t#disabled = false;\n\t#injectedLastRequest = false;\n\t#fallbackReason: string | null = null;\n\treadonly #deps: AnthropicNativeAdapterDeps;\n\n\tconstructor(deps: AnthropicNativeAdapterDeps) {\n\t\tthis.#deps = deps;\n\t}\n\n\tapplyBeforeRequest(api: string | undefined, payload: unknown): unknown {\n\t\tthis.#injectedLastRequest = false;\n\t\tif (this.#disabled || !this.#deps.enabled()) return payload;\n\t\tconst next = addAnthropicNativeToolSearch(api, payload, this.#deps);\n\t\tthis.#injectedLastRequest = next !== payload;\n\t\treturn next;\n\t}\n\n\tnoteResponseStatus(status: number): void {\n\t\tif (status !== 400 || !this.#injectedLastRequest || this.#disabled) return;\n\t\tthis.#disabled = true;\n\t\tthis.#fallbackReason =\n\t\t\t\"Anthropic returned 400 for native tool-search; disabled it and fell back to local tool_search for this session.\";\n\t\tthis.#deps.onFallback?.(this.#fallbackReason);\n\t}\n\n\tget disabled(): boolean {\n\t\treturn this.#disabled;\n\t}\n\n\tget fallbackReason(): string | null {\n\t\treturn this.#fallbackReason;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ExtensionAPI, ToolInfo } from "../../types.ts";
|
|
2
|
+
import { type Bm25Result, type Bm25SearchOptions } from "./engine/bm25.ts";
|
|
3
|
+
import type { ToolSearchDocument } from "./engine/document.ts";
|
|
4
|
+
export interface ToolSearchFeederHooks {
|
|
5
|
+
/** Activate every named match, including names already active as stubs. */
|
|
6
|
+
activate(names: readonly string[]): void;
|
|
7
|
+
}
|
|
8
|
+
export interface ToolSearchRuntime {
|
|
9
|
+
getAllTools(): ToolInfo[];
|
|
10
|
+
getActiveTools(): string[];
|
|
11
|
+
setActiveTools(names: readonly string[]): void;
|
|
12
|
+
}
|
|
13
|
+
type RuntimeApi = Pick<ExtensionAPI, "getActiveTools" | "getAllTools" | "setActiveTools">;
|
|
14
|
+
/** Session-scoped owner of the live generalized tool-search catalog. */
|
|
15
|
+
export declare class ToolSearchService {
|
|
16
|
+
#private;
|
|
17
|
+
constructor(runtime: ToolSearchRuntime);
|
|
18
|
+
bindRuntime(runtime: RuntimeApi): void;
|
|
19
|
+
bindActivationRuntime(runtime: Pick<RuntimeApi, "getActiveTools" | "setActiveTools">): void;
|
|
20
|
+
/** Register the resident search tool only after a searchable catalog exists. */
|
|
21
|
+
bindToolRegistrar(register: () => void): void;
|
|
22
|
+
beginSession(): void;
|
|
23
|
+
/** Replace one source's catalog generation and activation hook. */
|
|
24
|
+
feed(source: "mcp", docs: readonly ToolSearchDocument[], hooks: ToolSearchFeederHooks): void;
|
|
25
|
+
getCatalog(): ToolSearchDocument[];
|
|
26
|
+
search(query: string, limit?: number, options?: Bm25SearchOptions): Bm25Result[];
|
|
27
|
+
/** Route all matches through their owning feeder, even when already active. */
|
|
28
|
+
activate(matches: readonly Bm25Result[]): string[];
|
|
29
|
+
activateTool(name: string): boolean;
|
|
30
|
+
/** Replay ownership-aware and legacy MCP history once per catalog generation. */
|
|
31
|
+
maybeRehydrateFromHistory(messages: readonly unknown[]): string[];
|
|
32
|
+
}
|
|
33
|
+
/** Make a session-owned service visible to later builtins loaded in the same provider scope. */
|
|
34
|
+
export declare function installScopedToolSearchService(value: ToolSearchService): void;
|
|
35
|
+
export declare function getToolSearchService(runtime?: ToolSearchRuntime): ToolSearchService;
|
|
36
|
+
export declare function resetToolSearchServiceForTests(): void;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAkB,MAAM,kBAAkB,CAAC;AAC3F,OAAO,KAAK,EAAE,kBAAkB,EAAoB,MAAM,sBAAsB,CAAC;AAIjF,MAAM,WAAW,qBAAqB;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IACjC,WAAW,IAAI,QAAQ,EAAE,CAAC;IAC1B,cAAc,IAAI,MAAM,EAAE,CAAC;IAC3B,cAAc,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CAC/C;AAED,KAAK,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,gBAAgB,GAAG,aAAa,GAAG,gBAAgB,CAAC,CAAC;AAO1F,wEAAwE;AACxE,qBAAa,iBAAiB;;IAS7B,YAAY,OAAO,EAAE,iBAAiB,EAMrC;IAED,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAErC;IAED,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,CAAC,GAAG,IAAI,CAE1F;IAED,gFAAgF;IAChF,iBAAiB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAE5C;IAED,YAAY,IAAI,IAAI,CAMnB;IAED,mEAAmE;IACnE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,kBAAkB,EAAE,EAAE,KAAK,EAAE,qBAAqB,GAAG,IAAI,CAK3F;IAED,UAAU,IAAI,kBAAkB,EAAE,CAGjC;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,EAAE,OAAO,GAAE,iBAAsB,GAAG,UAAU,EAAE,CAE/E;IAED,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,EAAE,CAYjD;IAED,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKlC;IAED,iFAAiF;IACjF,yBAAyB,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,EAAE,CAkBhE;CAoDD;AAkCD,gGAAgG;AAChG,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAE7E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,CAanF;AAED,wBAAgB,8BAA8B,IAAI,IAAI,CAErD"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
import { basename, extname } from "node:path";
|
|
3
|
+
import { buildBm25Index } from "./engine/bm25.js";
|
|
4
|
+
import { deriveExtensionRegistrationId, rehydrate } from "./engine/marker.js";
|
|
5
|
+
import { TOOL_SEARCH_TOOL_NAME } from "./tool.js";
|
|
6
|
+
/** Session-scoped owner of the live generalized tool-search catalog. */
|
|
7
|
+
export class ToolSearchService {
|
|
8
|
+
#runtime;
|
|
9
|
+
#feeds = new Map();
|
|
10
|
+
#extensionDocs = [];
|
|
11
|
+
#extensionFingerprint = "";
|
|
12
|
+
#registryGeneration = 0;
|
|
13
|
+
#historyScannedGeneration = -1;
|
|
14
|
+
#registerToolSearch;
|
|
15
|
+
constructor(runtime) {
|
|
16
|
+
this.#runtime = runtime;
|
|
17
|
+
this.#feeds.set("extension", {
|
|
18
|
+
docs: [],
|
|
19
|
+
hooks: { activate: (names) => this.#promoteExtensionTools(names) },
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
bindRuntime(runtime) {
|
|
23
|
+
this.#runtime = runtime;
|
|
24
|
+
}
|
|
25
|
+
bindActivationRuntime(runtime) {
|
|
26
|
+
this.#runtime = { ...this.#runtime, ...runtime };
|
|
27
|
+
}
|
|
28
|
+
/** Register the resident search tool only after a searchable catalog exists. */
|
|
29
|
+
bindToolRegistrar(register) {
|
|
30
|
+
this.#registerToolSearch = register;
|
|
31
|
+
}
|
|
32
|
+
beginSession() {
|
|
33
|
+
this.#feeds.delete("mcp");
|
|
34
|
+
this.#registryGeneration += 1;
|
|
35
|
+
this.#historyScannedGeneration = -1;
|
|
36
|
+
this.#refreshExtensionDocs();
|
|
37
|
+
this.#syncToolSearchLifecycle();
|
|
38
|
+
}
|
|
39
|
+
/** Replace one source's catalog generation and activation hook. */
|
|
40
|
+
feed(source, docs, hooks) {
|
|
41
|
+
const validDocs = docs.filter((doc) => isValidDocument(doc, source));
|
|
42
|
+
this.#feeds.set(source, { docs: validDocs, hooks });
|
|
43
|
+
this.#registryGeneration += 1;
|
|
44
|
+
this.#syncToolSearchLifecycle();
|
|
45
|
+
}
|
|
46
|
+
getCatalog() {
|
|
47
|
+
this.#refreshExtensionDocs();
|
|
48
|
+
return [...(this.#feeds.get("mcp")?.docs ?? []), ...this.#extensionDocs];
|
|
49
|
+
}
|
|
50
|
+
search(query, limit = 10, options = {}) {
|
|
51
|
+
return buildBm25Index(this.getCatalog()).search(query, limit, options);
|
|
52
|
+
}
|
|
53
|
+
/** Route all matches through their owning feeder, even when already active. */
|
|
54
|
+
activate(matches) {
|
|
55
|
+
const namesBySource = new Map();
|
|
56
|
+
for (const match of matches) {
|
|
57
|
+
const names = namesBySource.get(match.doc.source) ?? [];
|
|
58
|
+
names.push(match.name);
|
|
59
|
+
namesBySource.set(match.doc.source, names);
|
|
60
|
+
}
|
|
61
|
+
for (const [source, names] of namesBySource) {
|
|
62
|
+
this.#feeds.get(source)?.hooks.activate(names);
|
|
63
|
+
}
|
|
64
|
+
const active = new Set(this.#runtime.getActiveTools());
|
|
65
|
+
return matches.map(({ name }) => name).filter((name) => active.has(name));
|
|
66
|
+
}
|
|
67
|
+
activateTool(name) {
|
|
68
|
+
const doc = this.getCatalog().find((candidate) => candidate.name === name);
|
|
69
|
+
if (doc === undefined)
|
|
70
|
+
return false;
|
|
71
|
+
this.#feeds.get(doc.source)?.hooks.activate([name]);
|
|
72
|
+
return this.#runtime.getActiveTools().includes(name);
|
|
73
|
+
}
|
|
74
|
+
/** Replay ownership-aware and legacy MCP history once per catalog generation. */
|
|
75
|
+
maybeRehydrateFromHistory(messages) {
|
|
76
|
+
const catalog = this.getCatalog();
|
|
77
|
+
if (this.#historyScannedGeneration === this.#registryGeneration)
|
|
78
|
+
return [];
|
|
79
|
+
this.#historyScannedGeneration = this.#registryGeneration;
|
|
80
|
+
const docsByName = new Map(catalog.map((doc) => [
|
|
81
|
+
doc.name,
|
|
82
|
+
{
|
|
83
|
+
name: doc.name,
|
|
84
|
+
registrationId: doc.registrationId,
|
|
85
|
+
source: doc.source,
|
|
86
|
+
allowLazyActivation: true,
|
|
87
|
+
},
|
|
88
|
+
]));
|
|
89
|
+
const restored = rehydrate(messages, docsByName);
|
|
90
|
+
if (restored.length > 0)
|
|
91
|
+
this.#activateNames(restored, catalog);
|
|
92
|
+
return restored;
|
|
93
|
+
}
|
|
94
|
+
#refreshExtensionDocs() {
|
|
95
|
+
const docs = this.#runtime
|
|
96
|
+
.getAllTools()
|
|
97
|
+
.filter((tool) => tool.exposure === "search" && tool.allowLazyActivation)
|
|
98
|
+
.map(extensionDocument)
|
|
99
|
+
.filter((doc) => doc !== undefined)
|
|
100
|
+
.sort((left, right) => left.name.localeCompare(right.name));
|
|
101
|
+
const fingerprint = JSON.stringify(docs);
|
|
102
|
+
if (fingerprint === this.#extensionFingerprint)
|
|
103
|
+
return;
|
|
104
|
+
this.#extensionDocs = docs;
|
|
105
|
+
this.#extensionFingerprint = fingerprint;
|
|
106
|
+
this.#feeds.set("extension", {
|
|
107
|
+
docs,
|
|
108
|
+
hooks: { activate: (names) => this.#promoteExtensionTools(names) },
|
|
109
|
+
});
|
|
110
|
+
this.#registryGeneration += 1;
|
|
111
|
+
this.#syncToolSearchLifecycle();
|
|
112
|
+
}
|
|
113
|
+
#activateNames(names, catalog = this.getCatalog()) {
|
|
114
|
+
const sourceByName = new Map(catalog.map((doc) => [doc.name, doc.source]));
|
|
115
|
+
const namesBySource = new Map();
|
|
116
|
+
for (const name of names) {
|
|
117
|
+
const source = sourceByName.get(name);
|
|
118
|
+
if (source === undefined)
|
|
119
|
+
continue;
|
|
120
|
+
const sourceNames = namesBySource.get(source) ?? [];
|
|
121
|
+
sourceNames.push(name);
|
|
122
|
+
namesBySource.set(source, sourceNames);
|
|
123
|
+
}
|
|
124
|
+
for (const [source, sourceNames] of namesBySource)
|
|
125
|
+
this.#feeds.get(source)?.hooks.activate(sourceNames);
|
|
126
|
+
}
|
|
127
|
+
#syncToolSearchLifecycle() {
|
|
128
|
+
const hasDocuments = this.#extensionDocs.length > 0 || (this.#feeds.get("mcp")?.docs.length ?? 0) > 0;
|
|
129
|
+
if (hasDocuments)
|
|
130
|
+
this.#registerToolSearch?.();
|
|
131
|
+
const current = this.#runtime.getActiveTools();
|
|
132
|
+
const isActive = current.includes(TOOL_SEARCH_TOOL_NAME);
|
|
133
|
+
if (hasDocuments === isActive)
|
|
134
|
+
return;
|
|
135
|
+
this.#runtime.setActiveTools(hasDocuments ? [...current, TOOL_SEARCH_TOOL_NAME] : current.filter((name) => name !== TOOL_SEARCH_TOOL_NAME));
|
|
136
|
+
}
|
|
137
|
+
#promoteExtensionTools(names) {
|
|
138
|
+
if (names.length === 0)
|
|
139
|
+
return;
|
|
140
|
+
const current = this.#runtime.getActiveTools();
|
|
141
|
+
const active = new Set(current);
|
|
142
|
+
const added = [...new Set(names.filter((name) => !active.has(name)))].sort();
|
|
143
|
+
this.#runtime.setActiveTools([...current, ...added]);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function extensionDocument(tool) {
|
|
147
|
+
if (tool.name.length === 0)
|
|
148
|
+
return undefined;
|
|
149
|
+
const ownerLabel = extensionOwnerLabel(tool);
|
|
150
|
+
const registrationId = deriveExtensionRegistrationId(tool.sourceInfo, tool.name);
|
|
151
|
+
if (registrationId.length === 0)
|
|
152
|
+
return undefined;
|
|
153
|
+
return {
|
|
154
|
+
name: tool.name,
|
|
155
|
+
label: tool.label,
|
|
156
|
+
aliases: [],
|
|
157
|
+
description: tool.description,
|
|
158
|
+
searchText: tool.searchText,
|
|
159
|
+
keywords: tool.searchKeywords,
|
|
160
|
+
source: "extension",
|
|
161
|
+
group: tool.searchGroup ?? ownerLabel,
|
|
162
|
+
ownerLabel,
|
|
163
|
+
registrationId,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function extensionOwnerLabel(tool) {
|
|
167
|
+
const fileName = basename(tool.sourceInfo.path);
|
|
168
|
+
const extension = extname(fileName);
|
|
169
|
+
return extension.length === 0 ? fileName : fileName.slice(0, -extension.length);
|
|
170
|
+
}
|
|
171
|
+
function isValidDocument(doc, source) {
|
|
172
|
+
return doc.source === source && doc.name.length > 0 && doc.registrationId.length > 0;
|
|
173
|
+
}
|
|
174
|
+
const scopedService = new AsyncLocalStorage();
|
|
175
|
+
let service = null;
|
|
176
|
+
/** Make a session-owned service visible to later builtins loaded in the same provider scope. */
|
|
177
|
+
export function installScopedToolSearchService(value) {
|
|
178
|
+
scopedService.enterWith(value);
|
|
179
|
+
}
|
|
180
|
+
export function getToolSearchService(runtime) {
|
|
181
|
+
const scoped = scopedService.getStore();
|
|
182
|
+
if (scoped !== undefined) {
|
|
183
|
+
if (runtime !== undefined)
|
|
184
|
+
scoped.bindRuntime(runtime);
|
|
185
|
+
return scoped;
|
|
186
|
+
}
|
|
187
|
+
if (service === null) {
|
|
188
|
+
if (runtime === undefined)
|
|
189
|
+
throw new Error("ToolSearchService runtime is not bound");
|
|
190
|
+
service = new ToolSearchService(runtime);
|
|
191
|
+
}
|
|
192
|
+
else if (runtime !== undefined) {
|
|
193
|
+
service.bindRuntime(runtime);
|
|
194
|
+
}
|
|
195
|
+
return service;
|
|
196
|
+
}
|
|
197
|
+
export function resetToolSearchServiceForTests() {
|
|
198
|
+
service = null;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { basename, extname } from \"node:path\";\nimport type { ExtensionAPI, ToolInfo } from \"../../types.ts\";\nimport { type Bm25Result, type Bm25SearchOptions, buildBm25Index } from \"./engine/bm25.ts\";\nimport type { ToolSearchDocument, ToolSearchSource } from \"./engine/document.ts\";\nimport { deriveExtensionRegistrationId, rehydrate } from \"./engine/marker.ts\";\nimport { TOOL_SEARCH_TOOL_NAME } from \"./tool.ts\";\n\nexport interface ToolSearchFeederHooks {\n\t/** Activate every named match, including names already active as stubs. */\n\tactivate(names: readonly string[]): void;\n}\n\nexport interface ToolSearchRuntime {\n\tgetAllTools(): ToolInfo[];\n\tgetActiveTools(): string[];\n\tsetActiveTools(names: readonly string[]): void;\n}\n\ntype RuntimeApi = Pick<ExtensionAPI, \"getActiveTools\" | \"getAllTools\" | \"setActiveTools\">;\n\ninterface FeedState {\n\tdocs: ToolSearchDocument[];\n\thooks: ToolSearchFeederHooks;\n}\n\n/** Session-scoped owner of the live generalized tool-search catalog. */\nexport class ToolSearchService {\n\t#runtime: ToolSearchRuntime;\n\treadonly #feeds = new Map<ToolSearchSource, FeedState>();\n\t#extensionDocs: ToolSearchDocument[] = [];\n\t#extensionFingerprint = \"\";\n\t#registryGeneration = 0;\n\t#historyScannedGeneration = -1;\n\t#registerToolSearch: (() => void) | undefined;\n\n\tconstructor(runtime: ToolSearchRuntime) {\n\t\tthis.#runtime = runtime;\n\t\tthis.#feeds.set(\"extension\", {\n\t\t\tdocs: [],\n\t\t\thooks: { activate: (names) => this.#promoteExtensionTools(names) },\n\t\t});\n\t}\n\n\tbindRuntime(runtime: RuntimeApi): void {\n\t\tthis.#runtime = runtime;\n\t}\n\n\tbindActivationRuntime(runtime: Pick<RuntimeApi, \"getActiveTools\" | \"setActiveTools\">): void {\n\t\tthis.#runtime = { ...this.#runtime, ...runtime };\n\t}\n\n\t/** Register the resident search tool only after a searchable catalog exists. */\n\tbindToolRegistrar(register: () => void): void {\n\t\tthis.#registerToolSearch = register;\n\t}\n\n\tbeginSession(): void {\n\t\tthis.#feeds.delete(\"mcp\");\n\t\tthis.#registryGeneration += 1;\n\t\tthis.#historyScannedGeneration = -1;\n\t\tthis.#refreshExtensionDocs();\n\t\tthis.#syncToolSearchLifecycle();\n\t}\n\n\t/** Replace one source's catalog generation and activation hook. */\n\tfeed(source: \"mcp\", docs: readonly ToolSearchDocument[], hooks: ToolSearchFeederHooks): void {\n\t\tconst validDocs = docs.filter((doc) => isValidDocument(doc, source));\n\t\tthis.#feeds.set(source, { docs: validDocs, hooks });\n\t\tthis.#registryGeneration += 1;\n\t\tthis.#syncToolSearchLifecycle();\n\t}\n\n\tgetCatalog(): ToolSearchDocument[] {\n\t\tthis.#refreshExtensionDocs();\n\t\treturn [...(this.#feeds.get(\"mcp\")?.docs ?? []), ...this.#extensionDocs];\n\t}\n\n\tsearch(query: string, limit = 10, options: Bm25SearchOptions = {}): Bm25Result[] {\n\t\treturn buildBm25Index(this.getCatalog()).search(query, limit, options);\n\t}\n\n\t/** Route all matches through their owning feeder, even when already active. */\n\tactivate(matches: readonly Bm25Result[]): string[] {\n\t\tconst namesBySource = new Map<ToolSearchSource, string[]>();\n\t\tfor (const match of matches) {\n\t\t\tconst names = namesBySource.get(match.doc.source) ?? [];\n\t\t\tnames.push(match.name);\n\t\t\tnamesBySource.set(match.doc.source, names);\n\t\t}\n\t\tfor (const [source, names] of namesBySource) {\n\t\t\tthis.#feeds.get(source)?.hooks.activate(names);\n\t\t}\n\t\tconst active = new Set(this.#runtime.getActiveTools());\n\t\treturn matches.map(({ name }) => name).filter((name) => active.has(name));\n\t}\n\n\tactivateTool(name: string): boolean {\n\t\tconst doc = this.getCatalog().find((candidate) => candidate.name === name);\n\t\tif (doc === undefined) return false;\n\t\tthis.#feeds.get(doc.source)?.hooks.activate([name]);\n\t\treturn this.#runtime.getActiveTools().includes(name);\n\t}\n\n\t/** Replay ownership-aware and legacy MCP history once per catalog generation. */\n\tmaybeRehydrateFromHistory(messages: readonly unknown[]): string[] {\n\t\tconst catalog = this.getCatalog();\n\t\tif (this.#historyScannedGeneration === this.#registryGeneration) return [];\n\t\tthis.#historyScannedGeneration = this.#registryGeneration;\n\t\tconst docsByName = new Map(\n\t\t\tcatalog.map((doc) => [\n\t\t\t\tdoc.name,\n\t\t\t\t{\n\t\t\t\t\tname: doc.name,\n\t\t\t\t\tregistrationId: doc.registrationId,\n\t\t\t\t\tsource: doc.source,\n\t\t\t\t\tallowLazyActivation: true,\n\t\t\t\t},\n\t\t\t]),\n\t\t);\n\t\tconst restored = rehydrate(messages, docsByName);\n\t\tif (restored.length > 0) this.#activateNames(restored, catalog);\n\t\treturn restored;\n\t}\n\n\t#refreshExtensionDocs(): void {\n\t\tconst docs = this.#runtime\n\t\t\t.getAllTools()\n\t\t\t.filter((tool) => tool.exposure === \"search\" && tool.allowLazyActivation)\n\t\t\t.map(extensionDocument)\n\t\t\t.filter((doc): doc is ToolSearchDocument => doc !== undefined)\n\t\t\t.sort((left, right) => left.name.localeCompare(right.name));\n\t\tconst fingerprint = JSON.stringify(docs);\n\t\tif (fingerprint === this.#extensionFingerprint) return;\n\t\tthis.#extensionDocs = docs;\n\t\tthis.#extensionFingerprint = fingerprint;\n\t\tthis.#feeds.set(\"extension\", {\n\t\t\tdocs,\n\t\t\thooks: { activate: (names) => this.#promoteExtensionTools(names) },\n\t\t});\n\t\tthis.#registryGeneration += 1;\n\t\tthis.#syncToolSearchLifecycle();\n\t}\n\n\t#activateNames(names: readonly string[], catalog = this.getCatalog()): void {\n\t\tconst sourceByName = new Map(catalog.map((doc) => [doc.name, doc.source] as const));\n\t\tconst namesBySource = new Map<ToolSearchSource, string[]>();\n\t\tfor (const name of names) {\n\t\t\tconst source = sourceByName.get(name);\n\t\t\tif (source === undefined) continue;\n\t\t\tconst sourceNames = namesBySource.get(source) ?? [];\n\t\t\tsourceNames.push(name);\n\t\t\tnamesBySource.set(source, sourceNames);\n\t\t}\n\t\tfor (const [source, sourceNames] of namesBySource) this.#feeds.get(source)?.hooks.activate(sourceNames);\n\t}\n\n\t#syncToolSearchLifecycle(): void {\n\t\tconst hasDocuments = this.#extensionDocs.length > 0 || (this.#feeds.get(\"mcp\")?.docs.length ?? 0) > 0;\n\t\tif (hasDocuments) this.#registerToolSearch?.();\n\t\tconst current = this.#runtime.getActiveTools();\n\t\tconst isActive = current.includes(TOOL_SEARCH_TOOL_NAME);\n\t\tif (hasDocuments === isActive) return;\n\t\tthis.#runtime.setActiveTools(\n\t\t\thasDocuments ? [...current, TOOL_SEARCH_TOOL_NAME] : current.filter((name) => name !== TOOL_SEARCH_TOOL_NAME),\n\t\t);\n\t}\n\n\t#promoteExtensionTools(names: readonly string[]): void {\n\t\tif (names.length === 0) return;\n\t\tconst current = this.#runtime.getActiveTools();\n\t\tconst active = new Set(current);\n\t\tconst added = [...new Set(names.filter((name) => !active.has(name)))].sort();\n\t\tthis.#runtime.setActiveTools([...current, ...added]);\n\t}\n}\n\nfunction extensionDocument(tool: ToolInfo): ToolSearchDocument | undefined {\n\tif (tool.name.length === 0) return undefined;\n\tconst ownerLabel = extensionOwnerLabel(tool);\n\tconst registrationId = deriveExtensionRegistrationId(tool.sourceInfo, tool.name);\n\tif (registrationId.length === 0) return undefined;\n\treturn {\n\t\tname: tool.name,\n\t\tlabel: tool.label,\n\t\taliases: [],\n\t\tdescription: tool.description,\n\t\tsearchText: tool.searchText,\n\t\tkeywords: tool.searchKeywords,\n\t\tsource: \"extension\",\n\t\tgroup: tool.searchGroup ?? ownerLabel,\n\t\townerLabel,\n\t\tregistrationId,\n\t};\n}\n\nfunction extensionOwnerLabel(tool: ToolInfo): string {\n\tconst fileName = basename(tool.sourceInfo.path);\n\tconst extension = extname(fileName);\n\treturn extension.length === 0 ? fileName : fileName.slice(0, -extension.length);\n}\n\nfunction isValidDocument(doc: ToolSearchDocument, source: ToolSearchSource): boolean {\n\treturn doc.source === source && doc.name.length > 0 && doc.registrationId.length > 0;\n}\n\nconst scopedService = new AsyncLocalStorage<ToolSearchService>();\nlet service: ToolSearchService | null = null;\n\n/** Make a session-owned service visible to later builtins loaded in the same provider scope. */\nexport function installScopedToolSearchService(value: ToolSearchService): void {\n\tscopedService.enterWith(value);\n}\n\nexport function getToolSearchService(runtime?: ToolSearchRuntime): ToolSearchService {\n\tconst scoped = scopedService.getStore();\n\tif (scoped !== undefined) {\n\t\tif (runtime !== undefined) scoped.bindRuntime(runtime);\n\t\treturn scoped;\n\t}\n\tif (service === null) {\n\t\tif (runtime === undefined) throw new Error(\"ToolSearchService runtime is not bound\");\n\t\tservice = new ToolSearchService(runtime);\n\t} else if (runtime !== undefined) {\n\t\tservice.bindRuntime(runtime);\n\t}\n\treturn service;\n}\n\nexport function resetToolSearchServiceForTests(): void {\n\tservice = null;\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import type { ToolDefinition } from "../../types.ts";
|
|
3
|
+
import type { Bm25Result } from "./engine/bm25.ts";
|
|
4
|
+
import type { ToolSearchSource } from "./engine/document.ts";
|
|
5
|
+
import type { ToolSearchService } from "./service.ts";
|
|
6
|
+
export declare const TOOL_SEARCH_TOOL_NAME = "tool_search";
|
|
7
|
+
declare const ParamsSchema: Type.TObject<{
|
|
8
|
+
query: Type.TString;
|
|
9
|
+
source: Type.TOptional<Type.TUnion<[Type.TLiteral<"mcp">, Type.TLiteral<"extension">]>>;
|
|
10
|
+
group: Type.TOptional<Type.TString>;
|
|
11
|
+
}>;
|
|
12
|
+
export interface ToolSearchDetails {
|
|
13
|
+
query: string;
|
|
14
|
+
activated: string[];
|
|
15
|
+
}
|
|
16
|
+
type ToolSearchTool = ToolDefinition<typeof ParamsSchema, ToolSearchDetails, unknown>;
|
|
17
|
+
/** Author the single shared tool-search definition registered by this builtin. */
|
|
18
|
+
export declare function createToolSearchTool(service: ToolSearchService): ToolSearchTool;
|
|
19
|
+
export declare function buildToolSearchResultText(query: string, matches: readonly Bm25Result[], source: ToolSearchSource | undefined, group: string | undefined): string;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/tool.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AAGnD,QAAA,MAAM,YAAY;;;;EAQhB,CAAC;AAGH,MAAM,WAAW,iBAAiB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,KAAK,cAAc,GAAG,cAAc,CAAC,OAAO,YAAY,EAAE,iBAAiB,EAAE,OAAO,CAAC,CAAC;AAEtF,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAyC/E;AAYD,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,KAAK,EAAE,MAAM,GAAG,SAAS,GACvB,MAAM,CAwBR"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
import { emitActivationMarker } from "./engine/marker.js";
|
|
4
|
+
export const TOOL_SEARCH_TOOL_NAME = "tool_search";
|
|
5
|
+
const MAX_RESULTS = 10;
|
|
6
|
+
const ParamsSchema = Type.Object({
|
|
7
|
+
query: Type.String({ description: "Natural-language description of the capability you need." }),
|
|
8
|
+
source: Type.Optional(Type.Union([Type.Literal("mcp"), Type.Literal("extension")], {
|
|
9
|
+
description: "Optional: restrict the search to MCP or extension tools.",
|
|
10
|
+
})),
|
|
11
|
+
group: Type.Optional(Type.String({ description: "Optional: restrict the search to one catalog group." })),
|
|
12
|
+
});
|
|
13
|
+
/** Author the single shared tool-search definition registered by this builtin. */
|
|
14
|
+
export function createToolSearchTool(service) {
|
|
15
|
+
return {
|
|
16
|
+
name: TOOL_SEARCH_TOOL_NAME,
|
|
17
|
+
label: "Tool search",
|
|
18
|
+
description: "Search the catalog of available tools by capability; matched tools are activated and become callable on your NEXT turn.",
|
|
19
|
+
promptSnippet: "Search available tool catalogs by capability; matched tools activate next turn.",
|
|
20
|
+
parameters: ParamsSchema,
|
|
21
|
+
prepareArguments: prepareToolSearchArguments,
|
|
22
|
+
executionMode: "parallel",
|
|
23
|
+
async execute(_toolCallId, params) {
|
|
24
|
+
const options = {
|
|
25
|
+
...(params.source === undefined ? {} : { source: params.source }),
|
|
26
|
+
...(params.group === undefined ? {} : { group: params.group }),
|
|
27
|
+
};
|
|
28
|
+
const matches = service.search(params.query, MAX_RESULTS, options);
|
|
29
|
+
const activated = service.activate(matches);
|
|
30
|
+
return {
|
|
31
|
+
content: [
|
|
32
|
+
{ type: "text", text: buildToolSearchResultText(params.query, matches, params.source, params.group) },
|
|
33
|
+
],
|
|
34
|
+
details: { activated, query: params.query },
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
renderCall(args, theme) {
|
|
38
|
+
const source = args.source === undefined ? "" : ` source:${args.source}`;
|
|
39
|
+
const group = args.group === undefined ? "" : ` @${args.group}`;
|
|
40
|
+
return new Text(theme.fg("toolTitle", theme.bold(`${TOOL_SEARCH_TOOL_NAME} "${args.query}"${source}${group}`)), 0, 0);
|
|
41
|
+
},
|
|
42
|
+
renderResult(result, options, theme) {
|
|
43
|
+
const count = result.details?.activated.length ?? 0;
|
|
44
|
+
const title = options.isPartial
|
|
45
|
+
? `${TOOL_SEARCH_TOOL_NAME}: searching`
|
|
46
|
+
: `${TOOL_SEARCH_TOOL_NAME}: ${count} tool(s) activated`;
|
|
47
|
+
return new Text(theme.fg("toolOutput", title), 0, 0);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function prepareToolSearchArguments(args) {
|
|
52
|
+
if (!isRecord(args))
|
|
53
|
+
return args;
|
|
54
|
+
const { server, ...rest } = args;
|
|
55
|
+
return {
|
|
56
|
+
...rest,
|
|
57
|
+
...(rest.source === undefined && server === undefined ? {} : { source: rest.source ?? "mcp" }),
|
|
58
|
+
...(rest.group === undefined && server === undefined ? {} : { group: rest.group ?? server }),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function buildToolSearchResultText(query, matches, source, group) {
|
|
62
|
+
const scope = [
|
|
63
|
+
source === undefined ? undefined : `source "${source}"`,
|
|
64
|
+
group === undefined ? undefined : `group "${group}"`,
|
|
65
|
+
]
|
|
66
|
+
.filter((part) => part !== undefined)
|
|
67
|
+
.join(" in ");
|
|
68
|
+
const scopeText = scope.length === 0 ? "" : ` in ${scope}`;
|
|
69
|
+
if (matches.length === 0) {
|
|
70
|
+
return `No tools matched "${query}"${scopeText}. No tools were activated; try different keywords or run tool_search with a broader query. Your active tool set is unchanged.`;
|
|
71
|
+
}
|
|
72
|
+
const bullets = matches
|
|
73
|
+
.map((match) => `- ${match.name} — ${oneLine(match.doc.description) ?? "(no description)"}`)
|
|
74
|
+
.join("\n");
|
|
75
|
+
const marker = emitActivationMarker(matches.map((match) => ({ name: match.name, registrationId: match.doc.registrationId })));
|
|
76
|
+
return [
|
|
77
|
+
`Found ${matches.length} tool(s) matching "${query}"${scopeText}. Matched tools are now active and callable from your NEXT turn:`,
|
|
78
|
+
"",
|
|
79
|
+
bullets,
|
|
80
|
+
"",
|
|
81
|
+
marker,
|
|
82
|
+
].join("\n");
|
|
83
|
+
}
|
|
84
|
+
function isRecord(value) {
|
|
85
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
86
|
+
}
|
|
87
|
+
function oneLine(text) {
|
|
88
|
+
if (text === undefined)
|
|
89
|
+
return undefined;
|
|
90
|
+
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
91
|
+
if (collapsed.length === 0)
|
|
92
|
+
return undefined;
|
|
93
|
+
return collapsed.length <= 100 ? collapsed : `${collapsed.slice(0, 97)}...`;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=tool.js.map
|