@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
|
@@ -20,7 +20,9 @@ export interface TerminalNotifierDeps {
|
|
|
20
20
|
/** Max chars of sanitized final output embedded in a completion notification. */
|
|
21
21
|
export declare const NOTICE_TAIL_MAX_CHARS = 2000;
|
|
22
22
|
export interface TerminalNotificationDelivery {
|
|
23
|
-
readonly send: (content: string
|
|
23
|
+
readonly send: (content: string, options?: {
|
|
24
|
+
readonly forceWake?: boolean;
|
|
25
|
+
}) => void;
|
|
24
26
|
}
|
|
25
27
|
/** Shared terminal-notification guard and notify-mode mapping. */
|
|
26
28
|
export declare function getTerminalNotificationDelivery(deps: TerminalNotifierDeps, customType?: string): TerminalNotificationDelivery | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/notify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,aAA6B,CAAC;AAChE,eAAO,MAAM,iCAAiC,gCAAgC,CAAC;AAE/E,MAAM,WAAW,oBAAoB;IACpC,mFAAmF;IACnF,QAAQ,CAAC,WAAW,EAAE,CACrB,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,EAClE,OAAO,EAAE;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,GAAG,UAAU,CAAA;KAAE,KAC9D,IAAI,CAAC;IACV,QAAQ,CAAC,UAAU,EAAE,MAAM,gBAAgB,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,UAAU,CAAC;CACnC;AAED,iFAAiF;AACjF,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/notify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,aAA6B,CAAC;AAChE,eAAO,MAAM,iCAAiC,gCAAgC,CAAC;AAE/E,MAAM,WAAW,oBAAoB;IACpC,mFAAmF;IACnF,QAAQ,CAAC,WAAW,EAAE,CACrB,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,EAClE,OAAO,EAAE;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,GAAG,UAAU,CAAA;KAAE,KAC9D,IAAI,CAAC;IACV,QAAQ,CAAC,UAAU,EAAE,MAAM,gBAAgB,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,UAAU,CAAC;CACnC;AAED,iFAAiF;AACjF,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CACrF;AAED,kEAAkE;AAClE,wBAAgB,+BAA+B,CAC9C,IAAI,EAAE,oBAAoB,EAC1B,UAAU,SAAoC,GAC5C,4BAA4B,GAAG,SAAS,CAe1C;AAmBD;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAE5C,YAAY,IAAI,EAAE,oBAAoB,EAErC;IAED,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAOlE;CACD"}
|
|
@@ -14,7 +14,10 @@ export function getTerminalNotificationDelivery(deps, customType = TERMINAL_NOTI
|
|
|
14
14
|
if (!ctx || NON_INTERACTIVE_MODES.has(ctx.mode) || !ctx.model)
|
|
15
15
|
return undefined;
|
|
16
16
|
return {
|
|
17
|
-
send: (content) => deps.sendMessage({ customType, content, display: false }, {
|
|
17
|
+
send: (content, options) => deps.sendMessage({ customType, content, display: false }, {
|
|
18
|
+
triggerTurn: true,
|
|
19
|
+
deliverAs: mode === "wake" || options?.forceWake === true ? "steer" : "followUp",
|
|
20
|
+
}),
|
|
18
21
|
};
|
|
19
22
|
}
|
|
20
23
|
function buildNotice(id, runtime) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/notify.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,uEAAuE;AACvE,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAChE,MAAM,CAAC,MAAM,iCAAiC,GAAG,6BAA6B,CAAC;AAY/E,iFAAiF;AACjF,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAM1C,kEAAkE;AAClE,MAAM,UAAU,+BAA+B,CAC9C,IAA0B,EAC1B,UAAU,GAAG,iCAAiC;IAE9C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC5B,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;IAC9B,IAAI,CAAC,GAAG,IAAI,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAChF,OAAO;QACN,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"notify.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/notify.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,uEAAuE;AACvE,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAChE,MAAM,CAAC,MAAM,iCAAiC,GAAG,6BAA6B,CAAC;AAY/E,iFAAiF;AACjF,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAM1C,kEAAkE;AAClE,MAAM,UAAU,+BAA+B,CAC9C,IAA0B,EAC1B,UAAU,GAAG,iCAAiC;IAE9C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC5B,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;IAC9B,IAAI,CAAC,GAAG,IAAI,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAChF,OAAO;QACN,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAC1B,IAAI,CAAC,WAAW,CACf,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EACvC;YACC,WAAW,EAAE,IAAI;YACjB,SAAS,EAAE,IAAI,KAAK,MAAM,IAAI,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU;SAChF,CACD;KACF,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,EAAU,EAAE,OAA+B;IAC/D,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,IAAI,GAAG,CAAC;IACnF,MAAM,IAAI,GAAG,sBAAsB,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;IACpE,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,qBAAqB,CAAC;QACtD,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACjF,MAAM,IAAI,GAAG,SAAS;YACrB,CAAC,CAAC,yCAAyC,qBAAqB,8CAA8C;YAC9G,CAAC,CAAC,EAAE,CAAC;QACN,WAAW,GAAG,oBAAoB,KAAK,GAAG,IAAI,EAAE,CAAC;IAClD,CAAC;IACD,OAAO,gDAAgD,EAAE,cAAc,MAAM,GAAG,QAAQ,IAAI,WAAW,oBAAoB,CAAC;AAC7H,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,gBAAgB;IAI5B,YAAY,IAA0B;QAHrB,aAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QAI7C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,gBAAgB,CAAC,EAAU,EAAE,OAA+B;QAC3D,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO;QAClC,MAAM,QAAQ,GAAG,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;IACzC,CAAC;CACD","sourcesContent":["import type { ExtensionContext } from \"../../types.ts\";\nimport { sanitizeTerminalOutput } from \"./output-format.ts\";\nimport type { TerminalRuntimeSession } from \"./runtime-session.ts\";\nimport type { NotifyMode } from \"./settings.ts\";\nimport { describeExit } from \"./tools/spawn.ts\";\n\n/** Modes that never wake the agent: one-shot, non-interactive runs. */\nexport const NON_INTERACTIVE_MODES = new Set([\"print\", \"json\"]);\nexport const TERMINAL_NOTIFICATION_CUSTOM_TYPE = \"senpi-terminal:notification\";\n\nexport interface TerminalNotifierDeps {\n\t/** Deliver a model-visible notification without rendering synthetic user input. */\n\treadonly sendMessage: (\n\t\tmessage: { customType: string; content: string; display: boolean },\n\t\toptions: { triggerTurn: boolean; deliverAs: \"steer\" | \"followUp\" },\n\t) => void;\n\treadonly getContext: () => ExtensionContext | undefined;\n\treadonly getMode: () => NotifyMode;\n}\n\n/** Max chars of sanitized final output embedded in a completion notification. */\nexport const NOTICE_TAIL_MAX_CHARS = 2000;\n\nexport interface TerminalNotificationDelivery {\n\treadonly send: (content: string, options?: { readonly forceWake?: boolean }) => void;\n}\n\n/** Shared terminal-notification guard and notify-mode mapping. */\nexport function getTerminalNotificationDelivery(\n\tdeps: TerminalNotifierDeps,\n\tcustomType = TERMINAL_NOTIFICATION_CUSTOM_TYPE,\n): TerminalNotificationDelivery | undefined {\n\tconst mode = deps.getMode();\n\tif (mode === \"off\") return undefined;\n\tconst ctx = deps.getContext();\n\tif (!ctx || NON_INTERACTIVE_MODES.has(ctx.mode) || !ctx.model) return undefined;\n\treturn {\n\t\tsend: (content, options) =>\n\t\t\tdeps.sendMessage(\n\t\t\t\t{ customType, content, display: false },\n\t\t\t\t{\n\t\t\t\t\ttriggerTurn: true,\n\t\t\t\t\tdeliverAs: mode === \"wake\" || options?.forceWake === true ? \"steer\" : \"followUp\",\n\t\t\t\t},\n\t\t\t),\n\t};\n}\n\nfunction buildNotice(id: string, runtime: TerminalRuntimeSession): string {\n\tconst status = describeExit(runtime) ?? \"exited\";\n\tconst code = runtime.exitResult?.exitCode;\n\tconst codeText = code === null || code === undefined ? \"\" : ` (exit code ${code})`;\n\tconst tail = sanitizeTerminalOutput(runtime.fullOutput()).trimEnd();\n\tlet tailSection = \"\";\n\tif (tail.length > 0) {\n\t\tconst truncated = tail.length > NOTICE_TAIL_MAX_CHARS;\n\t\tconst shown = truncated ? tail.slice(tail.length - NOTICE_TAIL_MAX_CHARS) : tail;\n\t\tconst note = truncated\n\t\t\t? `\\n[Final output truncated to the last ${NOTICE_TAIL_MAX_CHARS} chars; the full history is still peekable.]`\n\t\t\t: \"\";\n\t\ttailSection = `\\nFinal output:\\n${shown}${note}`;\n\t}\n\treturn `<system-reminder>Background terminal session ${id} finished: ${status}${codeText}.${tailSection}</system-reminder>`;\n}\n\n/**\n * Notifies an interactive agent once when a background session completes.\n *\n * Guards (todo 23): never wakes in one-shot `-p`/`--print`/`--mode json` runs; never wakes\n * without an active model (would spin an auth-less turn); `notify:\"off\"` suppresses entirely;\n * each session id fires at most once. `wake` steers immediately; `next-turn` queues a follow-up.\n */\nexport class TerminalNotifier {\n\tprivate readonly notified = new Set<string>();\n\tprivate readonly deps: TerminalNotifierDeps;\n\n\tconstructor(deps: TerminalNotifierDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tnotifyCompletion(id: string, runtime: TerminalRuntimeSession): void {\n\t\tif (this.notified.has(id)) return;\n\t\tconst delivery = getTerminalNotificationDelivery(this.deps);\n\t\tif (!delivery) return;\n\n\t\tthis.notified.add(id);\n\t\tdelivery.send(buildNotice(id, runtime));\n\t}\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ToolSearchDocument, ToolSearchSource } from "./document.ts";
|
|
2
|
+
export interface Bm25Result {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly score: number;
|
|
5
|
+
readonly exact: boolean;
|
|
6
|
+
readonly doc: ToolSearchDocument;
|
|
7
|
+
}
|
|
8
|
+
export interface Bm25SearchOptions {
|
|
9
|
+
readonly source?: ToolSearchSource;
|
|
10
|
+
readonly group?: string;
|
|
11
|
+
/** Disable the exact-name short-circuit (used to prove BM25-alone behaviour). */
|
|
12
|
+
readonly exactMatch?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface Bm25Index {
|
|
15
|
+
search(query: string, limit?: number, options?: Bm25SearchOptions): Bm25Result[];
|
|
16
|
+
}
|
|
17
|
+
export declare function buildBm25Index(docs: readonly ToolSearchDocument[]): Bm25Index;
|
|
18
|
+
/** Tokenise searchable text into lowercase word tokens, splitting identifiers. */
|
|
19
|
+
export declare function tokenizeToolText(text: string): string[];
|
|
20
|
+
/** Normalize a searchable name for separator- and case-insensitive exact matching. */
|
|
21
|
+
export declare function normalizeToolName(name: string): string;
|
|
22
|
+
//# sourceMappingURL=bm25.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bm25.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/tool-search/engine/bm25.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAS1E,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,kBAAkB,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACzB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,UAAU,EAAE,CAAC;CACjF;AAWD,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAAG,SAAS,CAmC7E;AA6DD,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CASvD;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD"}
|
|
@@ -1,19 +1,7 @@
|
|
|
1
|
-
// Zero-dependency BM25 tool-search engine (todo 30).
|
|
2
|
-
//
|
|
3
|
-
// Ranks MCP tools by relevance of a free-text query against tokenised
|
|
4
|
-
// name + description, with a server-name field boost. A normalised exact-name
|
|
5
|
-
// match short-circuits BEFORE BM25 (hyphen/underscore/case-insensitive) so a
|
|
6
|
-
// query equal to a tool's own name always wins rank-1 even when raw BM25
|
|
7
|
-
// term-frequency would float noisier tools above it (codex #21503 regression
|
|
8
|
-
// class). Constants k1=0.9, b=0.4 are SPEC-verified.
|
|
9
|
-
//
|
|
10
|
-
// Ranking is deterministic: equal scores tie-break by ascending full name.
|
|
11
1
|
const BM25_K1 = 0.9;
|
|
12
2
|
const BM25_B = 0.4;
|
|
13
|
-
// Field weights applied to term frequency. Name tokens matter most; the server
|
|
14
|
-
// name gets a modest boost; description is the baseline signal.
|
|
15
3
|
const NAME_FIELD_WEIGHT = 3;
|
|
16
|
-
const
|
|
4
|
+
const GROUP_FIELD_WEIGHT = 2;
|
|
17
5
|
const DESCRIPTION_FIELD_WEIGHT = 1;
|
|
18
6
|
const DEFAULT_LIMIT = 25;
|
|
19
7
|
export function buildBm25Index(docs) {
|
|
@@ -29,7 +17,8 @@ export function buildBm25Index(docs) {
|
|
|
29
17
|
const docCount = indexed.length;
|
|
30
18
|
return {
|
|
31
19
|
search(query, limit = DEFAULT_LIMIT, options = {}) {
|
|
32
|
-
const pool =
|
|
20
|
+
const pool = indexed.filter((entry) => (options.source === undefined || entry.doc.source === options.source) &&
|
|
21
|
+
(options.group === undefined || entry.doc.group === options.group));
|
|
33
22
|
const queryTerms = tokenizeToolText(query);
|
|
34
23
|
if (queryTerms.length === 0)
|
|
35
24
|
return [];
|
|
@@ -37,7 +26,7 @@ export function buildBm25Index(docs) {
|
|
|
37
26
|
const normQuery = normalizeToolName(query);
|
|
38
27
|
const results = [];
|
|
39
28
|
for (const entry of pool) {
|
|
40
|
-
const exact = useExact && normQuery.length > 0 &&
|
|
29
|
+
const exact = useExact && normQuery.length > 0 && entry.exactNames.has(normQuery);
|
|
41
30
|
const score = bm25Score(entry, queryTerms, docFreq, avgLength, docCount);
|
|
42
31
|
if (!exact && score <= 0)
|
|
43
32
|
continue;
|
|
@@ -51,17 +40,22 @@ export function buildBm25Index(docs) {
|
|
|
51
40
|
function indexDoc(doc) {
|
|
52
41
|
const termFreq = new Map();
|
|
53
42
|
addField(termFreq, tokenizeToolText(doc.name), NAME_FIELD_WEIGHT);
|
|
54
|
-
addField(termFreq, tokenizeToolText(doc.
|
|
55
|
-
|
|
43
|
+
addField(termFreq, tokenizeToolText(doc.label), NAME_FIELD_WEIGHT);
|
|
44
|
+
for (const alias of doc.aliases)
|
|
45
|
+
addField(termFreq, tokenizeToolText(alias), NAME_FIELD_WEIGHT);
|
|
46
|
+
for (const keyword of doc.keywords)
|
|
47
|
+
addField(termFreq, tokenizeToolText(keyword), NAME_FIELD_WEIGHT);
|
|
48
|
+
addField(termFreq, tokenizeToolText(doc.group), GROUP_FIELD_WEIGHT);
|
|
49
|
+
addField(termFreq, tokenizeToolText(doc.ownerLabel), GROUP_FIELD_WEIGHT);
|
|
56
50
|
addField(termFreq, tokenizeToolText(doc.description ?? ""), DESCRIPTION_FIELD_WEIGHT);
|
|
51
|
+
addField(termFreq, tokenizeToolText(doc.searchText ?? ""), DESCRIPTION_FIELD_WEIGHT);
|
|
57
52
|
let length = 0;
|
|
58
53
|
for (const count of termFreq.values())
|
|
59
54
|
length += count;
|
|
60
55
|
return {
|
|
61
56
|
doc,
|
|
57
|
+
exactNames: new Set([doc.name, doc.label, ...doc.aliases, ...doc.keywords].map(normalizeToolName)),
|
|
62
58
|
length,
|
|
63
|
-
normName: normalizeToolName(doc.name),
|
|
64
|
-
normToolName: normalizeToolName(doc.toolName),
|
|
65
59
|
termFreq,
|
|
66
60
|
};
|
|
67
61
|
}
|
|
@@ -87,14 +81,9 @@ function bm25Score(entry, queryTerms, docFreq, avgLength, docCount) {
|
|
|
87
81
|
return score;
|
|
88
82
|
}
|
|
89
83
|
function inverseDocFreq(termDocFreq, docCount) {
|
|
90
|
-
// BM25 idf with the standard +1 smoothing; clamped to be non-negative so a
|
|
91
|
-
// term present in every doc never contributes a negative score.
|
|
92
84
|
const value = Math.log(1 + (docCount - termDocFreq + 0.5) / (termDocFreq + 0.5));
|
|
93
85
|
return value < 0 ? 0 : value;
|
|
94
86
|
}
|
|
95
|
-
function isExactNameMatch(entry, normQuery) {
|
|
96
|
-
return normQuery === entry.normName || normQuery === entry.normToolName;
|
|
97
|
-
}
|
|
98
87
|
function compareResults(left, right) {
|
|
99
88
|
if (left.exact !== right.exact)
|
|
100
89
|
return left.exact ? -1 : 1;
|
|
@@ -102,15 +91,11 @@ function compareResults(left, right) {
|
|
|
102
91
|
return right.score - left.score;
|
|
103
92
|
return left.name.localeCompare(right.name);
|
|
104
93
|
}
|
|
105
|
-
/** Tokenise
|
|
106
|
-
* splitting snake_case, kebab-case and camelCase / PascalCase boundaries. */
|
|
94
|
+
/** Tokenise searchable text into lowercase word tokens, splitting identifiers. */
|
|
107
95
|
export function tokenizeToolText(text) {
|
|
108
96
|
if (text.length === 0)
|
|
109
97
|
return [];
|
|
110
|
-
const withBoundaries = text
|
|
111
|
-
// camelCase / PascalCase: insert a space at lower->Upper and Upper->UpperLower boundaries.
|
|
112
|
-
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
113
|
-
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2");
|
|
98
|
+
const withBoundaries = text.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2");
|
|
114
99
|
const tokens = [];
|
|
115
100
|
for (const raw of withBoundaries.split(/[^a-zA-Z0-9]+/)) {
|
|
116
101
|
if (raw.length === 0)
|
|
@@ -119,7 +104,7 @@ export function tokenizeToolText(text) {
|
|
|
119
104
|
}
|
|
120
105
|
return tokens;
|
|
121
106
|
}
|
|
122
|
-
/**
|
|
107
|
+
/** Normalize a searchable name for separator- and case-insensitive exact matching. */
|
|
123
108
|
export function normalizeToolName(name) {
|
|
124
109
|
return name.toLowerCase().replace(/[-_\s]+/g, "");
|
|
125
110
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bm25.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/tool-search/engine/bm25.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,MAAM,MAAM,GAAG,GAAG,CAAC;AAEnB,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,MAAM,wBAAwB,GAAG,CAAC,CAAC;AA2BnC,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB,MAAM,UAAU,cAAc,CAAC,IAAmC;IACjE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;IACF,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC1E,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAC1E,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAEhC,OAAO;QACN,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,aAAa,EAAE,OAAO,GAAG,EAAE;YAChD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAC1B,CAAC,KAAK,EAAE,EAAE,CACT,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC;gBACrE,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK,CAAC,CACnE,CAAC;YACF,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAEvC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,KAAK,KAAK,CAAC;YAC9C,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAiB,EAAE,CAAC;YACjC,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,QAAQ,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBAClF,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACzE,IAAI,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC;oBAAE,SAAS;gBACnC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACtE,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC7B,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7C,CAAC;KACD,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,GAAuB;IACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC,CAAC;IAClE,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC,CAAC;IACnE,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,OAAO;QAAE,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC,CAAC;IAChG,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,QAAQ;QAAE,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC;IACrG,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,kBAAkB,CAAC,CAAC;IACpE,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC,CAAC;IACzE,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,wBAAwB,CAAC,CAAC;IACtF,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,wBAAwB,CAAC,CAAC;IAErF,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC;IACvD,OAAO;QACN,GAAG;QACH,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAClG,MAAM;QACN,QAAQ;KACR,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,QAA6B,EAAE,MAAyB,EAAE,MAAc;IACzF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;IAC1D,CAAC;AACF,CAAC;AAED,SAAS,SAAS,CACjB,KAAiB,EACjB,UAA6B,EAC7B,OAAoC,EACpC,SAAiB,EACjB,QAAgB;IAEhB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAC7B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,EAAE,KAAK,SAAS;YAAE,SAAS;QAC/B,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC;QACvF,KAAK,IAAI,GAAG,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,WAAmB,EAAE,QAAgB;IAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC;IACjF,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9B,CAAC;AAED,SAAS,cAAc,CAAC,IAAgB,EAAE,KAAiB;IAC1D,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAChE,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC5C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;IAC7G,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;QACzD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAC/B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC7C,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AACnD,CAAC","sourcesContent":["import type { ToolSearchDocument, ToolSearchSource } from \"./document.ts\";\n\nconst BM25_K1 = 0.9;\nconst BM25_B = 0.4;\n\nconst NAME_FIELD_WEIGHT = 3;\nconst GROUP_FIELD_WEIGHT = 2;\nconst DESCRIPTION_FIELD_WEIGHT = 1;\n\nexport interface Bm25Result {\n\treadonly name: string;\n\treadonly score: number;\n\treadonly exact: boolean;\n\treadonly doc: ToolSearchDocument;\n}\n\nexport interface Bm25SearchOptions {\n\treadonly source?: ToolSearchSource;\n\treadonly group?: string;\n\t/** Disable the exact-name short-circuit (used to prove BM25-alone behaviour). */\n\treadonly exactMatch?: boolean;\n}\n\nexport interface Bm25Index {\n\tsearch(query: string, limit?: number, options?: Bm25SearchOptions): Bm25Result[];\n}\n\ninterface IndexedDoc {\n\treadonly doc: ToolSearchDocument;\n\treadonly termFreq: ReadonlyMap<string, number>;\n\treadonly length: number;\n\treadonly exactNames: ReadonlySet<string>;\n}\n\nconst DEFAULT_LIMIT = 25;\n\nexport function buildBm25Index(docs: readonly ToolSearchDocument[]): Bm25Index {\n\tconst indexed = docs.map(indexDoc);\n\tconst docFreq = new Map<string, number>();\n\tfor (const entry of indexed) {\n\t\tfor (const term of entry.termFreq.keys()) {\n\t\t\tdocFreq.set(term, (docFreq.get(term) ?? 0) + 1);\n\t\t}\n\t}\n\tconst totalLength = indexed.reduce((sum, entry) => sum + entry.length, 0);\n\tconst avgLength = indexed.length === 0 ? 0 : totalLength / indexed.length;\n\tconst docCount = indexed.length;\n\n\treturn {\n\t\tsearch(query, limit = DEFAULT_LIMIT, options = {}): Bm25Result[] {\n\t\t\tconst pool = indexed.filter(\n\t\t\t\t(entry) =>\n\t\t\t\t\t(options.source === undefined || entry.doc.source === options.source) &&\n\t\t\t\t\t(options.group === undefined || entry.doc.group === options.group),\n\t\t\t);\n\t\t\tconst queryTerms = tokenizeToolText(query);\n\t\t\tif (queryTerms.length === 0) return [];\n\n\t\t\tconst useExact = options.exactMatch !== false;\n\t\t\tconst normQuery = normalizeToolName(query);\n\t\t\tconst results: Bm25Result[] = [];\n\t\t\tfor (const entry of pool) {\n\t\t\t\tconst exact = useExact && normQuery.length > 0 && entry.exactNames.has(normQuery);\n\t\t\t\tconst score = bm25Score(entry, queryTerms, docFreq, avgLength, docCount);\n\t\t\t\tif (!exact && score <= 0) continue;\n\t\t\t\tresults.push({ doc: entry.doc, exact, name: entry.doc.name, score });\n\t\t\t}\n\t\t\tresults.sort(compareResults);\n\t\t\treturn results.slice(0, Math.max(0, limit));\n\t\t},\n\t};\n}\n\nfunction indexDoc(doc: ToolSearchDocument): IndexedDoc {\n\tconst termFreq = new Map<string, number>();\n\taddField(termFreq, tokenizeToolText(doc.name), NAME_FIELD_WEIGHT);\n\taddField(termFreq, tokenizeToolText(doc.label), NAME_FIELD_WEIGHT);\n\tfor (const alias of doc.aliases) addField(termFreq, tokenizeToolText(alias), NAME_FIELD_WEIGHT);\n\tfor (const keyword of doc.keywords) addField(termFreq, tokenizeToolText(keyword), NAME_FIELD_WEIGHT);\n\taddField(termFreq, tokenizeToolText(doc.group), GROUP_FIELD_WEIGHT);\n\taddField(termFreq, tokenizeToolText(doc.ownerLabel), GROUP_FIELD_WEIGHT);\n\taddField(termFreq, tokenizeToolText(doc.description ?? \"\"), DESCRIPTION_FIELD_WEIGHT);\n\taddField(termFreq, tokenizeToolText(doc.searchText ?? \"\"), DESCRIPTION_FIELD_WEIGHT);\n\n\tlet length = 0;\n\tfor (const count of termFreq.values()) length += count;\n\treturn {\n\t\tdoc,\n\t\texactNames: new Set([doc.name, doc.label, ...doc.aliases, ...doc.keywords].map(normalizeToolName)),\n\t\tlength,\n\t\ttermFreq,\n\t};\n}\n\nfunction addField(termFreq: Map<string, number>, tokens: readonly string[], weight: number): void {\n\tfor (const token of tokens) {\n\t\ttermFreq.set(token, (termFreq.get(token) ?? 0) + weight);\n\t}\n}\n\nfunction bm25Score(\n\tentry: IndexedDoc,\n\tqueryTerms: readonly string[],\n\tdocFreq: ReadonlyMap<string, number>,\n\tavgLength: number,\n\tdocCount: number,\n): number {\n\tlet score = 0;\n\tconst seen = new Set<string>();\n\tfor (const term of queryTerms) {\n\t\tif (seen.has(term)) continue;\n\t\tseen.add(term);\n\t\tconst tf = entry.termFreq.get(term);\n\t\tif (tf === undefined) continue;\n\t\tconst idf = inverseDocFreq(docFreq.get(term) ?? 0, docCount);\n\t\tconst denom = tf + BM25_K1 * (1 - BM25_B + (BM25_B * entry.length) / (avgLength || 1));\n\t\tscore += idf * ((tf * (BM25_K1 + 1)) / (denom || 1));\n\t}\n\treturn score;\n}\n\nfunction inverseDocFreq(termDocFreq: number, docCount: number): number {\n\tconst value = Math.log(1 + (docCount - termDocFreq + 0.5) / (termDocFreq + 0.5));\n\treturn value < 0 ? 0 : value;\n}\n\nfunction compareResults(left: Bm25Result, right: Bm25Result): number {\n\tif (left.exact !== right.exact) return left.exact ? -1 : 1;\n\tif (right.score !== left.score) return right.score - left.score;\n\treturn left.name.localeCompare(right.name);\n}\n\n/** Tokenise searchable text into lowercase word tokens, splitting identifiers. */\nexport function tokenizeToolText(text: string): string[] {\n\tif (text.length === 0) return [];\n\tconst withBoundaries = text.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\").replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\");\n\tconst tokens: string[] = [];\n\tfor (const raw of withBoundaries.split(/[^a-zA-Z0-9]+/)) {\n\t\tif (raw.length === 0) continue;\n\t\ttokens.push(raw.toLowerCase());\n\t}\n\treturn tokens;\n}\n\n/** Normalize a searchable name for separator- and case-insensitive exact matching. */\nexport function normalizeToolName(name: string): string {\n\treturn name.toLowerCase().replace(/[-_\\s]+/g, \"\");\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type ToolSearchSource = "mcp" | "extension";
|
|
2
|
+
export interface ToolSearchDocument {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly label: string;
|
|
5
|
+
readonly aliases: readonly string[];
|
|
6
|
+
readonly description?: string;
|
|
7
|
+
readonly searchText?: string;
|
|
8
|
+
readonly keywords: readonly string[];
|
|
9
|
+
readonly source: ToolSearchSource;
|
|
10
|
+
readonly group: string;
|
|
11
|
+
readonly ownerLabel: string;
|
|
12
|
+
readonly registrationId: string;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/tool-search/engine/document.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,WAAW,CAAC;AAEnD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/tool-search/engine/document.ts"],"names":[],"mappings":"","sourcesContent":["export type ToolSearchSource = \"mcp\" | \"extension\";\n\nexport interface ToolSearchDocument {\n\treadonly name: string;\n\treadonly label: string;\n\treadonly aliases: readonly string[];\n\treadonly description?: string;\n\treadonly searchText?: string;\n\treadonly keywords: readonly string[];\n\treadonly source: ToolSearchSource;\n\treadonly group: string;\n\treadonly ownerLabel: string;\n\treadonly registrationId: string;\n}\n"]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export declare const TOOL_SEARCH_ACTIVATION_MARKER_V2 = "[tool_search:activated:v2]";
|
|
2
|
+
export declare const LEGACY_TOOL_SEARCH_ACTIVATION_MARKER = "[tool_search:activated]";
|
|
3
|
+
export interface ToolActivationIdentity {
|
|
4
|
+
name: string;
|
|
5
|
+
registrationId: string;
|
|
6
|
+
}
|
|
7
|
+
export type ParsedActivationMarker = {
|
|
8
|
+
version: 2;
|
|
9
|
+
activations: ToolActivationIdentity[];
|
|
10
|
+
} | {
|
|
11
|
+
version: 1;
|
|
12
|
+
names: string[];
|
|
13
|
+
};
|
|
14
|
+
export interface RehydratableToolSearchDocument {
|
|
15
|
+
name: string;
|
|
16
|
+
registrationId: string;
|
|
17
|
+
source: "mcp" | "extension";
|
|
18
|
+
allowLazyActivation?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export type RegistrationIdentityInput = {
|
|
21
|
+
source: "mcp";
|
|
22
|
+
server: string;
|
|
23
|
+
name: string;
|
|
24
|
+
} | {
|
|
25
|
+
source: "extension";
|
|
26
|
+
sourceInfo: {
|
|
27
|
+
path: string;
|
|
28
|
+
resolvedPath?: string;
|
|
29
|
+
};
|
|
30
|
+
name: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Derive the host-owned registration identity for a tool. Authors must never
|
|
34
|
+
* supply this value: it binds an activation marker to the canonical owner and
|
|
35
|
+
* tool name selected by the current registry generation.
|
|
36
|
+
*/
|
|
37
|
+
export declare function deriveRegistrationId(input: RegistrationIdentityInput): string;
|
|
38
|
+
export declare function deriveMcpRegistrationId(server: string, toolName: string): string;
|
|
39
|
+
export declare function deriveExtensionRegistrationId(sourceInfo: {
|
|
40
|
+
path: string;
|
|
41
|
+
resolvedPath?: string;
|
|
42
|
+
}, toolName: string): string;
|
|
43
|
+
/** Emit a compact ownership-aware activation marker for persisted history. */
|
|
44
|
+
export declare function emitActivationMarker(activations: readonly ToolActivationIdentity[]): string;
|
|
45
|
+
/** Parse ownership-aware v2 markers and legacy MCP name-only markers. */
|
|
46
|
+
export declare function parseActivationMarkers(messages: readonly unknown[]): ParsedActivationMarker[];
|
|
47
|
+
/**
|
|
48
|
+
* Restore valid activation history against the current winning registry docs.
|
|
49
|
+
*
|
|
50
|
+
* This pure scan is intended to run ONCE per registry generation. The owning
|
|
51
|
+
* service is responsible for generation-level memoization; callers must not
|
|
52
|
+
* continuously reapply history after each active-tool update.
|
|
53
|
+
*/
|
|
54
|
+
export declare function rehydrate(messages: readonly unknown[], currentDocsByName: ReadonlyMap<string, RehydratableToolSearchDocument>): string[];
|
|
55
|
+
//# sourceMappingURL=marker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/tool-search/engine/marker.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gCAAgC,+BAA+B,CAAC;AAC7E,eAAO,MAAM,oCAAoC,4BAA4B,CAAC;AAE9E,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,sBAAsB,GAC/B;IAAE,OAAO,EAAE,CAAC,CAAC;IAAC,WAAW,EAAE,sBAAsB,EAAE,CAAA;CAAE,GACrD;IAAE,OAAO,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEnC,MAAM,WAAW,8BAA8B;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,KAAK,GAAG,WAAW,CAAC;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,MAAM,yBAAyB,GAClC;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9F;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,MAAM,CAG7E;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,wBAAgB,6BAA6B,CAC5C,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,EACnD,QAAQ,EAAE,MAAM,GACd,MAAM,CAER;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,SAAS,sBAAsB,EAAE,GAAG,MAAM,CAE3F;AAED,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,sBAAsB,EAAE,CAuB7F;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACxB,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,iBAAiB,EAAE,WAAW,CAAC,MAAM,EAAE,8BAA8B,CAAC,GACpE,MAAM,EAAE,CAuBV"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
export const TOOL_SEARCH_ACTIVATION_MARKER_V2 = "[tool_search:activated:v2]";
|
|
2
|
+
export const LEGACY_TOOL_SEARCH_ACTIVATION_MARKER = "[tool_search:activated]";
|
|
3
|
+
/**
|
|
4
|
+
* Derive the host-owned registration identity for a tool. Authors must never
|
|
5
|
+
* supply this value: it binds an activation marker to the canonical owner and
|
|
6
|
+
* tool name selected by the current registry generation.
|
|
7
|
+
*/
|
|
8
|
+
export function deriveRegistrationId(input) {
|
|
9
|
+
if (input.source === "mcp")
|
|
10
|
+
return `mcp\0${input.server}\0${input.name}`;
|
|
11
|
+
return `${input.sourceInfo.resolvedPath ?? input.sourceInfo.path}\0${input.name}`;
|
|
12
|
+
}
|
|
13
|
+
export function deriveMcpRegistrationId(server, toolName) {
|
|
14
|
+
return deriveRegistrationId({ source: "mcp", server, name: toolName });
|
|
15
|
+
}
|
|
16
|
+
export function deriveExtensionRegistrationId(sourceInfo, toolName) {
|
|
17
|
+
return deriveRegistrationId({ source: "extension", sourceInfo, name: toolName });
|
|
18
|
+
}
|
|
19
|
+
/** Emit a compact ownership-aware activation marker for persisted history. */
|
|
20
|
+
export function emitActivationMarker(activations) {
|
|
21
|
+
return `${TOOL_SEARCH_ACTIVATION_MARKER_V2} ${JSON.stringify(activations)}`;
|
|
22
|
+
}
|
|
23
|
+
/** Parse ownership-aware v2 markers and legacy MCP name-only markers. */
|
|
24
|
+
export function parseActivationMarkers(messages) {
|
|
25
|
+
const markers = [];
|
|
26
|
+
for (const message of messages) {
|
|
27
|
+
let blob;
|
|
28
|
+
try {
|
|
29
|
+
blob = JSON.stringify(message) ?? "";
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
for (const payload of extractV2Payloads(blob)) {
|
|
35
|
+
const activations = parseV2Payload(payload);
|
|
36
|
+
if (activations.length > 0)
|
|
37
|
+
markers.push({ version: 2, activations });
|
|
38
|
+
}
|
|
39
|
+
for (const segment of extractLegacyActivationSegments(blob)) {
|
|
40
|
+
const names = segment
|
|
41
|
+
.trim()
|
|
42
|
+
.split(/\s+/)
|
|
43
|
+
.filter((name) => name.length > 0);
|
|
44
|
+
if (names.length > 0)
|
|
45
|
+
markers.push({ version: 1, names });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return markers;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Restore valid activation history against the current winning registry docs.
|
|
52
|
+
*
|
|
53
|
+
* This pure scan is intended to run ONCE per registry generation. The owning
|
|
54
|
+
* service is responsible for generation-level memoization; callers must not
|
|
55
|
+
* continuously reapply history after each active-tool update.
|
|
56
|
+
*/
|
|
57
|
+
export function rehydrate(messages, currentDocsByName) {
|
|
58
|
+
const restored = new Set();
|
|
59
|
+
for (const marker of parseActivationMarkers(messages)) {
|
|
60
|
+
if (marker.version === 2) {
|
|
61
|
+
for (const activation of marker.activations) {
|
|
62
|
+
const current = currentDocsByName.get(activation.name);
|
|
63
|
+
if (current !== undefined &&
|
|
64
|
+
current.allowLazyActivation !== false &&
|
|
65
|
+
current.registrationId === activation.registrationId) {
|
|
66
|
+
restored.add(activation.name);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
for (const name of marker.names) {
|
|
72
|
+
const current = currentDocsByName.get(name);
|
|
73
|
+
if (current?.source === "mcp" && current.allowLazyActivation !== false)
|
|
74
|
+
restored.add(name);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return [...restored].sort();
|
|
78
|
+
}
|
|
79
|
+
function extractV2Payloads(blob) {
|
|
80
|
+
const payloads = [];
|
|
81
|
+
let cursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER_V2);
|
|
82
|
+
while (cursor >= 0) {
|
|
83
|
+
const encodedRemainder = extractEncodedJsonStringRemainder(blob, cursor + TOOL_SEARCH_ACTIVATION_MARKER_V2.length);
|
|
84
|
+
if (encodedRemainder !== undefined) {
|
|
85
|
+
try {
|
|
86
|
+
const decodedRemainder = JSON.parse(`"${encodedRemainder}"`);
|
|
87
|
+
if (typeof decodedRemainder === "string") {
|
|
88
|
+
const payload = extractJsonArrayPrefix(decodedRemainder.trimStart());
|
|
89
|
+
if (payload !== undefined)
|
|
90
|
+
payloads.push(payload);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Malformed history is ignored during best-effort rehydration.
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
cursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER_V2, cursor + TOOL_SEARCH_ACTIVATION_MARKER_V2.length);
|
|
98
|
+
}
|
|
99
|
+
return payloads;
|
|
100
|
+
}
|
|
101
|
+
function extractEncodedJsonStringRemainder(blob, start) {
|
|
102
|
+
let encoded = "";
|
|
103
|
+
for (let index = start; index < blob.length; index++) {
|
|
104
|
+
const character = blob[index];
|
|
105
|
+
if (character === '"')
|
|
106
|
+
return encoded;
|
|
107
|
+
if (character === "\n")
|
|
108
|
+
return undefined;
|
|
109
|
+
if (character === "\\") {
|
|
110
|
+
const escaped = blob[index + 1];
|
|
111
|
+
if (escaped === undefined)
|
|
112
|
+
return undefined;
|
|
113
|
+
encoded += character + escaped;
|
|
114
|
+
index++;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
encoded += character;
|
|
118
|
+
}
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
function extractJsonArrayPrefix(text) {
|
|
122
|
+
if (!text.startsWith("["))
|
|
123
|
+
return undefined;
|
|
124
|
+
let depth = 0;
|
|
125
|
+
let inString = false;
|
|
126
|
+
let escaped = false;
|
|
127
|
+
for (let index = 0; index < text.length; index++) {
|
|
128
|
+
const character = text[index];
|
|
129
|
+
if (inString) {
|
|
130
|
+
if (escaped)
|
|
131
|
+
escaped = false;
|
|
132
|
+
else if (character === "\\")
|
|
133
|
+
escaped = true;
|
|
134
|
+
else if (character === '"')
|
|
135
|
+
inString = false;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (character === '"')
|
|
139
|
+
inString = true;
|
|
140
|
+
else if (character === "[")
|
|
141
|
+
depth++;
|
|
142
|
+
else if (character === "]") {
|
|
143
|
+
depth--;
|
|
144
|
+
if (depth === 0)
|
|
145
|
+
return text.slice(0, index + 1);
|
|
146
|
+
if (depth < 0)
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
function parseV2Payload(payload) {
|
|
153
|
+
try {
|
|
154
|
+
const parsed = JSON.parse(payload);
|
|
155
|
+
if (!Array.isArray(parsed))
|
|
156
|
+
return [];
|
|
157
|
+
return parsed.filter(isToolActivationIdentity);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function isToolActivationIdentity(value) {
|
|
164
|
+
if (typeof value !== "object" || value === null)
|
|
165
|
+
return false;
|
|
166
|
+
const candidate = value;
|
|
167
|
+
return (typeof candidate.name === "string" &&
|
|
168
|
+
candidate.name.length > 0 &&
|
|
169
|
+
typeof candidate.registrationId === "string" &&
|
|
170
|
+
candidate.registrationId.length > 0);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Keep this scanner byte-for-byte equivalent to the legacy MCP extraction
|
|
174
|
+
* semantics so old JSON-stringified session history remains compatible.
|
|
175
|
+
*/
|
|
176
|
+
function extractLegacyActivationSegments(blob) {
|
|
177
|
+
const segments = [];
|
|
178
|
+
let cursor = blob.indexOf(LEGACY_TOOL_SEARCH_ACTIVATION_MARKER);
|
|
179
|
+
while (cursor >= 0) {
|
|
180
|
+
const rest = blob.slice(cursor + LEGACY_TOOL_SEARCH_ACTIVATION_MARKER.length);
|
|
181
|
+
// Tool names are [a-zA-Z0-9_-]; stop at the first JSON string terminator
|
|
182
|
+
// (quote / escape) or newline so we never swallow the rest of the blob.
|
|
183
|
+
const end = rest.search(/["\\\n]/);
|
|
184
|
+
segments.push(end < 0 ? rest : rest.slice(0, end));
|
|
185
|
+
cursor = blob.indexOf(LEGACY_TOOL_SEARCH_ACTIVATION_MARKER, cursor + LEGACY_TOOL_SEARCH_ACTIVATION_MARKER.length);
|
|
186
|
+
}
|
|
187
|
+
return segments;
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=marker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/tool-search/engine/marker.ts"],"names":[],"mappings":"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","sourcesContent":["export const TOOL_SEARCH_ACTIVATION_MARKER_V2 = \"[tool_search:activated:v2]\";\nexport const LEGACY_TOOL_SEARCH_ACTIVATION_MARKER = \"[tool_search:activated]\";\n\nexport interface ToolActivationIdentity {\n\tname: string;\n\tregistrationId: string;\n}\n\nexport type ParsedActivationMarker =\n\t| { version: 2; activations: ToolActivationIdentity[] }\n\t| { version: 1; names: string[] };\n\nexport interface RehydratableToolSearchDocument {\n\tname: string;\n\tregistrationId: string;\n\tsource: \"mcp\" | \"extension\";\n\tallowLazyActivation?: boolean;\n}\n\nexport type RegistrationIdentityInput =\n\t| { source: \"mcp\"; server: string; name: string }\n\t| { source: \"extension\"; sourceInfo: { path: string; resolvedPath?: string }; name: string };\n\n/**\n * Derive the host-owned registration identity for a tool. Authors must never\n * supply this value: it binds an activation marker to the canonical owner and\n * tool name selected by the current registry generation.\n */\nexport function deriveRegistrationId(input: RegistrationIdentityInput): string {\n\tif (input.source === \"mcp\") return `mcp\\0${input.server}\\0${input.name}`;\n\treturn `${input.sourceInfo.resolvedPath ?? input.sourceInfo.path}\\0${input.name}`;\n}\n\nexport function deriveMcpRegistrationId(server: string, toolName: string): string {\n\treturn deriveRegistrationId({ source: \"mcp\", server, name: toolName });\n}\n\nexport function deriveExtensionRegistrationId(\n\tsourceInfo: { path: string; resolvedPath?: string },\n\ttoolName: string,\n): string {\n\treturn deriveRegistrationId({ source: \"extension\", sourceInfo, name: toolName });\n}\n\n/** Emit a compact ownership-aware activation marker for persisted history. */\nexport function emitActivationMarker(activations: readonly ToolActivationIdentity[]): string {\n\treturn `${TOOL_SEARCH_ACTIVATION_MARKER_V2} ${JSON.stringify(activations)}`;\n}\n\n/** Parse ownership-aware v2 markers and legacy MCP name-only markers. */\nexport function parseActivationMarkers(messages: readonly unknown[]): ParsedActivationMarker[] {\n\tconst markers: ParsedActivationMarker[] = [];\n\tfor (const message of messages) {\n\t\tlet blob: string;\n\t\ttry {\n\t\t\tblob = JSON.stringify(message) ?? \"\";\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (const payload of extractV2Payloads(blob)) {\n\t\t\tconst activations = parseV2Payload(payload);\n\t\t\tif (activations.length > 0) markers.push({ version: 2, activations });\n\t\t}\n\t\tfor (const segment of extractLegacyActivationSegments(blob)) {\n\t\t\tconst names = segment\n\t\t\t\t.trim()\n\t\t\t\t.split(/\\s+/)\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t\tif (names.length > 0) markers.push({ version: 1, names });\n\t\t}\n\t}\n\treturn markers;\n}\n\n/**\n * Restore valid activation history against the current winning registry docs.\n *\n * This pure scan is intended to run ONCE per registry generation. The owning\n * service is responsible for generation-level memoization; callers must not\n * continuously reapply history after each active-tool update.\n */\nexport function rehydrate(\n\tmessages: readonly unknown[],\n\tcurrentDocsByName: ReadonlyMap<string, RehydratableToolSearchDocument>,\n): string[] {\n\tconst restored = new Set<string>();\n\tfor (const marker of parseActivationMarkers(messages)) {\n\t\tif (marker.version === 2) {\n\t\t\tfor (const activation of marker.activations) {\n\t\t\t\tconst current = currentDocsByName.get(activation.name);\n\t\t\t\tif (\n\t\t\t\t\tcurrent !== undefined &&\n\t\t\t\t\tcurrent.allowLazyActivation !== false &&\n\t\t\t\t\tcurrent.registrationId === activation.registrationId\n\t\t\t\t) {\n\t\t\t\t\trestored.add(activation.name);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (const name of marker.names) {\n\t\t\tconst current = currentDocsByName.get(name);\n\t\t\tif (current?.source === \"mcp\" && current.allowLazyActivation !== false) restored.add(name);\n\t\t}\n\t}\n\treturn [...restored].sort();\n}\n\nfunction extractV2Payloads(blob: string): string[] {\n\tconst payloads: string[] = [];\n\tlet cursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER_V2);\n\twhile (cursor >= 0) {\n\t\tconst encodedRemainder = extractEncodedJsonStringRemainder(\n\t\t\tblob,\n\t\t\tcursor + TOOL_SEARCH_ACTIVATION_MARKER_V2.length,\n\t\t);\n\t\tif (encodedRemainder !== undefined) {\n\t\t\ttry {\n\t\t\t\tconst decodedRemainder = JSON.parse(`\"${encodedRemainder}\"`) as unknown;\n\t\t\t\tif (typeof decodedRemainder === \"string\") {\n\t\t\t\t\tconst payload = extractJsonArrayPrefix(decodedRemainder.trimStart());\n\t\t\t\t\tif (payload !== undefined) payloads.push(payload);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Malformed history is ignored during best-effort rehydration.\n\t\t\t}\n\t\t}\n\t\tcursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER_V2, cursor + TOOL_SEARCH_ACTIVATION_MARKER_V2.length);\n\t}\n\treturn payloads;\n}\n\nfunction extractEncodedJsonStringRemainder(blob: string, start: number): string | undefined {\n\tlet encoded = \"\";\n\tfor (let index = start; index < blob.length; index++) {\n\t\tconst character = blob[index];\n\t\tif (character === '\"') return encoded;\n\t\tif (character === \"\\n\") return undefined;\n\t\tif (character === \"\\\\\") {\n\t\t\tconst escaped = blob[index + 1];\n\t\t\tif (escaped === undefined) return undefined;\n\t\t\tencoded += character + escaped;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tencoded += character;\n\t}\n\treturn undefined;\n}\n\nfunction extractJsonArrayPrefix(text: string): string | undefined {\n\tif (!text.startsWith(\"[\")) return undefined;\n\tlet depth = 0;\n\tlet inString = false;\n\tlet escaped = false;\n\tfor (let index = 0; index < text.length; index++) {\n\t\tconst character = text[index];\n\t\tif (inString) {\n\t\t\tif (escaped) escaped = false;\n\t\t\telse if (character === \"\\\\\") escaped = true;\n\t\t\telse if (character === '\"') inString = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (character === '\"') inString = true;\n\t\telse if (character === \"[\") depth++;\n\t\telse if (character === \"]\") {\n\t\t\tdepth--;\n\t\t\tif (depth === 0) return text.slice(0, index + 1);\n\t\t\tif (depth < 0) return undefined;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction parseV2Payload(payload: string): ToolActivationIdentity[] {\n\ttry {\n\t\tconst parsed = JSON.parse(payload) as unknown;\n\t\tif (!Array.isArray(parsed)) return [];\n\t\treturn parsed.filter(isToolActivationIdentity);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction isToolActivationIdentity(value: unknown): value is ToolActivationIdentity {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tconst candidate = value as { name?: unknown; registrationId?: unknown };\n\treturn (\n\t\ttypeof candidate.name === \"string\" &&\n\t\tcandidate.name.length > 0 &&\n\t\ttypeof candidate.registrationId === \"string\" &&\n\t\tcandidate.registrationId.length > 0\n\t);\n}\n\n/**\n * Keep this scanner byte-for-byte equivalent to the legacy MCP extraction\n * semantics so old JSON-stringified session history remains compatible.\n */\nfunction extractLegacyActivationSegments(blob: string): string[] {\n\tconst segments: string[] = [];\n\tlet cursor = blob.indexOf(LEGACY_TOOL_SEARCH_ACTIVATION_MARKER);\n\twhile (cursor >= 0) {\n\t\tconst rest = blob.slice(cursor + LEGACY_TOOL_SEARCH_ACTIVATION_MARKER.length);\n\t\t// Tool names are [a-zA-Z0-9_-]; stop at the first JSON string terminator\n\t\t// (quote / escape) or newline so we never swallow the rest of the blob.\n\t\tconst end = rest.search(/[\"\\\\\\n]/);\n\t\tsegments.push(end < 0 ? rest : rest.slice(0, end));\n\t\tcursor = blob.indexOf(LEGACY_TOOL_SEARCH_ACTIVATION_MARKER, cursor + LEGACY_TOOL_SEARCH_ACTIVATION_MARKER.length);\n\t}\n\treturn segments;\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionFactory } from "../../types.ts";
|
|
2
|
+
import { ToolSearchService } from "./service.ts";
|
|
3
|
+
export declare function createToolSearchExtension(service: ToolSearchService): ExtensionFactory;
|
|
4
|
+
export default function toolSearchExtension(pi: ExtensionAPI): void | Promise<void>;
|
|
5
|
+
export { getToolSearchService, ToolSearchService } from "./service.ts";
|
|
6
|
+
export { createToolSearchTool, TOOL_SEARCH_TOOL_NAME } from "./tool.ts";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-search/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAwD,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGvG,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CA6CtF;AAWD,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAUlF;AAED,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { bindToProviderScope } from "@earendil-works/pi-ai/node/provider-scope";
|
|
2
|
+
import { AnthropicNativeToolSearchAdapter, isMcpNativeToolSearchEnabled } from "./native-search.js";
|
|
3
|
+
import { getToolSearchService, installScopedToolSearchService, ToolSearchService } from "./service.js";
|
|
4
|
+
import { createToolSearchTool, TOOL_SEARCH_TOOL_NAME } from "./tool.js";
|
|
5
|
+
export function createToolSearchExtension(service) {
|
|
6
|
+
return (pi) => {
|
|
7
|
+
service.bindRuntime(pi);
|
|
8
|
+
pi.on("session_start", (_event, ctx) => {
|
|
9
|
+
service.beginSession();
|
|
10
|
+
service.maybeRehydrateFromHistory(ctx.sessionManager.getEntries());
|
|
11
|
+
});
|
|
12
|
+
pi.on("context", (event) => {
|
|
13
|
+
service.maybeRehydrateFromHistory(event.messages);
|
|
14
|
+
});
|
|
15
|
+
pi.registerLazyToolActivator((toolName) => service.activateTool(toolName));
|
|
16
|
+
let toolRegistered = false;
|
|
17
|
+
service.bindToolRegistrar(() => {
|
|
18
|
+
if (toolRegistered)
|
|
19
|
+
return;
|
|
20
|
+
toolRegistered = true;
|
|
21
|
+
pi.registerTool(createToolSearchTool(service));
|
|
22
|
+
});
|
|
23
|
+
const nativeAdapter = new AnthropicNativeToolSearchAdapter({
|
|
24
|
+
enabled: () => {
|
|
25
|
+
const active = new Set(pi.getActiveTools());
|
|
26
|
+
return service
|
|
27
|
+
.getCatalog()
|
|
28
|
+
.some((doc) => (doc.source === "extension" && !active.has(doc.name)) ||
|
|
29
|
+
(doc.source === "mcp" && isMcpNativeToolSearchEnabled()));
|
|
30
|
+
},
|
|
31
|
+
getCatalog: () => service.getCatalog(),
|
|
32
|
+
getToolDefinition: (name) => {
|
|
33
|
+
const tool = pi.getAllTools().find((candidate) => candidate.name === name);
|
|
34
|
+
return tool === undefined ? undefined : { description: tool.description, parameters: tool.parameters };
|
|
35
|
+
},
|
|
36
|
+
isDeferrable: (name) => {
|
|
37
|
+
const doc = service.getCatalog().find((candidate) => candidate.name === name);
|
|
38
|
+
if (doc?.source === "mcp")
|
|
39
|
+
return isMcpNativeToolSearchEnabled();
|
|
40
|
+
return doc?.source === "extension" && !pi.getActiveTools().includes(name);
|
|
41
|
+
},
|
|
42
|
+
searchToolName: TOOL_SEARCH_TOOL_NAME,
|
|
43
|
+
});
|
|
44
|
+
pi.on("before_provider_request", (event, ctx) => nativeAdapter.applyBeforeRequest(ctx.model?.api, event.payload));
|
|
45
|
+
pi.on("after_provider_response", (event) => nativeAdapter.noteResponseStatus(event.status));
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function hasProviderScope() {
|
|
49
|
+
try {
|
|
50
|
+
bindToProviderScope(() => undefined);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export default function toolSearchExtension(pi) {
|
|
58
|
+
const runtime = {
|
|
59
|
+
getAllTools: () => pi.getAllTools(),
|
|
60
|
+
getActiveTools: () => pi.getActiveTools(),
|
|
61
|
+
setActiveTools: (names) => pi.setActiveTools([...names]),
|
|
62
|
+
};
|
|
63
|
+
const sessionOwned = hasProviderScope();
|
|
64
|
+
const service = sessionOwned ? new ToolSearchService(runtime) : getToolSearchService(runtime);
|
|
65
|
+
if (sessionOwned)
|
|
66
|
+
installScopedToolSearchService(service);
|
|
67
|
+
return createToolSearchExtension(service)(pi);
|
|
68
|
+
}
|
|
69
|
+
export { getToolSearchService, ToolSearchService } from "./service.js";
|
|
70
|
+
export { createToolSearchTool, TOOL_SEARCH_TOOL_NAME } from "./tool.js";
|
|
71
|
+
//# sourceMappingURL=index.js.map
|