sidekick-shared 0.21.2 → 0.21.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -45
- package/dist/accountManager.js +9 -7
- package/dist/accountRegistry.d.ts +17 -0
- package/dist/accountRegistry.js +18 -14
- package/dist/accountStatus.js +7 -7
- package/dist/accounts.d.ts +13 -0
- package/dist/accounts.js +110 -25
- package/dist/aggregation/EventAggregator.d.ts +14 -11
- package/dist/aggregation/EventAggregator.js +68 -31
- package/dist/aggregation/PatternExtractor.js +5 -4
- package/dist/autoSwitch.js +6 -12
- package/dist/claudeProfiles.js +3 -3
- package/dist/codexProfiles.d.ts +15 -1
- package/dist/codexProfiles.js +96 -22
- package/dist/codexQuota.js +44 -16
- package/dist/codexQuotaWatcher.js +19 -4
- package/dist/context/composer.js +8 -6
- package/dist/context/sessionContext.js +12 -9
- package/dist/credentialIO.js +10 -8
- package/dist/extractors/sessionAssets.js +9 -1
- package/dist/extractors/sources/claudeAssets.js +7 -1
- package/dist/extractors/sources/codexAssets.js +14 -3
- package/dist/extractors/toolCall.js +1 -4
- package/dist/formatters/eventHighlighter.js +148 -28
- package/dist/formatters/noiseClassifier.js +3 -11
- package/dist/formatters/sessionDump.js +22 -13
- package/dist/formatters/toolSummary.js +1 -3
- package/dist/index.d.ts +26 -26
- package/dist/index.js +10 -4
- package/dist/modelContext.js +10 -8
- package/dist/modelInfo.js +11 -6
- package/dist/multiProviderQuotaService.d.ts +2 -2
- package/dist/multiProviderQuotaService.js +14 -10
- package/dist/parsers/codexParser.js +170 -103
- package/dist/parsers/debugLogParser.js +5 -4
- package/dist/parsers/openCodeParser.js +66 -48
- package/dist/parsers/planExtractor.js +3 -3
- package/dist/parsers/sessionActivityDetector.js +10 -6
- package/dist/parsers/sessionPathResolver.js +29 -34
- package/dist/parsers/subagentScanner.js +21 -20
- package/dist/parsers/subagentTraceParser.js +7 -4
- package/dist/phrases.js +11 -11
- package/dist/providerStatus.js +3 -4
- package/dist/providers/claudeCode.js +3 -1
- package/dist/providers/codex.js +35 -14
- package/dist/providers/codexDatabase.js +14 -5
- package/dist/providers/detect.js +10 -6
- package/dist/providers/openCode.js +91 -63
- package/dist/providers/openCodeDatabase.js +44 -17
- package/dist/quota.d.ts +19 -0
- package/dist/quota.js +50 -8
- package/dist/quotaHistory.js +10 -3
- package/dist/quotaSnapshots.js +2 -2
- package/dist/readers/decisions.js +1 -1
- package/dist/readers/notes.js +5 -3
- package/dist/readers/plans.js +43 -23
- package/dist/readers/tasks.js +1 -1
- package/dist/report/htmlHelpers.js +135 -16
- package/dist/report/htmlReportGenerator.js +38 -12
- package/dist/report/transcriptParser.js +8 -2
- package/dist/schemas/index.d.ts +4 -4
- package/dist/schemas/quota.js +2 -10
- package/dist/schemas/sessionEvent.js +20 -10
- package/dist/search/advancedFilter.js +3 -3
- package/dist/search/sessionSearch.js +10 -4
- package/dist/terminalSync.js +4 -2
- package/dist/turns/assistantTurn.js +5 -1
- package/dist/watchers/eventBridge.js +56 -26
- package/dist/watchers/factory.js +5 -2
- package/dist/watchers/jsonlTail.js +3 -1
- package/dist/watchers/jsonlWatcher.js +128 -52
- package/dist/watchers/providerReaderWatcher.js +3 -1
- package/dist/watchers/sqliteWatcher.js +52 -22
- package/dist/zaiQuota.js +6 -10
- package/dist/zaiQuotaApi.js +13 -5
- package/dist/zaiQuotaWatcher.js +1 -1
- package/package.json +5 -2
|
@@ -77,11 +77,12 @@ class MultiProviderQuotaService {
|
|
|
77
77
|
constructor(options = {}) {
|
|
78
78
|
this.activeIntervalMs = options.activeIntervalMs ?? ACTIVE_POLL_INTERVAL_MS;
|
|
79
79
|
this.idleIntervalMs = options.idleIntervalMs ?? IDLE_POLL_INTERVAL_MS;
|
|
80
|
-
this.transientFailureBackoffMs =
|
|
80
|
+
this.transientFailureBackoffMs =
|
|
81
|
+
options.transientFailureBackoffMs ?? TRANSIENT_FAILURE_BACKOFF_MS;
|
|
81
82
|
this.peakHoursCacheMaxAgeMs = options.peakHoursCacheMaxAgeMs ?? PEAK_HOURS_CACHE_MAX_AGE_MS;
|
|
82
83
|
this.includePeakHours = options.includePeakHours ?? true;
|
|
83
84
|
this.readClaudeCredentials = options.readClaudeCredentials ?? credentials_1.readClaudeMaxCredentials;
|
|
84
|
-
this.readClaudeAccount = options.readClaudeAccount ?? accounts_1.
|
|
85
|
+
this.readClaudeAccount = options.readClaudeAccount ?? accounts_1.resolveActiveClaudeAccount;
|
|
85
86
|
this.fetchClaudeQuota = options.fetchClaudeQuota ?? quota_1.fetchQuota;
|
|
86
87
|
this.fetchPeakHours = options.fetchPeakHours ?? peakHours_1.fetchPeakHoursStatus;
|
|
87
88
|
this.log = options.log;
|
|
@@ -97,9 +98,10 @@ class MultiProviderQuotaService {
|
|
|
97
98
|
this.codexWatcher = null;
|
|
98
99
|
this.ownsCodexWatcher = false;
|
|
99
100
|
}
|
|
100
|
-
this.codexSubscription =
|
|
101
|
-
this.
|
|
102
|
-
|
|
101
|
+
this.codexSubscription =
|
|
102
|
+
this.codexWatcher?.onUpdate((state) => {
|
|
103
|
+
this.updateProviderQuota('codex', state);
|
|
104
|
+
}) ?? null;
|
|
103
105
|
if (options.zaiWatcher !== undefined) {
|
|
104
106
|
this.zaiWatcher = options.zaiWatcher;
|
|
105
107
|
this.ownsZaiWatcher = false;
|
|
@@ -108,9 +110,10 @@ class MultiProviderQuotaService {
|
|
|
108
110
|
this.zaiWatcher = null;
|
|
109
111
|
this.ownsZaiWatcher = false;
|
|
110
112
|
}
|
|
111
|
-
this.zaiSubscription =
|
|
112
|
-
this.
|
|
113
|
-
|
|
113
|
+
this.zaiSubscription =
|
|
114
|
+
this.zaiWatcher?.onUpdate((state) => {
|
|
115
|
+
this.updateProviderQuota('zai', state);
|
|
116
|
+
}) ?? null;
|
|
114
117
|
}
|
|
115
118
|
startPolling() {
|
|
116
119
|
if (this.polling)
|
|
@@ -350,7 +353,8 @@ class MultiProviderQuotaService {
|
|
|
350
353
|
this.timer = setTimeout(() => void this.poll(), delay);
|
|
351
354
|
}
|
|
352
355
|
withClaudeAccountDetails(state) {
|
|
353
|
-
const
|
|
356
|
+
const resolved = this.readClaudeAccount();
|
|
357
|
+
const accountEmail = resolved.email;
|
|
354
358
|
if (!accountEmail) {
|
|
355
359
|
const nextState = { ...state };
|
|
356
360
|
delete nextState.accountLabel;
|
|
@@ -359,7 +363,7 @@ class MultiProviderQuotaService {
|
|
|
359
363
|
}
|
|
360
364
|
return {
|
|
361
365
|
...state,
|
|
362
|
-
accountLabel: accountEmail,
|
|
366
|
+
accountLabel: resolved.label ?? accountEmail,
|
|
363
367
|
accountDetail: accountEmail,
|
|
364
368
|
};
|
|
365
369
|
}
|
|
@@ -21,16 +21,20 @@ function normalizeRateLimits(rateLimits) {
|
|
|
21
21
|
if (!rateLimits?.primary && !rateLimits?.secondary)
|
|
22
22
|
return undefined;
|
|
23
23
|
return {
|
|
24
|
-
primary: rateLimits.primary
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
primary: rateLimits.primary
|
|
25
|
+
? {
|
|
26
|
+
usedPercent: rateLimits.primary.used_percent || 0,
|
|
27
|
+
windowMinutes: rateLimits.primary.window_minutes || 0,
|
|
28
|
+
resetsAt: rateLimits.primary.resets_at || 0,
|
|
29
|
+
}
|
|
30
|
+
: undefined,
|
|
31
|
+
secondary: rateLimits.secondary
|
|
32
|
+
? {
|
|
33
|
+
usedPercent: rateLimits.secondary.used_percent || 0,
|
|
34
|
+
windowMinutes: rateLimits.secondary.window_minutes || 0,
|
|
35
|
+
resetsAt: rateLimits.secondary.resets_at || 0,
|
|
36
|
+
}
|
|
37
|
+
: undefined,
|
|
34
38
|
};
|
|
35
39
|
}
|
|
36
40
|
/**
|
|
@@ -62,7 +66,9 @@ function normalizeCodexToolInput(canonicalToolName, rawToolName, input) {
|
|
|
62
66
|
const normalized = { ...input };
|
|
63
67
|
normalized._sidekickRawToolName = rawToolName;
|
|
64
68
|
// Codex exec_command uses cmd; monitor expects command for Bash context extraction.
|
|
65
|
-
if (canonicalToolName === 'Bash' &&
|
|
69
|
+
if (canonicalToolName === 'Bash' &&
|
|
70
|
+
typeof normalized.cmd === 'string' &&
|
|
71
|
+
normalized.command === undefined) {
|
|
66
72
|
normalized.command = normalized.cmd;
|
|
67
73
|
}
|
|
68
74
|
// request_user_input currently emits questions; keep as-is (compatible with AskUserQuestion extractor).
|
|
@@ -181,7 +187,8 @@ class CodexRolloutParser {
|
|
|
181
187
|
const text = payload.base_instructions?.text?.trim();
|
|
182
188
|
if (!text)
|
|
183
189
|
return [];
|
|
184
|
-
return [
|
|
190
|
+
return [
|
|
191
|
+
{
|
|
185
192
|
type: 'system',
|
|
186
193
|
message: {
|
|
187
194
|
role: 'system',
|
|
@@ -190,7 +197,8 @@ class CodexRolloutParser {
|
|
|
190
197
|
content: [{ type: 'text', text }],
|
|
191
198
|
},
|
|
192
199
|
timestamp,
|
|
193
|
-
}
|
|
200
|
+
},
|
|
201
|
+
];
|
|
194
202
|
}
|
|
195
203
|
handleResponseItem(timestamp, payload) {
|
|
196
204
|
// payload IS the item directly (no .item wrapper)
|
|
@@ -220,7 +228,8 @@ class CodexRolloutParser {
|
|
|
220
228
|
if (!text)
|
|
221
229
|
return [];
|
|
222
230
|
if (item.role === 'user') {
|
|
223
|
-
return [
|
|
231
|
+
return [
|
|
232
|
+
{
|
|
224
233
|
type: 'user',
|
|
225
234
|
message: {
|
|
226
235
|
role: 'user',
|
|
@@ -228,10 +237,12 @@ class CodexRolloutParser {
|
|
|
228
237
|
content: [{ type: 'text', text }],
|
|
229
238
|
},
|
|
230
239
|
timestamp,
|
|
231
|
-
}
|
|
240
|
+
},
|
|
241
|
+
];
|
|
232
242
|
}
|
|
233
243
|
if (item.role === 'assistant') {
|
|
234
|
-
return [
|
|
244
|
+
return [
|
|
245
|
+
{
|
|
235
246
|
type: 'assistant',
|
|
236
247
|
message: {
|
|
237
248
|
role: 'assistant',
|
|
@@ -240,10 +251,12 @@ class CodexRolloutParser {
|
|
|
240
251
|
content: [{ type: 'text', text }],
|
|
241
252
|
},
|
|
242
253
|
timestamp,
|
|
243
|
-
}
|
|
254
|
+
},
|
|
255
|
+
];
|
|
244
256
|
}
|
|
245
257
|
if (item.role === 'developer' || item.role === 'system') {
|
|
246
|
-
return [
|
|
258
|
+
return [
|
|
259
|
+
{
|
|
247
260
|
type: 'system',
|
|
248
261
|
message: {
|
|
249
262
|
role: item.role,
|
|
@@ -252,17 +265,19 @@ class CodexRolloutParser {
|
|
|
252
265
|
content: [{ type: 'text', text }],
|
|
253
266
|
},
|
|
254
267
|
timestamp,
|
|
255
|
-
}
|
|
268
|
+
},
|
|
269
|
+
];
|
|
256
270
|
}
|
|
257
271
|
return [];
|
|
258
272
|
}
|
|
259
273
|
handleReasoning(timestamp, item) {
|
|
260
274
|
const summaryTexts = (item.summary || [])
|
|
261
|
-
.filter(s => s.type === 'summary_text' && s.text)
|
|
262
|
-
.map(s => s.text);
|
|
275
|
+
.filter((s) => s.type === 'summary_text' && s.text)
|
|
276
|
+
.map((s) => s.text);
|
|
263
277
|
if (summaryTexts.length === 0)
|
|
264
278
|
return [];
|
|
265
|
-
return [
|
|
279
|
+
return [
|
|
280
|
+
{
|
|
266
281
|
type: 'assistant',
|
|
267
282
|
message: {
|
|
268
283
|
role: 'assistant',
|
|
@@ -271,7 +286,8 @@ class CodexRolloutParser {
|
|
|
271
286
|
content: [{ type: 'thinking', thinking: summaryTexts.join('\n') }],
|
|
272
287
|
},
|
|
273
288
|
timestamp,
|
|
274
|
-
}
|
|
289
|
+
},
|
|
290
|
+
];
|
|
275
291
|
}
|
|
276
292
|
handleFunctionCall(timestamp, item) {
|
|
277
293
|
let parsedArgs = {};
|
|
@@ -284,49 +300,59 @@ class CodexRolloutParser {
|
|
|
284
300
|
const canonicalName = normalizeCodexToolName(item.name);
|
|
285
301
|
const normalizedInput = normalizeCodexToolInput(canonicalName, item.name, parsedArgs);
|
|
286
302
|
this.emittedToolUseIds.add(item.call_id);
|
|
287
|
-
return [
|
|
303
|
+
return [
|
|
304
|
+
{
|
|
288
305
|
type: 'assistant',
|
|
289
306
|
message: {
|
|
290
307
|
role: 'assistant',
|
|
291
308
|
id: item.id,
|
|
292
309
|
model: this.currentModel || undefined,
|
|
293
|
-
content: [
|
|
310
|
+
content: [
|
|
311
|
+
{
|
|
294
312
|
type: 'tool_use',
|
|
295
313
|
id: item.call_id,
|
|
296
314
|
name: canonicalName,
|
|
297
315
|
input: normalizedInput,
|
|
298
|
-
}
|
|
316
|
+
},
|
|
317
|
+
],
|
|
299
318
|
},
|
|
300
319
|
timestamp,
|
|
301
|
-
}
|
|
320
|
+
},
|
|
321
|
+
];
|
|
302
322
|
}
|
|
303
323
|
handleFunctionCallOutput(timestamp, item) {
|
|
304
324
|
const isError = parsePlainTextFailure(item.output);
|
|
305
|
-
return [
|
|
325
|
+
return [
|
|
326
|
+
{
|
|
306
327
|
type: 'user',
|
|
307
328
|
message: {
|
|
308
329
|
role: 'user',
|
|
309
330
|
id: `${item.call_id}:result`,
|
|
310
|
-
content: [
|
|
331
|
+
content: [
|
|
332
|
+
{
|
|
311
333
|
type: 'tool_result',
|
|
312
334
|
tool_use_id: item.call_id,
|
|
313
335
|
content: item.output,
|
|
314
336
|
is_error: isError,
|
|
315
|
-
}
|
|
337
|
+
},
|
|
338
|
+
],
|
|
316
339
|
},
|
|
317
340
|
timestamp,
|
|
318
|
-
}
|
|
341
|
+
},
|
|
342
|
+
];
|
|
319
343
|
}
|
|
320
344
|
handleLocalShellCall(timestamp, item) {
|
|
321
345
|
const command = item.action?.command?.join(' ') || '';
|
|
322
346
|
this.emittedToolUseIds.add(item.call_id);
|
|
323
|
-
return [
|
|
347
|
+
return [
|
|
348
|
+
{
|
|
324
349
|
type: 'assistant',
|
|
325
350
|
message: {
|
|
326
351
|
role: 'assistant',
|
|
327
352
|
id: item.id,
|
|
328
353
|
model: this.currentModel || undefined,
|
|
329
|
-
content: [
|
|
354
|
+
content: [
|
|
355
|
+
{
|
|
330
356
|
type: 'tool_use',
|
|
331
357
|
id: item.call_id,
|
|
332
358
|
name: 'Bash',
|
|
@@ -335,28 +361,31 @@ class CodexRolloutParser {
|
|
|
335
361
|
workdir: item.action?.workdir,
|
|
336
362
|
_sidekickRawToolName: 'local_shell_call',
|
|
337
363
|
},
|
|
338
|
-
}
|
|
364
|
+
},
|
|
365
|
+
],
|
|
339
366
|
},
|
|
340
367
|
timestamp,
|
|
341
|
-
}
|
|
368
|
+
},
|
|
369
|
+
];
|
|
342
370
|
}
|
|
343
371
|
handleCustomToolCall(timestamp, item) {
|
|
344
372
|
if (item.name === 'apply_patch') {
|
|
345
373
|
const filePaths = extractPatchFilePaths(item.input);
|
|
346
374
|
if (filePaths.length === 0)
|
|
347
375
|
return [];
|
|
348
|
-
const toolUseIds = filePaths.map(fp => `${item.call_id}-${fp}`);
|
|
376
|
+
const toolUseIds = filePaths.map((fp) => `${item.call_id}-${fp}`);
|
|
349
377
|
this.patchExpandedToolUseIds.set(item.call_id, toolUseIds);
|
|
350
378
|
for (const id of toolUseIds) {
|
|
351
379
|
this.emittedToolUseIds.add(id);
|
|
352
380
|
}
|
|
353
|
-
return filePaths.map(fp => ({
|
|
381
|
+
return filePaths.map((fp) => ({
|
|
354
382
|
type: 'assistant',
|
|
355
383
|
message: {
|
|
356
384
|
role: 'assistant',
|
|
357
385
|
id: `${item.call_id}-${fp}`,
|
|
358
386
|
model: this.currentModel || undefined,
|
|
359
|
-
content: [
|
|
387
|
+
content: [
|
|
388
|
+
{
|
|
360
389
|
type: 'tool_use',
|
|
361
390
|
id: `${item.call_id}-${fp}`,
|
|
362
391
|
name: 'Edit',
|
|
@@ -364,7 +393,8 @@ class CodexRolloutParser {
|
|
|
364
393
|
file_path: fp,
|
|
365
394
|
_sidekickRawToolName: 'apply_patch',
|
|
366
395
|
},
|
|
367
|
-
}
|
|
396
|
+
},
|
|
397
|
+
],
|
|
368
398
|
},
|
|
369
399
|
timestamp,
|
|
370
400
|
}));
|
|
@@ -380,21 +410,25 @@ class CodexRolloutParser {
|
|
|
380
410
|
const canonicalName = normalizeCodexToolName(item.name);
|
|
381
411
|
const normalizedInput = normalizeCodexToolInput(canonicalName, item.name, parsedInput);
|
|
382
412
|
this.emittedToolUseIds.add(item.call_id);
|
|
383
|
-
return [
|
|
413
|
+
return [
|
|
414
|
+
{
|
|
384
415
|
type: 'assistant',
|
|
385
416
|
message: {
|
|
386
417
|
role: 'assistant',
|
|
387
418
|
id: item.call_id,
|
|
388
419
|
model: this.currentModel || undefined,
|
|
389
|
-
content: [
|
|
420
|
+
content: [
|
|
421
|
+
{
|
|
390
422
|
type: 'tool_use',
|
|
391
423
|
id: item.call_id,
|
|
392
424
|
name: canonicalName,
|
|
393
425
|
input: normalizedInput,
|
|
394
|
-
}
|
|
426
|
+
},
|
|
427
|
+
],
|
|
395
428
|
},
|
|
396
429
|
timestamp,
|
|
397
|
-
}
|
|
430
|
+
},
|
|
431
|
+
];
|
|
398
432
|
}
|
|
399
433
|
handleCustomToolCallOutput(timestamp, item) {
|
|
400
434
|
let isError = false;
|
|
@@ -411,24 +445,27 @@ class CodexRolloutParser {
|
|
|
411
445
|
}
|
|
412
446
|
const toolUseIds = this.patchExpandedToolUseIds.get(item.call_id) ?? [item.call_id];
|
|
413
447
|
this.patchExpandedToolUseIds.delete(item.call_id);
|
|
414
|
-
return toolUseIds.map(toolUseId => ({
|
|
448
|
+
return toolUseIds.map((toolUseId) => ({
|
|
415
449
|
type: 'user',
|
|
416
450
|
message: {
|
|
417
451
|
role: 'user',
|
|
418
452
|
id: `${toolUseId}:result`,
|
|
419
|
-
content: [
|
|
453
|
+
content: [
|
|
454
|
+
{
|
|
420
455
|
type: 'tool_result',
|
|
421
456
|
tool_use_id: toolUseId,
|
|
422
457
|
content: item.output,
|
|
423
458
|
is_error: isError,
|
|
424
459
|
duration,
|
|
425
|
-
}
|
|
460
|
+
},
|
|
461
|
+
],
|
|
426
462
|
},
|
|
427
463
|
timestamp,
|
|
428
464
|
}));
|
|
429
465
|
}
|
|
430
466
|
handleCompacted(timestamp, payload) {
|
|
431
|
-
return [
|
|
467
|
+
return [
|
|
468
|
+
{
|
|
432
469
|
type: 'summary',
|
|
433
470
|
message: {
|
|
434
471
|
role: 'assistant',
|
|
@@ -436,7 +473,8 @@ class CodexRolloutParser {
|
|
|
436
473
|
content: payload.summary || 'Context compacted',
|
|
437
474
|
},
|
|
438
475
|
timestamp,
|
|
439
|
-
}
|
|
476
|
+
},
|
|
477
|
+
];
|
|
440
478
|
}
|
|
441
479
|
handleTurnContext(payload) {
|
|
442
480
|
if (payload.model) {
|
|
@@ -489,7 +527,8 @@ class CodexRolloutParser {
|
|
|
489
527
|
role: 'assistant',
|
|
490
528
|
id: `exec-${e.call_id}`,
|
|
491
529
|
model: this.currentModel || undefined,
|
|
492
|
-
content: [
|
|
530
|
+
content: [
|
|
531
|
+
{
|
|
493
532
|
type: 'tool_use',
|
|
494
533
|
id: e.call_id,
|
|
495
534
|
name: 'Bash',
|
|
@@ -498,7 +537,8 @@ class CodexRolloutParser {
|
|
|
498
537
|
workdir: pending?.workdir,
|
|
499
538
|
_sidekickRawToolName: 'exec_command',
|
|
500
539
|
},
|
|
501
|
-
}
|
|
540
|
+
},
|
|
541
|
+
],
|
|
502
542
|
},
|
|
503
543
|
timestamp: pending?.timestamp || timestamp,
|
|
504
544
|
});
|
|
@@ -509,13 +549,15 @@ class CodexRolloutParser {
|
|
|
509
549
|
message: {
|
|
510
550
|
role: 'user',
|
|
511
551
|
id: `exec-${e.call_id}:result`,
|
|
512
|
-
content: [
|
|
552
|
+
content: [
|
|
553
|
+
{
|
|
513
554
|
type: 'tool_result',
|
|
514
555
|
tool_use_id: e.call_id,
|
|
515
556
|
content: output,
|
|
516
557
|
is_error: e.exit_code !== 0,
|
|
517
558
|
duration: e.duration_ms,
|
|
518
|
-
}
|
|
559
|
+
},
|
|
560
|
+
],
|
|
519
561
|
},
|
|
520
562
|
timestamp,
|
|
521
563
|
});
|
|
@@ -546,7 +588,8 @@ class CodexRolloutParser {
|
|
|
546
588
|
role: 'assistant',
|
|
547
589
|
id: `mcp-${e.call_id}`,
|
|
548
590
|
model: this.currentModel || undefined,
|
|
549
|
-
content: [
|
|
591
|
+
content: [
|
|
592
|
+
{
|
|
550
593
|
type: 'tool_use',
|
|
551
594
|
id: e.call_id,
|
|
552
595
|
name: normalizeCodexToolName(toolName),
|
|
@@ -555,7 +598,8 @@ class CodexRolloutParser {
|
|
|
555
598
|
_sidekickRawToolName: toolName,
|
|
556
599
|
_sidekickMcpServerName: pendingMcp?.server_name,
|
|
557
600
|
},
|
|
558
|
-
}
|
|
601
|
+
},
|
|
602
|
+
],
|
|
559
603
|
},
|
|
560
604
|
timestamp: pendingMcp?.timestamp || timestamp,
|
|
561
605
|
});
|
|
@@ -565,13 +609,15 @@ class CodexRolloutParser {
|
|
|
565
609
|
message: {
|
|
566
610
|
role: 'user',
|
|
567
611
|
id: `mcp-${e.call_id}:result`,
|
|
568
|
-
content: [
|
|
612
|
+
content: [
|
|
613
|
+
{
|
|
569
614
|
type: 'tool_result',
|
|
570
615
|
tool_use_id: e.call_id,
|
|
571
616
|
content: e.result || '',
|
|
572
617
|
is_error: e.is_error || false,
|
|
573
618
|
duration: e.duration_ms,
|
|
574
|
-
}
|
|
619
|
+
},
|
|
620
|
+
],
|
|
575
621
|
},
|
|
576
622
|
timestamp,
|
|
577
623
|
});
|
|
@@ -579,20 +625,25 @@ class CodexRolloutParser {
|
|
|
579
625
|
}
|
|
580
626
|
case 'error': {
|
|
581
627
|
const e = event;
|
|
582
|
-
return [
|
|
628
|
+
return [
|
|
629
|
+
{
|
|
583
630
|
type: 'assistant',
|
|
584
631
|
message: {
|
|
585
632
|
role: 'assistant',
|
|
586
633
|
id: `error-${timestamp}`,
|
|
587
634
|
model: this.currentModel || undefined,
|
|
588
|
-
content: [
|
|
635
|
+
content: [
|
|
636
|
+
{ type: 'text', text: `[Error${e.code ? ` (${e.code})` : ''}] ${e.message}` },
|
|
637
|
+
],
|
|
589
638
|
},
|
|
590
639
|
timestamp,
|
|
591
|
-
}
|
|
640
|
+
},
|
|
641
|
+
];
|
|
592
642
|
}
|
|
593
643
|
case 'context_compacted': {
|
|
594
644
|
const e = event;
|
|
595
|
-
return [
|
|
645
|
+
return [
|
|
646
|
+
{
|
|
596
647
|
type: 'summary',
|
|
597
648
|
message: {
|
|
598
649
|
role: 'assistant',
|
|
@@ -600,20 +651,23 @@ class CodexRolloutParser {
|
|
|
600
651
|
content: e.summary || 'Context compacted',
|
|
601
652
|
},
|
|
602
653
|
timestamp,
|
|
603
|
-
}
|
|
654
|
+
},
|
|
655
|
+
];
|
|
604
656
|
}
|
|
605
657
|
case 'patch_applied': {
|
|
606
658
|
const e = event;
|
|
607
659
|
if (!e.file_path)
|
|
608
660
|
return [];
|
|
609
661
|
const patchId = `patch-${timestamp}-${e.file_path}`;
|
|
610
|
-
return [
|
|
662
|
+
return [
|
|
663
|
+
{
|
|
611
664
|
type: 'assistant',
|
|
612
665
|
message: {
|
|
613
666
|
role: 'assistant',
|
|
614
667
|
id: patchId,
|
|
615
668
|
model: this.currentModel || undefined,
|
|
616
|
-
content: [
|
|
669
|
+
content: [
|
|
670
|
+
{
|
|
617
671
|
type: 'tool_use',
|
|
618
672
|
id: patchId,
|
|
619
673
|
name: 'Edit',
|
|
@@ -623,49 +677,56 @@ class CodexRolloutParser {
|
|
|
623
677
|
deletions: e.deletions ?? 0,
|
|
624
678
|
_sidekickRawToolName: 'patch_applied',
|
|
625
679
|
},
|
|
626
|
-
}
|
|
680
|
+
},
|
|
681
|
+
],
|
|
627
682
|
},
|
|
628
683
|
timestamp,
|
|
629
|
-
}
|
|
684
|
+
},
|
|
685
|
+
];
|
|
630
686
|
}
|
|
631
687
|
case 'turn_started':
|
|
632
688
|
case 'turn_complete':
|
|
633
|
-
case 'task_started':
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
}
|
|
657
|
-
|
|
689
|
+
case 'task_started': {
|
|
690
|
+
const collaborationMode = event.collaboration_mode_kind;
|
|
691
|
+
if (collaborationMode !== 'plan' || this.inPlanMode)
|
|
692
|
+
return [];
|
|
693
|
+
this.inPlanMode = true;
|
|
694
|
+
return [
|
|
695
|
+
{
|
|
696
|
+
type: 'assistant',
|
|
697
|
+
message: {
|
|
698
|
+
role: 'assistant',
|
|
699
|
+
id: `plan-enter-${timestamp}`,
|
|
700
|
+
model: this.currentModel || undefined,
|
|
701
|
+
content: [
|
|
702
|
+
{
|
|
703
|
+
type: 'tool_use',
|
|
704
|
+
id: `plan-enter-${timestamp}`,
|
|
705
|
+
name: 'EnterPlanMode',
|
|
706
|
+
input: {
|
|
707
|
+
source: 'codex_task_started',
|
|
708
|
+
_sidekickRawToolName: 'task_started',
|
|
709
|
+
},
|
|
710
|
+
},
|
|
711
|
+
],
|
|
712
|
+
},
|
|
713
|
+
timestamp,
|
|
714
|
+
},
|
|
715
|
+
];
|
|
716
|
+
}
|
|
658
717
|
case 'task_complete':
|
|
659
718
|
if (!this.inPlanMode)
|
|
660
719
|
return [];
|
|
661
720
|
this.inPlanMode = false;
|
|
662
|
-
return [
|
|
721
|
+
return [
|
|
722
|
+
{
|
|
663
723
|
type: 'assistant',
|
|
664
724
|
message: {
|
|
665
725
|
role: 'assistant',
|
|
666
726
|
id: `plan-exit-${timestamp}`,
|
|
667
727
|
model: this.currentModel || undefined,
|
|
668
|
-
content: [
|
|
728
|
+
content: [
|
|
729
|
+
{
|
|
669
730
|
type: 'tool_use',
|
|
670
731
|
id: `plan-exit-${timestamp}`,
|
|
671
732
|
name: 'ExitPlanMode',
|
|
@@ -673,10 +734,12 @@ class CodexRolloutParser {
|
|
|
673
734
|
source: 'codex_task_complete',
|
|
674
735
|
_sidekickRawToolName: 'task_complete',
|
|
675
736
|
},
|
|
676
|
-
}
|
|
737
|
+
},
|
|
738
|
+
],
|
|
677
739
|
},
|
|
678
740
|
timestamp,
|
|
679
|
-
}
|
|
741
|
+
},
|
|
742
|
+
];
|
|
680
743
|
case 'turn_aborted':
|
|
681
744
|
case 'agent_reasoning':
|
|
682
745
|
case 'agent_message':
|
|
@@ -691,17 +754,20 @@ class CodexRolloutParser {
|
|
|
691
754
|
const normalizedRateLimits = normalizeRateLimits(rateLimits);
|
|
692
755
|
if (!usage && !normalizedRateLimits)
|
|
693
756
|
return [];
|
|
694
|
-
const mappedUsage = usage
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
757
|
+
const mappedUsage = usage
|
|
758
|
+
? {
|
|
759
|
+
input_tokens: usage.input_tokens || 0,
|
|
760
|
+
output_tokens: usage.output_tokens || 0,
|
|
761
|
+
cache_read_input_tokens: usage.cached_input_tokens || 0,
|
|
762
|
+
cache_creation_input_tokens: 0,
|
|
763
|
+
reasoning_tokens: usage.reasoning_output_tokens || 0,
|
|
764
|
+
}
|
|
765
|
+
: undefined;
|
|
701
766
|
if (usage) {
|
|
702
767
|
this.lastTokenUsage = usage;
|
|
703
768
|
}
|
|
704
|
-
return [
|
|
769
|
+
return [
|
|
770
|
+
{
|
|
705
771
|
type: 'system',
|
|
706
772
|
message: {
|
|
707
773
|
role: 'system',
|
|
@@ -713,7 +779,8 @@ class CodexRolloutParser {
|
|
|
713
779
|
},
|
|
714
780
|
timestamp,
|
|
715
781
|
rateLimits: normalizedRateLimits,
|
|
716
|
-
}
|
|
782
|
+
},
|
|
783
|
+
];
|
|
717
784
|
}
|
|
718
785
|
}
|
|
719
786
|
exports.CodexRolloutParser = CodexRolloutParser;
|
|
@@ -103,7 +103,7 @@ function parseDebugLog(content) {
|
|
|
103
103
|
*/
|
|
104
104
|
function filterByLevel(entries, minLevel) {
|
|
105
105
|
const minOrder = LEVEL_ORDER[minLevel];
|
|
106
|
-
return entries.filter(e => LEVEL_ORDER[e.level] >= minOrder);
|
|
106
|
+
return entries.filter((e) => LEVEL_ORDER[e.level] >= minOrder);
|
|
107
107
|
}
|
|
108
108
|
/**
|
|
109
109
|
* Collapses consecutive identical log messages into single entries with counts.
|
|
@@ -138,9 +138,10 @@ function discoverDebugLogs() {
|
|
|
138
138
|
try {
|
|
139
139
|
if (!fs.existsSync(debugDir))
|
|
140
140
|
return [];
|
|
141
|
-
return fs
|
|
142
|
-
.
|
|
143
|
-
.
|
|
141
|
+
return fs
|
|
142
|
+
.readdirSync(debugDir)
|
|
143
|
+
.filter((f) => f.endsWith('.log') || f.endsWith('.txt'))
|
|
144
|
+
.map((name) => {
|
|
144
145
|
const fullPath = path.join(debugDir, name);
|
|
145
146
|
try {
|
|
146
147
|
const stat = fs.statSync(fullPath);
|