@langchain/google-common 0.0.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.
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isModelGemini = exports.validateGeminiParams = exports.responseToChatResult = exports.responseToBaseMessage = exports.responseToMessageContent = exports.responseToChatGenerations = exports.partToChatGeneration = exports.partToMessage = exports.responseToChatGeneration = exports.responseToGeneration = exports.responseToString = exports.partToText = exports.responseToParts = exports.responseToGenerateContentResponseData = exports.partsToMessageContent = exports.baseMessageToContent = exports.messageContentToParts = void 0;
4
+ const messages_1 = require("@langchain/core/messages");
5
+ const outputs_1 = require("@langchain/core/outputs");
6
+ function messageContentText(content) {
7
+ return {
8
+ text: content.text,
9
+ };
10
+ }
11
+ function messageContentImageUrl(content) {
12
+ const url = typeof content.image_url === "string"
13
+ ? content.image_url
14
+ : content.image_url.url;
15
+ if (!url) {
16
+ throw new Error("Missing Image URL");
17
+ }
18
+ if (url.startsWith("data:")) {
19
+ return {
20
+ mimeType: url.split(":")[1].split(";")[0],
21
+ data: url.split(",")[1],
22
+ };
23
+ }
24
+ else {
25
+ // FIXME - need some way to get mime type
26
+ return {
27
+ mimeType: "image/png",
28
+ fileUri: url,
29
+ };
30
+ }
31
+ }
32
+ function messageContentToParts(content) {
33
+ // Convert a string to a text type MessageContent if needed
34
+ const messageContent = typeof content === "string"
35
+ ? [
36
+ {
37
+ type: "text",
38
+ text: content,
39
+ },
40
+ ]
41
+ : content;
42
+ // eslint-disable-next-line array-callback-return
43
+ const parts = messageContent.map((content) => {
44
+ // eslint-disable-next-line default-case
45
+ switch (content.type) {
46
+ case "text":
47
+ return messageContentText(content);
48
+ case "image_url":
49
+ return messageContentImageUrl(content);
50
+ }
51
+ });
52
+ return parts;
53
+ }
54
+ exports.messageContentToParts = messageContentToParts;
55
+ function roleMessageToContent(role, message) {
56
+ return [
57
+ {
58
+ role,
59
+ parts: messageContentToParts(message.content),
60
+ },
61
+ ];
62
+ }
63
+ function systemMessageToContent(message) {
64
+ return [
65
+ ...roleMessageToContent("user", message),
66
+ ...roleMessageToContent("model", new messages_1.AIMessage("Ok")),
67
+ ];
68
+ }
69
+ function baseMessageToContent(message) {
70
+ const type = message._getType();
71
+ switch (type) {
72
+ case "system":
73
+ return systemMessageToContent(message);
74
+ case "human":
75
+ return roleMessageToContent("user", message);
76
+ case "ai":
77
+ return roleMessageToContent("model", message);
78
+ default:
79
+ console.log(`Unsupported message type: ${type}`);
80
+ return [];
81
+ }
82
+ }
83
+ exports.baseMessageToContent = baseMessageToContent;
84
+ function textPartToMessageContent(part) {
85
+ return {
86
+ type: "text",
87
+ text: part.text,
88
+ };
89
+ }
90
+ function inlineDataPartToMessageContent(part) {
91
+ return {
92
+ type: "image_url",
93
+ image_url: `data:${part.mimeType};base64,${part.data}`,
94
+ };
95
+ }
96
+ function fileDataPartToMessageContent(part) {
97
+ return {
98
+ type: "image_url",
99
+ image_url: part.fileUri,
100
+ };
101
+ }
102
+ function partsToMessageContent(parts) {
103
+ return parts
104
+ .map((part) => {
105
+ if ("text" in part) {
106
+ return textPartToMessageContent(part);
107
+ }
108
+ else if ("mimeType" in part && "data" in part) {
109
+ return inlineDataPartToMessageContent(part);
110
+ }
111
+ else if ("mimeType" in part && "fileUri" in part) {
112
+ return fileDataPartToMessageContent(part);
113
+ }
114
+ else {
115
+ return null;
116
+ }
117
+ })
118
+ .reduce((acc, content) => {
119
+ if (content) {
120
+ acc.push(content);
121
+ }
122
+ return acc;
123
+ }, []);
124
+ }
125
+ exports.partsToMessageContent = partsToMessageContent;
126
+ function responseToGenerateContentResponseData(response) {
127
+ if ("nextChunk" in response.data) {
128
+ throw new Error("Cannot convert Stream to GenerateContentResponseData");
129
+ }
130
+ else if (Array.isArray(response.data)) {
131
+ // Collapse the array of response data as if it was a single one
132
+ return response.data.reduce((acc, val) => {
133
+ // Add all the parts
134
+ // FIXME: Handle other candidates?
135
+ const valParts = val?.candidates?.[0]?.content?.parts ?? [];
136
+ acc.candidates[0].content.parts.push(...valParts);
137
+ // FIXME: Merge promptFeedback and safety settings
138
+ acc.promptFeedback = val.promptFeedback;
139
+ return acc;
140
+ });
141
+ }
142
+ else {
143
+ return response.data;
144
+ }
145
+ }
146
+ exports.responseToGenerateContentResponseData = responseToGenerateContentResponseData;
147
+ function responseToParts(response) {
148
+ const responseData = responseToGenerateContentResponseData(response);
149
+ const parts = responseData?.candidates?.[0]?.content?.parts ?? [];
150
+ return parts;
151
+ }
152
+ exports.responseToParts = responseToParts;
153
+ function partToText(part) {
154
+ return "text" in part ? part.text : "";
155
+ }
156
+ exports.partToText = partToText;
157
+ function responseToString(response) {
158
+ const parts = responseToParts(response);
159
+ const ret = parts.reduce((acc, part) => {
160
+ const val = partToText(part);
161
+ return acc + val;
162
+ }, "");
163
+ return ret;
164
+ }
165
+ exports.responseToString = responseToString;
166
+ function responseToGeneration(response) {
167
+ return {
168
+ text: responseToString(response),
169
+ generationInfo: response,
170
+ };
171
+ }
172
+ exports.responseToGeneration = responseToGeneration;
173
+ function responseToChatGeneration(response) {
174
+ return new outputs_1.ChatGenerationChunk({
175
+ text: responseToString(response),
176
+ message: partToMessage(responseToParts(response)[0]),
177
+ generationInfo: response,
178
+ });
179
+ }
180
+ exports.responseToChatGeneration = responseToChatGeneration;
181
+ function partToMessage(part) {
182
+ const content = partsToMessageContent([part]);
183
+ return new messages_1.AIMessageChunk({ content });
184
+ }
185
+ exports.partToMessage = partToMessage;
186
+ function partToChatGeneration(part) {
187
+ const message = partToMessage(part);
188
+ const text = partToText(part);
189
+ return new outputs_1.ChatGenerationChunk({
190
+ text,
191
+ message,
192
+ });
193
+ }
194
+ exports.partToChatGeneration = partToChatGeneration;
195
+ function responseToChatGenerations(response) {
196
+ const parts = responseToParts(response);
197
+ const ret = parts.map((part) => partToChatGeneration(part));
198
+ return ret;
199
+ }
200
+ exports.responseToChatGenerations = responseToChatGenerations;
201
+ function responseToMessageContent(response) {
202
+ const parts = responseToParts(response);
203
+ return partsToMessageContent(parts);
204
+ }
205
+ exports.responseToMessageContent = responseToMessageContent;
206
+ function responseToBaseMessage(response) {
207
+ return new messages_1.AIMessage({
208
+ content: responseToMessageContent(response),
209
+ });
210
+ }
211
+ exports.responseToBaseMessage = responseToBaseMessage;
212
+ function responseToChatResult(response) {
213
+ const generations = responseToChatGenerations(response);
214
+ return {
215
+ generations,
216
+ llmOutput: response,
217
+ };
218
+ }
219
+ exports.responseToChatResult = responseToChatResult;
220
+ function validateGeminiParams(params) {
221
+ if (params.maxOutputTokens && params.maxOutputTokens < 0) {
222
+ throw new Error("`maxOutputTokens` must be a positive integer");
223
+ }
224
+ if (params.temperature &&
225
+ (params.temperature < 0 || params.temperature > 1)) {
226
+ throw new Error("`temperature` must be in the range of [0.0,1.0]");
227
+ }
228
+ if (params.topP && (params.topP < 0 || params.topP > 1)) {
229
+ throw new Error("`topP` must be in the range of [0.0,1.0]");
230
+ }
231
+ if (params.topK && params.topK < 0) {
232
+ throw new Error("`topK` must be a positive integer");
233
+ }
234
+ }
235
+ exports.validateGeminiParams = validateGeminiParams;
236
+ function isModelGemini(modelName) {
237
+ return modelName.toLowerCase().startsWith("gemini");
238
+ }
239
+ exports.isModelGemini = isModelGemini;
@@ -0,0 +1,20 @@
1
+ import { BaseMessage, BaseMessageChunk, MessageContent } from "@langchain/core/messages";
2
+ import { ChatGeneration, ChatGenerationChunk, ChatResult, Generation } from "@langchain/core/outputs";
3
+ import type { GoogleLLMResponse, GoogleAIModelParams, GeminiPart, GeminiContent, GenerateContentResponseData } from "../types.js";
4
+ export declare function messageContentToParts(content: MessageContent): GeminiPart[];
5
+ export declare function baseMessageToContent(message: BaseMessage): GeminiContent[];
6
+ export declare function partsToMessageContent(parts: GeminiPart[]): MessageContent;
7
+ export declare function responseToGenerateContentResponseData(response: GoogleLLMResponse): GenerateContentResponseData;
8
+ export declare function responseToParts(response: GoogleLLMResponse): GeminiPart[];
9
+ export declare function partToText(part: GeminiPart): string;
10
+ export declare function responseToString(response: GoogleLLMResponse): string;
11
+ export declare function responseToGeneration(response: GoogleLLMResponse): Generation;
12
+ export declare function responseToChatGeneration(response: GoogleLLMResponse): ChatGenerationChunk;
13
+ export declare function partToMessage(part: GeminiPart): BaseMessageChunk;
14
+ export declare function partToChatGeneration(part: GeminiPart): ChatGeneration;
15
+ export declare function responseToChatGenerations(response: GoogleLLMResponse): ChatGeneration[];
16
+ export declare function responseToMessageContent(response: GoogleLLMResponse): MessageContent;
17
+ export declare function responseToBaseMessage(response: GoogleLLMResponse): BaseMessage;
18
+ export declare function responseToChatResult(response: GoogleLLMResponse): ChatResult;
19
+ export declare function validateGeminiParams(params: GoogleAIModelParams): void;
20
+ export declare function isModelGemini(modelName: string): boolean;
@@ -0,0 +1,219 @@
1
+ import { AIMessage, AIMessageChunk, } from "@langchain/core/messages";
2
+ import { ChatGenerationChunk, } from "@langchain/core/outputs";
3
+ function messageContentText(content) {
4
+ return {
5
+ text: content.text,
6
+ };
7
+ }
8
+ function messageContentImageUrl(content) {
9
+ const url = typeof content.image_url === "string"
10
+ ? content.image_url
11
+ : content.image_url.url;
12
+ if (!url) {
13
+ throw new Error("Missing Image URL");
14
+ }
15
+ if (url.startsWith("data:")) {
16
+ return {
17
+ mimeType: url.split(":")[1].split(";")[0],
18
+ data: url.split(",")[1],
19
+ };
20
+ }
21
+ else {
22
+ // FIXME - need some way to get mime type
23
+ return {
24
+ mimeType: "image/png",
25
+ fileUri: url,
26
+ };
27
+ }
28
+ }
29
+ export function messageContentToParts(content) {
30
+ // Convert a string to a text type MessageContent if needed
31
+ const messageContent = typeof content === "string"
32
+ ? [
33
+ {
34
+ type: "text",
35
+ text: content,
36
+ },
37
+ ]
38
+ : content;
39
+ // eslint-disable-next-line array-callback-return
40
+ const parts = messageContent.map((content) => {
41
+ // eslint-disable-next-line default-case
42
+ switch (content.type) {
43
+ case "text":
44
+ return messageContentText(content);
45
+ case "image_url":
46
+ return messageContentImageUrl(content);
47
+ }
48
+ });
49
+ return parts;
50
+ }
51
+ function roleMessageToContent(role, message) {
52
+ return [
53
+ {
54
+ role,
55
+ parts: messageContentToParts(message.content),
56
+ },
57
+ ];
58
+ }
59
+ function systemMessageToContent(message) {
60
+ return [
61
+ ...roleMessageToContent("user", message),
62
+ ...roleMessageToContent("model", new AIMessage("Ok")),
63
+ ];
64
+ }
65
+ export function baseMessageToContent(message) {
66
+ const type = message._getType();
67
+ switch (type) {
68
+ case "system":
69
+ return systemMessageToContent(message);
70
+ case "human":
71
+ return roleMessageToContent("user", message);
72
+ case "ai":
73
+ return roleMessageToContent("model", message);
74
+ default:
75
+ console.log(`Unsupported message type: ${type}`);
76
+ return [];
77
+ }
78
+ }
79
+ function textPartToMessageContent(part) {
80
+ return {
81
+ type: "text",
82
+ text: part.text,
83
+ };
84
+ }
85
+ function inlineDataPartToMessageContent(part) {
86
+ return {
87
+ type: "image_url",
88
+ image_url: `data:${part.mimeType};base64,${part.data}`,
89
+ };
90
+ }
91
+ function fileDataPartToMessageContent(part) {
92
+ return {
93
+ type: "image_url",
94
+ image_url: part.fileUri,
95
+ };
96
+ }
97
+ export function partsToMessageContent(parts) {
98
+ return parts
99
+ .map((part) => {
100
+ if ("text" in part) {
101
+ return textPartToMessageContent(part);
102
+ }
103
+ else if ("mimeType" in part && "data" in part) {
104
+ return inlineDataPartToMessageContent(part);
105
+ }
106
+ else if ("mimeType" in part && "fileUri" in part) {
107
+ return fileDataPartToMessageContent(part);
108
+ }
109
+ else {
110
+ return null;
111
+ }
112
+ })
113
+ .reduce((acc, content) => {
114
+ if (content) {
115
+ acc.push(content);
116
+ }
117
+ return acc;
118
+ }, []);
119
+ }
120
+ export function responseToGenerateContentResponseData(response) {
121
+ if ("nextChunk" in response.data) {
122
+ throw new Error("Cannot convert Stream to GenerateContentResponseData");
123
+ }
124
+ else if (Array.isArray(response.data)) {
125
+ // Collapse the array of response data as if it was a single one
126
+ return response.data.reduce((acc, val) => {
127
+ // Add all the parts
128
+ // FIXME: Handle other candidates?
129
+ const valParts = val?.candidates?.[0]?.content?.parts ?? [];
130
+ acc.candidates[0].content.parts.push(...valParts);
131
+ // FIXME: Merge promptFeedback and safety settings
132
+ acc.promptFeedback = val.promptFeedback;
133
+ return acc;
134
+ });
135
+ }
136
+ else {
137
+ return response.data;
138
+ }
139
+ }
140
+ export function responseToParts(response) {
141
+ const responseData = responseToGenerateContentResponseData(response);
142
+ const parts = responseData?.candidates?.[0]?.content?.parts ?? [];
143
+ return parts;
144
+ }
145
+ export function partToText(part) {
146
+ return "text" in part ? part.text : "";
147
+ }
148
+ export function responseToString(response) {
149
+ const parts = responseToParts(response);
150
+ const ret = parts.reduce((acc, part) => {
151
+ const val = partToText(part);
152
+ return acc + val;
153
+ }, "");
154
+ return ret;
155
+ }
156
+ export function responseToGeneration(response) {
157
+ return {
158
+ text: responseToString(response),
159
+ generationInfo: response,
160
+ };
161
+ }
162
+ export function responseToChatGeneration(response) {
163
+ return new ChatGenerationChunk({
164
+ text: responseToString(response),
165
+ message: partToMessage(responseToParts(response)[0]),
166
+ generationInfo: response,
167
+ });
168
+ }
169
+ export function partToMessage(part) {
170
+ const content = partsToMessageContent([part]);
171
+ return new AIMessageChunk({ content });
172
+ }
173
+ export function partToChatGeneration(part) {
174
+ const message = partToMessage(part);
175
+ const text = partToText(part);
176
+ return new ChatGenerationChunk({
177
+ text,
178
+ message,
179
+ });
180
+ }
181
+ export function responseToChatGenerations(response) {
182
+ const parts = responseToParts(response);
183
+ const ret = parts.map((part) => partToChatGeneration(part));
184
+ return ret;
185
+ }
186
+ export function responseToMessageContent(response) {
187
+ const parts = responseToParts(response);
188
+ return partsToMessageContent(parts);
189
+ }
190
+ export function responseToBaseMessage(response) {
191
+ return new AIMessage({
192
+ content: responseToMessageContent(response),
193
+ });
194
+ }
195
+ export function responseToChatResult(response) {
196
+ const generations = responseToChatGenerations(response);
197
+ return {
198
+ generations,
199
+ llmOutput: response,
200
+ };
201
+ }
202
+ export function validateGeminiParams(params) {
203
+ if (params.maxOutputTokens && params.maxOutputTokens < 0) {
204
+ throw new Error("`maxOutputTokens` must be a positive integer");
205
+ }
206
+ if (params.temperature &&
207
+ (params.temperature < 0 || params.temperature > 1)) {
208
+ throw new Error("`temperature` must be in the range of [0.0,1.0]");
209
+ }
210
+ if (params.topP && (params.topP < 0 || params.topP > 1)) {
211
+ throw new Error("`topP` must be in the range of [0.0,1.0]");
212
+ }
213
+ if (params.topK && params.topK < 0) {
214
+ throw new Error("`topK` must be a positive integer");
215
+ }
216
+ }
217
+ export function isModelGemini(modelName) {
218
+ return modelName.toLowerCase().startsWith("gemini");
219
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ export interface GoogleVertexAIBasePrediction {
2
+ safetyAttributes?: any;
3
+ }
4
+ export interface GoogleVertexAILLMPredictions<PredictionType extends GoogleVertexAIBasePrediction> {
5
+ predictions: PredictionType[];
6
+ }
@@ -0,0 +1 @@
1
+ export {};