@herbertgao/pi-extensions 2026.9.17 → 2026.9.19
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/README.md +31 -33
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/node_modules/@herbertgao/pi-bark/package.json +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +4 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +4 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/working-message.ts +21 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +15 -4
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/index.ts +43 -7
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +7 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +75 -75
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
- package/node_modules/@herbertgao/pi-subagents/package.json +7 -7
- package/node_modules/@herbertgao/resume-from/package.json +4 -2
- package/node_modules/@herbertgao/sol-pi/package.json +6 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +99 -99
- package/node_modules/@pi-plugins/fast-mode/package.json +1 -1
- package/node_modules/@tifan/pi-handoff/package.json +1 -1
- package/node_modules/@tifan/pi-handoff/src/index.ts +56 -26
- package/node_modules/@tifan/pi-mermaid-open/package.json +1 -1
- package/node_modules/@tifan/pi-preferred-thinking/package.json +1 -1
- package/node_modules/@tifan/pi-recap/package.json +1 -1
- package/node_modules/@tifan/pi-rename/package.json +1 -1
- package/node_modules/pi-antigravity/README.md +29 -6
- package/node_modules/pi-antigravity/package.json +14 -9
- package/node_modules/pi-antigravity/src/auth/accounts.ts +327 -0
- package/node_modules/pi-antigravity/src/auth/index.ts +9 -0
- package/node_modules/pi-antigravity/src/client/client.ts +1 -1
- package/node_modules/pi-antigravity/src/image/image.ts +4 -4
- package/node_modules/pi-antigravity/src/index.ts +203 -13
- package/node_modules/pi-antigravity/src/search/index.ts +1 -0
- package/node_modules/pi-antigravity/src/search/search.ts +325 -0
- package/node_modules/pi-antigravity/src/stream/stream.ts +191 -14
- package/node_modules/pi-antigravity/src/types/enums.ts +45 -36
- package/node_modules/pi-antigravity/src/types/types.ts +5 -12
- package/node_modules/pi-antigravity/src/utils/http.ts +7 -2
- package/node_modules/pi-antigravity/src/utils/util.ts +31 -3
- package/node_modules/pi-lens/package.json +158 -158
- package/node_modules/pi-multi-account/package.json +2 -2
- package/node_modules/pi-typesafe/README.md +3 -1
- package/node_modules/pi-typesafe/dist/auth.d.ts +9 -5
- package/node_modules/pi-typesafe/dist/auth.js +7 -3
- package/node_modules/pi-typesafe/dist/backends.d.ts +33 -3
- package/node_modules/pi-typesafe/dist/backends.js +95 -1
- package/node_modules/pi-typesafe/dist/client.d.ts +5 -5
- package/node_modules/pi-typesafe/dist/client.js +12 -9
- package/node_modules/pi-typesafe/dist/credentials.d.ts +14 -8
- package/node_modules/pi-typesafe/dist/credentials.js +10 -7
- package/node_modules/pi-typesafe/dist/errors.d.ts +2 -2
- package/node_modules/pi-typesafe/dist/index.d.ts +2 -2
- package/node_modules/pi-typesafe/dist/index.js +1 -1
- package/node_modules/pi-typesafe/dist/login.d.ts +2 -2
- package/node_modules/pi-typesafe/dist/login.js +2 -2
- package/node_modules/pi-typesafe/package.json +6 -5
- package/node_modules/pi-web-access/CHANGELOG.md +72 -0
- package/node_modules/pi-web-access/README.md +34 -13
- package/node_modules/pi-web-access/chrome-cookies.ts +79 -25
- package/node_modules/pi-web-access/curator-page.ts +5 -1
- package/node_modules/pi-web-access/curator-server.ts +2 -0
- package/node_modules/pi-web-access/dist/index.js +1337 -1009
- package/node_modules/pi-web-access/exa.ts +20 -52
- package/node_modules/pi-web-access/extract.ts +41 -4
- package/node_modules/pi-web-access/gemini-search.ts +12 -4
- package/node_modules/pi-web-access/index.ts +29 -37
- package/node_modules/pi-web-access/openai-search.ts +35 -7
- package/node_modules/pi-web-access/package.json +8 -7
- package/node_modules/pi-web-access/page-query.ts +2 -2
- package/node_modules/pi-web-access/query-rewrite.ts +2 -3
- package/node_modules/pi-web-access/ssrf-protection.ts +27 -10
- package/node_modules/pi-web-access/storage.ts +48 -77
- package/node_modules/pi-web-access/summary-model-scope.ts +6 -77
- package/node_modules/pi-web-access/summary-review.ts +3 -4
- package/node_modules/pi-web-access/tavily.ts +67 -20
- package/node_modules/pi-web-access/tool-activation.ts +53 -33
- package/node_modules/pi-web-access/utils.ts +1 -1
- package/node_modules/pi-web-access/you.ts +164 -0
- package/node_modules/pi-web-access/zai.ts +161 -0
- package/node_modules/remote-pi/package.json +5 -1
- package/package.json +19 -31
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +0 -1013
- package/node_modules/pi-mcp-adapter/LICENSE +0 -21
- package/node_modules/pi-mcp-adapter/OAUTH.md +0 -369
- package/node_modules/pi-mcp-adapter/README.md +0 -1021
- package/node_modules/pi-mcp-adapter/abort.ts +0 -34
- package/node_modules/pi-mcp-adapter/agent-dir.ts +0 -68
- package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +0 -416
- package/node_modules/pi-mcp-adapter/agent-plugin-provenance.ts +0 -36
- package/node_modules/pi-mcp-adapter/app-bridge.bundle.js +0 -67
- package/node_modules/pi-mcp-adapter/banner.png +0 -0
- package/node_modules/pi-mcp-adapter/bearer-command-resolver.ts +0 -193
- package/node_modules/pi-mcp-adapter/claude-plugin-loader.ts +0 -365
- package/node_modules/pi-mcp-adapter/cli.js +0 -454
- package/node_modules/pi-mcp-adapter/commands.ts +0 -861
- package/node_modules/pi-mcp-adapter/config.ts +0 -1565
- package/node_modules/pi-mcp-adapter/consent-manager.ts +0 -95
- package/node_modules/pi-mcp-adapter/direct-tool-surface.ts +0 -244
- package/node_modules/pi-mcp-adapter/direct-tools.ts +0 -428
- package/node_modules/pi-mcp-adapter/dist/abort.d.ts +0 -2
- package/node_modules/pi-mcp-adapter/dist/abort.js +0 -36
- package/node_modules/pi-mcp-adapter/dist/abort.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/agent-dir.d.ts +0 -10
- package/node_modules/pi-mcp-adapter/dist/agent-dir.js +0 -63
- package/node_modules/pi-mcp-adapter/dist/agent-dir.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.d.ts +0 -8
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js +0 -398
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-provenance.d.ts +0 -1
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-provenance.js +0 -31
- package/node_modules/pi-mcp-adapter/dist/agent-plugin-provenance.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/bearer-command-resolver.d.ts +0 -6
- package/node_modules/pi-mcp-adapter/dist/bearer-command-resolver.js +0 -194
- package/node_modules/pi-mcp-adapter/dist/bearer-command-resolver.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/claude-plugin-loader.d.ts +0 -9
- package/node_modules/pi-mcp-adapter/dist/claude-plugin-loader.js +0 -362
- package/node_modules/pi-mcp-adapter/dist/claude-plugin-loader.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/config.d.ts +0 -134
- package/node_modules/pi-mcp-adapter/dist/config.js +0 -1361
- package/node_modules/pi-mcp-adapter/dist/config.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/consent-manager.d.ts +0 -18
- package/node_modules/pi-mcp-adapter/dist/consent-manager.js +0 -88
- package/node_modules/pi-mcp-adapter/dist/consent-manager.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/elicitation-handler.d.ts +0 -17
- package/node_modules/pi-mcp-adapter/dist/elicitation-handler.js +0 -316
- package/node_modules/pi-mcp-adapter/dist/elicitation-handler.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/errors.d.ts +0 -131
- package/node_modules/pi-mcp-adapter/dist/errors.js +0 -278
- package/node_modules/pi-mcp-adapter/dist/errors.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/http-ca.d.ts +0 -8
- package/node_modules/pi-mcp-adapter/dist/http-ca.js +0 -88
- package/node_modules/pi-mcp-adapter/dist/http-ca.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/jev-client.d.ts +0 -14
- package/node_modules/pi-mcp-adapter/dist/jev-client.js +0 -367
- package/node_modules/pi-mcp-adapter/dist/jev-client.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/jev-contracts.d.ts +0 -77
- package/node_modules/pi-mcp-adapter/dist/jev-contracts.js +0 -2
- package/node_modules/pi-mcp-adapter/dist/jev-contracts.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/jev-key-store.d.ts +0 -51
- package/node_modules/pi-mcp-adapter/dist/jev-key-store.js +0 -205
- package/node_modules/pi-mcp-adapter/dist/jev-key-store.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/json-schema-validator.d.ts +0 -2
- package/node_modules/pi-mcp-adapter/dist/json-schema-validator.js +0 -68
- package/node_modules/pi-mcp-adapter/dist/json-schema-validator.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/lifecycle.d.ts +0 -56
- package/node_modules/pi-mcp-adapter/dist/lifecycle.js +0 -410
- package/node_modules/pi-mcp-adapter/dist/lifecycle.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/logger.d.ts +0 -51
- package/node_modules/pi-mcp-adapter/dist/logger.js +0 -131
- package/node_modules/pi-mcp-adapter/dist/logger.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/mcp-auth-fetch.d.ts +0 -26
- package/node_modules/pi-mcp-adapter/dist/mcp-auth-fetch.js +0 -103
- package/node_modules/pi-mcp-adapter/dist/mcp-auth-fetch.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/mcp-auth-flow.d.ts +0 -118
- package/node_modules/pi-mcp-adapter/dist/mcp-auth-flow.js +0 -1097
- package/node_modules/pi-mcp-adapter/dist/mcp-auth-flow.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/mcp-auth.d.ts +0 -170
- package/node_modules/pi-mcp-adapter/dist/mcp-auth.js +0 -1142
- package/node_modules/pi-mcp-adapter/dist/mcp-auth.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/mcp-bearer-store.d.ts +0 -24
- package/node_modules/pi-mcp-adapter/dist/mcp-bearer-store.js +0 -203
- package/node_modules/pi-mcp-adapter/dist/mcp-bearer-store.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/mcp-callback-server.d.ts +0 -53
- package/node_modules/pi-mcp-adapter/dist/mcp-callback-server.js +0 -441
- package/node_modules/pi-mcp-adapter/dist/mcp-callback-server.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/mcp-oauth-provider.d.ts +0 -148
- package/node_modules/pi-mcp-adapter/dist/mcp-oauth-provider.js +0 -689
- package/node_modules/pi-mcp-adapter/dist/mcp-oauth-provider.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/mcp-probe.d.ts +0 -6
- package/node_modules/pi-mcp-adapter/dist/mcp-probe.js +0 -166
- package/node_modules/pi-mcp-adapter/dist/mcp-probe.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/mcp-tasks.d.ts +0 -102
- package/node_modules/pi-mcp-adapter/dist/mcp-tasks.js +0 -369
- package/node_modules/pi-mcp-adapter/dist/mcp-tasks.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/mcp-trace.d.ts +0 -95
- package/node_modules/pi-mcp-adapter/dist/mcp-trace.js +0 -242
- package/node_modules/pi-mcp-adapter/dist/mcp-trace.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.d.ts +0 -19
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +0 -301
- package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/npx-resolver.d.ts +0 -6
- package/node_modules/pi-mcp-adapter/dist/npx-resolver.js +0 -505
- package/node_modules/pi-mcp-adapter/dist/npx-resolver.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.d.ts +0 -2
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js +0 -144
- package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/request-headers-command.d.ts +0 -10
- package/node_modules/pi-mcp-adapter/dist/request-headers-command.js +0 -312
- package/node_modules/pi-mcp-adapter/dist/request-headers-command.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/resource-tools.d.ts +0 -1
- package/node_modules/pi-mcp-adapter/dist/resource-tools.js +0 -15
- package/node_modules/pi-mcp-adapter/dist/resource-tools.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/runtime-owner.d.ts +0 -13
- package/node_modules/pi-mcp-adapter/dist/runtime-owner.js +0 -97
- package/node_modules/pi-mcp-adapter/dist/runtime-owner.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/sampling-handler.d.ts +0 -17
- package/node_modules/pi-mcp-adapter/dist/sampling-handler.js +0 -203
- package/node_modules/pi-mcp-adapter/dist/sampling-handler.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/secure-keyring.d.ts +0 -11
- package/node_modules/pi-mcp-adapter/dist/secure-keyring.js +0 -172
- package/node_modules/pi-mcp-adapter/dist/secure-keyring.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/server-manager.d.ts +0 -157
- package/node_modules/pi-mcp-adapter/dist/server-manager.js +0 -1745
- package/node_modules/pi-mcp-adapter/dist/server-manager.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/session-approvals.d.ts +0 -34
- package/node_modules/pi-mcp-adapter/dist/session-approvals.js +0 -140
- package/node_modules/pi-mcp-adapter/dist/session-approvals.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/session-recovery.d.ts +0 -26
- package/node_modules/pi-mcp-adapter/dist/session-recovery.js +0 -142
- package/node_modules/pi-mcp-adapter/dist/session-recovery.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/state.d.ts +0 -73
- package/node_modules/pi-mcp-adapter/dist/state.js +0 -2
- package/node_modules/pi-mcp-adapter/dist/state.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/types.d.ts +0 -642
- package/node_modules/pi-mcp-adapter/dist/types.js +0 -331
- package/node_modules/pi-mcp-adapter/dist/types.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.d.ts +0 -6
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js +0 -37
- package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/ui-resource-handler.d.ts +0 -17
- package/node_modules/pi-mcp-adapter/dist/ui-resource-handler.js +0 -219
- package/node_modules/pi-mcp-adapter/dist/ui-resource-handler.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.d.ts +0 -104
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js +0 -59
- package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.d.ts +0 -4
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js +0 -27
- package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/unix-socket-transport.d.ts +0 -15
- package/node_modules/pi-mcp-adapter/dist/unix-socket-transport.js +0 -85
- package/node_modules/pi-mcp-adapter/dist/unix-socket-transport.js.map +0 -1
- package/node_modules/pi-mcp-adapter/dist/utils.d.ts +0 -41
- package/node_modules/pi-mcp-adapter/dist/utils.js +0 -417
- package/node_modules/pi-mcp-adapter/dist/utils.js.map +0 -1
- package/node_modules/pi-mcp-adapter/elicitation-handler.ts +0 -358
- package/node_modules/pi-mcp-adapter/error-signal.ts +0 -32
- package/node_modules/pi-mcp-adapter/errors.ts +0 -364
- package/node_modules/pi-mcp-adapter/examples/jev-accessibility-loop.mjs +0 -85
- package/node_modules/pi-mcp-adapter/examples/jev-semantic-filter.mjs +0 -34
- package/node_modules/pi-mcp-adapter/failure-backoff.ts +0 -23
- package/node_modules/pi-mcp-adapter/glimpse-ui.ts +0 -80
- package/node_modules/pi-mcp-adapter/host-html-template.ts +0 -515
- package/node_modules/pi-mcp-adapter/http-ca.ts +0 -84
- package/node_modules/pi-mcp-adapter/index.ts +0 -2106
- package/node_modules/pi-mcp-adapter/init.ts +0 -721
- package/node_modules/pi-mcp-adapter/jev-client.ts +0 -300
- package/node_modules/pi-mcp-adapter/jev-contracts.ts +0 -53
- package/node_modules/pi-mcp-adapter/jev-key-store.ts +0 -192
- package/node_modules/pi-mcp-adapter/json-schema-validator.ts +0 -83
- package/node_modules/pi-mcp-adapter/lazy-loader.ts +0 -7
- package/node_modules/pi-mcp-adapter/lifecycle.ts +0 -457
- package/node_modules/pi-mcp-adapter/logger.ts +0 -169
- package/node_modules/pi-mcp-adapter/mcp-auth-fetch.ts +0 -113
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +0 -1296
- package/node_modules/pi-mcp-adapter/mcp-auth.ts +0 -1287
- package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +0 -250
- package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +0 -534
- package/node_modules/pi-mcp-adapter/mcp-code.ts +0 -495
- package/node_modules/pi-mcp-adapter/mcp-install.ts +0 -60
- package/node_modules/pi-mcp-adapter/mcp-keyring-helper.cjs +0 -89
- package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +0 -819
- package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +0 -511
- package/node_modules/pi-mcp-adapter/mcp-panel-theme.ts +0 -104
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +0 -1099
- package/node_modules/pi-mcp-adapter/mcp-probe.ts +0 -201
- package/node_modules/pi-mcp-adapter/mcp-references.ts +0 -373
- package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +0 -137
- package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +0 -747
- package/node_modules/pi-mcp-adapter/mcp-status.ts +0 -105
- package/node_modules/pi-mcp-adapter/mcp-tasks.ts +0 -467
- package/node_modules/pi-mcp-adapter/mcp-trace.ts +0 -306
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +0 -362
- package/node_modules/pi-mcp-adapter/namespace-tools.ts +0 -334
- package/node_modules/pi-mcp-adapter/npx-resolver.ts +0 -543
- package/node_modules/pi-mcp-adapter/oauth-handler.ts +0 -30
- package/node_modules/pi-mcp-adapter/oauth.ts +0 -52
- package/node_modules/pi-mcp-adapter/onboarding-state.ts +0 -76
- package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +0 -156
- package/node_modules/pi-mcp-adapter/package.json +0 -219
- package/node_modules/pi-mcp-adapter/panel-keys.ts +0 -53
- package/node_modules/pi-mcp-adapter/prompts.ts +0 -385
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +0 -1735
- package/node_modules/pi-mcp-adapter/request-headers-command.ts +0 -333
- package/node_modules/pi-mcp-adapter/resource-tools.ts +0 -17
- package/node_modules/pi-mcp-adapter/runtime-owner.ts +0 -106
- package/node_modules/pi-mcp-adapter/sampling-handler.ts +0 -261
- package/node_modules/pi-mcp-adapter/sandbox-proxy-template.ts +0 -144
- package/node_modules/pi-mcp-adapter/search-ranking.ts +0 -309
- package/node_modules/pi-mcp-adapter/secure-keyring.ts +0 -170
- package/node_modules/pi-mcp-adapter/semantic-search.ts +0 -186
- package/node_modules/pi-mcp-adapter/server-manager.ts +0 -2088
- package/node_modules/pi-mcp-adapter/session-approvals.ts +0 -201
- package/node_modules/pi-mcp-adapter/session-recovery.ts +0 -158
- package/node_modules/pi-mcp-adapter/skills/mcp-scripting/SKILL.md +0 -49
- package/node_modules/pi-mcp-adapter/state.ts +0 -71
- package/node_modules/pi-mcp-adapter/tool-approval.ts +0 -205
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +0 -302
- package/node_modules/pi-mcp-adapter/tool-registrar.ts +0 -255
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +0 -573
- package/node_modules/pi-mcp-adapter/ts-shape.ts +0 -149
- package/node_modules/pi-mcp-adapter/types.ts +0 -1120
- package/node_modules/pi-mcp-adapter/ui-app-bridge-helpers.ts +0 -40
- package/node_modules/pi-mcp-adapter/ui-resource-handler.ts +0 -266
- package/node_modules/pi-mcp-adapter/ui-server.ts +0 -993
- package/node_modules/pi-mcp-adapter/ui-session.ts +0 -624
- package/node_modules/pi-mcp-adapter/ui-stream-types.ts +0 -89
- package/node_modules/pi-mcp-adapter/ui-tool-visibility.ts +0 -25
- package/node_modules/pi-mcp-adapter/unix-socket-transport.ts +0 -85
- package/node_modules/pi-mcp-adapter/utils.ts +0 -464
|
@@ -16,11 +16,6 @@ interface WebSearchConfig {
|
|
|
16
16
|
exaBaseUrl?: unknown;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
interface ExaAnswerResponse {
|
|
20
|
-
answer?: string;
|
|
21
|
-
citations?: Array<{ url?: string; title?: string; text?: string; publishedDate?: string }>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
19
|
interface ExaSearchResponse {
|
|
25
20
|
results?: Array<{
|
|
26
21
|
title?: string;
|
|
@@ -146,6 +141,16 @@ function normalizeHighlights(value: unknown): string[] {
|
|
|
146
141
|
return value.filter((item): item is string => typeof item === "string" && item.trim().length > 0);
|
|
147
142
|
}
|
|
148
143
|
|
|
144
|
+
function fallbackSourceLabel(url: string | undefined, index: number): string {
|
|
145
|
+
try {
|
|
146
|
+
const hostname = url ? new URL(url).hostname : "";
|
|
147
|
+
if (hostname) return hostname;
|
|
148
|
+
} catch {
|
|
149
|
+
// Invalid URLs use the generic label.
|
|
150
|
+
}
|
|
151
|
+
return `Source ${index + 1}`;
|
|
152
|
+
}
|
|
153
|
+
|
|
149
154
|
function buildAnswerFromSearchResults(results: ExaSearchResponse["results"]): string {
|
|
150
155
|
if (!results?.length) return "";
|
|
151
156
|
const parts: string[] = [];
|
|
@@ -157,20 +162,20 @@ function buildAnswerFromSearchResults(results: ExaSearchResponse["results"]): st
|
|
|
157
162
|
? highlights.join(" ")
|
|
158
163
|
: typeof item.text === "string" ? item.text.trim().slice(0, 1000) : "";
|
|
159
164
|
if (!content) continue;
|
|
160
|
-
const sourceTitle = item.title ||
|
|
165
|
+
const sourceTitle = item.title || fallbackSourceLabel(item.url, i);
|
|
161
166
|
parts.push(`${content}\nSource: ${sourceTitle} (${item.url})`);
|
|
162
167
|
}
|
|
163
168
|
return parts.join("\n\n");
|
|
164
169
|
}
|
|
165
170
|
|
|
166
|
-
function mapResults(results: ExaSearchResponse["results"]
|
|
171
|
+
function mapResults(results: ExaSearchResponse["results"]): SearchResponse["results"] {
|
|
167
172
|
if (!Array.isArray(results)) return [];
|
|
168
173
|
const mapped: SearchResponse["results"] = [];
|
|
169
174
|
for (let i = 0; i < results.length; i++) {
|
|
170
175
|
const item = results[i];
|
|
171
176
|
if (!item?.url) continue;
|
|
172
177
|
mapped.push({
|
|
173
|
-
title: item.title ||
|
|
178
|
+
title: item.title || fallbackSourceLabel(item.url, i),
|
|
174
179
|
url: item.url,
|
|
175
180
|
snippet: "",
|
|
176
181
|
});
|
|
@@ -180,15 +185,9 @@ function mapResults(results: ExaSearchResponse["results"] | ExaAnswerResponse["c
|
|
|
180
185
|
|
|
181
186
|
function mapInlineContent(results: ExaSearchResponse["results"]): ExtractedContent[] {
|
|
182
187
|
if (!results?.length) return [];
|
|
183
|
-
return results
|
|
184
|
-
.
|
|
185
|
-
|
|
186
|
-
.map(r => ({
|
|
187
|
-
url: r.url,
|
|
188
|
-
title: r.title || "",
|
|
189
|
-
content: r.text,
|
|
190
|
-
error: null,
|
|
191
|
-
}));
|
|
188
|
+
return results.flatMap((r, i) => r?.url && typeof r.text === "string" && r.text.length > 0
|
|
189
|
+
? [{ url: r.url, title: r.title || fallbackSourceLabel(r.url, i), content: r.text, error: null }]
|
|
190
|
+
: []);
|
|
192
191
|
}
|
|
193
192
|
|
|
194
193
|
function toSearchResponse(
|
|
@@ -318,21 +317,16 @@ function buildAnswerFromMcpResults(results: McpParsedResult[]): string {
|
|
|
318
317
|
const result = results[i];
|
|
319
318
|
const snippet = result.content.replace(/\s+/g, " ").trim().slice(0, 500);
|
|
320
319
|
if (!snippet) continue;
|
|
321
|
-
const sourceTitle = result.title ||
|
|
320
|
+
const sourceTitle = result.title || fallbackSourceLabel(result.url, i);
|
|
322
321
|
parts.push(`${snippet}\nSource: ${sourceTitle} (${result.url})`);
|
|
323
322
|
}
|
|
324
323
|
return parts.join("\n\n");
|
|
325
324
|
}
|
|
326
325
|
|
|
327
326
|
function mapMcpInlineContent(results: McpParsedResult[]): ExtractedContent[] {
|
|
328
|
-
return results
|
|
329
|
-
.
|
|
330
|
-
|
|
331
|
-
url: result.url,
|
|
332
|
-
title: result.title,
|
|
333
|
-
content: result.content,
|
|
334
|
-
error: null,
|
|
335
|
-
}));
|
|
327
|
+
return results.flatMap((result, i) => result.content.length > 0
|
|
328
|
+
? [{ url: result.url, title: result.title || fallbackSourceLabel(result.url, i), content: result.content, error: null }]
|
|
329
|
+
: []);
|
|
336
330
|
}
|
|
337
331
|
|
|
338
332
|
function buildMcpQuery(query: string, options: ExaSearchOptions): string {
|
|
@@ -458,35 +452,9 @@ export async function searchWithExa(query: string, options: ExaSearchOptions = {
|
|
|
458
452
|
}
|
|
459
453
|
|
|
460
454
|
const apiBaseUrl = getApiBaseUrl();
|
|
461
|
-
const useSearch = options.includeContent
|
|
462
|
-
|| !!options.recencyFilter
|
|
463
|
-
|| !!options.domainFilter?.length
|
|
464
|
-
|| !!(options.numResults && options.numResults !== 5);
|
|
465
|
-
|
|
466
455
|
const activityId = activityMonitor.logStart({ type: "api", query });
|
|
467
456
|
|
|
468
457
|
try {
|
|
469
|
-
if (!useSearch) {
|
|
470
|
-
const response = await fetchWithCredentialRedirects(`${apiBaseUrl}/answer`, {
|
|
471
|
-
method: "POST",
|
|
472
|
-
headers: exaApiHeaders(apiKey),
|
|
473
|
-
body: JSON.stringify({ query }),
|
|
474
|
-
signal: requestSignal(options.signal),
|
|
475
|
-
}, ["x-api-key"]);
|
|
476
|
-
|
|
477
|
-
if (!response.ok) {
|
|
478
|
-
const errorText = redactCredential(await response.text(), apiKey);
|
|
479
|
-
throw new Error(`Exa API error ${response.status}: ${errorText.slice(0, 300)}`);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
const data = await response.json() as ExaAnswerResponse;
|
|
483
|
-
activityMonitor.logComplete(activityId, response.status);
|
|
484
|
-
return {
|
|
485
|
-
answer: data.answer || "",
|
|
486
|
-
results: mapResults(data.citations),
|
|
487
|
-
};
|
|
488
|
-
}
|
|
489
|
-
|
|
490
458
|
const response = await fetchWithCredentialRedirects(`${apiBaseUrl}/search`, {
|
|
491
459
|
method: "POST",
|
|
492
460
|
headers: exaApiHeaders(apiKey),
|
|
@@ -173,13 +173,14 @@ const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
|
|
|
173
173
|
async function fetchAuthenticatedRemoteUrl(
|
|
174
174
|
url: string,
|
|
175
175
|
init: RequestInit,
|
|
176
|
-
validationOptions: { ssrf: SsrfConfig; domainPolicy: DomainPolicy; lookup?: Lookup },
|
|
176
|
+
validationOptions: { ssrf: SsrfConfig; domainPolicy: DomainPolicy; lookup?: Lookup; proxy?: string },
|
|
177
177
|
profile: AuthFetchProfile,
|
|
178
178
|
): Promise<Response> {
|
|
179
179
|
let current = await validateRemoteUrl(url, {
|
|
180
180
|
allowRanges: validationOptions.ssrf.allowRanges,
|
|
181
181
|
trustEnvProxy: validationOptions.ssrf.trustEnvProxy,
|
|
182
182
|
domainPolicy: validationOptions.domainPolicy,
|
|
183
|
+
proxy: validationOptions.proxy,
|
|
183
184
|
...(validationOptions.lookup ? { lookup: validationOptions.lookup } : {}),
|
|
184
185
|
});
|
|
185
186
|
let requestInit = init;
|
|
@@ -196,6 +197,7 @@ async function fetchAuthenticatedRemoteUrl(
|
|
|
196
197
|
allowRanges: validationOptions.ssrf.allowRanges,
|
|
197
198
|
trustEnvProxy: validationOptions.ssrf.trustEnvProxy,
|
|
198
199
|
domainPolicy: validationOptions.domainPolicy,
|
|
200
|
+
proxy: validationOptions.proxy,
|
|
199
201
|
...(validationOptions.lookup ? { lookup: validationOptions.lookup } : {}),
|
|
200
202
|
});
|
|
201
203
|
authFetchRedirectGuard(profile, from, current);
|
|
@@ -287,6 +289,21 @@ function notFoundGuidance(result: ExtractedContent, toolNames?: RegisteredToolNa
|
|
|
287
289
|
return lines.join("\n");
|
|
288
290
|
}
|
|
289
291
|
|
|
292
|
+
|
|
293
|
+
/** Fallback-list hint for the keyless Jina Reader. Returns null when Jina
|
|
294
|
+
* already ran for this fetch, and otherwise names only the config change still
|
|
295
|
+
* missing, so users keep their existing or default provider order. */
|
|
296
|
+
function jinaReaderGuidance(routing: FetchRouting, providerOrder: FetchProvider[], needsRemoteOptIn: boolean): string | null {
|
|
297
|
+
if (providerOrder.includes("jina")) return null;
|
|
298
|
+
const privacy = "target URLs are fetched through Jina's infrastructure";
|
|
299
|
+
const optInCaveat = "this also allows the other hosted providers in your fetch provider order";
|
|
300
|
+
if (routing.providers.includes("jina")) {
|
|
301
|
+
return ` • Enable the keyless Jina Reader fallback: set fetchRouting.allowRemoteHostedProviders to true in ${WEB_SEARCH_CONFIG_PATH} (Jina is already in your fetch provider order; ${optInCaveat}; ${privacy})`;
|
|
302
|
+
}
|
|
303
|
+
return needsRemoteOptIn
|
|
304
|
+
? ` • Enable the keyless Jina Reader fallback: add "jina" to your existing fetchRouting.providers and set fetchRouting.allowRemoteHostedProviders to true in ${WEB_SEARCH_CONFIG_PATH} (${optInCaveat}; ${privacy})`
|
|
305
|
+
: ` • Enable the keyless Jina Reader fallback: add "jina" to your existing fetchRouting.providers in ${WEB_SEARCH_CONFIG_PATH} (${privacy})`;
|
|
306
|
+
}
|
|
290
307
|
function abortedResult(url: string): ExtractedContent {
|
|
291
308
|
return { url, title: "", content: "", error: "Aborted" };
|
|
292
309
|
}
|
|
@@ -527,6 +544,7 @@ export async function extractContent(
|
|
|
527
544
|
allowRanges: ssrf.allowRanges,
|
|
528
545
|
trustEnvProxy: ssrf.trustEnvProxy,
|
|
529
546
|
domainPolicy,
|
|
547
|
+
proxy: options?.proxy,
|
|
530
548
|
...(options?.lookup ? { lookup: options.lookup } : {}),
|
|
531
549
|
});
|
|
532
550
|
} catch (err) {
|
|
@@ -1020,6 +1038,7 @@ export async function extractContent(
|
|
|
1020
1038
|
}
|
|
1021
1039
|
|
|
1022
1040
|
const searchToolName = options?.toolNames?.webSearch;
|
|
1041
|
+
const jinaHint = jinaReaderGuidance(fetchRouting, providerOrder, Boolean(remoteUrl) && !fetchRouting.allowRemoteHostedProviders);
|
|
1023
1042
|
const guidance = [
|
|
1024
1043
|
finalHttpResult?.error ?? "No fetch_content provider returned content",
|
|
1025
1044
|
...(firecrawlError ? [`Firecrawl fallback failed: ${firecrawlError}`] : []),
|
|
@@ -1034,6 +1053,7 @@ export async function extractContent(
|
|
|
1034
1053
|
...(brightdataError ? [`Bright Data fallback failed: ${brightdataError}`] : []),
|
|
1035
1054
|
"",
|
|
1036
1055
|
"Fallback options:",
|
|
1056
|
+
...(jinaHint ? [jinaHint] : []),
|
|
1037
1057
|
` • Set firecrawlBaseUrl in ${WEB_SEARCH_CONFIG_PATH} to a self-hosted Firecrawl instance`,
|
|
1038
1058
|
` • Set crawl4aiBaseUrl in ${WEB_SEARCH_CONFIG_PATH} to a self-hosted Crawl4AI instance`,
|
|
1039
1059
|
` • Set tinyfishApiKey in ${WEB_SEARCH_CONFIG_PATH} or TINYFISH_API_KEY`,
|
|
@@ -1050,6 +1070,18 @@ export async function extractContent(
|
|
|
1050
1070
|
return { ...(finalHttpResult ?? { url, title: "", content: "", error: null }), error: guidance };
|
|
1051
1071
|
}
|
|
1052
1072
|
|
|
1073
|
+
// Cloudflare interstitials served with HTTP 200. The header is authoritative for
|
|
1074
|
+
// any text response; the body check is HTML-only and needs both challenge-platform
|
|
1075
|
+
// markers so a generic "Just a moment..." page never matches.
|
|
1076
|
+
function isCloudflareChallenge(response: Response, text: string, isHTML: boolean): boolean {
|
|
1077
|
+
if (response.status !== 200) return false;
|
|
1078
|
+
if (response.headers.get("cf-mitigated") === "challenge") return true;
|
|
1079
|
+
return isHTML &&
|
|
1080
|
+
/<title>\s*Just a moment\.\.\.\s*<\/title>/i.test(text) &&
|
|
1081
|
+
text.includes("window._cf_chl_opt") &&
|
|
1082
|
+
text.includes("/cdn-cgi/challenge-platform/");
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1053
1085
|
function isLikelyJSRendered(html: string): boolean {
|
|
1054
1086
|
const bodyMatch = html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
|
|
1055
1087
|
if (!bodyMatch) return false;
|
|
@@ -1162,7 +1194,6 @@ async function extractViaHttp(
|
|
|
1162
1194
|
const ssrf = loadSsrfConfig();
|
|
1163
1195
|
const domainPolicy = loadFetchContentDomainPolicy();
|
|
1164
1196
|
const authProfile = options?.authFetchProfile;
|
|
1165
|
-
const trustEnvProxy = options?.proxy === undefined && ssrf.trustEnvProxy;
|
|
1166
1197
|
const requestInit: ProxiedRequestInit = {
|
|
1167
1198
|
signal: controller.signal,
|
|
1168
1199
|
__proxy: options?.proxy,
|
|
@@ -1179,14 +1210,15 @@ async function extractViaHttp(
|
|
|
1179
1210
|
},
|
|
1180
1211
|
};
|
|
1181
1212
|
const response = authProfile
|
|
1182
|
-
? await fetchAuthenticatedRemoteUrl(url, requestInit, { ssrf
|
|
1213
|
+
? await fetchAuthenticatedRemoteUrl(url, requestInit, { ssrf, domainPolicy, proxy: options?.proxy, ...(options?.lookup ? { lookup: options.lookup } : {}) }, authProfile)
|
|
1183
1214
|
: await fetchRemoteUrl(
|
|
1184
1215
|
url,
|
|
1185
1216
|
requestInit,
|
|
1186
1217
|
{
|
|
1187
1218
|
allowRanges: ssrf.allowRanges,
|
|
1188
|
-
trustEnvProxy,
|
|
1219
|
+
trustEnvProxy: ssrf.trustEnvProxy,
|
|
1189
1220
|
domainPolicy,
|
|
1221
|
+
proxy: options?.proxy,
|
|
1190
1222
|
...(options?.lookup ? { lookup: options.lookup } : {}),
|
|
1191
1223
|
},
|
|
1192
1224
|
);
|
|
@@ -1310,6 +1342,11 @@ async function extractViaHttp(
|
|
|
1310
1342
|
const text = await readTextResponseWithLimit(response, maxResponseSize);
|
|
1311
1343
|
const isHTML = contentType.includes("text/html") || contentType.includes("application/xhtml+xml");
|
|
1312
1344
|
|
|
1345
|
+
if (isCloudflareChallenge(response, text, isHTML)) {
|
|
1346
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
1347
|
+
return { url, title: "", content: "", error: `HTTP ${response.status}: Blocked by Cloudflare challenge page`, status: response.status };
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1313
1350
|
if (!isHTML) {
|
|
1314
1351
|
activityMonitor.logComplete(activityId, response.status);
|
|
1315
1352
|
const title = extractTextTitle(text, url);
|
|
@@ -22,6 +22,7 @@ import { isSearch1APIAvailable, searchWithSearch1API } from "./search1api.ts";
|
|
|
22
22
|
import { isSearchinfinityAvailable, searchWithSearchinfinity } from "./searchinfinity.ts";
|
|
23
23
|
import { isQueritAvailable, searchWithQuerit } from "./querit.ts";
|
|
24
24
|
import { isTavilyAvailable, searchWithTavily } from "./tavily.ts";
|
|
25
|
+
import { isYouAvailable, searchWithYou } from "./you.ts";
|
|
25
26
|
import { isFirecrawlAvailable, searchWithFirecrawl } from "./firecrawl.ts";
|
|
26
27
|
import { isJinaSearchAvailable, searchWithJina } from "./jina-search.ts";
|
|
27
28
|
import { isSerpdiveAvailable, searchWithSerpdive } from "./serpdive.ts";
|
|
@@ -39,12 +40,13 @@ import { isSerpApiAvailable, searchWithSerpApi } from "./serpapi.ts";
|
|
|
39
40
|
import { isSerperAvailable, searchWithSerper } from "./serper.ts";
|
|
40
41
|
import { isSerplyAvailable, searchWithSerply } from "./serply.ts";
|
|
41
42
|
import { isBaizhiAvailable, searchWithBaizhi } from "./baizhi.ts";
|
|
43
|
+
import { isZaiAvailable, searchWithZai } from "./zai.ts";
|
|
42
44
|
import { isValyuAvailable, searchWithValyu } from "./valyu.ts";
|
|
43
45
|
import { isKimiSearchAvailable, searchWithKimi } from "./kimi-search.ts";
|
|
44
46
|
import { isMistralAvailable, searchWithMistral } from "./mistral-search.ts";
|
|
45
47
|
import { getWebSearchConfigPath } from "./utils.ts";
|
|
46
48
|
|
|
47
|
-
export const RESOLVED_SEARCH_PROVIDERS = ["openai", "brave", "parallel", "parallel-mcp", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "firecrawl", "jina", "searxng", "duckduckgo", "perplexity", "gemini", "kimi", "exa", "serpdive", "kagi", "ollama", "anysearch", "xai", "mistral", "brightdata", "serpbase", "serpapi", "serper", "serply", "valyu", "bocha", "xcrawl", "baizhi"] as const;
|
|
49
|
+
export const RESOLVED_SEARCH_PROVIDERS = ["openai", "brave", "parallel", "parallel-mcp", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "you", "firecrawl", "jina", "searxng", "duckduckgo", "perplexity", "gemini", "kimi", "exa", "serpdive", "kagi", "ollama", "anysearch", "xai", "mistral", "brightdata", "serpbase", "serpapi", "serper", "serply", "valyu", "bocha", "xcrawl", "baizhi", "zai"] as const;
|
|
48
50
|
export const SEARCH_PROVIDERS = ["auto", "all", ...RESOLVED_SEARCH_PROVIDERS] as const;
|
|
49
51
|
|
|
50
52
|
export type ResolvedSearchProvider = typeof RESOLVED_SEARCH_PROVIDERS[number];
|
|
@@ -109,7 +111,7 @@ export interface AttributedSearchResponse extends SearchResponse {
|
|
|
109
111
|
|
|
110
112
|
const CONFIG_PATH = getWebSearchConfigPath();
|
|
111
113
|
const DEFAULT_SEARCH_MODEL = "gemini-3.6-flash";
|
|
112
|
-
// Explicit-only providers (Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, xAI, Mistral, Bright Data, SerpBase, SerpApi, Serper, Serply, Valyu) are deliberately absent:
|
|
114
|
+
// Explicit-only providers (Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, xAI, Mistral, Bright Data, SerpBase, SerpApi, Serper, Serply, You.com, Valyu, Baizhi, Z.ai) are deliberately absent:
|
|
113
115
|
// `all` must never fan out to an opt-in or paid provider without the user asking for it.
|
|
114
116
|
export const ALL_SEARCH_PROVIDERS: ResolvedSearchProvider[] = ["searxng", "openai", "exa", "brave", "parallel", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "firecrawl", "jina", "serpdive", "kagi", "ollama", "perplexity", "gemini", "bocha"];
|
|
115
117
|
const VALID_ROUTING_KINDS = ["transient", "quota", "network", "invalid-response", "unsupported"] as const;
|
|
@@ -389,6 +391,7 @@ async function searchWithResolvedProvider(
|
|
|
389
391
|
if (provider === "searchinfinity") return { ...(await searchWithSearchinfinity(query, options)), provider };
|
|
390
392
|
if (provider === "querit") return { ...(await searchWithQuerit(query, options)), provider };
|
|
391
393
|
if (provider === "tavily") return { ...(await searchWithTavily(query, options)), provider };
|
|
394
|
+
if (provider === "you") return { ...(await searchWithYou(query, options)), provider };
|
|
392
395
|
if (provider === "firecrawl") return { ...(await searchWithFirecrawl(query, options)), provider };
|
|
393
396
|
if (provider === "jina") return { ...(await searchWithJina(query, options)), provider };
|
|
394
397
|
if (provider === "serpdive") return { ...(await searchWithSerpdive(query, options)), provider };
|
|
@@ -404,6 +407,7 @@ async function searchWithResolvedProvider(
|
|
|
404
407
|
if (provider === "serper") return { ...(await searchWithSerper(query, options)), provider };
|
|
405
408
|
if (provider === "serply") return { ...(await searchWithSerply(query, options)), provider };
|
|
406
409
|
if (provider === "baizhi") return { ...(await searchWithBaizhi(query, options)), provider };
|
|
410
|
+
if (provider === "zai") return { ...(await searchWithZai(query, options)), provider };
|
|
407
411
|
if (provider === "valyu") return { ...(await searchWithValyu(query, options)), provider };
|
|
408
412
|
if (provider === "xcrawl") return { ...(await searchWithXCrawl(query, options)), provider };
|
|
409
413
|
if (provider === "perplexity") return { ...(await searchWithPerplexity(query, options)), provider };
|
|
@@ -440,6 +444,7 @@ async function isResolvedProviderAvailable(provider: ResolvedSearchProvider, opt
|
|
|
440
444
|
if (provider === "searchinfinity") return isSearchinfinityAvailable();
|
|
441
445
|
if (provider === "querit") return isQueritAvailable();
|
|
442
446
|
if (provider === "tavily") return isTavilyAvailable();
|
|
447
|
+
if (provider === "you") return isYouAvailable();
|
|
443
448
|
if (provider === "firecrawl") return isFirecrawlAvailable();
|
|
444
449
|
if (provider === "jina") return isJinaSearchAvailable();
|
|
445
450
|
if (provider === "serpdive") return isSerpdiveAvailable();
|
|
@@ -455,6 +460,7 @@ async function isResolvedProviderAvailable(provider: ResolvedSearchProvider, opt
|
|
|
455
460
|
if (provider === "serper") return isSerperAvailable();
|
|
456
461
|
if (provider === "serply") return isSerplyAvailable();
|
|
457
462
|
if (provider === "baizhi") return isBaizhiAvailable();
|
|
463
|
+
if (provider === "zai") return isZaiAvailable();
|
|
458
464
|
if (provider === "valyu") return isValyuAvailable();
|
|
459
465
|
if (provider === "xcrawl") return isXcrawlAvailable();
|
|
460
466
|
if (provider === "perplexity") return isPerplexityAvailable();
|
|
@@ -496,7 +502,9 @@ export function providerLabel(provider: ResolvedSearchProvider): string {
|
|
|
496
502
|
if (provider === "serpapi") return "SerpApi";
|
|
497
503
|
if (provider === "serper") return "Serper";
|
|
498
504
|
if (provider === "serply") return "Serply";
|
|
505
|
+
if (provider === "you") return "You.com";
|
|
499
506
|
if (provider === "baizhi") return "Baizhi";
|
|
507
|
+
if (provider === "zai") return "Z.ai";
|
|
500
508
|
if (provider === "valyu") return "Valyu";
|
|
501
509
|
return provider.charAt(0).toUpperCase() + provider.slice(1);
|
|
502
510
|
}
|
|
@@ -525,7 +533,7 @@ async function searchWithProviders(
|
|
|
525
533
|
: await isResolvedProviderAvailable(provider, options),
|
|
526
534
|
})))).filter((entry) => entry.available).map((entry) => entry.provider);
|
|
527
535
|
if (providers.length === 0) {
|
|
528
|
-
throw new Error("No configured search provider available for provider \"all\". Parallel MCP, DuckDuckGo, Kimi, AnySearch, xAI, Mistral, Bright Data, SerpBase, SerpApi, Serper, Serply, Valyu, and XCrawl are excluded.");
|
|
536
|
+
throw new Error("No configured search provider available for provider \"all\". Parallel MCP, DuckDuckGo, Kimi, AnySearch, xAI, Mistral, Bright Data, SerpBase, SerpApi, Serper, Serply, You.com, Valyu, Baizhi, Z.ai, and XCrawl are excluded.");
|
|
529
537
|
}
|
|
530
538
|
|
|
531
539
|
const settled = await Promise.allSettled(
|
|
@@ -820,7 +828,7 @@ export async function search(query: string, options: FullSearchOptions = {}): Pr
|
|
|
820
828
|
" 3. Set OPENAI_API_KEY, BRAVE_API_KEY, PARALLEL_API_KEY, TINYFISH_API_KEY, SEARCH1API_KEY, SEARCHINFINITY_API_KEY, QUERIT_API_KEY, TAVILY_API_KEY, FIRECRAWL_BASE_URL, JINA_API_KEY, SERPDIVE_API_KEY, KAGI_API_KEY, BOCHA_API_KEY, OLLAMA_API_KEY, SEARXNG_BASE_URL, EXA_API_KEY, PERPLEXITY_API_KEY, GEMINI_API_KEY, or CLOUDFLARE_API_KEY env vars\n" +
|
|
821
829
|
" 4. Set GOOGLE_GEMINI_BASE_URL with CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing\n" +
|
|
822
830
|
" 5. Sign into gemini.google.com in a supported Chromium-based browser\n" +
|
|
823
|
-
" 6. Explicitly select provider: \"anysearch\" for anonymous AnySearch, \"xcrawl\" for XCrawl, \"xai\" for Grok, \"mistral\" for Mistral Conversations web search, \"brightdata\" with brightdataSerpZone for paid Bright Data SERP, \"serpbase\", \"serpapi\", \"serper\", or \"serply\" for Google SERP, or \"valyu\" for research search"
|
|
831
|
+
" 6. Explicitly select provider: \"anysearch\" for anonymous AnySearch, \"xcrawl\" for XCrawl, \"xai\" for Grok, \"mistral\" for Mistral Conversations web search, \"brightdata\" with brightdataSerpZone for paid Bright Data SERP, \"serpbase\", \"serpapi\", \"serper\", or \"serply\" for Google SERP, \"you\" for You.com, \"zai\" for Z.ai GLM Coding Plan search, or \"valyu\" for research search"
|
|
824
832
|
);
|
|
825
833
|
}
|
|
826
834
|
|
|
@@ -55,6 +55,7 @@ import { isSearch1APIAvailable } from "./search1api.ts";
|
|
|
55
55
|
import { isSearchinfinityAvailable } from "./searchinfinity.ts";
|
|
56
56
|
import { isQueritAvailable } from "./querit.ts";
|
|
57
57
|
import { isTavilyAvailable } from "./tavily.ts";
|
|
58
|
+
import { isYouAvailable } from "./you.ts";
|
|
58
59
|
import { isFirecrawlAvailable } from "./firecrawl.ts";
|
|
59
60
|
import { isJinaSearchAvailable } from "./jina-search.ts";
|
|
60
61
|
import { isSerpdiveAvailable } from "./serpdive.ts";
|
|
@@ -73,10 +74,11 @@ import { isSerpApiAvailable } from "./serpapi.ts";
|
|
|
73
74
|
import { isSerperAvailable } from "./serper.ts";
|
|
74
75
|
import { isSerplyAvailable } from "./serply.ts";
|
|
75
76
|
import { isBaizhiAvailable } from "./baizhi.ts";
|
|
77
|
+
import { isZaiAvailable } from "./zai.ts";
|
|
76
78
|
import { isValyuAvailable } from "./valyu.ts";
|
|
77
79
|
import { isXcrawlAvailable } from "./xcrawl.ts";
|
|
78
80
|
import { buildSearchErrorPlan, type SearchErrorDetails, type SearchErrorPlan } from "./render-search-error.ts";
|
|
79
|
-
import { findModelWithProviderRouting,
|
|
81
|
+
import { findModelWithProviderRouting, isModelInScope, splitThinkingSuffix } from "./summary-model-scope.ts";
|
|
80
82
|
import { registerCuratorRunLifecycle, resolveWebSearchWorkflow, type WebSearchWorkflow } from "./curator-run.ts";
|
|
81
83
|
import {
|
|
82
84
|
buildResearchArtifact,
|
|
@@ -86,7 +88,7 @@ import {
|
|
|
86
88
|
type RecencyFilter,
|
|
87
89
|
type ResearchArtifact,
|
|
88
90
|
} from "./source-check.ts";
|
|
89
|
-
import { registerWebToolActivation
|
|
91
|
+
import { registerWebToolActivation } from "./tool-activation.ts";
|
|
90
92
|
|
|
91
93
|
// Match pi-ai's StringEnum without loading its compat barrel during registration.
|
|
92
94
|
function StringEnum<T extends string[]>(values: T, options?: { description?: string; default?: T[number] }) {
|
|
@@ -157,7 +159,9 @@ interface WebSearchConfig {
|
|
|
157
159
|
serpapiApiKey?: unknown;
|
|
158
160
|
serperApiKey?: unknown;
|
|
159
161
|
serplyApiKey?: unknown;
|
|
162
|
+
youApiKey?: unknown;
|
|
160
163
|
baizhiApiKey?: unknown;
|
|
164
|
+
zaiApiKey?: unknown;
|
|
161
165
|
tinyfishApiKey?: unknown;
|
|
162
166
|
valyuApiKey?: unknown;
|
|
163
167
|
xaiApiKey?: unknown;
|
|
@@ -179,6 +183,7 @@ interface WebSearchConfig {
|
|
|
179
183
|
allowedProviders?: unknown;
|
|
180
184
|
};
|
|
181
185
|
tools?: Partial<Record<keyof ToolNames, { enabled?: boolean }>>;
|
|
186
|
+
toolActivation?: unknown;
|
|
182
187
|
commands?: Partial<Record<"websearch" | "curator" | "search" | "google-account", { enabled?: boolean }>>;
|
|
183
188
|
toolNames?: Partial<ToolNames>;
|
|
184
189
|
shortcuts?: {
|
|
@@ -471,6 +476,7 @@ async function getProviderAvailability(ctx: ExtensionContext): Promise<ProviderA
|
|
|
471
476
|
searchinfinity: allowedProviders.has("searchinfinity") && isSearchinfinityAvailable(),
|
|
472
477
|
querit: allowedProviders.has("querit") && isQueritAvailable(),
|
|
473
478
|
tavily: allowedProviders.has("tavily") && isTavilyAvailable(),
|
|
479
|
+
you: allowedProviders.has("you") && isYouAvailable(),
|
|
474
480
|
firecrawl: allowedProviders.has("firecrawl") && isFirecrawlAvailable(),
|
|
475
481
|
jina: allowedProviders.has("jina") && isJinaSearchAvailable(),
|
|
476
482
|
serpdive: allowedProviders.has("serpdive") && isSerpdiveAvailable(),
|
|
@@ -493,6 +499,7 @@ async function getProviderAvailability(ctx: ExtensionContext): Promise<ProviderA
|
|
|
493
499
|
serper: allowedProviders.has("serper") && isSerperAvailable(),
|
|
494
500
|
serply: allowedProviders.has("serply") && isSerplyAvailable(),
|
|
495
501
|
baizhi: allowedProviders.has("baizhi") && isBaizhiAvailable(),
|
|
502
|
+
zai: allowedProviders.has("zai") && isZaiAvailable(),
|
|
496
503
|
valyu: allowedProviders.has("valyu") && isValyuAvailable(),
|
|
497
504
|
};
|
|
498
505
|
return {
|
|
@@ -1069,6 +1076,10 @@ function handleSessionChange(ctx: ExtensionContext): void {
|
|
|
1069
1076
|
export default function (pi: ExtensionAPI) {
|
|
1070
1077
|
const initConfig = loadConfigForExtensionInit();
|
|
1071
1078
|
const fetchModeConfig = resolveFetchModeConfig(initConfig);
|
|
1079
|
+
const toolActivation = initConfig.toolActivation ?? "auto";
|
|
1080
|
+
if (toolActivation !== "auto" && toolActivation !== "dynamic" && toolActivation !== "eager") {
|
|
1081
|
+
throw new Error(`toolActivation in ${WEB_SEARCH_CONFIG_PATH} must be "auto", "dynamic", or "eager"`);
|
|
1082
|
+
}
|
|
1072
1083
|
const allowedSearchProviders = initConfig.webSearch?.allowedProviders === undefined ? RESOLVED_SEARCH_PROVIDERS : getAllowedSearchProviders();
|
|
1073
1084
|
const allEligibleProviders = allowedSearchProviders.filter(provider => ALL_SEARCH_PROVIDERS.includes(provider));
|
|
1074
1085
|
const allExcludedProviders = allowedSearchProviders.filter(provider => !ALL_SEARCH_PROVIDERS.includes(provider));
|
|
@@ -1297,27 +1308,16 @@ export default function (pi: ExtensionAPI) {
|
|
|
1297
1308
|
summaryModels.push({ value, label: value });
|
|
1298
1309
|
};
|
|
1299
1310
|
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
const availableModels = summaryContext.modelRegistry.getAvailable();
|
|
1305
|
-
for (const model of availableModels) {
|
|
1306
|
-
if (!modelMatchesEnabledPatterns(model, enabledModelPatterns)) continue;
|
|
1307
|
-
const value = `${model.provider}/${model.id}`;
|
|
1308
|
-
availableValues.add(value);
|
|
1309
|
-
addModel(model.provider, model.id);
|
|
1310
|
-
}
|
|
1311
|
-
} catch (err) {
|
|
1312
|
-
scopeLoaded = false;
|
|
1313
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1314
|
-
console.error(`Failed to load summary models: ${message}`);
|
|
1311
|
+
for (const model of summaryContext.modelRegistry.getAvailable()) {
|
|
1312
|
+
if (!isModelInScope(model, summaryContext.scopedModels)) continue;
|
|
1313
|
+
availableValues.add(`${model.provider}/${model.id}`);
|
|
1314
|
+
addModel(model.provider, model.id);
|
|
1315
1315
|
}
|
|
1316
1316
|
|
|
1317
1317
|
const currentModelValue = summaryContext.model
|
|
1318
1318
|
? `${summaryContext.model.provider}/${summaryContext.model.id}`
|
|
1319
1319
|
: null;
|
|
1320
|
-
if (
|
|
1320
|
+
if (summaryContext.model && currentModelValue && !seen.has(currentModelValue) && isModelInScope(summaryContext.model, summaryContext.scopedModels)) {
|
|
1321
1321
|
addModel(summaryContext.model.provider, summaryContext.model.id);
|
|
1322
1322
|
}
|
|
1323
1323
|
|
|
@@ -1352,12 +1352,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
1352
1352
|
};
|
|
1353
1353
|
|
|
1354
1354
|
let defaultSummaryModel: string | null = null;
|
|
1355
|
-
if (
|
|
1355
|
+
if (configuredSummaryModel.length > 0) {
|
|
1356
1356
|
defaultSummaryModel = availableValues.has(configuredSummaryModel)
|
|
1357
1357
|
? configuredSummaryModel
|
|
1358
1358
|
: resolveAvailableModelValue(configuredSummaryModel);
|
|
1359
1359
|
}
|
|
1360
|
-
if (
|
|
1360
|
+
if (!defaultSummaryModel) {
|
|
1361
1361
|
for (const preferred of preferredDefaults) {
|
|
1362
1362
|
const model = findModelWithProviderRouting(summaryContext.modelRegistry, preferred.provider, preferred.id);
|
|
1363
1363
|
const value = model ? `${model.provider}/${model.id}` : null;
|
|
@@ -1913,8 +1913,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1913
1913
|
model: ctx.model,
|
|
1914
1914
|
modelRegistry: ctx.modelRegistry,
|
|
1915
1915
|
sessionManager: ctx.sessionManager,
|
|
1916
|
-
|
|
1917
|
-
isProjectTrusted: () => ctx.isProjectTrusted(),
|
|
1916
|
+
scopedModels: ctx.scopedModels,
|
|
1918
1917
|
};
|
|
1919
1918
|
const summaryModelChoices = await loadSummaryModelChoices(summaryContext);
|
|
1920
1919
|
|
|
@@ -2143,8 +2142,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
2143
2142
|
model: ctx.model,
|
|
2144
2143
|
modelRegistry: ctx.modelRegistry,
|
|
2145
2144
|
sessionManager: ctx.sessionManager,
|
|
2146
|
-
|
|
2147
|
-
isProjectTrusted: () => ctx.isProjectTrusted(),
|
|
2145
|
+
scopedModels: ctx.scopedModels,
|
|
2148
2146
|
};
|
|
2149
2147
|
const summaryModelChoices = await loadSummaryModelChoices(summaryContext);
|
|
2150
2148
|
const generated = await generateSummaryDraft(
|
|
@@ -2185,13 +2183,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
2185
2183
|
}
|
|
2186
2184
|
if (queryList.length === 1) {
|
|
2187
2185
|
const q = queryList[0];
|
|
2188
|
-
|
|
2189
|
-
return new Text(theme.fg("toolTitle", theme.bold("search ")) + theme.fg("accent", `"${display}"`), 0, 0);
|
|
2186
|
+
return new Text(theme.fg("toolTitle", theme.bold("search ")) + theme.fg("accent", `"${q}"`), 0, 0);
|
|
2190
2187
|
}
|
|
2191
2188
|
const lines = [theme.fg("toolTitle", theme.bold("search ")) + theme.fg("accent", `${queryList.length} queries`)];
|
|
2192
2189
|
for (const q of queryList.slice(0, 5)) {
|
|
2193
|
-
|
|
2194
|
-
lines.push(theme.fg("muted", ` "${display}"`));
|
|
2190
|
+
lines.push(theme.fg("muted", ` "${q}"`));
|
|
2195
2191
|
}
|
|
2196
2192
|
if (queryList.length > 5) {
|
|
2197
2193
|
lines.push(theme.fg("muted", ` ... and ${queryList.length - 5} more`));
|
|
@@ -2759,13 +2755,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
2759
2755
|
}
|
|
2760
2756
|
const lines: string[] = [];
|
|
2761
2757
|
if (urlList.length === 1) {
|
|
2762
|
-
|
|
2763
|
-
lines.push(theme.fg("toolTitle", theme.bold("fetch ")) + theme.fg("accent", display));
|
|
2758
|
+
lines.push(theme.fg("toolTitle", theme.bold("fetch ")) + theme.fg("accent", urlList[0]));
|
|
2764
2759
|
} else {
|
|
2765
2760
|
lines.push(theme.fg("toolTitle", theme.bold("fetch ")) + theme.fg("accent", `${urlList.length} URLs`));
|
|
2766
2761
|
for (const u of urlList.slice(0, 5)) {
|
|
2767
|
-
|
|
2768
|
-
lines.push(theme.fg("muted", " " + display));
|
|
2762
|
+
lines.push(theme.fg("muted", " " + u));
|
|
2769
2763
|
}
|
|
2770
2764
|
if (urlList.length > 5) {
|
|
2771
2765
|
lines.push(theme.fg("muted", ` ... and ${urlList.length - 5} more`));
|
|
@@ -3264,13 +3258,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
3264
3258
|
});
|
|
3265
3259
|
}
|
|
3266
3260
|
|
|
3267
|
-
|
|
3261
|
+
if (toolActivation !== "eager") registerWebToolActivation(pi, [
|
|
3268
3262
|
...(webSearchEnabled ? [{ name: toolNames.webSearch, capability: "search" as const }] : []),
|
|
3269
3263
|
...(sourceCheckEnabled ? [{ name: toolNames.sourceCheck, capability: "source-check" as const }] : []),
|
|
3270
3264
|
...(fetchContentEnabled ? [{ name: toolNames.fetchContent, capability: "fetch" as const }] : []),
|
|
3271
3265
|
...(getSearchContentEnabled ? [{ name: toolNames.getSearchContent, capability: "stored-content" as const }] : []),
|
|
3272
|
-
];
|
|
3273
|
-
registerWebToolActivation(pi, activationTools);
|
|
3266
|
+
], toolActivation);
|
|
3274
3267
|
|
|
3275
3268
|
if (isCommandEnabled(initConfig, "websearch")) pi.registerCommand("websearch", {
|
|
3276
3269
|
description: "Open web search curator",
|
|
@@ -3308,8 +3301,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
3308
3301
|
model: ctx.model,
|
|
3309
3302
|
modelRegistry: ctx.modelRegistry,
|
|
3310
3303
|
sessionManager: ctx.sessionManager,
|
|
3311
|
-
|
|
3312
|
-
isProjectTrusted: () => ctx.isProjectTrusted(),
|
|
3304
|
+
scopedModels: ctx.scopedModels,
|
|
3313
3305
|
};
|
|
3314
3306
|
const summaryModelChoices = await loadSummaryModelChoices(summaryContext);
|
|
3315
3307
|
|