@aituber-onair/chat 0.15.0 → 0.17.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 +29 -0
- package/README.md +28 -0
- package/dist/cjs/constants/openai.d.ts +0 -1
- package/dist/cjs/constants/openai.d.ts.map +1 -1
- package/dist/cjs/constants/openai.js +1 -4
- package/dist/cjs/constants/openai.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/openai/OpenAIChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.js +0 -1
- package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.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/openai.d.ts +0 -1
- package/dist/esm/constants/openai.d.ts.map +1 -1
- package/dist/esm/constants/openai.js +0 -3
- package/dist/esm/constants/openai.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/openai/OpenAIChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.js +1 -2
- package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.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 +210 -7
- 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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"}
|
|
@@ -91,7 +91,6 @@ var AITuberOnAirChat = (() => {
|
|
|
91
91
|
MODEL_GPT_4_1: () => MODEL_GPT_4_1,
|
|
92
92
|
MODEL_GPT_4_1_MINI: () => MODEL_GPT_4_1_MINI,
|
|
93
93
|
MODEL_GPT_4_1_NANO: () => MODEL_GPT_4_1_NANO,
|
|
94
|
-
MODEL_GPT_4_5_PREVIEW: () => MODEL_GPT_4_5_PREVIEW,
|
|
95
94
|
MODEL_GPT_5: () => MODEL_GPT_5,
|
|
96
95
|
MODEL_GPT_5_1: () => MODEL_GPT_5_1,
|
|
97
96
|
MODEL_GPT_5_MINI: () => MODEL_GPT_5_MINI,
|
|
@@ -143,6 +142,7 @@ var AITuberOnAirChat = (() => {
|
|
|
143
142
|
parseOpenAICompatibleTextStream: () => parseOpenAICompatibleTextStream,
|
|
144
143
|
parseOpenAICompatibleToolStream: () => parseOpenAICompatibleToolStream,
|
|
145
144
|
processChatWithOptionalTools: () => processChatWithOptionalTools,
|
|
145
|
+
refreshOpenRouterFreeModels: () => refreshOpenRouterFreeModels,
|
|
146
146
|
resolveVisionModel: () => resolveVisionModel,
|
|
147
147
|
runOnceText: () => runOnceText,
|
|
148
148
|
screenplayToText: () => screenplayToText,
|
|
@@ -165,7 +165,6 @@ var AITuberOnAirChat = (() => {
|
|
|
165
165
|
var MODEL_O3_MINI = "o3-mini";
|
|
166
166
|
var MODEL_O1_MINI = "o1-mini";
|
|
167
167
|
var MODEL_O1 = "o1";
|
|
168
|
-
var MODEL_GPT_4_5_PREVIEW = "gpt-4.5-preview";
|
|
169
168
|
var VISION_SUPPORTED_MODELS = [
|
|
170
169
|
MODEL_GPT_5_NANO,
|
|
171
170
|
MODEL_GPT_5_MINI,
|
|
@@ -176,7 +175,6 @@ var AITuberOnAirChat = (() => {
|
|
|
176
175
|
MODEL_GPT_4_1_NANO,
|
|
177
176
|
MODEL_GPT_4O_MINI,
|
|
178
177
|
MODEL_GPT_4O,
|
|
179
|
-
MODEL_GPT_4_5_PREVIEW,
|
|
180
178
|
MODEL_O1
|
|
181
179
|
// MODEL_O3_MINI and MODEL_O1_MINI are not included as they don't support vision
|
|
182
180
|
];
|
|
@@ -294,7 +292,7 @@ var AITuberOnAirChat = (() => {
|
|
|
294
292
|
var OPENROUTER_FREE_DAILY_LIMIT_HIGH_CREDITS = 1e3;
|
|
295
293
|
var OPENROUTER_CREDITS_THRESHOLD = 10;
|
|
296
294
|
function isOpenRouterFreeModel(model) {
|
|
297
|
-
return
|
|
295
|
+
return model.trim().endsWith(":free");
|
|
298
296
|
}
|
|
299
297
|
function isOpenRouterVisionModel(model) {
|
|
300
298
|
return OPENROUTER_VISION_SUPPORTED_MODELS.some(
|
|
@@ -795,6 +793,212 @@ If it's in another language, summarize in that language.
|
|
|
795
793
|
return resolved;
|
|
796
794
|
};
|
|
797
795
|
|
|
796
|
+
// src/utils/refreshOpenRouterFreeModels.ts
|
|
797
|
+
var OPENROUTER_MODELS_ENDPOINT = "https://openrouter.ai/api/v1/models";
|
|
798
|
+
var DEFAULT_CONCURRENCY = 2;
|
|
799
|
+
var DEFAULT_TIMEOUT_MS = 12e3;
|
|
800
|
+
var DEFAULT_MAX_CANDIDATES = 1;
|
|
801
|
+
var DEFAULT_MAX_WORKING = 10;
|
|
802
|
+
function toErrorMessage(error) {
|
|
803
|
+
if (error instanceof Error) {
|
|
804
|
+
return error.message;
|
|
805
|
+
}
|
|
806
|
+
return String(error);
|
|
807
|
+
}
|
|
808
|
+
function normalizeLimit(value, fallback) {
|
|
809
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
810
|
+
return fallback;
|
|
811
|
+
}
|
|
812
|
+
return Math.max(1, Math.floor(value));
|
|
813
|
+
}
|
|
814
|
+
function normalizeModelIds(modelIds) {
|
|
815
|
+
const seen = /* @__PURE__ */ new Set();
|
|
816
|
+
const normalized = [];
|
|
817
|
+
for (const modelId of modelIds) {
|
|
818
|
+
const trimmed = modelId.trim();
|
|
819
|
+
if (!trimmed || seen.has(trimmed)) {
|
|
820
|
+
continue;
|
|
821
|
+
}
|
|
822
|
+
seen.add(trimmed);
|
|
823
|
+
normalized.push(trimmed);
|
|
824
|
+
}
|
|
825
|
+
return normalized;
|
|
826
|
+
}
|
|
827
|
+
async function fetchWithTimeout(url, init, timeoutMs) {
|
|
828
|
+
const hasAbortController = typeof AbortController !== "undefined";
|
|
829
|
+
if (!hasAbortController) {
|
|
830
|
+
return fetch(url, init);
|
|
831
|
+
}
|
|
832
|
+
const controller = new AbortController();
|
|
833
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
834
|
+
try {
|
|
835
|
+
return await fetch(url, {
|
|
836
|
+
...init,
|
|
837
|
+
signal: controller.signal
|
|
838
|
+
});
|
|
839
|
+
} catch (error) {
|
|
840
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
841
|
+
throw new Error(`Timeout after ${timeoutMs}ms`);
|
|
842
|
+
}
|
|
843
|
+
throw error;
|
|
844
|
+
} finally {
|
|
845
|
+
clearTimeout(timeoutId);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
async function toHttpFailureReason(response) {
|
|
849
|
+
const status = `HTTP ${response.status} ${response.statusText}`.trim();
|
|
850
|
+
let body = "";
|
|
851
|
+
try {
|
|
852
|
+
body = await response.text();
|
|
853
|
+
} catch {
|
|
854
|
+
return status;
|
|
855
|
+
}
|
|
856
|
+
const compactBody = body.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
857
|
+
if (!compactBody) {
|
|
858
|
+
return status;
|
|
859
|
+
}
|
|
860
|
+
return `${status}: ${compactBody}`;
|
|
861
|
+
}
|
|
862
|
+
function extractModelIds(payload) {
|
|
863
|
+
if (!payload || typeof payload !== "object") {
|
|
864
|
+
throw new Error("Invalid models response shape");
|
|
865
|
+
}
|
|
866
|
+
const response = payload;
|
|
867
|
+
const modelEntries = Array.isArray(response.data) ? response.data : Array.isArray(response.models) ? response.models : [];
|
|
868
|
+
if (modelEntries.length === 0) {
|
|
869
|
+
return [];
|
|
870
|
+
}
|
|
871
|
+
const modelIds = modelEntries.map((entry) => entry.id).filter((id) => typeof id === "string");
|
|
872
|
+
return normalizeModelIds(modelIds);
|
|
873
|
+
}
|
|
874
|
+
async function probeModel({
|
|
875
|
+
modelId,
|
|
876
|
+
apiKey,
|
|
877
|
+
endpoint,
|
|
878
|
+
timeoutMs,
|
|
879
|
+
appName,
|
|
880
|
+
appUrl
|
|
881
|
+
}) {
|
|
882
|
+
const headers = {
|
|
883
|
+
Authorization: `Bearer ${apiKey}`,
|
|
884
|
+
"Content-Type": "application/json"
|
|
885
|
+
};
|
|
886
|
+
if (appName) {
|
|
887
|
+
headers["X-Title"] = appName;
|
|
888
|
+
}
|
|
889
|
+
if (appUrl) {
|
|
890
|
+
headers["HTTP-Referer"] = appUrl;
|
|
891
|
+
}
|
|
892
|
+
try {
|
|
893
|
+
const response = await fetchWithTimeout(
|
|
894
|
+
endpoint,
|
|
895
|
+
{
|
|
896
|
+
method: "POST",
|
|
897
|
+
headers,
|
|
898
|
+
body: JSON.stringify({
|
|
899
|
+
model: modelId,
|
|
900
|
+
messages: [{ role: "user", content: "Reply only with OK." }],
|
|
901
|
+
stream: false
|
|
902
|
+
})
|
|
903
|
+
},
|
|
904
|
+
timeoutMs
|
|
905
|
+
);
|
|
906
|
+
if (!response.ok) {
|
|
907
|
+
return {
|
|
908
|
+
id: modelId,
|
|
909
|
+
ok: false,
|
|
910
|
+
reason: await toHttpFailureReason(response)
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
try {
|
|
914
|
+
await response.json();
|
|
915
|
+
} catch (error) {
|
|
916
|
+
return {
|
|
917
|
+
id: modelId,
|
|
918
|
+
ok: false,
|
|
919
|
+
reason: `JSON parse failed: ${toErrorMessage(error)}`
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
return { id: modelId, ok: true };
|
|
923
|
+
} catch (error) {
|
|
924
|
+
return {
|
|
925
|
+
id: modelId,
|
|
926
|
+
ok: false,
|
|
927
|
+
reason: toErrorMessage(error)
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
async function runWithConcurrency(items, concurrency, worker) {
|
|
932
|
+
if (items.length === 0) {
|
|
933
|
+
return [];
|
|
934
|
+
}
|
|
935
|
+
const results = new Array(items.length);
|
|
936
|
+
let nextIndex = 0;
|
|
937
|
+
const workerCount = Math.min(concurrency, items.length);
|
|
938
|
+
await Promise.all(
|
|
939
|
+
Array.from({ length: workerCount }, async () => {
|
|
940
|
+
while (nextIndex < items.length) {
|
|
941
|
+
const current = nextIndex;
|
|
942
|
+
nextIndex += 1;
|
|
943
|
+
results[current] = await worker(items[current]);
|
|
944
|
+
}
|
|
945
|
+
})
|
|
946
|
+
);
|
|
947
|
+
return results;
|
|
948
|
+
}
|
|
949
|
+
async function refreshOpenRouterFreeModels(options) {
|
|
950
|
+
const apiKey = options.apiKey.trim();
|
|
951
|
+
if (!apiKey) {
|
|
952
|
+
throw new Error("OpenRouter API key is required.");
|
|
953
|
+
}
|
|
954
|
+
const modelsEndpoint = options.modelsEndpoint || OPENROUTER_MODELS_ENDPOINT;
|
|
955
|
+
const endpoint = options.endpoint || ENDPOINT_OPENROUTER_API;
|
|
956
|
+
const timeoutMs = normalizeLimit(options.timeoutMs, DEFAULT_TIMEOUT_MS);
|
|
957
|
+
const concurrency = normalizeLimit(options.concurrency, DEFAULT_CONCURRENCY);
|
|
958
|
+
const maxCandidates = normalizeLimit(
|
|
959
|
+
options.maxCandidates,
|
|
960
|
+
DEFAULT_MAX_CANDIDATES
|
|
961
|
+
);
|
|
962
|
+
const maxWorking = normalizeLimit(options.maxWorking, DEFAULT_MAX_WORKING);
|
|
963
|
+
const modelsResponse = await fetchWithTimeout(
|
|
964
|
+
modelsEndpoint,
|
|
965
|
+
{ method: "GET" },
|
|
966
|
+
timeoutMs
|
|
967
|
+
);
|
|
968
|
+
if (!modelsResponse.ok) {
|
|
969
|
+
throw new Error(await toHttpFailureReason(modelsResponse));
|
|
970
|
+
}
|
|
971
|
+
let payload;
|
|
972
|
+
try {
|
|
973
|
+
payload = await modelsResponse.json();
|
|
974
|
+
} catch (error) {
|
|
975
|
+
throw new Error(`JSON parse failed: ${toErrorMessage(error)}`);
|
|
976
|
+
}
|
|
977
|
+
const candidateModelIds = extractModelIds(payload).filter((modelId) => isOpenRouterFreeModel(modelId)).slice(0, maxCandidates);
|
|
978
|
+
const probeResults = await runWithConcurrency(
|
|
979
|
+
candidateModelIds,
|
|
980
|
+
concurrency,
|
|
981
|
+
(modelId) => probeModel({
|
|
982
|
+
modelId,
|
|
983
|
+
apiKey,
|
|
984
|
+
endpoint,
|
|
985
|
+
timeoutMs,
|
|
986
|
+
appName: options.appName,
|
|
987
|
+
appUrl: options.appUrl
|
|
988
|
+
})
|
|
989
|
+
);
|
|
990
|
+
const working = probeResults.filter((result) => result.ok).map((result) => result.id).slice(0, maxWorking);
|
|
991
|
+
const failed = probeResults.filter((result) => !result.ok).map((result) => ({
|
|
992
|
+
id: result.id,
|
|
993
|
+
reason: result.reason || "Unknown error"
|
|
994
|
+
}));
|
|
995
|
+
return {
|
|
996
|
+
working,
|
|
997
|
+
failed,
|
|
998
|
+
fetchedAt: Date.now()
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
|
|
798
1002
|
// src/services/providers/claude/ClaudeChatService.ts
|
|
799
1003
|
var ClaudeChatService = class {
|
|
800
1004
|
/**
|
|
@@ -2929,8 +3133,7 @@ If it's in another language, summarize in that language.
|
|
|
2929
3133
|
MODEL_GPT_4O,
|
|
2930
3134
|
MODEL_O3_MINI,
|
|
2931
3135
|
MODEL_O1_MINI,
|
|
2932
|
-
MODEL_O1
|
|
2933
|
-
MODEL_GPT_4_5_PREVIEW
|
|
3136
|
+
MODEL_O1
|
|
2934
3137
|
];
|
|
2935
3138
|
}
|
|
2936
3139
|
/**
|
|
@@ -3362,7 +3565,7 @@ If it's in another language, summarize in that language.
|
|
|
3362
3565
|
* @returns True if the model is free
|
|
3363
3566
|
*/
|
|
3364
3567
|
isModelFree(model) {
|
|
3365
|
-
return
|
|
3568
|
+
return isOpenRouterFreeModel(model);
|
|
3366
3569
|
}
|
|
3367
3570
|
};
|
|
3368
3571
|
|