@blaxel/langgraph 0.2.50-dev.215 → 0.2.50
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/README.md +1 -1
- package/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/model/cohere.js +74 -0
- package/dist/cjs/model/google-genai.js +75 -12
- package/dist/cjs/model.js +1 -1
- package/dist/cjs/types/model/google-genai.d.ts +20 -3
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/model/cohere.js +74 -0
- package/dist/esm/model/google-genai.js +74 -11
- package/dist/esm/model.js +1 -1
- package/package.json +3 -2
- package/dist/cjs/model/google-genai/chat_models.js +0 -766
- package/dist/cjs/model/google-genai/embeddings.js +0 -111
- package/dist/cjs/model/google-genai/index.js +0 -18
- package/dist/cjs/model/google-genai/output_parsers.js +0 -51
- package/dist/cjs/model/google-genai/types.js +0 -2
- package/dist/cjs/model/google-genai/utils/common.js +0 -390
- package/dist/cjs/model/google-genai/utils/tools.js +0 -110
- package/dist/cjs/model/google-genai/utils/zod_to_genai_parameters.js +0 -46
- package/dist/cjs/types/model/google-genai/chat_models.d.ts +0 -557
- package/dist/cjs/types/model/google-genai/embeddings.d.ts +0 -94
- package/dist/cjs/types/model/google-genai/index.d.ts +0 -2
- package/dist/cjs/types/model/google-genai/output_parsers.d.ts +0 -20
- package/dist/cjs/types/model/google-genai/types.d.ts +0 -3
- package/dist/cjs/types/model/google-genai/utils/common.d.ts +0 -22
- package/dist/cjs/types/model/google-genai/utils/tools.d.ts +0 -10
- package/dist/cjs/types/model/google-genai/utils/zod_to_genai_parameters.d.ts +0 -13
- package/dist/esm/model/google-genai/chat_models.js +0 -762
- package/dist/esm/model/google-genai/embeddings.js +0 -107
- package/dist/esm/model/google-genai/index.js +0 -2
- package/dist/esm/model/google-genai/output_parsers.js +0 -47
- package/dist/esm/model/google-genai/types.js +0 -1
- package/dist/esm/model/google-genai/utils/common.js +0 -381
- package/dist/esm/model/google-genai/utils/tools.js +0 -107
- package/dist/esm/model/google-genai/utils/zod_to_genai_parameters.js +0 -41
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GoogleGenerativeAIEmbeddings = void 0;
|
|
4
|
-
const generative_ai_1 = require("@google/generative-ai");
|
|
5
|
-
const embeddings_1 = require("@langchain/core/embeddings");
|
|
6
|
-
const chunk_array_1 = require("@langchain/core/utils/chunk_array");
|
|
7
|
-
const env_1 = require("@langchain/core/utils/env");
|
|
8
|
-
/**
|
|
9
|
-
* Class that extends the Embeddings class and provides methods for
|
|
10
|
-
* generating embeddings using the Google Palm API.
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* const model = new GoogleGenerativeAIEmbeddings({
|
|
14
|
-
* apiKey: "<YOUR API KEY>",
|
|
15
|
-
* modelName: "embedding-001",
|
|
16
|
-
* });
|
|
17
|
-
*
|
|
18
|
-
* // Embed a single query
|
|
19
|
-
* const res = await model.embedQuery(
|
|
20
|
-
* "What would be a good company name for a company that makes colorful socks?"
|
|
21
|
-
* );
|
|
22
|
-
* console.log({ res });
|
|
23
|
-
*
|
|
24
|
-
* // Embed multiple documents
|
|
25
|
-
* const documentRes = await model.embedDocuments(["Hello world", "Bye bye"]);
|
|
26
|
-
* console.log({ documentRes });
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
class GoogleGenerativeAIEmbeddings extends embeddings_1.Embeddings {
|
|
30
|
-
apiKey;
|
|
31
|
-
modelName = "embedding-001";
|
|
32
|
-
model = "embedding-001";
|
|
33
|
-
taskType;
|
|
34
|
-
title;
|
|
35
|
-
stripNewLines = true;
|
|
36
|
-
maxBatchSize = 100; // Max batch size for embedDocuments set by GenerativeModel client's batchEmbedContents call
|
|
37
|
-
client;
|
|
38
|
-
constructor(fields) {
|
|
39
|
-
super(fields ?? {});
|
|
40
|
-
this.modelName =
|
|
41
|
-
fields?.model?.replace(/^models\//, "") ??
|
|
42
|
-
fields?.modelName?.replace(/^models\//, "") ??
|
|
43
|
-
this.modelName;
|
|
44
|
-
this.model = this.modelName;
|
|
45
|
-
this.taskType = fields?.taskType ?? this.taskType;
|
|
46
|
-
this.title = fields?.title ?? this.title;
|
|
47
|
-
if (this.title && this.taskType !== generative_ai_1.TaskType.RETRIEVAL_DOCUMENT) {
|
|
48
|
-
throw new Error("title can only be specified with TaskType.RETRIEVAL_DOCUMENT");
|
|
49
|
-
}
|
|
50
|
-
this.apiKey = fields?.apiKey ?? (0, env_1.getEnvironmentVariable)("GOOGLE_API_KEY");
|
|
51
|
-
if (!this.apiKey) {
|
|
52
|
-
throw new Error("Please set an API key for Google GenerativeAI " +
|
|
53
|
-
"in the environmentb variable GOOGLE_API_KEY " +
|
|
54
|
-
"or in the `apiKey` field of the " +
|
|
55
|
-
"GoogleGenerativeAIEmbeddings constructor");
|
|
56
|
-
}
|
|
57
|
-
this.client = new generative_ai_1.GoogleGenerativeAI(this.apiKey).getGenerativeModel({
|
|
58
|
-
model: this.model,
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
_convertToContent(text) {
|
|
62
|
-
const cleanedText = this.stripNewLines ? text.replace(/\n/g, " ") : text;
|
|
63
|
-
return {
|
|
64
|
-
content: { role: "user", parts: [{ text: cleanedText }] },
|
|
65
|
-
taskType: this.taskType,
|
|
66
|
-
title: this.title,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
async _embedQueryContent(text) {
|
|
70
|
-
const req = this._convertToContent(text);
|
|
71
|
-
const res = await this.client.embedContent(req);
|
|
72
|
-
return res.embedding.values ?? [];
|
|
73
|
-
}
|
|
74
|
-
async _embedDocumentsContent(documents) {
|
|
75
|
-
const batchEmbedChunks = (0, chunk_array_1.chunkArray)(documents, this.maxBatchSize);
|
|
76
|
-
const batchEmbedRequests = batchEmbedChunks.map((chunk) => ({
|
|
77
|
-
requests: chunk.map((doc) => this._convertToContent(doc)),
|
|
78
|
-
}));
|
|
79
|
-
const responses = await Promise.allSettled(batchEmbedRequests.map((req) => this.client.batchEmbedContents(req)));
|
|
80
|
-
const embeddings = responses.flatMap((res, idx) => {
|
|
81
|
-
if (res.status === "fulfilled") {
|
|
82
|
-
return res.value.embeddings.map((e) => e.values || []);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
return Array(batchEmbedChunks[idx].length).fill([]);
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
return embeddings;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Method that takes a document as input and returns a promise that
|
|
92
|
-
* resolves to an embedding for the document. It calls the _embedText
|
|
93
|
-
* method with the document as the input.
|
|
94
|
-
* @param document Document for which to generate an embedding.
|
|
95
|
-
* @returns Promise that resolves to an embedding for the input document.
|
|
96
|
-
*/
|
|
97
|
-
embedQuery(document) {
|
|
98
|
-
return this.caller.call(this._embedQueryContent.bind(this), document);
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Method that takes an array of documents as input and returns a promise
|
|
102
|
-
* that resolves to a 2D array of embeddings for each document. It calls
|
|
103
|
-
* the _embedText method for each document in the array.
|
|
104
|
-
* @param documents Array of documents for which to generate embeddings.
|
|
105
|
-
* @returns Promise that resolves to a 2D array of embeddings for each input document.
|
|
106
|
-
*/
|
|
107
|
-
embedDocuments(documents) {
|
|
108
|
-
return this.caller.call(this._embedDocumentsContent.bind(this), documents);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
exports.GoogleGenerativeAIEmbeddings = GoogleGenerativeAIEmbeddings;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./chat_models.js"), exports);
|
|
18
|
-
__exportStar(require("./embeddings.js"), exports);
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GoogleGenerativeAIToolsOutputParser = void 0;
|
|
4
|
-
const output_parsers_1 = require("@langchain/core/output_parsers");
|
|
5
|
-
class GoogleGenerativeAIToolsOutputParser extends output_parsers_1.BaseLLMOutputParser {
|
|
6
|
-
static lc_name() {
|
|
7
|
-
return "GoogleGenerativeAIToolsOutputParser";
|
|
8
|
-
}
|
|
9
|
-
lc_namespace = ["langchain", "google_genai", "output_parsers"];
|
|
10
|
-
returnId = false;
|
|
11
|
-
/** The type of tool calls to return. */
|
|
12
|
-
keyName;
|
|
13
|
-
/** Whether to return only the first tool call. */
|
|
14
|
-
returnSingle = false;
|
|
15
|
-
zodSchema;
|
|
16
|
-
constructor(params) {
|
|
17
|
-
super(params);
|
|
18
|
-
this.keyName = params.keyName;
|
|
19
|
-
this.returnSingle = params.returnSingle ?? this.returnSingle;
|
|
20
|
-
// @ts-ignore - Type instantiation depth issue with Zod schemas
|
|
21
|
-
this.zodSchema = params.zodSchema;
|
|
22
|
-
}
|
|
23
|
-
async _validateResult(result) {
|
|
24
|
-
if (this.zodSchema === undefined) {
|
|
25
|
-
return result;
|
|
26
|
-
}
|
|
27
|
-
const zodParsedResult = await this.zodSchema.safeParseAsync(result);
|
|
28
|
-
if (zodParsedResult.success) {
|
|
29
|
-
return zodParsedResult.data;
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
throw new output_parsers_1.OutputParserException(`Failed to parse. Text: "${JSON.stringify(result, null, 2)}". Error: ${JSON.stringify(zodParsedResult.error.errors)}`, JSON.stringify(result, null, 2));
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
async parseResult(generations) {
|
|
36
|
-
const tools = generations.flatMap((generation) => {
|
|
37
|
-
const { message } = generation;
|
|
38
|
-
if (!("tool_calls" in message) || !Array.isArray(message.tool_calls)) {
|
|
39
|
-
return [];
|
|
40
|
-
}
|
|
41
|
-
return message.tool_calls;
|
|
42
|
-
});
|
|
43
|
-
if (tools[0] === undefined) {
|
|
44
|
-
throw new Error("No parseable tool calls provided to GoogleGenerativeAIToolsOutputParser.");
|
|
45
|
-
}
|
|
46
|
-
const [tool] = tools;
|
|
47
|
-
const validatedResult = await this._validateResult(tool.args);
|
|
48
|
-
return validatedResult;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
exports.GoogleGenerativeAIToolsOutputParser = GoogleGenerativeAIToolsOutputParser;
|
|
@@ -1,390 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getMessageAuthor = getMessageAuthor;
|
|
4
|
-
exports.convertAuthorToRole = convertAuthorToRole;
|
|
5
|
-
exports.convertMessageContentToParts = convertMessageContentToParts;
|
|
6
|
-
exports.convertBaseMessagesToContent = convertBaseMessagesToContent;
|
|
7
|
-
exports.mapGenerateContentResultToChatResult = mapGenerateContentResultToChatResult;
|
|
8
|
-
exports.convertResponseContentToChatGenerationChunk = convertResponseContentToChatGenerationChunk;
|
|
9
|
-
exports.convertToGenerativeAITools = convertToGenerativeAITools;
|
|
10
|
-
const base_1 = require("@langchain/core/language_models/base");
|
|
11
|
-
const messages_1 = require("@langchain/core/messages");
|
|
12
|
-
const outputs_1 = require("@langchain/core/outputs");
|
|
13
|
-
const function_calling_1 = require("@langchain/core/utils/function_calling");
|
|
14
|
-
const zod_to_genai_parameters_js_1 = require("./zod_to_genai_parameters.js");
|
|
15
|
-
function getMessageAuthor(message) {
|
|
16
|
-
const type = message._getType();
|
|
17
|
-
if (messages_1.ChatMessage.isInstance(message)) {
|
|
18
|
-
return message.role;
|
|
19
|
-
}
|
|
20
|
-
if (type === "tool") {
|
|
21
|
-
return type;
|
|
22
|
-
}
|
|
23
|
-
return message.name ?? type;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Maps a message type to a Google Generative AI chat author.
|
|
27
|
-
* @param message The message to map.
|
|
28
|
-
* @param model The model to use for mapping.
|
|
29
|
-
* @returns The message type mapped to a Google Generative AI chat author.
|
|
30
|
-
*/
|
|
31
|
-
function convertAuthorToRole(author) {
|
|
32
|
-
switch (author) {
|
|
33
|
-
/**
|
|
34
|
-
* Note: Gemini currently is not supporting system messages
|
|
35
|
-
* we will convert them to human messages and merge with following
|
|
36
|
-
* */
|
|
37
|
-
case "ai":
|
|
38
|
-
case "model": // getMessageAuthor returns message.name. code ex.: return message.name ?? type;
|
|
39
|
-
return "model";
|
|
40
|
-
case "system":
|
|
41
|
-
return "system";
|
|
42
|
-
case "human":
|
|
43
|
-
return "user";
|
|
44
|
-
case "tool":
|
|
45
|
-
case "function":
|
|
46
|
-
return "function";
|
|
47
|
-
default:
|
|
48
|
-
throw new Error(`Unknown / unsupported author: ${author}`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
function messageContentMedia(content) {
|
|
52
|
-
if ("mimeType" in content && "data" in content) {
|
|
53
|
-
return {
|
|
54
|
-
inlineData: {
|
|
55
|
-
mimeType: content.mimeType,
|
|
56
|
-
data: content.data,
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
if ("mimeType" in content && "fileUri" in content) {
|
|
61
|
-
return {
|
|
62
|
-
fileData: {
|
|
63
|
-
mimeType: content.mimeType,
|
|
64
|
-
fileUri: content.fileUri,
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
throw new Error("Invalid media content");
|
|
69
|
-
}
|
|
70
|
-
function convertMessageContentToParts(message, isMultimodalModel) {
|
|
71
|
-
if (typeof message.content === "string" && message.content !== "") {
|
|
72
|
-
return [{ text: message.content }];
|
|
73
|
-
}
|
|
74
|
-
let functionCalls = [];
|
|
75
|
-
let functionResponses = [];
|
|
76
|
-
let messageParts = [];
|
|
77
|
-
if ("tool_calls" in message &&
|
|
78
|
-
Array.isArray(message.tool_calls) &&
|
|
79
|
-
message.tool_calls.length > 0) {
|
|
80
|
-
functionCalls = message.tool_calls
|
|
81
|
-
.map((tc) => {
|
|
82
|
-
if (typeof tc.name === "string") {
|
|
83
|
-
return {
|
|
84
|
-
functionCall: {
|
|
85
|
-
name: tc.name,
|
|
86
|
-
args: tc.args,
|
|
87
|
-
},
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
return null;
|
|
91
|
-
})
|
|
92
|
-
.filter(Boolean);
|
|
93
|
-
}
|
|
94
|
-
else if (message.getType() === "tool" && message.name && message.content) {
|
|
95
|
-
functionResponses = [
|
|
96
|
-
{
|
|
97
|
-
functionResponse: {
|
|
98
|
-
name: message.name,
|
|
99
|
-
response: message.content,
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
];
|
|
103
|
-
}
|
|
104
|
-
else if (Array.isArray(message.content)) {
|
|
105
|
-
messageParts = message.content.map((c) => {
|
|
106
|
-
if (c.type === "text") {
|
|
107
|
-
return {
|
|
108
|
-
text: c.text,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
else if (c.type === "executableCode") {
|
|
112
|
-
return {
|
|
113
|
-
executableCode: c.executableCode,
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
else if (c.type === "codeExecutionResult") {
|
|
117
|
-
return {
|
|
118
|
-
codeExecutionResult: c.codeExecutionResult,
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
if (c.type === "image_url") {
|
|
122
|
-
if (!isMultimodalModel) {
|
|
123
|
-
throw new Error(`This model does not support images`);
|
|
124
|
-
}
|
|
125
|
-
if (!c.image_url) {
|
|
126
|
-
throw new Error("Please provide image as base64 encoded data URL");
|
|
127
|
-
}
|
|
128
|
-
let source;
|
|
129
|
-
if (typeof c.image_url === "string") {
|
|
130
|
-
source = c.image_url;
|
|
131
|
-
}
|
|
132
|
-
else if (typeof c.image_url === "object" && "url" in c.image_url) {
|
|
133
|
-
source = c.image_url.url;
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
throw new Error("Please provide image as base64 encoded data URL");
|
|
137
|
-
}
|
|
138
|
-
const [dm, data] = source.split(",");
|
|
139
|
-
if (!dm.startsWith("data:")) {
|
|
140
|
-
throw new Error("Please provide image as base64 encoded data URL");
|
|
141
|
-
}
|
|
142
|
-
const [mimeType, encoding] = dm.replace(/^data:/, "").split(";");
|
|
143
|
-
if (encoding !== "base64") {
|
|
144
|
-
throw new Error("Please provide image as base64 encoded data URL");
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
inlineData: {
|
|
148
|
-
data,
|
|
149
|
-
mimeType,
|
|
150
|
-
},
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
else if (c.type === "media") {
|
|
154
|
-
return messageContentMedia(c);
|
|
155
|
-
}
|
|
156
|
-
else if (c.type === "tool_use") {
|
|
157
|
-
return {
|
|
158
|
-
functionCall: {
|
|
159
|
-
name: c.name,
|
|
160
|
-
args: c.input,
|
|
161
|
-
},
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
else if (c.type?.includes("/") &&
|
|
165
|
-
// Ensure it's a single slash.
|
|
166
|
-
c.type.split("/").length === 2 &&
|
|
167
|
-
"data" in c &&
|
|
168
|
-
typeof c.data === "string") {
|
|
169
|
-
return {
|
|
170
|
-
inlineData: {
|
|
171
|
-
mimeType: c.type,
|
|
172
|
-
data: c.data,
|
|
173
|
-
},
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
throw new Error(`Unknown content type ${c.type}`);
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
return [...messageParts, ...functionCalls, ...functionResponses];
|
|
180
|
-
}
|
|
181
|
-
function convertBaseMessagesToContent(messages, isMultimodalModel, convertSystemMessageToHumanContent = false) {
|
|
182
|
-
return messages.reduce((acc, message, index) => {
|
|
183
|
-
if (!(0, messages_1.isBaseMessage)(message)) {
|
|
184
|
-
throw new Error("Unsupported message input");
|
|
185
|
-
}
|
|
186
|
-
const author = getMessageAuthor(message);
|
|
187
|
-
if (author === "system" && index !== 0) {
|
|
188
|
-
throw new Error("System message should be the first one");
|
|
189
|
-
}
|
|
190
|
-
const role = convertAuthorToRole(author);
|
|
191
|
-
const prevContent = acc.content[acc.content.length];
|
|
192
|
-
if (!acc.mergeWithPreviousContent &&
|
|
193
|
-
prevContent &&
|
|
194
|
-
prevContent.role === role) {
|
|
195
|
-
throw new Error("Google Generative AI requires alternate messages between authors");
|
|
196
|
-
}
|
|
197
|
-
const parts = convertMessageContentToParts(message, isMultimodalModel);
|
|
198
|
-
if (acc.mergeWithPreviousContent) {
|
|
199
|
-
const prevContent = acc.content[acc.content.length - 1];
|
|
200
|
-
if (!prevContent) {
|
|
201
|
-
throw new Error("There was a problem parsing your system message. Please try a prompt without one.");
|
|
202
|
-
}
|
|
203
|
-
prevContent.parts.push(...parts);
|
|
204
|
-
return {
|
|
205
|
-
mergeWithPreviousContent: false,
|
|
206
|
-
content: acc.content,
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
let actualRole = role;
|
|
210
|
-
if (actualRole === "function" ||
|
|
211
|
-
(actualRole === "system" && !convertSystemMessageToHumanContent)) {
|
|
212
|
-
// GenerativeAI API will throw an error if the role is not "user" or "model."
|
|
213
|
-
actualRole = "user";
|
|
214
|
-
}
|
|
215
|
-
const content = {
|
|
216
|
-
role: actualRole,
|
|
217
|
-
parts,
|
|
218
|
-
};
|
|
219
|
-
return {
|
|
220
|
-
mergeWithPreviousContent: author === "system" && !convertSystemMessageToHumanContent,
|
|
221
|
-
content: [...acc.content, content],
|
|
222
|
-
};
|
|
223
|
-
}, { content: [], mergeWithPreviousContent: false }).content;
|
|
224
|
-
}
|
|
225
|
-
function mapGenerateContentResultToChatResult(response, extra) {
|
|
226
|
-
// if rejected or error, return empty generations with reason in filters
|
|
227
|
-
if (!response.candidates ||
|
|
228
|
-
response.candidates.length === 0 ||
|
|
229
|
-
!response.candidates[0]) {
|
|
230
|
-
return {
|
|
231
|
-
generations: [],
|
|
232
|
-
llmOutput: {
|
|
233
|
-
filters: response.promptFeedback,
|
|
234
|
-
},
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
const functionCalls = response.functionCalls();
|
|
238
|
-
const [candidate] = response.candidates;
|
|
239
|
-
const { content: candidateContent, ...generationInfo } = candidate;
|
|
240
|
-
let content;
|
|
241
|
-
if (candidateContent?.parts.length === 1 && candidateContent.parts[0].text) {
|
|
242
|
-
content = candidateContent.parts[0].text;
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
content = candidateContent.parts.map((p) => {
|
|
246
|
-
if ("text" in p) {
|
|
247
|
-
return {
|
|
248
|
-
type: "text",
|
|
249
|
-
text: p.text,
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
else if ("executableCode" in p) {
|
|
253
|
-
return {
|
|
254
|
-
type: "executableCode",
|
|
255
|
-
executableCode: p.executableCode,
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
else if ("codeExecutionResult" in p) {
|
|
259
|
-
return {
|
|
260
|
-
type: "codeExecutionResult",
|
|
261
|
-
codeExecutionResult: p.codeExecutionResult,
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
return p;
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
let text = "";
|
|
268
|
-
if (typeof content === "string") {
|
|
269
|
-
text = content;
|
|
270
|
-
}
|
|
271
|
-
else if ("text" in content[0]) {
|
|
272
|
-
text = content[0].text;
|
|
273
|
-
}
|
|
274
|
-
const generation = {
|
|
275
|
-
text,
|
|
276
|
-
message: new messages_1.AIMessage({
|
|
277
|
-
content,
|
|
278
|
-
tool_calls: functionCalls?.map((fc) => ({
|
|
279
|
-
...fc,
|
|
280
|
-
type: "tool_call",
|
|
281
|
-
})),
|
|
282
|
-
additional_kwargs: {
|
|
283
|
-
...generationInfo,
|
|
284
|
-
},
|
|
285
|
-
usage_metadata: extra?.usageMetadata,
|
|
286
|
-
}),
|
|
287
|
-
generationInfo,
|
|
288
|
-
};
|
|
289
|
-
return {
|
|
290
|
-
generations: [generation],
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
function convertResponseContentToChatGenerationChunk(response, extra) {
|
|
294
|
-
if (!response.candidates || response.candidates.length === 0) {
|
|
295
|
-
return null;
|
|
296
|
-
}
|
|
297
|
-
const functionCalls = response.functionCalls();
|
|
298
|
-
const [candidate] = response.candidates;
|
|
299
|
-
const { content: candidateContent, ...generationInfo } = candidate;
|
|
300
|
-
let content;
|
|
301
|
-
// Checks if some parts do not have text. If false, it means that the content is a string.
|
|
302
|
-
if (candidateContent?.parts &&
|
|
303
|
-
candidateContent.parts.every((p) => "text" in p)) {
|
|
304
|
-
content = candidateContent.parts.map((p) => p.text).join("");
|
|
305
|
-
}
|
|
306
|
-
else if (candidateContent.parts) {
|
|
307
|
-
content = candidateContent.parts.map((p) => {
|
|
308
|
-
if ("text" in p) {
|
|
309
|
-
return {
|
|
310
|
-
type: "text",
|
|
311
|
-
text: p.text,
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
else if ("executableCode" in p) {
|
|
315
|
-
return {
|
|
316
|
-
type: "executableCode",
|
|
317
|
-
executableCode: p.executableCode,
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
else if ("codeExecutionResult" in p) {
|
|
321
|
-
return {
|
|
322
|
-
type: "codeExecutionResult",
|
|
323
|
-
codeExecutionResult: p.codeExecutionResult,
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
return p;
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
let text = "";
|
|
330
|
-
if (content && typeof content === "string") {
|
|
331
|
-
text = content;
|
|
332
|
-
}
|
|
333
|
-
else if (content && typeof content === "object" && "text" in content[0]) {
|
|
334
|
-
text = content[0].text;
|
|
335
|
-
}
|
|
336
|
-
const toolCallChunks = [];
|
|
337
|
-
if (functionCalls) {
|
|
338
|
-
toolCallChunks.push(...functionCalls.map((fc) => ({
|
|
339
|
-
...fc,
|
|
340
|
-
args: JSON.stringify(fc.args),
|
|
341
|
-
index: extra.index,
|
|
342
|
-
type: "tool_call_chunk",
|
|
343
|
-
})));
|
|
344
|
-
}
|
|
345
|
-
return new outputs_1.ChatGenerationChunk({
|
|
346
|
-
text,
|
|
347
|
-
message: new messages_1.AIMessageChunk({
|
|
348
|
-
content: content || "",
|
|
349
|
-
name: !candidateContent ? undefined : candidateContent.role,
|
|
350
|
-
tool_call_chunks: toolCallChunks,
|
|
351
|
-
// Each chunk can have unique "generationInfo", and merging strategy is unclear,
|
|
352
|
-
// so leave blank for now.
|
|
353
|
-
additional_kwargs: {},
|
|
354
|
-
usage_metadata: extra.usageMetadata,
|
|
355
|
-
}),
|
|
356
|
-
generationInfo,
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
function isZodType(schema) {
|
|
360
|
-
return typeof schema === "object" && schema !== null && "_def" in schema;
|
|
361
|
-
}
|
|
362
|
-
function convertToGenerativeAITools(tools) {
|
|
363
|
-
if (tools.every((tool) => "functionDeclarations" in tool &&
|
|
364
|
-
Array.isArray(tool.functionDeclarations))) {
|
|
365
|
-
return tools;
|
|
366
|
-
}
|
|
367
|
-
return [
|
|
368
|
-
{
|
|
369
|
-
functionDeclarations: tools.map((tool) => {
|
|
370
|
-
if ((0, function_calling_1.isLangChainTool)(tool) && isZodType(tool.schema)) {
|
|
371
|
-
// @ts-ignore - Type instantiation depth issue with Zod schemas
|
|
372
|
-
const jsonSchema = (0, zod_to_genai_parameters_js_1.zodToGenerativeAIParameters)(tool.schema);
|
|
373
|
-
return {
|
|
374
|
-
name: tool.name,
|
|
375
|
-
description: tool.description,
|
|
376
|
-
parameters: jsonSchema,
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
if ((0, base_1.isOpenAITool)(tool)) {
|
|
380
|
-
return {
|
|
381
|
-
name: tool.function.name,
|
|
382
|
-
description: tool.function.description ?? `A function available to call.`,
|
|
383
|
-
parameters: (0, zod_to_genai_parameters_js_1.jsonSchemaToGeminiParameters)(tool.function.parameters),
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
return tool;
|
|
387
|
-
}),
|
|
388
|
-
},
|
|
389
|
-
];
|
|
390
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.convertToolsToGenAI = convertToolsToGenAI;
|
|
4
|
-
const generative_ai_1 = require("@google/generative-ai");
|
|
5
|
-
const function_calling_1 = require("@langchain/core/utils/function_calling");
|
|
6
|
-
const base_1 = require("@langchain/core/language_models/base");
|
|
7
|
-
const common_js_1 = require("./common.js");
|
|
8
|
-
const zod_to_genai_parameters_js_1 = require("./zod_to_genai_parameters.js");
|
|
9
|
-
function convertToolsToGenAI(tools, extra) {
|
|
10
|
-
// Extract function declaration processing to a separate function
|
|
11
|
-
const genAITools = processTools(tools);
|
|
12
|
-
// Simplify tool config creation
|
|
13
|
-
const toolConfig = createToolConfig(genAITools, extra);
|
|
14
|
-
return { tools: genAITools, toolConfig };
|
|
15
|
-
}
|
|
16
|
-
function processTools(tools) {
|
|
17
|
-
let functionDeclarationTools = [];
|
|
18
|
-
const genAITools = [];
|
|
19
|
-
tools.forEach((tool) => {
|
|
20
|
-
if ((0, function_calling_1.isLangChainTool)(tool)) {
|
|
21
|
-
const [convertedTool] = (0, common_js_1.convertToGenerativeAITools)([
|
|
22
|
-
tool,
|
|
23
|
-
]);
|
|
24
|
-
if (convertedTool.functionDeclarations) {
|
|
25
|
-
functionDeclarationTools.push(...convertedTool.functionDeclarations);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
else if ((0, base_1.isOpenAITool)(tool)) {
|
|
29
|
-
const { functionDeclarations } = convertOpenAIToolToGenAI(tool);
|
|
30
|
-
if (functionDeclarations) {
|
|
31
|
-
functionDeclarationTools.push(...functionDeclarations);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
throw new Error("Failed to convert OpenAI structured tool to GenerativeAI tool");
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
genAITools.push(tool);
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
const genAIFunctionDeclaration = genAITools.find((t) => "functionDeclarations" in t);
|
|
42
|
-
if (genAIFunctionDeclaration) {
|
|
43
|
-
return genAITools.map((tool) => {
|
|
44
|
-
if (functionDeclarationTools?.length > 0 &&
|
|
45
|
-
"functionDeclarations" in tool) {
|
|
46
|
-
const newTool = {
|
|
47
|
-
functionDeclarations: [
|
|
48
|
-
...(tool.functionDeclarations || []),
|
|
49
|
-
...functionDeclarationTools,
|
|
50
|
-
],
|
|
51
|
-
};
|
|
52
|
-
// Clear the functionDeclarationTools array so it is not passed again
|
|
53
|
-
functionDeclarationTools = [];
|
|
54
|
-
return newTool;
|
|
55
|
-
}
|
|
56
|
-
return tool;
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
return [
|
|
60
|
-
...genAITools,
|
|
61
|
-
...(functionDeclarationTools.length > 0
|
|
62
|
-
? [
|
|
63
|
-
{
|
|
64
|
-
functionDeclarations: functionDeclarationTools,
|
|
65
|
-
},
|
|
66
|
-
]
|
|
67
|
-
: []),
|
|
68
|
-
];
|
|
69
|
-
}
|
|
70
|
-
function convertOpenAIToolToGenAI(tool) {
|
|
71
|
-
return {
|
|
72
|
-
functionDeclarations: [
|
|
73
|
-
{
|
|
74
|
-
name: tool.function.name,
|
|
75
|
-
description: tool.function.description,
|
|
76
|
-
parameters: (0, zod_to_genai_parameters_js_1.removeAdditionalProperties)(tool.function.parameters),
|
|
77
|
-
},
|
|
78
|
-
],
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
function createToolConfig(genAITools, extra) {
|
|
82
|
-
if (!genAITools.length || !extra)
|
|
83
|
-
return undefined;
|
|
84
|
-
const { toolChoice, allowedFunctionNames } = extra;
|
|
85
|
-
const modeMap = {
|
|
86
|
-
any: generative_ai_1.FunctionCallingMode.ANY,
|
|
87
|
-
auto: generative_ai_1.FunctionCallingMode.AUTO,
|
|
88
|
-
none: generative_ai_1.FunctionCallingMode.NONE,
|
|
89
|
-
};
|
|
90
|
-
if (toolChoice && ["any", "auto", "none"].includes(toolChoice)) {
|
|
91
|
-
return {
|
|
92
|
-
functionCallingConfig: {
|
|
93
|
-
mode: modeMap[toolChoice] ?? "MODE_UNSPECIFIED",
|
|
94
|
-
allowedFunctionNames,
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
if (typeof toolChoice === "string" || allowedFunctionNames) {
|
|
99
|
-
return {
|
|
100
|
-
functionCallingConfig: {
|
|
101
|
-
mode: generative_ai_1.FunctionCallingMode.ANY,
|
|
102
|
-
allowedFunctionNames: [
|
|
103
|
-
...(allowedFunctionNames ?? []),
|
|
104
|
-
...(toolChoice && typeof toolChoice === "string" ? [toolChoice] : []),
|
|
105
|
-
],
|
|
106
|
-
},
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
return undefined;
|
|
110
|
-
}
|