@jaypie/llm 1.2.36 → 1.2.38

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 (36) hide show
  1. package/README.md +9 -0
  2. package/dist/cjs/constants.d.ts +49 -9
  3. package/dist/cjs/index.cjs +834 -82
  4. package/dist/cjs/index.cjs.map +1 -1
  5. package/dist/cjs/index.d.ts +4 -1
  6. package/dist/cjs/operate/adapters/BedrockAdapter.d.ts +78 -0
  7. package/dist/cjs/operate/adapters/{GeminiAdapter.d.ts → GoogleAdapter.d.ts} +4 -4
  8. package/dist/cjs/operate/adapters/index.d.ts +2 -1
  9. package/dist/cjs/operate/index.d.ts +1 -1
  10. package/dist/cjs/providers/bedrock/BedrockProvider.class.d.ts +21 -0
  11. package/dist/cjs/providers/bedrock/index.d.ts +1 -0
  12. package/dist/cjs/providers/bedrock/utils.d.ts +6 -0
  13. package/dist/cjs/providers/{gemini/GeminiProvider.class.d.ts → google/GoogleProvider.class.d.ts} +1 -1
  14. package/dist/cjs/providers/google/index.d.ts +3 -0
  15. package/dist/cjs/types/LlmProvider.interface.d.ts +1 -1
  16. package/dist/esm/constants.d.ts +49 -9
  17. package/dist/esm/index.d.ts +4 -1
  18. package/dist/esm/index.js +832 -82
  19. package/dist/esm/index.js.map +1 -1
  20. package/dist/esm/operate/adapters/BedrockAdapter.d.ts +78 -0
  21. package/dist/esm/operate/adapters/{GeminiAdapter.d.ts → GoogleAdapter.d.ts} +4 -4
  22. package/dist/esm/operate/adapters/index.d.ts +2 -1
  23. package/dist/esm/operate/index.d.ts +1 -1
  24. package/dist/esm/providers/bedrock/BedrockProvider.class.d.ts +21 -0
  25. package/dist/esm/providers/bedrock/index.d.ts +1 -0
  26. package/dist/esm/providers/bedrock/utils.d.ts +6 -0
  27. package/dist/esm/providers/{gemini/GeminiProvider.class.d.ts → google/GoogleProvider.class.d.ts} +1 -1
  28. package/dist/esm/providers/google/index.d.ts +3 -0
  29. package/dist/esm/types/LlmProvider.interface.d.ts +1 -1
  30. package/package.json +7 -1
  31. package/dist/cjs/providers/gemini/index.d.ts +0 -3
  32. package/dist/esm/providers/gemini/index.d.ts +0 -3
  33. /package/dist/cjs/providers/{gemini → google}/types.d.ts +0 -0
  34. /package/dist/cjs/providers/{gemini → google}/utils.d.ts +0 -0
  35. /package/dist/esm/providers/{gemini → google}/types.d.ts +0 -0
  36. /package/dist/esm/providers/{gemini → google}/utils.d.ts +0 -0
package/dist/esm/index.js CHANGED
@@ -15,16 +15,16 @@ const FIRST_CLASS_PROVIDER = {
15
15
  // https://docs.anthropic.com/en/docs/about-claude/models/overview
16
16
  ANTHROPIC: {
17
17
  DEFAULT: "claude-sonnet-4-6",
18
- LARGE: "claude-opus-4-7",
18
+ LARGE: "claude-opus-4-8",
19
19
  SMALL: "claude-sonnet-4-6",
20
20
  TINY: "claude-haiku-4-5",
21
21
  },
22
22
  // https://ai.google.dev/gemini-api/docs/models
23
- GEMINI: {
23
+ GOOGLE: {
24
24
  DEFAULT: "gemini-3.1-pro-preview",
25
25
  LARGE: "gemini-3.1-pro-preview",
26
- SMALL: "gemini-3.1-flash-lite-preview",
27
- TINY: "gemini-3.1-flash-lite-preview",
26
+ SMALL: "gemini-3.5-flash",
27
+ TINY: "gemini-3.1-flash-lite",
28
28
  },
29
29
  // https://developers.openai.com/api/docs/models
30
30
  OPENAI: {
@@ -41,7 +41,60 @@ const FIRST_CLASS_PROVIDER = {
41
41
  TINY: "grok-4-1-fast-non-reasoning",
42
42
  },
43
43
  };
44
+ const MODEL = {
45
+ // Anthropic
46
+ OPUS: "claude-opus-4-8",
47
+ SONNET: "claude-sonnet-4-6",
48
+ HAIKU: "claude-haiku-4-5",
49
+ FABLE: "claude-fable-5",
50
+ MYTHOS: "claude-mythos-5",
51
+ // Google
52
+ GEMINI_FLASH: "gemini-3.5-flash",
53
+ GEMINI_FLASH_LITE: "gemini-3.1-flash-lite",
54
+ GEMINI_PRO: "gemini-3.1-pro-preview",
55
+ // OpenAI
56
+ GPT: "gpt-5.5",
57
+ GPT_MINI: "gpt-5.5-mini",
58
+ GPT_NANO: "gpt-5.5-nano",
59
+ // xAI
60
+ GROK: "grok-latest",
61
+ };
62
+ const GOOGLE_PROVIDER = {
63
+ // https://ai.google.dev/gemini-api/docs/models
64
+ MODEL: {
65
+ DEFAULT: FIRST_CLASS_PROVIDER.GOOGLE.DEFAULT,
66
+ LARGE: FIRST_CLASS_PROVIDER.GOOGLE.LARGE,
67
+ SMALL: FIRST_CLASS_PROVIDER.GOOGLE.SMALL,
68
+ TINY: FIRST_CLASS_PROVIDER.GOOGLE.TINY,
69
+ },
70
+ MODEL_MATCH_WORDS: ["gemini", "google"],
71
+ NAME: "google",
72
+ ROLE: {
73
+ MODEL: "model",
74
+ USER: "user",
75
+ },
76
+ };
44
77
  const PROVIDER = {
78
+ // https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html
79
+ BEDROCK: {
80
+ MODEL: {
81
+ DEFAULT: "amazon.nova-lite-v1:0",
82
+ LARGE: "amazon.nova-pro-v1:0",
83
+ SMALL: "amazon.nova-lite-v1:0",
84
+ TINY: "amazon.nova-micro-v1:0",
85
+ },
86
+ MODEL_MATCH_WORDS: [
87
+ "amazon.nova",
88
+ "amazon.titan",
89
+ "anthropic.claude",
90
+ "cohere.command",
91
+ "meta.llama",
92
+ "mistral.mistral",
93
+ "ai21.",
94
+ ],
95
+ NAME: "bedrock",
96
+ REGION: "AWS_REGION",
97
+ },
45
98
  ANTHROPIC: {
46
99
  // https://docs.anthropic.com/en/docs/about-claude/models/overview
47
100
  MAX_TOKENS: {
@@ -74,21 +127,9 @@ const PROVIDER = {
74
127
  SCHEMA_VERSION: "v2",
75
128
  },
76
129
  },
77
- GEMINI: {
78
- // https://ai.google.dev/gemini-api/docs/models
79
- MODEL: {
80
- DEFAULT: FIRST_CLASS_PROVIDER.GEMINI.DEFAULT,
81
- LARGE: FIRST_CLASS_PROVIDER.GEMINI.LARGE,
82
- SMALL: FIRST_CLASS_PROVIDER.GEMINI.SMALL,
83
- TINY: FIRST_CLASS_PROVIDER.GEMINI.TINY,
84
- },
85
- MODEL_MATCH_WORDS: ["gemini", "google"],
86
- NAME: "google",
87
- ROLE: {
88
- MODEL: "model",
89
- USER: "user",
90
- },
91
- },
130
+ /** @deprecated Use PROVIDER.GOOGLE — "Google" is the provider; Gemini is the model family */
131
+ GEMINI: GOOGLE_PROVIDER,
132
+ GOOGLE: GOOGLE_PROVIDER,
92
133
  OPENAI: {
93
134
  // https://platform.openai.com/docs/models
94
135
  MODEL: {
@@ -144,7 +185,7 @@ const DEFAULT = {
144
185
  const ALL = {
145
186
  BASE: [
146
187
  PROVIDER.ANTHROPIC.MODEL.DEFAULT,
147
- PROVIDER.GEMINI.MODEL.DEFAULT,
188
+ PROVIDER.GOOGLE.MODEL.DEFAULT,
148
189
  PROVIDER.OPENAI.MODEL.DEFAULT,
149
190
  PROVIDER.XAI.MODEL.DEFAULT,
150
191
  ],
@@ -154,10 +195,10 @@ const ALL = {
154
195
  PROVIDER.ANTHROPIC.MODEL.LARGE,
155
196
  PROVIDER.ANTHROPIC.MODEL.SMALL,
156
197
  PROVIDER.ANTHROPIC.MODEL.TINY,
157
- PROVIDER.GEMINI.MODEL.DEFAULT,
158
- PROVIDER.GEMINI.MODEL.LARGE,
159
- PROVIDER.GEMINI.MODEL.SMALL,
160
- PROVIDER.GEMINI.MODEL.TINY,
198
+ PROVIDER.GOOGLE.MODEL.DEFAULT,
199
+ PROVIDER.GOOGLE.MODEL.LARGE,
200
+ PROVIDER.GOOGLE.MODEL.SMALL,
201
+ PROVIDER.GOOGLE.MODEL.TINY,
161
202
  PROVIDER.OPENAI.MODEL.DEFAULT,
162
203
  PROVIDER.OPENAI.MODEL.LARGE,
163
204
  PROVIDER.OPENAI.MODEL.SMALL,
@@ -170,19 +211,19 @@ const ALL = {
170
211
  ],
171
212
  LARGE: [
172
213
  PROVIDER.ANTHROPIC.MODEL.LARGE,
173
- PROVIDER.GEMINI.MODEL.LARGE,
214
+ PROVIDER.GOOGLE.MODEL.LARGE,
174
215
  PROVIDER.OPENAI.MODEL.LARGE,
175
216
  PROVIDER.XAI.MODEL.LARGE,
176
217
  ],
177
218
  SMALL: [
178
219
  PROVIDER.ANTHROPIC.MODEL.SMALL,
179
- PROVIDER.GEMINI.MODEL.SMALL,
220
+ PROVIDER.GOOGLE.MODEL.SMALL,
180
221
  PROVIDER.OPENAI.MODEL.SMALL,
181
222
  PROVIDER.XAI.MODEL.SMALL,
182
223
  ],
183
224
  TINY: [
184
225
  PROVIDER.ANTHROPIC.MODEL.TINY,
185
- PROVIDER.GEMINI.MODEL.TINY,
226
+ PROVIDER.GOOGLE.MODEL.TINY,
186
227
  PROVIDER.OPENAI.MODEL.TINY,
187
228
  PROVIDER.XAI.MODEL.TINY,
188
229
  ],
@@ -192,6 +233,7 @@ var constants = /*#__PURE__*/Object.freeze({
192
233
  __proto__: null,
193
234
  ALL: ALL,
194
235
  DEFAULT: DEFAULT,
236
+ MODEL: MODEL,
195
237
  PROVIDER: PROVIDER
196
238
  });
197
239
 
@@ -210,17 +252,31 @@ function determineModelProvider(input) {
210
252
  provider: PROVIDER.OPENROUTER.NAME,
211
253
  };
212
254
  }
255
+ // Check for explicit bedrock: prefix
256
+ if (input.startsWith("bedrock:")) {
257
+ const model = input.slice("bedrock:".length);
258
+ return {
259
+ model,
260
+ provider: PROVIDER.BEDROCK.NAME,
261
+ };
262
+ }
213
263
  // Check if input is a provider name
264
+ if (input === PROVIDER.BEDROCK.NAME) {
265
+ return {
266
+ model: PROVIDER.BEDROCK.MODEL.DEFAULT,
267
+ provider: PROVIDER.BEDROCK.NAME,
268
+ };
269
+ }
214
270
  if (input === PROVIDER.ANTHROPIC.NAME) {
215
271
  return {
216
272
  model: PROVIDER.ANTHROPIC.MODEL.DEFAULT,
217
273
  provider: PROVIDER.ANTHROPIC.NAME,
218
274
  };
219
275
  }
220
- if (input === PROVIDER.GEMINI.NAME || input === "gemini") {
276
+ if (input === PROVIDER.GOOGLE.NAME || input === "gemini") {
221
277
  return {
222
- model: PROVIDER.GEMINI.MODEL.DEFAULT,
223
- provider: PROVIDER.GEMINI.NAME,
278
+ model: PROVIDER.GOOGLE.MODEL.DEFAULT,
279
+ provider: PROVIDER.GOOGLE.NAME,
224
280
  };
225
281
  }
226
282
  if (input === PROVIDER.OPENAI.NAME) {
@@ -251,11 +307,11 @@ function determineModelProvider(input) {
251
307
  }
252
308
  }
253
309
  // Check if input matches a Gemini model exactly
254
- for (const [, modelValue] of Object.entries(PROVIDER.GEMINI.MODEL)) {
310
+ for (const [, modelValue] of Object.entries(PROVIDER.GOOGLE.MODEL)) {
255
311
  if (input === modelValue) {
256
312
  return {
257
313
  model: input,
258
- provider: PROVIDER.GEMINI.NAME,
314
+ provider: PROVIDER.GOOGLE.NAME,
259
315
  };
260
316
  }
261
317
  }
@@ -294,8 +350,17 @@ function determineModelProvider(input) {
294
350
  provider: PROVIDER.OPENROUTER.NAME,
295
351
  };
296
352
  }
297
- // Check Anthropic match words
353
+ // Check Bedrock match words (before Anthropic — "anthropic.claude-*" is a Bedrock model ID)
298
354
  const lowerInput = input.toLowerCase();
355
+ for (const matchWord of PROVIDER.BEDROCK.MODEL_MATCH_WORDS) {
356
+ if (lowerInput.includes(matchWord)) {
357
+ return {
358
+ model: input,
359
+ provider: PROVIDER.BEDROCK.NAME,
360
+ };
361
+ }
362
+ }
363
+ // Check Anthropic match words
299
364
  for (const matchWord of PROVIDER.ANTHROPIC.MODEL_MATCH_WORDS) {
300
365
  if (lowerInput.includes(matchWord)) {
301
366
  return {
@@ -305,11 +370,11 @@ function determineModelProvider(input) {
305
370
  }
306
371
  }
307
372
  // Check Gemini match words
308
- for (const matchWord of PROVIDER.GEMINI.MODEL_MATCH_WORDS) {
373
+ for (const matchWord of PROVIDER.GOOGLE.MODEL_MATCH_WORDS) {
309
374
  if (lowerInput.includes(matchWord)) {
310
375
  return {
311
376
  model: input,
312
- provider: PROVIDER.GEMINI.NAME,
377
+ provider: PROVIDER.GOOGLE.NAME,
313
378
  };
314
379
  }
315
380
  }
@@ -594,7 +659,7 @@ function jsonSchemaToOpenApi3(schema) {
594
659
  return result;
595
660
  }
596
661
 
597
- const getLogger$5 = () => log$1.lib({ lib: JAYPIE.LIB.LLM });
662
+ const getLogger$6 = () => log$1.lib({ lib: JAYPIE.LIB.LLM });
598
663
 
599
664
  // Turn policy constants
600
665
  const MAX_TURNS_ABSOLUTE_LIMIT = 72;
@@ -981,13 +1046,13 @@ function isTransientNetworkError(error) {
981
1046
  //
982
1047
  // Constants
983
1048
  //
984
- const STRUCTURED_OUTPUT_TOOL_NAME$2 = "structured_output";
1049
+ const STRUCTURED_OUTPUT_TOOL_NAME$3 = "structured_output";
985
1050
  const STRUCTURED_OUTPUT_NON_PARSE_STOP_REASONS = new Set([
986
1051
  "refusal",
987
1052
  "max_tokens",
988
1053
  ]);
989
1054
  // Regular expression to parse data URLs: data:mime/type;base64,data
990
- const DATA_URL_REGEX = /^data:([^;]+);base64,(.+)$/;
1055
+ const DATA_URL_REGEX$1 = /^data:([^;]+);base64,(.+)$/;
991
1056
  // String formats accepted by Anthropic's structured-output grammar compiler.
992
1057
  // Other formats are stripped (move to description) so the API does not 400.
993
1058
  const SUPPORTED_STRING_FORMATS = new Set([
@@ -1120,7 +1185,7 @@ function isJsonSchema(value) {
1120
1185
  * Parse a data URL into its components
1121
1186
  */
1122
1187
  function parseDataUrl(dataUrl) {
1123
- const match = dataUrl.match(DATA_URL_REGEX);
1188
+ const match = dataUrl.match(DATA_URL_REGEX$1);
1124
1189
  if (!match)
1125
1190
  return null;
1126
1191
  return { mediaType: match[1], data: match[2] };
@@ -1201,7 +1266,7 @@ const MODELS_WITHOUT_TEMPERATURE$2 = [
1201
1266
  /^claude-opus-4-[789]/,
1202
1267
  /^claude-opus-[5-9]/,
1203
1268
  ];
1204
- function isTemperatureDeprecationError$2(error) {
1269
+ function isTemperatureDeprecationError$3(error) {
1205
1270
  if (!error || typeof error !== "object")
1206
1271
  return false;
1207
1272
  const err = error;
@@ -1351,7 +1416,7 @@ class AnthropicAdapter extends BaseProviderAdapter {
1351
1416
  if (useFallbackStructuredOutput && request.format) {
1352
1417
  log$2.warn(`[AnthropicAdapter] Using legacy structured_output tool fallback for model ${anthropicRequest.model}; native output_config previously rejected for this model.`);
1353
1418
  allTools.push({
1354
- name: STRUCTURED_OUTPUT_TOOL_NAME$2,
1419
+ name: STRUCTURED_OUTPUT_TOOL_NAME$3,
1355
1420
  description: "Output a structured JSON object, " +
1356
1421
  "use this before your final response to give structured outputs to the user",
1357
1422
  parameters: request.format,
@@ -1449,7 +1514,7 @@ class AnthropicAdapter extends BaseProviderAdapter {
1449
1514
  return undefined;
1450
1515
  // If the model rejected `temperature`, cache it and retry without the param
1451
1516
  if (anthropicRequest.temperature !== undefined &&
1452
- isTemperatureDeprecationError$2(error)) {
1517
+ isTemperatureDeprecationError$3(error)) {
1453
1518
  this.rememberModelRejectsTemperature(anthropicRequest.model);
1454
1519
  const retryRequest = { ...anthropicRequest };
1455
1520
  delete retryRequest.temperature;
@@ -1482,7 +1547,7 @@ class AnthropicAdapter extends BaseProviderAdapter {
1482
1547
  return request;
1483
1548
  const fallbackRequest = { ...rest };
1484
1549
  const fakeTool = {
1485
- name: STRUCTURED_OUTPUT_TOOL_NAME$2,
1550
+ name: STRUCTURED_OUTPUT_TOOL_NAME$3,
1486
1551
  description: "Output a structured JSON object, " +
1487
1552
  "use this before your final response to give structured outputs to the user",
1488
1553
  input_schema: {
@@ -1510,7 +1575,7 @@ class AnthropicAdapter extends BaseProviderAdapter {
1510
1575
  }
1511
1576
  catch (error) {
1512
1577
  if (streamRequest.temperature !== undefined &&
1513
- isTemperatureDeprecationError$2(error)) {
1578
+ isTemperatureDeprecationError$3(error)) {
1514
1579
  this.rememberModelRejectsTemperature(streamRequest.model);
1515
1580
  streamRequest = {
1516
1581
  ...streamRequest,
@@ -1768,7 +1833,7 @@ class AnthropicAdapter extends BaseProviderAdapter {
1768
1833
  // runtime has cached as not supporting `output_format`.
1769
1834
  const lastBlock = anthropicResponse.content[anthropicResponse.content.length - 1];
1770
1835
  return (lastBlock?.type === "tool_use" &&
1771
- lastBlock.name === STRUCTURED_OUTPUT_TOOL_NAME$2);
1836
+ lastBlock.name === STRUCTURED_OUTPUT_TOOL_NAME$3);
1772
1837
  }
1773
1838
  extractStructuredOutput(response) {
1774
1839
  const anthropicResponse = response;
@@ -1794,7 +1859,7 @@ class AnthropicAdapter extends BaseProviderAdapter {
1794
1859
  // Fallback path: legacy fake-tool emulation
1795
1860
  const lastBlock = anthropicResponse.content[anthropicResponse.content.length - 1];
1796
1861
  if (lastBlock?.type === "tool_use" &&
1797
- lastBlock.name === STRUCTURED_OUTPUT_TOOL_NAME$2) {
1862
+ lastBlock.name === STRUCTURED_OUTPUT_TOOL_NAME$3) {
1798
1863
  return lastBlock.input;
1799
1864
  }
1800
1865
  return undefined;
@@ -1815,6 +1880,608 @@ class AnthropicAdapter extends BaseProviderAdapter {
1815
1880
  // Export singleton instance
1816
1881
  const anthropicAdapter = new AnthropicAdapter();
1817
1882
 
1883
+ //
1884
+ //
1885
+ // Helpers
1886
+ //
1887
+ // Regular expression to parse data URLs
1888
+ const DATA_URL_REGEX = /^data:([^;]+);base64,(.+)$/;
1889
+ const MIME_TO_DOCUMENT_FORMAT = {
1890
+ "application/pdf": "pdf",
1891
+ "text/csv": "csv",
1892
+ "application/msword": "doc",
1893
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
1894
+ "application/vnd.ms-excel": "xls",
1895
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
1896
+ "text/html": "html",
1897
+ "text/plain": "txt",
1898
+ "text/markdown": "md",
1899
+ };
1900
+ function convertContentToBedrock(content) {
1901
+ if (typeof content === "string") {
1902
+ return [{ text: content }];
1903
+ }
1904
+ return content.map((item) => {
1905
+ if (item.type === LlmMessageType.InputText) {
1906
+ return { text: item.text };
1907
+ }
1908
+ if (item.type === LlmMessageType.InputImage) {
1909
+ const imageUrl = item.image_url || "";
1910
+ const match = imageUrl.match(DATA_URL_REGEX);
1911
+ if (match) {
1912
+ const format = match[1].split("/")[1] || "jpeg";
1913
+ const bytes = Buffer.from(match[2], "base64");
1914
+ return {
1915
+ image: {
1916
+ format,
1917
+ source: { bytes: new Uint8Array(bytes) },
1918
+ },
1919
+ };
1920
+ }
1921
+ return { text: `[Image: ${imageUrl}]` };
1922
+ }
1923
+ if (item.type === LlmMessageType.InputFile) {
1924
+ const fileData = typeof item.file_data === "string" ? item.file_data : "";
1925
+ const match = fileData.match(DATA_URL_REGEX);
1926
+ if (match) {
1927
+ const mimeType = match[1];
1928
+ const documentFormat = MIME_TO_DOCUMENT_FORMAT[mimeType];
1929
+ if (documentFormat) {
1930
+ const bytes = Buffer.from(match[2], "base64");
1931
+ const rawName = item.filename || "document";
1932
+ const name = rawName.replace(/[^a-zA-Z0-9 \-()[\]]/g, "_");
1933
+ return {
1934
+ document: {
1935
+ format: documentFormat,
1936
+ name,
1937
+ source: { bytes: new Uint8Array(bytes) },
1938
+ },
1939
+ };
1940
+ }
1941
+ }
1942
+ return { text: `[File: ${item.filename || "unknown"}]` };
1943
+ }
1944
+ return { text: JSON.stringify(item) };
1945
+ });
1946
+ }
1947
+ //
1948
+ //
1949
+ // Constants / helpers
1950
+ //
1951
+ const STRUCTURED_OUTPUT_TOOL_NAME$2 = "structured_output";
1952
+ function isOutputConfigUnsupportedError(error) {
1953
+ const msg = error?.message ?? "";
1954
+ return /outputConfig|output_config/i.test(msg);
1955
+ }
1956
+ function isTemperatureDeprecationError$2(error) {
1957
+ const msg = error?.message ?? "";
1958
+ return /temperature.*deprecated|deprecated.*temperature/i.test(msg);
1959
+ }
1960
+ function extractJson(text) {
1961
+ // Try direct parse first
1962
+ try {
1963
+ const parsed = JSON.parse(text);
1964
+ if (typeof parsed === "object" && parsed !== null)
1965
+ return parsed;
1966
+ }
1967
+ catch {
1968
+ // fall through
1969
+ }
1970
+ // Try stripping markdown code fences
1971
+ const fenceMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
1972
+ if (fenceMatch) {
1973
+ try {
1974
+ const parsed = JSON.parse(fenceMatch[1].trim());
1975
+ if (typeof parsed === "object" && parsed !== null)
1976
+ return parsed;
1977
+ }
1978
+ catch {
1979
+ // fall through
1980
+ }
1981
+ }
1982
+ return undefined;
1983
+ }
1984
+ //
1985
+ //
1986
+ // Main
1987
+ //
1988
+ class BedrockAdapter extends BaseProviderAdapter {
1989
+ constructor() {
1990
+ super(...arguments);
1991
+ this.name = PROVIDER.BEDROCK.NAME;
1992
+ this.defaultModel = PROVIDER.BEDROCK.MODEL.DEFAULT;
1993
+ this._modelsFallbackToStructuredOutputTool = new Set();
1994
+ this._modelsWithoutTemperature = new Set();
1995
+ }
1996
+ rememberModelRejectsOutputConfig(model) {
1997
+ this._modelsFallbackToStructuredOutputTool.add(model);
1998
+ }
1999
+ useFakeToolForStructuredOutput(model) {
2000
+ return this._modelsFallbackToStructuredOutputTool.has(model);
2001
+ }
2002
+ rememberModelRejectsTemperature(model) {
2003
+ this._modelsWithoutTemperature.add(model);
2004
+ }
2005
+ supportsTemperature(model) {
2006
+ return !this._modelsWithoutTemperature.has(model);
2007
+ }
2008
+ //
2009
+ // Request Building
2010
+ //
2011
+ buildRequest(request) {
2012
+ const messages = [];
2013
+ for (const msg of request.messages) {
2014
+ const typedMsg = msg;
2015
+ if (typedMsg.role === "system")
2016
+ continue;
2017
+ if (typedMsg.type === LlmMessageType.FunctionCall) {
2018
+ let parsedInput;
2019
+ try {
2020
+ parsedInput = JSON.parse(typedMsg.arguments || "{}");
2021
+ }
2022
+ catch {
2023
+ parsedInput = {};
2024
+ }
2025
+ messages.push({
2026
+ role: "assistant",
2027
+ content: [
2028
+ {
2029
+ toolUse: {
2030
+ toolUseId: typedMsg.call_id || "",
2031
+ name: typedMsg.name || "",
2032
+ input: parsedInput,
2033
+ },
2034
+ },
2035
+ ],
2036
+ });
2037
+ continue;
2038
+ }
2039
+ if (typedMsg.type === LlmMessageType.FunctionCallOutput) {
2040
+ messages.push({
2041
+ role: "user",
2042
+ content: [
2043
+ {
2044
+ toolResult: {
2045
+ toolUseId: typedMsg.call_id || "",
2046
+ content: [{ text: typedMsg.output || "" }],
2047
+ },
2048
+ },
2049
+ ],
2050
+ });
2051
+ continue;
2052
+ }
2053
+ if (typedMsg.role && typedMsg.content !== undefined) {
2054
+ messages.push({
2055
+ role: typedMsg.role,
2056
+ content: convertContentToBedrock(typedMsg.content),
2057
+ });
2058
+ }
2059
+ }
2060
+ const model = request.model || this.defaultModel;
2061
+ const bedrockRequest = {
2062
+ modelId: model,
2063
+ messages,
2064
+ inferenceConfig: {
2065
+ maxTokens: 4096,
2066
+ },
2067
+ };
2068
+ if (request.system) {
2069
+ bedrockRequest.system = [{ text: request.system }];
2070
+ }
2071
+ if (request.temperature !== undefined &&
2072
+ this.supportsTemperature(model)) {
2073
+ bedrockRequest.inferenceConfig = {
2074
+ ...bedrockRequest.inferenceConfig,
2075
+ temperature: request.temperature,
2076
+ };
2077
+ }
2078
+ if (request.tools && request.tools.length > 0) {
2079
+ bedrockRequest.toolConfig = {
2080
+ tools: request.tools.map((tool) => ({
2081
+ toolSpec: {
2082
+ name: tool.name,
2083
+ description: tool.description,
2084
+ inputSchema: {
2085
+ json: tool.parameters,
2086
+ },
2087
+ },
2088
+ })),
2089
+ };
2090
+ }
2091
+ if (request.instructions && messages.length > 0) {
2092
+ const lastMsg = messages[messages.length - 1];
2093
+ if (lastMsg.content.length > 0) {
2094
+ const firstBlock = lastMsg.content[0];
2095
+ if ("text" in firstBlock) {
2096
+ firstBlock.text = firstBlock.text + "\n\n" + request.instructions;
2097
+ }
2098
+ }
2099
+ }
2100
+ if (request.format) {
2101
+ if (this.useFakeToolForStructuredOutput(model)) {
2102
+ const fakeTool = {
2103
+ toolSpec: {
2104
+ name: STRUCTURED_OUTPUT_TOOL_NAME$2,
2105
+ description: "REQUIRED: You MUST call this tool to provide your final response. " +
2106
+ "After gathering all necessary information (including results from other tools), " +
2107
+ "call this tool with the structured data to complete the request.",
2108
+ inputSchema: { json: request.format },
2109
+ },
2110
+ };
2111
+ bedrockRequest.toolConfig = {
2112
+ tools: [
2113
+ ...(bedrockRequest.toolConfig?.tools ?? []),
2114
+ fakeTool,
2115
+ ],
2116
+ };
2117
+ }
2118
+ else {
2119
+ bedrockRequest.outputConfig = {
2120
+ textFormat: {
2121
+ type: "json_schema",
2122
+ structure: {
2123
+ jsonSchema: {
2124
+ schema: JSON.stringify(request.format),
2125
+ name: "structured_output",
2126
+ },
2127
+ },
2128
+ },
2129
+ };
2130
+ }
2131
+ }
2132
+ if (request.providerOptions) {
2133
+ Object.assign(bedrockRequest, request.providerOptions);
2134
+ }
2135
+ return bedrockRequest;
2136
+ }
2137
+ formatTools(toolkit) {
2138
+ return toolkit.tools.map((tool) => ({
2139
+ name: tool.name,
2140
+ description: tool.description,
2141
+ parameters: {
2142
+ ...tool.parameters,
2143
+ type: "object",
2144
+ },
2145
+ }));
2146
+ }
2147
+ formatOutputSchema(schema) {
2148
+ const zodSchema = schema instanceof z.ZodType
2149
+ ? schema
2150
+ : naturalZodSchema(schema);
2151
+ return z.toJSONSchema(zodSchema);
2152
+ }
2153
+ //
2154
+ // API Execution
2155
+ //
2156
+ async executeRequest(client, request, signal) {
2157
+ const bedrockClient = client;
2158
+ const bedrockRequest = request;
2159
+ const { ConverseCommand } = await import('@aws-sdk/client-bedrock-runtime');
2160
+ const wantsStructuredOutput = Boolean(bedrockRequest.outputConfig);
2161
+ try {
2162
+ const response = (await bedrockClient.send(new ConverseCommand(bedrockRequest), signal ? { abortSignal: signal } : undefined));
2163
+ if (wantsStructuredOutput)
2164
+ response.__jaypieStructuredOutput = true;
2165
+ return response;
2166
+ }
2167
+ catch (error) {
2168
+ if (bedrockRequest.inferenceConfig?.temperature !== undefined &&
2169
+ isTemperatureDeprecationError$2(error)) {
2170
+ this.rememberModelRejectsTemperature(bedrockRequest.modelId || this.defaultModel);
2171
+ const retryRequest = {
2172
+ ...bedrockRequest,
2173
+ inferenceConfig: { ...bedrockRequest.inferenceConfig },
2174
+ };
2175
+ delete retryRequest.inferenceConfig.temperature;
2176
+ const response = (await bedrockClient.send(new ConverseCommand(retryRequest), signal ? { abortSignal: signal } : undefined));
2177
+ if (wantsStructuredOutput)
2178
+ response.__jaypieStructuredOutput = true;
2179
+ return response;
2180
+ }
2181
+ if (wantsStructuredOutput && isOutputConfigUnsupportedError(error)) {
2182
+ const model = bedrockRequest.modelId || this.defaultModel;
2183
+ this.rememberModelRejectsOutputConfig(model);
2184
+ const fallbackRequest = this.toFallbackStructuredOutputRequest(bedrockRequest);
2185
+ return (await bedrockClient.send(new ConverseCommand(fallbackRequest), signal ? { abortSignal: signal } : undefined));
2186
+ }
2187
+ throw error;
2188
+ }
2189
+ }
2190
+ toFallbackStructuredOutputRequest(request) {
2191
+ const { outputConfig, ...rest } = request;
2192
+ if (!outputConfig?.textFormat?.structure)
2193
+ return request;
2194
+ let schema;
2195
+ try {
2196
+ schema = JSON.parse(outputConfig.textFormat.structure.jsonSchema?.schema ?? "{}");
2197
+ }
2198
+ catch {
2199
+ schema = {};
2200
+ }
2201
+ const fakeTool = {
2202
+ toolSpec: {
2203
+ name: STRUCTURED_OUTPUT_TOOL_NAME$2,
2204
+ description: "REQUIRED: You MUST call this tool to provide your final response. " +
2205
+ "After gathering all necessary information (including results from other tools), " +
2206
+ "call this tool with the structured data to complete the request.",
2207
+ inputSchema: { json: schema },
2208
+ },
2209
+ };
2210
+ return {
2211
+ ...rest,
2212
+ toolConfig: {
2213
+ tools: [
2214
+ ...(rest.toolConfig?.tools ?? []),
2215
+ fakeTool,
2216
+ ],
2217
+ },
2218
+ };
2219
+ }
2220
+ async *executeStreamRequest(client, request, signal) {
2221
+ const bedrockClient = client;
2222
+ const bedrockRequest = request;
2223
+ const { ConverseStreamCommand } = await import('@aws-sdk/client-bedrock-runtime');
2224
+ const response = await bedrockClient.send(new ConverseStreamCommand(bedrockRequest), signal ? { abortSignal: signal } : undefined);
2225
+ if (!response.stream)
2226
+ return;
2227
+ let currentToolCall = null;
2228
+ let inputTokens = 0;
2229
+ let outputTokens = 0;
2230
+ const model = bedrockRequest.modelId || this.defaultModel;
2231
+ for await (const event of response.stream) {
2232
+ if (event.contentBlockStart?.start?.toolUse) {
2233
+ const toolUse = event.contentBlockStart.start.toolUse;
2234
+ currentToolCall = {
2235
+ toolUseId: toolUse.toolUseId || "",
2236
+ name: toolUse.name || "",
2237
+ arguments: "",
2238
+ };
2239
+ }
2240
+ else if (event.contentBlockDelta?.delta) {
2241
+ const delta = event.contentBlockDelta.delta;
2242
+ if (delta.text !== undefined) {
2243
+ yield { type: LlmStreamChunkType.Text, content: delta.text };
2244
+ }
2245
+ else if (delta.toolUse?.input && currentToolCall) {
2246
+ currentToolCall.arguments += delta.toolUse.input;
2247
+ }
2248
+ }
2249
+ else if (event.contentBlockStop && currentToolCall) {
2250
+ yield {
2251
+ type: LlmStreamChunkType.ToolCall,
2252
+ toolCall: {
2253
+ id: currentToolCall.toolUseId,
2254
+ name: currentToolCall.name,
2255
+ arguments: currentToolCall.arguments,
2256
+ },
2257
+ };
2258
+ currentToolCall = null;
2259
+ }
2260
+ else if (event.metadata?.usage) {
2261
+ inputTokens = event.metadata.usage.inputTokens ?? 0;
2262
+ outputTokens = event.metadata.usage.outputTokens ?? 0;
2263
+ }
2264
+ else if (event.messageStop) {
2265
+ yield {
2266
+ type: LlmStreamChunkType.Done,
2267
+ usage: [
2268
+ {
2269
+ input: inputTokens,
2270
+ output: outputTokens,
2271
+ reasoning: 0,
2272
+ total: inputTokens + outputTokens,
2273
+ provider: this.name,
2274
+ model,
2275
+ },
2276
+ ],
2277
+ };
2278
+ }
2279
+ }
2280
+ }
2281
+ //
2282
+ // Response Parsing
2283
+ //
2284
+ parseResponse(response, options) {
2285
+ const bedrockResponse = response;
2286
+ const message = bedrockResponse.output?.message;
2287
+ const rawContent = this.extractContentFromMessage(message);
2288
+ let content = rawContent;
2289
+ if (options?.format && typeof rawContent === "string") {
2290
+ content = extractJson(rawContent) ?? rawContent;
2291
+ }
2292
+ // Don't surface structured_output fake tool as a real tool call
2293
+ const allToolUses = (bedrockResponse.output?.message?.content ?? []).filter((b) => "toolUse" in b);
2294
+ const hasOnlyStructuredOutputTool = allToolUses.length > 0 &&
2295
+ allToolUses.every((b) => b.toolUse.name === STRUCTURED_OUTPUT_TOOL_NAME$2);
2296
+ const hasToolCalls = bedrockResponse.stopReason === "tool_use" && !hasOnlyStructuredOutputTool;
2297
+ return {
2298
+ content,
2299
+ hasToolCalls,
2300
+ stopReason: bedrockResponse.stopReason ?? undefined,
2301
+ usage: this.extractUsage(bedrockResponse, bedrockResponse.modelId ||
2302
+ this.defaultModel),
2303
+ raw: bedrockResponse,
2304
+ };
2305
+ }
2306
+ extractToolCalls(response) {
2307
+ const bedrockResponse = response;
2308
+ const content = bedrockResponse.output?.message?.content ?? [];
2309
+ const toolCalls = [];
2310
+ for (const block of content) {
2311
+ const typedBlock = block;
2312
+ if ("toolUse" in typedBlock && typedBlock.toolUse) {
2313
+ const toolUse = typedBlock.toolUse;
2314
+ toolCalls.push({
2315
+ callId: toolUse.toolUseId,
2316
+ name: toolUse.name,
2317
+ arguments: JSON.stringify(toolUse.input),
2318
+ raw: typedBlock,
2319
+ });
2320
+ }
2321
+ }
2322
+ return toolCalls;
2323
+ }
2324
+ extractUsage(response, model) {
2325
+ const bedrockResponse = response;
2326
+ const usage = bedrockResponse.usage;
2327
+ return {
2328
+ input: usage?.inputTokens ?? 0,
2329
+ output: usage?.outputTokens ?? 0,
2330
+ reasoning: 0,
2331
+ total: usage?.totalTokens ??
2332
+ (usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0),
2333
+ provider: this.name,
2334
+ model,
2335
+ };
2336
+ }
2337
+ //
2338
+ // Tool Result Handling
2339
+ //
2340
+ formatToolResult(toolCall, result) {
2341
+ return {
2342
+ toolResult: {
2343
+ toolUseId: toolCall.callId,
2344
+ content: [{ text: result.output }],
2345
+ },
2346
+ };
2347
+ }
2348
+ appendToolResult(request, toolCall, result) {
2349
+ const bedrockRequest = request;
2350
+ const toolCallRaw = toolCall.raw;
2351
+ bedrockRequest.messages.push({
2352
+ role: "assistant",
2353
+ content: [toolCallRaw],
2354
+ });
2355
+ bedrockRequest.messages.push({
2356
+ role: "user",
2357
+ content: [this.formatToolResult(toolCall, result)],
2358
+ });
2359
+ return bedrockRequest;
2360
+ }
2361
+ //
2362
+ // History Management
2363
+ //
2364
+ responseToHistoryItems(response) {
2365
+ const bedrockResponse = response;
2366
+ const historyItems = [];
2367
+ if (bedrockResponse.stopReason === "tool_use") {
2368
+ return historyItems;
2369
+ }
2370
+ const content = bedrockResponse.output?.message?.content ?? [];
2371
+ const textBlock = content.find((block) => "text" in block);
2372
+ if (textBlock) {
2373
+ historyItems.push({
2374
+ content: textBlock.text,
2375
+ role: "assistant",
2376
+ type: LlmMessageType.Message,
2377
+ });
2378
+ }
2379
+ return historyItems;
2380
+ }
2381
+ //
2382
+ // Error Classification
2383
+ //
2384
+ classifyError(error) {
2385
+ const errorName = error?.constructor?.name;
2386
+ const errorMessage = error?.message ?? "";
2387
+ if (errorName === "ThrottlingException" ||
2388
+ errorMessage.includes("ThrottlingException") ||
2389
+ errorMessage.includes("Too Many Requests")) {
2390
+ return {
2391
+ error,
2392
+ category: ErrorCategory.RateLimit,
2393
+ shouldRetry: false,
2394
+ suggestedDelayMs: 60000,
2395
+ };
2396
+ }
2397
+ if (errorName === "ServiceUnavailableException" ||
2398
+ errorName === "InternalServerException" ||
2399
+ errorMessage.includes("ServiceUnavailableException") ||
2400
+ errorMessage.includes("InternalServerException")) {
2401
+ return {
2402
+ error,
2403
+ category: ErrorCategory.Retryable,
2404
+ shouldRetry: true,
2405
+ };
2406
+ }
2407
+ if (errorName === "AccessDeniedException" ||
2408
+ errorName === "ValidationException" ||
2409
+ errorName === "ResourceNotFoundException" ||
2410
+ errorMessage.includes("AccessDeniedException") ||
2411
+ errorMessage.includes("ValidationException")) {
2412
+ return {
2413
+ error,
2414
+ category: ErrorCategory.Unrecoverable,
2415
+ shouldRetry: false,
2416
+ };
2417
+ }
2418
+ if (isTransientNetworkError(error)) {
2419
+ return {
2420
+ error,
2421
+ category: ErrorCategory.Retryable,
2422
+ shouldRetry: true,
2423
+ };
2424
+ }
2425
+ return {
2426
+ error,
2427
+ category: ErrorCategory.Unknown,
2428
+ shouldRetry: true,
2429
+ };
2430
+ }
2431
+ //
2432
+ // Structured Output
2433
+ //
2434
+ hasStructuredOutput(response) {
2435
+ const bedrockResponse = response;
2436
+ if (bedrockResponse.__jaypieStructuredOutput) {
2437
+ return this.extractStructuredOutput(response) !== undefined;
2438
+ }
2439
+ // Fake-tool path: last content block is a structured_output toolUse
2440
+ const content = (bedrockResponse.output?.message?.content ?? []);
2441
+ const last = content[content.length - 1];
2442
+ return (!!last &&
2443
+ "toolUse" in last &&
2444
+ last.toolUse.name === STRUCTURED_OUTPUT_TOOL_NAME$2);
2445
+ }
2446
+ extractStructuredOutput(response) {
2447
+ const bedrockResponse = response;
2448
+ if (bedrockResponse.__jaypieStructuredOutput) {
2449
+ const content = (bedrockResponse.output?.message?.content ?? []);
2450
+ const textBlock = content.find((b) => "text" in b);
2451
+ if (!textBlock)
2452
+ return undefined;
2453
+ return extractJson(textBlock.text);
2454
+ }
2455
+ // Fake-tool path
2456
+ const content = (bedrockResponse.output?.message?.content ?? []);
2457
+ const last = content[content.length - 1];
2458
+ if (last &&
2459
+ "toolUse" in last &&
2460
+ last.toolUse.name === STRUCTURED_OUTPUT_TOOL_NAME$2) {
2461
+ return last.toolUse.input;
2462
+ }
2463
+ return undefined;
2464
+ }
2465
+ //
2466
+ // Completion Detection
2467
+ //
2468
+ isComplete(response) {
2469
+ const bedrockResponse = response;
2470
+ return bedrockResponse.stopReason !== "tool_use";
2471
+ }
2472
+ //
2473
+ // Private Helpers
2474
+ //
2475
+ extractContentFromMessage(message) {
2476
+ if (!message?.content)
2477
+ return undefined;
2478
+ const content = message.content;
2479
+ const textBlock = content.find((block) => "text" in block);
2480
+ return textBlock?.text;
2481
+ }
2482
+ }
2483
+ const bedrockAdapter = new BedrockAdapter();
2484
+
1818
2485
  //
1819
2486
  //
1820
2487
  // Constants
@@ -1863,15 +2530,15 @@ const NOT_RETRYABLE_STATUS_CODES = [
1863
2530
  // Main
1864
2531
  //
1865
2532
  /**
1866
- * GeminiAdapter implements the ProviderAdapter interface for Google's Gemini API.
2533
+ * GoogleAdapter implements the ProviderAdapter interface for Google's Gemini API.
1867
2534
  * It handles request building, response parsing, and error classification
1868
2535
  * specific to Gemini's generateContent API.
1869
2536
  */
1870
- class GeminiAdapter extends BaseProviderAdapter {
2537
+ class GoogleAdapter extends BaseProviderAdapter {
1871
2538
  constructor() {
1872
2539
  super(...arguments);
1873
- this.name = PROVIDER.GEMINI.NAME;
1874
- this.defaultModel = PROVIDER.GEMINI.MODEL.DEFAULT;
2540
+ this.name = PROVIDER.GOOGLE.NAME;
2541
+ this.defaultModel = PROVIDER.GOOGLE.MODEL.DEFAULT;
1875
2542
  // Session-level cache of Gemini 3 models observed to reject the native
1876
2543
  // `responseJsonSchema` + tools combo. When a model is in this set,
1877
2544
  // buildRequest engages the legacy fake-tool path instead.
@@ -1926,7 +2593,7 @@ class GeminiAdapter extends BaseProviderAdapter {
1926
2593
  ? [...request.tools]
1927
2594
  : [];
1928
2595
  if (request.format && hasUserTools && !useNativeCombo) {
1929
- log$2.warn(`[GeminiAdapter] Using legacy structured_output tool fallback for model ${geminiRequest.model}; native responseJsonSchema + tools combo is only available on Gemini 3.`);
2596
+ log$2.warn(`[GoogleAdapter] Using legacy structured_output tool fallback for model ${geminiRequest.model}; native responseJsonSchema + tools combo is only available on Gemini 3.`);
1930
2597
  allTools.push({
1931
2598
  name: STRUCTURED_OUTPUT_TOOL_NAME$1,
1932
2599
  description: "Output a structured JSON object, " +
@@ -2057,7 +2724,7 @@ class GeminiAdapter extends BaseProviderAdapter {
2057
2724
  if (wantsNativeCombo && isStructuredOutputComboUnsupportedError(error)) {
2058
2725
  const model = geminiRequest.model;
2059
2726
  this.rememberModelRejectsStructuredOutputCombo(model);
2060
- log$2.warn(`[GeminiAdapter] Model ${model} rejected native responseJsonSchema + tools combo; falling back to legacy structured_output tool emulation.`);
2727
+ log$2.warn(`[GoogleAdapter] Model ${model} rejected native responseJsonSchema + tools combo; falling back to legacy structured_output tool emulation.`);
2061
2728
  const fallbackRequest = this.toFallbackStructuredOutputRequest(geminiRequest);
2062
2729
  const response = await genAI.models.generateContent({
2063
2730
  model: fallbackRequest.model,
@@ -2639,7 +3306,7 @@ class GeminiAdapter extends BaseProviderAdapter {
2639
3306
  }
2640
3307
  }
2641
3308
  // Export singleton instance
2642
- const geminiAdapter = new GeminiAdapter();
3309
+ const googleAdapter = new GoogleAdapter();
2643
3310
 
2644
3311
  // Patterns for OpenAI reasoning models that support extended thinking
2645
3312
  const REASONING_MODEL_PATTERNS = [
@@ -4854,7 +5521,7 @@ function matchesCaughtError(reason, caught) {
4854
5521
  * (e.g. undici `TypeError: terminated`) emitted between attempts.
4855
5522
  */
4856
5523
  function createStaleRejectionGuard() {
4857
- const log = getLogger$5();
5524
+ const log = getLogger$6();
4858
5525
  const caughtErrors = new Set();
4859
5526
  let listener;
4860
5527
  return {
@@ -4913,7 +5580,7 @@ class RetryExecutor {
4913
5580
  * @throws BadGatewayError if all retries are exhausted or error is not retryable
4914
5581
  */
4915
5582
  async execute(operation, options) {
4916
- const log = getLogger$5();
5583
+ const log = getLogger$6();
4917
5584
  let attempt = 0;
4918
5585
  // Guard against stale rejections firing on a subsequent microtask after
4919
5586
  // the retry layer has already caught the originating error: undici socket
@@ -5032,7 +5699,7 @@ class OperateLoop {
5032
5699
  * Execute the operate loop for multi-turn conversations with tool calling.
5033
5700
  */
5034
5701
  async execute(input, options = {}) {
5035
- const log = getLogger$5();
5702
+ const log = getLogger$6();
5036
5703
  // Log what was passed to operate
5037
5704
  log.trace("[operate] Starting operate loop");
5038
5705
  log.var({ "operate.input": input });
@@ -5145,7 +5812,7 @@ class OperateLoop {
5145
5812
  };
5146
5813
  }
5147
5814
  async executeOneTurn(request, state, context, options) {
5148
- const log = getLogger$5();
5815
+ const log = getLogger$6();
5149
5816
  // Create error classifier from adapter
5150
5817
  const errorClassifier = createErrorClassifier(this.adapter);
5151
5818
  // Create retry executor for this turn
@@ -5457,7 +6124,7 @@ class StreamLoop {
5457
6124
  * Yields stream chunks as they become available.
5458
6125
  */
5459
6126
  async *execute(input, options = {}) {
5460
- const log = getLogger$5();
6127
+ const log = getLogger$6();
5461
6128
  // Verify adapter supports streaming
5462
6129
  if (!this.adapter.executeStreamRequest) {
5463
6130
  throw new BadGatewayError(`Provider ${this.adapter.name} does not support streaming`);
@@ -5575,7 +6242,7 @@ class StreamLoop {
5575
6242
  };
5576
6243
  }
5577
6244
  async *executeOneStreamingTurn(request, state, context, options) {
5578
- const log = getLogger$5();
6245
+ const log = getLogger$6();
5579
6246
  // Build provider-specific request
5580
6247
  const providerRequest = this.adapter.buildRequest(request);
5581
6248
  // Execute beforeEachModelRequest hook
@@ -5705,7 +6372,7 @@ class StreamLoop {
5705
6372
  return { shouldContinue: false };
5706
6373
  }
5707
6374
  async *processToolCalls(toolCalls, state, context, _options) {
5708
- const log = getLogger$5();
6375
+ const log = getLogger$6();
5709
6376
  for (const toolCall of toolCalls) {
5710
6377
  try {
5711
6378
  // Execute beforeEachTool hook
@@ -5851,28 +6518,28 @@ function createStreamLoop(config) {
5851
6518
  }
5852
6519
 
5853
6520
  // SDK loader with caching
5854
- let cachedSdk$2 = null;
5855
- async function loadSdk$2() {
5856
- if (cachedSdk$2)
5857
- return cachedSdk$2;
6521
+ let cachedSdk$3 = null;
6522
+ async function loadSdk$3() {
6523
+ if (cachedSdk$3)
6524
+ return cachedSdk$3;
5858
6525
  try {
5859
- cachedSdk$2 = await import('@anthropic-ai/sdk');
5860
- return cachedSdk$2;
6526
+ cachedSdk$3 = await import('@anthropic-ai/sdk');
6527
+ return cachedSdk$3;
5861
6528
  }
5862
6529
  catch {
5863
6530
  throw new ConfigurationError("@anthropic-ai/sdk is required but not installed. Run: npm install @anthropic-ai/sdk");
5864
6531
  }
5865
6532
  }
5866
6533
  // Logger
5867
- const getLogger$4 = () => log$1.lib({ lib: JAYPIE.LIB.LLM });
6534
+ const getLogger$5 = () => log$1.lib({ lib: JAYPIE.LIB.LLM });
5868
6535
  // Client initialization
5869
- async function initializeClient$4({ apiKey, } = {}) {
5870
- const logger = getLogger$4();
6536
+ async function initializeClient$5({ apiKey, } = {}) {
6537
+ const logger = getLogger$5();
5871
6538
  const resolvedApiKey = apiKey || (await getEnvSecret("ANTHROPIC_API_KEY"));
5872
6539
  if (!resolvedApiKey) {
5873
6540
  throw new ConfigurationError("The application could not resolve the required API key: ANTHROPIC_API_KEY");
5874
6541
  }
5875
- const sdk = await loadSdk$2();
6542
+ const sdk = await loadSdk$3();
5876
6543
  const client = new sdk.default({ apiKey: resolvedApiKey });
5877
6544
  logger.trace("Initialized Anthropic client");
5878
6545
  return client;
@@ -5893,7 +6560,7 @@ function formatUserMessage$3(message, { data, placeholders: placeholders$1 } = {
5893
6560
  };
5894
6561
  }
5895
6562
  function prepareMessages$3(message, { data, placeholders } = {}) {
5896
- const logger = getLogger$4();
6563
+ const logger = getLogger$5();
5897
6564
  const messages = [];
5898
6565
  // Add user message (necessary for all requests)
5899
6566
  const userMessage = formatUserMessage$3(message, { data, placeholders });
@@ -5977,7 +6644,7 @@ async function createStructuredCompletion$1(client, messages, model, responseSch
5977
6644
  // Main class implementation
5978
6645
  class AnthropicProvider {
5979
6646
  constructor(model = PROVIDER.ANTHROPIC.MODEL.DEFAULT, { apiKey } = {}) {
5980
- this.log = getLogger$4();
6647
+ this.log = getLogger$5();
5981
6648
  this.conversationHistory = [];
5982
6649
  this.model = model;
5983
6650
  this.apiKey = apiKey;
@@ -5986,7 +6653,7 @@ class AnthropicProvider {
5986
6653
  if (this._client) {
5987
6654
  return this._client;
5988
6655
  }
5989
- this._client = await initializeClient$4({ apiKey: this.apiKey });
6656
+ this._client = await initializeClient$5({ apiKey: this.apiKey });
5990
6657
  return this._client;
5991
6658
  }
5992
6659
  async getOperateLoop() {
@@ -6061,6 +6728,87 @@ class AnthropicProvider {
6061
6728
  }
6062
6729
  }
6063
6730
 
6731
+ let cachedSdk$2 = null;
6732
+ async function loadSdk$2() {
6733
+ if (cachedSdk$2)
6734
+ return cachedSdk$2;
6735
+ try {
6736
+ cachedSdk$2 = await import('@aws-sdk/client-bedrock-runtime');
6737
+ return cachedSdk$2;
6738
+ }
6739
+ catch {
6740
+ throw new ConfigurationError("@aws-sdk/client-bedrock-runtime is required but not installed. Run: npm install @aws-sdk/client-bedrock-runtime");
6741
+ }
6742
+ }
6743
+ const getLogger$4 = () => log$1.lib({ lib: JAYPIE.LIB.LLM });
6744
+ async function initializeClient$4({ region, } = {}) {
6745
+ const logger = getLogger$4();
6746
+ const resolvedRegion = region || process.env.AWS_REGION || "us-east-1";
6747
+ const sdk = await loadSdk$2();
6748
+ const client = new sdk.BedrockRuntimeClient({ region: resolvedRegion });
6749
+ logger.trace("Initialized Bedrock client");
6750
+ return client;
6751
+ }
6752
+
6753
+ class BedrockProvider {
6754
+ constructor(model = PROVIDER.BEDROCK.MODEL.DEFAULT, { region } = {}) {
6755
+ this.log = getLogger$4();
6756
+ this.conversationHistory = [];
6757
+ this.model = model;
6758
+ this.region = region;
6759
+ }
6760
+ async getClient() {
6761
+ if (this._client)
6762
+ return this._client;
6763
+ this._client = await initializeClient$4({ region: this.region });
6764
+ return this._client;
6765
+ }
6766
+ async getOperateLoop() {
6767
+ if (this._operateLoop)
6768
+ return this._operateLoop;
6769
+ const client = await this.getClient();
6770
+ this._operateLoop = createOperateLoop({ adapter: bedrockAdapter, client });
6771
+ return this._operateLoop;
6772
+ }
6773
+ async getStreamLoop() {
6774
+ if (this._streamLoop)
6775
+ return this._streamLoop;
6776
+ const client = await this.getClient();
6777
+ this._streamLoop = createStreamLoop({ adapter: bedrockAdapter, client });
6778
+ return this._streamLoop;
6779
+ }
6780
+ async send(message, options) {
6781
+ const operateLoop = await this.getOperateLoop();
6782
+ const mergedOptions = { ...options, model: options?.model ?? this.model };
6783
+ const response = await operateLoop.execute(message, mergedOptions);
6784
+ return response.content ?? "";
6785
+ }
6786
+ async operate(input, options = {}) {
6787
+ const operateLoop = await this.getOperateLoop();
6788
+ const mergedOptions = { ...options, model: options.model ?? this.model };
6789
+ if (this.conversationHistory.length > 0) {
6790
+ mergedOptions.history = options.history
6791
+ ? [...this.conversationHistory, ...options.history]
6792
+ : [...this.conversationHistory];
6793
+ }
6794
+ const response = await operateLoop.execute(input, mergedOptions);
6795
+ if (response.history && response.history.length > 0) {
6796
+ this.conversationHistory = response.history;
6797
+ }
6798
+ return response;
6799
+ }
6800
+ async *stream(input, options = {}) {
6801
+ const streamLoop = await this.getStreamLoop();
6802
+ const mergedOptions = { ...options, model: options.model ?? this.model };
6803
+ if (this.conversationHistory.length > 0) {
6804
+ mergedOptions.history = options.history
6805
+ ? [...this.conversationHistory, ...options.history]
6806
+ : [...this.conversationHistory];
6807
+ }
6808
+ yield* streamLoop.execute(input, mergedOptions);
6809
+ }
6810
+ }
6811
+
6064
6812
  // SDK loader with caching
6065
6813
  let cachedSdk$1 = null;
6066
6814
  async function loadSdk$1() {
@@ -6109,8 +6857,8 @@ function prepareMessages$2(message, { data, placeholders } = {}) {
6109
6857
  return { messages, systemInstruction: undefined };
6110
6858
  }
6111
6859
 
6112
- class GeminiProvider {
6113
- constructor(model = PROVIDER.GEMINI.MODEL.DEFAULT, { apiKey } = {}) {
6860
+ class GoogleProvider {
6861
+ constructor(model = PROVIDER.GOOGLE.MODEL.DEFAULT, { apiKey } = {}) {
6114
6862
  this.log = getLogger$3();
6115
6863
  this.conversationHistory = [];
6116
6864
  this.model = model;
@@ -6129,7 +6877,7 @@ class GeminiProvider {
6129
6877
  }
6130
6878
  const client = await this.getClient();
6131
6879
  this._operateLoop = createOperateLoop({
6132
- adapter: geminiAdapter,
6880
+ adapter: googleAdapter,
6133
6881
  client,
6134
6882
  });
6135
6883
  return this._operateLoop;
@@ -6140,7 +6888,7 @@ class GeminiProvider {
6140
6888
  }
6141
6889
  const client = await this.getClient();
6142
6890
  this._streamLoop = createStreamLoop({
6143
- adapter: geminiAdapter,
6891
+ adapter: googleAdapter,
6144
6892
  client,
6145
6893
  });
6146
6894
  return this._streamLoop;
@@ -6665,7 +7413,7 @@ class Llm {
6665
7413
  let finalModel = model;
6666
7414
  // Legacy: accept "gemini" but warn
6667
7415
  if (providerName === "gemini") {
6668
- log$2.warn(`Provider "gemini" is deprecated, use "${PROVIDER.GEMINI.NAME}" instead`);
7416
+ log$2.warn(`Provider "gemini" is deprecated, use "${PROVIDER.GOOGLE.NAME}" instead`);
6669
7417
  }
6670
7418
  if (model) {
6671
7419
  const modelDetermined = determineModelProvider(model);
@@ -6707,8 +7455,10 @@ class Llm {
6707
7455
  switch (providerName) {
6708
7456
  case PROVIDER.ANTHROPIC.NAME:
6709
7457
  return new AnthropicProvider(model || PROVIDER.ANTHROPIC.MODEL.DEFAULT, { apiKey });
6710
- case PROVIDER.GEMINI.NAME:
6711
- return new GeminiProvider(model || PROVIDER.GEMINI.MODEL.DEFAULT, {
7458
+ case PROVIDER.BEDROCK.NAME:
7459
+ return new BedrockProvider(model || PROVIDER.BEDROCK.MODEL.DEFAULT);
7460
+ case PROVIDER.GOOGLE.NAME:
7461
+ return new GoogleProvider(model || PROVIDER.GOOGLE.MODEL.DEFAULT, {
6712
7462
  apiKey,
6713
7463
  });
6714
7464
  case PROVIDER.OPENAI.NAME:
@@ -6966,7 +7716,7 @@ const roll = {
6966
7716
  },
6967
7717
  type: "function",
6968
7718
  call: ({ number = 1, sides = 6 } = {}) => {
6969
- const log = getLogger$5();
7719
+ const log = getLogger$6();
6970
7720
  const rng = random$1();
6971
7721
  const rolls = [];
6972
7722
  let total = 0;
@@ -7164,5 +7914,5 @@ const toolkit = new JaypieToolkit(tools);
7164
7914
  [LlmMessageRole.Developer]: "user",
7165
7915
  });
7166
7916
 
7167
- export { GeminiProvider, JaypieToolkit, constants as LLM, Llm, LlmMessageRole, LlmMessageType, LlmStreamChunkType, OpenRouterProvider, Toolkit, XaiProvider, extractReasoning, isLlmOperateInput, isLlmOperateInputContent, isLlmOperateInputFile, isLlmOperateInputImage, toolkit, tools };
7917
+ export { BedrockProvider, GoogleProvider as GeminiProvider, GoogleProvider, JaypieToolkit, constants as LLM, Llm, LlmMessageRole, LlmMessageType, LlmStreamChunkType, OpenRouterProvider, Toolkit, XaiProvider, extractReasoning, isLlmOperateInput, isLlmOperateInputContent, isLlmOperateInputFile, isLlmOperateInputImage, toolkit, tools };
7168
7918
  //# sourceMappingURL=index.js.map