@langchain/google-common 0.1.4 → 0.1.6
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/dist/chat_models.cjs +32 -2
- package/dist/chat_models.d.ts +4 -2
- package/dist/chat_models.js +32 -2
- package/dist/embeddings.cjs +4 -0
- package/dist/embeddings.js +4 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/output_parsers.cjs +175 -0
- package/dist/output_parsers.d.ts +49 -0
- package/dist/output_parsers.js +169 -0
- package/dist/types.cjs +10 -1
- package/dist/types.d.ts +73 -0
- package/dist/types.js +9 -0
- package/dist/utils/common.cjs +13 -1
- package/dist/utils/common.d.ts +1 -1
- package/dist/utils/common.js +13 -1
- package/dist/utils/gemini.cjs +95 -7
- package/dist/utils/gemini.js +95 -7
- package/package.json +1 -1
package/dist/chat_models.cjs
CHANGED
|
@@ -53,10 +53,33 @@ class ChatConnection extends connection_js_1.AbstractGoogleLLMConnection {
|
|
|
53
53
|
}
|
|
54
54
|
return true;
|
|
55
55
|
}
|
|
56
|
+
computeGoogleSearchToolAdjustmentFromModel() {
|
|
57
|
+
if (this.modelName.startsWith("gemini-1.0")) {
|
|
58
|
+
return "googleSearchRetrieval";
|
|
59
|
+
}
|
|
60
|
+
else if (this.modelName.startsWith("gemini-1.5")) {
|
|
61
|
+
return "googleSearchRetrieval";
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return "googleSearch";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
computeGoogleSearchToolAdjustment(apiConfig) {
|
|
68
|
+
const adj = apiConfig.googleSearchToolAdjustment;
|
|
69
|
+
if (adj === undefined || adj === true) {
|
|
70
|
+
return this.computeGoogleSearchToolAdjustmentFromModel();
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
return adj;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
56
76
|
buildGeminiAPI() {
|
|
77
|
+
const apiConfig = this.apiConfig ?? {};
|
|
78
|
+
const googleSearchToolAdjustment = this.computeGoogleSearchToolAdjustment(apiConfig);
|
|
57
79
|
const geminiConfig = {
|
|
58
80
|
useSystemInstruction: this.useSystemInstruction,
|
|
59
|
-
|
|
81
|
+
googleSearchToolAdjustment,
|
|
82
|
+
...apiConfig,
|
|
60
83
|
};
|
|
61
84
|
return (0, gemini_js_1.getGeminiAPI)(geminiConfig);
|
|
62
85
|
}
|
|
@@ -199,7 +222,13 @@ class ChatGoogleBase extends chat_models_1.BaseChatModel {
|
|
|
199
222
|
return new auth_js_1.ApiKeyGoogleAuth(apiKey);
|
|
200
223
|
}
|
|
201
224
|
buildApiKey(fields) {
|
|
202
|
-
|
|
225
|
+
if (fields?.platformType !== "gcp") {
|
|
226
|
+
return fields?.apiKey ?? (0, env_1.getEnvironmentVariable)("GOOGLE_API_KEY");
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
// GCP doesn't support API Keys
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
203
232
|
}
|
|
204
233
|
buildClient(fields) {
|
|
205
234
|
const apiKey = this.buildApiKey(fields);
|
|
@@ -356,6 +385,7 @@ class ChatGoogleBase extends chat_models_1.BaseChatModel {
|
|
|
356
385
|
}
|
|
357
386
|
const llm = this.bind({
|
|
358
387
|
tools,
|
|
388
|
+
tool_choice: functionName,
|
|
359
389
|
});
|
|
360
390
|
if (!includeRaw) {
|
|
361
391
|
return llm.pipe(outputParser).withConfig({
|
package/dist/chat_models.d.ts
CHANGED
|
@@ -7,15 +7,17 @@ import { BaseLanguageModelInput, StructuredOutputMethodOptions } from "@langchai
|
|
|
7
7
|
import type { z } from "zod";
|
|
8
8
|
import { Runnable } from "@langchain/core/runnables";
|
|
9
9
|
import { AsyncCaller } from "@langchain/core/utils/async_caller";
|
|
10
|
-
import { GoogleAIBaseLLMInput, GoogleAIModelParams, GoogleAISafetySetting, GoogleConnectionParams, GooglePlatformType, GoogleAIBaseLanguageModelCallOptions, GoogleAIAPI, GoogleAIAPIParams } from "./types.js";
|
|
10
|
+
import { GoogleAIBaseLLMInput, GoogleAIModelParams, GoogleAISafetySetting, GoogleConnectionParams, GooglePlatformType, GoogleAIBaseLanguageModelCallOptions, GoogleAIAPI, GoogleAIAPIParams, GoogleSearchToolSetting } from "./types.js";
|
|
11
11
|
import { AbstractGoogleLLMConnection } from "./connection.js";
|
|
12
12
|
import { GoogleAbstractedClient } from "./auth.js";
|
|
13
|
-
import type { GoogleBaseLLMInput, GoogleAISafetyHandler, GoogleAISafetyParams, GoogleAIToolType } from "./types.js";
|
|
13
|
+
import type { GoogleBaseLLMInput, GoogleAISafetyHandler, GoogleAISafetyParams, GoogleAIToolType, GeminiAPIConfig } from "./types.js";
|
|
14
14
|
export declare class ChatConnection<AuthOptions> extends AbstractGoogleLLMConnection<BaseMessage[], AuthOptions> {
|
|
15
15
|
convertSystemMessageToHumanContent: boolean | undefined;
|
|
16
16
|
constructor(fields: GoogleAIBaseLLMInput<AuthOptions> | undefined, caller: AsyncCaller, client: GoogleAbstractedClient, streaming: boolean);
|
|
17
17
|
get useSystemInstruction(): boolean;
|
|
18
18
|
get computeUseSystemInstruction(): boolean;
|
|
19
|
+
computeGoogleSearchToolAdjustmentFromModel(): Exclude<GoogleSearchToolSetting, boolean>;
|
|
20
|
+
computeGoogleSearchToolAdjustment(apiConfig: GeminiAPIConfig): Exclude<GoogleSearchToolSetting, true>;
|
|
19
21
|
buildGeminiAPI(): GoogleAIAPI;
|
|
20
22
|
get api(): GoogleAIAPI;
|
|
21
23
|
}
|
package/dist/chat_models.js
CHANGED
|
@@ -50,10 +50,33 @@ export class ChatConnection extends AbstractGoogleLLMConnection {
|
|
|
50
50
|
}
|
|
51
51
|
return true;
|
|
52
52
|
}
|
|
53
|
+
computeGoogleSearchToolAdjustmentFromModel() {
|
|
54
|
+
if (this.modelName.startsWith("gemini-1.0")) {
|
|
55
|
+
return "googleSearchRetrieval";
|
|
56
|
+
}
|
|
57
|
+
else if (this.modelName.startsWith("gemini-1.5")) {
|
|
58
|
+
return "googleSearchRetrieval";
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
return "googleSearch";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
computeGoogleSearchToolAdjustment(apiConfig) {
|
|
65
|
+
const adj = apiConfig.googleSearchToolAdjustment;
|
|
66
|
+
if (adj === undefined || adj === true) {
|
|
67
|
+
return this.computeGoogleSearchToolAdjustmentFromModel();
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return adj;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
53
73
|
buildGeminiAPI() {
|
|
74
|
+
const apiConfig = this.apiConfig ?? {};
|
|
75
|
+
const googleSearchToolAdjustment = this.computeGoogleSearchToolAdjustment(apiConfig);
|
|
54
76
|
const geminiConfig = {
|
|
55
77
|
useSystemInstruction: this.useSystemInstruction,
|
|
56
|
-
|
|
78
|
+
googleSearchToolAdjustment,
|
|
79
|
+
...apiConfig,
|
|
57
80
|
};
|
|
58
81
|
return getGeminiAPI(geminiConfig);
|
|
59
82
|
}
|
|
@@ -195,7 +218,13 @@ export class ChatGoogleBase extends BaseChatModel {
|
|
|
195
218
|
return new ApiKeyGoogleAuth(apiKey);
|
|
196
219
|
}
|
|
197
220
|
buildApiKey(fields) {
|
|
198
|
-
|
|
221
|
+
if (fields?.platformType !== "gcp") {
|
|
222
|
+
return fields?.apiKey ?? getEnvironmentVariable("GOOGLE_API_KEY");
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
// GCP doesn't support API Keys
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
199
228
|
}
|
|
200
229
|
buildClient(fields) {
|
|
201
230
|
const apiKey = this.buildApiKey(fields);
|
|
@@ -352,6 +381,7 @@ export class ChatGoogleBase extends BaseChatModel {
|
|
|
352
381
|
}
|
|
353
382
|
const llm = this.bind({
|
|
354
383
|
tools,
|
|
384
|
+
tool_choice: functionName,
|
|
355
385
|
});
|
|
356
386
|
if (!includeRaw) {
|
|
357
387
|
return llm.pipe(outputParser).withConfig({
|
package/dist/embeddings.cjs
CHANGED
|
@@ -19,6 +19,10 @@ class EmbeddingsConnection extends connection_js_1.GoogleAIConnection {
|
|
|
19
19
|
async buildUrlMethod() {
|
|
20
20
|
return "predict";
|
|
21
21
|
}
|
|
22
|
+
get modelPublisher() {
|
|
23
|
+
// All the embedding models are currently published by "google"
|
|
24
|
+
return "google";
|
|
25
|
+
}
|
|
22
26
|
async formatData(input, parameters) {
|
|
23
27
|
return {
|
|
24
28
|
instances: input,
|
package/dist/embeddings.js
CHANGED
|
@@ -16,6 +16,10 @@ class EmbeddingsConnection extends GoogleAIConnection {
|
|
|
16
16
|
async buildUrlMethod() {
|
|
17
17
|
return "predict";
|
|
18
18
|
}
|
|
19
|
+
get modelPublisher() {
|
|
20
|
+
// All the embedding models are currently published by "google"
|
|
21
|
+
return "google";
|
|
22
|
+
}
|
|
19
23
|
async formatData(input, parameters) {
|
|
20
24
|
return {
|
|
21
25
|
instances: input,
|
package/dist/index.cjs
CHANGED
|
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./chat_models.cjs"), exports);
|
|
18
18
|
__exportStar(require("./llms.cjs"), exports);
|
|
19
19
|
__exportStar(require("./embeddings.cjs"), exports);
|
|
20
|
+
__exportStar(require("./output_parsers.cjs"), exports);
|
|
20
21
|
__exportStar(require("./auth.cjs"), exports);
|
|
21
22
|
__exportStar(require("./connection.cjs"), exports);
|
|
22
23
|
__exportStar(require("./types.cjs"), exports);
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MarkdownGoogleSearchOutputParser = exports.SimpleGoogleSearchOutputParser = exports.BaseGoogleSearchOutputParser = void 0;
|
|
4
|
+
const output_parsers_1 = require("@langchain/core/output_parsers");
|
|
5
|
+
class BaseGoogleSearchOutputParser extends output_parsers_1.BaseLLMOutputParser {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
Object.defineProperty(this, "lc_namespace", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value: ["google_common", "output_parsers"]
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
generationToGroundingInfo(generation) {
|
|
16
|
+
if ("message" in generation) {
|
|
17
|
+
const responseMetadata = generation?.message?.response_metadata;
|
|
18
|
+
const metadata = responseMetadata.groundingMetadata;
|
|
19
|
+
const supports = responseMetadata.groundingSupport ?? metadata.groundingSupports ?? [];
|
|
20
|
+
if (metadata) {
|
|
21
|
+
return {
|
|
22
|
+
metadata,
|
|
23
|
+
supports,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
generationsToGroundingInfo(generations) {
|
|
30
|
+
for (const generation of generations) {
|
|
31
|
+
const info = this.generationToGroundingInfo(generation);
|
|
32
|
+
if (info !== undefined) {
|
|
33
|
+
return info;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
generationToString(generation) {
|
|
39
|
+
if ("message" in generation) {
|
|
40
|
+
const content = generation?.message?.content;
|
|
41
|
+
if (typeof content === "string") {
|
|
42
|
+
return content;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
return content
|
|
46
|
+
.map((c) => {
|
|
47
|
+
if (c?.type === "text") {
|
|
48
|
+
return c?.text ?? "";
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
return "";
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
.reduce((previousValue, currentValue) => `${previousValue}${currentValue}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return generation.text;
|
|
58
|
+
}
|
|
59
|
+
generationsToString(generations) {
|
|
60
|
+
return generations
|
|
61
|
+
.map((generation) => this.generationToString(generation))
|
|
62
|
+
.reduce((previousValue, currentValue) => `${previousValue}${currentValue}`);
|
|
63
|
+
}
|
|
64
|
+
annotateSegment(text, grounding, support, index) {
|
|
65
|
+
const start = support.segment.startIndex ?? 0;
|
|
66
|
+
const end = support.segment.endIndex;
|
|
67
|
+
const textBefore = text.substring(0, start);
|
|
68
|
+
const textSegment = text.substring(start, end);
|
|
69
|
+
const textAfter = text.substring(end);
|
|
70
|
+
const textPrefix = this.segmentPrefix(grounding, support, index) ?? "";
|
|
71
|
+
const textSuffix = this.segmentSuffix(grounding, support, index) ?? "";
|
|
72
|
+
return `${textBefore}${textPrefix}${textSegment}${textSuffix}${textAfter}`;
|
|
73
|
+
}
|
|
74
|
+
annotateTextSegments(text, grounding) {
|
|
75
|
+
// Go through each support info in reverse, since the segment info
|
|
76
|
+
// is sorted, and we won't need to adjust string indexes this way.
|
|
77
|
+
let ret = text;
|
|
78
|
+
for (let co = grounding.supports.length - 1; co >= 0; co -= 1) {
|
|
79
|
+
const support = grounding.supports[co];
|
|
80
|
+
ret = this.annotateSegment(ret, grounding, support, co);
|
|
81
|
+
}
|
|
82
|
+
return ret;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Google requires us to
|
|
86
|
+
* "Display the Search Suggestion exactly as provided without any modifications"
|
|
87
|
+
* So this will typically be called from the textSuffix() method to get
|
|
88
|
+
* a string that renders HTML.
|
|
89
|
+
* See https://ai.google.dev/gemini-api/docs/grounding/search-suggestions
|
|
90
|
+
* @param grounding
|
|
91
|
+
*/
|
|
92
|
+
searchSuggestion(grounding) {
|
|
93
|
+
return grounding.metadata.searchEntryPoint?.renderedContent ?? "";
|
|
94
|
+
}
|
|
95
|
+
annotateText(text, grounding) {
|
|
96
|
+
const prefix = this.textPrefix(text, grounding) ?? "";
|
|
97
|
+
const suffix = this.textSuffix(text, grounding) ?? "";
|
|
98
|
+
const body = this.annotateTextSegments(text, grounding);
|
|
99
|
+
return `${prefix}${body}${suffix}`;
|
|
100
|
+
}
|
|
101
|
+
async parseResult(generations, _callbacks) {
|
|
102
|
+
const text = this.generationsToString(generations);
|
|
103
|
+
const grounding = this.generationsToGroundingInfo(generations);
|
|
104
|
+
if (!grounding) {
|
|
105
|
+
return text;
|
|
106
|
+
}
|
|
107
|
+
return this.annotateText(text, grounding);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.BaseGoogleSearchOutputParser = BaseGoogleSearchOutputParser;
|
|
111
|
+
class SimpleGoogleSearchOutputParser extends BaseGoogleSearchOutputParser {
|
|
112
|
+
segmentPrefix(_grounding, _support, _index) {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
segmentSuffix(_grounding, support, _index) {
|
|
116
|
+
const indices = support.groundingChunkIndices.map((i) => i + 1);
|
|
117
|
+
return ` [${indices.join(", ")}]`;
|
|
118
|
+
}
|
|
119
|
+
textPrefix(_text, _grounding) {
|
|
120
|
+
return "Google Says:\n";
|
|
121
|
+
}
|
|
122
|
+
chunkToString(chunk, index) {
|
|
123
|
+
const info = chunk.retrievedContext ?? chunk.web;
|
|
124
|
+
return `${index + 1}. ${info.title} - ${info.uri}`;
|
|
125
|
+
}
|
|
126
|
+
textSuffix(_text, grounding) {
|
|
127
|
+
let ret = "\n";
|
|
128
|
+
const chunks = grounding.metadata.groundingChunks;
|
|
129
|
+
chunks.forEach((chunk, index) => {
|
|
130
|
+
ret = `${ret}${this.chunkToString(chunk, index)}\n`;
|
|
131
|
+
});
|
|
132
|
+
return ret;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.SimpleGoogleSearchOutputParser = SimpleGoogleSearchOutputParser;
|
|
136
|
+
class MarkdownGoogleSearchOutputParser extends BaseGoogleSearchOutputParser {
|
|
137
|
+
segmentPrefix(_grounding, _support, _index) {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
chunkLink(grounding, index) {
|
|
141
|
+
const chunk = grounding.metadata.groundingChunks[index];
|
|
142
|
+
const url = chunk.retrievedContext?.uri ?? chunk.web?.uri;
|
|
143
|
+
const num = index + 1;
|
|
144
|
+
return `[[${num}](${url})]`;
|
|
145
|
+
}
|
|
146
|
+
segmentSuffix(grounding, support, _index) {
|
|
147
|
+
let ret = "";
|
|
148
|
+
support.groundingChunkIndices.forEach((chunkIndex) => {
|
|
149
|
+
const link = this.chunkLink(grounding, chunkIndex);
|
|
150
|
+
ret = `${ret}${link}`;
|
|
151
|
+
});
|
|
152
|
+
return ret;
|
|
153
|
+
}
|
|
154
|
+
textPrefix(_text, _grounding) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
chunkSuffixLink(chunk, index) {
|
|
158
|
+
const num = index + 1;
|
|
159
|
+
const info = chunk.retrievedContext ?? chunk.web;
|
|
160
|
+
const url = info.uri;
|
|
161
|
+
const site = info.title;
|
|
162
|
+
return `${num}. [${site}](${url})`;
|
|
163
|
+
}
|
|
164
|
+
textSuffix(_text, grounding) {
|
|
165
|
+
let ret = "\n**Search Sources**\n";
|
|
166
|
+
const chunks = grounding.metadata.groundingChunks;
|
|
167
|
+
chunks.forEach((chunk, index) => {
|
|
168
|
+
ret = `${ret}${this.chunkSuffixLink(chunk, index)}\n`;
|
|
169
|
+
});
|
|
170
|
+
const search = this.searchSuggestion(grounding);
|
|
171
|
+
ret = `${ret}\n${search}`;
|
|
172
|
+
return ret;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.MarkdownGoogleSearchOutputParser = MarkdownGoogleSearchOutputParser;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { BaseLLMOutputParser } from "@langchain/core/output_parsers";
|
|
2
|
+
import { Callbacks } from "@langchain/core/callbacks/manager";
|
|
3
|
+
import { ChatGeneration, Generation } from "@langchain/core/outputs";
|
|
4
|
+
import { GeminiGroundingChunk, GeminiGroundingMetadata, GeminiGroundingSupport } from "./types.js";
|
|
5
|
+
type Generations = Generation[] | ChatGeneration[];
|
|
6
|
+
type GroundingInfo = {
|
|
7
|
+
metadata: GeminiGroundingMetadata;
|
|
8
|
+
supports: GeminiGroundingSupport[];
|
|
9
|
+
};
|
|
10
|
+
export declare abstract class BaseGoogleSearchOutputParser extends BaseLLMOutputParser<string> {
|
|
11
|
+
lc_namespace: string[];
|
|
12
|
+
protected generationToGroundingInfo(generation: Generation | ChatGeneration): GroundingInfo | undefined;
|
|
13
|
+
protected generationsToGroundingInfo(generations: Generations): GroundingInfo | undefined;
|
|
14
|
+
protected generationToString(generation: Generation | ChatGeneration): string;
|
|
15
|
+
protected generationsToString(generations: Generations): string;
|
|
16
|
+
protected abstract segmentPrefix(grounding: GroundingInfo, support: GeminiGroundingSupport, index: number): string | undefined;
|
|
17
|
+
protected abstract segmentSuffix(grounding: GroundingInfo, support: GeminiGroundingSupport, index: number): string | undefined;
|
|
18
|
+
protected annotateSegment(text: string, grounding: GroundingInfo, support: GeminiGroundingSupport, index: number): string;
|
|
19
|
+
protected annotateTextSegments(text: string, grounding: GroundingInfo): string;
|
|
20
|
+
protected abstract textPrefix(text: string, grounding: GroundingInfo): string | undefined;
|
|
21
|
+
protected abstract textSuffix(text: string, grounding: GroundingInfo): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Google requires us to
|
|
24
|
+
* "Display the Search Suggestion exactly as provided without any modifications"
|
|
25
|
+
* So this will typically be called from the textSuffix() method to get
|
|
26
|
+
* a string that renders HTML.
|
|
27
|
+
* See https://ai.google.dev/gemini-api/docs/grounding/search-suggestions
|
|
28
|
+
* @param grounding
|
|
29
|
+
*/
|
|
30
|
+
protected searchSuggestion(grounding: GroundingInfo): string;
|
|
31
|
+
protected annotateText(text: string, grounding: GroundingInfo): string;
|
|
32
|
+
parseResult(generations: Generations, _callbacks?: Callbacks): Promise<string>;
|
|
33
|
+
}
|
|
34
|
+
export declare class SimpleGoogleSearchOutputParser extends BaseGoogleSearchOutputParser {
|
|
35
|
+
protected segmentPrefix(_grounding: GroundingInfo, _support: GeminiGroundingSupport, _index: number): string | undefined;
|
|
36
|
+
protected segmentSuffix(_grounding: GroundingInfo, support: GeminiGroundingSupport, _index: number): string | undefined;
|
|
37
|
+
protected textPrefix(_text: string, _grounding: GroundingInfo): string;
|
|
38
|
+
protected chunkToString(chunk: GeminiGroundingChunk, index: number): string;
|
|
39
|
+
protected textSuffix(_text: string, grounding: GroundingInfo): string;
|
|
40
|
+
}
|
|
41
|
+
export declare class MarkdownGoogleSearchOutputParser extends BaseGoogleSearchOutputParser {
|
|
42
|
+
protected segmentPrefix(_grounding: GroundingInfo, _support: GeminiGroundingSupport, _index: number): string | undefined;
|
|
43
|
+
protected chunkLink(grounding: GroundingInfo, index: number): string;
|
|
44
|
+
protected segmentSuffix(grounding: GroundingInfo, support: GeminiGroundingSupport, _index: number): string | undefined;
|
|
45
|
+
protected textPrefix(_text: string, _grounding: GroundingInfo): string | undefined;
|
|
46
|
+
protected chunkSuffixLink(chunk: GeminiGroundingChunk, index: number): string;
|
|
47
|
+
protected textSuffix(_text: string, grounding: GroundingInfo): string | undefined;
|
|
48
|
+
}
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { BaseLLMOutputParser } from "@langchain/core/output_parsers";
|
|
2
|
+
export class BaseGoogleSearchOutputParser extends BaseLLMOutputParser {
|
|
3
|
+
constructor() {
|
|
4
|
+
super(...arguments);
|
|
5
|
+
Object.defineProperty(this, "lc_namespace", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: ["google_common", "output_parsers"]
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
generationToGroundingInfo(generation) {
|
|
13
|
+
if ("message" in generation) {
|
|
14
|
+
const responseMetadata = generation?.message?.response_metadata;
|
|
15
|
+
const metadata = responseMetadata.groundingMetadata;
|
|
16
|
+
const supports = responseMetadata.groundingSupport ?? metadata.groundingSupports ?? [];
|
|
17
|
+
if (metadata) {
|
|
18
|
+
return {
|
|
19
|
+
metadata,
|
|
20
|
+
supports,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
generationsToGroundingInfo(generations) {
|
|
27
|
+
for (const generation of generations) {
|
|
28
|
+
const info = this.generationToGroundingInfo(generation);
|
|
29
|
+
if (info !== undefined) {
|
|
30
|
+
return info;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
generationToString(generation) {
|
|
36
|
+
if ("message" in generation) {
|
|
37
|
+
const content = generation?.message?.content;
|
|
38
|
+
if (typeof content === "string") {
|
|
39
|
+
return content;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
return content
|
|
43
|
+
.map((c) => {
|
|
44
|
+
if (c?.type === "text") {
|
|
45
|
+
return c?.text ?? "";
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return "";
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
.reduce((previousValue, currentValue) => `${previousValue}${currentValue}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return generation.text;
|
|
55
|
+
}
|
|
56
|
+
generationsToString(generations) {
|
|
57
|
+
return generations
|
|
58
|
+
.map((generation) => this.generationToString(generation))
|
|
59
|
+
.reduce((previousValue, currentValue) => `${previousValue}${currentValue}`);
|
|
60
|
+
}
|
|
61
|
+
annotateSegment(text, grounding, support, index) {
|
|
62
|
+
const start = support.segment.startIndex ?? 0;
|
|
63
|
+
const end = support.segment.endIndex;
|
|
64
|
+
const textBefore = text.substring(0, start);
|
|
65
|
+
const textSegment = text.substring(start, end);
|
|
66
|
+
const textAfter = text.substring(end);
|
|
67
|
+
const textPrefix = this.segmentPrefix(grounding, support, index) ?? "";
|
|
68
|
+
const textSuffix = this.segmentSuffix(grounding, support, index) ?? "";
|
|
69
|
+
return `${textBefore}${textPrefix}${textSegment}${textSuffix}${textAfter}`;
|
|
70
|
+
}
|
|
71
|
+
annotateTextSegments(text, grounding) {
|
|
72
|
+
// Go through each support info in reverse, since the segment info
|
|
73
|
+
// is sorted, and we won't need to adjust string indexes this way.
|
|
74
|
+
let ret = text;
|
|
75
|
+
for (let co = grounding.supports.length - 1; co >= 0; co -= 1) {
|
|
76
|
+
const support = grounding.supports[co];
|
|
77
|
+
ret = this.annotateSegment(ret, grounding, support, co);
|
|
78
|
+
}
|
|
79
|
+
return ret;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Google requires us to
|
|
83
|
+
* "Display the Search Suggestion exactly as provided without any modifications"
|
|
84
|
+
* So this will typically be called from the textSuffix() method to get
|
|
85
|
+
* a string that renders HTML.
|
|
86
|
+
* See https://ai.google.dev/gemini-api/docs/grounding/search-suggestions
|
|
87
|
+
* @param grounding
|
|
88
|
+
*/
|
|
89
|
+
searchSuggestion(grounding) {
|
|
90
|
+
return grounding.metadata.searchEntryPoint?.renderedContent ?? "";
|
|
91
|
+
}
|
|
92
|
+
annotateText(text, grounding) {
|
|
93
|
+
const prefix = this.textPrefix(text, grounding) ?? "";
|
|
94
|
+
const suffix = this.textSuffix(text, grounding) ?? "";
|
|
95
|
+
const body = this.annotateTextSegments(text, grounding);
|
|
96
|
+
return `${prefix}${body}${suffix}`;
|
|
97
|
+
}
|
|
98
|
+
async parseResult(generations, _callbacks) {
|
|
99
|
+
const text = this.generationsToString(generations);
|
|
100
|
+
const grounding = this.generationsToGroundingInfo(generations);
|
|
101
|
+
if (!grounding) {
|
|
102
|
+
return text;
|
|
103
|
+
}
|
|
104
|
+
return this.annotateText(text, grounding);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export class SimpleGoogleSearchOutputParser extends BaseGoogleSearchOutputParser {
|
|
108
|
+
segmentPrefix(_grounding, _support, _index) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
segmentSuffix(_grounding, support, _index) {
|
|
112
|
+
const indices = support.groundingChunkIndices.map((i) => i + 1);
|
|
113
|
+
return ` [${indices.join(", ")}]`;
|
|
114
|
+
}
|
|
115
|
+
textPrefix(_text, _grounding) {
|
|
116
|
+
return "Google Says:\n";
|
|
117
|
+
}
|
|
118
|
+
chunkToString(chunk, index) {
|
|
119
|
+
const info = chunk.retrievedContext ?? chunk.web;
|
|
120
|
+
return `${index + 1}. ${info.title} - ${info.uri}`;
|
|
121
|
+
}
|
|
122
|
+
textSuffix(_text, grounding) {
|
|
123
|
+
let ret = "\n";
|
|
124
|
+
const chunks = grounding.metadata.groundingChunks;
|
|
125
|
+
chunks.forEach((chunk, index) => {
|
|
126
|
+
ret = `${ret}${this.chunkToString(chunk, index)}\n`;
|
|
127
|
+
});
|
|
128
|
+
return ret;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export class MarkdownGoogleSearchOutputParser extends BaseGoogleSearchOutputParser {
|
|
132
|
+
segmentPrefix(_grounding, _support, _index) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
chunkLink(grounding, index) {
|
|
136
|
+
const chunk = grounding.metadata.groundingChunks[index];
|
|
137
|
+
const url = chunk.retrievedContext?.uri ?? chunk.web?.uri;
|
|
138
|
+
const num = index + 1;
|
|
139
|
+
return `[[${num}](${url})]`;
|
|
140
|
+
}
|
|
141
|
+
segmentSuffix(grounding, support, _index) {
|
|
142
|
+
let ret = "";
|
|
143
|
+
support.groundingChunkIndices.forEach((chunkIndex) => {
|
|
144
|
+
const link = this.chunkLink(grounding, chunkIndex);
|
|
145
|
+
ret = `${ret}${link}`;
|
|
146
|
+
});
|
|
147
|
+
return ret;
|
|
148
|
+
}
|
|
149
|
+
textPrefix(_text, _grounding) {
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
chunkSuffixLink(chunk, index) {
|
|
153
|
+
const num = index + 1;
|
|
154
|
+
const info = chunk.retrievedContext ?? chunk.web;
|
|
155
|
+
const url = info.uri;
|
|
156
|
+
const site = info.title;
|
|
157
|
+
return `${num}. [${site}](${url})`;
|
|
158
|
+
}
|
|
159
|
+
textSuffix(_text, grounding) {
|
|
160
|
+
let ret = "\n**Search Sources**\n";
|
|
161
|
+
const chunks = grounding.metadata.groundingChunks;
|
|
162
|
+
chunks.forEach((chunk, index) => {
|
|
163
|
+
ret = `${ret}${this.chunkSuffixLink(chunk, index)}\n`;
|
|
164
|
+
});
|
|
165
|
+
const search = this.searchSuggestion(grounding);
|
|
166
|
+
ret = `${ret}\n${search}`;
|
|
167
|
+
return ret;
|
|
168
|
+
}
|
|
169
|
+
}
|
package/dist/types.cjs
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.GoogleAISafetyMethod = exports.GoogleAISafetyThreshold = exports.GoogleAISafetyCategory = void 0;
|
|
17
|
+
exports.GeminiToolAttributes = exports.GeminiSearchToolAttributes = exports.GoogleAISafetyMethod = exports.GoogleAISafetyThreshold = exports.GoogleAISafetyCategory = void 0;
|
|
18
18
|
__exportStar(require("./types-anthropic.cjs"), exports);
|
|
19
19
|
exports.GoogleAISafetyCategory = {
|
|
20
20
|
Harassment: "HARM_CATEGORY_HARASSMENT",
|
|
@@ -54,3 +54,12 @@ exports.GoogleAISafetyMethod = {
|
|
|
54
54
|
Severity: "SEVERITY",
|
|
55
55
|
Probability: "PROBABILITY",
|
|
56
56
|
};
|
|
57
|
+
exports.GeminiSearchToolAttributes = [
|
|
58
|
+
"googleSearchRetrieval",
|
|
59
|
+
"googleSearch",
|
|
60
|
+
];
|
|
61
|
+
exports.GeminiToolAttributes = [
|
|
62
|
+
"functionDeclaration",
|
|
63
|
+
"retrieval",
|
|
64
|
+
...exports.GeminiSearchToolAttributes,
|
|
65
|
+
];
|
package/dist/types.d.ts
CHANGED
|
@@ -219,6 +219,60 @@ export type GeminiSafetyRating = {
|
|
|
219
219
|
category: string;
|
|
220
220
|
probability: string;
|
|
221
221
|
} & Record<string, unknown>;
|
|
222
|
+
export interface GeminiCitationMetadata {
|
|
223
|
+
citations: GeminiCitation[];
|
|
224
|
+
}
|
|
225
|
+
export interface GeminiCitation {
|
|
226
|
+
startIndex: number;
|
|
227
|
+
endIndex: number;
|
|
228
|
+
uri: string;
|
|
229
|
+
title: string;
|
|
230
|
+
license: string;
|
|
231
|
+
publicationDate: GoogleTypeDate;
|
|
232
|
+
}
|
|
233
|
+
export interface GoogleTypeDate {
|
|
234
|
+
year: number;
|
|
235
|
+
month: number;
|
|
236
|
+
day: number;
|
|
237
|
+
}
|
|
238
|
+
export interface GeminiGroundingMetadata {
|
|
239
|
+
webSearchQueries?: string[];
|
|
240
|
+
searchEntryPoint?: GeminiSearchEntryPoint;
|
|
241
|
+
groundingChunks: GeminiGroundingChunk[];
|
|
242
|
+
groundingSupports?: GeminiGroundingSupport[];
|
|
243
|
+
retrievalMetadata?: GeminiRetrievalMetadata;
|
|
244
|
+
}
|
|
245
|
+
export interface GeminiSearchEntryPoint {
|
|
246
|
+
renderedContent?: string;
|
|
247
|
+
sdkBlob?: string;
|
|
248
|
+
}
|
|
249
|
+
export interface GeminiGroundingChunk {
|
|
250
|
+
web: GeminiGroundingChunkWeb;
|
|
251
|
+
retrievedContext: GeminiGroundingChunkRetrievedContext;
|
|
252
|
+
}
|
|
253
|
+
export interface GeminiGroundingChunkWeb {
|
|
254
|
+
uri: string;
|
|
255
|
+
title: string;
|
|
256
|
+
}
|
|
257
|
+
export interface GeminiGroundingChunkRetrievedContext {
|
|
258
|
+
uri: string;
|
|
259
|
+
title: string;
|
|
260
|
+
text: string;
|
|
261
|
+
}
|
|
262
|
+
export interface GeminiGroundingSupport {
|
|
263
|
+
segment: GeminiSegment;
|
|
264
|
+
groundingChunkIndices: number[];
|
|
265
|
+
confidenceScores: number[];
|
|
266
|
+
}
|
|
267
|
+
export interface GeminiSegment {
|
|
268
|
+
partIndex: number;
|
|
269
|
+
startIndex: number;
|
|
270
|
+
endIndex: number;
|
|
271
|
+
text: string;
|
|
272
|
+
}
|
|
273
|
+
export interface GeminiRetrievalMetadata {
|
|
274
|
+
googleSearchDynamicRetrievalScore: number;
|
|
275
|
+
}
|
|
222
276
|
export type GeminiRole = "system" | "user" | "model" | "function";
|
|
223
277
|
export interface GeminiContent {
|
|
224
278
|
parts: GeminiPart[];
|
|
@@ -227,14 +281,20 @@ export interface GeminiContent {
|
|
|
227
281
|
export interface GeminiTool {
|
|
228
282
|
functionDeclarations?: GeminiFunctionDeclaration[];
|
|
229
283
|
googleSearchRetrieval?: GoogleSearchRetrieval;
|
|
284
|
+
googleSearch?: GoogleSearch;
|
|
230
285
|
retrieval?: VertexAIRetrieval;
|
|
231
286
|
}
|
|
287
|
+
export type GoogleSearchToolSetting = boolean | "googleSearchRetrieval" | "googleSearch" | string;
|
|
288
|
+
export declare const GeminiSearchToolAttributes: string[];
|
|
289
|
+
export declare const GeminiToolAttributes: string[];
|
|
232
290
|
export interface GoogleSearchRetrieval {
|
|
233
291
|
dynamicRetrievalConfig?: {
|
|
234
292
|
mode?: string;
|
|
235
293
|
dynamicThreshold?: number;
|
|
236
294
|
};
|
|
237
295
|
}
|
|
296
|
+
export interface GoogleSearch {
|
|
297
|
+
}
|
|
238
298
|
export interface VertexAIRetrieval {
|
|
239
299
|
vertexAiSearch: {
|
|
240
300
|
datastore: string;
|
|
@@ -288,6 +348,8 @@ interface GeminiResponseCandidate {
|
|
|
288
348
|
index: number;
|
|
289
349
|
tokenCount?: number;
|
|
290
350
|
safetyRatings: GeminiSafetyRating[];
|
|
351
|
+
citationMetadata?: GeminiCitationMetadata;
|
|
352
|
+
groundingMetadata?: GeminiGroundingMetadata;
|
|
291
353
|
}
|
|
292
354
|
interface GeminiResponsePromptFeedback {
|
|
293
355
|
blockReason?: string;
|
|
@@ -339,6 +401,17 @@ export interface GeminiAPIConfig {
|
|
|
339
401
|
safetyHandler?: GoogleAISafetyHandler;
|
|
340
402
|
mediaManager?: MediaManager;
|
|
341
403
|
useSystemInstruction?: boolean;
|
|
404
|
+
/**
|
|
405
|
+
* How to handle the Google Search tool, since the name (and format)
|
|
406
|
+
* of the tool changes between Gemini 1.5 and Gemini 2.0.
|
|
407
|
+
* true - Change based on the model version. (Default)
|
|
408
|
+
* false - Do not change the tool name provided
|
|
409
|
+
* string value - Use this as the attribute name for the search
|
|
410
|
+
* tool, adapting any tool attributes if possible.
|
|
411
|
+
* When the model is created, a "true" or default setting
|
|
412
|
+
* will be changed to a string based on the model.
|
|
413
|
+
*/
|
|
414
|
+
googleSearchToolAdjustment?: GoogleSearchToolSetting;
|
|
342
415
|
}
|
|
343
416
|
export type GoogleAIAPIConfig = GeminiAPIConfig | AnthropicAPIConfig;
|
|
344
417
|
export interface GoogleAIAPIParams {
|
package/dist/types.js
CHANGED
|
@@ -37,3 +37,12 @@ export const GoogleAISafetyMethod = {
|
|
|
37
37
|
Severity: "SEVERITY",
|
|
38
38
|
Probability: "PROBABILITY",
|
|
39
39
|
};
|
|
40
|
+
export const GeminiSearchToolAttributes = [
|
|
41
|
+
"googleSearchRetrieval",
|
|
42
|
+
"googleSearch",
|
|
43
|
+
];
|
|
44
|
+
export const GeminiToolAttributes = [
|
|
45
|
+
"functionDeclaration",
|
|
46
|
+
"retrieval",
|
|
47
|
+
...GeminiSearchToolAttributes,
|
|
48
|
+
];
|
package/dist/utils/common.cjs
CHANGED
|
@@ -4,6 +4,7 @@ exports.copyAndValidateModelParamsInto = exports.validateModelParams = exports.m
|
|
|
4
4
|
const base_1 = require("@langchain/core/language_models/base");
|
|
5
5
|
const function_calling_1 = require("@langchain/core/utils/function_calling");
|
|
6
6
|
const gemini_js_1 = require("./gemini.cjs");
|
|
7
|
+
const types_js_1 = require("../types.cjs");
|
|
7
8
|
const zod_to_gemini_parameters_js_1 = require("./zod_to_gemini_parameters.cjs");
|
|
8
9
|
const anthropic_js_1 = require("./anthropic.cjs");
|
|
9
10
|
function copyAIModelParams(params, options) {
|
|
@@ -37,11 +38,22 @@ function processToolChoice(toolChoice, allowedFunctionNames) {
|
|
|
37
38
|
}
|
|
38
39
|
throw new Error("Object inputs for tool_choice not supported.");
|
|
39
40
|
}
|
|
41
|
+
function isGeminiTool(tool) {
|
|
42
|
+
for (const toolAttribute of types_js_1.GeminiToolAttributes) {
|
|
43
|
+
if (toolAttribute in tool) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
function isGeminiNonFunctionTool(tool) {
|
|
50
|
+
return isGeminiTool(tool) && !("functionDeclaration" in tool);
|
|
51
|
+
}
|
|
40
52
|
function convertToGeminiTools(tools) {
|
|
41
53
|
const geminiTools = [];
|
|
42
54
|
let functionDeclarationsIndex = -1;
|
|
43
55
|
tools.forEach((tool) => {
|
|
44
|
-
if (
|
|
56
|
+
if (isGeminiNonFunctionTool(tool)) {
|
|
45
57
|
geminiTools.push(tool);
|
|
46
58
|
}
|
|
47
59
|
else {
|
package/dist/utils/common.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { GeminiTool, GoogleAIBaseLanguageModelCallOptions, GoogleAIModelParams, GoogleAIModelRequestParams, GoogleAIToolType, VertexModelFamily } from "../types.js";
|
|
2
2
|
export declare function copyAIModelParams(params: GoogleAIModelParams | undefined, options: GoogleAIBaseLanguageModelCallOptions | undefined): GoogleAIModelRequestParams;
|
|
3
3
|
export declare function convertToGeminiTools(tools: GoogleAIToolType[]): GeminiTool[];
|
|
4
4
|
export declare function copyAIModelParamsInto(params: GoogleAIModelParams | undefined, options: GoogleAIBaseLanguageModelCallOptions | undefined, target: GoogleAIModelParams): GoogleAIModelRequestParams;
|
package/dist/utils/common.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isOpenAITool } from "@langchain/core/language_models/base";
|
|
2
2
|
import { isLangChainTool } from "@langchain/core/utils/function_calling";
|
|
3
3
|
import { isModelGemini, validateGeminiParams } from "./gemini.js";
|
|
4
|
+
import { GeminiToolAttributes, } from "../types.js";
|
|
4
5
|
import { jsonSchemaToGeminiParameters, zodToGeminiParameters, } from "./zod_to_gemini_parameters.js";
|
|
5
6
|
import { isModelClaude, validateClaudeParams } from "./anthropic.js";
|
|
6
7
|
export function copyAIModelParams(params, options) {
|
|
@@ -33,11 +34,22 @@ function processToolChoice(toolChoice, allowedFunctionNames) {
|
|
|
33
34
|
}
|
|
34
35
|
throw new Error("Object inputs for tool_choice not supported.");
|
|
35
36
|
}
|
|
37
|
+
function isGeminiTool(tool) {
|
|
38
|
+
for (const toolAttribute of GeminiToolAttributes) {
|
|
39
|
+
if (toolAttribute in tool) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
function isGeminiNonFunctionTool(tool) {
|
|
46
|
+
return isGeminiTool(tool) && !("functionDeclaration" in tool);
|
|
47
|
+
}
|
|
36
48
|
export function convertToGeminiTools(tools) {
|
|
37
49
|
const geminiTools = [];
|
|
38
50
|
let functionDeclarationsIndex = -1;
|
|
39
51
|
tools.forEach((tool) => {
|
|
40
|
-
if (
|
|
52
|
+
if (isGeminiNonFunctionTool(tool)) {
|
|
41
53
|
geminiTools.push(tool);
|
|
42
54
|
}
|
|
43
55
|
else {
|
package/dist/utils/gemini.cjs
CHANGED
|
@@ -6,6 +6,7 @@ const messages_1 = require("@langchain/core/messages");
|
|
|
6
6
|
const outputs_1 = require("@langchain/core/outputs");
|
|
7
7
|
const function_calling_1 = require("@langchain/core/utils/function_calling");
|
|
8
8
|
const safety_js_1 = require("./safety.cjs");
|
|
9
|
+
const types_js_1 = require("../types.cjs");
|
|
9
10
|
const zod_to_gemini_parameters_js_1 = require("./zod_to_gemini_parameters.cjs");
|
|
10
11
|
class DefaultGeminiSafetyHandler {
|
|
11
12
|
constructor(settings) {
|
|
@@ -523,6 +524,8 @@ function getGeminiAPI(config) {
|
|
|
523
524
|
severity: rating.severity,
|
|
524
525
|
severity_score: rating.severityScore,
|
|
525
526
|
})),
|
|
527
|
+
citation_metadata: data.candidates[0]?.citationMetadata,
|
|
528
|
+
grounding_metadata: data.candidates[0]?.groundingMetadata,
|
|
526
529
|
finish_reason: data.candidates[0]?.finishReason,
|
|
527
530
|
};
|
|
528
531
|
}
|
|
@@ -577,12 +580,59 @@ function getGeminiAPI(config) {
|
|
|
577
580
|
message,
|
|
578
581
|
});
|
|
579
582
|
}
|
|
580
|
-
function
|
|
583
|
+
function groundingSupportByPart(groundingSupports) {
|
|
584
|
+
const ret = [];
|
|
585
|
+
if (!groundingSupports || groundingSupports.length === 0) {
|
|
586
|
+
return [];
|
|
587
|
+
}
|
|
588
|
+
groundingSupports?.forEach((groundingSupport) => {
|
|
589
|
+
const segment = groundingSupport?.segment;
|
|
590
|
+
const partIndex = segment?.partIndex ?? 0;
|
|
591
|
+
if (ret[partIndex]) {
|
|
592
|
+
ret[partIndex].push(groundingSupport);
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
ret[partIndex] = [groundingSupport];
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
return ret;
|
|
599
|
+
}
|
|
600
|
+
function responseToGroundedChatGenerations(response) {
|
|
581
601
|
const parts = responseToParts(response);
|
|
582
602
|
if (parts.length === 0) {
|
|
583
603
|
return [];
|
|
584
604
|
}
|
|
585
|
-
|
|
605
|
+
// Citation and grounding information connected to each part / ChatGeneration
|
|
606
|
+
// to make sure they are available in downstream filters.
|
|
607
|
+
const candidate = response?.data
|
|
608
|
+
?.candidates?.[0];
|
|
609
|
+
const groundingMetadata = candidate?.groundingMetadata;
|
|
610
|
+
const citationMetadata = candidate?.citationMetadata;
|
|
611
|
+
const groundingParts = groundingSupportByPart(groundingMetadata?.groundingSupports);
|
|
612
|
+
const ret = parts.map((part, index) => {
|
|
613
|
+
const gen = partToChatGeneration(part);
|
|
614
|
+
if (!gen.generationInfo) {
|
|
615
|
+
gen.generationInfo = {};
|
|
616
|
+
}
|
|
617
|
+
if (groundingMetadata) {
|
|
618
|
+
gen.generationInfo.groundingMetadata = groundingMetadata;
|
|
619
|
+
const groundingPart = groundingParts[index];
|
|
620
|
+
if (groundingPart) {
|
|
621
|
+
gen.generationInfo.groundingSupport = groundingPart;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
if (citationMetadata) {
|
|
625
|
+
gen.generationInfo.citationMetadata = citationMetadata;
|
|
626
|
+
}
|
|
627
|
+
return gen;
|
|
628
|
+
});
|
|
629
|
+
return ret;
|
|
630
|
+
}
|
|
631
|
+
function responseToChatGenerations(response) {
|
|
632
|
+
let ret = responseToGroundedChatGenerations(response);
|
|
633
|
+
if (ret.length === 0) {
|
|
634
|
+
return [];
|
|
635
|
+
}
|
|
586
636
|
if (ret.every((item) => typeof item.message.content === "string")) {
|
|
587
637
|
const combinedContent = ret.map((item) => item.message.content).join("");
|
|
588
638
|
const combinedText = ret.map((item) => item.text).join("");
|
|
@@ -788,14 +838,43 @@ function getGeminiAPI(config) {
|
|
|
788
838
|
parameters: jsonSchema,
|
|
789
839
|
};
|
|
790
840
|
}
|
|
841
|
+
function searchToolName(tool) {
|
|
842
|
+
for (const name of types_js_1.GeminiSearchToolAttributes) {
|
|
843
|
+
if (name in tool) {
|
|
844
|
+
return name;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
return undefined;
|
|
848
|
+
}
|
|
849
|
+
function cleanGeminiTool(tool) {
|
|
850
|
+
const orig = searchToolName(tool);
|
|
851
|
+
const adj = config?.googleSearchToolAdjustment;
|
|
852
|
+
if (orig && adj && adj !== orig) {
|
|
853
|
+
return {
|
|
854
|
+
[adj]: {},
|
|
855
|
+
};
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
return tool;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
791
861
|
function formatTools(parameters) {
|
|
792
862
|
const tools = parameters?.tools;
|
|
793
863
|
if (!tools || tools.length === 0) {
|
|
794
864
|
return [];
|
|
795
865
|
}
|
|
796
|
-
// Group all LangChain tools into a single functionDeclarations array
|
|
797
|
-
|
|
798
|
-
const
|
|
866
|
+
// Group all LangChain tools into a single functionDeclarations array.
|
|
867
|
+
// Gemini Tools may be normalized to different tool names
|
|
868
|
+
const langChainTools = [];
|
|
869
|
+
const otherTools = [];
|
|
870
|
+
tools.forEach((tool) => {
|
|
871
|
+
if ((0, function_calling_1.isLangChainTool)(tool)) {
|
|
872
|
+
langChainTools.push(tool);
|
|
873
|
+
}
|
|
874
|
+
else {
|
|
875
|
+
otherTools.push(cleanGeminiTool(tool));
|
|
876
|
+
}
|
|
877
|
+
});
|
|
799
878
|
const result = [...otherTools];
|
|
800
879
|
if (langChainTools.length > 0) {
|
|
801
880
|
result.push({
|
|
@@ -808,10 +887,19 @@ function getGeminiAPI(config) {
|
|
|
808
887
|
if (!parameters.tool_choice || typeof parameters.tool_choice !== "string") {
|
|
809
888
|
return undefined;
|
|
810
889
|
}
|
|
890
|
+
if (["auto", "any", "none"].includes(parameters.tool_choice)) {
|
|
891
|
+
return {
|
|
892
|
+
functionCallingConfig: {
|
|
893
|
+
mode: parameters.tool_choice,
|
|
894
|
+
allowedFunctionNames: parameters.allowed_function_names,
|
|
895
|
+
},
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
// force tool choice to be a single function name in case of structured output
|
|
811
899
|
return {
|
|
812
900
|
functionCallingConfig: {
|
|
813
|
-
mode:
|
|
814
|
-
allowedFunctionNames: parameters.
|
|
901
|
+
mode: "any",
|
|
902
|
+
allowedFunctionNames: [parameters.tool_choice],
|
|
815
903
|
},
|
|
816
904
|
};
|
|
817
905
|
}
|
package/dist/utils/gemini.js
CHANGED
|
@@ -3,6 +3,7 @@ import { AIMessage, AIMessageChunk, isAIMessage, } from "@langchain/core/message
|
|
|
3
3
|
import { ChatGenerationChunk, } from "@langchain/core/outputs";
|
|
4
4
|
import { isLangChainTool } from "@langchain/core/utils/function_calling";
|
|
5
5
|
import { GoogleAISafetyError } from "./safety.js";
|
|
6
|
+
import { GeminiSearchToolAttributes, } from "../types.js";
|
|
6
7
|
import { zodToGeminiParameters } from "./zod_to_gemini_parameters.js";
|
|
7
8
|
export class DefaultGeminiSafetyHandler {
|
|
8
9
|
constructor(settings) {
|
|
@@ -518,6 +519,8 @@ export function getGeminiAPI(config) {
|
|
|
518
519
|
severity: rating.severity,
|
|
519
520
|
severity_score: rating.severityScore,
|
|
520
521
|
})),
|
|
522
|
+
citation_metadata: data.candidates[0]?.citationMetadata,
|
|
523
|
+
grounding_metadata: data.candidates[0]?.groundingMetadata,
|
|
521
524
|
finish_reason: data.candidates[0]?.finishReason,
|
|
522
525
|
};
|
|
523
526
|
}
|
|
@@ -572,12 +575,59 @@ export function getGeminiAPI(config) {
|
|
|
572
575
|
message,
|
|
573
576
|
});
|
|
574
577
|
}
|
|
575
|
-
function
|
|
578
|
+
function groundingSupportByPart(groundingSupports) {
|
|
579
|
+
const ret = [];
|
|
580
|
+
if (!groundingSupports || groundingSupports.length === 0) {
|
|
581
|
+
return [];
|
|
582
|
+
}
|
|
583
|
+
groundingSupports?.forEach((groundingSupport) => {
|
|
584
|
+
const segment = groundingSupport?.segment;
|
|
585
|
+
const partIndex = segment?.partIndex ?? 0;
|
|
586
|
+
if (ret[partIndex]) {
|
|
587
|
+
ret[partIndex].push(groundingSupport);
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
ret[partIndex] = [groundingSupport];
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
return ret;
|
|
594
|
+
}
|
|
595
|
+
function responseToGroundedChatGenerations(response) {
|
|
576
596
|
const parts = responseToParts(response);
|
|
577
597
|
if (parts.length === 0) {
|
|
578
598
|
return [];
|
|
579
599
|
}
|
|
580
|
-
|
|
600
|
+
// Citation and grounding information connected to each part / ChatGeneration
|
|
601
|
+
// to make sure they are available in downstream filters.
|
|
602
|
+
const candidate = response?.data
|
|
603
|
+
?.candidates?.[0];
|
|
604
|
+
const groundingMetadata = candidate?.groundingMetadata;
|
|
605
|
+
const citationMetadata = candidate?.citationMetadata;
|
|
606
|
+
const groundingParts = groundingSupportByPart(groundingMetadata?.groundingSupports);
|
|
607
|
+
const ret = parts.map((part, index) => {
|
|
608
|
+
const gen = partToChatGeneration(part);
|
|
609
|
+
if (!gen.generationInfo) {
|
|
610
|
+
gen.generationInfo = {};
|
|
611
|
+
}
|
|
612
|
+
if (groundingMetadata) {
|
|
613
|
+
gen.generationInfo.groundingMetadata = groundingMetadata;
|
|
614
|
+
const groundingPart = groundingParts[index];
|
|
615
|
+
if (groundingPart) {
|
|
616
|
+
gen.generationInfo.groundingSupport = groundingPart;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
if (citationMetadata) {
|
|
620
|
+
gen.generationInfo.citationMetadata = citationMetadata;
|
|
621
|
+
}
|
|
622
|
+
return gen;
|
|
623
|
+
});
|
|
624
|
+
return ret;
|
|
625
|
+
}
|
|
626
|
+
function responseToChatGenerations(response) {
|
|
627
|
+
let ret = responseToGroundedChatGenerations(response);
|
|
628
|
+
if (ret.length === 0) {
|
|
629
|
+
return [];
|
|
630
|
+
}
|
|
581
631
|
if (ret.every((item) => typeof item.message.content === "string")) {
|
|
582
632
|
const combinedContent = ret.map((item) => item.message.content).join("");
|
|
583
633
|
const combinedText = ret.map((item) => item.text).join("");
|
|
@@ -783,14 +833,43 @@ export function getGeminiAPI(config) {
|
|
|
783
833
|
parameters: jsonSchema,
|
|
784
834
|
};
|
|
785
835
|
}
|
|
836
|
+
function searchToolName(tool) {
|
|
837
|
+
for (const name of GeminiSearchToolAttributes) {
|
|
838
|
+
if (name in tool) {
|
|
839
|
+
return name;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
return undefined;
|
|
843
|
+
}
|
|
844
|
+
function cleanGeminiTool(tool) {
|
|
845
|
+
const orig = searchToolName(tool);
|
|
846
|
+
const adj = config?.googleSearchToolAdjustment;
|
|
847
|
+
if (orig && adj && adj !== orig) {
|
|
848
|
+
return {
|
|
849
|
+
[adj]: {},
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
else {
|
|
853
|
+
return tool;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
786
856
|
function formatTools(parameters) {
|
|
787
857
|
const tools = parameters?.tools;
|
|
788
858
|
if (!tools || tools.length === 0) {
|
|
789
859
|
return [];
|
|
790
860
|
}
|
|
791
|
-
// Group all LangChain tools into a single functionDeclarations array
|
|
792
|
-
|
|
793
|
-
const
|
|
861
|
+
// Group all LangChain tools into a single functionDeclarations array.
|
|
862
|
+
// Gemini Tools may be normalized to different tool names
|
|
863
|
+
const langChainTools = [];
|
|
864
|
+
const otherTools = [];
|
|
865
|
+
tools.forEach((tool) => {
|
|
866
|
+
if (isLangChainTool(tool)) {
|
|
867
|
+
langChainTools.push(tool);
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
otherTools.push(cleanGeminiTool(tool));
|
|
871
|
+
}
|
|
872
|
+
});
|
|
794
873
|
const result = [...otherTools];
|
|
795
874
|
if (langChainTools.length > 0) {
|
|
796
875
|
result.push({
|
|
@@ -803,10 +882,19 @@ export function getGeminiAPI(config) {
|
|
|
803
882
|
if (!parameters.tool_choice || typeof parameters.tool_choice !== "string") {
|
|
804
883
|
return undefined;
|
|
805
884
|
}
|
|
885
|
+
if (["auto", "any", "none"].includes(parameters.tool_choice)) {
|
|
886
|
+
return {
|
|
887
|
+
functionCallingConfig: {
|
|
888
|
+
mode: parameters.tool_choice,
|
|
889
|
+
allowedFunctionNames: parameters.allowed_function_names,
|
|
890
|
+
},
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
// force tool choice to be a single function name in case of structured output
|
|
806
894
|
return {
|
|
807
895
|
functionCallingConfig: {
|
|
808
|
-
mode:
|
|
809
|
-
allowedFunctionNames: parameters.
|
|
896
|
+
mode: "any",
|
|
897
|
+
allowedFunctionNames: [parameters.tool_choice],
|
|
810
898
|
},
|
|
811
899
|
};
|
|
812
900
|
}
|