@aituber-onair/chat 0.17.0 → 0.19.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 (45) hide show
  1. package/README.ja.md +13 -6
  2. package/README.md +13 -6
  3. package/dist/cjs/constants/gemini.d.ts +1 -0
  4. package/dist/cjs/constants/gemini.d.ts.map +1 -1
  5. package/dist/cjs/constants/gemini.js +3 -1
  6. package/dist/cjs/constants/gemini.js.map +1 -1
  7. package/dist/cjs/constants/openai.d.ts +24 -2
  8. package/dist/cjs/constants/openai.d.ts.map +1 -1
  9. package/dist/cjs/constants/openai.js +47 -5
  10. package/dist/cjs/constants/openai.js.map +1 -1
  11. package/dist/cjs/services/providers/ChatServiceProvider.d.ts +2 -1
  12. package/dist/cjs/services/providers/ChatServiceProvider.d.ts.map +1 -1
  13. package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.d.ts.map +1 -1
  14. package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.js +1 -0
  15. package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.js.map +1 -1
  16. package/dist/cjs/services/providers/openai/OpenAIChatService.d.ts +2 -1
  17. package/dist/cjs/services/providers/openai/OpenAIChatService.d.ts.map +1 -1
  18. package/dist/cjs/services/providers/openai/OpenAIChatService.js.map +1 -1
  19. package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.d.ts +1 -3
  20. package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.d.ts.map +1 -1
  21. package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.js +17 -12
  22. package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.js.map +1 -1
  23. package/dist/esm/constants/gemini.d.ts +1 -0
  24. package/dist/esm/constants/gemini.d.ts.map +1 -1
  25. package/dist/esm/constants/gemini.js +2 -0
  26. package/dist/esm/constants/gemini.js.map +1 -1
  27. package/dist/esm/constants/openai.d.ts +24 -2
  28. package/dist/esm/constants/openai.d.ts.map +1 -1
  29. package/dist/esm/constants/openai.js +42 -4
  30. package/dist/esm/constants/openai.js.map +1 -1
  31. package/dist/esm/services/providers/ChatServiceProvider.d.ts +2 -1
  32. package/dist/esm/services/providers/ChatServiceProvider.d.ts.map +1 -1
  33. package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.d.ts.map +1 -1
  34. package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.js +2 -1
  35. package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.js.map +1 -1
  36. package/dist/esm/services/providers/openai/OpenAIChatService.d.ts +2 -1
  37. package/dist/esm/services/providers/openai/OpenAIChatService.d.ts.map +1 -1
  38. package/dist/esm/services/providers/openai/OpenAIChatService.js.map +1 -1
  39. package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.d.ts +1 -3
  40. package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.d.ts.map +1 -1
  41. package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.js +18 -13
  42. package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.js.map +1 -1
  43. package/dist/umd/aituber-onair-chat.js +48 -14
  44. package/dist/umd/aituber-onair-chat.min.js +6 -6
  45. package/package.json +1 -1
@@ -72,6 +72,7 @@ var AITuberOnAirChat = (() => {
72
72
  MODEL_GEMINI_2_5_FLASH_LITE: () => MODEL_GEMINI_2_5_FLASH_LITE,
73
73
  MODEL_GEMINI_2_5_FLASH_LITE_PREVIEW_06_17: () => MODEL_GEMINI_2_5_FLASH_LITE_PREVIEW_06_17,
74
74
  MODEL_GEMINI_2_5_PRO: () => MODEL_GEMINI_2_5_PRO,
75
+ MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW: () => MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW,
75
76
  MODEL_GEMINI_3_1_PRO_PREVIEW: () => MODEL_GEMINI_3_1_PRO_PREVIEW,
76
77
  MODEL_GEMINI_3_FLASH_PREVIEW: () => MODEL_GEMINI_3_FLASH_PREVIEW,
77
78
  MODEL_GEMINI_3_PRO_PREVIEW: () => MODEL_GEMINI_3_PRO_PREVIEW,
@@ -93,6 +94,8 @@ var AITuberOnAirChat = (() => {
93
94
  MODEL_GPT_4_1_NANO: () => MODEL_GPT_4_1_NANO,
94
95
  MODEL_GPT_5: () => MODEL_GPT_5,
95
96
  MODEL_GPT_5_1: () => MODEL_GPT_5_1,
97
+ MODEL_GPT_5_4: () => MODEL_GPT_5_4,
98
+ MODEL_GPT_5_4_PRO: () => MODEL_GPT_5_4_PRO,
96
99
  MODEL_GPT_5_MINI: () => MODEL_GPT_5_MINI,
97
100
  MODEL_GPT_5_NANO: () => MODEL_GPT_5_NANO,
98
101
  MODEL_GPT_OSS_20B_FREE: () => MODEL_GPT_OSS_20B_FREE,
@@ -127,15 +130,19 @@ var AITuberOnAirChat = (() => {
127
130
  ZAIChatService: () => ZAIChatService,
128
131
  ZAIChatServiceProvider: () => ZAIChatServiceProvider,
129
132
  ZAI_VISION_SUPPORTED_MODELS: () => ZAI_VISION_SUPPORTED_MODELS,
133
+ allowsReasoningLow: () => allowsReasoningLow,
130
134
  allowsReasoningMinimal: () => allowsReasoningMinimal,
131
135
  allowsReasoningNone: () => allowsReasoningNone,
136
+ allowsReasoningXHigh: () => allowsReasoningXHigh,
132
137
  buildOpenAICompatibleTools: () => buildOpenAICompatibleTools,
138
+ getDefaultReasoningEffortForGPT5Model: () => getDefaultReasoningEffortForGPT5Model,
133
139
  getMaxTokensForResponseLength: () => getMaxTokensForResponseLength,
134
140
  installGASFetch: () => installGASFetch,
135
141
  isGPT5Model: () => isGPT5Model,
136
142
  isKimiVisionModel: () => isKimiVisionModel,
137
143
  isOpenRouterFreeModel: () => isOpenRouterFreeModel,
138
144
  isOpenRouterVisionModel: () => isOpenRouterVisionModel,
145
+ isResponsesOnlyGPT5Model: () => isResponsesOnlyGPT5Model,
139
146
  isZaiToolStreamModel: () => isZaiToolStreamModel,
140
147
  isZaiVisionModel: () => isZaiVisionModel,
141
148
  parseOpenAICompatibleOneShot: () => parseOpenAICompatibleOneShot,
@@ -157,6 +164,8 @@ var AITuberOnAirChat = (() => {
157
164
  var MODEL_GPT_5_MINI = "gpt-5-mini";
158
165
  var MODEL_GPT_5 = "gpt-5";
159
166
  var MODEL_GPT_5_1 = "gpt-5.1";
167
+ var MODEL_GPT_5_4 = "gpt-5.4";
168
+ var MODEL_GPT_5_4_PRO = "gpt-5.4-pro";
160
169
  var MODEL_GPT_4_1 = "gpt-4.1";
161
170
  var MODEL_GPT_4_1_MINI = "gpt-4.1-mini";
162
171
  var MODEL_GPT_4_1_NANO = "gpt-4.1-nano";
@@ -170,6 +179,8 @@ var AITuberOnAirChat = (() => {
170
179
  MODEL_GPT_5_MINI,
171
180
  MODEL_GPT_5,
172
181
  MODEL_GPT_5_1,
182
+ MODEL_GPT_5_4,
183
+ MODEL_GPT_5_4_PRO,
173
184
  MODEL_GPT_4_1,
174
185
  MODEL_GPT_4_1_MINI,
175
186
  MODEL_GPT_4_1_NANO,
@@ -182,21 +193,39 @@ var AITuberOnAirChat = (() => {
182
193
  MODEL_GPT_5_NANO,
183
194
  MODEL_GPT_5_MINI,
184
195
  MODEL_GPT_5,
185
- MODEL_GPT_5_1
196
+ MODEL_GPT_5_1,
197
+ MODEL_GPT_5_4,
198
+ MODEL_GPT_5_4_PRO
186
199
  ];
187
200
  function isGPT5Model(model) {
188
201
  return GPT_5_MODELS.includes(model);
189
202
  }
203
+ function isResponsesOnlyGPT5Model(model) {
204
+ return model === MODEL_GPT_5_4_PRO;
205
+ }
206
+ function allowsReasoningXHigh(model) {
207
+ return model === MODEL_GPT_5_4 || model === MODEL_GPT_5_4_PRO;
208
+ }
190
209
  function allowsReasoningNone(model) {
191
- return model === MODEL_GPT_5_1;
210
+ return model === MODEL_GPT_5_1 || model === MODEL_GPT_5_4;
192
211
  }
193
212
  function allowsReasoningMinimal(model) {
194
- return model !== MODEL_GPT_5_1;
213
+ return model === MODEL_GPT_5_NANO || model === MODEL_GPT_5_MINI || model === MODEL_GPT_5;
214
+ }
215
+ function allowsReasoningLow(model) {
216
+ return model !== MODEL_GPT_5_4_PRO;
217
+ }
218
+ function getDefaultReasoningEffortForGPT5Model(model) {
219
+ if (model === MODEL_GPT_5_1 || model === MODEL_GPT_5_4) {
220
+ return "none";
221
+ }
222
+ return "medium";
195
223
  }
196
224
 
197
225
  // src/constants/gemini.ts
198
226
  var ENDPOINT_GEMINI_API = "https://generativelanguage.googleapis.com";
199
227
  var MODEL_GEMINI_3_1_PRO_PREVIEW = "gemini-3.1-pro-preview";
228
+ var MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW = "gemini-3.1-flash-lite-preview";
200
229
  var MODEL_GEMINI_3_PRO_PREVIEW = "gemini-3-pro-preview";
201
230
  var MODEL_GEMINI_3_FLASH_PREVIEW = "gemini-3-flash-preview";
202
231
  var MODEL_GEMINI_2_5_PRO = "gemini-2.5-pro";
@@ -207,6 +236,7 @@ var AITuberOnAirChat = (() => {
207
236
  var MODEL_GEMINI_2_0_FLASH_LITE = "gemini-2.0-flash-lite";
208
237
  var GEMINI_VISION_SUPPORTED_MODELS = [
209
238
  MODEL_GEMINI_3_1_PRO_PREVIEW,
239
+ MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW,
210
240
  MODEL_GEMINI_3_PRO_PREVIEW,
211
241
  MODEL_GEMINI_3_FLASH_PREVIEW,
212
242
  MODEL_GEMINI_2_5_PRO,
@@ -2245,6 +2275,7 @@ If it's in another language, summarize in that language.
2245
2275
  getSupportedModels() {
2246
2276
  return [
2247
2277
  MODEL_GEMINI_3_1_PRO_PREVIEW,
2278
+ MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW,
2248
2279
  MODEL_GEMINI_3_PRO_PREVIEW,
2249
2280
  MODEL_GEMINI_3_FLASH_PREVIEW,
2250
2281
  MODEL_GEMINI_2_5_PRO,
@@ -3090,6 +3121,8 @@ If it's in another language, summarize in that language.
3090
3121
  let shouldUseResponsesAPI = false;
3091
3122
  if (mcpServers.length > 0) {
3092
3123
  shouldUseResponsesAPI = true;
3124
+ } else if (isResponsesOnlyGPT5Model(modelName)) {
3125
+ shouldUseResponsesAPI = true;
3093
3126
  } else if (isGPT5Model(modelName)) {
3094
3127
  const preference = optimizedOptions.gpt5EndpointPreference || "chat";
3095
3128
  shouldUseResponsesAPI = preference === "responses";
@@ -3126,6 +3159,8 @@ If it's in another language, summarize in that language.
3126
3159
  MODEL_GPT_5_MINI,
3127
3160
  MODEL_GPT_5,
3128
3161
  MODEL_GPT_5_1,
3162
+ MODEL_GPT_5_4,
3163
+ MODEL_GPT_5_4_PRO,
3129
3164
  MODEL_GPT_4_1,
3130
3165
  MODEL_GPT_4_1_MINI,
3131
3166
  MODEL_GPT_4_1_NANO,
@@ -3175,7 +3210,7 @@ If it's in another language, summarize in that language.
3175
3210
  optimized.verbosity = preset.verbosity;
3176
3211
  } else {
3177
3212
  if (!options.reasoning_effort) {
3178
- optimized.reasoning_effort = this.getDefaultReasoningEffortForModel(modelName);
3213
+ optimized.reasoning_effort = getDefaultReasoningEffortForGPT5Model(modelName);
3179
3214
  }
3180
3215
  }
3181
3216
  optimized.reasoning_effort = this.normalizeReasoningEffort(
@@ -3185,24 +3220,23 @@ If it's in another language, summarize in that language.
3185
3220
  return optimized;
3186
3221
  }
3187
3222
  /**
3188
- * Determine the default reasoning effort for GPT-5 family models
3189
- * GPT-5.1 defaults to 'none' (fastest), earlier GPT-5 defaults to 'medium'
3223
+ * Normalize reasoning effort to a model-supported value
3190
3224
  */
3191
- getDefaultReasoningEffortForModel(modelName) {
3192
- if (modelName === MODEL_GPT_5_1) {
3193
- return "none";
3194
- }
3195
- return "medium";
3196
- }
3197
3225
  normalizeReasoningEffort(modelName, effort) {
3198
3226
  if (!effort) {
3199
3227
  return void 0;
3200
3228
  }
3201
3229
  if (effort === "none" && !allowsReasoningNone(modelName)) {
3202
- return this.getDefaultReasoningEffortForModel(modelName);
3230
+ return getDefaultReasoningEffortForGPT5Model(modelName);
3203
3231
  }
3204
3232
  if (effort === "minimal" && !allowsReasoningMinimal(modelName)) {
3205
- return "none";
3233
+ return getDefaultReasoningEffortForGPT5Model(modelName);
3234
+ }
3235
+ if (effort === "low" && !allowsReasoningLow(modelName)) {
3236
+ return getDefaultReasoningEffortForGPT5Model(modelName);
3237
+ }
3238
+ if (effort === "xhigh" && !allowsReasoningXHigh(modelName)) {
3239
+ return getDefaultReasoningEffortForGPT5Model(modelName);
3206
3240
  }
3207
3241
  return effort;
3208
3242
  }
@@ -1,4 +1,4 @@
1
- "use strict";var AITuberOnAirChat=(()=>{var st=Object.defineProperty;var Ht=Object.getOwnPropertyDescriptor;var Wt=Object.getOwnPropertyNames;var Bt=Object.prototype.hasOwnProperty;var Kt=(n,e)=>{for(var t in e)st(n,t,{get:e[t],enumerable:!0})},$t=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Wt(e))!Bt.call(n,r)&&r!==t&&st(n,r,{get:()=>e[r],enumerable:!(o=Ht(e,r))||o.enumerable});return n};var jt=n=>$t(st({},"__esModule",{value:!0}),n);var mo={};Kt(mo,{CHAT_RESPONSE_LENGTH:()=>F,CLAUDE_VISION_SUPPORTED_MODELS:()=>he,ChatServiceFactory:()=>ne,ChatServiceHttpClient:()=>g,ClaudeChatService:()=>q,ClaudeChatServiceProvider:()=>J,DEFAULT_MAX_TOKENS:()=>Et,DEFAULT_SUMMARY_PROMPT_TEMPLATE:()=>Xt,DEFAULT_VISION_PROMPT:()=>Zt,EMOTION_TAG_CLEANUP_REGEX:()=>Tt,EMOTION_TAG_REGEX:()=>Dt,ENDPOINT_CLAUDE_API:()=>ht,ENDPOINT_GEMINI_API:()=>ct,ENDPOINT_KIMI_CHAT_COMPLETIONS_API:()=>$,ENDPOINT_OPENAI_CHAT_COMPLETIONS_API:()=>G,ENDPOINT_OPENAI_RESPONSES_API:()=>y,ENDPOINT_OPENROUTER_API:()=>me,ENDPOINT_ZAI_CHAT_COMPLETIONS_API:()=>ue,EmotionParser:()=>z,GEMINI_VISION_SUPPORTED_MODELS:()=>ce,GPT5_PRESETS:()=>yt,GPT_5_MODELS:()=>xt,GeminiChatService:()=>Z,GeminiChatServiceProvider:()=>X,HttpError:()=>A,KIMI_VISION_SUPPORTED_MODELS:()=>Lt,KimiChatService:()=>Y,KimiChatServiceProvider:()=>Q,MAX_TOKENS_BY_LENGTH:()=>Rt,MODEL_ANTHROPIC_CLAUDE_3_5_SONNET:()=>mt,MODEL_ANTHROPIC_CLAUDE_3_7_SONNET:()=>ze,MODEL_ANTHROPIC_CLAUDE_4_5_HAIKU:()=>qe,MODEL_ANTHROPIC_CLAUDE_OPUS_4:()=>$e,MODEL_ANTHROPIC_CLAUDE_SONNET_4:()=>je,MODEL_CLAUDE_3_5_HAIKU:()=>xe,MODEL_CLAUDE_3_5_SONNET:()=>Ie,MODEL_CLAUDE_3_7_SONNET:()=>be,MODEL_CLAUDE_3_HAIKU:()=>T,MODEL_CLAUDE_4_5_HAIKU:()=>Ae,MODEL_CLAUDE_4_5_OPUS:()=>we,MODEL_CLAUDE_4_5_SONNET:()=>De,MODEL_CLAUDE_4_6_OPUS:()=>ke,MODEL_CLAUDE_4_6_SONNET:()=>Ne,MODEL_CLAUDE_4_OPUS:()=>Re,MODEL_CLAUDE_4_SONNET:()=>Le,MODEL_GEMINI_2_0_FLASH:()=>Pe,MODEL_GEMINI_2_0_FLASH_LITE:()=>R,MODEL_GEMINI_2_5_FLASH:()=>ye,MODEL_GEMINI_2_5_FLASH_LITE:()=>Te,MODEL_GEMINI_2_5_FLASH_LITE_PREVIEW_06_17:()=>Se,MODEL_GEMINI_2_5_PRO:()=>Ee,MODEL_GEMINI_3_1_PRO_PREVIEW:()=>Me,MODEL_GEMINI_3_FLASH_PREVIEW:()=>Oe,MODEL_GEMINI_3_PRO_PREVIEW:()=>Ce,MODEL_GLM_4_6:()=>Ct,MODEL_GLM_4_6V:()=>Qe,MODEL_GLM_4_6V_FLASH:()=>V,MODEL_GLM_4_6V_FLASHX:()=>et,MODEL_GLM_4_7:()=>B,MODEL_GLM_4_7_FLASH:()=>Mt,MODEL_GLM_4_7_FLASHX:()=>vt,MODEL_GLM_5:()=>ft,MODEL_GOOGLE_GEMINI_2_5_FLASH:()=>Ze,MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE_PREVIEW_09_2025:()=>Xe,MODEL_GOOGLE_GEMINI_2_5_PRO:()=>Je,MODEL_GPT_4O:()=>ve,MODEL_GPT_4O_MINI:()=>N,MODEL_GPT_4_1:()=>_e,MODEL_GPT_4_1_MINI:()=>ge,MODEL_GPT_4_1_NANO:()=>fe,MODEL_GPT_5:()=>le,MODEL_GPT_5_1:()=>L,MODEL_GPT_5_MINI:()=>ae,MODEL_GPT_5_NANO:()=>U,MODEL_GPT_OSS_20B_FREE:()=>D,MODEL_KIMI_K2_5:()=>S,MODEL_MOONSHOTAI_KIMI_K2_5:()=>Ve,MODEL_O1:()=>at,MODEL_O1_MINI:()=>nt,MODEL_O3_MINI:()=>it,MODEL_OPENAI_GPT_4O:()=>We,MODEL_OPENAI_GPT_4_1_MINI:()=>Be,MODEL_OPENAI_GPT_4_1_NANO:()=>Ke,MODEL_OPENAI_GPT_5_1_CHAT:()=>Fe,MODEL_OPENAI_GPT_5_1_CODEX:()=>Ge,MODEL_OPENAI_GPT_5_MINI:()=>Ue,MODEL_OPENAI_GPT_5_NANO:()=>He,MODEL_ZAI_GLM_4_5_AIR:()=>dt,MODEL_ZAI_GLM_4_5_AIR_FREE:()=>Ye,MODEL_ZAI_GLM_4_7_FLASH:()=>ut,OPENROUTER_CREDITS_THRESHOLD:()=>Jt,OPENROUTER_FREE_DAILY_LIMIT_HIGH_CREDITS:()=>qt,OPENROUTER_FREE_DAILY_LIMIT_LOW_CREDITS:()=>zt,OPENROUTER_FREE_MODELS:()=>_t,OPENROUTER_FREE_RATE_LIMIT_PER_MINUTE:()=>gt,OPENROUTER_VISION_SUPPORTED_MODELS:()=>It,OpenAIChatService:()=>w,OpenAIChatServiceProvider:()=>te,OpenAICompatibleChatServiceProvider:()=>ee,OpenRouterChatService:()=>oe,OpenRouterChatServiceProvider:()=>re,StreamTextAccumulator:()=>f,VISION_SUPPORTED_MODELS:()=>pe,ZAIChatService:()=>se,ZAIChatServiceProvider:()=>ie,ZAI_VISION_SUPPORTED_MODELS:()=>bt,allowsReasoningMinimal:()=>pt,allowsReasoningNone:()=>lt,buildOpenAICompatibleTools:()=>b,getMaxTokensForResponseLength:()=>C,installGASFetch:()=>Gt,isGPT5Model:()=>H,isKimiVisionModel:()=>j,isOpenRouterFreeModel:()=>k,isOpenRouterVisionModel:()=>W,isZaiToolStreamModel:()=>Ot,isZaiVisionModel:()=>K,parseOpenAICompatibleOneShot:()=>I,parseOpenAICompatibleTextStream:()=>P,parseOpenAICompatibleToolStream:()=>x,processChatWithOptionalTools:()=>v,refreshOpenRouterFreeModels:()=>ho,resolveVisionModel:()=>O,runOnceText:()=>to,screenplayToText:()=>eo,textToScreenplay:()=>At,textsToScreenplay:()=>Qt});var G="https://api.openai.com/v1/chat/completions",y="https://api.openai.com/v1/responses",U="gpt-5-nano",ae="gpt-5-mini",le="gpt-5",L="gpt-5.1",_e="gpt-4.1",ge="gpt-4.1-mini",fe="gpt-4.1-nano",N="gpt-4o-mini",ve="gpt-4o",it="o3-mini",nt="o1-mini",at="o1",pe=[U,ae,le,L,_e,ge,fe,N,ve,"o1"],xt=[U,ae,le,L];function H(n){return xt.includes(n)}function lt(n){return n===L}function pt(n){return n!==L}var ct="https://generativelanguage.googleapis.com",Me="gemini-3.1-pro-preview",Ce="gemini-3-pro-preview",Oe="gemini-3-flash-preview",Ee="gemini-2.5-pro",ye="gemini-2.5-flash",Te="gemini-2.5-flash-lite",Se="gemini-2.5-flash-lite-preview-06-17",Pe="gemini-2.0-flash",R="gemini-2.0-flash-lite",ce=[Me,Ce,Oe,Ee,ye,Te,Se,Pe,R];var ht="https://api.anthropic.com/v1/messages",T="claude-3-haiku-20240307",xe="claude-3-5-haiku-20241022",Ie="claude-3-5-sonnet-20241022",be="claude-3-7-sonnet-20250219",Le="claude-4-sonnet-20250514",Re="claude-4-opus-20250514",De="claude-sonnet-4-5-20250929",Ae="claude-haiku-4-5-20251001",we="claude-opus-4-5-20251101",Ne="claude-sonnet-4-6",ke="claude-opus-4-6",he=[T,xe,Ie,be,Le,Re,De,Ae,we,Ne,ke];var me="https://openrouter.ai/api/v1/chat/completions",D="openai/gpt-oss-20b:free",Ve="moonshotai/kimi-k2.5",Fe="openai/gpt-5.1-chat",Ge="openai/gpt-5.1-codex",Ue="openai/gpt-5-mini",He="openai/gpt-5-nano",We="openai/gpt-4o",Be="openai/gpt-4.1-mini",Ke="openai/gpt-4.1-nano",$e="anthropic/claude-opus-4",je="anthropic/claude-sonnet-4",ze="anthropic/claude-3.7-sonnet",mt="anthropic/claude-3.5-sonnet",qe="anthropic/claude-haiku-4.5",Je="google/gemini-2.5-pro",Ze="google/gemini-2.5-flash",Xe="google/gemini-2.5-flash-lite-preview-09-2025",ut="z-ai/glm-4.7-flash",dt="z-ai/glm-4.5-air",Ye="z-ai/glm-4.5-air:free",_t=[D,Ye],It=[Fe,Ge,Ue,He,We,Be,Ke,$e,je,ze,qe,Je,Ze,Xe,Ve],gt=20,zt=50,qt=1e3,Jt=10;function k(n){return n.trim().endsWith(":free")}function W(n){return It.some(e=>n.includes(e))}var ue="https://api.z.ai/api/paas/v4/chat/completions",ft="glm-5",B="glm-4.7",vt="glm-4.7-FlashX",Mt="glm-4.7-Flash",Ct="glm-4.6",Qe="glm-4.6V",et="glm-4.6V-FlashX",V="glm-4.6V-Flash",bt=[Qe,et,V];function K(n){return bt.includes(n)}function Ot(n){return n.toLowerCase().startsWith("glm-4.6")}var $="https://api.moonshot.ai/v1/chat/completions",S="kimi-k2.5",Lt=[S];function j(n){return Lt.includes(n)}var F={VERY_SHORT:"veryShort",SHORT:"short",MEDIUM:"medium",LONG:"long",VERY_LONG:"veryLong",DEEP:"deep"},Rt={[F.VERY_SHORT]:40,[F.SHORT]:100,[F.MEDIUM]:200,[F.LONG]:300,[F.VERY_LONG]:1e3,[F.DEEP]:5e3},Et=5e3,yt={casual:{reasoning_effort:"minimal",verbosity:"low",description:"Fast responses for casual chat, quick questions (GPT-4 like experience)"},balanced:{reasoning_effort:"medium",verbosity:"medium",description:"Balanced reasoning for business tasks, learning, general problem solving"},expert:{reasoning_effort:"high",verbosity:"high",description:"Deep reasoning for research, complex analysis, expert-level tasks"}};function C(n){return n?Rt[n]??Et:Et}var Zt="You are a friendly AI avatar. Comment on the situation based on the broadcast screen.",Xt=`You are a skilled summarizing assistant.
1
+ "use strict";var AITuberOnAirChat=(()=>{var lt=Object.defineProperty;var qt=Object.getOwnPropertyDescriptor;var Jt=Object.getOwnPropertyNames;var Zt=Object.prototype.hasOwnProperty;var Xt=(i,e)=>{for(var t in e)lt(i,t,{get:e[t],enumerable:!0})},Yt=(i,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Jt(e))!Zt.call(i,r)&&r!==t&&lt(i,r,{get:()=>e[r],enumerable:!(o=qt(e,r))||o.enumerable});return i};var Qt=i=>Yt(lt({},"__esModule",{value:!0}),i);var Oo={};Xt(Oo,{CHAT_RESPONSE_LENGTH:()=>W,CLAUDE_VISION_SUPPORTED_MODELS:()=>de,ChatServiceFactory:()=>he,ChatServiceHttpClient:()=>g,ClaudeChatService:()=>Q,ClaudeChatServiceProvider:()=>ee,DEFAULT_MAX_TOKENS:()=>bt,DEFAULT_SUMMARY_PROMPT_TEMPLATE:()=>so,DEFAULT_VISION_PROMPT:()=>ro,EMOTION_TAG_CLEANUP_REGEX:()=>Rt,EMOTION_TAG_REGEX:()=>Ft,ENDPOINT_CLAUDE_API:()=>vt,ENDPOINT_GEMINI_API:()=>ft,ENDPOINT_KIMI_CHAT_COMPLETIONS_API:()=>Z,ENDPOINT_OPENAI_CHAT_COMPLETIONS_API:()=>B,ENDPOINT_OPENAI_RESPONSES_API:()=>y,ENDPOINT_OPENROUTER_API:()=>_e,ENDPOINT_ZAI_CHAT_COMPLETIONS_API:()=>ge,EmotionParser:()=>Y,GEMINI_VISION_SUPPORTED_MODELS:()=>me,GPT5_PRESETS:()=>Lt,GPT_5_MODELS:()=>wt,GeminiChatService:()=>te,GeminiChatServiceProvider:()=>oe,HttpError:()=>w,KIMI_VISION_SUPPORTED_MODELS:()=>Vt,KimiChatService:()=>re,KimiChatServiceProvider:()=>se,MAX_TOKENS_BY_LENGTH:()=>Gt,MODEL_ANTHROPIC_CLAUDE_3_5_SONNET:()=>Mt,MODEL_ANTHROPIC_CLAUDE_3_7_SONNET:()=>Xe,MODEL_ANTHROPIC_CLAUDE_4_5_HAIKU:()=>Ye,MODEL_ANTHROPIC_CLAUDE_OPUS_4:()=>Je,MODEL_ANTHROPIC_CLAUDE_SONNET_4:()=>Ze,MODEL_CLAUDE_3_5_HAIKU:()=>Re,MODEL_CLAUDE_3_5_SONNET:()=>De,MODEL_CLAUDE_3_7_SONNET:()=>Ae,MODEL_CLAUDE_3_HAIKU:()=>T,MODEL_CLAUDE_4_5_HAIKU:()=>Ve,MODEL_CLAUDE_4_5_OPUS:()=>Ge,MODEL_CLAUDE_4_5_SONNET:()=>ke,MODEL_CLAUDE_4_6_OPUS:()=>Ue,MODEL_CLAUDE_4_6_SONNET:()=>Fe,MODEL_CLAUDE_4_OPUS:()=>Ne,MODEL_CLAUDE_4_SONNET:()=>we,MODEL_GEMINI_2_0_FLASH:()=>Le,MODEL_GEMINI_2_0_FLASH_LITE:()=>D,MODEL_GEMINI_2_5_FLASH:()=>xe,MODEL_GEMINI_2_5_FLASH_LITE:()=>Ie,MODEL_GEMINI_2_5_FLASH_LITE_PREVIEW_06_17:()=>be,MODEL_GEMINI_2_5_PRO:()=>Pe,MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW:()=>ye,MODEL_GEMINI_3_1_PRO_PREVIEW:()=>Ce,MODEL_GEMINI_3_FLASH_PREVIEW:()=>Se,MODEL_GEMINI_3_PRO_PREVIEW:()=>Te,MODEL_GLM_4_6:()=>xt,MODEL_GLM_4_6V:()=>rt,MODEL_GLM_4_6V_FLASH:()=>H,MODEL_GLM_4_6V_FLASHX:()=>st,MODEL_GLM_4_7:()=>q,MODEL_GLM_4_7_FLASH:()=>Pt,MODEL_GLM_4_7_FLASHX:()=>St,MODEL_GLM_5:()=>Tt,MODEL_GOOGLE_GEMINI_2_5_FLASH:()=>et,MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE_PREVIEW_09_2025:()=>tt,MODEL_GOOGLE_GEMINI_2_5_PRO:()=>Qe,MODEL_GPT_4O:()=>Ee,MODEL_GPT_4O_MINI:()=>G,MODEL_GPT_4_1:()=>ve,MODEL_GPT_4_1_MINI:()=>Me,MODEL_GPT_4_1_NANO:()=>Oe,MODEL_GPT_5:()=>$,MODEL_GPT_5_1:()=>V,MODEL_GPT_5_4:()=>L,MODEL_GPT_5_4_PRO:()=>R,MODEL_GPT_5_MINI:()=>K,MODEL_GPT_5_NANO:()=>k,MODEL_GPT_OSS_20B_FREE:()=>A,MODEL_KIMI_K2_5:()=>S,MODEL_MOONSHOTAI_KIMI_K2_5:()=>He,MODEL_O1:()=>ht,MODEL_O1_MINI:()=>ct,MODEL_O3_MINI:()=>pt,MODEL_OPENAI_GPT_4O:()=>je,MODEL_OPENAI_GPT_4_1_MINI:()=>ze,MODEL_OPENAI_GPT_4_1_NANO:()=>qe,MODEL_OPENAI_GPT_5_1_CHAT:()=>We,MODEL_OPENAI_GPT_5_1_CODEX:()=>Be,MODEL_OPENAI_GPT_5_MINI:()=>Ke,MODEL_OPENAI_GPT_5_NANO:()=>$e,MODEL_ZAI_GLM_4_5_AIR:()=>Et,MODEL_ZAI_GLM_4_5_AIR_FREE:()=>ot,MODEL_ZAI_GLM_4_7_FLASH:()=>Ot,OPENROUTER_CREDITS_THRESHOLD:()=>oo,OPENROUTER_FREE_DAILY_LIMIT_HIGH_CREDITS:()=>to,OPENROUTER_FREE_DAILY_LIMIT_LOW_CREDITS:()=>eo,OPENROUTER_FREE_MODELS:()=>Ct,OPENROUTER_FREE_RATE_LIMIT_PER_MINUTE:()=>yt,OPENROUTER_VISION_SUPPORTED_MODELS:()=>Nt,OpenAIChatService:()=>N,OpenAIChatServiceProvider:()=>ne,OpenAICompatibleChatServiceProvider:()=>ie,OpenRouterChatService:()=>ae,OpenRouterChatServiceProvider:()=>le,StreamTextAccumulator:()=>f,VISION_SUPPORTED_MODELS:()=>ue,ZAIChatService:()=>pe,ZAIChatServiceProvider:()=>ce,ZAI_VISION_SUPPORTED_MODELS:()=>kt,allowsReasoningLow:()=>gt,allowsReasoningMinimal:()=>_t,allowsReasoningNone:()=>dt,allowsReasoningXHigh:()=>mt,buildOpenAICompatibleTools:()=>b,getDefaultReasoningEffortForGPT5Model:()=>F,getMaxTokensForResponseLength:()=>O,installGASFetch:()=>jt,isGPT5Model:()=>j,isKimiVisionModel:()=>X,isOpenRouterFreeModel:()=>U,isOpenRouterVisionModel:()=>z,isResponsesOnlyGPT5Model:()=>ut,isZaiToolStreamModel:()=>It,isZaiVisionModel:()=>J,parseOpenAICompatibleOneShot:()=>I,parseOpenAICompatibleTextStream:()=>P,parseOpenAICompatibleToolStream:()=>x,processChatWithOptionalTools:()=>v,refreshOpenRouterFreeModels:()=>Mo,resolveVisionModel:()=>E,runOnceText:()=>lo,screenplayToText:()=>ao,textToScreenplay:()=>Ut,textsToScreenplay:()=>no});var B="https://api.openai.com/v1/chat/completions",y="https://api.openai.com/v1/responses",k="gpt-5-nano",K="gpt-5-mini",$="gpt-5",V="gpt-5.1",L="gpt-5.4",R="gpt-5.4-pro",ve="gpt-4.1",Me="gpt-4.1-mini",Oe="gpt-4.1-nano",G="gpt-4o-mini",Ee="gpt-4o",pt="o3-mini",ct="o1-mini",ht="o1",ue=[k,K,$,V,L,R,ve,Me,Oe,G,Ee,"o1"],wt=[k,K,$,V,L,R];function j(i){return wt.includes(i)}function ut(i){return i===R}function mt(i){return i===L||i===R}function dt(i){return i===V||i===L}function _t(i){return i===k||i===K||i===$}function gt(i){return i!==R}function F(i){return i===V||i===L?"none":"medium"}var ft="https://generativelanguage.googleapis.com",Ce="gemini-3.1-pro-preview",ye="gemini-3.1-flash-lite-preview",Te="gemini-3-pro-preview",Se="gemini-3-flash-preview",Pe="gemini-2.5-pro",xe="gemini-2.5-flash",Ie="gemini-2.5-flash-lite",be="gemini-2.5-flash-lite-preview-06-17",Le="gemini-2.0-flash",D="gemini-2.0-flash-lite",me=[Ce,ye,Te,Se,Pe,xe,Ie,be,Le,D];var vt="https://api.anthropic.com/v1/messages",T="claude-3-haiku-20240307",Re="claude-3-5-haiku-20241022",De="claude-3-5-sonnet-20241022",Ae="claude-3-7-sonnet-20250219",we="claude-4-sonnet-20250514",Ne="claude-4-opus-20250514",ke="claude-sonnet-4-5-20250929",Ve="claude-haiku-4-5-20251001",Ge="claude-opus-4-5-20251101",Fe="claude-sonnet-4-6",Ue="claude-opus-4-6",de=[T,Re,De,Ae,we,Ne,ke,Ve,Ge,Fe,Ue];var _e="https://openrouter.ai/api/v1/chat/completions",A="openai/gpt-oss-20b:free",He="moonshotai/kimi-k2.5",We="openai/gpt-5.1-chat",Be="openai/gpt-5.1-codex",Ke="openai/gpt-5-mini",$e="openai/gpt-5-nano",je="openai/gpt-4o",ze="openai/gpt-4.1-mini",qe="openai/gpt-4.1-nano",Je="anthropic/claude-opus-4",Ze="anthropic/claude-sonnet-4",Xe="anthropic/claude-3.7-sonnet",Mt="anthropic/claude-3.5-sonnet",Ye="anthropic/claude-haiku-4.5",Qe="google/gemini-2.5-pro",et="google/gemini-2.5-flash",tt="google/gemini-2.5-flash-lite-preview-09-2025",Ot="z-ai/glm-4.7-flash",Et="z-ai/glm-4.5-air",ot="z-ai/glm-4.5-air:free",Ct=[A,ot],Nt=[We,Be,Ke,$e,je,ze,qe,Je,Ze,Xe,Ye,Qe,et,tt,He],yt=20,eo=50,to=1e3,oo=10;function U(i){return i.trim().endsWith(":free")}function z(i){return Nt.some(e=>i.includes(e))}var ge="https://api.z.ai/api/paas/v4/chat/completions",Tt="glm-5",q="glm-4.7",St="glm-4.7-FlashX",Pt="glm-4.7-Flash",xt="glm-4.6",rt="glm-4.6V",st="glm-4.6V-FlashX",H="glm-4.6V-Flash",kt=[rt,st,H];function J(i){return kt.includes(i)}function It(i){return i.toLowerCase().startsWith("glm-4.6")}var Z="https://api.moonshot.ai/v1/chat/completions",S="kimi-k2.5",Vt=[S];function X(i){return Vt.includes(i)}var W={VERY_SHORT:"veryShort",SHORT:"short",MEDIUM:"medium",LONG:"long",VERY_LONG:"veryLong",DEEP:"deep"},Gt={[W.VERY_SHORT]:40,[W.SHORT]:100,[W.MEDIUM]:200,[W.LONG]:300,[W.VERY_LONG]:1e3,[W.DEEP]:5e3},bt=5e3,Lt={casual:{reasoning_effort:"minimal",verbosity:"low",description:"Fast responses for casual chat, quick questions (GPT-4 like experience)"},balanced:{reasoning_effort:"medium",verbosity:"medium",description:"Balanced reasoning for business tasks, learning, general problem solving"},expert:{reasoning_effort:"high",verbosity:"high",description:"Deep reasoning for research, complex analysis, expert-level tasks"}};function O(i){return i?Gt[i]??bt:bt}var ro="You are a friendly AI avatar. Comment on the situation based on the broadcast screen.",so=`You are a skilled summarizing assistant.
2
2
  Analyze the following conversation and produce a summary in the **same language** as the majority of the conversation:
3
3
  - Summaries should highlight key points
4
4
  - Stay concise (around {maxLength} characters if possible)
@@ -7,8 +7,8 @@ Analyze the following conversation and produce a summary in the **same language*
7
7
  If the conversation is in Japanese, summarize in Japanese.
8
8
  If it's in English, summarize in English.
9
9
  If it's in another language, summarize in that language.
10
- `;var A=class extends Error{constructor(t,o,r){super(`HTTP ${t}: ${o}`);this.status=t;this.statusText=o;this.body=r;this.name="HttpError"}},de=class de{static setFetch(e){this.fetchImpl=e}static async post(e,t,o={},r={}){let{timeout:s=3e4,retries:i=0,retryDelay:a=1e3}=r,c={...{"Content-Type":"application/json"},...o},m=null;for(let h=0;h<=i;h++)try{let u=typeof AbortController<"u",p=u?new AbortController:void 0,_=u?setTimeout(()=>p.abort(),s):void 0,M=await de.fetchImpl(e,{method:"POST",headers:c,body:typeof t=="string"?t:JSON.stringify(t),...p?{signal:p.signal}:{}});if(_&&clearTimeout(_),!M.ok){let d=await M.text();throw new A(M.status,M.statusText,d)}return M}catch(u){if(m=u,u instanceof A&&u.status>=400&&u.status<500)throw u;if(u instanceof Error&&u.name==="AbortError")throw new Error(`Request timeout after ${s}ms`);h<i&&await new Promise(p=>setTimeout(p,a*(h+1)))}throw m||new Error("Request failed")}static async handleErrorResponse(e){let t=await e.text();throw new A(e.status,e.statusText,t)}static async get(e,t={},o={}){let{timeout:r=3e4,retries:s=0,retryDelay:i=1e3}=o,a=null;for(let l=0;l<=s;l++)try{let c=typeof AbortController<"u",m=c?new AbortController:void 0,h=c?setTimeout(()=>m.abort(),r):void 0,u=await de.fetchImpl(e,{method:"GET",headers:t,...m?{signal:m.signal}:{}});if(h&&clearTimeout(h),!u.ok){let p=await u.text();throw new A(u.status,u.statusText,p)}return u}catch(c){if(a=c,c instanceof A&&c.status>=400&&c.status<500)throw c;if(c instanceof Error&&c.name==="AbortError")throw new Error(`Request timeout after ${r}ms`);l<s&&await new Promise(m=>setTimeout(m,i*(l+1)))}throw a||new Error("Request failed")}};de.fetchImpl=(e,t)=>fetch(e,t);var g=de;var f=class{static append(e,t){if(!t)return;let o=e[e.length-1];o&&o.type==="text"?o.text+=t:e.push({type:"text",text:t})}static getFullText(e){return e.filter(t=>t.type==="text").map(t=>t.text).join("")}static addTextBlock(e,t){t&&e.push({type:"text",text:t})}};var Yt=["happy","sad","angry","surprised","neutral"],Dt=/\[([a-z]+)\]/i,Tt=/\[[a-z]+\]\s*/gi,z=class{static extractEmotion(e){let t=e.match(Dt);if(t){let o=t[1].toLowerCase(),r=e.replace(Tt,"").trim();return{emotion:o,cleanText:r}}return{cleanText:e}}static isValidEmotion(e){return Yt.includes(e)}static cleanEmotionTags(e){return e.replace(Tt,"").trim()}static addEmotionTag(e,t){return`[${e}] ${t}`}};function At(n){let{emotion:e,cleanText:t}=z.extractEmotion(n);return e?{emotion:e,text:t}:{text:t}}function Qt(n){return n.map(e=>At(e))}function eo(n){return n.emotion?z.addEmotionTag(n.emotion,n.text):n.text}async function to(n,e){let{blocks:t}=await n.chatOnce(e,!1,()=>{});return f.getFullText(t)}var wt=(n,e)=>{try{return JSON.parse(n)}catch(t){if(e){e(n,t);return}throw t}},Nt=async(n,e)=>{let t=n.body?.getReader();if(!t)throw new Error("Response body is null.");let o=new TextDecoder,r="",s=!1;for(;!s;){let{done:i,value:a}=await t.read();if(i)break;r+=o.decode(a,{stream:!0});let l=r.split(`
11
- `);r=l.pop()||"";for(let c of l){let m=c.trim();if(!m||m.startsWith(":")||!m.startsWith("data:"))continue;let h=m.slice(5).trim();if(h==="[DONE]"){s=!0;break}e(h)}}};async function P(n,e,t={}){let o="";return await Nt(n,r=>{let s=wt(r,t.onJsonError);if(!s)return;let i=s.choices?.[0]?.delta?.content||"";i&&(e(i),o+=i)}),o}async function x(n,e,t={}){let o=[],r=new Map,s=t.appendTextBlock??f.append;await Nt(n,l=>{let c=wt(l,t.onJsonError);if(!c)return;let m=c.choices?.[0]?.delta;m?.content&&(e(m.content),s(o,m.content)),m?.tool_calls&&m.tool_calls.forEach(h=>{let u=r.get(h.index)??{id:h.id,name:h.function?.name,args:""};u.args+=h.function?.arguments||"",r.set(h.index,u)})});let i=Array.from(r.entries()).sort((l,c)=>l[0]-c[0]).map(([l,c])=>({type:"tool_use",id:c.id,name:c.name,input:JSON.parse(c.args||"{}")}));return{blocks:[...o,...i],stop_reason:i.length?"tool_use":"end"}}function I(n){let e=n?.choices?.[0],t=[];return e?.message?.tool_calls?.length?e.message.tool_calls.forEach(o=>t.push({type:"tool_use",id:o.id,name:o.function?.name,input:JSON.parse(o.function?.arguments||"{}")})):e?.message?.content&&t.push({type:"text",text:e.message.content}),{blocks:t,stop_reason:e?.finish_reason==="tool_calls"||t.some(o=>o.type==="tool_use")?"tool_use":"end"}}var b=(n,e="chat-completions")=>n.length===0?[]:e==="responses"?n.map(t=>({type:"function",name:t.name,description:t.description,parameters:t.parameters})):n.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.parameters}}));async function v(n){if(!n.hasTools){let t=await n.runWithoutTools();await n.onCompleteResponse(t);return}let e=await n.runWithTools();if(n.onToolBlocks&&n.onToolBlocks(e.blocks),e.stop_reason==="end"){let t=f.getFullText(e.blocks);await n.onCompleteResponse(t);return}throw new Error(n.toolErrorMessage)}var O=n=>{let e=n.model??n.defaultModel,t=n.visionModel??(n.supportsVisionForModel(e)?e:n.defaultVisionModel);if(n.validate==="explicit"&&n.visionModel&&!n.supportsVisionForModel(n.visionModel))throw new Error(`Model ${n.visionModel} does not support vision capabilities.`);if(n.validate==="resolved"&&!n.supportsVisionForModel(t))throw new Error(`Model ${t} does not support vision capabilities.`);return t};var oo="https://openrouter.ai/api/v1/models",ro=2,so=12e3,io=1,no=10;function St(n){return n instanceof Error?n.message:String(n)}function tt(n,e){return typeof n!="number"||!Number.isFinite(n)?e:Math.max(1,Math.floor(n))}function ao(n){let e=new Set,t=[];for(let o of n){let r=o.trim();!r||e.has(r)||(e.add(r),t.push(r))}return t}async function kt(n,e,t){if(!(typeof AbortController<"u"))return fetch(n,e);let r=new AbortController,s=setTimeout(()=>r.abort(),t);try{return await fetch(n,{...e,signal:r.signal})}catch(i){throw i instanceof Error&&i.name==="AbortError"?new Error(`Timeout after ${t}ms`):i}finally{clearTimeout(s)}}async function Vt(n){let e=`HTTP ${n.status} ${n.statusText}`.trim(),t="";try{t=await n.text()}catch{return e}let o=t.replace(/\s+/g," ").trim().slice(0,200);return o?`${e}: ${o}`:e}function lo(n){if(!n||typeof n!="object")throw new Error("Invalid models response shape");let e=n,t=Array.isArray(e.data)?e.data:Array.isArray(e.models)?e.models:[];if(t.length===0)return[];let o=t.map(r=>r.id).filter(r=>typeof r=="string");return ao(o)}async function po({modelId:n,apiKey:e,endpoint:t,timeoutMs:o,appName:r,appUrl:s}){let i={Authorization:`Bearer ${e}`,"Content-Type":"application/json"};r&&(i["X-Title"]=r),s&&(i["HTTP-Referer"]=s);try{let a=await kt(t,{method:"POST",headers:i,body:JSON.stringify({model:n,messages:[{role:"user",content:"Reply only with OK."}],stream:!1})},o);if(!a.ok)return{id:n,ok:!1,reason:await Vt(a)};try{await a.json()}catch(l){return{id:n,ok:!1,reason:`JSON parse failed: ${St(l)}`}}return{id:n,ok:!0}}catch(a){return{id:n,ok:!1,reason:St(a)}}}async function co(n,e,t){if(n.length===0)return[];let o=new Array(n.length),r=0,s=Math.min(e,n.length);return await Promise.all(Array.from({length:s},async()=>{for(;r<n.length;){let i=r;r+=1,o[i]=await t(n[i])}})),o}async function ho(n){let e=n.apiKey.trim();if(!e)throw new Error("OpenRouter API key is required.");let t=n.modelsEndpoint||oo,o=n.endpoint||me,r=tt(n.timeoutMs,so),s=tt(n.concurrency,ro),i=tt(n.maxCandidates,io),a=tt(n.maxWorking,no),l=await kt(t,{method:"GET"},r);if(!l.ok)throw new Error(await Vt(l));let c;try{c=await l.json()}catch(_){throw new Error(`JSON parse failed: ${St(_)}`)}let m=lo(c).filter(_=>k(_)).slice(0,i),h=await co(m,s,_=>po({modelId:_,apiKey:e,endpoint:o,timeoutMs:r,appName:n.appName,appUrl:n.appUrl})),u=h.filter(_=>_.ok).map(_=>_.id).slice(0,a),p=h.filter(_=>!_.ok).map(_=>({id:_.id,reason:_.reason||"Unknown error"}));return{working:u,failed:p,fetchedAt:Date.now()}}var q=class{constructor(e,t=T,o=T,r=[],s=[],i){this.provider="claude";if(this.apiKey=e,this.model=t||T,this.visionModel=o||T,this.tools=r,this.mcpServers=s,this.responseLength=i,!he.includes(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`)}getModel(){return this.model}getVisionModel(){return this.visionModel}getMCPServers(){return this.mcpServers}addMCPServer(e){this.mcpServers.push(e)}removeMCPServer(e){this.mcpServers=this.mcpServers.filter(t=>t.name!==e)}hasMCPServers(){return this.mcpServers.length>0}async processChat(e,t,o){await v({hasTools:this.tools.length>0||this.mcpServers.length>0,runWithoutTools:async()=>{let r=await this.callClaude(e,this.model,!0);return this.parsePureStream(r,t)},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}async processVisionChat(e,t,o){await v({hasTools:this.tools.length>0||this.mcpServers.length>0,runWithoutTools:async()=>{let r=await this.callClaude(e,this.visionModel,!0);return this.parsePureStream(r,t)},runWithTools:()=>this.visionChatOnce(e),onCompleteResponse:o,toolErrorMessage:"processVisionChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}convertMessagesToClaudeFormat(e){return e.map(t=>({role:this.mapRoleToClaude(t.role),content:t.content}))}convertVisionMessagesToClaudeFormat(e){return e.map(t=>{if(typeof t.content=="string")return{role:this.mapRoleToClaude(t.role),content:[{type:"text",text:t.content}]};if(Array.isArray(t.content)){let o=t.content.map(r=>{if(r.type==="image_url"){if(r.image_url.url.startsWith("data:")){let s=r.image_url.url.match(/^data:([^;]+);base64,(.+)$/);return s?{type:"image",source:{type:"base64",media_type:s[1],data:s[2]}}:null}return{type:"image",source:{type:"url",url:r.image_url.url,media_type:this.getMimeTypeFromUrl(r.image_url.url)}}}return r}).filter(r=>r);return{role:this.mapRoleToClaude(t.role),content:o}}return{role:this.mapRoleToClaude(t.role),content:[]}})}mapRoleToClaude(e){switch(e){case"system":return"system";case"user":return"user";case"assistant":return"assistant";default:return"user"}}getMimeTypeFromUrl(e){switch(e.split(".").pop()?.toLowerCase()){case"jpg":case"jpeg":return"image/jpeg";case"png":return"image/png";case"gif":return"image/gif";case"webp":return"image/webp";default:return"image/jpeg"}}async callClaude(e,t,o,r){let s=e.find(h=>h.role==="system")?.content??"",i=e.filter(h=>h.role!=="system"),a=i.some(h=>Array.isArray(h.content)&&h.content.some(u=>u.type==="image_url"||u.type==="image")),l={model:t,system:s,messages:a?this.convertVisionMessagesToClaudeFormat(i):this.convertMessagesToClaudeFormat(i),stream:o,max_tokens:r!==void 0?r:C(this.responseLength)};this.tools.length&&(l.tools=this.tools.map(h=>({name:h.name,description:h.description,input_schema:h.parameters})),l.tool_choice={type:"auto"}),this.mcpServers.length>0&&(l.mcp_servers=this.mcpServers);let c={"Content-Type":"application/json","x-api-key":this.apiKey,"anthropic-version":"2023-06-01","anthropic-dangerous-direct-browser-access":"true"};return this.mcpServers.length>0&&(c["anthropic-beta"]="mcp-client-2025-04-04"),await g.post(ht,l,c)}async parseStream(e,t){let o=e.body.getReader(),r=new TextDecoder,s=[],i=new Map,a="";for(;;){let{done:l,value:c}=await o.read();if(l)break;a+=r.decode(c,{stream:!0});let m;for(;(m=a.indexOf(`
12
- `))!==-1;){let h=a.slice(0,m).trim();if(a=a.slice(m+1),!h.startsWith("data:"))continue;let u=h.slice(5).trim();if(u==="[DONE]")break;let p=JSON.parse(u);if(p.type==="content_block_delta"&&p.delta?.text&&(t(p.delta.text),s.push({type:"text",text:p.delta.text})),p.type==="content_block_start"&&p.content_block?.type==="tool_use"?i.set(p.index,{id:p.content_block.id,name:p.content_block.name,args:""}):p.type==="content_block_start"&&p.content_block?.type==="mcp_tool_use"?i.set(p.index,{id:p.content_block.id,name:p.content_block.name,args:"",server_name:p.content_block.server_name}):p.type==="content_block_start"&&p.content_block?.type==="tool_result"?s.push({type:"tool_result",tool_use_id:p.content_block.tool_use_id,content:p.content_block.content??""}):p.type==="content_block_start"&&p.content_block?.type==="mcp_tool_result"&&s.push({type:"mcp_tool_result",tool_use_id:p.content_block.tool_use_id,is_error:p.content_block.is_error??!1,content:p.content_block.content??[]}),p.type==="content_block_delta"&&p.delta?.type==="input_json_delta"){let _=i.get(p.index);_&&(_.args+=p.delta.partial_json||"")}if(p.type==="content_block_stop"&&i.has(p.index)){let{id:_,name:M,args:d,server_name:E}=i.get(p.index);E?s.push({type:"mcp_tool_use",id:_,name:M,server_name:E,input:JSON.parse(d||"{}")}):s.push({type:"tool_use",id:_,name:M,input:JSON.parse(d||"{}")}),i.delete(p.index)}}}return{blocks:s,stop_reason:s.some(l=>l.type==="tool_use"||l.type==="mcp_tool_use")?"tool_use":"end"}}async parsePureStream(e,t){let{blocks:o}=await this.parseStream(e,t);return o.filter(r=>r.type==="text").map(r=>r.text).join("")}parseOneShot(e){let t=[];return(e.content??[]).forEach(o=>{o.type==="text"?t.push({type:"text",text:o.text}):o.type==="tool_use"?t.push({type:"tool_use",id:o.id,name:o.name,input:o.input??{}}):o.type==="mcp_tool_use"?t.push({type:"mcp_tool_use",id:o.id,name:o.name,server_name:o.server_name,input:o.input??{}}):o.type==="tool_result"?t.push({type:"tool_result",tool_use_id:o.tool_use_id,content:o.content??""}):o.type==="mcp_tool_result"&&t.push({type:"mcp_tool_result",tool_use_id:o.tool_use_id,is_error:o.is_error??!1,content:o.content??[]})}),{blocks:t,stop_reason:t.some(o=>o.type==="tool_use"||o.type==="mcp_tool_use")?"tool_use":"end"}}async chatOnce(e,t=!0,o=()=>{},r){let s=await this.callClaude(e,this.model,t,r),i=t?await this.parseStream(s,o):this.parseOneShot(await s.json());return this.convertToStandardCompletion(i)}async visionChatOnce(e,t=!1,o=()=>{},r){let s=await this.callClaude(e,this.visionModel,t,r),i=t?await this.parseStream(s,o):this.parseOneShot(await s.json());return this.convertToStandardCompletion(i)}convertToStandardCompletion(e){return{blocks:e.blocks.filter(o=>o.type==="text"||o.type==="tool_use"||o.type==="tool_result"),stop_reason:e.stop_reason}}};var J=class{createChatService(e){let t=O({model:e.model,visionModel:e.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:this.getDefaultModel(),supportsVisionForModel:o=>this.supportsVisionForModel(o),validate:"resolved"});return new q(e.apiKey,e.model||this.getDefaultModel(),t,e.tools??[],e.mcpServers??[],e.responseLength)}getProviderName(){return"claude"}getSupportedModels(){return[T,xe,Ie,be,Le,Re,De,Ae,we,Ne,ke]}getDefaultModel(){return T}supportsVision(){return!0}supportsVisionForModel(e){return he.includes(e)}};var ot=class{static async fetchToolSchemas(e){try{let t={"Content-Type":"application/json"};e.authorization_token&&(t.Authorization=`Bearer ${e.authorization_token}`);let r=await(await g.post(`${e.url}/tools`,{},t)).json();return Array.isArray(r.tools)?r.tools.map(s=>({name:`mcp_${e.name}_${s.name}`,description:s.description||`Tool from ${e.name} MCP server`,parameters:s.inputSchema||{type:"object",properties:{},required:[]}})):[{name:`mcp_${e.name}_search`,description:`Search using ${e.name} MCP server`,parameters:{type:"object",properties:{query:{type:"string",description:"Search query"}},required:["query"]}}]}catch(t){return console.warn(`Failed to fetch MCP schemas from ${e.name}:`,t),[{name:`mcp_${e.name}_search`,description:`Search using ${e.name} MCP server (schema fetch failed)`,parameters:{type:"object",properties:{query:{type:"string",description:"Search query"}},required:["query"]}}]}}static async fetchAllToolSchemas(e){let t=[];for(let o of e)try{let r=await this.fetchToolSchemas(o);t.push(...r)}catch(r){console.error(`Failed to fetch schemas from ${o.name}:`,r)}return t}};var Z=class{constructor(e,t=R,o=R,r=[],s=[],i){this.provider="gemini";this.mcpToolSchemas=[];this.mcpSchemasInitialized=!1;this.callIdMap=new Map;if(this.apiKey=e,this.model=t,this.responseLength=i,!ce.includes(o))throw new Error(`Model ${o} does not support vision capabilities.`);this.visionModel=o,this.tools=r,this.mcpServers=s}safeJsonParse(e){try{return JSON.parse(e)}catch{return e}}normalizeToolResult(e){return e===null?{content:null}:typeof e=="object"?e:{content:e}}adaptKeysForApi(e){let t={toolConfig:"tool_config",functionCallingConfig:"function_calling_config",functionDeclarations:"function_declarations",functionCall:"function_call",functionResponse:"function_response"};return Array.isArray(e)?e.map(o=>this.adaptKeysForApi(o)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([o,r])=>[t[o]??o,this.adaptKeysForApi(r)])):e}getModel(){return this.model}getVisionModel(){return this.visionModel}getMCPServers(){return this.mcpServers}addMCPServer(e){this.mcpServers.push(e),this.mcpSchemasInitialized=!1}removeMCPServer(e){this.mcpServers=this.mcpServers.filter(t=>t.name!==e),this.mcpSchemasInitialized=!1}hasMCPServers(){return this.mcpServers.length>0}async initializeMCPSchemas(){if(!(this.mcpSchemasInitialized||this.mcpServers.length===0))try{let e=new Promise((o,r)=>setTimeout(()=>r(new Error("MCP schema fetch timeout")),5e3)),t=ot.fetchAllToolSchemas(this.mcpServers);this.mcpToolSchemas=await Promise.race([t,e]),this.mcpSchemasInitialized=!0}catch(e){console.warn("Failed to initialize MCP schemas, using fallback:",e),this.mcpToolSchemas=this.mcpServers.map(t=>({name:`mcp_${t.name}_search`,description:`Search using ${t.name} MCP server (fallback)`,parameters:{type:"object",properties:{query:{type:"string",description:"Search query"}},required:["query"]}})),this.mcpSchemasInitialized=!0}}async processChat(e,t,o){try{await v({hasTools:this.tools.length>0||this.mcpServers.length>0,runWithoutTools:async()=>{let r=await this.callGemini(e,this.model,!0),{blocks:s}=await this.parseStream(r,t);return f.getFullText(s)},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"Received functionCall. Use chatOnce() loop when tools are enabled."})}catch(r){throw console.error("Error in processChat:",r),r}}async processVisionChat(e,t,o){try{await v({hasTools:this.tools.length>0||this.mcpServers.length>0,runWithoutTools:async()=>{let r=await this.callGemini(e,this.visionModel,!0),{blocks:s}=await this.parseStream(r,t);return f.getFullText(s)},runWithTools:()=>this.visionChatOnce(e),onToolBlocks:r=>{r.filter(s=>s.type==="text").forEach(s=>t(s.text))},onCompleteResponse:o,toolErrorMessage:"Received functionCall. Use visionChatOnce() loop when tools are enabled."})}catch(r){throw console.error("Error in processVisionChat:",r),r}}convertMessagesToGeminiFormat(e){let t=[],o=null,r=[],s=()=>{o&&r.length&&(t.push({role:o,parts:[...r]}),r=[])};for(let i of e){let a=this.mapRoleToGemini(i.role);if(i.tool_calls){s();for(let l of i.tool_calls)this.callIdMap.set(l.id,l.function.name),t.push({role:"model",parts:[{functionCall:{name:l.function.name,args:JSON.parse(l.function.arguments||"{}")}}]});continue}if(i.role==="tool"){s();let l=i.name??this.callIdMap.get(i.tool_call_id)??"result";t.push({role:"user",parts:[{functionResponse:{name:l,response:this.normalizeToolResult(this.safeJsonParse(i.content))}}]});continue}a!==o&&s(),o=a,r.push({text:i.content})}return s(),t}async callGemini(e,t,o=!1,r){let a={contents:e.some(d=>Array.isArray(d.content)&&d.content.some(E=>E?.type==="image_url"||E?.inlineData))?await this.convertVisionMessagesToGeminiFormat(e):this.convertMessagesToGeminiFormat(e),generationConfig:{maxOutputTokens:r!==void 0?r:C(this.responseLength)}},l=[];if(this.tools.length>0&&l.push(...this.tools.map(d=>({name:d.name,description:d.description,parameters:d.parameters}))),this.mcpServers.length>0)try{await this.initializeMCPSchemas(),l.push(...this.mcpToolSchemas.map(d=>({name:d.name,description:d.description,parameters:d.parameters})))}catch(d){console.warn("MCP initialization failed, skipping MCP tools:",d)}l.length>0&&(a.tools=[{functionDeclarations:l}],a.toolConfig={functionCallingConfig:{mode:"AUTO"}});let c=async(d,E)=>{let rt=o?"streamGenerateContent":"generateContent",Pt=o?"?alt=sse":"",Ut=`${ct}/${d}/models/${t}:${rt}${Pt}${Pt?"&":"?"}key=${this.apiKey}`;return g.post(Ut,E)},m=/flash[-_]lite/.test(t),h=/gemini-2\.5/.test(t),u=/^gemini-3(?:\.[0-9]+)?-.*preview/.test(t),p=m||h||u,_=p?"v1beta":"v1",M=async()=>{try{let d=_==="v1"?a:this.adaptKeysForApi(a);return await c(_,d)}catch(d){let E=/Unknown name|Cannot find field|404/.test(d?.message||"")||d?.status===404;if(!p&&E)return await c("v1beta",this.adaptKeysForApi(a));throw d}};try{return await M()}catch(d){throw d.body&&(console.error("Gemini API Error Details:",d.body),console.error("Request Body:",JSON.stringify(a,null,2))),d}}async convertVisionMessagesToGeminiFormat(e){let t=[],o=null,r=[];for(let s of e){let i=this.mapRoleToGemini(s.role);if(s.tool_calls){for(let a of s.tool_calls)t.push({role:"model",parts:[{functionCall:{name:a.function.name,args:JSON.parse(a.function.arguments||"{}")}}]});continue}if(s.role==="tool"){let a=s.name??this.callIdMap.get(s.tool_call_id)??"result";t.push({role:"user",parts:[{functionResponse:{name:a,response:this.normalizeToolResult(this.safeJsonParse(s.content))}}]});continue}if(i!==o&&r.length>0&&(t.push({role:o,parts:[...r]}),r=[]),o=i,typeof s.content=="string")r.push({text:s.content});else if(Array.isArray(s.content)){for(let a of s.content)if(a.type==="text")r.push({text:a.text});else if(a.type==="image_url")try{let c=await(await g.get(a.image_url.url)).blob(),m=await this.blobToBase64(c);r.push({inlineData:{mimeType:c.type||"image/jpeg",data:m.split(",")[1]}})}catch(l){throw console.error("Error processing image:",l),new Error(`Failed to process image: ${l.message}`)}}}return o&&r.length>0&&t.push({role:o,parts:[...r]}),t}blobToBase64(e){return new Promise((t,o)=>{let r=new FileReader;r.onloadend=()=>t(r.result),r.onerror=o,r.readAsDataURL(e)})}mapRoleToGemini(e){switch(e){case"system":return"model";case"user":return"user";case"assistant":return"model";default:return"user"}}async parseStream(e,t){let o=e.body.getReader(),r=new TextDecoder,s=[],i=[],a="",l=m=>{if(!m||m==="[DONE]")return;let h;try{h=JSON.parse(m)}catch{return}for(let u of h.candidates??[])for(let p of u.content?.parts??[])p.text&&(t(p.text),f.addTextBlock(s,p.text)),p.functionCall&&i.push({type:"tool_use",id:this.genUUID(),name:p.functionCall.name,input:p.functionCall.args??{}}),p.functionResponse&&i.push({type:"tool_result",tool_use_id:p.functionResponse.name,content:JSON.stringify(p.functionResponse.response)})};for(;;){let{done:m,value:h}=await o.read();if(m)break;a+=r.decode(h,{stream:!0});let u;for(;(u=a.indexOf(`
13
- `))!==-1;){let p=a.slice(0,u);if(a=a.slice(u+1),p.endsWith("\r")&&(p=p.slice(0,-1)),!p.trim()){l("");continue}p.startsWith("data:")&&(p=p.slice(5).trim()),p&&l(p)}}return a&&l(a),{blocks:[...s,...i],stop_reason:i.some(m=>m.type==="tool_use")?"tool_use":"end"}}parseOneShot(e){let t=[],o=[];for(let s of e.candidates??[])for(let i of s.content?.parts??[])i.text&&t.push({type:"text",text:i.text}),i.functionCall&&o.push({type:"tool_use",id:this.genUUID(),name:i.functionCall.name,input:i.functionCall.args??{}}),i.functionResponse&&o.push({type:"tool_result",tool_use_id:i.functionResponse.name,content:JSON.stringify(i.functionResponse.response)});return{blocks:[...t,...o],stop_reason:o.some(s=>s.type==="tool_use")?"tool_use":"end"}}async chatOnce(e,t=!0,o=()=>{},r){let s=await this.callGemini(e,this.model,t,r);return t?this.parseStream(s,o):this.parseOneShot(await s.json())}async visionChatOnce(e,t=!1,o=()=>{},r){let s=await this.callGemini(e,this.visionModel,t,r);return t?this.parseStream(s,o):this.parseOneShot(await s.json())}genUUID(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}};var X=class{createChatService(e){let t=O({model:e.model,visionModel:e.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:this.getDefaultModel(),supportsVisionForModel:o=>this.supportsVisionForModel(o),validate:"resolved"});return new Z(e.apiKey,e.model||this.getDefaultModel(),t,e.tools||[],e.mcpServers||[],e.responseLength)}getProviderName(){return"gemini"}getSupportedModels(){return[Me,Ce,Oe,Ee,ye,Te,Se,Pe,R]}getDefaultModel(){return R}supportsVision(){return!0}supportsVisionForModel(e){return ce.includes(e)}};var Y=class{constructor(e,t=S,o=S,r,s=$,i,a,l){this.provider="kimi";this.apiKey=e,this.model=t,this.tools=r||[],this.endpoint=s,this.responseLength=i,this.responseFormat=a,this.thinking=l??{type:"enabled"},this.visionModel=o}getModel(){return this.model}getVisionModel(){return this.visionModel}async processChat(e,t,o){await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callKimi(e,this.model,!0);return this.handleStream(r,t)},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}async processVisionChat(e,t,o){if(!j(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callKimi(e,this.visionModel,!0);return this.handleStream(r,t)},runWithTools:()=>this.visionChatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processVisionChat received tool_calls. ChatProcessor must use visionChatOnce() loop when tools are enabled."})}async chatOnce(e,t=!0,o=()=>{},r){let s=await this.callKimi(e,this.model,t,r);return this.parseResponse(s,t,o)}async visionChatOnce(e,t=!1,o=()=>{},r){if(!j(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);let s=await this.callKimi(e,this.visionModel,t,r);return this.parseResponse(s,t,o)}async parseResponse(e,t,o){return t?this.parseStream(e,o):this.parseOneShot(await e.json())}async callKimi(e,t,o=!1,r){let s=this.buildRequestBody(e,t,o,r);return await g.post(this.endpoint,s,{Authorization:`Bearer ${this.apiKey}`})}buildRequestBody(e,t,o,r){let s={model:t,stream:o,messages:e},i=r!==void 0?r:C(this.responseLength);i!==void 0&&(s.max_tokens=i),this.responseFormat&&(s.response_format=this.responseFormat);let a=this.tools.length>0?{type:"disabled"}:this.thinking;a&&(this.isSelfHostedEndpoint()?a.type==="disabled"&&(s.chat_template_kwargs={thinking:!1}):s.thinking=a);let l=this.buildToolsDefinition();return l.length>0&&(s.tools=l,s.tool_choice="auto"),s}isSelfHostedEndpoint(){return this.normalizeEndpoint(this.endpoint)!==this.normalizeEndpoint($)}normalizeEndpoint(e){return e.replace(/\/+$/,"")}buildToolsDefinition(){return b(this.tools,"chat-completions")}async handleStream(e,t){return P(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}async parseStream(e,t){return x(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}parseOneShot(e){return I(e)}};var Q=class{createChatService(e){let t=this.resolveEndpoint(e),o=e.model||this.getDefaultModel(),r=O({model:o,visionModel:e.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:this.getDefaultVisionModel(),supportsVisionForModel:l=>this.supportsVisionForModel(l),validate:"explicit"}),s=e.tools,i=e.thinking??{type:"enabled"},a=s&&s.length>0?{type:"disabled"}:i;return new Y(e.apiKey,o,r,s,t,e.responseLength,e.responseFormat,a)}getProviderName(){return"kimi"}getSupportedModels(){return[S]}getDefaultModel(){return S}getDefaultVisionModel(){return S}supportsVision(){return!0}supportsVisionForModel(e){return j(e)}resolveEndpoint(e){if(e.endpoint)return this.normalizeEndpoint(e.endpoint);if(e.baseUrl){let t=this.normalizeEndpoint(e.baseUrl);return t.endsWith("/chat/completions")?t:`${t}/chat/completions`}return $}normalizeEndpoint(e){return e.replace(/\/+$/,"")}};var w=class{constructor(e,t=N,o=N,r,s=G,i=[],a,l,c,m=!1,h="openai",u=!0){if(this.provider=h,this.apiKey=e,this.model=t,this.tools=r||[],this.endpoint=s,this.mcpServers=i,this.responseLength=a,this.verbosity=l,this.reasoning_effort=c,this.enableReasoningSummary=m,u&&!pe.includes(o))throw new Error(`Model ${o} does not support vision capabilities.`);this.visionModel=o}getModel(){return this.model}getVisionModel(){return this.visionModel}async processChat(e,t,o){await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callOpenAI(e,this.model,!0),s=this.endpoint===y;try{if(s){let i=await this.parseResponsesStream(r,t);return f.getFullText(i.blocks)}return this.handleStream(r,t)}catch(i){throw console.error("[processChat] Error in streaming/completion:",i),i}},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}async processVisionChat(e,t,o){try{await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callOpenAI(e,this.visionModel,!0),s=this.endpoint===y;try{if(s){let i=await this.parseResponsesStream(r,t);return f.getFullText(i.blocks)}return this.handleStream(r,t)}catch(i){throw console.error("[processVisionChat] Error in streaming/completion:",i),i}},runWithTools:()=>this.visionChatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processVisionChat received tool_calls. ChatProcessor must use visionChatOnce() loop when tools are enabled."})}catch(r){throw console.error("Error in processVisionChat:",r),r}}async chatOnce(e,t=!0,o=()=>{},r){let s=await this.callOpenAI(e,this.model,t,r);return this.parseResponse(s,t,o)}async visionChatOnce(e,t=!1,o=()=>{},r){let s=await this.callOpenAI(e,this.visionModel,t,r);return this.parseResponse(s,t,o)}async parseResponse(e,t,o){return this.endpoint===y?t?this.parseResponsesStream(e,o):this.parseResponsesOneShot(await e.json()):t?this.parseStream(e,o):this.parseOneShot(await e.json())}async callOpenAI(e,t,o=!1,r){let s=this.buildRequestBody(e,t,o,r),i={};return(this.provider!=="openai-compatible"||this.apiKey.trim()!=="")&&(i.Authorization=`Bearer ${this.apiKey}`),await g.post(this.endpoint,s,i)}buildRequestBody(e,t,o,r){let s=this.endpoint===y;this.validateMCPCompatibility();let i={model:t,stream:o},a=r!==void 0?r:this.provider==="openai-compatible"?this.responseLength!==void 0?C(this.responseLength):void 0:C(this.responseLength);s?a!==void 0&&(i.max_output_tokens=a):a!==void 0&&(this.provider==="openai-compatible"?i.max_tokens=a:i.max_completion_tokens=a),s?i.input=this.cleanMessagesForResponsesAPI(e):i.messages=e,H(t)&&(s?(this.reasoning_effort&&(i.reasoning={...i.reasoning,effort:this.reasoning_effort},this.enableReasoningSummary&&(i.reasoning.summary="auto")),this.verbosity&&(i.text={...i.text,format:{type:"text"},verbosity:this.verbosity})):(this.reasoning_effort&&(i.reasoning_effort=this.reasoning_effort),this.verbosity&&(i.verbosity=this.verbosity)));let l=this.buildToolsDefinition();return l.length>0&&(i.tools=l,s||(i.tool_choice="auto")),i}validateMCPCompatibility(){if(this.mcpServers.length>0&&this.endpoint===G)throw new Error(`MCP servers are not supported with Chat Completions API. Current endpoint: ${this.endpoint}. Please use OpenAI Responses API endpoint: ${y}. MCP tools are only available in the Responses API endpoint.`)}cleanMessagesForResponsesAPI(e){return e.map(t=>{let r={role:t.role==="tool"?"user":t.role};return typeof t.content=="string"?r.content=t.content:Array.isArray(t.content)?r.content=t.content.map(s=>s.type==="text"?{type:"input_text",text:s.text}:s.type==="image_url"?{type:"input_image",image_url:s.image_url.url}:s):r.content=t.content,r})}buildToolsDefinition(){let e=this.endpoint===y,t=[];return this.tools.length>0&&t.push(...b(this.tools,e?"responses":"chat-completions")),this.mcpServers.length>0&&e&&t.push(...this.buildMCPToolsDefinition()),t}buildMCPToolsDefinition(){return this.mcpServers.map(e=>{let t={type:"mcp",server_label:e.name,server_url:e.url};return e.require_approval&&(t.require_approval=e.require_approval),e.tool_configuration?.allowed_tools&&(t.allowed_tools=e.tool_configuration.allowed_tools),e.authorization_token&&(t.headers={Authorization:`Bearer ${e.authorization_token}`}),t})}async handleStream(e,t){return P(e,t)}async parseStream(e,t){return x(e,t,{appendTextBlock:f.addTextBlock})}parseOneShot(e){return I(e)}async parseResponsesStream(e,t){let o=e.body.getReader(),r=new TextDecoder,s=[],i=new Map,a="";for(;;){let{done:m,value:h}=await o.read();if(m)break;a+=r.decode(h,{stream:!0});let u="",p="",_=a.split(`
14
- `);a=_.pop()||"";for(let M=0;M<_.length;M++){let d=_[M].trim();if(d.startsWith("event:"))u=d.slice(6).trim();else if(d.startsWith("data:"))p=d.slice(5).trim();else if(d===""&&u&&p){try{let E=JSON.parse(p),rt=this.handleResponsesSSEEvent(u,E,t,s,i)}catch{console.warn("Failed to parse SSE data:",p)}u="",p=""}}}let l=Array.from(i.values()).map(m=>({type:"tool_use",id:m.id,name:m.name,input:m.input||{}}));return{blocks:[...s,...l],stop_reason:l.length?"tool_use":"end"}}handleResponsesSSEEvent(e,t,o,r,s){switch(e){case"response.output_item.added":t.item?.type==="message"&&Array.isArray(t.item.content)?t.item.content.forEach(i=>{i.type==="output_text"&&i.text&&(o(i.text),f.append(r,i.text))}):t.item?.type==="function_call"&&s.set(t.item.id,{id:t.item.id,name:t.item.name,input:t.item.arguments?JSON.parse(t.item.arguments):{}});break;case"response.content_part.added":t.part?.type==="output_text"&&typeof t.part.text=="string"&&(o(t.part.text),f.append(r,t.part.text));break;case"response.output_text.delta":case"response.content_part.delta":{let i=typeof t.delta=="string"?t.delta:t.delta?.text??"";i&&(o(i),f.append(r,i))}break;case"response.output_text.done":case"response.content_part.done":break;case"response.completed":return"completed";case"response.reasoning.started":case"response.reasoning.delta":case"response.reasoning.done":break;default:break}}parseResponsesOneShot(e){let t=[];return e.output&&Array.isArray(e.output)&&e.output.forEach(o=>{o.type==="message"&&o.content&&o.content.forEach(r=>{r.type==="output_text"&&r.text&&t.push({type:"text",text:r.text})}),o.type==="function_call"&&t.push({type:"tool_use",id:o.id,name:o.name,input:o.arguments?JSON.parse(o.arguments):{}})}),{blocks:t,stop_reason:t.some(o=>o.type==="tool_use")?"tool_use":"end"}}};var ee=class{createChatService(e){return this.validateRequiredOptions(e),new w(e.apiKey?.trim()??"",e.model,e.visionModel??e.model,e.tools,e.endpoint,[],e.responseLength,e.verbosity,e.reasoning_effort,e.enableReasoningSummary,this.getProviderName(),!1)}getProviderName(){return"openai-compatible"}getSupportedModels(){return[]}supportsVision(){return!1}getDefaultModel(){return"local-model"}validateRequiredOptions(e){if(e.mcpServers!==void 0)throw new Error("openai-compatible provider does not support mcpServers.");let t=e.endpoint?.trim();if(!t)throw new Error("openai-compatible provider requires endpoint (full URL).");let o;try{o=new URL(t)}catch{throw new Error("openai-compatible provider requires endpoint to be a full URL.")}if(o.protocol!=="http:"&&o.protocol!=="https:")throw new Error("openai-compatible provider requires endpoint to be a full URL.");if(!e.model?.trim())throw new Error("openai-compatible provider requires model.")}};var te=class{createChatService(e){let t=this.optimizeGPT5Options(e),o=O({model:t.model,visionModel:t.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:this.getDefaultModel(),supportsVisionForModel:c=>this.supportsVisionForModel(c),validate:"resolved"}),r=t.tools,s=t.mcpServers??[],i=t.model||this.getDefaultModel(),a=!1;s.length>0?a=!0:H(i)&&(a=(t.gpt5EndpointPreference||"chat")==="responses");let l=t.endpoint||(a?y:G);return new w(t.apiKey,i,o,r,l,s,t.responseLength,t.verbosity,t.reasoning_effort,t.enableReasoningSummary,this.getProviderName())}getProviderName(){return"openai"}getSupportedModels(){return[U,ae,le,L,_e,ge,fe,N,ve,it,nt,"o1"]}getDefaultModel(){return U}supportsVision(){return!0}supportsVisionForModel(e){return pe.includes(e)}optimizeGPT5Options(e){let t=e.model||this.getDefaultModel();if(!H(t))return e;let o={...e};if(e.gpt5Preset){let r=yt[e.gpt5Preset];o.reasoning_effort=r.reasoning_effort,o.verbosity=r.verbosity}else e.reasoning_effort||(o.reasoning_effort=this.getDefaultReasoningEffortForModel(t));return o.reasoning_effort=this.normalizeReasoningEffort(t,o.reasoning_effort),o}getDefaultReasoningEffortForModel(e){return e===L?"none":"medium"}normalizeReasoningEffort(e,t){if(t)return t==="none"&&!lt(e)?this.getDefaultReasoningEffortForModel(e):t==="minimal"&&!pt(e)?"none":t}};var oe=class{constructor(e,t=D,o=D,r,s=me,i,a,l,c,m,h){this.provider="openrouter";this.lastRequestTime=0;this.requestCount=0;this.apiKey=e,this.model=t,this.tools=r||[],this.endpoint=s,this.responseLength=i,this.appName=a,this.appUrl=l,this.reasoning_effort=c,this.includeReasoning=m,this.reasoningMaxTokens=h,this.visionModel=o}getModel(){return this.model}getVisionModel(){return this.visionModel}async applyRateLimiting(){if(!k(this.model))return;let e=Date.now(),t=e-this.lastRequestTime;if(t>6e4&&(this.requestCount=0),this.requestCount>=gt){let o=6e4-t;o>0&&(console.log(`Rate limit reached for free tier. Waiting ${o}ms...`),await new Promise(r=>setTimeout(r,o)),this.requestCount=0)}this.lastRequestTime=e,this.requestCount++}async processChat(e,t,o){await this.applyRateLimiting(),await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callOpenRouter(e,this.model,!0);return this.handleStream(r,t)},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}async processVisionChat(e,t,o){if(!W(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);await this.applyRateLimiting();try{await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callOpenRouter(e,this.visionModel,!0);return this.handleStream(r,t)},runWithTools:()=>this.visionChatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processVisionChat received tool_calls. ChatProcessor must use visionChatOnce() loop when tools are enabled."})}catch(r){throw console.error("Error in processVisionChat:",r),r}}async chatOnce(e,t=!0,o=()=>{},r){await this.applyRateLimiting();let s=await this.callOpenRouter(e,this.model,t,r);return t?this.parseStream(s,o):this.parseOneShot(await s.json())}async visionChatOnce(e,t=!1,o=()=>{},r){if(!W(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);await this.applyRateLimiting();let s=await this.callOpenRouter(e,this.visionModel,t,r);return t?this.parseStream(s,o):this.parseOneShot(await s.json())}async callOpenRouter(e,t,o=!1,r){let s=this.buildRequestBody(e,t,o,r),i={Authorization:`Bearer ${this.apiKey}`};return this.appUrl&&(i["HTTP-Referer"]=this.appUrl),this.appName&&(i["X-Title"]=this.appName),await g.post(this.endpoint,s,i)}buildRequestBody(e,t,o,r){let s={model:t,messages:e,stream:o};if((r!==void 0?r:C(this.responseLength))&&console.warn("OpenRouter: Token limits are not supported for gpt-oss-20b model due to known issues. Using unlimited tokens instead."),this.reasoning_effort!==void 0||this.includeReasoning!==void 0||this.reasoningMaxTokens){if(s.reasoning={},this.reasoning_effort&&this.reasoning_effort!=="none"){let a=this.reasoning_effort==="minimal"?"low":this.reasoning_effort;s.reasoning.effort=a}(this.reasoning_effort==="none"||this.includeReasoning!==!0)&&(s.reasoning.exclude=!0),this.reasoningMaxTokens&&(s.reasoning.max_tokens=this.reasoningMaxTokens)}else s.reasoning={exclude:!0};return this.tools.length>0&&(s.tools=b(this.tools,"chat-completions"),s.tool_choice="auto"),s}async handleStream(e,t){return P(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}async parseStream(e,t){return x(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}parseOneShot(e){return I(e)}};var re=class{createChatService(e){let t=O({model:e.model,visionModel:e.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:e.model||this.getDefaultModel(),supportsVisionForModel:i=>this.supportsVisionForModel(i),validate:"explicit"}),o=e.tools,r=e.appName,s=e.appUrl;return new oe(e.apiKey,e.model||this.getDefaultModel(),t,o,e.endpoint,e.responseLength,r,s,e.reasoning_effort,e.includeReasoning,e.reasoningMaxTokens)}getProviderName(){return"openrouter"}getSupportedModels(){return[D,Ye,Fe,Ge,Ue,He,We,Be,Ke,$e,je,ze,mt,qe,Je,Ze,Xe,ut,dt,Ve]}getDefaultModel(){return D}supportsVision(){return this.getSupportedModels().some(e=>this.supportsVisionForModel(e))}supportsVisionForModel(e){return W(e)}getFreeModels(){return _t}isModelFree(e){return k(e)}};var se=class{constructor(e,t=B,o=V,r,s=ue,i,a,l){this.provider="zai";this.apiKey=e,this.model=t,this.tools=r||[],this.endpoint=s,this.responseLength=i,this.responseFormat=a,this.thinking=l??{type:"disabled"},this.visionModel=o}getModel(){return this.model}getVisionModel(){return this.visionModel}async processChat(e,t,o){await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callZAI(e,this.model,!0);return this.handleStream(r,t)},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}async processVisionChat(e,t,o){if(!K(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callZAI(e,this.visionModel,!0);return this.handleStream(r,t)},runWithTools:()=>this.visionChatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processVisionChat received tool_calls. ChatProcessor must use visionChatOnce() loop when tools are enabled."})}async chatOnce(e,t=!0,o=()=>{},r){let s=await this.callZAI(e,this.model,t,r);return this.parseResponse(s,t,o)}async visionChatOnce(e,t=!1,o=()=>{},r){if(!K(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);let s=await this.callZAI(e,this.visionModel,t,r);return this.parseResponse(s,t,o)}async parseResponse(e,t,o){return t?this.parseStream(e,o):this.parseOneShot(await e.json())}async callZAI(e,t,o=!1,r){let s=this.buildRequestBody(e,t,o,r);return await g.post(this.endpoint,s,{Authorization:`Bearer ${this.apiKey}`})}buildRequestBody(e,t,o,r){let s={model:t,stream:o,messages:e},i=r!==void 0?r:C(this.responseLength);i!==void 0&&(s.max_tokens=i),this.responseFormat&&(s.response_format=this.responseFormat),this.thinking&&(s.thinking=this.thinking);let a=this.buildToolsDefinition();return a.length>0&&(s.tools=a,s.tool_choice="auto",o&&Ot(t)&&(s.tool_stream=!0)),s}buildToolsDefinition(){return b(this.tools,"chat-completions")}async handleStream(e,t){return P(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}async parseStream(e,t){return x(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}parseOneShot(e){return I(e)}};var ie=class{createChatService(e){let t=e.model||this.getDefaultModel(),o=O({model:t,visionModel:e.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:this.getDefaultVisionModel(),supportsVisionForModel:i=>this.supportsVisionForModel(i),validate:"explicit"}),r=e.tools,s=e.thinking??{type:"disabled"};return new se(e.apiKey,t,o,r,e.endpoint||ue,e.responseLength,e.responseFormat,s)}getProviderName(){return"zai"}getSupportedModels(){return[ft,B,vt,Mt,Ct,Qe,et,V]}getDefaultModel(){return B}getDefaultVisionModel(){return V}supportsVision(){return!0}supportsVisionForModel(e){return K(e)}};var Ft=[new te,new ee,new X,new J,new re,new ie,new Q];var ne=class{static registerProvider(e){this.providers.set(e.getProviderName(),e)}static createChatService(e,t){let o=this.providers.get(e);if(!o)throw new Error(`Unknown chat provider: ${e}`);return o.createChatService(t)}static getProviders(){return this.providers}static getAvailableProviders(){return Array.from(this.providers.keys())}static getSupportedModels(e){let t=this.providers.get(e);return t?t.getSupportedModels():[]}};ne.providers=new Map;Ft.forEach(n=>ne.registerProvider(n));function Gt(){g.setFetch(async(n,e={})=>{let t=(e.method||"GET").toString().toUpperCase(),o=e.headers,r={};if(Array.isArray(o))for(let[h,u]of o)r[h]=String(u);else if(o&&typeof o=="object")for(let[h,u]of Object.entries(o))r[h]=String(u);let s={method:t,headers:r,muteHttpExceptions:!0},i=e.body;typeof i=="string"?s.payload=i:i!=null&&(r["Content-Type"]||(r["Content-Type"]="application/json"),s.payload=JSON.stringify(i));let a=UrlFetchApp.fetch(n,s),l=a.getResponseCode(),c=a.getContentText();return{ok:l>=200&&l<300,status:l,statusText:String(l),text:async()=>c,json:async()=>c?JSON.parse(c):null}})}return jt(mo);})();
10
+ `;var w=class extends Error{constructor(t,o,r){super(`HTTP ${t}: ${o}`);this.status=t;this.statusText=o;this.body=r;this.name="HttpError"}},fe=class fe{static setFetch(e){this.fetchImpl=e}static async post(e,t,o={},r={}){let{timeout:s=3e4,retries:n=0,retryDelay:a=1e3}=r,c={...{"Content-Type":"application/json"},...o},u=null;for(let h=0;h<=n;h++)try{let m=typeof AbortController<"u",p=m?new AbortController:void 0,_=m?setTimeout(()=>p.abort(),s):void 0,M=await fe.fetchImpl(e,{method:"POST",headers:c,body:typeof t=="string"?t:JSON.stringify(t),...p?{signal:p.signal}:{}});if(_&&clearTimeout(_),!M.ok){let d=await M.text();throw new w(M.status,M.statusText,d)}return M}catch(m){if(u=m,m instanceof w&&m.status>=400&&m.status<500)throw m;if(m instanceof Error&&m.name==="AbortError")throw new Error(`Request timeout after ${s}ms`);h<n&&await new Promise(p=>setTimeout(p,a*(h+1)))}throw u||new Error("Request failed")}static async handleErrorResponse(e){let t=await e.text();throw new w(e.status,e.statusText,t)}static async get(e,t={},o={}){let{timeout:r=3e4,retries:s=0,retryDelay:n=1e3}=o,a=null;for(let l=0;l<=s;l++)try{let c=typeof AbortController<"u",u=c?new AbortController:void 0,h=c?setTimeout(()=>u.abort(),r):void 0,m=await fe.fetchImpl(e,{method:"GET",headers:t,...u?{signal:u.signal}:{}});if(h&&clearTimeout(h),!m.ok){let p=await m.text();throw new w(m.status,m.statusText,p)}return m}catch(c){if(a=c,c instanceof w&&c.status>=400&&c.status<500)throw c;if(c instanceof Error&&c.name==="AbortError")throw new Error(`Request timeout after ${r}ms`);l<s&&await new Promise(u=>setTimeout(u,n*(l+1)))}throw a||new Error("Request failed")}};fe.fetchImpl=(e,t)=>fetch(e,t);var g=fe;var f=class{static append(e,t){if(!t)return;let o=e[e.length-1];o&&o.type==="text"?o.text+=t:e.push({type:"text",text:t})}static getFullText(e){return e.filter(t=>t.type==="text").map(t=>t.text).join("")}static addTextBlock(e,t){t&&e.push({type:"text",text:t})}};var io=["happy","sad","angry","surprised","neutral"],Ft=/\[([a-z]+)\]/i,Rt=/\[[a-z]+\]\s*/gi,Y=class{static extractEmotion(e){let t=e.match(Ft);if(t){let o=t[1].toLowerCase(),r=e.replace(Rt,"").trim();return{emotion:o,cleanText:r}}return{cleanText:e}}static isValidEmotion(e){return io.includes(e)}static cleanEmotionTags(e){return e.replace(Rt,"").trim()}static addEmotionTag(e,t){return`[${e}] ${t}`}};function Ut(i){let{emotion:e,cleanText:t}=Y.extractEmotion(i);return e?{emotion:e,text:t}:{text:t}}function no(i){return i.map(e=>Ut(e))}function ao(i){return i.emotion?Y.addEmotionTag(i.emotion,i.text):i.text}async function lo(i,e){let{blocks:t}=await i.chatOnce(e,!1,()=>{});return f.getFullText(t)}var Ht=(i,e)=>{try{return JSON.parse(i)}catch(t){if(e){e(i,t);return}throw t}},Wt=async(i,e)=>{let t=i.body?.getReader();if(!t)throw new Error("Response body is null.");let o=new TextDecoder,r="",s=!1;for(;!s;){let{done:n,value:a}=await t.read();if(n)break;r+=o.decode(a,{stream:!0});let l=r.split(`
11
+ `);r=l.pop()||"";for(let c of l){let u=c.trim();if(!u||u.startsWith(":")||!u.startsWith("data:"))continue;let h=u.slice(5).trim();if(h==="[DONE]"){s=!0;break}e(h)}}};async function P(i,e,t={}){let o="";return await Wt(i,r=>{let s=Ht(r,t.onJsonError);if(!s)return;let n=s.choices?.[0]?.delta?.content||"";n&&(e(n),o+=n)}),o}async function x(i,e,t={}){let o=[],r=new Map,s=t.appendTextBlock??f.append;await Wt(i,l=>{let c=Ht(l,t.onJsonError);if(!c)return;let u=c.choices?.[0]?.delta;u?.content&&(e(u.content),s(o,u.content)),u?.tool_calls&&u.tool_calls.forEach(h=>{let m=r.get(h.index)??{id:h.id,name:h.function?.name,args:""};m.args+=h.function?.arguments||"",r.set(h.index,m)})});let n=Array.from(r.entries()).sort((l,c)=>l[0]-c[0]).map(([l,c])=>({type:"tool_use",id:c.id,name:c.name,input:JSON.parse(c.args||"{}")}));return{blocks:[...o,...n],stop_reason:n.length?"tool_use":"end"}}function I(i){let e=i?.choices?.[0],t=[];return e?.message?.tool_calls?.length?e.message.tool_calls.forEach(o=>t.push({type:"tool_use",id:o.id,name:o.function?.name,input:JSON.parse(o.function?.arguments||"{}")})):e?.message?.content&&t.push({type:"text",text:e.message.content}),{blocks:t,stop_reason:e?.finish_reason==="tool_calls"||t.some(o=>o.type==="tool_use")?"tool_use":"end"}}var b=(i,e="chat-completions")=>i.length===0?[]:e==="responses"?i.map(t=>({type:"function",name:t.name,description:t.description,parameters:t.parameters})):i.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.parameters}}));async function v(i){if(!i.hasTools){let t=await i.runWithoutTools();await i.onCompleteResponse(t);return}let e=await i.runWithTools();if(i.onToolBlocks&&i.onToolBlocks(e.blocks),e.stop_reason==="end"){let t=f.getFullText(e.blocks);await i.onCompleteResponse(t);return}throw new Error(i.toolErrorMessage)}var E=i=>{let e=i.model??i.defaultModel,t=i.visionModel??(i.supportsVisionForModel(e)?e:i.defaultVisionModel);if(i.validate==="explicit"&&i.visionModel&&!i.supportsVisionForModel(i.visionModel))throw new Error(`Model ${i.visionModel} does not support vision capabilities.`);if(i.validate==="resolved"&&!i.supportsVisionForModel(t))throw new Error(`Model ${t} does not support vision capabilities.`);return t};var po="https://openrouter.ai/api/v1/models",co=2,ho=12e3,uo=1,mo=10;function Dt(i){return i instanceof Error?i.message:String(i)}function it(i,e){return typeof i!="number"||!Number.isFinite(i)?e:Math.max(1,Math.floor(i))}function _o(i){let e=new Set,t=[];for(let o of i){let r=o.trim();!r||e.has(r)||(e.add(r),t.push(r))}return t}async function Bt(i,e,t){if(!(typeof AbortController<"u"))return fetch(i,e);let r=new AbortController,s=setTimeout(()=>r.abort(),t);try{return await fetch(i,{...e,signal:r.signal})}catch(n){throw n instanceof Error&&n.name==="AbortError"?new Error(`Timeout after ${t}ms`):n}finally{clearTimeout(s)}}async function Kt(i){let e=`HTTP ${i.status} ${i.statusText}`.trim(),t="";try{t=await i.text()}catch{return e}let o=t.replace(/\s+/g," ").trim().slice(0,200);return o?`${e}: ${o}`:e}function go(i){if(!i||typeof i!="object")throw new Error("Invalid models response shape");let e=i,t=Array.isArray(e.data)?e.data:Array.isArray(e.models)?e.models:[];if(t.length===0)return[];let o=t.map(r=>r.id).filter(r=>typeof r=="string");return _o(o)}async function fo({modelId:i,apiKey:e,endpoint:t,timeoutMs:o,appName:r,appUrl:s}){let n={Authorization:`Bearer ${e}`,"Content-Type":"application/json"};r&&(n["X-Title"]=r),s&&(n["HTTP-Referer"]=s);try{let a=await Bt(t,{method:"POST",headers:n,body:JSON.stringify({model:i,messages:[{role:"user",content:"Reply only with OK."}],stream:!1})},o);if(!a.ok)return{id:i,ok:!1,reason:await Kt(a)};try{await a.json()}catch(l){return{id:i,ok:!1,reason:`JSON parse failed: ${Dt(l)}`}}return{id:i,ok:!0}}catch(a){return{id:i,ok:!1,reason:Dt(a)}}}async function vo(i,e,t){if(i.length===0)return[];let o=new Array(i.length),r=0,s=Math.min(e,i.length);return await Promise.all(Array.from({length:s},async()=>{for(;r<i.length;){let n=r;r+=1,o[n]=await t(i[n])}})),o}async function Mo(i){let e=i.apiKey.trim();if(!e)throw new Error("OpenRouter API key is required.");let t=i.modelsEndpoint||po,o=i.endpoint||_e,r=it(i.timeoutMs,ho),s=it(i.concurrency,co),n=it(i.maxCandidates,uo),a=it(i.maxWorking,mo),l=await Bt(t,{method:"GET"},r);if(!l.ok)throw new Error(await Kt(l));let c;try{c=await l.json()}catch(_){throw new Error(`JSON parse failed: ${Dt(_)}`)}let u=go(c).filter(_=>U(_)).slice(0,n),h=await vo(u,s,_=>fo({modelId:_,apiKey:e,endpoint:o,timeoutMs:r,appName:i.appName,appUrl:i.appUrl})),m=h.filter(_=>_.ok).map(_=>_.id).slice(0,a),p=h.filter(_=>!_.ok).map(_=>({id:_.id,reason:_.reason||"Unknown error"}));return{working:m,failed:p,fetchedAt:Date.now()}}var Q=class{constructor(e,t=T,o=T,r=[],s=[],n){this.provider="claude";if(this.apiKey=e,this.model=t||T,this.visionModel=o||T,this.tools=r,this.mcpServers=s,this.responseLength=n,!de.includes(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`)}getModel(){return this.model}getVisionModel(){return this.visionModel}getMCPServers(){return this.mcpServers}addMCPServer(e){this.mcpServers.push(e)}removeMCPServer(e){this.mcpServers=this.mcpServers.filter(t=>t.name!==e)}hasMCPServers(){return this.mcpServers.length>0}async processChat(e,t,o){await v({hasTools:this.tools.length>0||this.mcpServers.length>0,runWithoutTools:async()=>{let r=await this.callClaude(e,this.model,!0);return this.parsePureStream(r,t)},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}async processVisionChat(e,t,o){await v({hasTools:this.tools.length>0||this.mcpServers.length>0,runWithoutTools:async()=>{let r=await this.callClaude(e,this.visionModel,!0);return this.parsePureStream(r,t)},runWithTools:()=>this.visionChatOnce(e),onCompleteResponse:o,toolErrorMessage:"processVisionChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}convertMessagesToClaudeFormat(e){return e.map(t=>({role:this.mapRoleToClaude(t.role),content:t.content}))}convertVisionMessagesToClaudeFormat(e){return e.map(t=>{if(typeof t.content=="string")return{role:this.mapRoleToClaude(t.role),content:[{type:"text",text:t.content}]};if(Array.isArray(t.content)){let o=t.content.map(r=>{if(r.type==="image_url"){if(r.image_url.url.startsWith("data:")){let s=r.image_url.url.match(/^data:([^;]+);base64,(.+)$/);return s?{type:"image",source:{type:"base64",media_type:s[1],data:s[2]}}:null}return{type:"image",source:{type:"url",url:r.image_url.url,media_type:this.getMimeTypeFromUrl(r.image_url.url)}}}return r}).filter(r=>r);return{role:this.mapRoleToClaude(t.role),content:o}}return{role:this.mapRoleToClaude(t.role),content:[]}})}mapRoleToClaude(e){switch(e){case"system":return"system";case"user":return"user";case"assistant":return"assistant";default:return"user"}}getMimeTypeFromUrl(e){switch(e.split(".").pop()?.toLowerCase()){case"jpg":case"jpeg":return"image/jpeg";case"png":return"image/png";case"gif":return"image/gif";case"webp":return"image/webp";default:return"image/jpeg"}}async callClaude(e,t,o,r){let s=e.find(h=>h.role==="system")?.content??"",n=e.filter(h=>h.role!=="system"),a=n.some(h=>Array.isArray(h.content)&&h.content.some(m=>m.type==="image_url"||m.type==="image")),l={model:t,system:s,messages:a?this.convertVisionMessagesToClaudeFormat(n):this.convertMessagesToClaudeFormat(n),stream:o,max_tokens:r!==void 0?r:O(this.responseLength)};this.tools.length&&(l.tools=this.tools.map(h=>({name:h.name,description:h.description,input_schema:h.parameters})),l.tool_choice={type:"auto"}),this.mcpServers.length>0&&(l.mcp_servers=this.mcpServers);let c={"Content-Type":"application/json","x-api-key":this.apiKey,"anthropic-version":"2023-06-01","anthropic-dangerous-direct-browser-access":"true"};return this.mcpServers.length>0&&(c["anthropic-beta"]="mcp-client-2025-04-04"),await g.post(vt,l,c)}async parseStream(e,t){let o=e.body.getReader(),r=new TextDecoder,s=[],n=new Map,a="";for(;;){let{done:l,value:c}=await o.read();if(l)break;a+=r.decode(c,{stream:!0});let u;for(;(u=a.indexOf(`
12
+ `))!==-1;){let h=a.slice(0,u).trim();if(a=a.slice(u+1),!h.startsWith("data:"))continue;let m=h.slice(5).trim();if(m==="[DONE]")break;let p=JSON.parse(m);if(p.type==="content_block_delta"&&p.delta?.text&&(t(p.delta.text),s.push({type:"text",text:p.delta.text})),p.type==="content_block_start"&&p.content_block?.type==="tool_use"?n.set(p.index,{id:p.content_block.id,name:p.content_block.name,args:""}):p.type==="content_block_start"&&p.content_block?.type==="mcp_tool_use"?n.set(p.index,{id:p.content_block.id,name:p.content_block.name,args:"",server_name:p.content_block.server_name}):p.type==="content_block_start"&&p.content_block?.type==="tool_result"?s.push({type:"tool_result",tool_use_id:p.content_block.tool_use_id,content:p.content_block.content??""}):p.type==="content_block_start"&&p.content_block?.type==="mcp_tool_result"&&s.push({type:"mcp_tool_result",tool_use_id:p.content_block.tool_use_id,is_error:p.content_block.is_error??!1,content:p.content_block.content??[]}),p.type==="content_block_delta"&&p.delta?.type==="input_json_delta"){let _=n.get(p.index);_&&(_.args+=p.delta.partial_json||"")}if(p.type==="content_block_stop"&&n.has(p.index)){let{id:_,name:M,args:d,server_name:C}=n.get(p.index);C?s.push({type:"mcp_tool_use",id:_,name:M,server_name:C,input:JSON.parse(d||"{}")}):s.push({type:"tool_use",id:_,name:M,input:JSON.parse(d||"{}")}),n.delete(p.index)}}}return{blocks:s,stop_reason:s.some(l=>l.type==="tool_use"||l.type==="mcp_tool_use")?"tool_use":"end"}}async parsePureStream(e,t){let{blocks:o}=await this.parseStream(e,t);return o.filter(r=>r.type==="text").map(r=>r.text).join("")}parseOneShot(e){let t=[];return(e.content??[]).forEach(o=>{o.type==="text"?t.push({type:"text",text:o.text}):o.type==="tool_use"?t.push({type:"tool_use",id:o.id,name:o.name,input:o.input??{}}):o.type==="mcp_tool_use"?t.push({type:"mcp_tool_use",id:o.id,name:o.name,server_name:o.server_name,input:o.input??{}}):o.type==="tool_result"?t.push({type:"tool_result",tool_use_id:o.tool_use_id,content:o.content??""}):o.type==="mcp_tool_result"&&t.push({type:"mcp_tool_result",tool_use_id:o.tool_use_id,is_error:o.is_error??!1,content:o.content??[]})}),{blocks:t,stop_reason:t.some(o=>o.type==="tool_use"||o.type==="mcp_tool_use")?"tool_use":"end"}}async chatOnce(e,t=!0,o=()=>{},r){let s=await this.callClaude(e,this.model,t,r),n=t?await this.parseStream(s,o):this.parseOneShot(await s.json());return this.convertToStandardCompletion(n)}async visionChatOnce(e,t=!1,o=()=>{},r){let s=await this.callClaude(e,this.visionModel,t,r),n=t?await this.parseStream(s,o):this.parseOneShot(await s.json());return this.convertToStandardCompletion(n)}convertToStandardCompletion(e){return{blocks:e.blocks.filter(o=>o.type==="text"||o.type==="tool_use"||o.type==="tool_result"),stop_reason:e.stop_reason}}};var ee=class{createChatService(e){let t=E({model:e.model,visionModel:e.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:this.getDefaultModel(),supportsVisionForModel:o=>this.supportsVisionForModel(o),validate:"resolved"});return new Q(e.apiKey,e.model||this.getDefaultModel(),t,e.tools??[],e.mcpServers??[],e.responseLength)}getProviderName(){return"claude"}getSupportedModels(){return[T,Re,De,Ae,we,Ne,ke,Ve,Ge,Fe,Ue]}getDefaultModel(){return T}supportsVision(){return!0}supportsVisionForModel(e){return de.includes(e)}};var nt=class{static async fetchToolSchemas(e){try{let t={"Content-Type":"application/json"};e.authorization_token&&(t.Authorization=`Bearer ${e.authorization_token}`);let r=await(await g.post(`${e.url}/tools`,{},t)).json();return Array.isArray(r.tools)?r.tools.map(s=>({name:`mcp_${e.name}_${s.name}`,description:s.description||`Tool from ${e.name} MCP server`,parameters:s.inputSchema||{type:"object",properties:{},required:[]}})):[{name:`mcp_${e.name}_search`,description:`Search using ${e.name} MCP server`,parameters:{type:"object",properties:{query:{type:"string",description:"Search query"}},required:["query"]}}]}catch(t){return console.warn(`Failed to fetch MCP schemas from ${e.name}:`,t),[{name:`mcp_${e.name}_search`,description:`Search using ${e.name} MCP server (schema fetch failed)`,parameters:{type:"object",properties:{query:{type:"string",description:"Search query"}},required:["query"]}}]}}static async fetchAllToolSchemas(e){let t=[];for(let o of e)try{let r=await this.fetchToolSchemas(o);t.push(...r)}catch(r){console.error(`Failed to fetch schemas from ${o.name}:`,r)}return t}};var te=class{constructor(e,t=D,o=D,r=[],s=[],n){this.provider="gemini";this.mcpToolSchemas=[];this.mcpSchemasInitialized=!1;this.callIdMap=new Map;if(this.apiKey=e,this.model=t,this.responseLength=n,!me.includes(o))throw new Error(`Model ${o} does not support vision capabilities.`);this.visionModel=o,this.tools=r,this.mcpServers=s}safeJsonParse(e){try{return JSON.parse(e)}catch{return e}}normalizeToolResult(e){return e===null?{content:null}:typeof e=="object"?e:{content:e}}adaptKeysForApi(e){let t={toolConfig:"tool_config",functionCallingConfig:"function_calling_config",functionDeclarations:"function_declarations",functionCall:"function_call",functionResponse:"function_response"};return Array.isArray(e)?e.map(o=>this.adaptKeysForApi(o)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([o,r])=>[t[o]??o,this.adaptKeysForApi(r)])):e}getModel(){return this.model}getVisionModel(){return this.visionModel}getMCPServers(){return this.mcpServers}addMCPServer(e){this.mcpServers.push(e),this.mcpSchemasInitialized=!1}removeMCPServer(e){this.mcpServers=this.mcpServers.filter(t=>t.name!==e),this.mcpSchemasInitialized=!1}hasMCPServers(){return this.mcpServers.length>0}async initializeMCPSchemas(){if(!(this.mcpSchemasInitialized||this.mcpServers.length===0))try{let e=new Promise((o,r)=>setTimeout(()=>r(new Error("MCP schema fetch timeout")),5e3)),t=nt.fetchAllToolSchemas(this.mcpServers);this.mcpToolSchemas=await Promise.race([t,e]),this.mcpSchemasInitialized=!0}catch(e){console.warn("Failed to initialize MCP schemas, using fallback:",e),this.mcpToolSchemas=this.mcpServers.map(t=>({name:`mcp_${t.name}_search`,description:`Search using ${t.name} MCP server (fallback)`,parameters:{type:"object",properties:{query:{type:"string",description:"Search query"}},required:["query"]}})),this.mcpSchemasInitialized=!0}}async processChat(e,t,o){try{await v({hasTools:this.tools.length>0||this.mcpServers.length>0,runWithoutTools:async()=>{let r=await this.callGemini(e,this.model,!0),{blocks:s}=await this.parseStream(r,t);return f.getFullText(s)},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"Received functionCall. Use chatOnce() loop when tools are enabled."})}catch(r){throw console.error("Error in processChat:",r),r}}async processVisionChat(e,t,o){try{await v({hasTools:this.tools.length>0||this.mcpServers.length>0,runWithoutTools:async()=>{let r=await this.callGemini(e,this.visionModel,!0),{blocks:s}=await this.parseStream(r,t);return f.getFullText(s)},runWithTools:()=>this.visionChatOnce(e),onToolBlocks:r=>{r.filter(s=>s.type==="text").forEach(s=>t(s.text))},onCompleteResponse:o,toolErrorMessage:"Received functionCall. Use visionChatOnce() loop when tools are enabled."})}catch(r){throw console.error("Error in processVisionChat:",r),r}}convertMessagesToGeminiFormat(e){let t=[],o=null,r=[],s=()=>{o&&r.length&&(t.push({role:o,parts:[...r]}),r=[])};for(let n of e){let a=this.mapRoleToGemini(n.role);if(n.tool_calls){s();for(let l of n.tool_calls)this.callIdMap.set(l.id,l.function.name),t.push({role:"model",parts:[{functionCall:{name:l.function.name,args:JSON.parse(l.function.arguments||"{}")}}]});continue}if(n.role==="tool"){s();let l=n.name??this.callIdMap.get(n.tool_call_id)??"result";t.push({role:"user",parts:[{functionResponse:{name:l,response:this.normalizeToolResult(this.safeJsonParse(n.content))}}]});continue}a!==o&&s(),o=a,r.push({text:n.content})}return s(),t}async callGemini(e,t,o=!1,r){let a={contents:e.some(d=>Array.isArray(d.content)&&d.content.some(C=>C?.type==="image_url"||C?.inlineData))?await this.convertVisionMessagesToGeminiFormat(e):this.convertMessagesToGeminiFormat(e),generationConfig:{maxOutputTokens:r!==void 0?r:O(this.responseLength)}},l=[];if(this.tools.length>0&&l.push(...this.tools.map(d=>({name:d.name,description:d.description,parameters:d.parameters}))),this.mcpServers.length>0)try{await this.initializeMCPSchemas(),l.push(...this.mcpToolSchemas.map(d=>({name:d.name,description:d.description,parameters:d.parameters})))}catch(d){console.warn("MCP initialization failed, skipping MCP tools:",d)}l.length>0&&(a.tools=[{functionDeclarations:l}],a.toolConfig={functionCallingConfig:{mode:"AUTO"}});let c=async(d,C)=>{let at=o?"streamGenerateContent":"generateContent",At=o?"?alt=sse":"",zt=`${ft}/${d}/models/${t}:${at}${At}${At?"&":"?"}key=${this.apiKey}`;return g.post(zt,C)},u=/flash[-_]lite/.test(t),h=/gemini-2\.5/.test(t),m=/^gemini-3(?:\.[0-9]+)?-.*preview/.test(t),p=u||h||m,_=p?"v1beta":"v1",M=async()=>{try{let d=_==="v1"?a:this.adaptKeysForApi(a);return await c(_,d)}catch(d){let C=/Unknown name|Cannot find field|404/.test(d?.message||"")||d?.status===404;if(!p&&C)return await c("v1beta",this.adaptKeysForApi(a));throw d}};try{return await M()}catch(d){throw d.body&&(console.error("Gemini API Error Details:",d.body),console.error("Request Body:",JSON.stringify(a,null,2))),d}}async convertVisionMessagesToGeminiFormat(e){let t=[],o=null,r=[];for(let s of e){let n=this.mapRoleToGemini(s.role);if(s.tool_calls){for(let a of s.tool_calls)t.push({role:"model",parts:[{functionCall:{name:a.function.name,args:JSON.parse(a.function.arguments||"{}")}}]});continue}if(s.role==="tool"){let a=s.name??this.callIdMap.get(s.tool_call_id)??"result";t.push({role:"user",parts:[{functionResponse:{name:a,response:this.normalizeToolResult(this.safeJsonParse(s.content))}}]});continue}if(n!==o&&r.length>0&&(t.push({role:o,parts:[...r]}),r=[]),o=n,typeof s.content=="string")r.push({text:s.content});else if(Array.isArray(s.content)){for(let a of s.content)if(a.type==="text")r.push({text:a.text});else if(a.type==="image_url")try{let c=await(await g.get(a.image_url.url)).blob(),u=await this.blobToBase64(c);r.push({inlineData:{mimeType:c.type||"image/jpeg",data:u.split(",")[1]}})}catch(l){throw console.error("Error processing image:",l),new Error(`Failed to process image: ${l.message}`)}}}return o&&r.length>0&&t.push({role:o,parts:[...r]}),t}blobToBase64(e){return new Promise((t,o)=>{let r=new FileReader;r.onloadend=()=>t(r.result),r.onerror=o,r.readAsDataURL(e)})}mapRoleToGemini(e){switch(e){case"system":return"model";case"user":return"user";case"assistant":return"model";default:return"user"}}async parseStream(e,t){let o=e.body.getReader(),r=new TextDecoder,s=[],n=[],a="",l=u=>{if(!u||u==="[DONE]")return;let h;try{h=JSON.parse(u)}catch{return}for(let m of h.candidates??[])for(let p of m.content?.parts??[])p.text&&(t(p.text),f.addTextBlock(s,p.text)),p.functionCall&&n.push({type:"tool_use",id:this.genUUID(),name:p.functionCall.name,input:p.functionCall.args??{}}),p.functionResponse&&n.push({type:"tool_result",tool_use_id:p.functionResponse.name,content:JSON.stringify(p.functionResponse.response)})};for(;;){let{done:u,value:h}=await o.read();if(u)break;a+=r.decode(h,{stream:!0});let m;for(;(m=a.indexOf(`
13
+ `))!==-1;){let p=a.slice(0,m);if(a=a.slice(m+1),p.endsWith("\r")&&(p=p.slice(0,-1)),!p.trim()){l("");continue}p.startsWith("data:")&&(p=p.slice(5).trim()),p&&l(p)}}return a&&l(a),{blocks:[...s,...n],stop_reason:n.some(u=>u.type==="tool_use")?"tool_use":"end"}}parseOneShot(e){let t=[],o=[];for(let s of e.candidates??[])for(let n of s.content?.parts??[])n.text&&t.push({type:"text",text:n.text}),n.functionCall&&o.push({type:"tool_use",id:this.genUUID(),name:n.functionCall.name,input:n.functionCall.args??{}}),n.functionResponse&&o.push({type:"tool_result",tool_use_id:n.functionResponse.name,content:JSON.stringify(n.functionResponse.response)});return{blocks:[...t,...o],stop_reason:o.some(s=>s.type==="tool_use")?"tool_use":"end"}}async chatOnce(e,t=!0,o=()=>{},r){let s=await this.callGemini(e,this.model,t,r);return t?this.parseStream(s,o):this.parseOneShot(await s.json())}async visionChatOnce(e,t=!1,o=()=>{},r){let s=await this.callGemini(e,this.visionModel,t,r);return t?this.parseStream(s,o):this.parseOneShot(await s.json())}genUUID(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}};var oe=class{createChatService(e){let t=E({model:e.model,visionModel:e.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:this.getDefaultModel(),supportsVisionForModel:o=>this.supportsVisionForModel(o),validate:"resolved"});return new te(e.apiKey,e.model||this.getDefaultModel(),t,e.tools||[],e.mcpServers||[],e.responseLength)}getProviderName(){return"gemini"}getSupportedModels(){return[Ce,ye,Te,Se,Pe,xe,Ie,be,Le,D]}getDefaultModel(){return D}supportsVision(){return!0}supportsVisionForModel(e){return me.includes(e)}};var re=class{constructor(e,t=S,o=S,r,s=Z,n,a,l){this.provider="kimi";this.apiKey=e,this.model=t,this.tools=r||[],this.endpoint=s,this.responseLength=n,this.responseFormat=a,this.thinking=l??{type:"enabled"},this.visionModel=o}getModel(){return this.model}getVisionModel(){return this.visionModel}async processChat(e,t,o){await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callKimi(e,this.model,!0);return this.handleStream(r,t)},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}async processVisionChat(e,t,o){if(!X(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callKimi(e,this.visionModel,!0);return this.handleStream(r,t)},runWithTools:()=>this.visionChatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processVisionChat received tool_calls. ChatProcessor must use visionChatOnce() loop when tools are enabled."})}async chatOnce(e,t=!0,o=()=>{},r){let s=await this.callKimi(e,this.model,t,r);return this.parseResponse(s,t,o)}async visionChatOnce(e,t=!1,o=()=>{},r){if(!X(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);let s=await this.callKimi(e,this.visionModel,t,r);return this.parseResponse(s,t,o)}async parseResponse(e,t,o){return t?this.parseStream(e,o):this.parseOneShot(await e.json())}async callKimi(e,t,o=!1,r){let s=this.buildRequestBody(e,t,o,r);return await g.post(this.endpoint,s,{Authorization:`Bearer ${this.apiKey}`})}buildRequestBody(e,t,o,r){let s={model:t,stream:o,messages:e},n=r!==void 0?r:O(this.responseLength);n!==void 0&&(s.max_tokens=n),this.responseFormat&&(s.response_format=this.responseFormat);let a=this.tools.length>0?{type:"disabled"}:this.thinking;a&&(this.isSelfHostedEndpoint()?a.type==="disabled"&&(s.chat_template_kwargs={thinking:!1}):s.thinking=a);let l=this.buildToolsDefinition();return l.length>0&&(s.tools=l,s.tool_choice="auto"),s}isSelfHostedEndpoint(){return this.normalizeEndpoint(this.endpoint)!==this.normalizeEndpoint(Z)}normalizeEndpoint(e){return e.replace(/\/+$/,"")}buildToolsDefinition(){return b(this.tools,"chat-completions")}async handleStream(e,t){return P(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}async parseStream(e,t){return x(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}parseOneShot(e){return I(e)}};var se=class{createChatService(e){let t=this.resolveEndpoint(e),o=e.model||this.getDefaultModel(),r=E({model:o,visionModel:e.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:this.getDefaultVisionModel(),supportsVisionForModel:l=>this.supportsVisionForModel(l),validate:"explicit"}),s=e.tools,n=e.thinking??{type:"enabled"},a=s&&s.length>0?{type:"disabled"}:n;return new re(e.apiKey,o,r,s,t,e.responseLength,e.responseFormat,a)}getProviderName(){return"kimi"}getSupportedModels(){return[S]}getDefaultModel(){return S}getDefaultVisionModel(){return S}supportsVision(){return!0}supportsVisionForModel(e){return X(e)}resolveEndpoint(e){if(e.endpoint)return this.normalizeEndpoint(e.endpoint);if(e.baseUrl){let t=this.normalizeEndpoint(e.baseUrl);return t.endsWith("/chat/completions")?t:`${t}/chat/completions`}return Z}normalizeEndpoint(e){return e.replace(/\/+$/,"")}};var N=class{constructor(e,t=G,o=G,r,s=B,n=[],a,l,c,u=!1,h="openai",m=!0){if(this.provider=h,this.apiKey=e,this.model=t,this.tools=r||[],this.endpoint=s,this.mcpServers=n,this.responseLength=a,this.verbosity=l,this.reasoning_effort=c,this.enableReasoningSummary=u,m&&!ue.includes(o))throw new Error(`Model ${o} does not support vision capabilities.`);this.visionModel=o}getModel(){return this.model}getVisionModel(){return this.visionModel}async processChat(e,t,o){await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callOpenAI(e,this.model,!0),s=this.endpoint===y;try{if(s){let n=await this.parseResponsesStream(r,t);return f.getFullText(n.blocks)}return this.handleStream(r,t)}catch(n){throw console.error("[processChat] Error in streaming/completion:",n),n}},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}async processVisionChat(e,t,o){try{await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callOpenAI(e,this.visionModel,!0),s=this.endpoint===y;try{if(s){let n=await this.parseResponsesStream(r,t);return f.getFullText(n.blocks)}return this.handleStream(r,t)}catch(n){throw console.error("[processVisionChat] Error in streaming/completion:",n),n}},runWithTools:()=>this.visionChatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processVisionChat received tool_calls. ChatProcessor must use visionChatOnce() loop when tools are enabled."})}catch(r){throw console.error("Error in processVisionChat:",r),r}}async chatOnce(e,t=!0,o=()=>{},r){let s=await this.callOpenAI(e,this.model,t,r);return this.parseResponse(s,t,o)}async visionChatOnce(e,t=!1,o=()=>{},r){let s=await this.callOpenAI(e,this.visionModel,t,r);return this.parseResponse(s,t,o)}async parseResponse(e,t,o){return this.endpoint===y?t?this.parseResponsesStream(e,o):this.parseResponsesOneShot(await e.json()):t?this.parseStream(e,o):this.parseOneShot(await e.json())}async callOpenAI(e,t,o=!1,r){let s=this.buildRequestBody(e,t,o,r),n={};return(this.provider!=="openai-compatible"||this.apiKey.trim()!=="")&&(n.Authorization=`Bearer ${this.apiKey}`),await g.post(this.endpoint,s,n)}buildRequestBody(e,t,o,r){let s=this.endpoint===y;this.validateMCPCompatibility();let n={model:t,stream:o},a=r!==void 0?r:this.provider==="openai-compatible"?this.responseLength!==void 0?O(this.responseLength):void 0:O(this.responseLength);s?a!==void 0&&(n.max_output_tokens=a):a!==void 0&&(this.provider==="openai-compatible"?n.max_tokens=a:n.max_completion_tokens=a),s?n.input=this.cleanMessagesForResponsesAPI(e):n.messages=e,j(t)&&(s?(this.reasoning_effort&&(n.reasoning={...n.reasoning,effort:this.reasoning_effort},this.enableReasoningSummary&&(n.reasoning.summary="auto")),this.verbosity&&(n.text={...n.text,format:{type:"text"},verbosity:this.verbosity})):(this.reasoning_effort&&(n.reasoning_effort=this.reasoning_effort),this.verbosity&&(n.verbosity=this.verbosity)));let l=this.buildToolsDefinition();return l.length>0&&(n.tools=l,s||(n.tool_choice="auto")),n}validateMCPCompatibility(){if(this.mcpServers.length>0&&this.endpoint===B)throw new Error(`MCP servers are not supported with Chat Completions API. Current endpoint: ${this.endpoint}. Please use OpenAI Responses API endpoint: ${y}. MCP tools are only available in the Responses API endpoint.`)}cleanMessagesForResponsesAPI(e){return e.map(t=>{let r={role:t.role==="tool"?"user":t.role};return typeof t.content=="string"?r.content=t.content:Array.isArray(t.content)?r.content=t.content.map(s=>s.type==="text"?{type:"input_text",text:s.text}:s.type==="image_url"?{type:"input_image",image_url:s.image_url.url}:s):r.content=t.content,r})}buildToolsDefinition(){let e=this.endpoint===y,t=[];return this.tools.length>0&&t.push(...b(this.tools,e?"responses":"chat-completions")),this.mcpServers.length>0&&e&&t.push(...this.buildMCPToolsDefinition()),t}buildMCPToolsDefinition(){return this.mcpServers.map(e=>{let t={type:"mcp",server_label:e.name,server_url:e.url};return e.require_approval&&(t.require_approval=e.require_approval),e.tool_configuration?.allowed_tools&&(t.allowed_tools=e.tool_configuration.allowed_tools),e.authorization_token&&(t.headers={Authorization:`Bearer ${e.authorization_token}`}),t})}async handleStream(e,t){return P(e,t)}async parseStream(e,t){return x(e,t,{appendTextBlock:f.addTextBlock})}parseOneShot(e){return I(e)}async parseResponsesStream(e,t){let o=e.body.getReader(),r=new TextDecoder,s=[],n=new Map,a="";for(;;){let{done:u,value:h}=await o.read();if(u)break;a+=r.decode(h,{stream:!0});let m="",p="",_=a.split(`
14
+ `);a=_.pop()||"";for(let M=0;M<_.length;M++){let d=_[M].trim();if(d.startsWith("event:"))m=d.slice(6).trim();else if(d.startsWith("data:"))p=d.slice(5).trim();else if(d===""&&m&&p){try{let C=JSON.parse(p),at=this.handleResponsesSSEEvent(m,C,t,s,n)}catch{console.warn("Failed to parse SSE data:",p)}m="",p=""}}}let l=Array.from(n.values()).map(u=>({type:"tool_use",id:u.id,name:u.name,input:u.input||{}}));return{blocks:[...s,...l],stop_reason:l.length?"tool_use":"end"}}handleResponsesSSEEvent(e,t,o,r,s){switch(e){case"response.output_item.added":t.item?.type==="message"&&Array.isArray(t.item.content)?t.item.content.forEach(n=>{n.type==="output_text"&&n.text&&(o(n.text),f.append(r,n.text))}):t.item?.type==="function_call"&&s.set(t.item.id,{id:t.item.id,name:t.item.name,input:t.item.arguments?JSON.parse(t.item.arguments):{}});break;case"response.content_part.added":t.part?.type==="output_text"&&typeof t.part.text=="string"&&(o(t.part.text),f.append(r,t.part.text));break;case"response.output_text.delta":case"response.content_part.delta":{let n=typeof t.delta=="string"?t.delta:t.delta?.text??"";n&&(o(n),f.append(r,n))}break;case"response.output_text.done":case"response.content_part.done":break;case"response.completed":return"completed";case"response.reasoning.started":case"response.reasoning.delta":case"response.reasoning.done":break;default:break}}parseResponsesOneShot(e){let t=[];return e.output&&Array.isArray(e.output)&&e.output.forEach(o=>{o.type==="message"&&o.content&&o.content.forEach(r=>{r.type==="output_text"&&r.text&&t.push({type:"text",text:r.text})}),o.type==="function_call"&&t.push({type:"tool_use",id:o.id,name:o.name,input:o.arguments?JSON.parse(o.arguments):{}})}),{blocks:t,stop_reason:t.some(o=>o.type==="tool_use")?"tool_use":"end"}}};var ie=class{createChatService(e){return this.validateRequiredOptions(e),new N(e.apiKey?.trim()??"",e.model,e.visionModel??e.model,e.tools,e.endpoint,[],e.responseLength,e.verbosity,e.reasoning_effort,e.enableReasoningSummary,this.getProviderName(),!1)}getProviderName(){return"openai-compatible"}getSupportedModels(){return[]}supportsVision(){return!1}getDefaultModel(){return"local-model"}validateRequiredOptions(e){if(e.mcpServers!==void 0)throw new Error("openai-compatible provider does not support mcpServers.");let t=e.endpoint?.trim();if(!t)throw new Error("openai-compatible provider requires endpoint (full URL).");let o;try{o=new URL(t)}catch{throw new Error("openai-compatible provider requires endpoint to be a full URL.")}if(o.protocol!=="http:"&&o.protocol!=="https:")throw new Error("openai-compatible provider requires endpoint to be a full URL.");if(!e.model?.trim())throw new Error("openai-compatible provider requires model.")}};var ne=class{createChatService(e){let t=this.optimizeGPT5Options(e),o=E({model:t.model,visionModel:t.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:this.getDefaultModel(),supportsVisionForModel:c=>this.supportsVisionForModel(c),validate:"resolved"}),r=t.tools,s=t.mcpServers??[],n=t.model||this.getDefaultModel(),a=!1;s.length>0||ut(n)?a=!0:j(n)&&(a=(t.gpt5EndpointPreference||"chat")==="responses");let l=t.endpoint||(a?y:B);return new N(t.apiKey,n,o,r,l,s,t.responseLength,t.verbosity,t.reasoning_effort,t.enableReasoningSummary,this.getProviderName())}getProviderName(){return"openai"}getSupportedModels(){return[k,K,$,V,L,R,ve,Me,Oe,G,Ee,pt,ct,"o1"]}getDefaultModel(){return k}supportsVision(){return!0}supportsVisionForModel(e){return ue.includes(e)}optimizeGPT5Options(e){let t=e.model||this.getDefaultModel();if(!j(t))return e;let o={...e};if(e.gpt5Preset){let r=Lt[e.gpt5Preset];o.reasoning_effort=r.reasoning_effort,o.verbosity=r.verbosity}else e.reasoning_effort||(o.reasoning_effort=F(t));return o.reasoning_effort=this.normalizeReasoningEffort(t,o.reasoning_effort),o}normalizeReasoningEffort(e,t){if(t)return t==="none"&&!dt(e)?F(e):t==="minimal"&&!_t(e)?F(e):t==="low"&&!gt(e)?F(e):t==="xhigh"&&!mt(e)?F(e):t}};var ae=class{constructor(e,t=A,o=A,r,s=_e,n,a,l,c,u,h){this.provider="openrouter";this.lastRequestTime=0;this.requestCount=0;this.apiKey=e,this.model=t,this.tools=r||[],this.endpoint=s,this.responseLength=n,this.appName=a,this.appUrl=l,this.reasoning_effort=c,this.includeReasoning=u,this.reasoningMaxTokens=h,this.visionModel=o}getModel(){return this.model}getVisionModel(){return this.visionModel}async applyRateLimiting(){if(!U(this.model))return;let e=Date.now(),t=e-this.lastRequestTime;if(t>6e4&&(this.requestCount=0),this.requestCount>=yt){let o=6e4-t;o>0&&(console.log(`Rate limit reached for free tier. Waiting ${o}ms...`),await new Promise(r=>setTimeout(r,o)),this.requestCount=0)}this.lastRequestTime=e,this.requestCount++}async processChat(e,t,o){await this.applyRateLimiting(),await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callOpenRouter(e,this.model,!0);return this.handleStream(r,t)},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}async processVisionChat(e,t,o){if(!z(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);await this.applyRateLimiting();try{await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callOpenRouter(e,this.visionModel,!0);return this.handleStream(r,t)},runWithTools:()=>this.visionChatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processVisionChat received tool_calls. ChatProcessor must use visionChatOnce() loop when tools are enabled."})}catch(r){throw console.error("Error in processVisionChat:",r),r}}async chatOnce(e,t=!0,o=()=>{},r){await this.applyRateLimiting();let s=await this.callOpenRouter(e,this.model,t,r);return t?this.parseStream(s,o):this.parseOneShot(await s.json())}async visionChatOnce(e,t=!1,o=()=>{},r){if(!z(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);await this.applyRateLimiting();let s=await this.callOpenRouter(e,this.visionModel,t,r);return t?this.parseStream(s,o):this.parseOneShot(await s.json())}async callOpenRouter(e,t,o=!1,r){let s=this.buildRequestBody(e,t,o,r),n={Authorization:`Bearer ${this.apiKey}`};return this.appUrl&&(n["HTTP-Referer"]=this.appUrl),this.appName&&(n["X-Title"]=this.appName),await g.post(this.endpoint,s,n)}buildRequestBody(e,t,o,r){let s={model:t,messages:e,stream:o};if((r!==void 0?r:O(this.responseLength))&&console.warn("OpenRouter: Token limits are not supported for gpt-oss-20b model due to known issues. Using unlimited tokens instead."),this.reasoning_effort!==void 0||this.includeReasoning!==void 0||this.reasoningMaxTokens){if(s.reasoning={},this.reasoning_effort&&this.reasoning_effort!=="none"){let a=this.reasoning_effort==="minimal"?"low":this.reasoning_effort;s.reasoning.effort=a}(this.reasoning_effort==="none"||this.includeReasoning!==!0)&&(s.reasoning.exclude=!0),this.reasoningMaxTokens&&(s.reasoning.max_tokens=this.reasoningMaxTokens)}else s.reasoning={exclude:!0};return this.tools.length>0&&(s.tools=b(this.tools,"chat-completions"),s.tool_choice="auto"),s}async handleStream(e,t){return P(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}async parseStream(e,t){return x(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}parseOneShot(e){return I(e)}};var le=class{createChatService(e){let t=E({model:e.model,visionModel:e.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:e.model||this.getDefaultModel(),supportsVisionForModel:n=>this.supportsVisionForModel(n),validate:"explicit"}),o=e.tools,r=e.appName,s=e.appUrl;return new ae(e.apiKey,e.model||this.getDefaultModel(),t,o,e.endpoint,e.responseLength,r,s,e.reasoning_effort,e.includeReasoning,e.reasoningMaxTokens)}getProviderName(){return"openrouter"}getSupportedModels(){return[A,ot,We,Be,Ke,$e,je,ze,qe,Je,Ze,Xe,Mt,Ye,Qe,et,tt,Ot,Et,He]}getDefaultModel(){return A}supportsVision(){return this.getSupportedModels().some(e=>this.supportsVisionForModel(e))}supportsVisionForModel(e){return z(e)}getFreeModels(){return Ct}isModelFree(e){return U(e)}};var pe=class{constructor(e,t=q,o=H,r,s=ge,n,a,l){this.provider="zai";this.apiKey=e,this.model=t,this.tools=r||[],this.endpoint=s,this.responseLength=n,this.responseFormat=a,this.thinking=l??{type:"disabled"},this.visionModel=o}getModel(){return this.model}getVisionModel(){return this.visionModel}async processChat(e,t,o){await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callZAI(e,this.model,!0);return this.handleStream(r,t)},runWithTools:()=>this.chatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."})}async processVisionChat(e,t,o){if(!J(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);await v({hasTools:this.tools.length>0,runWithoutTools:async()=>{let r=await this.callZAI(e,this.visionModel,!0);return this.handleStream(r,t)},runWithTools:()=>this.visionChatOnce(e,!0,t),onCompleteResponse:o,toolErrorMessage:"processVisionChat received tool_calls. ChatProcessor must use visionChatOnce() loop when tools are enabled."})}async chatOnce(e,t=!0,o=()=>{},r){let s=await this.callZAI(e,this.model,t,r);return this.parseResponse(s,t,o)}async visionChatOnce(e,t=!1,o=()=>{},r){if(!J(this.visionModel))throw new Error(`Model ${this.visionModel} does not support vision capabilities.`);let s=await this.callZAI(e,this.visionModel,t,r);return this.parseResponse(s,t,o)}async parseResponse(e,t,o){return t?this.parseStream(e,o):this.parseOneShot(await e.json())}async callZAI(e,t,o=!1,r){let s=this.buildRequestBody(e,t,o,r);return await g.post(this.endpoint,s,{Authorization:`Bearer ${this.apiKey}`})}buildRequestBody(e,t,o,r){let s={model:t,stream:o,messages:e},n=r!==void 0?r:O(this.responseLength);n!==void 0&&(s.max_tokens=n),this.responseFormat&&(s.response_format=this.responseFormat),this.thinking&&(s.thinking=this.thinking);let a=this.buildToolsDefinition();return a.length>0&&(s.tools=a,s.tool_choice="auto",o&&It(t)&&(s.tool_stream=!0)),s}buildToolsDefinition(){return b(this.tools,"chat-completions")}async handleStream(e,t){return P(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}async parseStream(e,t){return x(e,t,{onJsonError:o=>console.debug("Failed to parse SSE data:",o)})}parseOneShot(e){return I(e)}};var ce=class{createChatService(e){let t=e.model||this.getDefaultModel(),o=E({model:t,visionModel:e.visionModel,defaultModel:this.getDefaultModel(),defaultVisionModel:this.getDefaultVisionModel(),supportsVisionForModel:n=>this.supportsVisionForModel(n),validate:"explicit"}),r=e.tools,s=e.thinking??{type:"disabled"};return new pe(e.apiKey,t,o,r,e.endpoint||ge,e.responseLength,e.responseFormat,s)}getProviderName(){return"zai"}getSupportedModels(){return[Tt,q,St,Pt,xt,rt,st,H]}getDefaultModel(){return q}getDefaultVisionModel(){return H}supportsVision(){return!0}supportsVisionForModel(e){return J(e)}};var $t=[new ne,new ie,new oe,new ee,new le,new ce,new se];var he=class{static registerProvider(e){this.providers.set(e.getProviderName(),e)}static createChatService(e,t){let o=this.providers.get(e);if(!o)throw new Error(`Unknown chat provider: ${e}`);return o.createChatService(t)}static getProviders(){return this.providers}static getAvailableProviders(){return Array.from(this.providers.keys())}static getSupportedModels(e){let t=this.providers.get(e);return t?t.getSupportedModels():[]}};he.providers=new Map;$t.forEach(i=>he.registerProvider(i));function jt(){g.setFetch(async(i,e={})=>{let t=(e.method||"GET").toString().toUpperCase(),o=e.headers,r={};if(Array.isArray(o))for(let[h,m]of o)r[h]=String(m);else if(o&&typeof o=="object")for(let[h,m]of Object.entries(o))r[h]=String(m);let s={method:t,headers:r,muteHttpExceptions:!0},n=e.body;typeof n=="string"?s.payload=n:n!=null&&(r["Content-Type"]||(r["Content-Type"]="application/json"),s.payload=JSON.stringify(n));let a=UrlFetchApp.fetch(i,s),l=a.getResponseCode(),c=a.getContentText();return{ok:l>=200&&l<300,status:l,statusText:String(l),text:async()=>c,json:async()=>c?JSON.parse(c):null}})}return Qt(Oo);})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aituber-onair/chat",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "description": "Chat and LLM API integration library for AITuber OnAir",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",