privateboard 0.1.20 → 0.1.21
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/dist/boot.js +239 -34
- package/dist/boot.js.map +1 -1
- package/dist/cli.js +239 -34
- package/dist/cli.js.map +1 -1
- package/dist/server.js +239 -34
- package/dist/server.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +14 -3
- package/public/adjourn-overlay.css +19 -19
- package/public/agent-overlay.css +71 -71
- package/public/agent-profile.css +66 -66
- package/public/agent-profile.js +32 -31
- package/public/app.js +80 -22
- package/public/i18n.js +20 -16
- package/public/icons/fold.png +0 -0
- package/public/index.html +190 -94
- package/public/new-agent.css +111 -110
- package/public/new-agent.js +4 -1
- package/public/onboarding.css +96 -96
- package/public/onboarding.js +53 -24
- package/public/quote-cta.css +38 -38
- package/public/room-settings.css +145 -144
- package/public/themes.css +43 -64
- package/public/user-settings.css +257 -215
- package/public/user-settings.js +94 -13
- package/public/voice-onboarding.css +33 -33
- package/public/voice-replay.css +34 -34
package/dist/boot.js
CHANGED
|
@@ -951,6 +951,7 @@ var init_persona_jobs = __esm({
|
|
|
951
951
|
init_db();
|
|
952
952
|
var VALID_CARRIER_PREFS = /* @__PURE__ */ new Set([
|
|
953
953
|
"openrouter",
|
|
954
|
+
"bai",
|
|
954
955
|
"anthropic",
|
|
955
956
|
"openai",
|
|
956
957
|
"google",
|
|
@@ -2264,6 +2265,7 @@ var MODELS = {
|
|
|
2264
2265
|
provider: "anthropic",
|
|
2265
2266
|
directApiId: "claude-sonnet-4-6",
|
|
2266
2267
|
openrouterId: "anthropic/claude-sonnet-4.6",
|
|
2268
|
+
baiId: "claude-sonnet-4-6",
|
|
2267
2269
|
displayName: "Sonnet 4.6",
|
|
2268
2270
|
contextBudget: 2e5,
|
|
2269
2271
|
deck: "balanced \xB7 default"
|
|
@@ -2273,6 +2275,7 @@ var MODELS = {
|
|
|
2273
2275
|
provider: "anthropic",
|
|
2274
2276
|
directApiId: "claude-opus-4-6",
|
|
2275
2277
|
openrouterId: "anthropic/claude-opus-4.6",
|
|
2278
|
+
baiId: "claude-opus-4-6",
|
|
2276
2279
|
displayName: "Opus 4.6",
|
|
2277
2280
|
contextBudget: 1e6,
|
|
2278
2281
|
deck: "deep reasoning \xB7 1M ctx"
|
|
@@ -2282,6 +2285,7 @@ var MODELS = {
|
|
|
2282
2285
|
provider: "anthropic",
|
|
2283
2286
|
directApiId: "claude-opus-4-7",
|
|
2284
2287
|
openrouterId: "anthropic/claude-opus-4.7",
|
|
2288
|
+
baiId: "claude-opus-4-7",
|
|
2285
2289
|
displayName: "Opus 4.7",
|
|
2286
2290
|
contextBudget: 2e5,
|
|
2287
2291
|
deck: "deep reasoning"
|
|
@@ -2291,6 +2295,9 @@ var MODELS = {
|
|
|
2291
2295
|
provider: "anthropic",
|
|
2292
2296
|
directApiId: "claude-opus-4-6-fast",
|
|
2293
2297
|
openrouterId: "anthropic/claude-opus-4.6-fast",
|
|
2298
|
+
// No baiId · B.AI's catalog doesn't carry Anthropic's "fast"
|
|
2299
|
+
// variants (only the base models). Routing this through B.AI 503s
|
|
2300
|
+
// with "no available channel". Direct Anthropic key or OR carries it.
|
|
2294
2301
|
displayName: "Opus 4.6 Fast",
|
|
2295
2302
|
contextBudget: 2e5,
|
|
2296
2303
|
deck: "faster 4.6 \xB7 same intelligence"
|
|
@@ -2302,6 +2309,7 @@ var MODELS = {
|
|
|
2302
2309
|
// the unsuffixed `claude-haiku-4-5` 404s on the direct API.
|
|
2303
2310
|
directApiId: "claude-haiku-4-5-20251001",
|
|
2304
2311
|
openrouterId: "anthropic/claude-haiku-4.5",
|
|
2312
|
+
baiId: "claude-haiku-4-5",
|
|
2305
2313
|
displayName: "Haiku 4.5",
|
|
2306
2314
|
contextBudget: 2e5,
|
|
2307
2315
|
deck: "fast \xB7 low-cost"
|
|
@@ -2316,6 +2324,7 @@ var MODELS = {
|
|
|
2316
2324
|
provider: "openai",
|
|
2317
2325
|
directApiId: "gpt-5.5",
|
|
2318
2326
|
openrouterId: "openai/gpt-5.5",
|
|
2327
|
+
baiId: "gpt-5-5",
|
|
2319
2328
|
displayName: "GPT-5.5",
|
|
2320
2329
|
contextBudget: 1e6,
|
|
2321
2330
|
deck: "flagship \xB7 1M ctx"
|
|
@@ -2325,6 +2334,7 @@ var MODELS = {
|
|
|
2325
2334
|
provider: "openai",
|
|
2326
2335
|
directApiId: "gpt-5.4",
|
|
2327
2336
|
openrouterId: "openai/gpt-5.4",
|
|
2337
|
+
baiId: "gpt-5-4",
|
|
2328
2338
|
displayName: "GPT-5.4",
|
|
2329
2339
|
contextBudget: 1e6,
|
|
2330
2340
|
deck: "general \xB7 1M ctx"
|
|
@@ -2334,6 +2344,10 @@ var MODELS = {
|
|
|
2334
2344
|
provider: "openai",
|
|
2335
2345
|
directApiId: "gpt-5.4-mini",
|
|
2336
2346
|
openrouterId: "openai/gpt-5.4-mini",
|
|
2347
|
+
// No baiId · B.AI's catalog reports "No available channel for
|
|
2348
|
+
// model gpt-5-4-mini" on the OneAPI distributor — the mini
|
|
2349
|
+
// variant isn't routed there. The full `gpt-5-4` IS available on
|
|
2350
|
+
// B.AI; pick that or use direct / OR for the mini tier.
|
|
2337
2351
|
displayName: "GPT-5.4 Mini",
|
|
2338
2352
|
contextBudget: 4e5,
|
|
2339
2353
|
deck: "fast \xB7 400k ctx"
|
|
@@ -2344,20 +2358,23 @@ var MODELS = {
|
|
|
2344
2358
|
provider: "openai",
|
|
2345
2359
|
directApiId: "gpt-5.5-pro",
|
|
2346
2360
|
openrouterId: "openai/gpt-5.5-pro",
|
|
2361
|
+
baiId: "gpt-5-5-pro",
|
|
2347
2362
|
displayName: "GPT-5.5 Pro",
|
|
2348
2363
|
contextBudget: 1e6,
|
|
2349
2364
|
deck: "deep reasoning \xB7 1M ctx",
|
|
2350
|
-
|
|
2365
|
+
viaUniversalOnly: true
|
|
2351
2366
|
},
|
|
2352
2367
|
"codex-5-4": {
|
|
2353
2368
|
v: "codex-5-4",
|
|
2354
2369
|
provider: "openai",
|
|
2355
2370
|
directApiId: "gpt-5.3-codex",
|
|
2356
2371
|
openrouterId: "openai/gpt-5.3-codex",
|
|
2372
|
+
// No baiId · B.AI's catalog doesn't list a codex variant; the
|
|
2373
|
+
// preview only ships via OR. Routing it through B.AI 503s.
|
|
2357
2374
|
displayName: "ChatGPT Codex 5.4",
|
|
2358
2375
|
contextBudget: 4e5,
|
|
2359
2376
|
deck: "code \xB7 agents",
|
|
2360
|
-
|
|
2377
|
+
viaUniversalOnly: true
|
|
2361
2378
|
},
|
|
2362
2379
|
// ── Google · current frontier (3.1 Pro / 3 Flash / 3.1 Flash Lite) ──
|
|
2363
2380
|
// Replaced the legacy gemini-2.5-pro / gemini-2.5-flash entries — all
|
|
@@ -2369,6 +2386,7 @@ var MODELS = {
|
|
|
2369
2386
|
provider: "google",
|
|
2370
2387
|
directApiId: "gemini-3.1-pro-preview",
|
|
2371
2388
|
openrouterId: "google/gemini-3.1-pro-preview",
|
|
2389
|
+
baiId: "gemini-3-1-pro",
|
|
2372
2390
|
displayName: "Gemini 3.1 Pro",
|
|
2373
2391
|
contextBudget: 1e6,
|
|
2374
2392
|
deck: "flagship \xB7 1M ctx"
|
|
@@ -2378,6 +2396,7 @@ var MODELS = {
|
|
|
2378
2396
|
provider: "google",
|
|
2379
2397
|
directApiId: "gemini-3-flash-preview",
|
|
2380
2398
|
openrouterId: "google/gemini-3-flash-preview",
|
|
2399
|
+
baiId: "gemini-3-flash",
|
|
2381
2400
|
displayName: "Gemini 3 Flash",
|
|
2382
2401
|
contextBudget: 1e6,
|
|
2383
2402
|
deck: "frontier flash \xB7 1M ctx"
|
|
@@ -2387,6 +2406,11 @@ var MODELS = {
|
|
|
2387
2406
|
provider: "google",
|
|
2388
2407
|
directApiId: "gemini-3.1-flash-lite-preview",
|
|
2389
2408
|
openrouterId: "google/gemini-3.1-flash-lite-preview",
|
|
2409
|
+
// No baiId · B.AI's catalog only has `gemini-3-1-pro` and
|
|
2410
|
+
// `gemini-3-flash` for the Gemini family — no 3.1 Flash Lite
|
|
2411
|
+
// channel. Earlier mapping to `gemini-3-1-flash` 503'd with
|
|
2412
|
+
// "no available channel for model gemini-3-1-flash". Direct
|
|
2413
|
+
// Google key or OR carries this preview model.
|
|
2390
2414
|
displayName: "Gemini 3.1 Flash Lite",
|
|
2391
2415
|
contextBudget: 1e6,
|
|
2392
2416
|
deck: "fast \xB7 1M ctx"
|
|
@@ -2401,6 +2425,7 @@ var MODELS = {
|
|
|
2401
2425
|
provider: "xai",
|
|
2402
2426
|
directApiId: "grok-4.3",
|
|
2403
2427
|
openrouterId: "x-ai/grok-4.3",
|
|
2428
|
+
baiId: "grok-4-3",
|
|
2404
2429
|
displayName: "Grok 4.3",
|
|
2405
2430
|
contextBudget: 1e6,
|
|
2406
2431
|
deck: "flagship \xB7 1M ctx"
|
|
@@ -2410,6 +2435,7 @@ var MODELS = {
|
|
|
2410
2435
|
provider: "xai",
|
|
2411
2436
|
directApiId: "grok-4.1-fast",
|
|
2412
2437
|
openrouterId: "x-ai/grok-4.1-fast",
|
|
2438
|
+
baiId: "grok-4-1-fast",
|
|
2413
2439
|
displayName: "Grok 4.1 Fast",
|
|
2414
2440
|
contextBudget: 256e3,
|
|
2415
2441
|
deck: "fast \xB7 256k ctx"
|
|
@@ -2419,10 +2445,11 @@ var MODELS = {
|
|
|
2419
2445
|
provider: "xai",
|
|
2420
2446
|
directApiId: "grok-4.20",
|
|
2421
2447
|
openrouterId: "x-ai/grok-4.20",
|
|
2448
|
+
baiId: "grok-4-20",
|
|
2422
2449
|
displayName: "Grok 4.20",
|
|
2423
2450
|
contextBudget: 2e6,
|
|
2424
2451
|
deck: "2M ctx \xB7 big context",
|
|
2425
|
-
|
|
2452
|
+
viaUniversalOnly: true
|
|
2426
2453
|
},
|
|
2427
2454
|
// ── DeepSeek (OR-only · no @ai-sdk/deepseek shipped) ──
|
|
2428
2455
|
"deepseek-v4-pro": {
|
|
@@ -2430,10 +2457,11 @@ var MODELS = {
|
|
|
2430
2457
|
provider: "deepseek",
|
|
2431
2458
|
directApiId: "deepseek-v4-pro",
|
|
2432
2459
|
openrouterId: "deepseek/deepseek-v4-pro",
|
|
2460
|
+
baiId: "deepseek-v4-pro",
|
|
2433
2461
|
displayName: "DeepSeek V4 Pro",
|
|
2434
2462
|
contextBudget: 128e3,
|
|
2435
2463
|
deck: "reasoning \xB7 open weights",
|
|
2436
|
-
|
|
2464
|
+
viaUniversalOnly: true
|
|
2437
2465
|
},
|
|
2438
2466
|
// OpenRouter catalog id · deepseek/deepseek-v4-flash ("V4 Flash" — lite tier).
|
|
2439
2467
|
"deepseek-v4-flash": {
|
|
@@ -2441,10 +2469,41 @@ var MODELS = {
|
|
|
2441
2469
|
provider: "deepseek",
|
|
2442
2470
|
directApiId: "deepseek-v4-flash",
|
|
2443
2471
|
openrouterId: "deepseek/deepseek-v4-flash",
|
|
2472
|
+
baiId: "deepseek-v4-flash",
|
|
2444
2473
|
displayName: "DeepSeek Lite",
|
|
2445
2474
|
contextBudget: 1e6,
|
|
2446
2475
|
deck: "V4 Flash \xB7 fast \xB7 1M ctx",
|
|
2447
|
-
|
|
2476
|
+
viaUniversalOnly: true
|
|
2477
|
+
},
|
|
2478
|
+
// ── Zhipu (Z.AI) · GLM family · OR + B.AI only ──
|
|
2479
|
+
// OpenRouter catalog convention: `z-ai/glm-X.Y`. B.AI uses
|
|
2480
|
+
// hyphenated lowercase: `glm-5-1`. No direct @ai-sdk client ·
|
|
2481
|
+
// viaUniversalOnly skips the direct path.
|
|
2482
|
+
"glm-5-1": {
|
|
2483
|
+
v: "glm-5-1",
|
|
2484
|
+
provider: "zhipu",
|
|
2485
|
+
directApiId: "glm-5.1",
|
|
2486
|
+
openrouterId: "z-ai/glm-5.1",
|
|
2487
|
+
baiId: "glm-5-1",
|
|
2488
|
+
displayName: "GLM 5.1",
|
|
2489
|
+
contextBudget: 2e5,
|
|
2490
|
+
deck: "Zhipu flagship \xB7 200k ctx",
|
|
2491
|
+
viaUniversalOnly: true
|
|
2492
|
+
},
|
|
2493
|
+
// ── Moonshot · Kimi family · OR + B.AI only ──
|
|
2494
|
+
// OpenRouter catalog convention: `moonshotai/kimi-…`. B.AI uses
|
|
2495
|
+
// hyphenated lowercase: `kimi-2-6`. No direct @ai-sdk client ·
|
|
2496
|
+
// viaUniversalOnly skips the direct path.
|
|
2497
|
+
"kimi-2-6": {
|
|
2498
|
+
v: "kimi-2-6",
|
|
2499
|
+
provider: "moonshot",
|
|
2500
|
+
directApiId: "kimi-2.6",
|
|
2501
|
+
openrouterId: "moonshotai/kimi-2.6",
|
|
2502
|
+
baiId: "kimi-2-6",
|
|
2503
|
+
displayName: "Kimi 2.6",
|
|
2504
|
+
contextBudget: 256e3,
|
|
2505
|
+
deck: "Moonshot \xB7 long-context",
|
|
2506
|
+
viaUniversalOnly: true
|
|
2448
2507
|
}
|
|
2449
2508
|
};
|
|
2450
2509
|
function getModel(v) {
|
|
@@ -3482,6 +3541,7 @@ var NoKeyError = class extends Error {
|
|
|
3482
3541
|
provider;
|
|
3483
3542
|
};
|
|
3484
3543
|
var OPENROUTER_BASE = "https://openrouter.ai/api/v1";
|
|
3544
|
+
var BAI_BASE = "https://api.b.ai/v1";
|
|
3485
3545
|
var SENSITIVE_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
3486
3546
|
"authorization",
|
|
3487
3547
|
"x-api-key",
|
|
@@ -3609,70 +3669,107 @@ function formatStreamError(e) {
|
|
|
3609
3669
|
}
|
|
3610
3670
|
return String(e);
|
|
3611
3671
|
}
|
|
3612
|
-
function resolveModel(modelV, carrier) {
|
|
3672
|
+
function resolveModel(modelV, carrier, excludeCarriers) {
|
|
3613
3673
|
const meta = getModel(modelV);
|
|
3614
|
-
const
|
|
3615
|
-
const
|
|
3674
|
+
const skip = (c) => excludeCarriers?.has(c) === true;
|
|
3675
|
+
const orKey = !skip("openrouter") ? getKey("openrouter") : void 0;
|
|
3676
|
+
const baiKey = !skip("bai") ? getKey("bai") : void 0;
|
|
3677
|
+
const directKey = !skip(meta.provider) ? getKey(meta.provider) : void 0;
|
|
3616
3678
|
if (carrier === "openrouter" && orKey) {
|
|
3617
3679
|
process.stderr.write(`[adapter] modelV=${modelV} \u2192 openrouter:${meta.openrouterId} (pinned)
|
|
3618
3680
|
`);
|
|
3619
3681
|
return openRouterResolved(meta, orKey);
|
|
3620
3682
|
}
|
|
3621
|
-
if (carrier
|
|
3622
|
-
|
|
3683
|
+
if (carrier === "bai" && baiKey && meta.baiId) {
|
|
3684
|
+
process.stderr.write(`[adapter] modelV=${modelV} \u2192 bai:${meta.baiId} (pinned)
|
|
3685
|
+
`);
|
|
3686
|
+
return baiResolved(meta, baiKey);
|
|
3687
|
+
}
|
|
3688
|
+
if (carrier && carrier !== "openrouter" && carrier !== "bai" && carrier === meta.provider) {
|
|
3689
|
+
const pinnedKey = !skip(carrier) ? getKey(carrier) : void 0;
|
|
3623
3690
|
if (pinnedKey) {
|
|
3624
3691
|
process.stderr.write(`[adapter] modelV=${modelV} \u2192 direct:${meta.provider}/${meta.directApiId} (pinned)
|
|
3625
3692
|
`);
|
|
3626
3693
|
return directResolved(meta, pinnedKey);
|
|
3627
3694
|
}
|
|
3628
3695
|
}
|
|
3629
|
-
if (carrier) {
|
|
3696
|
+
if (carrier && !excludeCarriers?.size) {
|
|
3630
3697
|
process.stderr.write(
|
|
3631
3698
|
`[adapter] modelV=${modelV} pinned carrier=${carrier} unreachable; falling back to default routing
|
|
3632
3699
|
`
|
|
3633
3700
|
);
|
|
3634
3701
|
}
|
|
3635
|
-
if (meta.
|
|
3702
|
+
if (meta.viaUniversalOnly && orKey) {
|
|
3636
3703
|
process.stderr.write(`[adapter] modelV=${modelV} \u2192 openrouter:${meta.openrouterId} (preferred)
|
|
3637
3704
|
`);
|
|
3638
3705
|
return openRouterResolved(meta, orKey);
|
|
3639
3706
|
}
|
|
3640
|
-
if (directKey && !meta.
|
|
3707
|
+
if (directKey && !meta.viaUniversalOnly) {
|
|
3641
3708
|
process.stderr.write(`[adapter] modelV=${modelV} \u2192 direct:${meta.provider}/${meta.directApiId}
|
|
3642
3709
|
`);
|
|
3643
3710
|
return directResolved(meta, directKey);
|
|
3644
3711
|
}
|
|
3712
|
+
if (baiKey && meta.baiId) {
|
|
3713
|
+
process.stderr.write(`[adapter] modelV=${modelV} \u2192 bai:${meta.baiId}
|
|
3714
|
+
`);
|
|
3715
|
+
return baiResolved(meta, baiKey);
|
|
3716
|
+
}
|
|
3645
3717
|
if (orKey) {
|
|
3646
3718
|
process.stderr.write(`[adapter] modelV=${modelV} \u2192 openrouter:${meta.openrouterId}
|
|
3647
3719
|
`);
|
|
3648
3720
|
return openRouterResolved(meta, orKey);
|
|
3649
3721
|
}
|
|
3650
|
-
if (meta.
|
|
3651
|
-
process.stderr.write(`[adapter] modelV=${modelV} \u2192 direct:${meta.provider}/${meta.directApiId} (
|
|
3722
|
+
if (meta.viaUniversalOnly && directKey) {
|
|
3723
|
+
process.stderr.write(`[adapter] modelV=${modelV} \u2192 direct:${meta.provider}/${meta.directApiId} (viaUniversalOnly fallback \xB7 no OR / B.AI key)
|
|
3652
3724
|
`);
|
|
3653
3725
|
return directResolved(meta, directKey);
|
|
3654
3726
|
}
|
|
3655
3727
|
throw new NoKeyError(meta.provider);
|
|
3656
3728
|
}
|
|
3729
|
+
function isCarrierAccessDenied(message) {
|
|
3730
|
+
if (!message) return false;
|
|
3731
|
+
const m = message.toLowerCase();
|
|
3732
|
+
if (/\b40[23]\b/.test(m) && /(access|deposit|payment|paid|premium|subscri|quota|balance|fund)/.test(m)) return true;
|
|
3733
|
+
if (/access[_\s-]?denied/.test(m)) return true;
|
|
3734
|
+
if (/deposit\s+required/.test(m)) return true;
|
|
3735
|
+
if (/paid[_\s-]?plan[_\s-]?required/.test(m)) return true;
|
|
3736
|
+
if (/premium[_\s-]?model/.test(m)) return true;
|
|
3737
|
+
if (/insufficient[_\s-]?(?:quota|balance|fund)/.test(m)) return true;
|
|
3738
|
+
if (/quota[_\s-]?exceeded/.test(m)) return true;
|
|
3739
|
+
if (/payment[_\s-]?required/.test(m)) return true;
|
|
3740
|
+
if (/billing/.test(m) && /(disabled|inactive|required|invalid|missing)/.test(m)) return true;
|
|
3741
|
+
if (/model[_\s-]?not[_\s-]?found/.test(m)) return true;
|
|
3742
|
+
if (/no\s+available\s+channel/.test(m)) return true;
|
|
3743
|
+
if (/no\s+endpoints?\s+found/.test(m)) return true;
|
|
3744
|
+
if (/invalid\s+model/.test(m)) return true;
|
|
3745
|
+
if (/model.*(unavailable|not\s+(?:supported|available))/.test(m)) return true;
|
|
3746
|
+
if (/prohibited.*(?:terms?\s+of\s+service|provider)/.test(m)) return true;
|
|
3747
|
+
if (/provider.*terms?\s+of\s+service/.test(m)) return true;
|
|
3748
|
+
if (/violates?\s+(?:our|the)?\s*(?:terms|policy|content)/.test(m)) return true;
|
|
3749
|
+
return false;
|
|
3750
|
+
}
|
|
3657
3751
|
function directResolved(meta, apiKey) {
|
|
3658
3752
|
switch (meta.provider) {
|
|
3659
3753
|
case "anthropic":
|
|
3660
3754
|
return {
|
|
3661
|
-
model: createAnthropic({ apiKey, fetch: makeLoggedFetch("anthropic") })(meta.directApiId)
|
|
3755
|
+
model: createAnthropic({ apiKey, fetch: makeLoggedFetch("anthropic") })(meta.directApiId),
|
|
3756
|
+
carrier: "anthropic"
|
|
3662
3757
|
};
|
|
3663
3758
|
case "openai":
|
|
3664
3759
|
return {
|
|
3665
3760
|
model: createOpenAI({ apiKey, fetch: makeLoggedFetch("openai") }).responses(meta.directApiId),
|
|
3666
3761
|
providerOptions: {
|
|
3667
3762
|
openai: { reasoningEffort: "none" }
|
|
3668
|
-
}
|
|
3763
|
+
},
|
|
3764
|
+
carrier: "openai"
|
|
3669
3765
|
};
|
|
3670
3766
|
case "google":
|
|
3671
3767
|
return {
|
|
3672
3768
|
model: createGoogleGenerativeAI({ apiKey, fetch: makeLoggedFetch("google") })(meta.directApiId),
|
|
3673
3769
|
providerOptions: {
|
|
3674
3770
|
google: { thinkingConfig: { thinkingBudget: 0 } }
|
|
3675
|
-
}
|
|
3771
|
+
},
|
|
3772
|
+
carrier: "google"
|
|
3676
3773
|
};
|
|
3677
3774
|
case "xai": {
|
|
3678
3775
|
return {
|
|
@@ -3680,13 +3777,31 @@ function directResolved(meta, apiKey) {
|
|
|
3680
3777
|
apiKey,
|
|
3681
3778
|
baseURL: "https://api.x.ai/v1",
|
|
3682
3779
|
fetch: makeLoggedFetch("xai")
|
|
3683
|
-
}).responses(meta.directApiId)
|
|
3780
|
+
}).responses(meta.directApiId),
|
|
3781
|
+
carrier: "xai"
|
|
3684
3782
|
};
|
|
3685
3783
|
}
|
|
3686
3784
|
default:
|
|
3687
3785
|
throw new NoKeyError(meta.provider);
|
|
3688
3786
|
}
|
|
3689
3787
|
}
|
|
3788
|
+
function baiResolved(meta, apiKey) {
|
|
3789
|
+
const baiId = meta.baiId;
|
|
3790
|
+
if (!baiId) {
|
|
3791
|
+
throw new NoKeyError(meta.provider);
|
|
3792
|
+
}
|
|
3793
|
+
const compat = createOpenAICompatible({
|
|
3794
|
+
name: "bai",
|
|
3795
|
+
apiKey,
|
|
3796
|
+
baseURL: BAI_BASE,
|
|
3797
|
+
fetch: baiLoggedFetch
|
|
3798
|
+
});
|
|
3799
|
+
return {
|
|
3800
|
+
model: compat.chatModel(baiId),
|
|
3801
|
+
carrier: "bai"
|
|
3802
|
+
};
|
|
3803
|
+
}
|
|
3804
|
+
var baiLoggedFetch = makeLoggedFetch("bai");
|
|
3690
3805
|
function openRouterResolved(meta, apiKey) {
|
|
3691
3806
|
const compat = createOpenAICompatible({
|
|
3692
3807
|
name: "openrouter",
|
|
@@ -3711,7 +3826,8 @@ function openRouterResolved(meta, apiKey) {
|
|
|
3711
3826
|
openrouter: {
|
|
3712
3827
|
provider: { allow_fallbacks: false }
|
|
3713
3828
|
}
|
|
3714
|
-
}
|
|
3829
|
+
},
|
|
3830
|
+
carrier: "openrouter"
|
|
3715
3831
|
};
|
|
3716
3832
|
}
|
|
3717
3833
|
var RETRY_MAX_ATTEMPTS = 3;
|
|
@@ -3762,6 +3878,8 @@ async function* callLLMStream(req) {
|
|
|
3762
3878
|
let attempt = 0;
|
|
3763
3879
|
let lastTransientMessage = "";
|
|
3764
3880
|
let yieldedText = false;
|
|
3881
|
+
const triedCarriers = /* @__PURE__ */ new Set();
|
|
3882
|
+
triedCarriers.add(resolved.carrier);
|
|
3765
3883
|
while (attempt < RETRY_MAX_ATTEMPTS) {
|
|
3766
3884
|
attempt++;
|
|
3767
3885
|
if (req.signal?.aborted) {
|
|
@@ -3803,6 +3921,21 @@ async function* callLLMStream(req) {
|
|
|
3803
3921
|
retriableErrorMessage = msg;
|
|
3804
3922
|
break;
|
|
3805
3923
|
}
|
|
3924
|
+
if (!yieldedText && isCarrierAccessDenied(msg)) {
|
|
3925
|
+
try {
|
|
3926
|
+
const next = resolveModel(req.modelV, null, triedCarriers);
|
|
3927
|
+
triedCarriers.add(next.carrier);
|
|
3928
|
+
process.stderr.write(
|
|
3929
|
+
`[adapter] modelV=${req.modelV} carrier=${resolved.carrier} rejected (access denied); retrying via ${next.carrier}
|
|
3930
|
+
`
|
|
3931
|
+
);
|
|
3932
|
+
resolved = next;
|
|
3933
|
+
attempt = 0;
|
|
3934
|
+
retriableErrorMessage = msg;
|
|
3935
|
+
break;
|
|
3936
|
+
} catch {
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3806
3939
|
sawError = true;
|
|
3807
3940
|
yield { type: "error", message: msg };
|
|
3808
3941
|
}
|
|
@@ -3845,6 +3978,20 @@ async function* callLLMStream(req) {
|
|
|
3845
3978
|
lastTransientMessage = msg;
|
|
3846
3979
|
continue;
|
|
3847
3980
|
}
|
|
3981
|
+
if (!yieldedText && isCarrierAccessDenied(msg)) {
|
|
3982
|
+
try {
|
|
3983
|
+
const next = resolveModel(req.modelV, null, triedCarriers);
|
|
3984
|
+
triedCarriers.add(next.carrier);
|
|
3985
|
+
process.stderr.write(
|
|
3986
|
+
`[adapter] modelV=${req.modelV} carrier=${resolved.carrier} rejected (access denied / threw); retrying via ${next.carrier}
|
|
3987
|
+
`
|
|
3988
|
+
);
|
|
3989
|
+
resolved = next;
|
|
3990
|
+
attempt = 0;
|
|
3991
|
+
continue;
|
|
3992
|
+
} catch {
|
|
3993
|
+
}
|
|
3994
|
+
}
|
|
3848
3995
|
yield { type: "error", message: msg };
|
|
3849
3996
|
return;
|
|
3850
3997
|
}
|
|
@@ -3884,25 +4031,31 @@ async function callLLMWithUsage(req) {
|
|
|
3884
4031
|
// src/storage/reconcile-models.ts
|
|
3885
4032
|
var PRIMARY_BY_CARRIER = {
|
|
3886
4033
|
openrouter: "opus-4-6-fast",
|
|
4034
|
+
bai: "haiku-4-5",
|
|
3887
4035
|
anthropic: "haiku-4-5",
|
|
3888
4036
|
openai: "gpt-5-4-mini",
|
|
3889
4037
|
google: "gemini-3-1-flash",
|
|
3890
4038
|
xai: "grok-4-1-fast"
|
|
3891
4039
|
};
|
|
3892
|
-
var CARRIER_PRIORITY = ["openrouter", "anthropic", "openai", "google", "xai"];
|
|
4040
|
+
var CARRIER_PRIORITY = ["openrouter", "bai", "anthropic", "openai", "google", "xai"];
|
|
3893
4041
|
function reachableModelVs() {
|
|
3894
4042
|
const out = /* @__PURE__ */ new Set();
|
|
3895
4043
|
const orKey = !!getKey("openrouter");
|
|
4044
|
+
const baiKey = !!getKey("bai");
|
|
3896
4045
|
for (const [v, meta] of Object.entries(MODELS)) {
|
|
3897
4046
|
if (orKey) {
|
|
3898
4047
|
out.add(v);
|
|
3899
4048
|
continue;
|
|
3900
4049
|
}
|
|
3901
|
-
if (
|
|
4050
|
+
if (baiKey && meta.baiId) {
|
|
3902
4051
|
out.add(v);
|
|
3903
4052
|
continue;
|
|
3904
4053
|
}
|
|
3905
|
-
if (meta.
|
|
4054
|
+
if (!meta.viaUniversalOnly && hasDirectKey(meta.provider)) {
|
|
4055
|
+
out.add(v);
|
|
4056
|
+
continue;
|
|
4057
|
+
}
|
|
4058
|
+
if (meta.viaUniversalOnly && hasDirectKey(meta.provider)) {
|
|
3906
4059
|
out.add(v);
|
|
3907
4060
|
}
|
|
3908
4061
|
}
|
|
@@ -3924,14 +4077,16 @@ function activeCarrier() {
|
|
|
3924
4077
|
if (prefs.defaultModelV) {
|
|
3925
4078
|
const meta = MODELS[prefs.defaultModelV];
|
|
3926
4079
|
if (meta) {
|
|
3927
|
-
if (meta.
|
|
4080
|
+
if (meta.viaUniversalOnly && getKey("openrouter")) return "openrouter";
|
|
3928
4081
|
if (hasDirectKey(meta.provider)) return meta.provider;
|
|
4082
|
+
if (getKey("bai") && meta.baiId) return "bai";
|
|
3929
4083
|
if (getKey("openrouter")) return "openrouter";
|
|
3930
4084
|
}
|
|
3931
4085
|
}
|
|
3932
4086
|
for (const c of CARRIER_PRIORITY) {
|
|
3933
4087
|
if (c === "openrouter" && getKey("openrouter")) return "openrouter";
|
|
3934
|
-
if (c
|
|
4088
|
+
if (c === "bai" && getKey("bai")) return "bai";
|
|
4089
|
+
if (c !== "openrouter" && c !== "bai" && hasDirectKey(c)) return c;
|
|
3935
4090
|
}
|
|
3936
4091
|
return null;
|
|
3937
4092
|
}
|
|
@@ -3942,8 +4097,18 @@ function reconcileAgentModels(opts = {}) {
|
|
|
3942
4097
|
const forcePrimary = opts.forcePrimary === true;
|
|
3943
4098
|
const switched = [];
|
|
3944
4099
|
const cleared = [];
|
|
4100
|
+
const orReachable = !!getKey("openrouter");
|
|
4101
|
+
const baiReachable = !!getKey("bai");
|
|
4102
|
+
function carrierKeyReachable(c) {
|
|
4103
|
+
if (c === "openrouter") return orReachable;
|
|
4104
|
+
if (c === "bai") return baiReachable;
|
|
4105
|
+
return hasDirectKey(c);
|
|
4106
|
+
}
|
|
3945
4107
|
for (const agent of listAllAgents()) {
|
|
3946
4108
|
const v = (agent.modelV || "").trim();
|
|
4109
|
+
if (agent.carrierPref && !carrierKeyReachable(agent.carrierPref)) {
|
|
4110
|
+
updateAgent(agent.id, { carrierPref: null });
|
|
4111
|
+
}
|
|
3947
4112
|
if (!forcePrimary && v && reachable.has(v)) continue;
|
|
3948
4113
|
if (primary && carrier) {
|
|
3949
4114
|
const isChair = agent.roleKind === "moderator";
|
|
@@ -3972,26 +4137,29 @@ function reconcileAgentModels(opts = {}) {
|
|
|
3972
4137
|
function getProviderKeyState() {
|
|
3973
4138
|
const directProviders = /* @__PURE__ */ new Set();
|
|
3974
4139
|
let hasOpenRouter = false;
|
|
4140
|
+
let hasBai = false;
|
|
3975
4141
|
for (const meta of listKeyMeta()) {
|
|
3976
4142
|
if (!meta.configured) continue;
|
|
3977
4143
|
if (meta.provider === "openrouter") hasOpenRouter = true;
|
|
4144
|
+
else if (meta.provider === "bai") hasBai = true;
|
|
3978
4145
|
else if (meta.provider === "brave" || meta.provider === "tavily" || meta.provider === "minimax" || meta.provider === "elevenlabs") continue;
|
|
3979
4146
|
else directProviders.add(meta.provider);
|
|
3980
4147
|
}
|
|
3981
|
-
return { hasOpenRouter, directProviders };
|
|
4148
|
+
return { hasOpenRouter, hasBai, directProviders };
|
|
3982
4149
|
}
|
|
3983
4150
|
function availabilityFor(meta, keys) {
|
|
3984
|
-
const directReachable = !meta.
|
|
4151
|
+
const directReachable = !meta.viaUniversalOnly && keys.directProviders.has(meta.provider);
|
|
3985
4152
|
const orReachable = keys.hasOpenRouter && !!meta.openrouterId;
|
|
3986
|
-
const
|
|
4153
|
+
const baiReachable = keys.hasBai && !!meta.baiId;
|
|
4154
|
+
const reachable = directReachable || orReachable || baiReachable;
|
|
3987
4155
|
return {
|
|
3988
4156
|
modelV: meta.v,
|
|
3989
4157
|
displayName: meta.displayName,
|
|
3990
4158
|
provider: meta.provider,
|
|
3991
4159
|
deck: meta.deck,
|
|
3992
|
-
routes: { direct: directReachable, openrouter: orReachable },
|
|
4160
|
+
routes: { direct: directReachable, openrouter: orReachable, bai: baiReachable },
|
|
3993
4161
|
reachable,
|
|
3994
|
-
preferredRoute: directReachable ? "direct" : orReachable ? "openrouter" : null
|
|
4162
|
+
preferredRoute: directReachable ? "direct" : baiReachable ? "bai" : orReachable ? "openrouter" : null
|
|
3995
4163
|
};
|
|
3996
4164
|
}
|
|
3997
4165
|
function modelAvailability() {
|
|
@@ -4003,7 +4171,7 @@ function reachableModels() {
|
|
|
4003
4171
|
}
|
|
4004
4172
|
function hasAnyModelKey() {
|
|
4005
4173
|
const keys = getProviderKeyState();
|
|
4006
|
-
return keys.hasOpenRouter || keys.directProviders.size > 0;
|
|
4174
|
+
return keys.hasOpenRouter || keys.hasBai || keys.directProviders.size > 0;
|
|
4007
4175
|
}
|
|
4008
4176
|
var PROVIDER_FLAGSHIP = {
|
|
4009
4177
|
anthropic: "opus-4-7",
|
|
@@ -4011,7 +4179,10 @@ var PROVIDER_FLAGSHIP = {
|
|
|
4011
4179
|
google: "gemini-3-flash",
|
|
4012
4180
|
xai: "grok-4-3",
|
|
4013
4181
|
deepseek: "deepseek-v4-pro",
|
|
4182
|
+
zhipu: "glm-5-1",
|
|
4183
|
+
moonshot: "kimi-2-6",
|
|
4014
4184
|
openrouter: "opus-4-7",
|
|
4185
|
+
bai: "opus-4-7",
|
|
4015
4186
|
brave: null,
|
|
4016
4187
|
tavily: null,
|
|
4017
4188
|
minimax: null,
|
|
@@ -4023,7 +4194,13 @@ var PROVIDER_FAST = {
|
|
|
4023
4194
|
google: "gemini-3-1-flash",
|
|
4024
4195
|
xai: "grok-4-1-fast",
|
|
4025
4196
|
deepseek: "deepseek-v4-flash",
|
|
4197
|
+
// GLM / Kimi · no separate fast/flash tier in our registry yet, so
|
|
4198
|
+
// both providers' "fast pick" falls back to the same flagship that
|
|
4199
|
+
// PROVIDER_FLAGSHIP names. Reachability-via-OR/B.AI carries it.
|
|
4200
|
+
zhipu: "glm-5-1",
|
|
4201
|
+
moonshot: "kimi-2-6",
|
|
4026
4202
|
openrouter: "opus-4-6-fast",
|
|
4203
|
+
bai: "haiku-4-5",
|
|
4027
4204
|
brave: null,
|
|
4028
4205
|
tavily: null,
|
|
4029
4206
|
minimax: null,
|
|
@@ -4039,6 +4216,21 @@ var FAST_POOL_BY_CARRIER = {
|
|
|
4039
4216
|
"grok-4-1-fast",
|
|
4040
4217
|
"deepseek-v4-flash"
|
|
4041
4218
|
],
|
|
4219
|
+
// B.AI carries the same brand-spanning fast catalog as OpenRouter ·
|
|
4220
|
+
// identical pool gives a B.AI-only user the same visibly-mixed
|
|
4221
|
+
// director cast (different brand badges per seat) that the OpenRouter
|
|
4222
|
+
// path produces. Members are filtered against reachability inside
|
|
4223
|
+
// `pickRandomFastModel`, so models without a baiId fall out naturally
|
|
4224
|
+
// if B.AI ends up not carrying one of them in practice.
|
|
4225
|
+
bai: [
|
|
4226
|
+
"opus-4-6-fast",
|
|
4227
|
+
"haiku-4-5",
|
|
4228
|
+
"gpt-5-4-mini",
|
|
4229
|
+
"gemini-3-flash",
|
|
4230
|
+
"gemini-3-1-flash",
|
|
4231
|
+
"grok-4-1-fast",
|
|
4232
|
+
"deepseek-v4-flash"
|
|
4233
|
+
],
|
|
4042
4234
|
anthropic: ["opus-4-6-fast", "haiku-4-5"],
|
|
4043
4235
|
openai: ["gpt-5-4-mini"],
|
|
4044
4236
|
google: ["gemini-3-flash", "gemini-3-1-flash"],
|
|
@@ -4066,7 +4258,10 @@ var FLAGSHIP_TIER = /* @__PURE__ */ new Set([
|
|
|
4066
4258
|
// xAI
|
|
4067
4259
|
"grok-4-3",
|
|
4068
4260
|
// DeepSeek
|
|
4069
|
-
"deepseek-v4-pro"
|
|
4261
|
+
"deepseek-v4-pro",
|
|
4262
|
+
// Zhipu · Moonshot · single flagship each (both OR + B.AI routed).
|
|
4263
|
+
"glm-5-1",
|
|
4264
|
+
"kimi-2-6"
|
|
4070
4265
|
]);
|
|
4071
4266
|
function effectiveDefaultModel() {
|
|
4072
4267
|
const prefs = getPrefs();
|
|
@@ -4096,6 +4291,12 @@ function defaultModelFor(keys = getProviderKeyState()) {
|
|
|
4096
4291
|
const opus = reachable.find((m) => m.modelV === "opus-4-7");
|
|
4097
4292
|
if (opus) return opus.modelV;
|
|
4098
4293
|
}
|
|
4294
|
+
if (keys.hasBai) {
|
|
4295
|
+
const fast = reachable.find((m) => m.modelV === "haiku-4-5");
|
|
4296
|
+
if (fast) return fast.modelV;
|
|
4297
|
+
const opus = reachable.find((m) => m.modelV === "opus-4-7");
|
|
4298
|
+
if (opus) return opus.modelV;
|
|
4299
|
+
}
|
|
4099
4300
|
for (const provider of keys.directProviders) {
|
|
4100
4301
|
const fast = PROVIDER_FAST[provider];
|
|
4101
4302
|
if (fast && reachable.find((m) => m.modelV === fast)) return fast;
|
|
@@ -4108,6 +4309,8 @@ function defaultModelFor(keys = getProviderKeyState()) {
|
|
|
4108
4309
|
}
|
|
4109
4310
|
var CHEAP_BY_CARRIER = {
|
|
4110
4311
|
openrouter: "haiku-4-5",
|
|
4312
|
+
bai: "haiku-4-5",
|
|
4313
|
+
// B.AI carries Haiku 4.5 (claude-haiku-4-5)
|
|
4111
4314
|
anthropic: "sonnet-4-6",
|
|
4112
4315
|
// only direct-routable Claude
|
|
4113
4316
|
openai: "gpt-5-4-mini",
|
|
@@ -7628,7 +7831,7 @@ function agentsRouter() {
|
|
|
7628
7831
|
patch.carrierPref = null;
|
|
7629
7832
|
} else if (typeof b.carrierPref === "string") {
|
|
7630
7833
|
const v = b.carrierPref.trim();
|
|
7631
|
-
const allowed = /* @__PURE__ */ new Set(["openrouter", "anthropic", "openai", "google", "xai"]);
|
|
7834
|
+
const allowed = /* @__PURE__ */ new Set(["openrouter", "bai", "anthropic", "openai", "google", "xai"]);
|
|
7632
7835
|
if (!allowed.has(v)) {
|
|
7633
7836
|
return c.json({ error: `unknown carrier: ${v}` }, 400);
|
|
7634
7837
|
}
|
|
@@ -15196,6 +15399,7 @@ function defaultVoiceForProvider(provider) {
|
|
|
15196
15399
|
// src/routes/keys.ts
|
|
15197
15400
|
var PROVIDERS = /* @__PURE__ */ new Set([
|
|
15198
15401
|
"openrouter",
|
|
15402
|
+
"bai",
|
|
15199
15403
|
"anthropic",
|
|
15200
15404
|
"openai",
|
|
15201
15405
|
"google",
|
|
@@ -15208,6 +15412,7 @@ var PROVIDERS = /* @__PURE__ */ new Set([
|
|
|
15208
15412
|
]);
|
|
15209
15413
|
var LLM_PROVIDERS = /* @__PURE__ */ new Set([
|
|
15210
15414
|
"openrouter",
|
|
15415
|
+
"bai",
|
|
15211
15416
|
"anthropic",
|
|
15212
15417
|
"openai",
|
|
15213
15418
|
"google",
|
|
@@ -23339,7 +23544,7 @@ function voicesRouter() {
|
|
|
23339
23544
|
init_paths();
|
|
23340
23545
|
|
|
23341
23546
|
// src/version.ts
|
|
23342
|
-
var VERSION = "0.1.
|
|
23547
|
+
var VERSION = "0.1.21";
|
|
23343
23548
|
|
|
23344
23549
|
// src/server.ts
|
|
23345
23550
|
function createApp() {
|