Skip to content

Commit be83756

Browse files
authoredFeb 28, 2025··
Added Custom Header capability to the Server package, to match the Web/Client package (#363)
1 parent 16737d3 commit be83756

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed
 

‎.changeset/lazy-cougars-sip.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@google/generative-ai": patch
3+
---
4+
5+
Added custom header support to the Server package, matching functionality on the client package

‎src/server/request.test.ts

+30-2
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,17 @@ import { match, restore, stub } from "sinon";
2020
import * as sinonChai from "sinon-chai";
2121
import * as chaiAsPromised from "chai-as-promised";
2222
import { DEFAULT_API_VERSION, DEFAULT_BASE_URL } from "../requests/request";
23-
import { FilesRequestUrl, makeServerRequest } from "./request";
23+
import {
24+
FilesRequestUrl,
25+
ServerRequestUrl,
26+
getHeaders,
27+
makeServerRequest,
28+
} from "./request";
2429
import { RpcTask } from "./constants";
25-
import { GoogleGenerativeAIFetchError } from "../errors";
30+
import {
31+
GoogleGenerativeAIFetchError,
32+
GoogleGenerativeAIRequestInputError,
33+
} from "../errors";
2634

2735
use(sinonChai);
2836
use(chaiAsPromised);
@@ -212,4 +220,24 @@ describe("Files API - request methods", () => {
212220
expect(fetchStub).to.be.calledOnce;
213221
});
214222
});
223+
describe("getHeaders", () => {
224+
it("passes custom headers", () => {
225+
const url = new ServerRequestUrl(RpcTask.GET, "key", {
226+
customHeaders: new Headers({ customHeader: "customHeaderValue" }),
227+
});
228+
229+
const headers = getHeaders(url);
230+
231+
expect(headers.get("customHeader")).to.equal("customHeaderValue");
232+
});
233+
it("passes custom x-goog-api-client header", () => {
234+
const url = new ServerRequestUrl(RpcTask.GET, "key", {
235+
customHeaders: new Headers({ "x-goog-api-client": "client/version" }),
236+
});
237+
238+
expect(() => getHeaders(url)).to.throw(
239+
GoogleGenerativeAIRequestInputError,
240+
);
241+
});
242+
});
215243
});

‎src/server/request.ts

+30
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
} from "../requests/request";
2424
import { RequestOptions, SingleRequestOptions } from "../../types";
2525
import { RpcTask } from "./constants";
26+
import { GoogleGenerativeAIRequestInputError } from "../errors";
2627

2728
const taskToMethod = {
2829
[RpcTask.UPLOAD]: "POST",
@@ -91,6 +92,35 @@ export function getHeaders(url: ServerRequestUrl): Headers {
9192
const headers = new Headers();
9293
headers.append("x-goog-api-client", getClientHeaders(url.requestOptions));
9394
headers.append("x-goog-api-key", url.apiKey);
95+
96+
let customHeaders = url.requestOptions?.customHeaders;
97+
if (customHeaders) {
98+
if (!(customHeaders instanceof Headers)) {
99+
try {
100+
customHeaders = new Headers(customHeaders);
101+
} catch (e) {
102+
throw new GoogleGenerativeAIRequestInputError(
103+
`unable to convert customHeaders value ${JSON.stringify(
104+
customHeaders,
105+
)} to Headers: ${e.message}`,
106+
);
107+
}
108+
}
109+
110+
for (const [headerName, headerValue] of customHeaders.entries()) {
111+
if (headerName === "x-goog-api-key") {
112+
throw new GoogleGenerativeAIRequestInputError(
113+
`Cannot set reserved header name ${headerName}`,
114+
);
115+
} else if (headerName === "x-goog-api-client") {
116+
throw new GoogleGenerativeAIRequestInputError(
117+
`Header name ${headerName} can only be set using the apiClient field`,
118+
);
119+
}
120+
121+
headers.append(headerName, headerValue);
122+
}
123+
}
94124
return headers;
95125
}
96126

0 commit comments

Comments
 (0)
Please sign in to comment.