@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,194 @@
|
|
|
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 TAVILY_API_URL = "https://api.tavily.com/search";
|
|
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, "utf-8");
|
|
17
|
+
try {
|
|
18
|
+
cachedConfig = JSON.parse(raw);
|
|
19
|
+
return cachedConfig;
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23
|
+
throw new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function getApiKey(signal) {
|
|
27
|
+
return resolveCredential({
|
|
28
|
+
provider: "Tavily",
|
|
29
|
+
configuredValue: loadConfig().tavilyApiKey,
|
|
30
|
+
environmentValue: process.env.TAVILY_API_KEY,
|
|
31
|
+
signal,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
async function requireApiKey(signal) {
|
|
35
|
+
const apiKey = await getApiKey(signal);
|
|
36
|
+
if (!apiKey) {
|
|
37
|
+
throw new Error("Tavily API key not found. Either:\n" +
|
|
38
|
+
` 1. Create ${CONFIG_PATH} with { "tavilyApiKey": "your-key" }\n` +
|
|
39
|
+
" 2. Set TAVILY_API_KEY environment variable\n" +
|
|
40
|
+
"Get a key at https://app.tavily.com/");
|
|
41
|
+
}
|
|
42
|
+
return apiKey;
|
|
43
|
+
}
|
|
44
|
+
function normalizeCount(value) {
|
|
45
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
46
|
+
return 5;
|
|
47
|
+
return Math.max(1, Math.min(Math.floor(value), 20));
|
|
48
|
+
}
|
|
49
|
+
function normalizeDomain(value) {
|
|
50
|
+
let input = value.trim().toLowerCase();
|
|
51
|
+
if (!input)
|
|
52
|
+
return null;
|
|
53
|
+
if (input.startsWith("-"))
|
|
54
|
+
input = input.slice(1).trim();
|
|
55
|
+
if (!input)
|
|
56
|
+
return null;
|
|
57
|
+
try {
|
|
58
|
+
const parsed = input.includes("://") ? new URL(input) : new URL(`https://${input}`);
|
|
59
|
+
input = parsed.hostname;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
input = input.split("/")[0]?.split(":")[0] ?? "";
|
|
63
|
+
}
|
|
64
|
+
input = input.replace(/^\.+|\.+$/g, "");
|
|
65
|
+
return /^[a-z0-9][a-z0-9.-]*\.[a-z]{2,}$/i.test(input) ? input : null;
|
|
66
|
+
}
|
|
67
|
+
function mapDomainFilter(domainFilter) {
|
|
68
|
+
if (!domainFilter?.length)
|
|
69
|
+
return {};
|
|
70
|
+
const include_domains = [];
|
|
71
|
+
const exclude_domains = [];
|
|
72
|
+
for (const raw of domainFilter) {
|
|
73
|
+
const domain = normalizeDomain(raw);
|
|
74
|
+
if (!domain)
|
|
75
|
+
continue;
|
|
76
|
+
const target = raw.trim().startsWith("-") ? exclude_domains : include_domains;
|
|
77
|
+
if (!target.includes(domain))
|
|
78
|
+
target.push(domain);
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
...(include_domains.length > 0 ? { include_domains } : {}),
|
|
82
|
+
...(exclude_domains.length > 0 ? { exclude_domains } : {}),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function requestSignal(signal) {
|
|
86
|
+
const timeout = AbortSignal.timeout(SEARCH_TIMEOUT_MS);
|
|
87
|
+
return signal ? AbortSignal.any([signal, timeout]) : timeout;
|
|
88
|
+
}
|
|
89
|
+
function errorMessage(err) {
|
|
90
|
+
return err instanceof Error ? err.message : String(err);
|
|
91
|
+
}
|
|
92
|
+
function mapResults(results, numResults) {
|
|
93
|
+
if (!Array.isArray(results))
|
|
94
|
+
return [];
|
|
95
|
+
const mapped = [];
|
|
96
|
+
for (const item of results) {
|
|
97
|
+
if (!item?.url)
|
|
98
|
+
continue;
|
|
99
|
+
mapped.push({
|
|
100
|
+
title: item.title || `Source ${mapped.length + 1}`,
|
|
101
|
+
url: item.url,
|
|
102
|
+
snippet: typeof item.content === "string" ? item.content.replace(/\s+/g, " ").trim() : "",
|
|
103
|
+
});
|
|
104
|
+
if (mapped.length >= numResults)
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
return mapped;
|
|
108
|
+
}
|
|
109
|
+
function mapInlineContent(results) {
|
|
110
|
+
if (!Array.isArray(results))
|
|
111
|
+
return [];
|
|
112
|
+
return results.flatMap((item) => {
|
|
113
|
+
if (!item?.url || typeof item.raw_content !== "string" || item.raw_content.trim().length === 0)
|
|
114
|
+
return [];
|
|
115
|
+
return [{
|
|
116
|
+
url: item.url,
|
|
117
|
+
title: item.title || "",
|
|
118
|
+
content: item.raw_content,
|
|
119
|
+
error: null,
|
|
120
|
+
}];
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
export function isTavilyAvailable() {
|
|
124
|
+
return hasCredentialSource({
|
|
125
|
+
provider: "Tavily",
|
|
126
|
+
configuredValue: loadConfig().tavilyApiKey,
|
|
127
|
+
environmentValue: process.env.TAVILY_API_KEY,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
export async function searchWithTavily(query, options = {}) {
|
|
131
|
+
const apiKey = await requireApiKey(options.signal);
|
|
132
|
+
const numResults = normalizeCount(options.numResults);
|
|
133
|
+
const body = {
|
|
134
|
+
query,
|
|
135
|
+
search_depth: "basic",
|
|
136
|
+
max_results: numResults,
|
|
137
|
+
include_answer: "basic",
|
|
138
|
+
include_raw_content: options.includeContent ? "markdown" : false,
|
|
139
|
+
...(options.recencyFilter ? { time_range: options.recencyFilter } : {}),
|
|
140
|
+
...mapDomainFilter(options.domainFilter),
|
|
141
|
+
};
|
|
142
|
+
const activityId = activityMonitor.logStart({ type: "api", query });
|
|
143
|
+
let response;
|
|
144
|
+
try {
|
|
145
|
+
response = await fetch(TAVILY_API_URL, {
|
|
146
|
+
method: "POST",
|
|
147
|
+
headers: {
|
|
148
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
149
|
+
"Content-Type": "application/json",
|
|
150
|
+
},
|
|
151
|
+
body: JSON.stringify(body),
|
|
152
|
+
signal: requestSignal(options.signal),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
const message = errorMessage(err);
|
|
157
|
+
const redactedMessage = redactCredential(message, apiKey);
|
|
158
|
+
if (redactedMessage.toLowerCase().includes("abort"))
|
|
159
|
+
activityMonitor.logComplete(activityId, 0);
|
|
160
|
+
else
|
|
161
|
+
activityMonitor.logError(activityId, redactedMessage);
|
|
162
|
+
if (redactedMessage === message)
|
|
163
|
+
throw err;
|
|
164
|
+
const redactedError = new Error(redactedMessage);
|
|
165
|
+
if (err instanceof Error)
|
|
166
|
+
redactedError.name = err.name;
|
|
167
|
+
throw redactedError;
|
|
168
|
+
}
|
|
169
|
+
if (!response.ok) {
|
|
170
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
171
|
+
const errorText = redactCredential(await response.text(), apiKey);
|
|
172
|
+
throw new Error(`Tavily API error ${response.status}: ${errorText.slice(0, 300)}`);
|
|
173
|
+
}
|
|
174
|
+
let data;
|
|
175
|
+
try {
|
|
176
|
+
data = await response.json();
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
180
|
+
throw new Error(`Tavily API returned invalid JSON: ${errorMessage(err)}`);
|
|
181
|
+
}
|
|
182
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
183
|
+
const result = {
|
|
184
|
+
answer: typeof data.answer === "string" ? data.answer : "",
|
|
185
|
+
results: mapResults(data.results, numResults),
|
|
186
|
+
};
|
|
187
|
+
if (options.includeContent) {
|
|
188
|
+
const inlineContent = mapInlineContent(data.results);
|
|
189
|
+
if (inlineContent.length > 0)
|
|
190
|
+
result.inlineContent = inlineContent;
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=tavily.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tavily.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/tavily.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst TAVILY_API_URL = \"https://api.tavily.com/search\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\n\ninterface WebSearchConfig {\n\ttavilyApiKey?: unknown;\n}\n\ninterface TavilyResult {\n\ttitle?: string;\n\turl?: string;\n\tcontent?: string;\n\traw_content?: string | null;\n}\n\ninterface TavilyResponse {\n\tanswer?: string;\n\tresults?: TavilyResult[];\n}\n\ninterface TavilySearchOptions 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, \"utf-8\");\n\ttry {\n\t\tcachedConfig = JSON.parse(raw) 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: \"Tavily\",\n\t\tconfiguredValue: loadConfig().tavilyApiKey,\n\t\tenvironmentValue: process.env.TAVILY_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\"Tavily API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"tavilyApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set TAVILY_API_KEY environment variable\\n\" +\n\t\t\t\"Get a key at https://app.tavily.com/\",\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) return null;\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): { include_domains?: string[]; exclude_domains?: string[] } {\n\tif (!domainFilter?.length) return {};\n\tconst include_domains: string[] = [];\n\tconst exclude_domains: 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(\"-\") ? exclude_domains : include_domains;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn {\n\t\t...(include_domains.length > 0 ? { include_domains } : {}),\n\t\t...(exclude_domains.length > 0 ? { exclude_domains } : {}),\n\t};\n}\n\nfunction requestSignal(signal?: AbortSignal): AbortSignal {\n\tconst timeout = AbortSignal.timeout(SEARCH_TIMEOUT_MS);\n\treturn signal ? AbortSignal.any([signal, timeout]) : timeout;\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction mapResults(results: TavilyResult[] | undefined, numResults: number): SearchResponse[\"results\"] {\n\tif (!Array.isArray(results)) return [];\n\tconst mapped: SearchResponse[\"results\"] = [];\n\tfor (const item of results) {\n\t\tif (!item?.url) continue;\n\t\tmapped.push({\n\t\t\ttitle: item.title || `Source ${mapped.length + 1}`,\n\t\t\turl: item.url,\n\t\t\tsnippet: typeof item.content === \"string\" ? item.content.replace(/\\s+/g, \" \").trim() : \"\",\n\t\t});\n\t\tif (mapped.length >= numResults) break;\n\t}\n\treturn mapped;\n}\n\nfunction mapInlineContent(results: TavilyResult[] | undefined): ExtractedContent[] {\n\tif (!Array.isArray(results)) return [];\n\treturn results.flatMap((item) => {\n\t\tif (!item?.url || typeof item.raw_content !== \"string\" || item.raw_content.trim().length === 0) return [];\n\t\treturn [{\n\t\t\turl: item.url,\n\t\t\ttitle: item.title || \"\",\n\t\t\tcontent: item.raw_content,\n\t\t\terror: null,\n\t\t}];\n\t});\n}\n\nexport function isTavilyAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"Tavily\",\n\t\tconfiguredValue: loadConfig().tavilyApiKey,\n\t\tenvironmentValue: process.env.TAVILY_API_KEY,\n\t});\n}\n\nexport async function searchWithTavily(query: string, options: TavilySearchOptions = {}): Promise<SearchResponse> {\n\tconst apiKey = await requireApiKey(options.signal);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst body: Record<string, unknown> = {\n\t\tquery,\n\t\tsearch_depth: \"basic\",\n\t\tmax_results: numResults,\n\t\tinclude_answer: \"basic\",\n\t\tinclude_raw_content: options.includeContent ? \"markdown\" : false,\n\t\t...(options.recencyFilter ? { time_range: options.recencyFilter } : {}),\n\t\t...mapDomainFilter(options.domainFilter),\n\t};\n\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(TAVILY_API_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Authorization\": `Bearer ${apiKey}`,\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify(body),\n\t\t\tsignal: requestSignal(options.signal),\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\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(`Tavily API error ${response.status}: ${errorText.slice(0, 300)}`);\n\t}\n\n\tlet data: TavilyResponse;\n\ttry {\n\t\tdata = await response.json() as TavilyResponse;\n\t} catch (err) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`Tavily API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst result: SearchResponse = {\n\t\tanswer: typeof data.answer === \"string\" ? data.answer : \"\",\n\t\tresults: mapResults(data.results, numResults),\n\t};\n\tif (options.includeContent) {\n\t\tconst inlineContent = mapInlineContent(data.results);\n\t\tif (inlineContent.length > 0) result.inlineContent = inlineContent;\n\t}\n\treturn result;\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ExtractedContent, ExtractOptions } from "./extract.ts";
|
|
2
|
+
import type { SearchOptions, SearchResponse } from "./perplexity.ts";
|
|
3
|
+
interface TinyFishSearchOptions extends SearchOptions {
|
|
4
|
+
includeContent?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function clearTinyFishConfigCache(): void;
|
|
7
|
+
export declare function isTinyFishAvailable(): boolean;
|
|
8
|
+
export declare function searchWithTinyFish(query: string, options?: TinyFishSearchOptions): Promise<SearchResponse>;
|
|
9
|
+
export declare function extractWithTinyFish(url: string, signal?: AbortSignal, options?: ExtractOptions): Promise<ExtractedContent | null>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=tinyfish.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tinyfish.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/tinyfish.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;AAoDrE,UAAU,qBAAsB,SAAQ,aAAa;IACpD,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAqBD,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAoBD,wBAAgB,mBAAmB,IAAI,OAAO,CAM7C;AAsND,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,cAAc,CAAC,CAuCpH;AAED,wBAAsB,mBAAmB,CACxC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE,cAAmB,GAC1B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA+BlC","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 { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst TINYFISH_SEARCH_URL = \"https://api.search.tinyfish.ai\";\nconst TINYFISH_FETCH_URL = \"https://api.fetch.tinyfish.ai\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\nconst FETCH_TIMEOUT_MS = 150_000;\nconst MAX_FETCH_URLS = 10;\nconst MAX_FETCH_PER_URL_TIMEOUT_MS = 110_000;\n\ninterface WebSearchConfig {\n\ttinyfishApiKey?: unknown;\n}\n\ninterface TinyFishSearchResult {\n\tposition?: number;\n\tsite_name?: string | null;\n\ttitle?: string | null;\n\tsnippet?: string | null;\n\turl?: string | null;\n\tdate?: string | null;\n\tpublisher?: string | null;\n}\n\ninterface TinyFishSearchResponse {\n\tquery?: string;\n\tresults?: TinyFishSearchResult[];\n\ttotal_results?: number;\n\tpage?: number;\n}\n\ninterface TinyFishFetchResult {\n\turl?: string;\n\tfinal_url?: string;\n\ttitle?: string | null;\n\ttext?: string | Record<string, unknown> | null;\n\tformat?: string;\n}\n\ninterface TinyFishFetchError {\n\turl?: string;\n\terror?: string;\n\tstatus?: number;\n}\n\ninterface TinyFishFetchResponse {\n\tresults?: TinyFishFetchResult[];\n\terrors?: TinyFishFetchError[];\n}\n\ninterface TinyFishSearchOptions 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, \"utf-8\");\n\ttry {\n\t\tcachedConfig = JSON.parse(raw) 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\nexport function clearTinyFishConfigCache(): void {\n\tcachedConfig = null;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string> {\n\tconst key = await resolveCredential({\n\t\tprovider: \"TinyFish\",\n\t\tconfiguredValue: loadConfig().tinyfishApiKey,\n\t\tenvironmentValue: process.env.TINYFISH_API_KEY,\n\t\tsignal,\n\t});\n\tif (!key) {\n\t\tthrow new Error(\n\t\t\t\"TinyFish API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"tinyfishApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set TINYFISH_API_KEY environment variable\\n\" +\n\t\t\t\"Get a key at https://agent.tinyfish.ai/api-keys\",\n\t\t);\n\t}\n\treturn key;\n}\n\nexport function isTinyFishAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"TinyFish\",\n\t\tconfiguredValue: loadConfig().tinyfishApiKey,\n\t\tenvironmentValue: process.env.TINYFISH_API_KEY,\n\t});\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction requestSignal(signal: AbortSignal | undefined, timeoutMs: number): AbortSignal {\n\tconst timeout = AbortSignal.timeout(timeoutMs);\n\treturn signal ? AbortSignal.any([signal, timeout]) : timeout;\n}\n\nfunction normalizeDomain(value: string): string | null {\n\tlet input = value.trim().toLowerCase();\n\tif (!input) return null;\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): { includeDomains: string[]; excludeDomains: string[] } {\n\tconst includeDomains: string[] = [];\n\tconst excludeDomains: 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(\"-\") ? excludeDomains : includeDomains;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn { includeDomains, excludeDomains };\n}\n\nfunction recencyMinutes(filter: SearchOptions[\"recencyFilter\"]): number | undefined {\n\tif (!filter) return undefined;\n\tconst minutes: Record<NonNullable<SearchOptions[\"recencyFilter\"]>, number> = {\n\t\tday: 1_440,\n\t\tweek: 10_080,\n\t\tmonth: 43_200,\n\t\tyear: 525_600,\n\t};\n\treturn minutes[filter];\n}\n\nfunction normalizeNumResults(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 buildSearchUrl(query: string, options: SearchOptions, page: number): string {\n\tconst params = new URLSearchParams({ query });\n\tconst { includeDomains, excludeDomains } = mapDomainFilter(options.domainFilter);\n\tif (includeDomains.length > 0) params.set(\"include_domains\", includeDomains.join(\",\"));\n\tif (excludeDomains.length > 0) params.set(\"exclude_domains\", excludeDomains.join(\",\"));\n\tconst recency = recencyMinutes(options.recencyFilter);\n\tif (recency !== undefined) params.set(\"recency_minutes\", String(recency));\n\tif (page > 0) params.set(\"page\", String(page));\n\treturn `${TINYFISH_SEARCH_URL}?${params.toString()}`;\n}\n\nasync function tinyFishJsonRequest<T>(\n\tlabel: \"Search\" | \"Fetch\",\n\turl: string,\n\tapiKey: string,\n\tinit: RequestInit,\n\ttimeoutMs: number,\n\tsignal?: AbortSignal,\n): Promise<T> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\t...init,\n\t\t\theaders: {\n\t\t\t\t\"X-API-Key\": apiKey,\n\t\t\t\t...(init.body ? { \"Content-Type\": \"application/json\" } : {}),\n\t\t\t\t...init.headers,\n\t\t\t},\n\t\t\tsignal: requestSignal(signal, timeoutMs),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\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\n\tconst raw = await response.text();\n\tif (!response.ok) {\n\t\tthrow new Error(`TinyFish ${label} API error ${response.status}: ${redactCredential(raw, apiKey).slice(0, 300)}`);\n\t}\n\ttry {\n\t\treturn JSON.parse(raw) as T;\n\t} catch (err) {\n\t\tthrow new Error(`TinyFish ${label} API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n}\n\nfunction mapSearchResults(results: TinyFishSearchResult[] | undefined): SearchResponse[\"results\"] {\n\tif (!Array.isArray(results)) return [];\n\treturn results.flatMap((item) => {\n\t\tif (!item || typeof item.url !== \"string\" || item.url.trim().length === 0) return [];\n\t\tconst url = item.url.trim();\n\t\treturn [{\n\t\t\ttitle: typeof item.title === \"string\" && item.title.trim() ? item.title.trim() : url,\n\t\t\turl,\n\t\t\tsnippet: typeof item.snippet === \"string\" ? item.snippet.replace(/\\s+/g, \" \").trim() : \"\",\n\t\t}];\n\t});\n}\n\nfunction deduplicateResults(results: SearchResponse[\"results\"], limit: number): SearchResponse[\"results\"] {\n\tconst seen = new Set<string>();\n\tconst unique: SearchResponse[\"results\"] = [];\n\tfor (const result of results) {\n\t\tif (seen.has(result.url)) continue;\n\t\tseen.add(result.url);\n\t\tunique.push(result);\n\t\tif (unique.length >= limit) break;\n\t}\n\treturn unique;\n}\n\nfunction buildAnswer(results: SearchResponse[\"results\"]): string {\n\treturn results.map((result) => {\n\t\tif (result.snippet) return `${result.snippet}\\nSource: ${result.title} (${result.url})`;\n\t\treturn `Source: ${result.title} (${result.url})`;\n\t}).join(\"\\n\\n\");\n}\n\nfunction fetchPerUrlTimeout(value: number | undefined): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return MAX_FETCH_PER_URL_TIMEOUT_MS;\n\treturn Math.max(1, Math.min(Math.floor(value), MAX_FETCH_PER_URL_TIMEOUT_MS));\n}\n\nfunction fetchBody(urls: string[], options: ExtractOptions = {}): Record<string, unknown> {\n\tconst body: Record<string, unknown> = {\n\t\turls,\n\t\tformat: \"markdown\",\n\t\tper_url_timeout_ms: fetchPerUrlTimeout(options.timeoutMs),\n\t};\n\tconst purpose = options.prompt?.trim();\n\tif (purpose) body.purpose = purpose.slice(0, 2_000);\n\treturn body;\n}\n\nfunction findFetchError(errors: TinyFishFetchError[] | undefined, url: string): TinyFishFetchError | undefined {\n\tif (!Array.isArray(errors)) return undefined;\n\treturn errors.find(item => item?.url === url) ?? errors[0];\n}\n\nfunction fetchResultContent(result: TinyFishFetchResult): string {\n\tif (typeof result.text === \"string\") return result.text.trim();\n\tif (result.text && typeof result.text === \"object\") return JSON.stringify(result.text, null, 2);\n\treturn \"\";\n}\n\nfunction mapFetchResult(result: TinyFishFetchResult | undefined, requestedUrl: string): ExtractedContent | null {\n\tif (!result) return null;\n\tconst content = fetchResultContent(result);\n\tif (!content) return null;\n\treturn {\n\t\turl: requestedUrl,\n\t\ttitle: typeof result.title === \"string\" ? result.title.trim() : \"\",\n\t\tcontent,\n\t\terror: null,\n\t};\n}\n\nasync function fetchBatch(\n\turls: string[],\n\tapiKey: string,\n\tsignal?: AbortSignal,\n\toptions: ExtractOptions = {},\n): Promise<TinyFishFetchResponse> {\n\treturn tinyFishJsonRequest<TinyFishFetchResponse>(\n\t\t\"Fetch\",\n\t\tTINYFISH_FETCH_URL,\n\t\tapiKey,\n\t\t{ method: \"POST\", body: JSON.stringify(fetchBody(urls, options)) },\n\t\tFETCH_TIMEOUT_MS,\n\t\tsignal,\n\t);\n}\n\nasync function fetchInlineContent(\n\turls: string[],\n\tapiKey: string,\n\tsignal?: AbortSignal,\n): Promise<ExtractedContent[]> {\n\tconst content: ExtractedContent[] = [];\n\tfor (let offset = 0; offset < urls.length; offset += MAX_FETCH_URLS) {\n\t\tconst batch = urls.slice(offset, offset + MAX_FETCH_URLS);\n\t\tconst data = await fetchBatch(batch, apiKey, signal);\n\t\tif (!Array.isArray(data.results) || !Array.isArray(data.errors)) {\n\t\t\tthrow new Error(\"TinyFish Fetch API returned an unexpected response shape\");\n\t\t}\n\t\tfor (const url of batch) {\n\t\t\tconst result = Array.isArray(data.results)\n\t\t\t\t? data.results.find(item => item?.url === url || item?.final_url === url)\n\t\t\t\t: undefined;\n\t\t\tconst mapped = mapFetchResult(result, url);\n\t\t\tif (mapped) content.push(mapped);\n\t\t}\n\t}\n\treturn content;\n}\n\nexport async function searchWithTinyFish(query: string, options: TinyFishSearchOptions = {}): Promise<SearchResponse> {\n\tconst apiKey = await getApiKey(options.signal);\n\tconst numResults = normalizeNumResults(options.numResults);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\ttry {\n\t\tconst combined: SearchResponse[\"results\"] = [];\n\t\tconst pages = numResults > 10 ? 2 : 1;\n\t\tfor (let page = 0; page < pages; page++) {\n\t\t\tconst data = await tinyFishJsonRequest<TinyFishSearchResponse>(\n\t\t\t\t\"Search\",\n\t\t\t\tbuildSearchUrl(query, options, page),\n\t\t\t\tapiKey,\n\t\t\t\t{ method: \"GET\" },\n\t\t\t\tSEARCH_TIMEOUT_MS,\n\t\t\t\toptions.signal,\n\t\t\t);\n\t\t\tif (!Array.isArray(data.results)) throw new Error(\"TinyFish Search API returned an unexpected response shape\");\n\t\t\tcombined.push(...mapSearchResults(data.results));\n\t\t\tif (data.results.length < 10) break;\n\t\t}\n\n\t\tconst results = deduplicateResults(combined, numResults);\n\t\tconst response: SearchResponse = { answer: buildAnswer(results), results };\n\t\tif (options.includeContent && results.length > 0) {\n\t\t\tconst inlineContent = await fetchInlineContent(results.map(result => result.url), apiKey, options.signal);\n\t\t\tif (inlineContent.length > 0) response.inlineContent = inlineContent;\n\t\t}\n\t\tactivityMonitor.logComplete(activityId, 200);\n\t\treturn response;\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}\n\nexport async function extractWithTinyFish(\n\turl: string,\n\tsignal?: AbortSignal,\n\toptions: ExtractOptions = {},\n): Promise<ExtractedContent | null> {\n\tconst apiKey = await getApiKey(signal);\n\tconst activityId = activityMonitor.logStart({ type: \"fetch\", url });\n\ttry {\n\t\tconst data = await fetchBatch([url], apiKey, signal, options);\n\t\tif (!Array.isArray(data.results) || !Array.isArray(data.errors)) {\n\t\t\tthrow new Error(\"TinyFish Fetch API returned an unexpected response shape\");\n\t\t}\n\t\tconst result = data.results.find(item => item?.url === url || item?.final_url === url) ?? data.results[0];\n\t\tconst mapped = mapFetchResult(result, url);\n\t\tif (mapped) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\treturn mapped;\n\t\t}\n\t\tconst fetchError = findFetchError(data.errors, url);\n\t\tif (fetchError) {\n\t\t\tconst status = typeof fetchError.status === \"number\" ? ` (HTTP ${fetchError.status})` : \"\";\n\t\t\tthrow new Error(`TinyFish Fetch failed for ${url}: ${fetchError.error || \"unknown error\"}${status}`);\n\t\t}\n\t\tactivityMonitor.logComplete(activityId, 200);\n\t\treturn null;\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}\n"]}
|
|
@@ -0,0 +1,331 @@
|
|
|
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 TINYFISH_SEARCH_URL = "https://api.search.tinyfish.ai";
|
|
6
|
+
const TINYFISH_FETCH_URL = "https://api.fetch.tinyfish.ai";
|
|
7
|
+
const CONFIG_PATH = getWebSearchConfigPath();
|
|
8
|
+
const SEARCH_TIMEOUT_MS = 60_000;
|
|
9
|
+
const FETCH_TIMEOUT_MS = 150_000;
|
|
10
|
+
const MAX_FETCH_URLS = 10;
|
|
11
|
+
const MAX_FETCH_PER_URL_TIMEOUT_MS = 110_000;
|
|
12
|
+
let cachedConfig = null;
|
|
13
|
+
function loadConfig() {
|
|
14
|
+
if (cachedConfig)
|
|
15
|
+
return cachedConfig;
|
|
16
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
17
|
+
cachedConfig = {};
|
|
18
|
+
return cachedConfig;
|
|
19
|
+
}
|
|
20
|
+
const raw = readFileSync(CONFIG_PATH, "utf-8");
|
|
21
|
+
try {
|
|
22
|
+
cachedConfig = JSON.parse(raw);
|
|
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
|
+
export function clearTinyFishConfigCache() {
|
|
31
|
+
cachedConfig = null;
|
|
32
|
+
}
|
|
33
|
+
async function getApiKey(signal) {
|
|
34
|
+
const key = await resolveCredential({
|
|
35
|
+
provider: "TinyFish",
|
|
36
|
+
configuredValue: loadConfig().tinyfishApiKey,
|
|
37
|
+
environmentValue: process.env.TINYFISH_API_KEY,
|
|
38
|
+
signal,
|
|
39
|
+
});
|
|
40
|
+
if (!key) {
|
|
41
|
+
throw new Error("TinyFish API key not found. Either:\n" +
|
|
42
|
+
` 1. Create ${CONFIG_PATH} with { "tinyfishApiKey": "your-key" }\n` +
|
|
43
|
+
" 2. Set TINYFISH_API_KEY environment variable\n" +
|
|
44
|
+
"Get a key at https://agent.tinyfish.ai/api-keys");
|
|
45
|
+
}
|
|
46
|
+
return key;
|
|
47
|
+
}
|
|
48
|
+
export function isTinyFishAvailable() {
|
|
49
|
+
return hasCredentialSource({
|
|
50
|
+
provider: "TinyFish",
|
|
51
|
+
configuredValue: loadConfig().tinyfishApiKey,
|
|
52
|
+
environmentValue: process.env.TINYFISH_API_KEY,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function errorMessage(err) {
|
|
56
|
+
return err instanceof Error ? err.message : String(err);
|
|
57
|
+
}
|
|
58
|
+
function requestSignal(signal, timeoutMs) {
|
|
59
|
+
const timeout = AbortSignal.timeout(timeoutMs);
|
|
60
|
+
return signal ? AbortSignal.any([signal, timeout]) : timeout;
|
|
61
|
+
}
|
|
62
|
+
function normalizeDomain(value) {
|
|
63
|
+
let input = value.trim().toLowerCase();
|
|
64
|
+
if (!input)
|
|
65
|
+
return null;
|
|
66
|
+
if (input.startsWith("-"))
|
|
67
|
+
input = input.slice(1).trim();
|
|
68
|
+
if (!input)
|
|
69
|
+
return null;
|
|
70
|
+
try {
|
|
71
|
+
const parsed = input.includes("://") ? new URL(input) : new URL(`https://${input}`);
|
|
72
|
+
input = parsed.hostname;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
input = input.split("/")[0]?.split(":")[0] ?? "";
|
|
76
|
+
}
|
|
77
|
+
input = input.replace(/^\.+|\.+$/g, "");
|
|
78
|
+
return /^[a-z0-9][a-z0-9.-]*\.[a-z]{2,}$/i.test(input) ? input : null;
|
|
79
|
+
}
|
|
80
|
+
function mapDomainFilter(domainFilter) {
|
|
81
|
+
const includeDomains = [];
|
|
82
|
+
const excludeDomains = [];
|
|
83
|
+
for (const raw of domainFilter ?? []) {
|
|
84
|
+
const domain = normalizeDomain(raw);
|
|
85
|
+
if (!domain)
|
|
86
|
+
continue;
|
|
87
|
+
const target = raw.trim().startsWith("-") ? excludeDomains : includeDomains;
|
|
88
|
+
if (!target.includes(domain))
|
|
89
|
+
target.push(domain);
|
|
90
|
+
}
|
|
91
|
+
return { includeDomains, excludeDomains };
|
|
92
|
+
}
|
|
93
|
+
function recencyMinutes(filter) {
|
|
94
|
+
if (!filter)
|
|
95
|
+
return undefined;
|
|
96
|
+
const minutes = {
|
|
97
|
+
day: 1_440,
|
|
98
|
+
week: 10_080,
|
|
99
|
+
month: 43_200,
|
|
100
|
+
year: 525_600,
|
|
101
|
+
};
|
|
102
|
+
return minutes[filter];
|
|
103
|
+
}
|
|
104
|
+
function normalizeNumResults(value) {
|
|
105
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
106
|
+
return 5;
|
|
107
|
+
return Math.max(1, Math.min(Math.floor(value), 20));
|
|
108
|
+
}
|
|
109
|
+
function buildSearchUrl(query, options, page) {
|
|
110
|
+
const params = new URLSearchParams({ query });
|
|
111
|
+
const { includeDomains, excludeDomains } = mapDomainFilter(options.domainFilter);
|
|
112
|
+
if (includeDomains.length > 0)
|
|
113
|
+
params.set("include_domains", includeDomains.join(","));
|
|
114
|
+
if (excludeDomains.length > 0)
|
|
115
|
+
params.set("exclude_domains", excludeDomains.join(","));
|
|
116
|
+
const recency = recencyMinutes(options.recencyFilter);
|
|
117
|
+
if (recency !== undefined)
|
|
118
|
+
params.set("recency_minutes", String(recency));
|
|
119
|
+
if (page > 0)
|
|
120
|
+
params.set("page", String(page));
|
|
121
|
+
return `${TINYFISH_SEARCH_URL}?${params.toString()}`;
|
|
122
|
+
}
|
|
123
|
+
async function tinyFishJsonRequest(label, url, apiKey, init, timeoutMs, signal) {
|
|
124
|
+
let response;
|
|
125
|
+
try {
|
|
126
|
+
response = await fetch(url, {
|
|
127
|
+
...init,
|
|
128
|
+
headers: {
|
|
129
|
+
"X-API-Key": apiKey,
|
|
130
|
+
...(init.body ? { "Content-Type": "application/json" } : {}),
|
|
131
|
+
...init.headers,
|
|
132
|
+
},
|
|
133
|
+
signal: requestSignal(signal, timeoutMs),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
const message = errorMessage(err);
|
|
138
|
+
const redactedMessage = redactCredential(message, apiKey);
|
|
139
|
+
if (redactedMessage === message)
|
|
140
|
+
throw err;
|
|
141
|
+
const redactedError = new Error(redactedMessage);
|
|
142
|
+
if (err instanceof Error)
|
|
143
|
+
redactedError.name = err.name;
|
|
144
|
+
throw redactedError;
|
|
145
|
+
}
|
|
146
|
+
const raw = await response.text();
|
|
147
|
+
if (!response.ok) {
|
|
148
|
+
throw new Error(`TinyFish ${label} API error ${response.status}: ${redactCredential(raw, apiKey).slice(0, 300)}`);
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
return JSON.parse(raw);
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
throw new Error(`TinyFish ${label} API returned invalid JSON: ${errorMessage(err)}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function mapSearchResults(results) {
|
|
158
|
+
if (!Array.isArray(results))
|
|
159
|
+
return [];
|
|
160
|
+
return results.flatMap((item) => {
|
|
161
|
+
if (!item || typeof item.url !== "string" || item.url.trim().length === 0)
|
|
162
|
+
return [];
|
|
163
|
+
const url = item.url.trim();
|
|
164
|
+
return [{
|
|
165
|
+
title: typeof item.title === "string" && item.title.trim() ? item.title.trim() : url,
|
|
166
|
+
url,
|
|
167
|
+
snippet: typeof item.snippet === "string" ? item.snippet.replace(/\s+/g, " ").trim() : "",
|
|
168
|
+
}];
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function deduplicateResults(results, limit) {
|
|
172
|
+
const seen = new Set();
|
|
173
|
+
const unique = [];
|
|
174
|
+
for (const result of results) {
|
|
175
|
+
if (seen.has(result.url))
|
|
176
|
+
continue;
|
|
177
|
+
seen.add(result.url);
|
|
178
|
+
unique.push(result);
|
|
179
|
+
if (unique.length >= limit)
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
return unique;
|
|
183
|
+
}
|
|
184
|
+
function buildAnswer(results) {
|
|
185
|
+
return results.map((result) => {
|
|
186
|
+
if (result.snippet)
|
|
187
|
+
return `${result.snippet}\nSource: ${result.title} (${result.url})`;
|
|
188
|
+
return `Source: ${result.title} (${result.url})`;
|
|
189
|
+
}).join("\n\n");
|
|
190
|
+
}
|
|
191
|
+
function fetchPerUrlTimeout(value) {
|
|
192
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
193
|
+
return MAX_FETCH_PER_URL_TIMEOUT_MS;
|
|
194
|
+
return Math.max(1, Math.min(Math.floor(value), MAX_FETCH_PER_URL_TIMEOUT_MS));
|
|
195
|
+
}
|
|
196
|
+
function fetchBody(urls, options = {}) {
|
|
197
|
+
const body = {
|
|
198
|
+
urls,
|
|
199
|
+
format: "markdown",
|
|
200
|
+
per_url_timeout_ms: fetchPerUrlTimeout(options.timeoutMs),
|
|
201
|
+
};
|
|
202
|
+
const purpose = options.prompt?.trim();
|
|
203
|
+
if (purpose)
|
|
204
|
+
body.purpose = purpose.slice(0, 2_000);
|
|
205
|
+
return body;
|
|
206
|
+
}
|
|
207
|
+
function findFetchError(errors, url) {
|
|
208
|
+
if (!Array.isArray(errors))
|
|
209
|
+
return undefined;
|
|
210
|
+
return errors.find(item => item?.url === url) ?? errors[0];
|
|
211
|
+
}
|
|
212
|
+
function fetchResultContent(result) {
|
|
213
|
+
if (typeof result.text === "string")
|
|
214
|
+
return result.text.trim();
|
|
215
|
+
if (result.text && typeof result.text === "object")
|
|
216
|
+
return JSON.stringify(result.text, null, 2);
|
|
217
|
+
return "";
|
|
218
|
+
}
|
|
219
|
+
function mapFetchResult(result, requestedUrl) {
|
|
220
|
+
if (!result)
|
|
221
|
+
return null;
|
|
222
|
+
const content = fetchResultContent(result);
|
|
223
|
+
if (!content)
|
|
224
|
+
return null;
|
|
225
|
+
return {
|
|
226
|
+
url: requestedUrl,
|
|
227
|
+
title: typeof result.title === "string" ? result.title.trim() : "",
|
|
228
|
+
content,
|
|
229
|
+
error: null,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
async function fetchBatch(urls, apiKey, signal, options = {}) {
|
|
233
|
+
return tinyFishJsonRequest("Fetch", TINYFISH_FETCH_URL, apiKey, { method: "POST", body: JSON.stringify(fetchBody(urls, options)) }, FETCH_TIMEOUT_MS, signal);
|
|
234
|
+
}
|
|
235
|
+
async function fetchInlineContent(urls, apiKey, signal) {
|
|
236
|
+
const content = [];
|
|
237
|
+
for (let offset = 0; offset < urls.length; offset += MAX_FETCH_URLS) {
|
|
238
|
+
const batch = urls.slice(offset, offset + MAX_FETCH_URLS);
|
|
239
|
+
const data = await fetchBatch(batch, apiKey, signal);
|
|
240
|
+
if (!Array.isArray(data.results) || !Array.isArray(data.errors)) {
|
|
241
|
+
throw new Error("TinyFish Fetch API returned an unexpected response shape");
|
|
242
|
+
}
|
|
243
|
+
for (const url of batch) {
|
|
244
|
+
const result = Array.isArray(data.results)
|
|
245
|
+
? data.results.find(item => item?.url === url || item?.final_url === url)
|
|
246
|
+
: undefined;
|
|
247
|
+
const mapped = mapFetchResult(result, url);
|
|
248
|
+
if (mapped)
|
|
249
|
+
content.push(mapped);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return content;
|
|
253
|
+
}
|
|
254
|
+
export async function searchWithTinyFish(query, options = {}) {
|
|
255
|
+
const apiKey = await getApiKey(options.signal);
|
|
256
|
+
const numResults = normalizeNumResults(options.numResults);
|
|
257
|
+
const activityId = activityMonitor.logStart({ type: "api", query });
|
|
258
|
+
try {
|
|
259
|
+
const combined = [];
|
|
260
|
+
const pages = numResults > 10 ? 2 : 1;
|
|
261
|
+
for (let page = 0; page < pages; page++) {
|
|
262
|
+
const data = await tinyFishJsonRequest("Search", buildSearchUrl(query, options, page), apiKey, { method: "GET" }, SEARCH_TIMEOUT_MS, options.signal);
|
|
263
|
+
if (!Array.isArray(data.results))
|
|
264
|
+
throw new Error("TinyFish Search API returned an unexpected response shape");
|
|
265
|
+
combined.push(...mapSearchResults(data.results));
|
|
266
|
+
if (data.results.length < 10)
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
const results = deduplicateResults(combined, numResults);
|
|
270
|
+
const response = { answer: buildAnswer(results), results };
|
|
271
|
+
if (options.includeContent && results.length > 0) {
|
|
272
|
+
const inlineContent = await fetchInlineContent(results.map(result => result.url), apiKey, options.signal);
|
|
273
|
+
if (inlineContent.length > 0)
|
|
274
|
+
response.inlineContent = inlineContent;
|
|
275
|
+
}
|
|
276
|
+
activityMonitor.logComplete(activityId, 200);
|
|
277
|
+
return response;
|
|
278
|
+
}
|
|
279
|
+
catch (err) {
|
|
280
|
+
const message = errorMessage(err);
|
|
281
|
+
const redactedMessage = redactCredential(message, apiKey);
|
|
282
|
+
if (redactedMessage.toLowerCase().includes("abort"))
|
|
283
|
+
activityMonitor.logComplete(activityId, 0);
|
|
284
|
+
else
|
|
285
|
+
activityMonitor.logError(activityId, redactedMessage);
|
|
286
|
+
if (redactedMessage === message)
|
|
287
|
+
throw err;
|
|
288
|
+
const redactedError = new Error(redactedMessage);
|
|
289
|
+
if (err instanceof Error)
|
|
290
|
+
redactedError.name = err.name;
|
|
291
|
+
throw redactedError;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
export async function extractWithTinyFish(url, signal, options = {}) {
|
|
295
|
+
const apiKey = await getApiKey(signal);
|
|
296
|
+
const activityId = activityMonitor.logStart({ type: "fetch", url });
|
|
297
|
+
try {
|
|
298
|
+
const data = await fetchBatch([url], apiKey, signal, options);
|
|
299
|
+
if (!Array.isArray(data.results) || !Array.isArray(data.errors)) {
|
|
300
|
+
throw new Error("TinyFish Fetch API returned an unexpected response shape");
|
|
301
|
+
}
|
|
302
|
+
const result = data.results.find(item => item?.url === url || item?.final_url === url) ?? data.results[0];
|
|
303
|
+
const mapped = mapFetchResult(result, url);
|
|
304
|
+
if (mapped) {
|
|
305
|
+
activityMonitor.logComplete(activityId, 200);
|
|
306
|
+
return mapped;
|
|
307
|
+
}
|
|
308
|
+
const fetchError = findFetchError(data.errors, url);
|
|
309
|
+
if (fetchError) {
|
|
310
|
+
const status = typeof fetchError.status === "number" ? ` (HTTP ${fetchError.status})` : "";
|
|
311
|
+
throw new Error(`TinyFish Fetch failed for ${url}: ${fetchError.error || "unknown error"}${status}`);
|
|
312
|
+
}
|
|
313
|
+
activityMonitor.logComplete(activityId, 200);
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
catch (err) {
|
|
317
|
+
const message = errorMessage(err);
|
|
318
|
+
const redactedMessage = redactCredential(message, apiKey);
|
|
319
|
+
if (redactedMessage.toLowerCase().includes("abort"))
|
|
320
|
+
activityMonitor.logComplete(activityId, 0);
|
|
321
|
+
else
|
|
322
|
+
activityMonitor.logError(activityId, redactedMessage);
|
|
323
|
+
if (redactedMessage === message)
|
|
324
|
+
throw err;
|
|
325
|
+
const redactedError = new Error(redactedMessage);
|
|
326
|
+
if (err instanceof Error)
|
|
327
|
+
redactedError.name = err.name;
|
|
328
|
+
throw redactedError;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=tinyfish.js.map
|