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