remote-codex 0.11.25 → 0.11.27

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.
@@ -4,16 +4,16 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Remote Codex Supervisor</title>
7
- <script type="module" crossorigin src="/assets/index-JrzRGVx3.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-pMPBEcL2.js"></script>
8
8
  <link rel="modulepreload" crossorigin href="/assets/react-vendor-CgLzZcV4.js">
9
9
  <link rel="modulepreload" crossorigin href="/assets/ui-vendor-CeKGesq3.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/graph-vendor-DVPtkh3h.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/terminal-vendor-B365Go3Z.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/markdown-vendor-BQJfKm05.js">
13
- <link rel="modulepreload" crossorigin href="/assets/thread-ui-Ck4oSYRQ.js">
13
+ <link rel="modulepreload" crossorigin href="/assets/thread-ui-CpukI6ql.js">
14
14
  <link rel="stylesheet" crossorigin href="/assets/graph-vendor-C5ap-Sga.css">
15
15
  <link rel="stylesheet" crossorigin href="/assets/terminal-vendor-Beg8tuEN.css">
16
- <link rel="stylesheet" crossorigin href="/assets/index-Ch_S2n2I.css">
16
+ <link rel="stylesheet" crossorigin href="/assets/index-BVYGmxwf.css">
17
17
  </head>
18
18
  <body class="bg-stone-950">
19
19
  <div id="root"></div>
@@ -54,16 +54,23 @@
54
54
  "supportsFastMode": false
55
55
  },
56
56
  "sonnet": {
57
- "inputUsdPerMillion": 3,
58
- "cachedInputUsdPerMillion": 0.3,
59
- "outputUsdPerMillion": 15,
57
+ "inputUsdPerMillion": 2,
58
+ "cachedInputUsdPerMillion": 0.2,
59
+ "outputUsdPerMillion": 10,
60
60
  "supportsFastMode": false,
61
- "contextWindowTokens": 200000
61
+ "contextWindowTokens": 1000000
62
62
  },
63
63
  "sonnet[1m]": {
64
- "inputUsdPerMillion": 6,
65
- "cachedInputUsdPerMillion": 0.6,
66
- "outputUsdPerMillion": 22.5,
64
+ "inputUsdPerMillion": 2,
65
+ "cachedInputUsdPerMillion": 0.2,
66
+ "outputUsdPerMillion": 10,
67
+ "supportsFastMode": false,
68
+ "contextWindowTokens": 1000000
69
+ },
70
+ "fable": {
71
+ "inputUsdPerMillion": 10,
72
+ "cachedInputUsdPerMillion": 1,
73
+ "outputUsdPerMillion": 50,
67
74
  "supportsFastMode": false,
68
75
  "contextWindowTokens": 1000000
69
76
  },
@@ -72,7 +79,7 @@
72
79
  "cachedInputUsdPerMillion": 0.5,
73
80
  "outputUsdPerMillion": 25,
74
81
  "supportsFastMode": false,
75
- "contextWindowTokens": 200000
82
+ "contextWindowTokens": 1000000
76
83
  },
77
84
  "haiku": {
78
85
  "inputUsdPerMillion": 1,
@@ -81,6 +88,27 @@
81
88
  "supportsFastMode": false,
82
89
  "contextWindowTokens": 200000
83
90
  },
91
+ "claude-fable-5": {
92
+ "inputUsdPerMillion": 10,
93
+ "cachedInputUsdPerMillion": 1,
94
+ "outputUsdPerMillion": 50,
95
+ "supportsFastMode": false,
96
+ "contextWindowTokens": 1000000
97
+ },
98
+ "claude-mythos-5": {
99
+ "inputUsdPerMillion": 10,
100
+ "cachedInputUsdPerMillion": 1,
101
+ "outputUsdPerMillion": 50,
102
+ "supportsFastMode": false,
103
+ "contextWindowTokens": 1000000
104
+ },
105
+ "claude-sonnet-5": {
106
+ "inputUsdPerMillion": 2,
107
+ "cachedInputUsdPerMillion": 0.2,
108
+ "outputUsdPerMillion": 10,
109
+ "supportsFastMode": false,
110
+ "contextWindowTokens": 1000000
111
+ },
84
112
  "claude-sonnet-4-5": {
85
113
  "inputUsdPerMillion": 3,
86
114
  "cachedInputUsdPerMillion": 0.3,
@@ -93,7 +121,15 @@
93
121
  "cachedInputUsdPerMillion": 0.3,
94
122
  "outputUsdPerMillion": 15,
95
123
  "supportsFastMode": false,
96
- "contextWindowTokens": 200000
124
+ "contextWindowTokens": 1000000
125
+ },
126
+ "claude-opus-4-8": {
127
+ "inputUsdPerMillion": 5,
128
+ "cachedInputUsdPerMillion": 0.5,
129
+ "outputUsdPerMillion": 25,
130
+ "supportsFastMode": true,
131
+ "fastMultiplier": 2,
132
+ "contextWindowTokens": 1000000
97
133
  },
98
134
  "claude-opus-4-5": {
99
135
  "inputUsdPerMillion": 5,
@@ -102,10 +138,32 @@
102
138
  "supportsFastMode": false,
103
139
  "contextWindowTokens": 200000
104
140
  },
141
+ "claude-opus-4-6": {
142
+ "inputUsdPerMillion": 5,
143
+ "cachedInputUsdPerMillion": 0.5,
144
+ "outputUsdPerMillion": 25,
145
+ "supportsFastMode": false,
146
+ "contextWindowTokens": 1000000
147
+ },
105
148
  "claude-opus-4-7": {
106
149
  "inputUsdPerMillion": 5,
107
150
  "cachedInputUsdPerMillion": 0.5,
108
151
  "outputUsdPerMillion": 25,
152
+ "supportsFastMode": true,
153
+ "fastMultiplier": 6,
154
+ "contextWindowTokens": 1000000
155
+ },
156
+ "claude-opus-4-1": {
157
+ "inputUsdPerMillion": 15,
158
+ "cachedInputUsdPerMillion": 1.5,
159
+ "outputUsdPerMillion": 75,
160
+ "supportsFastMode": false,
161
+ "contextWindowTokens": 200000
162
+ },
163
+ "claude-opus-4": {
164
+ "inputUsdPerMillion": 15,
165
+ "cachedInputUsdPerMillion": 1.5,
166
+ "outputUsdPerMillion": 75,
109
167
  "supportsFastMode": false,
110
168
  "contextWindowTokens": 200000
111
169
  },
@@ -115,6 +173,13 @@
115
173
  "outputUsdPerMillion": 5,
116
174
  "supportsFastMode": false,
117
175
  "contextWindowTokens": 200000
176
+ },
177
+ "claude-haiku-3-5": {
178
+ "inputUsdPerMillion": 0.8,
179
+ "cachedInputUsdPerMillion": 0.08,
180
+ "outputUsdPerMillion": 4,
181
+ "supportsFastMode": false,
182
+ "contextWindowTokens": 200000
118
183
  }
119
184
  }
120
185
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remote-codex",
3
- "version": "0.11.25",
3
+ "version": "0.11.27",
4
4
  "description": "Local web supervisor for Codex workspaces and threads.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -28,6 +28,15 @@ const HIDDEN_ASK_USER_QUESTION_CONTINUATION_PREFIX =
28
28
  const SUPPRESSED_ASSISTANT_TEXTS = new Set([
29
29
  'No response requested.',
30
30
  ]);
31
+ const CLAUDE_LIMIT_ERROR_PATTERNS = [
32
+ /\byou(?:'|’)ve hit your session limit\b/i,
33
+ /\byou have hit your session limit\b/i,
34
+ /\b(?:hit|reached|exceeded) (?:the )?(?:session|usage|rate) limit\b/i,
35
+ /\b(?:session|usage|rate) limit (?:hit|reached|exceeded)\b/i,
36
+ /\bquota exceeded\b/i,
37
+ /\bcredit balance (?:is )?(?:too low|insufficient|exhausted)\b/i,
38
+ /\binsufficient credits?\b/i,
39
+ ];
31
40
 
32
41
  function normalizedToolName(toolName: string) {
33
42
  return toolName.replace(/[\s_-]+/g, '').toLowerCase();
@@ -94,6 +103,22 @@ function compactJson(value: unknown): string {
94
103
  }
95
104
  }
96
105
 
106
+ function joinReasoningText(left: string, right: string) {
107
+ if (!left) {
108
+ return right;
109
+ }
110
+ if (!right) {
111
+ return left;
112
+ }
113
+ if (right.startsWith(left)) {
114
+ return right;
115
+ }
116
+ if (left.endsWith(right)) {
117
+ return left;
118
+ }
119
+ return `${left}\n\n${right}`;
120
+ }
121
+
97
122
  function readableToolName(toolName: string) {
98
123
  if (CLAUDE_TOOL_LABELS[toolName]) {
99
124
  return CLAUDE_TOOL_LABELS[toolName];
@@ -249,6 +274,30 @@ function shouldSuppressAssistantText(text: string) {
249
274
  return SUPPRESSED_ASSISTANT_TEXTS.has(text.trim());
250
275
  }
251
276
 
277
+ export function claudeLimitErrorMessage(text: string | null | undefined) {
278
+ const normalized = text?.trim();
279
+ if (!normalized) {
280
+ return null;
281
+ }
282
+ return CLAUDE_LIMIT_ERROR_PATTERNS.some((pattern) => pattern.test(normalized))
283
+ ? normalized
284
+ : null;
285
+ }
286
+
287
+ export function limitErrorFromHistoryItems(items: AgentHistoryItem[]) {
288
+ for (let index = items.length - 1; index >= 0; index -= 1) {
289
+ const item = items[index];
290
+ if (item?.kind !== 'agentMessage') {
291
+ continue;
292
+ }
293
+ const error = claudeLimitErrorMessage(item.text);
294
+ if (error) {
295
+ return error;
296
+ }
297
+ }
298
+ return null;
299
+ }
300
+
252
301
  export function userMessageToHistoryItem(id: string, message: unknown): AgentHistoryItem {
253
302
  return {
254
303
  id,
@@ -418,6 +467,44 @@ export function toolResultBlocks(message: unknown): Array<{ toolUseId: string; r
418
467
  .filter((block): block is { toolUseId: string; result: unknown } => Boolean(block));
419
468
  }
420
469
 
470
+ function xmlTagText(input: string, tagName: string) {
471
+ const match = new RegExp(`<${tagName}>([\\s\\S]*?)</${tagName}>`, 'i').exec(input);
472
+ return match?.[1]?.trim() || null;
473
+ }
474
+
475
+ function decodeBasicXmlEntities(input: string) {
476
+ return input
477
+ .replace(/&quot;/g, '"')
478
+ .replace(/&apos;/g, "'")
479
+ .replace(/&gt;/g, '>')
480
+ .replace(/&lt;/g, '<')
481
+ .replace(/&amp;/g, '&');
482
+ }
483
+
484
+ export function taskNotificationToolResult(
485
+ message: unknown,
486
+ ): { toolUseId: string; result: string } | null {
487
+ const text = messageContentText(message).trim();
488
+ if (!text.startsWith('<task-notification>') || !text.includes('</task-notification>')) {
489
+ return null;
490
+ }
491
+
492
+ const toolUseId = xmlTagText(text, 'tool-use-id');
493
+ if (!toolUseId) {
494
+ return null;
495
+ }
496
+
497
+ const result =
498
+ xmlTagText(text, 'result') ??
499
+ xmlTagText(text, 'summary') ??
500
+ text;
501
+
502
+ return {
503
+ toolUseId,
504
+ result: decodeBasicXmlEntities(result),
505
+ };
506
+ }
507
+
421
508
  export function askUserQuestionToolUseIds(message: unknown): Set<string> {
422
509
  const ids = new Set<string>();
423
510
  for (const block of contentBlocks(message)) {
@@ -486,11 +573,16 @@ export function assistantMessageToHistoryItems(
486
573
  if (type === 'thinking') {
487
574
  const thinking = thinkingTextFromBlock(block);
488
575
  if (thinking) {
489
- items.push({
490
- id: `${input.messageId}:content:${index}`,
491
- kind: 'reasoning',
492
- text: thinking,
493
- });
576
+ const previous = items.at(-1);
577
+ if (previous?.kind === 'reasoning') {
578
+ previous.text = joinReasoningText(previous.text, thinking);
579
+ } else {
580
+ items.push({
581
+ id: `${input.messageId}:content:${index}`,
582
+ kind: 'reasoning',
583
+ text: thinking,
584
+ });
585
+ }
494
586
  }
495
587
  continue;
496
588
  }
@@ -715,12 +807,15 @@ export function buildAgentTurn(input: {
715
807
  items: AgentHistoryItem[];
716
808
  rawTurn?: unknown;
717
809
  }): AgentTurn {
810
+ const startedAt = input.startedAt ?? null;
718
811
  const turn: AgentTurn = {
719
812
  providerTurnId: input.providerTurnId,
720
- startedAt: input.startedAt ?? null,
813
+ startedAt,
721
814
  status: input.status,
722
815
  error: input.error ? { message: input.error } : null,
723
- items: input.items,
816
+ items: input.items.map((item) =>
817
+ item.createdAt || !startedAt ? item : { ...item, createdAt: startedAt },
818
+ ),
724
819
  };
725
820
  if (input.rawTurn !== undefined) {
726
821
  turn.rawTurn = input.rawTurn;