Skip to content

Commit 1e54054

Browse files
yu-iskwbenjamincburns
authored andcommitted
feat: Support Custom Metadata Labels on Vertex AI
Signed-off-by: Yu Ishikawa <[email protected]>
1 parent ef9167c commit 1e54054

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

libs/langchain-google-common/src/types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,11 @@ export interface GoogleAIModelRequestParams extends GoogleAIModelParams {
308308
* https://cloud.google.com/vertex-ai/generative-ai/docs/context-cache/context-cache-use
309309
*/
310310
cachedContent?: string;
311+
312+
/**
313+
* Custom metadata labels to associate with the API call.
314+
*/
315+
labels?: Record<string, string>;
311316
}
312317

313318
export interface GoogleAIBaseLLMInput<AuthOptions>
@@ -585,6 +590,11 @@ export interface GeminiRequest {
585590
safetySettings?: GeminiSafetySetting[];
586591
generationConfig?: GeminiGenerationConfig;
587592
cachedContent?: string;
593+
594+
/**
595+
* Custom metadata labels to associate with the API call.
596+
*/
597+
labels?: Record<string, string>;
588598
}
589599

590600
export interface GeminiResponseCandidate {

libs/langchain-google-common/src/utils/gemini.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,6 +1594,7 @@ export function getGeminiAPI(config?: GeminiAPIConfig): GoogleAIAPI {
15941594
const ret: GeminiRequest = {
15951595
contents,
15961596
generationConfig,
1597+
labels: parameters.labels,
15971598
};
15981599
if (tools && tools.length) {
15991600
ret.tools = tools;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { test, expect } from "@jest/globals";
2+
import { ChatVertexAI } from "../chat_models.js";
3+
import { MockClient } from "@langchain/google-common/src/tests/mock.ts";
4+
5+
test("ChatVertexAI should pass labels to the API call", async () => {
6+
const mockClient = new MockClient();
7+
const chatModel = new ChatVertexAI({
8+
model: "gemini-pro",
9+
// We need to force the client to be the mock client for testing purposes.
10+
// This is a bit of a hack, ideally there would be a cleaner way to inject mocks.
11+
// For now, we'll cast the chatModel to access the protected connection property.
12+
// In a real scenario, testing lower-level components or refactoring for dependency injection would be better.
13+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
14+
client: mockClient as any,
15+
});
16+
17+
const labels = {
18+
"user-id": "123",
19+
"session-id": "abc",
20+
};
21+
22+
await chatModel.invoke("hello", {
23+
labels,
24+
});
25+
26+
// Assert that the mock client's request record contains the labels
27+
// The request format is based on the Gemini API request structure
28+
expect(mockClient.record.opts.data.labels).toEqual(labels);
29+
});

0 commit comments

Comments
 (0)