@ljoukov/llm 3.0.2 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ CHATGPT_MODEL_IDS: () => CHATGPT_MODEL_IDS,
33
34
  CODEX_APPLY_PATCH_FREEFORM_TOOL_DESCRIPTION: () => CODEX_APPLY_PATCH_FREEFORM_TOOL_DESCRIPTION,
34
35
  CODEX_APPLY_PATCH_JSON_TOOL_DESCRIPTION: () => CODEX_APPLY_PATCH_JSON_TOOL_DESCRIPTION,
35
36
  CODEX_APPLY_PATCH_LARK_GRAMMAR: () => CODEX_APPLY_PATCH_LARK_GRAMMAR,
@@ -38,8 +39,15 @@ __export(index_exports, {
38
39
  FIREWORKS_DEFAULT_KIMI_MODEL: () => FIREWORKS_DEFAULT_KIMI_MODEL,
39
40
  FIREWORKS_DEFAULT_MINIMAX_MODEL: () => FIREWORKS_DEFAULT_MINIMAX_MODEL,
40
41
  FIREWORKS_MODEL_IDS: () => FIREWORKS_MODEL_IDS,
42
+ GEMINI_IMAGE_MODEL_IDS: () => GEMINI_IMAGE_MODEL_IDS,
43
+ GEMINI_MODEL_IDS: () => GEMINI_MODEL_IDS,
44
+ GEMINI_TEXT_MODEL_IDS: () => GEMINI_TEXT_MODEL_IDS,
41
45
  InMemoryAgentFilesystem: () => InMemoryAgentFilesystem,
46
+ LLM_IMAGE_MODEL_IDS: () => LLM_IMAGE_MODEL_IDS,
47
+ LLM_MODEL_IDS: () => LLM_MODEL_IDS,
48
+ LLM_TEXT_MODEL_IDS: () => LLM_TEXT_MODEL_IDS,
42
49
  LlmJsonCallError: () => LlmJsonCallError,
50
+ OPENAI_MODEL_IDS: () => OPENAI_MODEL_IDS,
43
51
  appendMarkdownSourcesSection: () => appendMarkdownSourcesSection,
44
52
  applyPatch: () => applyPatch,
45
53
  configureGemini: () => configureGemini,
@@ -74,8 +82,15 @@ __export(index_exports, {
74
82
  generateText: () => generateText,
75
83
  getChatGptAuthProfile: () => getChatGptAuthProfile,
76
84
  getCurrentToolCallContext: () => getCurrentToolCallContext,
85
+ isChatGptModelId: () => isChatGptModelId,
77
86
  isFireworksModelId: () => isFireworksModelId,
87
+ isGeminiImageModelId: () => isGeminiImageModelId,
78
88
  isGeminiModelId: () => isGeminiModelId,
89
+ isGeminiTextModelId: () => isGeminiTextModelId,
90
+ isLlmImageModelId: () => isLlmImageModelId,
91
+ isLlmModelId: () => isLlmModelId,
92
+ isLlmTextModelId: () => isLlmTextModelId,
93
+ isOpenAiModelId: () => isOpenAiModelId,
79
94
  loadEnvFromFile: () => loadEnvFromFile,
80
95
  loadLocalEnv: () => loadLocalEnv,
81
96
  parseJsonFromLlmText: () => parseJsonFromLlmText,
@@ -263,9 +278,6 @@ function getOpenAiPricing(modelId) {
263
278
  if (modelId.includes("gpt-5.3-codex")) {
264
279
  return OPENAI_GPT_53_CODEX_PRICING;
265
280
  }
266
- if (modelId.includes("gpt-5-codex")) {
267
- return OPENAI_GPT_53_CODEX_PRICING;
268
- }
269
281
  if (modelId.includes("gpt-5.2")) {
270
282
  return OPENAI_GPT_52_PRICING;
271
283
  }
@@ -788,6 +800,22 @@ var ResponsesWebSocketHttpError = class extends Error {
788
800
  this.headers = options.headers;
789
801
  }
790
802
  };
803
+ var UNSUPPORTED_WEBSOCKET_STATUS_CODES = /* @__PURE__ */ new Set([400, 404, 405, 406, 426, 501]);
804
+ var WEBSOCKET_CONNECT_TIMEOUT_MS = 3e4;
805
+ function parseUnexpectedServerResponseStatus(message) {
806
+ const match = /unexpected server response:\s*(\d+)/i.exec(message);
807
+ if (!match) {
808
+ return null;
809
+ }
810
+ const status = Number(match[1]);
811
+ if (!Number.isFinite(status) || status <= 0) {
812
+ return null;
813
+ }
814
+ return status;
815
+ }
816
+ function supportsUnexpectedResponseEvent() {
817
+ return !("bun" in process.versions);
818
+ }
791
819
  function resolveResponsesWebSocketMode(raw, fallback = "auto") {
792
820
  const value = raw?.trim().toLowerCase();
793
821
  if (value === "auto" || value === "off" || value === "only") {
@@ -822,9 +850,13 @@ function toWebSocketUrl(httpOrHttpsUrl) {
822
850
  }
823
851
  function isResponsesWebSocketUnsupportedError(error) {
824
852
  if (error instanceof ResponsesWebSocketHttpError) {
825
- return [400, 404, 405, 406, 426, 501].includes(error.status);
853
+ return UNSUPPORTED_WEBSOCKET_STATUS_CODES.has(error.status);
826
854
  }
827
855
  const message = error instanceof Error ? error.message.toLowerCase() : "";
856
+ const status = parseUnexpectedServerResponseStatus(message);
857
+ if (status !== null) {
858
+ return UNSUPPORTED_WEBSOCKET_STATUS_CODES.has(status);
859
+ }
828
860
  return message.includes("unexpected server response: 426");
829
861
  }
830
862
  function createAdaptiveResponsesStream(options) {
@@ -1063,12 +1095,20 @@ async function createResponsesWebSocketStream(options) {
1063
1095
  }
1064
1096
  async function connectWebSocket(options) {
1065
1097
  return await new Promise((resolve, reject) => {
1098
+ const shouldListenForUnexpectedResponse = supportsUnexpectedResponseEvent();
1066
1099
  const socket = new import_ws.default(options.url, {
1067
1100
  headers: options.headers,
1068
- handshakeTimeout: 3e4
1101
+ handshakeTimeout: WEBSOCKET_CONNECT_TIMEOUT_MS
1069
1102
  });
1070
1103
  let settled = false;
1071
1104
  let responseBody = "";
1105
+ let connectTimeout = setTimeout(() => {
1106
+ rejectOnce(
1107
+ new Error(
1108
+ `Responses WebSocket connection timed out after ${WEBSOCKET_CONNECT_TIMEOUT_MS}ms.`
1109
+ )
1110
+ );
1111
+ }, WEBSOCKET_CONNECT_TIMEOUT_MS);
1072
1112
  const rejectOnce = (error) => {
1073
1113
  if (settled) {
1074
1114
  return;
@@ -1093,9 +1133,15 @@ async function connectWebSocket(options) {
1093
1133
  rejectOnce(createAbortError(options.signal?.reason));
1094
1134
  };
1095
1135
  const cleanup = (removeAbortListener = true) => {
1136
+ if (connectTimeout) {
1137
+ clearTimeout(connectTimeout);
1138
+ connectTimeout = null;
1139
+ }
1096
1140
  socket.removeListener("open", onOpen);
1097
1141
  socket.removeListener("error", onError);
1098
- socket.removeListener("unexpected-response", onUnexpectedResponse);
1142
+ if (shouldListenForUnexpectedResponse) {
1143
+ socket.removeListener("unexpected-response", onUnexpectedResponse);
1144
+ }
1099
1145
  if (removeAbortListener && options.signal) {
1100
1146
  options.signal.removeEventListener("abort", onAbort);
1101
1147
  }
@@ -1146,7 +1192,9 @@ async function connectWebSocket(options) {
1146
1192
  };
1147
1193
  socket.once("open", onOpen);
1148
1194
  socket.once("error", onError);
1149
- socket.once("unexpected-response", onUnexpectedResponse);
1195
+ if (shouldListenForUnexpectedResponse) {
1196
+ socket.once("unexpected-response", onUnexpectedResponse);
1197
+ }
1150
1198
  if (options.signal) {
1151
1199
  if (options.signal.aborted) {
1152
1200
  onAbort();
@@ -1913,7 +1961,7 @@ function getGoogleAuthOptions(scopes) {
1913
1961
  }
1914
1962
 
1915
1963
  // src/google/client.ts
1916
- var GEMINI_MODEL_IDS = [
1964
+ var GEMINI_TEXT_MODEL_IDS = [
1917
1965
  "gemini-3-pro-preview",
1918
1966
  "gemini-3.1-pro-preview",
1919
1967
  "gemini-3-flash-preview",
@@ -1921,9 +1969,17 @@ var GEMINI_MODEL_IDS = [
1921
1969
  "gemini-flash-latest",
1922
1970
  "gemini-flash-lite-latest"
1923
1971
  ];
1972
+ var GEMINI_IMAGE_MODEL_IDS = ["gemini-3-pro-image-preview"];
1973
+ var GEMINI_MODEL_IDS = [...GEMINI_TEXT_MODEL_IDS, ...GEMINI_IMAGE_MODEL_IDS];
1924
1974
  function isGeminiModelId(value) {
1925
1975
  return GEMINI_MODEL_IDS.includes(value);
1926
1976
  }
1977
+ function isGeminiTextModelId(value) {
1978
+ return GEMINI_TEXT_MODEL_IDS.includes(value);
1979
+ }
1980
+ function isGeminiImageModelId(value) {
1981
+ return GEMINI_IMAGE_MODEL_IDS.includes(value);
1982
+ }
1927
1983
  var CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform";
1928
1984
  var DEFAULT_VERTEX_LOCATION = "global";
1929
1985
  var geminiConfiguration = {};
@@ -2342,11 +2398,51 @@ async function runOpenAiCall(fn) {
2342
2398
  return scheduler3.run(async () => fn(getOpenAiClient()));
2343
2399
  }
2344
2400
 
2401
+ // src/openai/models.ts
2402
+ var OPENAI_MODEL_IDS = [
2403
+ "gpt-5.3-codex",
2404
+ "gpt-5.3-codex-spark",
2405
+ "gpt-5.2",
2406
+ "gpt-5.1-codex-mini"
2407
+ ];
2408
+ function isOpenAiModelId(value) {
2409
+ return OPENAI_MODEL_IDS.includes(value);
2410
+ }
2411
+ var CHATGPT_MODEL_IDS = [
2412
+ "chatgpt-gpt-5.3-codex",
2413
+ "chatgpt-gpt-5.3-codex-spark",
2414
+ "chatgpt-gpt-5.2",
2415
+ "chatgpt-gpt-5.1-codex-mini"
2416
+ ];
2417
+ function isChatGptModelId(value) {
2418
+ return CHATGPT_MODEL_IDS.includes(value);
2419
+ }
2420
+ function stripChatGptPrefix(model) {
2421
+ return model.slice("chatgpt-".length);
2422
+ }
2423
+
2345
2424
  // src/llm.ts
2346
2425
  var toolCallContextStorage = new import_node_async_hooks.AsyncLocalStorage();
2347
2426
  function getCurrentToolCallContext() {
2348
2427
  return toolCallContextStorage.getStore() ?? null;
2349
2428
  }
2429
+ var LLM_TEXT_MODEL_IDS = [
2430
+ ...OPENAI_MODEL_IDS,
2431
+ ...CHATGPT_MODEL_IDS,
2432
+ ...FIREWORKS_MODEL_IDS,
2433
+ ...GEMINI_TEXT_MODEL_IDS
2434
+ ];
2435
+ var LLM_IMAGE_MODEL_IDS = [...GEMINI_IMAGE_MODEL_IDS];
2436
+ var LLM_MODEL_IDS = [...LLM_TEXT_MODEL_IDS, ...LLM_IMAGE_MODEL_IDS];
2437
+ function isLlmTextModelId(value) {
2438
+ return isOpenAiModelId(value) || isChatGptModelId(value) || isFireworksModelId(value) || isGeminiTextModelId(value);
2439
+ }
2440
+ function isLlmImageModelId(value) {
2441
+ return isGeminiImageModelId(value);
2442
+ }
2443
+ function isLlmModelId(value) {
2444
+ return isLlmTextModelId(value) || isLlmImageModelId(value);
2445
+ }
2350
2446
  var LlmJsonCallError = class extends Error {
2351
2447
  constructor(message, attempts) {
2352
2448
  super(message);
@@ -2704,17 +2800,22 @@ function convertLlmContentToGeminiContent(content) {
2704
2800
  };
2705
2801
  }
2706
2802
  function resolveProvider(model) {
2707
- if (model.startsWith("chatgpt-")) {
2708
- return { provider: "chatgpt", model: model.slice("chatgpt-".length) };
2803
+ if (isChatGptModelId(model)) {
2804
+ return { provider: "chatgpt", model: stripChatGptPrefix(model) };
2709
2805
  }
2710
- if (model.startsWith("gemini-")) {
2806
+ if (isGeminiTextModelId(model) || isGeminiImageModelId(model)) {
2711
2807
  return { provider: "gemini", model };
2712
2808
  }
2713
- const fireworksModel = resolveFireworksModelId(model);
2714
- if (fireworksModel) {
2715
- return { provider: "fireworks", model: fireworksModel };
2809
+ if (isFireworksModelId(model)) {
2810
+ const fireworksModel = resolveFireworksModelId(model);
2811
+ if (fireworksModel) {
2812
+ return { provider: "fireworks", model: fireworksModel };
2813
+ }
2814
+ }
2815
+ if (isOpenAiModelId(model)) {
2816
+ return { provider: "openai", model };
2716
2817
  }
2717
- return { provider: "openai", model };
2818
+ throw new Error(`Unsupported text model: ${model}`);
2718
2819
  }
2719
2820
  function isOpenAiCodexModel(modelId) {
2720
2821
  return modelId.includes("codex");
@@ -7298,6 +7399,7 @@ function mergeToolSets(base, extra) {
7298
7399
  }
7299
7400
  // Annotate the CommonJS export names for ESM import in node:
7300
7401
  0 && (module.exports = {
7402
+ CHATGPT_MODEL_IDS,
7301
7403
  CODEX_APPLY_PATCH_FREEFORM_TOOL_DESCRIPTION,
7302
7404
  CODEX_APPLY_PATCH_JSON_TOOL_DESCRIPTION,
7303
7405
  CODEX_APPLY_PATCH_LARK_GRAMMAR,
@@ -7306,8 +7408,15 @@ function mergeToolSets(base, extra) {
7306
7408
  FIREWORKS_DEFAULT_KIMI_MODEL,
7307
7409
  FIREWORKS_DEFAULT_MINIMAX_MODEL,
7308
7410
  FIREWORKS_MODEL_IDS,
7411
+ GEMINI_IMAGE_MODEL_IDS,
7412
+ GEMINI_MODEL_IDS,
7413
+ GEMINI_TEXT_MODEL_IDS,
7309
7414
  InMemoryAgentFilesystem,
7415
+ LLM_IMAGE_MODEL_IDS,
7416
+ LLM_MODEL_IDS,
7417
+ LLM_TEXT_MODEL_IDS,
7310
7418
  LlmJsonCallError,
7419
+ OPENAI_MODEL_IDS,
7311
7420
  appendMarkdownSourcesSection,
7312
7421
  applyPatch,
7313
7422
  configureGemini,
@@ -7342,8 +7451,15 @@ function mergeToolSets(base, extra) {
7342
7451
  generateText,
7343
7452
  getChatGptAuthProfile,
7344
7453
  getCurrentToolCallContext,
7454
+ isChatGptModelId,
7345
7455
  isFireworksModelId,
7456
+ isGeminiImageModelId,
7346
7457
  isGeminiModelId,
7458
+ isGeminiTextModelId,
7459
+ isLlmImageModelId,
7460
+ isLlmModelId,
7461
+ isLlmTextModelId,
7462
+ isOpenAiModelId,
7347
7463
  loadEnvFromFile,
7348
7464
  loadLocalEnv,
7349
7465
  parseJsonFromLlmText,