@humain/terminal 0.0.2 → 0.0.3-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +241 -24
- package/README.md +143 -119
- package/dist/cli/args.d.ts +4 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +37 -39
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-check.d.ts +19 -0
- package/dist/cli/auth-check.d.ts.map +1 -0
- package/dist/cli/auth-check.js +50 -0
- package/dist/cli/auth-check.js.map +1 -0
- package/dist/cli/auth-command.d.ts +24 -0
- package/dist/cli/auth-command.d.ts.map +1 -0
- package/dist/cli/auth-command.js +103 -0
- package/dist/cli/auth-command.js.map +1 -0
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +2 -2
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/credential-print.d.ts +5 -15
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js +42 -83
- package/dist/cli/credential-print.js.map +1 -1
- package/dist/cli/experimental/auth.d.ts +16 -0
- package/dist/cli/experimental/auth.d.ts.map +1 -0
- package/dist/cli/experimental/auth.js +13 -0
- package/dist/cli/experimental/auth.js.map +1 -0
- package/dist/cli/experimental/cli.d.ts +6 -0
- package/dist/cli/experimental/cli.d.ts.map +1 -0
- package/dist/cli/experimental/cli.js +5 -0
- package/dist/cli/experimental/cli.js.map +1 -0
- package/dist/cli/experimental/command-options.d.ts +17 -0
- package/dist/cli/experimental/command-options.d.ts.map +1 -0
- package/dist/cli/experimental/command-options.js +35 -0
- package/dist/cli/experimental/command-options.js.map +1 -0
- package/dist/cli/experimental/command.d.ts +63 -0
- package/dist/cli/experimental/command.d.ts.map +1 -0
- package/dist/cli/experimental/command.js +130 -0
- package/dist/cli/experimental/command.js.map +1 -0
- package/dist/cli/experimental/commands/client.d.ts +13 -0
- package/dist/cli/experimental/commands/client.d.ts.map +1 -0
- package/dist/cli/experimental/commands/client.js +25 -0
- package/dist/cli/experimental/commands/client.js.map +1 -0
- package/dist/cli/experimental/commands/pi.d.ts +15 -0
- package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
- package/dist/cli/experimental/commands/pi.js +28 -0
- package/dist/cli/experimental/commands/pi.js.map +1 -0
- package/dist/cli/experimental/commands/server.d.ts +13 -0
- package/dist/cli/experimental/commands/server.d.ts.map +1 -0
- package/dist/cli/experimental/commands/server.js +25 -0
- package/dist/cli/experimental/commands/server.js.map +1 -0
- package/dist/cli/experimental/transport-address.d.ts +10 -0
- package/dist/cli/experimental/transport-address.d.ts.map +1 -0
- package/dist/cli/experimental/transport-address.js +38 -0
- package/dist/cli/experimental/transport-address.js.map +1 -0
- package/dist/cli/list-models.d.ts +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +2 -2
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/startup-ui.d.ts +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +2 -2
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +3 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/remote-session.d.ts +53 -0
- package/dist/client/remote-session.d.ts.map +1 -0
- package/dist/client/remote-session.js +340 -0
- package/dist/client/remote-session.js.map +1 -0
- package/dist/client/transcript.d.ts +12 -0
- package/dist/client/transcript.d.ts.map +1 -0
- package/dist/client/transcript.js +98 -0
- package/dist/client/transcript.js.map +1 -0
- package/dist/core/agent-session-services.d.ts +1 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -10
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +72 -70
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +25 -9
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +237 -39
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +60 -41
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +2 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +3 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +27 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +5 -0
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/keybindings.d.ts +45 -5
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-config.d.ts +29 -5
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +4 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -3
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +13 -10
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +4 -3
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +42 -10
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +30 -13
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +233 -73
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/models-store.d.ts +12 -7
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +83 -14
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts +6 -3
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +80 -61
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts +8 -0
- package/dist/core/pi-manifest.d.ts.map +1 -0
- package/dist/core/pi-manifest.js +28 -0
- package/dist/core/pi-manifest.js.map +1 -0
- package/dist/core/provider-composer.d.ts +4 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +36 -15
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +73 -67
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +2 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts +5 -5
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js +11 -8
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +3 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +12 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +40 -16
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +8 -0
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +5 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +16 -15
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts +4 -0
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +11 -7
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts +7 -0
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +16 -19
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +4 -0
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +5 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts +4 -0
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +5 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts +4 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +7 -3
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts +4 -0
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +6 -2
- package/dist/core/tools/write.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +11 -2
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +21 -7
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/humain/agent-execution-protocol.d.ts +218 -0
- package/dist/humain/agent-execution-protocol.d.ts.map +1 -0
- package/dist/humain/agent-execution-protocol.js +204 -0
- package/dist/humain/agent-execution-protocol.js.map +1 -0
- package/dist/humain/agent-execution-runtime.d.ts +35 -0
- package/dist/humain/agent-execution-runtime.d.ts.map +1 -0
- package/dist/humain/agent-execution-runtime.js +170 -0
- package/dist/humain/agent-execution-runtime.js.map +1 -0
- package/dist/humain/index.d.ts.map +1 -1
- package/dist/humain/index.js +8 -7
- package/dist/humain/index.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/CHANGELOG.md +660 -0
- package/dist/humain/mcp-adapter/vendor/LICENSE +21 -0
- package/dist/humain/mcp-adapter/vendor/README.md +733 -0
- package/dist/humain/mcp-adapter/vendor/abort.ts +34 -0
- package/dist/humain/mcp-adapter/vendor/agent-dir.ts +60 -0
- package/dist/humain/mcp-adapter/vendor/agent-plugin-loader.ts +377 -0
- package/dist/humain/mcp-adapter/vendor/app-bridge.bundle.js +67 -0
- package/dist/humain/mcp-adapter/vendor/banner.png +0 -0
- package/dist/humain/mcp-adapter/vendor/cli.js +209 -0
- package/dist/humain/mcp-adapter/vendor/commands.ts +627 -0
- package/dist/humain/mcp-adapter/vendor/config.ts +1226 -0
- package/dist/humain/mcp-adapter/vendor/consent-manager.ts +64 -0
- package/dist/humain/mcp-adapter/vendor/direct-tools.ts +604 -0
- package/dist/humain/mcp-adapter/vendor/elicitation-handler.ts +348 -0
- package/dist/humain/mcp-adapter/vendor/error-signal.ts +21 -0
- package/dist/humain/mcp-adapter/vendor/errors.ts +223 -0
- package/dist/humain/mcp-adapter/vendor/glimpse-ui.ts +80 -0
- package/dist/humain/mcp-adapter/vendor/host-html-template.ts +461 -0
- package/dist/humain/mcp-adapter/vendor/index.bundle.d.mts +4 -0
- package/dist/humain/mcp-adapter/vendor/index.bundle.mjs +15923 -0
- package/dist/humain/mcp-adapter/vendor/index.ts +898 -0
- package/dist/humain/mcp-adapter/vendor/init.ts +649 -0
- package/dist/humain/mcp-adapter/vendor/json-schema-validator.ts +69 -0
- package/dist/humain/mcp-adapter/vendor/lifecycle.ts +147 -0
- package/dist/humain/mcp-adapter/vendor/logger.ts +169 -0
- package/dist/humain/mcp-adapter/vendor/mcp-auth-flow.ts +993 -0
- package/dist/humain/mcp-adapter/vendor/mcp-auth.ts +1000 -0
- package/dist/humain/mcp-adapter/vendor/mcp-callback-server.ts +510 -0
- package/dist/humain/mcp-adapter/vendor/mcp-code.ts +354 -0
- package/dist/humain/mcp-adapter/vendor/mcp-keyring-helper.cjs +89 -0
- package/dist/humain/mcp-adapter/vendor/mcp-oauth-provider.ts +616 -0
- package/dist/humain/mcp-adapter/vendor/mcp-output-guard.ts +408 -0
- package/dist/humain/mcp-adapter/vendor/mcp-panel.ts +1015 -0
- package/dist/humain/mcp-adapter/vendor/mcp-probe.ts +187 -0
- package/dist/humain/mcp-adapter/vendor/mcp-script-worker.mjs +130 -0
- package/dist/humain/mcp-adapter/vendor/mcp-setup-panel.ts +666 -0
- package/dist/humain/mcp-adapter/vendor/mcp-status.ts +109 -0
- package/dist/humain/mcp-adapter/vendor/mcp-trace.ts +306 -0
- package/dist/humain/mcp-adapter/vendor/metadata-cache.ts +353 -0
- package/dist/humain/mcp-adapter/vendor/npx-resolver.ts +543 -0
- package/dist/humain/mcp-adapter/vendor/oauth-handler.ts +30 -0
- package/dist/humain/mcp-adapter/vendor/oauth.ts +48 -0
- package/dist/humain/mcp-adapter/vendor/onboarding-state.ts +76 -0
- package/dist/humain/mcp-adapter/vendor/package.json +178 -0
- package/dist/humain/mcp-adapter/vendor/panel-keys.ts +53 -0
- package/dist/humain/mcp-adapter/vendor/prompts.ts +353 -0
- package/dist/humain/mcp-adapter/vendor/proxy-modes.ts +1331 -0
- package/dist/humain/mcp-adapter/vendor/resource-tools.ts +17 -0
- package/dist/humain/mcp-adapter/vendor/runtime-owner.ts +91 -0
- package/dist/humain/mcp-adapter/vendor/sampling-handler.ts +284 -0
- package/dist/humain/mcp-adapter/vendor/search-ranking.ts +206 -0
- package/dist/humain/mcp-adapter/vendor/server-manager.ts +1124 -0
- package/dist/humain/mcp-adapter/vendor/session-recovery.ts +151 -0
- package/dist/humain/mcp-adapter/vendor/skills/mcp-scripting/SKILL.md +38 -0
- package/dist/humain/mcp-adapter/vendor/state.ts +62 -0
- package/dist/humain/mcp-adapter/vendor/tool-approval.ts +182 -0
- package/dist/humain/mcp-adapter/vendor/tool-metadata.ts +276 -0
- package/dist/humain/mcp-adapter/vendor/tool-registrar.ts +253 -0
- package/dist/humain/mcp-adapter/vendor/tool-result-renderer.ts +423 -0
- package/dist/humain/mcp-adapter/vendor/ts-shape.ts +149 -0
- package/dist/humain/mcp-adapter/vendor/types.ts +859 -0
- package/dist/humain/mcp-adapter/vendor/ui-app-bridge-helpers.ts +40 -0
- package/dist/humain/mcp-adapter/vendor/ui-resource-handler.ts +250 -0
- package/dist/humain/mcp-adapter/vendor/ui-server.ts +866 -0
- package/dist/humain/mcp-adapter/vendor/ui-session.ts +570 -0
- package/dist/humain/mcp-adapter/vendor/ui-stream-types.ts +89 -0
- package/dist/humain/mcp-adapter/vendor/ui-tool-visibility.ts +25 -0
- package/dist/humain/mcp-adapter/vendor/unix-socket-transport.ts +85 -0
- package/dist/humain/mcp-adapter/vendor/utils.ts +310 -0
- package/dist/humain/mcp-adapter.d.ts +3 -0
- package/dist/humain/mcp-adapter.d.ts.map +1 -0
- package/dist/humain/mcp-adapter.js +5 -0
- package/dist/humain/mcp-adapter.js.map +1 -0
- package/dist/humain/pi-agent-execution-host.d.ts +34 -0
- package/dist/humain/pi-agent-execution-host.d.ts.map +1 -0
- package/dist/humain/pi-agent-execution-host.js +77 -0
- package/dist/humain/pi-agent-execution-host.js.map +1 -0
- package/dist/humain/web-access/host.d.ts +4 -0
- package/dist/humain/web-access/host.d.ts.map +1 -0
- package/dist/humain/web-access/host.js +3 -0
- package/dist/humain/web-access/host.js.map +1 -0
- package/dist/humain/web-access/index.d.ts +3 -0
- package/dist/humain/web-access/index.d.ts.map +1 -0
- package/dist/humain/web-access/index.js +5 -0
- package/dist/humain/web-access/index.js.map +1 -0
- package/dist/humain/web-access/vendor/activity.d.ts +34 -0
- package/dist/humain/web-access/vendor/activity.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/activity.js +68 -0
- package/dist/humain/web-access/vendor/activity.js.map +1 -0
- package/dist/humain/web-access/vendor/anysearch.d.ts +8 -0
- package/dist/humain/web-access/vendor/anysearch.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/anysearch.js +167 -0
- package/dist/humain/web-access/vendor/anysearch.js.map +1 -0
- package/dist/humain/web-access/vendor/bocha.d.ts +4 -0
- package/dist/humain/web-access/vendor/bocha.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/bocha.js +219 -0
- package/dist/humain/web-access/vendor/bocha.js.map +1 -0
- package/dist/humain/web-access/vendor/brave.d.ts +4 -0
- package/dist/humain/web-access/vendor/brave.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/brave.js +194 -0
- package/dist/humain/web-access/vendor/brave.js.map +1 -0
- package/dist/humain/web-access/vendor/brightdata-unlocker.d.ts +12 -0
- package/dist/humain/web-access/vendor/brightdata-unlocker.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/brightdata-unlocker.js +230 -0
- package/dist/humain/web-access/vendor/brightdata-unlocker.js.map +1 -0
- package/dist/humain/web-access/vendor/brightdata.d.ts +8 -0
- package/dist/humain/web-access/vendor/brightdata.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/brightdata.js +519 -0
- package/dist/humain/web-access/vendor/brightdata.js.map +1 -0
- package/dist/humain/web-access/vendor/chrome-cookies.d.ts +10 -0
- package/dist/humain/web-access/vendor/chrome-cookies.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/chrome-cookies.js +438 -0
- package/dist/humain/web-access/vendor/chrome-cookies.js.map +1 -0
- package/dist/humain/web-access/vendor/content-find.d.ts +11 -0
- package/dist/humain/web-access/vendor/content-find.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/content-find.js +117 -0
- package/dist/humain/web-access/vendor/content-find.js.map +1 -0
- package/dist/humain/web-access/vendor/credential-source.d.ts +28 -0
- package/dist/humain/web-access/vendor/credential-source.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/credential-source.js +151 -0
- package/dist/humain/web-access/vendor/credential-source.js.map +1 -0
- package/dist/humain/web-access/vendor/curator-page.d.ts +29 -0
- package/dist/humain/web-access/vendor/curator-page.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/curator-page.js +3554 -0
- package/dist/humain/web-access/vendor/curator-page.js.map +1 -0
- package/dist/humain/web-access/vendor/curator-server.d.ts +93 -0
- package/dist/humain/web-access/vendor/curator-server.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/curator-server.js +688 -0
- package/dist/humain/web-access/vendor/curator-server.js.map +1 -0
- package/dist/humain/web-access/vendor/datalab-pdf-extract.d.ts +60 -0
- package/dist/humain/web-access/vendor/datalab-pdf-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/datalab-pdf-extract.js +416 -0
- package/dist/humain/web-access/vendor/datalab-pdf-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/declared-web-links.d.ts +16 -0
- package/dist/humain/web-access/vendor/declared-web-links.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/declared-web-links.js +168 -0
- package/dist/humain/web-access/vendor/declared-web-links.js.map +1 -0
- package/dist/humain/web-access/vendor/duckduckgo.d.ts +4 -0
- package/dist/humain/web-access/vendor/duckduckgo.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/duckduckgo.js +123 -0
- package/dist/humain/web-access/vendor/duckduckgo.js.map +1 -0
- package/dist/humain/web-access/vendor/exa.d.ts +10 -0
- package/dist/humain/web-access/vendor/exa.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/exa.js +426 -0
- package/dist/humain/web-access/vendor/exa.js.map +1 -0
- package/dist/humain/web-access/vendor/extract.d.ts +46 -0
- package/dist/humain/web-access/vendor/extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/extract.js +1064 -0
- package/dist/humain/web-access/vendor/extract.js.map +1 -0
- package/dist/humain/web-access/vendor/feature-config.d.ts +3 -0
- package/dist/humain/web-access/vendor/feature-config.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/feature-config.js +27 -0
- package/dist/humain/web-access/vendor/feature-config.js.map +1 -0
- package/dist/humain/web-access/vendor/fetch-params.d.ts +25 -0
- package/dist/humain/web-access/vendor/fetch-params.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/fetch-params.js +57 -0
- package/dist/humain/web-access/vendor/fetch-params.js.map +1 -0
- package/dist/humain/web-access/vendor/firecrawl.d.ts +12 -0
- package/dist/humain/web-access/vendor/firecrawl.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/firecrawl.js +239 -0
- package/dist/humain/web-access/vendor/firecrawl.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-api.d.ts +27 -0
- package/dist/humain/web-access/vendor/gemini-api.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-api.js +230 -0
- package/dist/humain/web-access/vendor/gemini-api.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-pdf-extract.d.ts +9 -0
- package/dist/humain/web-access/vendor/gemini-pdf-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-pdf-extract.js +85 -0
- package/dist/humain/web-access/vendor/gemini-pdf-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-search.d.ts +40 -0
- package/dist/humain/web-access/vendor/gemini-search.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-search.js +814 -0
- package/dist/humain/web-access/vendor/gemini-search.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-url-context.d.ts +4 -0
- package/dist/humain/web-access/vendor/gemini-url-context.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-url-context.js +101 -0
- package/dist/humain/web-access/vendor/gemini-url-context.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-web-config.d.ts +4 -0
- package/dist/humain/web-access/vendor/gemini-web-config.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-web-config.js +42 -0
- package/dist/humain/web-access/vendor/gemini-web-config.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-web.d.ts +18 -0
- package/dist/humain/web-access/vendor/gemini-web.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-web.js +385 -0
- package/dist/humain/web-access/vendor/gemini-web.js.map +1 -0
- package/dist/humain/web-access/vendor/github-api.d.ts +7 -0
- package/dist/humain/web-access/vendor/github-api.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/github-api.js +160 -0
- package/dist/humain/web-access/vendor/github-api.js.map +1 -0
- package/dist/humain/web-access/vendor/github-extract.d.ts +13 -0
- package/dist/humain/web-access/vendor/github-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/github-extract.js +635 -0
- package/dist/humain/web-access/vendor/github-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/index.d.ts +4 -0
- package/dist/humain/web-access/vendor/index.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/index.js +3002 -0
- package/dist/humain/web-access/vendor/index.js.map +1 -0
- package/dist/humain/web-access/vendor/jina-search.d.ts +8 -0
- package/dist/humain/web-access/vendor/jina-search.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/jina-search.js +255 -0
- package/dist/humain/web-access/vendor/jina-search.js.map +1 -0
- package/dist/humain/web-access/vendor/kagi.d.ts +15 -0
- package/dist/humain/web-access/vendor/kagi.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/kagi.js +262 -0
- package/dist/humain/web-access/vendor/kagi.js.map +1 -0
- package/dist/humain/web-access/vendor/ollama.d.ts +15 -0
- package/dist/humain/web-access/vendor/ollama.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/ollama.js +216 -0
- package/dist/humain/web-access/vendor/ollama.js.map +1 -0
- package/dist/humain/web-access/vendor/openai-search.d.ts +15 -0
- package/dist/humain/web-access/vendor/openai-search.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/openai-search.js +459 -0
- package/dist/humain/web-access/vendor/openai-search.js.map +1 -0
- package/dist/humain/web-access/vendor/page-query.d.ts +16 -0
- package/dist/humain/web-access/vendor/page-query.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/page-query.js +79 -0
- package/dist/humain/web-access/vendor/page-query.js.map +1 -0
- package/dist/humain/web-access/vendor/parallel.d.ts +12 -0
- package/dist/humain/web-access/vendor/parallel.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/parallel.js +343 -0
- package/dist/humain/web-access/vendor/parallel.js.map +1 -0
- package/dist/humain/web-access/vendor/pdf-extract.d.ts +44 -0
- package/dist/humain/web-access/vendor/pdf-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/pdf-extract.js +298 -0
- package/dist/humain/web-access/vendor/pdf-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/perplexity.d.ts +20 -0
- package/dist/humain/web-access/vendor/perplexity.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/perplexity.js +159 -0
- package/dist/humain/web-access/vendor/perplexity.js.map +1 -0
- package/dist/humain/web-access/vendor/querit.d.ts +10 -0
- package/dist/humain/web-access/vendor/querit.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/querit.js +335 -0
- package/dist/humain/web-access/vendor/querit.js.map +1 -0
- package/dist/humain/web-access/vendor/render-search-error.d.ts +57 -0
- package/dist/humain/web-access/vendor/render-search-error.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/render-search-error.js +130 -0
- package/dist/humain/web-access/vendor/render-search-error.js.map +1 -0
- package/dist/humain/web-access/vendor/rsc-extract.d.ts +12 -0
- package/dist/humain/web-access/vendor/rsc-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/rsc-extract.js +329 -0
- package/dist/humain/web-access/vendor/rsc-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/search1api.d.ts +10 -0
- package/dist/humain/web-access/vendor/search1api.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/search1api.js +251 -0
- package/dist/humain/web-access/vendor/search1api.js.map +1 -0
- package/dist/humain/web-access/vendor/searchinfinity.d.ts +8 -0
- package/dist/humain/web-access/vendor/searchinfinity.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/searchinfinity.js +229 -0
- package/dist/humain/web-access/vendor/searchinfinity.js.map +1 -0
- package/dist/humain/web-access/vendor/searxng.d.ts +4 -0
- package/dist/humain/web-access/vendor/searxng.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/searxng.js +238 -0
- package/dist/humain/web-access/vendor/searxng.js.map +1 -0
- package/dist/humain/web-access/vendor/serpbase.d.ts +4 -0
- package/dist/humain/web-access/vendor/serpbase.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/serpbase.js +211 -0
- package/dist/humain/web-access/vendor/serpbase.js.map +1 -0
- package/dist/humain/web-access/vendor/serpdive.d.ts +8 -0
- package/dist/humain/web-access/vendor/serpdive.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/serpdive.js +267 -0
- package/dist/humain/web-access/vendor/serpdive.js.map +1 -0
- package/dist/humain/web-access/vendor/source-check.d.ts +99 -0
- package/dist/humain/web-access/vendor/source-check.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/source-check.js +205 -0
- package/dist/humain/web-access/vendor/source-check.js.map +1 -0
- package/dist/humain/web-access/vendor/ssrf-protection.d.ts +50 -0
- package/dist/humain/web-access/vendor/ssrf-protection.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/ssrf-protection.js +466 -0
- package/dist/humain/web-access/vendor/ssrf-protection.js.map +1 -0
- package/dist/humain/web-access/vendor/storage.d.ts +55 -0
- package/dist/humain/web-access/vendor/storage.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/storage.js +485 -0
- package/dist/humain/web-access/vendor/storage.js.map +1 -0
- package/dist/humain/web-access/vendor/summary-model-scope.d.ts +25 -0
- package/dist/humain/web-access/vendor/summary-model-scope.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/summary-model-scope.js +98 -0
- package/dist/humain/web-access/vendor/summary-model-scope.js.map +1 -0
- package/dist/humain/web-access/vendor/summary-review.d.ts +24 -0
- package/dist/humain/web-access/vendor/summary-review.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/summary-review.js +341 -0
- package/dist/humain/web-access/vendor/summary-review.js.map +1 -0
- package/dist/humain/web-access/vendor/tavily.d.ts +8 -0
- package/dist/humain/web-access/vendor/tavily.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/tavily.js +194 -0
- package/dist/humain/web-access/vendor/tavily.js.map +1 -0
- package/dist/humain/web-access/vendor/tinyfish.d.ts +11 -0
- package/dist/humain/web-access/vendor/tinyfish.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/tinyfish.js +331 -0
- package/dist/humain/web-access/vendor/tinyfish.js.map +1 -0
- package/dist/humain/web-access/vendor/utils.d.ts +20 -0
- package/dist/humain/web-access/vendor/utils.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/utils.js +91 -0
- package/dist/humain/web-access/vendor/utils.js.map +1 -0
- package/dist/humain/web-access/vendor/video-extract.d.ts +16 -0
- package/dist/humain/web-access/vendor/video-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/video-extract.js +335 -0
- package/dist/humain/web-access/vendor/video-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/xai-search.d.ts +13 -0
- package/dist/humain/web-access/vendor/xai-search.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/xai-search.js +331 -0
- package/dist/humain/web-access/vendor/xai-search.js.map +1 -0
- package/dist/humain/web-access/vendor/youtube-extract.d.ts +27 -0
- package/dist/humain/web-access/vendor/youtube-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/youtube-extract.js +282 -0
- package/dist/humain/web-access/vendor/youtube-extract.js.map +1 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +2 -2
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +169 -102
- package/dist/main.js.map +1 -1
- package/dist/modes/agent-exec-mode.d.ts +14 -0
- package/dist/modes/agent-exec-mode.d.ts.map +1 -0
- package/dist/modes/agent-exec-mode.js +92 -0
- package/dist/modes/agent-exec-mode.js.map +1 -0
- package/dist/modes/index.d.ts +4 -2
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +2 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +5 -2
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +13 -4
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +7 -0
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
- package/dist/modes/interactive/components/earendil-announcement.js +40 -0
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
- package/dist/modes/interactive/components/markdown-transform.js +19 -0
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
- package/dist/modes/interactive/components/mermaid.d.ts +11 -0
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
- package/dist/modes/interactive/components/mermaid.js +75 -0
- package/dist/modes/interactive/components/mermaid.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +16 -4
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +26 -0
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +8 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +30 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +3 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +9 -2
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +45 -9
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +581 -211
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +1 -0
- package/dist/modes/interactive/theme/light.json +1 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +3 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +10 -1
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +5 -1
- package/dist/modes/interactive/theme/theme.d.ts +2 -2
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +24 -6
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +28 -0
- package/dist/modes/json-event.d.ts.map +1 -0
- package/dist/modes/json-event.js +12 -0
- package/dist/modes/json-event.js.map +1 -0
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +12 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +12 -5
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +55 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +13 -3
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +15 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +11 -9
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.d.ts.map +1 -1
- package/dist/rpc-entry.js +3 -2
- package/dist/rpc-entry.js.map +1 -1
- package/dist/server/create-harness.d.ts +26 -0
- package/dist/server/create-harness.d.ts.map +1 -0
- package/dist/server/create-harness.js +104 -0
- package/dist/server/create-harness.js.map +1 -0
- package/dist/utils/abort.d.ts +5 -0
- package/dist/utils/abort.d.ts.map +1 -0
- package/dist/utils/abort.js +48 -0
- package/dist/utils/abort.js.map +1 -0
- package/dist/utils/clipboard.d.ts +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +22 -2
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/management-http.d.ts +23 -0
- package/dist/utils/management-http.d.ts.map +1 -0
- package/dist/utils/management-http.js +50 -0
- package/dist/utils/management-http.js.map +1 -0
- package/dist/utils/paths.d.ts +3 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +23 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/tool-result-images.d.ts +19 -0
- package/dist/utils/tool-result-images.d.ts.map +1 -0
- package/dist/utils/tool-result-images.js +45 -0
- package/dist/utils/tool-result-images.js.map +1 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +13 -25
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +4 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +23 -5
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +2 -2
- package/docs/custom-provider.md +7 -5
- package/docs/extensions.md +30 -5
- package/docs/humain-terminal.md +21 -1
- package/docs/json.md +24 -19
- package/docs/keybindings.md +46 -14
- package/docs/models.md +32 -11
- package/docs/providers.md +9 -1
- package/docs/quickstart.md +39 -37
- package/docs/rpc.md +31 -11
- package/docs/sdk.md +21 -2
- package/docs/security.md +21 -21
- package/docs/session-format.md +14 -14
- package/docs/settings.md +4 -1
- package/docs/themes.md +5 -3
- package/docs/usage.md +7 -0
- package/examples/extensions/custom-compaction.ts +3 -18
- package/examples/extensions/custom-provider-anthropic/index.ts +5 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +5 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/handoff.ts +4 -13
- package/examples/extensions/qna.ts +5 -9
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/summarize.ts +9 -20
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +11 -2
- package/examples/sdk/02-custom-model.ts +2 -3
- package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
- package/examples/sdk/12-full-control.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +2771 -535
- package/package.json +40 -11
- package/src/humain/mcp-adapter/UPSTREAM.md +15 -0
- package/src/humain/mcp-adapter/upstream.json +7 -0
- package/src/humain/mcp-adapter/vendor/CHANGELOG.md +660 -0
- package/src/humain/mcp-adapter/vendor/LICENSE +21 -0
- package/src/humain/web-access/UPSTREAM.md +17 -0
- package/src/humain/web-access/upstream.json +23 -0
- package/src/humain/web-access/vendor/LICENSE +21 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SearchOptions, SearchResponse } from "./perplexity.ts";
|
|
2
|
+
interface JinaSearchOptions extends SearchOptions {
|
|
3
|
+
includeContent?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function isJinaSearchAvailable(): boolean;
|
|
6
|
+
export declare function searchWithJina(query: string, options?: JinaSearchOptions): Promise<SearchResponse>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=jina-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jina-search.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/jina-search.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAuBrE,UAAU,iBAAkB,SAAQ,aAAa;IAChD,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAuLD,wBAAgB,qBAAqB,IAAI,OAAO,CAM/C;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,cAAc,CAAC,CA+D5G","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst JINA_SEARCH_BASE_URL = \"https://s.jina.ai/\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\n\ninterface WebSearchConfig {\n\tjinaApiKey?: unknown;\n}\n\ninterface JinaSearchItem {\n\ttitle?: unknown;\n\turl?: unknown;\n\tdescription?: unknown;\n\tcontent?: unknown;\n}\n\ninterface JinaSearchEnvelope {\n\tcode?: unknown;\n\tdata?: unknown;\n}\n\ninterface JinaSearchOptions extends SearchOptions {\n\tincludeContent?: boolean;\n}\n\nlet cachedConfig: WebSearchConfig | null = null;\n\nfunction loadConfig(): WebSearchConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\n\tconst raw = readFileSync(CONFIG_PATH, \"utf8\");\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(raw);\n\t\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\t\tthrow new Error(\"expected a JSON object\");\n\t\t}\n\t\tcachedConfig = parsed as WebSearchConfig;\n\t\treturn cachedConfig;\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"Jina Search\",\n\t\tconfiguredValue: loadConfig().jinaApiKey,\n\t\tenvironmentValue: process.env.JINA_API_KEY,\n\t\tsignal,\n\t});\n}\n\nasync function requireApiKey(signal?: AbortSignal): Promise<string> {\n\tconst apiKey = await getApiKey(signal);\n\tif (!apiKey) {\n\t\tthrow new Error(\n\t\t\t\"Jina Search API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"jinaApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set JINA_API_KEY environment variable\\n\" +\n\t\t\t\"Get a key at https://jina.ai/api-dashboard\",\n\t\t);\n\t}\n\treturn apiKey;\n}\n\nfunction normalizeCount(value: number | undefined): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return 5;\n\treturn Math.max(1, Math.min(Math.floor(value), 20));\n}\n\nfunction normalizeDomain(value: string): string | null {\n\tlet input = value.trim().toLowerCase();\n\tif (input.startsWith(\"-\")) input = input.slice(1).trim();\n\tif (!input) return null;\n\ttry {\n\t\tconst parsed = input.includes(\"://\") ? new URL(input) : new URL(`https://${input}`);\n\t\tinput = parsed.hostname;\n\t} catch {\n\t\tinput = input.split(\"/\")[0]?.split(\":\")[0] ?? \"\";\n\t}\n\tinput = input.replace(/^\\.+|\\.+$/g, \"\");\n\treturn /^[a-z0-9][a-z0-9.-]*\\.[a-z]{2,}$/i.test(input) ? input : null;\n}\n\nfunction mapDomainFilter(domainFilter: string[] | undefined): { includes: string[]; excludes: string[] } {\n\tconst includes: string[] = [];\n\tconst excludes: string[] = [];\n\tfor (const raw of domainFilter ?? []) {\n\t\tconst domain = normalizeDomain(raw);\n\t\tif (!domain) continue;\n\t\tconst target = raw.trim().startsWith(\"-\") ? excludes : includes;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn { includes, excludes };\n}\n\nfunction buildSearchRequest(query: string, options: JinaSearchOptions, numResults: number): { url: string; filters: ReturnType<typeof mapDomainFilter> } {\n\tconst filters = mapDomainFilter(options.domainFilter);\n\tconst recency = options.recencyFilter ? ` published in the past ${options.recencyFilter}` : \"\";\n\tconst exclusions = filters.excludes.map((domain) => ` -site:${domain}`).join(\"\");\n\tconst constrainedQuery = `${query.trim()}${exclusions}${recency}`.trim();\n\tconst url = new URL(encodeURIComponent(constrainedQuery), JINA_SEARCH_BASE_URL);\n\turl.searchParams.set(\"count\", String(numResults));\n\tfor (const domain of filters.includes) url.searchParams.append(\"site\", domain);\n\treturn { url: url.toString(), filters };\n}\n\nfunction requestSignal(signal?: AbortSignal): { signal: AbortSignal; timeout: AbortSignal } {\n\tconst timeout = AbortSignal.timeout(SEARCH_TIMEOUT_MS);\n\treturn {\n\t\ttimeout,\n\t\tsignal: signal ? AbortSignal.any([signal, timeout]) : timeout,\n\t};\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction parseItems(value: unknown): JinaSearchItem[] {\n\tif (Array.isArray(value)) return value as JinaSearchItem[];\n\tif (!value || typeof value !== \"object\") {\n\t\tthrow new Error(\"Jina Search API returned invalid response: expected an object or array\");\n\t}\n\tconst envelope = value as JinaSearchEnvelope;\n\tif (typeof envelope.code === \"number\" && envelope.code !== 200) {\n\t\tthrow new Error(`Jina Search API error ${envelope.code}: response envelope reported failure`);\n\t}\n\tif (!Array.isArray(envelope.data)) {\n\t\tthrow new Error(\"Jina Search API returned invalid response: expected data array\");\n\t}\n\treturn envelope.data as JinaSearchItem[];\n}\n\nfunction passesDomainFilter(url: string, filters: ReturnType<typeof mapDomainFilter>): boolean {\n\tlet hostname: string;\n\ttry {\n\t\thostname = new URL(url).hostname.toLowerCase();\n\t} catch {\n\t\treturn false;\n\t}\n\tconst matches = (domain: string): boolean => hostname === domain || hostname.endsWith(`.${domain}`);\n\tif (filters.includes.length > 0 && !filters.includes.some(matches)) return false;\n\treturn !filters.excludes.some(matches);\n}\n\nfunction mapItems(items: JinaSearchItem[], numResults: number, filters: ReturnType<typeof mapDomainFilter>): {\n\tresults: SearchResponse[\"results\"];\n\tcontent: ExtractedContent[];\n} {\n\tconst results: SearchResponse[\"results\"] = [];\n\tconst content: ExtractedContent[] = [];\n\tconst seen = new Set<string>();\n\tfor (const item of items) {\n\t\tconst url = typeof item?.url === \"string\" ? item.url.trim() : \"\";\n\t\tif (!url || seen.has(url) || !passesDomainFilter(url, filters)) continue;\n\t\tseen.add(url);\n\t\tconst title = typeof item.title === \"string\" && item.title.trim()\n\t\t\t? item.title.trim()\n\t\t\t: `Source ${results.length + 1}`;\n\t\tconst snippet = typeof item.description === \"string\"\n\t\t\t? item.description.replace(/\\s+/g, \" \").trim()\n\t\t\t: \"\";\n\t\tresults.push({ title, url, snippet });\n\t\tif (typeof item.content === \"string\" && item.content.trim()) {\n\t\t\tcontent.push({ url, title, content: item.content.trim(), error: null });\n\t\t}\n\t\tif (results.length >= numResults) break;\n\t}\n\treturn { results, content };\n}\n\nfunction buildAnswer(results: SearchResponse[\"results\"]): string {\n\treturn results\n\t\t.map((result) => result.snippet\n\t\t\t? `${result.snippet}\\nSource: ${result.title} (${result.url})`\n\t\t\t: `Source: ${result.title} (${result.url})`)\n\t\t.join(\"\\n\\n\");\n}\n\nfunction rethrowRequestError(\n\terr: unknown,\n\tapiKey: string,\n\tactivityId: string,\n\trequest: ReturnType<typeof requestSignal>,\n\tcallerSignal?: AbortSignal,\n): never {\n\tif (request.timeout.aborted && !callerSignal?.aborted) {\n\t\tactivityMonitor.logComplete(activityId, 408);\n\t\tthrow new Error(\"Jina Search API error 408: request timed out\");\n\t}\n\tconst message = errorMessage(err);\n\tconst redactedMessage = redactCredential(message, apiKey);\n\tif (redactedMessage.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\telse activityMonitor.logError(activityId, redactedMessage);\n\tif (redactedMessage === message) throw err;\n\tconst redactedError = new Error(redactedMessage);\n\tif (err instanceof Error) redactedError.name = err.name;\n\tthrow redactedError;\n}\n\nexport function isJinaSearchAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"Jina Search\",\n\t\tconfiguredValue: loadConfig().jinaApiKey,\n\t\tenvironmentValue: process.env.JINA_API_KEY,\n\t});\n}\n\nexport async function searchWithJina(query: string, options: JinaSearchOptions = {}): Promise<SearchResponse> {\n\tconst apiKey = await requireApiKey(options.signal);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst { url, filters } = buildSearchRequest(query, options, numResults);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\tconst request = requestSignal(options.signal);\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\theaders: {\n\t\t\t\t\"Accept\": \"application/json\",\n\t\t\t\t\"Authorization\": `Bearer ${apiKey}`,\n\t\t\t\t\"User-Agent\": \"pi-web-access\",\n\t\t\t\t\"X-Respond-With\": options.includeContent ? \"content\" : \"no-content\",\n\t\t\t\t\"X-Retain-Images\": \"none\",\n\t\t\t},\n\t\t\tsignal: request.signal,\n\t\t});\n\t} catch (err) {\n\t\trethrowRequestError(err, apiKey, activityId, request, options.signal);\n\t}\n\n\tif (!response.ok) {\n\t\tlet body: string;\n\t\ttry {\n\t\t\tbody = redactCredential(await response.text(), apiKey);\n\t\t} catch (err) {\n\t\t\trethrowRequestError(err, apiKey, activityId, request, options.signal);\n\t\t}\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`Jina Search API error ${response.status}: ${body.slice(0, 300)}`);\n\t}\n\n\tlet raw: unknown;\n\ttry {\n\t\traw = await response.json();\n\t} catch (err) {\n\t\tif (!(err instanceof SyntaxError)) {\n\t\t\trethrowRequestError(err, apiKey, activityId, request, options.signal);\n\t\t}\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(\"Jina Search API returned invalid JSON\");\n\t}\n\n\tlet mapped: ReturnType<typeof mapItems>;\n\ttry {\n\t\tmapped = mapItems(parseItems(raw), numResults, filters);\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tactivityMonitor.logError(activityId, redactedMessage);\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst result: SearchResponse = {\n\t\tanswer: buildAnswer(mapped.results),\n\t\tresults: mapped.results,\n\t};\n\tif (options.includeContent && mapped.content.length > 0) result.inlineContent = mapped.content;\n\treturn result;\n}\n"]}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { activityMonitor } from "./activity.js";
|
|
3
|
+
import { hasCredentialSource, redactCredential, resolveCredential } from "./credential-source.js";
|
|
4
|
+
import { getWebSearchConfigPath } from "./utils.js";
|
|
5
|
+
const JINA_SEARCH_BASE_URL = "https://s.jina.ai/";
|
|
6
|
+
const CONFIG_PATH = getWebSearchConfigPath();
|
|
7
|
+
const SEARCH_TIMEOUT_MS = 60_000;
|
|
8
|
+
let cachedConfig = null;
|
|
9
|
+
function loadConfig() {
|
|
10
|
+
if (cachedConfig)
|
|
11
|
+
return cachedConfig;
|
|
12
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
13
|
+
cachedConfig = {};
|
|
14
|
+
return cachedConfig;
|
|
15
|
+
}
|
|
16
|
+
const raw = readFileSync(CONFIG_PATH, "utf8");
|
|
17
|
+
try {
|
|
18
|
+
const parsed = JSON.parse(raw);
|
|
19
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
20
|
+
throw new Error("expected a JSON object");
|
|
21
|
+
}
|
|
22
|
+
cachedConfig = parsed;
|
|
23
|
+
return cachedConfig;
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
27
|
+
throw new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async function getApiKey(signal) {
|
|
31
|
+
return resolveCredential({
|
|
32
|
+
provider: "Jina Search",
|
|
33
|
+
configuredValue: loadConfig().jinaApiKey,
|
|
34
|
+
environmentValue: process.env.JINA_API_KEY,
|
|
35
|
+
signal,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async function requireApiKey(signal) {
|
|
39
|
+
const apiKey = await getApiKey(signal);
|
|
40
|
+
if (!apiKey) {
|
|
41
|
+
throw new Error("Jina Search API key not found. Either:\n" +
|
|
42
|
+
` 1. Create ${CONFIG_PATH} with { "jinaApiKey": "your-key" }\n` +
|
|
43
|
+
" 2. Set JINA_API_KEY environment variable\n" +
|
|
44
|
+
"Get a key at https://jina.ai/api-dashboard");
|
|
45
|
+
}
|
|
46
|
+
return apiKey;
|
|
47
|
+
}
|
|
48
|
+
function normalizeCount(value) {
|
|
49
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
50
|
+
return 5;
|
|
51
|
+
return Math.max(1, Math.min(Math.floor(value), 20));
|
|
52
|
+
}
|
|
53
|
+
function normalizeDomain(value) {
|
|
54
|
+
let input = value.trim().toLowerCase();
|
|
55
|
+
if (input.startsWith("-"))
|
|
56
|
+
input = input.slice(1).trim();
|
|
57
|
+
if (!input)
|
|
58
|
+
return null;
|
|
59
|
+
try {
|
|
60
|
+
const parsed = input.includes("://") ? new URL(input) : new URL(`https://${input}`);
|
|
61
|
+
input = parsed.hostname;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
input = input.split("/")[0]?.split(":")[0] ?? "";
|
|
65
|
+
}
|
|
66
|
+
input = input.replace(/^\.+|\.+$/g, "");
|
|
67
|
+
return /^[a-z0-9][a-z0-9.-]*\.[a-z]{2,}$/i.test(input) ? input : null;
|
|
68
|
+
}
|
|
69
|
+
function mapDomainFilter(domainFilter) {
|
|
70
|
+
const includes = [];
|
|
71
|
+
const excludes = [];
|
|
72
|
+
for (const raw of domainFilter ?? []) {
|
|
73
|
+
const domain = normalizeDomain(raw);
|
|
74
|
+
if (!domain)
|
|
75
|
+
continue;
|
|
76
|
+
const target = raw.trim().startsWith("-") ? excludes : includes;
|
|
77
|
+
if (!target.includes(domain))
|
|
78
|
+
target.push(domain);
|
|
79
|
+
}
|
|
80
|
+
return { includes, excludes };
|
|
81
|
+
}
|
|
82
|
+
function buildSearchRequest(query, options, numResults) {
|
|
83
|
+
const filters = mapDomainFilter(options.domainFilter);
|
|
84
|
+
const recency = options.recencyFilter ? ` published in the past ${options.recencyFilter}` : "";
|
|
85
|
+
const exclusions = filters.excludes.map((domain) => ` -site:${domain}`).join("");
|
|
86
|
+
const constrainedQuery = `${query.trim()}${exclusions}${recency}`.trim();
|
|
87
|
+
const url = new URL(encodeURIComponent(constrainedQuery), JINA_SEARCH_BASE_URL);
|
|
88
|
+
url.searchParams.set("count", String(numResults));
|
|
89
|
+
for (const domain of filters.includes)
|
|
90
|
+
url.searchParams.append("site", domain);
|
|
91
|
+
return { url: url.toString(), filters };
|
|
92
|
+
}
|
|
93
|
+
function requestSignal(signal) {
|
|
94
|
+
const timeout = AbortSignal.timeout(SEARCH_TIMEOUT_MS);
|
|
95
|
+
return {
|
|
96
|
+
timeout,
|
|
97
|
+
signal: signal ? AbortSignal.any([signal, timeout]) : timeout,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function errorMessage(err) {
|
|
101
|
+
return err instanceof Error ? err.message : String(err);
|
|
102
|
+
}
|
|
103
|
+
function parseItems(value) {
|
|
104
|
+
if (Array.isArray(value))
|
|
105
|
+
return value;
|
|
106
|
+
if (!value || typeof value !== "object") {
|
|
107
|
+
throw new Error("Jina Search API returned invalid response: expected an object or array");
|
|
108
|
+
}
|
|
109
|
+
const envelope = value;
|
|
110
|
+
if (typeof envelope.code === "number" && envelope.code !== 200) {
|
|
111
|
+
throw new Error(`Jina Search API error ${envelope.code}: response envelope reported failure`);
|
|
112
|
+
}
|
|
113
|
+
if (!Array.isArray(envelope.data)) {
|
|
114
|
+
throw new Error("Jina Search API returned invalid response: expected data array");
|
|
115
|
+
}
|
|
116
|
+
return envelope.data;
|
|
117
|
+
}
|
|
118
|
+
function passesDomainFilter(url, filters) {
|
|
119
|
+
let hostname;
|
|
120
|
+
try {
|
|
121
|
+
hostname = new URL(url).hostname.toLowerCase();
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
const matches = (domain) => hostname === domain || hostname.endsWith(`.${domain}`);
|
|
127
|
+
if (filters.includes.length > 0 && !filters.includes.some(matches))
|
|
128
|
+
return false;
|
|
129
|
+
return !filters.excludes.some(matches);
|
|
130
|
+
}
|
|
131
|
+
function mapItems(items, numResults, filters) {
|
|
132
|
+
const results = [];
|
|
133
|
+
const content = [];
|
|
134
|
+
const seen = new Set();
|
|
135
|
+
for (const item of items) {
|
|
136
|
+
const url = typeof item?.url === "string" ? item.url.trim() : "";
|
|
137
|
+
if (!url || seen.has(url) || !passesDomainFilter(url, filters))
|
|
138
|
+
continue;
|
|
139
|
+
seen.add(url);
|
|
140
|
+
const title = typeof item.title === "string" && item.title.trim()
|
|
141
|
+
? item.title.trim()
|
|
142
|
+
: `Source ${results.length + 1}`;
|
|
143
|
+
const snippet = typeof item.description === "string"
|
|
144
|
+
? item.description.replace(/\s+/g, " ").trim()
|
|
145
|
+
: "";
|
|
146
|
+
results.push({ title, url, snippet });
|
|
147
|
+
if (typeof item.content === "string" && item.content.trim()) {
|
|
148
|
+
content.push({ url, title, content: item.content.trim(), error: null });
|
|
149
|
+
}
|
|
150
|
+
if (results.length >= numResults)
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
return { results, content };
|
|
154
|
+
}
|
|
155
|
+
function buildAnswer(results) {
|
|
156
|
+
return results
|
|
157
|
+
.map((result) => result.snippet
|
|
158
|
+
? `${result.snippet}\nSource: ${result.title} (${result.url})`
|
|
159
|
+
: `Source: ${result.title} (${result.url})`)
|
|
160
|
+
.join("\n\n");
|
|
161
|
+
}
|
|
162
|
+
function rethrowRequestError(err, apiKey, activityId, request, callerSignal) {
|
|
163
|
+
if (request.timeout.aborted && !callerSignal?.aborted) {
|
|
164
|
+
activityMonitor.logComplete(activityId, 408);
|
|
165
|
+
throw new Error("Jina Search API error 408: request timed out");
|
|
166
|
+
}
|
|
167
|
+
const message = errorMessage(err);
|
|
168
|
+
const redactedMessage = redactCredential(message, apiKey);
|
|
169
|
+
if (redactedMessage.toLowerCase().includes("abort"))
|
|
170
|
+
activityMonitor.logComplete(activityId, 0);
|
|
171
|
+
else
|
|
172
|
+
activityMonitor.logError(activityId, redactedMessage);
|
|
173
|
+
if (redactedMessage === message)
|
|
174
|
+
throw err;
|
|
175
|
+
const redactedError = new Error(redactedMessage);
|
|
176
|
+
if (err instanceof Error)
|
|
177
|
+
redactedError.name = err.name;
|
|
178
|
+
throw redactedError;
|
|
179
|
+
}
|
|
180
|
+
export function isJinaSearchAvailable() {
|
|
181
|
+
return hasCredentialSource({
|
|
182
|
+
provider: "Jina Search",
|
|
183
|
+
configuredValue: loadConfig().jinaApiKey,
|
|
184
|
+
environmentValue: process.env.JINA_API_KEY,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
export async function searchWithJina(query, options = {}) {
|
|
188
|
+
const apiKey = await requireApiKey(options.signal);
|
|
189
|
+
const numResults = normalizeCount(options.numResults);
|
|
190
|
+
const { url, filters } = buildSearchRequest(query, options, numResults);
|
|
191
|
+
const activityId = activityMonitor.logStart({ type: "api", query });
|
|
192
|
+
const request = requestSignal(options.signal);
|
|
193
|
+
let response;
|
|
194
|
+
try {
|
|
195
|
+
response = await fetch(url, {
|
|
196
|
+
headers: {
|
|
197
|
+
"Accept": "application/json",
|
|
198
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
199
|
+
"User-Agent": "pi-web-access",
|
|
200
|
+
"X-Respond-With": options.includeContent ? "content" : "no-content",
|
|
201
|
+
"X-Retain-Images": "none",
|
|
202
|
+
},
|
|
203
|
+
signal: request.signal,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
rethrowRequestError(err, apiKey, activityId, request, options.signal);
|
|
208
|
+
}
|
|
209
|
+
if (!response.ok) {
|
|
210
|
+
let body;
|
|
211
|
+
try {
|
|
212
|
+
body = redactCredential(await response.text(), apiKey);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
rethrowRequestError(err, apiKey, activityId, request, options.signal);
|
|
216
|
+
}
|
|
217
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
218
|
+
throw new Error(`Jina Search API error ${response.status}: ${body.slice(0, 300)}`);
|
|
219
|
+
}
|
|
220
|
+
let raw;
|
|
221
|
+
try {
|
|
222
|
+
raw = await response.json();
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
if (!(err instanceof SyntaxError)) {
|
|
226
|
+
rethrowRequestError(err, apiKey, activityId, request, options.signal);
|
|
227
|
+
}
|
|
228
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
229
|
+
throw new Error("Jina Search API returned invalid JSON");
|
|
230
|
+
}
|
|
231
|
+
let mapped;
|
|
232
|
+
try {
|
|
233
|
+
mapped = mapItems(parseItems(raw), numResults, filters);
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
const message = errorMessage(err);
|
|
237
|
+
const redactedMessage = redactCredential(message, apiKey);
|
|
238
|
+
activityMonitor.logError(activityId, redactedMessage);
|
|
239
|
+
if (redactedMessage === message)
|
|
240
|
+
throw err;
|
|
241
|
+
const redactedError = new Error(redactedMessage);
|
|
242
|
+
if (err instanceof Error)
|
|
243
|
+
redactedError.name = err.name;
|
|
244
|
+
throw redactedError;
|
|
245
|
+
}
|
|
246
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
247
|
+
const result = {
|
|
248
|
+
answer: buildAnswer(mapped.results),
|
|
249
|
+
results: mapped.results,
|
|
250
|
+
};
|
|
251
|
+
if (options.includeContent && mapped.content.length > 0)
|
|
252
|
+
result.inlineContent = mapped.content;
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=jina-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jina-search.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/jina-search.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst JINA_SEARCH_BASE_URL = \"https://s.jina.ai/\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\n\ninterface WebSearchConfig {\n\tjinaApiKey?: unknown;\n}\n\ninterface JinaSearchItem {\n\ttitle?: unknown;\n\turl?: unknown;\n\tdescription?: unknown;\n\tcontent?: unknown;\n}\n\ninterface JinaSearchEnvelope {\n\tcode?: unknown;\n\tdata?: unknown;\n}\n\ninterface JinaSearchOptions extends SearchOptions {\n\tincludeContent?: boolean;\n}\n\nlet cachedConfig: WebSearchConfig | null = null;\n\nfunction loadConfig(): WebSearchConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\n\tconst raw = readFileSync(CONFIG_PATH, \"utf8\");\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(raw);\n\t\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\t\tthrow new Error(\"expected a JSON object\");\n\t\t}\n\t\tcachedConfig = parsed as WebSearchConfig;\n\t\treturn cachedConfig;\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"Jina Search\",\n\t\tconfiguredValue: loadConfig().jinaApiKey,\n\t\tenvironmentValue: process.env.JINA_API_KEY,\n\t\tsignal,\n\t});\n}\n\nasync function requireApiKey(signal?: AbortSignal): Promise<string> {\n\tconst apiKey = await getApiKey(signal);\n\tif (!apiKey) {\n\t\tthrow new Error(\n\t\t\t\"Jina Search API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"jinaApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set JINA_API_KEY environment variable\\n\" +\n\t\t\t\"Get a key at https://jina.ai/api-dashboard\",\n\t\t);\n\t}\n\treturn apiKey;\n}\n\nfunction normalizeCount(value: number | undefined): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return 5;\n\treturn Math.max(1, Math.min(Math.floor(value), 20));\n}\n\nfunction normalizeDomain(value: string): string | null {\n\tlet input = value.trim().toLowerCase();\n\tif (input.startsWith(\"-\")) input = input.slice(1).trim();\n\tif (!input) return null;\n\ttry {\n\t\tconst parsed = input.includes(\"://\") ? new URL(input) : new URL(`https://${input}`);\n\t\tinput = parsed.hostname;\n\t} catch {\n\t\tinput = input.split(\"/\")[0]?.split(\":\")[0] ?? \"\";\n\t}\n\tinput = input.replace(/^\\.+|\\.+$/g, \"\");\n\treturn /^[a-z0-9][a-z0-9.-]*\\.[a-z]{2,}$/i.test(input) ? input : null;\n}\n\nfunction mapDomainFilter(domainFilter: string[] | undefined): { includes: string[]; excludes: string[] } {\n\tconst includes: string[] = [];\n\tconst excludes: string[] = [];\n\tfor (const raw of domainFilter ?? []) {\n\t\tconst domain = normalizeDomain(raw);\n\t\tif (!domain) continue;\n\t\tconst target = raw.trim().startsWith(\"-\") ? excludes : includes;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn { includes, excludes };\n}\n\nfunction buildSearchRequest(query: string, options: JinaSearchOptions, numResults: number): { url: string; filters: ReturnType<typeof mapDomainFilter> } {\n\tconst filters = mapDomainFilter(options.domainFilter);\n\tconst recency = options.recencyFilter ? ` published in the past ${options.recencyFilter}` : \"\";\n\tconst exclusions = filters.excludes.map((domain) => ` -site:${domain}`).join(\"\");\n\tconst constrainedQuery = `${query.trim()}${exclusions}${recency}`.trim();\n\tconst url = new URL(encodeURIComponent(constrainedQuery), JINA_SEARCH_BASE_URL);\n\turl.searchParams.set(\"count\", String(numResults));\n\tfor (const domain of filters.includes) url.searchParams.append(\"site\", domain);\n\treturn { url: url.toString(), filters };\n}\n\nfunction requestSignal(signal?: AbortSignal): { signal: AbortSignal; timeout: AbortSignal } {\n\tconst timeout = AbortSignal.timeout(SEARCH_TIMEOUT_MS);\n\treturn {\n\t\ttimeout,\n\t\tsignal: signal ? AbortSignal.any([signal, timeout]) : timeout,\n\t};\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction parseItems(value: unknown): JinaSearchItem[] {\n\tif (Array.isArray(value)) return value as JinaSearchItem[];\n\tif (!value || typeof value !== \"object\") {\n\t\tthrow new Error(\"Jina Search API returned invalid response: expected an object or array\");\n\t}\n\tconst envelope = value as JinaSearchEnvelope;\n\tif (typeof envelope.code === \"number\" && envelope.code !== 200) {\n\t\tthrow new Error(`Jina Search API error ${envelope.code}: response envelope reported failure`);\n\t}\n\tif (!Array.isArray(envelope.data)) {\n\t\tthrow new Error(\"Jina Search API returned invalid response: expected data array\");\n\t}\n\treturn envelope.data as JinaSearchItem[];\n}\n\nfunction passesDomainFilter(url: string, filters: ReturnType<typeof mapDomainFilter>): boolean {\n\tlet hostname: string;\n\ttry {\n\t\thostname = new URL(url).hostname.toLowerCase();\n\t} catch {\n\t\treturn false;\n\t}\n\tconst matches = (domain: string): boolean => hostname === domain || hostname.endsWith(`.${domain}`);\n\tif (filters.includes.length > 0 && !filters.includes.some(matches)) return false;\n\treturn !filters.excludes.some(matches);\n}\n\nfunction mapItems(items: JinaSearchItem[], numResults: number, filters: ReturnType<typeof mapDomainFilter>): {\n\tresults: SearchResponse[\"results\"];\n\tcontent: ExtractedContent[];\n} {\n\tconst results: SearchResponse[\"results\"] = [];\n\tconst content: ExtractedContent[] = [];\n\tconst seen = new Set<string>();\n\tfor (const item of items) {\n\t\tconst url = typeof item?.url === \"string\" ? item.url.trim() : \"\";\n\t\tif (!url || seen.has(url) || !passesDomainFilter(url, filters)) continue;\n\t\tseen.add(url);\n\t\tconst title = typeof item.title === \"string\" && item.title.trim()\n\t\t\t? item.title.trim()\n\t\t\t: `Source ${results.length + 1}`;\n\t\tconst snippet = typeof item.description === \"string\"\n\t\t\t? item.description.replace(/\\s+/g, \" \").trim()\n\t\t\t: \"\";\n\t\tresults.push({ title, url, snippet });\n\t\tif (typeof item.content === \"string\" && item.content.trim()) {\n\t\t\tcontent.push({ url, title, content: item.content.trim(), error: null });\n\t\t}\n\t\tif (results.length >= numResults) break;\n\t}\n\treturn { results, content };\n}\n\nfunction buildAnswer(results: SearchResponse[\"results\"]): string {\n\treturn results\n\t\t.map((result) => result.snippet\n\t\t\t? `${result.snippet}\\nSource: ${result.title} (${result.url})`\n\t\t\t: `Source: ${result.title} (${result.url})`)\n\t\t.join(\"\\n\\n\");\n}\n\nfunction rethrowRequestError(\n\terr: unknown,\n\tapiKey: string,\n\tactivityId: string,\n\trequest: ReturnType<typeof requestSignal>,\n\tcallerSignal?: AbortSignal,\n): never {\n\tif (request.timeout.aborted && !callerSignal?.aborted) {\n\t\tactivityMonitor.logComplete(activityId, 408);\n\t\tthrow new Error(\"Jina Search API error 408: request timed out\");\n\t}\n\tconst message = errorMessage(err);\n\tconst redactedMessage = redactCredential(message, apiKey);\n\tif (redactedMessage.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\telse activityMonitor.logError(activityId, redactedMessage);\n\tif (redactedMessage === message) throw err;\n\tconst redactedError = new Error(redactedMessage);\n\tif (err instanceof Error) redactedError.name = err.name;\n\tthrow redactedError;\n}\n\nexport function isJinaSearchAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"Jina Search\",\n\t\tconfiguredValue: loadConfig().jinaApiKey,\n\t\tenvironmentValue: process.env.JINA_API_KEY,\n\t});\n}\n\nexport async function searchWithJina(query: string, options: JinaSearchOptions = {}): Promise<SearchResponse> {\n\tconst apiKey = await requireApiKey(options.signal);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst { url, filters } = buildSearchRequest(query, options, numResults);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\tconst request = requestSignal(options.signal);\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\theaders: {\n\t\t\t\t\"Accept\": \"application/json\",\n\t\t\t\t\"Authorization\": `Bearer ${apiKey}`,\n\t\t\t\t\"User-Agent\": \"pi-web-access\",\n\t\t\t\t\"X-Respond-With\": options.includeContent ? \"content\" : \"no-content\",\n\t\t\t\t\"X-Retain-Images\": \"none\",\n\t\t\t},\n\t\t\tsignal: request.signal,\n\t\t});\n\t} catch (err) {\n\t\trethrowRequestError(err, apiKey, activityId, request, options.signal);\n\t}\n\n\tif (!response.ok) {\n\t\tlet body: string;\n\t\ttry {\n\t\t\tbody = redactCredential(await response.text(), apiKey);\n\t\t} catch (err) {\n\t\t\trethrowRequestError(err, apiKey, activityId, request, options.signal);\n\t\t}\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`Jina Search API error ${response.status}: ${body.slice(0, 300)}`);\n\t}\n\n\tlet raw: unknown;\n\ttry {\n\t\traw = await response.json();\n\t} catch (err) {\n\t\tif (!(err instanceof SyntaxError)) {\n\t\t\trethrowRequestError(err, apiKey, activityId, request, options.signal);\n\t\t}\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(\"Jina Search API returned invalid JSON\");\n\t}\n\n\tlet mapped: ReturnType<typeof mapItems>;\n\ttry {\n\t\tmapped = mapItems(parseItems(raw), numResults, filters);\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tactivityMonitor.logError(activityId, redactedMessage);\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst result: SearchResponse = {\n\t\tanswer: buildAnswer(mapped.results),\n\t\tresults: mapped.results,\n\t};\n\tif (options.includeContent && mapped.content.length > 0) result.inlineContent = mapped.content;\n\treturn result;\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ExtractedContent, ExtractOptions } from "./extract.ts";
|
|
2
|
+
import type { SearchOptions, SearchResponse } from "./perplexity.ts";
|
|
3
|
+
import { type SsrfConfig } from "./ssrf-protection.ts";
|
|
4
|
+
interface KagiSearchOptions extends SearchOptions {
|
|
5
|
+
includeContent?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface KagiExtractOptions extends Pick<ExtractOptions, "timeoutMs" | "lookup"> {
|
|
8
|
+
ssrf?: SsrfConfig;
|
|
9
|
+
}
|
|
10
|
+
export declare function isKagiAvailable(): boolean;
|
|
11
|
+
export declare function searchWithKagi(query: string, options?: KagiSearchOptions): Promise<SearchResponse>;
|
|
12
|
+
export declare function isKagiExtractAvailable(): boolean;
|
|
13
|
+
export declare function extractWithKagi(url: string, signal?: AbortSignal, options?: KagiExtractOptions): Promise<ExtractedContent | null>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=kagi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kagi.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/kagi.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAErE,OAAO,EAAmF,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAYxI,UAAU,iBAAkB,SAAQ,aAAa;IAChD,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,QAAQ,CAAC;IACvF,IAAI,CAAC,EAAE,UAAU,CAAC;CAClB;AA0ID,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,cAAc,CAAC,CA4C5G;AAED,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAiD3I","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { ExtractedContent, ExtractOptions } from \"./extract.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { fetchRemoteUrl, loadFetchContentDomainPolicy, loadSsrfConfig, validateRemoteUrl, type SsrfConfig } from \"./ssrf-protection.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst KAGI_SEARCH_URL = \"https://kagi.com/api/v1/search\";\nconst KAGI_EXTRACT_URL = \"https://kagi.com/api/v1/extract\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\n\ninterface WebSearchConfig {\n\tkagiApiKey?: unknown;\n}\n\ninterface KagiSearchOptions extends SearchOptions {\n\tincludeContent?: boolean;\n}\n\nexport interface KagiExtractOptions extends Pick<ExtractOptions, \"timeoutMs\" | \"lookup\"> {\n\tssrf?: SsrfConfig;\n}\n\nlet cachedConfig: WebSearchConfig | null = null;\n\nfunction loadConfig(): WebSearchConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\tconst raw = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"Kagi\",\n\t\tconfiguredValue: loadConfig().kagiApiKey,\n\t\tenvironmentValue: process.env.KAGI_API_KEY,\n\t\tsignal,\n\t});\n}\n\nasync function requireApiKey(signal?: AbortSignal): Promise<string> {\n\tconst apiKey = await getApiKey(signal);\n\tif (!apiKey) {\n\t\tthrow new Error(\n\t\t\t\"Kagi API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"kagiApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set KAGI_API_KEY environment variable\\n\" +\n\t\t\t\"Create a key at https://kagi.com/settings?p=api\",\n\t\t);\n\t}\n\treturn apiKey;\n}\n\nfunction normalizeCount(value: number | undefined): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return 5;\n\treturn Math.max(1, Math.min(Math.floor(value), 20));\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction invalidResponse(message: string): Error {\n\treturn new Error(`Kagi API returned invalid response: ${message}`);\n}\n\nfunction firstString(...values: unknown[]): string | null {\n\tfor (const value of values) {\n\t\tif (typeof value === \"string\" && value.trim()) return value.trim();\n\t}\n\treturn null;\n}\n\nfunction appendSearchItems(value: unknown, results: SearchResponse[\"results\"], inlineContent: ExtractedContent[]): void {\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) appendSearchItems(item, results, inlineContent);\n\t\treturn;\n\t}\n\tif (!value || typeof value !== \"object\") return;\n\tconst item = value as Record<string, unknown>;\n\tconst url = firstString(item.url, item.href, item.link);\n\tif (!url) return;\n\tconst title = firstString(item.title, item.name) ?? url;\n\tconst snippet = firstString(item.snippet, item.description, item.summary, item.content, item.markdown, item.text) ?? \"\";\n\tresults.push({ title, url, snippet });\n\tconst content = firstString(item.markdown, item.content, item.text);\n\tif (content) inlineContent.push({ url, title, content, error: null });\n}\n\nfunction parseErrors(value: unknown): string | null {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n\tconst envelope = value as Record<string, unknown>;\n\tconst rawErrors = envelope.errors ?? envelope.error;\n\tif (!Array.isArray(rawErrors)) return null;\n\tconst messages = rawErrors.map((entry) => {\n\t\tif (!entry || typeof entry !== \"object\") return String(entry);\n\t\tconst raw = entry as Record<string, unknown>;\n\t\treturn firstString(raw.message, raw.msg, raw.code) ?? JSON.stringify(raw);\n\t});\n\treturn messages.length > 0 ? messages.join(\"; \") : null;\n}\n\nfunction parseSearchResponse(value: unknown): { results: SearchResponse[\"results\"]; inlineContent: ExtractedContent[] } {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw invalidResponse(\"expected an object envelope\");\n\tconst message = parseErrors(value);\n\tif (message) throw invalidResponse(message);\n\tconst envelope = value as Record<string, unknown>;\n\tconst results: SearchResponse[\"results\"] = [];\n\tconst inlineContent: ExtractedContent[] = [];\n\tconst data = envelope.data;\n\tconst items = (typeof data === \"object\" && data !== null && !Array.isArray(data))\n\t\t? (data as Record<string, unknown>).search\n\t\t: data;\n\tappendSearchItems(items, results, inlineContent);\n\treturn { results, inlineContent };\n}\n\nfunction parseExtractResponse(value: unknown, requestedUrl: string): ExtractedContent | null {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw invalidResponse(\"expected extract object envelope\");\n\tconst message = parseErrors(value);\n\tif (message) throw invalidResponse(message);\n\tconst envelope = value as Record<string, unknown>;\n\tconst candidates = Array.isArray(envelope.data) ? envelope.data : [envelope.data ?? envelope];\n\tfor (const candidate of candidates) {\n\t\tif (!candidate || typeof candidate !== \"object\" || Array.isArray(candidate)) continue;\n\t\tconst item = candidate as Record<string, unknown>;\n\t\tconst content = firstString(item.markdown, item.content, item.text);\n\t\tif (!content) continue;\n\t\treturn {\n\t\t\turl: firstString(item.url, item.href, item.link) ?? requestedUrl,\n\t\t\ttitle: firstString(item.title, item.name) ?? requestedUrl,\n\t\t\tcontent,\n\t\t\terror: null,\n\t\t};\n\t}\n\treturn null;\n}\n\nfunction buildAnswer(results: SearchResponse[\"results\"]): string {\n\treturn results.map((result) => result.snippet\n\t\t? `${result.snippet}\\nSource: ${result.title} (${result.url})`\n\t\t: `Source: ${result.title} (${result.url})`).join(\"\\n\\n\");\n}\n\nexport function isKagiAvailable(): boolean {\n\treturn hasCredentialSource({ provider: \"Kagi\", configuredValue: loadConfig().kagiApiKey, environmentValue: process.env.KAGI_API_KEY });\n}\n\nexport async function searchWithKagi(query: string, options: KagiSearchOptions = {}): Promise<SearchResponse> {\n\tconst apiKey = await requireApiKey(options.signal);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(KAGI_SEARCH_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { Authorization: `Bearer ${apiKey}`, \"Content-Type\": \"application/json\", Accept: \"application/json\" },\n\t\t\tbody: JSON.stringify({ query, limit: numResults }),\n\t\t\tsignal: options.signal ? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS), options.signal]) : AbortSignal.timeout(SEARCH_TIMEOUT_MS),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\t\telse activityMonitor.logError(activityId, redactedMessage);\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n\tif (!response.ok) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tconst errorText = redactCredential(await response.text(), apiKey);\n\t\tthrow new Error(`Kagi API error ${response.status}: ${errorText.slice(0, 300)}`);\n\t}\n\tlet rawData: unknown;\n\ttry {\n\t\trawData = await response.json();\n\t} catch (err) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`Kagi API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\tconst parsed = parseSearchResponse(rawData);\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst results = parsed.results.slice(0, numResults);\n\tconst mapped: SearchResponse = { answer: buildAnswer(results), results };\n\tif (options.includeContent) {\n\t\tconst urls = new Set(results.map(result => result.url));\n\t\tconst inlineContent = parsed.inlineContent.filter(content => urls.has(content.url));\n\t\tif (inlineContent.length > 0) mapped.inlineContent = inlineContent;\n\t}\n\treturn mapped;\n}\n\nexport function isKagiExtractAvailable(): boolean {\n\treturn isKagiAvailable();\n}\n\nexport async function extractWithKagi(url: string, signal?: AbortSignal, options: KagiExtractOptions = {}): Promise<ExtractedContent | null> {\n\tconst ssrf = options.ssrf ?? loadSsrfConfig();\n\tconst domainPolicy = loadFetchContentDomainPolicy();\n\tawait validateRemoteUrl(url, {\n\t\tallowRanges: ssrf.allowRanges,\n\t\ttrustEnvProxy: ssrf.trustEnvProxy,\n\t\tdomainPolicy,\n\t\t...(options.lookup ? { lookup: options.lookup } : {}),\n\t});\n\tconst apiKey = await requireApiKey(signal);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query: `kagi extract: ${url}` });\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchRemoteUrl(KAGI_EXTRACT_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { Authorization: `Bearer ${apiKey}`, \"Content-Type\": \"application/json\", Accept: \"application/json\" },\n\t\t\tbody: JSON.stringify({ pages: [{ url }] }),\n\t\t\tsignal: signal ? AbortSignal.any([AbortSignal.timeout(options.timeoutMs ?? SEARCH_TIMEOUT_MS), signal]) : AbortSignal.timeout(options.timeoutMs ?? SEARCH_TIMEOUT_MS),\n\t\t}, {\n\t\t\tallowRanges: ssrf.allowRanges,\n\t\t\ttrustEnvProxy: ssrf.trustEnvProxy,\n\t\t\tonRedirect: ({ from, to, init }) => to.origin === from.origin ? init : { ...init, headers: { \"Content-Type\": \"application/json\", Accept: \"application/json\" } },\n\t\t\t...(options.lookup ? { lookup: options.lookup } : {}),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\t\telse activityMonitor.logError(activityId, redactedMessage);\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n\tif (!response.ok) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tconst errorText = redactCredential(await response.text(), apiKey);\n\t\tthrow new Error(`Kagi Extract API error ${response.status}: ${errorText.slice(0, 300)}`);\n\t}\n\tlet rawData: unknown;\n\ttry {\n\t\trawData = await response.json();\n\t} catch (err) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`Kagi Extract API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\tconst parsed = parseExtractResponse(rawData, url);\n\tactivityMonitor.logComplete(activityId, response.status);\n\treturn parsed;\n}\n"]}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { activityMonitor } from "./activity.js";
|
|
3
|
+
import { hasCredentialSource, redactCredential, resolveCredential } from "./credential-source.js";
|
|
4
|
+
import { fetchRemoteUrl, loadFetchContentDomainPolicy, loadSsrfConfig, validateRemoteUrl } from "./ssrf-protection.js";
|
|
5
|
+
import { getWebSearchConfigPath } from "./utils.js";
|
|
6
|
+
const KAGI_SEARCH_URL = "https://kagi.com/api/v1/search";
|
|
7
|
+
const KAGI_EXTRACT_URL = "https://kagi.com/api/v1/extract";
|
|
8
|
+
const CONFIG_PATH = getWebSearchConfigPath();
|
|
9
|
+
const SEARCH_TIMEOUT_MS = 60_000;
|
|
10
|
+
let cachedConfig = null;
|
|
11
|
+
function loadConfig() {
|
|
12
|
+
if (cachedConfig)
|
|
13
|
+
return cachedConfig;
|
|
14
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
15
|
+
cachedConfig = {};
|
|
16
|
+
return cachedConfig;
|
|
17
|
+
}
|
|
18
|
+
const raw = readFileSync(CONFIG_PATH, "utf-8");
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = JSON.parse(raw);
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
25
|
+
throw new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);
|
|
26
|
+
}
|
|
27
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
28
|
+
throw new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);
|
|
29
|
+
}
|
|
30
|
+
cachedConfig = parsed;
|
|
31
|
+
return cachedConfig;
|
|
32
|
+
}
|
|
33
|
+
async function getApiKey(signal) {
|
|
34
|
+
return resolveCredential({
|
|
35
|
+
provider: "Kagi",
|
|
36
|
+
configuredValue: loadConfig().kagiApiKey,
|
|
37
|
+
environmentValue: process.env.KAGI_API_KEY,
|
|
38
|
+
signal,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
async function requireApiKey(signal) {
|
|
42
|
+
const apiKey = await getApiKey(signal);
|
|
43
|
+
if (!apiKey) {
|
|
44
|
+
throw new Error("Kagi API key not found. Either:\n" +
|
|
45
|
+
` 1. Create ${CONFIG_PATH} with { "kagiApiKey": "your-key" }\n` +
|
|
46
|
+
" 2. Set KAGI_API_KEY environment variable\n" +
|
|
47
|
+
"Create a key at https://kagi.com/settings?p=api");
|
|
48
|
+
}
|
|
49
|
+
return apiKey;
|
|
50
|
+
}
|
|
51
|
+
function normalizeCount(value) {
|
|
52
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
53
|
+
return 5;
|
|
54
|
+
return Math.max(1, Math.min(Math.floor(value), 20));
|
|
55
|
+
}
|
|
56
|
+
function errorMessage(err) {
|
|
57
|
+
return err instanceof Error ? err.message : String(err);
|
|
58
|
+
}
|
|
59
|
+
function invalidResponse(message) {
|
|
60
|
+
return new Error(`Kagi API returned invalid response: ${message}`);
|
|
61
|
+
}
|
|
62
|
+
function firstString(...values) {
|
|
63
|
+
for (const value of values) {
|
|
64
|
+
if (typeof value === "string" && value.trim())
|
|
65
|
+
return value.trim();
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
function appendSearchItems(value, results, inlineContent) {
|
|
70
|
+
if (Array.isArray(value)) {
|
|
71
|
+
for (const item of value)
|
|
72
|
+
appendSearchItems(item, results, inlineContent);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (!value || typeof value !== "object")
|
|
76
|
+
return;
|
|
77
|
+
const item = value;
|
|
78
|
+
const url = firstString(item.url, item.href, item.link);
|
|
79
|
+
if (!url)
|
|
80
|
+
return;
|
|
81
|
+
const title = firstString(item.title, item.name) ?? url;
|
|
82
|
+
const snippet = firstString(item.snippet, item.description, item.summary, item.content, item.markdown, item.text) ?? "";
|
|
83
|
+
results.push({ title, url, snippet });
|
|
84
|
+
const content = firstString(item.markdown, item.content, item.text);
|
|
85
|
+
if (content)
|
|
86
|
+
inlineContent.push({ url, title, content, error: null });
|
|
87
|
+
}
|
|
88
|
+
function parseErrors(value) {
|
|
89
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
90
|
+
return null;
|
|
91
|
+
const envelope = value;
|
|
92
|
+
const rawErrors = envelope.errors ?? envelope.error;
|
|
93
|
+
if (!Array.isArray(rawErrors))
|
|
94
|
+
return null;
|
|
95
|
+
const messages = rawErrors.map((entry) => {
|
|
96
|
+
if (!entry || typeof entry !== "object")
|
|
97
|
+
return String(entry);
|
|
98
|
+
const raw = entry;
|
|
99
|
+
return firstString(raw.message, raw.msg, raw.code) ?? JSON.stringify(raw);
|
|
100
|
+
});
|
|
101
|
+
return messages.length > 0 ? messages.join("; ") : null;
|
|
102
|
+
}
|
|
103
|
+
function parseSearchResponse(value) {
|
|
104
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
105
|
+
throw invalidResponse("expected an object envelope");
|
|
106
|
+
const message = parseErrors(value);
|
|
107
|
+
if (message)
|
|
108
|
+
throw invalidResponse(message);
|
|
109
|
+
const envelope = value;
|
|
110
|
+
const results = [];
|
|
111
|
+
const inlineContent = [];
|
|
112
|
+
const data = envelope.data;
|
|
113
|
+
const items = (typeof data === "object" && data !== null && !Array.isArray(data))
|
|
114
|
+
? data.search
|
|
115
|
+
: data;
|
|
116
|
+
appendSearchItems(items, results, inlineContent);
|
|
117
|
+
return { results, inlineContent };
|
|
118
|
+
}
|
|
119
|
+
function parseExtractResponse(value, requestedUrl) {
|
|
120
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
121
|
+
throw invalidResponse("expected extract object envelope");
|
|
122
|
+
const message = parseErrors(value);
|
|
123
|
+
if (message)
|
|
124
|
+
throw invalidResponse(message);
|
|
125
|
+
const envelope = value;
|
|
126
|
+
const candidates = Array.isArray(envelope.data) ? envelope.data : [envelope.data ?? envelope];
|
|
127
|
+
for (const candidate of candidates) {
|
|
128
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate))
|
|
129
|
+
continue;
|
|
130
|
+
const item = candidate;
|
|
131
|
+
const content = firstString(item.markdown, item.content, item.text);
|
|
132
|
+
if (!content)
|
|
133
|
+
continue;
|
|
134
|
+
return {
|
|
135
|
+
url: firstString(item.url, item.href, item.link) ?? requestedUrl,
|
|
136
|
+
title: firstString(item.title, item.name) ?? requestedUrl,
|
|
137
|
+
content,
|
|
138
|
+
error: null,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
function buildAnswer(results) {
|
|
144
|
+
return results.map((result) => result.snippet
|
|
145
|
+
? `${result.snippet}\nSource: ${result.title} (${result.url})`
|
|
146
|
+
: `Source: ${result.title} (${result.url})`).join("\n\n");
|
|
147
|
+
}
|
|
148
|
+
export function isKagiAvailable() {
|
|
149
|
+
return hasCredentialSource({ provider: "Kagi", configuredValue: loadConfig().kagiApiKey, environmentValue: process.env.KAGI_API_KEY });
|
|
150
|
+
}
|
|
151
|
+
export async function searchWithKagi(query, options = {}) {
|
|
152
|
+
const apiKey = await requireApiKey(options.signal);
|
|
153
|
+
const numResults = normalizeCount(options.numResults);
|
|
154
|
+
const activityId = activityMonitor.logStart({ type: "api", query });
|
|
155
|
+
let response;
|
|
156
|
+
try {
|
|
157
|
+
response = await fetch(KAGI_SEARCH_URL, {
|
|
158
|
+
method: "POST",
|
|
159
|
+
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", Accept: "application/json" },
|
|
160
|
+
body: JSON.stringify({ query, limit: numResults }),
|
|
161
|
+
signal: options.signal ? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS), options.signal]) : AbortSignal.timeout(SEARCH_TIMEOUT_MS),
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
const message = errorMessage(err);
|
|
166
|
+
const redactedMessage = redactCredential(message, apiKey);
|
|
167
|
+
if (redactedMessage.toLowerCase().includes("abort"))
|
|
168
|
+
activityMonitor.logComplete(activityId, 0);
|
|
169
|
+
else
|
|
170
|
+
activityMonitor.logError(activityId, redactedMessage);
|
|
171
|
+
if (redactedMessage === message)
|
|
172
|
+
throw err;
|
|
173
|
+
const redactedError = new Error(redactedMessage);
|
|
174
|
+
if (err instanceof Error)
|
|
175
|
+
redactedError.name = err.name;
|
|
176
|
+
throw redactedError;
|
|
177
|
+
}
|
|
178
|
+
if (!response.ok) {
|
|
179
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
180
|
+
const errorText = redactCredential(await response.text(), apiKey);
|
|
181
|
+
throw new Error(`Kagi API error ${response.status}: ${errorText.slice(0, 300)}`);
|
|
182
|
+
}
|
|
183
|
+
let rawData;
|
|
184
|
+
try {
|
|
185
|
+
rawData = await response.json();
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
189
|
+
throw new Error(`Kagi API returned invalid JSON: ${errorMessage(err)}`);
|
|
190
|
+
}
|
|
191
|
+
const parsed = parseSearchResponse(rawData);
|
|
192
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
193
|
+
const results = parsed.results.slice(0, numResults);
|
|
194
|
+
const mapped = { answer: buildAnswer(results), results };
|
|
195
|
+
if (options.includeContent) {
|
|
196
|
+
const urls = new Set(results.map(result => result.url));
|
|
197
|
+
const inlineContent = parsed.inlineContent.filter(content => urls.has(content.url));
|
|
198
|
+
if (inlineContent.length > 0)
|
|
199
|
+
mapped.inlineContent = inlineContent;
|
|
200
|
+
}
|
|
201
|
+
return mapped;
|
|
202
|
+
}
|
|
203
|
+
export function isKagiExtractAvailable() {
|
|
204
|
+
return isKagiAvailable();
|
|
205
|
+
}
|
|
206
|
+
export async function extractWithKagi(url, signal, options = {}) {
|
|
207
|
+
const ssrf = options.ssrf ?? loadSsrfConfig();
|
|
208
|
+
const domainPolicy = loadFetchContentDomainPolicy();
|
|
209
|
+
await validateRemoteUrl(url, {
|
|
210
|
+
allowRanges: ssrf.allowRanges,
|
|
211
|
+
trustEnvProxy: ssrf.trustEnvProxy,
|
|
212
|
+
domainPolicy,
|
|
213
|
+
...(options.lookup ? { lookup: options.lookup } : {}),
|
|
214
|
+
});
|
|
215
|
+
const apiKey = await requireApiKey(signal);
|
|
216
|
+
const activityId = activityMonitor.logStart({ type: "api", query: `kagi extract: ${url}` });
|
|
217
|
+
let response;
|
|
218
|
+
try {
|
|
219
|
+
response = await fetchRemoteUrl(KAGI_EXTRACT_URL, {
|
|
220
|
+
method: "POST",
|
|
221
|
+
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", Accept: "application/json" },
|
|
222
|
+
body: JSON.stringify({ pages: [{ url }] }),
|
|
223
|
+
signal: signal ? AbortSignal.any([AbortSignal.timeout(options.timeoutMs ?? SEARCH_TIMEOUT_MS), signal]) : AbortSignal.timeout(options.timeoutMs ?? SEARCH_TIMEOUT_MS),
|
|
224
|
+
}, {
|
|
225
|
+
allowRanges: ssrf.allowRanges,
|
|
226
|
+
trustEnvProxy: ssrf.trustEnvProxy,
|
|
227
|
+
onRedirect: ({ from, to, init }) => to.origin === from.origin ? init : { ...init, headers: { "Content-Type": "application/json", Accept: "application/json" } },
|
|
228
|
+
...(options.lookup ? { lookup: options.lookup } : {}),
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
const message = errorMessage(err);
|
|
233
|
+
const redactedMessage = redactCredential(message, apiKey);
|
|
234
|
+
if (redactedMessage.toLowerCase().includes("abort"))
|
|
235
|
+
activityMonitor.logComplete(activityId, 0);
|
|
236
|
+
else
|
|
237
|
+
activityMonitor.logError(activityId, redactedMessage);
|
|
238
|
+
if (redactedMessage === message)
|
|
239
|
+
throw err;
|
|
240
|
+
const redactedError = new Error(redactedMessage);
|
|
241
|
+
if (err instanceof Error)
|
|
242
|
+
redactedError.name = err.name;
|
|
243
|
+
throw redactedError;
|
|
244
|
+
}
|
|
245
|
+
if (!response.ok) {
|
|
246
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
247
|
+
const errorText = redactCredential(await response.text(), apiKey);
|
|
248
|
+
throw new Error(`Kagi Extract API error ${response.status}: ${errorText.slice(0, 300)}`);
|
|
249
|
+
}
|
|
250
|
+
let rawData;
|
|
251
|
+
try {
|
|
252
|
+
rawData = await response.json();
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
256
|
+
throw new Error(`Kagi Extract API returned invalid JSON: ${errorMessage(err)}`);
|
|
257
|
+
}
|
|
258
|
+
const parsed = parseExtractResponse(rawData, url);
|
|
259
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
260
|
+
return parsed;
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=kagi.js.map
|