From d56374b93aa935c251fb8a12bf640481672f4dc6 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 2 May 2026 05:16:29 +0100 Subject: [PATCH] fix(pdf): keep gemini keys out of request urls --- CHANGELOG.md | 1 + src/agents/tools/pdf-native-providers.test.ts | 2 ++ src/agents/tools/pdf-native-providers.ts | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eac6657bc8..31ad71576a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ Docs: https://docs.openclaw.ai - Slack/delivery: retry Slack Web API writes only when the SDK wraps a DNS request failure such as `EAI_AGAIN`, so transient resolver hiccups can recover without retrying platform errors that may duplicate messages. Fixes #68789. Thanks @sonnyb9. - Slack/mentions: resolve `` user-group mentions through Slack `usergroups.users.list` and treat them as explicit mentions only when the bot user is a member, so mention-gated agent channels wake for real user-group mentions without config-only allowlists. Fixes #73827. Thanks @CG-Intelligence-Agent-Jack. - Slack/message tool: let `read` fetch an exact Slack message timestamp, including a specific thread reply when paired with `threadId`, instead of returning only the parent thread or recent channel history. Fixes #53943. Thanks @zomars. +- PDF/Gemini: send native PDF analysis API keys in the `x-goog-api-key` header instead of the request URL, keeping secrets out of proxy and access logs. Supersedes #60600. Thanks @garagon. - Web search: point missing-key errors to `web_fetch` for known URLs and the browser tool for interactive pages. Thanks @zhaoyang97. - Web search: late-bind managed agent `web_search` calls to the current runtime config snapshot, so existing sessions do not keep stale unresolved SecretRefs after secrets reload. Fixes #75420. Thanks @richardmqq. - Web search/Gemini: reuse `models.providers.google.apiKey` and `models.providers.google.baseUrl` as lower-priority fallbacks for Gemini web search after dedicated search config and `GEMINI_API_KEY`. Supersedes #57496. Thanks @Aoiujz. diff --git a/src/agents/tools/pdf-native-providers.test.ts b/src/agents/tools/pdf-native-providers.test.ts index b2aedd833f8..8fbe4e1af44 100644 --- a/src/agents/tools/pdf-native-providers.test.ts +++ b/src/agents/tools/pdf-native-providers.test.ts @@ -134,6 +134,8 @@ describe("native PDF provider API calls", () => { const [url, opts] = fetchMock.mock.calls[0]; expect(url).toContain("generateContent"); expect(url).toContain("gemini-2.5-pro"); + expect(url).not.toContain("?key="); + expect(opts.headers["x-goog-api-key"]).toBe("test-key"); expect(opts.signal).toBeInstanceOf(AbortSignal); expect(opts.signal.aborted).toBe(false); const body = JSON.parse(opts.body); diff --git a/src/agents/tools/pdf-native-providers.ts b/src/agents/tools/pdf-native-providers.ts index fc7622145b2..f489aae1be7 100644 --- a/src/agents/tools/pdf-native-providers.ts +++ b/src/agents/tools/pdf-native-providers.ts @@ -153,11 +153,11 @@ export async function geminiAnalyzePdf(params: { /\/v1beta$/i, "", ); - const url = `${baseUrl}/v1beta/models/${encodeURIComponent(params.modelId)}:generateContent?key=${encodeURIComponent(apiKey)}`; + const url = `${baseUrl}/v1beta/models/${encodeURIComponent(params.modelId)}:generateContent`; const res = await fetch(url, { method: "POST", - headers: { "Content-Type": "application/json" }, + headers: { "Content-Type": "application/json", "x-goog-api-key": apiKey }, body: JSON.stringify({ contents: [{ role: "user", parts }], }),