@aituber-onair/chat 0.55.0 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.ja.md +48 -8
  2. package/README.md +54 -9
  3. package/dist/cjs/constants/claude.d.ts +1 -0
  4. package/dist/cjs/constants/claude.d.ts.map +1 -1
  5. package/dist/cjs/constants/claude.js +3 -1
  6. package/dist/cjs/constants/claude.js.map +1 -1
  7. package/dist/cjs/constants/openai.d.ts +5 -3
  8. package/dist/cjs/constants/openai.d.ts.map +1 -1
  9. package/dist/cjs/constants/openai.js +24 -7
  10. package/dist/cjs/constants/openai.js.map +1 -1
  11. package/dist/cjs/constants/xai.d.ts +1 -0
  12. package/dist/cjs/constants/xai.d.ts.map +1 -1
  13. package/dist/cjs/constants/xai.js +7 -2
  14. package/dist/cjs/constants/xai.js.map +1 -1
  15. package/dist/cjs/services/ChatService.d.ts +2 -0
  16. package/dist/cjs/services/ChatService.d.ts.map +1 -1
  17. package/dist/cjs/services/ChatServiceFactory.d.ts.map +1 -1
  18. package/dist/cjs/services/ChatServiceFactory.js +20 -15
  19. package/dist/cjs/services/ChatServiceFactory.js.map +1 -1
  20. package/dist/cjs/services/providers/ChatServiceProvider.d.ts +2 -0
  21. package/dist/cjs/services/providers/ChatServiceProvider.d.ts.map +1 -1
  22. package/dist/cjs/services/providers/claude/ClaudeChatServiceProvider.d.ts.map +1 -1
  23. package/dist/cjs/services/providers/claude/ClaudeChatServiceProvider.js +1 -0
  24. package/dist/cjs/services/providers/claude/ClaudeChatServiceProvider.js.map +1 -1
  25. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.d.ts +24 -3
  26. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.d.ts.map +1 -1
  27. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.js +211 -15
  28. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.js.map +1 -1
  29. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.d.ts.map +1 -1
  30. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.js +1 -0
  31. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.js.map +1 -1
  32. package/dist/cjs/services/providers/openai/OpenAIChatService.js +1 -1
  33. package/dist/cjs/services/providers/openai/OpenAIChatService.js.map +1 -1
  34. package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.d.ts.map +1 -1
  35. package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.js +10 -0
  36. package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.js.map +1 -1
  37. package/dist/cjs/services/providers/xai/XAIChatServiceProvider.d.ts.map +1 -1
  38. package/dist/cjs/services/providers/xai/XAIChatServiceProvider.js +1 -0
  39. package/dist/cjs/services/providers/xai/XAIChatServiceProvider.js.map +1 -1
  40. package/dist/cjs/utils/index.d.ts +1 -0
  41. package/dist/cjs/utils/index.d.ts.map +1 -1
  42. package/dist/cjs/utils/index.js +1 -0
  43. package/dist/cjs/utils/index.js.map +1 -1
  44. package/dist/cjs/utils/openaiCompatibleEndpoint.d.ts +57 -0
  45. package/dist/cjs/utils/openaiCompatibleEndpoint.d.ts.map +1 -0
  46. package/dist/cjs/utils/openaiCompatibleEndpoint.js +193 -0
  47. package/dist/cjs/utils/openaiCompatibleEndpoint.js.map +1 -0
  48. package/dist/esm/constants/claude.d.ts +1 -0
  49. package/dist/esm/constants/claude.d.ts.map +1 -1
  50. package/dist/esm/constants/claude.js +2 -0
  51. package/dist/esm/constants/claude.js.map +1 -1
  52. package/dist/esm/constants/openai.d.ts +5 -3
  53. package/dist/esm/constants/openai.d.ts.map +1 -1
  54. package/dist/esm/constants/openai.js +23 -6
  55. package/dist/esm/constants/openai.js.map +1 -1
  56. package/dist/esm/constants/xai.d.ts +1 -0
  57. package/dist/esm/constants/xai.d.ts.map +1 -1
  58. package/dist/esm/constants/xai.js +6 -1
  59. package/dist/esm/constants/xai.js.map +1 -1
  60. package/dist/esm/services/ChatService.d.ts +2 -0
  61. package/dist/esm/services/ChatService.d.ts.map +1 -1
  62. package/dist/esm/services/ChatServiceFactory.d.ts.map +1 -1
  63. package/dist/esm/services/ChatServiceFactory.js +21 -16
  64. package/dist/esm/services/ChatServiceFactory.js.map +1 -1
  65. package/dist/esm/services/providers/ChatServiceProvider.d.ts +2 -0
  66. package/dist/esm/services/providers/ChatServiceProvider.d.ts.map +1 -1
  67. package/dist/esm/services/providers/claude/ClaudeChatServiceProvider.d.ts.map +1 -1
  68. package/dist/esm/services/providers/claude/ClaudeChatServiceProvider.js +2 -1
  69. package/dist/esm/services/providers/claude/ClaudeChatServiceProvider.js.map +1 -1
  70. package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.d.ts +24 -3
  71. package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.d.ts.map +1 -1
  72. package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.js +211 -15
  73. package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.js.map +1 -1
  74. package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.d.ts.map +1 -1
  75. package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.js +1 -0
  76. package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.js.map +1 -1
  77. package/dist/esm/services/providers/openai/OpenAIChatService.js +1 -1
  78. package/dist/esm/services/providers/openai/OpenAIChatService.js.map +1 -1
  79. package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.d.ts.map +1 -1
  80. package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.js +11 -1
  81. package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.js.map +1 -1
  82. package/dist/esm/services/providers/xai/XAIChatServiceProvider.d.ts.map +1 -1
  83. package/dist/esm/services/providers/xai/XAIChatServiceProvider.js +2 -1
  84. package/dist/esm/services/providers/xai/XAIChatServiceProvider.js.map +1 -1
  85. package/dist/esm/utils/index.d.ts +1 -0
  86. package/dist/esm/utils/index.d.ts.map +1 -1
  87. package/dist/esm/utils/index.js +1 -0
  88. package/dist/esm/utils/index.js.map +1 -1
  89. package/dist/esm/utils/openaiCompatibleEndpoint.d.ts +57 -0
  90. package/dist/esm/utils/openaiCompatibleEndpoint.d.ts.map +1 -0
  91. package/dist/esm/utils/openaiCompatibleEndpoint.js +186 -0
  92. package/dist/esm/utils/openaiCompatibleEndpoint.js.map +1 -0
  93. package/dist/umd/aituber-onair-chat.js +500 -25
  94. package/dist/umd/aituber-onair-chat.min.js +8 -8
  95. package/package.json +1 -1
@@ -99,6 +99,7 @@ var AITuberOnAirChat = (() => {
99
99
  MODEL_CLAUDE_4_OPUS: () => MODEL_CLAUDE_4_OPUS,
100
100
  MODEL_CLAUDE_4_SONNET: () => MODEL_CLAUDE_4_SONNET,
101
101
  MODEL_CLAUDE_5_1_FABLE: () => MODEL_CLAUDE_5_1_FABLE,
102
+ MODEL_CLAUDE_5_5_OPUS: () => MODEL_CLAUDE_5_5_OPUS,
102
103
  MODEL_CLAUDE_5_FABLE: () => MODEL_CLAUDE_5_FABLE,
103
104
  MODEL_CLAUDE_5_OPUS: () => MODEL_CLAUDE_5_OPUS,
104
105
  MODEL_CLAUDE_5_SONNET: () => MODEL_CLAUDE_5_SONNET,
@@ -171,6 +172,8 @@ var AITuberOnAirChat = (() => {
171
172
  MODEL_GPT_5_MINI: () => MODEL_GPT_5_MINI,
172
173
  MODEL_GPT_5_NANO: () => MODEL_GPT_5_NANO,
173
174
  MODEL_GPT_6_ASTRA: () => MODEL_GPT_6_ASTRA,
175
+ MODEL_GPT_6_LUNA: () => MODEL_GPT_6_LUNA,
176
+ MODEL_GPT_6_SOL: () => MODEL_GPT_6_SOL,
174
177
  MODEL_GPT_OSS_20B_FREE: () => MODEL_GPT_OSS_20B_FREE,
175
178
  MODEL_GROK_4_1_FAST_NON_REASONING: () => MODEL_GROK_4_1_FAST_NON_REASONING,
176
179
  MODEL_GROK_4_1_FAST_REASONING: () => MODEL_GROK_4_1_FAST_REASONING,
@@ -179,6 +182,7 @@ var AITuberOnAirChat = (() => {
179
182
  MODEL_GROK_4_3: () => MODEL_GROK_4_3,
180
183
  MODEL_GROK_4_5: () => MODEL_GROK_4_5,
181
184
  MODEL_GROK_4_6: () => MODEL_GROK_4_6,
185
+ MODEL_GROK_4_7: () => MODEL_GROK_4_7,
182
186
  MODEL_INCEPTION_MERCURY_2_5: () => MODEL_INCEPTION_MERCURY_2_5,
183
187
  MODEL_INCLUSIONAI_LING_3_0_FLASH_VL_FREE: () => MODEL_INCLUSIONAI_LING_3_0_FLASH_VL_FREE,
184
188
  MODEL_KIMI_K2_5: () => MODEL_KIMI_K2_5,
@@ -248,6 +252,7 @@ var AITuberOnAirChat = (() => {
248
252
  MODEL_ZAI_GLM_5_3_FLASH: () => MODEL_ZAI_GLM_5_3_FLASH,
249
253
  MistralChatService: () => MistralChatService,
250
254
  MistralChatServiceProvider: () => MistralChatServiceProvider,
255
+ OPENAI_COMPATIBLE_LOCAL_PRESETS: () => OPENAI_COMPATIBLE_LOCAL_PRESETS,
251
256
  OPENROUTER_CREDITS_THRESHOLD: () => OPENROUTER_CREDITS_THRESHOLD,
252
257
  OPENROUTER_DEPRECATED_MODELS: () => OPENROUTER_DEPRECATED_MODELS,
253
258
  OPENROUTER_FREE_DAILY_LIMIT_HIGH_CREDITS: () => OPENROUTER_FREE_DAILY_LIMIT_HIGH_CREDITS,
@@ -258,6 +263,7 @@ var AITuberOnAirChat = (() => {
258
263
  OpenAIChatService: () => OpenAIChatService,
259
264
  OpenAIChatServiceProvider: () => OpenAIChatServiceProvider,
260
265
  OpenAICompatibleChatServiceProvider: () => OpenAICompatibleChatServiceProvider,
266
+ OpenAICompatibleEndpointError: () => OpenAICompatibleEndpointError,
261
267
  OpenRouterChatService: () => OpenRouterChatService,
262
268
  OpenRouterChatServiceProvider: () => OpenRouterChatServiceProvider,
263
269
  PLAMO_API_BASE_URL: () => PLAMO_API_BASE_URL,
@@ -329,6 +335,7 @@ var AITuberOnAirChat = (() => {
329
335
  isZaiReasoningEffortModel: () => isZaiReasoningEffortModel,
330
336
  isZaiToolStreamModel: () => isZaiToolStreamModel,
331
337
  isZaiVisionModel: () => isZaiVisionModel,
338
+ listOpenAICompatibleModels: () => listOpenAICompatibleModels,
332
339
  normalizeClaudeReasoningEffort: () => normalizeClaudeReasoningEffort,
333
340
  normalizeDeepSeekReasoningEffort: () => normalizeDeepSeekReasoningEffort,
334
341
  normalizeGeminiReasoningEffort: () => normalizeGeminiReasoningEffort,
@@ -340,11 +347,13 @@ var AITuberOnAirChat = (() => {
340
347
  parseOpenAICompatibleToolStream: () => parseOpenAICompatibleToolStream,
341
348
  processChatWithOptionalTools: () => processChatWithOptionalTools,
342
349
  refreshOpenRouterFreeModels: () => refreshOpenRouterFreeModels,
350
+ resolveOpenAICompatibleEndpoint: () => resolveOpenAICompatibleEndpoint,
343
351
  resolveVisionModel: () => resolveVisionModel,
344
352
  runOnceText: () => runOnceText,
345
353
  safeJsonParse: () => safeJsonParse,
346
354
  safeParseToolCallInput: () => safeParseToolCallInput,
347
355
  screenplayToText: () => screenplayToText,
356
+ testOpenAICompatibleConnection: () => testOpenAICompatibleConnection,
348
357
  textToScreenplay: () => textToScreenplay,
349
358
  textsToScreenplay: () => textsToScreenplay
350
359
  });
@@ -353,6 +362,8 @@ var AITuberOnAirChat = (() => {
353
362
  var ENDPOINT_OPENAI_CHAT_COMPLETIONS_API = "https://api.openai.com/v1/chat/completions";
354
363
  var ENDPOINT_OPENAI_RESPONSES_API = "https://api.openai.com/v1/responses";
355
364
  var MODEL_GPT_6_ASTRA = "gpt-6-astra";
365
+ var MODEL_GPT_6_SOL = "gpt-6-sol";
366
+ var MODEL_GPT_6_LUNA = "gpt-6-luna";
356
367
  var MODEL_GPT_5_NANO = "gpt-5-nano";
357
368
  var MODEL_GPT_5_MINI = "gpt-5-mini";
358
369
  var MODEL_GPT_5 = "gpt-5";
@@ -376,6 +387,8 @@ var AITuberOnAirChat = (() => {
376
387
  var MODEL_O1 = "o1";
377
388
  var VISION_SUPPORTED_MODELS = [
378
389
  MODEL_GPT_6_ASTRA,
390
+ MODEL_GPT_6_SOL,
391
+ MODEL_GPT_6_LUNA,
379
392
  MODEL_GPT_5_NANO,
380
393
  MODEL_GPT_5_MINI,
381
394
  MODEL_GPT_5,
@@ -416,19 +429,19 @@ var AITuberOnAirChat = (() => {
416
429
  return GPT_5_MODELS.includes(model);
417
430
  }
418
431
  function isOpenAIReasoningModel(model) {
419
- return model === MODEL_GPT_6_ASTRA || isGPT5Model(model);
432
+ return model === MODEL_GPT_6_ASTRA || model === MODEL_GPT_6_SOL || model === MODEL_GPT_6_LUNA || isGPT5Model(model);
420
433
  }
421
434
  function isResponsesOnlyGPT5Model(model) {
422
435
  return model === MODEL_GPT_5_4_PRO;
423
436
  }
424
437
  function allowsReasoningXHigh(model) {
425
- return model === MODEL_GPT_6_ASTRA || model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA || model === MODEL_GPT_5_5 || model === MODEL_GPT_5_4 || model === MODEL_GPT_5_4_MINI || model === MODEL_GPT_5_4_NANO || model === MODEL_GPT_5_4_PRO;
438
+ return model === MODEL_GPT_6_ASTRA || model === MODEL_GPT_6_SOL || model === MODEL_GPT_6_LUNA || model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA || model === MODEL_GPT_5_5 || model === MODEL_GPT_5_4 || model === MODEL_GPT_5_4_MINI || model === MODEL_GPT_5_4_NANO || model === MODEL_GPT_5_4_PRO;
426
439
  }
427
440
  function allowsReasoningMax(model) {
428
- return model === MODEL_GPT_6_ASTRA || model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA;
441
+ return model === MODEL_GPT_6_ASTRA || model === MODEL_GPT_6_SOL || model === MODEL_GPT_6_LUNA || model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA;
429
442
  }
430
443
  function allowsReasoningNone(model) {
431
- return model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA || model === MODEL_GPT_5_1 || model === MODEL_GPT_5_4 || model === MODEL_GPT_5_5 || model === MODEL_GPT_5_4_MINI || model === MODEL_GPT_5_4_NANO;
444
+ return model === MODEL_GPT_6_SOL || model === MODEL_GPT_6_LUNA || model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA || model === MODEL_GPT_5_1 || model === MODEL_GPT_5_4 || model === MODEL_GPT_5_5 || model === MODEL_GPT_5_4_MINI || model === MODEL_GPT_5_4_NANO;
432
445
  }
433
446
  function allowsReasoningMinimal(model) {
434
447
  return model === MODEL_GPT_5_NANO || model === MODEL_GPT_5_MINI || model === MODEL_GPT_5;
@@ -446,7 +459,7 @@ var AITuberOnAirChat = (() => {
446
459
  return "medium";
447
460
  }
448
461
  function getDefaultReasoningEffortForOpenAIModel(model) {
449
- return model === MODEL_GPT_6_ASTRA ? "low" : getDefaultReasoningEffortForGPT5Model(model);
462
+ return model === MODEL_GPT_6_ASTRA ? "low" : model === MODEL_GPT_6_SOL ? "medium" : model === MODEL_GPT_6_LUNA ? "low" : getDefaultReasoningEffortForGPT5Model(model);
450
463
  }
451
464
 
452
465
  // src/constants/gemini.ts
@@ -561,6 +574,7 @@ var AITuberOnAirChat = (() => {
561
574
  var MODEL_CLAUDE_5_FABLE = "claude-fable-5";
562
575
  var MODEL_CLAUDE_5_SONNET = "claude-sonnet-5";
563
576
  var MODEL_CLAUDE_5_OPUS = "claude-opus-5";
577
+ var MODEL_CLAUDE_5_5_OPUS = "claude-opus-5-5";
564
578
  var CLAUDE_DEPRECATED_MODELS = [
565
579
  MODEL_CLAUDE_3_HAIKU,
566
580
  MODEL_CLAUDE_3_5_HAIKU,
@@ -605,7 +619,8 @@ var AITuberOnAirChat = (() => {
605
619
  MODEL_CLAUDE_4_8_OPUS,
606
620
  MODEL_CLAUDE_5_FABLE,
607
621
  MODEL_CLAUDE_5_SONNET,
608
- MODEL_CLAUDE_5_OPUS
622
+ MODEL_CLAUDE_5_OPUS,
623
+ MODEL_CLAUDE_5_5_OPUS
609
624
  ];
610
625
  function getClaudeSupportedReasoningEfforts(model) {
611
626
  return CLAUDE_REASONING_EFFORTS_BY_MODEL[model] ?? [];
@@ -1054,6 +1069,7 @@ var AITuberOnAirChat = (() => {
1054
1069
  // src/constants/xai.ts
1055
1070
  var ENDPOINT_XAI_CHAT_COMPLETIONS_API = "https://api.x.ai/v1/chat/completions";
1056
1071
  var MODEL_GROK_4_6 = "grok-4.6";
1072
+ var MODEL_GROK_4_7 = "grok-4.7";
1057
1073
  var MODEL_GROK_4_5 = "grok-4.5";
1058
1074
  var MODEL_GROK_4_3 = "grok-4.3";
1059
1075
  var MODEL_GROK_4_20_REASONING = "grok-4.20-0309-reasoning";
@@ -1066,6 +1082,7 @@ var AITuberOnAirChat = (() => {
1066
1082
  ];
1067
1083
  var XAI_VISION_SUPPORTED_MODELS = [
1068
1084
  MODEL_GROK_4_6,
1085
+ MODEL_GROK_4_7,
1069
1086
  MODEL_GROK_4_5,
1070
1087
  MODEL_GROK_4_3,
1071
1088
  MODEL_GROK_4_20_REASONING,
@@ -1078,7 +1095,7 @@ var AITuberOnAirChat = (() => {
1078
1095
  return getXaiSupportedReasoningEfforts(model).length > 0;
1079
1096
  }
1080
1097
  function getXaiSupportedReasoningEfforts(model) {
1081
- if (model === MODEL_GROK_4_6) {
1098
+ if (model === MODEL_GROK_4_6 || model === MODEL_GROK_4_7) {
1082
1099
  return ["low", "medium", "high", "xhigh"];
1083
1100
  }
1084
1101
  if (model === MODEL_GROK_4_5) {
@@ -1093,6 +1110,9 @@ var AITuberOnAirChat = (() => {
1093
1110
  return getXaiSupportedReasoningEfforts(model).includes("none");
1094
1111
  }
1095
1112
  function getDefaultXaiReasoningEffort(model) {
1113
+ if (model === MODEL_GROK_4_7) {
1114
+ return "low";
1115
+ }
1096
1116
  if (model === MODEL_GROK_4_6 || model === MODEL_GROK_4_5) {
1097
1117
  return "low";
1098
1118
  }
@@ -1811,6 +1831,192 @@ If it's in another language, summarize in that language.
1811
1831
  };
1812
1832
  }
1813
1833
 
1834
+ // src/utils/openaiCompatibleEndpoint.ts
1835
+ var OPENAI_COMPATIBLE_LOCAL_PRESETS = [
1836
+ {
1837
+ id: "ollama",
1838
+ label: "Ollama",
1839
+ baseUrl: "http://localhost:11434/v1",
1840
+ docsUrl: "https://docs.ollama.com/api/openai-compatibility",
1841
+ corsHint: "Set OLLAMA_ORIGINS to allow additional browser origins."
1842
+ },
1843
+ {
1844
+ id: "lmStudio",
1845
+ label: "LM Studio",
1846
+ baseUrl: "http://localhost:1234/v1",
1847
+ docsUrl: "https://lmstudio.ai/docs/developer/openai-compat",
1848
+ corsHint: "Start the server with lms server start --cors for browser access."
1849
+ },
1850
+ {
1851
+ id: "llamaCpp",
1852
+ label: "llama.cpp",
1853
+ baseUrl: "http://127.0.0.1:8080/v1",
1854
+ docsUrl: "https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md",
1855
+ corsHint: "All origins are allowed by default; use --cors-origins to restrict them."
1856
+ },
1857
+ {
1858
+ id: "vllm",
1859
+ label: "vLLM",
1860
+ baseUrl: "http://localhost:8000/v1",
1861
+ docsUrl: "https://docs.vllm.ai/en/latest/serving/online_serving/openai_compatible_server/",
1862
+ corsHint: "All origins are allowed by default; use --allowed-origins to restrict them."
1863
+ }
1864
+ ];
1865
+ var OpenAICompatibleEndpointError = class extends Error {
1866
+ constructor(code, message, status) {
1867
+ super(message);
1868
+ this.name = "OpenAICompatibleEndpointError";
1869
+ this.code = code;
1870
+ this.status = status;
1871
+ }
1872
+ };
1873
+ function resolveOpenAICompatibleEndpoint(input) {
1874
+ let url;
1875
+ try {
1876
+ url = new URL(input.trim());
1877
+ } catch {
1878
+ throw new OpenAICompatibleEndpointError(
1879
+ "invalid-url",
1880
+ "Enter a valid HTTP or HTTPS endpoint URL."
1881
+ );
1882
+ }
1883
+ if (url.protocol !== "http:" && url.protocol !== "https:" || url.search || url.hash || url.username || url.password) {
1884
+ throw new OpenAICompatibleEndpointError(
1885
+ "invalid-url",
1886
+ "Use an HTTP or HTTPS endpoint URL without credentials, a query, or a fragment."
1887
+ );
1888
+ }
1889
+ const path = url.pathname.replace(/\/+$/, "");
1890
+ if (path.endsWith("/api/chat") || path.endsWith("/api/generate")) {
1891
+ throw new OpenAICompatibleEndpointError(
1892
+ "invalid-url",
1893
+ "This looks like Ollama's native API URL. Use the OpenAI-compatible base URL instead, e.g. http://localhost:11434/v1."
1894
+ );
1895
+ }
1896
+ const basePath = !path || path === "/" ? "/v1" : path.endsWith("/chat/completions") ? path.slice(0, -"/chat/completions".length) : path;
1897
+ const baseUrl = `${url.origin}${basePath}`;
1898
+ return {
1899
+ baseUrl,
1900
+ chatCompletionsUrl: `${baseUrl}/chat/completions`,
1901
+ modelsUrl: `${baseUrl}/models`
1902
+ };
1903
+ }
1904
+ async function listOpenAICompatibleModels(options) {
1905
+ const { modelsUrl } = resolveOpenAICompatibleEndpoint(options.endpoint);
1906
+ const timeoutMs = options.timeoutMs ?? 8e3;
1907
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
1908
+ throw new RangeError("timeoutMs must be a positive finite number.");
1909
+ }
1910
+ if (options.signal?.aborted) {
1911
+ throw new OpenAICompatibleEndpointError(
1912
+ "aborted",
1913
+ "The models request was aborted by the caller."
1914
+ );
1915
+ }
1916
+ const controller = new AbortController();
1917
+ let abortCause;
1918
+ const onAbort = () => {
1919
+ if (!abortCause) abortCause = "caller";
1920
+ controller.abort();
1921
+ };
1922
+ options.signal?.addEventListener("abort", onAbort, { once: true });
1923
+ if (options.signal?.aborted) onAbort();
1924
+ const timeout = setTimeout(() => {
1925
+ if (!abortCause) abortCause = "timeout";
1926
+ controller.abort();
1927
+ }, timeoutMs);
1928
+ try {
1929
+ const headers = {};
1930
+ if (options.apiKey?.trim()) {
1931
+ headers.Authorization = `Bearer ${options.apiKey.trim()}`;
1932
+ }
1933
+ const response = await (options.fetch ?? fetch)(modelsUrl, {
1934
+ method: "GET",
1935
+ headers,
1936
+ signal: controller.signal
1937
+ });
1938
+ if (abortCause) {
1939
+ throw new OpenAICompatibleEndpointError(
1940
+ "aborted",
1941
+ "The models request was aborted by the caller."
1942
+ );
1943
+ }
1944
+ if (!response.ok) {
1945
+ throw new OpenAICompatibleEndpointError(
1946
+ "http",
1947
+ `Model listing failed with HTTP ${response.status}.`,
1948
+ response.status
1949
+ );
1950
+ }
1951
+ let body;
1952
+ try {
1953
+ body = await response.json();
1954
+ } catch {
1955
+ throw new OpenAICompatibleEndpointError(
1956
+ "invalid-response",
1957
+ "The models endpoint did not return valid JSON."
1958
+ );
1959
+ }
1960
+ if (!body || typeof body !== "object" || !("data" in body) || !Array.isArray(body.data) || !body.data.every(
1961
+ (model) => model && typeof model === "object" && "id" in model && typeof model.id === "string"
1962
+ )) {
1963
+ throw new OpenAICompatibleEndpointError(
1964
+ "invalid-response",
1965
+ "The models response must contain data with model IDs."
1966
+ );
1967
+ }
1968
+ if (abortCause) {
1969
+ throw new OpenAICompatibleEndpointError(
1970
+ "aborted",
1971
+ "The models request was aborted by the caller."
1972
+ );
1973
+ }
1974
+ return [...new Set(body.data.map((model) => model.id))];
1975
+ } catch (error) {
1976
+ if (abortCause === "caller") {
1977
+ throw new OpenAICompatibleEndpointError(
1978
+ "aborted",
1979
+ "The models request was aborted by the caller."
1980
+ );
1981
+ }
1982
+ if (abortCause === "timeout") {
1983
+ throw new OpenAICompatibleEndpointError(
1984
+ "timeout",
1985
+ `The models request timed out after ${timeoutMs} ms.`
1986
+ );
1987
+ }
1988
+ if (error instanceof OpenAICompatibleEndpointError) throw error;
1989
+ throw new OpenAICompatibleEndpointError(
1990
+ "network",
1991
+ "Could not reach the models endpoint. In a browser, this is usually a CORS restriction or the server is not running."
1992
+ );
1993
+ } finally {
1994
+ clearTimeout(timeout);
1995
+ options.signal?.removeEventListener("abort", onAbort);
1996
+ }
1997
+ }
1998
+ async function testOpenAICompatibleConnection(options) {
1999
+ const startedAt = Date.now();
2000
+ try {
2001
+ const models = await listOpenAICompatibleModels(options);
2002
+ return {
2003
+ ok: true,
2004
+ latencyMs: Date.now() - startedAt,
2005
+ models,
2006
+ ...options.model !== void 0 ? { modelFound: models.includes(options.model) } : {}
2007
+ };
2008
+ } catch (error) {
2009
+ if (error instanceof RangeError) throw error;
2010
+ return {
2011
+ ok: false,
2012
+ error: error instanceof OpenAICompatibleEndpointError ? error : new OpenAICompatibleEndpointError(
2013
+ "network",
2014
+ "Could not reach the models endpoint. In a browser, this is usually a CORS restriction or the server is not running."
2015
+ )
2016
+ };
2017
+ }
2018
+ }
2019
+
1814
2020
  // src/utils/openaiCompatibleTools.ts
1815
2021
  var buildOpenAICompatibleTools = (tools, format = "chat-completions") => {
1816
2022
  if (tools.length === 0) return [];
@@ -2628,7 +2834,8 @@ If it's in another language, summarize in that language.
2628
2834
  MODEL_CLAUDE_5_1_FABLE,
2629
2835
  MODEL_CLAUDE_5_FABLE,
2630
2836
  MODEL_CLAUDE_5_SONNET,
2631
- MODEL_CLAUDE_5_OPUS
2837
+ MODEL_CLAUDE_5_OPUS,
2838
+ MODEL_CLAUDE_5_5_OPUS
2632
2839
  ];
2633
2840
  }
2634
2841
  /**
@@ -4335,6 +4542,7 @@ If it's in another language, summarize in that language.
4335
4542
  var GeminiNanoChatService = class {
4336
4543
  constructor(options = {}) {
4337
4544
  this.provider = "gemini-nano";
4545
+ this.consumedTranscript = [];
4338
4546
  this.expectedInputLanguages = options.expectedInputLanguages ?? [
4339
4547
  "ja",
4340
4548
  "en"
@@ -4344,6 +4552,7 @@ If it's in another language, summarize in that language.
4344
4552
  ...prompt
4345
4553
  }));
4346
4554
  this._responseLength = options.responseLength;
4555
+ this.sessionMode = options.sessionMode ?? "stateless";
4347
4556
  }
4348
4557
  getModel() {
4349
4558
  return MODEL_GEMINI_NANO;
@@ -4351,23 +4560,33 @@ If it's in another language, summarize in that language.
4351
4560
  getVisionModel() {
4352
4561
  return MODEL_GEMINI_NANO;
4353
4562
  }
4563
+ /** Destroy any persistent Prompt API sessions held by this service. */
4564
+ dispose() {
4565
+ this.destroyPersistentSessions();
4566
+ }
4354
4567
  /**
4355
4568
  * Process chat messages using Gemini Nano.
4356
- * Non-streaming: calls onPartialResponse once with the full response,
4357
- * then calls onCompleteResponse.
4569
+ * Streams response deltas when Chrome exposes promptStreaming(), then calls
4570
+ * onCompleteResponse with the complete response.
4358
4571
  */
4359
4572
  async processChat(messages, onPartialResponse, onCompleteResponse) {
4360
- const response = await this.generateResponse(messages);
4361
- onPartialResponse(response);
4573
+ const response = await this.generateResponse(
4574
+ messages,
4575
+ true,
4576
+ onPartialResponse
4577
+ );
4362
4578
  await onCompleteResponse(response);
4363
4579
  }
4364
4580
  async processVisionChat(_messages, _onPartialResponse, _onCompleteResponse) {
4365
4581
  throw new Error("Gemini Nano does not support vision capabilities.");
4366
4582
  }
4367
- async chatOnce(messages, _stream = false, onPartialResponse = () => {
4583
+ async chatOnce(messages, stream = false, onPartialResponse = () => {
4368
4584
  }, _maxTokens) {
4369
- const response = await this.generateResponse(messages);
4370
- onPartialResponse(response);
4585
+ const response = await this.generateResponse(
4586
+ messages,
4587
+ stream,
4588
+ onPartialResponse
4589
+ );
4371
4590
  return {
4372
4591
  blocks: [{ type: "text", text: response }],
4373
4592
  stop_reason: "end"
@@ -4380,7 +4599,7 @@ If it's in another language, summarize in that language.
4380
4599
  /**
4381
4600
  * Core logic: extract system prompt, manage session, call prompt().
4382
4601
  */
4383
- async generateResponse(messages) {
4602
+ async generateResponse(messages, stream, onPartialResponse) {
4384
4603
  const api = getLanguageModelAPI();
4385
4604
  if (!api) {
4386
4605
  throw new Error(
@@ -4388,11 +4607,8 @@ If it's in another language, summarize in that language.
4388
4607
  );
4389
4608
  }
4390
4609
  const modelOptions = this.getModelOptions();
4391
- const availability = await api.availability(modelOptions);
4392
- if (availability !== "available" && availability !== "downloadable") {
4393
- throw new Error(
4394
- `Gemini Nano Prompt API is not ready in this environment. LanguageModel.availability() returned "${availability}". Expected "available" or "downloadable".`
4395
- );
4610
+ if (this.sessionMode === "stateless") {
4611
+ await this.ensureAvailability(api, modelOptions);
4396
4612
  }
4397
4613
  const systemMessages = messages.filter((m) => m.role === "system");
4398
4614
  const systemPrompt = systemMessages.map((m) => m.content).join("\n");
@@ -4402,14 +4618,31 @@ If it's in another language, summarize in that language.
4402
4618
  throw new Error("No user message found in the provided messages.");
4403
4619
  }
4404
4620
  const lastUserMessage = conversationMessages[lastUserMessageIndex];
4621
+ const contextHistory = conversationMessages.slice(0, lastUserMessageIndex);
4622
+ if (this.sessionMode === "persistent") {
4623
+ return this.generatePersistentResponse(
4624
+ api,
4625
+ systemPrompt,
4626
+ contextHistory,
4627
+ lastUserMessage.content,
4628
+ modelOptions,
4629
+ stream,
4630
+ onPartialResponse
4631
+ );
4632
+ }
4405
4633
  const session = await this.createSession(
4406
4634
  api,
4407
4635
  systemPrompt,
4408
- conversationMessages.slice(0, lastUserMessageIndex),
4636
+ contextHistory,
4409
4637
  modelOptions
4410
4638
  );
4411
4639
  try {
4412
- return await session.prompt(lastUserMessage.content);
4640
+ return await this.promptSession(
4641
+ session,
4642
+ lastUserMessage.content,
4643
+ stream,
4644
+ onPartialResponse
4645
+ );
4413
4646
  } finally {
4414
4647
  try {
4415
4648
  session.destroy();
@@ -4417,6 +4650,241 @@ If it's in another language, summarize in that language.
4417
4650
  }
4418
4651
  }
4419
4652
  }
4653
+ async generatePersistentResponse(api, systemPrompt, contextHistory, userPrompt, modelOptions, stream, onPartialResponse) {
4654
+ const sessionKey = this.getPersistentSessionKey(systemPrompt, modelOptions);
4655
+ if (this.persistentSessionKey !== sessionKey) {
4656
+ this.destroyPersistentSessions();
4657
+ }
4658
+ if (!this.baseSession && !this.liveSession) {
4659
+ await this.ensureAvailability(api, modelOptions);
4660
+ await this.createPersistentBaseSession(
4661
+ api,
4662
+ systemPrompt,
4663
+ contextHistory,
4664
+ modelOptions
4665
+ );
4666
+ this.persistentSessionKey = sessionKey;
4667
+ }
4668
+ let session = await this.getPersistentLiveSession(
4669
+ api,
4670
+ systemPrompt,
4671
+ contextHistory,
4672
+ modelOptions
4673
+ );
4674
+ const reusedLiveSession = session === this.liveSession && this.isHistoryCompatible(contextHistory, this.consumedTranscript);
4675
+ this.persistentSessionKey = sessionKey;
4676
+ try {
4677
+ const response = await this.promptSession(
4678
+ session,
4679
+ userPrompt,
4680
+ stream,
4681
+ onPartialResponse
4682
+ );
4683
+ this.recordConsumedTranscript(
4684
+ contextHistory,
4685
+ userPrompt,
4686
+ response,
4687
+ reusedLiveSession
4688
+ );
4689
+ return response;
4690
+ } catch (error) {
4691
+ if (!this.isQuotaExceededError(error)) {
4692
+ this.destroyPersistentLiveSession();
4693
+ throw error;
4694
+ }
4695
+ this.destroyPersistentLiveSession();
4696
+ session = await this.getPersistentLiveSession(
4697
+ api,
4698
+ systemPrompt,
4699
+ [],
4700
+ modelOptions
4701
+ );
4702
+ this.persistentSessionKey = sessionKey;
4703
+ try {
4704
+ const response = await this.promptSession(
4705
+ session,
4706
+ userPrompt,
4707
+ stream,
4708
+ onPartialResponse
4709
+ );
4710
+ this.recordConsumedTranscript([], userPrompt, response, false);
4711
+ return response;
4712
+ } catch (retryError) {
4713
+ this.destroyPersistentLiveSession();
4714
+ throw retryError;
4715
+ }
4716
+ }
4717
+ }
4718
+ async ensureAvailability(api, modelOptions) {
4719
+ const availability = await api.availability(modelOptions);
4720
+ if (availability !== "available" && availability !== "downloadable") {
4721
+ throw new Error(
4722
+ `Gemini Nano Prompt API is not ready in this environment. LanguageModel.availability() returned "${availability}". Expected "available" or "downloadable".`
4723
+ );
4724
+ }
4725
+ }
4726
+ async createPersistentBaseSession(api, systemPrompt, contextHistory, modelOptions) {
4727
+ this.baseSession = await this.createSession(
4728
+ api,
4729
+ systemPrompt,
4730
+ [],
4731
+ modelOptions
4732
+ );
4733
+ if (contextHistory.length > 0) {
4734
+ this.liveSession = await this.createSession(
4735
+ api,
4736
+ systemPrompt,
4737
+ contextHistory,
4738
+ modelOptions
4739
+ );
4740
+ this.consumedTranscript = contextHistory.map((message) => ({
4741
+ ...message
4742
+ }));
4743
+ } else if (typeof this.baseSession.clone === "function") {
4744
+ this.liveSession = await this.baseSession.clone();
4745
+ } else {
4746
+ this.liveSession = this.baseSession;
4747
+ }
4748
+ }
4749
+ async getPersistentLiveSession(api, systemPrompt, contextHistory, modelOptions) {
4750
+ if (this.liveSession && this.isHistoryCompatible(contextHistory, this.consumedTranscript)) {
4751
+ return this.liveSession;
4752
+ }
4753
+ if (this.liveSession && this.liveSession !== this.baseSession) {
4754
+ this.destroyPersistentLiveSession();
4755
+ }
4756
+ if (contextHistory.length === 0 && this.baseSession) {
4757
+ if (typeof this.baseSession.clone === "function") {
4758
+ this.liveSession = await this.baseSession.clone();
4759
+ } else {
4760
+ if (this.consumedTranscript.length > 0) {
4761
+ this.destroyPersistentSessions();
4762
+ await this.createPersistentBaseSession(
4763
+ api,
4764
+ systemPrompt,
4765
+ [],
4766
+ modelOptions
4767
+ );
4768
+ return this.liveSession;
4769
+ }
4770
+ this.liveSession = this.baseSession;
4771
+ }
4772
+ return this.liveSession;
4773
+ }
4774
+ if (this.baseSession && typeof this.baseSession.clone === "function") {
4775
+ this.liveSession = await this.createSession(
4776
+ api,
4777
+ systemPrompt,
4778
+ contextHistory,
4779
+ modelOptions
4780
+ );
4781
+ return this.liveSession;
4782
+ }
4783
+ this.destroyPersistentSessions();
4784
+ await this.ensureAvailability(api, modelOptions);
4785
+ await this.createPersistentBaseSessionWithHistory(
4786
+ api,
4787
+ systemPrompt,
4788
+ contextHistory,
4789
+ modelOptions
4790
+ );
4791
+ return this.liveSession;
4792
+ }
4793
+ async createPersistentBaseSessionWithHistory(api, systemPrompt, contextHistory, modelOptions) {
4794
+ this.baseSession = await this.createSession(
4795
+ api,
4796
+ systemPrompt,
4797
+ contextHistory,
4798
+ modelOptions
4799
+ );
4800
+ this.liveSession = this.baseSession;
4801
+ this.consumedTranscript = contextHistory.map((message) => ({
4802
+ ...message
4803
+ }));
4804
+ }
4805
+ recordConsumedTranscript(contextHistory, userPrompt, response, reusedLiveSession) {
4806
+ const priorTranscript = reusedLiveSession ? this.consumedTranscript : contextHistory;
4807
+ this.consumedTranscript = [
4808
+ ...priorTranscript,
4809
+ { role: "user", content: userPrompt },
4810
+ { role: "assistant", content: response }
4811
+ ];
4812
+ }
4813
+ getPersistentSessionKey(systemPrompt, modelOptions) {
4814
+ return JSON.stringify({
4815
+ systemPrompt,
4816
+ modelOptions,
4817
+ initialPrompts: this.initialPrompts,
4818
+ responseLength: this._responseLength
4819
+ });
4820
+ }
4821
+ isHistoryCompatible(left, right) {
4822
+ if (left.length === 0 || right.length === 0) {
4823
+ return left.length === 0 && right.length === 0;
4824
+ }
4825
+ return this.isSuffix(left, right) || this.isSuffix(right, left);
4826
+ }
4827
+ isSuffix(candidate, full) {
4828
+ if (candidate.length > full.length) return false;
4829
+ const offset = full.length - candidate.length;
4830
+ return candidate.every(
4831
+ (message, index) => message.role === full[offset + index].role && message.content === full[offset + index].content
4832
+ );
4833
+ }
4834
+ isQuotaExceededError(error) {
4835
+ return typeof error === "object" && error !== null && "name" in error && error.name === "QuotaExceededError";
4836
+ }
4837
+ destroyPersistentLiveSession() {
4838
+ if (this.liveSession) {
4839
+ this.destroySession(this.liveSession);
4840
+ if (this.liveSession === this.baseSession) {
4841
+ this.baseSession = void 0;
4842
+ }
4843
+ }
4844
+ this.liveSession = void 0;
4845
+ this.consumedTranscript = [];
4846
+ }
4847
+ destroyPersistentSessions() {
4848
+ if (this.liveSession && this.liveSession !== this.baseSession) {
4849
+ this.destroySession(this.liveSession);
4850
+ }
4851
+ if (this.baseSession) {
4852
+ this.destroySession(this.baseSession);
4853
+ }
4854
+ this.baseSession = void 0;
4855
+ this.liveSession = void 0;
4856
+ this.persistentSessionKey = void 0;
4857
+ this.consumedTranscript = [];
4858
+ }
4859
+ destroySession(session) {
4860
+ try {
4861
+ session.destroy();
4862
+ } catch {
4863
+ }
4864
+ }
4865
+ async promptSession(session, prompt, stream, onPartialResponse) {
4866
+ if (stream && typeof session.promptStreaming === "function") {
4867
+ const reader = session.promptStreaming(prompt).getReader();
4868
+ let response2 = "";
4869
+ let streamMode = "unknown";
4870
+ while (true) {
4871
+ const { done, value } = await reader.read();
4872
+ if (done) break;
4873
+ const chunk = String(value ?? "");
4874
+ if (streamMode === "unknown" && response2 !== "") {
4875
+ streamMode = chunk.startsWith(response2) ? "cumulative" : "delta";
4876
+ }
4877
+ const isCumulative = streamMode === "cumulative";
4878
+ const delta = isCumulative ? chunk.slice(response2.length) : chunk;
4879
+ response2 = isCumulative ? chunk : response2 + chunk;
4880
+ if (delta) onPartialResponse(delta);
4881
+ }
4882
+ return response2;
4883
+ }
4884
+ const response = await session.prompt(prompt);
4885
+ onPartialResponse(response);
4886
+ return response;
4887
+ }
4420
4888
  /**
4421
4889
  * Create a new LanguageModel session with structured initial prompts.
4422
4890
  * System instructions, few-shot examples, and conversation history retain
@@ -4511,7 +4979,8 @@ If it's in another language, summarize in that language.
4511
4979
  expectedInputLanguages: options.expectedInputLanguages,
4512
4980
  expectedOutputLanguages: options.expectedOutputLanguages,
4513
4981
  initialPrompts: options.initialPrompts,
4514
- responseLength: options.responseLength
4982
+ responseLength: options.responseLength,
4983
+ sessionMode: options.sessionMode
4515
4984
  });
4516
4985
  }
4517
4986
  getProviderName() {
@@ -5061,6 +5530,9 @@ If it's in another language, summarize in that language.
5061
5530
  let shouldUseResponsesAPI = false;
5062
5531
  if (mcpServers.length > 0 || modelName === MODEL_GPT_6_ASTRA || visionModel === MODEL_GPT_6_ASTRA) {
5063
5532
  shouldUseResponsesAPI = true;
5533
+ } else if (modelName === MODEL_GPT_6_SOL || visionModel === MODEL_GPT_6_SOL || modelName === MODEL_GPT_6_LUNA || visionModel === MODEL_GPT_6_LUNA) {
5534
+ const preference = optimizedOptions.gpt5EndpointPreference || "responses";
5535
+ shouldUseResponsesAPI = preference !== "chat" || optimizedOptions.reasoning_effort !== "none";
5064
5536
  } else if (isResponsesOnlyGPT5Model(modelName)) {
5065
5537
  shouldUseResponsesAPI = true;
5066
5538
  } else if (isOpenAIReasoningModel(modelName)) {
@@ -5107,6 +5579,8 @@ If it's in another language, summarize in that language.
5107
5579
  MODEL_GPT_5_5,
5108
5580
  MODEL_GPT_5_6,
5109
5581
  MODEL_GPT_6_ASTRA,
5582
+ MODEL_GPT_6_SOL,
5583
+ MODEL_GPT_6_LUNA,
5110
5584
  MODEL_GPT_5_6_SOL,
5111
5585
  MODEL_GPT_5_6_TERRA,
5112
5586
  MODEL_GPT_5_6_LUNA,
@@ -6035,6 +6509,7 @@ If it's in another language, summarize in that language.
6035
6509
  getSupportedModels() {
6036
6510
  return [
6037
6511
  MODEL_GROK_4_6,
6512
+ MODEL_GROK_4_7,
6038
6513
  MODEL_GROK_4_5,
6039
6514
  MODEL_GROK_4_3,
6040
6515
  MODEL_GROK_4_20_REASONING,
@@ -6553,7 +7028,7 @@ If it's in another language, summarize in that language.
6553
7028
  mcp: MCP_SUPPORTED_PROVIDERS.has(providerName),
6554
7029
  jsonMode: JSON_MODE_SUPPORTED_PROVIDERS.has(providerName),
6555
7030
  responseLength: true,
6556
- reasoningEffort: providerName === "openai" && model === MODEL_GPT_6_ASTRA ? ["low", "medium", "high", "xhigh", "max"] : providerName === "claude" && model ? [...getClaudeSupportedReasoningEfforts(model)] : providerName === "gemini" && model ? [...getGeminiSupportedReasoningEfforts(model)] : providerName === "kimi" && model ? [...getKimiSupportedReasoningEfforts(model)] : providerName === "deepseek" && model ? [...getDeepSeekSupportedReasoningEfforts(model)] : providerName === "openrouter" && model ? [...getOpenRouterSupportedReasoningEfforts(model)] : providerName === "xai" && model ? [...getXaiSupportedReasoningEfforts(model)] : providerName === "zai" && model ? [...getZaiSupportedReasoningEfforts(model)] : REASONING_EFFORT_BY_PROVIDER[providerName] ?? []
7031
+ reasoningEffort: providerName === "openai" && model === MODEL_GPT_6_ASTRA ? ["low", "medium", "high", "xhigh", "max"] : providerName === "openai" && model === MODEL_GPT_6_SOL ? ["none", "low", "medium", "high", "xhigh", "max"] : providerName === "openai" && model === MODEL_GPT_6_LUNA ? ["none", "low", "medium", "high", "xhigh", "max"] : providerName === "claude" && model ? [...getClaudeSupportedReasoningEfforts(model)] : providerName === "gemini" && model ? [...getGeminiSupportedReasoningEfforts(model)] : providerName === "kimi" && model ? [...getKimiSupportedReasoningEfforts(model)] : providerName === "deepseek" && model ? [...getDeepSeekSupportedReasoningEfforts(model)] : providerName === "openrouter" && model ? [...getOpenRouterSupportedReasoningEfforts(model)] : providerName === "xai" && model ? [...getXaiSupportedReasoningEfforts(model)] : providerName === "zai" && model ? [...getZaiSupportedReasoningEfforts(model)] : REASONING_EFFORT_BY_PROVIDER[providerName] ?? []
6557
7032
  };
6558
7033
  }
6559
7034
  /**