@humain/terminal 0.0.2 → 0.0.3-beta.1
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 +251 -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/config.d.ts.map +1 -1
- package/dist/config.js +4 -3
- package/dist/config.js.map +1 -1
- 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 +673 -0
- package/dist/humain/mcp-adapter/vendor/LICENSE +21 -0
- package/dist/humain/mcp-adapter/vendor/README.md +736 -0
- package/dist/humain/mcp-adapter/vendor/abort.ts +34 -0
- package/dist/humain/mcp-adapter/vendor/agent-dir.ts +68 -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 +230 -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 +607 -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 +16279 -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 +667 -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 +363 -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 +179 -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/request-headers-command.ts +336 -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 +1129 -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 +296 -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 +942 -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/auth-fetch.d.ts +13 -0
- package/dist/humain/web-access/vendor/auth-fetch.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/auth-fetch.js +134 -0
- package/dist/humain/web-access/vendor/auth-fetch.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 +23 -0
- package/dist/humain/web-access/vendor/chrome-cookies.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/chrome-cookies.js +522 -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 +30 -0
- package/dist/humain/web-access/vendor/curator-page.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/curator-page.js +3556 -0
- package/dist/humain/web-access/vendor/curator-page.js.map +1 -0
- package/dist/humain/web-access/vendor/curator-server.d.ts +94 -0
- package/dist/humain/web-access/vendor/curator-server.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/curator-server.js +690 -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 +48 -0
- package/dist/humain/web-access/vendor/extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/extract.js +1126 -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 +27 -0
- package/dist/humain/web-access/vendor/fetch-params.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/fetch-params.js +71 -0
- package/dist/humain/web-access/vendor/fetch-params.js.map +1 -0
- package/dist/humain/web-access/vendor/firecrawl.d.ts +19 -0
- package/dist/humain/web-access/vendor/firecrawl.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/firecrawl.js +370 -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 +832 -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 +3076 -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 +26 -0
- package/dist/humain/web-access/vendor/summary-review.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/summary-review.js +344 -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 +673 -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,370 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { activityMonitor } from "./activity.js";
|
|
3
|
+
import { redactCredential, resolveCredential } from "./credential-source.js";
|
|
4
|
+
import { loadSsrfConfig, validateRemoteUrl } from "./ssrf-protection.js";
|
|
5
|
+
import { getWebSearchConfigPath } from "./utils.js";
|
|
6
|
+
const CONFIG_PATH = getWebSearchConfigPath();
|
|
7
|
+
const DEFAULT_API_VERSION = "v2";
|
|
8
|
+
const EXTRACT_TIMEOUT_MS = 60_000;
|
|
9
|
+
const SEARCH_TIMEOUT_MS = 60_000;
|
|
10
|
+
const DEFAULT_MAX_REDIRECTS = 5;
|
|
11
|
+
const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
|
|
12
|
+
const SUPPORTED_API_VERSIONS = ["v1", "v2"];
|
|
13
|
+
let cachedConfig = null;
|
|
14
|
+
function loadConfig() {
|
|
15
|
+
if (cachedConfig)
|
|
16
|
+
return cachedConfig;
|
|
17
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
18
|
+
cachedConfig = {};
|
|
19
|
+
return cachedConfig;
|
|
20
|
+
}
|
|
21
|
+
const raw = readFileSync(CONFIG_PATH, "utf8");
|
|
22
|
+
let parsed;
|
|
23
|
+
try {
|
|
24
|
+
parsed = JSON.parse(raw);
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
28
|
+
throw new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);
|
|
29
|
+
}
|
|
30
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
31
|
+
throw new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);
|
|
32
|
+
}
|
|
33
|
+
cachedConfig = parsed;
|
|
34
|
+
return cachedConfig;
|
|
35
|
+
}
|
|
36
|
+
export function clearFirecrawlConfigCache() {
|
|
37
|
+
cachedConfig = null;
|
|
38
|
+
}
|
|
39
|
+
function normalizeBaseUrl(value) {
|
|
40
|
+
if (typeof value !== "string")
|
|
41
|
+
return null;
|
|
42
|
+
const trimmed = value.trim();
|
|
43
|
+
if (!trimmed)
|
|
44
|
+
return null;
|
|
45
|
+
let parsed;
|
|
46
|
+
try {
|
|
47
|
+
parsed = new URL(trimmed);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
throw new Error(`Invalid Firecrawl base URL in ${CONFIG_PATH}: expected an HTTP or HTTPS URL`);
|
|
51
|
+
}
|
|
52
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
53
|
+
throw new Error(`Invalid Firecrawl base URL in ${CONFIG_PATH}: expected an HTTP or HTTPS URL`);
|
|
54
|
+
}
|
|
55
|
+
if (parsed.username || parsed.password) {
|
|
56
|
+
throw new Error(`Invalid Firecrawl base URL in ${CONFIG_PATH}: URL credentials are not allowed`);
|
|
57
|
+
}
|
|
58
|
+
parsed.pathname = parsed.pathname.replace(/\/+$/, "");
|
|
59
|
+
parsed.search = "";
|
|
60
|
+
parsed.hash = "";
|
|
61
|
+
return parsed.toString().replace(/\/+$/, "");
|
|
62
|
+
}
|
|
63
|
+
function getBaseUrl() {
|
|
64
|
+
return normalizeBaseUrl(process.env.FIRECRAWL_BASE_URL) ?? normalizeBaseUrl(loadConfig().firecrawlBaseUrl);
|
|
65
|
+
}
|
|
66
|
+
function requireBaseUrl() {
|
|
67
|
+
const baseUrl = getBaseUrl();
|
|
68
|
+
if (!baseUrl) {
|
|
69
|
+
throw new Error("Firecrawl base URL not configured. Either:\n" +
|
|
70
|
+
` 1. Set firecrawlBaseUrl in ${CONFIG_PATH}\n` +
|
|
71
|
+
" 2. Set FIRECRAWL_BASE_URL environment variable");
|
|
72
|
+
}
|
|
73
|
+
return baseUrl;
|
|
74
|
+
}
|
|
75
|
+
function getApiVersion() {
|
|
76
|
+
const environmentValue = typeof process.env.FIRECRAWL_API_VERSION === "string"
|
|
77
|
+
? process.env.FIRECRAWL_API_VERSION.trim()
|
|
78
|
+
: "";
|
|
79
|
+
const raw = environmentValue || loadConfig().firecrawlApiVersion;
|
|
80
|
+
if (raw === undefined || raw === null)
|
|
81
|
+
return DEFAULT_API_VERSION;
|
|
82
|
+
if (typeof raw !== "string") {
|
|
83
|
+
throw new Error(`firecrawlApiVersion in ${CONFIG_PATH} must be a string ("v1" or "v2")`);
|
|
84
|
+
}
|
|
85
|
+
const normalized = raw.trim().toLowerCase();
|
|
86
|
+
if (!normalized)
|
|
87
|
+
return DEFAULT_API_VERSION;
|
|
88
|
+
if (!SUPPORTED_API_VERSIONS.includes(normalized)) {
|
|
89
|
+
throw new Error(`Unsupported Firecrawl API version "${raw}". Supported versions: ${SUPPORTED_API_VERSIONS.join(", ")}`);
|
|
90
|
+
}
|
|
91
|
+
return normalized;
|
|
92
|
+
}
|
|
93
|
+
function allowFreshScrape() {
|
|
94
|
+
const environmentValue = process.env.FIRECRAWL_FRESH_SCRAPE;
|
|
95
|
+
if (environmentValue !== undefined)
|
|
96
|
+
return environmentValue === "1" || environmentValue.toLowerCase() === "true";
|
|
97
|
+
const configured = loadConfig().firecrawlFreshScrape;
|
|
98
|
+
if (configured === undefined || configured === null)
|
|
99
|
+
return false;
|
|
100
|
+
if (typeof configured !== "boolean")
|
|
101
|
+
throw new Error(`firecrawlFreshScrape in ${CONFIG_PATH} must be a boolean`);
|
|
102
|
+
return configured;
|
|
103
|
+
}
|
|
104
|
+
async function getApiKey(signal) {
|
|
105
|
+
const configKey = loadConfig().firecrawlApiKey;
|
|
106
|
+
return resolveCredential({
|
|
107
|
+
provider: "Firecrawl",
|
|
108
|
+
configuredValue: configKey,
|
|
109
|
+
environmentValue: process.env.FIRECRAWL_API_KEY,
|
|
110
|
+
signal,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function requestSignal(timeoutMs, signal) {
|
|
114
|
+
const timeout = AbortSignal.timeout(timeoutMs);
|
|
115
|
+
return signal ? AbortSignal.any([timeout, signal]) : timeout;
|
|
116
|
+
}
|
|
117
|
+
function errorMessage(err) {
|
|
118
|
+
return err instanceof Error ? err.message : String(err);
|
|
119
|
+
}
|
|
120
|
+
function isAbortError(err) {
|
|
121
|
+
return errorMessage(err).toLowerCase().includes("abort");
|
|
122
|
+
}
|
|
123
|
+
function ssrfOptions(options) {
|
|
124
|
+
const config = loadSsrfConfig();
|
|
125
|
+
return {
|
|
126
|
+
allowRanges: options?.ssrf?.allowRanges ?? config.allowRanges,
|
|
127
|
+
trustEnvProxy: options?.ssrf?.trustEnvProxy ?? config.trustEnvProxy,
|
|
128
|
+
...(options?.lookup ? { lookup: options.lookup } : {}),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function withoutSensitiveHeaders(headers) {
|
|
132
|
+
const next = { ...headers };
|
|
133
|
+
delete next.Authorization;
|
|
134
|
+
delete next.authorization;
|
|
135
|
+
delete next.Cookie;
|
|
136
|
+
delete next.cookie;
|
|
137
|
+
delete next["X-API-Key"];
|
|
138
|
+
delete next["x-api-key"];
|
|
139
|
+
return next;
|
|
140
|
+
}
|
|
141
|
+
async function fetchFirecrawlApi(url, init, options) {
|
|
142
|
+
let current = await validateRemoteUrl(url, ssrfOptions(options));
|
|
143
|
+
let headers = init.headers;
|
|
144
|
+
for (let redirects = 0; redirects <= DEFAULT_MAX_REDIRECTS; redirects++) {
|
|
145
|
+
const response = await fetch(current, { ...init, headers, redirect: "manual" });
|
|
146
|
+
if (!REDIRECT_STATUSES.has(response.status))
|
|
147
|
+
return response;
|
|
148
|
+
const location = response.headers.get("location");
|
|
149
|
+
if (!location)
|
|
150
|
+
return response;
|
|
151
|
+
if (redirects === DEFAULT_MAX_REDIRECTS)
|
|
152
|
+
throw new Error(`Too many redirects fetching ${current.toString()}`);
|
|
153
|
+
const next = await validateRemoteUrl(new URL(location, current), ssrfOptions(options));
|
|
154
|
+
if (next.origin !== current.origin)
|
|
155
|
+
headers = withoutSensitiveHeaders(headers);
|
|
156
|
+
current = next;
|
|
157
|
+
}
|
|
158
|
+
throw new Error(`Too many redirects fetching ${current.toString()}`);
|
|
159
|
+
}
|
|
160
|
+
function scrapeBody(url) {
|
|
161
|
+
return {
|
|
162
|
+
url,
|
|
163
|
+
formats: ["markdown"],
|
|
164
|
+
onlyMainContent: true,
|
|
165
|
+
...(allowFreshScrape() ? {} : { lockdown: true }),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function normalizeCount(value) {
|
|
169
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
170
|
+
return 5;
|
|
171
|
+
return Math.max(1, Math.min(Math.floor(value), 20));
|
|
172
|
+
}
|
|
173
|
+
function normalizeDomain(value) {
|
|
174
|
+
let input = value.trim().toLowerCase();
|
|
175
|
+
if (!input)
|
|
176
|
+
return null;
|
|
177
|
+
if (input.startsWith("-"))
|
|
178
|
+
input = input.slice(1).trim();
|
|
179
|
+
if (!input)
|
|
180
|
+
return null;
|
|
181
|
+
try {
|
|
182
|
+
const parsed = input.includes("://") ? new URL(input) : new URL(`https://${input}`);
|
|
183
|
+
input = parsed.hostname;
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
input = input.split("/")[0]?.split(":")[0] ?? "";
|
|
187
|
+
}
|
|
188
|
+
input = input.replace(/^\.+|\.+$/g, "");
|
|
189
|
+
return /^[a-z0-9][a-z0-9.-]*\.[a-z]{2,}$/i.test(input) ? input : null;
|
|
190
|
+
}
|
|
191
|
+
function parseDomainFilter(domainFilter) {
|
|
192
|
+
const filters = { include: [], exclude: [] };
|
|
193
|
+
for (const raw of domainFilter ?? []) {
|
|
194
|
+
const domain = normalizeDomain(raw);
|
|
195
|
+
if (!domain)
|
|
196
|
+
continue;
|
|
197
|
+
const target = raw.trim().startsWith("-") ? filters.exclude : filters.include;
|
|
198
|
+
if (!target.includes(domain))
|
|
199
|
+
target.push(domain);
|
|
200
|
+
}
|
|
201
|
+
return filters;
|
|
202
|
+
}
|
|
203
|
+
function passesDomainFilters(url, filters) {
|
|
204
|
+
if (filters.include.length === 0 && filters.exclude.length === 0)
|
|
205
|
+
return true;
|
|
206
|
+
let hostname;
|
|
207
|
+
try {
|
|
208
|
+
hostname = new URL(url).hostname.toLowerCase();
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
const matches = (domain) => hostname === domain || hostname.endsWith(`.${domain}`);
|
|
214
|
+
if (filters.exclude.some(matches))
|
|
215
|
+
return false;
|
|
216
|
+
return filters.include.length === 0 || filters.include.some(matches);
|
|
217
|
+
}
|
|
218
|
+
function mapRecencyFilter(value) {
|
|
219
|
+
switch (value) {
|
|
220
|
+
case "day": return "qdr:d";
|
|
221
|
+
case "week": return "qdr:w";
|
|
222
|
+
case "month": return "qdr:m";
|
|
223
|
+
case "year": return "qdr:y";
|
|
224
|
+
default: return undefined;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function searchBody(query, options, numResults, filters) {
|
|
228
|
+
return {
|
|
229
|
+
query,
|
|
230
|
+
limit: numResults,
|
|
231
|
+
sources: ["web"],
|
|
232
|
+
...(filters.include.length > 0 ? { includeDomains: filters.include } : {}),
|
|
233
|
+
...(filters.include.length === 0 && filters.exclude.length > 0 ? { excludeDomains: filters.exclude } : {}),
|
|
234
|
+
...(mapRecencyFilter(options.recencyFilter) ? { tbs: mapRecencyFilter(options.recencyFilter) } : {}),
|
|
235
|
+
...(options.includeContent ? {
|
|
236
|
+
scrapeOptions: {
|
|
237
|
+
formats: ["markdown"],
|
|
238
|
+
onlyMainContent: true,
|
|
239
|
+
...(allowFreshScrape() ? {} : { lockdown: true }),
|
|
240
|
+
},
|
|
241
|
+
} : {}),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function firstString(...values) {
|
|
245
|
+
for (const value of values) {
|
|
246
|
+
if (typeof value === "string" && value.trim())
|
|
247
|
+
return value.trim();
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
function buildAnswer(results) {
|
|
252
|
+
return results.map((result) => {
|
|
253
|
+
if (result.snippet)
|
|
254
|
+
return `${result.snippet}\nSource: ${result.title} (${result.url})`;
|
|
255
|
+
return `Source: ${result.title} (${result.url})`;
|
|
256
|
+
}).join("\n\n");
|
|
257
|
+
}
|
|
258
|
+
function mapSearchResults(data, numResults, filters) {
|
|
259
|
+
const web = Array.isArray(data)
|
|
260
|
+
? data
|
|
261
|
+
: data && typeof data === "object" ? data.web : undefined;
|
|
262
|
+
if (!Array.isArray(web))
|
|
263
|
+
throw new Error("Firecrawl search returned an unexpected web result shape");
|
|
264
|
+
const results = [];
|
|
265
|
+
const inlineContent = [];
|
|
266
|
+
const seen = new Set();
|
|
267
|
+
for (const rawItem of web) {
|
|
268
|
+
if (!rawItem || typeof rawItem !== "object" || Array.isArray(rawItem))
|
|
269
|
+
continue;
|
|
270
|
+
const item = rawItem;
|
|
271
|
+
const url = firstString(item.url, item.metadata?.sourceURL, item.metadata?.url);
|
|
272
|
+
if (!url || seen.has(url) || !passesDomainFilters(url, filters))
|
|
273
|
+
continue;
|
|
274
|
+
seen.add(url);
|
|
275
|
+
const title = firstString(item.title, item.metadata?.title) ?? url;
|
|
276
|
+
const snippet = firstString(item.description, item.snippet, item.metadata?.description) ?? "";
|
|
277
|
+
results.push({ title, url, snippet });
|
|
278
|
+
const markdown = firstString(item.markdown);
|
|
279
|
+
if (markdown)
|
|
280
|
+
inlineContent.push({ url, title, content: markdown, error: null });
|
|
281
|
+
if (results.length >= numResults)
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
return { results, inlineContent };
|
|
285
|
+
}
|
|
286
|
+
async function firecrawlFetch(endpoint, body, signal, options, label = endpoint, activity = undefined) {
|
|
287
|
+
const baseUrl = requireBaseUrl();
|
|
288
|
+
const version = getApiVersion();
|
|
289
|
+
const apiKey = await getApiKey(signal);
|
|
290
|
+
const headers = { "Content-Type": "application/json" };
|
|
291
|
+
if (apiKey)
|
|
292
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
293
|
+
const requestUrl = `${baseUrl}/${version}/${endpoint}`;
|
|
294
|
+
const activityId = activityMonitor.logStart(activity ?? { type: "fetch", url: requestUrl });
|
|
295
|
+
try {
|
|
296
|
+
const response = await fetchFirecrawlApi(requestUrl, {
|
|
297
|
+
method: "POST",
|
|
298
|
+
headers,
|
|
299
|
+
body: JSON.stringify(body),
|
|
300
|
+
signal: requestSignal(options?.timeoutMs ?? EXTRACT_TIMEOUT_MS, signal),
|
|
301
|
+
}, options);
|
|
302
|
+
if (!response.ok) {
|
|
303
|
+
const text = await response.text().catch(() => "");
|
|
304
|
+
throw new Error(`Firecrawl ${label} error ${response.status}: ${redactCredential(text.slice(0, 300), apiKey)}`);
|
|
305
|
+
}
|
|
306
|
+
let data;
|
|
307
|
+
try {
|
|
308
|
+
data = await response.json();
|
|
309
|
+
}
|
|
310
|
+
catch (err) {
|
|
311
|
+
throw new Error(`Firecrawl ${label} returned invalid JSON: ${errorMessage(err)}`);
|
|
312
|
+
}
|
|
313
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
314
|
+
throw new Error(`Firecrawl ${label} returned an unexpected response shape`);
|
|
315
|
+
}
|
|
316
|
+
const envelope = data;
|
|
317
|
+
if (envelope.success === false) {
|
|
318
|
+
const reason = typeof envelope.error === "string" && envelope.error.trim() ? envelope.error : "unknown error";
|
|
319
|
+
throw new Error(`Firecrawl ${label} unsuccessful: ${redactCredential(reason, apiKey)}`);
|
|
320
|
+
}
|
|
321
|
+
if (envelope.success !== true) {
|
|
322
|
+
throw new Error(`Firecrawl ${label} returned an unexpected response shape`);
|
|
323
|
+
}
|
|
324
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
325
|
+
return envelope;
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
if (isAbortError(err))
|
|
329
|
+
activityMonitor.logComplete(activityId, 0);
|
|
330
|
+
else
|
|
331
|
+
activityMonitor.logError(activityId, errorMessage(err));
|
|
332
|
+
throw err;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
export function isFirecrawlAvailable() {
|
|
336
|
+
return getBaseUrl() !== null;
|
|
337
|
+
}
|
|
338
|
+
export async function searchWithFirecrawl(query, options = {}) {
|
|
339
|
+
requireBaseUrl();
|
|
340
|
+
const numResults = normalizeCount(options.numResults);
|
|
341
|
+
const filters = parseDomainFilter(options.domainFilter);
|
|
342
|
+
const envelope = await firecrawlFetch("search", searchBody(query, options, numResults, filters), options.signal, { ...options, timeoutMs: options.timeoutMs ?? SEARCH_TIMEOUT_MS }, "search", { type: "api", query });
|
|
343
|
+
const mapped = mapSearchResults(envelope.data, numResults, filters);
|
|
344
|
+
const response = { answer: buildAnswer(mapped.results), results: mapped.results };
|
|
345
|
+
if (options.includeContent && mapped.inlineContent.length > 0)
|
|
346
|
+
response.inlineContent = mapped.inlineContent;
|
|
347
|
+
return response;
|
|
348
|
+
}
|
|
349
|
+
export async function extractWithFirecrawl(url, signal, options) {
|
|
350
|
+
requireBaseUrl();
|
|
351
|
+
await validateRemoteUrl(url, ssrfOptions(options));
|
|
352
|
+
const envelope = await firecrawlFetch("scrape", scrapeBody(url), signal, options);
|
|
353
|
+
const data = envelope.data;
|
|
354
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
355
|
+
throw new Error("Firecrawl scrape returned an unexpected data shape");
|
|
356
|
+
}
|
|
357
|
+
const scrape = data;
|
|
358
|
+
if (typeof scrape.markdown !== "string") {
|
|
359
|
+
throw new Error("Firecrawl scrape returned markdown in an unexpected shape");
|
|
360
|
+
}
|
|
361
|
+
const content = scrape.markdown.trim();
|
|
362
|
+
if (!content)
|
|
363
|
+
return null;
|
|
364
|
+
const metadataTitle = scrape.metadata?.title;
|
|
365
|
+
const title = typeof metadataTitle === "string" && metadataTitle.trim()
|
|
366
|
+
? metadataTitle.trim()
|
|
367
|
+
: typeof scrape.title === "string" ? scrape.title.trim() : "";
|
|
368
|
+
return { url, title, content, error: null };
|
|
369
|
+
}
|
|
370
|
+
//# sourceMappingURL=firecrawl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firecrawl.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/firecrawl.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport { redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport type { ExtractedContent, ExtractOptions } from \"./extract.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { loadSsrfConfig, validateRemoteUrl, type Lookup } from \"./ssrf-protection.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst DEFAULT_API_VERSION = \"v2\";\nconst EXTRACT_TIMEOUT_MS = 60_000;\nconst SEARCH_TIMEOUT_MS = 60_000;\nconst DEFAULT_MAX_REDIRECTS = 5;\nconst REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);\nconst SUPPORTED_API_VERSIONS = [\"v1\", \"v2\"] as const;\ntype FirecrawlApiVersion = (typeof SUPPORTED_API_VERSIONS)[number];\n\nexport interface FirecrawlSsrfOptions {\n\tallowRanges: string[];\n\ttrustEnvProxy: boolean;\n}\n\nexport interface FirecrawlExtractOptions extends Pick<ExtractOptions, \"timeoutMs\" | \"lookup\"> {\n\tssrf?: FirecrawlSsrfOptions;\n}\n\ninterface FirecrawlSearchOptions extends SearchOptions, Pick<ExtractOptions, \"timeoutMs\" | \"lookup\"> {\n\tincludeContent?: boolean;\n\tssrf?: FirecrawlSsrfOptions;\n}\n\ninterface FirecrawlConfig {\n\tfirecrawlBaseUrl?: unknown;\n\tfirecrawlApiKey?: unknown;\n\tfirecrawlApiVersion?: unknown;\n\tfirecrawlFreshScrape?: unknown;\n}\n\ninterface FirecrawlScrapeData {\n\ttitle?: unknown;\n\tmarkdown?: unknown;\n\tmetadata?: { title?: unknown };\n}\n\ninterface FirecrawlSearchItem {\n\ttitle?: unknown;\n\tdescription?: unknown;\n\tsnippet?: unknown;\n\turl?: unknown;\n\tmarkdown?: unknown;\n\tmetadata?: {\n\t\ttitle?: unknown;\n\t\tdescription?: unknown;\n\t\tsourceURL?: unknown;\n\t\turl?: unknown;\n\t};\n}\n\ninterface DomainFilters {\n\tinclude: string[];\n\texclude: string[];\n}\n\nlet cachedConfig: FirecrawlConfig | null = null;\n\nfunction loadConfig(): FirecrawlConfig {\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, \"utf8\");\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 FirecrawlConfig;\n\treturn cachedConfig;\n}\n\nexport function clearFirecrawlConfigCache(): void {\n\tcachedConfig = null;\n}\n\nfunction normalizeBaseUrl(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst trimmed = value.trim();\n\tif (!trimmed) return null;\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(trimmed);\n\t} catch {\n\t\tthrow new Error(`Invalid Firecrawl base URL in ${CONFIG_PATH}: expected an HTTP or HTTPS URL`);\n\t}\n\tif (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n\t\tthrow new Error(`Invalid Firecrawl base URL in ${CONFIG_PATH}: expected an HTTP or HTTPS URL`);\n\t}\n\tif (parsed.username || parsed.password) {\n\t\tthrow new Error(`Invalid Firecrawl base URL in ${CONFIG_PATH}: URL credentials are not allowed`);\n\t}\n\tparsed.pathname = parsed.pathname.replace(/\\/+$/, \"\");\n\tparsed.search = \"\";\n\tparsed.hash = \"\";\n\treturn parsed.toString().replace(/\\/+$/, \"\");\n}\n\nfunction getBaseUrl(): string | null {\n\treturn normalizeBaseUrl(process.env.FIRECRAWL_BASE_URL) ?? normalizeBaseUrl(loadConfig().firecrawlBaseUrl);\n}\n\nfunction requireBaseUrl(): string {\n\tconst baseUrl = getBaseUrl();\n\tif (!baseUrl) {\n\t\tthrow new Error(\n\t\t\t\"Firecrawl base URL not configured. Either:\\n\" +\n\t\t\t` 1. Set firecrawlBaseUrl in ${CONFIG_PATH}\\n` +\n\t\t\t\" 2. Set FIRECRAWL_BASE_URL environment variable\",\n\t\t);\n\t}\n\treturn baseUrl;\n}\n\nfunction getApiVersion(): FirecrawlApiVersion {\n\tconst environmentValue = typeof process.env.FIRECRAWL_API_VERSION === \"string\"\n\t\t? process.env.FIRECRAWL_API_VERSION.trim()\n\t\t: \"\";\n\tconst raw = environmentValue || loadConfig().firecrawlApiVersion;\n\tif (raw === undefined || raw === null) return DEFAULT_API_VERSION;\n\tif (typeof raw !== \"string\") {\n\t\tthrow new Error(`firecrawlApiVersion in ${CONFIG_PATH} must be a string (\"v1\" or \"v2\")`);\n\t}\n\tconst normalized = raw.trim().toLowerCase();\n\tif (!normalized) return DEFAULT_API_VERSION;\n\tif (!SUPPORTED_API_VERSIONS.includes(normalized as FirecrawlApiVersion)) {\n\t\tthrow new Error(`Unsupported Firecrawl API version \"${raw}\". Supported versions: ${SUPPORTED_API_VERSIONS.join(\", \")}`);\n\t}\n\treturn normalized as FirecrawlApiVersion;\n}\n\nfunction allowFreshScrape(): boolean {\n\tconst environmentValue = process.env.FIRECRAWL_FRESH_SCRAPE;\n\tif (environmentValue !== undefined) return environmentValue === \"1\" || environmentValue.toLowerCase() === \"true\";\n\tconst configured = loadConfig().firecrawlFreshScrape;\n\tif (configured === undefined || configured === null) return false;\n\tif (typeof configured !== \"boolean\") throw new Error(`firecrawlFreshScrape in ${CONFIG_PATH} must be a boolean`);\n\treturn configured;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\tconst configKey = loadConfig().firecrawlApiKey;\n\treturn resolveCredential({\n\t\tprovider: \"Firecrawl\",\n\t\tconfiguredValue: configKey,\n\t\tenvironmentValue: process.env.FIRECRAWL_API_KEY,\n\t\tsignal,\n\t});\n}\n\nfunction requestSignal(timeoutMs: number, signal?: AbortSignal): AbortSignal {\n\tconst timeout = AbortSignal.timeout(timeoutMs);\n\treturn signal ? AbortSignal.any([timeout, signal]) : timeout;\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction isAbortError(err: unknown): boolean {\n\treturn errorMessage(err).toLowerCase().includes(\"abort\");\n}\n\nfunction ssrfOptions(options?: FirecrawlExtractOptions | FirecrawlSearchOptions): { lookup?: Lookup; allowRanges: string[]; trustEnvProxy: boolean } {\n\tconst config = loadSsrfConfig();\n\treturn {\n\t\tallowRanges: options?.ssrf?.allowRanges ?? config.allowRanges,\n\t\ttrustEnvProxy: options?.ssrf?.trustEnvProxy ?? config.trustEnvProxy,\n\t\t...(options?.lookup ? { lookup: options.lookup } : {}),\n\t};\n}\n\nfunction withoutSensitiveHeaders(headers: Record<string, string>): Record<string, string> {\n\tconst next = { ...headers };\n\tdelete next.Authorization;\n\tdelete next.authorization;\n\tdelete next.Cookie;\n\tdelete next.cookie;\n\tdelete next[\"X-API-Key\"];\n\tdelete next[\"x-api-key\"];\n\treturn next;\n}\n\nasync function fetchFirecrawlApi(\n\turl: string,\n\tinit: { method: string; headers: Record<string, string>; body: string; signal: AbortSignal },\n\toptions: FirecrawlExtractOptions | FirecrawlSearchOptions | undefined,\n): Promise<Response> {\n\tlet current = await validateRemoteUrl(url, ssrfOptions(options));\n\tlet headers = init.headers;\n\tfor (let redirects = 0; redirects <= DEFAULT_MAX_REDIRECTS; redirects++) {\n\t\tconst response = await fetch(current, { ...init, headers, redirect: \"manual\" });\n\t\tif (!REDIRECT_STATUSES.has(response.status)) return response;\n\n\t\tconst location = response.headers.get(\"location\");\n\t\tif (!location) return response;\n\t\tif (redirects === DEFAULT_MAX_REDIRECTS) throw new Error(`Too many redirects fetching ${current.toString()}`);\n\n\t\tconst next = await validateRemoteUrl(new URL(location, current), ssrfOptions(options));\n\t\tif (next.origin !== current.origin) headers = withoutSensitiveHeaders(headers);\n\t\tcurrent = next;\n\t}\n\tthrow new Error(`Too many redirects fetching ${current.toString()}`);\n}\n\nfunction scrapeBody(url: string): Record<string, unknown> {\n\treturn {\n\t\turl,\n\t\tformats: [\"markdown\"],\n\t\tonlyMainContent: true,\n\t\t...(allowFreshScrape() ? {} : { lockdown: true }),\n\t};\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 parseDomainFilter(domainFilter: string[] | undefined): DomainFilters {\n\tconst filters: DomainFilters = { include: [], exclude: [] };\n\tfor (const raw of domainFilter ?? []) {\n\t\tconst domain = normalizeDomain(raw);\n\t\tif (!domain) continue;\n\t\tconst target = raw.trim().startsWith(\"-\") ? filters.exclude : filters.include;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn filters;\n}\n\nfunction passesDomainFilters(url: string, filters: DomainFilters): boolean {\n\tif (filters.include.length === 0 && filters.exclude.length === 0) return true;\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) => hostname === domain || hostname.endsWith(`.${domain}`);\n\tif (filters.exclude.some(matches)) return false;\n\treturn filters.include.length === 0 || filters.include.some(matches);\n}\n\nfunction mapRecencyFilter(value: SearchOptions[\"recencyFilter\"]): string | undefined {\n\tswitch (value) {\n\t\tcase \"day\": return \"qdr:d\";\n\t\tcase \"week\": return \"qdr:w\";\n\t\tcase \"month\": return \"qdr:m\";\n\t\tcase \"year\": return \"qdr:y\";\n\t\tdefault: return undefined;\n\t}\n}\n\nfunction searchBody(query: string, options: FirecrawlSearchOptions, numResults: number, filters: DomainFilters): Record<string, unknown> {\n\treturn {\n\t\tquery,\n\t\tlimit: numResults,\n\t\tsources: [\"web\"],\n\t\t...(filters.include.length > 0 ? { includeDomains: filters.include } : {}),\n\t\t...(filters.include.length === 0 && filters.exclude.length > 0 ? { excludeDomains: filters.exclude } : {}),\n\t\t...(mapRecencyFilter(options.recencyFilter) ? { tbs: mapRecencyFilter(options.recencyFilter) } : {}),\n\t\t...(options.includeContent ? {\n\t\t\tscrapeOptions: {\n\t\t\t\tformats: [\"markdown\"],\n\t\t\t\tonlyMainContent: true,\n\t\t\t\t...(allowFreshScrape() ? {} : { lockdown: true }),\n\t\t\t},\n\t\t} : {}),\n\t};\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 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 mapSearchResults(data: unknown, numResults: number, filters: DomainFilters): {\n\tresults: SearchResponse[\"results\"];\n\tinlineContent: ExtractedContent[];\n} {\n\tconst web = Array.isArray(data)\n\t\t? data\n\t\t: data && typeof data === \"object\" ? (data as Record<string, unknown>).web : undefined;\n\tif (!Array.isArray(web)) throw new Error(\"Firecrawl search returned an unexpected web result shape\");\n\tconst results: SearchResponse[\"results\"] = [];\n\tconst inlineContent: ExtractedContent[] = [];\n\tconst seen = new Set<string>();\n\tfor (const rawItem of web) {\n\t\tif (!rawItem || typeof rawItem !== \"object\" || Array.isArray(rawItem)) continue;\n\t\tconst item = rawItem as FirecrawlSearchItem;\n\t\tconst url = firstString(item.url, item.metadata?.sourceURL, item.metadata?.url);\n\t\tif (!url || seen.has(url) || !passesDomainFilters(url, filters)) continue;\n\t\tseen.add(url);\n\t\tconst title = firstString(item.title, item.metadata?.title) ?? url;\n\t\tconst snippet = firstString(item.description, item.snippet, item.metadata?.description) ?? \"\";\n\t\tresults.push({ title, url, snippet });\n\t\tconst markdown = firstString(item.markdown);\n\t\tif (markdown) inlineContent.push({ url, title, content: markdown, error: null });\n\t\tif (results.length >= numResults) break;\n\t}\n\treturn { results, inlineContent };\n}\n\nasync function firecrawlFetch(\n\tendpoint: string,\n\tbody: Record<string, unknown>,\n\tsignal: AbortSignal | undefined,\n\toptions: FirecrawlExtractOptions | FirecrawlSearchOptions | undefined,\n\tlabel = endpoint,\n\tactivity: { type: \"api\"; query: string } | { type: \"fetch\"; url: string } | undefined = undefined,\n): Promise<Record<string, unknown>> {\n\tconst baseUrl = requireBaseUrl();\n\tconst version = getApiVersion();\n\tconst apiKey = await getApiKey(signal);\n\tconst headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n\tif (apiKey) headers.Authorization = `Bearer ${apiKey}`;\n\tconst requestUrl = `${baseUrl}/${version}/${endpoint}`;\n\tconst activityId = activityMonitor.logStart(activity ?? { type: \"fetch\", url: requestUrl });\n\ttry {\n\t\tconst response = await fetchFirecrawlApi(requestUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders,\n\t\t\tbody: JSON.stringify(body),\n\t\t\tsignal: requestSignal(options?.timeoutMs ?? EXTRACT_TIMEOUT_MS, signal),\n\t\t}, options);\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text().catch(() => \"\");\n\t\t\tthrow new Error(`Firecrawl ${label} error ${response.status}: ${redactCredential(text.slice(0, 300), apiKey)}`);\n\t\t}\n\t\tlet data: unknown;\n\t\ttry {\n\t\t\tdata = await response.json();\n\t\t} catch (err) {\n\t\t\tthrow new Error(`Firecrawl ${label} returned invalid JSON: ${errorMessage(err)}`);\n\t\t}\n\t\tif (!data || typeof data !== \"object\" || Array.isArray(data)) {\n\t\t\tthrow new Error(`Firecrawl ${label} returned an unexpected response shape`);\n\t\t}\n\t\tconst envelope = data as Record<string, unknown>;\n\t\tif (envelope.success === false) {\n\t\t\tconst reason = typeof envelope.error === \"string\" && envelope.error.trim() ? envelope.error : \"unknown error\";\n\t\t\tthrow new Error(`Firecrawl ${label} unsuccessful: ${redactCredential(reason, apiKey)}`);\n\t\t}\n\t\tif (envelope.success !== true) {\n\t\t\tthrow new Error(`Firecrawl ${label} returned an unexpected response shape`);\n\t\t}\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\treturn envelope;\n\t} catch (err) {\n\t\tif (isAbortError(err)) activityMonitor.logComplete(activityId, 0);\n\t\telse activityMonitor.logError(activityId, errorMessage(err));\n\t\tthrow err;\n\t}\n}\n\nexport function isFirecrawlAvailable(): boolean {\n\treturn getBaseUrl() !== null;\n}\n\nexport async function searchWithFirecrawl(query: string, options: FirecrawlSearchOptions = {}): Promise<SearchResponse> {\n\trequireBaseUrl();\n\tconst numResults = normalizeCount(options.numResults);\n\tconst filters = parseDomainFilter(options.domainFilter);\n\tconst envelope = await firecrawlFetch(\n\t\t\"search\",\n\t\tsearchBody(query, options, numResults, filters),\n\t\toptions.signal,\n\t\t{ ...options, timeoutMs: options.timeoutMs ?? SEARCH_TIMEOUT_MS },\n\t\t\"search\",\n\t\t{ type: \"api\", query },\n\t);\n\tconst mapped = mapSearchResults(envelope.data, numResults, filters);\n\tconst response: SearchResponse = { answer: buildAnswer(mapped.results), results: mapped.results };\n\tif (options.includeContent && mapped.inlineContent.length > 0) response.inlineContent = mapped.inlineContent;\n\treturn response;\n}\n\nexport async function extractWithFirecrawl(\n\turl: string,\n\tsignal?: AbortSignal,\n\toptions?: FirecrawlExtractOptions,\n): Promise<ExtractedContent | null> {\n\trequireBaseUrl();\n\tawait validateRemoteUrl(url, ssrfOptions(options));\n\tconst envelope = await firecrawlFetch(\"scrape\", scrapeBody(url), signal, options);\n\tconst data = envelope.data;\n\tif (!data || typeof data !== \"object\" || Array.isArray(data)) {\n\t\tthrow new Error(\"Firecrawl scrape returned an unexpected data shape\");\n\t}\n\tconst scrape = data as FirecrawlScrapeData;\n\tif (typeof scrape.markdown !== \"string\") {\n\t\tthrow new Error(\"Firecrawl scrape returned markdown in an unexpected shape\");\n\t}\n\tconst content = scrape.markdown.trim();\n\tif (!content) return null;\n\tconst metadataTitle = scrape.metadata?.title;\n\tconst title = typeof metadataTitle === \"string\" && metadataTitle.trim()\n\t\t? metadataTitle.trim()\n\t\t: typeof scrape.title === \"string\" ? scrape.title.trim() : \"\";\n\treturn { url, title, content, error: null };\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare const API_BASE = "https://generativelanguage.googleapis.com/v1beta";
|
|
2
|
+
export declare const DEFAULT_MODEL = "gemini-3.6-flash";
|
|
3
|
+
export declare function getApiKey(signal?: AbortSignal): Promise<string | null>;
|
|
4
|
+
export declare function getApiHost(): string;
|
|
5
|
+
export declare function getVersionedApiBase(): string;
|
|
6
|
+
export declare function getUploadBase(): string;
|
|
7
|
+
export declare function getCloudflareApiKey(): string | null;
|
|
8
|
+
export declare function isGatewayConfigured(): boolean;
|
|
9
|
+
export declare function buildAuthHeaders(apiKey?: string | null, cloudflareApiKey?: string | null): Record<string, string>;
|
|
10
|
+
export declare function redactGeminiApiResponse(response: Response, text: string, apiKey?: string | null): string;
|
|
11
|
+
export declare function fetchGeminiApi(url: string | URL, init?: RequestInit, apiKey?: string | null): Promise<Response>;
|
|
12
|
+
export declare function isGeminiApiAvailable(): boolean;
|
|
13
|
+
export interface GeminiApiOptions {
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
model?: string;
|
|
16
|
+
mimeType?: string;
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface GeminiGenerateContentResult {
|
|
21
|
+
text: string;
|
|
22
|
+
finishReason?: string;
|
|
23
|
+
blockReason?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function queryGeminiApiWithInlineData(prompt: string, data: string, mimeType: string, options?: GeminiApiOptions): Promise<GeminiGenerateContentResult>;
|
|
26
|
+
export declare function queryGeminiApiWithVideo(prompt: string, videoUri: string, options?: GeminiApiOptions): Promise<string>;
|
|
27
|
+
//# sourceMappingURL=gemini-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-api.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/gemini-api.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,QAAQ,qDAAuC,CAAC;AAE7D,eAAO,MAAM,aAAa,qBAAqB,CAAC;AAgDhD,wBAAsB,SAAS,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO5E;AAED,wBAAgB,UAAU,IAAI,MAAM,CAMnC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAeD,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAEnD;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAM7C;AAED,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,MAAM,GAAG,IAAW,EAAE,gBAAgB,GAAE,MAAM,GAAG,IAAkC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGpJ;AAWD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGxG;AAED,wBAAsB,cAAc,CACnC,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,IAAI,GAAE,WAAgB,EACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,QAAQ,CAAC,CAkCnB;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAM9C;AAED,MAAM,WAAW,gBAAgB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,2BAA2B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,4BAA4B,CACjD,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC5B,OAAO,CAAC,2BAA2B,CAAC,CAiDtC;AAED,wBAAsB,uBAAuB,CAC5C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAiDjB","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst DEFAULT_API_HOST = \"https://generativelanguage.googleapis.com\";\nconst API_VERSION = \"v1beta\";\nexport const API_BASE = `${DEFAULT_API_HOST}/${API_VERSION}`;\nconst CONFIG_PATH = getWebSearchConfigPath();\nexport const DEFAULT_MODEL = \"gemini-3.6-flash\";\n\ninterface GeminiApiConfig {\n\tgeminiApiKey?: unknown;\n\tgeminiBaseUrl?: unknown;\n\tcloudflareApiKey?: unknown;\n}\n\nlet cachedConfig: GeminiApiConfig | null = null;\n\nfunction loadConfig(): GeminiApiConfig {\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 GeminiApiConfig;\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\nfunction withTimeout(signal: AbortSignal | undefined, timeoutMs: number): AbortSignal {\n\tconst timeout = AbortSignal.timeout(timeoutMs);\n\treturn signal ? AbortSignal.any([signal, timeout]) : timeout;\n}\n\nfunction normalizeApiKey(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst normalized = value.trim();\n\treturn normalized.length > 0 ? normalized : null;\n}\n\nfunction normalizeBaseUrl(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst normalized = value.trim().replace(/\\/+$/, \"\");\n\treturn normalized.length > 0 ? normalized : null;\n}\n\nfunction isCloudflareGateway(): boolean {\n\treturn getApiHost().includes(\"gateway.ai.cloudflare.com\");\n}\n\nexport async function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"Gemini\",\n\t\tconfiguredValue: loadConfig().geminiApiKey,\n\t\tenvironmentValue: process.env.GEMINI_API_KEY,\n\t\tsignal,\n\t});\n}\n\nexport function getApiHost(): string {\n\treturn (\n\t\tnormalizeBaseUrl(process.env.GOOGLE_GEMINI_BASE_URL) ??\n\t\tnormalizeBaseUrl(loadConfig().geminiBaseUrl) ??\n\t\tDEFAULT_API_HOST\n\t);\n}\n\nexport function getVersionedApiBase(): string {\n\treturn `${getApiHost()}/${API_VERSION}`;\n}\n\nexport function getUploadBase(): string {\n\treturn `${getApiHost()}/upload/${API_VERSION}`;\n}\n\nfunction getLegacyCloudflareApiKey(): string | null {\n\treturn normalizeApiKey(process.env.CLOUDFLARE_API_KEY) ?? normalizeApiKey(loadConfig().cloudflareApiKey);\n}\n\nasync function resolveCloudflareApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"Cloudflare\",\n\t\tconfiguredValue: loadConfig().cloudflareApiKey,\n\t\tenvironmentValue: process.env.CLOUDFLARE_API_KEY,\n\t\tsignal,\n\t});\n}\n\nexport function getCloudflareApiKey(): string | null {\n\treturn getLegacyCloudflareApiKey();\n}\n\nexport function isGatewayConfigured(): boolean {\n\treturn isCloudflareGateway() && hasCredentialSource({\n\t\tprovider: \"Cloudflare\",\n\t\tconfiguredValue: loadConfig().cloudflareApiKey,\n\t\tenvironmentValue: process.env.CLOUDFLARE_API_KEY,\n\t});\n}\n\nexport function buildAuthHeaders(apiKey: string | null = null, cloudflareApiKey: string | null = getLegacyCloudflareApiKey()): Record<string, string> {\n\tif (!isCloudflareGateway()) return apiKey ? { \"x-goog-api-key\": apiKey } : {};\n\treturn cloudflareApiKey ? { \"cf-aig-authorization\": `Bearer ${cloudflareApiKey}` } : {};\n}\n\nfunction redactGeminiCredentials(text: string, apiKey: string | null | undefined, cloudflareApiKey: string | null | undefined): string {\n\treturn redactCredential(redactCredential(text, apiKey), cloudflareApiKey);\n}\n\nconst responseCredentials = new WeakMap<Response, {\n\tapiKey: string | null | undefined;\n\tcloudflareApiKey: string | null | undefined;\n}>();\n\nexport function redactGeminiApiResponse(response: Response, text: string, apiKey?: string | null): string {\n\tconst credentials = responseCredentials.get(response);\n\treturn redactGeminiCredentials(text, credentials?.apiKey ?? apiKey, credentials?.cloudflareApiKey);\n}\n\nexport async function fetchGeminiApi(\n\turl: string | URL,\n\tinit: RequestInit = {},\n\tapiKey?: string | null,\n): Promise<Response> {\n\tconst parsedUrl = new URL(url);\n\tfor (const name of parsedUrl.searchParams.keys()) {\n\t\tif ([\"key\", \"api_key\"].includes(name.toLowerCase())) {\n\t\t\tthrow new Error(\"Gemini API credential query parameters are not allowed\");\n\t\t}\n\t}\n\tconst resolvedApiKey = apiKey === undefined ? await getApiKey(init.signal ?? undefined) : apiKey;\n\tconst cloudflareApiKey = isCloudflareGateway() ? await resolveCloudflareApiKey(init.signal ?? undefined) : null;\n\tconst allowedOrigins = new Set([\n\t\tnew URL(getApiHost()).origin,\n\t\tnew URL(DEFAULT_API_HOST).origin,\n\t]);\n\tif ((resolvedApiKey || isGatewayConfigured()) && !allowedOrigins.has(parsedUrl.origin)) {\n\t\tthrow new Error(\"Gemini API request host is not allowed\");\n\t}\n\tconst headers = new Headers(init.headers);\n\theaders.delete(\"x-goog-api-key\");\n\theaders.delete(\"cf-aig-authorization\");\n\tfor (const [name, value] of Object.entries(buildAuthHeaders(resolvedApiKey, cloudflareApiKey))) {\n\t\theaders.set(name, value);\n\t}\n\ttry {\n\t\tconst response = await fetch(parsedUrl, { ...init, headers });\n\t\tresponseCredentials.set(response, { apiKey: resolvedApiKey, cloudflareApiKey });\n\t\treturn response;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst redactedMessage = redactGeminiCredentials(message, resolvedApiKey, cloudflareApiKey);\n\t\tif (redactedMessage === message) throw error;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (error instanceof Error) redactedError.name = error.name;\n\t\tthrow redactedError;\n\t}\n}\n\nexport function isGeminiApiAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"Gemini\",\n\t\tconfiguredValue: loadConfig().geminiApiKey,\n\t\tenvironmentValue: process.env.GEMINI_API_KEY,\n\t}) || isGatewayConfigured();\n}\n\nexport interface GeminiApiOptions {\n\tapiKey?: string;\n\tmodel?: string;\n\tmimeType?: string;\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n}\n\nexport interface GeminiGenerateContentResult {\n\ttext: string;\n\tfinishReason?: string;\n\tblockReason?: string;\n}\n\nexport async function queryGeminiApiWithInlineData(\n\tprompt: string,\n\tdata: string,\n\tmimeType: string,\n\toptions: GeminiApiOptions = {},\n): Promise<GeminiGenerateContentResult> {\n\tconst signal = withTimeout(options.signal, options.timeoutMs ?? 120000);\n\tconst apiKey = options.apiKey ?? await getApiKey(signal);\n\tif (!apiKey && !isGatewayConfigured()) {\n\t\tthrow new Error(\n\t\t\t\"Gemini API not configured. Either:\\n\" +\n\t\t\t` 1. Configure geminiApiKey in ${CONFIG_PATH} or set GEMINI_API_KEY\\n` +\n\t\t\t\" 2. Set GOOGLE_GEMINI_BASE_URL + CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing\"\n\t\t);\n\t}\n\n\tconst model = options.model ?? DEFAULT_MODEL;\n\tconst url = `${getVersionedApiBase()}/models/${model}:generateContent`;\n\tconst body = {\n\t\tcontents: [\n\t\t\t{\n\t\t\t\trole: \"user\",\n\t\t\t\tparts: [\n\t\t\t\t\t{ inlineData: { mimeType, data } },\n\t\t\t\t\t{ text: prompt },\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tconst res = await fetchGeminiApi(url, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\tbody: JSON.stringify(body),\n\t\tsignal,\n\t}, apiKey);\n\n\tif (!res.ok) {\n\t\tconst errorText = redactGeminiApiResponse(res, await res.text(), apiKey);\n\t\tthrow new Error(`Gemini API error ${res.status}: ${errorText.slice(0, 300)}`);\n\t}\n\n\tconst response = (await res.json()) as GenerateContentResponse;\n\tconst candidate = response.candidates?.[0];\n\tconst text = candidate?.content?.parts\n\t\t?.map((part) => part.text)\n\t\t.filter((part): part is string => typeof part === \"string\" && part.length > 0)\n\t\t.join(\"\\n\") ?? \"\";\n\n\treturn {\n\t\ttext,\n\t\t...(candidate?.finishReason ? { finishReason: candidate.finishReason } : {}),\n\t\t...(response.promptFeedback?.blockReason ? { blockReason: response.promptFeedback.blockReason } : {}),\n\t};\n}\n\nexport async function queryGeminiApiWithVideo(\n\tprompt: string,\n\tvideoUri: string,\n\toptions: GeminiApiOptions = {},\n): Promise<string> {\n\tconst signal = withTimeout(options.signal, options.timeoutMs ?? 120000);\n\tconst apiKey = options.apiKey ?? await getApiKey(signal);\n\tif (!apiKey && !isGatewayConfigured()) {\n\t\tthrow new Error(\n\t\t\t\"Gemini API not configured. Either:\\n\" +\n\t\t\t` 1. Configure geminiApiKey in ${CONFIG_PATH} or set GEMINI_API_KEY\\n` +\n\t\t\t\" 2. Set GOOGLE_GEMINI_BASE_URL + CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing\"\n\t\t);\n\t}\n\n\tconst model = options.model ?? DEFAULT_MODEL;\n\tconst url = `${getVersionedApiBase()}/models/${model}:generateContent`;\n\n\tconst fileData: Record<string, string> = { fileUri: videoUri };\n\tif (options.mimeType) fileData.mimeType = options.mimeType;\n\n\tconst body = {\n\t\tcontents: [\n\t\t\t{\n\t\t\t\trole: \"user\",\n\t\t\t\tparts: [\n\t\t\t\t\t{ fileData },\n\t\t\t\t\t{ text: prompt },\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tconst res = await fetchGeminiApi(url, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\tbody: JSON.stringify(body),\n\t\tsignal,\n\t}, apiKey);\n\n\tif (!res.ok) {\n\t\tconst errorText = redactGeminiApiResponse(res, await res.text(), apiKey);\n\t\tthrow new Error(`Gemini API error ${res.status}: ${errorText.slice(0, 300)}`);\n\t}\n\n\tconst data = (await res.json()) as GenerateContentResponse;\n\tconst text = data.candidates?.[0]?.content?.parts\n\t\t?.map((p) => p.text)\n\t\t.filter(Boolean)\n\t\t.join(\"\\n\");\n\n\tif (!text) throw new Error(\"Gemini API returned empty response\");\n\treturn text;\n}\n\ninterface GenerateContentResponse {\n\tcandidates?: Array<{\n\t\tcontent?: {\n\t\t\tparts?: Array<{ text?: string }>;\n\t\t};\n\t\tfinishReason?: string;\n\t}>;\n\tpromptFeedback?: {\n\t\tblockReason?: string;\n\t};\n}\n"]}
|