@aituber-onair/chat 0.16.0 → 0.18.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 +31 -2
- package/README.md +30 -2
- package/dist/cjs/constants/gemini.d.ts +1 -0
- package/dist/cjs/constants/gemini.d.ts.map +1 -1
- package/dist/cjs/constants/gemini.js +3 -1
- package/dist/cjs/constants/gemini.js.map +1 -1
- package/dist/cjs/constants/openrouter.js +1 -1
- package/dist/cjs/constants/openrouter.js.map +1 -1
- package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.js +1 -0
- package/dist/cjs/services/providers/gemini/GeminiChatServiceProvider.js.map +1 -1
- package/dist/cjs/services/providers/openrouter/OpenRouterChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/openrouter/OpenRouterChatServiceProvider.js +1 -1
- package/dist/cjs/services/providers/openrouter/OpenRouterChatServiceProvider.js.map +1 -1
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +1 -0
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/refreshOpenRouterFreeModels.d.ts +25 -0
- package/dist/cjs/utils/refreshOpenRouterFreeModels.d.ts.map +1 -0
- package/dist/cjs/utils/refreshOpenRouterFreeModels.js +207 -0
- package/dist/cjs/utils/refreshOpenRouterFreeModels.js.map +1 -0
- package/dist/esm/constants/gemini.d.ts +1 -0
- package/dist/esm/constants/gemini.d.ts.map +1 -1
- package/dist/esm/constants/gemini.js +2 -0
- package/dist/esm/constants/gemini.js.map +1 -1
- package/dist/esm/constants/openrouter.js +1 -1
- package/dist/esm/constants/openrouter.js.map +1 -1
- package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.js +2 -1
- package/dist/esm/services/providers/gemini/GeminiChatServiceProvider.js.map +1 -1
- package/dist/esm/services/providers/openrouter/OpenRouterChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/openrouter/OpenRouterChatServiceProvider.js +2 -2
- package/dist/esm/services/providers/openrouter/OpenRouterChatServiceProvider.js.map +1 -1
- package/dist/esm/utils/index.d.ts +1 -0
- package/dist/esm/utils/index.d.ts.map +1 -1
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/refreshOpenRouterFreeModels.d.ts +25 -0
- package/dist/esm/utils/refreshOpenRouterFreeModels.d.ts.map +1 -0
- package/dist/esm/utils/refreshOpenRouterFreeModels.js +204 -0
- package/dist/esm/utils/refreshOpenRouterFreeModels.js.map +1 -0
- package/dist/umd/aituber-onair-chat.js +213 -2
- package/dist/umd/aituber-onair-chat.min.js +6 -6
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MODEL_GPT_OSS_20B_FREE, MODEL_MOONSHOTAI_KIMI_K2_5, MODEL_OPENAI_GPT_5_1_CHAT, MODEL_OPENAI_GPT_5_1_CODEX, MODEL_OPENAI_GPT_5_MINI, MODEL_OPENAI_GPT_5_NANO, MODEL_OPENAI_GPT_4O, MODEL_OPENAI_GPT_4_1_MINI, MODEL_OPENAI_GPT_4_1_NANO, MODEL_ANTHROPIC_CLAUDE_OPUS_4, MODEL_ANTHROPIC_CLAUDE_SONNET_4, MODEL_ANTHROPIC_CLAUDE_3_7_SONNET, MODEL_ANTHROPIC_CLAUDE_3_5_SONNET, MODEL_ANTHROPIC_CLAUDE_4_5_HAIKU, MODEL_GOOGLE_GEMINI_2_5_PRO, MODEL_GOOGLE_GEMINI_2_5_FLASH, MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE_PREVIEW_09_2025, MODEL_ZAI_GLM_4_7_FLASH, MODEL_ZAI_GLM_4_5_AIR, MODEL_ZAI_GLM_4_5_AIR_FREE, OPENROUTER_FREE_MODELS, isOpenRouterVisionModel, } from '../../../constants/openrouter';
|
|
1
|
+
import { MODEL_GPT_OSS_20B_FREE, MODEL_MOONSHOTAI_KIMI_K2_5, MODEL_OPENAI_GPT_5_1_CHAT, MODEL_OPENAI_GPT_5_1_CODEX, MODEL_OPENAI_GPT_5_MINI, MODEL_OPENAI_GPT_5_NANO, MODEL_OPENAI_GPT_4O, MODEL_OPENAI_GPT_4_1_MINI, MODEL_OPENAI_GPT_4_1_NANO, MODEL_ANTHROPIC_CLAUDE_OPUS_4, MODEL_ANTHROPIC_CLAUDE_SONNET_4, MODEL_ANTHROPIC_CLAUDE_3_7_SONNET, MODEL_ANTHROPIC_CLAUDE_3_5_SONNET, MODEL_ANTHROPIC_CLAUDE_4_5_HAIKU, MODEL_GOOGLE_GEMINI_2_5_PRO, MODEL_GOOGLE_GEMINI_2_5_FLASH, MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE_PREVIEW_09_2025, MODEL_ZAI_GLM_4_7_FLASH, MODEL_ZAI_GLM_4_5_AIR, MODEL_ZAI_GLM_4_5_AIR_FREE, OPENROUTER_FREE_MODELS, isOpenRouterFreeModel, isOpenRouterVisionModel, } from '../../../constants/openrouter';
|
|
2
2
|
import { OpenRouterChatService } from './OpenRouterChatService';
|
|
3
3
|
import { resolveVisionModel } from '../../../utils';
|
|
4
4
|
/**
|
|
@@ -106,7 +106,7 @@ export class OpenRouterChatServiceProvider {
|
|
|
106
106
|
* @returns True if the model is free
|
|
107
107
|
*/
|
|
108
108
|
isModelFree(model) {
|
|
109
|
-
return
|
|
109
|
+
return isOpenRouterFreeModel(model);
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
//# sourceMappingURL=OpenRouterChatServiceProvider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenRouterChatServiceProvider.js","sourceRoot":"","sources":["../../../../../src/services/providers/openrouter/OpenRouterChatServiceProvider.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"OpenRouterChatServiceProvider.js","sourceRoot":"","sources":["../../../../../src/services/providers/openrouter/OpenRouterChatServiceProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC"}
|
package/dist/esm/utils/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface RefreshOpenRouterFreeModelsOptions {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
endpoint?: string;
|
|
4
|
+
modelsEndpoint?: string;
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
concurrency?: number;
|
|
7
|
+
maxCandidates?: number;
|
|
8
|
+
maxWorking?: number;
|
|
9
|
+
appName?: string;
|
|
10
|
+
appUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface RefreshOpenRouterFreeModelsFailure {
|
|
13
|
+
id: string;
|
|
14
|
+
reason: string;
|
|
15
|
+
}
|
|
16
|
+
export interface RefreshOpenRouterFreeModelsResult {
|
|
17
|
+
working: string[];
|
|
18
|
+
failed: RefreshOpenRouterFreeModelsFailure[];
|
|
19
|
+
fetchedAt: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Fetch currently available OpenRouter free models and probe each model.
|
|
23
|
+
*/
|
|
24
|
+
export declare function refreshOpenRouterFreeModels(options: RefreshOpenRouterFreeModelsOptions): Promise<RefreshOpenRouterFreeModelsResult>;
|
|
25
|
+
//# sourceMappingURL=refreshOpenRouterFreeModels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refreshOpenRouterFreeModels.d.ts","sourceRoot":"","sources":["../../../src/utils/refreshOpenRouterFreeModels.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,kCAAkC;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kCAAkC;IACjD,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iCAAiC;IAChD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,kCAAkC,EAAE,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;CACnB;AA6MD;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,kCAAkC,GAC1C,OAAO,CAAC,iCAAiC,CAAC,CAoE5C"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { ENDPOINT_OPENROUTER_API, isOpenRouterFreeModel, } from '../constants/openrouter';
|
|
2
|
+
const OPENROUTER_MODELS_ENDPOINT = 'https://openrouter.ai/api/v1/models';
|
|
3
|
+
const DEFAULT_CONCURRENCY = 2;
|
|
4
|
+
const DEFAULT_TIMEOUT_MS = 12000;
|
|
5
|
+
const DEFAULT_MAX_CANDIDATES = 1;
|
|
6
|
+
const DEFAULT_MAX_WORKING = 10;
|
|
7
|
+
function toErrorMessage(error) {
|
|
8
|
+
if (error instanceof Error) {
|
|
9
|
+
return error.message;
|
|
10
|
+
}
|
|
11
|
+
return String(error);
|
|
12
|
+
}
|
|
13
|
+
function normalizeLimit(value, fallback) {
|
|
14
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
15
|
+
return fallback;
|
|
16
|
+
}
|
|
17
|
+
return Math.max(1, Math.floor(value));
|
|
18
|
+
}
|
|
19
|
+
function normalizeModelIds(modelIds) {
|
|
20
|
+
const seen = new Set();
|
|
21
|
+
const normalized = [];
|
|
22
|
+
for (const modelId of modelIds) {
|
|
23
|
+
const trimmed = modelId.trim();
|
|
24
|
+
if (!trimmed || seen.has(trimmed)) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
seen.add(trimmed);
|
|
28
|
+
normalized.push(trimmed);
|
|
29
|
+
}
|
|
30
|
+
return normalized;
|
|
31
|
+
}
|
|
32
|
+
async function fetchWithTimeout(url, init, timeoutMs) {
|
|
33
|
+
const hasAbortController = typeof AbortController !== 'undefined';
|
|
34
|
+
if (!hasAbortController) {
|
|
35
|
+
return fetch(url, init);
|
|
36
|
+
}
|
|
37
|
+
const controller = new AbortController();
|
|
38
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
39
|
+
try {
|
|
40
|
+
return await fetch(url, {
|
|
41
|
+
...init,
|
|
42
|
+
signal: controller.signal,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
47
|
+
throw new Error(`Timeout after ${timeoutMs}ms`);
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
clearTimeout(timeoutId);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function toHttpFailureReason(response) {
|
|
56
|
+
const status = `HTTP ${response.status} ${response.statusText}`.trim();
|
|
57
|
+
let body = '';
|
|
58
|
+
try {
|
|
59
|
+
body = await response.text();
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return status;
|
|
63
|
+
}
|
|
64
|
+
const compactBody = body.replace(/\s+/g, ' ').trim().slice(0, 200);
|
|
65
|
+
if (!compactBody) {
|
|
66
|
+
return status;
|
|
67
|
+
}
|
|
68
|
+
return `${status}: ${compactBody}`;
|
|
69
|
+
}
|
|
70
|
+
function extractModelIds(payload) {
|
|
71
|
+
if (!payload || typeof payload !== 'object') {
|
|
72
|
+
throw new Error('Invalid models response shape');
|
|
73
|
+
}
|
|
74
|
+
const response = payload;
|
|
75
|
+
const modelEntries = Array.isArray(response.data)
|
|
76
|
+
? response.data
|
|
77
|
+
: Array.isArray(response.models)
|
|
78
|
+
? response.models
|
|
79
|
+
: [];
|
|
80
|
+
if (modelEntries.length === 0) {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
const modelIds = modelEntries
|
|
84
|
+
.map((entry) => entry.id)
|
|
85
|
+
.filter((id) => typeof id === 'string');
|
|
86
|
+
return normalizeModelIds(modelIds);
|
|
87
|
+
}
|
|
88
|
+
async function probeModel({ modelId, apiKey, endpoint, timeoutMs, appName, appUrl, }) {
|
|
89
|
+
const headers = {
|
|
90
|
+
Authorization: `Bearer ${apiKey}`,
|
|
91
|
+
'Content-Type': 'application/json',
|
|
92
|
+
};
|
|
93
|
+
if (appName) {
|
|
94
|
+
headers['X-Title'] = appName;
|
|
95
|
+
}
|
|
96
|
+
if (appUrl) {
|
|
97
|
+
headers['HTTP-Referer'] = appUrl;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const response = await fetchWithTimeout(endpoint, {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
headers,
|
|
103
|
+
body: JSON.stringify({
|
|
104
|
+
model: modelId,
|
|
105
|
+
messages: [{ role: 'user', content: 'Reply only with OK.' }],
|
|
106
|
+
stream: false,
|
|
107
|
+
}),
|
|
108
|
+
}, timeoutMs);
|
|
109
|
+
if (!response.ok) {
|
|
110
|
+
return {
|
|
111
|
+
id: modelId,
|
|
112
|
+
ok: false,
|
|
113
|
+
reason: await toHttpFailureReason(response),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
await response.json();
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
return {
|
|
121
|
+
id: modelId,
|
|
122
|
+
ok: false,
|
|
123
|
+
reason: `JSON parse failed: ${toErrorMessage(error)}`,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return { id: modelId, ok: true };
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
return {
|
|
130
|
+
id: modelId,
|
|
131
|
+
ok: false,
|
|
132
|
+
reason: toErrorMessage(error),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async function runWithConcurrency(items, concurrency, worker) {
|
|
137
|
+
if (items.length === 0) {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
const results = new Array(items.length);
|
|
141
|
+
let nextIndex = 0;
|
|
142
|
+
const workerCount = Math.min(concurrency, items.length);
|
|
143
|
+
await Promise.all(Array.from({ length: workerCount }, async () => {
|
|
144
|
+
while (nextIndex < items.length) {
|
|
145
|
+
const current = nextIndex;
|
|
146
|
+
nextIndex += 1;
|
|
147
|
+
results[current] = await worker(items[current]);
|
|
148
|
+
}
|
|
149
|
+
}));
|
|
150
|
+
return results;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Fetch currently available OpenRouter free models and probe each model.
|
|
154
|
+
*/
|
|
155
|
+
export async function refreshOpenRouterFreeModels(options) {
|
|
156
|
+
const apiKey = options.apiKey.trim();
|
|
157
|
+
if (!apiKey) {
|
|
158
|
+
throw new Error('OpenRouter API key is required.');
|
|
159
|
+
}
|
|
160
|
+
const modelsEndpoint = options.modelsEndpoint || OPENROUTER_MODELS_ENDPOINT;
|
|
161
|
+
const endpoint = options.endpoint || ENDPOINT_OPENROUTER_API;
|
|
162
|
+
const timeoutMs = normalizeLimit(options.timeoutMs, DEFAULT_TIMEOUT_MS);
|
|
163
|
+
const concurrency = normalizeLimit(options.concurrency, DEFAULT_CONCURRENCY);
|
|
164
|
+
const maxCandidates = normalizeLimit(options.maxCandidates, DEFAULT_MAX_CANDIDATES);
|
|
165
|
+
const maxWorking = normalizeLimit(options.maxWorking, DEFAULT_MAX_WORKING);
|
|
166
|
+
const modelsResponse = await fetchWithTimeout(modelsEndpoint, { method: 'GET' }, timeoutMs);
|
|
167
|
+
if (!modelsResponse.ok) {
|
|
168
|
+
throw new Error(await toHttpFailureReason(modelsResponse));
|
|
169
|
+
}
|
|
170
|
+
let payload;
|
|
171
|
+
try {
|
|
172
|
+
payload = await modelsResponse.json();
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
throw new Error(`JSON parse failed: ${toErrorMessage(error)}`);
|
|
176
|
+
}
|
|
177
|
+
const candidateModelIds = extractModelIds(payload)
|
|
178
|
+
.filter((modelId) => isOpenRouterFreeModel(modelId))
|
|
179
|
+
.slice(0, maxCandidates);
|
|
180
|
+
const probeResults = await runWithConcurrency(candidateModelIds, concurrency, (modelId) => probeModel({
|
|
181
|
+
modelId,
|
|
182
|
+
apiKey,
|
|
183
|
+
endpoint,
|
|
184
|
+
timeoutMs,
|
|
185
|
+
appName: options.appName,
|
|
186
|
+
appUrl: options.appUrl,
|
|
187
|
+
}));
|
|
188
|
+
const working = probeResults
|
|
189
|
+
.filter((result) => result.ok)
|
|
190
|
+
.map((result) => result.id)
|
|
191
|
+
.slice(0, maxWorking);
|
|
192
|
+
const failed = probeResults
|
|
193
|
+
.filter((result) => !result.ok)
|
|
194
|
+
.map((result) => ({
|
|
195
|
+
id: result.id,
|
|
196
|
+
reason: result.reason || 'Unknown error',
|
|
197
|
+
}));
|
|
198
|
+
return {
|
|
199
|
+
working,
|
|
200
|
+
failed,
|
|
201
|
+
fetchedAt: Date.now(),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=refreshOpenRouterFreeModels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refreshOpenRouterFreeModels.js","sourceRoot":"","sources":["../../../src/utils/refreshOpenRouterFreeModels.ts"],"names":[],"mappings":"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"}
|
|
@@ -72,6 +72,7 @@ var AITuberOnAirChat = (() => {
|
|
|
72
72
|
MODEL_GEMINI_2_5_FLASH_LITE: () => MODEL_GEMINI_2_5_FLASH_LITE,
|
|
73
73
|
MODEL_GEMINI_2_5_FLASH_LITE_PREVIEW_06_17: () => MODEL_GEMINI_2_5_FLASH_LITE_PREVIEW_06_17,
|
|
74
74
|
MODEL_GEMINI_2_5_PRO: () => MODEL_GEMINI_2_5_PRO,
|
|
75
|
+
MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW: () => MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW,
|
|
75
76
|
MODEL_GEMINI_3_1_PRO_PREVIEW: () => MODEL_GEMINI_3_1_PRO_PREVIEW,
|
|
76
77
|
MODEL_GEMINI_3_FLASH_PREVIEW: () => MODEL_GEMINI_3_FLASH_PREVIEW,
|
|
77
78
|
MODEL_GEMINI_3_PRO_PREVIEW: () => MODEL_GEMINI_3_PRO_PREVIEW,
|
|
@@ -142,6 +143,7 @@ var AITuberOnAirChat = (() => {
|
|
|
142
143
|
parseOpenAICompatibleTextStream: () => parseOpenAICompatibleTextStream,
|
|
143
144
|
parseOpenAICompatibleToolStream: () => parseOpenAICompatibleToolStream,
|
|
144
145
|
processChatWithOptionalTools: () => processChatWithOptionalTools,
|
|
146
|
+
refreshOpenRouterFreeModels: () => refreshOpenRouterFreeModels,
|
|
145
147
|
resolveVisionModel: () => resolveVisionModel,
|
|
146
148
|
runOnceText: () => runOnceText,
|
|
147
149
|
screenplayToText: () => screenplayToText,
|
|
@@ -196,6 +198,7 @@ var AITuberOnAirChat = (() => {
|
|
|
196
198
|
// src/constants/gemini.ts
|
|
197
199
|
var ENDPOINT_GEMINI_API = "https://generativelanguage.googleapis.com";
|
|
198
200
|
var MODEL_GEMINI_3_1_PRO_PREVIEW = "gemini-3.1-pro-preview";
|
|
201
|
+
var MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW = "gemini-3.1-flash-lite-preview";
|
|
199
202
|
var MODEL_GEMINI_3_PRO_PREVIEW = "gemini-3-pro-preview";
|
|
200
203
|
var MODEL_GEMINI_3_FLASH_PREVIEW = "gemini-3-flash-preview";
|
|
201
204
|
var MODEL_GEMINI_2_5_PRO = "gemini-2.5-pro";
|
|
@@ -206,6 +209,7 @@ var AITuberOnAirChat = (() => {
|
|
|
206
209
|
var MODEL_GEMINI_2_0_FLASH_LITE = "gemini-2.0-flash-lite";
|
|
207
210
|
var GEMINI_VISION_SUPPORTED_MODELS = [
|
|
208
211
|
MODEL_GEMINI_3_1_PRO_PREVIEW,
|
|
212
|
+
MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW,
|
|
209
213
|
MODEL_GEMINI_3_PRO_PREVIEW,
|
|
210
214
|
MODEL_GEMINI_3_FLASH_PREVIEW,
|
|
211
215
|
MODEL_GEMINI_2_5_PRO,
|
|
@@ -291,7 +295,7 @@ var AITuberOnAirChat = (() => {
|
|
|
291
295
|
var OPENROUTER_FREE_DAILY_LIMIT_HIGH_CREDITS = 1e3;
|
|
292
296
|
var OPENROUTER_CREDITS_THRESHOLD = 10;
|
|
293
297
|
function isOpenRouterFreeModel(model) {
|
|
294
|
-
return
|
|
298
|
+
return model.trim().endsWith(":free");
|
|
295
299
|
}
|
|
296
300
|
function isOpenRouterVisionModel(model) {
|
|
297
301
|
return OPENROUTER_VISION_SUPPORTED_MODELS.some(
|
|
@@ -792,6 +796,212 @@ If it's in another language, summarize in that language.
|
|
|
792
796
|
return resolved;
|
|
793
797
|
};
|
|
794
798
|
|
|
799
|
+
// src/utils/refreshOpenRouterFreeModels.ts
|
|
800
|
+
var OPENROUTER_MODELS_ENDPOINT = "https://openrouter.ai/api/v1/models";
|
|
801
|
+
var DEFAULT_CONCURRENCY = 2;
|
|
802
|
+
var DEFAULT_TIMEOUT_MS = 12e3;
|
|
803
|
+
var DEFAULT_MAX_CANDIDATES = 1;
|
|
804
|
+
var DEFAULT_MAX_WORKING = 10;
|
|
805
|
+
function toErrorMessage(error) {
|
|
806
|
+
if (error instanceof Error) {
|
|
807
|
+
return error.message;
|
|
808
|
+
}
|
|
809
|
+
return String(error);
|
|
810
|
+
}
|
|
811
|
+
function normalizeLimit(value, fallback) {
|
|
812
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
813
|
+
return fallback;
|
|
814
|
+
}
|
|
815
|
+
return Math.max(1, Math.floor(value));
|
|
816
|
+
}
|
|
817
|
+
function normalizeModelIds(modelIds) {
|
|
818
|
+
const seen = /* @__PURE__ */ new Set();
|
|
819
|
+
const normalized = [];
|
|
820
|
+
for (const modelId of modelIds) {
|
|
821
|
+
const trimmed = modelId.trim();
|
|
822
|
+
if (!trimmed || seen.has(trimmed)) {
|
|
823
|
+
continue;
|
|
824
|
+
}
|
|
825
|
+
seen.add(trimmed);
|
|
826
|
+
normalized.push(trimmed);
|
|
827
|
+
}
|
|
828
|
+
return normalized;
|
|
829
|
+
}
|
|
830
|
+
async function fetchWithTimeout(url, init, timeoutMs) {
|
|
831
|
+
const hasAbortController = typeof AbortController !== "undefined";
|
|
832
|
+
if (!hasAbortController) {
|
|
833
|
+
return fetch(url, init);
|
|
834
|
+
}
|
|
835
|
+
const controller = new AbortController();
|
|
836
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
837
|
+
try {
|
|
838
|
+
return await fetch(url, {
|
|
839
|
+
...init,
|
|
840
|
+
signal: controller.signal
|
|
841
|
+
});
|
|
842
|
+
} catch (error) {
|
|
843
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
844
|
+
throw new Error(`Timeout after ${timeoutMs}ms`);
|
|
845
|
+
}
|
|
846
|
+
throw error;
|
|
847
|
+
} finally {
|
|
848
|
+
clearTimeout(timeoutId);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
async function toHttpFailureReason(response) {
|
|
852
|
+
const status = `HTTP ${response.status} ${response.statusText}`.trim();
|
|
853
|
+
let body = "";
|
|
854
|
+
try {
|
|
855
|
+
body = await response.text();
|
|
856
|
+
} catch {
|
|
857
|
+
return status;
|
|
858
|
+
}
|
|
859
|
+
const compactBody = body.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
860
|
+
if (!compactBody) {
|
|
861
|
+
return status;
|
|
862
|
+
}
|
|
863
|
+
return `${status}: ${compactBody}`;
|
|
864
|
+
}
|
|
865
|
+
function extractModelIds(payload) {
|
|
866
|
+
if (!payload || typeof payload !== "object") {
|
|
867
|
+
throw new Error("Invalid models response shape");
|
|
868
|
+
}
|
|
869
|
+
const response = payload;
|
|
870
|
+
const modelEntries = Array.isArray(response.data) ? response.data : Array.isArray(response.models) ? response.models : [];
|
|
871
|
+
if (modelEntries.length === 0) {
|
|
872
|
+
return [];
|
|
873
|
+
}
|
|
874
|
+
const modelIds = modelEntries.map((entry) => entry.id).filter((id) => typeof id === "string");
|
|
875
|
+
return normalizeModelIds(modelIds);
|
|
876
|
+
}
|
|
877
|
+
async function probeModel({
|
|
878
|
+
modelId,
|
|
879
|
+
apiKey,
|
|
880
|
+
endpoint,
|
|
881
|
+
timeoutMs,
|
|
882
|
+
appName,
|
|
883
|
+
appUrl
|
|
884
|
+
}) {
|
|
885
|
+
const headers = {
|
|
886
|
+
Authorization: `Bearer ${apiKey}`,
|
|
887
|
+
"Content-Type": "application/json"
|
|
888
|
+
};
|
|
889
|
+
if (appName) {
|
|
890
|
+
headers["X-Title"] = appName;
|
|
891
|
+
}
|
|
892
|
+
if (appUrl) {
|
|
893
|
+
headers["HTTP-Referer"] = appUrl;
|
|
894
|
+
}
|
|
895
|
+
try {
|
|
896
|
+
const response = await fetchWithTimeout(
|
|
897
|
+
endpoint,
|
|
898
|
+
{
|
|
899
|
+
method: "POST",
|
|
900
|
+
headers,
|
|
901
|
+
body: JSON.stringify({
|
|
902
|
+
model: modelId,
|
|
903
|
+
messages: [{ role: "user", content: "Reply only with OK." }],
|
|
904
|
+
stream: false
|
|
905
|
+
})
|
|
906
|
+
},
|
|
907
|
+
timeoutMs
|
|
908
|
+
);
|
|
909
|
+
if (!response.ok) {
|
|
910
|
+
return {
|
|
911
|
+
id: modelId,
|
|
912
|
+
ok: false,
|
|
913
|
+
reason: await toHttpFailureReason(response)
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
try {
|
|
917
|
+
await response.json();
|
|
918
|
+
} catch (error) {
|
|
919
|
+
return {
|
|
920
|
+
id: modelId,
|
|
921
|
+
ok: false,
|
|
922
|
+
reason: `JSON parse failed: ${toErrorMessage(error)}`
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
return { id: modelId, ok: true };
|
|
926
|
+
} catch (error) {
|
|
927
|
+
return {
|
|
928
|
+
id: modelId,
|
|
929
|
+
ok: false,
|
|
930
|
+
reason: toErrorMessage(error)
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
async function runWithConcurrency(items, concurrency, worker) {
|
|
935
|
+
if (items.length === 0) {
|
|
936
|
+
return [];
|
|
937
|
+
}
|
|
938
|
+
const results = new Array(items.length);
|
|
939
|
+
let nextIndex = 0;
|
|
940
|
+
const workerCount = Math.min(concurrency, items.length);
|
|
941
|
+
await Promise.all(
|
|
942
|
+
Array.from({ length: workerCount }, async () => {
|
|
943
|
+
while (nextIndex < items.length) {
|
|
944
|
+
const current = nextIndex;
|
|
945
|
+
nextIndex += 1;
|
|
946
|
+
results[current] = await worker(items[current]);
|
|
947
|
+
}
|
|
948
|
+
})
|
|
949
|
+
);
|
|
950
|
+
return results;
|
|
951
|
+
}
|
|
952
|
+
async function refreshOpenRouterFreeModels(options) {
|
|
953
|
+
const apiKey = options.apiKey.trim();
|
|
954
|
+
if (!apiKey) {
|
|
955
|
+
throw new Error("OpenRouter API key is required.");
|
|
956
|
+
}
|
|
957
|
+
const modelsEndpoint = options.modelsEndpoint || OPENROUTER_MODELS_ENDPOINT;
|
|
958
|
+
const endpoint = options.endpoint || ENDPOINT_OPENROUTER_API;
|
|
959
|
+
const timeoutMs = normalizeLimit(options.timeoutMs, DEFAULT_TIMEOUT_MS);
|
|
960
|
+
const concurrency = normalizeLimit(options.concurrency, DEFAULT_CONCURRENCY);
|
|
961
|
+
const maxCandidates = normalizeLimit(
|
|
962
|
+
options.maxCandidates,
|
|
963
|
+
DEFAULT_MAX_CANDIDATES
|
|
964
|
+
);
|
|
965
|
+
const maxWorking = normalizeLimit(options.maxWorking, DEFAULT_MAX_WORKING);
|
|
966
|
+
const modelsResponse = await fetchWithTimeout(
|
|
967
|
+
modelsEndpoint,
|
|
968
|
+
{ method: "GET" },
|
|
969
|
+
timeoutMs
|
|
970
|
+
);
|
|
971
|
+
if (!modelsResponse.ok) {
|
|
972
|
+
throw new Error(await toHttpFailureReason(modelsResponse));
|
|
973
|
+
}
|
|
974
|
+
let payload;
|
|
975
|
+
try {
|
|
976
|
+
payload = await modelsResponse.json();
|
|
977
|
+
} catch (error) {
|
|
978
|
+
throw new Error(`JSON parse failed: ${toErrorMessage(error)}`);
|
|
979
|
+
}
|
|
980
|
+
const candidateModelIds = extractModelIds(payload).filter((modelId) => isOpenRouterFreeModel(modelId)).slice(0, maxCandidates);
|
|
981
|
+
const probeResults = await runWithConcurrency(
|
|
982
|
+
candidateModelIds,
|
|
983
|
+
concurrency,
|
|
984
|
+
(modelId) => probeModel({
|
|
985
|
+
modelId,
|
|
986
|
+
apiKey,
|
|
987
|
+
endpoint,
|
|
988
|
+
timeoutMs,
|
|
989
|
+
appName: options.appName,
|
|
990
|
+
appUrl: options.appUrl
|
|
991
|
+
})
|
|
992
|
+
);
|
|
993
|
+
const working = probeResults.filter((result) => result.ok).map((result) => result.id).slice(0, maxWorking);
|
|
994
|
+
const failed = probeResults.filter((result) => !result.ok).map((result) => ({
|
|
995
|
+
id: result.id,
|
|
996
|
+
reason: result.reason || "Unknown error"
|
|
997
|
+
}));
|
|
998
|
+
return {
|
|
999
|
+
working,
|
|
1000
|
+
failed,
|
|
1001
|
+
fetchedAt: Date.now()
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
|
|
795
1005
|
// src/services/providers/claude/ClaudeChatService.ts
|
|
796
1006
|
var ClaudeChatService = class {
|
|
797
1007
|
/**
|
|
@@ -2038,6 +2248,7 @@ If it's in another language, summarize in that language.
|
|
|
2038
2248
|
getSupportedModels() {
|
|
2039
2249
|
return [
|
|
2040
2250
|
MODEL_GEMINI_3_1_PRO_PREVIEW,
|
|
2251
|
+
MODEL_GEMINI_3_1_FLASH_LITE_PREVIEW,
|
|
2041
2252
|
MODEL_GEMINI_3_PRO_PREVIEW,
|
|
2042
2253
|
MODEL_GEMINI_3_FLASH_PREVIEW,
|
|
2043
2254
|
MODEL_GEMINI_2_5_PRO,
|
|
@@ -3358,7 +3569,7 @@ If it's in another language, summarize in that language.
|
|
|
3358
3569
|
* @returns True if the model is free
|
|
3359
3570
|
*/
|
|
3360
3571
|
isModelFree(model) {
|
|
3361
|
-
return
|
|
3572
|
+
return isOpenRouterFreeModel(model);
|
|
3362
3573
|
}
|
|
3363
3574
|
};
|
|
3364
3575
|
|