@aituber-onair/chat 0.47.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +25 -12
- package/README.md +27 -12
- package/dist/cjs/constants/gemini.d.ts +17 -0
- package/dist/cjs/constants/gemini.d.ts.map +1 -1
- package/dist/cjs/constants/gemini.js +67 -1
- package/dist/cjs/constants/gemini.js.map +1 -1
- package/dist/cjs/constants/kimi.d.ts +10 -0
- package/dist/cjs/constants/kimi.d.ts.map +1 -1
- package/dist/cjs/constants/kimi.js +20 -1
- package/dist/cjs/constants/kimi.js.map +1 -1
- package/dist/cjs/services/ChatService.d.ts +2 -2
- package/dist/cjs/services/ChatService.d.ts.map +1 -1
- package/dist/cjs/services/ChatServiceFactory.d.ts.map +1 -1
- package/dist/cjs/services/ChatServiceFactory.js +1 -0
- package/dist/cjs/services/ChatServiceFactory.js.map +1 -1
- package/dist/cjs/services/providers/ChatServiceProvider.d.ts +9 -2
- package/dist/cjs/services/providers/ChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/gemini/GeminiChatService.d.ts +8 -2
- package/dist/cjs/services/providers/gemini/GeminiChatService.d.ts.map +1 -1
- package/dist/cjs/services/providers/gemini/GeminiChatService.js +65 -38
- package/dist/cjs/services/providers/gemini/GeminiChatService.js.map +1 -1
- package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.js +9 -2
- package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.js.map +1 -1
- package/dist/cjs/services/providers/gemini/geminiMessageConverter.d.ts +6 -0
- package/dist/cjs/services/providers/gemini/geminiMessageConverter.d.ts.map +1 -1
- package/dist/cjs/services/providers/gemini/geminiMessageConverter.js +61 -58
- package/dist/cjs/services/providers/gemini/geminiMessageConverter.js.map +1 -1
- package/dist/cjs/services/providers/kimi/KimiChatService.d.ts +5 -4
- package/dist/cjs/services/providers/kimi/KimiChatService.d.ts.map +1 -1
- package/dist/cjs/services/providers/kimi/KimiChatService.js +34 -18
- package/dist/cjs/services/providers/kimi/KimiChatService.js.map +1 -1
- package/dist/cjs/services/providers/kimi/KimiChatServiceProvider.d.ts +1 -0
- package/dist/cjs/services/providers/kimi/KimiChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/kimi/KimiChatServiceProvider.js +23 -1
- package/dist/cjs/services/providers/kimi/KimiChatServiceProvider.js.map +1 -1
- package/dist/cjs/types/chat.d.ts +10 -2
- package/dist/cjs/types/chat.d.ts.map +1 -1
- package/dist/cjs/types/toolChat.d.ts +20 -0
- package/dist/cjs/types/toolChat.d.ts.map +1 -1
- package/dist/cjs/utils/openaiCompatibleSse.d.ts +1 -0
- package/dist/cjs/utils/openaiCompatibleSse.d.ts.map +1 -1
- package/dist/cjs/utils/openaiCompatibleSse.js +48 -5
- package/dist/cjs/utils/openaiCompatibleSse.js.map +1 -1
- package/dist/cjs/utils/processChatFlow.d.ts +2 -2
- package/dist/cjs/utils/processChatFlow.d.ts.map +1 -1
- package/dist/cjs/utils/processChatFlow.js +8 -3
- package/dist/cjs/utils/processChatFlow.js.map +1 -1
- package/dist/esm/constants/gemini.d.ts +17 -0
- package/dist/esm/constants/gemini.d.ts.map +1 -1
- package/dist/esm/constants/gemini.js +62 -0
- package/dist/esm/constants/gemini.js.map +1 -1
- package/dist/esm/constants/kimi.d.ts +10 -0
- package/dist/esm/constants/kimi.d.ts.map +1 -1
- package/dist/esm/constants/kimi.js +17 -0
- package/dist/esm/constants/kimi.js.map +1 -1
- package/dist/esm/services/ChatService.d.ts +2 -2
- package/dist/esm/services/ChatService.d.ts.map +1 -1
- package/dist/esm/services/ChatServiceFactory.d.ts.map +1 -1
- package/dist/esm/services/ChatServiceFactory.js +1 -0
- package/dist/esm/services/ChatServiceFactory.js.map +1 -1
- package/dist/esm/services/providers/ChatServiceProvider.d.ts +9 -2
- package/dist/esm/services/providers/ChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/gemini/GeminiChatService.d.ts +8 -2
- package/dist/esm/services/providers/gemini/GeminiChatService.d.ts.map +1 -1
- package/dist/esm/services/providers/gemini/GeminiChatService.js +66 -39
- package/dist/esm/services/providers/gemini/GeminiChatService.js.map +1 -1
- package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.js +10 -3
- package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.js.map +1 -1
- package/dist/esm/services/providers/gemini/geminiMessageConverter.d.ts +6 -0
- package/dist/esm/services/providers/gemini/geminiMessageConverter.d.ts.map +1 -1
- package/dist/esm/services/providers/gemini/geminiMessageConverter.js +61 -58
- package/dist/esm/services/providers/gemini/geminiMessageConverter.js.map +1 -1
- package/dist/esm/services/providers/kimi/KimiChatService.d.ts +5 -4
- package/dist/esm/services/providers/kimi/KimiChatService.d.ts.map +1 -1
- package/dist/esm/services/providers/kimi/KimiChatService.js +36 -20
- package/dist/esm/services/providers/kimi/KimiChatService.js.map +1 -1
- package/dist/esm/services/providers/kimi/KimiChatServiceProvider.d.ts +1 -0
- package/dist/esm/services/providers/kimi/KimiChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/kimi/KimiChatServiceProvider.js +24 -2
- package/dist/esm/services/providers/kimi/KimiChatServiceProvider.js.map +1 -1
- package/dist/esm/types/chat.d.ts +10 -2
- package/dist/esm/types/chat.d.ts.map +1 -1
- package/dist/esm/types/toolChat.d.ts +20 -0
- package/dist/esm/types/toolChat.d.ts.map +1 -1
- package/dist/esm/utils/openaiCompatibleSse.d.ts +1 -0
- package/dist/esm/utils/openaiCompatibleSse.d.ts.map +1 -1
- package/dist/esm/utils/openaiCompatibleSse.js +48 -5
- package/dist/esm/utils/openaiCompatibleSse.js.map +1 -1
- package/dist/esm/utils/processChatFlow.d.ts +2 -2
- package/dist/esm/utils/processChatFlow.d.ts.map +1 -1
- package/dist/esm/utils/processChatFlow.js +8 -3
- package/dist/esm/utils/processChatFlow.js.map +1 -1
- package/dist/umd/aituber-onair-chat.js +325 -131
- package/dist/umd/aituber-onair-chat.min.js +8 -8
- package/package.json +1 -1
|
@@ -106,6 +106,8 @@ var AITuberOnAirChat = (() => {
|
|
|
106
106
|
MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW: () => MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW,
|
|
107
107
|
MODEL_GEMINI_3_1_PRO_PREVIEW: () => MODEL_GEMINI_3_1_PRO_PREVIEW,
|
|
108
108
|
MODEL_GEMINI_3_5_FLASH: () => MODEL_GEMINI_3_5_FLASH,
|
|
109
|
+
MODEL_GEMINI_3_5_FLASH_LITE: () => MODEL_GEMINI_3_5_FLASH_LITE,
|
|
110
|
+
MODEL_GEMINI_3_6_FLASH: () => MODEL_GEMINI_3_6_FLASH,
|
|
109
111
|
MODEL_GEMINI_3_FLASH_PREVIEW: () => MODEL_GEMINI_3_FLASH_PREVIEW,
|
|
110
112
|
MODEL_GEMINI_3_PRO_PREVIEW: () => MODEL_GEMINI_3_PRO_PREVIEW,
|
|
111
113
|
MODEL_GEMINI_NANO: () => MODEL_GEMINI_NANO,
|
|
@@ -157,6 +159,7 @@ var AITuberOnAirChat = (() => {
|
|
|
157
159
|
MODEL_KIMI_K2_6: () => MODEL_KIMI_K2_6,
|
|
158
160
|
MODEL_KIMI_K2_7_CODE: () => MODEL_KIMI_K2_7_CODE,
|
|
159
161
|
MODEL_KIMI_K2_7_CODE_HIGHSPEED: () => MODEL_KIMI_K2_7_CODE_HIGHSPEED,
|
|
162
|
+
MODEL_KIMI_K3: () => MODEL_KIMI_K3,
|
|
160
163
|
MODEL_MINISTRAL_14B_2512: () => MODEL_MINISTRAL_14B_2512,
|
|
161
164
|
MODEL_MINISTRAL_3B_2512: () => MODEL_MINISTRAL_3B_2512,
|
|
162
165
|
MODEL_MINISTRAL_8B_2512: () => MODEL_MINISTRAL_8B_2512,
|
|
@@ -226,11 +229,16 @@ var AITuberOnAirChat = (() => {
|
|
|
226
229
|
allowsReasoningNone: () => allowsReasoningNone,
|
|
227
230
|
allowsReasoningXHigh: () => allowsReasoningXHigh,
|
|
228
231
|
buildOpenAICompatibleTools: () => buildOpenAICompatibleTools,
|
|
232
|
+
getDefaultGeminiReasoningEffort: () => getDefaultGeminiReasoningEffort,
|
|
229
233
|
getDefaultReasoningEffortForGPT5Model: () => getDefaultReasoningEffortForGPT5Model,
|
|
230
234
|
getDefaultXaiReasoningEffort: () => getDefaultXaiReasoningEffort,
|
|
235
|
+
getGeminiSupportedReasoningEfforts: () => getGeminiSupportedReasoningEfforts,
|
|
236
|
+
getKimiSupportedReasoningEfforts: () => getKimiSupportedReasoningEfforts,
|
|
231
237
|
getMaxTokensForResponseLength: () => getMaxTokensForResponseLength,
|
|
232
238
|
installGASFetch: () => installGASFetch,
|
|
233
239
|
isGPT5Model: () => isGPT5Model,
|
|
240
|
+
isGeminiReasoningEffortModel: () => isGeminiReasoningEffortModel,
|
|
241
|
+
isKimiReasoningEffortModel: () => isKimiReasoningEffortModel,
|
|
234
242
|
isKimiThinkingRequiredModel: () => isKimiThinkingRequiredModel,
|
|
235
243
|
isKimiVisionModel: () => isKimiVisionModel,
|
|
236
244
|
isMistralReasoningEffort: () => isMistralReasoningEffort,
|
|
@@ -244,6 +252,7 @@ var AITuberOnAirChat = (() => {
|
|
|
244
252
|
isXaiVisionModel: () => isXaiVisionModel,
|
|
245
253
|
isZaiToolStreamModel: () => isZaiToolStreamModel,
|
|
246
254
|
isZaiVisionModel: () => isZaiVisionModel,
|
|
255
|
+
normalizeGeminiReasoningEffort: () => normalizeGeminiReasoningEffort,
|
|
247
256
|
normalizeXaiReasoningEffort: () => normalizeXaiReasoningEffort,
|
|
248
257
|
parseOpenAICompatibleOneShot: () => parseOpenAICompatibleOneShot,
|
|
249
258
|
parseOpenAICompatibleTextStream: () => parseOpenAICompatibleTextStream,
|
|
@@ -355,7 +364,9 @@ var AITuberOnAirChat = (() => {
|
|
|
355
364
|
var ENDPOINT_GEMINI_API = "https://generativelanguage.googleapis.com";
|
|
356
365
|
var MODEL_GEMMA_4_31B_IT = "gemma-4-31b-it";
|
|
357
366
|
var MODEL_GEMMA_4_26B_A4B_IT = "gemma-4-26b-a4b-it";
|
|
367
|
+
var MODEL_GEMINI_3_6_FLASH = "gemini-3.6-flash";
|
|
358
368
|
var MODEL_GEMINI_3_5_FLASH = "gemini-3.5-flash";
|
|
369
|
+
var MODEL_GEMINI_3_5_FLASH_LITE = "gemini-3.5-flash-lite";
|
|
359
370
|
var MODEL_GEMINI_3_1_PRO_PREVIEW = "gemini-3.1-pro-preview";
|
|
360
371
|
var MODEL_GEMINI_3_1_FLASH_LITE = "gemini-3.1-flash-lite";
|
|
361
372
|
var MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW = "gemini-3.1-flash-lite-preview";
|
|
@@ -366,7 +377,9 @@ var AITuberOnAirChat = (() => {
|
|
|
366
377
|
var MODEL_GEMINI_2_5_FLASH_LITE = "gemini-2.5-flash-lite";
|
|
367
378
|
var MODEL_GEMINI_2_5_FLASH_LITE_PREVIEW_06_17 = "gemini-2.5-flash-lite-preview-06-17";
|
|
368
379
|
var GEMINI_RECOMMENDED_MODELS = [
|
|
380
|
+
MODEL_GEMINI_3_6_FLASH,
|
|
369
381
|
MODEL_GEMINI_3_5_FLASH,
|
|
382
|
+
MODEL_GEMINI_3_5_FLASH_LITE,
|
|
370
383
|
MODEL_GEMINI_3_1_FLASH_LITE,
|
|
371
384
|
MODEL_GEMINI_3_1_PRO_PREVIEW,
|
|
372
385
|
MODEL_GEMINI_3_FLASH_PREVIEW,
|
|
@@ -385,6 +398,54 @@ var AITuberOnAirChat = (() => {
|
|
|
385
398
|
...GEMINI_RECOMMENDED_MODELS,
|
|
386
399
|
...GEMINI_DEPRECATED_MODELS
|
|
387
400
|
];
|
|
401
|
+
var GEMINI_FLASH_REASONING_EFFORTS = [
|
|
402
|
+
"minimal",
|
|
403
|
+
"low",
|
|
404
|
+
"medium",
|
|
405
|
+
"high"
|
|
406
|
+
];
|
|
407
|
+
var GEMINI_PRO_REASONING_EFFORTS = [
|
|
408
|
+
"low",
|
|
409
|
+
"medium",
|
|
410
|
+
"high"
|
|
411
|
+
];
|
|
412
|
+
var GEMINI_FLASH_REASONING_EFFORT_MODELS = [
|
|
413
|
+
MODEL_GEMINI_3_6_FLASH,
|
|
414
|
+
MODEL_GEMINI_3_5_FLASH,
|
|
415
|
+
MODEL_GEMINI_3_5_FLASH_LITE,
|
|
416
|
+
MODEL_GEMINI_3_1_FLASH_LITE,
|
|
417
|
+
MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW,
|
|
418
|
+
MODEL_GEMINI_3_FLASH_PREVIEW
|
|
419
|
+
];
|
|
420
|
+
var GEMINI_PRO_REASONING_EFFORT_MODELS = [
|
|
421
|
+
MODEL_GEMINI_3_1_PRO_PREVIEW,
|
|
422
|
+
MODEL_GEMINI_3_PRO_PREVIEW
|
|
423
|
+
];
|
|
424
|
+
function getGeminiSupportedReasoningEfforts(model) {
|
|
425
|
+
if (GEMINI_FLASH_REASONING_EFFORT_MODELS.includes(model)) {
|
|
426
|
+
return GEMINI_FLASH_REASONING_EFFORTS;
|
|
427
|
+
}
|
|
428
|
+
if (GEMINI_PRO_REASONING_EFFORT_MODELS.includes(model)) {
|
|
429
|
+
return GEMINI_PRO_REASONING_EFFORTS;
|
|
430
|
+
}
|
|
431
|
+
return [];
|
|
432
|
+
}
|
|
433
|
+
function isGeminiReasoningEffortModel(model) {
|
|
434
|
+
return getGeminiSupportedReasoningEfforts(model).length > 0;
|
|
435
|
+
}
|
|
436
|
+
function getDefaultGeminiReasoningEffort(model) {
|
|
437
|
+
return getGeminiSupportedReasoningEfforts(model)[0];
|
|
438
|
+
}
|
|
439
|
+
function normalizeGeminiReasoningEffort(model, effort) {
|
|
440
|
+
const supported = getGeminiSupportedReasoningEfforts(model);
|
|
441
|
+
if (supported.length === 0) {
|
|
442
|
+
return void 0;
|
|
443
|
+
}
|
|
444
|
+
if (effort && supported.includes(effort)) {
|
|
445
|
+
return effort;
|
|
446
|
+
}
|
|
447
|
+
return supported[0];
|
|
448
|
+
}
|
|
388
449
|
|
|
389
450
|
// src/constants/claude.ts
|
|
390
451
|
var ENDPOINT_CLAUDE_API = "https://api.anthropic.com/v1/messages";
|
|
@@ -565,11 +626,16 @@ var AITuberOnAirChat = (() => {
|
|
|
565
626
|
|
|
566
627
|
// src/constants/kimi.ts
|
|
567
628
|
var ENDPOINT_KIMI_CHAT_COMPLETIONS_API = "https://api.moonshot.ai/v1/chat/completions";
|
|
629
|
+
var MODEL_KIMI_K3 = "kimi-k3";
|
|
568
630
|
var MODEL_KIMI_K2_7_CODE = "kimi-k2.7-code";
|
|
569
631
|
var MODEL_KIMI_K2_7_CODE_HIGHSPEED = "kimi-k2.7-code-highspeed";
|
|
570
632
|
var MODEL_KIMI_K2_6 = "kimi-k2.6";
|
|
571
633
|
var MODEL_KIMI_K2_5 = "kimi-k2.5";
|
|
634
|
+
var KIMI_REASONING_EFFORTS_BY_MODEL = {
|
|
635
|
+
[MODEL_KIMI_K3]: ["max"]
|
|
636
|
+
};
|
|
572
637
|
var KIMI_VISION_SUPPORTED_MODELS = [
|
|
638
|
+
MODEL_KIMI_K3,
|
|
573
639
|
MODEL_KIMI_K2_7_CODE,
|
|
574
640
|
MODEL_KIMI_K2_7_CODE_HIGHSPEED,
|
|
575
641
|
MODEL_KIMI_K2_6,
|
|
@@ -585,6 +651,12 @@ var AITuberOnAirChat = (() => {
|
|
|
585
651
|
function isKimiThinkingRequiredModel(model) {
|
|
586
652
|
return KIMI_THINKING_REQUIRED_MODELS.includes(model);
|
|
587
653
|
}
|
|
654
|
+
function getKimiSupportedReasoningEfforts(model) {
|
|
655
|
+
return KIMI_REASONING_EFFORTS_BY_MODEL[model] ?? [];
|
|
656
|
+
}
|
|
657
|
+
function isKimiReasoningEffortModel(model) {
|
|
658
|
+
return getKimiSupportedReasoningEfforts(model).length > 0;
|
|
659
|
+
}
|
|
588
660
|
|
|
589
661
|
// src/constants/deepseek.ts
|
|
590
662
|
var DEEPSEEK_API_BASE_URL = "https://api.deepseek.com";
|
|
@@ -1061,6 +1133,8 @@ If it's in another language, summarize in that language.
|
|
|
1061
1133
|
async function parseOpenAICompatibleToolStream(res, onPartial, options = {}) {
|
|
1062
1134
|
const textBlocks = [];
|
|
1063
1135
|
const toolCallsMap = /* @__PURE__ */ new Map();
|
|
1136
|
+
let fullContent = "";
|
|
1137
|
+
let reasoningContent = "";
|
|
1064
1138
|
let finishReason;
|
|
1065
1139
|
let usage;
|
|
1066
1140
|
const appendTextBlock = options.appendTextBlock ?? StreamTextAccumulator.append;
|
|
@@ -1079,14 +1153,23 @@ If it's in another language, summarize in that language.
|
|
|
1079
1153
|
if (content) {
|
|
1080
1154
|
onPartial(content);
|
|
1081
1155
|
appendTextBlock(textBlocks, content);
|
|
1156
|
+
fullContent += content;
|
|
1157
|
+
}
|
|
1158
|
+
const reasoning = extractTextContent(delta?.reasoning_content);
|
|
1159
|
+
if (reasoning) {
|
|
1160
|
+
reasoningContent += reasoning;
|
|
1082
1161
|
}
|
|
1083
1162
|
if (delta?.tool_calls) {
|
|
1084
1163
|
delta.tool_calls.forEach((c) => {
|
|
1085
1164
|
const entry = toolCallsMap.get(c.index) ?? {
|
|
1086
1165
|
id: c.id,
|
|
1166
|
+
type: c.type,
|
|
1087
1167
|
name: c.function?.name,
|
|
1088
1168
|
args: ""
|
|
1089
1169
|
};
|
|
1170
|
+
if (c.id) entry.id = c.id;
|
|
1171
|
+
if (c.type) entry.type = c.type;
|
|
1172
|
+
if (c.function?.name) entry.name = c.function.name;
|
|
1090
1173
|
entry.args += c.function?.arguments || "";
|
|
1091
1174
|
toolCallsMap.set(c.index, entry);
|
|
1092
1175
|
});
|
|
@@ -1099,17 +1182,35 @@ If it's in another language, summarize in that language.
|
|
|
1099
1182
|
input: safeParseToolCallInput(e.args, options.onJsonError)
|
|
1100
1183
|
}));
|
|
1101
1184
|
const blocks = [...textBlocks, ...toolBlocks];
|
|
1185
|
+
const assistantToolCalls = Array.from(
|
|
1186
|
+
toolCallsMap.entries()
|
|
1187
|
+
).sort((a, b) => a[0] - b[0]).map(([_, entry]) => ({
|
|
1188
|
+
id: entry.id,
|
|
1189
|
+
type: "function",
|
|
1190
|
+
function: {
|
|
1191
|
+
name: entry.name,
|
|
1192
|
+
arguments: entry.args
|
|
1193
|
+
}
|
|
1194
|
+
}));
|
|
1195
|
+
const assistantMessage = {
|
|
1196
|
+
role: "assistant",
|
|
1197
|
+
content: fullContent,
|
|
1198
|
+
...reasoningContent ? { reasoning_content: reasoningContent } : {},
|
|
1199
|
+
...assistantToolCalls.length > 0 ? { tool_calls: assistantToolCalls } : {}
|
|
1200
|
+
};
|
|
1102
1201
|
return {
|
|
1103
1202
|
blocks,
|
|
1104
1203
|
stop_reason: toolBlocks.length ? "tool_use" : "end",
|
|
1105
1204
|
truncated: finishReason === "length",
|
|
1106
1205
|
finish_reason: finishReason,
|
|
1107
|
-
usage
|
|
1206
|
+
usage,
|
|
1207
|
+
...options.preserveAssistantMessage ? { assistant_message: assistantMessage } : {}
|
|
1108
1208
|
};
|
|
1109
1209
|
}
|
|
1110
1210
|
function parseOpenAICompatibleOneShot(data, options = {}) {
|
|
1111
1211
|
const choice = data?.choices?.[0];
|
|
1112
1212
|
const blocks = [];
|
|
1213
|
+
const content = extractTextContent(choice?.message?.content);
|
|
1113
1214
|
if (choice?.message?.tool_calls?.length) {
|
|
1114
1215
|
choice.message.tool_calls.forEach(
|
|
1115
1216
|
(c) => blocks.push({
|
|
@@ -1122,18 +1223,21 @@ If it's in another language, summarize in that language.
|
|
|
1122
1223
|
)
|
|
1123
1224
|
})
|
|
1124
1225
|
);
|
|
1125
|
-
} else {
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1226
|
+
} else if (content) {
|
|
1227
|
+
blocks.push({ type: "text", text: content });
|
|
1228
|
+
}
|
|
1229
|
+
const assistantMessage = choice?.message ? {
|
|
1230
|
+
...choice.message,
|
|
1231
|
+
role: "assistant",
|
|
1232
|
+
content
|
|
1233
|
+
} : void 0;
|
|
1131
1234
|
return {
|
|
1132
1235
|
blocks,
|
|
1133
1236
|
stop_reason: choice?.finish_reason === "tool_calls" || blocks.some((b) => b.type === "tool_use") ? "tool_use" : "end",
|
|
1134
1237
|
truncated: choice?.finish_reason === "length",
|
|
1135
1238
|
finish_reason: choice?.finish_reason,
|
|
1136
|
-
usage: data?.usage
|
|
1239
|
+
usage: data?.usage,
|
|
1240
|
+
...options.preserveAssistantMessage ? { assistant_message: assistantMessage } : {}
|
|
1137
1241
|
};
|
|
1138
1242
|
}
|
|
1139
1243
|
|
|
@@ -1161,8 +1265,15 @@ If it's in another language, summarize in that language.
|
|
|
1161
1265
|
// src/utils/processChatFlow.ts
|
|
1162
1266
|
async function processChatWithOptionalTools(options) {
|
|
1163
1267
|
if (!options.hasTools) {
|
|
1164
|
-
const
|
|
1165
|
-
|
|
1268
|
+
const result2 = await options.runWithoutTools();
|
|
1269
|
+
if (typeof result2 === "string") {
|
|
1270
|
+
await options.onCompleteResponse(result2);
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1273
|
+
const full = StreamTextAccumulator.getFullText(
|
|
1274
|
+
result2.blocks
|
|
1275
|
+
);
|
|
1276
|
+
await options.onCompleteResponse(full, result2);
|
|
1166
1277
|
return;
|
|
1167
1278
|
}
|
|
1168
1279
|
const result = await options.runWithTools();
|
|
@@ -1173,7 +1284,7 @@ If it's in another language, summarize in that language.
|
|
|
1173
1284
|
const full = StreamTextAccumulator.getFullText(
|
|
1174
1285
|
result.blocks
|
|
1175
1286
|
);
|
|
1176
|
-
await options.onCompleteResponse(full);
|
|
1287
|
+
await options.onCompleteResponse(full, result);
|
|
1177
1288
|
return;
|
|
1178
1289
|
}
|
|
1179
1290
|
throw new Error(options.toolErrorMessage);
|
|
@@ -2732,41 +2843,26 @@ If it's in another language, summarize in that language.
|
|
|
2732
2843
|
gemini.push({ role: currentRole, parts: [...currentParts] });
|
|
2733
2844
|
currentParts = [];
|
|
2734
2845
|
}
|
|
2846
|
+
currentRole = null;
|
|
2735
2847
|
};
|
|
2736
2848
|
for (const msg of messages) {
|
|
2737
2849
|
const role = mapRoleToGemini(msg.role);
|
|
2738
2850
|
if (msg.tool_calls) {
|
|
2739
2851
|
pushCurrent();
|
|
2740
|
-
|
|
2741
|
-
|
|
2852
|
+
const parts = msg.tool_calls.map(
|
|
2853
|
+
(call) => createFunctionCallPart(call, options)
|
|
2854
|
+
);
|
|
2855
|
+
if (parts.length > 0) {
|
|
2742
2856
|
gemini.push({
|
|
2743
2857
|
role: "model",
|
|
2744
|
-
parts
|
|
2745
|
-
{
|
|
2746
|
-
functionCall: {
|
|
2747
|
-
name: call.function.name,
|
|
2748
|
-
args: JSON.parse(call.function.arguments || "{}")
|
|
2749
|
-
}
|
|
2750
|
-
}
|
|
2751
|
-
]
|
|
2858
|
+
parts
|
|
2752
2859
|
});
|
|
2753
2860
|
}
|
|
2754
2861
|
continue;
|
|
2755
2862
|
}
|
|
2756
2863
|
if (msg.role === "tool") {
|
|
2757
2864
|
pushCurrent();
|
|
2758
|
-
|
|
2759
|
-
gemini.push({
|
|
2760
|
-
role: "user",
|
|
2761
|
-
parts: [
|
|
2762
|
-
{
|
|
2763
|
-
functionResponse: {
|
|
2764
|
-
name: funcName,
|
|
2765
|
-
response: normalizeToolResult(safeJsonParse2(msg.content))
|
|
2766
|
-
}
|
|
2767
|
-
}
|
|
2768
|
-
]
|
|
2769
|
-
});
|
|
2865
|
+
appendFunctionResponse(gemini, createFunctionResponsePart(msg, options));
|
|
2770
2866
|
continue;
|
|
2771
2867
|
}
|
|
2772
2868
|
if (role !== currentRole) pushCurrent();
|
|
@@ -2782,47 +2878,41 @@ If it's in another language, summarize in that language.
|
|
|
2782
2878
|
const geminiMessages = [];
|
|
2783
2879
|
let currentRole = null;
|
|
2784
2880
|
let currentParts = [];
|
|
2881
|
+
const pushCurrent = () => {
|
|
2882
|
+
if (currentRole && currentParts.length > 0) {
|
|
2883
|
+
geminiMessages.push({
|
|
2884
|
+
role: currentRole,
|
|
2885
|
+
parts: [...currentParts]
|
|
2886
|
+
});
|
|
2887
|
+
currentParts = [];
|
|
2888
|
+
}
|
|
2889
|
+
currentRole = null;
|
|
2890
|
+
};
|
|
2785
2891
|
for (const msg of messages) {
|
|
2786
2892
|
const role = mapRoleToGemini(msg.role);
|
|
2787
2893
|
if (msg.tool_calls) {
|
|
2788
|
-
|
|
2894
|
+
pushCurrent();
|
|
2895
|
+
const parts = msg.tool_calls.map(
|
|
2896
|
+
(call) => createFunctionCallPart(call, options)
|
|
2897
|
+
);
|
|
2898
|
+
if (parts.length > 0) {
|
|
2789
2899
|
geminiMessages.push({
|
|
2790
2900
|
role: "model",
|
|
2791
|
-
parts
|
|
2792
|
-
{
|
|
2793
|
-
functionCall: {
|
|
2794
|
-
name: call.function.name,
|
|
2795
|
-
args: JSON.parse(call.function.arguments || "{}")
|
|
2796
|
-
}
|
|
2797
|
-
}
|
|
2798
|
-
]
|
|
2901
|
+
parts
|
|
2799
2902
|
});
|
|
2800
2903
|
}
|
|
2801
2904
|
continue;
|
|
2802
2905
|
}
|
|
2803
2906
|
if (msg.role === "tool") {
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
functionResponse: {
|
|
2810
|
-
name: funcName,
|
|
2811
|
-
response: normalizeToolResult(
|
|
2812
|
-
safeJsonParse2(msg.content)
|
|
2813
|
-
)
|
|
2814
|
-
}
|
|
2815
|
-
}
|
|
2816
|
-
]
|
|
2817
|
-
});
|
|
2907
|
+
pushCurrent();
|
|
2908
|
+
appendFunctionResponse(
|
|
2909
|
+
geminiMessages,
|
|
2910
|
+
createFunctionResponsePart(msg, options)
|
|
2911
|
+
);
|
|
2818
2912
|
continue;
|
|
2819
2913
|
}
|
|
2820
2914
|
if (role !== currentRole && currentParts.length > 0) {
|
|
2821
|
-
|
|
2822
|
-
role: currentRole,
|
|
2823
|
-
parts: [...currentParts]
|
|
2824
|
-
});
|
|
2825
|
-
currentParts = [];
|
|
2915
|
+
pushCurrent();
|
|
2826
2916
|
}
|
|
2827
2917
|
currentRole = role;
|
|
2828
2918
|
if (typeof msg.content === "string") {
|
|
@@ -2850,14 +2940,43 @@ If it's in another language, summarize in that language.
|
|
|
2850
2940
|
}
|
|
2851
2941
|
}
|
|
2852
2942
|
}
|
|
2853
|
-
|
|
2854
|
-
geminiMessages.push({
|
|
2855
|
-
role: currentRole,
|
|
2856
|
-
parts: [...currentParts]
|
|
2857
|
-
});
|
|
2858
|
-
}
|
|
2943
|
+
pushCurrent();
|
|
2859
2944
|
return geminiMessages;
|
|
2860
2945
|
}
|
|
2946
|
+
function createFunctionCallPart(call, options) {
|
|
2947
|
+
options.callIdMap?.set(call.id, call.function.name);
|
|
2948
|
+
const context = options.functionCallContextMap?.get(call.id);
|
|
2949
|
+
const part = {
|
|
2950
|
+
functionCall: {
|
|
2951
|
+
...context?.providerCallId ? { id: context.providerCallId } : {},
|
|
2952
|
+
name: call.function.name,
|
|
2953
|
+
args: JSON.parse(call.function.arguments || "{}")
|
|
2954
|
+
}
|
|
2955
|
+
};
|
|
2956
|
+
if (context?.thoughtSignature) {
|
|
2957
|
+
part.thoughtSignature = context.thoughtSignature;
|
|
2958
|
+
}
|
|
2959
|
+
return part;
|
|
2960
|
+
}
|
|
2961
|
+
function createFunctionResponsePart(msg, options) {
|
|
2962
|
+
const toolCallId = msg.tool_call_id;
|
|
2963
|
+
const context = options.functionCallContextMap?.get(toolCallId);
|
|
2964
|
+
const functionResponse = {
|
|
2965
|
+
...context?.providerCallId ? { id: context.providerCallId } : {},
|
|
2966
|
+
name: msg.name ?? context?.name ?? options.callIdMap?.get(toolCallId) ?? "result",
|
|
2967
|
+
response: normalizeToolResult(safeJsonParse2(msg.content))
|
|
2968
|
+
};
|
|
2969
|
+
return { functionResponse };
|
|
2970
|
+
}
|
|
2971
|
+
function appendFunctionResponse(messages, part) {
|
|
2972
|
+
const previous = messages[messages.length - 1];
|
|
2973
|
+
const isFunctionResponseGroup = previous?.role === "user" && previous.parts.every((item) => item.functionResponse);
|
|
2974
|
+
if (isFunctionResponseGroup) {
|
|
2975
|
+
previous.parts.push(part);
|
|
2976
|
+
return;
|
|
2977
|
+
}
|
|
2978
|
+
messages.push({ role: "user", parts: [part] });
|
|
2979
|
+
}
|
|
2861
2980
|
function safeJsonParse2(str) {
|
|
2862
2981
|
try {
|
|
2863
2982
|
return JSON.parse(str);
|
|
@@ -2935,16 +3054,19 @@ If it's in another language, summarize in that language.
|
|
|
2935
3054
|
* @param tools Array of tool definitions
|
|
2936
3055
|
* @param mcpServers Array of MCP server configurations
|
|
2937
3056
|
*/
|
|
2938
|
-
constructor(apiKey, model = MODEL_GEMINI_3_1_FLASH_LITE, visionModel = MODEL_GEMINI_3_1_FLASH_LITE, tools = [], mcpServers = [], responseLength) {
|
|
3057
|
+
constructor(apiKey, model = MODEL_GEMINI_3_1_FLASH_LITE, visionModel = MODEL_GEMINI_3_1_FLASH_LITE, tools = [], mcpServers = [], responseLength, reasoningEffort) {
|
|
2939
3058
|
/** Provider name */
|
|
2940
3059
|
this.provider = "gemini";
|
|
2941
3060
|
this.mcpToolSchemas = [];
|
|
2942
3061
|
this.mcpSchemasInitialized = false;
|
|
2943
3062
|
/** id(OpenAI) → name(Gemini) mapping */
|
|
2944
3063
|
this.callIdMap = /* @__PURE__ */ new Map();
|
|
3064
|
+
/** Common tool id → Gemini function-call metadata required for replay. */
|
|
3065
|
+
this.functionCallContextMap = /* @__PURE__ */ new Map();
|
|
2945
3066
|
this.apiKey = apiKey;
|
|
2946
3067
|
this.model = model;
|
|
2947
3068
|
this.responseLength = responseLength;
|
|
3069
|
+
this.reasoningEffort = reasoningEffort;
|
|
2948
3070
|
if (!GEMINI_VISION_SUPPORTED_MODELS.includes(visionModel)) {
|
|
2949
3071
|
throw new Error(
|
|
2950
3072
|
`Model ${visionModel} does not support vision capabilities.`
|
|
@@ -2957,8 +3079,21 @@ If it's in another language, summarize in that language.
|
|
|
2957
3079
|
isGemma4Model(model) {
|
|
2958
3080
|
return /^gemma-4-/.test(model);
|
|
2959
3081
|
}
|
|
2960
|
-
|
|
2961
|
-
|
|
3082
|
+
resolveThinkingConfig(model) {
|
|
3083
|
+
const effort = normalizeGeminiReasoningEffort(model, this.reasoningEffort);
|
|
3084
|
+
if (effort) {
|
|
3085
|
+
return {
|
|
3086
|
+
includeThoughts: false,
|
|
3087
|
+
thinkingLevel: effort.toUpperCase()
|
|
3088
|
+
};
|
|
3089
|
+
}
|
|
3090
|
+
if (this.isGemma4Model(model)) {
|
|
3091
|
+
return {
|
|
3092
|
+
includeThoughts: false,
|
|
3093
|
+
thinkingLevel: "MINIMAL"
|
|
3094
|
+
};
|
|
3095
|
+
}
|
|
3096
|
+
return void 0;
|
|
2962
3097
|
}
|
|
2963
3098
|
shouldExposeTextPart(part, model) {
|
|
2964
3099
|
if (!part.text) return false;
|
|
@@ -2976,7 +3111,8 @@ If it's in another language, summarize in that language.
|
|
|
2976
3111
|
functionCallingConfig: "function_calling_config",
|
|
2977
3112
|
functionDeclarations: "function_declarations",
|
|
2978
3113
|
functionCall: "function_call",
|
|
2979
|
-
functionResponse: "function_response"
|
|
3114
|
+
functionResponse: "function_response",
|
|
3115
|
+
thoughtSignature: "thought_signature"
|
|
2980
3116
|
};
|
|
2981
3117
|
if (Array.isArray(obj)) return obj.map((v) => this.adaptKeysForApi(v));
|
|
2982
3118
|
if (obj && typeof obj === "object") {
|
|
@@ -3136,10 +3272,12 @@ If it's in another language, summarize in that language.
|
|
|
3136
3272
|
const contents = hasVision ? await convertVisionMessagesToGeminiFormat(
|
|
3137
3273
|
messages,
|
|
3138
3274
|
{
|
|
3139
|
-
callIdMap: this.callIdMap
|
|
3275
|
+
callIdMap: this.callIdMap,
|
|
3276
|
+
functionCallContextMap: this.functionCallContextMap
|
|
3140
3277
|
}
|
|
3141
3278
|
) : convertMessagesToGeminiFormat(messages, {
|
|
3142
|
-
callIdMap: this.callIdMap
|
|
3279
|
+
callIdMap: this.callIdMap,
|
|
3280
|
+
functionCallContextMap: this.functionCallContextMap
|
|
3143
3281
|
});
|
|
3144
3282
|
const body = {
|
|
3145
3283
|
contents,
|
|
@@ -3147,11 +3285,9 @@ If it's in another language, summarize in that language.
|
|
|
3147
3285
|
maxOutputTokens: maxTokens !== void 0 ? maxTokens : getMaxTokensForResponseLength(this.responseLength)
|
|
3148
3286
|
}
|
|
3149
3287
|
};
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
thinkingLevel: "MINIMAL"
|
|
3154
|
-
};
|
|
3288
|
+
const thinkingConfig = this.resolveThinkingConfig(model);
|
|
3289
|
+
if (thinkingConfig) {
|
|
3290
|
+
body.generationConfig.thinkingConfig = thinkingConfig;
|
|
3155
3291
|
}
|
|
3156
3292
|
let activeMCPToolSchemas = [];
|
|
3157
3293
|
if (this.mcpServers.length > 0) {
|
|
@@ -3208,6 +3344,32 @@ If it's in another language, summarize in that language.
|
|
|
3208
3344
|
throw error;
|
|
3209
3345
|
}
|
|
3210
3346
|
}
|
|
3347
|
+
createFunctionCallBlock(part) {
|
|
3348
|
+
const functionCall = part.functionCall ?? part.function_call;
|
|
3349
|
+
if (!functionCall) return void 0;
|
|
3350
|
+
const toolUseId = functionCall.id ?? this.genUUID();
|
|
3351
|
+
this.callIdMap.set(toolUseId, functionCall.name);
|
|
3352
|
+
this.functionCallContextMap.set(toolUseId, {
|
|
3353
|
+
name: functionCall.name,
|
|
3354
|
+
providerCallId: functionCall.id,
|
|
3355
|
+
thoughtSignature: part.thoughtSignature ?? part.thought_signature
|
|
3356
|
+
});
|
|
3357
|
+
return {
|
|
3358
|
+
type: "tool_use",
|
|
3359
|
+
id: toolUseId,
|
|
3360
|
+
name: functionCall.name,
|
|
3361
|
+
input: functionCall.args ?? {}
|
|
3362
|
+
};
|
|
3363
|
+
}
|
|
3364
|
+
createFunctionResponseBlock(part) {
|
|
3365
|
+
const functionResponse = part.functionResponse ?? part.function_response;
|
|
3366
|
+
if (!functionResponse) return void 0;
|
|
3367
|
+
return {
|
|
3368
|
+
type: "tool_result",
|
|
3369
|
+
tool_use_id: functionResponse.id ?? functionResponse.name,
|
|
3370
|
+
content: JSON.stringify(functionResponse.response)
|
|
3371
|
+
};
|
|
3372
|
+
}
|
|
3211
3373
|
/* ────────────────────────────────────────────────────────── */
|
|
3212
3374
|
/* Convert NDJSON stream to common format */
|
|
3213
3375
|
/* ────────────────────────────────────────────────────────── */
|
|
@@ -3231,21 +3393,10 @@ If it's in another language, summarize in that language.
|
|
|
3231
3393
|
onPartial(part.text);
|
|
3232
3394
|
StreamTextAccumulator.addTextBlock(textBlocks, part.text);
|
|
3233
3395
|
}
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
name: part.functionCall.name,
|
|
3239
|
-
input: part.functionCall.args ?? {}
|
|
3240
|
-
});
|
|
3241
|
-
}
|
|
3242
|
-
if (part.functionResponse) {
|
|
3243
|
-
toolBlocks.push({
|
|
3244
|
-
type: "tool_result",
|
|
3245
|
-
tool_use_id: part.functionResponse.name,
|
|
3246
|
-
content: JSON.stringify(part.functionResponse.response)
|
|
3247
|
-
});
|
|
3248
|
-
}
|
|
3396
|
+
const functionCallBlock = this.createFunctionCallBlock(part);
|
|
3397
|
+
if (functionCallBlock) toolBlocks.push(functionCallBlock);
|
|
3398
|
+
const functionResponseBlock = this.createFunctionResponseBlock(part);
|
|
3399
|
+
if (functionResponseBlock) toolBlocks.push(functionResponseBlock);
|
|
3249
3400
|
}
|
|
3250
3401
|
}
|
|
3251
3402
|
};
|
|
@@ -3285,21 +3436,10 @@ If it's in another language, summarize in that language.
|
|
|
3285
3436
|
if (this.shouldExposeTextPart(part, model)) {
|
|
3286
3437
|
textBlocks.push({ type: "text", text: part.text });
|
|
3287
3438
|
}
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
name: part.functionCall.name,
|
|
3293
|
-
input: part.functionCall.args ?? {}
|
|
3294
|
-
});
|
|
3295
|
-
}
|
|
3296
|
-
if (part.functionResponse) {
|
|
3297
|
-
toolBlocks.push({
|
|
3298
|
-
type: "tool_result",
|
|
3299
|
-
tool_use_id: part.functionResponse.name,
|
|
3300
|
-
content: JSON.stringify(part.functionResponse.response)
|
|
3301
|
-
});
|
|
3302
|
-
}
|
|
3439
|
+
const functionCallBlock = this.createFunctionCallBlock(part);
|
|
3440
|
+
if (functionCallBlock) toolBlocks.push(functionCallBlock);
|
|
3441
|
+
const functionResponseBlock = this.createFunctionResponseBlock(part);
|
|
3442
|
+
if (functionResponseBlock) toolBlocks.push(functionResponseBlock);
|
|
3303
3443
|
}
|
|
3304
3444
|
}
|
|
3305
3445
|
const blocks = [...textBlocks, ...toolBlocks];
|
|
@@ -3349,21 +3489,28 @@ If it's in another language, summarize in that language.
|
|
|
3349
3489
|
* @returns GeminiChatService instance
|
|
3350
3490
|
*/
|
|
3351
3491
|
createChatService(options) {
|
|
3492
|
+
const model = options.model || this.getDefaultModel();
|
|
3493
|
+
if (options.reasoning_effort !== void 0 && !isGeminiReasoningEffortModel(model)) {
|
|
3494
|
+
throw new Error(
|
|
3495
|
+
`Model ${model} does not support Gemini reasoning_effort. Use it with Gemini 3 thinkingLevel models; Gemini 2.5 models use thinkingBudget instead.`
|
|
3496
|
+
);
|
|
3497
|
+
}
|
|
3352
3498
|
const visionModel = resolveVisionModel({
|
|
3353
|
-
model
|
|
3499
|
+
model,
|
|
3354
3500
|
visionModel: options.visionModel,
|
|
3355
3501
|
defaultModel: this.getDefaultModel(),
|
|
3356
3502
|
defaultVisionModel: this.getDefaultModel(),
|
|
3357
|
-
supportsVisionForModel: (
|
|
3503
|
+
supportsVisionForModel: (model2) => this.supportsVisionForModel(model2),
|
|
3358
3504
|
validate: "resolved"
|
|
3359
3505
|
});
|
|
3360
3506
|
return new GeminiChatService(
|
|
3361
3507
|
options.apiKey,
|
|
3362
|
-
|
|
3508
|
+
model,
|
|
3363
3509
|
visionModel,
|
|
3364
3510
|
options.tools || [],
|
|
3365
3511
|
options.mcpServers || [],
|
|
3366
|
-
options.responseLength
|
|
3512
|
+
options.responseLength,
|
|
3513
|
+
normalizeGeminiReasoningEffort(model, options.reasoning_effort)
|
|
3367
3514
|
);
|
|
3368
3515
|
}
|
|
3369
3516
|
/**
|
|
@@ -3571,7 +3718,7 @@ If it's in another language, summarize in that language.
|
|
|
3571
3718
|
* @param model Name of the model to use
|
|
3572
3719
|
* @param visionModel Name of the vision model
|
|
3573
3720
|
*/
|
|
3574
|
-
constructor(apiKey, model = MODEL_KIMI_K2_6, visionModel = MODEL_KIMI_K2_6, tools, endpoint = ENDPOINT_KIMI_CHAT_COMPLETIONS_API, responseLength, responseFormat, thinking) {
|
|
3721
|
+
constructor(apiKey, model = MODEL_KIMI_K2_6, visionModel = MODEL_KIMI_K2_6, tools, endpoint = ENDPOINT_KIMI_CHAT_COMPLETIONS_API, responseLength, responseFormat, thinking, reasoningEffort) {
|
|
3575
3722
|
/** Provider name */
|
|
3576
3723
|
this.provider = "kimi";
|
|
3577
3724
|
this.apiKey = apiKey;
|
|
@@ -3580,7 +3727,14 @@ If it's in another language, summarize in that language.
|
|
|
3580
3727
|
this.endpoint = endpoint;
|
|
3581
3728
|
this.responseLength = responseLength;
|
|
3582
3729
|
this.responseFormat = responseFormat;
|
|
3583
|
-
this.thinking = thinking
|
|
3730
|
+
this.thinking = thinking;
|
|
3731
|
+
const supportedReasoningEfforts = getKimiSupportedReasoningEfforts(model);
|
|
3732
|
+
if (reasoningEffort !== void 0 && !supportedReasoningEfforts.includes(reasoningEffort)) {
|
|
3733
|
+
throw new Error(
|
|
3734
|
+
`Model ${model} does not support reasoning_effort: ${reasoningEffort}.`
|
|
3735
|
+
);
|
|
3736
|
+
}
|
|
3737
|
+
this.reasoningEffort = reasoningEffort ?? (isKimiReasoningEffortModel(model) ? supportedReasoningEfforts[0] : void 0);
|
|
3584
3738
|
this.visionModel = visionModel;
|
|
3585
3739
|
}
|
|
3586
3740
|
/**
|
|
@@ -3601,10 +3755,7 @@ If it's in another language, summarize in that language.
|
|
|
3601
3755
|
async processChat(messages, onPartialResponse, onCompleteResponse) {
|
|
3602
3756
|
await processChatWithOptionalTools({
|
|
3603
3757
|
hasTools: this.tools.length > 0,
|
|
3604
|
-
runWithoutTools:
|
|
3605
|
-
const res = await this.callKimi(messages, this.model, true);
|
|
3606
|
-
return this.handleStream(res, onPartialResponse);
|
|
3607
|
-
},
|
|
3758
|
+
runWithoutTools: () => this.chatOnce(messages, true, onPartialResponse),
|
|
3608
3759
|
runWithTools: () => this.chatOnce(messages, true, onPartialResponse),
|
|
3609
3760
|
onCompleteResponse,
|
|
3610
3761
|
toolErrorMessage: "processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."
|
|
@@ -3621,10 +3772,7 @@ If it's in another language, summarize in that language.
|
|
|
3621
3772
|
}
|
|
3622
3773
|
await processChatWithOptionalTools({
|
|
3623
3774
|
hasTools: this.tools.length > 0,
|
|
3624
|
-
runWithoutTools:
|
|
3625
|
-
const res = await this.callKimi(messages, this.visionModel, true);
|
|
3626
|
-
return this.handleStream(res, onPartialResponse);
|
|
3627
|
-
},
|
|
3775
|
+
runWithoutTools: () => this.visionChatOnce(messages, true, onPartialResponse),
|
|
3628
3776
|
runWithTools: () => this.visionChatOnce(messages, true, onPartialResponse),
|
|
3629
3777
|
onCompleteResponse,
|
|
3630
3778
|
toolErrorMessage: "processVisionChat received tool_calls. ChatProcessor must use visionChatOnce() loop when tools are enabled."
|
|
@@ -3677,11 +3825,18 @@ If it's in another language, summarize in that language.
|
|
|
3677
3825
|
};
|
|
3678
3826
|
const tokenLimit = maxTokens !== void 0 ? maxTokens : getMaxTokensForResponseLength(this.responseLength);
|
|
3679
3827
|
if (tokenLimit !== void 0) {
|
|
3680
|
-
|
|
3828
|
+
if (isKimiReasoningEffortModel(model)) {
|
|
3829
|
+
body.max_completion_tokens = tokenLimit;
|
|
3830
|
+
} else {
|
|
3831
|
+
body.max_tokens = tokenLimit;
|
|
3832
|
+
}
|
|
3681
3833
|
}
|
|
3682
3834
|
if (this.responseFormat) {
|
|
3683
3835
|
body.response_format = this.responseFormat;
|
|
3684
3836
|
}
|
|
3837
|
+
if (isKimiReasoningEffortModel(model)) {
|
|
3838
|
+
body.reasoning_effort = this.reasoningEffort ?? "max";
|
|
3839
|
+
}
|
|
3685
3840
|
const effectiveThinking = this.resolveEffectiveThinking(model);
|
|
3686
3841
|
if (effectiveThinking) {
|
|
3687
3842
|
if (this.isSelfHostedEndpoint()) {
|
|
@@ -3706,6 +3861,14 @@ If it's in another language, summarize in that language.
|
|
|
3706
3861
|
return value.replace(/\/+$/, "");
|
|
3707
3862
|
}
|
|
3708
3863
|
resolveEffectiveThinking(model) {
|
|
3864
|
+
if (isKimiReasoningEffortModel(model)) {
|
|
3865
|
+
if (this.thinking) {
|
|
3866
|
+
throw new Error(
|
|
3867
|
+
`Model ${model} uses reasoning_effort and does not support the K2.x thinking option.`
|
|
3868
|
+
);
|
|
3869
|
+
}
|
|
3870
|
+
return void 0;
|
|
3871
|
+
}
|
|
3709
3872
|
if (isKimiThinkingRequiredModel(model)) {
|
|
3710
3873
|
if (this.thinking?.type === "disabled") {
|
|
3711
3874
|
throw new Error(
|
|
@@ -3717,21 +3880,17 @@ If it's in another language, summarize in that language.
|
|
|
3717
3880
|
if (this.tools.length > 0) {
|
|
3718
3881
|
return { type: "disabled" };
|
|
3719
3882
|
}
|
|
3720
|
-
return this.thinking;
|
|
3883
|
+
return this.thinking ?? { type: "enabled" };
|
|
3721
3884
|
}
|
|
3722
3885
|
buildToolsDefinition() {
|
|
3723
3886
|
return buildOpenAICompatibleTools(this.tools, "chat-completions");
|
|
3724
3887
|
}
|
|
3725
|
-
async handleStream(res, onPartial) {
|
|
3726
|
-
return parseOpenAICompatibleTextStream(res, onPartial, {
|
|
3727
|
-
onJsonError: (payload) => console.debug("Failed to parse SSE data:", payload)
|
|
3728
|
-
});
|
|
3729
|
-
}
|
|
3730
3888
|
/**
|
|
3731
3889
|
* Parse streaming response with tool support
|
|
3732
3890
|
*/
|
|
3733
3891
|
async parseStream(res, onPartial) {
|
|
3734
3892
|
return parseOpenAICompatibleToolStream(res, onPartial, {
|
|
3893
|
+
preserveAssistantMessage: true,
|
|
3735
3894
|
onJsonError: (payload) => console.debug("Failed to parse SSE data:", payload)
|
|
3736
3895
|
});
|
|
3737
3896
|
}
|
|
@@ -3739,7 +3898,9 @@ If it's in another language, summarize in that language.
|
|
|
3739
3898
|
* Parse non-streaming response
|
|
3740
3899
|
*/
|
|
3741
3900
|
parseOneShot(data) {
|
|
3742
|
-
return parseOpenAICompatibleOneShot(data
|
|
3901
|
+
return parseOpenAICompatibleOneShot(data, {
|
|
3902
|
+
preserveAssistantMessage: true
|
|
3903
|
+
});
|
|
3743
3904
|
}
|
|
3744
3905
|
};
|
|
3745
3906
|
|
|
@@ -3764,6 +3925,10 @@ If it's in another language, summarize in that language.
|
|
|
3764
3925
|
});
|
|
3765
3926
|
const tools = options.tools;
|
|
3766
3927
|
const thinking = this.resolveThinking(model, tools, options.thinking);
|
|
3928
|
+
const reasoningEffort = this.resolveReasoningEffort(
|
|
3929
|
+
model,
|
|
3930
|
+
options.reasoning_effort
|
|
3931
|
+
);
|
|
3767
3932
|
return new KimiChatService(
|
|
3768
3933
|
options.apiKey,
|
|
3769
3934
|
model,
|
|
@@ -3772,7 +3937,8 @@ If it's in another language, summarize in that language.
|
|
|
3772
3937
|
endpoint,
|
|
3773
3938
|
options.responseLength,
|
|
3774
3939
|
options.responseFormat,
|
|
3775
|
-
thinking
|
|
3940
|
+
thinking,
|
|
3941
|
+
reasoningEffort
|
|
3776
3942
|
);
|
|
3777
3943
|
}
|
|
3778
3944
|
/**
|
|
@@ -3786,6 +3952,7 @@ If it's in another language, summarize in that language.
|
|
|
3786
3952
|
*/
|
|
3787
3953
|
getSupportedModels() {
|
|
3788
3954
|
return [
|
|
3955
|
+
MODEL_KIMI_K3,
|
|
3789
3956
|
MODEL_KIMI_K2_7_CODE,
|
|
3790
3957
|
MODEL_KIMI_K2_7_CODE_HIGHSPEED,
|
|
3791
3958
|
MODEL_KIMI_K2_6,
|
|
@@ -3839,6 +4006,14 @@ If it's in another language, summarize in that language.
|
|
|
3839
4006
|
return value.replace(/\/+$/, "");
|
|
3840
4007
|
}
|
|
3841
4008
|
resolveThinking(model, tools, thinking) {
|
|
4009
|
+
if (isKimiReasoningEffortModel(model)) {
|
|
4010
|
+
if (thinking) {
|
|
4011
|
+
throw new Error(
|
|
4012
|
+
`Model ${model} uses reasoning_effort and does not support the K2.x thinking option.`
|
|
4013
|
+
);
|
|
4014
|
+
}
|
|
4015
|
+
return void 0;
|
|
4016
|
+
}
|
|
3842
4017
|
if (isKimiThinkingRequiredModel(model)) {
|
|
3843
4018
|
if (thinking?.type === "disabled") {
|
|
3844
4019
|
throw new Error(
|
|
@@ -3852,6 +4027,24 @@ If it's in another language, summarize in that language.
|
|
|
3852
4027
|
}
|
|
3853
4028
|
return thinking ?? this.defaultThinking;
|
|
3854
4029
|
}
|
|
4030
|
+
resolveReasoningEffort(model, reasoningEffort) {
|
|
4031
|
+
const supported = getKimiSupportedReasoningEfforts(model);
|
|
4032
|
+
if (supported.length === 0) {
|
|
4033
|
+
if (reasoningEffort !== void 0) {
|
|
4034
|
+
throw new Error(
|
|
4035
|
+
`Model ${model} does not support the reasoning_effort option.`
|
|
4036
|
+
);
|
|
4037
|
+
}
|
|
4038
|
+
return void 0;
|
|
4039
|
+
}
|
|
4040
|
+
const resolved = reasoningEffort ?? supported[0];
|
|
4041
|
+
if (!supported.includes(resolved)) {
|
|
4042
|
+
throw new Error(
|
|
4043
|
+
`Model ${model} supports reasoning_effort values: ${supported.join(", ")}.`
|
|
4044
|
+
);
|
|
4045
|
+
}
|
|
4046
|
+
return resolved;
|
|
4047
|
+
}
|
|
3855
4048
|
};
|
|
3856
4049
|
|
|
3857
4050
|
// src/services/providers/mistral/MistralChatService.ts
|
|
@@ -5258,6 +5451,7 @@ If it's in another language, summarize in that language.
|
|
|
5258
5451
|
]);
|
|
5259
5452
|
var REASONING_EFFORT_BY_PROVIDER = {
|
|
5260
5453
|
openai: ["none", "minimal", "low", "medium", "high", "xhigh", "max"],
|
|
5454
|
+
gemini: ["minimal", "low", "medium", "high"],
|
|
5261
5455
|
openrouter: ["none", "minimal", "low", "medium", "high"],
|
|
5262
5456
|
mistral: ["low", "medium", "high"],
|
|
5263
5457
|
plamo: ["none", "medium"],
|