@herbertgao/pi-extensions 2026.8.2 → 2026.8.3
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 +9 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +6 -8
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +5 -7
- package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/hero.en.svg +101 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +1 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +5 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/{utils/agent-summary.ts → feature/agent-summary/core.ts} +37 -35
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{agent-summary.ts → agent-summary/index.ts} +2 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{session-reference.ts → reference/index.ts} +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{agent-autocomplete.ts → reference/subagent.ts} +19 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{pi-startup-header.ts → shell/startup-header.ts} +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{working-message.ts → shell/working-message.ts} +5 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +32 -28
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +379 -85
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +727 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +65 -775
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/{feature → renderer}/markdown-enhance.ts +35 -31
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-hover.ts → mouse/hover.ts} +5 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-interaction.ts → mouse/interaction.ts} +34 -35
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-layout.ts → mouse/layout.ts} +5 -21
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-packets.ts → mouse/packets.ts} +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-scroll.ts → mouse/scroll.ts} +48 -37
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/ansi-utils.ts +56 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/diff-renderer.ts +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/line-width-safety.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-display-utils.ts +12 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/write-execution.ts +1 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-grouping.ts → tool/grouping.ts} +18 -8
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-result.ts → tool/result.ts} +4 -13
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/fullscreen-detect.ts +0 -27
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
- package/node_modules/@herbertgao/pi-subagents/package.json +2 -2
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +1 -0
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +3 -1
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +33 -35
- package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +26 -35
- package/node_modules/@herbertgao/pi-subagents/src/prompts.ts +15 -1
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +19 -0
- package/node_modules/pi-mcp-adapter/README.md +19 -4
- package/node_modules/pi-mcp-adapter/agent-dir.ts +40 -0
- package/node_modules/pi-mcp-adapter/commands.ts +12 -2
- package/node_modules/pi-mcp-adapter/direct-tools.ts +6 -8
- package/node_modules/pi-mcp-adapter/index.ts +15 -3
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +87 -4
- package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +138 -61
- package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +43 -4
- package/node_modules/pi-mcp-adapter/oauth.ts +48 -0
- package/node_modules/pi-mcp-adapter/package.json +8 -2
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +8 -10
- package/node_modules/pi-mcp-adapter/tool-registrar.ts +187 -3
- package/node_modules/pi-mcp-adapter/types.ts +2 -0
- package/node_modules/pi-web-access/CHANGELOG.md +45 -0
- package/node_modules/pi-web-access/README.md +104 -29
- package/node_modules/pi-web-access/bocha.ts +221 -0
- package/node_modules/pi-web-access/curator-page.ts +113 -12
- package/node_modules/pi-web-access/curator-server.ts +56 -20
- package/node_modules/pi-web-access/datalab-pdf-extract.ts +568 -0
- package/node_modules/pi-web-access/duckduckgo.ts +123 -0
- package/node_modules/pi-web-access/extract.ts +288 -143
- package/node_modules/pi-web-access/feature-config.ts +29 -0
- package/node_modules/pi-web-access/gemini-api.ts +4 -0
- package/node_modules/pi-web-access/gemini-search.ts +45 -12
- package/node_modules/pi-web-access/gemini-web.ts +68 -3
- package/node_modules/pi-web-access/index.ts +160 -71
- package/node_modules/pi-web-access/jina-search.ts +284 -0
- package/node_modules/pi-web-access/kagi.ts +12 -12
- package/node_modules/pi-web-access/openai-search.ts +12 -2
- package/node_modules/pi-web-access/package.json +4 -3
- package/node_modules/pi-web-access/pdf-extract.ts +327 -228
- package/node_modules/pi-web-access/storage.ts +440 -2
- package/node_modules/pi-web-access/summary-model-scope.ts +1 -1
- package/node_modules/pi-web-access/summary-review.ts +4 -2
- package/node_modules/pi-web-access/video-extract.ts +10 -8
- package/node_modules/pi-web-access/xai-search.ts +12 -2
- package/node_modules/pi-web-access/youtube-extract.ts +2 -1
- package/node_modules/remote-pi/LICENSE +21 -0
- package/node_modules/remote-pi/README.md +675 -0
- package/node_modules/remote-pi/dist/actions/handlers.d.ts +122 -0
- package/node_modules/remote-pi/dist/actions/handlers.js +160 -0
- package/node_modules/remote-pi/dist/actions/handlers.js.map +1 -0
- package/node_modules/remote-pi/dist/actions/registry.d.ts +39 -0
- package/node_modules/remote-pi/dist/actions/registry.js +58 -0
- package/node_modules/remote-pi/dist/actions/registry.js.map +1 -0
- package/node_modules/remote-pi/dist/bin/supervisord.d.ts +2 -0
- package/node_modules/remote-pi/dist/bin/supervisord.js +86 -0
- package/node_modules/remote-pi/dist/bin/supervisord.js.map +1 -0
- package/node_modules/remote-pi/dist/commands/builtin_mirror.d.ts +58 -0
- package/node_modules/remote-pi/dist/commands/builtin_mirror.js +71 -0
- package/node_modules/remote-pi/dist/commands/builtin_mirror.js.map +1 -0
- package/node_modules/remote-pi/dist/commands/list_commands.d.ts +60 -0
- package/node_modules/remote-pi/dist/commands/list_commands.js +73 -0
- package/node_modules/remote-pi/dist/commands/list_commands.js.map +1 -0
- package/node_modules/remote-pi/dist/config.d.ts +62 -0
- package/node_modules/remote-pi/dist/config.js +115 -0
- package/node_modules/remote-pi/dist/config.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/client.d.ts +20 -0
- package/node_modules/remote-pi/dist/daemon/client.js +131 -0
- package/node_modules/remote-pi/dist/daemon/client.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/control_protocol.d.ts +176 -0
- package/node_modules/remote-pi/dist/daemon/control_protocol.js +63 -0
- package/node_modules/remote-pi/dist/daemon/control_protocol.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/cron_log.d.ts +45 -0
- package/node_modules/remote-pi/dist/daemon/cron_log.js +72 -0
- package/node_modules/remote-pi/dist/daemon/cron_log.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/cron_registry.d.ts +80 -0
- package/node_modules/remote-pi/dist/daemon/cron_registry.js +194 -0
- package/node_modules/remote-pi/dist/daemon/cron_registry.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/id.d.ts +24 -0
- package/node_modules/remote-pi/dist/daemon/id.js +36 -0
- package/node_modules/remote-pi/dist/daemon/id.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/install.d.ts +170 -0
- package/node_modules/remote-pi/dist/daemon/install.js +547 -0
- package/node_modules/remote-pi/dist/daemon/install.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/registry.d.ts +63 -0
- package/node_modules/remote-pi/dist/daemon/registry.js +153 -0
- package/node_modules/remote-pi/dist/daemon/registry.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/rpc_child.d.ts +194 -0
- package/node_modules/remote-pi/dist/daemon/rpc_child.js +389 -0
- package/node_modules/remote-pi/dist/daemon/rpc_child.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/supervisor.d.ts +93 -0
- package/node_modules/remote-pi/dist/daemon/supervisor.js +596 -0
- package/node_modules/remote-pi/dist/daemon/supervisor.js.map +1 -0
- package/node_modules/remote-pi/dist/extension_ui_bridge.d.ts +26 -0
- package/node_modules/remote-pi/dist/extension_ui_bridge.js +341 -0
- package/node_modules/remote-pi/dist/extension_ui_bridge.js.map +1 -0
- package/node_modules/remote-pi/dist/index.d.ts +213 -0
- package/node_modules/remote-pi/dist/index.js +4996 -0
- package/node_modules/remote-pi/dist/index.js.map +1 -0
- package/node_modules/remote-pi/dist/mcp/mesh_result.d.ts +10 -0
- package/node_modules/remote-pi/dist/mcp/mesh_result.js +42 -0
- package/node_modules/remote-pi/dist/mcp/mesh_result.js.map +1 -0
- package/node_modules/remote-pi/dist/mcp/mesh_server.d.ts +16 -0
- package/node_modules/remote-pi/dist/mcp/mesh_server.js +327 -0
- package/node_modules/remote-pi/dist/mcp/mesh_server.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/canonical.d.ts +30 -0
- package/node_modules/remote-pi/dist/mesh/canonical.js +61 -0
- package/node_modules/remote-pi/dist/mesh/canonical.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/client.d.ts +18 -0
- package/node_modules/remote-pi/dist/mesh/client.js +125 -0
- package/node_modules/remote-pi/dist/mesh/client.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/encoding.d.ts +38 -0
- package/node_modules/remote-pi/dist/mesh/encoding.js +216 -0
- package/node_modules/remote-pi/dist/mesh/encoding.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/self_revoke.d.ts +73 -0
- package/node_modules/remote-pi/dist/mesh/self_revoke.js +401 -0
- package/node_modules/remote-pi/dist/mesh/self_revoke.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/siblings.d.ts +49 -0
- package/node_modules/remote-pi/dist/mesh/siblings.js +159 -0
- package/node_modules/remote-pi/dist/mesh/siblings.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/types.d.ts +34 -0
- package/node_modules/remote-pi/dist/mesh/types.js +11 -0
- package/node_modules/remote-pi/dist/mesh/types.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/verify.d.ts +17 -0
- package/node_modules/remote-pi/dist/mesh/verify.js +86 -0
- package/node_modules/remote-pi/dist/mesh/verify.js.map +1 -0
- package/node_modules/remote-pi/dist/pairing/crypto.d.ts +8 -0
- package/node_modules/remote-pi/dist/pairing/crypto.js +22 -0
- package/node_modules/remote-pi/dist/pairing/crypto.js.map +1 -0
- package/node_modules/remote-pi/dist/pairing/handshake.d.ts +28 -0
- package/node_modules/remote-pi/dist/pairing/handshake.js +113 -0
- package/node_modules/remote-pi/dist/pairing/handshake.js.map +1 -0
- package/node_modules/remote-pi/dist/pairing/noise-sha256.d.ts +16 -0
- package/node_modules/remote-pi/dist/pairing/noise-sha256.js +103 -0
- package/node_modules/remote-pi/dist/pairing/noise-sha256.js.map +1 -0
- package/node_modules/remote-pi/dist/pairing/qr.d.ts +59 -0
- package/node_modules/remote-pi/dist/pairing/qr.js +125 -0
- package/node_modules/remote-pi/dist/pairing/qr.js.map +1 -0
- package/node_modules/remote-pi/dist/pairing/storage.d.ts +120 -0
- package/node_modules/remote-pi/dist/pairing/storage.js +604 -0
- package/node_modules/remote-pi/dist/pairing/storage.js.map +1 -0
- package/node_modules/remote-pi/dist/protocol/codec.d.ts +7 -0
- package/node_modules/remote-pi/dist/protocol/codec.js +49 -0
- package/node_modules/remote-pi/dist/protocol/codec.js.map +1 -0
- package/node_modules/remote-pi/dist/protocol/types.d.ts +393 -0
- package/node_modules/remote-pi/dist/protocol/types.js +2 -0
- package/node_modules/remote-pi/dist/protocol/types.js.map +1 -0
- package/node_modules/remote-pi/dist/rooms.d.ts +29 -0
- package/node_modules/remote-pi/dist/rooms.js +57 -0
- package/node_modules/remote-pi/dist/rooms.js.map +1 -0
- package/node_modules/remote-pi/dist/session/address.d.ts +49 -0
- package/node_modules/remote-pi/dist/session/address.js +58 -0
- package/node_modules/remote-pi/dist/session/address.js.map +1 -0
- package/node_modules/remote-pi/dist/session/agent_bridge.d.ts +55 -0
- package/node_modules/remote-pi/dist/session/agent_bridge.js +146 -0
- package/node_modules/remote-pi/dist/session/agent_bridge.js.map +1 -0
- package/node_modules/remote-pi/dist/session/bridge.d.ts +37 -0
- package/node_modules/remote-pi/dist/session/bridge.js +130 -0
- package/node_modules/remote-pi/dist/session/bridge.js.map +1 -0
- package/node_modules/remote-pi/dist/session/broker.d.ts +189 -0
- package/node_modules/remote-pi/dist/session/broker.js +507 -0
- package/node_modules/remote-pi/dist/session/broker.js.map +1 -0
- package/node_modules/remote-pi/dist/session/broker_remote.d.ts +74 -0
- package/node_modules/remote-pi/dist/session/broker_remote.js +583 -0
- package/node_modules/remote-pi/dist/session/broker_remote.js.map +1 -0
- package/node_modules/remote-pi/dist/session/cwd_lock.d.ts +33 -0
- package/node_modules/remote-pi/dist/session/cwd_lock.js +126 -0
- package/node_modules/remote-pi/dist/session/cwd_lock.js.map +1 -0
- package/node_modules/remote-pi/dist/session/envelope.d.ts +33 -0
- package/node_modules/remote-pi/dist/session/envelope.js +117 -0
- package/node_modules/remote-pi/dist/session/envelope.js.map +1 -0
- package/node_modules/remote-pi/dist/session/global_config.d.ts +33 -0
- package/node_modules/remote-pi/dist/session/global_config.js +73 -0
- package/node_modules/remote-pi/dist/session/global_config.js.map +1 -0
- package/node_modules/remote-pi/dist/session/ipc.d.ts +27 -0
- package/node_modules/remote-pi/dist/session/ipc.js +22 -0
- package/node_modules/remote-pi/dist/session/ipc.js.map +1 -0
- package/node_modules/remote-pi/dist/session/leader_election.d.ts +32 -0
- package/node_modules/remote-pi/dist/session/leader_election.js +106 -0
- package/node_modules/remote-pi/dist/session/leader_election.js.map +1 -0
- package/node_modules/remote-pi/dist/session/local_config.d.ts +55 -0
- package/node_modules/remote-pi/dist/session/local_config.js +157 -0
- package/node_modules/remote-pi/dist/session/local_config.js.map +1 -0
- package/node_modules/remote-pi/dist/session/mesh_message.d.ts +20 -0
- package/node_modules/remote-pi/dist/session/mesh_message.js +28 -0
- package/node_modules/remote-pi/dist/session/mesh_message.js.map +1 -0
- package/node_modules/remote-pi/dist/session/mesh_node.d.ts +116 -0
- package/node_modules/remote-pi/dist/session/mesh_node.js +573 -0
- package/node_modules/remote-pi/dist/session/mesh_node.js.map +1 -0
- package/node_modules/remote-pi/dist/session/peer.d.ts +139 -0
- package/node_modules/remote-pi/dist/session/peer.js +451 -0
- package/node_modules/remote-pi/dist/session/peer.js.map +1 -0
- package/node_modules/remote-pi/dist/session/peer_inventory.d.ts +13 -0
- package/node_modules/remote-pi/dist/session/peer_inventory.js +48 -0
- package/node_modules/remote-pi/dist/session/peer_inventory.js.map +1 -0
- package/node_modules/remote-pi/dist/session/peer_limits.d.ts +9 -0
- package/node_modules/remote-pi/dist/session/peer_limits.js +21 -0
- package/node_modules/remote-pi/dist/session/peer_limits.js.map +1 -0
- package/node_modules/remote-pi/dist/session/setup_wizard.d.ts +39 -0
- package/node_modules/remote-pi/dist/session/setup_wizard.js +63 -0
- package/node_modules/remote-pi/dist/session/setup_wizard.js.map +1 -0
- package/node_modules/remote-pi/dist/session/tool_gate.d.ts +5 -0
- package/node_modules/remote-pi/dist/session/tool_gate.js +11 -0
- package/node_modules/remote-pi/dist/session/tool_gate.js.map +1 -0
- package/node_modules/remote-pi/dist/session/tools.d.ts +24 -0
- package/node_modules/remote-pi/dist/session/tools.js +252 -0
- package/node_modules/remote-pi/dist/session/tools.js.map +1 -0
- package/node_modules/remote-pi/dist/session/wizard.d.ts +13 -0
- package/node_modules/remote-pi/dist/session/wizard.js +20 -0
- package/node_modules/remote-pi/dist/session/wizard.js.map +1 -0
- package/node_modules/remote-pi/dist/settings.d.ts +15 -0
- package/node_modules/remote-pi/dist/settings.js +52 -0
- package/node_modules/remote-pi/dist/settings.js.map +1 -0
- package/node_modules/remote-pi/dist/transport/peer_channel.d.ts +37 -0
- package/node_modules/remote-pi/dist/transport/peer_channel.js +98 -0
- package/node_modules/remote-pi/dist/transport/peer_channel.js.map +1 -0
- package/node_modules/remote-pi/dist/transport/pi_forward_client.d.ts +29 -0
- package/node_modules/remote-pi/dist/transport/pi_forward_client.js +62 -0
- package/node_modules/remote-pi/dist/transport/pi_forward_client.js.map +1 -0
- package/node_modules/remote-pi/dist/transport/relay_client.d.ts +91 -0
- package/node_modules/remote-pi/dist/transport/relay_client.js +206 -0
- package/node_modules/remote-pi/dist/transport/relay_client.js.map +1 -0
- package/node_modules/remote-pi/dist/ui/footer.d.ts +32 -0
- package/node_modules/remote-pi/dist/ui/footer.js +34 -0
- package/node_modules/remote-pi/dist/ui/footer.js.map +1 -0
- package/node_modules/remote-pi/docs/daemon.md +289 -0
- package/node_modules/remote-pi/package.json +88 -0
- package/node_modules/remote-pi/service-templates/launchd.plist.template +35 -0
- package/node_modules/remote-pi/service-templates/systemd.service.template +19 -0
- package/node_modules/remote-pi/service-templates/task-launcher.vbs.template +10 -0
- package/node_modules/remote-pi/service-templates/task-scheduler.xml.template +38 -0
- package/node_modules/remote-pi/skills/agent-network/SKILL.md +310 -0
- package/package.json +19 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool-diff/write-display-utils.ts +0 -29
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{session-reference-core.ts → reference/session.ts} +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{pi-aliases.ts → shell/aliases.ts} +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/ATTRIBUTION.md +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/diff-presentation.ts +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/index.ts +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/render-utils.ts +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/shiki-highlight.ts +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/types.ts +0 -0
|
@@ -14,17 +14,20 @@ import { isSearch1APIAvailable, searchWithSearch1API } from "./search1api.ts";
|
|
|
14
14
|
import { isSearchinfinityAvailable, searchWithSearchinfinity } from "./searchinfinity.ts";
|
|
15
15
|
import { isQueritAvailable, searchWithQuerit } from "./querit.ts";
|
|
16
16
|
import { isTavilyAvailable, searchWithTavily } from "./tavily.ts";
|
|
17
|
+
import { isJinaSearchAvailable, searchWithJina } from "./jina-search.ts";
|
|
17
18
|
import { isSerpdiveAvailable, searchWithSerpdive } from "./serpdive.ts";
|
|
18
19
|
import { isKagiAvailable, searchWithKagi } from "./kagi.ts";
|
|
20
|
+
import { isBochaAvailable, searchWithBocha } from "./bocha.ts";
|
|
19
21
|
import { isOllamaAvailable, searchWithOllama } from "./ollama.ts";
|
|
20
22
|
import { isSearXNGAvailable, searchWithSearXNG } from "./searxng.ts";
|
|
23
|
+
import { isDuckDuckGoAvailable, searchWithDuckDuckGo } from "./duckduckgo.ts";
|
|
21
24
|
import { isAnySearchAvailable, searchWithAnySearch } from "./anysearch.ts";
|
|
22
25
|
import { isXaiSearchAvailable, searchWithXai } from "./xai-search.ts";
|
|
23
26
|
import { isBrightDataAvailable, searchWithBrightData } from "./brightdata.ts";
|
|
24
27
|
import { isSerpBaseAvailable, searchWithSerpBase } from "./serpbase.ts";
|
|
25
28
|
import { getWebSearchConfigPath } from "./utils.ts";
|
|
26
29
|
|
|
27
|
-
export const RESOLVED_SEARCH_PROVIDERS = ["openai", "brave", "parallel", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "searxng", "perplexity", "gemini", "exa", "serpdive", "kagi", "ollama", "anysearch", "xai", "brightdata", "serpbase"] as const;
|
|
30
|
+
export const RESOLVED_SEARCH_PROVIDERS = ["openai", "brave", "parallel", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "jina", "searxng", "duckduckgo", "perplexity", "gemini", "exa", "serpdive", "kagi", "ollama", "anysearch", "xai", "brightdata", "serpbase", "bocha"] as const;
|
|
28
31
|
export const SEARCH_PROVIDERS = ["auto", "all", ...RESOLVED_SEARCH_PROVIDERS] as const;
|
|
29
32
|
|
|
30
33
|
export type ResolvedSearchProvider = typeof RESOLVED_SEARCH_PROVIDERS[number];
|
|
@@ -44,7 +47,7 @@ export type SearchProviderErrorKind =
|
|
|
44
47
|
|
|
45
48
|
export interface SearchRoutingConfig {
|
|
46
49
|
providers: ResolvedSearchProvider[];
|
|
47
|
-
fallbackOn: Array<Extract<SearchProviderErrorKind, "transient" | "quota" | "network">>;
|
|
50
|
+
fallbackOn: Array<Extract<SearchProviderErrorKind, "transient" | "quota" | "network" | "invalid-response">>;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
export class SearchProviderError extends Error {
|
|
@@ -86,10 +89,10 @@ export interface AttributedSearchResponse extends SearchResponse {
|
|
|
86
89
|
|
|
87
90
|
const CONFIG_PATH = getWebSearchConfigPath();
|
|
88
91
|
const DEFAULT_SEARCH_MODEL = "gemini-3.6-flash";
|
|
89
|
-
// Explicit-only providers (AnySearch, xAI, Bright Data, SerpBase) are deliberately absent:
|
|
90
|
-
// `all` must never fan out to
|
|
91
|
-
const ALL_SEARCH_PROVIDERS: ResolvedSearchProvider[] = ["searxng", "openai", "exa", "brave", "parallel", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "serpdive", "kagi", "ollama", "perplexity", "gemini"];
|
|
92
|
-
const VALID_ROUTING_KINDS = ["transient", "quota", "network"] as const;
|
|
92
|
+
// Explicit-only providers (DuckDuckGo, AnySearch, xAI, Bright Data, SerpBase) are deliberately absent:
|
|
93
|
+
// `all` must never fan out to an opt-in or paid provider without the user asking for it.
|
|
94
|
+
const ALL_SEARCH_PROVIDERS: ResolvedSearchProvider[] = ["searxng", "openai", "exa", "brave", "parallel", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "jina", "serpdive", "kagi", "ollama", "perplexity", "gemini", "bocha"];
|
|
95
|
+
const VALID_ROUTING_KINDS = ["transient", "quota", "network", "invalid-response"] as const;
|
|
93
96
|
|
|
94
97
|
type SearchConfig = {
|
|
95
98
|
searchProvider: SearchProviderSelection;
|
|
@@ -143,7 +146,7 @@ function normalizeSearchRouting(value: unknown): SearchRoutingConfig {
|
|
|
143
146
|
const fallbackOn: SearchRoutingConfig["fallbackOn"] = [];
|
|
144
147
|
for (const kind of raw.fallbackOn) {
|
|
145
148
|
if (typeof kind !== "string" || !VALID_ROUTING_KINDS.includes(kind as typeof VALID_ROUTING_KINDS[number])) {
|
|
146
|
-
throw new Error(`searchRouting.fallbackOn in ${CONFIG_PATH} may only contain transient, quota, or
|
|
149
|
+
throw new Error(`searchRouting.fallbackOn in ${CONFIG_PATH} may only contain transient, quota, network, or invalid-response`);
|
|
147
150
|
}
|
|
148
151
|
if (!fallbackOn.includes(kind as SearchRoutingConfig["fallbackOn"][number])) {
|
|
149
152
|
fallbackOn.push(kind as SearchRoutingConfig["fallbackOn"][number]);
|
|
@@ -257,6 +260,8 @@ function classifyProviderError(provider: ResolvedSearchProvider, err: unknown):
|
|
|
257
260
|
kind = "credential";
|
|
258
261
|
} else if (isAbortError(err)) {
|
|
259
262
|
kind = "aborted";
|
|
263
|
+
} else if (provider === "xai" && status === 403 && /spending[- ]limit|(?:no|out of) credits?|insufficient quota|quota (?:exceeded|exhausted)|credits? (?:exhausted|depleted|used up)/.test(lower)) {
|
|
264
|
+
kind = "quota";
|
|
260
265
|
} else if (status === 401 || status === 403) {
|
|
261
266
|
kind = "auth";
|
|
262
267
|
} else if (status === 400 || status === 422) {
|
|
@@ -271,7 +276,7 @@ function classifyProviderError(provider: ResolvedSearchProvider, err: unknown):
|
|
|
271
276
|
kind = "auth";
|
|
272
277
|
} else if (/bad request|invalid request/.test(lower)) {
|
|
273
278
|
kind = "invalid-request";
|
|
274
|
-
} else if (/invalid json|no parseable response|
|
|
279
|
+
} else if (/invalid json|no parseable response|no parseable results|invalid response|returned empty response/.test(lower)) {
|
|
275
280
|
kind = "invalid-response";
|
|
276
281
|
} else if (/temporar|service unavailable|server error/.test(lower)) {
|
|
277
282
|
kind = "transient";
|
|
@@ -299,8 +304,10 @@ async function searchWithResolvedProvider(
|
|
|
299
304
|
if (provider === "searchinfinity") return { ...(await searchWithSearchinfinity(query, options)), provider };
|
|
300
305
|
if (provider === "querit") return { ...(await searchWithQuerit(query, options)), provider };
|
|
301
306
|
if (provider === "tavily") return { ...(await searchWithTavily(query, options)), provider };
|
|
307
|
+
if (provider === "jina") return { ...(await searchWithJina(query, options)), provider };
|
|
302
308
|
if (provider === "serpdive") return { ...(await searchWithSerpdive(query, options)), provider };
|
|
303
309
|
if (provider === "kagi") return { ...(await searchWithKagi(query, options)), provider };
|
|
310
|
+
if (provider === "bocha") return { ...(await searchWithBocha(query, options)), provider };
|
|
304
311
|
if (provider === "ollama") return { ...(await searchWithOllama(query, options)), provider };
|
|
305
312
|
if (provider === "anysearch") return { ...(await searchWithAnySearch(query, options)), provider };
|
|
306
313
|
if (provider === "xai") return { ...(await searchWithXai(query, options, options.extensionContext)), provider };
|
|
@@ -308,6 +315,7 @@ async function searchWithResolvedProvider(
|
|
|
308
315
|
if (provider === "serpbase") return { ...(await searchWithSerpBase(query, options)), provider };
|
|
309
316
|
if (provider === "perplexity") return { ...(await searchWithPerplexity(query, options)), provider };
|
|
310
317
|
if (provider === "searxng") return { ...(await searchWithSearXNG(query, options)), provider };
|
|
318
|
+
if (provider === "duckduckgo") return { ...(await searchWithDuckDuckGo(query, options)), provider };
|
|
311
319
|
if (provider === "gemini") {
|
|
312
320
|
const result = await searchWithGemini(query, options, true);
|
|
313
321
|
if (result) return { ...result, provider };
|
|
@@ -332,8 +340,10 @@ async function isResolvedProviderAvailable(provider: ResolvedSearchProvider, opt
|
|
|
332
340
|
if (provider === "searchinfinity") return isSearchinfinityAvailable();
|
|
333
341
|
if (provider === "querit") return isQueritAvailable();
|
|
334
342
|
if (provider === "tavily") return isTavilyAvailable();
|
|
343
|
+
if (provider === "jina") return isJinaSearchAvailable();
|
|
335
344
|
if (provider === "serpdive") return isSerpdiveAvailable();
|
|
336
345
|
if (provider === "kagi") return isKagiAvailable();
|
|
346
|
+
if (provider === "bocha") return isBochaAvailable();
|
|
337
347
|
if (provider === "ollama") return isOllamaAvailable();
|
|
338
348
|
if (provider === "anysearch") return isAnySearchAvailable();
|
|
339
349
|
if (provider === "xai") return isXaiSearchAvailable(options.extensionContext);
|
|
@@ -341,6 +351,7 @@ async function isResolvedProviderAvailable(provider: ResolvedSearchProvider, opt
|
|
|
341
351
|
if (provider === "serpbase") return isSerpBaseAvailable();
|
|
342
352
|
if (provider === "perplexity") return isPerplexityAvailable();
|
|
343
353
|
if (provider === "searxng") return isSearXNGAvailable();
|
|
354
|
+
if (provider === "duckduckgo") return isDuckDuckGoAvailable();
|
|
344
355
|
if (provider === "gemini") return isGeminiApiAvailable() || !!(await isGeminiWebAvailable());
|
|
345
356
|
return isExaAvailable();
|
|
346
357
|
}
|
|
@@ -353,7 +364,9 @@ function providerLabel(provider: ResolvedSearchProvider): string {
|
|
|
353
364
|
if (provider === "querit") return "Querit";
|
|
354
365
|
if (provider === "serpdive") return "SERPdive";
|
|
355
366
|
if (provider === "searxng") return "SearXNG";
|
|
367
|
+
if (provider === "duckduckgo") return "DuckDuckGo";
|
|
356
368
|
if (provider === "kagi") return "Kagi";
|
|
369
|
+
if (provider === "bocha") return "Bocha";
|
|
357
370
|
if (provider === "ollama") return "Ollama";
|
|
358
371
|
if (provider === "xai") return "xAI";
|
|
359
372
|
if (provider === "brightdata") return "Bright Data";
|
|
@@ -587,6 +600,16 @@ export async function search(query: string, options: FullSearchOptions = {}): Pr
|
|
|
587
600
|
}
|
|
588
601
|
}
|
|
589
602
|
|
|
603
|
+
if (isJinaSearchAvailable()) {
|
|
604
|
+
try {
|
|
605
|
+
const result = await searchWithJina(query, options);
|
|
606
|
+
return { ...result, provider: "jina" };
|
|
607
|
+
} catch (err) {
|
|
608
|
+
if (isAbortError(err)) throw err;
|
|
609
|
+
fallbackErrors.push(`Jina: ${errorMessage(err)}`);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
590
613
|
if (isSerpdiveAvailable()) {
|
|
591
614
|
try {
|
|
592
615
|
const result = await searchWithSerpdive(query, options);
|
|
@@ -607,6 +630,16 @@ export async function search(query: string, options: FullSearchOptions = {}): Pr
|
|
|
607
630
|
}
|
|
608
631
|
}
|
|
609
632
|
|
|
633
|
+
if (isBochaAvailable()) {
|
|
634
|
+
try {
|
|
635
|
+
const result = await searchWithBocha(query, options);
|
|
636
|
+
return { ...result, provider: "bocha" };
|
|
637
|
+
} catch (err) {
|
|
638
|
+
if (isAbortError(err)) throw err;
|
|
639
|
+
fallbackErrors.push(`Bocha: ${errorMessage(err)}`);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
610
643
|
if (isOllamaAvailable()) {
|
|
611
644
|
try {
|
|
612
645
|
const result = await searchWithOllama(query, options);
|
|
@@ -642,8 +675,8 @@ export async function search(query: string, options: FullSearchOptions = {}): Pr
|
|
|
642
675
|
throw new Error(
|
|
643
676
|
"No search provider available. Either:\n" +
|
|
644
677
|
" 1. Use /login to sign in with a Codex subscription for OpenAI web search\n" +
|
|
645
|
-
` 2. Set openaiApiKey, braveApiKey, parallelApiKey, tinyfishApiKey, search1apiApiKey, searchinfinityApiKey, queritApiKey, tavilyApiKey, serpdiveApiKey, kagiApiKey, ollamaApiKey, searxngBaseUrl, perplexityApiKey, exaApiKey, geminiApiKey, or cloudflareApiKey in ${CONFIG_PATH}\n` +
|
|
646
|
-
" 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, SERPDIVE_API_KEY, KAGI_API_KEY, OLLAMA_API_KEY, SEARXNG_BASE_URL, EXA_API_KEY, PERPLEXITY_API_KEY, GEMINI_API_KEY, or CLOUDFLARE_API_KEY env vars\n" +
|
|
678
|
+
` 2. Set openaiApiKey, braveApiKey, parallelApiKey, tinyfishApiKey, search1apiApiKey, searchinfinityApiKey, queritApiKey, tavilyApiKey, jinaApiKey, serpdiveApiKey, kagiApiKey, ollamaApiKey, searxngBaseUrl, perplexityApiKey, exaApiKey, geminiApiKey, bochaApiKey, or cloudflareApiKey in ${CONFIG_PATH}\n` +
|
|
679
|
+
" 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, 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" +
|
|
647
680
|
" 4. Set GOOGLE_GEMINI_BASE_URL with CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing\n" +
|
|
648
681
|
" 5. Sign into gemini.google.com in a supported Chromium-based browser\n" +
|
|
649
682
|
" 6. Explicitly select provider: \"anysearch\" for anonymous AnySearch, \"xai\" for Grok, \"brightdata\" with brightdataSerpZone for paid Bright Data SERP, or \"serpbase\" with serpbaseApiKey for paid Google SERP"
|
|
@@ -652,7 +685,7 @@ export async function search(query: string, options: FullSearchOptions = {}): Pr
|
|
|
652
685
|
|
|
653
686
|
async function searchWithGeminiApi(query: string, options: SearchOptions = {}): Promise<SearchResponse | null> {
|
|
654
687
|
const requestSignal = AbortSignal.any([
|
|
655
|
-
AbortSignal.timeout(
|
|
688
|
+
AbortSignal.timeout(120000),
|
|
656
689
|
...(options.signal ? [options.signal] : []),
|
|
657
690
|
]);
|
|
658
691
|
const apiKey = await getApiKey(requestSignal);
|
|
@@ -711,7 +744,7 @@ async function searchWithGeminiWeb(query: string, options: SearchOptions = {}):
|
|
|
711
744
|
try {
|
|
712
745
|
const text = await queryWithCookies(prompt, cookies, {
|
|
713
746
|
signal: options.signal,
|
|
714
|
-
timeoutMs:
|
|
747
|
+
timeoutMs: 120000,
|
|
715
748
|
});
|
|
716
749
|
|
|
717
750
|
activityMonitor.logComplete(activityId, 200);
|
|
@@ -24,6 +24,71 @@ const MODEL_HEADERS: Record<string, string> = {
|
|
|
24
24
|
|
|
25
25
|
const REQUIRED_COOKIES = ["__Secure-1PSID", "__Secure-1PSIDTS"];
|
|
26
26
|
|
|
27
|
+
// Gemini Web talks to Google's frontend inside the host agent (pi), whose
|
|
28
|
+
// global undici dispatcher runs HTTP/1.1 with undici's default 16 KiB
|
|
29
|
+
// maxHeaderSize. Google's gemini.google.com /app response headers routinely
|
|
30
|
+
// exceed that budget over HTTP/1.1, so cookie-bearing requests fail with
|
|
31
|
+
// UND_ERR_HEADERS_OVERFLOW surfaced as "fetch failed". Route these requests
|
|
32
|
+
// through a dedicated undici Agent with a larger header budget instead; fall
|
|
33
|
+
// back to the ambient global fetch when undici is not resolvable (e.g.
|
|
34
|
+
// standalone test environments).
|
|
35
|
+
let geminiFetchImpl: typeof fetch | null = null;
|
|
36
|
+
|
|
37
|
+
// Test-only hook: lets tests inject a simulated transport instead of patching
|
|
38
|
+
// globalThis.fetch. Gemini Web deliberately bypasses the ambient global fetch
|
|
39
|
+
// (inside the pi host agent it is constrained to undici's 16 KiB
|
|
40
|
+
// maxHeaderSize and cannot serve Google's /app page over HTTP/1.1), so
|
|
41
|
+
// globalThis.fetch patching is no longer a reliable way to intercept these
|
|
42
|
+
// requests.
|
|
43
|
+
export function setGeminiFetchOverrideForTests(fetchImpl: typeof fetch | null): void {
|
|
44
|
+
geminiFetchOverride = fetchImpl;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let geminiFetchOverride: typeof fetch | null = null;
|
|
48
|
+
|
|
49
|
+
// The header budget Gemini Web needs for Google frontend responses.
|
|
50
|
+
// Google's /app page exceeds undici's default 16 KiB maxHeaderSize when
|
|
51
|
+
// served over HTTP/1.1, which is how pi's global dispatcher operates.
|
|
52
|
+
export const GEMINI_MAX_HEADER_SIZE = 4 * 1024 * 1024;
|
|
53
|
+
|
|
54
|
+
// Build a fetch that routes through a dedicated undici Agent with a larger
|
|
55
|
+
// header budget than the host agent's global dispatcher allows. Exported for
|
|
56
|
+
// tests so the agent configuration can be asserted without network access.
|
|
57
|
+
export function createGeminiFetch(undiciImpl: typeof import("undici")): typeof fetch {
|
|
58
|
+
const agent = new undiciImpl.EnvHttpProxyAgent({
|
|
59
|
+
allowH2: false,
|
|
60
|
+
connectTimeout: 30_000,
|
|
61
|
+
maxHeaderSize: GEMINI_MAX_HEADER_SIZE,
|
|
62
|
+
pipelining: 1,
|
|
63
|
+
});
|
|
64
|
+
// undici 8 types its fetch request/response structurally differently from
|
|
65
|
+
// the DOM lib types (duplex/textStream on Request, Symbol.dispose on
|
|
66
|
+
// Headers); the shape this module uses (status, ok, headers.get, text) is
|
|
67
|
+
// identical, so bridge the two.
|
|
68
|
+
type UndiciFetch = typeof undiciImpl.fetch;
|
|
69
|
+
return (input, init) =>
|
|
70
|
+
undiciImpl.fetch(
|
|
71
|
+
input as unknown as Parameters<UndiciFetch>[0],
|
|
72
|
+
{ ...init, dispatcher: agent } as unknown as Parameters<UndiciFetch>[1],
|
|
73
|
+
) as unknown as Promise<Response>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function resolveGeminiFetch(): Promise<typeof fetch> {
|
|
77
|
+
if (geminiFetchOverride) return geminiFetchOverride;
|
|
78
|
+
if (geminiFetchImpl) return geminiFetchImpl;
|
|
79
|
+
|
|
80
|
+
let undici: typeof import("undici");
|
|
81
|
+
try {
|
|
82
|
+
undici = await import("undici");
|
|
83
|
+
} catch {
|
|
84
|
+
geminiFetchImpl = fetch;
|
|
85
|
+
return geminiFetchImpl;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
geminiFetchImpl = createGeminiFetch(undici);
|
|
89
|
+
return geminiFetchImpl;
|
|
90
|
+
}
|
|
91
|
+
|
|
27
92
|
export interface GeminiWebOptions {
|
|
28
93
|
youtubeUrl?: string;
|
|
29
94
|
model?: string;
|
|
@@ -129,7 +194,7 @@ async function runGeminiWebOnce(
|
|
|
129
194
|
params.set("at", accessToken);
|
|
130
195
|
params.set("f.req", fReq);
|
|
131
196
|
|
|
132
|
-
const res = await
|
|
197
|
+
const res = await (await resolveGeminiFetch())(GEMINI_STREAM_GENERATE_URL, {
|
|
133
198
|
method: "POST",
|
|
134
199
|
redirect: "error",
|
|
135
200
|
headers: {
|
|
@@ -192,7 +257,7 @@ async function fetchWithCookieRedirects(
|
|
|
192
257
|
let current = url;
|
|
193
258
|
const allowedOrigin = new URL(url).origin;
|
|
194
259
|
for (let i = 0; i <= maxRedirects; i++) {
|
|
195
|
-
const res = await
|
|
260
|
+
const res = await (await resolveGeminiFetch())(current, {
|
|
196
261
|
headers: { "user-agent": USER_AGENT, cookie: cookieHeader },
|
|
197
262
|
redirect: "manual",
|
|
198
263
|
signal,
|
|
@@ -302,7 +367,7 @@ async function uploadFile(
|
|
|
302
367
|
Buffer.from(footer, "utf-8"),
|
|
303
368
|
]);
|
|
304
369
|
|
|
305
|
-
const res = await
|
|
370
|
+
const res = await (await resolveGeminiFetch())(GEMINI_UPLOAD_URL, {
|
|
306
371
|
method: "POST",
|
|
307
372
|
redirect: "error",
|
|
308
373
|
headers: {
|