@langchain/google 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.
Files changed (93) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +97 -0
  4. package/dist/_virtual/rolldown_runtime.cjs +25 -0
  5. package/dist/chat_models/api-types.d.cts +1506 -0
  6. package/dist/chat_models/api-types.d.ts +1506 -0
  7. package/dist/chat_models/base.cjs +445 -0
  8. package/dist/chat_models/base.cjs.map +1 -0
  9. package/dist/chat_models/base.d.cts +319 -0
  10. package/dist/chat_models/base.d.ts +319 -0
  11. package/dist/chat_models/base.js +442 -0
  12. package/dist/chat_models/base.js.map +1 -0
  13. package/dist/chat_models/index.cjs +23 -0
  14. package/dist/chat_models/index.cjs.map +1 -0
  15. package/dist/chat_models/index.d.cts +39 -0
  16. package/dist/chat_models/index.d.ts +39 -0
  17. package/dist/chat_models/index.js +22 -0
  18. package/dist/chat_models/index.js.map +1 -0
  19. package/dist/chat_models/node.cjs +35 -0
  20. package/dist/chat_models/node.cjs.map +1 -0
  21. package/dist/chat_models/node.d.cts +13 -0
  22. package/dist/chat_models/node.d.ts +13 -0
  23. package/dist/chat_models/node.js +34 -0
  24. package/dist/chat_models/node.js.map +1 -0
  25. package/dist/chat_models/profiles.cjs +373 -0
  26. package/dist/chat_models/profiles.cjs.map +1 -0
  27. package/dist/chat_models/profiles.js +372 -0
  28. package/dist/chat_models/profiles.js.map +1 -0
  29. package/dist/chat_models/types.d.cts +250 -0
  30. package/dist/chat_models/types.d.ts +250 -0
  31. package/dist/clients/index.cjs +219 -0
  32. package/dist/clients/index.cjs.map +1 -0
  33. package/dist/clients/index.d.cts +49 -0
  34. package/dist/clients/index.d.ts +49 -0
  35. package/dist/clients/index.js +217 -0
  36. package/dist/clients/index.js.map +1 -0
  37. package/dist/clients/node.cjs +327 -0
  38. package/dist/clients/node.cjs.map +1 -0
  39. package/dist/clients/node.d.cts +59 -0
  40. package/dist/clients/node.d.ts +59 -0
  41. package/dist/clients/node.js +325 -0
  42. package/dist/clients/node.js.map +1 -0
  43. package/dist/const.cjs +13 -0
  44. package/dist/const.cjs.map +1 -0
  45. package/dist/const.js +9 -0
  46. package/dist/const.js.map +1 -0
  47. package/dist/converters/messages.cjs +697 -0
  48. package/dist/converters/messages.cjs.map +1 -0
  49. package/dist/converters/messages.js +691 -0
  50. package/dist/converters/messages.js.map +1 -0
  51. package/dist/converters/params.cjs +205 -0
  52. package/dist/converters/params.cjs.map +1 -0
  53. package/dist/converters/params.js +202 -0
  54. package/dist/converters/params.js.map +1 -0
  55. package/dist/converters/tools.cjs +356 -0
  56. package/dist/converters/tools.cjs.map +1 -0
  57. package/dist/converters/tools.js +353 -0
  58. package/dist/converters/tools.js.map +1 -0
  59. package/dist/index.cjs +7 -0
  60. package/dist/index.d.cts +3 -0
  61. package/dist/index.d.ts +3 -0
  62. package/dist/index.js +4 -0
  63. package/dist/node.cjs +7 -0
  64. package/dist/node.d.cts +3 -0
  65. package/dist/node.d.ts +3 -0
  66. package/dist/node.js +4 -0
  67. package/dist/utils/errors.cjs +543 -0
  68. package/dist/utils/errors.cjs.map +1 -0
  69. package/dist/utils/errors.js +535 -0
  70. package/dist/utils/errors.js.map +1 -0
  71. package/dist/utils/gcp-auth.cjs +188 -0
  72. package/dist/utils/gcp-auth.cjs.map +1 -0
  73. package/dist/utils/gcp-auth.d.cts +43 -0
  74. package/dist/utils/gcp-auth.d.ts +43 -0
  75. package/dist/utils/gcp-auth.js +186 -0
  76. package/dist/utils/gcp-auth.js.map +1 -0
  77. package/dist/utils/handler.cjs +67 -0
  78. package/dist/utils/handler.cjs.map +1 -0
  79. package/dist/utils/handler.d.cts +34 -0
  80. package/dist/utils/handler.d.ts +34 -0
  81. package/dist/utils/handler.js +64 -0
  82. package/dist/utils/handler.js.map +1 -0
  83. package/dist/utils/misc.cjs +10 -0
  84. package/dist/utils/misc.cjs.map +1 -0
  85. package/dist/utils/misc.d.cts +14 -0
  86. package/dist/utils/misc.d.ts +14 -0
  87. package/dist/utils/misc.js +9 -0
  88. package/dist/utils/misc.js.map +1 -0
  89. package/dist/utils/stream.cjs +26 -0
  90. package/dist/utils/stream.cjs.map +1 -0
  91. package/dist/utils/stream.js +25 -0
  92. package/dist/utils/stream.js.map +1 -0
  93. package/package.json +96 -0
@@ -0,0 +1,535 @@
1
+ import { iife } from "./misc.js";
2
+
3
+ //#region src/utils/errors.ts
4
+ function GoogleError(marker) {
5
+ const symbol = Symbol.for(`langchain.google.error.${marker}`);
6
+ return class extends Error {
7
+ [symbol] = true;
8
+ constructor(message) {
9
+ super(message);
10
+ if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
11
+ }
12
+ isInstance(obj) {
13
+ return typeof obj === "object" && obj !== null && symbol in obj && obj[symbol] === true;
14
+ }
15
+ };
16
+ }
17
+ /**
18
+ * Error thrown when there is a configuration issue with the Google provider.
19
+ *
20
+ * This error is thrown when the Google provider encounters invalid configuration
21
+ * parameters or settings that prevent it from functioning correctly.
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * try {
26
+ * const model = new ChatGoogle({ invalidOption: true });
27
+ * } catch (error) {
28
+ * if (ConfigurationError.isInstance(error)) {
29
+ * console.log(`Configuration error: ${error.message}`);
30
+ * }
31
+ * }
32
+ * ```
33
+ */
34
+ var ConfigurationError = class extends GoogleError("configuration") {
35
+ name = "ConfigurationError";
36
+ };
37
+ /**
38
+ * Error thrown when a prompt is blocked by Google's safety filters.
39
+ *
40
+ * This error is thrown when the Gemini API blocks a prompt due to safety concerns.
41
+ * It contains information about why the prompt was blocked and the safety ratings
42
+ * that triggered the block.
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * try {
47
+ * await model.invoke("some potentially unsafe prompt");
48
+ * } catch (error) {
49
+ * if (PromptBlockedError.isInstance(error)) {
50
+ * console.log(`Blocked due to: ${error.blockReason}`);
51
+ * console.log(`Safety ratings:`, error.safetyRatings);
52
+ * }
53
+ * }
54
+ * ```
55
+ */
56
+ var PromptBlockedError = class PromptBlockedError extends GoogleError("prompt-blocked") {
57
+ /**
58
+ * The name of the error class.
59
+ * @readonly
60
+ */
61
+ name = "PromptBlockedError";
62
+ /**
63
+ * The reason why the prompt was blocked.
64
+ *
65
+ * Common values include:
66
+ * - "SAFETY" - Blocked due to safety concerns
67
+ * - "OTHER" - Blocked for other reasons
68
+ * - "UNKNOWN" - Reason is unknown
69
+ *
70
+ * @readonly
71
+ */
72
+ blockReason;
73
+ /**
74
+ * Optional array of safety ratings that contributed to the block decision.
75
+ *
76
+ * Each rating contains information about different safety categories
77
+ * (e.g., hate speech, sexually explicit content, dangerous content)
78
+ * and their probability levels.
79
+ *
80
+ * @readonly
81
+ */
82
+ safetyRatings;
83
+ constructor(params) {
84
+ const message = params.message ?? `Prompt was blocked: ${params.blockReason}.${params.safetyRatings && params.safetyRatings.length > 0 ? ` Safety ratings: ${JSON.stringify(params.safetyRatings)}` : ""}`;
85
+ super(message);
86
+ this.blockReason = params.blockReason;
87
+ this.safetyRatings = params.safetyRatings;
88
+ }
89
+ /**
90
+ * Creates a PromptBlockedError from a Gemini API prompt feedback object.
91
+ *
92
+ * This is a convenience factory method for creating errors from the API response
93
+ * when a prompt is blocked. It extracts the relevant information from the
94
+ * promptFeedback object returned by the Gemini API.
95
+ *
96
+ * @param promptFeedback - The prompt feedback object from the Gemini API response
97
+ * @returns A new PromptBlockedError instance with information from the feedback
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * const response = await geminiApi.generateContent(request);
102
+ * if (response.promptFeedback?.blockReason) {
103
+ * throw PromptBlockedError.fromPromptFeedback(response.promptFeedback);
104
+ * }
105
+ * ```
106
+ */
107
+ static fromPromptFeedback(promptFeedback) {
108
+ return new PromptBlockedError({
109
+ blockReason: promptFeedback.blockReason ?? "UNKNOWN",
110
+ safetyRatings: promptFeedback.safetyRatings
111
+ });
112
+ }
113
+ };
114
+ /**
115
+ * Error class for authentication failures when communicating with Google APIs.
116
+ *
117
+ * This error is thrown when authentication with a Google API fails, typically
118
+ * during the OAuth token exchange process or when using service account credentials.
119
+ * It captures detailed information about the failed authentication attempt including
120
+ * the status code, headers, and response body to aid in debugging and error handling.
121
+ *
122
+ * Common authentication failure scenarios include:
123
+ * - Invalid or expired credentials
124
+ * - Incorrect service account configuration
125
+ * - Missing or invalid API keys
126
+ * - Insufficient permissions or scopes
127
+ * - Token exchange failures
128
+ *
129
+ * @example
130
+ * ```typescript
131
+ * try {
132
+ * const token = await getAccessToken(credentials);
133
+ * } catch (error) {
134
+ * if (AuthError.isInstance(error)) {
135
+ * console.error(`Auth failed with status ${error.statusCode}: ${error.message}`);
136
+ * console.error('Response data:', error.data);
137
+ * }
138
+ * }
139
+ * ```
140
+ */
141
+ var AuthError = class AuthError extends GoogleError("auth") {
142
+ name = "AuthError";
143
+ /**
144
+ * The HTTP status code of the failed response.
145
+ * Common values include 400 (Bad Request), 401 (Unauthorized),
146
+ * 403 (Forbidden), 404 (Not Found), 429 (Too Many Requests),
147
+ * 500 (Internal Server Error), etc.
148
+ */
149
+ statusCode;
150
+ /**
151
+ * The HTTP status text of the failed response.
152
+ * This is the human-readable status message that accompanies the status code
153
+ * (e.g., "Bad Request", "Internal Server Error").
154
+ */
155
+ statusText;
156
+ /**
157
+ * The HTTP response headers from the failed request.
158
+ * Stored as a key-value record for easy access to header information.
159
+ */
160
+ headers;
161
+ /**
162
+ * The response body data from the failed request.
163
+ * This may be a parsed JSON object, a text string, or null if the body
164
+ * could not be read. Often contains additional error details from the API.
165
+ */
166
+ data;
167
+ constructor(params) {
168
+ super(params.message);
169
+ this.statusCode = params.statusCode;
170
+ this.statusText = params.statusText;
171
+ this.headers = params.headers;
172
+ this.data = params.data;
173
+ }
174
+ /**
175
+ * Creates an AuthError from a failed HTTP response.
176
+ *
177
+ * This is a convenience factory method for creating authentication errors from
178
+ * HTTP responses. It automatically extracts the error message, status code,
179
+ * headers, and response body from the Response object.
180
+ *
181
+ * The method attempts to parse the response body as JSON to extract an
182
+ * `error_description` field if available. If JSON parsing fails or the
183
+ * content type is not JSON, it falls back to reading the response as text.
184
+ * If both fail, the error body will be null.
185
+ *
186
+ * @param response - The failed HTTP Response object from the authentication request
187
+ * @returns A Promise that resolves to a new AuthError instance with information from the response
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * const response = await fetch(tokenUrl, {
192
+ * method: 'POST',
193
+ * body: authRequestBody
194
+ * });
195
+ *
196
+ * if (!response.ok) {
197
+ * throw await AuthError.fromResponse(response);
198
+ * }
199
+ * ```
200
+ */
201
+ static async fromResponse(response) {
202
+ const errorBody = await iife(async () => {
203
+ try {
204
+ const contentType = response.headers.get("content-type") ?? "";
205
+ if (contentType.includes("application/json")) return await response.json();
206
+ return await response.text();
207
+ } catch {
208
+ return null;
209
+ }
210
+ });
211
+ const message = errorBody?.error_description ?? `Authentication failed with status code ${response.status}`;
212
+ const headers = iife(() => {
213
+ const object = {};
214
+ response.headers.forEach((value, name) => {
215
+ object[name] = value;
216
+ });
217
+ return object;
218
+ });
219
+ return new AuthError({
220
+ message,
221
+ statusCode: response.status,
222
+ statusText: response.statusText,
223
+ headers,
224
+ data: errorBody
225
+ });
226
+ }
227
+ };
228
+ const RETRYABLE_STATUS_CODES = [
229
+ 408,
230
+ 429,
231
+ 500,
232
+ 502,
233
+ 503,
234
+ 504
235
+ ];
236
+ /**
237
+ * Error class for HTTP request failures when communicating with Google APIs.
238
+ *
239
+ * This error is thrown when an HTTP request to a Google API endpoint fails.
240
+ * It captures detailed information about the failed request including the URL,
241
+ * status code, headers, and response body to aid in debugging and error handling.
242
+ *
243
+ * The error includes a `isRetryable()` method to determine if the request should
244
+ * be retried based on the HTTP status code (e.g., 429 Too Many Requests, 503 Service Unavailable).
245
+ *
246
+ * @example
247
+ * ```typescript
248
+ * try {
249
+ * const response = await apiClient.fetch(request);
250
+ * if (!response.ok) {
251
+ * throw await RequestError.fromResponse(response);
252
+ * }
253
+ * } catch (error) {
254
+ * if (RequestError.isInstance(error) && error.isRetryable()) {
255
+ * // Retry the request
256
+ * }
257
+ * }
258
+ * ```
259
+ */
260
+ var RequestError = class RequestError extends GoogleError("request") {
261
+ name = "RequestError";
262
+ /**
263
+ * The URL of the failed request.
264
+ * This is the full URL that was being accessed when the error occurred.
265
+ */
266
+ url;
267
+ /**
268
+ * The HTTP status code of the failed response.
269
+ * Common values include 400 (Bad Request), 401 (Unauthorized),
270
+ * 403 (Forbidden), 404 (Not Found), 429 (Too Many Requests),
271
+ * 500 (Internal Server Error), etc.
272
+ */
273
+ statusCode;
274
+ /**
275
+ * The HTTP status text of the failed response.
276
+ * This is the human-readable status message that accompanies the status code
277
+ * (e.g., "Bad Request", "Internal Server Error").
278
+ */
279
+ statusText;
280
+ /**
281
+ * The HTTP response headers from the failed request.
282
+ * Stored as a key-value record for easy access to header information.
283
+ */
284
+ headers;
285
+ /**
286
+ * The response body data from the failed request.
287
+ * This may be a parsed JSON object, a text string, or null if the body
288
+ * could not be read. Often contains additional error details from the API.
289
+ */
290
+ data;
291
+ constructor(params) {
292
+ super(params.message);
293
+ this.url = params.url;
294
+ this.statusCode = params.statusCode;
295
+ this.statusText = params.statusText;
296
+ this.headers = params.headers;
297
+ this.data = params.data;
298
+ }
299
+ /**
300
+ * Determines if this error represents a retryable request failure.
301
+ *
302
+ * A request is considered retryable if it failed with a status code that
303
+ * indicates a temporary issue that might succeed on retry. This includes:
304
+ * - 408 (Request Timeout)
305
+ * - 429 (Too Many Requests / Rate Limiting)
306
+ * - 500 (Internal Server Error)
307
+ * - 502 (Bad Gateway)
308
+ * - 503 (Service Unavailable)
309
+ * - 504 (Gateway Timeout)
310
+ *
311
+ * @returns `true` if the request should be retried, `false` otherwise
312
+ *
313
+ * @example
314
+ * ```typescript
315
+ * if (RequestError.isInstance(error) && error.isRetryable()) {
316
+ * await sleep(1000);
317
+ * return retry(request);
318
+ * }
319
+ * ```
320
+ */
321
+ isRetryable() {
322
+ if (!this.statusCode) return false;
323
+ return RETRYABLE_STATUS_CODES.includes(this.statusCode);
324
+ }
325
+ /**
326
+ * Creates a RequestError from a failed HTTP Response object.
327
+ *
328
+ * This is a factory method that extracts all relevant information from a
329
+ * Response object and constructs a RequestError with appropriate details.
330
+ * It attempts to parse the response body as JSON first, falling back to
331
+ * text if that fails, and finally to null if the body cannot be read.
332
+ *
333
+ * The error message is extracted from the response body if available
334
+ * (looking for `message` or `error` fields), otherwise a generic message
335
+ * is constructed using the status code.
336
+ *
337
+ * @param response - The failed HTTP Response object to convert into an error
338
+ * @returns A Promise that resolves to a new RequestError instance
339
+ *
340
+ * @example
341
+ * ```typescript
342
+ * const response = await fetch(url);
343
+ * if (!response.ok) {
344
+ * throw await RequestError.fromResponse(response);
345
+ * }
346
+ * ```
347
+ */
348
+ static async fromResponse(response) {
349
+ const errorBody = await iife(async () => {
350
+ try {
351
+ const contentType = response.headers.get("content-type") ?? "";
352
+ if (contentType.includes("application/json")) return await response.json();
353
+ return await response.text();
354
+ } catch {
355
+ return null;
356
+ }
357
+ });
358
+ const message = errorBody?.error?.message ?? errorBody?.message ?? errorBody?.error ?? `Request failed with status code ${response.status}`;
359
+ const headers = iife(() => {
360
+ const object = {};
361
+ response.headers.forEach((value, name) => {
362
+ object[name] = value;
363
+ });
364
+ return object;
365
+ });
366
+ return new RequestError({
367
+ message,
368
+ url: response.url,
369
+ statusCode: response.status,
370
+ statusText: response.statusText,
371
+ headers,
372
+ data: errorBody
373
+ });
374
+ }
375
+ };
376
+ /**
377
+ * Error thrown when the Gemini API returns no candidates in the response.
378
+ *
379
+ * This error is thrown when the API successfully processes a request but returns
380
+ * an empty candidates array. This can occur when:
381
+ * - The prompt was blocked by safety filters (but no explicit block reason was provided)
382
+ * - An internal error occurred during generation
383
+ * - The model was unable to generate a valid response
384
+ *
385
+ * @example
386
+ * ```typescript
387
+ * try {
388
+ * await model.invoke("some prompt");
389
+ * } catch (error) {
390
+ * if (NoCandidatesError.isInstance(error)) {
391
+ * console.log("No response candidates were generated");
392
+ * }
393
+ * }
394
+ * ```
395
+ */
396
+ var NoCandidatesError = class extends GoogleError("no-candidates") {
397
+ name = "NoCandidatesError";
398
+ constructor() {
399
+ super("No candidates returned from API. This may indicate the prompt was blocked or an error occurred.");
400
+ }
401
+ };
402
+ /**
403
+ * Error thrown when an invalid tool is provided to the tool converter.
404
+ *
405
+ * This error is thrown when a tool cannot be converted to Gemini's function
406
+ * declaration format. Tools must be one of:
407
+ * - LangChain structured tools (with Zod schemas)
408
+ * - OpenAI format tools (with JSON Schema)
409
+ * - Gemini-native function declarations
410
+ * - Gemini-native tools (codeExecution, googleSearchRetrieval)
411
+ *
412
+ * @example
413
+ * ```typescript
414
+ * try {
415
+ * convertToolsToGeminiFunctionDeclarations([invalidTool]);
416
+ * } catch (error) {
417
+ * if (InvalidToolError.isInstance(error)) {
418
+ * console.log(`Invalid tool: ${error.tool}`);
419
+ * console.log(`Expected formats: LangChain tools, OpenAI tools, or Gemini function declarations`);
420
+ * }
421
+ * }
422
+ * ```
423
+ */
424
+ var InvalidToolError = class extends GoogleError("invalid-tool") {
425
+ name = "InvalidToolError";
426
+ /**
427
+ * The invalid tool that was provided.
428
+ */
429
+ tool;
430
+ constructor(tool, message) {
431
+ const defaultMessage = `Received invalid tool: ${JSON.stringify(tool)}. Tools must be LangChain tools, OpenAI tools, or Gemini function declarations.`;
432
+ super(message ?? defaultMessage);
433
+ this.tool = tool;
434
+ }
435
+ };
436
+ /**
437
+ * Error thrown when a ToolMessage references a tool call that cannot be found.
438
+ *
439
+ * This error is thrown when a ToolMessage is passed to ChatGoogle but there is no
440
+ * corresponding AIMessage with a matching toolCallId in the conversation history.
441
+ * This typically indicates that:
442
+ * - The tool call ID in the ToolMessage doesn't match any previous tool calls
443
+ * - The AIMessage containing the tool call was not included in the message history
444
+ * - The tool call ID was incorrectly set or modified
445
+ *
446
+ * @example
447
+ * ```typescript
448
+ * try {
449
+ * await model.invoke([
450
+ * new ToolMessage({ content: "result", tool_call_id: "nonexistent-id" })
451
+ * ]);
452
+ * } catch (error) {
453
+ * if (ToolCallNotFoundError.isInstance(error)) {
454
+ * console.log(`Tool call not found: ${error.toolCallId}`);
455
+ * }
456
+ * }
457
+ * ```
458
+ */
459
+ var ToolCallNotFoundError = class extends GoogleError("tool-call-not-found") {
460
+ name = "ToolCallNotFoundError";
461
+ /**
462
+ * The tool call ID that could not be found in the conversation history.
463
+ */
464
+ toolCallId;
465
+ constructor(toolCallId, message) {
466
+ const defaultMessage = `Tool call with ID "${toolCallId}" not found in conversation history. Ensure the corresponding AIMessage with this tool call ID is included in the input.`;
467
+ super(message ?? defaultMessage);
468
+ this.toolCallId = toolCallId;
469
+ }
470
+ };
471
+ /**
472
+ * Error thrown when output parsing fails in structured output methods.
473
+ *
474
+ * This error is thrown when the model's response cannot be parsed according to
475
+ * the expected schema or format. Common causes include:
476
+ * - Invalid message type (not an AIMessage or AIMessageChunk)
477
+ * - Missing or empty content in the response
478
+ * - Malformed JSON that cannot be parsed
479
+ * - Schema validation failures
480
+ *
481
+ * @example
482
+ * ```typescript
483
+ * try {
484
+ * const result = await model.withStructuredOutput(schema).invoke("extract data");
485
+ * } catch (error) {
486
+ * if (MalformedOutputError.isInstance(error)) {
487
+ * console.log(`Failed to parse output: ${error.message}`);
488
+ * if (error.cause) {
489
+ * console.log(`Cause:`, error.cause);
490
+ * }
491
+ * }
492
+ * }
493
+ * ```
494
+ */
495
+ var MalformedOutputError = class extends GoogleError("malformed-output") {
496
+ name = "MalformedOutputError";
497
+ /**
498
+ * Optional cause of the parsing error.
499
+ * This may be the original error that occurred during parsing,
500
+ * or additional context about what went wrong.
501
+ */
502
+ cause;
503
+ constructor(params) {
504
+ super(params.message);
505
+ this.cause = params.cause;
506
+ }
507
+ };
508
+ /**
509
+ * Error thrown when input provided to the Google provider is invalid.
510
+ *
511
+ * This error is thrown when the user provides input that cannot be
512
+ * processed by Gemini, such as:
513
+ * - Union types in tool/function schemas
514
+ * - Null-only types in schemas
515
+ * - Unsupported content block source types
516
+ * - Missing required fields in content blocks
517
+ *
518
+ * @example
519
+ * ```typescript
520
+ * try {
521
+ * const result = schemaToGeminiParameters(unionTypeSchema);
522
+ * } catch (error) {
523
+ * if (InvalidInputError.isInstance(error)) {
524
+ * console.log(`Invalid input: ${error.message}`);
525
+ * }
526
+ * }
527
+ * ```
528
+ */
529
+ var InvalidInputError = class extends GoogleError("invalid-input") {
530
+ name = "InvalidInputError";
531
+ };
532
+
533
+ //#endregion
534
+ export { AuthError, ConfigurationError, InvalidInputError, InvalidToolError, MalformedOutputError, NoCandidatesError, PromptBlockedError, RequestError, ToolCallNotFoundError };
535
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","names":["marker: TMarker","symbol: symbol","message: string","obj: unknown","params: PromptBlockedErrorParams","promptFeedback: Gemini.PromptFeedback","params: AuthErrorParams","response: Response","object: Record<string, string>","params: RequestErrorParams","tool: unknown","message?: string","toolCallId: string","params: MalformedOutputErrorParams"],"sources":["../../src/utils/errors.ts"],"sourcesContent":["import type { Gemini } from \"../chat_models/types.js\";\nimport { iife } from \"./misc.js\";\n\nfunction GoogleError<TMarker extends string>(marker: TMarker) {\n const symbol: symbol = Symbol.for(`langchain.google.error.${marker}`);\n\n return class extends Error {\n readonly [symbol] = true as const;\n\n constructor(message: string) {\n super(message);\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n isInstance(obj: unknown): obj is this {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n symbol in obj &&\n obj[symbol as keyof typeof obj] === true\n );\n }\n };\n}\n\n/**\n * Error thrown when there is a configuration issue with the Google provider.\n *\n * This error is thrown when the Google provider encounters invalid configuration\n * parameters or settings that prevent it from functioning correctly.\n *\n * @example\n * ```typescript\n * try {\n * const model = new ChatGoogle({ invalidOption: true });\n * } catch (error) {\n * if (ConfigurationError.isInstance(error)) {\n * console.log(`Configuration error: ${error.message}`);\n * }\n * }\n * ```\n */\nexport class ConfigurationError extends GoogleError(\"configuration\") {\n readonly name = \"ConfigurationError\" as const;\n}\n\n/**\n * Parameters for constructing a PromptBlockedError\n */\ntype PromptBlockedErrorParams = {\n /**\n * The reason why the prompt was blocked (e.g., \"SAFETY\", \"OTHER\", \"UNKNOWN\")\n */\n blockReason: string;\n /**\n * Optional array of safety ratings that contributed to the block decision\n */\n safetyRatings?: Gemini.SafetyRating[];\n /**\n * Optional custom error message. If not provided, a default message will be generated\n */\n message?: string;\n};\n\n/**\n * Error thrown when a prompt is blocked by Google's safety filters.\n *\n * This error is thrown when the Gemini API blocks a prompt due to safety concerns.\n * It contains information about why the prompt was blocked and the safety ratings\n * that triggered the block.\n *\n * @example\n * ```typescript\n * try {\n * await model.invoke(\"some potentially unsafe prompt\");\n * } catch (error) {\n * if (PromptBlockedError.isInstance(error)) {\n * console.log(`Blocked due to: ${error.blockReason}`);\n * console.log(`Safety ratings:`, error.safetyRatings);\n * }\n * }\n * ```\n */\nexport class PromptBlockedError extends GoogleError(\"prompt-blocked\") {\n /**\n * The name of the error class.\n * @readonly\n */\n readonly name = \"PromptBlockedError\" as const;\n\n /**\n * The reason why the prompt was blocked.\n *\n * Common values include:\n * - \"SAFETY\" - Blocked due to safety concerns\n * - \"OTHER\" - Blocked for other reasons\n * - \"UNKNOWN\" - Reason is unknown\n *\n * @readonly\n */\n readonly blockReason: string;\n\n /**\n * Optional array of safety ratings that contributed to the block decision.\n *\n * Each rating contains information about different safety categories\n * (e.g., hate speech, sexually explicit content, dangerous content)\n * and their probability levels.\n *\n * @readonly\n */\n readonly safetyRatings?: Gemini.SafetyRating[];\n\n constructor(params: PromptBlockedErrorParams) {\n const message =\n params.message ??\n `Prompt was blocked: ${params.blockReason}.${\n params.safetyRatings && params.safetyRatings.length > 0\n ? ` Safety ratings: ${JSON.stringify(params.safetyRatings)}`\n : \"\"\n }`;\n\n super(message);\n this.blockReason = params.blockReason;\n this.safetyRatings = params.safetyRatings;\n }\n\n /**\n * Creates a PromptBlockedError from a Gemini API prompt feedback object.\n *\n * This is a convenience factory method for creating errors from the API response\n * when a prompt is blocked. It extracts the relevant information from the\n * promptFeedback object returned by the Gemini API.\n *\n * @param promptFeedback - The prompt feedback object from the Gemini API response\n * @returns A new PromptBlockedError instance with information from the feedback\n *\n * @example\n * ```typescript\n * const response = await geminiApi.generateContent(request);\n * if (response.promptFeedback?.blockReason) {\n * throw PromptBlockedError.fromPromptFeedback(response.promptFeedback);\n * }\n * ```\n */\n static fromPromptFeedback(\n promptFeedback: Gemini.PromptFeedback\n ): PromptBlockedError {\n return new PromptBlockedError({\n blockReason: promptFeedback.blockReason ?? \"UNKNOWN\",\n safetyRatings: promptFeedback.safetyRatings,\n });\n }\n}\n\n/**\n * Parameters for constructing an AuthError\n */\ntype AuthErrorParams = {\n /**\n * The error message describing what went wrong\n */\n message: string;\n\n /**\n * The HTTP status code of the failed response.\n * Common values include 400 (Bad Request), 401 (Unauthorized),\n * 403 (Forbidden), 404 (Not Found), 429 (Too Many Requests),\n * 500 (Internal Server Error), etc.\n */\n statusCode?: number;\n\n /**\n * The HTTP status text of the failed response.\n * This is the human-readable status message that accompanies the status code\n * (e.g., \"Bad Request\", \"Internal Server Error\").\n */\n statusText?: string;\n\n /**\n * The HTTP response headers from the failed request.\n * Stored as a key-value record for easy access to header information.\n */\n headers?: Record<string, string>;\n\n /**\n * The response body data from the failed request.\n * This may be a parsed JSON object, a text string, or null if the body\n * could not be read. Often contains additional error details from the API.\n */\n data?: unknown;\n};\n\n/**\n * Error class for authentication failures when communicating with Google APIs.\n *\n * This error is thrown when authentication with a Google API fails, typically\n * during the OAuth token exchange process or when using service account credentials.\n * It captures detailed information about the failed authentication attempt including\n * the status code, headers, and response body to aid in debugging and error handling.\n *\n * Common authentication failure scenarios include:\n * - Invalid or expired credentials\n * - Incorrect service account configuration\n * - Missing or invalid API keys\n * - Insufficient permissions or scopes\n * - Token exchange failures\n *\n * @example\n * ```typescript\n * try {\n * const token = await getAccessToken(credentials);\n * } catch (error) {\n * if (AuthError.isInstance(error)) {\n * console.error(`Auth failed with status ${error.statusCode}: ${error.message}`);\n * console.error('Response data:', error.data);\n * }\n * }\n * ```\n */\nexport class AuthError extends GoogleError(\"auth\") {\n readonly name = \"AuthError\" as const;\n\n /**\n * The HTTP status code of the failed response.\n * Common values include 400 (Bad Request), 401 (Unauthorized),\n * 403 (Forbidden), 404 (Not Found), 429 (Too Many Requests),\n * 500 (Internal Server Error), etc.\n */\n readonly statusCode?: number;\n\n /**\n * The HTTP status text of the failed response.\n * This is the human-readable status message that accompanies the status code\n * (e.g., \"Bad Request\", \"Internal Server Error\").\n */\n readonly statusText?: string;\n\n /**\n * The HTTP response headers from the failed request.\n * Stored as a key-value record for easy access to header information.\n */\n readonly headers?: Record<string, string>;\n\n /**\n * The response body data from the failed request.\n * This may be a parsed JSON object, a text string, or null if the body\n * could not be read. Often contains additional error details from the API.\n */\n readonly data?: unknown;\n\n constructor(params: AuthErrorParams) {\n super(params.message);\n\n this.statusCode = params.statusCode;\n this.statusText = params.statusText;\n this.headers = params.headers;\n this.data = params.data;\n }\n\n /**\n * Creates an AuthError from a failed HTTP response.\n *\n * This is a convenience factory method for creating authentication errors from\n * HTTP responses. It automatically extracts the error message, status code,\n * headers, and response body from the Response object.\n *\n * The method attempts to parse the response body as JSON to extract an\n * `error_description` field if available. If JSON parsing fails or the\n * content type is not JSON, it falls back to reading the response as text.\n * If both fail, the error body will be null.\n *\n * @param response - The failed HTTP Response object from the authentication request\n * @returns A Promise that resolves to a new AuthError instance with information from the response\n *\n * @example\n * ```typescript\n * const response = await fetch(tokenUrl, {\n * method: 'POST',\n * body: authRequestBody\n * });\n *\n * if (!response.ok) {\n * throw await AuthError.fromResponse(response);\n * }\n * ```\n */\n static async fromResponse(response: Response): Promise<AuthError> {\n const errorBody = await iife(async () => {\n try {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n return await response.json();\n }\n return await response.text();\n } catch {\n return null;\n }\n });\n\n const message =\n errorBody?.error_description ??\n `Authentication failed with status code ${response.status}`;\n\n const headers = iife(() => {\n const object: Record<string, string> = {};\n response.headers.forEach((value, name) => {\n object[name] = value;\n });\n return object;\n });\n\n return new AuthError({\n message,\n statusCode: response.status,\n statusText: response.statusText,\n headers,\n data: errorBody,\n });\n }\n}\n\nconst RETRYABLE_STATUS_CODES = [\n 408, // Request Timeout\n 429, // Too Many Requests\n 500, // Internal Server Error\n 502, // Bad Gateway\n 503, // Service Unavailable\n 504, // Gateway Timeout\n];\n\n/**\n * Parameters for constructing a RequestError\n */\ntype RequestErrorParams = {\n /**\n * The error message describing what went wrong\n */\n message: string;\n\n /**\n * The URL of the failed request.\n * This is the full URL that was being accessed when the error occurred.\n */\n url: string;\n\n /**\n * The HTTP status code of the failed response.\n * Common values include 400 (Bad Request), 401 (Unauthorized),\n * 403 (Forbidden), 404 (Not Found), 429 (Too Many Requests),\n * 500 (Internal Server Error), etc.\n */\n statusCode?: number;\n\n /**\n * The HTTP status text of the failed response.\n * This is the human-readable status message that accompanies the status code\n * (e.g., \"Bad Request\", \"Internal Server Error\").\n */\n statusText?: string;\n\n /**\n * The HTTP response headers from the failed request.\n * Stored as a key-value record for easy access to header information.\n */\n headers?: Record<string, string>;\n\n /**\n * The response body data from the failed request.\n * This may be a parsed JSON object, a text string, or null if the body\n * could not be read. Often contains additional error details from the API.\n */\n data?: unknown;\n};\n\n/**\n * Error class for HTTP request failures when communicating with Google APIs.\n *\n * This error is thrown when an HTTP request to a Google API endpoint fails.\n * It captures detailed information about the failed request including the URL,\n * status code, headers, and response body to aid in debugging and error handling.\n *\n * The error includes a `isRetryable()` method to determine if the request should\n * be retried based on the HTTP status code (e.g., 429 Too Many Requests, 503 Service Unavailable).\n *\n * @example\n * ```typescript\n * try {\n * const response = await apiClient.fetch(request);\n * if (!response.ok) {\n * throw await RequestError.fromResponse(response);\n * }\n * } catch (error) {\n * if (RequestError.isInstance(error) && error.isRetryable()) {\n * // Retry the request\n * }\n * }\n * ```\n */\nexport class RequestError extends GoogleError(\"request\") {\n readonly name = \"RequestError\" as const;\n\n /**\n * The URL of the failed request.\n * This is the full URL that was being accessed when the error occurred.\n */\n readonly url: string;\n\n /**\n * The HTTP status code of the failed response.\n * Common values include 400 (Bad Request), 401 (Unauthorized),\n * 403 (Forbidden), 404 (Not Found), 429 (Too Many Requests),\n * 500 (Internal Server Error), etc.\n */\n readonly statusCode?: number;\n\n /**\n * The HTTP status text of the failed response.\n * This is the human-readable status message that accompanies the status code\n * (e.g., \"Bad Request\", \"Internal Server Error\").\n */\n readonly statusText?: string;\n\n /**\n * The HTTP response headers from the failed request.\n * Stored as a key-value record for easy access to header information.\n */\n readonly headers?: Record<string, string>;\n\n /**\n * The response body data from the failed request.\n * This may be a parsed JSON object, a text string, or null if the body\n * could not be read. Often contains additional error details from the API.\n */\n readonly data?: unknown;\n\n constructor(params: RequestErrorParams) {\n super(params.message);\n\n this.url = params.url;\n this.statusCode = params.statusCode;\n this.statusText = params.statusText;\n this.headers = params.headers;\n this.data = params.data;\n }\n\n /**\n * Determines if this error represents a retryable request failure.\n *\n * A request is considered retryable if it failed with a status code that\n * indicates a temporary issue that might succeed on retry. This includes:\n * - 408 (Request Timeout)\n * - 429 (Too Many Requests / Rate Limiting)\n * - 500 (Internal Server Error)\n * - 502 (Bad Gateway)\n * - 503 (Service Unavailable)\n * - 504 (Gateway Timeout)\n *\n * @returns `true` if the request should be retried, `false` otherwise\n *\n * @example\n * ```typescript\n * if (RequestError.isInstance(error) && error.isRetryable()) {\n * await sleep(1000);\n * return retry(request);\n * }\n * ```\n */\n isRetryable(): boolean {\n if (!this.statusCode) return false;\n return RETRYABLE_STATUS_CODES.includes(this.statusCode);\n }\n\n /**\n * Creates a RequestError from a failed HTTP Response object.\n *\n * This is a factory method that extracts all relevant information from a\n * Response object and constructs a RequestError with appropriate details.\n * It attempts to parse the response body as JSON first, falling back to\n * text if that fails, and finally to null if the body cannot be read.\n *\n * The error message is extracted from the response body if available\n * (looking for `message` or `error` fields), otherwise a generic message\n * is constructed using the status code.\n *\n * @param response - The failed HTTP Response object to convert into an error\n * @returns A Promise that resolves to a new RequestError instance\n *\n * @example\n * ```typescript\n * const response = await fetch(url);\n * if (!response.ok) {\n * throw await RequestError.fromResponse(response);\n * }\n * ```\n */\n static async fromResponse(response: Response): Promise<RequestError> {\n const errorBody = await iife(async () => {\n try {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n return await response.json();\n }\n return await response.text();\n } catch {\n return null;\n }\n });\n\n const message =\n errorBody?.error?.message ??\n errorBody?.message ??\n errorBody?.error ??\n `Request failed with status code ${response.status}`;\n\n const headers = iife(() => {\n const object: Record<string, string> = {};\n response.headers.forEach((value, name) => {\n object[name] = value;\n });\n return object;\n });\n\n return new RequestError({\n message,\n url: response.url,\n statusCode: response.status,\n statusText: response.statusText,\n headers,\n data: errorBody,\n });\n }\n}\n\n/**\n * Error thrown when the Gemini API returns no candidates in the response.\n *\n * This error is thrown when the API successfully processes a request but returns\n * an empty candidates array. This can occur when:\n * - The prompt was blocked by safety filters (but no explicit block reason was provided)\n * - An internal error occurred during generation\n * - The model was unable to generate a valid response\n *\n * @example\n * ```typescript\n * try {\n * await model.invoke(\"some prompt\");\n * } catch (error) {\n * if (NoCandidatesError.isInstance(error)) {\n * console.log(\"No response candidates were generated\");\n * }\n * }\n * ```\n */\nexport class NoCandidatesError extends GoogleError(\"no-candidates\") {\n readonly name = \"NoCandidatesError\" as const;\n\n constructor() {\n super(\n \"No candidates returned from API. This may indicate the prompt was blocked or an error occurred.\"\n );\n }\n}\n\n/**\n * Error thrown when an invalid tool is provided to the tool converter.\n *\n * This error is thrown when a tool cannot be converted to Gemini's function\n * declaration format. Tools must be one of:\n * - LangChain structured tools (with Zod schemas)\n * - OpenAI format tools (with JSON Schema)\n * - Gemini-native function declarations\n * - Gemini-native tools (codeExecution, googleSearchRetrieval)\n *\n * @example\n * ```typescript\n * try {\n * convertToolsToGeminiFunctionDeclarations([invalidTool]);\n * } catch (error) {\n * if (InvalidToolError.isInstance(error)) {\n * console.log(`Invalid tool: ${error.tool}`);\n * console.log(`Expected formats: LangChain tools, OpenAI tools, or Gemini function declarations`);\n * }\n * }\n * ```\n */\nexport class InvalidToolError extends GoogleError(\"invalid-tool\") {\n readonly name = \"InvalidToolError\" as const;\n\n /**\n * The invalid tool that was provided.\n */\n readonly tool: unknown;\n\n constructor(tool: unknown, message?: string) {\n const defaultMessage = `Received invalid tool: ${JSON.stringify(\n tool\n )}. Tools must be LangChain tools, OpenAI tools, or Gemini function declarations.`;\n\n super(message ?? defaultMessage);\n this.tool = tool;\n }\n}\n\n/**\n * Error thrown when a ToolMessage references a tool call that cannot be found.\n *\n * This error is thrown when a ToolMessage is passed to ChatGoogle but there is no\n * corresponding AIMessage with a matching toolCallId in the conversation history.\n * This typically indicates that:\n * - The tool call ID in the ToolMessage doesn't match any previous tool calls\n * - The AIMessage containing the tool call was not included in the message history\n * - The tool call ID was incorrectly set or modified\n *\n * @example\n * ```typescript\n * try {\n * await model.invoke([\n * new ToolMessage({ content: \"result\", tool_call_id: \"nonexistent-id\" })\n * ]);\n * } catch (error) {\n * if (ToolCallNotFoundError.isInstance(error)) {\n * console.log(`Tool call not found: ${error.toolCallId}`);\n * }\n * }\n * ```\n */\nexport class ToolCallNotFoundError extends GoogleError(\"tool-call-not-found\") {\n readonly name = \"ToolCallNotFoundError\" as const;\n\n /**\n * The tool call ID that could not be found in the conversation history.\n */\n readonly toolCallId: string;\n\n constructor(toolCallId: string, message?: string) {\n const defaultMessage = `Tool call with ID \"${toolCallId}\" not found in conversation history. Ensure the corresponding AIMessage with this tool call ID is included in the input.`;\n\n super(message ?? defaultMessage);\n this.toolCallId = toolCallId;\n }\n}\n\n/**\n * Parameters for constructing a MalformedOutputError\n */\ntype MalformedOutputErrorParams = {\n /**\n * The error message describing what went wrong during parsing\n */\n message: string;\n /**\n * Optional cause of the parsing error (e.g., the original error that occurred)\n */\n cause?: unknown;\n};\n\n/**\n * Error thrown when output parsing fails in structured output methods.\n *\n * This error is thrown when the model's response cannot be parsed according to\n * the expected schema or format. Common causes include:\n * - Invalid message type (not an AIMessage or AIMessageChunk)\n * - Missing or empty content in the response\n * - Malformed JSON that cannot be parsed\n * - Schema validation failures\n *\n * @example\n * ```typescript\n * try {\n * const result = await model.withStructuredOutput(schema).invoke(\"extract data\");\n * } catch (error) {\n * if (MalformedOutputError.isInstance(error)) {\n * console.log(`Failed to parse output: ${error.message}`);\n * if (error.cause) {\n * console.log(`Cause:`, error.cause);\n * }\n * }\n * }\n * ```\n */\nexport class MalformedOutputError extends GoogleError(\"malformed-output\") {\n readonly name = \"MalformedOutputError\" as const;\n\n /**\n * Optional cause of the parsing error.\n * This may be the original error that occurred during parsing,\n * or additional context about what went wrong.\n */\n readonly cause?: unknown;\n\n constructor(params: MalformedOutputErrorParams) {\n super(params.message);\n this.cause = params.cause;\n }\n}\n\n/**\n * Error thrown when input provided to the Google provider is invalid.\n *\n * This error is thrown when the user provides input that cannot be\n * processed by Gemini, such as:\n * - Union types in tool/function schemas\n * - Null-only types in schemas\n * - Unsupported content block source types\n * - Missing required fields in content blocks\n *\n * @example\n * ```typescript\n * try {\n * const result = schemaToGeminiParameters(unionTypeSchema);\n * } catch (error) {\n * if (InvalidInputError.isInstance(error)) {\n * console.log(`Invalid input: ${error.message}`);\n * }\n * }\n * ```\n */\nexport class InvalidInputError extends GoogleError(\"invalid-input\") {\n readonly name = \"InvalidInputError\" as const;\n}\n"],"mappings":"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"}