@langchain/google-common 0.0.26 → 0.1.0

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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MessageGeminiSafetyHandler = exports.DefaultGeminiSafetyHandler = exports.isModelGemini = exports.validateGeminiParams = exports.safeResponseToChatResult = exports.responseToChatResult = exports.safeResponseToBaseMessage = exports.responseToBaseMessage = exports.partsToBaseMessageChunkFields = exports.responseToBaseMessageFields = exports.responseToChatGenerations = exports.partToChatGeneration = exports.partToMessageChunk = exports.chunkToString = exports.safeResponseToChatGeneration = exports.responseToChatGeneration = exports.safeResponseToGeneration = exports.responseToGeneration = exports.responseToGenerationInfo = exports.safeResponseToString = exports.responseToString = exports.partToText = exports.responseToParts = exports.responseToGenerateContentResponseData = exports.toolsRawToTools = exports.partsToToolsRaw = exports.partsToMessageContent = exports.baseMessageToContent = exports.messageContentToParts = void 0;
3
+ exports.MessageGeminiSafetyHandler = exports.DefaultGeminiSafetyHandler = exports.isModelGemini = exports.validateGeminiParams = exports.getGeminiAPI = void 0;
4
4
  const uuid_1 = require("uuid");
5
5
  const messages_1 = require("@langchain/core/messages");
6
6
  const outputs_1 = require("@langchain/core/outputs");
@@ -14,73 +14,80 @@ const extractMimeType = (str) => {
14
14
  }
15
15
  return null;
16
16
  };
17
- function messageContentText(content) {
18
- if (content?.text && content?.text.length > 0) {
19
- return {
20
- text: content.text,
21
- };
22
- }
23
- else {
24
- return null;
17
+ function getGeminiAPI(config) {
18
+ function messageContentText(content) {
19
+ if (content?.text && content?.text.length > 0) {
20
+ return {
21
+ text: content.text,
22
+ };
23
+ }
24
+ else {
25
+ return null;
26
+ }
25
27
  }
26
- }
27
- function messageContentImageUrl(content) {
28
- const url = typeof content.image_url === "string"
29
- ? content.image_url
30
- : content.image_url.url;
31
- if (!url) {
32
- throw new Error("Missing Image URL");
33
- }
34
- const mineTypeAndData = extractMimeType(url);
35
- if (mineTypeAndData) {
36
- return {
37
- inlineData: mineTypeAndData,
38
- };
28
+ function messageContentImageUrl(content) {
29
+ const url = typeof content.image_url === "string"
30
+ ? content.image_url
31
+ : content.image_url.url;
32
+ if (!url) {
33
+ throw new Error("Missing Image URL");
34
+ }
35
+ const mineTypeAndData = extractMimeType(url);
36
+ if (mineTypeAndData) {
37
+ return {
38
+ inlineData: mineTypeAndData,
39
+ };
40
+ }
41
+ else {
42
+ // FIXME - need some way to get mime type
43
+ return {
44
+ fileData: {
45
+ mimeType: "image/png",
46
+ fileUri: url,
47
+ },
48
+ };
49
+ }
39
50
  }
40
- else {
41
- // FIXME - need some way to get mime type
51
+ async function blobToFileData(blob) {
42
52
  return {
43
53
  fileData: {
44
- mimeType: "image/png",
45
- fileUri: url,
46
- },
47
- };
48
- }
49
- }
50
- function messageContentMedia(
51
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
- content) {
53
- if ("mimeType" in content && "data" in content) {
54
- return {
55
- inlineData: {
56
- mimeType: content.mimeType,
57
- data: content.data,
54
+ fileUri: blob.path,
55
+ mimeType: blob.mimetype,
58
56
  },
59
57
  };
60
58
  }
61
- else if ("mimeType" in content && "fileUri" in content) {
62
- return {
63
- fileData: {
64
- mimeType: content.mimeType,
65
- fileUri: content.fileUri,
66
- },
67
- };
59
+ async function fileUriContentToBlob(uri) {
60
+ return config?.mediaManager?.getMediaBlob(uri);
61
+ }
62
+ async function messageContentMedia(
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ content) {
65
+ if ("mimeType" in content && "data" in content) {
66
+ return {
67
+ inlineData: {
68
+ mimeType: content.mimeType,
69
+ data: content.data,
70
+ },
71
+ };
72
+ }
73
+ else if ("mimeType" in content && "fileUri" in content) {
74
+ return {
75
+ fileData: {
76
+ mimeType: content.mimeType,
77
+ fileUri: content.fileUri,
78
+ },
79
+ };
80
+ }
81
+ else {
82
+ const uri = content.fileUri;
83
+ const blob = await fileUriContentToBlob(uri);
84
+ if (blob) {
85
+ return await blobToFileData(blob);
86
+ }
87
+ }
88
+ throw new Error("Invalid media content");
68
89
  }
69
- throw new Error("Invalid media content");
70
- }
71
- function messageContentToParts(content) {
72
- // Convert a string to a text type MessageContent if needed
73
- const messageContent = typeof content === "string"
74
- ? [
75
- {
76
- type: "text",
77
- text: content,
78
- },
79
- ]
80
- : content;
81
- // eslint-disable-next-line array-callback-return
82
- const parts = messageContent
83
- .map((content) => {
90
+ async function messageContentComplexToPart(content) {
84
91
  switch (content.type) {
85
92
  case "text":
86
93
  if ("text" in content) {
@@ -94,489 +101,482 @@ function messageContentToParts(content) {
94
101
  }
95
102
  break;
96
103
  case "media":
97
- return messageContentMedia(content);
104
+ return await messageContentMedia(content);
98
105
  default:
99
106
  throw new Error(`Unsupported type received while converting message to message parts`);
100
107
  }
101
108
  throw new Error(`Cannot coerce "${content.type}" message part into a string.`);
102
- })
103
- .reduce((acc, val) => {
104
- if (val) {
105
- return [...acc, val];
109
+ }
110
+ async function messageContentComplexToParts(content) {
111
+ const contents = content.map(messageContentComplexToPart);
112
+ return Promise.all(contents);
113
+ }
114
+ async function messageContentToParts(content) {
115
+ // Convert a string to a text type MessageContent if needed
116
+ const messageContent = typeof content === "string"
117
+ ? [
118
+ {
119
+ type: "text",
120
+ text: content,
121
+ },
122
+ ]
123
+ : content;
124
+ // Get all of the parts, even those that don't correctly resolve
125
+ const allParts = await messageContentComplexToParts(messageContent);
126
+ // Remove any invalid parts
127
+ const parts = allParts.reduce((acc, val) => {
128
+ if (val) {
129
+ return [...acc, val];
130
+ }
131
+ else {
132
+ return acc;
133
+ }
134
+ }, []);
135
+ return parts;
136
+ }
137
+ function messageToolCallsToParts(toolCalls) {
138
+ if (!toolCalls || toolCalls.length === 0) {
139
+ return [];
140
+ }
141
+ return toolCalls.map((tool) => {
142
+ let args = {};
143
+ if (tool?.function?.arguments) {
144
+ const argStr = tool.function.arguments;
145
+ args = JSON.parse(argStr);
146
+ }
147
+ return {
148
+ functionCall: {
149
+ name: tool.function.name,
150
+ args,
151
+ },
152
+ };
153
+ });
154
+ }
155
+ function messageKwargsToParts(kwargs) {
156
+ const ret = [];
157
+ if (kwargs?.tool_calls) {
158
+ ret.push(...messageToolCallsToParts(kwargs.tool_calls));
159
+ }
160
+ return ret;
161
+ }
162
+ async function roleMessageToContent(role, message) {
163
+ const contentParts = await messageContentToParts(message.content);
164
+ let toolParts;
165
+ if ((0, messages_1.isAIMessage)(message) && !!message.tool_calls?.length) {
166
+ toolParts = message.tool_calls.map((toolCall) => ({
167
+ functionCall: {
168
+ name: toolCall.name,
169
+ args: toolCall.args,
170
+ },
171
+ }));
106
172
  }
107
173
  else {
108
- return acc;
174
+ toolParts = messageKwargsToParts(message.additional_kwargs);
175
+ }
176
+ const parts = [...contentParts, ...toolParts];
177
+ return [
178
+ {
179
+ role,
180
+ parts,
181
+ },
182
+ ];
183
+ }
184
+ async function systemMessageToContent(message, useSystemInstruction) {
185
+ return useSystemInstruction
186
+ ? roleMessageToContent("system", message)
187
+ : [
188
+ ...(await roleMessageToContent("user", message)),
189
+ ...(await roleMessageToContent("model", new messages_1.AIMessage("Ok"))),
190
+ ];
191
+ }
192
+ function toolMessageToContent(message, prevMessage) {
193
+ const contentStr = typeof message.content === "string"
194
+ ? message.content
195
+ : message.content.reduce((acc, content) => {
196
+ if (content.type === "text") {
197
+ return acc + content.text;
198
+ }
199
+ else {
200
+ return acc;
201
+ }
202
+ }, "");
203
+ // Hacky :(
204
+ const responseName = ((0, messages_1.isAIMessage)(prevMessage) && !!prevMessage.tool_calls?.length
205
+ ? prevMessage.tool_calls[0].name
206
+ : prevMessage.name) ?? message.tool_call_id;
207
+ try {
208
+ const content = JSON.parse(contentStr);
209
+ return [
210
+ {
211
+ role: "function",
212
+ parts: [
213
+ {
214
+ functionResponse: {
215
+ name: responseName,
216
+ response: { content },
217
+ },
218
+ },
219
+ ],
220
+ },
221
+ ];
222
+ }
223
+ catch (_) {
224
+ return [
225
+ {
226
+ role: "function",
227
+ parts: [
228
+ {
229
+ functionResponse: {
230
+ name: responseName,
231
+ response: { content: contentStr },
232
+ },
233
+ },
234
+ ],
235
+ },
236
+ ];
109
237
  }
110
- }, []);
111
- return parts;
112
- }
113
- exports.messageContentToParts = messageContentToParts;
114
- function messageToolCallsToParts(toolCalls) {
115
- if (!toolCalls || toolCalls.length === 0) {
116
- return [];
117
238
  }
118
- return toolCalls.map((tool) => {
119
- let args = {};
120
- if (tool?.function?.arguments) {
121
- const argStr = tool.function.arguments;
122
- args = JSON.parse(argStr);
239
+ async function baseMessageToContent(message, prevMessage, useSystemInstruction) {
240
+ const type = message._getType();
241
+ switch (type) {
242
+ case "system":
243
+ return systemMessageToContent(message, useSystemInstruction);
244
+ case "human":
245
+ return roleMessageToContent("user", message);
246
+ case "ai":
247
+ return roleMessageToContent("model", message);
248
+ case "tool":
249
+ if (!prevMessage) {
250
+ throw new Error("Tool messages cannot be the first message passed to the model.");
251
+ }
252
+ return toolMessageToContent(message, prevMessage);
253
+ default:
254
+ console.log(`Unsupported message type: ${type}`);
255
+ return [];
123
256
  }
257
+ }
258
+ function textPartToMessageContent(part) {
124
259
  return {
125
- functionCall: {
126
- name: tool.function.name,
127
- args,
128
- },
260
+ type: "text",
261
+ text: part.text,
129
262
  };
130
- });
131
- }
132
- function messageKwargsToParts(kwargs) {
133
- const ret = [];
134
- if (kwargs?.tool_calls) {
135
- ret.push(...messageToolCallsToParts(kwargs.tool_calls));
136
263
  }
137
- return ret;
138
- }
139
- function roleMessageToContent(role, message) {
140
- const contentParts = messageContentToParts(message.content);
141
- let toolParts;
142
- if ((0, messages_1.isAIMessage)(message) && !!message.tool_calls?.length) {
143
- toolParts = message.tool_calls.map((toolCall) => ({
144
- functionCall: {
145
- name: toolCall.name,
146
- args: toolCall.args,
147
- },
148
- }));
149
- }
150
- else {
151
- toolParts = messageKwargsToParts(message.additional_kwargs);
152
- }
153
- const parts = [...contentParts, ...toolParts];
154
- return [
155
- {
156
- role,
157
- parts,
158
- },
159
- ];
160
- }
161
- function systemMessageToContent(message, useSystemInstruction) {
162
- return useSystemInstruction
163
- ? roleMessageToContent("system", message)
164
- : [
165
- ...roleMessageToContent("user", message),
166
- ...roleMessageToContent("model", new messages_1.AIMessage("Ok")),
167
- ];
168
- }
169
- function toolMessageToContent(message, prevMessage) {
170
- const contentStr = typeof message.content === "string"
171
- ? message.content
172
- : message.content.reduce((acc, content) => {
173
- if (content.type === "text") {
174
- return acc + content.text;
264
+ function inlineDataPartToMessageContent(part) {
265
+ return {
266
+ type: "image_url",
267
+ image_url: `data:${part.inlineData.mimeType};base64,${part.inlineData.data}`,
268
+ };
269
+ }
270
+ function fileDataPartToMessageContent(part) {
271
+ return {
272
+ type: "image_url",
273
+ image_url: part.fileData.fileUri,
274
+ };
275
+ }
276
+ function partsToMessageContent(parts) {
277
+ return parts
278
+ .map((part) => {
279
+ if (part === undefined || part === null) {
280
+ return null;
281
+ }
282
+ else if ("text" in part) {
283
+ return textPartToMessageContent(part);
284
+ }
285
+ else if ("inlineData" in part) {
286
+ return inlineDataPartToMessageContent(part);
287
+ }
288
+ else if ("fileData" in part) {
289
+ return fileDataPartToMessageContent(part);
175
290
  }
176
291
  else {
177
- return acc;
292
+ return null;
178
293
  }
179
- }, "");
180
- // Hacky :(
181
- const responseName = ((0, messages_1.isAIMessage)(prevMessage) && !!prevMessage.tool_calls?.length
182
- ? prevMessage.tool_calls[0].name
183
- : prevMessage.name) ?? message.tool_call_id;
184
- try {
185
- const content = JSON.parse(contentStr);
186
- return [
187
- {
188
- role: "function",
189
- parts: [
190
- {
191
- functionResponse: {
192
- name: responseName,
193
- response: { content },
194
- },
195
- },
196
- ],
294
+ })
295
+ .reduce((acc, content) => {
296
+ if (content) {
297
+ acc.push(content);
298
+ }
299
+ return acc;
300
+ }, []);
301
+ }
302
+ function toolRawToTool(raw) {
303
+ return {
304
+ id: raw.id,
305
+ type: raw.type,
306
+ function: {
307
+ name: raw.function.name,
308
+ arguments: JSON.stringify(raw.function.arguments),
197
309
  },
198
- ];
310
+ };
199
311
  }
200
- catch (_) {
201
- return [
202
- {
203
- role: "function",
204
- parts: [
205
- {
206
- functionResponse: {
207
- name: responseName,
208
- response: { content: contentStr },
209
- },
210
- },
211
- ],
312
+ function functionCallPartToToolRaw(part) {
313
+ return {
314
+ id: (0, uuid_1.v4)().replace(/-/g, ""),
315
+ type: "function",
316
+ function: {
317
+ name: part.functionCall.name,
318
+ arguments: part.functionCall.args ?? {},
212
319
  },
213
- ];
320
+ };
214
321
  }
215
- }
216
- function baseMessageToContent(message, prevMessage, useSystemInstruction) {
217
- const type = message._getType();
218
- switch (type) {
219
- case "system":
220
- return systemMessageToContent(message, useSystemInstruction);
221
- case "human":
222
- return roleMessageToContent("user", message);
223
- case "ai":
224
- return roleMessageToContent("model", message);
225
- case "tool":
226
- if (!prevMessage) {
227
- throw new Error("Tool messages cannot be the first message passed to the model.");
322
+ function partsToToolsRaw(parts) {
323
+ return parts
324
+ .map((part) => {
325
+ if (part === undefined || part === null) {
326
+ return null;
228
327
  }
229
- return toolMessageToContent(message, prevMessage);
230
- default:
231
- console.log(`Unsupported message type: ${type}`);
232
- return [];
328
+ else if ("functionCall" in part) {
329
+ return functionCallPartToToolRaw(part);
330
+ }
331
+ else {
332
+ return null;
333
+ }
334
+ })
335
+ .reduce((acc, content) => {
336
+ if (content) {
337
+ acc.push(content);
338
+ }
339
+ return acc;
340
+ }, []);
233
341
  }
234
- }
235
- exports.baseMessageToContent = baseMessageToContent;
236
- function textPartToMessageContent(part) {
237
- return {
238
- type: "text",
239
- text: part.text,
240
- };
241
- }
242
- function inlineDataPartToMessageContent(part) {
243
- return {
244
- type: "image_url",
245
- image_url: `data:${part.inlineData.mimeType};base64,${part.inlineData.data}`,
246
- };
247
- }
248
- function fileDataPartToMessageContent(part) {
249
- return {
250
- type: "image_url",
251
- image_url: part.fileData.fileUri,
252
- };
253
- }
254
- function partsToMessageContent(parts) {
255
- return parts
256
- .map((part) => {
257
- if (part === undefined || part === null) {
258
- return null;
259
- }
260
- else if ("text" in part) {
261
- return textPartToMessageContent(part);
262
- }
263
- else if ("inlineData" in part) {
264
- return inlineDataPartToMessageContent(part);
265
- }
266
- else if ("fileData" in part) {
267
- return fileDataPartToMessageContent(part);
268
- }
269
- else {
270
- return null;
271
- }
272
- })
273
- .reduce((acc, content) => {
274
- if (content) {
275
- acc.push(content);
276
- }
277
- return acc;
278
- }, []);
279
- }
280
- exports.partsToMessageContent = partsToMessageContent;
281
- function toolRawToTool(raw) {
282
- return {
283
- id: raw.id,
284
- type: raw.type,
285
- function: {
286
- name: raw.function.name,
287
- arguments: JSON.stringify(raw.function.arguments),
288
- },
289
- };
290
- }
291
- function functionCallPartToToolRaw(part) {
292
- return {
293
- id: (0, uuid_1.v4)().replace(/-/g, ""),
294
- type: "function",
295
- function: {
296
- name: part.functionCall.name,
297
- arguments: part.functionCall.args ?? {},
298
- },
299
- };
300
- }
301
- function partsToToolsRaw(parts) {
302
- return parts
303
- .map((part) => {
304
- if (part === undefined || part === null) {
305
- return null;
342
+ function toolsRawToTools(raws) {
343
+ return raws.map((raw) => toolRawToTool(raw));
344
+ }
345
+ function responseToGenerateContentResponseData(response) {
346
+ if ("nextChunk" in response.data) {
347
+ throw new Error("Cannot convert Stream to GenerateContentResponseData");
306
348
  }
307
- else if ("functionCall" in part) {
308
- return functionCallPartToToolRaw(part);
349
+ else if (Array.isArray(response.data)) {
350
+ // Collapse the array of response data as if it was a single one
351
+ return response.data.reduce((acc, val) => {
352
+ // Add all the parts
353
+ // FIXME: Handle other candidates?
354
+ const valParts = val?.candidates?.[0]?.content?.parts ?? [];
355
+ acc.candidates[0].content.parts.push(...valParts);
356
+ // FIXME: Merge promptFeedback and safety settings
357
+ acc.promptFeedback = val.promptFeedback;
358
+ return acc;
359
+ });
309
360
  }
310
361
  else {
311
- return null;
312
- }
313
- })
314
- .reduce((acc, content) => {
315
- if (content) {
316
- acc.push(content);
362
+ return response.data;
317
363
  }
318
- return acc;
319
- }, []);
320
- }
321
- exports.partsToToolsRaw = partsToToolsRaw;
322
- function toolsRawToTools(raws) {
323
- return raws.map((raw) => toolRawToTool(raw));
324
- }
325
- exports.toolsRawToTools = toolsRawToTools;
326
- function responseToGenerateContentResponseData(response) {
327
- if ("nextChunk" in response.data) {
328
- throw new Error("Cannot convert Stream to GenerateContentResponseData");
329
- }
330
- else if (Array.isArray(response.data)) {
331
- // Collapse the array of response data as if it was a single one
332
- return response.data.reduce((acc, val) => {
333
- // Add all the parts
334
- // FIXME: Handle other candidates?
335
- const valParts = val?.candidates?.[0]?.content?.parts ?? [];
336
- acc.candidates[0].content.parts.push(...valParts);
337
- // FIXME: Merge promptFeedback and safety settings
338
- acc.promptFeedback = val.promptFeedback;
339
- return acc;
340
- });
341
364
  }
342
- else {
343
- return response.data;
365
+ function responseToParts(response) {
366
+ const responseData = responseToGenerateContentResponseData(response);
367
+ const parts = responseData?.candidates?.[0]?.content?.parts ?? [];
368
+ return parts;
344
369
  }
345
- }
346
- exports.responseToGenerateContentResponseData = responseToGenerateContentResponseData;
347
- function responseToParts(response) {
348
- const responseData = responseToGenerateContentResponseData(response);
349
- const parts = responseData?.candidates?.[0]?.content?.parts ?? [];
350
- return parts;
351
- }
352
- exports.responseToParts = responseToParts;
353
- function partToText(part) {
354
- return "text" in part ? part.text : "";
355
- }
356
- exports.partToText = partToText;
357
- function responseToString(response) {
358
- const parts = responseToParts(response);
359
- const ret = parts.reduce((acc, part) => {
360
- const val = partToText(part);
361
- return acc + val;
362
- }, "");
363
- return ret;
364
- }
365
- exports.responseToString = responseToString;
366
- function safeResponseTo(response, safetyHandler, responseTo) {
367
- try {
368
- const safeResponse = safetyHandler.handle(response);
369
- return responseTo(safeResponse);
370
+ function partToText(part) {
371
+ return "text" in part ? part.text : "";
370
372
  }
371
- catch (xx) {
372
- // eslint-disable-next-line no-instanceof/no-instanceof
373
- if (xx instanceof safety_js_1.GoogleAISafetyError) {
374
- const ret = responseTo(xx.response);
375
- xx.reply = ret;
373
+ function responseToString(response) {
374
+ const parts = responseToParts(response);
375
+ const ret = parts.reduce((acc, part) => {
376
+ const val = partToText(part);
377
+ return acc + val;
378
+ }, "");
379
+ return ret;
380
+ }
381
+ function safeResponseTo(response, safetyHandler, responseTo) {
382
+ try {
383
+ const safeResponse = safetyHandler.handle(response);
384
+ return responseTo(safeResponse);
385
+ }
386
+ catch (xx) {
387
+ // eslint-disable-next-line no-instanceof/no-instanceof
388
+ if (xx instanceof safety_js_1.GoogleAISafetyError) {
389
+ const ret = responseTo(xx.response);
390
+ xx.reply = ret;
391
+ }
392
+ throw xx;
376
393
  }
377
- throw xx;
378
394
  }
379
- }
380
- function safeResponseToString(response, safetyHandler) {
381
- return safeResponseTo(response, safetyHandler, responseToString);
382
- }
383
- exports.safeResponseToString = safeResponseToString;
384
- function responseToGenerationInfo(response) {
385
- if (!Array.isArray(response.data)) {
386
- return {};
395
+ function safeResponseToString(response, safetyHandler) {
396
+ return safeResponseTo(response, safetyHandler, responseToString);
387
397
  }
388
- const data = response.data[0];
389
- return {
390
- usage_metadata: {
391
- prompt_token_count: data.usageMetadata?.promptTokenCount,
392
- candidates_token_count: data.usageMetadata?.candidatesTokenCount,
393
- total_token_count: data.usageMetadata?.totalTokenCount,
394
- },
395
- safety_ratings: data.candidates[0]?.safetyRatings?.map((rating) => ({
396
- category: rating.category,
397
- probability: rating.probability,
398
- probability_score: rating.probabilityScore,
399
- severity: rating.severity,
400
- severity_score: rating.severityScore,
401
- })),
402
- finish_reason: data.candidates[0]?.finishReason,
403
- };
404
- }
405
- exports.responseToGenerationInfo = responseToGenerationInfo;
406
- function responseToGeneration(response) {
407
- return {
408
- text: responseToString(response),
409
- generationInfo: responseToGenerationInfo(response),
410
- };
411
- }
412
- exports.responseToGeneration = responseToGeneration;
413
- function safeResponseToGeneration(response, safetyHandler) {
414
- return safeResponseTo(response, safetyHandler, responseToGeneration);
415
- }
416
- exports.safeResponseToGeneration = safeResponseToGeneration;
417
- function responseToChatGeneration(response) {
418
- return new outputs_1.ChatGenerationChunk({
419
- text: responseToString(response),
420
- message: partToMessageChunk(responseToParts(response)[0]),
421
- generationInfo: responseToGenerationInfo(response),
422
- });
423
- }
424
- exports.responseToChatGeneration = responseToChatGeneration;
425
- function safeResponseToChatGeneration(response, safetyHandler) {
426
- return safeResponseTo(response, safetyHandler, responseToChatGeneration);
427
- }
428
- exports.safeResponseToChatGeneration = safeResponseToChatGeneration;
429
- function chunkToString(chunk) {
430
- if (chunk === null) {
431
- return "";
432
- }
433
- else if (typeof chunk.content === "string") {
434
- return chunk.content;
398
+ function responseToGenerationInfo(response) {
399
+ if (!Array.isArray(response.data)) {
400
+ return {};
401
+ }
402
+ const data = response.data[0];
403
+ return {
404
+ usage_metadata: {
405
+ prompt_token_count: data.usageMetadata?.promptTokenCount,
406
+ candidates_token_count: data.usageMetadata?.candidatesTokenCount,
407
+ total_token_count: data.usageMetadata?.totalTokenCount,
408
+ },
409
+ safety_ratings: data.candidates[0]?.safetyRatings?.map((rating) => ({
410
+ category: rating.category,
411
+ probability: rating.probability,
412
+ probability_score: rating.probabilityScore,
413
+ severity: rating.severity,
414
+ severity_score: rating.severityScore,
415
+ })),
416
+ finish_reason: data.candidates[0]?.finishReason,
417
+ };
435
418
  }
436
- else if (chunk.content.length === 0) {
437
- return "";
419
+ function responseToChatGeneration(response) {
420
+ return new outputs_1.ChatGenerationChunk({
421
+ text: responseToString(response),
422
+ message: partToMessageChunk(responseToParts(response)[0]),
423
+ generationInfo: responseToGenerationInfo(response),
424
+ });
438
425
  }
439
- else if (chunk.content[0].type === "text") {
440
- return chunk.content[0].text;
426
+ function safeResponseToChatGeneration(response, safetyHandler) {
427
+ return safeResponseTo(response, safetyHandler, responseToChatGeneration);
441
428
  }
442
- else {
443
- throw new Error(`Unexpected chunk: ${chunk}`);
429
+ function chunkToString(chunk) {
430
+ if (chunk === null) {
431
+ return "";
432
+ }
433
+ else if (typeof chunk.content === "string") {
434
+ return chunk.content;
435
+ }
436
+ else if (chunk.content.length === 0) {
437
+ return "";
438
+ }
439
+ else if (chunk.content[0].type === "text") {
440
+ return chunk.content[0].text;
441
+ }
442
+ else {
443
+ throw new Error(`Unexpected chunk: ${chunk}`);
444
+ }
444
445
  }
445
- }
446
- exports.chunkToString = chunkToString;
447
- function partToMessageChunk(part) {
448
- const fields = partsToBaseMessageChunkFields([part]);
449
- if (typeof fields.content === "string") {
446
+ function partToMessageChunk(part) {
447
+ const fields = partsToBaseMessageChunkFields([part]);
448
+ if (typeof fields.content === "string") {
449
+ return new messages_1.AIMessageChunk(fields);
450
+ }
451
+ else if (fields.content.every((item) => item.type === "text")) {
452
+ const newContent = fields.content
453
+ .map((item) => ("text" in item ? item.text : ""))
454
+ .join("");
455
+ return new messages_1.AIMessageChunk({
456
+ ...fields,
457
+ content: newContent,
458
+ });
459
+ }
450
460
  return new messages_1.AIMessageChunk(fields);
451
461
  }
452
- else if (fields.content.every((item) => item.type === "text")) {
453
- const newContent = fields.content
454
- .map((item) => ("text" in item ? item.text : ""))
455
- .join("");
456
- return new messages_1.AIMessageChunk({
457
- ...fields,
458
- content: newContent,
462
+ function partToChatGeneration(part) {
463
+ const message = partToMessageChunk(part);
464
+ const text = partToText(part);
465
+ return new outputs_1.ChatGenerationChunk({
466
+ text,
467
+ message,
459
468
  });
460
469
  }
461
- return new messages_1.AIMessageChunk(fields);
462
- }
463
- exports.partToMessageChunk = partToMessageChunk;
464
- function partToChatGeneration(part) {
465
- const message = partToMessageChunk(part);
466
- const text = partToText(part);
467
- return new outputs_1.ChatGenerationChunk({
468
- text,
469
- message,
470
- });
471
- }
472
- exports.partToChatGeneration = partToChatGeneration;
473
- function responseToChatGenerations(response) {
474
- const parts = responseToParts(response);
475
- let ret = parts.map((part) => partToChatGeneration(part));
476
- if (ret.every((item) => typeof item.message.content === "string")) {
477
- const combinedContent = ret.map((item) => item.message.content).join("");
478
- const combinedText = ret.map((item) => item.text).join("");
479
- const toolCallChunks = ret[ret.length - 1]?.message.additional_kwargs?.tool_calls?.map((toolCall, i) => ({
480
- name: toolCall.function.name,
481
- args: toolCall.function.arguments,
482
- id: toolCall.id,
483
- index: i,
484
- type: "tool_call_chunk",
485
- }));
486
- let usageMetadata;
487
- if ("usageMetadata" in response.data) {
488
- usageMetadata = {
489
- input_tokens: response.data.usageMetadata.promptTokenCount,
490
- output_tokens: response.data.usageMetadata
491
- .candidatesTokenCount,
492
- total_tokens: response.data.usageMetadata.totalTokenCount,
493
- };
494
- }
495
- ret = [
496
- new outputs_1.ChatGenerationChunk({
497
- message: new messages_1.AIMessageChunk({
498
- content: combinedContent,
499
- additional_kwargs: ret[ret.length - 1]?.message.additional_kwargs,
500
- tool_call_chunks: toolCallChunks,
501
- usage_metadata: usageMetadata,
502
- }),
503
- text: combinedText,
504
- generationInfo: ret[ret.length - 1].generationInfo,
505
- }),
506
- ];
507
- }
508
- return ret;
509
- }
510
- exports.responseToChatGenerations = responseToChatGenerations;
511
- function responseToBaseMessageFields(response) {
512
- const parts = responseToParts(response);
513
- return partsToBaseMessageChunkFields(parts);
514
- }
515
- exports.responseToBaseMessageFields = responseToBaseMessageFields;
516
- function partsToBaseMessageChunkFields(parts) {
517
- const fields = {
518
- content: partsToMessageContent(parts),
519
- tool_call_chunks: [],
520
- tool_calls: [],
521
- invalid_tool_calls: [],
522
- };
523
- const rawTools = partsToToolsRaw(parts);
524
- if (rawTools.length > 0) {
525
- const tools = toolsRawToTools(rawTools);
526
- for (const tool of tools) {
527
- fields.tool_call_chunks?.push({
528
- name: tool.function.name,
529
- args: tool.function.arguments,
530
- id: tool.id,
470
+ function responseToChatGenerations(response) {
471
+ const parts = responseToParts(response);
472
+ let ret = parts.map((part) => partToChatGeneration(part));
473
+ if (ret.every((item) => typeof item.message.content === "string")) {
474
+ const combinedContent = ret.map((item) => item.message.content).join("");
475
+ const combinedText = ret.map((item) => item.text).join("");
476
+ const toolCallChunks = ret[ret.length - 1]?.message.additional_kwargs?.tool_calls?.map((toolCall, i) => ({
477
+ name: toolCall.function.name,
478
+ args: toolCall.function.arguments,
479
+ id: toolCall.id,
480
+ index: i,
531
481
  type: "tool_call_chunk",
532
- });
533
- try {
534
- fields.tool_calls?.push({
535
- name: tool.function.name,
536
- args: JSON.parse(tool.function.arguments),
537
- id: tool.id,
538
- type: "tool_call",
539
- });
540
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
482
+ }));
483
+ let usageMetadata;
484
+ if ("usageMetadata" in response.data) {
485
+ usageMetadata = {
486
+ input_tokens: response.data.usageMetadata.promptTokenCount,
487
+ output_tokens: response.data.usageMetadata
488
+ .candidatesTokenCount,
489
+ total_tokens: response.data.usageMetadata.totalTokenCount,
490
+ };
541
491
  }
542
- catch (e) {
543
- fields.invalid_tool_calls?.push({
492
+ ret = [
493
+ new outputs_1.ChatGenerationChunk({
494
+ message: new messages_1.AIMessageChunk({
495
+ content: combinedContent,
496
+ additional_kwargs: ret[ret.length - 1]?.message.additional_kwargs,
497
+ tool_call_chunks: toolCallChunks,
498
+ usage_metadata: usageMetadata,
499
+ }),
500
+ text: combinedText,
501
+ generationInfo: ret[ret.length - 1].generationInfo,
502
+ }),
503
+ ];
504
+ }
505
+ return ret;
506
+ }
507
+ function responseToBaseMessageFields(response) {
508
+ const parts = responseToParts(response);
509
+ return partsToBaseMessageChunkFields(parts);
510
+ }
511
+ function partsToBaseMessageChunkFields(parts) {
512
+ const fields = {
513
+ content: partsToMessageContent(parts),
514
+ tool_call_chunks: [],
515
+ tool_calls: [],
516
+ invalid_tool_calls: [],
517
+ };
518
+ const rawTools = partsToToolsRaw(parts);
519
+ if (rawTools.length > 0) {
520
+ const tools = toolsRawToTools(rawTools);
521
+ for (const tool of tools) {
522
+ fields.tool_call_chunks?.push({
544
523
  name: tool.function.name,
545
524
  args: tool.function.arguments,
546
525
  id: tool.id,
547
- error: e.message,
548
- type: "invalid_tool_call",
526
+ type: "tool_call_chunk",
549
527
  });
528
+ try {
529
+ fields.tool_calls?.push({
530
+ name: tool.function.name,
531
+ args: JSON.parse(tool.function.arguments),
532
+ id: tool.id,
533
+ });
534
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
535
+ }
536
+ catch (e) {
537
+ fields.invalid_tool_calls?.push({
538
+ name: tool.function.name,
539
+ args: tool.function.arguments,
540
+ id: tool.id,
541
+ error: e.message,
542
+ type: "invalid_tool_call",
543
+ });
544
+ }
550
545
  }
546
+ fields.additional_kwargs = {
547
+ tool_calls: tools,
548
+ };
551
549
  }
552
- fields.additional_kwargs = {
553
- tool_calls: tools,
550
+ return fields;
551
+ }
552
+ function responseToBaseMessage(response) {
553
+ const fields = responseToBaseMessageFields(response);
554
+ return new messages_1.AIMessage(fields);
555
+ }
556
+ function safeResponseToBaseMessage(response, safetyHandler) {
557
+ return safeResponseTo(response, safetyHandler, responseToBaseMessage);
558
+ }
559
+ function responseToChatResult(response) {
560
+ const generations = responseToChatGenerations(response);
561
+ return {
562
+ generations,
563
+ llmOutput: responseToGenerationInfo(response),
554
564
  };
555
565
  }
556
- return fields;
557
- }
558
- exports.partsToBaseMessageChunkFields = partsToBaseMessageChunkFields;
559
- function responseToBaseMessage(response) {
560
- const fields = responseToBaseMessageFields(response);
561
- return new messages_1.AIMessage(fields);
562
- }
563
- exports.responseToBaseMessage = responseToBaseMessage;
564
- function safeResponseToBaseMessage(response, safetyHandler) {
565
- return safeResponseTo(response, safetyHandler, responseToBaseMessage);
566
- }
567
- exports.safeResponseToBaseMessage = safeResponseToBaseMessage;
568
- function responseToChatResult(response) {
569
- const generations = responseToChatGenerations(response);
566
+ function safeResponseToChatResult(response, safetyHandler) {
567
+ return safeResponseTo(response, safetyHandler, responseToChatResult);
568
+ }
570
569
  return {
571
- generations,
572
- llmOutput: responseToGenerationInfo(response),
570
+ messageContentToParts,
571
+ baseMessageToContent,
572
+ safeResponseToString,
573
+ safeResponseToChatGeneration,
574
+ chunkToString,
575
+ safeResponseToBaseMessage,
576
+ safeResponseToChatResult,
573
577
  };
574
578
  }
575
- exports.responseToChatResult = responseToChatResult;
576
- function safeResponseToChatResult(response, safetyHandler) {
577
- return safeResponseTo(response, safetyHandler, responseToChatResult);
578
- }
579
- exports.safeResponseToChatResult = safeResponseToChatResult;
579
+ exports.getGeminiAPI = getGeminiAPI;
580
580
  function validateGeminiParams(params) {
581
581
  if (params.maxOutputTokens && params.maxOutputTokens < 0) {
582
582
  throw new Error("`maxOutputTokens` must be a positive integer");