@namzu/sdk 21.0.0 → 22.0.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/CHANGELOG.md +134 -0
- package/dist/advisory/executor.d.ts +9 -4
- package/dist/advisory/executor.d.ts.map +1 -1
- package/dist/advisory/executor.js +16 -9
- package/dist/advisory/executor.js.map +1 -1
- package/dist/constants/limits.d.ts +13 -0
- package/dist/constants/limits.d.ts.map +1 -1
- package/dist/constants/limits.js +14 -2
- package/dist/constants/limits.js.map +1 -1
- package/dist/manager/agent/lifecycle.d.ts +2 -2
- package/dist/manager/run/persistence.d.ts +37 -2
- package/dist/manager/run/persistence.d.ts.map +1 -1
- package/dist/manager/run/persistence.js +48 -7
- package/dist/manager/run/persistence.js.map +1 -1
- package/dist/pricing/catalogue.generated.d.ts +15 -0
- package/dist/pricing/catalogue.generated.d.ts.map +1 -0
- package/dist/pricing/catalogue.generated.js +293 -0
- package/dist/pricing/catalogue.generated.js.map +1 -0
- package/dist/pricing/index.d.ts +46 -0
- package/dist/pricing/index.d.ts.map +1 -0
- package/dist/pricing/index.js +70 -0
- package/dist/pricing/index.js.map +1 -0
- package/dist/public-runtime.d.ts +6 -1
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +21 -1
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-types.d.ts +3 -1
- package/dist/public-types.d.ts.map +1 -1
- package/dist/run/LimitChecker.d.ts +10 -0
- package/dist/run/LimitChecker.d.ts.map +1 -1
- package/dist/run/LimitChecker.js +14 -2
- package/dist/run/LimitChecker.js.map +1 -1
- package/dist/run/command-gate.d.ts +107 -0
- package/dist/run/command-gate.d.ts.map +1 -0
- package/dist/run/command-gate.js +157 -0
- package/dist/run/command-gate.js.map +1 -0
- package/dist/run/index.d.ts +6 -0
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +3 -0
- package/dist/run/index.js.map +1 -1
- package/dist/run/memory-promoter.d.ts +70 -0
- package/dist/run/memory-promoter.d.ts.map +1 -0
- package/dist/run/memory-promoter.js +117 -0
- package/dist/run/memory-promoter.js.map +1 -0
- package/dist/run/workspace-fingerprint.d.ts +105 -0
- package/dist/run/workspace-fingerprint.d.ts.map +1 -0
- package/dist/run/workspace-fingerprint.js +147 -0
- package/dist/run/workspace-fingerprint.js.map +1 -0
- package/dist/runtime/query/checkpoint.d.ts +23 -2
- package/dist/runtime/query/checkpoint.d.ts.map +1 -1
- package/dist/runtime/query/checkpoint.js +24 -3
- package/dist/runtime/query/checkpoint.js.map +1 -1
- package/dist/runtime/query/guard.d.ts.map +1 -1
- package/dist/runtime/query/guard.js +1 -0
- package/dist/runtime/query/guard.js.map +1 -1
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +42 -0
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +15 -2
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/advisory.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/advisory.js +9 -1
- package/dist/runtime/query/iteration/phases/advisory.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +11 -2
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/store/run/conformance.d.ts.map +1 -1
- package/dist/store/run/conformance.js +8 -2
- package/dist/store/run/conformance.js.map +1 -1
- package/dist/types/common/index.d.ts +38 -2
- package/dist/types/common/index.d.ts.map +1 -1
- package/dist/types/run/stop-reason.d.ts +31 -1
- package/dist/types/run/stop-reason.d.ts.map +1 -1
- package/dist/utils/cost.d.ts +60 -2
- package/dist/utils/cost.d.ts.map +1 -1
- package/dist/utils/cost.js +126 -11
- package/dist/utils/cost.js.map +1 -1
- package/package.json +1 -1
- package/src/advisory/executor.ts +16 -9
- package/src/constants/limits.ts +14 -2
- package/src/manager/agent/lifecycle.ts +2 -2
- package/src/manager/run/persistence.ts +67 -7
- package/src/pricing/catalogue.generated.ts +308 -0
- package/src/pricing/index.ts +78 -0
- package/src/pricing/rates.source.json +206 -0
- package/src/public-runtime.ts +39 -0
- package/src/public-types.ts +3 -1
- package/src/run/LimitChecker.ts +24 -2
- package/src/run/command-gate.ts +234 -0
- package/src/run/index.ts +17 -0
- package/src/run/memory-promoter.ts +155 -0
- package/src/run/workspace-fingerprint.ts +193 -0
- package/src/runtime/query/checkpoint.ts +24 -3
- package/src/runtime/query/guard.ts +1 -0
- package/src/runtime/query/index.ts +42 -0
- package/src/runtime/query/iteration/index.ts +15 -2
- package/src/runtime/query/iteration/phases/advisory.ts +9 -1
- package/src/runtime/query/iteration/phases/compaction.ts +12 -2
- package/src/store/run/conformance.ts +8 -2
- package/src/types/common/index.ts +38 -2
- package/src/types/run/stop-reason.ts +30 -0
- package/src/utils/cost.ts +186 -16
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
// GENERATED FILE — DO NOT EDIT.
|
|
2
|
+
//
|
|
3
|
+
// Produced by `node scripts/generate-model-prices.mjs` from
|
|
4
|
+
// `packages/sdk/src/pricing/rates.source.json`, which is the file to edit.
|
|
5
|
+
// CI re-runs the generator and fails on any difference, so a hand edit here is
|
|
6
|
+
// reverted by the next run at best and reported as drift at worst.
|
|
7
|
+
//
|
|
8
|
+
// 4 vendors, 32 priced models.
|
|
9
|
+
|
|
10
|
+
import type { ModelPricing } from '../utils/cost.js'
|
|
11
|
+
|
|
12
|
+
export interface VendorRates {
|
|
13
|
+
/** Matched against `LLMProvider.id`. */
|
|
14
|
+
readonly providerId: string
|
|
15
|
+
/**
|
|
16
|
+
* This driver bills nothing for a token, whatever the model — local
|
|
17
|
+
* inference. Its runs are priced at zero, which is KNOWN-free and so
|
|
18
|
+
* distinct from a model nobody has a rate for.
|
|
19
|
+
*/
|
|
20
|
+
readonly unmetered: boolean
|
|
21
|
+
/** Keyed by normalised model id. Empty when `unmetered`. */
|
|
22
|
+
readonly models: ReadonlyMap<string, ModelPricing>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const VENDOR_RATES: readonly VendorRates[] = [
|
|
26
|
+
{
|
|
27
|
+
providerId: 'anthropic',
|
|
28
|
+
unmetered: false,
|
|
29
|
+
models: new Map([
|
|
30
|
+
[
|
|
31
|
+
'claude-fable-5',
|
|
32
|
+
{
|
|
33
|
+
inputCostPer1M: 10,
|
|
34
|
+
outputCostPer1M: 50,
|
|
35
|
+
cache: { promptIncludesCacheReads: false, readCostPer1M: 1, writeCostPer1M: 12.5 },
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
[
|
|
39
|
+
'claude-haiku-4-5',
|
|
40
|
+
{
|
|
41
|
+
inputCostPer1M: 1,
|
|
42
|
+
outputCostPer1M: 5,
|
|
43
|
+
cache: { promptIncludesCacheReads: false, readCostPer1M: 0.1, writeCostPer1M: 1.25 },
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
[
|
|
47
|
+
'claude-mythos-5',
|
|
48
|
+
{
|
|
49
|
+
inputCostPer1M: 10,
|
|
50
|
+
outputCostPer1M: 50,
|
|
51
|
+
cache: { promptIncludesCacheReads: false, readCostPer1M: 1, writeCostPer1M: 12.5 },
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
'claude-opus-4-1',
|
|
56
|
+
{
|
|
57
|
+
inputCostPer1M: 15,
|
|
58
|
+
outputCostPer1M: 75,
|
|
59
|
+
cache: { promptIncludesCacheReads: false, readCostPer1M: 1.5, writeCostPer1M: 18.75 },
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
[
|
|
63
|
+
'claude-opus-4-6',
|
|
64
|
+
{
|
|
65
|
+
inputCostPer1M: 5,
|
|
66
|
+
outputCostPer1M: 25,
|
|
67
|
+
cache: { promptIncludesCacheReads: false, readCostPer1M: 0.5, writeCostPer1M: 6.25 },
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
[
|
|
71
|
+
'claude-opus-4-7',
|
|
72
|
+
{
|
|
73
|
+
inputCostPer1M: 5,
|
|
74
|
+
outputCostPer1M: 25,
|
|
75
|
+
cache: { promptIncludesCacheReads: false, readCostPer1M: 0.5, writeCostPer1M: 6.25 },
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
[
|
|
79
|
+
'claude-opus-4-8',
|
|
80
|
+
{
|
|
81
|
+
inputCostPer1M: 5,
|
|
82
|
+
outputCostPer1M: 25,
|
|
83
|
+
cache: { promptIncludesCacheReads: false, readCostPer1M: 0.5, writeCostPer1M: 6.25 },
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
[
|
|
87
|
+
'claude-opus-5',
|
|
88
|
+
{
|
|
89
|
+
inputCostPer1M: 5,
|
|
90
|
+
outputCostPer1M: 25,
|
|
91
|
+
cache: { promptIncludesCacheReads: false, readCostPer1M: 0.5, writeCostPer1M: 6.25 },
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
[
|
|
95
|
+
'claude-sonnet-4-5',
|
|
96
|
+
{
|
|
97
|
+
inputCostPer1M: 3,
|
|
98
|
+
outputCostPer1M: 15,
|
|
99
|
+
cache: { promptIncludesCacheReads: false, readCostPer1M: 0.3, writeCostPer1M: 3.75 },
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
[
|
|
103
|
+
'claude-sonnet-4-6',
|
|
104
|
+
{
|
|
105
|
+
inputCostPer1M: 3,
|
|
106
|
+
outputCostPer1M: 15,
|
|
107
|
+
cache: { promptIncludesCacheReads: false, readCostPer1M: 0.3, writeCostPer1M: 3.75 },
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
[
|
|
111
|
+
'claude-sonnet-5',
|
|
112
|
+
{
|
|
113
|
+
inputCostPer1M: 3,
|
|
114
|
+
outputCostPer1M: 15,
|
|
115
|
+
cache: { promptIncludesCacheReads: false, readCostPer1M: 0.3, writeCostPer1M: 3.75 },
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
]),
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
providerId: 'lmstudio',
|
|
122
|
+
unmetered: true,
|
|
123
|
+
models: new Map([
|
|
124
|
+
// none — see `unmetered`.
|
|
125
|
+
]),
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
providerId: 'ollama',
|
|
129
|
+
unmetered: true,
|
|
130
|
+
models: new Map([
|
|
131
|
+
// none — see `unmetered`.
|
|
132
|
+
]),
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
providerId: 'openai',
|
|
136
|
+
unmetered: false,
|
|
137
|
+
models: new Map([
|
|
138
|
+
[
|
|
139
|
+
'gpt-4.1',
|
|
140
|
+
{
|
|
141
|
+
inputCostPer1M: 2,
|
|
142
|
+
outputCostPer1M: 8,
|
|
143
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.5 },
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
[
|
|
147
|
+
'gpt-4.1-mini',
|
|
148
|
+
{
|
|
149
|
+
inputCostPer1M: 0.4,
|
|
150
|
+
outputCostPer1M: 1.6,
|
|
151
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.1 },
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
[
|
|
155
|
+
'gpt-4.1-nano',
|
|
156
|
+
{
|
|
157
|
+
inputCostPer1M: 0.1,
|
|
158
|
+
outputCostPer1M: 0.4,
|
|
159
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.025 },
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
[
|
|
163
|
+
'gpt-4o',
|
|
164
|
+
{
|
|
165
|
+
inputCostPer1M: 2.5,
|
|
166
|
+
outputCostPer1M: 10,
|
|
167
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 1.25 },
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
[
|
|
171
|
+
'gpt-4o-mini',
|
|
172
|
+
{
|
|
173
|
+
inputCostPer1M: 0.15,
|
|
174
|
+
outputCostPer1M: 0.6,
|
|
175
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.075 },
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
[
|
|
179
|
+
'gpt-5',
|
|
180
|
+
{
|
|
181
|
+
inputCostPer1M: 1.25,
|
|
182
|
+
outputCostPer1M: 10,
|
|
183
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.125 },
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
[
|
|
187
|
+
'gpt-5-mini',
|
|
188
|
+
{
|
|
189
|
+
inputCostPer1M: 0.25,
|
|
190
|
+
outputCostPer1M: 2,
|
|
191
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.025 },
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
[
|
|
195
|
+
'gpt-5-nano',
|
|
196
|
+
{
|
|
197
|
+
inputCostPer1M: 0.05,
|
|
198
|
+
outputCostPer1M: 0.4,
|
|
199
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.005 },
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
[
|
|
203
|
+
'gpt-5.1',
|
|
204
|
+
{
|
|
205
|
+
inputCostPer1M: 1.25,
|
|
206
|
+
outputCostPer1M: 10,
|
|
207
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.125 },
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
[
|
|
211
|
+
'gpt-5.2',
|
|
212
|
+
{
|
|
213
|
+
inputCostPer1M: 1.75,
|
|
214
|
+
outputCostPer1M: 14,
|
|
215
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.175 },
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
[
|
|
219
|
+
'gpt-5.4',
|
|
220
|
+
{
|
|
221
|
+
inputCostPer1M: 2.5,
|
|
222
|
+
outputCostPer1M: 15,
|
|
223
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.25 },
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
[
|
|
227
|
+
'gpt-5.4-mini',
|
|
228
|
+
{
|
|
229
|
+
inputCostPer1M: 0.75,
|
|
230
|
+
outputCostPer1M: 4.5,
|
|
231
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.075 },
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
[
|
|
235
|
+
'gpt-5.4-nano',
|
|
236
|
+
{
|
|
237
|
+
inputCostPer1M: 0.2,
|
|
238
|
+
outputCostPer1M: 1.25,
|
|
239
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.02 },
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
[
|
|
243
|
+
'gpt-5.5',
|
|
244
|
+
{
|
|
245
|
+
inputCostPer1M: 5,
|
|
246
|
+
outputCostPer1M: 30,
|
|
247
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.5 },
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
[
|
|
251
|
+
'gpt-5.6-luna',
|
|
252
|
+
{
|
|
253
|
+
inputCostPer1M: 0.2,
|
|
254
|
+
outputCostPer1M: 1.2,
|
|
255
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.02 },
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
[
|
|
259
|
+
'gpt-5.6-sol',
|
|
260
|
+
{
|
|
261
|
+
inputCostPer1M: 5,
|
|
262
|
+
outputCostPer1M: 30,
|
|
263
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.5 },
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
[
|
|
267
|
+
'gpt-5.6-terra',
|
|
268
|
+
{
|
|
269
|
+
inputCostPer1M: 2,
|
|
270
|
+
outputCostPer1M: 12,
|
|
271
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.2 },
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
[
|
|
275
|
+
'o1',
|
|
276
|
+
{
|
|
277
|
+
inputCostPer1M: 15,
|
|
278
|
+
outputCostPer1M: 60,
|
|
279
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 7.5 },
|
|
280
|
+
},
|
|
281
|
+
],
|
|
282
|
+
[
|
|
283
|
+
'o3',
|
|
284
|
+
{
|
|
285
|
+
inputCostPer1M: 2,
|
|
286
|
+
outputCostPer1M: 8,
|
|
287
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.5 },
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
[
|
|
291
|
+
'o3-mini',
|
|
292
|
+
{
|
|
293
|
+
inputCostPer1M: 1.1,
|
|
294
|
+
outputCostPer1M: 4.4,
|
|
295
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.55 },
|
|
296
|
+
},
|
|
297
|
+
],
|
|
298
|
+
[
|
|
299
|
+
'o4-mini',
|
|
300
|
+
{
|
|
301
|
+
inputCostPer1M: 1.1,
|
|
302
|
+
outputCostPer1M: 4.4,
|
|
303
|
+
cache: { promptIncludesCacheReads: true, readCostPer1M: 0.275 },
|
|
304
|
+
},
|
|
305
|
+
],
|
|
306
|
+
]),
|
|
307
|
+
},
|
|
308
|
+
]
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate lookup for a run's tokens.
|
|
3
|
+
*
|
|
4
|
+
* The kernel had a cost calculation and no data to feed it: `costInfo` moved
|
|
5
|
+
* only when a host passed `pricing` to `query()`, no shipped surface passed
|
|
6
|
+
* one, and so every run reported a total of zero. `runConfig.costLimitUsd` is
|
|
7
|
+
* enforced against that same total, which made a declared budget a budget that
|
|
8
|
+
* could never trigger.
|
|
9
|
+
*
|
|
10
|
+
* This is the data. It is IN-TREE and versioned at build time rather than
|
|
11
|
+
* fetched, so a cost number is reproducible from a commit and an offline run
|
|
12
|
+
* still prices correctly — a runtime fetch gives neither. See
|
|
13
|
+
* `scripts/generate-model-prices.mjs` for why the source is reviewed rather
|
|
14
|
+
* than refreshed, and `rates.source.json` for the rates themselves.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { ModelPricing } from '../utils/cost.js'
|
|
18
|
+
import { VENDOR_RATES } from './catalogue.generated.js'
|
|
19
|
+
|
|
20
|
+
export type { VendorRates } from './catalogue.generated.js'
|
|
21
|
+
export { VENDOR_RATES }
|
|
22
|
+
|
|
23
|
+
/** A driver that bills nothing per token resolves to this. */
|
|
24
|
+
const UNMETERED: ModelPricing = { inputCostPer1M: 0, outputCostPer1M: 0 }
|
|
25
|
+
|
|
26
|
+
const BY_PROVIDER = new Map(VENDOR_RATES.map((vendor) => [vendor.providerId, vendor]))
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A dated snapshot suffix, in the two shapes vendors actually ship:
|
|
30
|
+
* `claude-sonnet-4-5-20250929` and `claude-opus-4-5@20251101`. Stripping it
|
|
31
|
+
* is the ONLY normalisation, because a snapshot of a model is that model at
|
|
32
|
+
* that model's rate — the vendor prices the family, not the date.
|
|
33
|
+
*/
|
|
34
|
+
const SNAPSHOT_SUFFIX = /[-@]\d{8}$/
|
|
35
|
+
|
|
36
|
+
/** Lowercase, snapshot suffix removed. Exported because tests assert it. */
|
|
37
|
+
export function normaliseModelId(model: string): string {
|
|
38
|
+
return model.toLowerCase().replace(SNAPSHOT_SUFFIX, '')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The rate card for a model, or `undefined` when nobody here has one.
|
|
43
|
+
*
|
|
44
|
+
* `undefined` is a real answer and the caller must keep it distinct from a
|
|
45
|
+
* rate of zero. Zero means this run genuinely costs nothing — the local
|
|
46
|
+
* drivers, which bill per token exactly never. `undefined` means the total is
|
|
47
|
+
* unknowable, and a caller that flattens the two reproduces the defect this
|
|
48
|
+
* whole module exists to remove, one level down.
|
|
49
|
+
*
|
|
50
|
+
* ## Matching is exact, and that is the point
|
|
51
|
+
*
|
|
52
|
+
* The neighbouring context-window table matches on longest substring, and it
|
|
53
|
+
* is right to: a window guessed one size small costs a compaction pass. A rate
|
|
54
|
+
* guessed one row across costs the caller money and moves their budget. Inside
|
|
55
|
+
* a single vendor here, ids one character apart differ in price by 4x and by
|
|
56
|
+
* 24x. So a near-miss is not a degraded answer, it is a wrong one, and this
|
|
57
|
+
* returns `undefined` instead — which is safe by construction, because
|
|
58
|
+
* `undefined` refuses rather than proceeds.
|
|
59
|
+
*
|
|
60
|
+
* The cost of exactness is stated rather than hidden: a model the vendor has
|
|
61
|
+
* released since this table was reviewed is unpriced until somebody adds the
|
|
62
|
+
* row. That is a visible, fixable gap. A silently wrong total is neither.
|
|
63
|
+
*/
|
|
64
|
+
export function resolveModelPricing(
|
|
65
|
+
providerId: string,
|
|
66
|
+
model: string | undefined,
|
|
67
|
+
): ModelPricing | undefined {
|
|
68
|
+
const vendor = BY_PROVIDER.get(providerId)
|
|
69
|
+
if (vendor === undefined) return undefined
|
|
70
|
+
// Checked before the model id, deliberately. An unmetered driver bills
|
|
71
|
+
// nothing whatever it is asked to run, and its models are whatever the
|
|
72
|
+
// operator has pulled onto the machine — enumerable by nobody. Requiring a
|
|
73
|
+
// row for each would make every local run unpriced, which would report
|
|
74
|
+
// "cost unknown" about the one case where the cost is known exactly.
|
|
75
|
+
if (vendor.unmetered) return UNMETERED
|
|
76
|
+
if (model === undefined) return undefined
|
|
77
|
+
return vendor.models.get(normaliseModelId(model))
|
|
78
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
{
|
|
2
|
+
"about": [
|
|
3
|
+
"The reviewed input to scripts/generate-model-prices.mjs. Edit THIS file, never",
|
|
4
|
+
"catalogue.generated.ts — the generator overwrites that file and a CI gate",
|
|
5
|
+
"re-derives it from this one and fails on any difference.",
|
|
6
|
+
"",
|
|
7
|
+
"A rate here is a commercial fact about a vendor's published list price. It is",
|
|
8
|
+
"entered by a human who read that vendor's own pricing page, and `verified` is",
|
|
9
|
+
"the date they read it. It is NOT fetched at build time: an auto-refreshing",
|
|
10
|
+
"generator would change every consumer's reported cost AND every consumer's",
|
|
11
|
+
"costLimitUsd behaviour on an unrelated commit, with no review and no diff.",
|
|
12
|
+
"",
|
|
13
|
+
"Absent is a real answer. A model with no row here reports UNKNOWN cost, not",
|
|
14
|
+
"zero, and a run that sets runConfig.costLimitUsd against it is refused rather",
|
|
15
|
+
"than run without a budget. So the correct move when a rate cannot be",
|
|
16
|
+
"established is to leave the row out, never to approximate it.",
|
|
17
|
+
"",
|
|
18
|
+
"unmetered: true means this driver bills nothing by construction — local",
|
|
19
|
+
"inference. Its runs are priced at zero, which is KNOWN-free and therefore",
|
|
20
|
+
"distinct from unknown. Such a vendor needs no model rows.",
|
|
21
|
+
"",
|
|
22
|
+
"Matching is EXACT on a normalised id (lowercased, one trailing -YYYYMMDD or",
|
|
23
|
+
"@YYYYMMDD snapshot suffix removed). Deliberately not prefix or substring:",
|
|
24
|
+
"within one vendor here, ids one character apart differ in price by 4x, so a",
|
|
25
|
+
"near-miss would misprice silently. A miss reports unknown, which is safe."
|
|
26
|
+
],
|
|
27
|
+
"cacheTokensAre": [
|
|
28
|
+
"Two of the four rates only mean anything alongside a fact about the DRIVER,",
|
|
29
|
+
"not about the model: whether the prompt-token count it reports already",
|
|
30
|
+
"contains the tokens it read from cache.",
|
|
31
|
+
"",
|
|
32
|
+
"The drivers in this repository disagree, and it is measured, not assumed:",
|
|
33
|
+
" packages/providers/anthropic/src/client.ts parseUsage — promptTokens is",
|
|
34
|
+
" input_tokens, which EXCLUDES cache reads and cache writes.",
|
|
35
|
+
" packages/providers/bedrock/src/client.ts parseBedrockUsage — same.",
|
|
36
|
+
" packages/providers/openai/src/client.ts parseUsage — promptTokens is",
|
|
37
|
+
" prompt_tokens, which INCLUDES cached_tokens.",
|
|
38
|
+
"",
|
|
39
|
+
"So the same TokenUsage shape carries two incompatible meanings, and a rate",
|
|
40
|
+
"applied without knowing which one is off by the whole cache-read volume. The",
|
|
41
|
+
"fact is a property of the driver, and the driver's identity is in hand at the",
|
|
42
|
+
"moment cost is accumulated — so it is declared here, per vendor, once.",
|
|
43
|
+
"",
|
|
44
|
+
"promptIncludesCacheReads true => billable input is promptTokens minus",
|
|
45
|
+
" cachedTokens.",
|
|
46
|
+
" false => billable input is promptTokens, and",
|
|
47
|
+
" cachedTokens are charged on top.",
|
|
48
|
+
"",
|
|
49
|
+
"reportsCacheWrites declares whether the driver ever produces a non-zero",
|
|
50
|
+
"cacheWriteTokens. When false, model rows carry no write rate — a rate for a",
|
|
51
|
+
"quantity nothing produces is a declaration nothing drives. If such a driver",
|
|
52
|
+
"later does report writes, those tokens are counted as unpriced rather than",
|
|
53
|
+
"quietly charged at some other rate, so the contradiction surfaces."
|
|
54
|
+
],
|
|
55
|
+
"vendors": [
|
|
56
|
+
{
|
|
57
|
+
"providerId": "anthropic",
|
|
58
|
+
"unmetered": false,
|
|
59
|
+
"verified": "2026-08-10",
|
|
60
|
+
"promptIncludesCacheReads": false,
|
|
61
|
+
"reportsCacheWrites": true,
|
|
62
|
+
"note": "The last two rows exist because the driver's own offline catalogue offers those models and this table did not price them — a lookup-key gap that reads as `cost unknown` and is invisible to the generator's own check, which only proves the module matches this file. `providers/anthropic` asserts the two lists agree. Vendor list prices. Cache read is the vendor's published 0.1x of the input rate; cache write is its published 1.25x for the five-minute entry, which is the default TTL and the one the driver's `cacheControl: { type: 'auto' }` asks for. A time-limited introductory rate applied to one model at the time of entry; this table has no time dimension and records the list rate, so a run inside a promotional window is over-reported rather than mis-modelled.",
|
|
63
|
+
"models": [
|
|
64
|
+
{
|
|
65
|
+
"id": "claude-fable-5",
|
|
66
|
+
"inputPer1M": 10,
|
|
67
|
+
"outputPer1M": 50,
|
|
68
|
+
"cacheReadPer1M": 1,
|
|
69
|
+
"cacheWritePer1M": 12.5
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "claude-mythos-5",
|
|
73
|
+
"inputPer1M": 10,
|
|
74
|
+
"outputPer1M": 50,
|
|
75
|
+
"cacheReadPer1M": 1,
|
|
76
|
+
"cacheWritePer1M": 12.5
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"id": "claude-opus-5",
|
|
80
|
+
"inputPer1M": 5,
|
|
81
|
+
"outputPer1M": 25,
|
|
82
|
+
"cacheReadPer1M": 0.5,
|
|
83
|
+
"cacheWritePer1M": 6.25
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"id": "claude-opus-4-8",
|
|
87
|
+
"inputPer1M": 5,
|
|
88
|
+
"outputPer1M": 25,
|
|
89
|
+
"cacheReadPer1M": 0.5,
|
|
90
|
+
"cacheWritePer1M": 6.25
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "claude-opus-4-7",
|
|
94
|
+
"inputPer1M": 5,
|
|
95
|
+
"outputPer1M": 25,
|
|
96
|
+
"cacheReadPer1M": 0.5,
|
|
97
|
+
"cacheWritePer1M": 6.25
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"id": "claude-opus-4-6",
|
|
101
|
+
"inputPer1M": 5,
|
|
102
|
+
"outputPer1M": 25,
|
|
103
|
+
"cacheReadPer1M": 0.5,
|
|
104
|
+
"cacheWritePer1M": 6.25
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"id": "claude-sonnet-5",
|
|
108
|
+
"inputPer1M": 3,
|
|
109
|
+
"outputPer1M": 15,
|
|
110
|
+
"cacheReadPer1M": 0.3,
|
|
111
|
+
"cacheWritePer1M": 3.75
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"id": "claude-sonnet-4-6",
|
|
115
|
+
"inputPer1M": 3,
|
|
116
|
+
"outputPer1M": 15,
|
|
117
|
+
"cacheReadPer1M": 0.3,
|
|
118
|
+
"cacheWritePer1M": 3.75
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "claude-haiku-4-5",
|
|
122
|
+
"inputPer1M": 1,
|
|
123
|
+
"outputPer1M": 5,
|
|
124
|
+
"cacheReadPer1M": 0.1,
|
|
125
|
+
"cacheWritePer1M": 1.25
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"id": "claude-sonnet-4-5",
|
|
129
|
+
"inputPer1M": 3,
|
|
130
|
+
"outputPer1M": 15,
|
|
131
|
+
"cacheReadPer1M": 0.3,
|
|
132
|
+
"cacheWritePer1M": 3.75
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"id": "claude-opus-4-1",
|
|
136
|
+
"inputPer1M": 15,
|
|
137
|
+
"outputPer1M": 75,
|
|
138
|
+
"cacheReadPer1M": 1.5,
|
|
139
|
+
"cacheWritePer1M": 18.75
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"providerId": "openai",
|
|
145
|
+
"unmetered": false,
|
|
146
|
+
"verified": "2026-08-10",
|
|
147
|
+
"promptIncludesCacheReads": true,
|
|
148
|
+
"reportsCacheWrites": false,
|
|
149
|
+
"note": "Vendor list prices for text models, cached-input rate included. The driver hard-codes cacheWriteTokens to zero, so no write rate is carried. Embedding models are omitted (no output rate, and a chat run never reaches one), as are models whose cached-input rate was not published alongside the others — an unestablished rate is left out rather than approximated, which is the rule this whole file follows.",
|
|
150
|
+
"models": [
|
|
151
|
+
{ "id": "gpt-5.6-sol", "inputPer1M": 5, "outputPer1M": 30, "cacheReadPer1M": 0.5 },
|
|
152
|
+
{ "id": "gpt-5.6-terra", "inputPer1M": 2, "outputPer1M": 12, "cacheReadPer1M": 0.2 },
|
|
153
|
+
{ "id": "gpt-5.6-luna", "inputPer1M": 0.2, "outputPer1M": 1.2, "cacheReadPer1M": 0.02 },
|
|
154
|
+
{ "id": "gpt-5.5", "inputPer1M": 5, "outputPer1M": 30, "cacheReadPer1M": 0.5 },
|
|
155
|
+
{ "id": "gpt-5.4", "inputPer1M": 2.5, "outputPer1M": 15, "cacheReadPer1M": 0.25 },
|
|
156
|
+
{ "id": "gpt-5.4-mini", "inputPer1M": 0.75, "outputPer1M": 4.5, "cacheReadPer1M": 0.075 },
|
|
157
|
+
{ "id": "gpt-5.4-nano", "inputPer1M": 0.2, "outputPer1M": 1.25, "cacheReadPer1M": 0.02 },
|
|
158
|
+
{ "id": "gpt-5.2", "inputPer1M": 1.75, "outputPer1M": 14, "cacheReadPer1M": 0.175 },
|
|
159
|
+
{ "id": "gpt-5.1", "inputPer1M": 1.25, "outputPer1M": 10, "cacheReadPer1M": 0.125 },
|
|
160
|
+
{ "id": "gpt-5", "inputPer1M": 1.25, "outputPer1M": 10, "cacheReadPer1M": 0.125 },
|
|
161
|
+
{ "id": "gpt-5-mini", "inputPer1M": 0.25, "outputPer1M": 2, "cacheReadPer1M": 0.025 },
|
|
162
|
+
{ "id": "gpt-5-nano", "inputPer1M": 0.05, "outputPer1M": 0.4, "cacheReadPer1M": 0.005 },
|
|
163
|
+
{ "id": "gpt-4.1", "inputPer1M": 2, "outputPer1M": 8, "cacheReadPer1M": 0.5 },
|
|
164
|
+
{ "id": "gpt-4.1-mini", "inputPer1M": 0.4, "outputPer1M": 1.6, "cacheReadPer1M": 0.1 },
|
|
165
|
+
{ "id": "gpt-4.1-nano", "inputPer1M": 0.1, "outputPer1M": 0.4, "cacheReadPer1M": 0.025 },
|
|
166
|
+
{ "id": "gpt-4o", "inputPer1M": 2.5, "outputPer1M": 10, "cacheReadPer1M": 1.25 },
|
|
167
|
+
{ "id": "gpt-4o-mini", "inputPer1M": 0.15, "outputPer1M": 0.6, "cacheReadPer1M": 0.075 },
|
|
168
|
+
{ "id": "o1", "inputPer1M": 15, "outputPer1M": 60, "cacheReadPer1M": 7.5 },
|
|
169
|
+
{ "id": "o3", "inputPer1M": 2, "outputPer1M": 8, "cacheReadPer1M": 0.5 },
|
|
170
|
+
{ "id": "o3-mini", "inputPer1M": 1.1, "outputPer1M": 4.4, "cacheReadPer1M": 0.55 },
|
|
171
|
+
{ "id": "o4-mini", "inputPer1M": 1.1, "outputPer1M": 4.4, "cacheReadPer1M": 0.275 }
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"providerId": "ollama",
|
|
176
|
+
"unmetered": true,
|
|
177
|
+
"verified": "2026-08-10",
|
|
178
|
+
"note": "Local inference. Nothing is billed for a token, whatever the model, so there is no model list to keep current.",
|
|
179
|
+
"models": []
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"providerId": "lmstudio",
|
|
183
|
+
"unmetered": true,
|
|
184
|
+
"verified": "2026-08-10",
|
|
185
|
+
"note": "Local inference. Same as above.",
|
|
186
|
+
"models": []
|
|
187
|
+
}
|
|
188
|
+
],
|
|
189
|
+
"absent": [
|
|
190
|
+
"Drivers deliberately carrying no rows, so that a run through them reports",
|
|
191
|
+
"unknown rather than a number nobody checked:",
|
|
192
|
+
"",
|
|
193
|
+
" bedrock — partner-operated, on a separate rate card from the vendor whose",
|
|
194
|
+
" models it serves. Entering the vendor's own rates against it",
|
|
195
|
+
" would be the exact class of quiet wrongness this file exists to",
|
|
196
|
+
" stop.",
|
|
197
|
+
" openrouter — routes to arbitrary upstreams and publishes per-model rates from",
|
|
198
|
+
" its own catalogue endpoint at run time. That is a live source",
|
|
199
|
+
" and a static table cannot be one.",
|
|
200
|
+
" http — a driver for whatever endpoint the host points it at. There is",
|
|
201
|
+
" no vendor to have a price.",
|
|
202
|
+
"",
|
|
203
|
+
"Adding one is a normal change: add the vendor here with the rows and the date",
|
|
204
|
+
"they were read, run the generator, commit both files."
|
|
205
|
+
]
|
|
206
|
+
}
|
package/src/public-runtime.ts
CHANGED
|
@@ -49,10 +49,18 @@ export * from './utils/id.js'
|
|
|
49
49
|
|
|
50
50
|
export {
|
|
51
51
|
accumulateCost,
|
|
52
|
+
accumulateUnpricedCost,
|
|
52
53
|
calculateCost,
|
|
54
|
+
describeCost,
|
|
53
55
|
formatCost,
|
|
54
56
|
ZERO_COST,
|
|
55
57
|
} from './utils/cost.js'
|
|
58
|
+
|
|
59
|
+
// The price catalogue. Exported because a driver package has to be able to ask
|
|
60
|
+
// whether the models it offers an operator are ones the kernel can price —
|
|
61
|
+
// `sdk ← providers` means the SDK's own tests can never reach a real driver's
|
|
62
|
+
// model list, so that check lives in the driver and needs this.
|
|
63
|
+
export { normaliseModelId, resolveModelPricing, VENDOR_RATES } from './pricing/index.js'
|
|
56
64
|
export { toErrorMessage } from './utils/error.js'
|
|
57
65
|
export { configureLogger, getRootLogger, Logger } from './utils/logger.js'
|
|
58
66
|
export { buildToolResultHashes, hashToolResult } from './utils/hash.js'
|
|
@@ -141,6 +149,37 @@ export type {
|
|
|
141
149
|
DrainRunsParams,
|
|
142
150
|
DrainRunsResult,
|
|
143
151
|
} from './run/index.js'
|
|
152
|
+
// A `ReviewAnswer` that runs shell commands, so "don't finish until the
|
|
153
|
+
// build passes" needs no TypeScript. `reviewAnswer` was the seam for this
|
|
154
|
+
// and nothing shipped supplied one. Skips re-running a command whose
|
|
155
|
+
// failure the workspace has not changed since — the difference between a
|
|
156
|
+
// bounded loop and one that spends its whole budget confirming a failure it
|
|
157
|
+
// already reported.
|
|
158
|
+
export {
|
|
159
|
+
DEFAULT_GATE_MAX_RETRIES,
|
|
160
|
+
DEFAULT_GATE_OUTPUT_CHARS,
|
|
161
|
+
DEFAULT_GATE_TIMEOUT_MS,
|
|
162
|
+
FINGERPRINT_MAX_BYTES,
|
|
163
|
+
FINGERPRINT_TIMEOUT_MS,
|
|
164
|
+
clipOutput,
|
|
165
|
+
createCommandGate,
|
|
166
|
+
fingerprintWorkspace,
|
|
167
|
+
} from './run/index.js'
|
|
168
|
+
export type {
|
|
169
|
+
CommandGateOptions,
|
|
170
|
+
FingerprintExec,
|
|
171
|
+
GateExec,
|
|
172
|
+
WorkspaceFingerprintOptions,
|
|
173
|
+
} from './run/index.js'
|
|
174
|
+
// The default `promoteMemory`: write what a run learned into a MemoryStore,
|
|
175
|
+
// or write NOTHING. The hook was invoked at settle with the compaction
|
|
176
|
+
// extractor's already-structured output and no shipped app supplied it, so
|
|
177
|
+
// that structure was serialized into one system message and dropped when
|
|
178
|
+
// the run ended. A run that learned nothing leaves no record at all — the
|
|
179
|
+
// model reads this store, so noise here is context spent on a run that did
|
|
180
|
+
// nothing.
|
|
181
|
+
export { RUN_MEMORY_TAG, createMemoryPromoter } from './run/index.js'
|
|
182
|
+
export type { MemoryPromoterOptions } from './run/index.js'
|
|
144
183
|
|
|
145
184
|
// ─── personas, skills, advisory ──────────────────────────────────────────
|
|
146
185
|
|
package/src/public-types.ts
CHANGED
|
@@ -98,7 +98,9 @@ export type {
|
|
|
98
98
|
|
|
99
99
|
export type { AdvisoryCallContext, AdvisoryExecutionResult } from './advisory/index.js'
|
|
100
100
|
|
|
101
|
-
export type { ModelPricing } from './utils/cost.js'
|
|
101
|
+
export type { CacheRates, ModelPricing } from './utils/cost.js'
|
|
102
|
+
export type { VendorRates } from './pricing/index.js'
|
|
103
|
+
export type { PricingSubject } from './manager/run/persistence.js'
|
|
102
104
|
export type { FrontmatterValue, ParsedFrontmatter } from './utils/frontmatter.js'
|
|
103
105
|
export type { Logger } from './utils/logger.js'
|
|
104
106
|
export type { ShellCompressOptions, ShellCompressResult } from './utils/shell-compress.js'
|