@aituber-onair/chat 0.48.0 → 0.49.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 +106 -14
  2. package/README.md +113 -14
  3. package/dist/cjs/constants/claude.d.ts +15 -0
  4. package/dist/cjs/constants/claude.d.ts.map +1 -1
  5. package/dist/cjs/constants/claude.js +61 -1
  6. package/dist/cjs/constants/claude.js.map +1 -1
  7. package/dist/cjs/constants/kimi.d.ts +5 -1
  8. package/dist/cjs/constants/kimi.d.ts.map +1 -1
  9. package/dist/cjs/constants/kimi.js +8 -1
  10. package/dist/cjs/constants/kimi.js.map +1 -1
  11. package/dist/cjs/constants/openrouter.d.ts +12 -0
  12. package/dist/cjs/constants/openrouter.d.ts.map +1 -1
  13. package/dist/cjs/constants/openrouter.js +24 -1
  14. package/dist/cjs/constants/openrouter.js.map +1 -1
  15. package/dist/cjs/index.d.ts +1 -1
  16. package/dist/cjs/index.d.ts.map +1 -1
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/services/ChatServiceFactory.d.ts.map +1 -1
  19. package/dist/cjs/services/ChatServiceFactory.js +9 -1
  20. package/dist/cjs/services/ChatServiceFactory.js.map +1 -1
  21. package/dist/cjs/services/providers/ChatServiceProvider.d.ts +15 -3
  22. package/dist/cjs/services/providers/ChatServiceProvider.d.ts.map +1 -1
  23. package/dist/cjs/services/providers/claude/ClaudeChatService.d.ts +3 -1
  24. package/dist/cjs/services/providers/claude/ClaudeChatService.d.ts.map +1 -1
  25. package/dist/cjs/services/providers/claude/ClaudeChatService.js +51 -4
  26. package/dist/cjs/services/providers/claude/ClaudeChatService.js.map +1 -1
  27. package/dist/cjs/services/providers/claude/ClaudeChatServiceProvider.d.ts.map +1 -1
  28. package/dist/cjs/services/providers/claude/ClaudeChatServiceProvider.js +13 -2
  29. package/dist/cjs/services/providers/claude/ClaudeChatServiceProvider.js.map +1 -1
  30. package/dist/cjs/services/providers/claude/claudeMessageConverter.d.ts.map +1 -1
  31. package/dist/cjs/services/providers/claude/claudeMessageConverter.js +7 -1
  32. package/dist/cjs/services/providers/claude/claudeMessageConverter.js.map +1 -1
  33. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.d.ts +7 -2
  34. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.d.ts.map +1 -1
  35. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.js +83 -30
  36. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.js.map +1 -1
  37. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.d.ts.map +1 -1
  38. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.js +1 -0
  39. package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.js.map +1 -1
  40. package/dist/cjs/services/providers/kimi/KimiChatService.d.ts.map +1 -1
  41. package/dist/cjs/services/providers/kimi/KimiChatService.js +3 -5
  42. package/dist/cjs/services/providers/kimi/KimiChatService.js.map +1 -1
  43. package/dist/cjs/services/providers/kimi/KimiChatServiceProvider.d.ts.map +1 -1
  44. package/dist/cjs/services/providers/kimi/KimiChatServiceProvider.js +1 -1
  45. package/dist/cjs/services/providers/kimi/KimiChatServiceProvider.js.map +1 -1
  46. package/dist/cjs/services/providers/openrouter/OpenRouterChatService.d.ts.map +1 -1
  47. package/dist/cjs/services/providers/openrouter/OpenRouterChatService.js +34 -15
  48. package/dist/cjs/services/providers/openrouter/OpenRouterChatService.js.map +1 -1
  49. package/dist/cjs/services/providers/openrouter/OpenRouterChatServiceProvider.d.ts.map +1 -1
  50. package/dist/cjs/services/providers/openrouter/OpenRouterChatServiceProvider.js +13 -0
  51. package/dist/cjs/services/providers/openrouter/OpenRouterChatServiceProvider.js.map +1 -1
  52. package/dist/cjs/types/chat.d.ts +2 -0
  53. package/dist/cjs/types/chat.d.ts.map +1 -1
  54. package/dist/cjs/types/toolChat.d.ts +2 -3
  55. package/dist/cjs/types/toolChat.d.ts.map +1 -1
  56. package/dist/cjs/utils/openaiCompatibleSse.d.ts +1 -0
  57. package/dist/cjs/utils/openaiCompatibleSse.d.ts.map +1 -1
  58. package/dist/cjs/utils/openaiCompatibleSse.js +22 -0
  59. package/dist/cjs/utils/openaiCompatibleSse.js.map +1 -1
  60. package/dist/esm/constants/claude.d.ts +15 -0
  61. package/dist/esm/constants/claude.d.ts.map +1 -1
  62. package/dist/esm/constants/claude.js +56 -0
  63. package/dist/esm/constants/claude.js.map +1 -1
  64. package/dist/esm/constants/kimi.d.ts +5 -1
  65. package/dist/esm/constants/kimi.d.ts.map +1 -1
  66. package/dist/esm/constants/kimi.js +7 -1
  67. package/dist/esm/constants/kimi.js.map +1 -1
  68. package/dist/esm/constants/openrouter.d.ts +12 -0
  69. package/dist/esm/constants/openrouter.d.ts.map +1 -1
  70. package/dist/esm/constants/openrouter.js +22 -0
  71. package/dist/esm/constants/openrouter.js.map +1 -1
  72. package/dist/esm/index.d.ts +1 -1
  73. package/dist/esm/index.d.ts.map +1 -1
  74. package/dist/esm/index.js.map +1 -1
  75. package/dist/esm/services/ChatServiceFactory.d.ts.map +1 -1
  76. package/dist/esm/services/ChatServiceFactory.js +9 -1
  77. package/dist/esm/services/ChatServiceFactory.js.map +1 -1
  78. package/dist/esm/services/providers/ChatServiceProvider.d.ts +15 -3
  79. package/dist/esm/services/providers/ChatServiceProvider.d.ts.map +1 -1
  80. package/dist/esm/services/providers/claude/ClaudeChatService.d.ts +3 -1
  81. package/dist/esm/services/providers/claude/ClaudeChatService.d.ts.map +1 -1
  82. package/dist/esm/services/providers/claude/ClaudeChatService.js +52 -5
  83. package/dist/esm/services/providers/claude/ClaudeChatService.js.map +1 -1
  84. package/dist/esm/services/providers/claude/ClaudeChatServiceProvider.d.ts.map +1 -1
  85. package/dist/esm/services/providers/claude/ClaudeChatServiceProvider.js +14 -3
  86. package/dist/esm/services/providers/claude/ClaudeChatServiceProvider.js.map +1 -1
  87. package/dist/esm/services/providers/claude/claudeMessageConverter.d.ts.map +1 -1
  88. package/dist/esm/services/providers/claude/claudeMessageConverter.js +7 -1
  89. package/dist/esm/services/providers/claude/claudeMessageConverter.js.map +1 -1
  90. package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.d.ts +7 -2
  91. package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.d.ts.map +1 -1
  92. package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.js +84 -31
  93. package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.js.map +1 -1
  94. package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.d.ts.map +1 -1
  95. package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.js +1 -0
  96. package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.js.map +1 -1
  97. package/dist/esm/services/providers/kimi/KimiChatService.d.ts.map +1 -1
  98. package/dist/esm/services/providers/kimi/KimiChatService.js +4 -6
  99. package/dist/esm/services/providers/kimi/KimiChatService.js.map +1 -1
  100. package/dist/esm/services/providers/kimi/KimiChatServiceProvider.d.ts.map +1 -1
  101. package/dist/esm/services/providers/kimi/KimiChatServiceProvider.js +2 -2
  102. package/dist/esm/services/providers/kimi/KimiChatServiceProvider.js.map +1 -1
  103. package/dist/esm/services/providers/openrouter/OpenRouterChatService.d.ts.map +1 -1
  104. package/dist/esm/services/providers/openrouter/OpenRouterChatService.js +35 -16
  105. package/dist/esm/services/providers/openrouter/OpenRouterChatService.js.map +1 -1
  106. package/dist/esm/services/providers/openrouter/OpenRouterChatServiceProvider.d.ts.map +1 -1
  107. package/dist/esm/services/providers/openrouter/OpenRouterChatServiceProvider.js +14 -1
  108. package/dist/esm/services/providers/openrouter/OpenRouterChatServiceProvider.js.map +1 -1
  109. package/dist/esm/types/chat.d.ts +2 -0
  110. package/dist/esm/types/chat.d.ts.map +1 -1
  111. package/dist/esm/types/toolChat.d.ts +2 -3
  112. package/dist/esm/types/toolChat.d.ts.map +1 -1
  113. package/dist/esm/utils/openaiCompatibleSse.d.ts +1 -0
  114. package/dist/esm/utils/openaiCompatibleSse.d.ts.map +1 -1
  115. package/dist/esm/utils/openaiCompatibleSse.js +22 -0
  116. package/dist/esm/utils/openaiCompatibleSse.js.map +1 -1
  117. package/dist/umd/aituber-onair-chat.js +300 -50
  118. package/dist/umd/aituber-onair-chat.min.js +9 -11
  119. package/package.json +1 -1
@@ -75,6 +75,7 @@ var AITuberOnAirChat = (() => {
75
75
  MODEL_ANTHROPIC_CLAUDE_4_5_HAIKU: () => MODEL_ANTHROPIC_CLAUDE_4_5_HAIKU,
76
76
  MODEL_ANTHROPIC_CLAUDE_HAIKU_LATEST: () => MODEL_ANTHROPIC_CLAUDE_HAIKU_LATEST,
77
77
  MODEL_ANTHROPIC_CLAUDE_OPUS_4: () => MODEL_ANTHROPIC_CLAUDE_OPUS_4,
78
+ MODEL_ANTHROPIC_CLAUDE_OPUS_5: () => MODEL_ANTHROPIC_CLAUDE_OPUS_5,
78
79
  MODEL_ANTHROPIC_CLAUDE_SONNET_4: () => MODEL_ANTHROPIC_CLAUDE_SONNET_4,
79
80
  MODEL_ANTHROPIC_CLAUDE_SONNET_LATEST: () => MODEL_ANTHROPIC_CLAUDE_SONNET_LATEST,
80
81
  MODEL_CLAUDE_3_5_HAIKU: () => MODEL_CLAUDE_3_5_HAIKU,
@@ -90,6 +91,7 @@ var AITuberOnAirChat = (() => {
90
91
  MODEL_CLAUDE_4_8_OPUS: () => MODEL_CLAUDE_4_8_OPUS,
91
92
  MODEL_CLAUDE_4_OPUS: () => MODEL_CLAUDE_4_OPUS,
92
93
  MODEL_CLAUDE_4_SONNET: () => MODEL_CLAUDE_4_SONNET,
94
+ MODEL_CLAUDE_5_OPUS: () => MODEL_CLAUDE_5_OPUS,
93
95
  MODEL_CLAUDE_5_SONNET: () => MODEL_CLAUDE_5_SONNET,
94
96
  MODEL_DEEPSEEK_CHAT: () => MODEL_DEEPSEEK_CHAT,
95
97
  MODEL_DEEPSEEK_REASONER: () => MODEL_DEEPSEEK_REASONER,
@@ -128,6 +130,8 @@ var AITuberOnAirChat = (() => {
128
130
  MODEL_GOOGLE_GEMINI_2_5_FLASH: () => MODEL_GOOGLE_GEMINI_2_5_FLASH,
129
131
  MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE_PREVIEW_09_2025: () => MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE_PREVIEW_09_2025,
130
132
  MODEL_GOOGLE_GEMINI_2_5_PRO: () => MODEL_GOOGLE_GEMINI_2_5_PRO,
133
+ MODEL_GOOGLE_GEMINI_3_5_FLASH_LITE: () => MODEL_GOOGLE_GEMINI_3_5_FLASH_LITE,
134
+ MODEL_GOOGLE_GEMINI_3_6_FLASH: () => MODEL_GOOGLE_GEMINI_3_6_FLASH,
131
135
  MODEL_GOOGLE_GEMINI_FLASH_LATEST: () => MODEL_GOOGLE_GEMINI_FLASH_LATEST,
132
136
  MODEL_GOOGLE_GEMINI_PRO_LATEST: () => MODEL_GOOGLE_GEMINI_PRO_LATEST,
133
137
  MODEL_GPT_4O: () => MODEL_GPT_4O,
@@ -160,6 +164,8 @@ var AITuberOnAirChat = (() => {
160
164
  MODEL_KIMI_K2_7_CODE: () => MODEL_KIMI_K2_7_CODE,
161
165
  MODEL_KIMI_K2_7_CODE_HIGHSPEED: () => MODEL_KIMI_K2_7_CODE_HIGHSPEED,
162
166
  MODEL_KIMI_K3: () => MODEL_KIMI_K3,
167
+ MODEL_KWAIPILOT_KAT_CODER_AIR_V2_5: () => MODEL_KWAIPILOT_KAT_CODER_AIR_V2_5,
168
+ MODEL_KWAIPILOT_KAT_CODER_PRO_V2_5: () => MODEL_KWAIPILOT_KAT_CODER_PRO_V2_5,
163
169
  MODEL_MINISTRAL_14B_2512: () => MODEL_MINISTRAL_14B_2512,
164
170
  MODEL_MINISTRAL_3B_2512: () => MODEL_MINISTRAL_3B_2512,
165
171
  MODEL_MINISTRAL_8B_2512: () => MODEL_MINISTRAL_8B_2512,
@@ -171,6 +177,7 @@ var AITuberOnAirChat = (() => {
171
177
  MODEL_MISTRAL_SMALL_LATEST: () => MODEL_MISTRAL_SMALL_LATEST,
172
178
  MODEL_MOONSHOTAI_KIMI_K2_5: () => MODEL_MOONSHOTAI_KIMI_K2_5,
173
179
  MODEL_MOONSHOTAI_KIMI_K2_7_CODE: () => MODEL_MOONSHOTAI_KIMI_K2_7_CODE,
180
+ MODEL_MOONSHOTAI_KIMI_K3: () => MODEL_MOONSHOTAI_KIMI_K3,
174
181
  MODEL_MOONSHOTAI_KIMI_LATEST: () => MODEL_MOONSHOTAI_KIMI_LATEST,
175
182
  MODEL_O1: () => MODEL_O1,
176
183
  MODEL_O1_MINI: () => MODEL_O1_MINI,
@@ -182,14 +189,20 @@ var AITuberOnAirChat = (() => {
182
189
  MODEL_OPENAI_GPT_5_1_CODEX: () => MODEL_OPENAI_GPT_5_1_CODEX,
183
190
  MODEL_OPENAI_GPT_5_5: () => MODEL_OPENAI_GPT_5_5,
184
191
  MODEL_OPENAI_GPT_5_5_PRO: () => MODEL_OPENAI_GPT_5_5_PRO,
192
+ MODEL_OPENAI_GPT_5_6_LUNA: () => MODEL_OPENAI_GPT_5_6_LUNA,
193
+ MODEL_OPENAI_GPT_5_6_SOL: () => MODEL_OPENAI_GPT_5_6_SOL,
194
+ MODEL_OPENAI_GPT_5_6_TERRA: () => MODEL_OPENAI_GPT_5_6_TERRA,
185
195
  MODEL_OPENAI_GPT_5_MINI: () => MODEL_OPENAI_GPT_5_MINI,
186
196
  MODEL_OPENAI_GPT_5_NANO: () => MODEL_OPENAI_GPT_5_NANO,
187
197
  MODEL_OPENAI_GPT_LATEST: () => MODEL_OPENAI_GPT_LATEST,
188
198
  MODEL_OPENAI_GPT_MINI_LATEST: () => MODEL_OPENAI_GPT_MINI_LATEST,
189
199
  MODEL_OPENROUTER_AUTO: () => MODEL_OPENROUTER_AUTO,
200
+ MODEL_OPENROUTER_AUTO_BETA: () => MODEL_OPENROUTER_AUTO_BETA,
190
201
  MODEL_OPENROUTER_FUSION: () => MODEL_OPENROUTER_FUSION,
191
202
  MODEL_PLAMO_2_2_PRIME: () => MODEL_PLAMO_2_2_PRIME,
192
203
  MODEL_PLAMO_3_0_PRIME: () => MODEL_PLAMO_3_0_PRIME,
204
+ MODEL_XAI_GROK_4_5: () => MODEL_XAI_GROK_4_5,
205
+ MODEL_XAI_GROK_LATEST: () => MODEL_XAI_GROK_LATEST,
193
206
  MODEL_ZAI_GLM_4_5_AIR: () => MODEL_ZAI_GLM_4_5_AIR,
194
207
  MODEL_ZAI_GLM_4_5_AIR_FREE: () => MODEL_ZAI_GLM_4_5_AIR_FREE,
195
208
  MODEL_ZAI_GLM_4_7_FLASH: () => MODEL_ZAI_GLM_4_7_FLASH,
@@ -229,13 +242,17 @@ var AITuberOnAirChat = (() => {
229
242
  allowsReasoningNone: () => allowsReasoningNone,
230
243
  allowsReasoningXHigh: () => allowsReasoningXHigh,
231
244
  buildOpenAICompatibleTools: () => buildOpenAICompatibleTools,
245
+ getClaudeSupportedReasoningEfforts: () => getClaudeSupportedReasoningEfforts,
246
+ getDefaultClaudeReasoningEffort: () => getDefaultClaudeReasoningEffort,
232
247
  getDefaultGeminiReasoningEffort: () => getDefaultGeminiReasoningEffort,
248
+ getDefaultKimiReasoningEffort: () => getDefaultKimiReasoningEffort,
233
249
  getDefaultReasoningEffortForGPT5Model: () => getDefaultReasoningEffortForGPT5Model,
234
250
  getDefaultXaiReasoningEffort: () => getDefaultXaiReasoningEffort,
235
251
  getGeminiSupportedReasoningEfforts: () => getGeminiSupportedReasoningEfforts,
236
252
  getKimiSupportedReasoningEfforts: () => getKimiSupportedReasoningEfforts,
237
253
  getMaxTokensForResponseLength: () => getMaxTokensForResponseLength,
238
254
  installGASFetch: () => installGASFetch,
255
+ isClaudeReasoningEffortModel: () => isClaudeReasoningEffortModel,
239
256
  isGPT5Model: () => isGPT5Model,
240
257
  isGeminiReasoningEffortModel: () => isGeminiReasoningEffortModel,
241
258
  isKimiReasoningEffortModel: () => isKimiReasoningEffortModel,
@@ -252,6 +269,7 @@ var AITuberOnAirChat = (() => {
252
269
  isXaiVisionModel: () => isXaiVisionModel,
253
270
  isZaiToolStreamModel: () => isZaiToolStreamModel,
254
271
  isZaiVisionModel: () => isZaiVisionModel,
272
+ normalizeClaudeReasoningEffort: () => normalizeClaudeReasoningEffort,
255
273
  normalizeGeminiReasoningEffort: () => normalizeGeminiReasoningEffort,
256
274
  normalizeXaiReasoningEffort: () => normalizeXaiReasoningEffort,
257
275
  parseOpenAICompatibleOneShot: () => parseOpenAICompatibleOneShot,
@@ -463,6 +481,30 @@ var AITuberOnAirChat = (() => {
463
481
  var MODEL_CLAUDE_4_7_OPUS = "claude-opus-4-7";
464
482
  var MODEL_CLAUDE_4_8_OPUS = "claude-opus-4-8";
465
483
  var MODEL_CLAUDE_5_SONNET = "claude-sonnet-5";
484
+ var MODEL_CLAUDE_5_OPUS = "claude-opus-5";
485
+ var CLAUDE_STANDARD_REASONING_EFFORTS = [
486
+ "low",
487
+ "medium",
488
+ "high"
489
+ ];
490
+ var CLAUDE_MAX_REASONING_EFFORTS = [
491
+ ...CLAUDE_STANDARD_REASONING_EFFORTS,
492
+ "max"
493
+ ];
494
+ var CLAUDE_XHIGH_REASONING_EFFORTS = [
495
+ ...CLAUDE_STANDARD_REASONING_EFFORTS,
496
+ "xhigh",
497
+ "max"
498
+ ];
499
+ var CLAUDE_REASONING_EFFORTS_BY_MODEL = {
500
+ [MODEL_CLAUDE_4_5_OPUS]: CLAUDE_STANDARD_REASONING_EFFORTS,
501
+ [MODEL_CLAUDE_4_6_SONNET]: CLAUDE_MAX_REASONING_EFFORTS,
502
+ [MODEL_CLAUDE_4_6_OPUS]: CLAUDE_MAX_REASONING_EFFORTS,
503
+ [MODEL_CLAUDE_4_7_OPUS]: CLAUDE_XHIGH_REASONING_EFFORTS,
504
+ [MODEL_CLAUDE_4_8_OPUS]: CLAUDE_XHIGH_REASONING_EFFORTS,
505
+ [MODEL_CLAUDE_5_SONNET]: CLAUDE_XHIGH_REASONING_EFFORTS,
506
+ [MODEL_CLAUDE_5_OPUS]: CLAUDE_XHIGH_REASONING_EFFORTS
507
+ };
466
508
  var CLAUDE_VISION_SUPPORTED_MODELS = [
467
509
  MODEL_CLAUDE_3_HAIKU,
468
510
  MODEL_CLAUDE_4_SONNET,
@@ -474,19 +516,47 @@ var AITuberOnAirChat = (() => {
474
516
  MODEL_CLAUDE_4_6_OPUS,
475
517
  MODEL_CLAUDE_4_7_OPUS,
476
518
  MODEL_CLAUDE_4_8_OPUS,
477
- MODEL_CLAUDE_5_SONNET
519
+ MODEL_CLAUDE_5_SONNET,
520
+ MODEL_CLAUDE_5_OPUS
478
521
  ];
522
+ function getClaudeSupportedReasoningEfforts(model) {
523
+ return CLAUDE_REASONING_EFFORTS_BY_MODEL[model] ?? [];
524
+ }
525
+ function isClaudeReasoningEffortModel(model) {
526
+ return getClaudeSupportedReasoningEfforts(model).length > 0;
527
+ }
528
+ function getDefaultClaudeReasoningEffort(model) {
529
+ return isClaudeReasoningEffortModel(model) ? "high" : void 0;
530
+ }
531
+ function normalizeClaudeReasoningEffort(model, effort) {
532
+ const supported = getClaudeSupportedReasoningEfforts(model);
533
+ if (supported.length === 0) {
534
+ return void 0;
535
+ }
536
+ if (!effort) {
537
+ return getDefaultClaudeReasoningEffort(model);
538
+ }
539
+ if (supported.includes(effort)) {
540
+ return effort;
541
+ }
542
+ return "high";
543
+ }
479
544
 
480
545
  // src/constants/openrouter.ts
481
546
  var ENDPOINT_OPENROUTER_API = "https://openrouter.ai/api/v1/chat/completions";
482
547
  var MODEL_OPENROUTER_AUTO = "openrouter/auto";
548
+ var MODEL_OPENROUTER_AUTO_BETA = "openrouter/auto-beta";
483
549
  var MODEL_OPENROUTER_FUSION = "openrouter/fusion";
484
550
  var MODEL_GPT_OSS_20B_FREE = "openai/gpt-oss-20b:free";
551
+ var MODEL_MOONSHOTAI_KIMI_K3 = "moonshotai/kimi-k3";
485
552
  var MODEL_MOONSHOTAI_KIMI_K2_7_CODE = "moonshotai/kimi-k2.7-code";
486
553
  var MODEL_MOONSHOTAI_KIMI_K2_5 = "moonshotai/kimi-k2.5";
487
554
  var MODEL_MOONSHOTAI_KIMI_LATEST = "~moonshotai/kimi-latest";
488
555
  var MODEL_OPENAI_GPT_LATEST = "~openai/gpt-latest";
489
556
  var MODEL_OPENAI_GPT_MINI_LATEST = "~openai/gpt-mini-latest";
557
+ var MODEL_OPENAI_GPT_5_6_SOL = "openai/gpt-5.6-sol";
558
+ var MODEL_OPENAI_GPT_5_6_TERRA = "openai/gpt-5.6-terra";
559
+ var MODEL_OPENAI_GPT_5_6_LUNA = "openai/gpt-5.6-luna";
490
560
  var MODEL_OPENAI_GPT_5_5_PRO = "openai/gpt-5.5-pro";
491
561
  var MODEL_OPENAI_GPT_5_5 = "openai/gpt-5.5";
492
562
  var MODEL_OPENAI_GPT_5_1_CHAT = "openai/gpt-5.1-chat";
@@ -498,6 +568,7 @@ var AITuberOnAirChat = (() => {
498
568
  var MODEL_OPENAI_GPT_4_1_NANO = "openai/gpt-4.1-nano";
499
569
  var MODEL_ANTHROPIC_CLAUDE_SONNET_LATEST = "~anthropic/claude-sonnet-latest";
500
570
  var MODEL_ANTHROPIC_CLAUDE_HAIKU_LATEST = "~anthropic/claude-haiku-latest";
571
+ var MODEL_ANTHROPIC_CLAUDE_OPUS_5 = "anthropic/claude-opus-5";
501
572
  var MODEL_ANTHROPIC_CLAUDE_OPUS_4 = "anthropic/claude-opus-4";
502
573
  var MODEL_ANTHROPIC_CLAUDE_SONNET_4 = "anthropic/claude-sonnet-4";
503
574
  var MODEL_ANTHROPIC_CLAUDE_3_7_SONNET = "anthropic/claude-3.7-sonnet";
@@ -505,6 +576,8 @@ var AITuberOnAirChat = (() => {
505
576
  var MODEL_ANTHROPIC_CLAUDE_4_5_HAIKU = "anthropic/claude-haiku-4.5";
506
577
  var MODEL_GOOGLE_GEMINI_PRO_LATEST = "~google/gemini-pro-latest";
507
578
  var MODEL_GOOGLE_GEMINI_FLASH_LATEST = "~google/gemini-flash-latest";
579
+ var MODEL_GOOGLE_GEMINI_3_6_FLASH = "google/gemini-3.6-flash";
580
+ var MODEL_GOOGLE_GEMINI_3_5_FLASH_LITE = "google/gemini-3.5-flash-lite";
508
581
  var MODEL_GOOGLE_GEMINI_2_5_PRO = "google/gemini-2.5-pro";
509
582
  var MODEL_GOOGLE_GEMINI_2_5_FLASH = "google/gemini-2.5-flash";
510
583
  var MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE_PREVIEW_09_2025 = "google/gemini-2.5-flash-lite-preview-09-2025";
@@ -512,14 +585,23 @@ var AITuberOnAirChat = (() => {
512
585
  var MODEL_ZAI_GLM_4_7_FLASH = "z-ai/glm-4.7-flash";
513
586
  var MODEL_ZAI_GLM_4_5_AIR = "z-ai/glm-4.5-air";
514
587
  var MODEL_ZAI_GLM_4_5_AIR_FREE = "z-ai/glm-4.5-air:free";
588
+ var MODEL_KWAIPILOT_KAT_CODER_AIR_V2_5 = "kwaipilot/kat-coder-air-v2.5";
589
+ var MODEL_KWAIPILOT_KAT_CODER_PRO_V2_5 = "kwaipilot/kat-coder-pro-v2.5";
590
+ var MODEL_XAI_GROK_LATEST = "~x-ai/grok-latest";
591
+ var MODEL_XAI_GROK_4_5 = "x-ai/grok-4.5";
515
592
  var OPENROUTER_FREE_MODELS = [
516
593
  MODEL_GPT_OSS_20B_FREE,
517
594
  MODEL_ZAI_GLM_4_5_AIR_FREE
518
595
  ];
519
596
  var OPENROUTER_VISION_SUPPORTED_MODELS = [
597
+ MODEL_OPENROUTER_AUTO_BETA,
598
+ MODEL_MOONSHOTAI_KIMI_K3,
520
599
  MODEL_MOONSHOTAI_KIMI_LATEST,
521
600
  MODEL_OPENAI_GPT_LATEST,
522
601
  MODEL_OPENAI_GPT_MINI_LATEST,
602
+ MODEL_OPENAI_GPT_5_6_SOL,
603
+ MODEL_OPENAI_GPT_5_6_TERRA,
604
+ MODEL_OPENAI_GPT_5_6_LUNA,
523
605
  MODEL_OPENAI_GPT_5_5_PRO,
524
606
  MODEL_OPENAI_GPT_5_5,
525
607
  MODEL_OPENAI_GPT_5_1_CHAT,
@@ -531,17 +613,22 @@ var AITuberOnAirChat = (() => {
531
613
  MODEL_OPENAI_GPT_4_1_NANO,
532
614
  MODEL_ANTHROPIC_CLAUDE_SONNET_LATEST,
533
615
  MODEL_ANTHROPIC_CLAUDE_HAIKU_LATEST,
616
+ MODEL_ANTHROPIC_CLAUDE_OPUS_5,
534
617
  MODEL_ANTHROPIC_CLAUDE_OPUS_4,
535
618
  MODEL_ANTHROPIC_CLAUDE_SONNET_4,
536
619
  MODEL_ANTHROPIC_CLAUDE_3_7_SONNET,
537
620
  MODEL_ANTHROPIC_CLAUDE_4_5_HAIKU,
538
621
  MODEL_GOOGLE_GEMINI_PRO_LATEST,
539
622
  MODEL_GOOGLE_GEMINI_FLASH_LATEST,
623
+ MODEL_GOOGLE_GEMINI_3_6_FLASH,
624
+ MODEL_GOOGLE_GEMINI_3_5_FLASH_LITE,
540
625
  MODEL_GOOGLE_GEMINI_2_5_PRO,
541
626
  MODEL_GOOGLE_GEMINI_2_5_FLASH,
542
627
  MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE_PREVIEW_09_2025,
543
628
  MODEL_MOONSHOTAI_KIMI_K2_7_CODE,
544
- MODEL_MOONSHOTAI_KIMI_K2_5
629
+ MODEL_MOONSHOTAI_KIMI_K2_5,
630
+ MODEL_XAI_GROK_LATEST,
631
+ MODEL_XAI_GROK_4_5
545
632
  ];
546
633
  var OPENROUTER_FREE_RATE_LIMIT_PER_MINUTE = 20;
547
634
  var OPENROUTER_FREE_DAILY_LIMIT_LOW_CREDITS = 50;
@@ -632,7 +719,7 @@ var AITuberOnAirChat = (() => {
632
719
  var MODEL_KIMI_K2_6 = "kimi-k2.6";
633
720
  var MODEL_KIMI_K2_5 = "kimi-k2.5";
634
721
  var KIMI_REASONING_EFFORTS_BY_MODEL = {
635
- [MODEL_KIMI_K3]: ["max"]
722
+ [MODEL_KIMI_K3]: ["low", "high", "max"]
636
723
  };
637
724
  var KIMI_VISION_SUPPORTED_MODELS = [
638
725
  MODEL_KIMI_K3,
@@ -654,6 +741,9 @@ var AITuberOnAirChat = (() => {
654
741
  function getKimiSupportedReasoningEfforts(model) {
655
742
  return KIMI_REASONING_EFFORTS_BY_MODEL[model] ?? [];
656
743
  }
744
+ function getDefaultKimiReasoningEffort(model) {
745
+ return model === MODEL_KIMI_K3 ? "max" : void 0;
746
+ }
657
747
  function isKimiReasoningEffortModel(model) {
658
748
  return getKimiSupportedReasoningEfforts(model).length > 0;
659
749
  }
@@ -1090,6 +1180,15 @@ If it's in another language, summarize in that language.
1090
1180
  return "";
1091
1181
  }).join("");
1092
1182
  };
1183
+ var throwIfApiError = (data) => {
1184
+ const choice = data.choices?.[0];
1185
+ const error = data.error ?? choice?.error;
1186
+ if (!error && choice?.finish_reason !== "error") {
1187
+ return;
1188
+ }
1189
+ const message = typeof error === "string" ? error : typeof error?.message === "string" ? error.message : "The provider ended the response with an error.";
1190
+ throw new Error(`Provider response error: ${message}`);
1191
+ };
1093
1192
  var forEachSsePayload = async (res, onPayload) => {
1094
1193
  const reader = res.body?.getReader();
1095
1194
  if (!reader) {
@@ -1122,6 +1221,9 @@ If it's in another language, summarize in that language.
1122
1221
  await forEachSsePayload(res, (payload) => {
1123
1222
  const json = parseJsonPayload(payload, options.onJsonError);
1124
1223
  if (!json) return;
1224
+ if (options.throwOnApiError) {
1225
+ throwIfApiError(json);
1226
+ }
1125
1227
  const content = extractTextContent(json.choices?.[0]?.delta?.content);
1126
1228
  if (content) {
1127
1229
  onPartial(content);
@@ -1141,6 +1243,9 @@ If it's in another language, summarize in that language.
1141
1243
  await forEachSsePayload(res, (payload) => {
1142
1244
  const json = parseJsonPayload(payload, options.onJsonError);
1143
1245
  if (!json) return;
1246
+ if (options.throwOnApiError) {
1247
+ throwIfApiError(json);
1248
+ }
1144
1249
  const choice = json.choices?.[0];
1145
1250
  if (typeof choice?.finish_reason === "string") {
1146
1251
  finishReason = choice.finish_reason;
@@ -1208,6 +1313,9 @@ If it's in another language, summarize in that language.
1208
1313
  };
1209
1314
  }
1210
1315
  function parseOpenAICompatibleOneShot(data, options = {}) {
1316
+ if (options.throwOnApiError) {
1317
+ throwIfApiError(data);
1318
+ }
1211
1319
  const choice = data?.choices?.[0];
1212
1320
  const blocks = [];
1213
1321
  const content = extractTextContent(choice?.message?.content);
@@ -1515,11 +1623,17 @@ If it's in another language, summarize in that language.
1515
1623
  function convertMessagesToClaudeFormat(messages) {
1516
1624
  return messages.map((msg) => ({
1517
1625
  role: mapRoleToClaude(msg.role),
1518
- content: msg.content
1626
+ content: msg.provider_content ?? msg.content
1519
1627
  }));
1520
1628
  }
1521
1629
  function convertVisionMessagesToClaudeFormat(messages) {
1522
1630
  return messages.map((msg) => {
1631
+ if (msg.provider_content) {
1632
+ return {
1633
+ role: mapRoleToClaude(msg.role),
1634
+ content: msg.provider_content
1635
+ };
1636
+ }
1523
1637
  if (typeof msg.content === "string") {
1524
1638
  return {
1525
1639
  role: mapRoleToClaude(msg.role),
@@ -1610,7 +1724,7 @@ If it's in another language, summarize in that language.
1610
1724
  * @param mcpServers Array of MCP server configurations (optional)
1611
1725
  * @throws Error if the vision model doesn't support vision capabilities
1612
1726
  */
1613
- constructor(apiKey, model = MODEL_CLAUDE_4_5_HAIKU, visionModel = MODEL_CLAUDE_4_5_HAIKU, tools = [], mcpServers = [], responseLength) {
1727
+ constructor(apiKey, model = MODEL_CLAUDE_4_5_HAIKU, visionModel = MODEL_CLAUDE_4_5_HAIKU, tools = [], mcpServers = [], responseLength, reasoningEffort) {
1614
1728
  /** Provider name */
1615
1729
  this.provider = "claude";
1616
1730
  this.apiKey = apiKey;
@@ -1619,6 +1733,7 @@ If it's in another language, summarize in that language.
1619
1733
  this.tools = tools;
1620
1734
  this.mcpServers = mcpServers;
1621
1735
  this.responseLength = responseLength;
1736
+ this.reasoningEffort = reasoningEffort;
1622
1737
  if (!CLAUDE_VISION_SUPPORTED_MODELS.includes(this.visionModel)) {
1623
1738
  throw new Error(
1624
1739
  `Model ${this.visionModel} does not support vision capabilities.`
@@ -1728,6 +1843,9 @@ If it's in another language, summarize in that language.
1728
1843
  stream,
1729
1844
  max_tokens: maxTokens !== void 0 ? maxTokens : getMaxTokensForResponseLength(this.responseLength)
1730
1845
  };
1846
+ if (this.reasoningEffort !== void 0 && getClaudeSupportedReasoningEfforts(model).includes(this.reasoningEffort)) {
1847
+ body.output_config = { effort: this.reasoningEffort };
1848
+ }
1731
1849
  if (this.tools.length) {
1732
1850
  body.tools = this.tools.map((t) => ({
1733
1851
  name: t.name,
@@ -1765,6 +1883,7 @@ If it's in another language, summarize in that language.
1765
1883
  const reader = res.body.getReader();
1766
1884
  const dec = new TextDecoder();
1767
1885
  const textBlocks = [];
1886
+ const providerBlocks = /* @__PURE__ */ new Map();
1768
1887
  const toolCalls = /* @__PURE__ */ new Map();
1769
1888
  let buf = "";
1770
1889
  while (true) {
@@ -1779,9 +1898,28 @@ If it's in another language, summarize in that language.
1779
1898
  const payload = line.slice(5).trim();
1780
1899
  if (payload === "[DONE]") break;
1781
1900
  const ev = JSON.parse(payload);
1782
- if (ev.type === "content_block_delta" && ev.delta?.text) {
1901
+ if (ev.type === "content_block_start" && ev.content_block && typeof ev.index === "number") {
1902
+ providerBlocks.set(ev.index, { ...ev.content_block });
1903
+ }
1904
+ if (ev.type === "content_block_delta" && ev.delta?.type === "text_delta") {
1783
1905
  onPartial(ev.delta.text);
1784
1906
  textBlocks.push({ type: "text", text: ev.delta.text });
1907
+ const block = providerBlocks.get(ev.index);
1908
+ if (block?.type === "text") {
1909
+ block.text = `${block.text ?? ""}${ev.delta.text}`;
1910
+ }
1911
+ }
1912
+ if (ev.type === "content_block_delta" && ev.delta?.type === "thinking_delta") {
1913
+ const block = providerBlocks.get(ev.index);
1914
+ if (block?.type === "thinking") {
1915
+ block.thinking = `${block.thinking ?? ""}${ev.delta.thinking ?? ""}`;
1916
+ }
1917
+ }
1918
+ if (ev.type === "content_block_delta" && ev.delta?.type === "signature_delta") {
1919
+ const block = providerBlocks.get(ev.index);
1920
+ if (block?.type === "thinking") {
1921
+ block.signature = `${block.signature ?? ""}${ev.delta.signature ?? ""}`;
1922
+ }
1785
1923
  }
1786
1924
  if (ev.type === "content_block_start" && ev.content_block?.type === "tool_use") {
1787
1925
  toolCalls.set(ev.index, {
@@ -1817,20 +1955,25 @@ If it's in another language, summarize in that language.
1817
1955
  }
1818
1956
  if (ev.type === "content_block_stop" && toolCalls.has(ev.index)) {
1819
1957
  const { id, name, args, server_name } = toolCalls.get(ev.index);
1958
+ const input = JSON.parse(args || "{}");
1959
+ const providerBlock = providerBlocks.get(ev.index);
1960
+ if (providerBlock) {
1961
+ providerBlock.input = input;
1962
+ }
1820
1963
  if (server_name) {
1821
1964
  textBlocks.push({
1822
1965
  type: "mcp_tool_use",
1823
1966
  id,
1824
1967
  name,
1825
1968
  server_name,
1826
- input: JSON.parse(args || "{}")
1969
+ input
1827
1970
  });
1828
1971
  } else {
1829
1972
  textBlocks.push({
1830
1973
  type: "tool_use",
1831
1974
  id,
1832
1975
  name,
1833
- input: JSON.parse(args || "{}")
1976
+ input
1834
1977
  });
1835
1978
  }
1836
1979
  toolCalls.delete(ev.index);
@@ -1839,6 +1982,7 @@ If it's in another language, summarize in that language.
1839
1982
  }
1840
1983
  return {
1841
1984
  blocks: textBlocks,
1985
+ providerContent: [...providerBlocks.entries()].sort(([a], [b]) => a - b).map(([, block]) => block),
1842
1986
  stop_reason: textBlocks.some(
1843
1987
  (b) => b.type === "tool_use" || b.type === "mcp_tool_use"
1844
1988
  ) ? "tool_use" : "end"
@@ -1885,6 +2029,7 @@ If it's in another language, summarize in that language.
1885
2029
  });
1886
2030
  return {
1887
2031
  blocks,
2032
+ providerContent: (data.content ?? []).map((block) => ({ ...block })),
1888
2033
  stop_reason: blocks.some(
1889
2034
  (b) => b.type === "tool_use" || b.type === "mcp_tool_use"
1890
2035
  ) ? "tool_use" : "end"
@@ -1936,7 +2081,12 @@ If it's in another language, summarize in that language.
1936
2081
  );
1937
2082
  return {
1938
2083
  blocks: standardBlocks,
1939
- stop_reason: completion.stop_reason
2084
+ stop_reason: completion.stop_reason,
2085
+ assistant_message: {
2086
+ role: "assistant",
2087
+ content: standardBlocks.filter((block) => block.type === "text").map((block) => block.text).join(""),
2088
+ provider_content: completion.providerContent
2089
+ }
1940
2090
  };
1941
2091
  }
1942
2092
  };
@@ -1949,21 +2099,30 @@ If it's in another language, summarize in that language.
1949
2099
  * @returns ClaudeChatService instance
1950
2100
  */
1951
2101
  createChatService(options) {
2102
+ const model = options.model || this.getDefaultModel();
2103
+ const supportedReasoningEfforts = getClaudeSupportedReasoningEfforts(model);
2104
+ if (options.reasoning_effort !== void 0 && !supportedReasoningEfforts.includes(options.reasoning_effort)) {
2105
+ const supportedMessage = supportedReasoningEfforts.length > 0 ? `Supported values: ${supportedReasoningEfforts.join(", ")}.` : "This model does not expose configurable effort.";
2106
+ throw new Error(
2107
+ `Model ${model} does not support Claude reasoning_effort: ${options.reasoning_effort}. ${supportedMessage}`
2108
+ );
2109
+ }
1952
2110
  const visionModel = resolveVisionModel({
1953
- model: options.model,
2111
+ model,
1954
2112
  visionModel: options.visionModel,
1955
2113
  defaultModel: this.getDefaultModel(),
1956
2114
  defaultVisionModel: this.getDefaultModel(),
1957
- supportsVisionForModel: (model) => this.supportsVisionForModel(model),
2115
+ supportsVisionForModel: (model2) => this.supportsVisionForModel(model2),
1958
2116
  validate: "resolved"
1959
2117
  });
1960
2118
  return new ClaudeChatService(
1961
2119
  options.apiKey,
1962
- options.model || this.getDefaultModel(),
2120
+ model,
1963
2121
  visionModel,
1964
2122
  options.tools ?? [],
1965
2123
  options.mcpServers ?? [],
1966
- options.responseLength
2124
+ options.responseLength,
2125
+ options.reasoning_effort
1967
2126
  );
1968
2127
  }
1969
2128
  /**
@@ -1989,6 +2148,7 @@ If it's in another language, summarize in that language.
1989
2148
  MODEL_CLAUDE_4_7_OPUS,
1990
2149
  MODEL_CLAUDE_4_8_OPUS,
1991
2150
  MODEL_CLAUDE_5_SONNET,
2151
+ MODEL_CLAUDE_5_OPUS,
1992
2152
  MODEL_CLAUDE_3_HAIKU
1993
2153
  ];
1994
2154
  }
@@ -3567,8 +3727,14 @@ If it's in another language, summarize in that language.
3567
3727
  var GeminiNanoChatService = class {
3568
3728
  constructor(options = {}) {
3569
3729
  this.provider = "gemini-nano";
3570
- this.expectedInputLanguages = options.expectedInputLanguages ?? ["ja"];
3730
+ this.expectedInputLanguages = options.expectedInputLanguages ?? [
3731
+ "ja",
3732
+ "en"
3733
+ ];
3571
3734
  this.expectedOutputLanguages = options.expectedOutputLanguages ?? ["ja"];
3735
+ this.initialPrompts = (options.initialPrompts ?? []).map((prompt) => ({
3736
+ ...prompt
3737
+ }));
3572
3738
  this._responseLength = options.responseLength;
3573
3739
  }
3574
3740
  getModel() {
@@ -3613,7 +3779,8 @@ If it's in another language, summarize in that language.
3613
3779
  "Gemini Nano is not available in this environment. Chrome 138+ with Prompt API enabled is required."
3614
3780
  );
3615
3781
  }
3616
- const availability = await api.availability();
3782
+ const modelOptions = this.getModelOptions();
3783
+ const availability = await api.availability(modelOptions);
3617
3784
  if (availability !== "available" && availability !== "downloadable") {
3618
3785
  throw new Error(
3619
3786
  `Gemini Nano Prompt API is not ready in this environment. LanguageModel.availability() returned "${availability}". Expected "available" or "downloadable".`
@@ -3621,15 +3788,17 @@ If it's in another language, summarize in that language.
3621
3788
  }
3622
3789
  const systemMessages = messages.filter((m) => m.role === "system");
3623
3790
  const systemPrompt = systemMessages.map((m) => m.content).join("\n");
3624
- const conversationMessages = messages.filter((m) => m.role !== "system").slice(-GEMINI_NANO_MAX_CONTEXT_MESSAGES);
3625
- const lastUserMessage = [...conversationMessages].reverse().find((m) => m.role === "user");
3626
- if (!lastUserMessage) {
3791
+ const conversationMessages = messages.filter((m) => m.role === "user" || m.role === "assistant").slice(-GEMINI_NANO_MAX_CONTEXT_MESSAGES);
3792
+ const lastUserMessageIndex = this.findLastUserMessageIndex(conversationMessages);
3793
+ if (lastUserMessageIndex === -1) {
3627
3794
  throw new Error("No user message found in the provided messages.");
3628
3795
  }
3796
+ const lastUserMessage = conversationMessages[lastUserMessageIndex];
3629
3797
  const session = await this.createSession(
3630
3798
  api,
3631
3799
  systemPrompt,
3632
- conversationMessages
3800
+ conversationMessages.slice(0, lastUserMessageIndex),
3801
+ modelOptions
3633
3802
  );
3634
3803
  try {
3635
3804
  return await session.prompt(lastUserMessage.content);
@@ -3641,25 +3810,55 @@ If it's in another language, summarize in that language.
3641
3810
  }
3642
3811
  }
3643
3812
  /**
3644
- * Create a new LanguageModel session with system prompt and context history.
3645
- * Context history (excluding the last user message) is embedded in the system prompt.
3813
+ * Create a new LanguageModel session with structured initial prompts.
3814
+ * System instructions, few-shot examples, and conversation history retain
3815
+ * their roles instead of being flattened into a single string.
3646
3816
  */
3647
- async createSession(api, systemPrompt, contextHistory) {
3648
- let prompt = this.buildSystemPrompt(systemPrompt);
3649
- const historyMessages = contextHistory.slice(0, -1);
3650
- if (historyMessages.length > 0) {
3651
- const history = historyMessages.map((m) => `${m.role === "user" ? "User" : "Assistant"}: ${m.content}`).join("\n");
3652
- prompt += "\n\nThe following is the prior conversation history. Use it as context for your response:\n" + history;
3653
- }
3654
- return api.create({
3655
- systemPrompt: prompt,
3817
+ async createSession(api, systemPrompt, contextHistory, modelOptions) {
3818
+ const initialPrompts = this.buildInitialPrompts(
3819
+ systemPrompt,
3820
+ contextHistory
3821
+ );
3822
+ const createOptions = {
3823
+ ...modelOptions,
3824
+ ...initialPrompts.length > 0 ? { initialPrompts } : {}
3825
+ };
3826
+ return api.create(createOptions);
3827
+ }
3828
+ getModelOptions() {
3829
+ return {
3656
3830
  expectedInputs: [
3657
3831
  { type: "text", languages: this.expectedInputLanguages }
3658
3832
  ],
3659
3833
  expectedOutputs: [
3660
3834
  { type: "text", languages: this.expectedOutputLanguages }
3661
3835
  ]
3662
- });
3836
+ };
3837
+ }
3838
+ buildInitialPrompts(systemPrompt, contextHistory) {
3839
+ const configuredSystemPrompts = this.initialPrompts.filter((prompt) => prompt.role === "system").map((prompt) => prompt.content);
3840
+ const combinedSystemPrompt = this.buildSystemPrompt(
3841
+ [systemPrompt, ...configuredSystemPrompts].filter(Boolean).join("\n\n")
3842
+ );
3843
+ const prompts = [];
3844
+ if (combinedSystemPrompt) {
3845
+ prompts.push({ role: "system", content: combinedSystemPrompt });
3846
+ }
3847
+ prompts.push(
3848
+ ...this.initialPrompts.filter((prompt) => prompt.role !== "system").map((prompt) => ({ ...prompt })),
3849
+ ...contextHistory.filter(
3850
+ (message) => message.role === "user" || message.role === "assistant"
3851
+ ).map(({ role, content }) => ({ role, content }))
3852
+ );
3853
+ return prompts;
3854
+ }
3855
+ findLastUserMessageIndex(messages) {
3856
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
3857
+ if (messages[index].role === "user") {
3858
+ return index;
3859
+ }
3860
+ }
3861
+ return -1;
3663
3862
  }
3664
3863
  buildSystemPrompt(systemPrompt) {
3665
3864
  const promptParts = [];
@@ -3680,7 +3879,20 @@ If it's in another language, summarize in that language.
3680
3879
  if (!maxTokens) {
3681
3880
  return void 0;
3682
3881
  }
3683
- return `Please keep your response concise, within approximately ${maxTokens} tokens.`;
3882
+ switch (this._responseLength) {
3883
+ case CHAT_RESPONSE_LENGTH.VERY_SHORT:
3884
+ return `Reply in no more than one concise sentence. Do not use a preamble, summary, bullet points, or Markdown. Keep the reaction and answer short enough to read in one breath. Stay within approximately ${maxTokens} tokens.`;
3885
+ case CHAT_RESPONSE_LENGTH.SHORT:
3886
+ return `Reply in no more than two concise sentences. Do not use a preamble, summary, bullet points, or Markdown. Keep the reaction and answer short enough to read in one breath. Use natural conversational language. Stay within approximately ${maxTokens} tokens.`;
3887
+ case CHAT_RESPONSE_LENGTH.MEDIUM:
3888
+ return `Reply in no more than three concise sentences. Answer directly and include only the context needed to understand the answer. Do not use a preamble, summary, bullet points, or Markdown. Use natural conversational language. Stay within approximately ${maxTokens} tokens.`;
3889
+ case CHAT_RESPONSE_LENGTH.LONG:
3890
+ return `Reply in no more than five sentences. Explain the important details clearly, but avoid unnecessary preambles, repetition, bullet points, or Markdown. Use natural conversational language. Stay within approximately ${maxTokens} tokens.`;
3891
+ case CHAT_RESPONSE_LENGTH.VERY_LONG:
3892
+ return `Reply in no more than ten sentences. Give a thorough but focused answer. Use short plain-text paragraphs when helpful, and avoid unnecessary repetition, bullet points, or Markdown. Stay within approximately ${maxTokens} tokens.`;
3893
+ case CHAT_RESPONSE_LENGTH.DEEP:
3894
+ return `Give a detailed response and organize it in the way that best fits the request. No sentence-count limit applies at this level. Stay within approximately ${maxTokens} tokens.`;
3895
+ }
3684
3896
  }
3685
3897
  };
3686
3898
 
@@ -3690,6 +3902,7 @@ If it's in another language, summarize in that language.
3690
3902
  return new GeminiNanoChatService({
3691
3903
  expectedInputLanguages: options.expectedInputLanguages,
3692
3904
  expectedOutputLanguages: options.expectedOutputLanguages,
3905
+ initialPrompts: options.initialPrompts,
3693
3906
  responseLength: options.responseLength
3694
3907
  });
3695
3908
  }
@@ -3734,7 +3947,7 @@ If it's in another language, summarize in that language.
3734
3947
  `Model ${model} does not support reasoning_effort: ${reasoningEffort}.`
3735
3948
  );
3736
3949
  }
3737
- this.reasoningEffort = reasoningEffort ?? (isKimiReasoningEffortModel(model) ? supportedReasoningEfforts[0] : void 0);
3950
+ this.reasoningEffort = reasoningEffort ?? getDefaultKimiReasoningEffort(model);
3738
3951
  this.visionModel = visionModel;
3739
3952
  }
3740
3953
  /**
@@ -3835,7 +4048,7 @@ If it's in another language, summarize in that language.
3835
4048
  body.response_format = this.responseFormat;
3836
4049
  }
3837
4050
  if (isKimiReasoningEffortModel(model)) {
3838
- body.reasoning_effort = this.reasoningEffort ?? "max";
4051
+ body.reasoning_effort = this.reasoningEffort ?? getDefaultKimiReasoningEffort(model);
3839
4052
  }
3840
4053
  const effectiveThinking = this.resolveEffectiveThinking(model);
3841
4054
  if (effectiveThinking) {
@@ -4037,7 +4250,7 @@ If it's in another language, summarize in that language.
4037
4250
  }
4038
4251
  return void 0;
4039
4252
  }
4040
- const resolved = reasoningEffort ?? supported[0];
4253
+ const resolved = reasoningEffort ?? getDefaultKimiReasoningEffort(model) ?? supported[0];
4041
4254
  if (!supported.includes(resolved)) {
4042
4255
  throw new Error(
4043
4256
  `Model ${model} supports reasoning_effort values: ${supported.join(", ")}.`
@@ -4391,8 +4604,19 @@ If it's in another language, summarize in that language.
4391
4604
  };
4392
4605
 
4393
4606
  // src/services/providers/openrouter/OpenRouterChatService.ts
4607
+ var isOpenRouterAutoModel = (model) => [MODEL_OPENROUTER_AUTO, MODEL_OPENROUTER_AUTO_BETA].includes(model.trim());
4394
4608
  var isTokenLimitUnsupportedModel = (model) => [MODEL_GPT_OSS_20B_FREE, MODEL_ZAI_GLM_5_2].includes(model.trim());
4395
4609
  var getDefaultReasoningEffort = (model) => model.trim() === MODEL_ZAI_GLM_5_2 ? "none" : void 0;
4610
+ var ensureAutoRouterOutput = (model, hasVisibleOutput) => {
4611
+ if (isOpenRouterAutoModel(model) && !hasVisibleOutput) {
4612
+ throw new Error(
4613
+ "OpenRouter Auto Router returned no visible content. Please retry."
4614
+ );
4615
+ }
4616
+ };
4617
+ var hasUsableCompletionOutput = (completion) => completion.blocks.some(
4618
+ (block) => block.type !== "text" || block.text.trim().length > 0
4619
+ );
4396
4620
  var OpenRouterChatService = class {
4397
4621
  /**
4398
4622
  * Constructor
@@ -4476,7 +4700,7 @@ If it's in another language, summarize in that language.
4476
4700
  hasTools: this.tools.length > 0,
4477
4701
  runWithoutTools: async () => {
4478
4702
  const res = await this.callOpenRouter(messages, this.model, true);
4479
- return this.handleStream(res, onPartialResponse);
4703
+ return this.handleStream(res, onPartialResponse, this.model);
4480
4704
  },
4481
4705
  runWithTools: () => this.chatOnce(messages, true, onPartialResponse),
4482
4706
  onCompleteResponse,
@@ -4505,7 +4729,7 @@ If it's in another language, summarize in that language.
4505
4729
  this.visionModel,
4506
4730
  true
4507
4731
  );
4508
- return this.handleStream(res, onPartialResponse);
4732
+ return this.handleStream(res, onPartialResponse, this.visionModel);
4509
4733
  },
4510
4734
  runWithTools: () => this.visionChatOnce(messages, true, onPartialResponse),
4511
4735
  onCompleteResponse,
@@ -4533,7 +4757,7 @@ If it's in another language, summarize in that language.
4533
4757
  stream,
4534
4758
  maxTokens
4535
4759
  );
4536
- return stream ? this.parseStream(res, onPartialResponse) : this.parseOneShot(await res.json());
4760
+ return stream ? this.parseStream(res, onPartialResponse, this.model) : this.parseOneShot(await res.json(), this.model);
4537
4761
  }
4538
4762
  /**
4539
4763
  * Process vision chat messages with tools
@@ -4557,7 +4781,7 @@ If it's in another language, summarize in that language.
4557
4781
  stream,
4558
4782
  maxTokens
4559
4783
  );
4560
- return stream ? this.parseStream(res, onPartialResponse) : this.parseOneShot(await res.json());
4784
+ return stream ? this.parseStream(res, onPartialResponse, this.visionModel) : this.parseOneShot(await res.json(), this.visionModel);
4561
4785
  }
4562
4786
  /**
4563
4787
  * Call OpenRouter API
@@ -4586,7 +4810,8 @@ If it's in another language, summarize in that language.
4586
4810
  stream
4587
4811
  };
4588
4812
  const tokenLimit = maxTokens !== void 0 ? maxTokens : getMaxTokensForResponseLength(this.responseLength);
4589
- if (tokenLimit && isTokenLimitUnsupportedModel(model)) {
4813
+ const shouldOmitTokenLimit = isTokenLimitUnsupportedModel(model) || isOpenRouterAutoModel(model) && maxTokens === void 0;
4814
+ if (tokenLimit && shouldOmitTokenLimit) {
4590
4815
  console.warn(
4591
4816
  `OpenRouter: Token limits are disabled for ${model} because this model can return empty content when a token limit is set.`
4592
4817
  );
@@ -4621,24 +4846,34 @@ If it's in another language, summarize in that language.
4621
4846
  * Handle streaming response from OpenRouter
4622
4847
  * OpenRouter uses SSE format with potential comment lines
4623
4848
  */
4624
- async handleStream(res, onPartial) {
4625
- return parseOpenAICompatibleTextStream(res, onPartial, {
4626
- onJsonError: (payload) => console.debug("Failed to parse SSE data:", payload)
4849
+ async handleStream(res, onPartial, model) {
4850
+ const text = await parseOpenAICompatibleTextStream(res, onPartial, {
4851
+ onJsonError: (payload) => console.debug("Failed to parse SSE data:", payload),
4852
+ throwOnApiError: isOpenRouterAutoModel(model)
4627
4853
  });
4854
+ ensureAutoRouterOutput(model, text.trim().length > 0);
4855
+ return text;
4628
4856
  }
4629
4857
  /**
4630
4858
  * Parse streaming response with tool support
4631
4859
  */
4632
- async parseStream(res, onPartial) {
4633
- return parseOpenAICompatibleToolStream(res, onPartial, {
4634
- onJsonError: (payload) => console.debug("Failed to parse SSE data:", payload)
4860
+ async parseStream(res, onPartial, model) {
4861
+ const completion = await parseOpenAICompatibleToolStream(res, onPartial, {
4862
+ onJsonError: (payload) => console.debug("Failed to parse SSE data:", payload),
4863
+ throwOnApiError: isOpenRouterAutoModel(model)
4635
4864
  });
4865
+ ensureAutoRouterOutput(model, hasUsableCompletionOutput(completion));
4866
+ return completion;
4636
4867
  }
4637
4868
  /**
4638
4869
  * Parse non-streaming response
4639
4870
  */
4640
- parseOneShot(data) {
4641
- return parseOpenAICompatibleOneShot(data);
4871
+ parseOneShot(data, model) {
4872
+ const completion = parseOpenAICompatibleOneShot(data, {
4873
+ throwOnApiError: isOpenRouterAutoModel(model)
4874
+ });
4875
+ ensureAutoRouterOutput(model, hasUsableCompletionOutput(completion));
4876
+ return completion;
4642
4877
  }
4643
4878
  };
4644
4879
 
@@ -4691,6 +4926,7 @@ If it's in another language, summarize in that language.
4691
4926
  return [
4692
4927
  // OpenRouter routing
4693
4928
  MODEL_OPENROUTER_AUTO,
4929
+ MODEL_OPENROUTER_AUTO_BETA,
4694
4930
  MODEL_OPENROUTER_FUSION,
4695
4931
  // Free models
4696
4932
  MODEL_GPT_OSS_20B_FREE,
@@ -4698,6 +4934,9 @@ If it's in another language, summarize in that language.
4698
4934
  // OpenAI models
4699
4935
  MODEL_OPENAI_GPT_LATEST,
4700
4936
  MODEL_OPENAI_GPT_MINI_LATEST,
4937
+ MODEL_OPENAI_GPT_5_6_SOL,
4938
+ MODEL_OPENAI_GPT_5_6_TERRA,
4939
+ MODEL_OPENAI_GPT_5_6_LUNA,
4701
4940
  MODEL_OPENAI_GPT_5_5_PRO,
4702
4941
  MODEL_OPENAI_GPT_5_5,
4703
4942
  MODEL_OPENAI_GPT_5_1_CHAT,
@@ -4710,6 +4949,7 @@ If it's in another language, summarize in that language.
4710
4949
  // Anthropic models
4711
4950
  MODEL_ANTHROPIC_CLAUDE_SONNET_LATEST,
4712
4951
  MODEL_ANTHROPIC_CLAUDE_HAIKU_LATEST,
4952
+ MODEL_ANTHROPIC_CLAUDE_OPUS_5,
4713
4953
  MODEL_ANTHROPIC_CLAUDE_OPUS_4,
4714
4954
  MODEL_ANTHROPIC_CLAUDE_SONNET_4,
4715
4955
  MODEL_ANTHROPIC_CLAUDE_3_7_SONNET,
@@ -4718,6 +4958,8 @@ If it's in another language, summarize in that language.
4718
4958
  // Gemini models
4719
4959
  MODEL_GOOGLE_GEMINI_PRO_LATEST,
4720
4960
  MODEL_GOOGLE_GEMINI_FLASH_LATEST,
4961
+ MODEL_GOOGLE_GEMINI_3_6_FLASH,
4962
+ MODEL_GOOGLE_GEMINI_3_5_FLASH_LITE,
4721
4963
  MODEL_GOOGLE_GEMINI_2_5_PRO,
4722
4964
  MODEL_GOOGLE_GEMINI_2_5_FLASH,
4723
4965
  MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE_PREVIEW_09_2025,
@@ -4725,10 +4967,16 @@ If it's in another language, summarize in that language.
4725
4967
  MODEL_ZAI_GLM_5_2,
4726
4968
  MODEL_ZAI_GLM_4_7_FLASH,
4727
4969
  MODEL_ZAI_GLM_4_5_AIR,
4970
+ // xAI models
4971
+ MODEL_XAI_GROK_LATEST,
4972
+ MODEL_XAI_GROK_4_5,
4728
4973
  // Other models
4729
4974
  MODEL_MOONSHOTAI_KIMI_LATEST,
4975
+ MODEL_MOONSHOTAI_KIMI_K3,
4730
4976
  MODEL_MOONSHOTAI_KIMI_K2_7_CODE,
4731
- MODEL_MOONSHOTAI_KIMI_K2_5
4977
+ MODEL_MOONSHOTAI_KIMI_K2_5,
4978
+ MODEL_KWAIPILOT_KAT_CODER_AIR_V2_5,
4979
+ MODEL_KWAIPILOT_KAT_CODER_PRO_V2_5
4732
4980
  ];
4733
4981
  }
4734
4982
  /**
@@ -5451,8 +5699,10 @@ If it's in another language, summarize in that language.
5451
5699
  ]);
5452
5700
  var REASONING_EFFORT_BY_PROVIDER = {
5453
5701
  openai: ["none", "minimal", "low", "medium", "high", "xhigh", "max"],
5702
+ claude: ["low", "medium", "high", "xhigh", "max"],
5454
5703
  gemini: ["minimal", "low", "medium", "high"],
5455
5704
  openrouter: ["none", "minimal", "low", "medium", "high"],
5705
+ kimi: ["low", "high", "max"],
5456
5706
  mistral: ["low", "medium", "high"],
5457
5707
  plamo: ["none", "medium"],
5458
5708
  xai: ["none", "low", "medium", "high"]
@@ -5515,7 +5765,7 @@ If it's in another language, summarize in that language.
5515
5765
  mcp: MCP_SUPPORTED_PROVIDERS.has(providerName),
5516
5766
  jsonMode: JSON_MODE_SUPPORTED_PROVIDERS.has(providerName),
5517
5767
  responseLength: true,
5518
- reasoningEffort: REASONING_EFFORT_BY_PROVIDER[providerName] ?? []
5768
+ reasoningEffort: providerName === "claude" && model ? [...getClaudeSupportedReasoningEfforts(model)] : providerName === "kimi" && model ? [...getKimiSupportedReasoningEfforts(model)] : REASONING_EFFORT_BY_PROVIDER[providerName] ?? []
5519
5769
  };
5520
5770
  }
5521
5771
  /**