remote-codex 0.11.29 → 0.11.31
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/apps/relay-server/dist/index.js +713 -39
- package/apps/supervisor-api/dist/index.js +64 -10
- package/apps/supervisor-web/dist/apple-touch-icon.png +0 -0
- package/apps/supervisor-web/dist/assets/{core-oEok_Crl.js → core-DODVy7wn.js} +1 -1
- package/apps/supervisor-web/dist/assets/{graph-vendor-DVPtkh3h.js → graph-vendor-DVQUpZ8C.js} +1 -1
- package/apps/supervisor-web/dist/assets/index-BkwJP0KB.js +6 -0
- package/apps/supervisor-web/dist/assets/index-CJFMmjP5.css +1 -0
- package/apps/supervisor-web/dist/assets/{markdown-vendor-BQJfKm05.js → markdown-vendor-RZk8L7-L.js} +1 -1
- package/apps/supervisor-web/dist/assets/{react-vendor-CgLzZcV4.js → react-vendor-Dfg_6BLf.js} +1 -1
- package/apps/supervisor-web/dist/assets/{terminal-vendor-B365Go3Z.js → terminal-vendor-C5bTa-Ka.js} +1 -1
- package/apps/supervisor-web/dist/assets/{thread-ui-DXUs5Aqt.js → thread-ui-BOqbjoiB.js} +27 -27
- package/apps/supervisor-web/dist/assets/{ui-vendor-CeKGesq3.js → ui-vendor-CuR8GHb0.js} +1 -1
- package/apps/supervisor-web/dist/favicon-16x16.png +0 -0
- package/apps/supervisor-web/dist/favicon-32x32.png +0 -0
- package/apps/supervisor-web/dist/favicon-48x48.png +0 -0
- package/apps/supervisor-web/dist/icon-192.png +0 -0
- package/apps/supervisor-web/dist/icon-512.png +0 -0
- package/apps/supervisor-web/dist/index.html +15 -9
- package/apps/supervisor-web/dist/remote-codex-icon.png +0 -0
- package/apps/supervisor-web/dist/site.webmanifest +19 -0
- package/config/codex-model-pricing.json +44 -0
- package/package.json +1 -1
- package/packages/agent-runtime/src/model-pricing.ts +66 -6
- package/packages/claude/src/runtimeAdapter.ts +4 -0
- package/packages/codex/src/modelPricing.test.ts +84 -0
- package/packages/codex/src/types.ts +3 -1
- package/packages/opencode/src/runtimeAdapter.ts +15 -0
- package/packages/shared/src/index.ts +86 -1
- package/apps/supervisor-web/dist/assets/index-FOSXdyuj.css +0 -1
- package/apps/supervisor-web/dist/assets/index-fi_pAm4J.js +0 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as s,R as Tv,a as Tw,j as v,b as Fv}from"./react-vendor-
|
|
1
|
+
import{r as s,R as Tv,a as Tw,j as v,b as Fv}from"./react-vendor-Dfg_6BLf.js";function mN(t,a){if(typeof t=="function")return t(a);t!=null&&(t.current=a)}function Fw(...t){return a=>{let c=!1;const n=t.map(i=>{const d=mN(i,a);return!c&&typeof d=="function"&&(c=!0),d});if(c)return()=>{for(let i=0;i<n.length;i++){const d=n[i];typeof d=="function"?d():mN(t[i],null)}}}}function B(...t){return s.useCallback(Fw(...t),t)}function Da(t){const a=s.forwardRef((c,n)=>{let{children:i,...d}=c,r=null,h=!1;const o=[];gN(i)&&typeof Tg=="function"&&(i=Tg(i._payload)),s.Children.forEach(i,k=>{var _;if(Gw(k)){h=!0;const f=k;let u="child"in f.props?f.props.child:f.props.children;gN(u)&&typeof Tg=="function"&&(u=Tg(u._payload)),r=Ew(f,u),o.push((_=r==null?void 0:r.props)==null?void 0:_.children)}else o.push(k)}),r?r=s.cloneElement(r,void 0,o):!h&&s.Children.count(i)===1&&s.isValidElement(i)&&(r=i);const y=r?Ww(r):void 0,l=B(n,y);if(!r){if(i||i===0)throw new Error(h?Qw(t):Kw(t));return i}const p=Uw(d,r.props??{});return r.type!==s.Fragment&&(p.ref=n?l:y),s.cloneElement(r,p)});return a.displayName=`${t}.Slot`,a}var Rae=Da("Slot"),GN=Symbol.for("radix.slottable");function Ow(t){const a=c=>"child"in c?c.children(c.child):c.children;return a.displayName=`${t}.Slottable`,a.__radixId=GN,a}var Ew=(t,a)=>{if("child"in t.props){const c=t.props.child;return s.isValidElement(c)?s.cloneElement(c,void 0,t.props.children(c.props.children)):null}return s.isValidElement(a)?a:null};function Uw(t,a){const c={...a};for(const n in a){const i=t[n],d=a[n];/^on[A-Z]/.test(n)?i&&d?c[n]=(...h)=>{const o=d(...h);return i(...h),o}:i&&(c[n]=i):n==="style"?c[n]={...i,...d}:n==="className"&&(c[n]=[i,d].filter(Boolean).join(" "))}return{...t,...c}}function Ww(t){var n,i;let a=(n=Object.getOwnPropertyDescriptor(t.props,"ref"))==null?void 0:n.get,c=a&&"isReactWarning"in a&&a.isReactWarning;return c?t.ref:(a=(i=Object.getOwnPropertyDescriptor(t,"ref"))==null?void 0:i.get,c=a&&"isReactWarning"in a&&a.isReactWarning,c?t.props.ref:t.props.ref||t.ref)}function Gw(t){return s.isValidElement(t)&&typeof t.type=="function"&&"__radixId"in t.type&&t.type.__radixId===GN}var Zw=Symbol.for("react.lazy");function gN(t){return t!=null&&typeof t=="object"&&"$$typeof"in t&&t.$$typeof===Zw&&"_payload"in t&&Xw(t._payload)}function Xw(t){return typeof t=="object"&&t!==null&&"then"in t}var Kw=t=>`${t} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`,Qw=t=>`${t} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`,Tg=Tv[" use ".trim().toString()],e={};/**
|
|
2
2
|
* @license lucide-react v0.544.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -3,17 +3,23 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<
|
|
7
|
-
<
|
|
8
|
-
<link rel="
|
|
9
|
-
<link rel="
|
|
10
|
-
<link rel="
|
|
11
|
-
<link rel="
|
|
12
|
-
<
|
|
13
|
-
<
|
|
6
|
+
<meta name="theme-color" content="#101722" />
|
|
7
|
+
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
|
8
|
+
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
|
9
|
+
<link rel="icon" type="image/png" sizes="48x48" href="/favicon-48x48.png" />
|
|
10
|
+
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
|
11
|
+
<link rel="manifest" href="/site.webmanifest" />
|
|
12
|
+
<title>Remote Codex</title>
|
|
13
|
+
<script type="module" crossorigin src="/assets/index-BkwJP0KB.js"></script>
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/react-vendor-Dfg_6BLf.js">
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/ui-vendor-CuR8GHb0.js">
|
|
16
|
+
<link rel="modulepreload" crossorigin href="/assets/graph-vendor-DVQUpZ8C.js">
|
|
17
|
+
<link rel="modulepreload" crossorigin href="/assets/terminal-vendor-C5bTa-Ka.js">
|
|
18
|
+
<link rel="modulepreload" crossorigin href="/assets/markdown-vendor-RZk8L7-L.js">
|
|
19
|
+
<link rel="modulepreload" crossorigin href="/assets/thread-ui-BOqbjoiB.js">
|
|
14
20
|
<link rel="stylesheet" crossorigin href="/assets/graph-vendor-C5ap-Sga.css">
|
|
15
21
|
<link rel="stylesheet" crossorigin href="/assets/terminal-vendor-Beg8tuEN.css">
|
|
16
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
22
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CJFMmjP5.css">
|
|
17
23
|
</head>
|
|
18
24
|
<body class="bg-stone-950">
|
|
19
25
|
<div id="root"></div>
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Remote Codex",
|
|
3
|
+
"short_name": "Remote Codex",
|
|
4
|
+
"icons": [
|
|
5
|
+
{
|
|
6
|
+
"src": "/icon-192.png",
|
|
7
|
+
"sizes": "192x192",
|
|
8
|
+
"type": "image/png"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"src": "/icon-512.png",
|
|
12
|
+
"sizes": "512x512",
|
|
13
|
+
"type": "image/png"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"theme_color": "#101722",
|
|
17
|
+
"background_color": "#101722",
|
|
18
|
+
"display": "standalone"
|
|
19
|
+
}
|
|
@@ -9,6 +9,50 @@
|
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
11
|
"models": {
|
|
12
|
+
"gpt-5.6": {
|
|
13
|
+
"inputUsdPerMillion": 5,
|
|
14
|
+
"cachedInputUsdPerMillion": 0.5,
|
|
15
|
+
"cacheWriteInputUsdPerMillion": 6.25,
|
|
16
|
+
"outputUsdPerMillion": 30,
|
|
17
|
+
"supportsFastMode": true,
|
|
18
|
+
"contextWindowTokens": 353400,
|
|
19
|
+
"longContextThresholdTokens": 272000,
|
|
20
|
+
"longContextInputMultiplier": 2,
|
|
21
|
+
"longContextOutputMultiplier": 1.5
|
|
22
|
+
},
|
|
23
|
+
"gpt-5.6-sol": {
|
|
24
|
+
"inputUsdPerMillion": 5,
|
|
25
|
+
"cachedInputUsdPerMillion": 0.5,
|
|
26
|
+
"cacheWriteInputUsdPerMillion": 6.25,
|
|
27
|
+
"outputUsdPerMillion": 30,
|
|
28
|
+
"supportsFastMode": true,
|
|
29
|
+
"contextWindowTokens": 353400,
|
|
30
|
+
"longContextThresholdTokens": 272000,
|
|
31
|
+
"longContextInputMultiplier": 2,
|
|
32
|
+
"longContextOutputMultiplier": 1.5
|
|
33
|
+
},
|
|
34
|
+
"gpt-5.6-terra": {
|
|
35
|
+
"inputUsdPerMillion": 2.5,
|
|
36
|
+
"cachedInputUsdPerMillion": 0.25,
|
|
37
|
+
"cacheWriteInputUsdPerMillion": 3.125,
|
|
38
|
+
"outputUsdPerMillion": 15,
|
|
39
|
+
"supportsFastMode": true,
|
|
40
|
+
"contextWindowTokens": 353400,
|
|
41
|
+
"longContextThresholdTokens": 272000,
|
|
42
|
+
"longContextInputMultiplier": 2,
|
|
43
|
+
"longContextOutputMultiplier": 1.5
|
|
44
|
+
},
|
|
45
|
+
"gpt-5.6-luna": {
|
|
46
|
+
"inputUsdPerMillion": 1,
|
|
47
|
+
"cachedInputUsdPerMillion": 0.1,
|
|
48
|
+
"cacheWriteInputUsdPerMillion": 1.25,
|
|
49
|
+
"outputUsdPerMillion": 6,
|
|
50
|
+
"supportsFastMode": true,
|
|
51
|
+
"contextWindowTokens": 353400,
|
|
52
|
+
"longContextThresholdTokens": 272000,
|
|
53
|
+
"longContextInputMultiplier": 2,
|
|
54
|
+
"longContextOutputMultiplier": 1.5
|
|
55
|
+
},
|
|
12
56
|
"gpt-5.5": {
|
|
13
57
|
"inputUsdPerMillion": 5,
|
|
14
58
|
"cachedInputUsdPerMillion": 0.5,
|
package/package.json
CHANGED
|
@@ -11,10 +11,14 @@ export type PricingTierKey = 'standard' | 'fast';
|
|
|
11
11
|
interface ModelPricingEntry {
|
|
12
12
|
inputUsdPerMillion: number;
|
|
13
13
|
cachedInputUsdPerMillion: number;
|
|
14
|
+
cacheWriteInputUsdPerMillion?: number;
|
|
14
15
|
outputUsdPerMillion: number;
|
|
15
16
|
supportsFastMode: boolean;
|
|
16
17
|
fastMultiplier?: number;
|
|
17
18
|
contextWindowTokens?: number;
|
|
19
|
+
longContextThresholdTokens?: number;
|
|
20
|
+
longContextInputMultiplier?: number;
|
|
21
|
+
longContextOutputMultiplier?: number;
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
interface PricingTierConfig {
|
|
@@ -119,10 +123,14 @@ function parsePricingConfig(raw: unknown): PricingConfig {
|
|
|
119
123
|
const entry = value as {
|
|
120
124
|
inputUsdPerMillion?: unknown;
|
|
121
125
|
cachedInputUsdPerMillion?: unknown;
|
|
126
|
+
cacheWriteInputUsdPerMillion?: unknown;
|
|
122
127
|
outputUsdPerMillion?: unknown;
|
|
123
128
|
supportsFastMode?: unknown;
|
|
124
129
|
fastMultiplier?: unknown;
|
|
125
130
|
contextWindowTokens?: unknown;
|
|
131
|
+
longContextThresholdTokens?: unknown;
|
|
132
|
+
longContextInputMultiplier?: unknown;
|
|
133
|
+
longContextOutputMultiplier?: unknown;
|
|
126
134
|
};
|
|
127
135
|
|
|
128
136
|
if (
|
|
@@ -133,6 +141,12 @@ function parsePricingConfig(raw: unknown): PricingConfig {
|
|
|
133
141
|
) {
|
|
134
142
|
throw new Error(`Pricing config model "${modelKey}" has invalid fields.`);
|
|
135
143
|
}
|
|
144
|
+
if (
|
|
145
|
+
entry.cacheWriteInputUsdPerMillion !== undefined &&
|
|
146
|
+
!isPositiveNumber(entry.cacheWriteInputUsdPerMillion)
|
|
147
|
+
) {
|
|
148
|
+
throw new Error(`Pricing config model "${modelKey}" cacheWriteInputUsdPerMillion must be a non-negative number.`);
|
|
149
|
+
}
|
|
136
150
|
if (
|
|
137
151
|
entry.fastMultiplier !== undefined &&
|
|
138
152
|
!isPositiveNumber(entry.fastMultiplier)
|
|
@@ -145,10 +159,22 @@ function parsePricingConfig(raw: unknown): PricingConfig {
|
|
|
145
159
|
) {
|
|
146
160
|
throw new Error(`Pricing config model "${modelKey}" contextWindowTokens must be a non-negative number.`);
|
|
147
161
|
}
|
|
162
|
+
for (const field of [
|
|
163
|
+
'longContextThresholdTokens',
|
|
164
|
+
'longContextInputMultiplier',
|
|
165
|
+
'longContextOutputMultiplier',
|
|
166
|
+
] as const) {
|
|
167
|
+
if (entry[field] !== undefined && !isPositiveNumber(entry[field])) {
|
|
168
|
+
throw new Error(`Pricing config model "${modelKey}" ${field} must be a non-negative number.`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
148
171
|
|
|
149
172
|
models[modelKey] = {
|
|
150
173
|
inputUsdPerMillion: entry.inputUsdPerMillion as number,
|
|
151
174
|
cachedInputUsdPerMillion: entry.cachedInputUsdPerMillion as number,
|
|
175
|
+
...(entry.cacheWriteInputUsdPerMillion !== undefined
|
|
176
|
+
? { cacheWriteInputUsdPerMillion: entry.cacheWriteInputUsdPerMillion as number }
|
|
177
|
+
: {}),
|
|
152
178
|
outputUsdPerMillion: entry.outputUsdPerMillion as number,
|
|
153
179
|
supportsFastMode: entry.supportsFastMode,
|
|
154
180
|
...(entry.fastMultiplier !== undefined
|
|
@@ -157,6 +183,15 @@ function parsePricingConfig(raw: unknown): PricingConfig {
|
|
|
157
183
|
...(entry.contextWindowTokens !== undefined
|
|
158
184
|
? { contextWindowTokens: entry.contextWindowTokens as number }
|
|
159
185
|
: {}),
|
|
186
|
+
...(entry.longContextThresholdTokens !== undefined
|
|
187
|
+
? { longContextThresholdTokens: entry.longContextThresholdTokens as number }
|
|
188
|
+
: {}),
|
|
189
|
+
...(entry.longContextInputMultiplier !== undefined
|
|
190
|
+
? { longContextInputMultiplier: entry.longContextInputMultiplier as number }
|
|
191
|
+
: {}),
|
|
192
|
+
...(entry.longContextOutputMultiplier !== undefined
|
|
193
|
+
? { longContextOutputMultiplier: entry.longContextOutputMultiplier as number }
|
|
194
|
+
: {}),
|
|
160
195
|
};
|
|
161
196
|
}
|
|
162
197
|
|
|
@@ -293,24 +328,48 @@ export function estimateTurnPrice(
|
|
|
293
328
|
}
|
|
294
329
|
|
|
295
330
|
const nonCachedInputTokens = Math.max(
|
|
296
|
-
usage.total.inputTokens -
|
|
331
|
+
usage.total.inputTokens -
|
|
332
|
+
usage.total.cachedInputTokens -
|
|
333
|
+
(usage.total.cacheWriteInputTokens ?? 0),
|
|
297
334
|
0,
|
|
298
335
|
);
|
|
299
336
|
const cachedInputTokens = Math.max(usage.total.cachedInputTokens, 0);
|
|
337
|
+
const cacheWriteInputTokens = Math.max(
|
|
338
|
+
usage.total.cacheWriteInputTokens ?? 0,
|
|
339
|
+
0,
|
|
340
|
+
);
|
|
300
341
|
const outputTokens = Math.max(usage.total.outputTokens, 0);
|
|
301
|
-
const
|
|
342
|
+
const tierMultiplier =
|
|
302
343
|
tierKey === 'fast' && modelPricing.fastMultiplier !== undefined
|
|
303
344
|
? modelPricing.fastMultiplier
|
|
304
345
|
: tier.multiplier;
|
|
346
|
+
const usesLongContextPricing =
|
|
347
|
+
typeof modelPricing.longContextThresholdTokens === 'number' &&
|
|
348
|
+
usage.total.inputTokens > modelPricing.longContextThresholdTokens;
|
|
349
|
+
const inputMultiplier =
|
|
350
|
+
tierMultiplier *
|
|
351
|
+
(usesLongContextPricing
|
|
352
|
+
? modelPricing.longContextInputMultiplier ?? 1
|
|
353
|
+
: 1);
|
|
354
|
+
const outputMultiplier =
|
|
355
|
+
tierMultiplier *
|
|
356
|
+
(usesLongContextPricing
|
|
357
|
+
? modelPricing.longContextOutputMultiplier ?? 1
|
|
358
|
+
: 1);
|
|
305
359
|
|
|
306
360
|
const inputUsd =
|
|
307
|
-
(nonCachedInputTokens * modelPricing.inputUsdPerMillion *
|
|
361
|
+
(nonCachedInputTokens * modelPricing.inputUsdPerMillion * inputMultiplier) /
|
|
308
362
|
TOKEN_PRICE_DENOMINATOR;
|
|
309
363
|
const cachedInputUsd =
|
|
310
|
-
(cachedInputTokens * modelPricing.cachedInputUsdPerMillion *
|
|
364
|
+
(cachedInputTokens * modelPricing.cachedInputUsdPerMillion * inputMultiplier) /
|
|
365
|
+
TOKEN_PRICE_DENOMINATOR;
|
|
366
|
+
const cacheWriteInputUsd =
|
|
367
|
+
(cacheWriteInputTokens *
|
|
368
|
+
(modelPricing.cacheWriteInputUsdPerMillion ?? modelPricing.inputUsdPerMillion) *
|
|
369
|
+
inputMultiplier) /
|
|
311
370
|
TOKEN_PRICE_DENOMINATOR;
|
|
312
371
|
const outputUsd =
|
|
313
|
-
(outputTokens * modelPricing.outputUsdPerMillion *
|
|
372
|
+
(outputTokens * modelPricing.outputUsdPerMillion * outputMultiplier) /
|
|
314
373
|
TOKEN_PRICE_DENOMINATOR;
|
|
315
374
|
|
|
316
375
|
return {
|
|
@@ -319,7 +378,8 @@ export function estimateTurnPrice(
|
|
|
319
378
|
currency: pricingConfig.currency,
|
|
320
379
|
inputUsd,
|
|
321
380
|
cachedInputUsd,
|
|
381
|
+
cacheWriteInputUsd,
|
|
322
382
|
outputUsd,
|
|
323
|
-
totalUsd: inputUsd + cachedInputUsd + outputUsd,
|
|
383
|
+
totalUsd: inputUsd + cachedInputUsd + cacheWriteInputUsd + outputUsd,
|
|
324
384
|
};
|
|
325
385
|
}
|
|
@@ -364,6 +364,7 @@ interface ClaudeTokenUsageBreakdown {
|
|
|
364
364
|
totalTokens: number;
|
|
365
365
|
inputTokens: number;
|
|
366
366
|
cachedInputTokens: number;
|
|
367
|
+
cacheWriteInputTokens: number;
|
|
367
368
|
outputTokens: number;
|
|
368
369
|
reasoningOutputTokens: number;
|
|
369
370
|
}
|
|
@@ -792,6 +793,8 @@ function addClaudeUsage(
|
|
|
792
793
|
totalTokens: left.totalTokens + right.totalTokens,
|
|
793
794
|
inputTokens: left.inputTokens + right.inputTokens,
|
|
794
795
|
cachedInputTokens: left.cachedInputTokens + right.cachedInputTokens,
|
|
796
|
+
cacheWriteInputTokens:
|
|
797
|
+
left.cacheWriteInputTokens + right.cacheWriteInputTokens,
|
|
795
798
|
outputTokens: left.outputTokens + right.outputTokens,
|
|
796
799
|
reasoningOutputTokens: left.reasoningOutputTokens + right.reasoningOutputTokens,
|
|
797
800
|
};
|
|
@@ -821,6 +824,7 @@ function normalizeClaudeUsage(value: unknown): ClaudeTokenUsageBreakdown | null
|
|
|
821
824
|
totalTokens,
|
|
822
825
|
inputTokens,
|
|
823
826
|
cachedInputTokens: cacheReadInputTokens,
|
|
827
|
+
cacheWriteInputTokens: cacheCreationInputTokens,
|
|
824
828
|
outputTokens,
|
|
825
829
|
reasoningOutputTokens: 0,
|
|
826
830
|
};
|
|
@@ -52,6 +52,90 @@ describe('modelPricing', () => {
|
|
|
52
52
|
expect(estimate?.totalUsd).toBeCloseTo(0.05025, 10);
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
+
it('prices GPT-5.6 aliases and cache writes with the published rates', () => {
|
|
56
|
+
const usage = {
|
|
57
|
+
...sampleUsage,
|
|
58
|
+
total: {
|
|
59
|
+
...sampleUsage.total,
|
|
60
|
+
cacheWriteInputTokens: 200,
|
|
61
|
+
},
|
|
62
|
+
last: {
|
|
63
|
+
...sampleUsage.last,
|
|
64
|
+
cacheWriteInputTokens: 200,
|
|
65
|
+
},
|
|
66
|
+
modelContextWindow: 353_400,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
expect(contextWindowForModel('gpt-5.6')).toBe(353_400);
|
|
70
|
+
expect(contextWindowForModel('openai/gpt-5.6-sol')).toBe(353_400);
|
|
71
|
+
expect(supportsFastMode('gpt-5.6-terra')).toBe(true);
|
|
72
|
+
expect(buildTurnPricingSnapshot('gpt-5.6-luna', false)).toEqual({
|
|
73
|
+
pricingModelKey: 'gpt-5.6-luna',
|
|
74
|
+
pricingTierKey: 'standard',
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const solEstimate = estimateTurnPrice(usage, {
|
|
78
|
+
pricingModelKey: 'gpt-5.6-sol',
|
|
79
|
+
pricingTierKey: 'standard',
|
|
80
|
+
});
|
|
81
|
+
expect(solEstimate).toMatchObject({
|
|
82
|
+
pricingModelKey: 'gpt-5.6-sol',
|
|
83
|
+
inputUsd: 0.004,
|
|
84
|
+
cachedInputUsd: 0.00025,
|
|
85
|
+
cacheWriteInputUsd: 0.00125,
|
|
86
|
+
outputUsd: 0.045,
|
|
87
|
+
});
|
|
88
|
+
expect(solEstimate?.totalUsd).toBeCloseTo(0.0505, 10);
|
|
89
|
+
|
|
90
|
+
const terraEstimate = estimateTurnPrice(usage, {
|
|
91
|
+
pricingModelKey: 'gpt-5.6-terra',
|
|
92
|
+
pricingTierKey: 'standard',
|
|
93
|
+
});
|
|
94
|
+
expect(terraEstimate?.cacheWriteInputUsd).toBeCloseTo(0.000625, 10);
|
|
95
|
+
|
|
96
|
+
const lunaEstimate = estimateTurnPrice(usage, {
|
|
97
|
+
pricingModelKey: 'gpt-5.6-luna',
|
|
98
|
+
pricingTierKey: 'standard',
|
|
99
|
+
});
|
|
100
|
+
expect(lunaEstimate?.cacheWriteInputUsd).toBeCloseTo(0.00025, 10);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('applies GPT-5.6 long-context rates above 272K input tokens', () => {
|
|
104
|
+
const estimate = estimateTurnPrice(
|
|
105
|
+
{
|
|
106
|
+
total: {
|
|
107
|
+
totalTokens: 301_000,
|
|
108
|
+
inputTokens: 300_000,
|
|
109
|
+
cachedInputTokens: 0,
|
|
110
|
+
cacheWriteInputTokens: 0,
|
|
111
|
+
outputTokens: 1_000,
|
|
112
|
+
reasoningOutputTokens: 0,
|
|
113
|
+
},
|
|
114
|
+
last: {
|
|
115
|
+
totalTokens: 301_000,
|
|
116
|
+
inputTokens: 300_000,
|
|
117
|
+
cachedInputTokens: 0,
|
|
118
|
+
cacheWriteInputTokens: 0,
|
|
119
|
+
outputTokens: 1_000,
|
|
120
|
+
reasoningOutputTokens: 0,
|
|
121
|
+
},
|
|
122
|
+
modelContextWindow: 353_400,
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
pricingModelKey: 'gpt-5.6-sol',
|
|
126
|
+
pricingTierKey: 'standard',
|
|
127
|
+
},
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
expect(estimate).toMatchObject({
|
|
131
|
+
inputUsd: 3,
|
|
132
|
+
cachedInputUsd: 0,
|
|
133
|
+
cacheWriteInputUsd: 0,
|
|
134
|
+
outputUsd: 0.045,
|
|
135
|
+
});
|
|
136
|
+
expect(estimate?.totalUsd).toBeCloseTo(3.045, 10);
|
|
137
|
+
});
|
|
138
|
+
|
|
55
139
|
it('uses the gpt-5.5-specific fast multiplier and marks it fast-capable', () => {
|
|
56
140
|
expect(supportsFastMode('gpt-5.5')).toBe(true);
|
|
57
141
|
expect(contextWindowForModel('gpt-5.5')).toBe(272000);
|
|
@@ -63,7 +63,9 @@ export type ReasoningEffort =
|
|
|
63
63
|
| 'low'
|
|
64
64
|
| 'medium'
|
|
65
65
|
| 'high'
|
|
66
|
-
| 'xhigh'
|
|
66
|
+
| 'xhigh'
|
|
67
|
+
| 'max'
|
|
68
|
+
| 'ultra';
|
|
67
69
|
|
|
68
70
|
export type CollaborationModeKind = 'default' | 'plan';
|
|
69
71
|
export type SandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access';
|
|
@@ -439,6 +439,13 @@ function openCodeUsageFromTokens(tokens: unknown) {
|
|
|
439
439
|
const cachedInputTokens = nonNegativeNumberValue(
|
|
440
440
|
tokens.cachedInputTokens ?? tokens.cached_input_tokens ?? cache?.read,
|
|
441
441
|
) ?? 0;
|
|
442
|
+
const cacheWriteInputTokens = nonNegativeNumberValue(
|
|
443
|
+
tokens.cacheWriteInputTokens ??
|
|
444
|
+
tokens.cache_write_input_tokens ??
|
|
445
|
+
tokens.cacheWriteTokens ??
|
|
446
|
+
tokens.cache_write_tokens ??
|
|
447
|
+
cache?.write,
|
|
448
|
+
) ?? 0;
|
|
442
449
|
const totalTokens = nonNegativeNumberValue(tokens.total ?? tokens.totalTokens ?? tokens.total_tokens)
|
|
443
450
|
?? inputTokens + outputTokens;
|
|
444
451
|
|
|
@@ -451,6 +458,7 @@ function openCodeUsageFromTokens(tokens: unknown) {
|
|
|
451
458
|
totalTokens,
|
|
452
459
|
inputTokens,
|
|
453
460
|
cachedInputTokens,
|
|
461
|
+
...(cacheWriteInputTokens > 0 ? { cacheWriteInputTokens } : {}),
|
|
454
462
|
outputTokens,
|
|
455
463
|
reasoningOutputTokens,
|
|
456
464
|
},
|
|
@@ -524,6 +532,13 @@ function turnTokenUsage(messages: unknown[], model: ReturnType<typeof parseModel
|
|
|
524
532
|
totalTokens: sum.totalTokens + usage.totalTokens,
|
|
525
533
|
inputTokens: sum.inputTokens + usage.inputTokens,
|
|
526
534
|
cachedInputTokens: sum.cachedInputTokens + usage.cachedInputTokens,
|
|
535
|
+
...((sum.cacheWriteInputTokens ?? 0) + (usage.cacheWriteInputTokens ?? 0) > 0
|
|
536
|
+
? {
|
|
537
|
+
cacheWriteInputTokens:
|
|
538
|
+
(sum.cacheWriteInputTokens ?? 0) +
|
|
539
|
+
(usage.cacheWriteInputTokens ?? 0),
|
|
540
|
+
}
|
|
541
|
+
: {}),
|
|
527
542
|
outputTokens: sum.outputTokens + usage.outputTokens,
|
|
528
543
|
reasoningOutputTokens: sum.reasoningOutputTokens + usage.reasoningOutputTokens,
|
|
529
544
|
}), firstRecord);
|
|
@@ -156,6 +156,8 @@ export interface RelayPendingRegistrationDto {
|
|
|
156
156
|
|
|
157
157
|
export type RelayThreadAccessDto = 'read' | 'control';
|
|
158
158
|
export type RelayWorkspaceAccessDto = 'none' | 'read' | 'write';
|
|
159
|
+
export type RelayShareScopeDto = 'thread' | 'workspace' | 'device';
|
|
160
|
+
export type RelayWorkspaceScopeDto = 'all' | 'selected';
|
|
159
161
|
|
|
160
162
|
export interface CreateRelaySessionShareInput {
|
|
161
163
|
targetIdentifier: string;
|
|
@@ -204,15 +206,91 @@ export interface RelaySessionShareAccessDto {
|
|
|
204
206
|
shareId: string;
|
|
205
207
|
userId: string;
|
|
206
208
|
username: string;
|
|
209
|
+
kind: RelayAccessEventKindDto;
|
|
207
210
|
accessedAt: string;
|
|
208
211
|
}
|
|
209
212
|
|
|
213
|
+
export type RelayAccessEventKindDto =
|
|
214
|
+
| 'access'
|
|
215
|
+
| 'open_device'
|
|
216
|
+
| 'open_thread'
|
|
217
|
+
| 'create_thread'
|
|
218
|
+
| 'send_prompt'
|
|
219
|
+
| 'read_workspace_file'
|
|
220
|
+
| 'write_workspace_file';
|
|
221
|
+
|
|
222
|
+
export interface RelayAccessGrantEventDto {
|
|
223
|
+
id: string;
|
|
224
|
+
grantId: string;
|
|
225
|
+
userId: string;
|
|
226
|
+
username: string;
|
|
227
|
+
kind: RelayAccessEventKindDto;
|
|
228
|
+
accessedAt: string;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export interface CreateRelayAccessGrantInput {
|
|
232
|
+
targetIdentifier: string;
|
|
233
|
+
deviceId: string;
|
|
234
|
+
scope: RelayShareScopeDto;
|
|
235
|
+
threadId?: string | null;
|
|
236
|
+
workspaceId?: string | null;
|
|
237
|
+
workspaceScope?: RelayWorkspaceScopeDto;
|
|
238
|
+
workspaceIds?: string[];
|
|
239
|
+
label?: string | null;
|
|
240
|
+
threadAccess: RelayThreadAccessDto;
|
|
241
|
+
workspaceAccess: RelayWorkspaceAccessDto;
|
|
242
|
+
canCreateThreads?: boolean;
|
|
243
|
+
expiresAt?: string | null;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export interface UpdateRelayAccessGrantInput {
|
|
247
|
+
workspaceId?: string | null | undefined;
|
|
248
|
+
workspaceScope?: RelayWorkspaceScopeDto | undefined;
|
|
249
|
+
workspaceIds?: string[] | undefined;
|
|
250
|
+
label?: string | null | undefined;
|
|
251
|
+
threadAccess?: RelayThreadAccessDto | undefined;
|
|
252
|
+
workspaceAccess?: RelayWorkspaceAccessDto | undefined;
|
|
253
|
+
canCreateThreads?: boolean | undefined;
|
|
254
|
+
expiresAt?: string | null | undefined;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export interface RelayAccessGrantDto {
|
|
258
|
+
id: string;
|
|
259
|
+
ownerUserId: string;
|
|
260
|
+
ownerUsername: string;
|
|
261
|
+
targetUserId: string;
|
|
262
|
+
targetUsername: string;
|
|
263
|
+
deviceId: string;
|
|
264
|
+
deviceName: string;
|
|
265
|
+
scope: RelayShareScopeDto;
|
|
266
|
+
threadId: string | null;
|
|
267
|
+
threadTitle: string | null;
|
|
268
|
+
workspaceId: string | null;
|
|
269
|
+
workspaceLabel: string | null;
|
|
270
|
+
workspaceScope: RelayWorkspaceScopeDto;
|
|
271
|
+
workspaceIds: string[];
|
|
272
|
+
label: string | null;
|
|
273
|
+
threadAccess: RelayThreadAccessDto;
|
|
274
|
+
workspaceAccess: RelayWorkspaceAccessDto;
|
|
275
|
+
canCreateThreads: boolean;
|
|
276
|
+
createdAt: string;
|
|
277
|
+
revokedAt: string | null;
|
|
278
|
+
expiresAt: string | null;
|
|
279
|
+
lastAccessedAt: string | null;
|
|
280
|
+
lastAccessedByUsername: string | null;
|
|
281
|
+
accessEvents: RelayAccessGrantEventDto[];
|
|
282
|
+
}
|
|
283
|
+
|
|
210
284
|
export interface RelayEffectiveAccessDto {
|
|
211
285
|
kind: 'owner' | 'shared';
|
|
286
|
+
grantId?: string | null;
|
|
212
287
|
shareId: string | null;
|
|
288
|
+
scope?: 'owner' | RelayShareScopeDto;
|
|
213
289
|
threadAccess: RelayThreadAccessDto;
|
|
214
290
|
workspaceAccess: RelayWorkspaceAccessDto;
|
|
215
291
|
workspaceId: string | null;
|
|
292
|
+
workspaceScope?: RelayWorkspaceScopeDto | null;
|
|
293
|
+
canCreateThreads?: boolean;
|
|
216
294
|
}
|
|
217
295
|
|
|
218
296
|
export interface RelaySessionDto {
|
|
@@ -243,12 +321,16 @@ export interface RelayPortalSummaryDto {
|
|
|
243
321
|
devices: RelayDeviceDto[];
|
|
244
322
|
sharedWithMe: RelaySessionShareDto[];
|
|
245
323
|
sharedByMe: RelaySessionShareDto[];
|
|
324
|
+
sharedDevicesWithMe?: RelayAccessGrantDto[];
|
|
325
|
+
sharedThreadsWithMe?: RelayAccessGrantDto[];
|
|
326
|
+
grantsByMe?: RelayAccessGrantDto[];
|
|
246
327
|
}
|
|
247
328
|
|
|
248
329
|
export interface RelayAdminSummaryDto {
|
|
249
330
|
users: RelayAdminUserDto[];
|
|
250
331
|
devices: RelayAdminDeviceDto[];
|
|
251
332
|
shares: RelaySessionShareDto[];
|
|
333
|
+
grants?: RelayAccessGrantDto[];
|
|
252
334
|
pendingRegistrations: RelayPendingRegistrationDto[];
|
|
253
335
|
settings: RelayRegistrationSettingsDto;
|
|
254
336
|
conversationWindowDays: number;
|
|
@@ -620,7 +702,8 @@ export type ReasoningEffortDto =
|
|
|
620
702
|
| 'medium'
|
|
621
703
|
| 'high'
|
|
622
704
|
| 'xhigh'
|
|
623
|
-
| 'max'
|
|
705
|
+
| 'max'
|
|
706
|
+
| 'ultra';
|
|
624
707
|
export type CollaborationModeDto = 'default' | 'plan';
|
|
625
708
|
export type SandboxModeDto = 'read-only' | 'workspace-write' | 'danger-full-access';
|
|
626
709
|
|
|
@@ -812,6 +895,7 @@ export interface ThreadTurnTokenBreakdownDto {
|
|
|
812
895
|
totalTokens: number;
|
|
813
896
|
inputTokens: number;
|
|
814
897
|
cachedInputTokens: number;
|
|
898
|
+
cacheWriteInputTokens?: number;
|
|
815
899
|
outputTokens: number;
|
|
816
900
|
reasoningOutputTokens: number;
|
|
817
901
|
}
|
|
@@ -830,6 +914,7 @@ export interface ThreadTurnPriceEstimateDto {
|
|
|
830
914
|
currency: 'USD';
|
|
831
915
|
inputUsd: number;
|
|
832
916
|
cachedInputUsd: number;
|
|
917
|
+
cacheWriteInputUsd?: number;
|
|
833
918
|
outputUsd: number;
|
|
834
919
|
totalUsd: number;
|
|
835
920
|
}
|