@prismshadow/penguin-server 0.2.16 → 0.2.18
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.md +1 -1
- package/dist/api/types.d.ts +402 -52
- package/dist/api/types.js +17 -3
- package/dist/auth-token.js +1 -1
- package/dist/{chunk-HMTT2PX4.js → chunk-2LZDP26O.js} +8 -5
- package/dist/chunk-2LZDP26O.js.map +1 -0
- package/dist/chunk-5YLLSHY3.js +1195 -0
- package/dist/chunk-5YLLSHY3.js.map +1 -0
- package/dist/{chunk-D3JNA6ZI.js → chunk-B3PSKR3D.js} +2 -2
- package/dist/chunk-B3PSKR3D.js.map +1 -0
- package/dist/{chunk-LPPVGHYD.js → chunk-BL4U7GYY.js} +2 -2
- package/dist/chunk-BL4U7GYY.js.map +1 -0
- package/dist/chunk-BRMNPLU6.js +37 -0
- package/dist/chunk-BRMNPLU6.js.map +1 -0
- package/dist/chunk-GGIINEEK.js +3401 -0
- package/dist/chunk-GGIINEEK.js.map +1 -0
- package/dist/{chunk-QFV3ERQO.js → chunk-OQZDL3TR.js} +2 -2
- package/dist/hmr/manifest.js +1 -1
- package/dist/index.js +13440 -8991
- package/dist/index.js.map +1 -1
- package/dist/machine-status.js +2 -2
- package/dist/model-catalog.d.ts +610 -0
- package/dist/model-catalog.js +108 -0
- package/dist/model-catalog.js.map +1 -0
- package/dist/plugin/index.d.ts +170 -74
- package/dist/reset-admin-password.js +2 -2
- package/dist/version-report.js +2 -2
- package/package.json +14 -9
- package/web-dist/assets/{abnfDiagram-VCTEODGH-0AKFiyig.js → abnfDiagram-VCTEODGH-C_Ej4MyZ.js} +1 -1
- package/web-dist/assets/{addon-clipboard-BovFnNVg.js → addon-clipboard-eONBCa8x.js} +1 -1
- package/web-dist/assets/{addon-fit-B1npgxQk.js → addon-fit-Dk6bkT8u.js} +1 -1
- package/web-dist/assets/{addon-web-links-D88QHj7A.js → addon-web-links-e0JpGvGv.js} +1 -1
- package/web-dist/assets/{arc-Beox1Cgf.js → arc-ytwqobEL.js} +1 -1
- package/web-dist/assets/{architectureDiagram-5GKGNRK7-CC1sLMY1.js → architectureDiagram-5GKGNRK7-oxT9SNOE.js} +1 -1
- package/web-dist/assets/{blockDiagram-I7D4REHJ-B8BY1PkZ.js → blockDiagram-I7D4REHJ-D8OXfpb9.js} +1 -1
- package/web-dist/assets/{c4Diagram-7LVT6UL2-yjY0BkxQ.js → c4Diagram-7LVT6UL2-BNYNzSWK.js} +1 -1
- package/web-dist/assets/channel-7Be_pU-b.js +1 -0
- package/web-dist/assets/{chunk-2Q5K7J3B-DdgIvETg.js → chunk-2Q5K7J3B-C2yNhFmh.js} +1 -1
- package/web-dist/assets/{chunk-5VM5RSS4-BE38k1Rs.js → chunk-5VM5RSS4-CAeuhwbB.js} +1 -1
- package/web-dist/assets/{chunk-F27PBJKO-D4YXmaqQ.js → chunk-F27PBJKO-DSuRiLxP.js} +1 -1
- package/web-dist/assets/{chunk-IMKFNOWR-CyJFdThc.js → chunk-IMKFNOWR-MStar4cf.js} +1 -1
- package/web-dist/assets/{chunk-JWPE2WC7-BAM_oEUU.js → chunk-JWPE2WC7-CIgQwRv4.js} +1 -1
- package/web-dist/assets/{chunk-POPQ4Y6H-BP3D0FVi.js → chunk-POPQ4Y6H-CA8evx9g.js} +1 -1
- package/web-dist/assets/{chunk-SVP7TREG-Clk8PdKZ.js → chunk-SVP7TREG-bR7-FT1W.js} +1 -1
- package/web-dist/assets/{chunk-TICWLB2K-EvWPnEGg.js → chunk-TICWLB2K-C0ZdCnvI.js} +1 -1
- package/web-dist/assets/{chunk-XXDRQBXY-6p5D0UB1.js → chunk-XXDRQBXY-CzozFLFI.js} +1 -1
- package/web-dist/assets/classDiagram-ZZMXUADV-BjVhvDIH.js +1 -0
- package/web-dist/assets/classDiagram-v2-VYDZK3BY-BjVhvDIH.js +1 -0
- package/web-dist/assets/{cose-bilkent-JH36ORCC-bpkI-tLJ.js → cose-bilkent-JH36ORCC-nkjrY6eI.js} +1 -1
- package/web-dist/assets/{cynefin-OW5HDTMX-srLaqJ4e.js → cynefin-OW5HDTMX-D2A0h062.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-5FMLGOSQ-BPfpHSPc.js → cynefinDiagram-5FMLGOSQ-DFZQ7d_T.js} +1 -1
- package/web-dist/assets/{dagre-GXQ25YYZ-C4fF5-j7.js → dagre-GXQ25YYZ-DPYLLARd.js} +1 -1
- package/web-dist/assets/{diagram-S7CK7UJ4-BzBLb_9-.js → diagram-S7CK7UJ4-B204Nrur.js} +1 -1
- package/web-dist/assets/{diagram-UQ7AKVKN-BJuJ1o_T.js → diagram-UQ7AKVKN-DWORCZlS.js} +1 -1
- package/web-dist/assets/{diagram-VSXAHHWV-DFelN9i9.js → diagram-VSXAHHWV-Su6Bzm4Z.js} +1 -1
- package/web-dist/assets/{diagram-VX7I27RA-BgrEoPyp.js → diagram-VX7I27RA-B4p8ssYj.js} +1 -1
- package/web-dist/assets/{diagram-Z3DM3KII-C71KiMiX.js → diagram-Z3DM3KII-BgMz7jjW.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-PWID7BFC-EYteyp1b.js → ebnfDiagram-PWID7BFC-DBCS3Cwc.js} +1 -1
- package/web-dist/assets/{erDiagram-RLTQ6QDP-B6n6-sz6.js → erDiagram-RLTQ6QDP-DEm39S5C.js} +1 -1
- package/web-dist/assets/{flowDiagram-HODETNUW-BtoMTdyT.js → flowDiagram-HODETNUW-CEUQGUza.js} +1 -1
- package/web-dist/assets/{ganttDiagram-EL5Y4UJY-CbOAa3vS.js → ganttDiagram-EL5Y4UJY-myYTgwFp.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-WWUBYQGX-B7-8sszH.js → gitGraphDiagram-WWUBYQGX-BAQ0Kl1C.js} +1 -1
- package/web-dist/assets/highlighter-DRTMVWxI.js +2 -0
- package/web-dist/assets/{highlighter-core-CMXoD8ze.js → highlighter-core-DgISzHrX.js} +1 -1
- package/web-dist/assets/{highlighter.worker-D6D9fPma.js → highlighter.worker-CKF6ok1g.js} +1 -1
- package/web-dist/assets/index-PA-IFoA6.js +1300 -0
- package/web-dist/assets/index-oCEyg9BT.css +1 -0
- package/web-dist/assets/{infoDiagram-27XIBGKW-BBjf6pkP.js → infoDiagram-27XIBGKW-B2WDMvX9.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-5VMMS53U-BBSvCv45.js → ishikawaDiagram-5VMMS53U-8qHTttjq.js} +1 -1
- package/web-dist/assets/{journeyDiagram-3NMN7TZE-CuHHl5zk.js → journeyDiagram-3NMN7TZE-DKE_xRCO.js} +1 -1
- package/web-dist/assets/{kanban-definition-UXKFOSKX-DJyP4Myw.js → kanban-definition-UXKFOSKX-EnJbHEmV.js} +1 -1
- package/web-dist/assets/{layout-Bqqhdwtt.js → layout-BlhCFmEZ.js} +1 -1
- package/web-dist/assets/{linear-BZfUSIf8.js → linear-Dw2VzU-D.js} +1 -1
- package/web-dist/assets/mermaid.core-CaXNMz57.js +310 -0
- package/web-dist/assets/{mindmap-definition-YA3MSWOX-BtyMD4wz.js → mindmap-definition-YA3MSWOX-DnTTfqbu.js} +1 -1
- package/web-dist/assets/{pegDiagram-XKGWAZYB-BUF_GJ0B.js → pegDiagram-XKGWAZYB-C3SArVd6.js} +1 -1
- package/web-dist/assets/{pieDiagram-E7YTZNPT-nweubbsU.js → pieDiagram-E7YTZNPT-CTOmO6ke.js} +1 -1
- package/web-dist/assets/powershell-DXrKVo3G.js +1 -0
- package/web-dist/assets/powershell-Dpen1YoG.js +1 -0
- package/web-dist/assets/{quadrantDiagram-AXDQQJYC-B_r4Wkxy.js → quadrantDiagram-AXDQQJYC-CbUsMwzO.js} +1 -1
- package/web-dist/assets/{railroadDiagram-O6MQD6OU-Dn7nm0MX.js → railroadDiagram-O6MQD6OU-Co2hsvaZ.js} +1 -1
- package/web-dist/assets/{requirementDiagram-BXWQKSXE-DaagYJ49.js → requirementDiagram-BXWQKSXE-BqFG0eYQ.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-P5KCCOFB-CqEX6H-B.js → sankeyDiagram-P5KCCOFB-YgQHJlB7.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-WJ2MYXX4-BzLfQO55.js → sequenceDiagram-WJ2MYXX4-CdDrP6O2.js} +1 -1
- package/web-dist/assets/{sizeCapture-INFHLROL-BcUuVH2L.js → sizeCapture-INFHLROL-CKwbEVhU.js} +1 -1
- package/web-dist/assets/{stateDiagram-D77RDMKH-BO3LWLvT.js → stateDiagram-D77RDMKH-kTJR3t2p.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-MP3YSRHH-DzaSnZwj.js +1 -0
- package/web-dist/assets/{swimlanes-42K2YHIH-etP_hkIB.js → swimlanes-42K2YHIH-DCAO3rCQ.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-VR7AAH4N-DNfCLejq.js +8 -0
- package/web-dist/assets/{timeline-definition-24CTP7MA-CTLt2XCT.js → timeline-definition-24CTP7MA-DEjnyzKw.js} +1 -1
- package/web-dist/assets/{vennDiagram-4TSXK5OY-DPO6ZSvH.js → vennDiagram-4TSXK5OY-DSihUvCq.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-VM6X3IG4-DFofGg8b.js → wardleyDiagram-VM6X3IG4-CnAoMeCH.js} +1 -1
- package/web-dist/assets/{xterm-RdyTuaAH.js → xterm-3JwPT74G.js} +1 -1
- package/web-dist/assets/{xychartDiagram-S5SC5T6Z-Bgtb34Gu.js → xychartDiagram-S5SC5T6Z-43dHqZTr.js} +1 -1
- package/web-dist/index.html +6 -5
- package/web-dist/workbench-ui.css +164 -34
- package/dist/chunk-3SFJKLQU.js +0 -1016
- package/dist/chunk-3SFJKLQU.js.map +0 -1
- package/dist/chunk-D3JNA6ZI.js.map +0 -1
- package/dist/chunk-HMTT2PX4.js.map +0 -1
- package/dist/chunk-LPPVGHYD.js.map +0 -1
- package/dist/chunk-W7JNIJ25.js +0 -19
- package/dist/chunk-W7JNIJ25.js.map +0 -1
- package/web-dist/assets/channel-mfsAVJLE.js +0 -1
- package/web-dist/assets/classDiagram-ZZMXUADV-BPVO1m8i.js +0 -1
- package/web-dist/assets/classDiagram-v2-VYDZK3BY-BPVO1m8i.js +0 -1
- package/web-dist/assets/highlighter-Bj5l2XH_.js +0 -2
- package/web-dist/assets/index-BOCqRT4e.css +0 -1
- package/web-dist/assets/index-BrMpjp2s.js +0 -1286
- package/web-dist/assets/mermaid.core-BlUspEsI.js +0 -310
- package/web-dist/assets/stateDiagram-v2-MP3YSRHH-B-EuucjM.js +0 -1
- package/web-dist/assets/swimlanesDiagram-VR7AAH4N-0JbFdDbQ.js +0 -8
- /package/dist/{chunk-QFV3ERQO.js.map → chunk-OQZDL3TR.js.map} +0 -0
package/dist/machine-status.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MachinesRepo
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2LZDP26O.js";
|
|
4
4
|
import {
|
|
5
5
|
liveServerLock
|
|
6
6
|
} from "./chunk-GOO5VUAB.js";
|
|
7
7
|
import {
|
|
8
8
|
openDatabaseReadOnly
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-5YLLSHY3.js";
|
|
10
10
|
import "./chunk-B5IP37ZQ.js";
|
|
11
11
|
|
|
12
12
|
// src/machine-status.ts
|
|
@@ -0,0 +1,610 @@
|
|
|
1
|
+
import { ModelPricing, ModelRef, ProviderTable, ModelEntry } from '@prismshadow/penguin-core';
|
|
2
|
+
import { ModelCredentialShape, ProviderConnectionShape } from '@prismshadow/penguin-core/model-connection';
|
|
3
|
+
export { routedClientType } from '@prismshadow/mmsp/credentials';
|
|
4
|
+
|
|
5
|
+
/** Model provider info (used for web grouping/logo and the "API key blank falls back to env var" hint). */
|
|
6
|
+
/**
|
|
7
|
+
* A provider that mints API keys through an authorization page instead of a console visit.
|
|
8
|
+
* Present only on providers that publish such a flow; its absence is what makes the harness
|
|
9
|
+
* refuse to start one.
|
|
10
|
+
*/
|
|
11
|
+
interface ModelProviderOAuth {
|
|
12
|
+
/** Authorization page the user is sent to; the flow's parameters ride on its query string. */
|
|
13
|
+
authorizeUrl: string;
|
|
14
|
+
/** Endpoint that trades an authorization code for a newly minted key. */
|
|
15
|
+
exchangeUrl: string;
|
|
16
|
+
/** Name recorded on the minted key, and the app name the authorization page displays. */
|
|
17
|
+
keyName: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A group whose credential the App obtains through its own authorization flow rather than by
|
|
21
|
+
* asking the vendor: the client registers a one-time code and device secret with an external
|
|
22
|
+
* bridge, sends the user to the page that bridge hands back, and polls until the bridge
|
|
23
|
+
* delivers the credential. Distinct from `oauth`, where the App itself speaks the vendor's
|
|
24
|
+
* PKCE page — here the App never reaches the vendor at all, because the bridge holds the
|
|
25
|
+
* client secret that conversation would need.
|
|
26
|
+
*
|
|
27
|
+
* The bridge's own address is deliberately NOT here: this file is bundled for the browser and
|
|
28
|
+
* cannot read configuration, so the App resolves the bridge server-side from its environment
|
|
29
|
+
* (PENGUIN_GO_ORIGIN / MODELSCOPE_BRIDGE_URL), keyed by the group's id.
|
|
30
|
+
*/
|
|
31
|
+
interface ModelProviderBridgeAuth {
|
|
32
|
+
/**
|
|
33
|
+
* Which App-side flow serves this group — one route family and one service per value, so
|
|
34
|
+
* the Web App picks from the group's descriptor rather than from its id.
|
|
35
|
+
*/
|
|
36
|
+
flow: "penguin-go" | "modelscope";
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* An account-balance endpoint the vendor publishes, called with the group's own API key as a
|
|
40
|
+
* Bearer token. The server makes that call (the key never reaches the browser); the endpoint
|
|
41
|
+
* is the vendor's, like the OAuth one above, so it can live in this browser-bundled file.
|
|
42
|
+
*/
|
|
43
|
+
interface ModelProviderBalance {
|
|
44
|
+
/** GET endpoint answering the balance of the account the key belongs to. */
|
|
45
|
+
url: string;
|
|
46
|
+
/**
|
|
47
|
+
* How to read the answer, one reader per published response shape:
|
|
48
|
+
* - `tokendance`: `{ balance: { credits, credits_used, balance } }`, integers in micro-yuan
|
|
49
|
+
* (1 CNY = 1,000,000);
|
|
50
|
+
* - `deepseek`: `{ is_available, balance_infos: [{ currency, total_balance, … }] }`, one entry
|
|
51
|
+
* per currency the account holds.
|
|
52
|
+
* - `penguin-go`: `{ balance: { units, currency } }`, a CNY ledger integer in 10^-12 yuan.
|
|
53
|
+
*/
|
|
54
|
+
format: "tokendance" | "deepseek" | "penguin-go";
|
|
55
|
+
}
|
|
56
|
+
interface ModelProviderInfo {
|
|
57
|
+
id: string;
|
|
58
|
+
/** Display name (brand name, shared by Chinese and English UI). */
|
|
59
|
+
label: string;
|
|
60
|
+
/**
|
|
61
|
+
* API key env var name: the variable MMSP's client for this group's rows reads when handed no
|
|
62
|
+
* key, which it does only for its own default endpoint (PRN-021, MMSP's rule). A gateway group
|
|
63
|
+
* records OPENAI_* because that is what its generic client reads, and its rows carry the
|
|
64
|
+
* gateway's base URL, so that client never reads it for them.
|
|
65
|
+
*/
|
|
66
|
+
envKey: string;
|
|
67
|
+
/** base URL env var name. */
|
|
68
|
+
envBaseUrlKey: string;
|
|
69
|
+
/** Console URL for obtaining an API key (frontend links it beside the API key field of the group key dialog and the model dialog); none for custom. */
|
|
70
|
+
apiKeyUrl?: string;
|
|
71
|
+
/** Vendor's model list / docs page URL (frontend's "add model" dialog links this as "get model id"); none for custom. */
|
|
72
|
+
modelsUrl?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Gateway's OpenAI-compatible endpoint (openrouter / siliconflow / qwen-token-plan / …): what
|
|
75
|
+
* a new Project writes as the group's `[providers.<id>]` base URL (catalogGroupConnection),
|
|
76
|
+
* so every row of the group — a model added by hand included — follows it without storing
|
|
77
|
+
* the address itself. A reference value: nothing reads it when a request is built. Left
|
|
78
|
+
* blank for direct vendors, custom and vLLM (whose rows name the local server's address).
|
|
79
|
+
*/
|
|
80
|
+
gatewayBaseUrl?: string;
|
|
81
|
+
/**
|
|
82
|
+
* Authorization flow that mints a key for the user (see ModelProviderOAuth); absent for
|
|
83
|
+
* every provider whose keys are only obtainable from its console.
|
|
84
|
+
*/
|
|
85
|
+
oauth?: ModelProviderOAuth;
|
|
86
|
+
/**
|
|
87
|
+
* The App-side authorization flow that obtains this group's credential (see
|
|
88
|
+
* ModelProviderBridgeAuth); absent for every group whose credential comes from a console or
|
|
89
|
+
* from the vendor's own page. Declaring it is what puts the "authorize a key" action on the
|
|
90
|
+
* group in the Web App.
|
|
91
|
+
*/
|
|
92
|
+
bridgeAuth?: ModelProviderBridgeAuth;
|
|
93
|
+
/**
|
|
94
|
+
* The vendor's account-balance endpoint (see ModelProviderBalance); absent for every group
|
|
95
|
+
* whose vendor publishes none. Declaring it is what puts the balance in the group's header.
|
|
96
|
+
*/
|
|
97
|
+
balance?: ModelProviderBalance;
|
|
98
|
+
/**
|
|
99
|
+
* The group takes models the user adds by hand: `custom` and vLLM, whose rows point at an
|
|
100
|
+
* endpoint the catalog cannot know, and the four gateways whose catalogs list a fraction of
|
|
101
|
+
* what they serve — OpenRouter, TokenDance, SiliconFlow and Atlas Cloud — where an added
|
|
102
|
+
* model follows the group's connection (its endpoint, key and protocol) exactly as the
|
|
103
|
+
* presets do. Every other built-in group carries its catalog presets and the rows it already
|
|
104
|
+
* stores, and nothing else. Read it through isAddableGroup, which also answers for
|
|
105
|
+
* user-defined groups.
|
|
106
|
+
*/
|
|
107
|
+
addable?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* The MMSP protocol EVERY entry in this group speaks, models the user adds included.
|
|
110
|
+
*
|
|
111
|
+
* Set it where the group itself decides the answer for a row the catalog does not list:
|
|
112
|
+
* every group that takes hand-added models and speaks one protocol (vLLM, OpenRouter,
|
|
113
|
+
* TokenDance, SiliconFlow, Atlas Cloud). The other gateways hold catalog rows only, each
|
|
114
|
+
* carrying its own pin, and `custom` / user-defined groups deliberately declare nothing —
|
|
115
|
+
* their whole point is that the protocol is detected from the endpoint or picked by hand,
|
|
116
|
+
* and a pin here would take that choice away.
|
|
117
|
+
*
|
|
118
|
+
* Where it IS set, a new Project writes it as the group's `[providers.<id>]` protocol
|
|
119
|
+
* (catalogGroupConnection), and the rows — models added by hand included — follow that
|
|
120
|
+
* table. A reference value like gatewayBaseUrl: what the app reads at runtime is the file's
|
|
121
|
+
* table. Read it through providerClientType rather than reaching for the field.
|
|
122
|
+
*/
|
|
123
|
+
clientType?: string;
|
|
124
|
+
/**
|
|
125
|
+
* The group the product recommends, captioned as such on the models page. It marks the
|
|
126
|
+
* GROUP, not a position: a user who drags the group elsewhere keeps the caption with it,
|
|
127
|
+
* and the default sequence below is what places it first for everyone else.
|
|
128
|
+
*/
|
|
129
|
+
recommended?: boolean;
|
|
130
|
+
}
|
|
131
|
+
/** A single built-in model's catalog entry (`modelId` is the upstream id; paired with `provider` it forms the catalog's unique key). */
|
|
132
|
+
interface ModelCatalogEntry {
|
|
133
|
+
modelId: string;
|
|
134
|
+
displayName: string;
|
|
135
|
+
/** Provider id (one of MODEL_PROVIDERS). */
|
|
136
|
+
provider: string;
|
|
137
|
+
contextWindow?: number;
|
|
138
|
+
pricing?: ModelPricing;
|
|
139
|
+
/**
|
|
140
|
+
* Fraction off the list price the seller is currently running (0.5 = 50% off), applied to
|
|
141
|
+
* every bucket. `pricing` stays the LIST price whatever promotion is live, so a lapsed
|
|
142
|
+
* promotion is one field to delete rather than three numbers to reconstruct;
|
|
143
|
+
* effectivePricing is the rate actually billed. A Project stores the list price too: the
|
|
144
|
+
* fraction is seeded beside it as a promotion (presetPromotions), which the cost center
|
|
145
|
+
* applies when it prices usage, so it charges what the seller charges.
|
|
146
|
+
*/
|
|
147
|
+
discount?: number;
|
|
148
|
+
/**
|
|
149
|
+
* A discount that is only live outside a weekly set of peak windows — a vendor billing
|
|
150
|
+
* cheaper off-hours. `pricing` holds the PEAK price, the one billed inside the windows, and
|
|
151
|
+
* the rate applies everywhere else.
|
|
152
|
+
*
|
|
153
|
+
* Like `discount`, this one is never baked into a Project, and here there is no choice: it
|
|
154
|
+
* changes twice a day. `presetModelEntries` writes the peak price and the rate is applied
|
|
155
|
+
* when a price is read.
|
|
156
|
+
* A number on disk that silently meant something different at 09:00 than at 08:00 would be
|
|
157
|
+
* unreadable, and re-syncing presets would rewrite prices by the clock. A seller that also
|
|
158
|
+
* takes something off on top of the schedule, in both tiers, declares it in `discount`: it is
|
|
159
|
+
* seeded like any promotion, and the two multiply, as a Project's promotion and schedule do
|
|
160
|
+
* wherever a price is read.
|
|
161
|
+
*/
|
|
162
|
+
offPeakDiscount?: OffPeakDiscount;
|
|
163
|
+
/** Whether image input (vision modality) is supported. */
|
|
164
|
+
supportsVision: boolean;
|
|
165
|
+
/** MMSP client type: required when an id cannot be auto-routed or a shared protocol must be pinned. */
|
|
166
|
+
clientType?: string;
|
|
167
|
+
/**
|
|
168
|
+
* Preset base URL, so only an API key is required. A new Project stores it once: on the
|
|
169
|
+
* group's `[providers.<id>]` table when it is the group's endpoint (catalogGroupConnection),
|
|
170
|
+
* else on the row itself (catalogModelEntry). Never read when a request is built.
|
|
171
|
+
*/
|
|
172
|
+
baseUrl?: string;
|
|
173
|
+
/**
|
|
174
|
+
* No longer a preset (superseded or withdrawn), but saved Projects still carry it: a
|
|
175
|
+
* row a Project has is never deleted by "Add new models", and several of these were the
|
|
176
|
+
* default model of new Projects. A retired row is not a preset — `presetModelEntries` and
|
|
177
|
+
* `presetPromotions` skip it, so a new Project never gets it or a promotion for it, a sync
|
|
178
|
+
* never adds it, and "Restore defaults" deletes it with every other row that is not a preset —
|
|
179
|
+
* but it is still in `catalogModelEntries`, and lookups by `(provider, modelId)` still find
|
|
180
|
+
* it. Projects carrying it keep its display name and vision flag, and their usage on it is
|
|
181
|
+
* priced on its off-peak schedule whenever the row stores the catalog's price: the tier only
|
|
182
|
+
* applies to that price. The schedule is the part that matters: cost is priced when it is
|
|
183
|
+
* read, so deleting a scheduled row would reprice every off-peak record already on those
|
|
184
|
+
* Projects at the peak rate.
|
|
185
|
+
*
|
|
186
|
+
* Compatibility, not catalog data: remove a retired row only after its seller has stopped
|
|
187
|
+
* accepting the id AND the release notes have told users that usage recorded on it will be
|
|
188
|
+
* priced without its schedule from then on. Whoever does the catalog refresh that finds the
|
|
189
|
+
* id rejected makes that call.
|
|
190
|
+
*/
|
|
191
|
+
retired?: true;
|
|
192
|
+
/**
|
|
193
|
+
* This row is, or once was, the default model of new Projects (PRESET_DEFAULT_MODEL). Usage
|
|
194
|
+
* recorded on it stays priced after a Project stops storing the row — "Restore defaults"
|
|
195
|
+
* deletes every row that is not a preset, retired ones included, and a former default is
|
|
196
|
+
* often most of an older Project's history: retainedCatalogPricing gives the cost path this
|
|
197
|
+
* row's `pricing` for it. Moving the default sets this on the new row and leaves it on the
|
|
198
|
+
* old one, which also keeps the old row in the catalog (retired once it stops being a preset)
|
|
199
|
+
* for as long as anyone may have recorded usage on it.
|
|
200
|
+
*/
|
|
201
|
+
wasDefault?: true;
|
|
202
|
+
}
|
|
203
|
+
declare const PENGUIN_GO_BASE_URL = "https://go.penguin.ooo/api/v1";
|
|
204
|
+
/** Provider id for the preconfigured Penguin Go relay group. */
|
|
205
|
+
declare const PENGUIN_GO_PROVIDER_ID = "penguin-go";
|
|
206
|
+
/**
|
|
207
|
+
* The protocol a group is fixed to, or undefined where the group's protocol is the user's to
|
|
208
|
+
* choose. Penguin Go's platform endpoint speaks MMSP alone, so neither its group nor its rows
|
|
209
|
+
* offer a protocol: the Web App shows MMSP without a picker, and the server's model writes and
|
|
210
|
+
* the CLI refuse any other value (fixedClientTypeRefuses).
|
|
211
|
+
*/
|
|
212
|
+
declare function fixedClientType(providerId: string): string | undefined;
|
|
213
|
+
/**
|
|
214
|
+
* Whether writing `next` as the protocol of a group (`target: "group"`) or of one of its rows
|
|
215
|
+
* (`"row"`) is refused because the group's protocol is fixed (fixedClientType). `next` is the
|
|
216
|
+
* value written, blank or absent for none; `stored` is what that group, or that same row in that
|
|
217
|
+
* same group, stores now.
|
|
218
|
+
*
|
|
219
|
+
* The fixed protocol is always accepted, and so is `stored` written back unchanged: a row a user
|
|
220
|
+
* pointed at their own proxy on another protocol before the protocol was fixed (left alone by
|
|
221
|
+
* migratePenguinGoRoutes) keeps it, and a whole-table save carrying it is not refused. A row
|
|
222
|
+
* with no protocol of its own follows its group, so clearing a row's is accepted; clearing the
|
|
223
|
+
* group's would leave its rows routed by model id, and is refused.
|
|
224
|
+
*/
|
|
225
|
+
declare function fixedClientTypeRefuses(providerId: string, target: "group" | "row", next: string | null | undefined, stored: string | undefined): boolean;
|
|
226
|
+
/** Provider id for the ModelScope group. */
|
|
227
|
+
declare const MODELSCOPE_PROVIDER_ID = "modelscope";
|
|
228
|
+
/**
|
|
229
|
+
* Provider list (web model page groups in this order BY DEFAULT — a user's dragged
|
|
230
|
+
* arrangement is stored per Project and wins over this sequence; see the web's
|
|
231
|
+
* model-group-order.ts). The sequence is a hand-curated display order: TokenDance leads as
|
|
232
|
+
* the recommended group, Penguin Go follows, then OpenCode Go, then DeepSeek as the default
|
|
233
|
+
* model's provider, and custom
|
|
234
|
+
* (custom OpenAI-protocol models) is always last; in between, gateways and first-party
|
|
235
|
+
* vendors are interleaved by expected use rather than sorted by kind. Only this default
|
|
236
|
+
* moves when the curation changes: a Project that has ever reordered its groups has every
|
|
237
|
+
* key stored already, so it keeps the arrangement its user built.
|
|
238
|
+
*
|
|
239
|
+
* The eight gateway groups — OpenRouter, Fireworks AI, SiliconFlow, Atlas Cloud, TokenDance,
|
|
240
|
+
* OpenCode Go, Qwen Pay-As-You-Go and Qwen Token Plan — reach their models through MMSP's generic
|
|
241
|
+
* protocol clients (`openai-responses` for OpenRouter, `openai-chat` for the rest, and all
|
|
242
|
+
* three generic clients within OpenCode Go). Those clients read the vendor variables
|
|
243
|
+
* (**OPENAI_API_KEY / OPENAI_BASE_URL**, and ANTHROPIC_* for OpenCode Go's `ant-messages`
|
|
244
|
+
* rows) when the credential is blank, not the gateway's own variable names, so every gateway
|
|
245
|
+
* group records the OPENAI_* pair as the fact it is. A new Project writes each gateway's base
|
|
246
|
+
* URL on its group, so MMSP refuses a keyless gateway row rather than reading a variable: the
|
|
247
|
+
* variable holds the user's OpenAI (or Anthropic) key, and a gateway is neither. ModelScope
|
|
248
|
+
* also records the OPENAI_* pair; its group credential is an api-inference access token taken
|
|
249
|
+
* from the config alone.
|
|
250
|
+
*/
|
|
251
|
+
declare const MODEL_PROVIDERS: ModelProviderInfo[];
|
|
252
|
+
/**
|
|
253
|
+
* A weekly peak/off-peak billing schedule, written in a fixed-offset zone.
|
|
254
|
+
*
|
|
255
|
+
* Only fixed offsets are expressible, which is the whole of what the catalog needs: the vendors
|
|
256
|
+
* that bill this way publish their windows in a single national zone that does not observe DST
|
|
257
|
+
* (Beijing is UTC+8 year round). A vendor on a DST zone would need a real tz database, and the
|
|
258
|
+
* honest move then is to add one rather than to approximate.
|
|
259
|
+
*/
|
|
260
|
+
interface OffPeakDiscount {
|
|
261
|
+
/** Fraction off the peak price outside the windows below (0.5 = half price). */
|
|
262
|
+
rate: number;
|
|
263
|
+
/** Minutes east of UTC the windows are written in (Beijing = 480). */
|
|
264
|
+
utcOffsetMinutes: number;
|
|
265
|
+
/** Days the windows apply to, ISO numbering: 1 = Monday … 7 = Sunday. Days not listed are off-peak all day. */
|
|
266
|
+
peakDays: readonly number[];
|
|
267
|
+
/** Peak windows as [startHour, endHour) in the zone's local hours — end-exclusive, so 12:00 is already off-peak. */
|
|
268
|
+
peakHours: readonly (readonly [number, number])[];
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Whether `now` falls outside every peak window, i.e. whether the discount is live.
|
|
272
|
+
*
|
|
273
|
+
* Computed in UTC arithmetic rather than through the host's local time: the schedule belongs to
|
|
274
|
+
* the vendor's zone, and a server in Los Angeles must reach the same answer as one in Shanghai.
|
|
275
|
+
*/
|
|
276
|
+
declare function offPeakAt(schedule: OffPeakDiscount, now: Date): boolean;
|
|
277
|
+
/** DeepSeek's official off-peak tier: half price outside Beijing weekday 09:00–12:00 and 14:00–18:00. */
|
|
278
|
+
declare const DEEPSEEK_OFF_PEAK: OffPeakDiscount;
|
|
279
|
+
/**
|
|
280
|
+
* Qwen's off-peak tier on the time-banded models it sells (www.qianwenai.com/models/<id>, read
|
|
281
|
+
* 2026-09-16): half price from 22:00 to 08:00 Beijing time, every day of the week, and the peak
|
|
282
|
+
* price at every other hour. Each model page shows the two tiers as separate price tabs, and
|
|
283
|
+
* every bucket's off-peak figure is exactly half its peak one.
|
|
284
|
+
*/
|
|
285
|
+
declare const QWEN_OFF_PEAK: OffPeakDiscount;
|
|
286
|
+
/**
|
|
287
|
+
* The catalog's time-based schedules, each with the references that carry it.
|
|
288
|
+
*
|
|
289
|
+
* The cost center needs this to split an aggregation by tier before it prices anything: the
|
|
290
|
+
* rate a request ran at is a fact about when it ran, and only the catalog knows which rows have
|
|
291
|
+
* two rates at all. Grouped by schedule so a second vendor's windows cost one entry, not a
|
|
292
|
+
* second query.
|
|
293
|
+
*/
|
|
294
|
+
declare function offPeakScheduledRefs(): Array<{
|
|
295
|
+
schedule: OffPeakDiscount;
|
|
296
|
+
refs: Array<{
|
|
297
|
+
provider: string;
|
|
298
|
+
modelId: string;
|
|
299
|
+
}>;
|
|
300
|
+
}>;
|
|
301
|
+
/**
|
|
302
|
+
* What the seller actually bills for an entry at `now`: its list `pricing` less any running
|
|
303
|
+
* `discount` and any live off-peak tier, the two multiplied, on every bucket. Rounded to the six
|
|
304
|
+
* decimals cny() already stores at, so a promotional rate reads as a price rather than as a
|
|
305
|
+
* float artifact. An entry with nothing off (or no pricing at all) is returned untouched.
|
|
306
|
+
*
|
|
307
|
+
* Nothing writes this rate into a Project: `presetModelEntries` writes the list price (a
|
|
308
|
+
* scheduled row's peak price), a flat promotion is stored beside it as a fraction, and which
|
|
309
|
+
* tier a request ran in is decided from that request's own timestamp when the usage is
|
|
310
|
+
* aggregated.
|
|
311
|
+
*/
|
|
312
|
+
declare function effectivePricing(entry: ModelCatalogEntry, now?: Date): ModelPricing | undefined;
|
|
313
|
+
/**
|
|
314
|
+
* Built-in model catalog, clustered by provider. Within each provider, entries are in
|
|
315
|
+
* dictionary order by model id, except that newer versions of the same series come first
|
|
316
|
+
* (e.g. gpt-5.6-* before gpt-5.5, claude-opus-4.8 before 4.7, glm-5.2 before glm-5). The
|
|
317
|
+
* order is precomputed by hand right here — no runtime sorting anywhere.
|
|
318
|
+
*
|
|
319
|
+
* The clusters run in their own sequence, which is the row order a new Project's
|
|
320
|
+
* `[[models]]` table is written in. It is not MODEL_PROVIDERS' display order and does not
|
|
321
|
+
* have to track it: nothing renders a catalog row outside its provider group, and the page
|
|
322
|
+
* takes the group sequence from MODEL_PROVIDERS.
|
|
323
|
+
*/
|
|
324
|
+
declare const MODEL_CATALOG: ModelCatalogEntry[];
|
|
325
|
+
/** Looks up a catalog entry by (provider, upstream id) pair (**the sole catalog-matching entry point**); returns undefined if not in the catalog. */
|
|
326
|
+
declare function catalogEntryFor(provider: string, upstreamId: string): ModelCatalogEntry | undefined;
|
|
327
|
+
/** Looks up provider info by provider id; returns undefined for an unknown id. */
|
|
328
|
+
declare function providerInfo(providerId: string): ModelProviderInfo | undefined;
|
|
329
|
+
/**
|
|
330
|
+
* The protocol a group pins on every one of its entries (ModelProviderInfo.clientType), or
|
|
331
|
+
* undefined when the group pins none — an unknown id (a user-defined group) included.
|
|
332
|
+
*
|
|
333
|
+
* Five groups pin: vLLM, whose models are served by the user's own vLLM adapter,
|
|
334
|
+
* OpenRouter, whose models all speak the Responses API OpenRouter serves at its preset base
|
|
335
|
+
* URL, and TokenDance, SiliconFlow and Atlas Cloud, whose models all speak Chat Completions.
|
|
336
|
+
*
|
|
337
|
+
* A reference value, read when a file is written from the catalog (catalogGroupConnection:
|
|
338
|
+
* a new Project, "Add new models" for a group new to the file, "Restore defaults") and by
|
|
339
|
+
* nothing that builds or judges a request: at runtime a group's protocol is its
|
|
340
|
+
* `[providers.<id>]` table's.
|
|
341
|
+
*/
|
|
342
|
+
declare function providerClientType(providerId: string): string | undefined;
|
|
343
|
+
/**
|
|
344
|
+
* A first-party vendor group: one this catalog knows, that is not `custom`, carries no
|
|
345
|
+
* gateway endpoint and pins no protocol of its own — DeepSeek, Google, OpenAI, Anthropic,
|
|
346
|
+
* Z.AI, Moonshot, MiniMax, and the Penguin Go relay.
|
|
347
|
+
*
|
|
348
|
+
* What distinguishes it is that nothing in it decides a protocol: its entries persist no
|
|
349
|
+
* `client_type`, so MMSP places every one of them by the spelling of the upstream model
|
|
350
|
+
* id alone — the vendor family it begins with. An id of no known family cannot be started at
|
|
351
|
+
* all, whatever else is configured on the entry (the Penguin Go rows pin their protocol
|
|
352
|
+
* instead: the relay serves Gemini through generateContent, not the API a `gemini-` id routes
|
|
353
|
+
* to). Every
|
|
354
|
+
* surface that has to answer "is this one routable?" reads the group's shape through this one
|
|
355
|
+
* predicate rather than re-deriving it: the models page's cards and its config dialog, the
|
|
356
|
+
* models PUT, and the CLI's `config model add`. Whether a model may be added to the group at
|
|
357
|
+
* all is a separate, wider rule: isAddableGroup.
|
|
358
|
+
*
|
|
359
|
+
* Every other group answers the protocol question by itself and therefore routes any id the
|
|
360
|
+
* endpoint serves: `custom` and user-defined groups detect or pick it, and a gateway's or
|
|
361
|
+
* vLLM's rows speak the protocol their group's `[providers.<id>]` table or the row itself
|
|
362
|
+
* stores (a new Project writes it there).
|
|
363
|
+
*/
|
|
364
|
+
declare function isVendorGroup(providerId: string): boolean;
|
|
365
|
+
/**
|
|
366
|
+
* Whether this entry would be written into a vendor group with an id MMSP cannot place —
|
|
367
|
+
* the configuration that produces `No client for model "<id>": its family is not known` on
|
|
368
|
+
* the first request, and nothing before it.
|
|
369
|
+
*
|
|
370
|
+
* MMSP's `routedClientType` is the authority: AutoLLMClient routes through it, and it returns
|
|
371
|
+
* null on exactly the entries that client rejects. A blank id is not a routing failure — the
|
|
372
|
+
* entry is still being typed, and the required-field validation is what has something to say
|
|
373
|
+
* about it.
|
|
374
|
+
*/
|
|
375
|
+
declare function unroutableVendorModel(provider: string, modelId: string, clientType?: string): boolean;
|
|
376
|
+
/**
|
|
377
|
+
* The official MMSP client a first-party vendor group's unpinned rows route to: the vendor's
|
|
378
|
+
* own, the official client that reads the variable the group records (`envKey`; MMSP's
|
|
379
|
+
* credentials module). Undefined for every other group, whose protocol its table or its rows
|
|
380
|
+
* decide.
|
|
381
|
+
*/
|
|
382
|
+
declare function vendorClientType(providerId: string): string | undefined;
|
|
383
|
+
/**
|
|
384
|
+
* Whether models may be added to this group by hand: `custom`, vLLM, OpenRouter, TokenDance,
|
|
385
|
+
* SiliconFlow, Atlas Cloud (ModelProviderInfo.addable) and every user-defined group, i.e. an
|
|
386
|
+
* id this catalog does not know. Every other built-in group — the first-party vendors and the
|
|
387
|
+
* other gateways — carries its catalog presets and the rows it already stores: the models page
|
|
388
|
+
* offers no add-model entry point there, and the models PUT and the CLI's `config model add`
|
|
389
|
+
* refuse a new row that is not a preset (unaddableModel).
|
|
390
|
+
*/
|
|
391
|
+
declare function isAddableGroup(providerId: string): boolean;
|
|
392
|
+
/**
|
|
393
|
+
* Whether writing this pair as a NEW row of its group would add a model by hand where the group
|
|
394
|
+
* takes none: a group isAddableGroup refuses, and a `(provider, model_id)` pair that is not one
|
|
395
|
+
* of the catalog's rows for it. A preset passes, so "Sync presets" can put a deleted one back;
|
|
396
|
+
* a row the table already stores is not a new one, and the callers never ask about it.
|
|
397
|
+
*/
|
|
398
|
+
declare function unaddableModel(provider: string, modelId: string): boolean;
|
|
399
|
+
/**
|
|
400
|
+
* The price usage on a model is costed at when the Project no longer stores the model's row:
|
|
401
|
+
* the catalog's list `pricing` of a row that is or was the default of new Projects
|
|
402
|
+
* (ModelCatalogEntry.wasDefault), and undefined for every other pair — a row the Project does
|
|
403
|
+
* store is priced from the file, never from here. No promotion applies: a Project's promotion
|
|
404
|
+
* goes with its row. An off-peak schedule still does, since this is the catalog's own peak price.
|
|
405
|
+
*/
|
|
406
|
+
declare function retainedCatalogPricing(provider: string, modelId: string): ModelPricing | undefined;
|
|
407
|
+
/**
|
|
408
|
+
* The model's own homepage/detail page for the frontend's model-card link. Gateway groups
|
|
409
|
+
* have a stable per-model URL pattern (works for user-added ids in those groups too);
|
|
410
|
+
* direct-vendor models link to the vendor's model list/docs page; custom and user-defined
|
|
411
|
+
* groups have no page to vouch for.
|
|
412
|
+
*/
|
|
413
|
+
declare function modelHomepageUrl(provider: string, modelId: string): string | undefined;
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* The wire protocol that carries MMSP's `fast_mode` on a client: `"openai"` for the clients
|
|
417
|
+
* that send `service_tier: "priority"` (the OpenAI protocols, and Google's Interactions API
|
|
418
|
+
* and MiniMax alike), `"anthropic"` for those that send `speed: "fast"` plus the
|
|
419
|
+
* `fast-mode-2026-02-01` beta header. The two differ in what the user must be warned about,
|
|
420
|
+
* not just in wire shape.
|
|
421
|
+
*/
|
|
422
|
+
type FastModeProtocol = "openai" | "anthropic";
|
|
423
|
+
/**
|
|
424
|
+
* What the UI shows about each MMSP client, which MMSP exports nothing for: the path it appends
|
|
425
|
+
* to its base URL (the models page's endpoint hint) and the protocol that carries `fast_mode`
|
|
426
|
+
* (absent = the client rejects it, or the harness cannot tell what it does with it). Keyed by
|
|
427
|
+
* the canonical client type MMSP's routedClientType returns; the catalog test holds it to the
|
|
428
|
+
* client types MMSP's credentials module knows.
|
|
429
|
+
*/
|
|
430
|
+
declare const CLIENT_PROTOCOLS: Readonly<Record<string, {
|
|
431
|
+
path: string;
|
|
432
|
+
fastMode?: FastModeProtocol;
|
|
433
|
+
}>>;
|
|
434
|
+
/**
|
|
435
|
+
* Whether a model can carry fast mode at all, and on which protocol - `undefined` means no.
|
|
436
|
+
*
|
|
437
|
+
* The fast tier is a property of the **client MMSP routes to** (MMSP's routedClientType), never of
|
|
438
|
+
* the catalog row: the registry carries no fast-tier capability flag, but the routing is
|
|
439
|
+
* deterministic, so the answer is too. This reports what the selected client does with the
|
|
440
|
+
* parameter:
|
|
441
|
+
*
|
|
442
|
+
* - maps it -> the protocol, and the toggle may be offered;
|
|
443
|
+
* - raises UnsupportedParameterError (the Z.AI, Moonshot, DeepSeek, google-genai and
|
|
444
|
+
* embedding clients, and anthropic-official on Bedrock or for the generations that reject
|
|
445
|
+
* the `speed` parameter) -> `undefined`;
|
|
446
|
+
* - forwards it to an MMSP server, whose upstream client decides what it does with it (mmsp)
|
|
447
|
+
* -> `undefined`: the harness cannot say on which protocol, or whether at all;
|
|
448
|
+
* - routes nowhere (AutoLLMClient throws for an id it cannot place) -> `undefined` as well,
|
|
449
|
+
* since a model that cannot run has no fast tier either.
|
|
450
|
+
*
|
|
451
|
+
* A rule rather than a per-model list on purpose: catalog rows added later inherit the right
|
|
452
|
+
* answer without anyone remembering to update a table.
|
|
453
|
+
*
|
|
454
|
+
* `"anthropic"` is reported for every Claude the client serves, including ids outside the
|
|
455
|
+
* research preview's Opus allowlist: Anthropic answers those with a 429 at request time, which
|
|
456
|
+
* is something to warn about before enabling, not grounds to hide the setting.
|
|
457
|
+
*
|
|
458
|
+
* Two runtime inputs stay invisible to a pure function of the config and can still flip the
|
|
459
|
+
* answer: the server's `CLIENT_TYPE` env var names the client for an entry that pins none, and
|
|
460
|
+
* `ANTHROPIC_BASE_URL` supplies the base URL when the entry leaves it blank (so a `bedrock://`
|
|
461
|
+
* there sends Claude to Bedrock, which has no fast tier). Third-party OpenAI-compatible
|
|
462
|
+
* endpoints are a third: they accept `service_tier` and may quietly serve the standard tier.
|
|
463
|
+
* That residue is why llm/generative-model.ts still handles the rejection at runtime.
|
|
464
|
+
*/
|
|
465
|
+
declare function fastModeProtocol(modelId: string, clientType?: string, baseUrl?: string): FastModeProtocol | undefined;
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* The variable MMSP's client of this type reads its key from when handed none at this base URL
|
|
469
|
+
* (environmentCredential), or undefined: the client refuses that URL, calls it keyless, or is
|
|
470
|
+
* not one MMSP has. With no base URL it is always the client's own `*_API_KEY`.
|
|
471
|
+
*/
|
|
472
|
+
declare function clientEnvKey(clientType: string, baseUrl: string | undefined): string | undefined;
|
|
473
|
+
/** The variables MMSP's routed client reads for a row as configured (see modelEnvironment). */
|
|
474
|
+
interface ModelEnvironment {
|
|
475
|
+
/** The key's variable: only for a row with no key in the file. */
|
|
476
|
+
apiKeyEnv?: string;
|
|
477
|
+
/** The endpoint's variable: only for a row with no base URL in the file. */
|
|
478
|
+
baseUrlEnv?: string;
|
|
479
|
+
/**
|
|
480
|
+
* Where that row's requests go while `baseUrlEnv` is unset: the routed client's default
|
|
481
|
+
* endpoint, as MMSP's credentials table records it. Present exactly when `baseUrlEnv` is.
|
|
482
|
+
*/
|
|
483
|
+
defaultBaseUrl?: string;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* What a row takes from the environment, as MMSP decides it (PRN-021). The row's effective
|
|
487
|
+
* connection (core's effectiveConnection) picks the client MMSP routes it to (`routedClientType`)
|
|
488
|
+
* and the base URL that client is handed; `environmentCredential` then says what the client
|
|
489
|
+
* reads. With no key in the file it reads its `*_API_KEY` only for no base URL or its own default
|
|
490
|
+
* endpoint, and with no base URL in the file it goes where its `*_BASE_URL` points, key or not.
|
|
491
|
+
* A row MMSP refuses (no key and another base URL), an open MMSP server and a row nothing routes
|
|
492
|
+
* read nothing. With no base URL in the file the row also names the endpoint its requests go to
|
|
493
|
+
* while that variable is unset (`defaultBaseUrl`). `entry` is the row's OWN values, key
|
|
494
|
+
* included, and `group` its `[providers.<id>]` table.
|
|
495
|
+
*/
|
|
496
|
+
declare function modelEnvironment(entry: ModelCredentialShape & {
|
|
497
|
+
apiKey?: string | undefined;
|
|
498
|
+
}, group: ProviderConnectionShape | undefined): ModelEnvironment;
|
|
499
|
+
/**
|
|
500
|
+
* The variable a row with no key in the file authenticates with, or undefined: modelEnvironment's
|
|
501
|
+
* `apiKeyEnv`. The server's `GET /models` preview, the web dialog's hint and the CLI's list read
|
|
502
|
+
* this, so none of them can disagree with what a Session does.
|
|
503
|
+
*/
|
|
504
|
+
declare function modelEnvPreviewKey(entry: ModelCredentialShape & {
|
|
505
|
+
apiKey?: string | undefined;
|
|
506
|
+
}, group: ProviderConnectionShape | undefined): string | undefined;
|
|
507
|
+
/**
|
|
508
|
+
* The variable a group's settings may present as covering a blank group key, or undefined —
|
|
509
|
+
* the group dialog's hint: what MMSP's client for the group (groupClientType) reads when handed
|
|
510
|
+
* no key at the group's base URL (clientEnvKey). A group with no one client names nothing.
|
|
511
|
+
*/
|
|
512
|
+
declare function providerEnvFallbackKey(providerId: string, group: Pick<ProviderConnectionShape, "baseUrl" | "clientType"> | undefined): string | undefined;
|
|
513
|
+
/**
|
|
514
|
+
* Whether a group with no key, and its client's variable unset, has its rows called without a
|
|
515
|
+
* key — the group dialog's "send no key" hint: MMSP's client for the group (groupClientType) at
|
|
516
|
+
* the group's base URL calls it keyless (calledKeyless). A group with no one client, and one
|
|
517
|
+
* keyed by a sign-in flow, answers no.
|
|
518
|
+
*/
|
|
519
|
+
declare function providerCalledKeyless(providerId: string, group: Pick<ProviderConnectionShape, "baseUrl" | "clientType"> | undefined): boolean;
|
|
520
|
+
/**
|
|
521
|
+
* Whether a row with no key of its own or its group's, and its client's variable unset, is
|
|
522
|
+
* called without a key — the model dialog's "send no key" hint: its routed client at its
|
|
523
|
+
* effective base URL calls it keyless (calledKeyless). A row of a sign-in-keyed group, and one
|
|
524
|
+
* nothing routes, answers no. `entry` is the row's OWN values, and `group` its table.
|
|
525
|
+
*/
|
|
526
|
+
declare function modelCalledKeyless(entry: ModelCredentialShape & {
|
|
527
|
+
apiKey?: string | undefined;
|
|
528
|
+
}, group: ProviderConnectionShape | undefined): boolean;
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* The catalog as a Project config seeds it: each built-in group's `[providers.<id>]` table, the
|
|
532
|
+
* preset rows (storing a protocol or endpoint only where it differs from the table beside it),
|
|
533
|
+
* the default model and the flat promotions — what the server writes when a Project is created,
|
|
534
|
+
* on "Add new models" and on "Restore defaults". Reference values: nothing reads them when a
|
|
535
|
+
* request is built.
|
|
536
|
+
*/
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* The connection the catalog gives a built-in group when a file is written from it — a new
|
|
540
|
+
* Project, "Add new models" for a group new to the file, "Restore defaults": its gateway
|
|
541
|
+
* endpoint (`gatewayBaseUrl`, else the one base URL every catalog row of the group carries)
|
|
542
|
+
* and its one protocol (the group's pin, providerClientType, else the one pin every catalog
|
|
543
|
+
* row of the group carries; canonical spelling). Retired rows count: the Projects that still
|
|
544
|
+
* carry one store its difference from the same table.
|
|
545
|
+
*
|
|
546
|
+
* Undefined for `custom` (it holds the user's own endpoints), for an id the catalog does not
|
|
547
|
+
* know, and for a group with neither — the first-party vendors, whose rows go to the
|
|
548
|
+
* client's defaults, so their keyless rows are handed no key and MMSP's client reads the
|
|
549
|
+
* vendor's environment variable (PRN-021). A reference value: nothing reads it when a request
|
|
550
|
+
* is built.
|
|
551
|
+
*/
|
|
552
|
+
declare function catalogGroupConnection(providerId: string): {
|
|
553
|
+
base_url?: string;
|
|
554
|
+
client_type?: string;
|
|
555
|
+
} | undefined;
|
|
556
|
+
/**
|
|
557
|
+
* The default model of a new Project: DeepSeek V4.1 Flash, which the vendor serves under the
|
|
558
|
+
* bare name `deepseek-flash` — the current generation of the Flash series, at the same price
|
|
559
|
+
* and schedule as the V4 rows it replaces, and it reads images, so a new Project can take a
|
|
560
|
+
* pasted screenshot without anyone having to notice why it could not. The bare id begins with
|
|
561
|
+
* the `deepseek-` family, so MMSP routes it to DeepSeek's official client without a pin. A
|
|
562
|
+
* Project's default is copied in at creation (the server's seed, and "Restore defaults") and
|
|
563
|
+
* owned by it from then on, so this reaches new Projects alone; an existing one keeps whatever
|
|
564
|
+
* it stored, and "Add new models" never touches the stored default. Its catalog row carries
|
|
565
|
+
* `wasDefault`, as every former default's does.
|
|
566
|
+
*/
|
|
567
|
+
declare const PRESET_DEFAULT_MODEL: Readonly<ModelRef>;
|
|
568
|
+
/**
|
|
569
|
+
* `[providers.<id>]` for every built-in group with a catalogGroupConnection, in the catalog's
|
|
570
|
+
* group order — what a new Project's file stores beside presetModelEntries' rows. A fresh
|
|
571
|
+
* object on every call, so a caller may change it.
|
|
572
|
+
*/
|
|
573
|
+
declare function presetProviderTable(): ProviderTable;
|
|
574
|
+
/**
|
|
575
|
+
* Catalog -> preset ModelEntry list (what the server seeds a new Project with and what
|
|
576
|
+
* "Add new models" and "Restore defaults" write, avoiding duplicate hand-written copies). `provider` and `model_id` are persisted as
|
|
577
|
+
* separate fields (`model_id` is the plain upstream id). The facts a row stores are the
|
|
578
|
+
* context window, the price and `vision = false`, plus the row's protocol and endpoint where
|
|
579
|
+
* they differ from its group's table in `groups` (catalogModelEntry): beside those tables, the
|
|
580
|
+
* file alone says where every request goes, and nothing is left for a resolver to fill from
|
|
581
|
+
* the catalog. `groups` is the `[providers]` table the rows will sit beside — a new Project's
|
|
582
|
+
* (presetProviderTable, the default), or the file's own when "Add new models" adds rows to an
|
|
583
|
+
* existing Project, so each added row resolves to its catalog connection whatever the user
|
|
584
|
+
* has set on its group. No secrets are included, so only an API key is needed.
|
|
585
|
+
*
|
|
586
|
+
* Pricing is written as the LIST price the catalog records (a scheduled row's PEAK price),
|
|
587
|
+
* never a discounted number. What is on disk then stays true whatever promotion is live and
|
|
588
|
+
* whatever hour the Project is created or re-synced in: a flat promotion is stored beside the
|
|
589
|
+
* file as a per-Project fraction (presetPromotions), and both it and an off-peak tier are
|
|
590
|
+
* applied when the price is read, by the models page and by the cost center alike.
|
|
591
|
+
*/
|
|
592
|
+
declare function presetModelEntries(groups?: ProviderTable): ModelEntry[];
|
|
593
|
+
/**
|
|
594
|
+
* Every catalog row as a ModelEntry, retired rows included, in the shape presetModelEntries
|
|
595
|
+
* writes: what a Project carrying a retired row stores for it beside a new Project's group
|
|
596
|
+
* tables (see ModelCatalogEntry.retired). `groups` as in presetModelEntries.
|
|
597
|
+
*/
|
|
598
|
+
declare function catalogModelEntries(groups?: ProviderTable): ModelEntry[];
|
|
599
|
+
/**
|
|
600
|
+
* The catalog's flat promotions, as a new Project is seeded with them: every row whose `discount`
|
|
601
|
+
* is a fraction in (0, 1). A retired row is skipped like it is in presetModelEntries: a new
|
|
602
|
+
* Project never carries it, so there is nothing for its promotion to apply to.
|
|
603
|
+
*/
|
|
604
|
+
declare function presetPromotions(): Array<{
|
|
605
|
+
provider: string;
|
|
606
|
+
modelId: string;
|
|
607
|
+
discount: number;
|
|
608
|
+
}>;
|
|
609
|
+
|
|
610
|
+
export { CLIENT_PROTOCOLS, DEEPSEEK_OFF_PEAK, type FastModeProtocol, MODELSCOPE_PROVIDER_ID, MODEL_CATALOG, MODEL_PROVIDERS, type ModelCatalogEntry, type ModelEnvironment, type ModelProviderBalance, type ModelProviderBridgeAuth, type ModelProviderInfo, type ModelProviderOAuth, type OffPeakDiscount, PENGUIN_GO_BASE_URL, PENGUIN_GO_PROVIDER_ID, PRESET_DEFAULT_MODEL, QWEN_OFF_PEAK, catalogEntryFor, catalogGroupConnection, catalogModelEntries, clientEnvKey, effectivePricing, fastModeProtocol, fixedClientType, fixedClientTypeRefuses, isAddableGroup, isVendorGroup, modelCalledKeyless, modelEnvPreviewKey, modelEnvironment, modelHomepageUrl, offPeakAt, offPeakScheduledRefs, presetModelEntries, presetPromotions, presetProviderTable, providerCalledKeyless, providerClientType, providerEnvFallbackKey, providerInfo, retainedCatalogPricing, unaddableModel, unroutableVendorModel, vendorClientType };
|