@humain/terminal 0.0.3-beta.3 → 0.0.4-beta.2
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 +30 -0
- package/README.md +1 -0
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.js.map +1 -1
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-check.d.ts.map +1 -1
- package/dist/cli/auth-check.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js.map +1 -1
- package/dist/cli/experimental/auth.d.ts.map +1 -1
- package/dist/cli/experimental/auth.js.map +1 -1
- package/dist/cli/experimental/cli.d.ts.map +1 -1
- package/dist/cli/experimental/command-options.d.ts.map +1 -1
- package/dist/cli/experimental/command-options.js.map +1 -1
- package/dist/cli/experimental/command.d.ts.map +1 -1
- package/dist/cli/experimental/command.js +2 -5
- package/dist/cli/experimental/command.js.map +1 -1
- package/dist/cli/experimental/commands/client.d.ts.map +1 -1
- package/dist/cli/experimental/commands/client.js.map +1 -1
- package/dist/cli/experimental/commands/pi.d.ts.map +1 -1
- package/dist/cli/experimental/commands/pi.js.map +1 -1
- package/dist/cli/experimental/commands/server.d.ts.map +1 -1
- package/dist/cli/experimental/commands/server.js.map +1 -1
- package/dist/cli/experimental/transport-address.d.ts.map +1 -1
- package/dist/cli/experimental/transport-address.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/initial-message.d.ts +1 -1
- package/dist/cli/initial-message.d.ts.map +1 -1
- package/dist/cli/initial-message.js.map +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/project-trust.d.ts.map +1 -1
- package/dist/cli/project-trust.js.map +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/remote-session.d.ts.map +1 -1
- package/dist/client/remote-session.js.map +1 -1
- package/dist/client/transcript.d.ts.map +1 -1
- package/dist/client/transcript.js +1 -1
- package/dist/client/transcript.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +0 -8
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +36 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +107 -129
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -8
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/diagnostics.d.ts.map +1 -1
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/experimental.d.ts +4 -0
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +4 -0
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
- package/dist/core/export-html/ansi-to-html.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +22 -30
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +4 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +17 -18
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/keybindings.d.ts +24 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +0 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-config.d.ts +5 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +1 -2
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +0 -1
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +15 -25
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +3 -4
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +0 -7
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/radius.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +0 -44
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js +1 -2
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts +5 -3
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +3 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js +0 -1
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/session-manager.d.ts +4 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +55 -35
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +19 -17
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +10 -5
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +2 -0
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +2 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +9 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +12 -18
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +2 -0
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/subagent.d.ts +82 -0
- package/dist/core/tools/subagent.d.ts.map +1 -0
- package/dist/core/tools/subagent.js +980 -0
- package/dist/core/tools/subagent.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +2 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +0 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js.map +1 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js +0 -2
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/huggingface.d.ts.map +1 -1
- package/dist/extensions/llama/huggingface.js +0 -2
- package/dist/extensions/llama/huggingface.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/extensions/llama/ui.d.ts.map +1 -1
- package/dist/extensions/llama/ui.js +12 -28
- package/dist/extensions/llama/ui.js.map +1 -1
- package/dist/humain/agent-execution-protocol.d.ts.map +1 -1
- package/dist/humain/agent-execution-protocol.js.map +1 -1
- package/dist/humain/agent-execution-runtime.d.ts.map +1 -1
- package/dist/humain/agent-execution-runtime.js.map +1 -1
- package/dist/humain/bedrock-provider/vendor/index.bundle.mjs +127 -7
- package/dist/humain/brand-logo.d.ts.map +1 -1
- package/dist/humain/index.d.ts.map +1 -1
- package/dist/humain/index.js.map +1 -1
- package/dist/humain/legacy-workflow-tiers.d.ts.map +1 -1
- package/dist/humain/legacy-workflow-tiers.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/CHANGELOG.md +36 -0
- package/dist/humain/mcp-adapter/vendor/README.md +47 -5
- package/dist/humain/mcp-adapter/vendor/cli.js +163 -1
- package/dist/humain/mcp-adapter/vendor/commands.ts +128 -22
- package/dist/humain/mcp-adapter/vendor/config.ts +25 -7
- package/dist/humain/mcp-adapter/vendor/direct-tools.ts +5 -4
- package/dist/humain/mcp-adapter/vendor/index.bundle.mjs +1663 -458
- package/dist/humain/mcp-adapter/vendor/index.ts +219 -32
- package/dist/humain/mcp-adapter/vendor/init.ts +36 -4
- package/dist/humain/mcp-adapter/vendor/lifecycle.ts +315 -24
- package/dist/humain/mcp-adapter/vendor/mcp-auth-flow.ts +39 -6
- package/dist/humain/mcp-adapter/vendor/mcp-bearer-store.ts +387 -0
- package/dist/humain/mcp-adapter/vendor/mcp-callback-server.ts +27 -3
- package/dist/humain/mcp-adapter/vendor/mcp-code.ts +4 -0
- package/dist/humain/mcp-adapter/vendor/mcp-panel.ts +42 -13
- package/dist/humain/mcp-adapter/vendor/metadata-cache.ts +32 -21
- package/dist/humain/mcp-adapter/vendor/package-mcp-loader.ts +168 -0
- package/dist/humain/mcp-adapter/vendor/package.json +179 -177
- package/dist/humain/mcp-adapter/vendor/proxy-modes.ts +5 -4
- package/dist/humain/mcp-adapter/vendor/request-headers-command.ts +31 -37
- package/dist/humain/mcp-adapter/vendor/search-ranking.ts +92 -22
- package/dist/humain/mcp-adapter/vendor/server-manager.ts +140 -2
- package/dist/humain/mcp-adapter/vendor/session-recovery.ts +7 -0
- package/dist/humain/mcp-adapter/vendor/tool-approval.ts +15 -2
- package/dist/humain/mcp-adapter/vendor/tool-result-renderer.ts +44 -4
- package/dist/humain/mcp-adapter/vendor/types.ts +2 -0
- package/dist/humain/mcp-adapter/vendor/ui-server.ts +18 -16
- package/dist/humain/mcp-adapter/vendor/utils.ts +70 -0
- package/dist/humain/mcp-adapter.d.ts.map +1 -1
- package/dist/humain/mcp-adapter.js.map +1 -1
- package/dist/humain/pi-agent-execution-host.d.ts.map +1 -1
- package/dist/humain/pi-agent-execution-host.js.map +1 -1
- package/dist/humain/web-access/host.d.ts.map +1 -1
- package/dist/humain/web-access/index.d.ts.map +1 -1
- package/dist/humain/web-access/index.js.map +1 -1
- package/dist/humain/web-access/vendor/activity.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/activity.js +7 -5
- package/dist/humain/web-access/vendor/activity.js.map +1 -1
- package/dist/humain/web-access/vendor/anysearch.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/anysearch.js +3 -2
- package/dist/humain/web-access/vendor/anysearch.js.map +1 -1
- package/dist/humain/web-access/vendor/auth-fetch.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/auth-fetch.js.map +1 -1
- package/dist/humain/web-access/vendor/bocha.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/bocha.js.map +1 -1
- package/dist/humain/web-access/vendor/brave.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/brave.js +14 -4
- package/dist/humain/web-access/vendor/brave.js.map +1 -1
- package/dist/humain/web-access/vendor/brightdata-unlocker.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/brightdata-unlocker.js.map +1 -1
- package/dist/humain/web-access/vendor/brightdata.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/brightdata.js.map +1 -1
- package/dist/humain/web-access/vendor/chrome-cookies.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/chrome-cookies.js +92 -14
- package/dist/humain/web-access/vendor/chrome-cookies.js.map +1 -1
- package/dist/humain/web-access/vendor/content-find.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/content-find.js.map +1 -1
- package/dist/humain/web-access/vendor/credential-source.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/credential-source.js +0 -2
- package/dist/humain/web-access/vendor/credential-source.js.map +1 -1
- package/dist/humain/web-access/vendor/curator-page.d.ts +3 -0
- package/dist/humain/web-access/vendor/curator-page.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/curator-page.js +4 -1
- package/dist/humain/web-access/vendor/curator-page.js.map +1 -1
- package/dist/humain/web-access/vendor/curator-server.d.ts +3 -0
- package/dist/humain/web-access/vendor/curator-server.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/curator-server.js +6 -0
- package/dist/humain/web-access/vendor/curator-server.js.map +1 -1
- package/dist/humain/web-access/vendor/data-uri-sanitize.d.ts +21 -0
- package/dist/humain/web-access/vendor/data-uri-sanitize.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/data-uri-sanitize.js +373 -0
- package/dist/humain/web-access/vendor/data-uri-sanitize.js.map +1 -0
- package/dist/humain/web-access/vendor/datalab-pdf-extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/datalab-pdf-extract.js.map +1 -1
- package/dist/humain/web-access/vendor/declared-web-links.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/declared-web-links.js.map +1 -1
- package/dist/humain/web-access/vendor/duckduckgo.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/duckduckgo.js.map +1 -1
- package/dist/humain/web-access/vendor/exa.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/exa.js +16 -7
- package/dist/humain/web-access/vendor/exa.js.map +1 -1
- package/dist/humain/web-access/vendor/extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/extract.js +45 -5
- package/dist/humain/web-access/vendor/extract.js.map +1 -1
- package/dist/humain/web-access/vendor/feature-config.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/feature-config.js.map +1 -1
- package/dist/humain/web-access/vendor/fetch-params.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/fetch-params.js.map +1 -1
- package/dist/humain/web-access/vendor/firecrawl.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/firecrawl.js +15 -2
- package/dist/humain/web-access/vendor/firecrawl.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-api.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-api.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-pdf-extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-pdf-extract.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-search.d.ts +2 -2
- package/dist/humain/web-access/vendor/gemini-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-search.js +25 -8
- package/dist/humain/web-access/vendor/gemini-search.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-url-context.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-url-context.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-web-config.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-web-config.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-web.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-web.js.map +1 -1
- package/dist/humain/web-access/vendor/github-api.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/github-api.js.map +1 -1
- package/dist/humain/web-access/vendor/github-extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/github-extract.js +69 -35
- package/dist/humain/web-access/vendor/github-extract.js.map +1 -1
- package/dist/humain/web-access/vendor/index.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/index.js +58 -54
- package/dist/humain/web-access/vendor/index.js.map +1 -1
- package/dist/humain/web-access/vendor/jina-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/jina-search.js.map +1 -1
- package/dist/humain/web-access/vendor/kagi.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/kagi.js.map +1 -1
- package/dist/humain/web-access/vendor/ollama.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/ollama.js.map +1 -1
- package/dist/humain/web-access/vendor/openai-search.d.ts +1 -1
- package/dist/humain/web-access/vendor/openai-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/openai-search.js +15 -5
- package/dist/humain/web-access/vendor/openai-search.js.map +1 -1
- package/dist/humain/web-access/vendor/page-query.d.ts +1 -2
- package/dist/humain/web-access/vendor/page-query.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/page-query.js +5 -2
- package/dist/humain/web-access/vendor/page-query.js.map +1 -1
- package/dist/humain/web-access/vendor/parallel-mcp.d.ts +10 -0
- package/dist/humain/web-access/vendor/parallel-mcp.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/parallel-mcp.js +224 -0
- package/dist/humain/web-access/vendor/parallel-mcp.js.map +1 -0
- package/dist/humain/web-access/vendor/parallel.d.ts +1 -0
- package/dist/humain/web-access/vendor/parallel.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/parallel.js +2 -2
- package/dist/humain/web-access/vendor/parallel.js.map +1 -1
- package/dist/humain/web-access/vendor/pdf-extract.d.ts +1 -0
- package/dist/humain/web-access/vendor/pdf-extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/pdf-extract.js +15 -5
- package/dist/humain/web-access/vendor/pdf-extract.js.map +1 -1
- package/dist/humain/web-access/vendor/perplexity.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/perplexity.js.map +1 -1
- package/dist/humain/web-access/vendor/querit.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/querit.js.map +1 -1
- package/dist/humain/web-access/vendor/query-rewrite.d.ts +3 -0
- package/dist/humain/web-access/vendor/query-rewrite.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/query-rewrite.js +42 -0
- package/dist/humain/web-access/vendor/query-rewrite.js.map +1 -0
- package/dist/humain/web-access/vendor/render-search-error.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/render-search-error.js.map +1 -1
- package/dist/humain/web-access/vendor/rsc-extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/rsc-extract.js.map +1 -1
- package/dist/humain/web-access/vendor/search1api.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/search1api.js.map +1 -1
- package/dist/humain/web-access/vendor/searchinfinity.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/searchinfinity.js.map +1 -1
- package/dist/humain/web-access/vendor/searxng.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/searxng.js.map +1 -1
- package/dist/humain/web-access/vendor/serpbase.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/serpbase.js.map +1 -1
- package/dist/humain/web-access/vendor/serpdive.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/serpdive.js.map +1 -1
- package/dist/humain/web-access/vendor/serper.d.ts +4 -0
- package/dist/humain/web-access/vendor/serper.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/serper.js +206 -0
- package/dist/humain/web-access/vendor/serper.js.map +1 -0
- package/dist/humain/web-access/vendor/source-check.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/source-check.js.map +1 -1
- package/dist/humain/web-access/vendor/ssrf-protection.d.ts +2 -0
- package/dist/humain/web-access/vendor/ssrf-protection.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/ssrf-protection.js +11 -2
- package/dist/humain/web-access/vendor/ssrf-protection.js.map +1 -1
- package/dist/humain/web-access/vendor/storage.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/storage.js.map +1 -1
- package/dist/humain/web-access/vendor/summary-model-scope.d.ts +5 -0
- package/dist/humain/web-access/vendor/summary-model-scope.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/summary-model-scope.js +10 -5
- package/dist/humain/web-access/vendor/summary-model-scope.js.map +1 -1
- package/dist/humain/web-access/vendor/summary-review.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/summary-review.js +40 -14
- package/dist/humain/web-access/vendor/summary-review.js.map +1 -1
- package/dist/humain/web-access/vendor/tavily.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/tavily.js +14 -4
- package/dist/humain/web-access/vendor/tavily.js.map +1 -1
- package/dist/humain/web-access/vendor/tinyfish.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/tinyfish.js.map +1 -1
- package/dist/humain/web-access/vendor/utils.d.ts +10 -0
- package/dist/humain/web-access/vendor/utils.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/utils.js +70 -0
- package/dist/humain/web-access/vendor/utils.js.map +1 -1
- package/dist/humain/web-access/vendor/valyu.d.ts +6 -0
- package/dist/humain/web-access/vendor/valyu.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/valyu.js +194 -0
- package/dist/humain/web-access/vendor/valyu.js.map +1 -0
- package/dist/humain/web-access/vendor/video-extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/video-extract.js.map +1 -1
- package/dist/humain/web-access/vendor/xai-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/xai-search.js.map +1 -1
- package/dist/humain/web-access/vendor/youtube-extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/youtube-extract.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +4 -0
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/agent-exec-mode.d.ts.map +1 -1
- package/dist/modes/agent-exec-mode.js.map +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js +6 -10
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +2 -9
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +4 -9
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +0 -3
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +1 -3
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +1 -3
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +5 -22
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js +0 -5
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +1 -8
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js +1 -4
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +1 -7
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js +6 -8
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js +2 -2
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +0 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +1 -7
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +2 -8
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +1 -9
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +2 -4
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -3
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +3 -9
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
- package/dist/modes/interactive/components/mermaid.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +14 -26
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +3 -11
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +9 -14
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +33 -57
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +10 -14
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js +0 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +1 -3
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +0 -2
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +0 -2
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +0 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +19 -25
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +18 -34
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js +0 -6
- package/dist/modes/interactive/components/trust-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +3 -6
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +0 -4
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +18 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +147 -137
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
- package/dist/modes/interactive/model-catalog-refresh.js +36 -0
- package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
- package/dist/modes/interactive/model-search.d.ts.map +1 -1
- package/dist/modes/interactive/model-search.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +2 -0
- package/dist/modes/interactive/theme/light.json +2 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +25 -18
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +9 -1
- package/dist/modes/interactive/theme/theme.d.ts +7 -5
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +12 -8
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +4 -1
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +5 -2
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/jsonl.d.ts.map +1 -1
- package/dist/modes/rpc/jsonl.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +9 -10
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.d.ts.map +1 -1
- package/dist/rpc-entry.js.map +1 -1
- package/dist/server/create-harness.d.ts.map +1 -1
- package/dist/server/create-harness.js +2 -0
- package/dist/server/create-harness.js.map +1 -1
- package/dist/utils/abort.d.ts.map +1 -1
- package/dist/utils/abort.js.map +1 -1
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/deprecation.d.ts.map +1 -1
- package/dist/utils/deprecation.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js.map +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/html.d.ts.map +1 -1
- package/dist/utils/html.js.map +1 -1
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-process.d.ts.map +1 -1
- package/dist/utils/image-process.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/image-resize-worker.d.ts.map +1 -1
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/mime.d.ts.map +1 -1
- package/dist/utils/mime.js.map +1 -1
- package/dist/utils/open-browser.d.ts.map +1 -1
- package/dist/utils/open-browser.js.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js.map +1 -1
- package/dist/utils/pi-user-agent.d.ts.map +1 -1
- package/dist/utils/pi-user-agent.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +1 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/tool-result-images.d.ts.map +1 -1
- package/dist/utils/tool-result-images.js.map +1 -1
- package/dist/utils/tools-manager.d.ts +10 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +14 -19
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts.map +1 -1
- package/dist/utils/windows-self-update.js.map +1 -1
- package/docs/compaction.md +3 -3
- package/docs/custom-provider.md +1 -1
- package/docs/environment-variables.md +1 -0
- package/docs/extensions.md +5 -1
- package/docs/json.md +6 -4
- package/docs/keybindings.md +8 -2
- package/docs/rpc.md +15 -4
- package/docs/sdk.md +9 -0
- package/docs/settings.md +31 -0
- package/docs/terminal-setup.md +23 -2
- package/docs/themes.md +23 -3
- package/docs/tui.md +2 -2
- package/docs/usage.md +3 -2
- package/examples/extensions/README.md +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/minimal-mode.ts +6 -6
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +2 -2
- package/examples/extensions/subagent/README.md +24 -147
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +853 -661
- package/package.json +33 -33
- package/src/humain/mcp-adapter/UPSTREAM.md +1 -1
- package/src/humain/mcp-adapter/upstream.json +3 -3
- package/src/humain/mcp-adapter/vendor/CHANGELOG.md +36 -0
- package/src/humain/web-access/UPSTREAM.md +1 -1
- package/src/humain/web-access/upstream.json +4 -4
- package/examples/extensions/subagent/agents.ts +0 -126
- package/examples/extensions/subagent/index.ts +0 -1015
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search1api.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/search1api.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport type { ExtractedContent, ExtractOptions } from \"./extract.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst SEARCH1API_SEARCH_URL = \"https://api.search1api.com/search\";\nconst SEARCH1API_CRAWL_URL = \"https://api.search1api.com/crawl\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\nconst CRAWL_TIMEOUT_MS = 60_000;\n\ninterface WebSearchConfig {\n\tsearch1apiApiKey?: unknown;\n}\n\ninterface Search1APISearchResult {\n\ttitle?: string | null;\n\tlink?: string | null;\n\tsnippet?: string | null;\n\tcontent?: string | null;\n}\n\ninterface Search1APISearchResponse {\n\tsearchParameters?: Record<string, unknown>;\n\tresults?: Search1APISearchResult[];\n}\n\ninterface Search1APICrawlResult {\n\ttitle?: string | null;\n\tlink?: string | null;\n\tcontent?: string | null;\n\tmetadata?: Record<string, unknown>;\n}\n\ninterface Search1APICrawlResponse {\n\tcrawlParameters?: { url?: string };\n\tresults?: Search1APICrawlResult;\n}\n\ninterface Search1APISearchOptions 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\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string> {\n\tconst key = await resolveCredential({\n\t\tprovider: \"Search1API\",\n\t\tconfiguredValue: loadConfig().search1apiApiKey,\n\t\tenvironmentValue: process.env.SEARCH1API_KEY,\n\t\tsignal,\n\t});\n\tif (!key) {\n\t\tthrow new Error(\n\t\t\t\"Search1API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"search1apiApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set SEARCH1API_KEY environment variable\\n\" +\n\t\t\t\"Create a key at https://dashboard.search1api.com\",\n\t\t);\n\t}\n\treturn key;\n}\n\nexport function isSearch1APIAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"Search1API\",\n\t\tconfiguredValue: loadConfig().search1apiApiKey,\n\t\tenvironmentValue: process.env.SEARCH1API_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 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 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): { includeSites: string[]; excludeSites: string[] } {\n\tconst includeSites: string[] = [];\n\tconst excludeSites: 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(\"-\") ? excludeSites : includeSites;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn { includeSites, excludeSites };\n}\n\nfunction buildSearchBody(query: string, options: Search1APISearchOptions): Record<string, unknown> {\n\tconst numResults = normalizeNumResults(options.numResults);\n\tconst { includeSites, excludeSites } = mapDomainFilter(options.domainFilter);\n\treturn {\n\t\tquery,\n\t\tmax_results: numResults,\n\t\tcrawl_results: options.includeContent ? numResults : 0,\n\t\t...(includeSites.length > 0 ? { include_sites: includeSites } : {}),\n\t\t...(excludeSites.length > 0 ? { exclude_sites: excludeSites } : {}),\n\t\t...(options.recencyFilter ? { time_range: options.recencyFilter } : {}),\n\t};\n}\n\nasync function search1APIJsonRequest<T>(\n\tlabel: \"Search\" | \"Crawl\",\n\turl: string,\n\tapiKey: string,\n\tbody: Record<string, unknown>,\n\ttimeoutMs: number,\n\tsignal?: AbortSignal,\n): Promise<T> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `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(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(`Search1API ${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(`Search1API ${label} API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n}\n\nfunction mapSearchResults(results: Search1APISearchResult[] | undefined): SearchResponse[\"results\"] {\n\tif (!Array.isArray(results)) {\n\t\tthrow new Error(\"Search1API Search API returned an unexpected response shape\");\n\t}\n\treturn results.flatMap((item) => {\n\t\tif (!item || typeof item.link !== \"string\" || item.link.trim().length === 0) return [];\n\t\tconst url = item.link.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 mapInlineContent(results: Search1APISearchResult[] | undefined): ExtractedContent[] {\n\tif (!Array.isArray(results)) return [];\n\treturn results.flatMap((item) => {\n\t\tif (!item || typeof item.link !== \"string\" || item.link.trim().length === 0) return [];\n\t\tif (typeof item.content !== \"string\" || item.content.trim().length === 0) return [];\n\t\treturn [{\n\t\t\turl: item.link.trim(),\n\t\t\ttitle: typeof item.title === \"string\" ? item.title.trim() : \"\",\n\t\t\tcontent: item.content,\n\t\t\terror: null,\n\t\t}];\n\t});\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\nexport async function searchWithSearch1API(\n\tquery: string,\n\toptions: Search1APISearchOptions = {},\n): Promise<SearchResponse> {\n\tconst apiKey = await getApiKey(options.signal);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\ttry {\n\t\tconst data = await search1APIJsonRequest<Search1APISearchResponse>(\n\t\t\t\"Search\",\n\t\t\tSEARCH1API_SEARCH_URL,\n\t\t\tapiKey,\n\t\t\tbuildSearchBody(query, options),\n\t\t\tSEARCH_TIMEOUT_MS,\n\t\t\toptions.signal,\n\t\t);\n\t\tconst results = mapSearchResults(data.results);\n\t\tconst response: SearchResponse = { answer: buildAnswer(results), results };\n\t\tif (options.includeContent) {\n\t\t\tconst inlineContent = mapInlineContent(data.results);\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 extractWithSearch1API(\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 search1APIJsonRequest<Search1APICrawlResponse>(\n\t\t\t\"Crawl\",\n\t\t\tSEARCH1API_CRAWL_URL,\n\t\t\tapiKey,\n\t\t\t{ url },\n\t\t\ttypeof options.timeoutMs === \"number\" && Number.isFinite(options.timeoutMs)\n\t\t\t\t? Math.max(1, Math.floor(options.timeoutMs))\n\t\t\t\t: CRAWL_TIMEOUT_MS,\n\t\t\tsignal,\n\t\t);\n\t\tconst result = data.results;\n\t\tif (!result || typeof result !== \"object\") {\n\t\t\tthrow new Error(\"Search1API Crawl API returned an unexpected response shape\");\n\t\t}\n\t\tconst content = typeof result.content === \"string\" ? result.content.trim() : \"\";\n\t\tif (!content) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\treturn null;\n\t\t}\n\t\tactivityMonitor.logComplete(activityId, 200);\n\t\treturn {\n\t\t\turl,\n\t\t\ttitle: typeof result.title === \"string\" ? result.title.trim() : \"\",\n\t\t\tcontent,\n\t\t\terror: null,\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"]}
|
|
1
|
+
{"version":3,"file":"search1api.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/search1api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGlG,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,qBAAqB,GAAG,mCAAmC,CAAC;AAClE,MAAM,oBAAoB,GAAG,kCAAkC,CAAC;AAChE,MAAM,WAAW,GAAG,sBAAsB,EAAE,CAAC;AAC7C,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACjC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAkChC,IAAI,YAAY,GAA2B,IAAI,CAAC;AAEhD,SAAS,UAAU;IAClB,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IACtC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9B,YAAY,GAAG,EAAE,CAAC;QAClB,OAAO,YAAY,CAAC;IACrB,CAAC;IAED,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,mBAAmB,WAAW,KAAK,OAAO,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,qBAAqB,WAAW,0BAA0B,CAAC,CAAC;IAC7E,CAAC;IACD,YAAY,GAAG,MAAyB,CAAC;IACzC,OAAO,YAAY,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,MAAoB;IAC5C,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC;QACnC,QAAQ,EAAE,YAAY;QACtB,eAAe,EAAE,UAAU,EAAE,CAAC,gBAAgB;QAC9C,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;QAC5C,MAAM;KACN,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACd,qCAAqC;YACrC,eAAe,WAAW,4CAA4C;YACtE,gDAAgD;YAChD,kDAAkD,CAClD,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,qBAAqB;IACpC,OAAO,mBAAmB,CAAC;QAC1B,QAAQ,EAAE,YAAY;QACtB,eAAe,EAAE,UAAU,EAAE,CAAC,gBAAgB;QAC9C,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;KAC5C,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,GAAY;IACjC,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,aAAa,CAAC,MAA+B,EAAE,SAAiB;IACxE,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAC9D,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAyB;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACnE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACrC,IAAI,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACzD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,WAAW,KAAK,EAAE,CAAC,CAAC;QACpF,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACR,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,CAAC;IACD,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACxC,OAAO,mCAAmC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC;AAED,SAAS,eAAe,CAAC,YAAkC;IAC1D,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,YAAY,IAAI,EAAE,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;QACxE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;AACvC,CAAC;AAED,SAAS,eAAe,CAAC,KAAa,EAAE,OAAgC;IACvE,MAAM,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3D,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7E,OAAO;QACN,KAAK;QACL,WAAW,EAAE,UAAU;QACvB,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACtD,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvE,CAAC;AACH,CAAC;AAED,KAAK,UAAU,qBAAqB,CACnC,KAAyB,EACzB,GAAW,EACX,MAAc,EACd,IAA6B,EAC7B,SAAiB,EACjB,MAAoB;IAEpB,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACJ,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACR,aAAa,EAAE,UAAU,MAAM,EAAE;gBACjC,cAAc,EAAE,kBAAkB;aAClC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAC1B,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC;SACxC,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,eAAe,GAAG,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1D,IAAI,eAAe,KAAK,OAAO;YAAE,MAAM,GAAG,CAAC;QAC3C,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACjD,IAAI,GAAG,YAAY,KAAK;YAAE,aAAa,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACxD,MAAM,aAAa,CAAC;IACrB,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,cAAc,QAAQ,CAAC,MAAM,KAAK,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACrH,CAAC;IACD,IAAI,CAAC;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,+BAA+B,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACxF,CAAC;AACF,CAAC;AAED,SAAS,gBAAgB,CAAC,OAA6C;IACtE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACvF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC7B,OAAO,CAAC;gBACP,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG;gBACpF,GAAG;gBACH,OAAO,EAAE,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;aACzF,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,OAA6C;IACtE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACvF,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACpF,OAAO,CAAC;gBACP,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBACrB,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;gBAC9D,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,KAAK,EAAE,IAAI;aACX,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,OAAkC;IACtD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC7B,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO,GAAG,MAAM,CAAC,OAAO,aAAa,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,GAAG,GAAG,CAAC;QACxF,OAAO,WAAW,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,GAAG,GAAG,CAAC;IAClD,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACzC,KAAa,EACb,OAAO,GAA4B,EAAE;IAErC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACpE,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,qBAAqB,CACvC,QAAQ,EACR,qBAAqB,EACrB,MAAM,EACN,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,EAC/B,iBAAiB,EACjB,OAAO,CAAC,MAAM,CACd,CAAC;QACF,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAmB,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QAC3E,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;YAC5B,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;gBAAE,QAAQ,CAAC,aAAa,GAAG,aAAa,CAAC;QACtE,CAAC;QACD,eAAe,CAAC,WAAW,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAC7C,OAAO,QAAQ,CAAC;IACjB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,eAAe,GAAG,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1D,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,eAAe,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;;YAC3F,eAAe,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QAC3D,IAAI,eAAe,KAAK,OAAO;YAAE,MAAM,GAAG,CAAC;QAC3C,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACjD,IAAI,GAAG,YAAY,KAAK;YAAE,aAAa,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACxD,MAAM,aAAa,CAAC;IACrB,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAC1C,GAAW,EACX,MAAoB,EACpB,OAAO,GAAmB,EAAE;IAE5B,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IACpE,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,qBAAqB,CACvC,OAAO,EACP,oBAAoB,EACpB,MAAM,EACN,EAAE,GAAG,EAAE,EACP,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;YAC1E,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC5C,CAAC,CAAC,gBAAgB,EACnB,MAAM,CACN,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAC/E,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChF,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,eAAe,CAAC,WAAW,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;YAC7C,OAAO,IAAI,CAAC;QACb,CAAC;QACD,eAAe,CAAC,WAAW,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAC7C,OAAO;YACN,GAAG;YACH,KAAK,EAAE,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;YAClE,OAAO;YACP,KAAK,EAAE,IAAI;SACX,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,eAAe,GAAG,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1D,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,eAAe,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;;YAC3F,eAAe,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QAC3D,IAAI,eAAe,KAAK,OAAO;YAAE,MAAM,GAAG,CAAC;QAC3C,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACjD,IAAI,GAAG,YAAY,KAAK;YAAE,aAAa,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACxD,MAAM,aAAa,CAAC;IACrB,CAAC;AACF,CAAC","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport type { ExtractedContent, ExtractOptions } from \"./extract.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst SEARCH1API_SEARCH_URL = \"https://api.search1api.com/search\";\nconst SEARCH1API_CRAWL_URL = \"https://api.search1api.com/crawl\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\nconst CRAWL_TIMEOUT_MS = 60_000;\n\ninterface WebSearchConfig {\n\tsearch1apiApiKey?: unknown;\n}\n\ninterface Search1APISearchResult {\n\ttitle?: string | null;\n\tlink?: string | null;\n\tsnippet?: string | null;\n\tcontent?: string | null;\n}\n\ninterface Search1APISearchResponse {\n\tsearchParameters?: Record<string, unknown>;\n\tresults?: Search1APISearchResult[];\n}\n\ninterface Search1APICrawlResult {\n\ttitle?: string | null;\n\tlink?: string | null;\n\tcontent?: string | null;\n\tmetadata?: Record<string, unknown>;\n}\n\ninterface Search1APICrawlResponse {\n\tcrawlParameters?: { url?: string };\n\tresults?: Search1APICrawlResult;\n}\n\ninterface Search1APISearchOptions 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\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string> {\n\tconst key = await resolveCredential({\n\t\tprovider: \"Search1API\",\n\t\tconfiguredValue: loadConfig().search1apiApiKey,\n\t\tenvironmentValue: process.env.SEARCH1API_KEY,\n\t\tsignal,\n\t});\n\tif (!key) {\n\t\tthrow new Error(\n\t\t\t\"Search1API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"search1apiApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set SEARCH1API_KEY environment variable\\n\" +\n\t\t\t\"Create a key at https://dashboard.search1api.com\",\n\t\t);\n\t}\n\treturn key;\n}\n\nexport function isSearch1APIAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"Search1API\",\n\t\tconfiguredValue: loadConfig().search1apiApiKey,\n\t\tenvironmentValue: process.env.SEARCH1API_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 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 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): { includeSites: string[]; excludeSites: string[] } {\n\tconst includeSites: string[] = [];\n\tconst excludeSites: 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(\"-\") ? excludeSites : includeSites;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn { includeSites, excludeSites };\n}\n\nfunction buildSearchBody(query: string, options: Search1APISearchOptions): Record<string, unknown> {\n\tconst numResults = normalizeNumResults(options.numResults);\n\tconst { includeSites, excludeSites } = mapDomainFilter(options.domainFilter);\n\treturn {\n\t\tquery,\n\t\tmax_results: numResults,\n\t\tcrawl_results: options.includeContent ? numResults : 0,\n\t\t...(includeSites.length > 0 ? { include_sites: includeSites } : {}),\n\t\t...(excludeSites.length > 0 ? { exclude_sites: excludeSites } : {}),\n\t\t...(options.recencyFilter ? { time_range: options.recencyFilter } : {}),\n\t};\n}\n\nasync function search1APIJsonRequest<T>(\n\tlabel: \"Search\" | \"Crawl\",\n\turl: string,\n\tapiKey: string,\n\tbody: Record<string, unknown>,\n\ttimeoutMs: number,\n\tsignal?: AbortSignal,\n): Promise<T> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `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(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(`Search1API ${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(`Search1API ${label} API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n}\n\nfunction mapSearchResults(results: Search1APISearchResult[] | undefined): SearchResponse[\"results\"] {\n\tif (!Array.isArray(results)) {\n\t\tthrow new Error(\"Search1API Search API returned an unexpected response shape\");\n\t}\n\treturn results.flatMap((item) => {\n\t\tif (!item || typeof item.link !== \"string\" || item.link.trim().length === 0) return [];\n\t\tconst url = item.link.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 mapInlineContent(results: Search1APISearchResult[] | undefined): ExtractedContent[] {\n\tif (!Array.isArray(results)) return [];\n\treturn results.flatMap((item) => {\n\t\tif (!item || typeof item.link !== \"string\" || item.link.trim().length === 0) return [];\n\t\tif (typeof item.content !== \"string\" || item.content.trim().length === 0) return [];\n\t\treturn [{\n\t\t\turl: item.link.trim(),\n\t\t\ttitle: typeof item.title === \"string\" ? item.title.trim() : \"\",\n\t\t\tcontent: item.content,\n\t\t\terror: null,\n\t\t}];\n\t});\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\nexport async function searchWithSearch1API(\n\tquery: string,\n\toptions: Search1APISearchOptions = {},\n): Promise<SearchResponse> {\n\tconst apiKey = await getApiKey(options.signal);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\ttry {\n\t\tconst data = await search1APIJsonRequest<Search1APISearchResponse>(\n\t\t\t\"Search\",\n\t\t\tSEARCH1API_SEARCH_URL,\n\t\t\tapiKey,\n\t\t\tbuildSearchBody(query, options),\n\t\t\tSEARCH_TIMEOUT_MS,\n\t\t\toptions.signal,\n\t\t);\n\t\tconst results = mapSearchResults(data.results);\n\t\tconst response: SearchResponse = { answer: buildAnswer(results), results };\n\t\tif (options.includeContent) {\n\t\t\tconst inlineContent = mapInlineContent(data.results);\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 extractWithSearch1API(\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 search1APIJsonRequest<Search1APICrawlResponse>(\n\t\t\t\"Crawl\",\n\t\t\tSEARCH1API_CRAWL_URL,\n\t\t\tapiKey,\n\t\t\t{ url },\n\t\t\ttypeof options.timeoutMs === \"number\" && Number.isFinite(options.timeoutMs)\n\t\t\t\t? Math.max(1, Math.floor(options.timeoutMs))\n\t\t\t\t: CRAWL_TIMEOUT_MS,\n\t\t\tsignal,\n\t\t);\n\t\tconst result = data.results;\n\t\tif (!result || typeof result !== \"object\") {\n\t\t\tthrow new Error(\"Search1API Crawl API returned an unexpected response shape\");\n\t\t}\n\t\tconst content = typeof result.content === \"string\" ? result.content.trim() : \"\";\n\t\tif (!content) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\treturn null;\n\t\t}\n\t\tactivityMonitor.logComplete(activityId, 200);\n\t\treturn {\n\t\t\turl,\n\t\t\ttitle: typeof result.title === \"string\" ? result.title.trim() : \"\",\n\t\t\tcontent,\n\t\t\terror: null,\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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchinfinity.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/searchinfinity.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AA6CrE,UAAU,2BAA4B,SAAQ,aAAa;IAC1D,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AA4CD,wBAAgB,yBAAyB,IAAI,OAAO,CAMnD;AAkJD,wBAAsB,wBAAwB,CAC7C,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,2BAAgC,GACvC,OAAO,CAAC,cAAc,CAAC,CAmBzB","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst SEARCHINFINITY_SEARCH_URL = \"https://torchlight.byteintlapi.com/search_api/web_search\";\nconst CONFIG_PATH = getWebSearchConfigPath();\n// API Key authenticated requests time out server-side after 30 seconds.\nconst SEARCH_TIMEOUT_MS = 30_000;\n\ninterface WebSearchConfig {\n\tsearchinfinityApiKey?: unknown;\n}\n\ninterface SearchinfinityWebResult {\n\tId?: string;\n\tSortId?: number;\n\tTitle?: string | null;\n\tSiteName?: string | null;\n\tUrl?: string | null;\n\tSnippet?: string | null;\n\tSummary?: string | null;\n\tPublishTime?: string | null;\n\tLogoUrl?: string | null;\n}\n\ninterface SearchinfinitySearchResponse {\n\tResponseMetadata?: {\n\t\tRequestId?: string;\n\t\tError?: {\n\t\t\tCodeN?: number;\n\t\t\tCode?: string;\n\t\t\tMessage?: string;\n\t\t} | null;\n\t};\n\tResult?: {\n\t\tResultCount?: number;\n\t\tWebResults?: SearchinfinityWebResult[];\n\t\tSearchContext?: {\n\t\t\tOriginQuery?: string;\n\t\t\tSearchType?: string;\n\t\t};\n\t\tTimeCost?: number;\n\t\tLogId?: string;\n\t} | null;\n}\n\ninterface SearchinfinitySearchOptions 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\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string> {\n\tconst key = await resolveCredential({\n\t\tprovider: \"Searchinfinity\",\n\t\tconfiguredValue: loadConfig().searchinfinityApiKey,\n\t\tenvironmentValue: process.env.SEARCHINFINITY_API_KEY,\n\t\tsignal,\n\t});\n\tif (!key) {\n\t\tthrow new Error(\n\t\t\t\"Searchinfinity API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"searchinfinityApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set SEARCHINFINITY_API_KEY environment variable\\n\" +\n\t\t\t\"Create a key at https://console.byteplus.com/search-infinity/api-key\",\n\t\t);\n\t}\n\treturn key;\n}\n\nexport function isSearchinfinityAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"Searchinfinity\",\n\t\tconfiguredValue: loadConfig().searchinfinityApiKey,\n\t\tenvironmentValue: process.env.SEARCHINFINITY_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 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 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 mapRecencyFilter(recency: SearchOptions[\"recencyFilter\"]): string | undefined {\n\tif (recency === \"day\") return \"OneDay\";\n\tif (recency === \"week\") return \"OneWeek\";\n\tif (recency === \"month\") return \"OneMonth\";\n\tif (recency === \"year\") return \"OneYear\";\n\treturn undefined;\n}\n\nfunction buildSearchBody(query: string, options: SearchinfinitySearchOptions): Record<string, unknown> {\n\tconst includeSites: string[] = [];\n\tconst blockHosts: string[] = [];\n\tfor (const raw of options.domainFilter ?? []) {\n\t\tconst domain = normalizeDomain(raw);\n\t\tif (!domain) continue;\n\t\tconst target = raw.trim().startsWith(\"-\") ? blockHosts : includeSites;\n\t\tif (target.length < 5 && !target.includes(domain)) target.push(domain);\n\t}\n\tconst filter: Record<string, unknown> = {};\n\tif (includeSites.length > 0) filter.Sites = includeSites.join(\"|\");\n\tif (blockHosts.length > 0) filter.BlockHosts = blockHosts.join(\"|\");\n\n\tconst timeRange = mapRecencyFilter(options.recencyFilter);\n\treturn {\n\t\tQuery: query,\n\t\tCount: normalizeNumResults(options.numResults),\n\t\t...(Object.keys(filter).length > 0 ? { Filter: filter } : {}),\n\t\t...(timeRange ? { TimeRange: timeRange } : {}),\n\t};\n}\n\n// Map Searchinfinity business error codes to the closest HTTP semantics so\n// error classification (auth/quota/invalid-request/transient) keeps working.\n// CodeN carries the numeric code (e.g. 700901); Code may be a slug (e.g.\n// \"invalid_api_key\"), so match both.\nfunction businessErrorStatus(codeN: number | undefined, code: string, message: string): number | undefined {\n\tif (codeN === 700901 || code === \"invalid_api_key\") return 401;\n\tif (codeN === 700429 || code === \"700429\") return 429;\n\tif (codeN === 10400 || code === \"10400\") return 400;\n\tif (codeN === 10500 || code === \"10500\") return 500;\n\tif (codeN === 10403 || code === \"10403\") return /quota|exhaust/i.test(message) ? 429 : 403;\n\treturn undefined;\n}\n\nasync function searchinfinityJsonRequest(\n\tapiKey: string,\n\tbody: Record<string, unknown>,\n\tsignal?: AbortSignal,\n): Promise<SearchinfinitySearchResponse> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(SEARCHINFINITY_SEARCH_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `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(signal, SEARCH_TIMEOUT_MS),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage === 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(`Searchinfinity Search API error ${response.status}: ${redactCredential(raw, apiKey).slice(0, 300)}`);\n\t}\n\tlet data: SearchinfinitySearchResponse;\n\ttry {\n\t\tdata = JSON.parse(raw) as SearchinfinitySearchResponse;\n\t} catch (err) {\n\t\tthrow new Error(`Searchinfinity Search API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\tconst businessError = data.ResponseMetadata?.Error;\n\tif (businessError && (businessError.Code || businessError.Message)) {\n\t\tconst code = typeof businessError.Code === \"string\" && businessError.Code ? businessError.Code : \"unknown\";\n\t\tconst message = typeof businessError.Message === \"string\" && businessError.Message ? businessError.Message : \"unknown error\";\n\t\tconst status = businessErrorStatus(businessError.CodeN, code, message);\n\t\tconst codeLabel = typeof businessError.CodeN === \"number\" ? `${businessError.CodeN} ${code}` : code;\n\t\tthrow new Error(\n\t\t\t`Searchinfinity Search API error ${status ?? \"unknown\"}: ${message} (code ${codeLabel})`,\n\t\t);\n\t}\n\treturn data;\n}\n\nfunction mapSearchResults(results: SearchinfinityWebResult[] | undefined): SearchResponse[\"results\"] {\n\tif (!Array.isArray(results)) {\n\t\tthrow new Error(\"Searchinfinity Search API returned an unexpected response shape\");\n\t}\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\tconst summary = typeof item.Summary === \"string\" ? item.Summary.replace(/\\s+/g, \" \").trim() : \"\";\n\t\tconst snippet = typeof item.Snippet === \"string\" ? item.Snippet.replace(/\\s+/g, \" \").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: summary || snippet,\n\t\t}];\n\t});\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\nexport async function searchWithSearchinfinity(\n\tquery: string,\n\toptions: SearchinfinitySearchOptions = {},\n): Promise<SearchResponse> {\n\tconst apiKey = await getApiKey(options.signal);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\ttry {\n\t\tconst data = await searchinfinityJsonRequest(apiKey, buildSearchBody(query, options), options.signal);\n\t\tconst results = mapSearchResults(data.Result?.WebResults);\n\t\tconst response: SearchResponse = { answer: buildAnswer(results), results };\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"]}
|
|
1
|
+
{"version":3,"file":"searchinfinity.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/searchinfinity.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AA6CrE,UAAU,2BAA4B,SAAQ,aAAa;IAC1D,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AA4CD,wBAAgB,yBAAyB,IAAI,OAAO,CAMnD;AAkJD,wBAAsB,wBAAwB,CAC7C,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,2BAAgC,GACvC,OAAO,CAAC,cAAc,CAAC,CAmBzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchinfinity.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/searchinfinity.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst SEARCHINFINITY_SEARCH_URL = \"https://torchlight.byteintlapi.com/search_api/web_search\";\nconst CONFIG_PATH = getWebSearchConfigPath();\n// API Key authenticated requests time out server-side after 30 seconds.\nconst SEARCH_TIMEOUT_MS = 30_000;\n\ninterface WebSearchConfig {\n\tsearchinfinityApiKey?: unknown;\n}\n\ninterface SearchinfinityWebResult {\n\tId?: string;\n\tSortId?: number;\n\tTitle?: string | null;\n\tSiteName?: string | null;\n\tUrl?: string | null;\n\tSnippet?: string | null;\n\tSummary?: string | null;\n\tPublishTime?: string | null;\n\tLogoUrl?: string | null;\n}\n\ninterface SearchinfinitySearchResponse {\n\tResponseMetadata?: {\n\t\tRequestId?: string;\n\t\tError?: {\n\t\t\tCodeN?: number;\n\t\t\tCode?: string;\n\t\t\tMessage?: string;\n\t\t} | null;\n\t};\n\tResult?: {\n\t\tResultCount?: number;\n\t\tWebResults?: SearchinfinityWebResult[];\n\t\tSearchContext?: {\n\t\t\tOriginQuery?: string;\n\t\t\tSearchType?: string;\n\t\t};\n\t\tTimeCost?: number;\n\t\tLogId?: string;\n\t} | null;\n}\n\ninterface SearchinfinitySearchOptions 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\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string> {\n\tconst key = await resolveCredential({\n\t\tprovider: \"Searchinfinity\",\n\t\tconfiguredValue: loadConfig().searchinfinityApiKey,\n\t\tenvironmentValue: process.env.SEARCHINFINITY_API_KEY,\n\t\tsignal,\n\t});\n\tif (!key) {\n\t\tthrow new Error(\n\t\t\t\"Searchinfinity API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"searchinfinityApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set SEARCHINFINITY_API_KEY environment variable\\n\" +\n\t\t\t\"Create a key at https://console.byteplus.com/search-infinity/api-key\",\n\t\t);\n\t}\n\treturn key;\n}\n\nexport function isSearchinfinityAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"Searchinfinity\",\n\t\tconfiguredValue: loadConfig().searchinfinityApiKey,\n\t\tenvironmentValue: process.env.SEARCHINFINITY_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 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 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 mapRecencyFilter(recency: SearchOptions[\"recencyFilter\"]): string | undefined {\n\tif (recency === \"day\") return \"OneDay\";\n\tif (recency === \"week\") return \"OneWeek\";\n\tif (recency === \"month\") return \"OneMonth\";\n\tif (recency === \"year\") return \"OneYear\";\n\treturn undefined;\n}\n\nfunction buildSearchBody(query: string, options: SearchinfinitySearchOptions): Record<string, unknown> {\n\tconst includeSites: string[] = [];\n\tconst blockHosts: string[] = [];\n\tfor (const raw of options.domainFilter ?? []) {\n\t\tconst domain = normalizeDomain(raw);\n\t\tif (!domain) continue;\n\t\tconst target = raw.trim().startsWith(\"-\") ? blockHosts : includeSites;\n\t\tif (target.length < 5 && !target.includes(domain)) target.push(domain);\n\t}\n\tconst filter: Record<string, unknown> = {};\n\tif (includeSites.length > 0) filter.Sites = includeSites.join(\"|\");\n\tif (blockHosts.length > 0) filter.BlockHosts = blockHosts.join(\"|\");\n\n\tconst timeRange = mapRecencyFilter(options.recencyFilter);\n\treturn {\n\t\tQuery: query,\n\t\tCount: normalizeNumResults(options.numResults),\n\t\t...(Object.keys(filter).length > 0 ? { Filter: filter } : {}),\n\t\t...(timeRange ? { TimeRange: timeRange } : {}),\n\t};\n}\n\n// Map Searchinfinity business error codes to the closest HTTP semantics so\n// error classification (auth/quota/invalid-request/transient) keeps working.\n// CodeN carries the numeric code (e.g. 700901); Code may be a slug (e.g.\n// \"invalid_api_key\"), so match both.\nfunction businessErrorStatus(codeN: number | undefined, code: string, message: string): number | undefined {\n\tif (codeN === 700901 || code === \"invalid_api_key\") return 401;\n\tif (codeN === 700429 || code === \"700429\") return 429;\n\tif (codeN === 10400 || code === \"10400\") return 400;\n\tif (codeN === 10500 || code === \"10500\") return 500;\n\tif (codeN === 10403 || code === \"10403\") return /quota|exhaust/i.test(message) ? 429 : 403;\n\treturn undefined;\n}\n\nasync function searchinfinityJsonRequest(\n\tapiKey: string,\n\tbody: Record<string, unknown>,\n\tsignal?: AbortSignal,\n): Promise<SearchinfinitySearchResponse> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(SEARCHINFINITY_SEARCH_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `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(signal, SEARCH_TIMEOUT_MS),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage === 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(`Searchinfinity Search API error ${response.status}: ${redactCredential(raw, apiKey).slice(0, 300)}`);\n\t}\n\tlet data: SearchinfinitySearchResponse;\n\ttry {\n\t\tdata = JSON.parse(raw) as SearchinfinitySearchResponse;\n\t} catch (err) {\n\t\tthrow new Error(`Searchinfinity Search API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\tconst businessError = data.ResponseMetadata?.Error;\n\tif (businessError && (businessError.Code || businessError.Message)) {\n\t\tconst code = typeof businessError.Code === \"string\" && businessError.Code ? businessError.Code : \"unknown\";\n\t\tconst message = typeof businessError.Message === \"string\" && businessError.Message ? businessError.Message : \"unknown error\";\n\t\tconst status = businessErrorStatus(businessError.CodeN, code, message);\n\t\tconst codeLabel = typeof businessError.CodeN === \"number\" ? `${businessError.CodeN} ${code}` : code;\n\t\tthrow new Error(\n\t\t\t`Searchinfinity Search API error ${status ?? \"unknown\"}: ${message} (code ${codeLabel})`,\n\t\t);\n\t}\n\treturn data;\n}\n\nfunction mapSearchResults(results: SearchinfinityWebResult[] | undefined): SearchResponse[\"results\"] {\n\tif (!Array.isArray(results)) {\n\t\tthrow new Error(\"Searchinfinity Search API returned an unexpected response shape\");\n\t}\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\tconst summary = typeof item.Summary === \"string\" ? item.Summary.replace(/\\s+/g, \" \").trim() : \"\";\n\t\tconst snippet = typeof item.Snippet === \"string\" ? item.Snippet.replace(/\\s+/g, \" \").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: summary || snippet,\n\t\t}];\n\t});\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\nexport async function searchWithSearchinfinity(\n\tquery: string,\n\toptions: SearchinfinitySearchOptions = {},\n): Promise<SearchResponse> {\n\tconst apiKey = await getApiKey(options.signal);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\ttry {\n\t\tconst data = await searchinfinityJsonRequest(apiKey, buildSearchBody(query, options), options.signal);\n\t\tconst results = mapSearchResults(data.Result?.WebResults);\n\t\tconst response: SearchResponse = { answer: buildAnswer(results), results };\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"]}
|
|
1
|
+
{"version":3,"file":"searchinfinity.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/searchinfinity.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst SEARCHINFINITY_SEARCH_URL = \"https://torchlight.byteintlapi.com/search_api/web_search\";\nconst CONFIG_PATH = getWebSearchConfigPath();\n// API Key authenticated requests time out server-side after 30 seconds.\nconst SEARCH_TIMEOUT_MS = 30_000;\n\ninterface WebSearchConfig {\n\tsearchinfinityApiKey?: unknown;\n}\n\ninterface SearchinfinityWebResult {\n\tId?: string;\n\tSortId?: number;\n\tTitle?: string | null;\n\tSiteName?: string | null;\n\tUrl?: string | null;\n\tSnippet?: string | null;\n\tSummary?: string | null;\n\tPublishTime?: string | null;\n\tLogoUrl?: string | null;\n}\n\ninterface SearchinfinitySearchResponse {\n\tResponseMetadata?: {\n\t\tRequestId?: string;\n\t\tError?: {\n\t\t\tCodeN?: number;\n\t\t\tCode?: string;\n\t\t\tMessage?: string;\n\t\t} | null;\n\t};\n\tResult?: {\n\t\tResultCount?: number;\n\t\tWebResults?: SearchinfinityWebResult[];\n\t\tSearchContext?: {\n\t\t\tOriginQuery?: string;\n\t\t\tSearchType?: string;\n\t\t};\n\t\tTimeCost?: number;\n\t\tLogId?: string;\n\t} | null;\n}\n\ninterface SearchinfinitySearchOptions 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\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string> {\n\tconst key = await resolveCredential({\n\t\tprovider: \"Searchinfinity\",\n\t\tconfiguredValue: loadConfig().searchinfinityApiKey,\n\t\tenvironmentValue: process.env.SEARCHINFINITY_API_KEY,\n\t\tsignal,\n\t});\n\tif (!key) {\n\t\tthrow new Error(\n\t\t\t\"Searchinfinity API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"searchinfinityApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set SEARCHINFINITY_API_KEY environment variable\\n\" +\n\t\t\t\"Create a key at https://console.byteplus.com/search-infinity/api-key\",\n\t\t);\n\t}\n\treturn key;\n}\n\nexport function isSearchinfinityAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"Searchinfinity\",\n\t\tconfiguredValue: loadConfig().searchinfinityApiKey,\n\t\tenvironmentValue: process.env.SEARCHINFINITY_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 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 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 mapRecencyFilter(recency: SearchOptions[\"recencyFilter\"]): string | undefined {\n\tif (recency === \"day\") return \"OneDay\";\n\tif (recency === \"week\") return \"OneWeek\";\n\tif (recency === \"month\") return \"OneMonth\";\n\tif (recency === \"year\") return \"OneYear\";\n\treturn undefined;\n}\n\nfunction buildSearchBody(query: string, options: SearchinfinitySearchOptions): Record<string, unknown> {\n\tconst includeSites: string[] = [];\n\tconst blockHosts: string[] = [];\n\tfor (const raw of options.domainFilter ?? []) {\n\t\tconst domain = normalizeDomain(raw);\n\t\tif (!domain) continue;\n\t\tconst target = raw.trim().startsWith(\"-\") ? blockHosts : includeSites;\n\t\tif (target.length < 5 && !target.includes(domain)) target.push(domain);\n\t}\n\tconst filter: Record<string, unknown> = {};\n\tif (includeSites.length > 0) filter.Sites = includeSites.join(\"|\");\n\tif (blockHosts.length > 0) filter.BlockHosts = blockHosts.join(\"|\");\n\n\tconst timeRange = mapRecencyFilter(options.recencyFilter);\n\treturn {\n\t\tQuery: query,\n\t\tCount: normalizeNumResults(options.numResults),\n\t\t...(Object.keys(filter).length > 0 ? { Filter: filter } : {}),\n\t\t...(timeRange ? { TimeRange: timeRange } : {}),\n\t};\n}\n\n// Map Searchinfinity business error codes to the closest HTTP semantics so\n// error classification (auth/quota/invalid-request/transient) keeps working.\n// CodeN carries the numeric code (e.g. 700901); Code may be a slug (e.g.\n// \"invalid_api_key\"), so match both.\nfunction businessErrorStatus(codeN: number | undefined, code: string, message: string): number | undefined {\n\tif (codeN === 700901 || code === \"invalid_api_key\") return 401;\n\tif (codeN === 700429 || code === \"700429\") return 429;\n\tif (codeN === 10400 || code === \"10400\") return 400;\n\tif (codeN === 10500 || code === \"10500\") return 500;\n\tif (codeN === 10403 || code === \"10403\") return /quota|exhaust/i.test(message) ? 429 : 403;\n\treturn undefined;\n}\n\nasync function searchinfinityJsonRequest(\n\tapiKey: string,\n\tbody: Record<string, unknown>,\n\tsignal?: AbortSignal,\n): Promise<SearchinfinitySearchResponse> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(SEARCHINFINITY_SEARCH_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `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(signal, SEARCH_TIMEOUT_MS),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage === 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(`Searchinfinity Search API error ${response.status}: ${redactCredential(raw, apiKey).slice(0, 300)}`);\n\t}\n\tlet data: SearchinfinitySearchResponse;\n\ttry {\n\t\tdata = JSON.parse(raw) as SearchinfinitySearchResponse;\n\t} catch (err) {\n\t\tthrow new Error(`Searchinfinity Search API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\tconst businessError = data.ResponseMetadata?.Error;\n\tif (businessError && (businessError.Code || businessError.Message)) {\n\t\tconst code = typeof businessError.Code === \"string\" && businessError.Code ? businessError.Code : \"unknown\";\n\t\tconst message = typeof businessError.Message === \"string\" && businessError.Message ? businessError.Message : \"unknown error\";\n\t\tconst status = businessErrorStatus(businessError.CodeN, code, message);\n\t\tconst codeLabel = typeof businessError.CodeN === \"number\" ? `${businessError.CodeN} ${code}` : code;\n\t\tthrow new Error(\n\t\t\t`Searchinfinity Search API error ${status ?? \"unknown\"}: ${message} (code ${codeLabel})`,\n\t\t);\n\t}\n\treturn data;\n}\n\nfunction mapSearchResults(results: SearchinfinityWebResult[] | undefined): SearchResponse[\"results\"] {\n\tif (!Array.isArray(results)) {\n\t\tthrow new Error(\"Searchinfinity Search API returned an unexpected response shape\");\n\t}\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\tconst summary = typeof item.Summary === \"string\" ? item.Summary.replace(/\\s+/g, \" \").trim() : \"\";\n\t\tconst snippet = typeof item.Snippet === \"string\" ? item.Snippet.replace(/\\s+/g, \" \").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: summary || snippet,\n\t\t}];\n\t});\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\nexport async function searchWithSearchinfinity(\n\tquery: string,\n\toptions: SearchinfinitySearchOptions = {},\n): Promise<SearchResponse> {\n\tconst apiKey = await getApiKey(options.signal);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\ttry {\n\t\tconst data = await searchinfinityJsonRequest(apiKey, buildSearchBody(query, options), options.signal);\n\t\tconst results = mapSearchResults(data.Result?.WebResults);\n\t\tconst response: SearchResponse = { answer: buildAnswer(results), results };\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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searxng.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/searxng.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAgB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAwLnF,wBAAgB,kBAAkB,IAAI,OAAO,CAK5C;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CA0D3G"
|
|
1
|
+
{"version":3,"file":"searxng.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/searxng.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAgB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAwLnF,wBAAgB,kBAAkB,IAAI,OAAO,CAK5C;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CA0D3G"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searxng.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/searxng.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,GAAG,sBAAsB,EAAE,CAAC;AAC7C,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAuBjC,IAAI,YAAY,GAA2B,IAAI,CAAC;AAEhD,SAAS,UAAU,GAAoB;IACtC,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IACtC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9B,YAAY,GAAG,EAAE,CAAC;QAClB,OAAO,YAAY,CAAC;IACrB,CAAC;IAED,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,CAAC;QACJ,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;QAClD,OAAO,YAAY,CAAC;IACrB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,mBAAmB,WAAW,KAAK,OAAO,EAAE,CAAC,CAAC;IAC/D,CAAC;AAAA,CACD;AAED,SAAS,gBAAgB,CAAC,KAAc,EAAiB;IACxD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACvE,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC9C,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChD,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;QAChB,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;QACd,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AAAA,CACD;AAED,SAAS,UAAU,GAAkB;IACpC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAChD,OAAO,UAAU,KAAK,SAAS;QAC9B,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC;QAC9B,CAAC,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC,cAAc,CAAC,CAAC;AAAA,CACjD;AAED,SAAS,kBAAkB,CAAC,KAAa,EAAW;IACnD,IAAI,CAAC;QACJ,IAAI,OAAO,CAAC,EAAE,4BAA4B,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AAAA,CACD;AAED,SAAS,gBAAgB,CAAC,KAAc,EAA0B;IACjE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3E,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QACnF,IAAI,OAAO,WAAW,KAAK,QAAQ;YAAE,SAAS;QAC9C,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,wEAAsE;QACtE,IAAI,CAAC,IAAI,IAAI,CAAC,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QACnE,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC;YAAE,SAAS;QAC/C,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC;IAC7B,CAAC;IACD,OAAO,OAAO,CAAC;AAAA,CACf;AAED,SAAS,oBAAoB,GAA2B;IACvD,OAAO,gBAAgB,CAAC,UAAU,EAAE,CAAC,cAAc,CAAC,CAAC;AAAA,CACrD;AAED,SAAS,mBAAmB,CAAC,UAAkC,EAA0B;IACxF,MAAM,OAAO,GAA2B,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACvE,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACxD,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,IAAI,QAAQ,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE;gBAAE,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACvB,CAAC;IACD,OAAO,OAAO,CAAC;AAAA,CACf;AAED,SAAS,cAAc,GAAW;IACjC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACd,mDAAmD;YACnD,eAAe,WAAW,4DAA4D;YACtF,6CAA6C,CAC7C,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AAAA,CACf;AAED,SAAS,cAAc,CAAC,KAAyB,EAAU;IAC1D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACnE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAAA,CACpD;AAED,SAAS,eAAe,CAAC,KAAa,EAAiB;IACtD,IAAI,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACzD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,WAAW,KAAK,EAAE,CAAC,CAAC;QACpF,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACR,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,CAAC;IACD,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACxC,OAAO,mCAAmC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAAA,CACtE;AAED,SAAS,sBAAsB,CAAC,YAAkC,EAA2B;IAC5F,MAAM,OAAO,GAA4B,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACtE,KAAK,MAAM,GAAG,IAAI,YAAY,IAAI,EAAE,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;QAC9E,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,OAAO,CAAC;AAAA,CACf;AAED,SAAS,iBAAiB,CAAC,KAAa,EAAE,OAAgC,EAAU;IACnF,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC;IACtB,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,QAAQ,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC;SAAM,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1E,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IACpE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAAA,CACvB;AAED,SAAS,iBAAiB,CAAC,QAAgB,EAAE,MAAc,EAAW;IACrE,OAAO,QAAQ,KAAK,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;AAAA,CAC9D;AAED,SAAS,oBAAoB,CAAC,GAAW,EAAE,OAAgC,EAAW;IACrF,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9E,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACJ,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrH,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAAA,CAC5E;AAED,SAAS,YAAY,CAAC,aAA6C,EAAiB;IACnF,OAAO,aAAa,KAAK,KAAK,IAAI,aAAa,KAAK,MAAM,IAAI,aAAa,KAAK,OAAO,IAAI,aAAa,KAAK,MAAM;QAClH,CAAC,CAAC,aAAa;QACf,CAAC,CAAC,IAAI,CAAC;AAAA,CACR;AAED,MAAM,UAAU,kBAAkB,GAAY;IAC7C,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACnC,cAAc,EAAE,CAAC;IACjB,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAAa,EAAE,OAAO,GAAkB,EAAE,EAA2B;IAC5G,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,sBAAsB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,OAAO,SAAS,CAAC,CAAC;IACzC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACvC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACtD,IAAI,SAAS;QAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IAEjF,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,mBAAmB,CAAC,oBAAoB,EAAE,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE;YAC1C,MAAM,EAAE,KAAK;YACb,OAAO;YACP,MAAM,EAAE,OAAO,CAAC,MAAM;gBACrB,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC3E,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,CAAC;SACzC,EAAE;YACF,GAAG,cAAc,EAAE;YACnB,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE;SAC3H,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YAClB,eAAe,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAChE,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,wBAAwB,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACxF,CAAC;QAED,IAAI,IAAqB,CAAC;QAC1B,IAAI,CAAC;YACJ,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAqB,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,kCAAkC,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,eAAe,CAAC,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QACzD,MAAM,OAAO,GAAmB,EAAE,CAAC;QACnC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;gBAAE,SAAS;YACpE,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC;YAC5F,IAAI,OAAO,CAAC,MAAM,IAAI,UAAU;gBAAE,MAAM;QACzC,CAAC;QAED,MAAM,WAAW,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAoB,EAAE,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACnK,WAAW,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO;YACvD,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,aAAa,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,GAAG,GAAG;YAC9D,CAAC,CAAC,WAAW,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAC/C,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,eAAe,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;;YACnF,eAAe,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,GAAG,CAAC;IACX,CAAC;AAAA,CACD","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport { fetchRemoteUrl, loadSsrfConfig } from \"./ssrf-protection.ts\";\nimport type { SearchOptions, SearchResult, SearchResponse } from \"./perplexity.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 30_000;\n\ninterface WebSearchConfig {\n\tsearxngBaseUrl?: unknown;\n\tsearxngHeaders?: unknown;\n}\n\ninterface NormalizedDomainFilters {\n\tallowed: string[];\n\tblocked: string[];\n}\n\ninterface SearXNGResult {\n\ttitle?: string;\n\turl?: string;\n\tcontent?: string;\n}\n\ninterface SearXNGResponse {\n\tresults?: SearXNGResult[];\n\tanswers?: string[];\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\nfunction normalizeBaseUrl(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst trimmed = value.trim();\n\tif (!trimmed) return null;\n\ttry {\n\t\tconst url = new URL(trimmed);\n\t\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") return null;\n\t\tif (url.username || url.password) return null;\n\t\turl.pathname = url.pathname.replace(/\\/+$/, \"\");\n\t\turl.search = \"\";\n\t\turl.hash = \"\";\n\t\treturn url.toString().replace(/\\/+$/, \"\");\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getBaseUrl(): string | null {\n\tconst configured = process.env.SEARXNG_BASE_URL;\n\treturn configured !== undefined\n\t\t? normalizeBaseUrl(configured)\n\t\t: normalizeBaseUrl(loadConfig().searxngBaseUrl);\n}\n\nfunction isValidHeaderValue(value: string): boolean {\n\ttry {\n\t\tnew Headers({ \"x-pi-web-access-validation\": value });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction normalizeHeaders(value: unknown): Record<string, string> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return {};\n\tconst headers: Record<string, string> = {};\n\tfor (const [key, headerValue] of Object.entries(value as Record<string, unknown>)) {\n\t\tif (typeof headerValue !== \"string\") continue;\n\t\tconst name = key.trim();\n\t\t// RFC 7230 token chars only — reject empty or malformed header names.\n\t\tif (!name || !/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(name)) continue;\n\t\tif (!isValidHeaderValue(headerValue)) continue;\n\t\theaders[name] = headerValue;\n\t}\n\treturn headers;\n}\n\nfunction getConfiguredHeaders(): Record<string, string> {\n\treturn normalizeHeaders(loadConfig().searxngHeaders);\n}\n\nfunction mergeDefaultHeaders(configured: Record<string, string>): Record<string, string> {\n\tconst headers: Record<string, string> = { Accept: \"application/json\" };\n\tfor (const [name, value] of Object.entries(configured)) {\n\t\tfor (const existing of Object.keys(headers)) {\n\t\t\tif (existing.toLowerCase() === name.toLowerCase()) delete headers[existing];\n\t\t}\n\t\theaders[name] = value;\n\t}\n\treturn headers;\n}\n\nfunction requireBaseUrl(): string {\n\tconst baseUrl = getBaseUrl();\n\tif (!baseUrl) {\n\t\tthrow new Error(\n\t\t\t\"SearXNG base URL is invalid or missing. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"searxngBaseUrl\": \"https://search.example.com\" }\\n` +\n\t\t\t\" 2. Set SEARXNG_BASE_URL to an HTTP(S) URL\",\n\t\t);\n\t}\n\treturn baseUrl;\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 normalizeDomainFilters(domainFilter: string[] | undefined): NormalizedDomainFilters {\n\tconst filters: NormalizedDomainFilters = { allowed: [], blocked: [] };\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.blocked : filters.allowed;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn filters;\n}\n\nfunction buildSearXNGQuery(query: string, filters: NormalizedDomainFilters): string {\n\tconst parts = [query];\n\tif (filters.allowed.length === 1) {\n\t\tparts.push(`site:${filters.allowed[0]}`);\n\t} else if (filters.allowed.length > 1) {\n\t\tparts.push(filters.allowed.map(domain => `site:${domain}`).join(\" OR \"));\n\t}\n\tfor (const domain of filters.blocked) parts.push(`-site:${domain}`);\n\treturn parts.join(\" \");\n}\n\nfunction hostMatchesDomain(hostname: string, domain: string): boolean {\n\treturn hostname === domain || hostname.endsWith(`.${domain}`);\n}\n\nfunction matchesDomainFilters(url: string, filters: NormalizedDomainFilters): boolean {\n\tif (filters.allowed.length === 0 && filters.blocked.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\tif (filters.allowed.length > 0 && !filters.allowed.some(domain => hostMatchesDomain(hostname, domain))) return false;\n\treturn !filters.blocked.some(domain => hostMatchesDomain(hostname, domain));\n}\n\nfunction mapTimeRange(recencyFilter: SearchOptions[\"recencyFilter\"]): string | null {\n\treturn recencyFilter === \"day\" || recencyFilter === \"week\" || recencyFilter === \"month\" || recencyFilter === \"year\"\n\t\t? recencyFilter\n\t\t: null;\n}\n\nexport function isSearXNGAvailable(): boolean {\n\tconst baseUrl = getBaseUrl();\n\tif (baseUrl === null) return false;\n\tloadSsrfConfig();\n\treturn true;\n}\n\nexport async function searchWithSearXNG(query: string, options: SearchOptions = {}): Promise<SearchResponse> {\n\tconst baseUrl = requireBaseUrl();\n\tconst numResults = normalizeCount(options.numResults);\n\tconst filters = normalizeDomainFilters(options.domainFilter);\n\tconst searchQuery = buildSearXNGQuery(query, filters);\n\tconst url = new URL(`${baseUrl}/search`);\n\turl.searchParams.set(\"q\", searchQuery);\n\turl.searchParams.set(\"format\", \"json\");\n\tconst timeRange = mapTimeRange(options.recencyFilter);\n\tif (timeRange) url.searchParams.set(\"time_range\", timeRange);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query: searchQuery });\n\n\ttry {\n\t\tconst headers = mergeDefaultHeaders(getConfiguredHeaders());\n\t\tconst response = await fetchRemoteUrl(url, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders,\n\t\t\tsignal: options.signal\n\t\t\t\t? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS), options.signal])\n\t\t\t\t: AbortSignal.timeout(SEARCH_TIMEOUT_MS),\n\t\t}, {\n\t\t\t...loadSsrfConfig(),\n\t\t\tonRedirect: ({ from, to, init }) => from.origin === to.origin ? init : { ...init, headers: { Accept: \"application/json\" } },\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tactivityMonitor.logError(activityId, `HTTP ${response.status}`);\n\t\t\tconst errorText = await response.text();\n\t\t\tthrow new Error(`SearXNG search error ${response.status}: ${errorText.slice(0, 300)}`);\n\t\t}\n\n\t\tlet data: SearXNGResponse;\n\t\ttry {\n\t\t\tdata = await response.json() as SearXNGResponse;\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tthrow new Error(`SearXNG returned invalid JSON: ${message}`);\n\t\t}\n\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tconst results: SearchResult[] = [];\n\t\tfor (const item of data.results ?? []) {\n\t\t\tif (!item.url || !matchesDomainFilters(item.url, filters)) continue;\n\t\t\tresults.push({ title: item.title || item.url, url: item.url, snippet: item.content || \"\" });\n\t\t\tif (results.length >= numResults) break;\n\t\t}\n\n\t\tconst answerParts = (data.answers ?? []).filter((answer): answer is string => typeof answer === \"string\" && answer.trim().length > 0).map(answer => answer.trim());\n\t\tanswerParts.push(...results.map(result => result.snippet\n\t\t\t? `${result.snippet}\\nSource: ${result.title} (${result.url})`\n\t\t\t: `Source: ${result.title} (${result.url})`));\n\t\treturn { answer: answerParts.join(\"\\n\\n\"), results };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tif (message.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\t\telse activityMonitor.logError(activityId, message);\n\t\tthrow err;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"searxng.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/searxng.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport { fetchRemoteUrl, loadSsrfConfig } from \"./ssrf-protection.ts\";\nimport type { SearchOptions, SearchResult, SearchResponse } from \"./perplexity.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 30_000;\n\ninterface WebSearchConfig {\n\tsearxngBaseUrl?: unknown;\n\tsearxngHeaders?: unknown;\n}\n\ninterface NormalizedDomainFilters {\n\tallowed: string[];\n\tblocked: string[];\n}\n\ninterface SearXNGResult {\n\ttitle?: string;\n\turl?: string;\n\tcontent?: string;\n}\n\ninterface SearXNGResponse {\n\tresults?: SearXNGResult[];\n\tanswers?: string[];\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\nfunction normalizeBaseUrl(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst trimmed = value.trim();\n\tif (!trimmed) return null;\n\ttry {\n\t\tconst url = new URL(trimmed);\n\t\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") return null;\n\t\tif (url.username || url.password) return null;\n\t\turl.pathname = url.pathname.replace(/\\/+$/, \"\");\n\t\turl.search = \"\";\n\t\turl.hash = \"\";\n\t\treturn url.toString().replace(/\\/+$/, \"\");\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getBaseUrl(): string | null {\n\tconst configured = process.env.SEARXNG_BASE_URL;\n\treturn configured !== undefined\n\t\t? normalizeBaseUrl(configured)\n\t\t: normalizeBaseUrl(loadConfig().searxngBaseUrl);\n}\n\nfunction isValidHeaderValue(value: string): boolean {\n\ttry {\n\t\tnew Headers({ \"x-pi-web-access-validation\": value });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction normalizeHeaders(value: unknown): Record<string, string> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return {};\n\tconst headers: Record<string, string> = {};\n\tfor (const [key, headerValue] of Object.entries(value as Record<string, unknown>)) {\n\t\tif (typeof headerValue !== \"string\") continue;\n\t\tconst name = key.trim();\n\t\t// RFC 7230 token chars only — reject empty or malformed header names.\n\t\tif (!name || !/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(name)) continue;\n\t\tif (!isValidHeaderValue(headerValue)) continue;\n\t\theaders[name] = headerValue;\n\t}\n\treturn headers;\n}\n\nfunction getConfiguredHeaders(): Record<string, string> {\n\treturn normalizeHeaders(loadConfig().searxngHeaders);\n}\n\nfunction mergeDefaultHeaders(configured: Record<string, string>): Record<string, string> {\n\tconst headers: Record<string, string> = { Accept: \"application/json\" };\n\tfor (const [name, value] of Object.entries(configured)) {\n\t\tfor (const existing of Object.keys(headers)) {\n\t\t\tif (existing.toLowerCase() === name.toLowerCase()) delete headers[existing];\n\t\t}\n\t\theaders[name] = value;\n\t}\n\treturn headers;\n}\n\nfunction requireBaseUrl(): string {\n\tconst baseUrl = getBaseUrl();\n\tif (!baseUrl) {\n\t\tthrow new Error(\n\t\t\t\"SearXNG base URL is invalid or missing. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"searxngBaseUrl\": \"https://search.example.com\" }\\n` +\n\t\t\t\" 2. Set SEARXNG_BASE_URL to an HTTP(S) URL\",\n\t\t);\n\t}\n\treturn baseUrl;\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 normalizeDomainFilters(domainFilter: string[] | undefined): NormalizedDomainFilters {\n\tconst filters: NormalizedDomainFilters = { allowed: [], blocked: [] };\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.blocked : filters.allowed;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn filters;\n}\n\nfunction buildSearXNGQuery(query: string, filters: NormalizedDomainFilters): string {\n\tconst parts = [query];\n\tif (filters.allowed.length === 1) {\n\t\tparts.push(`site:${filters.allowed[0]}`);\n\t} else if (filters.allowed.length > 1) {\n\t\tparts.push(filters.allowed.map(domain => `site:${domain}`).join(\" OR \"));\n\t}\n\tfor (const domain of filters.blocked) parts.push(`-site:${domain}`);\n\treturn parts.join(\" \");\n}\n\nfunction hostMatchesDomain(hostname: string, domain: string): boolean {\n\treturn hostname === domain || hostname.endsWith(`.${domain}`);\n}\n\nfunction matchesDomainFilters(url: string, filters: NormalizedDomainFilters): boolean {\n\tif (filters.allowed.length === 0 && filters.blocked.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\tif (filters.allowed.length > 0 && !filters.allowed.some(domain => hostMatchesDomain(hostname, domain))) return false;\n\treturn !filters.blocked.some(domain => hostMatchesDomain(hostname, domain));\n}\n\nfunction mapTimeRange(recencyFilter: SearchOptions[\"recencyFilter\"]): string | null {\n\treturn recencyFilter === \"day\" || recencyFilter === \"week\" || recencyFilter === \"month\" || recencyFilter === \"year\"\n\t\t? recencyFilter\n\t\t: null;\n}\n\nexport function isSearXNGAvailable(): boolean {\n\tconst baseUrl = getBaseUrl();\n\tif (baseUrl === null) return false;\n\tloadSsrfConfig();\n\treturn true;\n}\n\nexport async function searchWithSearXNG(query: string, options: SearchOptions = {}): Promise<SearchResponse> {\n\tconst baseUrl = requireBaseUrl();\n\tconst numResults = normalizeCount(options.numResults);\n\tconst filters = normalizeDomainFilters(options.domainFilter);\n\tconst searchQuery = buildSearXNGQuery(query, filters);\n\tconst url = new URL(`${baseUrl}/search`);\n\turl.searchParams.set(\"q\", searchQuery);\n\turl.searchParams.set(\"format\", \"json\");\n\tconst timeRange = mapTimeRange(options.recencyFilter);\n\tif (timeRange) url.searchParams.set(\"time_range\", timeRange);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query: searchQuery });\n\n\ttry {\n\t\tconst headers = mergeDefaultHeaders(getConfiguredHeaders());\n\t\tconst response = await fetchRemoteUrl(url, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders,\n\t\t\tsignal: options.signal\n\t\t\t\t? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS), options.signal])\n\t\t\t\t: AbortSignal.timeout(SEARCH_TIMEOUT_MS),\n\t\t}, {\n\t\t\t...loadSsrfConfig(),\n\t\t\tonRedirect: ({ from, to, init }) => from.origin === to.origin ? init : { ...init, headers: { Accept: \"application/json\" } },\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tactivityMonitor.logError(activityId, `HTTP ${response.status}`);\n\t\t\tconst errorText = await response.text();\n\t\t\tthrow new Error(`SearXNG search error ${response.status}: ${errorText.slice(0, 300)}`);\n\t\t}\n\n\t\tlet data: SearXNGResponse;\n\t\ttry {\n\t\t\tdata = await response.json() as SearXNGResponse;\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tthrow new Error(`SearXNG returned invalid JSON: ${message}`);\n\t\t}\n\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tconst results: SearchResult[] = [];\n\t\tfor (const item of data.results ?? []) {\n\t\t\tif (!item.url || !matchesDomainFilters(item.url, filters)) continue;\n\t\t\tresults.push({ title: item.title || item.url, url: item.url, snippet: item.content || \"\" });\n\t\t\tif (results.length >= numResults) break;\n\t\t}\n\n\t\tconst answerParts = (data.answers ?? []).filter((answer): answer is string => typeof answer === \"string\" && answer.trim().length > 0).map(answer => answer.trim());\n\t\tanswerParts.push(...results.map(result => result.snippet\n\t\t\t? `${result.snippet}\\nSource: ${result.title} (${result.url})`\n\t\t\t: `Source: ${result.title} (${result.url})`));\n\t\treturn { answer: answerParts.join(\"\\n\\n\"), results };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tif (message.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\t\telse activityMonitor.logError(activityId, message);\n\t\tthrow err;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serpbase.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/serpbase.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAwKrE,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAqD5G"
|
|
1
|
+
{"version":3,"file":"serpbase.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/serpbase.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAwKrE,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAqD5G"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serpbase.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/serpbase.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst SERPBASE_API_URL = \"https://api.serpbase.dev/google/search\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\nconst RECENCY_TBS: Record<string, string> = {\n\tday: \"qdr:d\",\n\tweek: \"qdr:w\",\n\tmonth: \"qdr:m\",\n\tyear: \"qdr:y\",\n};\n\ninterface WebSearchConfig {\n\tserpbaseApiKey?: unknown;\n}\n\ninterface SerpBaseOrganicResult {\n\ttitle?: unknown;\n\tlink?: unknown;\n\turl?: unknown;\n\tsnippet?: unknown;\n\tdescription?: unknown;\n}\n\ninterface SerpBaseResponse {\n\torganic_results?: SerpBaseOrganicResult[];\n\torganic?: SerpBaseOrganicResult[];\n\tresults?: SerpBaseOrganicResult[];\n\tstatus?: unknown;\n\terror?: unknown;\n\tmessage?: unknown;\n}\n\nlet cachedConfig: WebSearchConfig | null = null;\n\nfunction loadConfig(): WebSearchConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\tconst raw = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"SerpBase\",\n\t\tconfiguredValue: loadConfig().serpbaseApiKey,\n\t\tenvironmentValue: process.env.SERPBASE_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\"SerpBase API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"serpbaseApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set SERPBASE_API_KEY environment variable\\n\" +\n\t\t\t\"Get a key at https://serpbase.dev\",\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 10;\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\ninterface DomainFilters {\n\tinclude: string[];\n\texclude: string[];\n}\n\nfunction parseDomainFilter(domainFilter: string[] | undefined): DomainFilters {\n\tconst filters: DomainFilters = { include: [], exclude: [] };\n\tif (!domainFilter?.length) return filters;\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 domainMatches(hostname: string, domain: string): boolean {\n\treturn hostname === domain || hostname.endsWith(`.${domain}`);\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\tif (filters.exclude.some((domain) => domainMatches(hostname, domain))) return false;\n\tif (filters.include.length === 0) return true;\n\treturn filters.include.some((domain) => domainMatches(hostname, domain));\n}\n\nfunction buildQuery(query: string, filters: DomainFilters): string {\n\tconst parts = [query];\n\tif (filters.include.length === 1) parts.push(`site:${filters.include[0]}`);\n\tif (filters.include.length > 1) parts.push(`(${filters.include.map(domain => `site:${domain}`).join(\" OR \")})`);\n\tfor (const domain of filters.exclude) parts.push(`-site:${domain}`);\n\treturn parts.join(\" \");\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction invalidResponse(message: string): Error {\n\treturn new Error(`SerpBase API returned invalid response: ${message}`);\n}\n\nfunction parseResponse(value: unknown): SerpBaseResponse {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw invalidResponse(\"expected an object envelope\");\n\tconst envelope = value as SerpBaseResponse;\n\tif (typeof envelope.error === \"string\" && envelope.error.trim()) {\n\t\tconst suffix = typeof envelope.status === \"number\" || typeof envelope.status === \"string\" ? ` (status ${envelope.status})` : \"\";\n\t\tthrow invalidResponse(`${envelope.error}${suffix}`);\n\t}\n\tconst organic = envelope.organic_results ?? envelope.organic ?? envelope.results;\n\tif (!Array.isArray(organic)) throw invalidResponse(\"expected organic_results array\");\n\treturn { ...envelope, organic_results: organic };\n}\n\nfunction buildAnswer(results: SearchResponse[\"results\"]): string {\n\treturn results.map((result) => result.snippet\n\t\t? `${result.snippet}\\nSource: ${result.title} (${result.url})`\n\t\t: `Source: ${result.title} (${result.url})`).join(\"\\n\\n\");\n}\n\nexport function isSerpBaseAvailable(): boolean {\n\treturn hasCredentialSource({ provider: \"SerpBase\", configuredValue: loadConfig().serpbaseApiKey, environmentValue: process.env.SERPBASE_API_KEY });\n}\n\nexport async function searchWithSerpBase(query: string, options: SearchOptions = {}): Promise<SearchResponse> {\n\tconst apiKey = await requireApiKey(options.signal);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst filters = parseDomainFilter(options.domainFilter);\n\tconst url = new URL(SERPBASE_API_URL);\n\turl.searchParams.set(\"q\", buildQuery(query, filters));\n\t// SerpBase's Google Search endpoint authenticates with an `api_key` query parameter.\n\turl.searchParams.set(\"api_key\", apiKey);\n\turl.searchParams.set(\"num\", String(numResults));\n\tif (options.recencyFilter && RECENCY_TBS[options.recencyFilter]) url.searchParams.set(\"tbs\", RECENCY_TBS[options.recencyFilter]);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\theaders: { Accept: \"application/json\" },\n\t\t\tsignal: options.signal ? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS), options.signal]) : AbortSignal.timeout(SEARCH_TIMEOUT_MS),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\t\telse activityMonitor.logError(activityId, redactedMessage);\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n\tif (!response.ok) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tconst errorText = redactCredential(await response.text(), apiKey);\n\t\tthrow new Error(`SerpBase API error ${response.status}: ${errorText.slice(0, 300)}`);\n\t}\n\tlet rawData: unknown;\n\ttry {\n\t\trawData = await response.json();\n\t} catch (err) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`SerpBase API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\tconst data = parseResponse(rawData);\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst results: SearchResponse[\"results\"] = [];\n\tfor (const item of data.organic_results ?? []) {\n\t\tconst url = typeof item.link === \"string\" ? item.link : typeof item.url === \"string\" ? item.url : \"\";\n\t\tif (!url || !passesDomainFilters(url, filters)) continue;\n\t\tresults.push({\n\t\t\ttitle: typeof item.title === \"string\" && item.title.trim() ? item.title : `Source ${results.length + 1}`,\n\t\t\turl,\n\t\t\tsnippet: typeof item.snippet === \"string\" ? item.snippet : typeof item.description === \"string\" ? item.description : \"\",\n\t\t});\n\t\tif (results.length >= numResults) break;\n\t}\n\treturn { answer: buildAnswer(results), results };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"serpbase.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/serpbase.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst SERPBASE_API_URL = \"https://api.serpbase.dev/google/search\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\nconst RECENCY_TBS: Record<string, string> = {\n\tday: \"qdr:d\",\n\tweek: \"qdr:w\",\n\tmonth: \"qdr:m\",\n\tyear: \"qdr:y\",\n};\n\ninterface WebSearchConfig {\n\tserpbaseApiKey?: unknown;\n}\n\ninterface SerpBaseOrganicResult {\n\ttitle?: unknown;\n\tlink?: unknown;\n\turl?: unknown;\n\tsnippet?: unknown;\n\tdescription?: unknown;\n}\n\ninterface SerpBaseResponse {\n\torganic_results?: SerpBaseOrganicResult[];\n\torganic?: SerpBaseOrganicResult[];\n\tresults?: SerpBaseOrganicResult[];\n\tstatus?: unknown;\n\terror?: unknown;\n\tmessage?: unknown;\n}\n\nlet cachedConfig: WebSearchConfig | null = null;\n\nfunction loadConfig(): WebSearchConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\tconst raw = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"SerpBase\",\n\t\tconfiguredValue: loadConfig().serpbaseApiKey,\n\t\tenvironmentValue: process.env.SERPBASE_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\"SerpBase API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"serpbaseApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set SERPBASE_API_KEY environment variable\\n\" +\n\t\t\t\"Get a key at https://serpbase.dev\",\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 10;\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\ninterface DomainFilters {\n\tinclude: string[];\n\texclude: string[];\n}\n\nfunction parseDomainFilter(domainFilter: string[] | undefined): DomainFilters {\n\tconst filters: DomainFilters = { include: [], exclude: [] };\n\tif (!domainFilter?.length) return filters;\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 domainMatches(hostname: string, domain: string): boolean {\n\treturn hostname === domain || hostname.endsWith(`.${domain}`);\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\tif (filters.exclude.some((domain) => domainMatches(hostname, domain))) return false;\n\tif (filters.include.length === 0) return true;\n\treturn filters.include.some((domain) => domainMatches(hostname, domain));\n}\n\nfunction buildQuery(query: string, filters: DomainFilters): string {\n\tconst parts = [query];\n\tif (filters.include.length === 1) parts.push(`site:${filters.include[0]}`);\n\tif (filters.include.length > 1) parts.push(`(${filters.include.map(domain => `site:${domain}`).join(\" OR \")})`);\n\tfor (const domain of filters.exclude) parts.push(`-site:${domain}`);\n\treturn parts.join(\" \");\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction invalidResponse(message: string): Error {\n\treturn new Error(`SerpBase API returned invalid response: ${message}`);\n}\n\nfunction parseResponse(value: unknown): SerpBaseResponse {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw invalidResponse(\"expected an object envelope\");\n\tconst envelope = value as SerpBaseResponse;\n\tif (typeof envelope.error === \"string\" && envelope.error.trim()) {\n\t\tconst suffix = typeof envelope.status === \"number\" || typeof envelope.status === \"string\" ? ` (status ${envelope.status})` : \"\";\n\t\tthrow invalidResponse(`${envelope.error}${suffix}`);\n\t}\n\tconst organic = envelope.organic_results ?? envelope.organic ?? envelope.results;\n\tif (!Array.isArray(organic)) throw invalidResponse(\"expected organic_results array\");\n\treturn { ...envelope, organic_results: organic };\n}\n\nfunction buildAnswer(results: SearchResponse[\"results\"]): string {\n\treturn results.map((result) => result.snippet\n\t\t? `${result.snippet}\\nSource: ${result.title} (${result.url})`\n\t\t: `Source: ${result.title} (${result.url})`).join(\"\\n\\n\");\n}\n\nexport function isSerpBaseAvailable(): boolean {\n\treturn hasCredentialSource({ provider: \"SerpBase\", configuredValue: loadConfig().serpbaseApiKey, environmentValue: process.env.SERPBASE_API_KEY });\n}\n\nexport async function searchWithSerpBase(query: string, options: SearchOptions = {}): Promise<SearchResponse> {\n\tconst apiKey = await requireApiKey(options.signal);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst filters = parseDomainFilter(options.domainFilter);\n\tconst url = new URL(SERPBASE_API_URL);\n\turl.searchParams.set(\"q\", buildQuery(query, filters));\n\t// SerpBase's Google Search endpoint authenticates with an `api_key` query parameter.\n\turl.searchParams.set(\"api_key\", apiKey);\n\turl.searchParams.set(\"num\", String(numResults));\n\tif (options.recencyFilter && RECENCY_TBS[options.recencyFilter]) url.searchParams.set(\"tbs\", RECENCY_TBS[options.recencyFilter]);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\theaders: { Accept: \"application/json\" },\n\t\t\tsignal: options.signal ? AbortSignal.any([AbortSignal.timeout(SEARCH_TIMEOUT_MS), options.signal]) : AbortSignal.timeout(SEARCH_TIMEOUT_MS),\n\t\t});\n\t} catch (err) {\n\t\tconst message = errorMessage(err);\n\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\tif (redactedMessage.toLowerCase().includes(\"abort\")) activityMonitor.logComplete(activityId, 0);\n\t\telse activityMonitor.logError(activityId, redactedMessage);\n\t\tif (redactedMessage === message) throw err;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\tthrow redactedError;\n\t}\n\tif (!response.ok) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tconst errorText = redactCredential(await response.text(), apiKey);\n\t\tthrow new Error(`SerpBase API error ${response.status}: ${errorText.slice(0, 300)}`);\n\t}\n\tlet rawData: unknown;\n\ttry {\n\t\trawData = await response.json();\n\t} catch (err) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`SerpBase API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\tconst data = parseResponse(rawData);\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst results: SearchResponse[\"results\"] = [];\n\tfor (const item of data.organic_results ?? []) {\n\t\tconst url = typeof item.link === \"string\" ? item.link : typeof item.url === \"string\" ? item.url : \"\";\n\t\tif (!url || !passesDomainFilters(url, filters)) continue;\n\t\tresults.push({\n\t\t\ttitle: typeof item.title === \"string\" && item.title.trim() ? item.title : `Source ${results.length + 1}`,\n\t\t\turl,\n\t\t\tsnippet: typeof item.snippet === \"string\" ? item.snippet : typeof item.description === \"string\" ? item.description : \"\",\n\t\t});\n\t\tif (results.length >= numResults) break;\n\t}\n\treturn { answer: buildAnswer(results), results };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serpdive.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/serpdive.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAsCrE,UAAU,qBAAsB,SAAQ,aAAa;IACpD,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAqLD,wBAAgB,mBAAmB,IAAI,OAAO,CAM7C;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,cAAc,CAAC,CAgEpH","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 SERPDIVE_API_URL = \"https://api.serpdive.com/v1/search\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\n\n// Retrieval depth. The default is deliberately the free tier: this provider\n// ships inside someone else's framework, and installing it must never start\n// spending on a user's behalf without them choosing it.\n// krill — free, fair use, no synthesized answer (see buildAnswer below)\n// mako — the fact-carrying sentences of each page, 1 credit\n// moby — the full readable content of every page, 1.5 credits\n// Pricing: https://serpdive.com/pricing\nconst MODELS = [\"krill\", \"mako\", \"moby\"] as const;\ntype SerpdiveModel = (typeof MODELS)[number];\nconst DEFAULT_MODEL: SerpdiveModel = \"krill\";\n\ninterface WebSearchConfig {\n\tserpdiveApiKey?: unknown;\n\tserpdiveModel?: unknown;\n}\n\ninterface SerpdiveResult {\n\turl?: string;\n\ttitle?: string | null;\n\tdate?: string;\n\tcontent?: string;\n}\n\ninterface SerpdiveResponse {\n\tquery?: string;\n\tmodel?: string;\n\tanswer?: string | null;\n\tresults?: SerpdiveResult[];\n}\n\ninterface SerpdiveSearchOptions 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: \"SERPdive\",\n\t\tconfiguredValue: loadConfig().serpdiveApiKey,\n\t\tenvironmentValue: process.env.SERPDIVE_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\"SERPdive API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"serpdiveApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set SERPDIVE_API_KEY environment variable\\n\" +\n\t\t\t\"Get a key at https://serpdive.com/dashboard/keys\",\n\t\t);\n\t}\n\treturn apiKey;\n}\n\n// An unknown value falls back to the free default rather than failing: a typo\n// in a config file must not cost the user money, and must not break search.\nfunction resolveModel(): SerpdiveModel {\n\tconst raw = process.env.SERPDIVE_MODEL ?? loadConfig().serpdiveModel;\n\tif (typeof raw !== \"string\") return DEFAULT_MODEL;\n\tconst value = raw.trim().toLowerCase();\n\treturn (MODELS as readonly string[]).includes(value) ? value as SerpdiveModel : DEFAULT_MODEL;\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\ninterface DomainFilters {\n\tinclude: string[];\n\texclude: string[];\n}\n\nfunction parseDomainFilter(domainFilter: string[] | undefined): DomainFilters {\n\tconst filters: DomainFilters = { include: [], exclude: [] };\n\tif (!domainFilter?.length) return filters;\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 domainMatches(hostname: string, domain: string): boolean {\n\treturn hostname === domain || hostname.endsWith(`.${domain}`);\n}\n\n// SERPdive exposes no include/exclude domain parameter, so the filter is applied\n// here, on what came back. It can therefore only ever narrow a page of results —\n// it cannot ask the engine for more pages from a given domain.\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\tif (filters.exclude.some((domain) => domainMatches(hostname, domain))) return false;\n\tif (filters.include.length === 0) return true;\n\treturn filters.include.some((domain) => domainMatches(hostname, domain));\n}\n\n// SERPdive has NO time-range parameter. Recency is expressed inside the question\n// and read by the engine, which biases ranking toward recent pages — it is a\n// hint, never a guaranteed freshness filter, and results outside the window can\n// still come back.\nfunction applyRecencyHint(query: string, recencyFilter: SearchOptions[\"recencyFilter\"]): string {\n\tif (!recencyFilter) return query;\n\tconst hints: Record<string, string> = {\n\t\tday: \"past 24 hours\",\n\t\tweek: \"past week\",\n\t\tmonth: \"past month\",\n\t\tyear: \"past year\",\n\t};\n\tconst hint = hints[recencyFilter];\n\treturn hint ? `${query} ${hint}` : query;\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(\n\tresults: SerpdiveResult[] | undefined,\n\tnumResults: number,\n\tfilters: DomainFilters,\n): SearchResponse[\"results\"] {\n\tif (!Array.isArray(results)) return [];\n\tconst mapped: SearchResponse[\"results\"] = [];\n\tfor (const item of results) {\n\t\tif (!item?.url || !passesDomainFilters(item.url, filters)) 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: SerpdiveResult[] | undefined, filters: DomainFilters): ExtractedContent[] {\n\tif (!Array.isArray(results)) return [];\n\treturn results.flatMap((item) => {\n\t\tif (!item?.url || !passesDomainFilters(item.url, filters)) return [];\n\t\tif (typeof item.content !== \"string\" || item.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.content,\n\t\t\terror: null,\n\t\t}];\n\t});\n}\n\n// The free krill tier returns extracted content but no synthesized answer, so\n// one is assembled from the sources — the same shape brave.ts and searxng.ts\n// produce for providers that do not synthesize. mako and moby ask the API for a\n// real answer and use it when it comes back.\nfunction buildAnswer(apiAnswer: string | null | undefined, results: SearchResponse[\"results\"]): string {\n\tif (typeof apiAnswer === \"string\" && apiAnswer.trim().length > 0) return apiAnswer;\n\treturn results\n\t\t.map((result) => {\n\t\t\tif (result.snippet) return `${result.snippet}\\nSource: ${result.title} (${result.url})`;\n\t\t\treturn `Source: ${result.title} (${result.url})`;\n\t\t})\n\t\t.join(\"\\n\\n\");\n}\n\nexport function isSerpdiveAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"SERPdive\",\n\t\tconfiguredValue: loadConfig().serpdiveApiKey,\n\t\tenvironmentValue: process.env.SERPDIVE_API_KEY,\n\t});\n}\n\nexport async function searchWithSerpdive(query: string, options: SerpdiveSearchOptions = {}): Promise<SearchResponse> {\n\tconst apiKey = await requireApiKey(options.signal);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst filters = parseDomainFilter(options.domainFilter);\n\tconst model = resolveModel();\n\tconst body: Record<string, unknown> = {\n\t\tquery: applyRecencyHint(query, options.recencyFilter),\n\t\tmodel,\n\t\t// max_results is a CAP, never a minimum: the engine returns what it\n\t\t// judges relevant, up to this many. Asking for more does not produce more.\n\t\tmax_results: Math.min(numResults, 10),\n\t\t// krill has no answer synthesis — asking for one there is silently ignored\n\t\t// by the API, so it is not asked for at all.\n\t\t...(model === \"krill\" ? {} : { answer: true }),\n\t};\n\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(SERPDIVE_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(`SERPdive API error ${response.status}: ${errorText.slice(0, 300)}`);\n\t}\n\n\tlet data: SerpdiveResponse;\n\ttry {\n\t\tdata = await response.json() as SerpdiveResponse;\n\t} catch (err) {\n\t\tactivityMonitor.logComplete(activityId, response.status);\n\t\tthrow new Error(`SERPdive API returned invalid JSON: ${errorMessage(err)}`);\n\t}\n\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst results = mapResults(data.results, numResults, filters);\n\tconst result: SearchResponse = {\n\t\tanswer: buildAnswer(data.answer, results),\n\t\tresults,\n\t};\n\tif (options.includeContent) {\n\t\tconst inlineContent = mapInlineContent(data.results, filters);\n\t\tif (inlineContent.length > 0) result.inlineContent = inlineContent;\n\t}\n\treturn result;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"serpdive.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/serpdive.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAsCrE,UAAU,qBAAsB,SAAQ,aAAa;IACpD,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAqLD,wBAAgB,mBAAmB,IAAI,OAAO,CAM7C;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,cAAc,CAAC,CAgEpH"}
|