@langchain/google-genai 0.2.8 → 0.2.9

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.
@@ -79,31 +79,13 @@ function inferToolNameFromPreviousMessages(message, previousMessages) {
79
79
  })?.name;
80
80
  }
81
81
  function convertMessageContentToParts(message, isMultimodalModel, previousMessages) {
82
- if (typeof message.content === "string" &&
83
- message.content !== "" &&
84
- !(0, messages_1.isToolMessage)(message)) {
85
- return [{ text: message.content }];
86
- }
87
- let functionCalls = [];
88
- let functionResponses = [];
89
- let messageParts = [];
90
- if ("tool_calls" in message &&
91
- Array.isArray(message.tool_calls) &&
92
- message.tool_calls.length > 0) {
93
- functionCalls = message.tool_calls.map((tc) => ({
94
- functionCall: {
95
- name: tc.name,
96
- args: tc.args,
97
- },
98
- }));
99
- }
100
- else if ((0, messages_1.isToolMessage)(message) && message.content) {
82
+ if ((0, messages_1.isToolMessage)(message)) {
101
83
  const messageName = message.name ??
102
84
  inferToolNameFromPreviousMessages(message, previousMessages);
103
85
  if (messageName === undefined) {
104
86
  throw new Error(`Google requires a tool name for each tool call response, and we could not infer a called tool name for ToolMessage "${message.id}" from your passed messages. Please populate a "name" field on that ToolMessage explicitly.`);
105
87
  }
106
- functionResponses = [
88
+ return [
107
89
  {
108
90
  functionResponse: {
109
91
  name: messageName,
@@ -114,24 +96,23 @@ function convertMessageContentToParts(message, isMultimodalModel, previousMessag
114
96
  },
115
97
  ];
116
98
  }
117
- else if (Array.isArray(message.content)) {
118
- messageParts = message.content.map((c) => {
99
+ let functionCalls = [];
100
+ const messageParts = [];
101
+ if (typeof message.content === "string" && message.content) {
102
+ messageParts.push({ text: message.content });
103
+ }
104
+ if (Array.isArray(message.content)) {
105
+ message.content.forEach((c) => {
119
106
  if (c.type === "text") {
120
- return {
121
- text: c.text,
122
- };
107
+ messageParts.push({ text: c.text });
123
108
  }
124
109
  else if (c.type === "executableCode") {
125
- return {
126
- executableCode: c.executableCode,
127
- };
110
+ messageParts.push({ executableCode: c.executableCode });
128
111
  }
129
112
  else if (c.type === "codeExecutionResult") {
130
- return {
131
- codeExecutionResult: c.codeExecutionResult,
132
- };
113
+ messageParts.push({ codeExecutionResult: c.codeExecutionResult });
133
114
  }
134
- if (c.type === "image_url") {
115
+ else if (c.type === "image_url") {
135
116
  if (!isMultimodalModel) {
136
117
  throw new Error(`This model does not support images`);
137
118
  }
@@ -153,40 +134,60 @@ function convertMessageContentToParts(message, isMultimodalModel, previousMessag
153
134
  if (encoding !== "base64") {
154
135
  throw new Error("Please provide image as base64 encoded data URL");
155
136
  }
156
- return {
137
+ messageParts.push({
157
138
  inlineData: {
158
139
  data,
159
140
  mimeType,
160
141
  },
161
- };
142
+ });
162
143
  }
163
144
  else if (c.type === "media") {
164
- return messageContentMedia(c);
145
+ messageParts.push(messageContentMedia(c));
165
146
  }
166
147
  else if (c.type === "tool_use") {
167
- return {
148
+ functionCalls.push({
168
149
  functionCall: {
169
150
  name: c.name,
170
151
  args: c.input,
171
152
  },
172
- };
153
+ });
173
154
  }
174
155
  else if (c.type?.includes("/") &&
175
156
  // Ensure it's a single slash.
176
157
  c.type.split("/").length === 2 &&
177
158
  "data" in c &&
178
159
  typeof c.data === "string") {
179
- return {
160
+ messageParts.push({
180
161
  inlineData: {
181
162
  mimeType: c.type,
182
163
  data: c.data,
183
164
  },
184
- };
165
+ });
166
+ }
167
+ else if ("functionCall" in c) {
168
+ // No action needed here — function calls will be added later from message.tool_calls
169
+ }
170
+ else {
171
+ if ("type" in c) {
172
+ throw new Error(`Unknown content type ${c.type}`);
173
+ }
174
+ else {
175
+ throw new Error(`Unknown content ${JSON.stringify(c)}`);
176
+ }
185
177
  }
186
- throw new Error(`Unknown content type ${c.type}`);
187
178
  });
188
179
  }
189
- return [...messageParts, ...functionCalls, ...functionResponses];
180
+ if ((0, messages_1.isAIMessage)(message) && message.tool_calls?.length) {
181
+ functionCalls = message.tool_calls.map((tc) => {
182
+ return {
183
+ functionCall: {
184
+ name: tc.name,
185
+ args: tc.args,
186
+ },
187
+ };
188
+ });
189
+ }
190
+ return [...messageParts, ...functionCalls];
190
191
  }
191
192
  exports.convertMessageContentToParts = convertMessageContentToParts;
192
193
  function convertBaseMessagesToContent(messages, isMultimodalModel, convertSystemMessageToHumanContent = false) {
@@ -74,31 +74,13 @@ function inferToolNameFromPreviousMessages(message, previousMessages) {
74
74
  })?.name;
75
75
  }
76
76
  export function convertMessageContentToParts(message, isMultimodalModel, previousMessages) {
77
- if (typeof message.content === "string" &&
78
- message.content !== "" &&
79
- !isToolMessage(message)) {
80
- return [{ text: message.content }];
81
- }
82
- let functionCalls = [];
83
- let functionResponses = [];
84
- let messageParts = [];
85
- if ("tool_calls" in message &&
86
- Array.isArray(message.tool_calls) &&
87
- message.tool_calls.length > 0) {
88
- functionCalls = message.tool_calls.map((tc) => ({
89
- functionCall: {
90
- name: tc.name,
91
- args: tc.args,
92
- },
93
- }));
94
- }
95
- else if (isToolMessage(message) && message.content) {
77
+ if (isToolMessage(message)) {
96
78
  const messageName = message.name ??
97
79
  inferToolNameFromPreviousMessages(message, previousMessages);
98
80
  if (messageName === undefined) {
99
81
  throw new Error(`Google requires a tool name for each tool call response, and we could not infer a called tool name for ToolMessage "${message.id}" from your passed messages. Please populate a "name" field on that ToolMessage explicitly.`);
100
82
  }
101
- functionResponses = [
83
+ return [
102
84
  {
103
85
  functionResponse: {
104
86
  name: messageName,
@@ -109,24 +91,23 @@ export function convertMessageContentToParts(message, isMultimodalModel, previou
109
91
  },
110
92
  ];
111
93
  }
112
- else if (Array.isArray(message.content)) {
113
- messageParts = message.content.map((c) => {
94
+ let functionCalls = [];
95
+ const messageParts = [];
96
+ if (typeof message.content === "string" && message.content) {
97
+ messageParts.push({ text: message.content });
98
+ }
99
+ if (Array.isArray(message.content)) {
100
+ message.content.forEach((c) => {
114
101
  if (c.type === "text") {
115
- return {
116
- text: c.text,
117
- };
102
+ messageParts.push({ text: c.text });
118
103
  }
119
104
  else if (c.type === "executableCode") {
120
- return {
121
- executableCode: c.executableCode,
122
- };
105
+ messageParts.push({ executableCode: c.executableCode });
123
106
  }
124
107
  else if (c.type === "codeExecutionResult") {
125
- return {
126
- codeExecutionResult: c.codeExecutionResult,
127
- };
108
+ messageParts.push({ codeExecutionResult: c.codeExecutionResult });
128
109
  }
129
- if (c.type === "image_url") {
110
+ else if (c.type === "image_url") {
130
111
  if (!isMultimodalModel) {
131
112
  throw new Error(`This model does not support images`);
132
113
  }
@@ -148,40 +129,60 @@ export function convertMessageContentToParts(message, isMultimodalModel, previou
148
129
  if (encoding !== "base64") {
149
130
  throw new Error("Please provide image as base64 encoded data URL");
150
131
  }
151
- return {
132
+ messageParts.push({
152
133
  inlineData: {
153
134
  data,
154
135
  mimeType,
155
136
  },
156
- };
137
+ });
157
138
  }
158
139
  else if (c.type === "media") {
159
- return messageContentMedia(c);
140
+ messageParts.push(messageContentMedia(c));
160
141
  }
161
142
  else if (c.type === "tool_use") {
162
- return {
143
+ functionCalls.push({
163
144
  functionCall: {
164
145
  name: c.name,
165
146
  args: c.input,
166
147
  },
167
- };
148
+ });
168
149
  }
169
150
  else if (c.type?.includes("/") &&
170
151
  // Ensure it's a single slash.
171
152
  c.type.split("/").length === 2 &&
172
153
  "data" in c &&
173
154
  typeof c.data === "string") {
174
- return {
155
+ messageParts.push({
175
156
  inlineData: {
176
157
  mimeType: c.type,
177
158
  data: c.data,
178
159
  },
179
- };
160
+ });
161
+ }
162
+ else if ("functionCall" in c) {
163
+ // No action needed here — function calls will be added later from message.tool_calls
164
+ }
165
+ else {
166
+ if ("type" in c) {
167
+ throw new Error(`Unknown content type ${c.type}`);
168
+ }
169
+ else {
170
+ throw new Error(`Unknown content ${JSON.stringify(c)}`);
171
+ }
180
172
  }
181
- throw new Error(`Unknown content type ${c.type}`);
182
173
  });
183
174
  }
184
- return [...messageParts, ...functionCalls, ...functionResponses];
175
+ if (isAIMessage(message) && message.tool_calls?.length) {
176
+ functionCalls = message.tool_calls.map((tc) => {
177
+ return {
178
+ functionCall: {
179
+ name: tc.name,
180
+ args: tc.args,
181
+ },
182
+ };
183
+ });
184
+ }
185
+ return [...messageParts, ...functionCalls];
185
186
  }
186
187
  export function convertBaseMessagesToContent(messages, isMultimodalModel, convertSystemMessageToHumanContent = false) {
187
188
  return messages.reduce((acc, message, index) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/google-genai",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "Google Generative AI integration for LangChain.js",
5
5
  "type": "module",
6
6
  "engines": {