@aituber-onair/chat 0.55.0 → 0.56.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 +28 -8
- package/README.md +30 -9
- package/dist/cjs/constants/claude.d.ts +1 -0
- package/dist/cjs/constants/claude.d.ts.map +1 -1
- package/dist/cjs/constants/claude.js +3 -1
- package/dist/cjs/constants/claude.js.map +1 -1
- package/dist/cjs/constants/openai.d.ts +5 -3
- package/dist/cjs/constants/openai.d.ts.map +1 -1
- package/dist/cjs/constants/openai.js +24 -7
- package/dist/cjs/constants/openai.js.map +1 -1
- package/dist/cjs/constants/xai.d.ts +1 -0
- package/dist/cjs/constants/xai.d.ts.map +1 -1
- package/dist/cjs/constants/xai.js +7 -2
- package/dist/cjs/constants/xai.js.map +1 -1
- package/dist/cjs/services/ChatService.d.ts +2 -0
- 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 +20 -15
- package/dist/cjs/services/ChatServiceFactory.js.map +1 -1
- package/dist/cjs/services/providers/ChatServiceProvider.d.ts +2 -0
- package/dist/cjs/services/providers/ChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/claude/ClaudeChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/claude/ClaudeChatServiceProvider.js +1 -0
- package/dist/cjs/services/providers/claude/ClaudeChatServiceProvider.js.map +1 -1
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.d.ts +24 -3
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.d.ts.map +1 -1
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.js +211 -15
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatService.js.map +1 -1
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.js +1 -0
- package/dist/cjs/services/providers/geminiNano/GeminiNanoChatServiceProvider.js.map +1 -1
- package/dist/cjs/services/providers/openai/OpenAIChatService.js +1 -1
- package/dist/cjs/services/providers/openai/OpenAIChatService.js.map +1 -1
- package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.js +10 -0
- package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.js.map +1 -1
- package/dist/cjs/services/providers/xai/XAIChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/xai/XAIChatServiceProvider.js +1 -0
- package/dist/cjs/services/providers/xai/XAIChatServiceProvider.js.map +1 -1
- package/dist/esm/constants/claude.d.ts +1 -0
- package/dist/esm/constants/claude.d.ts.map +1 -1
- package/dist/esm/constants/claude.js +2 -0
- package/dist/esm/constants/claude.js.map +1 -1
- package/dist/esm/constants/openai.d.ts +5 -3
- package/dist/esm/constants/openai.d.ts.map +1 -1
- package/dist/esm/constants/openai.js +23 -6
- package/dist/esm/constants/openai.js.map +1 -1
- package/dist/esm/constants/xai.d.ts +1 -0
- package/dist/esm/constants/xai.d.ts.map +1 -1
- package/dist/esm/constants/xai.js +6 -1
- package/dist/esm/constants/xai.js.map +1 -1
- package/dist/esm/services/ChatService.d.ts +2 -0
- 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 +21 -16
- package/dist/esm/services/ChatServiceFactory.js.map +1 -1
- package/dist/esm/services/providers/ChatServiceProvider.d.ts +2 -0
- package/dist/esm/services/providers/ChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/claude/ClaudeChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/claude/ClaudeChatServiceProvider.js +2 -1
- package/dist/esm/services/providers/claude/ClaudeChatServiceProvider.js.map +1 -1
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.d.ts +24 -3
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.d.ts.map +1 -1
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.js +211 -15
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatService.js.map +1 -1
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.js +1 -0
- package/dist/esm/services/providers/geminiNano/GeminiNanoChatServiceProvider.js.map +1 -1
- package/dist/esm/services/providers/openai/OpenAIChatService.js +1 -1
- package/dist/esm/services/providers/openai/OpenAIChatService.js.map +1 -1
- package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.js +11 -1
- package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.js.map +1 -1
- package/dist/esm/services/providers/xai/XAIChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/xai/XAIChatServiceProvider.js +2 -1
- package/dist/esm/services/providers/xai/XAIChatServiceProvider.js.map +1 -1
- package/dist/umd/aituber-onair-chat.js +309 -25
- package/dist/umd/aituber-onair-chat.min.js +8 -8
- package/package.json +1 -1
|
@@ -99,6 +99,7 @@ var AITuberOnAirChat = (() => {
|
|
|
99
99
|
MODEL_CLAUDE_4_OPUS: () => MODEL_CLAUDE_4_OPUS,
|
|
100
100
|
MODEL_CLAUDE_4_SONNET: () => MODEL_CLAUDE_4_SONNET,
|
|
101
101
|
MODEL_CLAUDE_5_1_FABLE: () => MODEL_CLAUDE_5_1_FABLE,
|
|
102
|
+
MODEL_CLAUDE_5_5_OPUS: () => MODEL_CLAUDE_5_5_OPUS,
|
|
102
103
|
MODEL_CLAUDE_5_FABLE: () => MODEL_CLAUDE_5_FABLE,
|
|
103
104
|
MODEL_CLAUDE_5_OPUS: () => MODEL_CLAUDE_5_OPUS,
|
|
104
105
|
MODEL_CLAUDE_5_SONNET: () => MODEL_CLAUDE_5_SONNET,
|
|
@@ -171,6 +172,8 @@ var AITuberOnAirChat = (() => {
|
|
|
171
172
|
MODEL_GPT_5_MINI: () => MODEL_GPT_5_MINI,
|
|
172
173
|
MODEL_GPT_5_NANO: () => MODEL_GPT_5_NANO,
|
|
173
174
|
MODEL_GPT_6_ASTRA: () => MODEL_GPT_6_ASTRA,
|
|
175
|
+
MODEL_GPT_6_LUNA: () => MODEL_GPT_6_LUNA,
|
|
176
|
+
MODEL_GPT_6_SOL: () => MODEL_GPT_6_SOL,
|
|
174
177
|
MODEL_GPT_OSS_20B_FREE: () => MODEL_GPT_OSS_20B_FREE,
|
|
175
178
|
MODEL_GROK_4_1_FAST_NON_REASONING: () => MODEL_GROK_4_1_FAST_NON_REASONING,
|
|
176
179
|
MODEL_GROK_4_1_FAST_REASONING: () => MODEL_GROK_4_1_FAST_REASONING,
|
|
@@ -179,6 +182,7 @@ var AITuberOnAirChat = (() => {
|
|
|
179
182
|
MODEL_GROK_4_3: () => MODEL_GROK_4_3,
|
|
180
183
|
MODEL_GROK_4_5: () => MODEL_GROK_4_5,
|
|
181
184
|
MODEL_GROK_4_6: () => MODEL_GROK_4_6,
|
|
185
|
+
MODEL_GROK_4_7: () => MODEL_GROK_4_7,
|
|
182
186
|
MODEL_INCEPTION_MERCURY_2_5: () => MODEL_INCEPTION_MERCURY_2_5,
|
|
183
187
|
MODEL_INCLUSIONAI_LING_3_0_FLASH_VL_FREE: () => MODEL_INCLUSIONAI_LING_3_0_FLASH_VL_FREE,
|
|
184
188
|
MODEL_KIMI_K2_5: () => MODEL_KIMI_K2_5,
|
|
@@ -353,6 +357,8 @@ var AITuberOnAirChat = (() => {
|
|
|
353
357
|
var ENDPOINT_OPENAI_CHAT_COMPLETIONS_API = "https://api.openai.com/v1/chat/completions";
|
|
354
358
|
var ENDPOINT_OPENAI_RESPONSES_API = "https://api.openai.com/v1/responses";
|
|
355
359
|
var MODEL_GPT_6_ASTRA = "gpt-6-astra";
|
|
360
|
+
var MODEL_GPT_6_SOL = "gpt-6-sol";
|
|
361
|
+
var MODEL_GPT_6_LUNA = "gpt-6-luna";
|
|
356
362
|
var MODEL_GPT_5_NANO = "gpt-5-nano";
|
|
357
363
|
var MODEL_GPT_5_MINI = "gpt-5-mini";
|
|
358
364
|
var MODEL_GPT_5 = "gpt-5";
|
|
@@ -376,6 +382,8 @@ var AITuberOnAirChat = (() => {
|
|
|
376
382
|
var MODEL_O1 = "o1";
|
|
377
383
|
var VISION_SUPPORTED_MODELS = [
|
|
378
384
|
MODEL_GPT_6_ASTRA,
|
|
385
|
+
MODEL_GPT_6_SOL,
|
|
386
|
+
MODEL_GPT_6_LUNA,
|
|
379
387
|
MODEL_GPT_5_NANO,
|
|
380
388
|
MODEL_GPT_5_MINI,
|
|
381
389
|
MODEL_GPT_5,
|
|
@@ -416,19 +424,19 @@ var AITuberOnAirChat = (() => {
|
|
|
416
424
|
return GPT_5_MODELS.includes(model);
|
|
417
425
|
}
|
|
418
426
|
function isOpenAIReasoningModel(model) {
|
|
419
|
-
return model === MODEL_GPT_6_ASTRA || isGPT5Model(model);
|
|
427
|
+
return model === MODEL_GPT_6_ASTRA || model === MODEL_GPT_6_SOL || model === MODEL_GPT_6_LUNA || isGPT5Model(model);
|
|
420
428
|
}
|
|
421
429
|
function isResponsesOnlyGPT5Model(model) {
|
|
422
430
|
return model === MODEL_GPT_5_4_PRO;
|
|
423
431
|
}
|
|
424
432
|
function allowsReasoningXHigh(model) {
|
|
425
|
-
return model === MODEL_GPT_6_ASTRA || model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA || model === MODEL_GPT_5_5 || model === MODEL_GPT_5_4 || model === MODEL_GPT_5_4_MINI || model === MODEL_GPT_5_4_NANO || model === MODEL_GPT_5_4_PRO;
|
|
433
|
+
return model === MODEL_GPT_6_ASTRA || model === MODEL_GPT_6_SOL || model === MODEL_GPT_6_LUNA || model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA || model === MODEL_GPT_5_5 || model === MODEL_GPT_5_4 || model === MODEL_GPT_5_4_MINI || model === MODEL_GPT_5_4_NANO || model === MODEL_GPT_5_4_PRO;
|
|
426
434
|
}
|
|
427
435
|
function allowsReasoningMax(model) {
|
|
428
|
-
return model === MODEL_GPT_6_ASTRA || model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA;
|
|
436
|
+
return model === MODEL_GPT_6_ASTRA || model === MODEL_GPT_6_SOL || model === MODEL_GPT_6_LUNA || model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA;
|
|
429
437
|
}
|
|
430
438
|
function allowsReasoningNone(model) {
|
|
431
|
-
return model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA || model === MODEL_GPT_5_1 || model === MODEL_GPT_5_4 || model === MODEL_GPT_5_5 || model === MODEL_GPT_5_4_MINI || model === MODEL_GPT_5_4_NANO;
|
|
439
|
+
return model === MODEL_GPT_6_SOL || model === MODEL_GPT_6_LUNA || model === MODEL_GPT_5_6 || model === MODEL_GPT_5_6_SOL || model === MODEL_GPT_5_6_TERRA || model === MODEL_GPT_5_6_LUNA || model === MODEL_GPT_5_1 || model === MODEL_GPT_5_4 || model === MODEL_GPT_5_5 || model === MODEL_GPT_5_4_MINI || model === MODEL_GPT_5_4_NANO;
|
|
432
440
|
}
|
|
433
441
|
function allowsReasoningMinimal(model) {
|
|
434
442
|
return model === MODEL_GPT_5_NANO || model === MODEL_GPT_5_MINI || model === MODEL_GPT_5;
|
|
@@ -446,7 +454,7 @@ var AITuberOnAirChat = (() => {
|
|
|
446
454
|
return "medium";
|
|
447
455
|
}
|
|
448
456
|
function getDefaultReasoningEffortForOpenAIModel(model) {
|
|
449
|
-
return model === MODEL_GPT_6_ASTRA ? "low" : getDefaultReasoningEffortForGPT5Model(model);
|
|
457
|
+
return model === MODEL_GPT_6_ASTRA ? "low" : model === MODEL_GPT_6_SOL ? "medium" : model === MODEL_GPT_6_LUNA ? "low" : getDefaultReasoningEffortForGPT5Model(model);
|
|
450
458
|
}
|
|
451
459
|
|
|
452
460
|
// src/constants/gemini.ts
|
|
@@ -561,6 +569,7 @@ var AITuberOnAirChat = (() => {
|
|
|
561
569
|
var MODEL_CLAUDE_5_FABLE = "claude-fable-5";
|
|
562
570
|
var MODEL_CLAUDE_5_SONNET = "claude-sonnet-5";
|
|
563
571
|
var MODEL_CLAUDE_5_OPUS = "claude-opus-5";
|
|
572
|
+
var MODEL_CLAUDE_5_5_OPUS = "claude-opus-5-5";
|
|
564
573
|
var CLAUDE_DEPRECATED_MODELS = [
|
|
565
574
|
MODEL_CLAUDE_3_HAIKU,
|
|
566
575
|
MODEL_CLAUDE_3_5_HAIKU,
|
|
@@ -605,7 +614,8 @@ var AITuberOnAirChat = (() => {
|
|
|
605
614
|
MODEL_CLAUDE_4_8_OPUS,
|
|
606
615
|
MODEL_CLAUDE_5_FABLE,
|
|
607
616
|
MODEL_CLAUDE_5_SONNET,
|
|
608
|
-
MODEL_CLAUDE_5_OPUS
|
|
617
|
+
MODEL_CLAUDE_5_OPUS,
|
|
618
|
+
MODEL_CLAUDE_5_5_OPUS
|
|
609
619
|
];
|
|
610
620
|
function getClaudeSupportedReasoningEfforts(model) {
|
|
611
621
|
return CLAUDE_REASONING_EFFORTS_BY_MODEL[model] ?? [];
|
|
@@ -1054,6 +1064,7 @@ var AITuberOnAirChat = (() => {
|
|
|
1054
1064
|
// src/constants/xai.ts
|
|
1055
1065
|
var ENDPOINT_XAI_CHAT_COMPLETIONS_API = "https://api.x.ai/v1/chat/completions";
|
|
1056
1066
|
var MODEL_GROK_4_6 = "grok-4.6";
|
|
1067
|
+
var MODEL_GROK_4_7 = "grok-4.7";
|
|
1057
1068
|
var MODEL_GROK_4_5 = "grok-4.5";
|
|
1058
1069
|
var MODEL_GROK_4_3 = "grok-4.3";
|
|
1059
1070
|
var MODEL_GROK_4_20_REASONING = "grok-4.20-0309-reasoning";
|
|
@@ -1066,6 +1077,7 @@ var AITuberOnAirChat = (() => {
|
|
|
1066
1077
|
];
|
|
1067
1078
|
var XAI_VISION_SUPPORTED_MODELS = [
|
|
1068
1079
|
MODEL_GROK_4_6,
|
|
1080
|
+
MODEL_GROK_4_7,
|
|
1069
1081
|
MODEL_GROK_4_5,
|
|
1070
1082
|
MODEL_GROK_4_3,
|
|
1071
1083
|
MODEL_GROK_4_20_REASONING,
|
|
@@ -1078,7 +1090,7 @@ var AITuberOnAirChat = (() => {
|
|
|
1078
1090
|
return getXaiSupportedReasoningEfforts(model).length > 0;
|
|
1079
1091
|
}
|
|
1080
1092
|
function getXaiSupportedReasoningEfforts(model) {
|
|
1081
|
-
if (model === MODEL_GROK_4_6) {
|
|
1093
|
+
if (model === MODEL_GROK_4_6 || model === MODEL_GROK_4_7) {
|
|
1082
1094
|
return ["low", "medium", "high", "xhigh"];
|
|
1083
1095
|
}
|
|
1084
1096
|
if (model === MODEL_GROK_4_5) {
|
|
@@ -1093,6 +1105,9 @@ var AITuberOnAirChat = (() => {
|
|
|
1093
1105
|
return getXaiSupportedReasoningEfforts(model).includes("none");
|
|
1094
1106
|
}
|
|
1095
1107
|
function getDefaultXaiReasoningEffort(model) {
|
|
1108
|
+
if (model === MODEL_GROK_4_7) {
|
|
1109
|
+
return "low";
|
|
1110
|
+
}
|
|
1096
1111
|
if (model === MODEL_GROK_4_6 || model === MODEL_GROK_4_5) {
|
|
1097
1112
|
return "low";
|
|
1098
1113
|
}
|
|
@@ -2628,7 +2643,8 @@ If it's in another language, summarize in that language.
|
|
|
2628
2643
|
MODEL_CLAUDE_5_1_FABLE,
|
|
2629
2644
|
MODEL_CLAUDE_5_FABLE,
|
|
2630
2645
|
MODEL_CLAUDE_5_SONNET,
|
|
2631
|
-
MODEL_CLAUDE_5_OPUS
|
|
2646
|
+
MODEL_CLAUDE_5_OPUS,
|
|
2647
|
+
MODEL_CLAUDE_5_5_OPUS
|
|
2632
2648
|
];
|
|
2633
2649
|
}
|
|
2634
2650
|
/**
|
|
@@ -4335,6 +4351,7 @@ If it's in another language, summarize in that language.
|
|
|
4335
4351
|
var GeminiNanoChatService = class {
|
|
4336
4352
|
constructor(options = {}) {
|
|
4337
4353
|
this.provider = "gemini-nano";
|
|
4354
|
+
this.consumedTranscript = [];
|
|
4338
4355
|
this.expectedInputLanguages = options.expectedInputLanguages ?? [
|
|
4339
4356
|
"ja",
|
|
4340
4357
|
"en"
|
|
@@ -4344,6 +4361,7 @@ If it's in another language, summarize in that language.
|
|
|
4344
4361
|
...prompt
|
|
4345
4362
|
}));
|
|
4346
4363
|
this._responseLength = options.responseLength;
|
|
4364
|
+
this.sessionMode = options.sessionMode ?? "stateless";
|
|
4347
4365
|
}
|
|
4348
4366
|
getModel() {
|
|
4349
4367
|
return MODEL_GEMINI_NANO;
|
|
@@ -4351,23 +4369,33 @@ If it's in another language, summarize in that language.
|
|
|
4351
4369
|
getVisionModel() {
|
|
4352
4370
|
return MODEL_GEMINI_NANO;
|
|
4353
4371
|
}
|
|
4372
|
+
/** Destroy any persistent Prompt API sessions held by this service. */
|
|
4373
|
+
dispose() {
|
|
4374
|
+
this.destroyPersistentSessions();
|
|
4375
|
+
}
|
|
4354
4376
|
/**
|
|
4355
4377
|
* Process chat messages using Gemini Nano.
|
|
4356
|
-
*
|
|
4357
|
-
*
|
|
4378
|
+
* Streams response deltas when Chrome exposes promptStreaming(), then calls
|
|
4379
|
+
* onCompleteResponse with the complete response.
|
|
4358
4380
|
*/
|
|
4359
4381
|
async processChat(messages, onPartialResponse, onCompleteResponse) {
|
|
4360
|
-
const response = await this.generateResponse(
|
|
4361
|
-
|
|
4382
|
+
const response = await this.generateResponse(
|
|
4383
|
+
messages,
|
|
4384
|
+
true,
|
|
4385
|
+
onPartialResponse
|
|
4386
|
+
);
|
|
4362
4387
|
await onCompleteResponse(response);
|
|
4363
4388
|
}
|
|
4364
4389
|
async processVisionChat(_messages, _onPartialResponse, _onCompleteResponse) {
|
|
4365
4390
|
throw new Error("Gemini Nano does not support vision capabilities.");
|
|
4366
4391
|
}
|
|
4367
|
-
async chatOnce(messages,
|
|
4392
|
+
async chatOnce(messages, stream = false, onPartialResponse = () => {
|
|
4368
4393
|
}, _maxTokens) {
|
|
4369
|
-
const response = await this.generateResponse(
|
|
4370
|
-
|
|
4394
|
+
const response = await this.generateResponse(
|
|
4395
|
+
messages,
|
|
4396
|
+
stream,
|
|
4397
|
+
onPartialResponse
|
|
4398
|
+
);
|
|
4371
4399
|
return {
|
|
4372
4400
|
blocks: [{ type: "text", text: response }],
|
|
4373
4401
|
stop_reason: "end"
|
|
@@ -4380,7 +4408,7 @@ If it's in another language, summarize in that language.
|
|
|
4380
4408
|
/**
|
|
4381
4409
|
* Core logic: extract system prompt, manage session, call prompt().
|
|
4382
4410
|
*/
|
|
4383
|
-
async generateResponse(messages) {
|
|
4411
|
+
async generateResponse(messages, stream, onPartialResponse) {
|
|
4384
4412
|
const api = getLanguageModelAPI();
|
|
4385
4413
|
if (!api) {
|
|
4386
4414
|
throw new Error(
|
|
@@ -4388,11 +4416,8 @@ If it's in another language, summarize in that language.
|
|
|
4388
4416
|
);
|
|
4389
4417
|
}
|
|
4390
4418
|
const modelOptions = this.getModelOptions();
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
throw new Error(
|
|
4394
|
-
`Gemini Nano Prompt API is not ready in this environment. LanguageModel.availability() returned "${availability}". Expected "available" or "downloadable".`
|
|
4395
|
-
);
|
|
4419
|
+
if (this.sessionMode === "stateless") {
|
|
4420
|
+
await this.ensureAvailability(api, modelOptions);
|
|
4396
4421
|
}
|
|
4397
4422
|
const systemMessages = messages.filter((m) => m.role === "system");
|
|
4398
4423
|
const systemPrompt = systemMessages.map((m) => m.content).join("\n");
|
|
@@ -4402,14 +4427,31 @@ If it's in another language, summarize in that language.
|
|
|
4402
4427
|
throw new Error("No user message found in the provided messages.");
|
|
4403
4428
|
}
|
|
4404
4429
|
const lastUserMessage = conversationMessages[lastUserMessageIndex];
|
|
4430
|
+
const contextHistory = conversationMessages.slice(0, lastUserMessageIndex);
|
|
4431
|
+
if (this.sessionMode === "persistent") {
|
|
4432
|
+
return this.generatePersistentResponse(
|
|
4433
|
+
api,
|
|
4434
|
+
systemPrompt,
|
|
4435
|
+
contextHistory,
|
|
4436
|
+
lastUserMessage.content,
|
|
4437
|
+
modelOptions,
|
|
4438
|
+
stream,
|
|
4439
|
+
onPartialResponse
|
|
4440
|
+
);
|
|
4441
|
+
}
|
|
4405
4442
|
const session = await this.createSession(
|
|
4406
4443
|
api,
|
|
4407
4444
|
systemPrompt,
|
|
4408
|
-
|
|
4445
|
+
contextHistory,
|
|
4409
4446
|
modelOptions
|
|
4410
4447
|
);
|
|
4411
4448
|
try {
|
|
4412
|
-
return await
|
|
4449
|
+
return await this.promptSession(
|
|
4450
|
+
session,
|
|
4451
|
+
lastUserMessage.content,
|
|
4452
|
+
stream,
|
|
4453
|
+
onPartialResponse
|
|
4454
|
+
);
|
|
4413
4455
|
} finally {
|
|
4414
4456
|
try {
|
|
4415
4457
|
session.destroy();
|
|
@@ -4417,6 +4459,241 @@ If it's in another language, summarize in that language.
|
|
|
4417
4459
|
}
|
|
4418
4460
|
}
|
|
4419
4461
|
}
|
|
4462
|
+
async generatePersistentResponse(api, systemPrompt, contextHistory, userPrompt, modelOptions, stream, onPartialResponse) {
|
|
4463
|
+
const sessionKey = this.getPersistentSessionKey(systemPrompt, modelOptions);
|
|
4464
|
+
if (this.persistentSessionKey !== sessionKey) {
|
|
4465
|
+
this.destroyPersistentSessions();
|
|
4466
|
+
}
|
|
4467
|
+
if (!this.baseSession && !this.liveSession) {
|
|
4468
|
+
await this.ensureAvailability(api, modelOptions);
|
|
4469
|
+
await this.createPersistentBaseSession(
|
|
4470
|
+
api,
|
|
4471
|
+
systemPrompt,
|
|
4472
|
+
contextHistory,
|
|
4473
|
+
modelOptions
|
|
4474
|
+
);
|
|
4475
|
+
this.persistentSessionKey = sessionKey;
|
|
4476
|
+
}
|
|
4477
|
+
let session = await this.getPersistentLiveSession(
|
|
4478
|
+
api,
|
|
4479
|
+
systemPrompt,
|
|
4480
|
+
contextHistory,
|
|
4481
|
+
modelOptions
|
|
4482
|
+
);
|
|
4483
|
+
const reusedLiveSession = session === this.liveSession && this.isHistoryCompatible(contextHistory, this.consumedTranscript);
|
|
4484
|
+
this.persistentSessionKey = sessionKey;
|
|
4485
|
+
try {
|
|
4486
|
+
const response = await this.promptSession(
|
|
4487
|
+
session,
|
|
4488
|
+
userPrompt,
|
|
4489
|
+
stream,
|
|
4490
|
+
onPartialResponse
|
|
4491
|
+
);
|
|
4492
|
+
this.recordConsumedTranscript(
|
|
4493
|
+
contextHistory,
|
|
4494
|
+
userPrompt,
|
|
4495
|
+
response,
|
|
4496
|
+
reusedLiveSession
|
|
4497
|
+
);
|
|
4498
|
+
return response;
|
|
4499
|
+
} catch (error) {
|
|
4500
|
+
if (!this.isQuotaExceededError(error)) {
|
|
4501
|
+
this.destroyPersistentLiveSession();
|
|
4502
|
+
throw error;
|
|
4503
|
+
}
|
|
4504
|
+
this.destroyPersistentLiveSession();
|
|
4505
|
+
session = await this.getPersistentLiveSession(
|
|
4506
|
+
api,
|
|
4507
|
+
systemPrompt,
|
|
4508
|
+
[],
|
|
4509
|
+
modelOptions
|
|
4510
|
+
);
|
|
4511
|
+
this.persistentSessionKey = sessionKey;
|
|
4512
|
+
try {
|
|
4513
|
+
const response = await this.promptSession(
|
|
4514
|
+
session,
|
|
4515
|
+
userPrompt,
|
|
4516
|
+
stream,
|
|
4517
|
+
onPartialResponse
|
|
4518
|
+
);
|
|
4519
|
+
this.recordConsumedTranscript([], userPrompt, response, false);
|
|
4520
|
+
return response;
|
|
4521
|
+
} catch (retryError) {
|
|
4522
|
+
this.destroyPersistentLiveSession();
|
|
4523
|
+
throw retryError;
|
|
4524
|
+
}
|
|
4525
|
+
}
|
|
4526
|
+
}
|
|
4527
|
+
async ensureAvailability(api, modelOptions) {
|
|
4528
|
+
const availability = await api.availability(modelOptions);
|
|
4529
|
+
if (availability !== "available" && availability !== "downloadable") {
|
|
4530
|
+
throw new Error(
|
|
4531
|
+
`Gemini Nano Prompt API is not ready in this environment. LanguageModel.availability() returned "${availability}". Expected "available" or "downloadable".`
|
|
4532
|
+
);
|
|
4533
|
+
}
|
|
4534
|
+
}
|
|
4535
|
+
async createPersistentBaseSession(api, systemPrompt, contextHistory, modelOptions) {
|
|
4536
|
+
this.baseSession = await this.createSession(
|
|
4537
|
+
api,
|
|
4538
|
+
systemPrompt,
|
|
4539
|
+
[],
|
|
4540
|
+
modelOptions
|
|
4541
|
+
);
|
|
4542
|
+
if (contextHistory.length > 0) {
|
|
4543
|
+
this.liveSession = await this.createSession(
|
|
4544
|
+
api,
|
|
4545
|
+
systemPrompt,
|
|
4546
|
+
contextHistory,
|
|
4547
|
+
modelOptions
|
|
4548
|
+
);
|
|
4549
|
+
this.consumedTranscript = contextHistory.map((message) => ({
|
|
4550
|
+
...message
|
|
4551
|
+
}));
|
|
4552
|
+
} else if (typeof this.baseSession.clone === "function") {
|
|
4553
|
+
this.liveSession = await this.baseSession.clone();
|
|
4554
|
+
} else {
|
|
4555
|
+
this.liveSession = this.baseSession;
|
|
4556
|
+
}
|
|
4557
|
+
}
|
|
4558
|
+
async getPersistentLiveSession(api, systemPrompt, contextHistory, modelOptions) {
|
|
4559
|
+
if (this.liveSession && this.isHistoryCompatible(contextHistory, this.consumedTranscript)) {
|
|
4560
|
+
return this.liveSession;
|
|
4561
|
+
}
|
|
4562
|
+
if (this.liveSession && this.liveSession !== this.baseSession) {
|
|
4563
|
+
this.destroyPersistentLiveSession();
|
|
4564
|
+
}
|
|
4565
|
+
if (contextHistory.length === 0 && this.baseSession) {
|
|
4566
|
+
if (typeof this.baseSession.clone === "function") {
|
|
4567
|
+
this.liveSession = await this.baseSession.clone();
|
|
4568
|
+
} else {
|
|
4569
|
+
if (this.consumedTranscript.length > 0) {
|
|
4570
|
+
this.destroyPersistentSessions();
|
|
4571
|
+
await this.createPersistentBaseSession(
|
|
4572
|
+
api,
|
|
4573
|
+
systemPrompt,
|
|
4574
|
+
[],
|
|
4575
|
+
modelOptions
|
|
4576
|
+
);
|
|
4577
|
+
return this.liveSession;
|
|
4578
|
+
}
|
|
4579
|
+
this.liveSession = this.baseSession;
|
|
4580
|
+
}
|
|
4581
|
+
return this.liveSession;
|
|
4582
|
+
}
|
|
4583
|
+
if (this.baseSession && typeof this.baseSession.clone === "function") {
|
|
4584
|
+
this.liveSession = await this.createSession(
|
|
4585
|
+
api,
|
|
4586
|
+
systemPrompt,
|
|
4587
|
+
contextHistory,
|
|
4588
|
+
modelOptions
|
|
4589
|
+
);
|
|
4590
|
+
return this.liveSession;
|
|
4591
|
+
}
|
|
4592
|
+
this.destroyPersistentSessions();
|
|
4593
|
+
await this.ensureAvailability(api, modelOptions);
|
|
4594
|
+
await this.createPersistentBaseSessionWithHistory(
|
|
4595
|
+
api,
|
|
4596
|
+
systemPrompt,
|
|
4597
|
+
contextHistory,
|
|
4598
|
+
modelOptions
|
|
4599
|
+
);
|
|
4600
|
+
return this.liveSession;
|
|
4601
|
+
}
|
|
4602
|
+
async createPersistentBaseSessionWithHistory(api, systemPrompt, contextHistory, modelOptions) {
|
|
4603
|
+
this.baseSession = await this.createSession(
|
|
4604
|
+
api,
|
|
4605
|
+
systemPrompt,
|
|
4606
|
+
contextHistory,
|
|
4607
|
+
modelOptions
|
|
4608
|
+
);
|
|
4609
|
+
this.liveSession = this.baseSession;
|
|
4610
|
+
this.consumedTranscript = contextHistory.map((message) => ({
|
|
4611
|
+
...message
|
|
4612
|
+
}));
|
|
4613
|
+
}
|
|
4614
|
+
recordConsumedTranscript(contextHistory, userPrompt, response, reusedLiveSession) {
|
|
4615
|
+
const priorTranscript = reusedLiveSession ? this.consumedTranscript : contextHistory;
|
|
4616
|
+
this.consumedTranscript = [
|
|
4617
|
+
...priorTranscript,
|
|
4618
|
+
{ role: "user", content: userPrompt },
|
|
4619
|
+
{ role: "assistant", content: response }
|
|
4620
|
+
];
|
|
4621
|
+
}
|
|
4622
|
+
getPersistentSessionKey(systemPrompt, modelOptions) {
|
|
4623
|
+
return JSON.stringify({
|
|
4624
|
+
systemPrompt,
|
|
4625
|
+
modelOptions,
|
|
4626
|
+
initialPrompts: this.initialPrompts,
|
|
4627
|
+
responseLength: this._responseLength
|
|
4628
|
+
});
|
|
4629
|
+
}
|
|
4630
|
+
isHistoryCompatible(left, right) {
|
|
4631
|
+
if (left.length === 0 || right.length === 0) {
|
|
4632
|
+
return left.length === 0 && right.length === 0;
|
|
4633
|
+
}
|
|
4634
|
+
return this.isSuffix(left, right) || this.isSuffix(right, left);
|
|
4635
|
+
}
|
|
4636
|
+
isSuffix(candidate, full) {
|
|
4637
|
+
if (candidate.length > full.length) return false;
|
|
4638
|
+
const offset = full.length - candidate.length;
|
|
4639
|
+
return candidate.every(
|
|
4640
|
+
(message, index) => message.role === full[offset + index].role && message.content === full[offset + index].content
|
|
4641
|
+
);
|
|
4642
|
+
}
|
|
4643
|
+
isQuotaExceededError(error) {
|
|
4644
|
+
return typeof error === "object" && error !== null && "name" in error && error.name === "QuotaExceededError";
|
|
4645
|
+
}
|
|
4646
|
+
destroyPersistentLiveSession() {
|
|
4647
|
+
if (this.liveSession) {
|
|
4648
|
+
this.destroySession(this.liveSession);
|
|
4649
|
+
if (this.liveSession === this.baseSession) {
|
|
4650
|
+
this.baseSession = void 0;
|
|
4651
|
+
}
|
|
4652
|
+
}
|
|
4653
|
+
this.liveSession = void 0;
|
|
4654
|
+
this.consumedTranscript = [];
|
|
4655
|
+
}
|
|
4656
|
+
destroyPersistentSessions() {
|
|
4657
|
+
if (this.liveSession && this.liveSession !== this.baseSession) {
|
|
4658
|
+
this.destroySession(this.liveSession);
|
|
4659
|
+
}
|
|
4660
|
+
if (this.baseSession) {
|
|
4661
|
+
this.destroySession(this.baseSession);
|
|
4662
|
+
}
|
|
4663
|
+
this.baseSession = void 0;
|
|
4664
|
+
this.liveSession = void 0;
|
|
4665
|
+
this.persistentSessionKey = void 0;
|
|
4666
|
+
this.consumedTranscript = [];
|
|
4667
|
+
}
|
|
4668
|
+
destroySession(session) {
|
|
4669
|
+
try {
|
|
4670
|
+
session.destroy();
|
|
4671
|
+
} catch {
|
|
4672
|
+
}
|
|
4673
|
+
}
|
|
4674
|
+
async promptSession(session, prompt, stream, onPartialResponse) {
|
|
4675
|
+
if (stream && typeof session.promptStreaming === "function") {
|
|
4676
|
+
const reader = session.promptStreaming(prompt).getReader();
|
|
4677
|
+
let response2 = "";
|
|
4678
|
+
let streamMode = "unknown";
|
|
4679
|
+
while (true) {
|
|
4680
|
+
const { done, value } = await reader.read();
|
|
4681
|
+
if (done) break;
|
|
4682
|
+
const chunk = String(value ?? "");
|
|
4683
|
+
if (streamMode === "unknown" && response2 !== "") {
|
|
4684
|
+
streamMode = chunk.startsWith(response2) ? "cumulative" : "delta";
|
|
4685
|
+
}
|
|
4686
|
+
const isCumulative = streamMode === "cumulative";
|
|
4687
|
+
const delta = isCumulative ? chunk.slice(response2.length) : chunk;
|
|
4688
|
+
response2 = isCumulative ? chunk : response2 + chunk;
|
|
4689
|
+
if (delta) onPartialResponse(delta);
|
|
4690
|
+
}
|
|
4691
|
+
return response2;
|
|
4692
|
+
}
|
|
4693
|
+
const response = await session.prompt(prompt);
|
|
4694
|
+
onPartialResponse(response);
|
|
4695
|
+
return response;
|
|
4696
|
+
}
|
|
4420
4697
|
/**
|
|
4421
4698
|
* Create a new LanguageModel session with structured initial prompts.
|
|
4422
4699
|
* System instructions, few-shot examples, and conversation history retain
|
|
@@ -4511,7 +4788,8 @@ If it's in another language, summarize in that language.
|
|
|
4511
4788
|
expectedInputLanguages: options.expectedInputLanguages,
|
|
4512
4789
|
expectedOutputLanguages: options.expectedOutputLanguages,
|
|
4513
4790
|
initialPrompts: options.initialPrompts,
|
|
4514
|
-
responseLength: options.responseLength
|
|
4791
|
+
responseLength: options.responseLength,
|
|
4792
|
+
sessionMode: options.sessionMode
|
|
4515
4793
|
});
|
|
4516
4794
|
}
|
|
4517
4795
|
getProviderName() {
|
|
@@ -5061,6 +5339,9 @@ If it's in another language, summarize in that language.
|
|
|
5061
5339
|
let shouldUseResponsesAPI = false;
|
|
5062
5340
|
if (mcpServers.length > 0 || modelName === MODEL_GPT_6_ASTRA || visionModel === MODEL_GPT_6_ASTRA) {
|
|
5063
5341
|
shouldUseResponsesAPI = true;
|
|
5342
|
+
} else if (modelName === MODEL_GPT_6_SOL || visionModel === MODEL_GPT_6_SOL || modelName === MODEL_GPT_6_LUNA || visionModel === MODEL_GPT_6_LUNA) {
|
|
5343
|
+
const preference = optimizedOptions.gpt5EndpointPreference || "responses";
|
|
5344
|
+
shouldUseResponsesAPI = preference !== "chat" || optimizedOptions.reasoning_effort !== "none";
|
|
5064
5345
|
} else if (isResponsesOnlyGPT5Model(modelName)) {
|
|
5065
5346
|
shouldUseResponsesAPI = true;
|
|
5066
5347
|
} else if (isOpenAIReasoningModel(modelName)) {
|
|
@@ -5107,6 +5388,8 @@ If it's in another language, summarize in that language.
|
|
|
5107
5388
|
MODEL_GPT_5_5,
|
|
5108
5389
|
MODEL_GPT_5_6,
|
|
5109
5390
|
MODEL_GPT_6_ASTRA,
|
|
5391
|
+
MODEL_GPT_6_SOL,
|
|
5392
|
+
MODEL_GPT_6_LUNA,
|
|
5110
5393
|
MODEL_GPT_5_6_SOL,
|
|
5111
5394
|
MODEL_GPT_5_6_TERRA,
|
|
5112
5395
|
MODEL_GPT_5_6_LUNA,
|
|
@@ -6035,6 +6318,7 @@ If it's in another language, summarize in that language.
|
|
|
6035
6318
|
getSupportedModels() {
|
|
6036
6319
|
return [
|
|
6037
6320
|
MODEL_GROK_4_6,
|
|
6321
|
+
MODEL_GROK_4_7,
|
|
6038
6322
|
MODEL_GROK_4_5,
|
|
6039
6323
|
MODEL_GROK_4_3,
|
|
6040
6324
|
MODEL_GROK_4_20_REASONING,
|
|
@@ -6553,7 +6837,7 @@ If it's in another language, summarize in that language.
|
|
|
6553
6837
|
mcp: MCP_SUPPORTED_PROVIDERS.has(providerName),
|
|
6554
6838
|
jsonMode: JSON_MODE_SUPPORTED_PROVIDERS.has(providerName),
|
|
6555
6839
|
responseLength: true,
|
|
6556
|
-
reasoningEffort: providerName === "openai" && model === MODEL_GPT_6_ASTRA ? ["low", "medium", "high", "xhigh", "max"] : providerName === "claude" && model ? [...getClaudeSupportedReasoningEfforts(model)] : providerName === "gemini" && model ? [...getGeminiSupportedReasoningEfforts(model)] : providerName === "kimi" && model ? [...getKimiSupportedReasoningEfforts(model)] : providerName === "deepseek" && model ? [...getDeepSeekSupportedReasoningEfforts(model)] : providerName === "openrouter" && model ? [...getOpenRouterSupportedReasoningEfforts(model)] : providerName === "xai" && model ? [...getXaiSupportedReasoningEfforts(model)] : providerName === "zai" && model ? [...getZaiSupportedReasoningEfforts(model)] : REASONING_EFFORT_BY_PROVIDER[providerName] ?? []
|
|
6840
|
+
reasoningEffort: providerName === "openai" && model === MODEL_GPT_6_ASTRA ? ["low", "medium", "high", "xhigh", "max"] : providerName === "openai" && model === MODEL_GPT_6_SOL ? ["none", "low", "medium", "high", "xhigh", "max"] : providerName === "openai" && model === MODEL_GPT_6_LUNA ? ["none", "low", "medium", "high", "xhigh", "max"] : providerName === "claude" && model ? [...getClaudeSupportedReasoningEfforts(model)] : providerName === "gemini" && model ? [...getGeminiSupportedReasoningEfforts(model)] : providerName === "kimi" && model ? [...getKimiSupportedReasoningEfforts(model)] : providerName === "deepseek" && model ? [...getDeepSeekSupportedReasoningEfforts(model)] : providerName === "openrouter" && model ? [...getOpenRouterSupportedReasoningEfforts(model)] : providerName === "xai" && model ? [...getXaiSupportedReasoningEfforts(model)] : providerName === "zai" && model ? [...getZaiSupportedReasoningEfforts(model)] : REASONING_EFFORT_BY_PROVIDER[providerName] ?? []
|
|
6557
6841
|
};
|
|
6558
6842
|
}
|
|
6559
6843
|
/**
|