@aituber-onair/chat 0.22.0 → 0.24.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 +18 -2
- package/README.md +18 -2
- package/dist/cjs/constants/geminiNano.d.ts +6 -0
- package/dist/cjs/constants/geminiNano.d.ts.map +1 -0
- package/dist/cjs/constants/geminiNano.js +9 -0
- package/dist/cjs/constants/geminiNano.js.map +1 -0
- package/dist/cjs/constants/index.d.ts +2 -0
- package/dist/cjs/constants/index.d.ts.map +1 -1
- package/dist/cjs/constants/index.js +2 -0
- package/dist/cjs/constants/index.js.map +1 -1
- package/dist/cjs/constants/xai.d.ts +11 -0
- package/dist/cjs/constants/xai.d.ts.map +1 -0
- package/dist/cjs/constants/xai.js +24 -0
- package/dist/cjs/constants/xai.js.map +1 -0
- package/dist/cjs/index.d.ts +5 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +11 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/services/providers/ChatServiceProvider.d.ts +15 -0
- package/dist/cjs/services/providers/ChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.d.ts +37 -0
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.d.ts.map +1 -0
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.js +128 -0
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.js.map +1 -0
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.d.ts +15 -0
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.d.ts.map +1 -0
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.js +35 -0
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.js.map +1 -0
- package/dist/cjs/services/providers/index.d.ts +3 -1
- package/dist/cjs/services/providers/index.d.ts.map +1 -1
- package/dist/cjs/services/providers/index.js +4 -0
- package/dist/cjs/services/providers/index.js.map +1 -1
- package/dist/cjs/services/providers/xai/XAIChatService.d.ts +65 -0
- package/dist/cjs/services/providers/xai/XAIChatService.d.ts.map +1 -0
- package/dist/cjs/services/providers/xai/XAIChatService.js +150 -0
- package/dist/cjs/services/providers/xai/XAIChatService.js.map +1 -0
- package/dist/cjs/services/providers/xai/XAIChatServiceProvider.d.ts +38 -0
- package/dist/cjs/services/providers/xai/XAIChatServiceProvider.d.ts.map +1 -0
- package/dist/cjs/services/providers/xai/XAIChatServiceProvider.js +76 -0
- package/dist/cjs/services/providers/xai/XAIChatServiceProvider.js.map +1 -0
- package/dist/esm/constants/geminiNano.d.ts +6 -0
- package/dist/esm/constants/geminiNano.d.ts.map +1 -0
- package/dist/esm/constants/geminiNano.js +6 -0
- package/dist/esm/constants/geminiNano.js.map +1 -0
- package/dist/esm/constants/index.d.ts +2 -0
- package/dist/esm/constants/index.d.ts.map +1 -1
- package/dist/esm/constants/index.js +2 -0
- package/dist/esm/constants/index.js.map +1 -1
- package/dist/esm/constants/xai.d.ts +11 -0
- package/dist/esm/constants/xai.d.ts.map +1 -0
- package/dist/esm/constants/xai.js +20 -0
- package/dist/esm/constants/xai.js.map +1 -0
- package/dist/esm/index.d.ts +5 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/services/providers/ChatServiceProvider.d.ts +15 -0
- package/dist/esm/services/providers/ChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.d.ts +37 -0
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.d.ts.map +1 -0
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.js +124 -0
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.js.map +1 -0
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.d.ts +15 -0
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.d.ts.map +1 -0
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.js +31 -0
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.js.map +1 -0
- package/dist/esm/services/providers/index.d.ts +3 -1
- package/dist/esm/services/providers/index.d.ts.map +1 -1
- package/dist/esm/services/providers/index.js +4 -0
- package/dist/esm/services/providers/index.js.map +1 -1
- package/dist/esm/services/providers/xai/XAIChatService.d.ts +65 -0
- package/dist/esm/services/providers/xai/XAIChatService.d.ts.map +1 -0
- package/dist/esm/services/providers/xai/XAIChatService.js +146 -0
- package/dist/esm/services/providers/xai/XAIChatService.js.map +1 -0
- package/dist/esm/services/providers/xai/XAIChatServiceProvider.d.ts +38 -0
- package/dist/esm/services/providers/xai/XAIChatServiceProvider.d.ts.map +1 -0
- package/dist/esm/services/providers/xai/XAIChatServiceProvider.js +72 -0
- package/dist/esm/services/providers/xai/XAIChatServiceProvider.js.map +1 -0
- package/dist/umd/aituber-onair-chat.js +387 -0
- package/dist/umd/aituber-onair-chat.min.js +11 -6
- package/package.json +1 -1
|
@@ -38,13 +38,17 @@ var AITuberOnAirChat = (() => {
|
|
|
38
38
|
ENDPOINT_OPENAI_CHAT_COMPLETIONS_API: () => ENDPOINT_OPENAI_CHAT_COMPLETIONS_API,
|
|
39
39
|
ENDPOINT_OPENAI_RESPONSES_API: () => ENDPOINT_OPENAI_RESPONSES_API,
|
|
40
40
|
ENDPOINT_OPENROUTER_API: () => ENDPOINT_OPENROUTER_API,
|
|
41
|
+
ENDPOINT_XAI_CHAT_COMPLETIONS_API: () => ENDPOINT_XAI_CHAT_COMPLETIONS_API,
|
|
41
42
|
ENDPOINT_ZAI_CHAT_COMPLETIONS_API: () => ENDPOINT_ZAI_CHAT_COMPLETIONS_API,
|
|
42
43
|
EmotionParser: () => EmotionParser,
|
|
44
|
+
GEMINI_NANO_MAX_CONTEXT_MESSAGES: () => GEMINI_NANO_MAX_CONTEXT_MESSAGES,
|
|
43
45
|
GEMINI_VISION_SUPPORTED_MODELS: () => GEMINI_VISION_SUPPORTED_MODELS,
|
|
44
46
|
GPT5_PRESETS: () => GPT5_PRESETS,
|
|
45
47
|
GPT_5_MODELS: () => GPT_5_MODELS,
|
|
46
48
|
GeminiChatService: () => GeminiChatService,
|
|
47
49
|
GeminiChatServiceProvider: () => GeminiChatServiceProvider,
|
|
50
|
+
GeminiNanoChatService: () => GeminiNanoChatService,
|
|
51
|
+
GeminiNanoChatServiceProvider: () => GeminiNanoChatServiceProvider,
|
|
48
52
|
HttpError: () => HttpError,
|
|
49
53
|
KIMI_VISION_SUPPORTED_MODELS: () => KIMI_VISION_SUPPORTED_MODELS,
|
|
50
54
|
KimiChatService: () => KimiChatService,
|
|
@@ -76,6 +80,7 @@ var AITuberOnAirChat = (() => {
|
|
|
76
80
|
MODEL_GEMINI_3_1_PRO_PREVIEW: () => MODEL_GEMINI_3_1_PRO_PREVIEW,
|
|
77
81
|
MODEL_GEMINI_3_FLASH_PREVIEW: () => MODEL_GEMINI_3_FLASH_PREVIEW,
|
|
78
82
|
MODEL_GEMINI_3_PRO_PREVIEW: () => MODEL_GEMINI_3_PRO_PREVIEW,
|
|
83
|
+
MODEL_GEMINI_NANO: () => MODEL_GEMINI_NANO,
|
|
79
84
|
MODEL_GLM_4_6: () => MODEL_GLM_4_6,
|
|
80
85
|
MODEL_GLM_4_6V: () => MODEL_GLM_4_6V,
|
|
81
86
|
MODEL_GLM_4_6V_FLASH: () => MODEL_GLM_4_6V_FLASH,
|
|
@@ -102,6 +107,10 @@ var AITuberOnAirChat = (() => {
|
|
|
102
107
|
MODEL_GPT_5_MINI: () => MODEL_GPT_5_MINI,
|
|
103
108
|
MODEL_GPT_5_NANO: () => MODEL_GPT_5_NANO,
|
|
104
109
|
MODEL_GPT_OSS_20B_FREE: () => MODEL_GPT_OSS_20B_FREE,
|
|
110
|
+
MODEL_GROK_4_1_FAST_NON_REASONING: () => MODEL_GROK_4_1_FAST_NON_REASONING,
|
|
111
|
+
MODEL_GROK_4_1_FAST_REASONING: () => MODEL_GROK_4_1_FAST_REASONING,
|
|
112
|
+
MODEL_GROK_4_20_NON_REASONING: () => MODEL_GROK_4_20_NON_REASONING,
|
|
113
|
+
MODEL_GROK_4_20_REASONING: () => MODEL_GROK_4_20_REASONING,
|
|
105
114
|
MODEL_KIMI_K2_5: () => MODEL_KIMI_K2_5,
|
|
106
115
|
MODEL_MOONSHOTAI_KIMI_K2_5: () => MODEL_MOONSHOTAI_KIMI_K2_5,
|
|
107
116
|
MODEL_O1: () => MODEL_O1,
|
|
@@ -130,6 +139,9 @@ var AITuberOnAirChat = (() => {
|
|
|
130
139
|
OpenRouterChatServiceProvider: () => OpenRouterChatServiceProvider,
|
|
131
140
|
StreamTextAccumulator: () => StreamTextAccumulator,
|
|
132
141
|
VISION_SUPPORTED_MODELS: () => VISION_SUPPORTED_MODELS,
|
|
142
|
+
XAIChatService: () => XAIChatService,
|
|
143
|
+
XAIChatServiceProvider: () => XAIChatServiceProvider,
|
|
144
|
+
XAI_VISION_SUPPORTED_MODELS: () => XAI_VISION_SUPPORTED_MODELS,
|
|
133
145
|
ZAIChatService: () => ZAIChatService,
|
|
134
146
|
ZAIChatServiceProvider: () => ZAIChatServiceProvider,
|
|
135
147
|
ZAI_VISION_SUPPORTED_MODELS: () => ZAI_VISION_SUPPORTED_MODELS,
|
|
@@ -146,6 +158,7 @@ var AITuberOnAirChat = (() => {
|
|
|
146
158
|
isOpenRouterFreeModel: () => isOpenRouterFreeModel,
|
|
147
159
|
isOpenRouterVisionModel: () => isOpenRouterVisionModel,
|
|
148
160
|
isResponsesOnlyGPT5Model: () => isResponsesOnlyGPT5Model,
|
|
161
|
+
isXaiVisionModel: () => isXaiVisionModel,
|
|
149
162
|
isZaiToolStreamModel: () => isZaiToolStreamModel,
|
|
150
163
|
isZaiVisionModel: () => isZaiVisionModel,
|
|
151
164
|
parseOpenAICompatibleOneShot: () => parseOpenAICompatibleOneShot,
|
|
@@ -362,6 +375,22 @@ var AITuberOnAirChat = (() => {
|
|
|
362
375
|
return model.toLowerCase().startsWith("glm-4.6");
|
|
363
376
|
}
|
|
364
377
|
|
|
378
|
+
// src/constants/xai.ts
|
|
379
|
+
var ENDPOINT_XAI_CHAT_COMPLETIONS_API = "https://api.x.ai/v1/chat/completions";
|
|
380
|
+
var MODEL_GROK_4_20_REASONING = "grok-4.20-0309-reasoning";
|
|
381
|
+
var MODEL_GROK_4_20_NON_REASONING = "grok-4.20-0309-non-reasoning";
|
|
382
|
+
var MODEL_GROK_4_1_FAST_REASONING = "grok-4-1-fast-reasoning";
|
|
383
|
+
var MODEL_GROK_4_1_FAST_NON_REASONING = "grok-4-1-fast-non-reasoning";
|
|
384
|
+
var XAI_VISION_SUPPORTED_MODELS = [
|
|
385
|
+
MODEL_GROK_4_20_REASONING,
|
|
386
|
+
MODEL_GROK_4_20_NON_REASONING,
|
|
387
|
+
MODEL_GROK_4_1_FAST_REASONING,
|
|
388
|
+
MODEL_GROK_4_1_FAST_NON_REASONING
|
|
389
|
+
];
|
|
390
|
+
function isXaiVisionModel(model) {
|
|
391
|
+
return XAI_VISION_SUPPORTED_MODELS.includes(model);
|
|
392
|
+
}
|
|
393
|
+
|
|
365
394
|
// src/constants/kimi.ts
|
|
366
395
|
var ENDPOINT_KIMI_CHAT_COMPLETIONS_API = "https://api.moonshot.ai/v1/chat/completions";
|
|
367
396
|
var MODEL_KIMI_K2_5 = "kimi-k2.5";
|
|
@@ -427,6 +456,10 @@ If it's in English, summarize in English.
|
|
|
427
456
|
If it's in another language, summarize in that language.
|
|
428
457
|
`;
|
|
429
458
|
|
|
459
|
+
// src/constants/geminiNano.ts
|
|
460
|
+
var MODEL_GEMINI_NANO = "gemini-nano";
|
|
461
|
+
var GEMINI_NANO_MAX_CONTEXT_MESSAGES = 20;
|
|
462
|
+
|
|
430
463
|
// src/utils/chatServiceHttpClient.ts
|
|
431
464
|
var HttpError = class extends Error {
|
|
432
465
|
constructor(status, statusText, body) {
|
|
@@ -2347,6 +2380,139 @@ If it's in another language, summarize in that language.
|
|
|
2347
2380
|
}
|
|
2348
2381
|
};
|
|
2349
2382
|
|
|
2383
|
+
// src/services/providers/geminiNano/GeminiNanoChatService.ts
|
|
2384
|
+
function getLanguageModelAPI() {
|
|
2385
|
+
if (typeof globalThis !== "undefined" && "LanguageModel" in globalThis) {
|
|
2386
|
+
return globalThis.LanguageModel;
|
|
2387
|
+
}
|
|
2388
|
+
return void 0;
|
|
2389
|
+
}
|
|
2390
|
+
var GeminiNanoChatService = class {
|
|
2391
|
+
constructor(options = {}) {
|
|
2392
|
+
this.provider = "gemini-nano";
|
|
2393
|
+
this.expectedInputLanguages = options.expectedInputLanguages ?? ["ja"];
|
|
2394
|
+
this.expectedOutputLanguages = options.expectedOutputLanguages ?? ["ja"];
|
|
2395
|
+
this._responseLength = options.responseLength;
|
|
2396
|
+
void this._responseLength;
|
|
2397
|
+
}
|
|
2398
|
+
getModel() {
|
|
2399
|
+
return MODEL_GEMINI_NANO;
|
|
2400
|
+
}
|
|
2401
|
+
getVisionModel() {
|
|
2402
|
+
return MODEL_GEMINI_NANO;
|
|
2403
|
+
}
|
|
2404
|
+
/**
|
|
2405
|
+
* Process chat messages using Gemini Nano.
|
|
2406
|
+
* Non-streaming: calls onPartialResponse once with the full response,
|
|
2407
|
+
* then calls onCompleteResponse.
|
|
2408
|
+
*/
|
|
2409
|
+
async processChat(messages, onPartialResponse, onCompleteResponse) {
|
|
2410
|
+
const response = await this.generateResponse(messages);
|
|
2411
|
+
onPartialResponse(response);
|
|
2412
|
+
await onCompleteResponse(response);
|
|
2413
|
+
}
|
|
2414
|
+
async processVisionChat(_messages, _onPartialResponse, _onCompleteResponse) {
|
|
2415
|
+
throw new Error("Gemini Nano does not support vision capabilities.");
|
|
2416
|
+
}
|
|
2417
|
+
async chatOnce(messages, _stream = false, onPartialResponse = () => {
|
|
2418
|
+
}, _maxTokens) {
|
|
2419
|
+
const response = await this.generateResponse(messages);
|
|
2420
|
+
onPartialResponse(response);
|
|
2421
|
+
return {
|
|
2422
|
+
blocks: [{ type: "text", text: response }],
|
|
2423
|
+
stop_reason: "end"
|
|
2424
|
+
};
|
|
2425
|
+
}
|
|
2426
|
+
async visionChatOnce(_messages, _stream = false, _onPartialResponse = () => {
|
|
2427
|
+
}, _maxTokens) {
|
|
2428
|
+
throw new Error("Gemini Nano does not support vision capabilities.");
|
|
2429
|
+
}
|
|
2430
|
+
/**
|
|
2431
|
+
* Core logic: extract system prompt, manage session, call prompt().
|
|
2432
|
+
*/
|
|
2433
|
+
async generateResponse(messages) {
|
|
2434
|
+
const api = getLanguageModelAPI();
|
|
2435
|
+
if (!api) {
|
|
2436
|
+
throw new Error(
|
|
2437
|
+
"Gemini Nano is not available in this environment. Chrome 138+ with Prompt API enabled is required."
|
|
2438
|
+
);
|
|
2439
|
+
}
|
|
2440
|
+
const availability = await api.availability();
|
|
2441
|
+
if (availability !== "available" && availability !== "downloadable") {
|
|
2442
|
+
throw new Error(
|
|
2443
|
+
`Gemini Nano Prompt API is not ready in this environment. LanguageModel.availability() returned "${availability}". Expected "available" or "downloadable".`
|
|
2444
|
+
);
|
|
2445
|
+
}
|
|
2446
|
+
const systemMessages = messages.filter((m) => m.role === "system");
|
|
2447
|
+
const systemPrompt = systemMessages.map((m) => m.content).join("\n");
|
|
2448
|
+
const conversationMessages = messages.filter((m) => m.role !== "system").slice(-GEMINI_NANO_MAX_CONTEXT_MESSAGES);
|
|
2449
|
+
const lastUserMessage = [...conversationMessages].reverse().find((m) => m.role === "user");
|
|
2450
|
+
if (!lastUserMessage) {
|
|
2451
|
+
throw new Error("No user message found in the provided messages.");
|
|
2452
|
+
}
|
|
2453
|
+
const session = await this.createSession(
|
|
2454
|
+
api,
|
|
2455
|
+
systemPrompt,
|
|
2456
|
+
conversationMessages
|
|
2457
|
+
);
|
|
2458
|
+
try {
|
|
2459
|
+
return await session.prompt(lastUserMessage.content);
|
|
2460
|
+
} finally {
|
|
2461
|
+
try {
|
|
2462
|
+
session.destroy();
|
|
2463
|
+
} catch {
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
/**
|
|
2468
|
+
* Create a new LanguageModel session with system prompt and context history.
|
|
2469
|
+
* Context history (excluding the last user message) is embedded in the system prompt.
|
|
2470
|
+
*/
|
|
2471
|
+
async createSession(api, systemPrompt, contextHistory) {
|
|
2472
|
+
let prompt = systemPrompt;
|
|
2473
|
+
const historyMessages = contextHistory.slice(0, -1);
|
|
2474
|
+
if (historyMessages.length > 0) {
|
|
2475
|
+
const history = historyMessages.map((m) => `${m.role === "user" ? "User" : "Assistant"}: ${m.content}`).join("\n");
|
|
2476
|
+
prompt += "\n\n\u4EE5\u4E0B\u306F\u3053\u308C\u307E\u3067\u306E\u4F1A\u8A71\u5C65\u6B74\u3067\u3059\u3002\u3053\u306E\u6587\u8108\u3092\u8E0F\u307E\u3048\u3066\u56DE\u7B54\u3057\u3066\u304F\u3060\u3055\u3044:\n" + history;
|
|
2477
|
+
}
|
|
2478
|
+
return api.create({
|
|
2479
|
+
systemPrompt: prompt,
|
|
2480
|
+
expectedInputs: [
|
|
2481
|
+
{ type: "text", languages: this.expectedInputLanguages }
|
|
2482
|
+
],
|
|
2483
|
+
expectedOutputs: [
|
|
2484
|
+
{ type: "text", languages: this.expectedOutputLanguages }
|
|
2485
|
+
]
|
|
2486
|
+
});
|
|
2487
|
+
}
|
|
2488
|
+
};
|
|
2489
|
+
|
|
2490
|
+
// src/services/providers/geminiNano/GeminiNanoChatServiceProvider.ts
|
|
2491
|
+
var GeminiNanoChatServiceProvider = class {
|
|
2492
|
+
createChatService(options) {
|
|
2493
|
+
return new GeminiNanoChatService({
|
|
2494
|
+
expectedInputLanguages: options.expectedInputLanguages,
|
|
2495
|
+
expectedOutputLanguages: options.expectedOutputLanguages,
|
|
2496
|
+
responseLength: options.responseLength
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2499
|
+
getProviderName() {
|
|
2500
|
+
return "gemini-nano";
|
|
2501
|
+
}
|
|
2502
|
+
getSupportedModels() {
|
|
2503
|
+
return [MODEL_GEMINI_NANO];
|
|
2504
|
+
}
|
|
2505
|
+
getDefaultModel() {
|
|
2506
|
+
return MODEL_GEMINI_NANO;
|
|
2507
|
+
}
|
|
2508
|
+
supportsVision() {
|
|
2509
|
+
return false;
|
|
2510
|
+
}
|
|
2511
|
+
getVisionSupportLevel() {
|
|
2512
|
+
return "unsupported";
|
|
2513
|
+
}
|
|
2514
|
+
};
|
|
2515
|
+
|
|
2350
2516
|
// src/services/providers/kimi/KimiChatService.ts
|
|
2351
2517
|
var KimiChatService = class {
|
|
2352
2518
|
/**
|
|
@@ -3734,6 +3900,225 @@ If it's in another language, summarize in that language.
|
|
|
3734
3900
|
}
|
|
3735
3901
|
};
|
|
3736
3902
|
|
|
3903
|
+
// src/services/providers/xai/XAIChatService.ts
|
|
3904
|
+
var XAIChatService = class {
|
|
3905
|
+
/**
|
|
3906
|
+
* Constructor
|
|
3907
|
+
* @param apiKey xAI API key
|
|
3908
|
+
* @param model Name of the model to use
|
|
3909
|
+
* @param visionModel Name of the vision model
|
|
3910
|
+
*/
|
|
3911
|
+
constructor(apiKey, model = MODEL_GROK_4_1_FAST_NON_REASONING, visionModel = MODEL_GROK_4_1_FAST_NON_REASONING, tools, endpoint = ENDPOINT_XAI_CHAT_COMPLETIONS_API, responseLength) {
|
|
3912
|
+
/** Provider name */
|
|
3913
|
+
this.provider = "xai";
|
|
3914
|
+
this.apiKey = apiKey;
|
|
3915
|
+
this.model = model;
|
|
3916
|
+
this.tools = tools || [];
|
|
3917
|
+
this.endpoint = endpoint;
|
|
3918
|
+
this.responseLength = responseLength;
|
|
3919
|
+
this.visionModel = visionModel;
|
|
3920
|
+
}
|
|
3921
|
+
/**
|
|
3922
|
+
* Get the current model name
|
|
3923
|
+
*/
|
|
3924
|
+
getModel() {
|
|
3925
|
+
return this.model;
|
|
3926
|
+
}
|
|
3927
|
+
/**
|
|
3928
|
+
* Get the current vision model name
|
|
3929
|
+
*/
|
|
3930
|
+
getVisionModel() {
|
|
3931
|
+
return this.visionModel;
|
|
3932
|
+
}
|
|
3933
|
+
/**
|
|
3934
|
+
* Process chat messages
|
|
3935
|
+
*/
|
|
3936
|
+
async processChat(messages, onPartialResponse, onCompleteResponse) {
|
|
3937
|
+
await processChatWithOptionalTools({
|
|
3938
|
+
hasTools: this.tools.length > 0,
|
|
3939
|
+
runWithoutTools: async () => {
|
|
3940
|
+
const res = await this.callXAI(messages, this.model, true);
|
|
3941
|
+
return this.handleStream(res, onPartialResponse);
|
|
3942
|
+
},
|
|
3943
|
+
runWithTools: () => this.chatOnce(messages, true, onPartialResponse),
|
|
3944
|
+
onCompleteResponse,
|
|
3945
|
+
toolErrorMessage: "processChat received tool_calls. ChatProcessor must use chatOnce() loop when tools are enabled."
|
|
3946
|
+
});
|
|
3947
|
+
}
|
|
3948
|
+
/**
|
|
3949
|
+
* Process chat messages with images
|
|
3950
|
+
*/
|
|
3951
|
+
async processVisionChat(messages, onPartialResponse, onCompleteResponse) {
|
|
3952
|
+
if (!isXaiVisionModel(this.visionModel)) {
|
|
3953
|
+
throw new Error(
|
|
3954
|
+
`Model ${this.visionModel} does not support vision capabilities.`
|
|
3955
|
+
);
|
|
3956
|
+
}
|
|
3957
|
+
await processChatWithOptionalTools({
|
|
3958
|
+
hasTools: this.tools.length > 0,
|
|
3959
|
+
runWithoutTools: async () => {
|
|
3960
|
+
const res = await this.callXAI(messages, this.visionModel, true);
|
|
3961
|
+
return this.handleStream(res, onPartialResponse);
|
|
3962
|
+
},
|
|
3963
|
+
runWithTools: () => this.visionChatOnce(messages, true, onPartialResponse),
|
|
3964
|
+
onCompleteResponse,
|
|
3965
|
+
toolErrorMessage: "processVisionChat received tool_calls. ChatProcessor must use visionChatOnce() loop when tools are enabled."
|
|
3966
|
+
});
|
|
3967
|
+
}
|
|
3968
|
+
/**
|
|
3969
|
+
* Process chat messages with tools (text only)
|
|
3970
|
+
*/
|
|
3971
|
+
async chatOnce(messages, stream = true, onPartialResponse = () => {
|
|
3972
|
+
}, maxTokens) {
|
|
3973
|
+
const res = await this.callXAI(messages, this.model, stream, maxTokens);
|
|
3974
|
+
return this.parseResponse(res, stream, onPartialResponse);
|
|
3975
|
+
}
|
|
3976
|
+
/**
|
|
3977
|
+
* Process vision chat messages with tools
|
|
3978
|
+
*/
|
|
3979
|
+
async visionChatOnce(messages, stream = false, onPartialResponse = () => {
|
|
3980
|
+
}, maxTokens) {
|
|
3981
|
+
if (!isXaiVisionModel(this.visionModel)) {
|
|
3982
|
+
throw new Error(
|
|
3983
|
+
`Model ${this.visionModel} does not support vision capabilities.`
|
|
3984
|
+
);
|
|
3985
|
+
}
|
|
3986
|
+
const res = await this.callXAI(
|
|
3987
|
+
messages,
|
|
3988
|
+
this.visionModel,
|
|
3989
|
+
stream,
|
|
3990
|
+
maxTokens
|
|
3991
|
+
);
|
|
3992
|
+
return this.parseResponse(res, stream, onPartialResponse);
|
|
3993
|
+
}
|
|
3994
|
+
async parseResponse(res, stream, onPartialResponse) {
|
|
3995
|
+
return stream ? this.parseStream(res, onPartialResponse) : this.parseOneShot(await res.json());
|
|
3996
|
+
}
|
|
3997
|
+
async callXAI(messages, model, stream = false, maxTokens) {
|
|
3998
|
+
const body = this.buildRequestBody(messages, model, stream, maxTokens);
|
|
3999
|
+
const res = await ChatServiceHttpClient.post(this.endpoint, body, {
|
|
4000
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
4001
|
+
});
|
|
4002
|
+
return res;
|
|
4003
|
+
}
|
|
4004
|
+
/**
|
|
4005
|
+
* Build request body (OpenAI-compatible Chat Completions)
|
|
4006
|
+
*/
|
|
4007
|
+
buildRequestBody(messages, model, stream, maxTokens) {
|
|
4008
|
+
const body = {
|
|
4009
|
+
model,
|
|
4010
|
+
stream,
|
|
4011
|
+
messages
|
|
4012
|
+
};
|
|
4013
|
+
const tokenLimit = maxTokens !== void 0 ? maxTokens : getMaxTokensForResponseLength(this.responseLength);
|
|
4014
|
+
if (tokenLimit !== void 0) {
|
|
4015
|
+
body.max_tokens = tokenLimit;
|
|
4016
|
+
}
|
|
4017
|
+
const tools = this.buildToolsDefinition();
|
|
4018
|
+
if (tools.length > 0) {
|
|
4019
|
+
body.tools = tools;
|
|
4020
|
+
body.tool_choice = "auto";
|
|
4021
|
+
}
|
|
4022
|
+
return body;
|
|
4023
|
+
}
|
|
4024
|
+
buildToolsDefinition() {
|
|
4025
|
+
return buildOpenAICompatibleTools(this.tools, "chat-completions");
|
|
4026
|
+
}
|
|
4027
|
+
async handleStream(res, onPartial) {
|
|
4028
|
+
return parseOpenAICompatibleTextStream(res, onPartial, {
|
|
4029
|
+
onJsonError: (payload) => console.debug("Failed to parse SSE data:", payload)
|
|
4030
|
+
});
|
|
4031
|
+
}
|
|
4032
|
+
/**
|
|
4033
|
+
* Parse streaming response with tool support
|
|
4034
|
+
*/
|
|
4035
|
+
async parseStream(res, onPartial) {
|
|
4036
|
+
return parseOpenAICompatibleToolStream(res, onPartial, {
|
|
4037
|
+
onJsonError: (payload) => console.debug("Failed to parse SSE data:", payload)
|
|
4038
|
+
});
|
|
4039
|
+
}
|
|
4040
|
+
/**
|
|
4041
|
+
* Parse non-streaming response
|
|
4042
|
+
*/
|
|
4043
|
+
parseOneShot(data) {
|
|
4044
|
+
return parseOpenAICompatibleOneShot(data);
|
|
4045
|
+
}
|
|
4046
|
+
};
|
|
4047
|
+
|
|
4048
|
+
// src/services/providers/xai/XAIChatServiceProvider.ts
|
|
4049
|
+
var XAIChatServiceProvider = class {
|
|
4050
|
+
/**
|
|
4051
|
+
* Create a chat service instance
|
|
4052
|
+
*/
|
|
4053
|
+
createChatService(options) {
|
|
4054
|
+
const model = options.model || this.getDefaultModel();
|
|
4055
|
+
const visionModel = resolveVisionModel({
|
|
4056
|
+
model,
|
|
4057
|
+
visionModel: options.visionModel,
|
|
4058
|
+
defaultModel: this.getDefaultModel(),
|
|
4059
|
+
defaultVisionModel: this.getDefaultVisionModel(),
|
|
4060
|
+
supportsVisionForModel: (visionModel2) => this.supportsVisionForModel(visionModel2),
|
|
4061
|
+
validate: "explicit"
|
|
4062
|
+
});
|
|
4063
|
+
const tools = options.tools;
|
|
4064
|
+
return new XAIChatService(
|
|
4065
|
+
options.apiKey,
|
|
4066
|
+
model,
|
|
4067
|
+
visionModel,
|
|
4068
|
+
tools,
|
|
4069
|
+
options.endpoint || ENDPOINT_XAI_CHAT_COMPLETIONS_API,
|
|
4070
|
+
options.responseLength
|
|
4071
|
+
);
|
|
4072
|
+
}
|
|
4073
|
+
/**
|
|
4074
|
+
* Get the provider name
|
|
4075
|
+
*/
|
|
4076
|
+
getProviderName() {
|
|
4077
|
+
return "xai";
|
|
4078
|
+
}
|
|
4079
|
+
/**
|
|
4080
|
+
* Get the list of supported models
|
|
4081
|
+
*/
|
|
4082
|
+
getSupportedModels() {
|
|
4083
|
+
return [
|
|
4084
|
+
MODEL_GROK_4_20_REASONING,
|
|
4085
|
+
MODEL_GROK_4_20_NON_REASONING,
|
|
4086
|
+
MODEL_GROK_4_1_FAST_REASONING,
|
|
4087
|
+
MODEL_GROK_4_1_FAST_NON_REASONING
|
|
4088
|
+
];
|
|
4089
|
+
}
|
|
4090
|
+
/**
|
|
4091
|
+
* Get the default model
|
|
4092
|
+
*/
|
|
4093
|
+
getDefaultModel() {
|
|
4094
|
+
return MODEL_GROK_4_1_FAST_NON_REASONING;
|
|
4095
|
+
}
|
|
4096
|
+
/**
|
|
4097
|
+
* Get the default vision model
|
|
4098
|
+
*/
|
|
4099
|
+
getDefaultVisionModel() {
|
|
4100
|
+
return MODEL_GROK_4_1_FAST_NON_REASONING;
|
|
4101
|
+
}
|
|
4102
|
+
/**
|
|
4103
|
+
* Check if this provider supports vision
|
|
4104
|
+
*/
|
|
4105
|
+
supportsVision() {
|
|
4106
|
+
return this.getVisionSupportLevel() !== "unsupported";
|
|
4107
|
+
}
|
|
4108
|
+
getVisionSupportLevel() {
|
|
4109
|
+
return "supported";
|
|
4110
|
+
}
|
|
4111
|
+
/**
|
|
4112
|
+
* Check if a specific model supports vision capabilities
|
|
4113
|
+
*/
|
|
4114
|
+
supportsVisionForModel(model) {
|
|
4115
|
+
return isXaiVisionModel(model);
|
|
4116
|
+
}
|
|
4117
|
+
getVisionSupportLevelForModel(model) {
|
|
4118
|
+
return this.supportsVisionForModel(model) ? "supported" : "unsupported";
|
|
4119
|
+
}
|
|
4120
|
+
};
|
|
4121
|
+
|
|
3737
4122
|
// src/services/providers/zai/ZAIChatService.ts
|
|
3738
4123
|
var ZAIChatService = class {
|
|
3739
4124
|
/**
|
|
@@ -3977,9 +4362,11 @@ If it's in another language, summarize in that language.
|
|
|
3977
4362
|
new OpenAIChatServiceProvider(),
|
|
3978
4363
|
new OpenAICompatibleChatServiceProvider(),
|
|
3979
4364
|
new GeminiChatServiceProvider(),
|
|
4365
|
+
new GeminiNanoChatServiceProvider(),
|
|
3980
4366
|
new ClaudeChatServiceProvider(),
|
|
3981
4367
|
new OpenRouterChatServiceProvider(),
|
|
3982
4368
|
new ZAIChatServiceProvider(),
|
|
4369
|
+
new XAIChatServiceProvider(),
|
|
3983
4370
|
new KimiChatServiceProvider()
|
|
3984
4371
|
];
|
|
3985
4372
|
|