@aituber-onair/chat 0.46.0 → 0.48.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 (119) hide show
  1. package/README.ja.md +31 -17
  2. package/README.md +33 -17
  3. package/dist/cjs/constants/gemini.d.ts +17 -0
  4. package/dist/cjs/constants/gemini.d.ts.map +1 -1
  5. package/dist/cjs/constants/gemini.js +67 -1
  6. package/dist/cjs/constants/gemini.js.map +1 -1
  7. package/dist/cjs/constants/kimi.d.ts +10 -0
  8. package/dist/cjs/constants/kimi.d.ts.map +1 -1
  9. package/dist/cjs/constants/kimi.js +20 -1
  10. package/dist/cjs/constants/kimi.js.map +1 -1
  11. package/dist/cjs/constants/mistral.d.ts +3 -0
  12. package/dist/cjs/constants/mistral.d.ts.map +1 -1
  13. package/dist/cjs/constants/mistral.js +11 -1
  14. package/dist/cjs/constants/mistral.js.map +1 -1
  15. package/dist/cjs/constants/zai.d.ts +2 -0
  16. package/dist/cjs/constants/zai.d.ts.map +1 -1
  17. package/dist/cjs/constants/zai.js +4 -1
  18. package/dist/cjs/constants/zai.js.map +1 -1
  19. package/dist/cjs/services/ChatService.d.ts +2 -2
  20. package/dist/cjs/services/ChatService.d.ts.map +1 -1
  21. package/dist/cjs/services/ChatServiceFactory.d.ts.map +1 -1
  22. package/dist/cjs/services/ChatServiceFactory.js +1 -0
  23. package/dist/cjs/services/ChatServiceFactory.js.map +1 -1
  24. package/dist/cjs/services/providers/ChatServiceProvider.d.ts +9 -2
  25. package/dist/cjs/services/providers/ChatServiceProvider.d.ts.map +1 -1
  26. package/dist/cjs/services/providers/gemini/GeminiChatService.d.ts +8 -2
  27. package/dist/cjs/services/providers/gemini/GeminiChatService.d.ts.map +1 -1
  28. package/dist/cjs/services/providers/gemini/GeminiChatService.js +65 -38
  29. package/dist/cjs/services/providers/gemini/GeminiChatService.js.map +1 -1
  30. package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.d.ts.map +1 -1
  31. package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.js +9 -2
  32. package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.js.map +1 -1
  33. package/dist/cjs/services/providers/gemini/geminiMessageConverter.d.ts +6 -0
  34. package/dist/cjs/services/providers/gemini/geminiMessageConverter.d.ts.map +1 -1
  35. package/dist/cjs/services/providers/gemini/geminiMessageConverter.js +61 -58
  36. package/dist/cjs/services/providers/gemini/geminiMessageConverter.js.map +1 -1
  37. package/dist/cjs/services/providers/kimi/KimiChatService.d.ts +5 -4
  38. package/dist/cjs/services/providers/kimi/KimiChatService.d.ts.map +1 -1
  39. package/dist/cjs/services/providers/kimi/KimiChatService.js +34 -18
  40. package/dist/cjs/services/providers/kimi/KimiChatService.js.map +1 -1
  41. package/dist/cjs/services/providers/kimi/KimiChatServiceProvider.d.ts +1 -0
  42. package/dist/cjs/services/providers/kimi/KimiChatServiceProvider.d.ts.map +1 -1
  43. package/dist/cjs/services/providers/kimi/KimiChatServiceProvider.js +23 -1
  44. package/dist/cjs/services/providers/kimi/KimiChatServiceProvider.js.map +1 -1
  45. package/dist/cjs/services/providers/zai/ZAIChatServiceProvider.d.ts.map +1 -1
  46. package/dist/cjs/services/providers/zai/ZAIChatServiceProvider.js +2 -0
  47. package/dist/cjs/services/providers/zai/ZAIChatServiceProvider.js.map +1 -1
  48. package/dist/cjs/types/chat.d.ts +10 -2
  49. package/dist/cjs/types/chat.d.ts.map +1 -1
  50. package/dist/cjs/types/toolChat.d.ts +20 -0
  51. package/dist/cjs/types/toolChat.d.ts.map +1 -1
  52. package/dist/cjs/utils/openaiCompatibleSse.d.ts +1 -0
  53. package/dist/cjs/utils/openaiCompatibleSse.d.ts.map +1 -1
  54. package/dist/cjs/utils/openaiCompatibleSse.js +48 -5
  55. package/dist/cjs/utils/openaiCompatibleSse.js.map +1 -1
  56. package/dist/cjs/utils/processChatFlow.d.ts +2 -2
  57. package/dist/cjs/utils/processChatFlow.d.ts.map +1 -1
  58. package/dist/cjs/utils/processChatFlow.js +8 -3
  59. package/dist/cjs/utils/processChatFlow.js.map +1 -1
  60. package/dist/esm/constants/gemini.d.ts +17 -0
  61. package/dist/esm/constants/gemini.d.ts.map +1 -1
  62. package/dist/esm/constants/gemini.js +62 -0
  63. package/dist/esm/constants/gemini.js.map +1 -1
  64. package/dist/esm/constants/kimi.d.ts +10 -0
  65. package/dist/esm/constants/kimi.d.ts.map +1 -1
  66. package/dist/esm/constants/kimi.js +17 -0
  67. package/dist/esm/constants/kimi.js.map +1 -1
  68. package/dist/esm/constants/mistral.d.ts +3 -0
  69. package/dist/esm/constants/mistral.d.ts.map +1 -1
  70. package/dist/esm/constants/mistral.js +10 -0
  71. package/dist/esm/constants/mistral.js.map +1 -1
  72. package/dist/esm/constants/zai.d.ts +2 -0
  73. package/dist/esm/constants/zai.d.ts.map +1 -1
  74. package/dist/esm/constants/zai.js +3 -0
  75. package/dist/esm/constants/zai.js.map +1 -1
  76. package/dist/esm/services/ChatService.d.ts +2 -2
  77. package/dist/esm/services/ChatService.d.ts.map +1 -1
  78. package/dist/esm/services/ChatServiceFactory.d.ts.map +1 -1
  79. package/dist/esm/services/ChatServiceFactory.js +1 -0
  80. package/dist/esm/services/ChatServiceFactory.js.map +1 -1
  81. package/dist/esm/services/providers/ChatServiceProvider.d.ts +9 -2
  82. package/dist/esm/services/providers/ChatServiceProvider.d.ts.map +1 -1
  83. package/dist/esm/services/providers/gemini/GeminiChatService.d.ts +8 -2
  84. package/dist/esm/services/providers/gemini/GeminiChatService.d.ts.map +1 -1
  85. package/dist/esm/services/providers/gemini/GeminiChatService.js +66 -39
  86. package/dist/esm/services/providers/gemini/GeminiChatService.js.map +1 -1
  87. package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.d.ts.map +1 -1
  88. package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.js +10 -3
  89. package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.js.map +1 -1
  90. package/dist/esm/services/providers/gemini/geminiMessageConverter.d.ts +6 -0
  91. package/dist/esm/services/providers/gemini/geminiMessageConverter.d.ts.map +1 -1
  92. package/dist/esm/services/providers/gemini/geminiMessageConverter.js +61 -58
  93. package/dist/esm/services/providers/gemini/geminiMessageConverter.js.map +1 -1
  94. package/dist/esm/services/providers/kimi/KimiChatService.d.ts +5 -4
  95. package/dist/esm/services/providers/kimi/KimiChatService.d.ts.map +1 -1
  96. package/dist/esm/services/providers/kimi/KimiChatService.js +36 -20
  97. package/dist/esm/services/providers/kimi/KimiChatService.js.map +1 -1
  98. package/dist/esm/services/providers/kimi/KimiChatServiceProvider.d.ts +1 -0
  99. package/dist/esm/services/providers/kimi/KimiChatServiceProvider.d.ts.map +1 -1
  100. package/dist/esm/services/providers/kimi/KimiChatServiceProvider.js +24 -2
  101. package/dist/esm/services/providers/kimi/KimiChatServiceProvider.js.map +1 -1
  102. package/dist/esm/services/providers/zai/ZAIChatServiceProvider.d.ts.map +1 -1
  103. package/dist/esm/services/providers/zai/ZAIChatServiceProvider.js +3 -1
  104. package/dist/esm/services/providers/zai/ZAIChatServiceProvider.js.map +1 -1
  105. package/dist/esm/types/chat.d.ts +10 -2
  106. package/dist/esm/types/chat.d.ts.map +1 -1
  107. package/dist/esm/types/toolChat.d.ts +20 -0
  108. package/dist/esm/types/toolChat.d.ts.map +1 -1
  109. package/dist/esm/utils/openaiCompatibleSse.d.ts +1 -0
  110. package/dist/esm/utils/openaiCompatibleSse.d.ts.map +1 -1
  111. package/dist/esm/utils/openaiCompatibleSse.js +48 -5
  112. package/dist/esm/utils/openaiCompatibleSse.js.map +1 -1
  113. package/dist/esm/utils/processChatFlow.d.ts +2 -2
  114. package/dist/esm/utils/processChatFlow.d.ts.map +1 -1
  115. package/dist/esm/utils/processChatFlow.js +8 -3
  116. package/dist/esm/utils/processChatFlow.js.map +1 -1
  117. package/dist/umd/aituber-onair-chat.js +344 -131
  118. package/dist/umd/aituber-onair-chat.min.js +8 -8
  119. package/package.json +1 -1
@@ -106,6 +106,8 @@ var AITuberOnAirChat = (() => {
106
106
  MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW: () => MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW,
107
107
  MODEL_GEMINI_3_1_PRO_PREVIEW: () => MODEL_GEMINI_3_1_PRO_PREVIEW,
108
108
  MODEL_GEMINI_3_5_FLASH: () => MODEL_GEMINI_3_5_FLASH,
109
+ MODEL_GEMINI_3_5_FLASH_LITE: () => MODEL_GEMINI_3_5_FLASH_LITE,
110
+ MODEL_GEMINI_3_6_FLASH: () => MODEL_GEMINI_3_6_FLASH,
109
111
  MODEL_GEMINI_3_FLASH_PREVIEW: () => MODEL_GEMINI_3_FLASH_PREVIEW,
110
112
  MODEL_GEMINI_3_PRO_PREVIEW: () => MODEL_GEMINI_3_PRO_PREVIEW,
111
113
  MODEL_GEMINI_NANO: () => MODEL_GEMINI_NANO,
@@ -119,6 +121,8 @@ var AITuberOnAirChat = (() => {
119
121
  MODEL_GLM_4_7_FLASH: () => MODEL_GLM_4_7_FLASH,
120
122
  MODEL_GLM_4_7_FLASHX: () => MODEL_GLM_4_7_FLASHX,
121
123
  MODEL_GLM_5: () => MODEL_GLM_5,
124
+ MODEL_GLM_5V_TURBO: () => MODEL_GLM_5V_TURBO,
125
+ MODEL_GLM_5_1: () => MODEL_GLM_5_1,
122
126
  MODEL_GLM_5_2: () => MODEL_GLM_5_2,
123
127
  MODEL_GLM_5_TURBO: () => MODEL_GLM_5_TURBO,
124
128
  MODEL_GOOGLE_GEMINI_2_5_FLASH: () => MODEL_GOOGLE_GEMINI_2_5_FLASH,
@@ -155,6 +159,10 @@ var AITuberOnAirChat = (() => {
155
159
  MODEL_KIMI_K2_6: () => MODEL_KIMI_K2_6,
156
160
  MODEL_KIMI_K2_7_CODE: () => MODEL_KIMI_K2_7_CODE,
157
161
  MODEL_KIMI_K2_7_CODE_HIGHSPEED: () => MODEL_KIMI_K2_7_CODE_HIGHSPEED,
162
+ MODEL_KIMI_K3: () => MODEL_KIMI_K3,
163
+ MODEL_MINISTRAL_14B_2512: () => MODEL_MINISTRAL_14B_2512,
164
+ MODEL_MINISTRAL_3B_2512: () => MODEL_MINISTRAL_3B_2512,
165
+ MODEL_MINISTRAL_8B_2512: () => MODEL_MINISTRAL_8B_2512,
158
166
  MODEL_MISTRAL_LARGE_2512: () => MODEL_MISTRAL_LARGE_2512,
159
167
  MODEL_MISTRAL_LARGE_LATEST: () => MODEL_MISTRAL_LARGE_LATEST,
160
168
  MODEL_MISTRAL_MEDIUM_2508: () => MODEL_MISTRAL_MEDIUM_2508,
@@ -221,11 +229,16 @@ var AITuberOnAirChat = (() => {
221
229
  allowsReasoningNone: () => allowsReasoningNone,
222
230
  allowsReasoningXHigh: () => allowsReasoningXHigh,
223
231
  buildOpenAICompatibleTools: () => buildOpenAICompatibleTools,
232
+ getDefaultGeminiReasoningEffort: () => getDefaultGeminiReasoningEffort,
224
233
  getDefaultReasoningEffortForGPT5Model: () => getDefaultReasoningEffortForGPT5Model,
225
234
  getDefaultXaiReasoningEffort: () => getDefaultXaiReasoningEffort,
235
+ getGeminiSupportedReasoningEfforts: () => getGeminiSupportedReasoningEfforts,
236
+ getKimiSupportedReasoningEfforts: () => getKimiSupportedReasoningEfforts,
226
237
  getMaxTokensForResponseLength: () => getMaxTokensForResponseLength,
227
238
  installGASFetch: () => installGASFetch,
228
239
  isGPT5Model: () => isGPT5Model,
240
+ isGeminiReasoningEffortModel: () => isGeminiReasoningEffortModel,
241
+ isKimiReasoningEffortModel: () => isKimiReasoningEffortModel,
229
242
  isKimiThinkingRequiredModel: () => isKimiThinkingRequiredModel,
230
243
  isKimiVisionModel: () => isKimiVisionModel,
231
244
  isMistralReasoningEffort: () => isMistralReasoningEffort,
@@ -239,6 +252,7 @@ var AITuberOnAirChat = (() => {
239
252
  isXaiVisionModel: () => isXaiVisionModel,
240
253
  isZaiToolStreamModel: () => isZaiToolStreamModel,
241
254
  isZaiVisionModel: () => isZaiVisionModel,
255
+ normalizeGeminiReasoningEffort: () => normalizeGeminiReasoningEffort,
242
256
  normalizeXaiReasoningEffort: () => normalizeXaiReasoningEffort,
243
257
  parseOpenAICompatibleOneShot: () => parseOpenAICompatibleOneShot,
244
258
  parseOpenAICompatibleTextStream: () => parseOpenAICompatibleTextStream,
@@ -350,7 +364,9 @@ var AITuberOnAirChat = (() => {
350
364
  var ENDPOINT_GEMINI_API = "https://generativelanguage.googleapis.com";
351
365
  var MODEL_GEMMA_4_31B_IT = "gemma-4-31b-it";
352
366
  var MODEL_GEMMA_4_26B_A4B_IT = "gemma-4-26b-a4b-it";
367
+ var MODEL_GEMINI_3_6_FLASH = "gemini-3.6-flash";
353
368
  var MODEL_GEMINI_3_5_FLASH = "gemini-3.5-flash";
369
+ var MODEL_GEMINI_3_5_FLASH_LITE = "gemini-3.5-flash-lite";
354
370
  var MODEL_GEMINI_3_1_PRO_PREVIEW = "gemini-3.1-pro-preview";
355
371
  var MODEL_GEMINI_3_1_FLASH_LITE = "gemini-3.1-flash-lite";
356
372
  var MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW = "gemini-3.1-flash-lite-preview";
@@ -361,7 +377,9 @@ var AITuberOnAirChat = (() => {
361
377
  var MODEL_GEMINI_2_5_FLASH_LITE = "gemini-2.5-flash-lite";
362
378
  var MODEL_GEMINI_2_5_FLASH_LITE_PREVIEW_06_17 = "gemini-2.5-flash-lite-preview-06-17";
363
379
  var GEMINI_RECOMMENDED_MODELS = [
380
+ MODEL_GEMINI_3_6_FLASH,
364
381
  MODEL_GEMINI_3_5_FLASH,
382
+ MODEL_GEMINI_3_5_FLASH_LITE,
365
383
  MODEL_GEMINI_3_1_FLASH_LITE,
366
384
  MODEL_GEMINI_3_1_PRO_PREVIEW,
367
385
  MODEL_GEMINI_3_FLASH_PREVIEW,
@@ -380,6 +398,54 @@ var AITuberOnAirChat = (() => {
380
398
  ...GEMINI_RECOMMENDED_MODELS,
381
399
  ...GEMINI_DEPRECATED_MODELS
382
400
  ];
401
+ var GEMINI_FLASH_REASONING_EFFORTS = [
402
+ "minimal",
403
+ "low",
404
+ "medium",
405
+ "high"
406
+ ];
407
+ var GEMINI_PRO_REASONING_EFFORTS = [
408
+ "low",
409
+ "medium",
410
+ "high"
411
+ ];
412
+ var GEMINI_FLASH_REASONING_EFFORT_MODELS = [
413
+ MODEL_GEMINI_3_6_FLASH,
414
+ MODEL_GEMINI_3_5_FLASH,
415
+ MODEL_GEMINI_3_5_FLASH_LITE,
416
+ MODEL_GEMINI_3_1_FLASH_LITE,
417
+ MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW,
418
+ MODEL_GEMINI_3_FLASH_PREVIEW
419
+ ];
420
+ var GEMINI_PRO_REASONING_EFFORT_MODELS = [
421
+ MODEL_GEMINI_3_1_PRO_PREVIEW,
422
+ MODEL_GEMINI_3_PRO_PREVIEW
423
+ ];
424
+ function getGeminiSupportedReasoningEfforts(model) {
425
+ if (GEMINI_FLASH_REASONING_EFFORT_MODELS.includes(model)) {
426
+ return GEMINI_FLASH_REASONING_EFFORTS;
427
+ }
428
+ if (GEMINI_PRO_REASONING_EFFORT_MODELS.includes(model)) {
429
+ return GEMINI_PRO_REASONING_EFFORTS;
430
+ }
431
+ return [];
432
+ }
433
+ function isGeminiReasoningEffortModel(model) {
434
+ return getGeminiSupportedReasoningEfforts(model).length > 0;
435
+ }
436
+ function getDefaultGeminiReasoningEffort(model) {
437
+ return getGeminiSupportedReasoningEfforts(model)[0];
438
+ }
439
+ function normalizeGeminiReasoningEffort(model, effort) {
440
+ const supported = getGeminiSupportedReasoningEfforts(model);
441
+ if (supported.length === 0) {
442
+ return void 0;
443
+ }
444
+ if (effort && supported.includes(effort)) {
445
+ return effort;
446
+ }
447
+ return supported[0];
448
+ }
383
449
 
384
450
  // src/constants/claude.ts
385
451
  var ENDPOINT_CLAUDE_API = "https://api.anthropic.com/v1/messages";
@@ -493,8 +559,10 @@ var AITuberOnAirChat = (() => {
493
559
  // src/constants/zai.ts
494
560
  var ENDPOINT_ZAI_CHAT_COMPLETIONS_API = "https://api.z.ai/api/paas/v4/chat/completions";
495
561
  var MODEL_GLM_5_2 = "glm-5.2";
562
+ var MODEL_GLM_5_1 = "glm-5.1";
496
563
  var MODEL_GLM_5 = "glm-5";
497
564
  var MODEL_GLM_5_TURBO = "glm-5-turbo";
565
+ var MODEL_GLM_5V_TURBO = "glm-5v-turbo";
498
566
  var MODEL_GLM_4_7 = "glm-4.7";
499
567
  var MODEL_GLM_4_7_FLASHX = "glm-4.7-FlashX";
500
568
  var MODEL_GLM_4_7_FLASH = "glm-4.7-Flash";
@@ -503,6 +571,7 @@ var AITuberOnAirChat = (() => {
503
571
  var MODEL_GLM_4_6V_FLASHX = "glm-4.6V-FlashX";
504
572
  var MODEL_GLM_4_6V_FLASH = "glm-4.6V-Flash";
505
573
  var ZAI_VISION_SUPPORTED_MODELS = [
574
+ MODEL_GLM_5V_TURBO,
506
575
  MODEL_GLM_4_6V,
507
576
  MODEL_GLM_4_6V_FLASHX,
508
577
  MODEL_GLM_4_6V_FLASH
@@ -557,11 +626,16 @@ var AITuberOnAirChat = (() => {
557
626
 
558
627
  // src/constants/kimi.ts
559
628
  var ENDPOINT_KIMI_CHAT_COMPLETIONS_API = "https://api.moonshot.ai/v1/chat/completions";
629
+ var MODEL_KIMI_K3 = "kimi-k3";
560
630
  var MODEL_KIMI_K2_7_CODE = "kimi-k2.7-code";
561
631
  var MODEL_KIMI_K2_7_CODE_HIGHSPEED = "kimi-k2.7-code-highspeed";
562
632
  var MODEL_KIMI_K2_6 = "kimi-k2.6";
563
633
  var MODEL_KIMI_K2_5 = "kimi-k2.5";
634
+ var KIMI_REASONING_EFFORTS_BY_MODEL = {
635
+ [MODEL_KIMI_K3]: ["max"]
636
+ };
564
637
  var KIMI_VISION_SUPPORTED_MODELS = [
638
+ MODEL_KIMI_K3,
565
639
  MODEL_KIMI_K2_7_CODE,
566
640
  MODEL_KIMI_K2_7_CODE_HIGHSPEED,
567
641
  MODEL_KIMI_K2_6,
@@ -577,6 +651,12 @@ var AITuberOnAirChat = (() => {
577
651
  function isKimiThinkingRequiredModel(model) {
578
652
  return KIMI_THINKING_REQUIRED_MODELS.includes(model);
579
653
  }
654
+ function getKimiSupportedReasoningEfforts(model) {
655
+ return KIMI_REASONING_EFFORTS_BY_MODEL[model] ?? [];
656
+ }
657
+ function isKimiReasoningEffortModel(model) {
658
+ return getKimiSupportedReasoningEfforts(model).length > 0;
659
+ }
580
660
 
581
661
  // src/constants/deepseek.ts
582
662
  var DEEPSEEK_API_BASE_URL = "https://api.deepseek.com";
@@ -597,6 +677,9 @@ var AITuberOnAirChat = (() => {
597
677
  // src/constants/mistral.ts
598
678
  var MISTRAL_API_BASE_URL = "https://api.mistral.ai/v1";
599
679
  var ENDPOINT_MISTRAL_CHAT_COMPLETIONS_API = `${MISTRAL_API_BASE_URL}/chat/completions`;
680
+ var MODEL_MINISTRAL_3B_2512 = "ministral-3b-2512";
681
+ var MODEL_MINISTRAL_8B_2512 = "ministral-8b-2512";
682
+ var MODEL_MINISTRAL_14B_2512 = "ministral-14b-2512";
600
683
  var MODEL_MISTRAL_SMALL_LATEST = "mistral-small-latest";
601
684
  var MODEL_MISTRAL_SMALL_2603 = "mistral-small-2603";
602
685
  var MODEL_MISTRAL_MEDIUM_3_5 = "mistral-medium-3-5";
@@ -605,6 +688,9 @@ var AITuberOnAirChat = (() => {
605
688
  var MODEL_MISTRAL_LARGE_2512 = "mistral-large-2512";
606
689
  var MISTRAL_SUPPORTED_MODELS = [
607
690
  MODEL_MISTRAL_SMALL_LATEST,
691
+ MODEL_MINISTRAL_3B_2512,
692
+ MODEL_MINISTRAL_8B_2512,
693
+ MODEL_MINISTRAL_14B_2512,
608
694
  MODEL_MISTRAL_MEDIUM_3_5,
609
695
  MODEL_MISTRAL_LARGE_LATEST,
610
696
  MODEL_MISTRAL_LARGE_2512,
@@ -617,6 +703,9 @@ var AITuberOnAirChat = (() => {
617
703
  ];
618
704
  var MISTRAL_VISION_SUPPORTED_MODELS = [
619
705
  MODEL_MISTRAL_SMALL_LATEST,
706
+ MODEL_MINISTRAL_3B_2512,
707
+ MODEL_MINISTRAL_8B_2512,
708
+ MODEL_MINISTRAL_14B_2512,
620
709
  MODEL_MISTRAL_SMALL_2603,
621
710
  MODEL_MISTRAL_MEDIUM_3_5,
622
711
  MODEL_MISTRAL_MEDIUM_2508,
@@ -1044,6 +1133,8 @@ If it's in another language, summarize in that language.
1044
1133
  async function parseOpenAICompatibleToolStream(res, onPartial, options = {}) {
1045
1134
  const textBlocks = [];
1046
1135
  const toolCallsMap = /* @__PURE__ */ new Map();
1136
+ let fullContent = "";
1137
+ let reasoningContent = "";
1047
1138
  let finishReason;
1048
1139
  let usage;
1049
1140
  const appendTextBlock = options.appendTextBlock ?? StreamTextAccumulator.append;
@@ -1062,14 +1153,23 @@ If it's in another language, summarize in that language.
1062
1153
  if (content) {
1063
1154
  onPartial(content);
1064
1155
  appendTextBlock(textBlocks, content);
1156
+ fullContent += content;
1157
+ }
1158
+ const reasoning = extractTextContent(delta?.reasoning_content);
1159
+ if (reasoning) {
1160
+ reasoningContent += reasoning;
1065
1161
  }
1066
1162
  if (delta?.tool_calls) {
1067
1163
  delta.tool_calls.forEach((c) => {
1068
1164
  const entry = toolCallsMap.get(c.index) ?? {
1069
1165
  id: c.id,
1166
+ type: c.type,
1070
1167
  name: c.function?.name,
1071
1168
  args: ""
1072
1169
  };
1170
+ if (c.id) entry.id = c.id;
1171
+ if (c.type) entry.type = c.type;
1172
+ if (c.function?.name) entry.name = c.function.name;
1073
1173
  entry.args += c.function?.arguments || "";
1074
1174
  toolCallsMap.set(c.index, entry);
1075
1175
  });
@@ -1082,17 +1182,35 @@ If it's in another language, summarize in that language.
1082
1182
  input: safeParseToolCallInput(e.args, options.onJsonError)
1083
1183
  }));
1084
1184
  const blocks = [...textBlocks, ...toolBlocks];
1185
+ const assistantToolCalls = Array.from(
1186
+ toolCallsMap.entries()
1187
+ ).sort((a, b) => a[0] - b[0]).map(([_, entry]) => ({
1188
+ id: entry.id,
1189
+ type: "function",
1190
+ function: {
1191
+ name: entry.name,
1192
+ arguments: entry.args
1193
+ }
1194
+ }));
1195
+ const assistantMessage = {
1196
+ role: "assistant",
1197
+ content: fullContent,
1198
+ ...reasoningContent ? { reasoning_content: reasoningContent } : {},
1199
+ ...assistantToolCalls.length > 0 ? { tool_calls: assistantToolCalls } : {}
1200
+ };
1085
1201
  return {
1086
1202
  blocks,
1087
1203
  stop_reason: toolBlocks.length ? "tool_use" : "end",
1088
1204
  truncated: finishReason === "length",
1089
1205
  finish_reason: finishReason,
1090
- usage
1206
+ usage,
1207
+ ...options.preserveAssistantMessage ? { assistant_message: assistantMessage } : {}
1091
1208
  };
1092
1209
  }
1093
1210
  function parseOpenAICompatibleOneShot(data, options = {}) {
1094
1211
  const choice = data?.choices?.[0];
1095
1212
  const blocks = [];
1213
+ const content = extractTextContent(choice?.message?.content);
1096
1214
  if (choice?.message?.tool_calls?.length) {
1097
1215
  choice.message.tool_calls.forEach(
1098
1216
  (c) => blocks.push({
@@ -1105,18 +1223,21 @@ If it's in another language, summarize in that language.
1105
1223
  )
1106
1224
  })
1107
1225
  );
1108
- } else {
1109
- const content = extractTextContent(choice?.message?.content);
1110
- if (content) {
1111
- blocks.push({ type: "text", text: content });
1112
- }
1113
- }
1226
+ } else if (content) {
1227
+ blocks.push({ type: "text", text: content });
1228
+ }
1229
+ const assistantMessage = choice?.message ? {
1230
+ ...choice.message,
1231
+ role: "assistant",
1232
+ content
1233
+ } : void 0;
1114
1234
  return {
1115
1235
  blocks,
1116
1236
  stop_reason: choice?.finish_reason === "tool_calls" || blocks.some((b) => b.type === "tool_use") ? "tool_use" : "end",
1117
1237
  truncated: choice?.finish_reason === "length",
1118
1238
  finish_reason: choice?.finish_reason,
1119
- usage: data?.usage
1239
+ usage: data?.usage,
1240
+ ...options.preserveAssistantMessage ? { assistant_message: assistantMessage } : {}
1120
1241
  };
1121
1242
  }
1122
1243
 
@@ -1144,8 +1265,15 @@ If it's in another language, summarize in that language.
1144
1265
  // src/utils/processChatFlow.ts
1145
1266
  async function processChatWithOptionalTools(options) {
1146
1267
  if (!options.hasTools) {
1147
- const full = await options.runWithoutTools();
1148
- await options.onCompleteResponse(full);
1268
+ const result2 = await options.runWithoutTools();
1269
+ if (typeof result2 === "string") {
1270
+ await options.onCompleteResponse(result2);
1271
+ return;
1272
+ }
1273
+ const full = StreamTextAccumulator.getFullText(
1274
+ result2.blocks
1275
+ );
1276
+ await options.onCompleteResponse(full, result2);
1149
1277
  return;
1150
1278
  }
1151
1279
  const result = await options.runWithTools();
@@ -1156,7 +1284,7 @@ If it's in another language, summarize in that language.
1156
1284
  const full = StreamTextAccumulator.getFullText(
1157
1285
  result.blocks
1158
1286
  );
1159
- await options.onCompleteResponse(full);
1287
+ await options.onCompleteResponse(full, result);
1160
1288
  return;
1161
1289
  }
1162
1290
  throw new Error(options.toolErrorMessage);
@@ -2715,41 +2843,26 @@ If it's in another language, summarize in that language.
2715
2843
  gemini.push({ role: currentRole, parts: [...currentParts] });
2716
2844
  currentParts = [];
2717
2845
  }
2846
+ currentRole = null;
2718
2847
  };
2719
2848
  for (const msg of messages) {
2720
2849
  const role = mapRoleToGemini(msg.role);
2721
2850
  if (msg.tool_calls) {
2722
2851
  pushCurrent();
2723
- for (const call of msg.tool_calls) {
2724
- options.callIdMap?.set(call.id, call.function.name);
2852
+ const parts = msg.tool_calls.map(
2853
+ (call) => createFunctionCallPart(call, options)
2854
+ );
2855
+ if (parts.length > 0) {
2725
2856
  gemini.push({
2726
2857
  role: "model",
2727
- parts: [
2728
- {
2729
- functionCall: {
2730
- name: call.function.name,
2731
- args: JSON.parse(call.function.arguments || "{}")
2732
- }
2733
- }
2734
- ]
2858
+ parts
2735
2859
  });
2736
2860
  }
2737
2861
  continue;
2738
2862
  }
2739
2863
  if (msg.role === "tool") {
2740
2864
  pushCurrent();
2741
- const funcName = msg.name ?? options.callIdMap?.get(msg.tool_call_id) ?? "result";
2742
- gemini.push({
2743
- role: "user",
2744
- parts: [
2745
- {
2746
- functionResponse: {
2747
- name: funcName,
2748
- response: normalizeToolResult(safeJsonParse2(msg.content))
2749
- }
2750
- }
2751
- ]
2752
- });
2865
+ appendFunctionResponse(gemini, createFunctionResponsePart(msg, options));
2753
2866
  continue;
2754
2867
  }
2755
2868
  if (role !== currentRole) pushCurrent();
@@ -2765,47 +2878,41 @@ If it's in another language, summarize in that language.
2765
2878
  const geminiMessages = [];
2766
2879
  let currentRole = null;
2767
2880
  let currentParts = [];
2881
+ const pushCurrent = () => {
2882
+ if (currentRole && currentParts.length > 0) {
2883
+ geminiMessages.push({
2884
+ role: currentRole,
2885
+ parts: [...currentParts]
2886
+ });
2887
+ currentParts = [];
2888
+ }
2889
+ currentRole = null;
2890
+ };
2768
2891
  for (const msg of messages) {
2769
2892
  const role = mapRoleToGemini(msg.role);
2770
2893
  if (msg.tool_calls) {
2771
- for (const call of msg.tool_calls) {
2894
+ pushCurrent();
2895
+ const parts = msg.tool_calls.map(
2896
+ (call) => createFunctionCallPart(call, options)
2897
+ );
2898
+ if (parts.length > 0) {
2772
2899
  geminiMessages.push({
2773
2900
  role: "model",
2774
- parts: [
2775
- {
2776
- functionCall: {
2777
- name: call.function.name,
2778
- args: JSON.parse(call.function.arguments || "{}")
2779
- }
2780
- }
2781
- ]
2901
+ parts
2782
2902
  });
2783
2903
  }
2784
2904
  continue;
2785
2905
  }
2786
2906
  if (msg.role === "tool") {
2787
- const funcName = msg.name ?? options.callIdMap?.get(msg.tool_call_id) ?? "result";
2788
- geminiMessages.push({
2789
- role: "user",
2790
- parts: [
2791
- {
2792
- functionResponse: {
2793
- name: funcName,
2794
- response: normalizeToolResult(
2795
- safeJsonParse2(msg.content)
2796
- )
2797
- }
2798
- }
2799
- ]
2800
- });
2907
+ pushCurrent();
2908
+ appendFunctionResponse(
2909
+ geminiMessages,
2910
+ createFunctionResponsePart(msg, options)
2911
+ );
2801
2912
  continue;
2802
2913
  }
2803
2914
  if (role !== currentRole && currentParts.length > 0) {
2804
- geminiMessages.push({
2805
- role: currentRole,
2806
- parts: [...currentParts]
2807
- });
2808
- currentParts = [];
2915
+ pushCurrent();
2809
2916
  }
2810
2917
  currentRole = role;
2811
2918
  if (typeof msg.content === "string") {
@@ -2833,14 +2940,43 @@ If it's in another language, summarize in that language.
2833
2940
  }
2834
2941
  }
2835
2942
  }
2836
- if (currentRole && currentParts.length > 0) {
2837
- geminiMessages.push({
2838
- role: currentRole,
2839
- parts: [...currentParts]
2840
- });
2841
- }
2943
+ pushCurrent();
2842
2944
  return geminiMessages;
2843
2945
  }
2946
+ function createFunctionCallPart(call, options) {
2947
+ options.callIdMap?.set(call.id, call.function.name);
2948
+ const context = options.functionCallContextMap?.get(call.id);
2949
+ const part = {
2950
+ functionCall: {
2951
+ ...context?.providerCallId ? { id: context.providerCallId } : {},
2952
+ name: call.function.name,
2953
+ args: JSON.parse(call.function.arguments || "{}")
2954
+ }
2955
+ };
2956
+ if (context?.thoughtSignature) {
2957
+ part.thoughtSignature = context.thoughtSignature;
2958
+ }
2959
+ return part;
2960
+ }
2961
+ function createFunctionResponsePart(msg, options) {
2962
+ const toolCallId = msg.tool_call_id;
2963
+ const context = options.functionCallContextMap?.get(toolCallId);
2964
+ const functionResponse = {
2965
+ ...context?.providerCallId ? { id: context.providerCallId } : {},
2966
+ name: msg.name ?? context?.name ?? options.callIdMap?.get(toolCallId) ?? "result",
2967
+ response: normalizeToolResult(safeJsonParse2(msg.content))
2968
+ };
2969
+ return { functionResponse };
2970
+ }
2971
+ function appendFunctionResponse(messages, part) {
2972
+ const previous = messages[messages.length - 1];
2973
+ const isFunctionResponseGroup = previous?.role === "user" && previous.parts.every((item) => item.functionResponse);
2974
+ if (isFunctionResponseGroup) {
2975
+ previous.parts.push(part);
2976
+ return;
2977
+ }
2978
+ messages.push({ role: "user", parts: [part] });
2979
+ }
2844
2980
  function safeJsonParse2(str) {
2845
2981
  try {
2846
2982
  return JSON.parse(str);
@@ -2918,16 +3054,19 @@ If it's in another language, summarize in that language.
2918
3054
  * @param tools Array of tool definitions
2919
3055
  * @param mcpServers Array of MCP server configurations
2920
3056
  */
2921
- constructor(apiKey, model = MODEL_GEMINI_3_1_FLASH_LITE, visionModel = MODEL_GEMINI_3_1_FLASH_LITE, tools = [], mcpServers = [], responseLength) {
3057
+ constructor(apiKey, model = MODEL_GEMINI_3_1_FLASH_LITE, visionModel = MODEL_GEMINI_3_1_FLASH_LITE, tools = [], mcpServers = [], responseLength, reasoningEffort) {
2922
3058
  /** Provider name */
2923
3059
  this.provider = "gemini";
2924
3060
  this.mcpToolSchemas = [];
2925
3061
  this.mcpSchemasInitialized = false;
2926
3062
  /** id(OpenAI) → name(Gemini) mapping */
2927
3063
  this.callIdMap = /* @__PURE__ */ new Map();
3064
+ /** Common tool id → Gemini function-call metadata required for replay. */
3065
+ this.functionCallContextMap = /* @__PURE__ */ new Map();
2928
3066
  this.apiKey = apiKey;
2929
3067
  this.model = model;
2930
3068
  this.responseLength = responseLength;
3069
+ this.reasoningEffort = reasoningEffort;
2931
3070
  if (!GEMINI_VISION_SUPPORTED_MODELS.includes(visionModel)) {
2932
3071
  throw new Error(
2933
3072
  `Model ${visionModel} does not support vision capabilities.`
@@ -2940,8 +3079,21 @@ If it's in another language, summarize in that language.
2940
3079
  isGemma4Model(model) {
2941
3080
  return /^gemma-4-/.test(model);
2942
3081
  }
2943
- shouldMinimizeThinking(model) {
2944
- return model === MODEL_GEMINI_3_5_FLASH || this.isGemma4Model(model);
3082
+ resolveThinkingConfig(model) {
3083
+ const effort = normalizeGeminiReasoningEffort(model, this.reasoningEffort);
3084
+ if (effort) {
3085
+ return {
3086
+ includeThoughts: false,
3087
+ thinkingLevel: effort.toUpperCase()
3088
+ };
3089
+ }
3090
+ if (this.isGemma4Model(model)) {
3091
+ return {
3092
+ includeThoughts: false,
3093
+ thinkingLevel: "MINIMAL"
3094
+ };
3095
+ }
3096
+ return void 0;
2945
3097
  }
2946
3098
  shouldExposeTextPart(part, model) {
2947
3099
  if (!part.text) return false;
@@ -2959,7 +3111,8 @@ If it's in another language, summarize in that language.
2959
3111
  functionCallingConfig: "function_calling_config",
2960
3112
  functionDeclarations: "function_declarations",
2961
3113
  functionCall: "function_call",
2962
- functionResponse: "function_response"
3114
+ functionResponse: "function_response",
3115
+ thoughtSignature: "thought_signature"
2963
3116
  };
2964
3117
  if (Array.isArray(obj)) return obj.map((v) => this.adaptKeysForApi(v));
2965
3118
  if (obj && typeof obj === "object") {
@@ -3119,10 +3272,12 @@ If it's in another language, summarize in that language.
3119
3272
  const contents = hasVision ? await convertVisionMessagesToGeminiFormat(
3120
3273
  messages,
3121
3274
  {
3122
- callIdMap: this.callIdMap
3275
+ callIdMap: this.callIdMap,
3276
+ functionCallContextMap: this.functionCallContextMap
3123
3277
  }
3124
3278
  ) : convertMessagesToGeminiFormat(messages, {
3125
- callIdMap: this.callIdMap
3279
+ callIdMap: this.callIdMap,
3280
+ functionCallContextMap: this.functionCallContextMap
3126
3281
  });
3127
3282
  const body = {
3128
3283
  contents,
@@ -3130,11 +3285,9 @@ If it's in another language, summarize in that language.
3130
3285
  maxOutputTokens: maxTokens !== void 0 ? maxTokens : getMaxTokensForResponseLength(this.responseLength)
3131
3286
  }
3132
3287
  };
3133
- if (this.shouldMinimizeThinking(model)) {
3134
- body.generationConfig.thinkingConfig = {
3135
- includeThoughts: false,
3136
- thinkingLevel: "MINIMAL"
3137
- };
3288
+ const thinkingConfig = this.resolveThinkingConfig(model);
3289
+ if (thinkingConfig) {
3290
+ body.generationConfig.thinkingConfig = thinkingConfig;
3138
3291
  }
3139
3292
  let activeMCPToolSchemas = [];
3140
3293
  if (this.mcpServers.length > 0) {
@@ -3191,6 +3344,32 @@ If it's in another language, summarize in that language.
3191
3344
  throw error;
3192
3345
  }
3193
3346
  }
3347
+ createFunctionCallBlock(part) {
3348
+ const functionCall = part.functionCall ?? part.function_call;
3349
+ if (!functionCall) return void 0;
3350
+ const toolUseId = functionCall.id ?? this.genUUID();
3351
+ this.callIdMap.set(toolUseId, functionCall.name);
3352
+ this.functionCallContextMap.set(toolUseId, {
3353
+ name: functionCall.name,
3354
+ providerCallId: functionCall.id,
3355
+ thoughtSignature: part.thoughtSignature ?? part.thought_signature
3356
+ });
3357
+ return {
3358
+ type: "tool_use",
3359
+ id: toolUseId,
3360
+ name: functionCall.name,
3361
+ input: functionCall.args ?? {}
3362
+ };
3363
+ }
3364
+ createFunctionResponseBlock(part) {
3365
+ const functionResponse = part.functionResponse ?? part.function_response;
3366
+ if (!functionResponse) return void 0;
3367
+ return {
3368
+ type: "tool_result",
3369
+ tool_use_id: functionResponse.id ?? functionResponse.name,
3370
+ content: JSON.stringify(functionResponse.response)
3371
+ };
3372
+ }
3194
3373
  /* ────────────────────────────────────────────────────────── */
3195
3374
  /* Convert NDJSON stream to common format */
3196
3375
  /* ────────────────────────────────────────────────────────── */
@@ -3214,21 +3393,10 @@ If it's in another language, summarize in that language.
3214
3393
  onPartial(part.text);
3215
3394
  StreamTextAccumulator.addTextBlock(textBlocks, part.text);
3216
3395
  }
3217
- if (part.functionCall) {
3218
- toolBlocks.push({
3219
- type: "tool_use",
3220
- id: this.genUUID(),
3221
- name: part.functionCall.name,
3222
- input: part.functionCall.args ?? {}
3223
- });
3224
- }
3225
- if (part.functionResponse) {
3226
- toolBlocks.push({
3227
- type: "tool_result",
3228
- tool_use_id: part.functionResponse.name,
3229
- content: JSON.stringify(part.functionResponse.response)
3230
- });
3231
- }
3396
+ const functionCallBlock = this.createFunctionCallBlock(part);
3397
+ if (functionCallBlock) toolBlocks.push(functionCallBlock);
3398
+ const functionResponseBlock = this.createFunctionResponseBlock(part);
3399
+ if (functionResponseBlock) toolBlocks.push(functionResponseBlock);
3232
3400
  }
3233
3401
  }
3234
3402
  };
@@ -3268,21 +3436,10 @@ If it's in another language, summarize in that language.
3268
3436
  if (this.shouldExposeTextPart(part, model)) {
3269
3437
  textBlocks.push({ type: "text", text: part.text });
3270
3438
  }
3271
- if (part.functionCall) {
3272
- toolBlocks.push({
3273
- type: "tool_use",
3274
- id: this.genUUID(),
3275
- name: part.functionCall.name,
3276
- input: part.functionCall.args ?? {}
3277
- });
3278
- }
3279
- if (part.functionResponse) {
3280
- toolBlocks.push({
3281
- type: "tool_result",
3282
- tool_use_id: part.functionResponse.name,
3283
- content: JSON.stringify(part.functionResponse.response)
3284
- });
3285
- }
3439
+ const functionCallBlock = this.createFunctionCallBlock(part);
3440
+ if (functionCallBlock) toolBlocks.push(functionCallBlock);
3441
+ const functionResponseBlock = this.createFunctionResponseBlock(part);
3442
+ if (functionResponseBlock) toolBlocks.push(functionResponseBlock);
3286
3443
  }
3287
3444
  }
3288
3445
  const blocks = [...textBlocks, ...toolBlocks];
@@ -3332,21 +3489,28 @@ If it's in another language, summarize in that language.
3332
3489
  * @returns GeminiChatService instance
3333
3490
  */
3334
3491
  createChatService(options) {
3492
+ const model = options.model || this.getDefaultModel();
3493
+ if (options.reasoning_effort !== void 0 && !isGeminiReasoningEffortModel(model)) {
3494
+ throw new Error(
3495
+ `Model ${model} does not support Gemini reasoning_effort. Use it with Gemini 3 thinkingLevel models; Gemini 2.5 models use thinkingBudget instead.`
3496
+ );
3497
+ }
3335
3498
  const visionModel = resolveVisionModel({
3336
- model: options.model,
3499
+ model,
3337
3500
  visionModel: options.visionModel,
3338
3501
  defaultModel: this.getDefaultModel(),
3339
3502
  defaultVisionModel: this.getDefaultModel(),
3340
- supportsVisionForModel: (model) => this.supportsVisionForModel(model),
3503
+ supportsVisionForModel: (model2) => this.supportsVisionForModel(model2),
3341
3504
  validate: "resolved"
3342
3505
  });
3343
3506
  return new GeminiChatService(
3344
3507
  options.apiKey,
3345
- options.model || this.getDefaultModel(),
3508
+ model,
3346
3509
  visionModel,
3347
3510
  options.tools || [],
3348
3511
  options.mcpServers || [],
3349
- options.responseLength
3512
+ options.responseLength,
3513
+ normalizeGeminiReasoningEffort(model, options.reasoning_effort)
3350
3514
  );
3351
3515
  }
3352
3516
  /**
@@ -3554,7 +3718,7 @@ If it's in another language, summarize in that language.
3554
3718
  * @param model Name of the model to use
3555
3719
  * @param visionModel Name of the vision model
3556
3720
  */
3557
- constructor(apiKey, model = MODEL_KIMI_K2_6, visionModel = MODEL_KIMI_K2_6, tools, endpoint = ENDPOINT_KIMI_CHAT_COMPLETIONS_API, responseLength, responseFormat, thinking) {
3721
+ constructor(apiKey, model = MODEL_KIMI_K2_6, visionModel = MODEL_KIMI_K2_6, tools, endpoint = ENDPOINT_KIMI_CHAT_COMPLETIONS_API, responseLength, responseFormat, thinking, reasoningEffort) {
3558
3722
  /** Provider name */
3559
3723
  this.provider = "kimi";
3560
3724
  this.apiKey = apiKey;
@@ -3563,7 +3727,14 @@ If it's in another language, summarize in that language.
3563
3727
  this.endpoint = endpoint;
3564
3728
  this.responseLength = responseLength;
3565
3729
  this.responseFormat = responseFormat;
3566
- this.thinking = thinking ?? { type: "enabled" };
3730
+ this.thinking = thinking;
3731
+ const supportedReasoningEfforts = getKimiSupportedReasoningEfforts(model);
3732
+ if (reasoningEffort !== void 0 && !supportedReasoningEfforts.includes(reasoningEffort)) {
3733
+ throw new Error(
3734
+ `Model ${model} does not support reasoning_effort: ${reasoningEffort}.`
3735
+ );
3736
+ }
3737
+ this.reasoningEffort = reasoningEffort ?? (isKimiReasoningEffortModel(model) ? supportedReasoningEfforts[0] : void 0);
3567
3738
  this.visionModel = visionModel;
3568
3739
  }
3569
3740
  /**
@@ -3584,10 +3755,7 @@ If it's in another language, summarize in that language.
3584
3755
  async processChat(messages, onPartialResponse, onCompleteResponse) {
3585
3756
  await processChatWithOptionalTools({
3586
3757
  hasTools: this.tools.length > 0,
3587
- runWithoutTools: async () => {
3588
- const res = await this.callKimi(messages, this.model, true);
3589
- return this.handleStream(res, onPartialResponse);
3590
- },
3758
+ runWithoutTools: () => this.chatOnce(messages, true, onPartialResponse),
3591
3759
  runWithTools: () => this.chatOnce(messages, true, onPartialResponse),
3592
3760
  onCompleteResponse,
3593
3761
  toolErrorMessage: "processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."
@@ -3604,10 +3772,7 @@ If it's in another language, summarize in that language.
3604
3772
  }
3605
3773
  await processChatWithOptionalTools({
3606
3774
  hasTools: this.tools.length > 0,
3607
- runWithoutTools: async () => {
3608
- const res = await this.callKimi(messages, this.visionModel, true);
3609
- return this.handleStream(res, onPartialResponse);
3610
- },
3775
+ runWithoutTools: () => this.visionChatOnce(messages, true, onPartialResponse),
3611
3776
  runWithTools: () => this.visionChatOnce(messages, true, onPartialResponse),
3612
3777
  onCompleteResponse,
3613
3778
  toolErrorMessage: "processVisionChat received tool_calls. ChatProcessor must use visionChatOnce() loop when tools are enabled."
@@ -3660,11 +3825,18 @@ If it's in another language, summarize in that language.
3660
3825
  };
3661
3826
  const tokenLimit = maxTokens !== void 0 ? maxTokens : getMaxTokensForResponseLength(this.responseLength);
3662
3827
  if (tokenLimit !== void 0) {
3663
- body.max_tokens = tokenLimit;
3828
+ if (isKimiReasoningEffortModel(model)) {
3829
+ body.max_completion_tokens = tokenLimit;
3830
+ } else {
3831
+ body.max_tokens = tokenLimit;
3832
+ }
3664
3833
  }
3665
3834
  if (this.responseFormat) {
3666
3835
  body.response_format = this.responseFormat;
3667
3836
  }
3837
+ if (isKimiReasoningEffortModel(model)) {
3838
+ body.reasoning_effort = this.reasoningEffort ?? "max";
3839
+ }
3668
3840
  const effectiveThinking = this.resolveEffectiveThinking(model);
3669
3841
  if (effectiveThinking) {
3670
3842
  if (this.isSelfHostedEndpoint()) {
@@ -3689,6 +3861,14 @@ If it's in another language, summarize in that language.
3689
3861
  return value.replace(/\/+$/, "");
3690
3862
  }
3691
3863
  resolveEffectiveThinking(model) {
3864
+ if (isKimiReasoningEffortModel(model)) {
3865
+ if (this.thinking) {
3866
+ throw new Error(
3867
+ `Model ${model} uses reasoning_effort and does not support the K2.x thinking option.`
3868
+ );
3869
+ }
3870
+ return void 0;
3871
+ }
3692
3872
  if (isKimiThinkingRequiredModel(model)) {
3693
3873
  if (this.thinking?.type === "disabled") {
3694
3874
  throw new Error(
@@ -3700,21 +3880,17 @@ If it's in another language, summarize in that language.
3700
3880
  if (this.tools.length > 0) {
3701
3881
  return { type: "disabled" };
3702
3882
  }
3703
- return this.thinking;
3883
+ return this.thinking ?? { type: "enabled" };
3704
3884
  }
3705
3885
  buildToolsDefinition() {
3706
3886
  return buildOpenAICompatibleTools(this.tools, "chat-completions");
3707
3887
  }
3708
- async handleStream(res, onPartial) {
3709
- return parseOpenAICompatibleTextStream(res, onPartial, {
3710
- onJsonError: (payload) => console.debug("Failed to parse SSE data:", payload)
3711
- });
3712
- }
3713
3888
  /**
3714
3889
  * Parse streaming response with tool support
3715
3890
  */
3716
3891
  async parseStream(res, onPartial) {
3717
3892
  return parseOpenAICompatibleToolStream(res, onPartial, {
3893
+ preserveAssistantMessage: true,
3718
3894
  onJsonError: (payload) => console.debug("Failed to parse SSE data:", payload)
3719
3895
  });
3720
3896
  }
@@ -3722,7 +3898,9 @@ If it's in another language, summarize in that language.
3722
3898
  * Parse non-streaming response
3723
3899
  */
3724
3900
  parseOneShot(data) {
3725
- return parseOpenAICompatibleOneShot(data);
3901
+ return parseOpenAICompatibleOneShot(data, {
3902
+ preserveAssistantMessage: true
3903
+ });
3726
3904
  }
3727
3905
  };
3728
3906
 
@@ -3747,6 +3925,10 @@ If it's in another language, summarize in that language.
3747
3925
  });
3748
3926
  const tools = options.tools;
3749
3927
  const thinking = this.resolveThinking(model, tools, options.thinking);
3928
+ const reasoningEffort = this.resolveReasoningEffort(
3929
+ model,
3930
+ options.reasoning_effort
3931
+ );
3750
3932
  return new KimiChatService(
3751
3933
  options.apiKey,
3752
3934
  model,
@@ -3755,7 +3937,8 @@ If it's in another language, summarize in that language.
3755
3937
  endpoint,
3756
3938
  options.responseLength,
3757
3939
  options.responseFormat,
3758
- thinking
3940
+ thinking,
3941
+ reasoningEffort
3759
3942
  );
3760
3943
  }
3761
3944
  /**
@@ -3769,6 +3952,7 @@ If it's in another language, summarize in that language.
3769
3952
  */
3770
3953
  getSupportedModels() {
3771
3954
  return [
3955
+ MODEL_KIMI_K3,
3772
3956
  MODEL_KIMI_K2_7_CODE,
3773
3957
  MODEL_KIMI_K2_7_CODE_HIGHSPEED,
3774
3958
  MODEL_KIMI_K2_6,
@@ -3822,6 +4006,14 @@ If it's in another language, summarize in that language.
3822
4006
  return value.replace(/\/+$/, "");
3823
4007
  }
3824
4008
  resolveThinking(model, tools, thinking) {
4009
+ if (isKimiReasoningEffortModel(model)) {
4010
+ if (thinking) {
4011
+ throw new Error(
4012
+ `Model ${model} uses reasoning_effort and does not support the K2.x thinking option.`
4013
+ );
4014
+ }
4015
+ return void 0;
4016
+ }
3825
4017
  if (isKimiThinkingRequiredModel(model)) {
3826
4018
  if (thinking?.type === "disabled") {
3827
4019
  throw new Error(
@@ -3835,6 +4027,24 @@ If it's in another language, summarize in that language.
3835
4027
  }
3836
4028
  return thinking ?? this.defaultThinking;
3837
4029
  }
4030
+ resolveReasoningEffort(model, reasoningEffort) {
4031
+ const supported = getKimiSupportedReasoningEfforts(model);
4032
+ if (supported.length === 0) {
4033
+ if (reasoningEffort !== void 0) {
4034
+ throw new Error(
4035
+ `Model ${model} does not support the reasoning_effort option.`
4036
+ );
4037
+ }
4038
+ return void 0;
4039
+ }
4040
+ const resolved = reasoningEffort ?? supported[0];
4041
+ if (!supported.includes(resolved)) {
4042
+ throw new Error(
4043
+ `Model ${model} supports reasoning_effort values: ${supported.join(", ")}.`
4044
+ );
4045
+ }
4046
+ return resolved;
4047
+ }
3838
4048
  };
3839
4049
 
3840
4050
  // src/services/providers/mistral/MistralChatService.ts
@@ -5155,8 +5365,10 @@ If it's in another language, summarize in that language.
5155
5365
  getSupportedModels() {
5156
5366
  return [
5157
5367
  MODEL_GLM_5_2,
5368
+ MODEL_GLM_5_1,
5158
5369
  MODEL_GLM_5,
5159
5370
  MODEL_GLM_5_TURBO,
5371
+ MODEL_GLM_5V_TURBO,
5160
5372
  MODEL_GLM_4_7,
5161
5373
  MODEL_GLM_4_7_FLASHX,
5162
5374
  MODEL_GLM_4_7_FLASH,
@@ -5239,6 +5451,7 @@ If it's in another language, summarize in that language.
5239
5451
  ]);
5240
5452
  var REASONING_EFFORT_BY_PROVIDER = {
5241
5453
  openai: ["none", "minimal", "low", "medium", "high", "xhigh", "max"],
5454
+ gemini: ["minimal", "low", "medium", "high"],
5242
5455
  openrouter: ["none", "minimal", "low", "medium", "high"],
5243
5456
  mistral: ["low", "medium", "high"],
5244
5457
  plamo: ["none", "medium"],