@tangle-network/cli-agent-registry 0.0.0-stage → 0.14.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/LICENSE +11 -0
- package/README.md +145 -2
- package/dist/backend-types-CJH-wHS3.d.mts +56 -0
- package/dist/backend-types-CREj4iOY.mjs +45 -0
- package/dist/backend-types.d.mts +2 -0
- package/dist/backend-types.mjs +2 -0
- package/dist/cli-auth-bundle.d.mts +49 -0
- package/dist/cli-auth-bundle.mjs +92 -0
- package/dist/cli-auth-placeholder.d.mts +54 -0
- package/dist/cli-auth-placeholder.mjs +200 -0
- package/dist/cli-backend-auth-env.d.mts +6 -0
- package/dist/cli-backend-auth-env.mjs +44 -0
- package/dist/default-backend.d.mts +24 -0
- package/dist/default-backend.mjs +31 -0
- package/dist/harness-DIdVNSwl.mjs +167 -0
- package/dist/index.d.mts +1400 -0
- package/dist/index.mjs +146 -0
- package/dist/local-cli-auth.d.mts +14 -0
- package/dist/local-cli-auth.mjs +31 -0
- package/dist/native-session-contracts-DWFzgoye.mjs +1162 -0
- package/dist/native-session-contracts.d.mts +354 -0
- package/dist/native-session-contracts.mjs +2 -0
- package/dist/servable-models.d.mts +104 -0
- package/dist/servable-models.mjs +147 -0
- package/dist/session-contract-BC75JdnA.d.mts +131 -0
- package/dist/session-contract.d.mts +2 -0
- package/dist/session-contract.mjs +190 -0
- package/dist/specs-BSELpX1h.d.mts +415 -0
- package/dist/specs-Bbiay_8K.mjs +704 -0
- package/dist/specs.d.mts +3 -0
- package/dist/specs.mjs +3 -0
- package/package.json +81 -3
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { o as NativeSessionStore } from "./session-contract-BC75JdnA.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/native-session-contracts.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The native session projection of the per-harness declarations in harness-contracts/. Each entry is
|
|
6
|
+
* proven by a conformance receipt (tests/harness/receipts) for
|
|
7
|
+
* its pinned CLI version, or is listed in HARNESS_CONFORMANCE_PENDING.
|
|
8
|
+
*
|
|
9
|
+
* CLI versions are the pins in infra/nix (agent-clis.json and flake.nix),
|
|
10
|
+
* generated into harness-cli-versions.ts by the bump. The registry test
|
|
11
|
+
* tests/harness-session-contract.test.ts fails when a pin, a contract or an
|
|
12
|
+
* adapter's source moves without a new receipt.
|
|
13
|
+
*/
|
|
14
|
+
declare const NATIVE_SESSION_CONTRACTS: {
|
|
15
|
+
readonly "claude-code": {
|
|
16
|
+
version: 1;
|
|
17
|
+
stores: [NativeSessionStore];
|
|
18
|
+
identity: {
|
|
19
|
+
kind: "pre-minted";
|
|
20
|
+
args: string[];
|
|
21
|
+
};
|
|
22
|
+
resume: {
|
|
23
|
+
kind: "args";
|
|
24
|
+
args: string[];
|
|
25
|
+
};
|
|
26
|
+
forbiddenArgs: string[];
|
|
27
|
+
storeEnv: {
|
|
28
|
+
CLAUDE_CONFIG_DIR: string;
|
|
29
|
+
};
|
|
30
|
+
evidence: {
|
|
31
|
+
servedModel: "provider-response";
|
|
32
|
+
usage: "per-response";
|
|
33
|
+
endingError: "session-record";
|
|
34
|
+
};
|
|
35
|
+
cliVersion: "2.1.311";
|
|
36
|
+
};
|
|
37
|
+
readonly codex: {
|
|
38
|
+
version: 1;
|
|
39
|
+
stores: [NativeSessionStore, NativeSessionStore];
|
|
40
|
+
identity: {
|
|
41
|
+
kind: "first-event";
|
|
42
|
+
event: string;
|
|
43
|
+
deadlineMs: number;
|
|
44
|
+
};
|
|
45
|
+
resume: {
|
|
46
|
+
kind: "args";
|
|
47
|
+
args: string[];
|
|
48
|
+
};
|
|
49
|
+
forbiddenArgs: string[];
|
|
50
|
+
storeEnv: {
|
|
51
|
+
CODEX_HOME: string;
|
|
52
|
+
};
|
|
53
|
+
evidence: {
|
|
54
|
+
servedModel: "turn-context";
|
|
55
|
+
usage: "cumulative";
|
|
56
|
+
endingError: "session-record";
|
|
57
|
+
};
|
|
58
|
+
cliVersion: "0.164.0";
|
|
59
|
+
};
|
|
60
|
+
readonly opencode: {
|
|
61
|
+
version: 1;
|
|
62
|
+
stores: [{
|
|
63
|
+
root: string;
|
|
64
|
+
files: string[];
|
|
65
|
+
write: "sqlite-wal";
|
|
66
|
+
shared: true;
|
|
67
|
+
format: "opencode.sqlite";
|
|
68
|
+
}];
|
|
69
|
+
identity: {
|
|
70
|
+
kind: "first-event";
|
|
71
|
+
event: string;
|
|
72
|
+
deadlineMs: number;
|
|
73
|
+
};
|
|
74
|
+
resume: {
|
|
75
|
+
kind: "args";
|
|
76
|
+
args: string[];
|
|
77
|
+
};
|
|
78
|
+
forbiddenArgs: never[];
|
|
79
|
+
storeEnv: {
|
|
80
|
+
XDG_DATA_HOME: string;
|
|
81
|
+
};
|
|
82
|
+
evidence: {
|
|
83
|
+
servedModel: "turn-context";
|
|
84
|
+
usage: "per-response";
|
|
85
|
+
endingError: "session-record";
|
|
86
|
+
};
|
|
87
|
+
cliVersion: "1.19.4";
|
|
88
|
+
};
|
|
89
|
+
readonly pi: {
|
|
90
|
+
version: 1;
|
|
91
|
+
stores: [{
|
|
92
|
+
root: string;
|
|
93
|
+
files: string[];
|
|
94
|
+
write: "jsonl-append";
|
|
95
|
+
shared: false;
|
|
96
|
+
format: "pi.session-jsonl";
|
|
97
|
+
}];
|
|
98
|
+
identity: {
|
|
99
|
+
kind: "pre-minted";
|
|
100
|
+
args: string[];
|
|
101
|
+
};
|
|
102
|
+
resume: {
|
|
103
|
+
kind: "args";
|
|
104
|
+
args: string[];
|
|
105
|
+
};
|
|
106
|
+
forbiddenArgs: string[];
|
|
107
|
+
storeEnv: {
|
|
108
|
+
PI_CODING_AGENT_DIR: string;
|
|
109
|
+
PI_CODING_AGENT_SESSION_DIR: string;
|
|
110
|
+
"--session-dir": string;
|
|
111
|
+
};
|
|
112
|
+
evidence: {
|
|
113
|
+
servedModel: "session-record";
|
|
114
|
+
usage: "per-response";
|
|
115
|
+
endingError: "session-record";
|
|
116
|
+
};
|
|
117
|
+
cliVersion: "1.4.0";
|
|
118
|
+
};
|
|
119
|
+
readonly "kimi-code": {
|
|
120
|
+
version: 1;
|
|
121
|
+
stores: [NativeSessionStore];
|
|
122
|
+
identity: {
|
|
123
|
+
kind: "pre-minted";
|
|
124
|
+
args: string[];
|
|
125
|
+
};
|
|
126
|
+
resume: {
|
|
127
|
+
kind: "args";
|
|
128
|
+
args: string[];
|
|
129
|
+
};
|
|
130
|
+
forbiddenArgs: never[];
|
|
131
|
+
storeEnv: {};
|
|
132
|
+
evidence: {
|
|
133
|
+
servedModel: "session-record";
|
|
134
|
+
usage: "per-response";
|
|
135
|
+
endingError: "none";
|
|
136
|
+
};
|
|
137
|
+
cliVersion: "1.49.0";
|
|
138
|
+
};
|
|
139
|
+
readonly "factory-droids": {
|
|
140
|
+
version: 1;
|
|
141
|
+
stores: [{
|
|
142
|
+
root: string;
|
|
143
|
+
files: string[];
|
|
144
|
+
write: "jsonl-append";
|
|
145
|
+
shared: false;
|
|
146
|
+
format: "factory.session-jsonl";
|
|
147
|
+
}, {
|
|
148
|
+
root: string;
|
|
149
|
+
files: string[];
|
|
150
|
+
write: "json-rewrite";
|
|
151
|
+
shared: false;
|
|
152
|
+
format: "factory.session-jsonl";
|
|
153
|
+
}];
|
|
154
|
+
identity: {
|
|
155
|
+
kind: "first-event";
|
|
156
|
+
event: string;
|
|
157
|
+
deadlineMs: number;
|
|
158
|
+
};
|
|
159
|
+
resume: {
|
|
160
|
+
kind: "args";
|
|
161
|
+
args: string[];
|
|
162
|
+
};
|
|
163
|
+
forbiddenArgs: never[];
|
|
164
|
+
storeEnv: {};
|
|
165
|
+
evidence: {
|
|
166
|
+
servedModel: "turn-context";
|
|
167
|
+
usage: "session-total";
|
|
168
|
+
endingError: "none";
|
|
169
|
+
};
|
|
170
|
+
cliVersion: "0.249.0";
|
|
171
|
+
};
|
|
172
|
+
readonly amp: {
|
|
173
|
+
version: 1;
|
|
174
|
+
stores: [{
|
|
175
|
+
root: string;
|
|
176
|
+
files: string[];
|
|
177
|
+
write: "json-rewrite";
|
|
178
|
+
shared: false;
|
|
179
|
+
format: "amp.thread-json";
|
|
180
|
+
}];
|
|
181
|
+
identity: {
|
|
182
|
+
kind: "first-event";
|
|
183
|
+
event: string;
|
|
184
|
+
deadlineMs: number;
|
|
185
|
+
};
|
|
186
|
+
resume: {
|
|
187
|
+
kind: "args";
|
|
188
|
+
args: string[];
|
|
189
|
+
};
|
|
190
|
+
forbiddenArgs: never[];
|
|
191
|
+
storeEnv: {
|
|
192
|
+
XDG_DATA_HOME: string;
|
|
193
|
+
};
|
|
194
|
+
evidence: {
|
|
195
|
+
servedModel: "session-record";
|
|
196
|
+
usage: "per-response";
|
|
197
|
+
endingError: "none";
|
|
198
|
+
};
|
|
199
|
+
cliVersion: "0.0.1793044831-ga1b1a0";
|
|
200
|
+
};
|
|
201
|
+
readonly prime: {
|
|
202
|
+
version: 1;
|
|
203
|
+
stores: [{
|
|
204
|
+
root: string;
|
|
205
|
+
files: string[];
|
|
206
|
+
write: "jsonl-append";
|
|
207
|
+
shared: false;
|
|
208
|
+
format: "prime.session-jsonl";
|
|
209
|
+
}];
|
|
210
|
+
identity: {
|
|
211
|
+
kind: "api-created";
|
|
212
|
+
call: "acp session/new";
|
|
213
|
+
};
|
|
214
|
+
resume: {
|
|
215
|
+
kind: "api";
|
|
216
|
+
};
|
|
217
|
+
forbiddenArgs: string[];
|
|
218
|
+
storeEnv: {};
|
|
219
|
+
evidence: {
|
|
220
|
+
servedModel: "session-record";
|
|
221
|
+
usage: "per-response";
|
|
222
|
+
endingError: "session-record";
|
|
223
|
+
};
|
|
224
|
+
cliVersion: "0.10.1";
|
|
225
|
+
};
|
|
226
|
+
readonly hermes: {
|
|
227
|
+
version: 1;
|
|
228
|
+
stores: [NativeSessionStore];
|
|
229
|
+
identity: {
|
|
230
|
+
kind: "first-event";
|
|
231
|
+
event: string;
|
|
232
|
+
deadlineMs: number;
|
|
233
|
+
};
|
|
234
|
+
resume: {
|
|
235
|
+
kind: "args";
|
|
236
|
+
args: string[];
|
|
237
|
+
};
|
|
238
|
+
forbiddenArgs: never[];
|
|
239
|
+
storeEnv: {
|
|
240
|
+
HERMES_HOME: string;
|
|
241
|
+
};
|
|
242
|
+
evidence: {
|
|
243
|
+
servedModel: "session-record";
|
|
244
|
+
usage: "session-total";
|
|
245
|
+
endingError: "none";
|
|
246
|
+
};
|
|
247
|
+
cliVersion: "0.22.4";
|
|
248
|
+
};
|
|
249
|
+
readonly forge: {
|
|
250
|
+
version: 1;
|
|
251
|
+
stores: [{
|
|
252
|
+
root: string;
|
|
253
|
+
files: string[];
|
|
254
|
+
write: "sqlite-wal";
|
|
255
|
+
shared: true;
|
|
256
|
+
format: "forge.sqlite";
|
|
257
|
+
}];
|
|
258
|
+
identity: {
|
|
259
|
+
kind: "first-event";
|
|
260
|
+
event: string;
|
|
261
|
+
deadlineMs: number;
|
|
262
|
+
};
|
|
263
|
+
resume: {
|
|
264
|
+
kind: "args";
|
|
265
|
+
args: string[];
|
|
266
|
+
};
|
|
267
|
+
forbiddenArgs: never[];
|
|
268
|
+
storeEnv: {};
|
|
269
|
+
evidence: {
|
|
270
|
+
servedModel: "session-record";
|
|
271
|
+
usage: "per-response";
|
|
272
|
+
endingError: "none";
|
|
273
|
+
};
|
|
274
|
+
cliVersion: "2.14.0";
|
|
275
|
+
};
|
|
276
|
+
readonly openclaw: {
|
|
277
|
+
version: 1;
|
|
278
|
+
stores: [{
|
|
279
|
+
root: string;
|
|
280
|
+
files: string[];
|
|
281
|
+
write: "jsonl-append";
|
|
282
|
+
shared: false;
|
|
283
|
+
format: "openclaw.session-jsonl";
|
|
284
|
+
}];
|
|
285
|
+
identity: {
|
|
286
|
+
kind: "first-event";
|
|
287
|
+
event: string;
|
|
288
|
+
deadlineMs: number;
|
|
289
|
+
};
|
|
290
|
+
resume: {
|
|
291
|
+
kind: "args";
|
|
292
|
+
args: string[];
|
|
293
|
+
};
|
|
294
|
+
forbiddenArgs: never[];
|
|
295
|
+
storeEnv: {};
|
|
296
|
+
evidence: {
|
|
297
|
+
servedModel: "session-record";
|
|
298
|
+
usage: "per-response";
|
|
299
|
+
endingError: "none";
|
|
300
|
+
};
|
|
301
|
+
cliVersion: "2026.10.7";
|
|
302
|
+
};
|
|
303
|
+
readonly acp: {
|
|
304
|
+
version: 1;
|
|
305
|
+
stores: [NativeSessionStore, NativeSessionStore, NativeSessionStore, NativeSessionStore, NativeSessionStore];
|
|
306
|
+
identity: {
|
|
307
|
+
kind: "api-created";
|
|
308
|
+
call: "acp session/new";
|
|
309
|
+
};
|
|
310
|
+
resume: {
|
|
311
|
+
kind: "api";
|
|
312
|
+
};
|
|
313
|
+
forbiddenArgs: never[];
|
|
314
|
+
storeEnv: {};
|
|
315
|
+
evidence: {
|
|
316
|
+
servedModel: "session-record";
|
|
317
|
+
usage: "per-response";
|
|
318
|
+
endingError: "none";
|
|
319
|
+
};
|
|
320
|
+
cliVersion: "claude-agent-acp 0.97.0; codex-acp 0.16.0; gemini-cli 0.65.0";
|
|
321
|
+
};
|
|
322
|
+
};
|
|
323
|
+
/**
|
|
324
|
+
* The child environment of a harness whose contract can move every native
|
|
325
|
+
* store off HOME, or undefined when it cannot.
|
|
326
|
+
*
|
|
327
|
+
* HOME becomes the shared agent home, so toolchains and repos the agent puts
|
|
328
|
+
* under ~ persist across sessions and restarts. Each declared store env and
|
|
329
|
+
* the XDG roots stay in the private runtime home, so credentials, config and
|
|
330
|
+
* session records do not collide between sessions. A harness whose contract
|
|
331
|
+
* declares no store env (kimi-code, factory-droids, forge, openclaw, acp,
|
|
332
|
+
* prime) writes credentials straight under HOME and keeps the private HOME.
|
|
333
|
+
* So does OpenCode: its warm-server pool, spare adoption, plugin dependencies
|
|
334
|
+
* and correlation file all use HOME as the session's runtime identity, and a
|
|
335
|
+
* shared HOME would merge those identities across sessions.
|
|
336
|
+
*/
|
|
337
|
+
declare function configDirHomeEnv(harness: string, runtimeHome: string, agentHome: string): Record<string, string> | undefined;
|
|
338
|
+
/**
|
|
339
|
+
* Harnesses whose declared contract has no conformance receipt yet, with
|
|
340
|
+
* the reason. They keep running with persistence-disabling flags refused,
|
|
341
|
+
* but the store-location and identity-deadline checks wait for their
|
|
342
|
+
* receipt. This list may only shrink: tests/harness-session-contract.test.ts
|
|
343
|
+
* fails on a new entry, and on an entry whose receipt now passes.
|
|
344
|
+
*/
|
|
345
|
+
declare const HARNESS_CONFORMANCE_PENDING: Readonly<Record<string, string>>;
|
|
346
|
+
/**
|
|
347
|
+
* Harnesses that cannot meet the contract at all. They stay listed until
|
|
348
|
+
* their product surfaces (sandbox web launch list, CLI connect, SDK
|
|
349
|
+
* placement) drop them, and no capture claims their sessions.
|
|
350
|
+
*/
|
|
351
|
+
declare const HARNESS_SESSION_UNSUPPORTED: Readonly<Record<string, string>>;
|
|
352
|
+
//#endregion
|
|
353
|
+
export { HARNESS_CONFORMANCE_PENDING, HARNESS_SESSION_UNSUPPORTED, NATIVE_SESSION_CONTRACTS, configDirHomeEnv };
|
|
354
|
+
//# sourceMappingURL=native-session-contracts.d.mts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { i as configDirHomeEnv, n as HARNESS_SESSION_UNSUPPORTED, r as NATIVE_SESSION_CONTRACTS, t as HARNESS_CONFORMANCE_PENDING } from "./native-session-contracts-DWFzgoye.mjs";
|
|
2
|
+
export { HARNESS_CONFORMANCE_PENDING, HARNESS_SESSION_UNSUPPORTED, NATIVE_SESSION_CONTRACTS, configDirHomeEnv };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { HarnessModelSupportOptions } from "@tangle-network/agent-interface/harness-capabilities";
|
|
2
|
+
|
|
3
|
+
//#region src/servable-models.d.ts
|
|
4
|
+
/** One reviewed rung of {@link MANAGED_MODEL_LADDER}. */
|
|
5
|
+
interface ManagedModelRung {
|
|
6
|
+
/** Provider-qualified id the Tangle Router routes verbatim. */
|
|
7
|
+
id: string;
|
|
8
|
+
/** Why this rung sits where it does: serving state and price when reviewed. */
|
|
9
|
+
reason: string;
|
|
10
|
+
/** ISO date the rung was checked against the live `GET /v1/models`. */
|
|
11
|
+
reviewedAt: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The models a managed (Tangle-funded) run may default to, most preferred
|
|
15
|
+
* first. Every managed default in the platform is the first rung a harness can
|
|
16
|
+
* run ({@link managedModelChain}), so this list is the one place a default
|
|
17
|
+
* model is chosen.
|
|
18
|
+
*
|
|
19
|
+
* A managed run sends its model id to the Tangle router, which answers only
|
|
20
|
+
* when BOTH of these hold:
|
|
21
|
+
*
|
|
22
|
+
* 1. the router routes the id — it appears in `GET /v1/models` with
|
|
23
|
+
* `routeability.routeable = true`; and
|
|
24
|
+
* 2. the router holds a spend-authorizing price for the id — a
|
|
25
|
+
* `ProviderPriceVersion` row whose `authority` is `provider_official` or
|
|
26
|
+
* `operator_reviewed`. Third-party price observations are recorded but
|
|
27
|
+
* cannot authorize spend, so they do not count.
|
|
28
|
+
*
|
|
29
|
+
* A model that fails either test answers 503 `provider_pricing_unavailable`
|
|
30
|
+
* to a Tangle-funded call. A CLI reads 503 as transient and retries until its
|
|
31
|
+
* own timeout, so the run produces no output and no error for many minutes.
|
|
32
|
+
* That is why an unservable default is worse than a wrong one: it does not
|
|
33
|
+
* fail, it hangs.
|
|
34
|
+
*
|
|
35
|
+
* Which models a harness can run is not decided here: the capability table
|
|
36
|
+
* ({@link harnessModelSupportFor}) drops the rungs a harness refuses (a vendor
|
|
37
|
+
* lock, measured exclusions). claude-code and codex run the whole ladder: the
|
|
38
|
+
* router translates every non-vendor model on their Messages and Responses
|
|
39
|
+
* wires to chat completions, so they lead with the same cheapest rung as every
|
|
40
|
+
* other Router-backed harness. A rung exists for a vendor-locked harness when
|
|
41
|
+
* it is the only model that harness can run (kimi-code runs Moonshot).
|
|
42
|
+
*/
|
|
43
|
+
declare const MANAGED_MODEL_LADDER: readonly ManagedModelRung[];
|
|
44
|
+
/** The bare id a provider-prefixed model id carries. */
|
|
45
|
+
declare function bareModelId(modelId: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Whether a managed default may use this id. Accepts the provider-prefixed
|
|
48
|
+
* form and the bare form, because a harness on a provider-native wire sends
|
|
49
|
+
* the bare id its own CLI expects.
|
|
50
|
+
*/
|
|
51
|
+
declare function isServableManagedModel(modelId: string): boolean;
|
|
52
|
+
interface ManagedModelChainOptions {
|
|
53
|
+
/**
|
|
54
|
+
* The model the caller or its profile named. It is returned alone and never
|
|
55
|
+
* substituted: a named model that cannot run fails loud where it is checked.
|
|
56
|
+
*/
|
|
57
|
+
named?: string;
|
|
58
|
+
/**
|
|
59
|
+
* The operator's configured model (a deployment's `OPENCODE_MODEL_NAME` or
|
|
60
|
+
* `TANGLE_ROUTER_MODEL`), tried ahead of the ladder when the harness runs it.
|
|
61
|
+
*/
|
|
62
|
+
operatorModel?: string;
|
|
63
|
+
/** The run's reasoning effort; some harness × model pairs fail only with one. */
|
|
64
|
+
reasoningEffort?: HarnessModelSupportOptions["reasoningEffort"];
|
|
65
|
+
/**
|
|
66
|
+
* The models the box's Router key allows (Platform's `allowedModels` on the
|
|
67
|
+
* minted key); absent or null allows every model. A default the key refuses
|
|
68
|
+
* fails the box's first turn with `model_not_allowed`, so the chain keeps
|
|
69
|
+
* only allowed ladder rungs, spelled as the key spells them, then the key's
|
|
70
|
+
* other models.
|
|
71
|
+
*/
|
|
72
|
+
allowedModels?: readonly string[] | null;
|
|
73
|
+
}
|
|
74
|
+
/** A model the chain left out, and why. */
|
|
75
|
+
interface SkippedManagedModel {
|
|
76
|
+
id: string;
|
|
77
|
+
reason: string;
|
|
78
|
+
}
|
|
79
|
+
type ManagedModelChain = {
|
|
80
|
+
ok: true;
|
|
81
|
+
chain: string[];
|
|
82
|
+
skipped: SkippedManagedModel[];
|
|
83
|
+
} | {
|
|
84
|
+
ok: false;
|
|
85
|
+
chain: [];
|
|
86
|
+
skipped: SkippedManagedModel[]; /** One sentence a create or run refusal can show as-is. */
|
|
87
|
+
message: string;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* The ordered models a managed run of `harness` may use, first choice first.
|
|
91
|
+
* Every managed default site takes `chain[0]`; the rest is the order a later
|
|
92
|
+
* fallback would try.
|
|
93
|
+
*
|
|
94
|
+
* - A named model is the whole chain.
|
|
95
|
+
* - A harness the Router cannot serve (`CliAgentSpec.callerCredentialOnly`)
|
|
96
|
+
* has no managed chain: its CLI calls its vendor's own service, so it runs
|
|
97
|
+
* only on the caller's own credential.
|
|
98
|
+
* - Otherwise the operator's model, then {@link MANAGED_MODEL_LADDER}, keeping
|
|
99
|
+
* only the ids the capability table lets this harness run.
|
|
100
|
+
*/
|
|
101
|
+
declare function managedModelChain(harness: string, options?: ManagedModelChainOptions): ManagedModelChain;
|
|
102
|
+
//#endregion
|
|
103
|
+
export { MANAGED_MODEL_LADDER, ManagedModelChain, ManagedModelChainOptions, ManagedModelRung, SkippedManagedModel, bareModelId, isServableManagedModel, managedModelChain };
|
|
104
|
+
//# sourceMappingURL=servable-models.d.mts.map
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { l as getSpec, m as harnessModelSupportFor } from "./specs-Bbiay_8K.mjs";
|
|
2
|
+
//#region src/servable-models.ts
|
|
3
|
+
/**
|
|
4
|
+
* The models a managed (Tangle-funded) run may default to, most preferred
|
|
5
|
+
* first. Every managed default in the platform is the first rung a harness can
|
|
6
|
+
* run ({@link managedModelChain}), so this list is the one place a default
|
|
7
|
+
* model is chosen.
|
|
8
|
+
*
|
|
9
|
+
* A managed run sends its model id to the Tangle router, which answers only
|
|
10
|
+
* when BOTH of these hold:
|
|
11
|
+
*
|
|
12
|
+
* 1. the router routes the id — it appears in `GET /v1/models` with
|
|
13
|
+
* `routeability.routeable = true`; and
|
|
14
|
+
* 2. the router holds a spend-authorizing price for the id — a
|
|
15
|
+
* `ProviderPriceVersion` row whose `authority` is `provider_official` or
|
|
16
|
+
* `operator_reviewed`. Third-party price observations are recorded but
|
|
17
|
+
* cannot authorize spend, so they do not count.
|
|
18
|
+
*
|
|
19
|
+
* A model that fails either test answers 503 `provider_pricing_unavailable`
|
|
20
|
+
* to a Tangle-funded call. A CLI reads 503 as transient and retries until its
|
|
21
|
+
* own timeout, so the run produces no output and no error for many minutes.
|
|
22
|
+
* That is why an unservable default is worse than a wrong one: it does not
|
|
23
|
+
* fail, it hangs.
|
|
24
|
+
*
|
|
25
|
+
* Which models a harness can run is not decided here: the capability table
|
|
26
|
+
* ({@link harnessModelSupportFor}) drops the rungs a harness refuses (a vendor
|
|
27
|
+
* lock, measured exclusions). claude-code and codex run the whole ladder: the
|
|
28
|
+
* router translates every non-vendor model on their Messages and Responses
|
|
29
|
+
* wires to chat completions, so they lead with the same cheapest rung as every
|
|
30
|
+
* other Router-backed harness. A rung exists for a vendor-locked harness when
|
|
31
|
+
* it is the only model that harness can run (kimi-code runs Moonshot).
|
|
32
|
+
*/
|
|
33
|
+
const MANAGED_MODEL_LADDER = [
|
|
34
|
+
{
|
|
35
|
+
id: "google/gemini-2.5-flash-lite",
|
|
36
|
+
reason: "available, $0.10/$0.40 per Mtok; the production canary passes on it",
|
|
37
|
+
reviewedAt: "2026-10-14"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: "zai/glm-5.3",
|
|
41
|
+
reason: "degraded but served by zai direct (200 on chat/completions)",
|
|
42
|
+
reviewedAt: "2026-10-14"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "google/gemini-2.5-flash",
|
|
46
|
+
reason: "available",
|
|
47
|
+
reviewedAt: "2026-10-14"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "deepseek/deepseek-chat",
|
|
51
|
+
reason: "routeable and priced; no recent dispatch",
|
|
52
|
+
reviewedAt: "2026-10-14"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "moonshot/kimi-k3",
|
|
56
|
+
reason: "kimi-code's first rung (Moonshot-locked); Moonshot and Together quota-exhausted when reviewed",
|
|
57
|
+
reviewedAt: "2026-10-14"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "moonshot/kimi-k2.7-code",
|
|
61
|
+
reason: "Moonshot direct coding model; quota-exhausted when reviewed",
|
|
62
|
+
reviewedAt: "2026-10-14"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: "moonshotai/kimi-k2-0905",
|
|
66
|
+
reason: "served through OpenRouter; no recent dispatch",
|
|
67
|
+
reviewedAt: "2026-10-14"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "openai/gpt-6-luna",
|
|
71
|
+
reason: "the router's tangle/cheap role; no recent dispatch",
|
|
72
|
+
reviewedAt: "2026-10-14"
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
/** The bare id a provider-prefixed model id carries. */
|
|
76
|
+
function bareModelId(modelId) {
|
|
77
|
+
const slash = modelId.lastIndexOf("/");
|
|
78
|
+
return slash < 0 ? modelId : modelId.slice(slash + 1);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Whether a managed default may use this id. Accepts the provider-prefixed
|
|
82
|
+
* form and the bare form, because a harness on a provider-native wire sends
|
|
83
|
+
* the bare id its own CLI expects.
|
|
84
|
+
*/
|
|
85
|
+
function isServableManagedModel(modelId) {
|
|
86
|
+
const candidate = modelId.trim();
|
|
87
|
+
if (!candidate) return false;
|
|
88
|
+
const bare = bareModelId(candidate);
|
|
89
|
+
return MANAGED_MODEL_LADDER.some((rung) => rung.id === candidate || bareModelId(rung.id) === bare);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The ordered models a managed run of `harness` may use, first choice first.
|
|
93
|
+
* Every managed default site takes `chain[0]`; the rest is the order a later
|
|
94
|
+
* fallback would try.
|
|
95
|
+
*
|
|
96
|
+
* - A named model is the whole chain.
|
|
97
|
+
* - A harness the Router cannot serve (`CliAgentSpec.callerCredentialOnly`)
|
|
98
|
+
* has no managed chain: its CLI calls its vendor's own service, so it runs
|
|
99
|
+
* only on the caller's own credential.
|
|
100
|
+
* - Otherwise the operator's model, then {@link MANAGED_MODEL_LADDER}, keeping
|
|
101
|
+
* only the ids the capability table lets this harness run.
|
|
102
|
+
*/
|
|
103
|
+
function managedModelChain(harness, options = {}) {
|
|
104
|
+
if (getSpec(harness)?.callerCredentialOnly) return {
|
|
105
|
+
ok: false,
|
|
106
|
+
chain: [],
|
|
107
|
+
skipped: [],
|
|
108
|
+
message: `${harness} cannot run on Tangle Router: its CLI calls its vendor's own service, so it runs only on the caller's own credential.`
|
|
109
|
+
};
|
|
110
|
+
const named = options.named?.trim();
|
|
111
|
+
if (named) return {
|
|
112
|
+
ok: true,
|
|
113
|
+
chain: [named],
|
|
114
|
+
skipped: []
|
|
115
|
+
};
|
|
116
|
+
const preferred = [options.operatorModel?.trim(), ...MANAGED_MODEL_LADDER.map((rung) => rung.id)].filter((id) => Boolean(id));
|
|
117
|
+
const allowed = options.allowedModels?.map((id) => id.trim()).filter(Boolean);
|
|
118
|
+
const candidates = allowed ? [...preferred.flatMap((id) => {
|
|
119
|
+
const match = allowed.find((entry) => entry === id) ?? allowed.find((entry) => bareModelId(entry) === bareModelId(id));
|
|
120
|
+
return match ? [match] : [];
|
|
121
|
+
}), ...allowed] : preferred;
|
|
122
|
+
const chain = [];
|
|
123
|
+
const skipped = [];
|
|
124
|
+
for (const id of new Set(candidates)) {
|
|
125
|
+
const support = harnessModelSupportFor(harness, id, { reasoningEffort: options.reasoningEffort });
|
|
126
|
+
if (support.supported) chain.push(id);
|
|
127
|
+
else skipped.push({
|
|
128
|
+
id,
|
|
129
|
+
reason: support.message
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
if (chain.length > 0) return {
|
|
133
|
+
ok: true,
|
|
134
|
+
chain,
|
|
135
|
+
skipped
|
|
136
|
+
};
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
chain: [],
|
|
140
|
+
skipped,
|
|
141
|
+
message: `No managed model can run on ${harness}: ` + skipped.map((entry) => `${entry.id} (${entry.reason})`).join("; ")
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
export { MANAGED_MODEL_LADDER, bareModelId, isServableManagedModel, managedModelChain };
|
|
146
|
+
|
|
147
|
+
//# sourceMappingURL=servable-models.mjs.map
|