@langchain/google-common 0.0.2 → 0.0.3

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.
@@ -22,6 +22,58 @@ function copyAIModelParamsInto(params, options, target) {
22
22
  ret.safetySettings =
23
23
  options?.safetySettings ?? params?.safetySettings ?? target.safetySettings;
24
24
  ret.tools = options?.tools;
25
+ // Ensure tools are formatted properly for Gemini
26
+ const geminiTools = options?.tools
27
+ ?.map((tool) => {
28
+ if ("function" in tool &&
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ "parameters" in tool.function) {
31
+ // Tool is in OpenAI format. Convert to Gemini then return.
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ const castTool = tool.function;
34
+ const cleanedParameters = castTool.parameters;
35
+ if ("$schema" in cleanedParameters) {
36
+ delete cleanedParameters.$schema;
37
+ }
38
+ if ("additionalProperties" in cleanedParameters) {
39
+ delete cleanedParameters.additionalProperties;
40
+ }
41
+ const toolInGeminiFormat = {
42
+ functionDeclarations: [
43
+ {
44
+ name: castTool.name,
45
+ description: castTool.description,
46
+ parameters: cleanedParameters,
47
+ },
48
+ ],
49
+ };
50
+ return toolInGeminiFormat;
51
+ }
52
+ else if ("functionDeclarations" in tool) {
53
+ return tool;
54
+ }
55
+ else {
56
+ return null;
57
+ }
58
+ })
59
+ .filter((tool) => tool !== null);
60
+ const structuredOutputTools = options?.tools
61
+ ?.map((tool) => {
62
+ if ("lc_namespace" in tool) {
63
+ return tool;
64
+ }
65
+ else {
66
+ return null;
67
+ }
68
+ })
69
+ .filter((tool) => tool !== null);
70
+ if (structuredOutputTools &&
71
+ structuredOutputTools.length > 0 &&
72
+ geminiTools &&
73
+ geminiTools.length > 0) {
74
+ throw new Error(`Cannot mix structured tools with Gemini tools.\nReceived ${structuredOutputTools.length} structured tools and ${geminiTools.length} Gemini tools.`);
75
+ }
76
+ ret.tools = geminiTools ?? structuredOutputTools;
25
77
  return ret;
26
78
  }
27
79
  exports.copyAIModelParamsInto = copyAIModelParamsInto;
@@ -18,6 +18,58 @@ export function copyAIModelParamsInto(params, options, target) {
18
18
  ret.safetySettings =
19
19
  options?.safetySettings ?? params?.safetySettings ?? target.safetySettings;
20
20
  ret.tools = options?.tools;
21
+ // Ensure tools are formatted properly for Gemini
22
+ const geminiTools = options?.tools
23
+ ?.map((tool) => {
24
+ if ("function" in tool &&
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ "parameters" in tool.function) {
27
+ // Tool is in OpenAI format. Convert to Gemini then return.
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ const castTool = tool.function;
30
+ const cleanedParameters = castTool.parameters;
31
+ if ("$schema" in cleanedParameters) {
32
+ delete cleanedParameters.$schema;
33
+ }
34
+ if ("additionalProperties" in cleanedParameters) {
35
+ delete cleanedParameters.additionalProperties;
36
+ }
37
+ const toolInGeminiFormat = {
38
+ functionDeclarations: [
39
+ {
40
+ name: castTool.name,
41
+ description: castTool.description,
42
+ parameters: cleanedParameters,
43
+ },
44
+ ],
45
+ };
46
+ return toolInGeminiFormat;
47
+ }
48
+ else if ("functionDeclarations" in tool) {
49
+ return tool;
50
+ }
51
+ else {
52
+ return null;
53
+ }
54
+ })
55
+ .filter((tool) => tool !== null);
56
+ const structuredOutputTools = options?.tools
57
+ ?.map((tool) => {
58
+ if ("lc_namespace" in tool) {
59
+ return tool;
60
+ }
61
+ else {
62
+ return null;
63
+ }
64
+ })
65
+ .filter((tool) => tool !== null);
66
+ if (structuredOutputTools &&
67
+ structuredOutputTools.length > 0 &&
68
+ geminiTools &&
69
+ geminiTools.length > 0) {
70
+ throw new Error(`Cannot mix structured tools with Gemini tools.\nReceived ${structuredOutputTools.length} structured tools and ${geminiTools.length} Gemini tools.`);
71
+ }
72
+ ret.tools = geminiTools ?? structuredOutputTools;
21
73
  return ret;
22
74
  }
23
75
  export function modelToFamily(modelName) {
@@ -125,20 +125,39 @@ function toolMessageToContent(message) {
125
125
  return acc;
126
126
  }
127
127
  }, "");
128
- const content = JSON.parse(contentStr);
129
- return [
130
- {
131
- role: "function",
132
- parts: [
133
- {
134
- functionResponse: {
135
- name: message.tool_call_id,
136
- response: content,
128
+ try {
129
+ const content = JSON.parse(contentStr);
130
+ return [
131
+ {
132
+ role: "function",
133
+ parts: [
134
+ {
135
+ functionResponse: {
136
+ name: message.tool_call_id,
137
+ response: content,
138
+ },
137
139
  },
138
- },
139
- ],
140
- },
141
- ];
140
+ ],
141
+ },
142
+ ];
143
+ }
144
+ catch (_) {
145
+ return [
146
+ {
147
+ role: "function",
148
+ parts: [
149
+ {
150
+ functionResponse: {
151
+ name: message.tool_call_id,
152
+ response: {
153
+ response: contentStr,
154
+ },
155
+ },
156
+ },
157
+ ],
158
+ },
159
+ ];
160
+ }
142
161
  }
143
162
  function baseMessageToContent(message) {
144
163
  const type = message._getType();
@@ -348,6 +367,18 @@ function chunkToString(chunk) {
348
367
  exports.chunkToString = chunkToString;
349
368
  function partToMessage(part) {
350
369
  const fields = partsToBaseMessageFields([part]);
370
+ if (typeof fields.content === "string") {
371
+ return new messages_1.AIMessageChunk(fields);
372
+ }
373
+ else if (fields.content.every((item) => item.type === "text")) {
374
+ const newContent = fields.content
375
+ .map((item) => ("text" in item ? item.text : ""))
376
+ .join("");
377
+ return new messages_1.AIMessageChunk({
378
+ ...fields,
379
+ content: newContent,
380
+ });
381
+ }
351
382
  return new messages_1.AIMessageChunk(fields);
352
383
  }
353
384
  exports.partToMessage = partToMessage;
@@ -121,20 +121,39 @@ function toolMessageToContent(message) {
121
121
  return acc;
122
122
  }
123
123
  }, "");
124
- const content = JSON.parse(contentStr);
125
- return [
126
- {
127
- role: "function",
128
- parts: [
129
- {
130
- functionResponse: {
131
- name: message.tool_call_id,
132
- response: content,
124
+ try {
125
+ const content = JSON.parse(contentStr);
126
+ return [
127
+ {
128
+ role: "function",
129
+ parts: [
130
+ {
131
+ functionResponse: {
132
+ name: message.tool_call_id,
133
+ response: content,
134
+ },
133
135
  },
134
- },
135
- ],
136
- },
137
- ];
136
+ ],
137
+ },
138
+ ];
139
+ }
140
+ catch (_) {
141
+ return [
142
+ {
143
+ role: "function",
144
+ parts: [
145
+ {
146
+ functionResponse: {
147
+ name: message.tool_call_id,
148
+ response: {
149
+ response: contentStr,
150
+ },
151
+ },
152
+ },
153
+ ],
154
+ },
155
+ ];
156
+ }
138
157
  }
139
158
  export function baseMessageToContent(message) {
140
159
  const type = message._getType();
@@ -330,6 +349,18 @@ export function chunkToString(chunk) {
330
349
  }
331
350
  export function partToMessage(part) {
332
351
  const fields = partsToBaseMessageFields([part]);
352
+ if (typeof fields.content === "string") {
353
+ return new AIMessageChunk(fields);
354
+ }
355
+ else if (fields.content.every((item) => item.type === "text")) {
356
+ const newContent = fields.content
357
+ .map((item) => ("text" in item ? item.text : ""))
358
+ .join("");
359
+ return new AIMessageChunk({
360
+ ...fields,
361
+ content: newContent,
362
+ });
363
+ }
333
364
  return new AIMessageChunk(fields);
334
365
  }
335
366
  export function partToChatGeneration(part) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/google-common",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Core types and classes for Google services.",
5
5
  "type": "module",
6
6
  "engines": {