@humain/terminal 0.0.6 → 0.0.7
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 +52 -0
- package/README.md +10 -4
- package/dist/bundle/chunks/anthropic-messages-GDMGYAZB.js +6 -0
- package/dist/bundle/chunks/anthropic.js +75 -0
- package/dist/bundle/chunks/azure-openai-responses-ZN52D6YC.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +77 -0
- package/dist/bundle/chunks/chunk-3D3G2X5U.js +6 -0
- package/dist/bundle/chunks/chunk-3VI4HD7D.js +31 -0
- package/dist/bundle/chunks/chunk-6R7UI4IY.js +2 -0
- package/dist/bundle/chunks/chunk-72KO4OMP.js +2 -0
- package/dist/bundle/chunks/chunk-7DDKXS2Q.js +2 -0
- package/dist/bundle/chunks/chunk-ARF4OE6X.js +105 -0
- package/dist/bundle/chunks/chunk-BOW22LW6.js +42 -0
- package/dist/bundle/chunks/chunk-BZQ53VGE.js +70 -0
- package/dist/bundle/chunks/chunk-CBHC6EL7.js +133 -0
- package/dist/bundle/chunks/chunk-D7XAASZM.js +4 -0
- package/dist/bundle/chunks/chunk-ECWELYBH.js +17 -0
- package/dist/bundle/chunks/chunk-GMWCTUPB.js +2 -0
- package/dist/bundle/chunks/chunk-H2O6VOXT.js +11 -0
- package/dist/bundle/chunks/chunk-HNVPY4LZ.js +5995 -0
- package/dist/bundle/chunks/chunk-JUUC5AZY.js +2 -0
- package/dist/bundle/chunks/chunk-JXWJOIH4.js +2 -0
- package/dist/bundle/chunks/chunk-L2ZPNLYD.js +2 -0
- package/dist/bundle/chunks/chunk-LVVZS2NO.js +12 -0
- package/dist/bundle/chunks/chunk-M2GYSCCG.js +44 -0
- package/dist/bundle/chunks/chunk-MA4UUCYX.js +18 -0
- package/dist/bundle/chunks/chunk-PGXDEOVV.js +2 -0
- package/dist/bundle/chunks/chunk-PJACZCIR.js +2 -0
- package/dist/bundle/chunks/chunk-PRRNXB7S.js +2 -0
- package/dist/bundle/chunks/chunk-SGTGQNNP.js +4 -0
- package/dist/bundle/chunks/chunk-TEPMHNKQ.js +2 -0
- package/dist/bundle/chunks/chunk-TXBQIIIO.js +2 -0
- package/dist/bundle/chunks/chunk-WJZ4KLGL.js +2 -0
- package/dist/bundle/chunks/chunk-XNGRGP62.js +2 -0
- package/dist/bundle/chunks/dist-7DSXV2TY.js +9 -0
- package/dist/bundle/chunks/dist-BXEVYJIO.js +7 -0
- package/dist/bundle/chunks/es-P2KNSZYR.js +9 -0
- package/dist/bundle/chunks/es5-FGTJ7ZFW.js +2 -0
- package/dist/bundle/chunks/event-streams-JOSQQSII.js +2 -0
- package/dist/bundle/chunks/extract-2L7ZVN7F.js +106 -0
- package/dist/bundle/chunks/github-copilot.js +2 -0
- package/dist/bundle/chunks/google-generative-ai-XT7NQJ2E.js +2 -0
- package/dist/bundle/chunks/google-vertex-IDQ6Z53W.js +2 -0
- package/dist/bundle/chunks/image-resize-worker.js +2 -0
- package/dist/bundle/chunks/kimi-coding.js +2 -0
- package/dist/bundle/chunks/mistral-conversations-HHDZ4FHR.js +5 -0
- package/dist/bundle/chunks/multipart-parser-FMGQ7342.js +3 -0
- package/dist/bundle/chunks/node-XY3CBY3C.js +294 -0
- package/dist/bundle/chunks/node-ZHY4LHC7.js +15 -0
- package/dist/bundle/chunks/openai-codex-responses-HRVCDY54.js +8 -0
- package/dist/bundle/chunks/openai-codex.js +75 -0
- package/dist/bundle/chunks/openai-completions-6QBYTBXY.js +7 -0
- package/dist/bundle/chunks/openai-responses-4MWLJHIK.js +2 -0
- package/dist/bundle/chunks/openrouter-images-Y2PCWAQH.js +2 -0
- package/dist/bundle/chunks/openrouter.js +75 -0
- package/dist/bundle/chunks/pdfjs-UKQT3OWY.js +107 -0
- package/dist/bundle/chunks/pi-messages-57K43J6J.js +8 -0
- package/dist/bundle/chunks/promise-J5TGSM32.js +2 -0
- package/dist/bundle/chunks/radius.js +75 -0
- package/dist/bundle/chunks/src-QKGKDFSU.js +4 -0
- package/dist/bundle/chunks/undici-D6ABF53Q.js +2 -0
- package/dist/bundle/chunks/webapi-AFS5FDJJ.js +5 -0
- package/dist/bundle/chunks/xai.js +2 -0
- package/dist/bundle/cli.js +3 -0
- package/dist/bundle/client.js +2 -0
- package/dist/bundle/index.js +2 -0
- package/dist/bundle/rpc-entry.js +3 -0
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +29 -9
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -11
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +50 -14
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +163 -95
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +6 -7
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +115 -48
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +38 -9
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +3 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/keybindings.d.ts +20 -19
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +26 -5
- package/dist/core/keybindings.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 +3 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +14 -8
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +22 -14
- 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 +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +2 -1
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +3 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +10 -3
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-export.d.ts +4 -0
- package/dist/core/session-export.d.ts.map +1 -0
- package/dist/core/session-export.js +32 -0
- package/dist/core/session-export.js.map +1 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +9 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +51 -10
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +51 -33
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +11 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +16 -3
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +62 -29
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- 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 +20 -4
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/index.d.ts +4 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +19 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/powershell.d.ts +16 -0
- package/dist/core/tools/powershell.d.ts.map +1 -0
- package/dist/core/tools/powershell.js +39 -0
- package/dist/core/tools/powershell.js.map +1 -0
- package/dist/core/tools/subagent.d.ts.map +1 -1
- package/dist/core/tools/subagent.js +4 -1
- package/dist/core/tools/subagent.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- 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 +6 -2
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/humain/agent-execution-protocol.d.ts +1 -217
- package/dist/humain/agent-execution-protocol.d.ts.map +1 -1
- package/dist/humain/agent-execution-protocol.js +1 -203
- package/dist/humain/agent-execution-protocol.js.map +1 -1
- package/dist/humain/bedrock-provider/vendor/index.bundle.mjs +107 -16
- package/dist/humain/mcp-adapter/vendor/CHANGELOG.md +82 -0
- package/dist/humain/mcp-adapter/vendor/README.md +47 -15
- package/dist/humain/mcp-adapter/vendor/cli.js +4 -4
- package/dist/humain/mcp-adapter/vendor/commands.ts +5 -3
- package/dist/humain/mcp-adapter/vendor/config.ts +46 -5
- package/dist/humain/mcp-adapter/vendor/direct-tools.ts +103 -92
- package/dist/humain/mcp-adapter/vendor/dist/agent-dir.d.ts +10 -0
- package/dist/humain/mcp-adapter/vendor/dist/agent-dir.js +63 -0
- package/dist/humain/mcp-adapter/vendor/dist/agent-dir.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-loader.d.ts +8 -0
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-loader.js +356 -0
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-loader.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/config.d.ts +123 -0
- package/dist/humain/mcp-adapter/vendor/dist/config.js +1088 -0
- package/dist/humain/mcp-adapter/vendor/dist/config.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/mcp-bearer-store.d.ts +24 -0
- package/dist/humain/mcp-adapter/vendor/dist/mcp-bearer-store.js +336 -0
- package/dist/humain/mcp-adapter/vendor/dist/mcp-bearer-store.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/metadata-cache.d.ts +19 -0
- package/dist/humain/mcp-adapter/vendor/dist/metadata-cache.js +319 -0
- package/dist/humain/mcp-adapter/vendor/dist/metadata-cache.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/package-mcp-loader.d.ts +2 -0
- package/dist/humain/mcp-adapter/vendor/dist/package-mcp-loader.js +156 -0
- package/dist/humain/mcp-adapter/vendor/dist/package-mcp-loader.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/resource-tools.d.ts +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/resource-tools.js +15 -0
- package/dist/humain/mcp-adapter/vendor/dist/resource-tools.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/types.d.ts +566 -0
- package/dist/humain/mcp-adapter/vendor/dist/types.js +287 -0
- package/dist/humain/mcp-adapter/vendor/dist/types.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/ui-app-bridge-helpers.d.ts +6 -0
- package/dist/humain/mcp-adapter/vendor/dist/ui-app-bridge-helpers.js +37 -0
- package/dist/humain/mcp-adapter/vendor/dist/ui-app-bridge-helpers.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/ui-stream-types.d.ts +104 -0
- package/dist/humain/mcp-adapter/vendor/dist/ui-stream-types.js +59 -0
- package/dist/humain/mcp-adapter/vendor/dist/ui-stream-types.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/ui-tool-visibility.d.ts +4 -0
- package/dist/humain/mcp-adapter/vendor/dist/ui-tool-visibility.js +27 -0
- package/dist/humain/mcp-adapter/vendor/dist/ui-tool-visibility.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/utils.d.ts +32 -0
- package/dist/humain/mcp-adapter/vendor/dist/utils.js +338 -0
- package/dist/humain/mcp-adapter/vendor/dist/utils.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/failure-backoff.ts +23 -0
- package/dist/humain/mcp-adapter/vendor/index.bundle.mjs +4870 -3878
- package/dist/humain/mcp-adapter/vendor/index.ts +294 -88
- package/dist/humain/mcp-adapter/vendor/init.ts +41 -30
- package/dist/humain/mcp-adapter/vendor/lifecycle.ts +16 -8
- package/dist/humain/mcp-adapter/vendor/mcp-auth-flow.ts +124 -32
- package/dist/humain/mcp-adapter/vendor/mcp-bearer-store.ts +0 -2
- package/dist/humain/mcp-adapter/vendor/mcp-code.ts +2 -0
- package/dist/humain/mcp-adapter/vendor/mcp-oauth-provider.ts +155 -16
- package/dist/humain/mcp-adapter/vendor/mcp-output-guard.ts +95 -7
- package/dist/humain/mcp-adapter/vendor/mcp-probe.ts +18 -4
- package/dist/humain/mcp-adapter/vendor/mcp-references.ts +376 -0
- package/dist/humain/mcp-adapter/vendor/mcp-status.ts +8 -19
- package/dist/humain/mcp-adapter/vendor/metadata-cache.ts +20 -12
- package/dist/humain/mcp-adapter/vendor/namespace-tools.ts +276 -0
- package/dist/humain/mcp-adapter/vendor/package.json +26 -8
- package/dist/humain/mcp-adapter/vendor/proxy-modes.ts +128 -32
- package/dist/humain/mcp-adapter/vendor/request-headers-command.ts +1 -1
- package/dist/humain/mcp-adapter/vendor/search-ranking.ts +2 -0
- package/dist/humain/mcp-adapter/vendor/server-manager.ts +69 -12
- package/dist/humain/mcp-adapter/vendor/state.ts +1 -3
- package/dist/humain/mcp-adapter/vendor/tool-result-renderer.ts +16 -2
- package/dist/humain/mcp-adapter/vendor/types.ts +51 -2
- package/dist/humain/mcp-adapter/vendor/ui-server.ts +3 -19
- package/dist/humain/mcp-adapter/vendor/ui-session.ts +2 -1
- package/dist/humain/mcp-adapter/vendor/utils.ts +21 -19
- package/dist/humain/mcp-adapter.d.ts.map +1 -1
- package/dist/humain/mcp-adapter.js +4 -0
- package/dist/humain/mcp-adapter.js.map +1 -1
- package/dist/humain/web-access/vendor/chrome-cookies.d.ts +14 -0
- package/dist/humain/web-access/vendor/chrome-cookies.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/chrome-cookies.js +85 -33
- package/dist/humain/web-access/vendor/chrome-cookies.js.map +1 -1
- package/dist/humain/web-access/vendor/credential-source.d.ts +1 -1
- package/dist/humain/web-access/vendor/credential-source.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/credential-source.js +3 -1
- package/dist/humain/web-access/vendor/credential-source.js.map +1 -1
- package/dist/humain/web-access/vendor/curator-page.d.ts +2 -29
- package/dist/humain/web-access/vendor/curator-page.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/curator-page.js +10 -1
- package/dist/humain/web-access/vendor/curator-page.js.map +1 -1
- package/dist/humain/web-access/vendor/curator-server.d.ts +2 -29
- package/dist/humain/web-access/vendor/curator-server.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/curator-server.js +4 -0
- package/dist/humain/web-access/vendor/curator-server.js.map +1 -1
- package/dist/humain/web-access/vendor/extract.d.ts +11 -0
- package/dist/humain/web-access/vendor/extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/extract.js +163 -20
- package/dist/humain/web-access/vendor/extract.js.map +1 -1
- package/dist/humain/web-access/vendor/fetch-params.d.ts +2 -0
- package/dist/humain/web-access/vendor/fetch-params.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/fetch-params.js +11 -0
- package/dist/humain/web-access/vendor/fetch-params.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-adc.d.ts +10 -0
- package/dist/humain/web-access/vendor/gemini-adc.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-adc.js +268 -0
- package/dist/humain/web-access/vendor/gemini-adc.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-api.d.ts +7 -1
- package/dist/humain/web-access/vendor/gemini-api.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-api.js +51 -15
- package/dist/humain/web-access/vendor/gemini-api.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-search.d.ts +9 -4
- package/dist/humain/web-access/vendor/gemini-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-search.js +63 -21
- 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 +3 -2
- package/dist/humain/web-access/vendor/gemini-url-context.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-web-config.d.ts +8 -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 +49 -4
- package/dist/humain/web-access/vendor/gemini-web-config.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-web.d.ts +2 -1
- package/dist/humain/web-access/vendor/gemini-web.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-web.js +8 -3
- package/dist/humain/web-access/vendor/gemini-web.js.map +1 -1
- package/dist/humain/web-access/vendor/github-api.d.ts +1 -1
- package/dist/humain/web-access/vendor/github-api.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/github-api.js +6 -4
- 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 +50 -3
- package/dist/humain/web-access/vendor/github-extract.js.map +1 -1
- package/dist/humain/web-access/vendor/github-issue-pr.d.ts +27 -0
- package/dist/humain/web-access/vendor/github-issue-pr.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/github-issue-pr.js +701 -0
- package/dist/humain/web-access/vendor/github-issue-pr.js.map +1 -0
- package/dist/humain/web-access/vendor/index.d.ts +3 -31
- package/dist/humain/web-access/vendor/index.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/index.js +643 -530
- package/dist/humain/web-access/vendor/index.js.map +1 -1
- package/dist/humain/web-access/vendor/kimi-search.d.ts +5 -0
- package/dist/humain/web-access/vendor/kimi-search.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/kimi-search.js +228 -0
- package/dist/humain/web-access/vendor/kimi-search.js.map +1 -0
- package/dist/humain/web-access/vendor/openai-search.d.ts +3 -0
- package/dist/humain/web-access/vendor/openai-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/openai-search.js +89 -16
- package/dist/humain/web-access/vendor/openai-search.js.map +1 -1
- package/dist/humain/web-access/vendor/page-query.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/page-query.js +56 -8
- package/dist/humain/web-access/vendor/page-query.js.map +1 -1
- package/dist/humain/web-access/vendor/ssrf-protection.js +6 -1
- package/dist/humain/web-access/vendor/ssrf-protection.js.map +1 -1
- package/dist/humain/web-access/vendor/utils.d.ts +12 -0
- package/dist/humain/web-access/vendor/utils.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/utils.js +343 -1
- package/dist/humain/web-access/vendor/utils.js.map +1 -1
- package/dist/humain/web-access/vendor/xcrawl.d.ts +4 -0
- package/dist/humain/web-access/vendor/xcrawl.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/xcrawl.js +251 -0
- package/dist/humain/web-access/vendor/xcrawl.js.map +1 -0
- package/dist/humain/web-access/vendor/youtube-extract.js +2 -2
- package/dist/humain/web-access/vendor/youtube-extract.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +17 -14
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +9 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +53 -10
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +7 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +118 -55
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +151 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +68 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +11 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +176 -106
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/session-share.d.ts +16 -0
- package/dist/modes/interactive/session-share.d.ts.map +1 -0
- package/dist/modes/interactive/session-share.js +188 -0
- package/dist/modes/interactive/session-share.js.map +1 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +6 -5
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +16 -13
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +20 -6
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +3 -2
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +2 -7
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +189 -3
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/changelog.d.ts +1 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js +12 -2
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/shell.d.ts +3 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +17 -5
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +64 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/utils/version-check.js +4 -4
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +15 -0
- package/docs/custom-provider.md +5 -2
- package/docs/environment-variables.md +7 -7
- package/docs/extensions.md +17 -7
- package/docs/json.md +7 -2
- package/docs/keybindings.md +8 -8
- package/docs/llama-cpp.md +2 -0
- package/docs/models.md +8 -2
- package/docs/packages.md +2 -2
- package/docs/rpc.md +9 -3
- package/docs/sdk.md +7 -2
- package/docs/settings.md +11 -3
- package/docs/skills.md +3 -2
- package/docs/terminal-setup.md +8 -0
- package/docs/usage.md +10 -7
- package/docs/windows.md +15 -1
- package/examples/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +70 -8
- package/examples/extensions/custom-provider-anthropic/package.json +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/git-checkpoint.ts +2 -2
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/sandbox/package-lock.json +14 -40
- package/examples/extensions/sandbox/package.json +2 -2
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +4 -4
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +293 -221
- package/package.json +21 -18
- package/src/humain/mcp-adapter/UPSTREAM.md +15 -5
- package/src/humain/mcp-adapter/upstream.json +4 -3
- package/src/humain/mcp-adapter/vendor/CHANGELOG.md +82 -0
- package/src/humain/web-access/UPSTREAM.md +1 -1
- package/src/humain/web-access/upstream.json +6 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-params.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/fetch-params.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetch-params.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/fetch-params.ts"],"names":[],"mappings":"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","sourcesContent":["import { normalizeProxyUrl } from \"./utils.ts\";\n\nexport interface FetchContentParams {\n\turl?: unknown;\n\turls?: unknown;\n\tforceClone?: unknown;\n\tprompt?: unknown;\n\ttimestamp?: unknown;\n\tframes?: unknown;\n\tmodel?: unknown;\n\tmode?: unknown;\n\tanswerModel?: unknown;\n\tauth?: unknown;\n\tproxy?: unknown;\n}\n\nexport interface NormalizedFetchContentParams {\n\turlList: string[];\n\toptions: {\n\t\tforceClone?: boolean;\n\t\tprompt?: string;\n\t\ttimestamp?: string;\n\t\tframes?: number;\n\t\tmodel?: string;\n\t\tmode?: \"readable\" | \"raw\" | \"answer\";\n\t\tanswerModel?: string;\n\t\tauth?: true | string;\n\t\tproxy?: string;\n\t};\n}\n\nexport function normalizeFetchContentParams(params: FetchContentParams): NormalizedFetchContentParams {\n\tconst normalizedUrls = uniqueUrls(normalizeUrlArray(params.urls));\n\tconst urlList = normalizedUrls.length > 0 ? normalizedUrls : normalizeSingleUrl(params.url);\n\tconst prompt = normalizeOptionalString(params.prompt);\n\tconst timestamp = normalizeOptionalString(params.timestamp);\n\tconst frames = normalizeOptionalFrameCount(params.frames);\n\n\tconst shouldIncludeFrames = frames !== undefined && (timestamp !== undefined || frames > 1);\n\n\tconst forceClone = typeof params.forceClone === \"boolean\" ? params.forceClone : undefined;\n\tconst model = normalizeOptionalString(params.model);\n\tconst mode = normalizeMode(params.mode);\n\tconst answerModel = normalizeOptionalString(params.answerModel);\n\tconst auth = normalizeAuth(params.auth);\n\tconst proxy = normalizeProxy(params.proxy);\n\n\treturn {\n\t\turlList,\n\t\toptions: {\n\t\t\t...(forceClone !== undefined ? { forceClone } : {}),\n\t\t\t...(prompt !== undefined ? { prompt } : {}),\n\t\t\t...(timestamp !== undefined ? { timestamp } : {}),\n\t\t\t...(shouldIncludeFrames ? { frames } : {}),\n\t\t\t...(model !== undefined ? { model } : {}),\n\t\t\t...(mode !== undefined ? { mode } : {}),\n\t\t\t...(answerModel !== undefined ? { answerModel } : {}),\n\t\t\t...(auth !== undefined ? { auth } : {}),\n\t\t\t...(proxy !== undefined ? { proxy } : {}),\n\t\t},\n\t};\n}\n\nfunction normalizeUrlArray(value: unknown): string[] {\n\tif (!Array.isArray(value)) return [];\n\treturn value.flatMap(normalizeSingleUrl);\n}\n\nfunction normalizeSingleUrl(value: unknown): string[] {\n\tif (typeof value !== \"string\") return [];\n\tconst trimmed = value.trim();\n\treturn trimmed ? [trimmed] : [];\n}\n\nfunction normalizeOptionalString(value: unknown): string | undefined {\n\tif (typeof value !== \"string\") return undefined;\n\tconst trimmed = value.trim();\n\treturn trimmed || undefined;\n}\n\nfunction normalizeMode(value: unknown): \"readable\" | \"raw\" | \"answer\" | undefined {\n\tif (value === undefined) return undefined;\n\tif (value === \"readable\" || value === \"raw\" || value === \"answer\") return value;\n\tthrow new Error('mode must be \"readable\", \"raw\", or \"answer\"');\n}\n\nfunction normalizeAuth(value: unknown): true | string | undefined {\n\tif (value === undefined || value === false) return undefined;\n\tif (value === true) return true;\n\tif (typeof value === \"string\") {\n\t\tconst trimmed = value.trim();\n\t\tif (trimmed) return trimmed;\n\t}\n\tthrow new Error(\"auth must be a profile name, true, or false\");\n}\n\nfunction normalizeProxy(value: unknown): string | undefined {\n\tif (value === undefined || value === false) return undefined;\n\tif (value === null) throw new Error(\"proxy must be an http(s) proxy URL string\");\n\tconst normalized = normalizeProxyUrl(value, \"proxy\");\n\treturn normalized ?? \"\";\n}\n\nfunction normalizeOptionalFrameCount(value: unknown): number | undefined {\n\tif (typeof value !== \"number\" || !Number.isInteger(value) || value < 1 || value > 12) return undefined;\n\treturn value;\n}\n\nfunction uniqueUrls(urls: string[]): string[] {\n\treturn [...new Set(urls)];\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function isAdcAuthSelected(): boolean;
|
|
2
|
+
export declare function getAdcProject(): string | null;
|
|
3
|
+
export declare function getAdcLocation(): string | null;
|
|
4
|
+
export declare function getVertexApiBase(project: string, location: string): string;
|
|
5
|
+
export declare function isVertexHost(origin: string): boolean;
|
|
6
|
+
export declare function clearAdcTokenCache(): void;
|
|
7
|
+
export declare function getAdcAccessToken(signal?: AbortSignal): Promise<string>;
|
|
8
|
+
export declare function isGeminiAdcAvailable(): boolean;
|
|
9
|
+
export declare function redactAdcToken(text: string): string;
|
|
10
|
+
//# sourceMappingURL=gemini-adc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-adc.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/gemini-adc.ts"],"names":[],"mappings":"AAqDA,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAK7C;AAED,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAE9C;AAMD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpD;AA+FD,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAsFD,wBAAsB,iBAAiB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAc7E;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAU9C;AAgBD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { createSign } from "node:crypto";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { getWebSearchConfigPath } from "./utils.js";
|
|
6
|
+
import { redactCredential, CredentialResolutionError } from "./credential-source.js";
|
|
7
|
+
const CONFIG_PATH = getWebSearchConfigPath();
|
|
8
|
+
const DEFAULT_ADC_PATH = join(homedir(), ".config", "gcloud", "application_default_credentials.json");
|
|
9
|
+
const TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token";
|
|
10
|
+
const VERTEX_HOST = "https://aiplatform.googleapis.com";
|
|
11
|
+
const VERTEX_API_VERSION = "v1";
|
|
12
|
+
const REFRESH_SKEW_MS = 60_000;
|
|
13
|
+
let cachedConfig = null;
|
|
14
|
+
function loadConfig() {
|
|
15
|
+
if (cachedConfig)
|
|
16
|
+
return cachedConfig;
|
|
17
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
18
|
+
cachedConfig = {};
|
|
19
|
+
return cachedConfig;
|
|
20
|
+
}
|
|
21
|
+
const raw = readFileSync(CONFIG_PATH, "utf-8");
|
|
22
|
+
try {
|
|
23
|
+
const parsed = JSON.parse(raw);
|
|
24
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
25
|
+
throw new Error("config root must be an object");
|
|
26
|
+
}
|
|
27
|
+
cachedConfig = parsed;
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
31
|
+
throw new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);
|
|
32
|
+
}
|
|
33
|
+
return cachedConfig;
|
|
34
|
+
}
|
|
35
|
+
function normalizeIdentifier(value, envName) {
|
|
36
|
+
if (typeof value === "string") {
|
|
37
|
+
const trimmed = value.trim();
|
|
38
|
+
if (trimmed)
|
|
39
|
+
return trimmed;
|
|
40
|
+
}
|
|
41
|
+
const fromEnv = process.env[envName]?.trim();
|
|
42
|
+
return fromEnv ? fromEnv : null;
|
|
43
|
+
}
|
|
44
|
+
export function isAdcAuthSelected() {
|
|
45
|
+
return (loadConfig().geminiAuth ?? "").toString().trim().toLowerCase() === "adc";
|
|
46
|
+
}
|
|
47
|
+
export function getAdcProject() {
|
|
48
|
+
return (normalizeIdentifier(loadConfig().geminiProject, "GOOGLE_CLOUD_PROJECT") ??
|
|
49
|
+
normalizeIdentifier(null, "GCLOUD_PROJECT"));
|
|
50
|
+
}
|
|
51
|
+
export function getAdcLocation() {
|
|
52
|
+
return normalizeIdentifier(loadConfig().geminiLocation, "GOOGLE_CLOUD_LOCATION");
|
|
53
|
+
}
|
|
54
|
+
function getAdcPath() {
|
|
55
|
+
return process.env.GOOGLE_APPLICATION_CREDENTIALS?.trim() || DEFAULT_ADC_PATH;
|
|
56
|
+
}
|
|
57
|
+
export function getVertexApiBase(project, location) {
|
|
58
|
+
return `${VERTEX_HOST}/${VERTEX_API_VERSION}/projects/${encodeURIComponent(project)}/locations/${encodeURIComponent(location)}/publishers/google`;
|
|
59
|
+
}
|
|
60
|
+
export function isVertexHost(origin) {
|
|
61
|
+
return origin === VERTEX_HOST;
|
|
62
|
+
}
|
|
63
|
+
function objectRecord(value) {
|
|
64
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
65
|
+
}
|
|
66
|
+
function stringField(record, name) {
|
|
67
|
+
const value = record[name];
|
|
68
|
+
return typeof value === "string" ? value : undefined;
|
|
69
|
+
}
|
|
70
|
+
function requiredString(record, name, context) {
|
|
71
|
+
const value = stringField(record, name)?.trim();
|
|
72
|
+
if (!value)
|
|
73
|
+
throw new Error(`${context} is missing ${name}`);
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
function parseAdcFile(raw) {
|
|
77
|
+
const parsed = objectRecord(JSON.parse(raw));
|
|
78
|
+
if (!parsed)
|
|
79
|
+
throw new Error("credential root must be an object");
|
|
80
|
+
const type = stringField(parsed, "type") ?? "authorized_user";
|
|
81
|
+
if (type === "authorized_user") {
|
|
82
|
+
return {
|
|
83
|
+
type,
|
|
84
|
+
client_id: requiredString(parsed, "client_id", "Gemini ADC authorized_user file"),
|
|
85
|
+
client_secret: requiredString(parsed, "client_secret", "Gemini ADC authorized_user file"),
|
|
86
|
+
refresh_token: requiredString(parsed, "refresh_token", "Gemini ADC authorized_user file"),
|
|
87
|
+
universe_domain: stringField(parsed, "universe_domain"),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (type === "service_account") {
|
|
91
|
+
return {
|
|
92
|
+
type,
|
|
93
|
+
client_email: requiredString(parsed, "client_email", "Gemini ADC service_account file"),
|
|
94
|
+
private_key: requiredString(parsed, "private_key", "Gemini ADC service_account file"),
|
|
95
|
+
private_key_id: stringField(parsed, "private_key_id"),
|
|
96
|
+
token_uri: stringField(parsed, "token_uri"),
|
|
97
|
+
universe_domain: stringField(parsed, "universe_domain"),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return { type };
|
|
101
|
+
}
|
|
102
|
+
function parseTokenExchangeResponse(text, context) {
|
|
103
|
+
let raw;
|
|
104
|
+
try {
|
|
105
|
+
raw = JSON.parse(text);
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
109
|
+
throw new Error(`${context} returned invalid JSON: ${message}`);
|
|
110
|
+
}
|
|
111
|
+
const parsed = objectRecord(raw);
|
|
112
|
+
if (!parsed)
|
|
113
|
+
throw new Error(`${context} returned a non-object response`);
|
|
114
|
+
const token = stringField(parsed, "access_token")?.trim();
|
|
115
|
+
if (!token)
|
|
116
|
+
throw new Error(`${context} returned no access_token`);
|
|
117
|
+
const expiresIn = parsed.expires_in ?? 3600;
|
|
118
|
+
if (typeof expiresIn !== "number" || !Number.isFinite(expiresIn)) {
|
|
119
|
+
throw new Error(`${context} returned invalid expires_in`);
|
|
120
|
+
}
|
|
121
|
+
return { token, expiresAt: Date.now() + Math.max((expiresIn * 1000) - REFRESH_SKEW_MS, 60_000) };
|
|
122
|
+
}
|
|
123
|
+
async function loadAdcFile() {
|
|
124
|
+
const path = getAdcPath();
|
|
125
|
+
if (!path || !existsSync(path)) {
|
|
126
|
+
throw new Error(`Google Application Default Credentials file not found at ${path}`);
|
|
127
|
+
}
|
|
128
|
+
const raw = readFileSync(path, "utf-8");
|
|
129
|
+
try {
|
|
130
|
+
return parseAdcFile(raw);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
134
|
+
throw new Error(`Failed to parse Google Application Default Credentials file at ${path}: ${message}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
let cachedToken = null;
|
|
138
|
+
export function clearAdcTokenCache() {
|
|
139
|
+
cachedToken = null;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Classifies a failed OAuth token exchange. Only explicit credential/authorization
|
|
143
|
+
* rejections (400 invalid_client/invalid_grant/invalid_scope, 401, 403 denied)
|
|
144
|
+
* mean the configured credentials themselves were refused — a hard credential
|
|
145
|
+
* problem callers should surface rather than silently fall back. Everything else
|
|
146
|
+
* (429 rate limit, 404, 5xx, network failures, timeouts) is transient, so it is
|
|
147
|
+
* left as a plain Error and existing per-provider fallbacks keep working.
|
|
148
|
+
*/
|
|
149
|
+
const OAUTH_CREDENTIAL_REJECTION_STATUSES = new Set([400, 401, 403]);
|
|
150
|
+
function throwOnTokenExchangeFailure(res, detail, status) {
|
|
151
|
+
if (OAUTH_CREDENTIAL_REJECTION_STATUSES.has(status)) {
|
|
152
|
+
throw new CredentialResolutionError("Gemini ADC", "oauth-credential-rejected");
|
|
153
|
+
}
|
|
154
|
+
throw new Error(`Gemini ADC token exchange failed (${status}): ${detail.slice(0, 300)}`);
|
|
155
|
+
}
|
|
156
|
+
function redactValues(text, values) {
|
|
157
|
+
let redacted = text;
|
|
158
|
+
for (const value of values) {
|
|
159
|
+
if (value)
|
|
160
|
+
redacted = redactCredential(redacted, value);
|
|
161
|
+
}
|
|
162
|
+
return redacted;
|
|
163
|
+
}
|
|
164
|
+
async function exchangeRefreshToken(cfg, signal) {
|
|
165
|
+
const body = new URLSearchParams({
|
|
166
|
+
client_id: cfg.client_id ?? "",
|
|
167
|
+
client_secret: cfg.client_secret ?? "",
|
|
168
|
+
refresh_token: cfg.refresh_token ?? "",
|
|
169
|
+
grant_type: "refresh_token",
|
|
170
|
+
});
|
|
171
|
+
const res = await fetch(TOKEN_ENDPOINT, {
|
|
172
|
+
method: "POST",
|
|
173
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
174
|
+
body,
|
|
175
|
+
signal,
|
|
176
|
+
});
|
|
177
|
+
const text = await res.text();
|
|
178
|
+
if (!res.ok) {
|
|
179
|
+
throwOnTokenExchangeFailure(res, redactValues(text, [cfg.client_secret, cfg.refresh_token]), res.status);
|
|
180
|
+
}
|
|
181
|
+
return parseTokenExchangeResponse(text, "Gemini ADC token exchange");
|
|
182
|
+
}
|
|
183
|
+
async function exchangeServiceAccountJwt(cfg, signal) {
|
|
184
|
+
if (!cfg.client_email || !cfg.private_key) {
|
|
185
|
+
throw new Error("Gemini ADC service_account file is missing client_email or private_key");
|
|
186
|
+
}
|
|
187
|
+
const now = Math.floor(Date.now() / 1000);
|
|
188
|
+
const header = { alg: "RS256", typ: "JWT" };
|
|
189
|
+
const claims = {
|
|
190
|
+
iss: cfg.client_email,
|
|
191
|
+
scope: "https://www.googleapis.com/auth/cloud-platform",
|
|
192
|
+
aud: TOKEN_ENDPOINT,
|
|
193
|
+
iat: now,
|
|
194
|
+
exp: now + 3600,
|
|
195
|
+
};
|
|
196
|
+
const encodePart = (obj) => Buffer.from(JSON.stringify(obj)).toString("base64url");
|
|
197
|
+
const assertion = `${encodePart(header)}.${encodePart(claims)}`;
|
|
198
|
+
const signer = createSign("RSA-SHA256");
|
|
199
|
+
signer.update(assertion);
|
|
200
|
+
signer.end();
|
|
201
|
+
const signature = signer.sign(cfg.private_key, "base64url");
|
|
202
|
+
const jwt = `${assertion}.${signature}`;
|
|
203
|
+
const body = new URLSearchParams({
|
|
204
|
+
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
205
|
+
assertion: jwt,
|
|
206
|
+
});
|
|
207
|
+
const res = await fetch(TOKEN_ENDPOINT, {
|
|
208
|
+
method: "POST",
|
|
209
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
210
|
+
body,
|
|
211
|
+
signal,
|
|
212
|
+
});
|
|
213
|
+
const text = await res.text();
|
|
214
|
+
if (!res.ok) {
|
|
215
|
+
throwOnTokenExchangeFailure(res, redactValues(text, [jwt, cfg.private_key]), res.status);
|
|
216
|
+
}
|
|
217
|
+
return parseTokenExchangeResponse(text, "Gemini ADC service account token exchange");
|
|
218
|
+
}
|
|
219
|
+
export async function getAdcAccessToken(signal) {
|
|
220
|
+
if (cachedToken && cachedToken.expiresAt > Date.now()) {
|
|
221
|
+
return cachedToken.token;
|
|
222
|
+
}
|
|
223
|
+
const cfg = await loadAdcFile();
|
|
224
|
+
const type = cfg.type ?? "authorized_user";
|
|
225
|
+
if (type === "authorized_user") {
|
|
226
|
+
cachedToken = await exchangeRefreshToken(cfg, signal);
|
|
227
|
+
}
|
|
228
|
+
else if (type === "service_account") {
|
|
229
|
+
cachedToken = await exchangeServiceAccountJwt(cfg, signal);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
throw new Error(`Gemini ADC unsupported credential type "${type}" (expected authorized_user or service_account)`);
|
|
233
|
+
}
|
|
234
|
+
return cachedToken.token;
|
|
235
|
+
}
|
|
236
|
+
export function isGeminiAdcAvailable() {
|
|
237
|
+
if (!isAdcAuthSelected())
|
|
238
|
+
return false;
|
|
239
|
+
// An explicitly configured Gemini API key takes precedence over ADC, so
|
|
240
|
+
// existing key-based setups and their unit tests keep working unchanged.
|
|
241
|
+
if (hasGeminiApiKeySource())
|
|
242
|
+
return false;
|
|
243
|
+
// An explicit base URL (gateway/relay/proxy) also wins over ADC: if the
|
|
244
|
+
// user deliberately routed Gemini somewhere, honor that routing.
|
|
245
|
+
if (hasExplicitApiBase())
|
|
246
|
+
return false;
|
|
247
|
+
if (!getAdcProject() || !getAdcLocation())
|
|
248
|
+
return false;
|
|
249
|
+
return existsSync(getAdcPath());
|
|
250
|
+
}
|
|
251
|
+
function hasGeminiApiKeySource() {
|
|
252
|
+
const configured = loadConfig().geminiApiKey;
|
|
253
|
+
if (typeof configured === "string" && configured.trim())
|
|
254
|
+
return true;
|
|
255
|
+
const fromEnv = process.env.GEMINI_API_KEY?.trim();
|
|
256
|
+
return !!fromEnv;
|
|
257
|
+
}
|
|
258
|
+
function hasExplicitApiBase() {
|
|
259
|
+
const fromEnv = process.env.GOOGLE_GEMINI_BASE_URL?.trim();
|
|
260
|
+
if (fromEnv)
|
|
261
|
+
return true;
|
|
262
|
+
const configured = loadConfig().geminiBaseUrl;
|
|
263
|
+
return typeof configured === "string" && configured.trim().length > 0;
|
|
264
|
+
}
|
|
265
|
+
export function redactAdcToken(text) {
|
|
266
|
+
return cachedToken ? redactCredential(text, cachedToken.token) : text;
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=gemini-adc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-adc.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/gemini-adc.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { createSign } from \"node:crypto\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\nimport { redactCredential, CredentialResolutionError } from \"./credential-source.ts\";\n\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst DEFAULT_ADC_PATH = join(homedir(), \".config\", \"gcloud\", \"application_default_credentials.json\");\nconst TOKEN_ENDPOINT = \"https://oauth2.googleapis.com/token\";\nconst VERTEX_HOST = \"https://aiplatform.googleapis.com\";\nconst VERTEX_API_VERSION = \"v1\";\nconst REFRESH_SKEW_MS = 60_000;\n\ninterface GeminiAdcConfig {\n\tgeminiAuth?: unknown;\n\tgeminiProject?: unknown;\n\tgeminiLocation?: unknown;\n\tgeminiApiKey?: unknown;\n\tgeminiBaseUrl?: unknown;\n}\n\nlet cachedConfig: GeminiAdcConfig | null = null;\n\nfunction loadConfig(): GeminiAdcConfig {\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\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\t\tthrow new Error(\"config root must be an object\");\n\t\t}\n\t\tcachedConfig = parsed as GeminiAdcConfig;\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\treturn cachedConfig;\n}\n\nfunction normalizeIdentifier(value: unknown, envName: string): string | null {\n\tif (typeof value === \"string\") {\n\t\tconst trimmed = value.trim();\n\t\tif (trimmed) return trimmed;\n\t}\n\tconst fromEnv = process.env[envName]?.trim();\n\treturn fromEnv ? fromEnv : null;\n}\n\nexport function isAdcAuthSelected(): boolean {\n\treturn (loadConfig().geminiAuth ?? \"\").toString().trim().toLowerCase() === \"adc\";\n}\n\nexport function getAdcProject(): string | null {\n\treturn (\n\t\tnormalizeIdentifier(loadConfig().geminiProject, \"GOOGLE_CLOUD_PROJECT\") ??\n\t\tnormalizeIdentifier(null, \"GCLOUD_PROJECT\")\n\t);\n}\n\nexport function getAdcLocation(): string | null {\n\treturn normalizeIdentifier(loadConfig().geminiLocation, \"GOOGLE_CLOUD_LOCATION\");\n}\n\nfunction getAdcPath(): string {\n\treturn process.env.GOOGLE_APPLICATION_CREDENTIALS?.trim() || DEFAULT_ADC_PATH;\n}\n\nexport function getVertexApiBase(project: string, location: string): string {\n\treturn `${VERTEX_HOST}/${VERTEX_API_VERSION}/projects/${encodeURIComponent(project)}/locations/${encodeURIComponent(location)}/publishers/google`;\n}\n\nexport function isVertexHost(origin: string): boolean {\n\treturn origin === VERTEX_HOST;\n}\n\ninterface AdcFile {\n\ttype?: string;\n\tclient_id?: string;\n\tclient_secret?: string;\n\trefresh_token?: string;\n\tclient_email?: string;\n\tprivate_key?: string;\n\tprivate_key_id?: string;\n\ttoken_uri?: string;\n\tuniverse_domain?: string;\n}\n\nfunction objectRecord(value: unknown): Record<string, unknown> | null {\n\treturn value && typeof value === \"object\" && !Array.isArray(value) ? value as Record<string, unknown> : null;\n}\n\nfunction stringField(record: Record<string, unknown>, name: string): string | undefined {\n\tconst value = record[name];\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction requiredString(record: Record<string, unknown>, name: string, context: string): string {\n\tconst value = stringField(record, name)?.trim();\n\tif (!value) throw new Error(`${context} is missing ${name}`);\n\treturn value;\n}\n\nfunction parseAdcFile(raw: string): AdcFile {\n\tconst parsed = objectRecord(JSON.parse(raw));\n\tif (!parsed) throw new Error(\"credential root must be an object\");\n\tconst type = stringField(parsed, \"type\") ?? \"authorized_user\";\n\tif (type === \"authorized_user\") {\n\t\treturn {\n\t\t\ttype,\n\t\t\tclient_id: requiredString(parsed, \"client_id\", \"Gemini ADC authorized_user file\"),\n\t\t\tclient_secret: requiredString(parsed, \"client_secret\", \"Gemini ADC authorized_user file\"),\n\t\t\trefresh_token: requiredString(parsed, \"refresh_token\", \"Gemini ADC authorized_user file\"),\n\t\t\tuniverse_domain: stringField(parsed, \"universe_domain\"),\n\t\t};\n\t}\n\tif (type === \"service_account\") {\n\t\treturn {\n\t\t\ttype,\n\t\t\tclient_email: requiredString(parsed, \"client_email\", \"Gemini ADC service_account file\"),\n\t\t\tprivate_key: requiredString(parsed, \"private_key\", \"Gemini ADC service_account file\"),\n\t\t\tprivate_key_id: stringField(parsed, \"private_key_id\"),\n\t\t\ttoken_uri: stringField(parsed, \"token_uri\"),\n\t\t\tuniverse_domain: stringField(parsed, \"universe_domain\"),\n\t\t};\n\t}\n\treturn { type };\n}\n\nfunction parseTokenExchangeResponse(text: string, context: string): CachedToken {\n\tlet raw: unknown;\n\ttry {\n\t\traw = JSON.parse(text);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`${context} returned invalid JSON: ${message}`);\n\t}\n\tconst parsed = objectRecord(raw);\n\tif (!parsed) throw new Error(`${context} returned a non-object response`);\n\tconst token = stringField(parsed, \"access_token\")?.trim();\n\tif (!token) throw new Error(`${context} returned no access_token`);\n\tconst expiresIn = parsed.expires_in ?? 3600;\n\tif (typeof expiresIn !== \"number\" || !Number.isFinite(expiresIn)) {\n\t\tthrow new Error(`${context} returned invalid expires_in`);\n\t}\n\treturn { token, expiresAt: Date.now() + Math.max((expiresIn * 1000) - REFRESH_SKEW_MS, 60_000) };\n}\n\nasync function loadAdcFile(): Promise<AdcFile> {\n\tconst path = getAdcPath();\n\tif (!path || !existsSync(path)) {\n\t\tthrow new Error(`Google Application Default Credentials file not found at ${path}`);\n\t}\n\tconst raw = readFileSync(path, \"utf-8\");\n\ttry {\n\t\treturn parseAdcFile(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse Google Application Default Credentials file at ${path}: ${message}`);\n\t}\n}\n\ninterface CachedToken {\n\ttoken: string;\n\texpiresAt: number;\n}\n\nlet cachedToken: CachedToken | null = null;\n\nexport function clearAdcTokenCache(): void {\n\tcachedToken = null;\n}\n\n/**\n * Classifies a failed OAuth token exchange. Only explicit credential/authorization\n * rejections (400 invalid_client/invalid_grant/invalid_scope, 401, 403 denied)\n * mean the configured credentials themselves were refused — a hard credential\n * problem callers should surface rather than silently fall back. Everything else\n * (429 rate limit, 404, 5xx, network failures, timeouts) is transient, so it is\n * left as a plain Error and existing per-provider fallbacks keep working.\n */\nconst OAUTH_CREDENTIAL_REJECTION_STATUSES = new Set([400, 401, 403]);\n\nfunction throwOnTokenExchangeFailure(res: Response, detail: string, status: number): never {\n\tif (OAUTH_CREDENTIAL_REJECTION_STATUSES.has(status)) {\n\t\tthrow new CredentialResolutionError(\"Gemini ADC\", \"oauth-credential-rejected\");\n\t}\n\tthrow new Error(`Gemini ADC token exchange failed (${status}): ${detail.slice(0, 300)}`);\n}\n\nfunction redactValues(text: string, values: Array<string | undefined>): string {\n\tlet redacted = text;\n\tfor (const value of values) {\n\t\tif (value) redacted = redactCredential(redacted, value);\n\t}\n\treturn redacted;\n}\n\nasync function exchangeRefreshToken(cfg: AdcFile, signal?: AbortSignal): Promise<CachedToken> {\n\tconst body = new URLSearchParams({\n\t\tclient_id: cfg.client_id ?? \"\",\n\t\tclient_secret: cfg.client_secret ?? \"\",\n\t\trefresh_token: cfg.refresh_token ?? \"\",\n\t\tgrant_type: \"refresh_token\",\n\t});\n\tconst res = await fetch(TOKEN_ENDPOINT, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\tbody,\n\t\tsignal,\n\t});\n\tconst text = await res.text();\n\tif (!res.ok) {\n\t\tthrowOnTokenExchangeFailure(res, redactValues(text, [cfg.client_secret, cfg.refresh_token]), res.status);\n\t}\n\treturn parseTokenExchangeResponse(text, \"Gemini ADC token exchange\");\n}\n\nasync function exchangeServiceAccountJwt(cfg: AdcFile, signal?: AbortSignal): Promise<CachedToken> {\n\tif (!cfg.client_email || !cfg.private_key) {\n\t\tthrow new Error(\"Gemini ADC service_account file is missing client_email or private_key\");\n\t}\n\tconst now = Math.floor(Date.now() / 1000);\n\tconst header = { alg: \"RS256\", typ: \"JWT\" };\n\tconst claims = {\n\t\tiss: cfg.client_email,\n\t\tscope: \"https://www.googleapis.com/auth/cloud-platform\",\n\t\taud: TOKEN_ENDPOINT,\n\t\tiat: now,\n\t\texp: now + 3600,\n\t};\n\tconst encodePart = (obj: object): string =>\n\t\tBuffer.from(JSON.stringify(obj)).toString(\"base64url\");\n\tconst assertion = `${encodePart(header)}.${encodePart(claims)}`;\n\tconst signer = createSign(\"RSA-SHA256\");\n\tsigner.update(assertion);\n\tsigner.end();\n\tconst signature = signer.sign(cfg.private_key, \"base64url\");\n\tconst jwt = `${assertion}.${signature}`;\n\n\tconst body = new URLSearchParams({\n\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:jwt-bearer\",\n\t\tassertion: jwt,\n\t});\n\tconst res = await fetch(TOKEN_ENDPOINT, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\tbody,\n\t\tsignal,\n\t});\n\tconst text = await res.text();\n\tif (!res.ok) {\n\t\tthrowOnTokenExchangeFailure(res, redactValues(text, [jwt, cfg.private_key]), res.status);\n\t}\n\treturn parseTokenExchangeResponse(text, \"Gemini ADC service account token exchange\");\n}\n\nexport async function getAdcAccessToken(signal?: AbortSignal): Promise<string> {\n\tif (cachedToken && cachedToken.expiresAt > Date.now()) {\n\t\treturn cachedToken.token;\n\t}\n\tconst cfg = await loadAdcFile();\n\tconst type = cfg.type ?? \"authorized_user\";\n\tif (type === \"authorized_user\") {\n\t\tcachedToken = await exchangeRefreshToken(cfg, signal);\n\t} else if (type === \"service_account\") {\n\t\tcachedToken = await exchangeServiceAccountJwt(cfg, signal);\n\t} else {\n\t\tthrow new Error(`Gemini ADC unsupported credential type \"${type}\" (expected authorized_user or service_account)`);\n\t}\n\treturn cachedToken.token;\n}\n\nexport function isGeminiAdcAvailable(): boolean {\n\tif (!isAdcAuthSelected()) return false;\n\t// An explicitly configured Gemini API key takes precedence over ADC, so\n\t// existing key-based setups and their unit tests keep working unchanged.\n\tif (hasGeminiApiKeySource()) return false;\n\t// An explicit base URL (gateway/relay/proxy) also wins over ADC: if the\n\t// user deliberately routed Gemini somewhere, honor that routing.\n\tif (hasExplicitApiBase()) return false;\n\tif (!getAdcProject() || !getAdcLocation()) return false;\n\treturn existsSync(getAdcPath());\n}\n\nfunction hasGeminiApiKeySource(): boolean {\n\tconst configured = loadConfig().geminiApiKey;\n\tif (typeof configured === \"string\" && configured.trim()) return true;\n\tconst fromEnv = process.env.GEMINI_API_KEY?.trim();\n\treturn !!fromEnv;\n}\n\nfunction hasExplicitApiBase(): boolean {\n\tconst fromEnv = process.env.GOOGLE_GEMINI_BASE_URL?.trim();\n\tif (fromEnv) return true;\n\tconst configured = loadConfig().geminiBaseUrl;\n\treturn typeof configured === \"string\" && configured.trim().length > 0;\n}\n\nexport function redactAdcToken(text: string): string {\n\treturn cachedToken ? redactCredential(text, cachedToken.token) : text;\n}\n"]}
|
|
@@ -7,9 +7,15 @@ export declare function getUploadBase(): string;
|
|
|
7
7
|
export declare function getCloudflareApiKey(): string | null;
|
|
8
8
|
export declare function isGatewayConfigured(): boolean;
|
|
9
9
|
export declare function buildAuthHeaders(apiKey?: string | null, cloudflareApiKey?: string | null): Record<string, string>;
|
|
10
|
-
export declare function redactGeminiApiResponse(response: Response, text: string, apiKey?: string | null): string;
|
|
10
|
+
export declare function redactGeminiApiResponse(response: Response, text: string, apiKey?: string | null, adcToken?: string | null): string;
|
|
11
11
|
export declare function fetchGeminiApi(url: string | URL, init?: RequestInit, apiKey?: string | null): Promise<Response>;
|
|
12
12
|
export declare function isGeminiApiAvailable(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Whether the Gemini Files-API paths (YouTube and local video analysis) can
|
|
15
|
+
* authenticate. These use the Gemini Files API and metadata endpoints, which do
|
|
16
|
+
* not support ADC, so they still require an API key or a Cloudflare gateway.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isGeminiApiAvailableWithVideo(): boolean;
|
|
13
19
|
export interface GeminiApiOptions {
|
|
14
20
|
apiKey?: string;
|
|
15
21
|
model?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini-api.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/gemini-api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gemini-api.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/gemini-api.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,QAAQ,qDAAuC,CAAC;AAE7D,eAAO,MAAM,aAAa,qBAAqB,CAAC;AAgDhD,wBAAsB,SAAS,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO5E;AAED,wBAAgB,UAAU,IAAI,MAAM,CAMnC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAO5C;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAeD,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAEnD;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAM7C;AAED,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,MAAM,GAAG,IAAW,EAAE,gBAAgB,GAAE,MAAM,GAAG,IAAkC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGpJ;AAcD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGlI;AAED,wBAAsB,cAAc,CACnC,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,IAAI,GAAE,WAAgB,EACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,QAAQ,CAAC,CAgDnB;AAUD,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAEvD;AAED,MAAM,WAAW,gBAAgB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,2BAA2B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,4BAA4B,CACjD,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC5B,OAAO,CAAC,2BAA2B,CAAC,CAkDtC;AAED,wBAAsB,uBAAuB,CAC5C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAiDjB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { hasCredentialSource, redactCredential, resolveCredential } from "./credential-source.js";
|
|
3
3
|
import { getWebSearchConfigPath } from "./utils.js";
|
|
4
|
+
import { isGeminiAdcAvailable, getAdcAccessToken, getAdcProject, getAdcLocation, getVertexApiBase, isVertexHost, } from "./gemini-adc.js";
|
|
4
5
|
const DEFAULT_API_HOST = "https://generativelanguage.googleapis.com";
|
|
5
6
|
const API_VERSION = "v1beta";
|
|
6
7
|
export const API_BASE = `${DEFAULT_API_HOST}/${API_VERSION}`;
|
|
@@ -57,6 +58,11 @@ export function getApiHost() {
|
|
|
57
58
|
DEFAULT_API_HOST);
|
|
58
59
|
}
|
|
59
60
|
export function getVersionedApiBase() {
|
|
61
|
+
const project = getAdcProject();
|
|
62
|
+
const location = getAdcLocation();
|
|
63
|
+
if (isGeminiAdcAvailable() && project && location) {
|
|
64
|
+
return getVertexApiBase(project, location);
|
|
65
|
+
}
|
|
60
66
|
return `${getApiHost()}/${API_VERSION}`;
|
|
61
67
|
}
|
|
62
68
|
export function getUploadBase() {
|
|
@@ -88,13 +94,16 @@ export function buildAuthHeaders(apiKey = null, cloudflareApiKey = getLegacyClou
|
|
|
88
94
|
return apiKey ? { "x-goog-api-key": apiKey } : {};
|
|
89
95
|
return cloudflareApiKey ? { "cf-aig-authorization": `Bearer ${cloudflareApiKey}` } : {};
|
|
90
96
|
}
|
|
91
|
-
function redactGeminiCredentials(text, apiKey, cloudflareApiKey) {
|
|
92
|
-
|
|
97
|
+
function redactGeminiCredentials(text, apiKey, cloudflareApiKey, adcToken) {
|
|
98
|
+
let out = redactCredential(redactCredential(text, apiKey), cloudflareApiKey);
|
|
99
|
+
if (adcToken)
|
|
100
|
+
out = redactCredential(out, adcToken);
|
|
101
|
+
return out;
|
|
93
102
|
}
|
|
94
103
|
const responseCredentials = new WeakMap();
|
|
95
|
-
export function redactGeminiApiResponse(response, text, apiKey) {
|
|
104
|
+
export function redactGeminiApiResponse(response, text, apiKey, adcToken) {
|
|
96
105
|
const credentials = responseCredentials.get(response);
|
|
97
|
-
return redactGeminiCredentials(text, credentials?.apiKey ?? apiKey, credentials?.cloudflareApiKey);
|
|
106
|
+
return redactGeminiCredentials(text, credentials?.apiKey ?? apiKey, credentials?.cloudflareApiKey, credentials?.adcToken ?? adcToken);
|
|
98
107
|
}
|
|
99
108
|
export async function fetchGeminiApi(url, init = {}, apiKey) {
|
|
100
109
|
const parsedUrl = new URL(url);
|
|
@@ -103,29 +112,44 @@ export async function fetchGeminiApi(url, init = {}, apiKey) {
|
|
|
103
112
|
throw new Error("Gemini API credential query parameters are not allowed");
|
|
104
113
|
}
|
|
105
114
|
}
|
|
106
|
-
const
|
|
115
|
+
const project = getAdcProject();
|
|
116
|
+
const location = getAdcLocation();
|
|
117
|
+
const adcMode = isGeminiAdcAvailable() && !!project && !!location && isVertexHost(parsedUrl.origin);
|
|
118
|
+
let adcToken = null;
|
|
119
|
+
if (adcMode) {
|
|
120
|
+
adcToken = await getAdcAccessToken(init.signal ?? undefined);
|
|
121
|
+
}
|
|
122
|
+
const resolvedApiKey = adcMode ? null : (apiKey === undefined ? await getApiKey(init.signal ?? undefined) : apiKey);
|
|
107
123
|
const cloudflareApiKey = isCloudflareGateway() ? await resolveCloudflareApiKey(init.signal ?? undefined) : null;
|
|
108
124
|
const allowedOrigins = new Set([
|
|
109
125
|
new URL(getApiHost()).origin,
|
|
110
126
|
new URL(DEFAULT_API_HOST).origin,
|
|
127
|
+
...(adcMode ? [parsedUrl.origin] : []),
|
|
111
128
|
]);
|
|
112
|
-
|
|
129
|
+
const needsAuth = resolvedApiKey || isGatewayConfigured() || adcMode;
|
|
130
|
+
if (needsAuth && !allowedOrigins.has(parsedUrl.origin)) {
|
|
113
131
|
throw new Error("Gemini API request host is not allowed");
|
|
114
132
|
}
|
|
115
133
|
const headers = new Headers(init.headers);
|
|
116
134
|
headers.delete("x-goog-api-key");
|
|
117
135
|
headers.delete("cf-aig-authorization");
|
|
118
|
-
|
|
119
|
-
|
|
136
|
+
headers.delete("authorization");
|
|
137
|
+
if (adcMode && adcToken) {
|
|
138
|
+
headers.set("Authorization", `Bearer ${adcToken}`);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
for (const [name, value] of Object.entries(buildAuthHeaders(resolvedApiKey, cloudflareApiKey))) {
|
|
142
|
+
headers.set(name, value);
|
|
143
|
+
}
|
|
120
144
|
}
|
|
121
145
|
try {
|
|
122
146
|
const response = await fetch(parsedUrl, { ...init, headers });
|
|
123
|
-
responseCredentials.set(response, { apiKey: resolvedApiKey, cloudflareApiKey });
|
|
147
|
+
responseCredentials.set(response, { apiKey: resolvedApiKey, cloudflareApiKey, adcToken });
|
|
124
148
|
return response;
|
|
125
149
|
}
|
|
126
150
|
catch (error) {
|
|
127
151
|
const message = error instanceof Error ? error.message : String(error);
|
|
128
|
-
const redactedMessage = redactGeminiCredentials(message, resolvedApiKey, cloudflareApiKey);
|
|
152
|
+
const redactedMessage = redactGeminiCredentials(message, resolvedApiKey, cloudflareApiKey, adcToken);
|
|
129
153
|
if (redactedMessage === message)
|
|
130
154
|
throw error;
|
|
131
155
|
const redactedError = new Error(redactedMessage);
|
|
@@ -134,20 +158,32 @@ export async function fetchGeminiApi(url, init = {}, apiKey) {
|
|
|
134
158
|
throw redactedError;
|
|
135
159
|
}
|
|
136
160
|
}
|
|
137
|
-
|
|
161
|
+
function hasGeminiApiKeySource() {
|
|
138
162
|
return hasCredentialSource({
|
|
139
163
|
provider: "Gemini",
|
|
140
164
|
configuredValue: loadConfig().geminiApiKey,
|
|
141
165
|
environmentValue: process.env.GEMINI_API_KEY,
|
|
142
|
-
})
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
export function isGeminiApiAvailable() {
|
|
169
|
+
return isGeminiAdcAvailable() || hasGeminiApiKeySource() || isGatewayConfigured();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Whether the Gemini Files-API paths (YouTube and local video analysis) can
|
|
173
|
+
* authenticate. These use the Gemini Files API and metadata endpoints, which do
|
|
174
|
+
* not support ADC, so they still require an API key or a Cloudflare gateway.
|
|
175
|
+
*/
|
|
176
|
+
export function isGeminiApiAvailableWithVideo() {
|
|
177
|
+
return hasGeminiApiKeySource() || isGatewayConfigured();
|
|
143
178
|
}
|
|
144
179
|
export async function queryGeminiApiWithInlineData(prompt, data, mimeType, options = {}) {
|
|
145
180
|
const signal = withTimeout(options.signal, options.timeoutMs ?? 120000);
|
|
146
|
-
const apiKey = options.apiKey ?? await getApiKey(signal);
|
|
147
|
-
if (!apiKey && !isGatewayConfigured()) {
|
|
181
|
+
const apiKey = isGeminiAdcAvailable() ? null : (options.apiKey ?? await getApiKey(signal));
|
|
182
|
+
if (!apiKey && !isGatewayConfigured() && !isGeminiAdcAvailable()) {
|
|
148
183
|
throw new Error("Gemini API not configured. Either:\n" +
|
|
149
184
|
` 1. Configure geminiApiKey in ${CONFIG_PATH} or set GEMINI_API_KEY\n` +
|
|
150
|
-
" 2. Set GOOGLE_GEMINI_BASE_URL + CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing"
|
|
185
|
+
" 2. Set GOOGLE_GEMINI_BASE_URL + CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing\n" +
|
|
186
|
+
" 3. Set geminiAuth to \"adc\" with a Google Cloud ADC (GOOGLE_APPLICATION_CREDENTIALS) + project/location");
|
|
151
187
|
}
|
|
152
188
|
const model = options.model ?? DEFAULT_MODEL;
|
|
153
189
|
const url = `${getVersionedApiBase()}/models/${model}:generateContent`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini-api.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/gemini-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst DEFAULT_API_HOST = \"https://generativelanguage.googleapis.com\";\nconst API_VERSION = \"v1beta\";\nexport const API_BASE = `${DEFAULT_API_HOST}/${API_VERSION}`;\nconst CONFIG_PATH = getWebSearchConfigPath();\nexport const DEFAULT_MODEL = \"gemini-3.6-flash\";\n\ninterface GeminiApiConfig {\n\tgeminiApiKey?: unknown;\n\tgeminiBaseUrl?: unknown;\n\tcloudflareApiKey?: unknown;\n}\n\nlet cachedConfig: GeminiApiConfig | null = null;\n\nfunction loadConfig(): GeminiApiConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\n\tconst raw = readFileSync(CONFIG_PATH, \"utf-8\");\n\ttry {\n\t\tcachedConfig = JSON.parse(raw) as GeminiApiConfig;\n\t\treturn cachedConfig;\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n}\n\nfunction withTimeout(signal: AbortSignal | undefined, timeoutMs: number): AbortSignal {\n\tconst timeout = AbortSignal.timeout(timeoutMs);\n\treturn signal ? AbortSignal.any([signal, timeout]) : timeout;\n}\n\nfunction normalizeApiKey(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst normalized = value.trim();\n\treturn normalized.length > 0 ? normalized : null;\n}\n\nfunction normalizeBaseUrl(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst normalized = value.trim().replace(/\\/+$/, \"\");\n\treturn normalized.length > 0 ? normalized : null;\n}\n\nfunction isCloudflareGateway(): boolean {\n\treturn getApiHost().includes(\"gateway.ai.cloudflare.com\");\n}\n\nexport async function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"Gemini\",\n\t\tconfiguredValue: loadConfig().geminiApiKey,\n\t\tenvironmentValue: process.env.GEMINI_API_KEY,\n\t\tsignal,\n\t});\n}\n\nexport function getApiHost(): string {\n\treturn (\n\t\tnormalizeBaseUrl(process.env.GOOGLE_GEMINI_BASE_URL) ??\n\t\tnormalizeBaseUrl(loadConfig().geminiBaseUrl) ??\n\t\tDEFAULT_API_HOST\n\t);\n}\n\nexport function getVersionedApiBase(): string {\n\treturn `${getApiHost()}/${API_VERSION}`;\n}\n\nexport function getUploadBase(): string {\n\treturn `${getApiHost()}/upload/${API_VERSION}`;\n}\n\nfunction getLegacyCloudflareApiKey(): string | null {\n\treturn normalizeApiKey(process.env.CLOUDFLARE_API_KEY) ?? normalizeApiKey(loadConfig().cloudflareApiKey);\n}\n\nasync function resolveCloudflareApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"Cloudflare\",\n\t\tconfiguredValue: loadConfig().cloudflareApiKey,\n\t\tenvironmentValue: process.env.CLOUDFLARE_API_KEY,\n\t\tsignal,\n\t});\n}\n\nexport function getCloudflareApiKey(): string | null {\n\treturn getLegacyCloudflareApiKey();\n}\n\nexport function isGatewayConfigured(): boolean {\n\treturn isCloudflareGateway() && hasCredentialSource({\n\t\tprovider: \"Cloudflare\",\n\t\tconfiguredValue: loadConfig().cloudflareApiKey,\n\t\tenvironmentValue: process.env.CLOUDFLARE_API_KEY,\n\t});\n}\n\nexport function buildAuthHeaders(apiKey: string | null = null, cloudflareApiKey: string | null = getLegacyCloudflareApiKey()): Record<string, string> {\n\tif (!isCloudflareGateway()) return apiKey ? { \"x-goog-api-key\": apiKey } : {};\n\treturn cloudflareApiKey ? { \"cf-aig-authorization\": `Bearer ${cloudflareApiKey}` } : {};\n}\n\nfunction redactGeminiCredentials(text: string, apiKey: string | null | undefined, cloudflareApiKey: string | null | undefined): string {\n\treturn redactCredential(redactCredential(text, apiKey), cloudflareApiKey);\n}\n\nconst responseCredentials = new WeakMap<Response, {\n\tapiKey: string | null | undefined;\n\tcloudflareApiKey: string | null | undefined;\n}>();\n\nexport function redactGeminiApiResponse(response: Response, text: string, apiKey?: string | null): string {\n\tconst credentials = responseCredentials.get(response);\n\treturn redactGeminiCredentials(text, credentials?.apiKey ?? apiKey, credentials?.cloudflareApiKey);\n}\n\nexport async function fetchGeminiApi(\n\turl: string | URL,\n\tinit: RequestInit = {},\n\tapiKey?: string | null,\n): Promise<Response> {\n\tconst parsedUrl = new URL(url);\n\tfor (const name of parsedUrl.searchParams.keys()) {\n\t\tif ([\"key\", \"api_key\"].includes(name.toLowerCase())) {\n\t\t\tthrow new Error(\"Gemini API credential query parameters are not allowed\");\n\t\t}\n\t}\n\tconst resolvedApiKey = apiKey === undefined ? await getApiKey(init.signal ?? undefined) : apiKey;\n\tconst cloudflareApiKey = isCloudflareGateway() ? await resolveCloudflareApiKey(init.signal ?? undefined) : null;\n\tconst allowedOrigins = new Set([\n\t\tnew URL(getApiHost()).origin,\n\t\tnew URL(DEFAULT_API_HOST).origin,\n\t]);\n\tif ((resolvedApiKey || isGatewayConfigured()) && !allowedOrigins.has(parsedUrl.origin)) {\n\t\tthrow new Error(\"Gemini API request host is not allowed\");\n\t}\n\tconst headers = new Headers(init.headers);\n\theaders.delete(\"x-goog-api-key\");\n\theaders.delete(\"cf-aig-authorization\");\n\tfor (const [name, value] of Object.entries(buildAuthHeaders(resolvedApiKey, cloudflareApiKey))) {\n\t\theaders.set(name, value);\n\t}\n\ttry {\n\t\tconst response = await fetch(parsedUrl, { ...init, headers });\n\t\tresponseCredentials.set(response, { apiKey: resolvedApiKey, cloudflareApiKey });\n\t\treturn response;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst redactedMessage = redactGeminiCredentials(message, resolvedApiKey, cloudflareApiKey);\n\t\tif (redactedMessage === message) throw error;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (error instanceof Error) redactedError.name = error.name;\n\t\tthrow redactedError;\n\t}\n}\n\nexport function isGeminiApiAvailable(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"Gemini\",\n\t\tconfiguredValue: loadConfig().geminiApiKey,\n\t\tenvironmentValue: process.env.GEMINI_API_KEY,\n\t}) || isGatewayConfigured();\n}\n\nexport interface GeminiApiOptions {\n\tapiKey?: string;\n\tmodel?: string;\n\tmimeType?: string;\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n}\n\nexport interface GeminiGenerateContentResult {\n\ttext: string;\n\tfinishReason?: string;\n\tblockReason?: string;\n}\n\nexport async function queryGeminiApiWithInlineData(\n\tprompt: string,\n\tdata: string,\n\tmimeType: string,\n\toptions: GeminiApiOptions = {},\n): Promise<GeminiGenerateContentResult> {\n\tconst signal = withTimeout(options.signal, options.timeoutMs ?? 120000);\n\tconst apiKey = options.apiKey ?? await getApiKey(signal);\n\tif (!apiKey && !isGatewayConfigured()) {\n\t\tthrow new Error(\n\t\t\t\"Gemini API not configured. Either:\\n\" +\n\t\t\t` 1. Configure geminiApiKey in ${CONFIG_PATH} or set GEMINI_API_KEY\\n` +\n\t\t\t\" 2. Set GOOGLE_GEMINI_BASE_URL + CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing\"\n\t\t);\n\t}\n\n\tconst model = options.model ?? DEFAULT_MODEL;\n\tconst url = `${getVersionedApiBase()}/models/${model}:generateContent`;\n\tconst body = {\n\t\tcontents: [\n\t\t\t{\n\t\t\t\trole: \"user\",\n\t\t\t\tparts: [\n\t\t\t\t\t{ inlineData: { mimeType, data } },\n\t\t\t\t\t{ text: prompt },\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tconst res = await fetchGeminiApi(url, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\tbody: JSON.stringify(body),\n\t\tsignal,\n\t}, apiKey);\n\n\tif (!res.ok) {\n\t\tconst errorText = redactGeminiApiResponse(res, await res.text(), apiKey);\n\t\tthrow new Error(`Gemini API error ${res.status}: ${errorText.slice(0, 300)}`);\n\t}\n\n\tconst response = (await res.json()) as GenerateContentResponse;\n\tconst candidate = response.candidates?.[0];\n\tconst text = candidate?.content?.parts\n\t\t?.map((part) => part.text)\n\t\t.filter((part): part is string => typeof part === \"string\" && part.length > 0)\n\t\t.join(\"\\n\") ?? \"\";\n\n\treturn {\n\t\ttext,\n\t\t...(candidate?.finishReason ? { finishReason: candidate.finishReason } : {}),\n\t\t...(response.promptFeedback?.blockReason ? { blockReason: response.promptFeedback.blockReason } : {}),\n\t};\n}\n\nexport async function queryGeminiApiWithVideo(\n\tprompt: string,\n\tvideoUri: string,\n\toptions: GeminiApiOptions = {},\n): Promise<string> {\n\tconst signal = withTimeout(options.signal, options.timeoutMs ?? 120000);\n\tconst apiKey = options.apiKey ?? await getApiKey(signal);\n\tif (!apiKey && !isGatewayConfigured()) {\n\t\tthrow new Error(\n\t\t\t\"Gemini API not configured. Either:\\n\" +\n\t\t\t` 1. Configure geminiApiKey in ${CONFIG_PATH} or set GEMINI_API_KEY\\n` +\n\t\t\t\" 2. Set GOOGLE_GEMINI_BASE_URL + CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing\"\n\t\t);\n\t}\n\n\tconst model = options.model ?? DEFAULT_MODEL;\n\tconst url = `${getVersionedApiBase()}/models/${model}:generateContent`;\n\n\tconst fileData: Record<string, string> = { fileUri: videoUri };\n\tif (options.mimeType) fileData.mimeType = options.mimeType;\n\n\tconst body = {\n\t\tcontents: [\n\t\t\t{\n\t\t\t\trole: \"user\",\n\t\t\t\tparts: [\n\t\t\t\t\t{ fileData },\n\t\t\t\t\t{ text: prompt },\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tconst res = await fetchGeminiApi(url, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\tbody: JSON.stringify(body),\n\t\tsignal,\n\t}, apiKey);\n\n\tif (!res.ok) {\n\t\tconst errorText = redactGeminiApiResponse(res, await res.text(), apiKey);\n\t\tthrow new Error(`Gemini API error ${res.status}: ${errorText.slice(0, 300)}`);\n\t}\n\n\tconst data = (await res.json()) as GenerateContentResponse;\n\tconst text = data.candidates?.[0]?.content?.parts\n\t\t?.map((p) => p.text)\n\t\t.filter(Boolean)\n\t\t.join(\"\\n\");\n\n\tif (!text) throw new Error(\"Gemini API returned empty response\");\n\treturn text;\n}\n\ninterface GenerateContentResponse {\n\tcandidates?: Array<{\n\t\tcontent?: {\n\t\t\tparts?: Array<{ text?: string }>;\n\t\t};\n\t\tfinishReason?: string;\n\t}>;\n\tpromptFeedback?: {\n\t\tblockReason?: string;\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"gemini-api.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/gemini-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\nimport {\n\tisGeminiAdcAvailable,\n\tgetAdcAccessToken,\n\tgetAdcProject,\n\tgetAdcLocation,\n\tgetVertexApiBase,\n\tisVertexHost,\n} from \"./gemini-adc.ts\";\n\nconst DEFAULT_API_HOST = \"https://generativelanguage.googleapis.com\";\nconst API_VERSION = \"v1beta\";\nexport const API_BASE = `${DEFAULT_API_HOST}/${API_VERSION}`;\nconst CONFIG_PATH = getWebSearchConfigPath();\nexport const DEFAULT_MODEL = \"gemini-3.6-flash\";\n\ninterface GeminiApiConfig {\n\tgeminiApiKey?: unknown;\n\tgeminiBaseUrl?: unknown;\n\tcloudflareApiKey?: unknown;\n}\n\nlet cachedConfig: GeminiApiConfig | null = null;\n\nfunction loadConfig(): GeminiApiConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\n\tconst raw = readFileSync(CONFIG_PATH, \"utf-8\");\n\ttry {\n\t\tcachedConfig = JSON.parse(raw) as GeminiApiConfig;\n\t\treturn cachedConfig;\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n}\n\nfunction withTimeout(signal: AbortSignal | undefined, timeoutMs: number): AbortSignal {\n\tconst timeout = AbortSignal.timeout(timeoutMs);\n\treturn signal ? AbortSignal.any([signal, timeout]) : timeout;\n}\n\nfunction normalizeApiKey(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst normalized = value.trim();\n\treturn normalized.length > 0 ? normalized : null;\n}\n\nfunction normalizeBaseUrl(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst normalized = value.trim().replace(/\\/+$/, \"\");\n\treturn normalized.length > 0 ? normalized : null;\n}\n\nfunction isCloudflareGateway(): boolean {\n\treturn getApiHost().includes(\"gateway.ai.cloudflare.com\");\n}\n\nexport async function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"Gemini\",\n\t\tconfiguredValue: loadConfig().geminiApiKey,\n\t\tenvironmentValue: process.env.GEMINI_API_KEY,\n\t\tsignal,\n\t});\n}\n\nexport function getApiHost(): string {\n\treturn (\n\t\tnormalizeBaseUrl(process.env.GOOGLE_GEMINI_BASE_URL) ??\n\t\tnormalizeBaseUrl(loadConfig().geminiBaseUrl) ??\n\t\tDEFAULT_API_HOST\n\t);\n}\n\nexport function getVersionedApiBase(): string {\n\tconst project = getAdcProject();\n\tconst location = getAdcLocation();\n\tif (isGeminiAdcAvailable() && project && location) {\n\t\treturn getVertexApiBase(project, location);\n\t}\n\treturn `${getApiHost()}/${API_VERSION}`;\n}\n\nexport function getUploadBase(): string {\n\treturn `${getApiHost()}/upload/${API_VERSION}`;\n}\n\nfunction getLegacyCloudflareApiKey(): string | null {\n\treturn normalizeApiKey(process.env.CLOUDFLARE_API_KEY) ?? normalizeApiKey(loadConfig().cloudflareApiKey);\n}\n\nasync function resolveCloudflareApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"Cloudflare\",\n\t\tconfiguredValue: loadConfig().cloudflareApiKey,\n\t\tenvironmentValue: process.env.CLOUDFLARE_API_KEY,\n\t\tsignal,\n\t});\n}\n\nexport function getCloudflareApiKey(): string | null {\n\treturn getLegacyCloudflareApiKey();\n}\n\nexport function isGatewayConfigured(): boolean {\n\treturn isCloudflareGateway() && hasCredentialSource({\n\t\tprovider: \"Cloudflare\",\n\t\tconfiguredValue: loadConfig().cloudflareApiKey,\n\t\tenvironmentValue: process.env.CLOUDFLARE_API_KEY,\n\t});\n}\n\nexport function buildAuthHeaders(apiKey: string | null = null, cloudflareApiKey: string | null = getLegacyCloudflareApiKey()): Record<string, string> {\n\tif (!isCloudflareGateway()) return apiKey ? { \"x-goog-api-key\": apiKey } : {};\n\treturn cloudflareApiKey ? { \"cf-aig-authorization\": `Bearer ${cloudflareApiKey}` } : {};\n}\n\nfunction redactGeminiCredentials(text: string, apiKey: string | null | undefined, cloudflareApiKey: string | null | undefined, adcToken?: string | null): string {\n\tlet out = redactCredential(redactCredential(text, apiKey), cloudflareApiKey);\n\tif (adcToken) out = redactCredential(out, adcToken);\n\treturn out;\n}\n\nconst responseCredentials = new WeakMap<Response, {\n\tapiKey: string | null | undefined;\n\tcloudflareApiKey: string | null | undefined;\n\tadcToken?: string | null;\n}>();\n\nexport function redactGeminiApiResponse(response: Response, text: string, apiKey?: string | null, adcToken?: string | null): string {\n\tconst credentials = responseCredentials.get(response);\n\treturn redactGeminiCredentials(text, credentials?.apiKey ?? apiKey, credentials?.cloudflareApiKey, credentials?.adcToken ?? adcToken);\n}\n\nexport async function fetchGeminiApi(\n\turl: string | URL,\n\tinit: RequestInit = {},\n\tapiKey?: string | null,\n): Promise<Response> {\n\tconst parsedUrl = new URL(url);\n\tfor (const name of parsedUrl.searchParams.keys()) {\n\t\tif ([\"key\", \"api_key\"].includes(name.toLowerCase())) {\n\t\t\tthrow new Error(\"Gemini API credential query parameters are not allowed\");\n\t\t}\n\t}\n\tconst project = getAdcProject();\n\tconst location = getAdcLocation();\n\tconst adcMode = isGeminiAdcAvailable() && !!project && !!location && isVertexHost(parsedUrl.origin);\n\tlet adcToken: string | null = null;\n\tif (adcMode) {\n\t\tadcToken = await getAdcAccessToken(init.signal ?? undefined);\n\t}\n\tconst resolvedApiKey = adcMode ? null : (apiKey === undefined ? await getApiKey(init.signal ?? undefined) : apiKey);\n\tconst cloudflareApiKey = isCloudflareGateway() ? await resolveCloudflareApiKey(init.signal ?? undefined) : null;\n\tconst allowedOrigins = new Set([\n\t\tnew URL(getApiHost()).origin,\n\t\tnew URL(DEFAULT_API_HOST).origin,\n\t\t...(adcMode ? [parsedUrl.origin] : []),\n\t]);\n\tconst needsAuth = resolvedApiKey || isGatewayConfigured() || adcMode;\n\tif (needsAuth && !allowedOrigins.has(parsedUrl.origin)) {\n\t\tthrow new Error(\"Gemini API request host is not allowed\");\n\t}\n\tconst headers = new Headers(init.headers);\n\theaders.delete(\"x-goog-api-key\");\n\theaders.delete(\"cf-aig-authorization\");\n\theaders.delete(\"authorization\");\n\tif (adcMode && adcToken) {\n\t\theaders.set(\"Authorization\", `Bearer ${adcToken}`);\n\t} else {\n\t\tfor (const [name, value] of Object.entries(buildAuthHeaders(resolvedApiKey, cloudflareApiKey))) {\n\t\t\theaders.set(name, value);\n\t\t}\n\t}\n\ttry {\n\t\tconst response = await fetch(parsedUrl, { ...init, headers });\n\t\tresponseCredentials.set(response, { apiKey: resolvedApiKey, cloudflareApiKey, adcToken });\n\t\treturn response;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst redactedMessage = redactGeminiCredentials(message, resolvedApiKey, cloudflareApiKey, adcToken);\n\t\tif (redactedMessage === message) throw error;\n\t\tconst redactedError = new Error(redactedMessage);\n\t\tif (error instanceof Error) redactedError.name = error.name;\n\t\tthrow redactedError;\n\t}\n}\n\nfunction hasGeminiApiKeySource(): boolean {\n\treturn hasCredentialSource({\n\t\tprovider: \"Gemini\",\n\t\tconfiguredValue: loadConfig().geminiApiKey,\n\t\tenvironmentValue: process.env.GEMINI_API_KEY,\n\t});\n}\n\nexport function isGeminiApiAvailable(): boolean {\n\treturn isGeminiAdcAvailable() || hasGeminiApiKeySource() || isGatewayConfigured();\n}\n\n/**\n * Whether the Gemini Files-API paths (YouTube and local video analysis) can\n * authenticate. These use the Gemini Files API and metadata endpoints, which do\n * not support ADC, so they still require an API key or a Cloudflare gateway.\n */\nexport function isGeminiApiAvailableWithVideo(): boolean {\n\treturn hasGeminiApiKeySource() || isGatewayConfigured();\n}\n\nexport interface GeminiApiOptions {\n\tapiKey?: string;\n\tmodel?: string;\n\tmimeType?: string;\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n}\n\nexport interface GeminiGenerateContentResult {\n\ttext: string;\n\tfinishReason?: string;\n\tblockReason?: string;\n}\n\nexport async function queryGeminiApiWithInlineData(\n\tprompt: string,\n\tdata: string,\n\tmimeType: string,\n\toptions: GeminiApiOptions = {},\n): Promise<GeminiGenerateContentResult> {\n\tconst signal = withTimeout(options.signal, options.timeoutMs ?? 120000);\n\tconst apiKey = isGeminiAdcAvailable() ? null : (options.apiKey ?? await getApiKey(signal));\n\tif (!apiKey && !isGatewayConfigured() && !isGeminiAdcAvailable()) {\n\t\tthrow new Error(\n\t\t\t\"Gemini API not configured. Either:\\n\" +\n\t\t\t` 1. Configure geminiApiKey in ${CONFIG_PATH} or set GEMINI_API_KEY\\n` +\n\t\t\t\" 2. Set GOOGLE_GEMINI_BASE_URL + CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing\\n\" +\n\t\t\t\" 3. Set geminiAuth to \\\"adc\\\" with a Google Cloud ADC (GOOGLE_APPLICATION_CREDENTIALS) + project/location\"\n\t\t);\n\t}\n\n\tconst model = options.model ?? DEFAULT_MODEL;\n\tconst url = `${getVersionedApiBase()}/models/${model}:generateContent`;\n\tconst body = {\n\t\tcontents: [\n\t\t\t{\n\t\t\t\trole: \"user\",\n\t\t\t\tparts: [\n\t\t\t\t\t{ inlineData: { mimeType, data } },\n\t\t\t\t\t{ text: prompt },\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tconst res = await fetchGeminiApi(url, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\tbody: JSON.stringify(body),\n\t\tsignal,\n\t}, apiKey);\n\n\tif (!res.ok) {\n\t\tconst errorText = redactGeminiApiResponse(res, await res.text(), apiKey);\n\t\tthrow new Error(`Gemini API error ${res.status}: ${errorText.slice(0, 300)}`);\n\t}\n\n\tconst response = (await res.json()) as GenerateContentResponse;\n\tconst candidate = response.candidates?.[0];\n\tconst text = candidate?.content?.parts\n\t\t?.map((part) => part.text)\n\t\t.filter((part): part is string => typeof part === \"string\" && part.length > 0)\n\t\t.join(\"\\n\") ?? \"\";\n\n\treturn {\n\t\ttext,\n\t\t...(candidate?.finishReason ? { finishReason: candidate.finishReason } : {}),\n\t\t...(response.promptFeedback?.blockReason ? { blockReason: response.promptFeedback.blockReason } : {}),\n\t};\n}\n\nexport async function queryGeminiApiWithVideo(\n\tprompt: string,\n\tvideoUri: string,\n\toptions: GeminiApiOptions = {},\n): Promise<string> {\n\tconst signal = withTimeout(options.signal, options.timeoutMs ?? 120000);\n\tconst apiKey = options.apiKey ?? await getApiKey(signal);\n\tif (!apiKey && !isGatewayConfigured()) {\n\t\tthrow new Error(\n\t\t\t\"Gemini API not configured. Either:\\n\" +\n\t\t\t` 1. Configure geminiApiKey in ${CONFIG_PATH} or set GEMINI_API_KEY\\n` +\n\t\t\t\" 2. Set GOOGLE_GEMINI_BASE_URL + CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing\"\n\t\t);\n\t}\n\n\tconst model = options.model ?? DEFAULT_MODEL;\n\tconst url = `${getVersionedApiBase()}/models/${model}:generateContent`;\n\n\tconst fileData: Record<string, string> = { fileUri: videoUri };\n\tif (options.mimeType) fileData.mimeType = options.mimeType;\n\n\tconst body = {\n\t\tcontents: [\n\t\t\t{\n\t\t\t\trole: \"user\",\n\t\t\t\tparts: [\n\t\t\t\t\t{ fileData },\n\t\t\t\t\t{ text: prompt },\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tconst res = await fetchGeminiApi(url, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\tbody: JSON.stringify(body),\n\t\tsignal,\n\t}, apiKey);\n\n\tif (!res.ok) {\n\t\tconst errorText = redactGeminiApiResponse(res, await res.text(), apiKey);\n\t\tthrow new Error(`Gemini API error ${res.status}: ${errorText.slice(0, 300)}`);\n\t}\n\n\tconst data = (await res.json()) as GenerateContentResponse;\n\tconst text = data.candidates?.[0]?.content?.parts\n\t\t?.map((p) => p.text)\n\t\t.filter(Boolean)\n\t\t.join(\"\\n\");\n\n\tif (!text) throw new Error(\"Gemini API returned empty response\");\n\treturn text;\n}\n\ninterface GenerateContentResponse {\n\tcandidates?: Array<{\n\t\tcontent?: {\n\t\t\tparts?: Array<{ text?: string }>;\n\t\t};\n\t\tfinishReason?: string;\n\t}>;\n\tpromptFeedback?: {\n\t\tblockReason?: string;\n\t};\n}\n"]}
|