sidekick-shared 0.29.1 → 0.30.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 +26 -0
- package/README.md +171 -60
- package/dist/aggregation/EventAggregator.d.ts +79 -4
- package/dist/aggregation/EventAggregator.js +391 -37
- package/dist/aggregation/types.d.ts +27 -3
- package/dist/browser.d.ts +7 -3
- package/dist/browser.js +23 -3
- package/dist/context/sessionContext.js +5 -1
- package/dist/esm/aggregation/EventAggregator.js +392 -38
- package/dist/esm/browser.js +3 -1
- package/dist/esm/context/sessionContext.js +6 -2
- package/dist/esm/fileContinuity.js +149 -0
- package/dist/esm/index.js +5 -2
- package/dist/esm/node.js +2 -0
- package/dist/esm/parsers/codexParser.js +192 -3
- package/dist/esm/parsers/subagentEndState.js +61 -0
- package/dist/esm/parsers/subagentScanner.js +4 -0
- package/dist/esm/parsers/subagentTraceParser.js +6 -0
- package/dist/esm/promptHistory.js +22 -11
- package/dist/esm/providers/claudeCode.js +50 -27
- package/dist/esm/providers/codex.js +153 -163
- package/dist/esm/providers/codexCompressedReader.js +184 -0
- package/dist/esm/providers/codexDatabase.js +47 -2
- package/dist/esm/providers/codexRollouts.js +20 -2
- package/dist/esm/providers/codexSubagents.js +456 -0
- package/dist/esm/providers/compressedRollouts.js +330 -0
- package/dist/esm/providers/factory.js +4 -1
- package/dist/esm/providers/rolloutWalker.js +32 -4
- package/dist/esm/schemas/sessionEvent.js +32 -4
- package/dist/esm/sessionMonitor.js +7 -1
- package/dist/esm/sessionPreviews.js +9 -0
- package/dist/esm/sessionPromptHistory.js +5 -3
- package/dist/esm/subagentActivity.js +125 -0
- package/dist/esm/subagentDisplayState.js +81 -0
- package/dist/esm/subagentSpawn.js +206 -6
- package/dist/esm/testing/codexSubagentFixtures.js +336 -0
- package/dist/esm/toolCallOrigins.js +17 -10
- package/dist/esm/toolCategory.js +6 -2
- package/dist/esm/transcript.js +6 -2
- package/dist/esm/turns/assistantTurn.js +6 -3
- package/dist/esm/usage/usageEvents.js +4 -1
- package/dist/esm/watchers/eventBridge.js +31 -1
- package/dist/esm/watchers/jsonlTail.js +11 -42
- package/dist/esm/watchers/jsonlWatcher.js +19 -9
- package/dist/esm/watchers/providerReaderWatcher.js +5 -4
- package/dist/fileContinuity.d.ts +95 -0
- package/dist/fileContinuity.js +187 -0
- package/dist/index.d.ts +14 -7
- package/dist/index.js +39 -10
- package/dist/node.d.ts +4 -0
- package/dist/node.js +16 -2
- package/dist/parsers/codexParser.d.ts +44 -0
- package/dist/parsers/codexParser.js +192 -3
- package/dist/parsers/subagentEndState.d.ts +20 -0
- package/dist/parsers/subagentEndState.js +65 -0
- package/dist/parsers/subagentScanner.js +4 -0
- package/dist/parsers/subagentTraceParser.d.ts +8 -0
- package/dist/parsers/subagentTraceParser.js +6 -0
- package/dist/promptHistory.d.ts +13 -3
- package/dist/promptHistory.js +22 -11
- package/dist/providers/claudeCode.js +50 -27
- package/dist/providers/codex.d.ts +35 -5
- package/dist/providers/codex.js +150 -160
- package/dist/providers/codexCompressedReader.d.ts +58 -0
- package/dist/providers/codexCompressedReader.js +221 -0
- package/dist/providers/codexDatabase.d.ts +25 -0
- package/dist/providers/codexDatabase.js +48 -2
- package/dist/providers/codexRollouts.d.ts +16 -2
- package/dist/providers/codexRollouts.js +20 -2
- package/dist/providers/codexSubagents.d.ts +66 -0
- package/dist/providers/codexSubagents.js +495 -0
- package/dist/providers/compressedRollouts.d.ts +114 -0
- package/dist/providers/compressedRollouts.js +380 -0
- package/dist/providers/factory.d.ts +5 -0
- package/dist/providers/factory.js +4 -1
- package/dist/providers/rolloutWalker.d.ts +15 -2
- package/dist/providers/rolloutWalker.js +33 -4
- package/dist/providers/types.d.ts +22 -1
- package/dist/schemas/sessionEvent.d.ts +26 -2
- package/dist/schemas/sessionEvent.js +31 -3
- package/dist/sessionMonitor.d.ts +6 -0
- package/dist/sessionMonitor.js +7 -1
- package/dist/sessionPreviews.js +9 -0
- package/dist/sessionPromptHistory.d.ts +5 -0
- package/dist/sessionPromptHistory.js +5 -36
- package/dist/subagentActivity.d.ts +91 -0
- package/dist/subagentActivity.js +132 -0
- package/dist/subagentDisplayState.d.ts +81 -0
- package/dist/subagentDisplayState.js +86 -0
- package/dist/subagentSpawn.d.ts +100 -5
- package/dist/subagentSpawn.js +218 -7
- package/dist/testing/codexSubagentFixtures.d.ts +48 -0
- package/dist/testing/codexSubagentFixtures.js +344 -0
- package/dist/toolCallOrigins.d.ts +5 -0
- package/dist/toolCallOrigins.js +17 -10
- package/dist/toolCategory.js +6 -2
- package/dist/transcript.js +5 -1
- package/dist/turns/assistantTurn.d.ts +4 -1
- package/dist/turns/assistantTurn.js +5 -2
- package/dist/types/codex.d.ts +71 -2
- package/dist/types/sessionEvent.d.ts +38 -3
- package/dist/usage/usageEvents.d.ts +4 -1
- package/dist/usage/usageEvents.js +4 -1
- package/dist/watchers/eventBridge.js +30 -0
- package/dist/watchers/jsonlTail.js +11 -42
- package/dist/watchers/jsonlWatcher.d.ts +5 -1
- package/dist/watchers/jsonlWatcher.js +18 -8
- package/dist/watchers/providerReaderWatcher.js +5 -4
- package/package.json +1 -1
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Redacted rollouts in the shape Codex 0.166 writes for multi-agent sessions:
|
|
4
|
+
* a parent that spawns a child (`spawn_agent` → `SubAgentActivity` started →
|
|
5
|
+
* `{"task_name": …}` output → MESSAGE / FINAL_ANSWER agent messages →
|
|
6
|
+
* `completed`), a failed spawn, `followup_task` / `send_message` /
|
|
7
|
+
* `interrupt_agent` interactions, and a forked child whose rollout embeds the
|
|
8
|
+
* parent's history (and session_meta) before its
|
|
9
|
+
* `subagent_history_start_ordinal`, which itself spawns a grandchild.
|
|
10
|
+
* Payload text is placeholder; ids are synthetic.
|
|
11
|
+
*
|
|
12
|
+
* Test-only helpers.
|
|
13
|
+
*
|
|
14
|
+
* @module testing/codexSubagentFixtures
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.GRANDCHILD_PATH = exports.CHILD_PATH = exports.CHILD_TURN_ID = exports.CALL_SPAWN_GRANDCHILD = exports.CALL_INTERRUPT = exports.CALL_SEND = exports.CALL_FOLLOWUP = exports.CALL_SPAWN_FAILED = exports.CALL_SPAWN = exports.GRANDCHILD_ID = exports.CHILD_ID = exports.PARENT_ID = void 0;
|
|
18
|
+
exports.at = at;
|
|
19
|
+
exports.parentRollout = parentRollout;
|
|
20
|
+
exports.childRollout = childRollout;
|
|
21
|
+
exports.grandchildRollout = grandchildRollout;
|
|
22
|
+
exports.toJsonl = toJsonl;
|
|
23
|
+
exports.PARENT_ID = '01a18f87-0000-7000-8000-000000000001';
|
|
24
|
+
exports.CHILD_ID = '01a18f9d-0000-7000-8000-000000000002';
|
|
25
|
+
exports.GRANDCHILD_ID = '01a18fa0-0000-7000-8000-000000000003';
|
|
26
|
+
exports.CALL_SPAWN = 'call_spawn_builder';
|
|
27
|
+
exports.CALL_SPAWN_FAILED = 'call_spawn_failed';
|
|
28
|
+
exports.CALL_FOLLOWUP = 'call_followup_builder';
|
|
29
|
+
exports.CALL_SEND = 'call_send_builder';
|
|
30
|
+
exports.CALL_INTERRUPT = 'call_interrupt_builder';
|
|
31
|
+
exports.CALL_SPAWN_GRANDCHILD = 'call_spawn_deep_dive';
|
|
32
|
+
exports.CHILD_TURN_ID = '01a18f9d-0000-7000-8000-0000000000t1';
|
|
33
|
+
exports.CHILD_PATH = '/root/review_builder';
|
|
34
|
+
exports.GRANDCHILD_PATH = '/root/review_builder/deep_dive';
|
|
35
|
+
/** `2026-10-31T01:<minute>:<second>.000Z`. */
|
|
36
|
+
function at(minute, second = 0) {
|
|
37
|
+
return `2026-10-31T01:${String(minute).padStart(2, '0')}:${String(second).padStart(2, '0')}.000Z`;
|
|
38
|
+
}
|
|
39
|
+
function numbered(rows) {
|
|
40
|
+
return rows.map((row, ordinal) => ({ timestamp: row.timestamp, ordinal, ...row }));
|
|
41
|
+
}
|
|
42
|
+
function tokenCount(timestamp, total, last) {
|
|
43
|
+
return {
|
|
44
|
+
timestamp,
|
|
45
|
+
type: 'event_msg',
|
|
46
|
+
payload: {
|
|
47
|
+
type: 'token_count',
|
|
48
|
+
info: {
|
|
49
|
+
total_token_usage: { input_tokens: total, output_tokens: 0, total_tokens: total },
|
|
50
|
+
last_token_usage: { input_tokens: last, output_tokens: 0, total_tokens: last },
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function functionCall(timestamp, callId, name, args, namespace = 'collaboration') {
|
|
56
|
+
return {
|
|
57
|
+
timestamp,
|
|
58
|
+
type: 'response_item',
|
|
59
|
+
payload: {
|
|
60
|
+
type: 'function_call',
|
|
61
|
+
status: 'completed',
|
|
62
|
+
id: `fc_${callId}`,
|
|
63
|
+
name,
|
|
64
|
+
...(namespace ? { namespace } : {}),
|
|
65
|
+
arguments: JSON.stringify(args),
|
|
66
|
+
call_id: callId,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function output(timestamp, callId, text) {
|
|
71
|
+
return {
|
|
72
|
+
timestamp,
|
|
73
|
+
type: 'response_item',
|
|
74
|
+
payload: { type: 'function_call_output', call_id: callId, output: text },
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function activity(timestamp, threadId, item) {
|
|
78
|
+
return {
|
|
79
|
+
timestamp,
|
|
80
|
+
type: 'event_msg',
|
|
81
|
+
payload: {
|
|
82
|
+
type: 'item_completed',
|
|
83
|
+
thread_id: threadId,
|
|
84
|
+
turn_id: `${threadId}-turn`,
|
|
85
|
+
item: { type: 'SubAgentActivity', model: null, reasoning_effort: null, ...item },
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function agentMessage(timestamp, id, author, recipient, messageType, payload) {
|
|
90
|
+
return {
|
|
91
|
+
timestamp,
|
|
92
|
+
type: 'response_item',
|
|
93
|
+
payload: {
|
|
94
|
+
type: 'agent_message',
|
|
95
|
+
id,
|
|
96
|
+
author,
|
|
97
|
+
recipient,
|
|
98
|
+
content: [
|
|
99
|
+
{
|
|
100
|
+
type: 'input_text',
|
|
101
|
+
text: `Message Type: ${messageType}\nTask name: ${recipient}\nSender: ${author}\nPayload:\n${payload}`,
|
|
102
|
+
},
|
|
103
|
+
...(payload ? [] : [{ type: 'encrypted_content', encrypted_content: 'gAAAA-redacted' }]),
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function exec(timestamp, callId) {
|
|
109
|
+
return functionCall(timestamp, callId, 'exec_command', { cmd: 'rg TODO' }, undefined);
|
|
110
|
+
}
|
|
111
|
+
/** The parent session's rollout (ordinals 0…). */
|
|
112
|
+
function parentRollout(options) {
|
|
113
|
+
const rows = [
|
|
114
|
+
{
|
|
115
|
+
timestamp: at(15),
|
|
116
|
+
type: 'session_meta',
|
|
117
|
+
payload: {
|
|
118
|
+
id: exports.PARENT_ID,
|
|
119
|
+
session_id: exports.PARENT_ID,
|
|
120
|
+
timestamp: at(15),
|
|
121
|
+
cwd: options.cwd,
|
|
122
|
+
originator: 'codex-tui',
|
|
123
|
+
cli_version: '0.166.0',
|
|
124
|
+
source: 'vscode',
|
|
125
|
+
thread_source: 'user',
|
|
126
|
+
history_mode: 'paginated',
|
|
127
|
+
base_instructions: { text: 'Parent base instructions.' },
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
timestamp: at(15, 1),
|
|
132
|
+
type: 'turn_context',
|
|
133
|
+
payload: { model: 'gpt-test', cwd: options.cwd },
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
timestamp: at(15, 2),
|
|
137
|
+
type: 'response_item',
|
|
138
|
+
payload: {
|
|
139
|
+
type: 'message',
|
|
140
|
+
role: 'user',
|
|
141
|
+
content: [{ type: 'input_text', text: 'Review the builder.' }],
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
tokenCount(at(15, 3), 1000, 1000),
|
|
145
|
+
functionCall(at(40, 33), exports.CALL_SPAWN, 'spawn_agent', {
|
|
146
|
+
task_name: 'review_builder',
|
|
147
|
+
message: 'gAAAA-redacted',
|
|
148
|
+
}),
|
|
149
|
+
options.withoutActivity
|
|
150
|
+
? null
|
|
151
|
+
: activity(at(40, 33), exports.PARENT_ID, {
|
|
152
|
+
id: exports.CALL_SPAWN,
|
|
153
|
+
kind: 'started',
|
|
154
|
+
model: 'gpt-test',
|
|
155
|
+
reasoning_effort: 'high',
|
|
156
|
+
agent_thread_id: exports.CHILD_ID,
|
|
157
|
+
agent_path: exports.CHILD_PATH,
|
|
158
|
+
}),
|
|
159
|
+
output(at(40, 34), exports.CALL_SPAWN, JSON.stringify({ task_name: exports.CHILD_PATH })),
|
|
160
|
+
functionCall(at(40, 35), exports.CALL_SPAWN_FAILED, 'spawn_agent', {
|
|
161
|
+
task_name: 'review_extra',
|
|
162
|
+
message: 'gAAAA-redacted',
|
|
163
|
+
}),
|
|
164
|
+
output(at(40, 35), exports.CALL_SPAWN_FAILED, 'collab spawn failed: agent thread limit reached'),
|
|
165
|
+
{
|
|
166
|
+
timestamp: at(41, 8),
|
|
167
|
+
type: 'inter_agent_communication_metadata',
|
|
168
|
+
payload: { trigger_turn: false },
|
|
169
|
+
},
|
|
170
|
+
agentMessage(at(41, 8), 'amsg_progress', exports.CHILD_PATH, '/root', 'MESSAGE', ''),
|
|
171
|
+
options.withoutActivity || options.withoutCompleted
|
|
172
|
+
? null
|
|
173
|
+
: activity(at(42, 21), exports.PARENT_ID, {
|
|
174
|
+
id: `subagent-completed-${exports.CHILD_TURN_ID}`,
|
|
175
|
+
kind: 'completed',
|
|
176
|
+
agent_thread_id: exports.CHILD_ID,
|
|
177
|
+
agent_path: exports.CHILD_PATH,
|
|
178
|
+
}),
|
|
179
|
+
agentMessage(at(42, 25), 'amsg_final', exports.CHILD_PATH, '/root', 'FINAL_ANSWER', 'Found two issues.'),
|
|
180
|
+
functionCall(at(45, 37), exports.CALL_FOLLOWUP, 'followup_task', {
|
|
181
|
+
target: 'review_builder',
|
|
182
|
+
message: 'gAAAA-redacted',
|
|
183
|
+
}),
|
|
184
|
+
options.withoutActivity
|
|
185
|
+
? null
|
|
186
|
+
: activity(at(45, 37), exports.PARENT_ID, {
|
|
187
|
+
id: exports.CALL_FOLLOWUP,
|
|
188
|
+
kind: 'interacted',
|
|
189
|
+
agent_thread_id: exports.CHILD_ID,
|
|
190
|
+
agent_path: exports.CHILD_PATH,
|
|
191
|
+
}),
|
|
192
|
+
output(at(45, 38), exports.CALL_FOLLOWUP, ''),
|
|
193
|
+
functionCall(at(45, 40), exports.CALL_SEND, 'send_message', {
|
|
194
|
+
target: 'review_builder',
|
|
195
|
+
message: 'gAAAA-redacted',
|
|
196
|
+
}),
|
|
197
|
+
options.withoutActivity
|
|
198
|
+
? null
|
|
199
|
+
: activity(at(45, 40), exports.PARENT_ID, {
|
|
200
|
+
id: exports.CALL_SEND,
|
|
201
|
+
kind: 'interacted',
|
|
202
|
+
agent_thread_id: exports.CHILD_ID,
|
|
203
|
+
agent_path: exports.CHILD_PATH,
|
|
204
|
+
}),
|
|
205
|
+
functionCall(at(46, 0), exports.CALL_INTERRUPT, 'interrupt_agent', { target: 'review_builder' }),
|
|
206
|
+
options.withoutActivity
|
|
207
|
+
? null
|
|
208
|
+
: activity(at(46, 0), exports.PARENT_ID, {
|
|
209
|
+
id: exports.CALL_INTERRUPT,
|
|
210
|
+
kind: 'interrupted',
|
|
211
|
+
agent_thread_id: exports.CHILD_ID,
|
|
212
|
+
agent_path: exports.CHILD_PATH,
|
|
213
|
+
}),
|
|
214
|
+
tokenCount(at(46, 5), 2000, 1000),
|
|
215
|
+
];
|
|
216
|
+
return numbered(rows.filter((row) => row !== null));
|
|
217
|
+
}
|
|
218
|
+
/** Records the child inherits from the parent (re-stamped at fork time, as Codex does). */
|
|
219
|
+
const INHERITED_RECORDS = 5;
|
|
220
|
+
/** The forked child's rollout: its meta, the parent's history, then its own records. */
|
|
221
|
+
function childRollout(options) {
|
|
222
|
+
const start = 1 + INHERITED_RECORDS;
|
|
223
|
+
return numbered([
|
|
224
|
+
{
|
|
225
|
+
timestamp: at(40, 33),
|
|
226
|
+
type: 'session_meta',
|
|
227
|
+
payload: {
|
|
228
|
+
id: exports.CHILD_ID,
|
|
229
|
+
session_id: exports.PARENT_ID,
|
|
230
|
+
forked_from_id: exports.PARENT_ID,
|
|
231
|
+
parent_thread_id: exports.PARENT_ID,
|
|
232
|
+
timestamp: at(40, 33),
|
|
233
|
+
cwd: options.cwd,
|
|
234
|
+
originator: 'codex-tui',
|
|
235
|
+
cli_version: '0.166.0',
|
|
236
|
+
source: {
|
|
237
|
+
subagent: {
|
|
238
|
+
thread_spawn: {
|
|
239
|
+
parent_thread_id: exports.PARENT_ID,
|
|
240
|
+
depth: 1,
|
|
241
|
+
agent_path: exports.CHILD_PATH,
|
|
242
|
+
agent_nickname: 'Banach',
|
|
243
|
+
agent_role: null,
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
thread_source: 'subagent',
|
|
248
|
+
agent_nickname: 'Banach',
|
|
249
|
+
agent_path: exports.CHILD_PATH,
|
|
250
|
+
history_mode: 'paginated',
|
|
251
|
+
subagent_history_start_ordinal: start,
|
|
252
|
+
multi_agent_version: 'v2',
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
// The parent's history, embedded by the fork.
|
|
256
|
+
{
|
|
257
|
+
timestamp: at(40, 33),
|
|
258
|
+
type: 'session_meta',
|
|
259
|
+
payload: {
|
|
260
|
+
id: exports.PARENT_ID,
|
|
261
|
+
timestamp: at(15),
|
|
262
|
+
cwd: '/somewhere/else',
|
|
263
|
+
source: 'vscode',
|
|
264
|
+
base_instructions: { text: 'Parent base instructions.' },
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
{ timestamp: at(40, 33), type: 'turn_context', payload: { model: 'gpt-parent' } },
|
|
268
|
+
exec(at(40, 33), 'call_parent_exec'),
|
|
269
|
+
tokenCount(at(40, 33), 5000, 5000),
|
|
270
|
+
{
|
|
271
|
+
timestamp: at(40, 33),
|
|
272
|
+
type: 'response_item',
|
|
273
|
+
payload: {
|
|
274
|
+
type: 'message',
|
|
275
|
+
role: 'developer',
|
|
276
|
+
content: [{ type: 'input_text', text: 'You are now a newly spawned child agent.' }],
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
// The child's own records.
|
|
280
|
+
{
|
|
281
|
+
timestamp: at(40, 34),
|
|
282
|
+
type: 'event_msg',
|
|
283
|
+
payload: { type: 'task_started', turn_id: exports.CHILD_TURN_ID },
|
|
284
|
+
},
|
|
285
|
+
{ timestamp: at(40, 34), type: 'turn_context', payload: { model: 'gpt-test' } },
|
|
286
|
+
exec(at(40, 35), 'call_child_exec'),
|
|
287
|
+
output(at(40, 36), 'call_child_exec', 'Process exited with code 0'),
|
|
288
|
+
tokenCount(at(40, 37), 300, 300),
|
|
289
|
+
functionCall(at(40, 38), exports.CALL_SPAWN_GRANDCHILD, 'spawn_agent', {
|
|
290
|
+
task_name: 'deep_dive',
|
|
291
|
+
message: 'gAAAA-redacted',
|
|
292
|
+
}),
|
|
293
|
+
activity(at(40, 38), exports.CHILD_ID, {
|
|
294
|
+
id: exports.CALL_SPAWN_GRANDCHILD,
|
|
295
|
+
kind: 'started',
|
|
296
|
+
agent_thread_id: exports.GRANDCHILD_ID,
|
|
297
|
+
agent_path: exports.GRANDCHILD_PATH,
|
|
298
|
+
}),
|
|
299
|
+
output(at(40, 39), exports.CALL_SPAWN_GRANDCHILD, JSON.stringify({ task_name: exports.GRANDCHILD_PATH })),
|
|
300
|
+
tokenCount(at(42, 20), 500, 200),
|
|
301
|
+
]);
|
|
302
|
+
}
|
|
303
|
+
/** The grandchild's rollout (depth 2): a fork of the child. */
|
|
304
|
+
function grandchildRollout(options) {
|
|
305
|
+
return numbered([
|
|
306
|
+
{
|
|
307
|
+
timestamp: at(40, 38),
|
|
308
|
+
type: 'session_meta',
|
|
309
|
+
payload: {
|
|
310
|
+
id: exports.GRANDCHILD_ID,
|
|
311
|
+
session_id: exports.PARENT_ID,
|
|
312
|
+
forked_from_id: exports.CHILD_ID,
|
|
313
|
+
parent_thread_id: exports.CHILD_ID,
|
|
314
|
+
timestamp: at(40, 38),
|
|
315
|
+
cwd: options.cwd,
|
|
316
|
+
cli_version: '0.166.0',
|
|
317
|
+
source: {
|
|
318
|
+
subagent: {
|
|
319
|
+
thread_spawn: {
|
|
320
|
+
parent_thread_id: exports.CHILD_ID,
|
|
321
|
+
depth: 2,
|
|
322
|
+
agent_path: exports.GRANDCHILD_PATH,
|
|
323
|
+
agent_nickname: 'Noether',
|
|
324
|
+
agent_role: 'explorer',
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
thread_source: 'subagent',
|
|
329
|
+
agent_nickname: 'Noether',
|
|
330
|
+
agent_path: exports.GRANDCHILD_PATH,
|
|
331
|
+
agent_role: 'explorer',
|
|
332
|
+
subagent_history_start_ordinal: 3,
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
{ timestamp: at(40, 38), type: 'session_meta', payload: { id: exports.CHILD_ID, cwd: options.cwd } },
|
|
336
|
+
exec(at(40, 38), 'call_child_exec'),
|
|
337
|
+
exec(at(40, 40), 'call_grandchild_exec'),
|
|
338
|
+
tokenCount(at(40, 41), 50, 50),
|
|
339
|
+
]);
|
|
340
|
+
}
|
|
341
|
+
/** Rows as JSONL text. */
|
|
342
|
+
function toJsonl(rows) {
|
|
343
|
+
return rows.map((row) => JSON.stringify(row)).join('\n') + '\n';
|
|
344
|
+
}
|
|
@@ -32,6 +32,11 @@ export interface FindToolCallOriginsOptions {
|
|
|
32
32
|
providers?: PromptHistoryProvider[];
|
|
33
33
|
/** Stops between files and lines; the promise rejects with the signal's reason. */
|
|
34
34
|
signal?: AbortSignal;
|
|
35
|
+
/**
|
|
36
|
+
* Codex: also search compressed rollouts (`….jsonl.zst`), as for
|
|
37
|
+
* `collectPromptHistory()`. Default false.
|
|
38
|
+
*/
|
|
39
|
+
includeCompressedRollouts?: boolean;
|
|
35
40
|
}
|
|
36
41
|
export interface ToolCallOrigin {
|
|
37
42
|
provider: PromptHistoryProvider;
|
package/dist/toolCallOrigins.js
CHANGED
|
@@ -57,6 +57,8 @@ exports.findToolCallOrigins = findToolCallOrigins;
|
|
|
57
57
|
const fs = __importStar(require("fs"));
|
|
58
58
|
const path = __importStar(require("path"));
|
|
59
59
|
const readline = __importStar(require("readline"));
|
|
60
|
+
const stream_1 = require("stream");
|
|
61
|
+
const compressedRollouts_1 = require("./providers/compressedRollouts");
|
|
60
62
|
const promptHistory_1 = require("./promptHistory");
|
|
61
63
|
const codexRolloutOrigin_1 = require("./parsers/codexRolloutOrigin");
|
|
62
64
|
const workspaceRoots_1 = require("./workspaceRoots");
|
|
@@ -78,7 +80,9 @@ async function findToolCallOrigins(options) {
|
|
|
78
80
|
return found;
|
|
79
81
|
const providers = options.providers ?? ['claude-code', 'codex'];
|
|
80
82
|
const sinceMs = options.since ? options.since.getTime() : null;
|
|
81
|
-
const candidates = await (0, promptHistory_1.listCandidates)(providers, listingRoots, sinceMs
|
|
83
|
+
const candidates = await (0, promptHistory_1.listCandidates)(providers, listingRoots, sinceMs, {
|
|
84
|
+
includeCompressedRollouts: options.includeCompressedRollouts,
|
|
85
|
+
});
|
|
82
86
|
const byProviderSession = new Map();
|
|
83
87
|
for (const candidate of candidates) {
|
|
84
88
|
byProviderSession.set(`${candidate.provider}:${candidate.sessionId}`, candidate);
|
|
@@ -188,21 +192,15 @@ function claudeSubagentTranscripts(sessionFile, sessionId) {
|
|
|
188
192
|
}));
|
|
189
193
|
}
|
|
190
194
|
async function readFirstRecord(filePath) {
|
|
191
|
-
let handle;
|
|
192
195
|
try {
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
196
|
-
const text = buffer.subarray(0, bytesRead).toString('utf8');
|
|
196
|
+
// A compressed rollout's head is decompressed.
|
|
197
|
+
const text = (await (0, compressedRollouts_1.readRolloutHeadAsync)(filePath, 256 * 1024)).toString('utf8');
|
|
197
198
|
const newline = text.indexOf('\n');
|
|
198
199
|
return JSON.parse(newline === -1 ? text : text.slice(0, newline));
|
|
199
200
|
}
|
|
200
201
|
catch {
|
|
201
202
|
return undefined;
|
|
202
203
|
}
|
|
203
|
-
finally {
|
|
204
|
-
await handle?.close();
|
|
205
|
-
}
|
|
206
204
|
}
|
|
207
205
|
/** Fail-closed scope check on a recorded working directory. */
|
|
208
206
|
function inScope(cwd, roots, realpaths) {
|
|
@@ -223,7 +221,16 @@ async function scanForIds(filePath, provider, wanted, roots, realpaths, signal)
|
|
|
223
221
|
const hits = [];
|
|
224
222
|
let stream;
|
|
225
223
|
try {
|
|
226
|
-
|
|
224
|
+
if ((0, compressedRollouts_1.isCompressedRolloutPath)(filePath)) {
|
|
225
|
+
// Compressed rollouts are complete; search their decompressed content.
|
|
226
|
+
const content = await (0, compressedRollouts_1.readRolloutBufferAsync)(filePath);
|
|
227
|
+
if (!content)
|
|
228
|
+
return hits;
|
|
229
|
+
stream = stream_1.Readable.from([content.toString('utf8')]);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
stream = fs.createReadStream(filePath, { encoding: 'utf8' });
|
|
233
|
+
}
|
|
227
234
|
}
|
|
228
235
|
catch {
|
|
229
236
|
return hits;
|
package/dist/toolCategory.js
CHANGED
|
@@ -20,7 +20,11 @@ exports.TOOL_CATEGORIES = [
|
|
|
20
20
|
'mcp',
|
|
21
21
|
'other',
|
|
22
22
|
];
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Lower-cased tool names of every provider, by category. Codex's bare `wait`
|
|
25
|
+
* is a code-mode cell wait, not a subagent wait (that is `wait_agent`), so it
|
|
26
|
+
* is `other`.
|
|
27
|
+
*/
|
|
24
28
|
const CATEGORY_BY_NAME = new Map([
|
|
25
29
|
[
|
|
26
30
|
'shell',
|
|
@@ -54,7 +58,7 @@ const CATEGORY_BY_NAME = new Map([
|
|
|
54
58
|
'send_message',
|
|
55
59
|
'followup_task',
|
|
56
60
|
'list_agents',
|
|
57
|
-
'
|
|
61
|
+
'interrupt_agent',
|
|
58
62
|
],
|
|
59
63
|
],
|
|
60
64
|
[
|
package/dist/transcript.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.projectSessionTranscript = projectSessionTranscript;
|
|
4
4
|
const usageNormalization_1 = require("./usageNormalization");
|
|
5
5
|
const subagentSpawn_1 = require("./subagentSpawn");
|
|
6
|
+
const subagentActivity_1 = require("./subagentActivity");
|
|
6
7
|
const EMPTY_TOTALS = {
|
|
7
8
|
uncachedInputTokens: 0,
|
|
8
9
|
cacheReadTokens: 0,
|
|
@@ -30,7 +31,10 @@ function projectSessionTranscript(events, options = {}) {
|
|
|
30
31
|
let gitBranch;
|
|
31
32
|
events.forEach((event, eventIndex) => {
|
|
32
33
|
// A reader's synthetic notice that a background task finished, not a message.
|
|
33
|
-
if ((0, subagentSpawn_1.isTaskNotificationSystemEvent)(event))
|
|
34
|
+
if ((0, subagentSpawn_1.isTaskNotificationSystemEvent)(event) || (0, subagentSpawn_1.isTaskStatusSystemEvent)(event))
|
|
35
|
+
return;
|
|
36
|
+
// Likewise a subagent lifecycle record (opt-in Codex parser event).
|
|
37
|
+
if ((0, subagentActivity_1.isSubagentActivitySystemEvent)(event))
|
|
34
38
|
return;
|
|
35
39
|
if (nonEmpty(event.cwd))
|
|
36
40
|
cwd = event.cwd;
|
|
@@ -70,7 +70,10 @@ export interface ReasoningSummary {
|
|
|
70
70
|
body: string;
|
|
71
71
|
}
|
|
72
72
|
export declare function reasoningSummary(text: string): ReasoningSummary;
|
|
73
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Whether a tool call spawns a subagent (`Agent`, or its earlier name `Task`).
|
|
75
|
+
* Codex `spawn_agent` is not included here (its turns project as before).
|
|
76
|
+
*/
|
|
74
77
|
export declare function isAssistantTurnSubagentTool(toolName: string | undefined): boolean;
|
|
75
78
|
export declare function segmentAssistantTurn(events: readonly AssistantTurnEvent[], options?: SegmentAssistantTurnOptions): AssistantTurnProjection;
|
|
76
79
|
export declare function assistantTurnEventsFromSessionEvents(events: readonly SessionEvent[]): AssistantTurnEvent[];
|
|
@@ -29,9 +29,12 @@ function reasoningSummary(text) {
|
|
|
29
29
|
}
|
|
30
30
|
return { title: null, body: trimmed };
|
|
31
31
|
}
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Whether a tool call spawns a subagent (`Agent`, or its earlier name `Task`).
|
|
34
|
+
* Codex `spawn_agent` is not included here (its turns project as before).
|
|
35
|
+
*/
|
|
33
36
|
function isAssistantTurnSubagentTool(toolName) {
|
|
34
|
-
return
|
|
37
|
+
return typeof toolName === 'string' && subagentSpawn_1.SUBAGENT_SPAWN_TOOL_NAMES.includes(toolName);
|
|
35
38
|
}
|
|
36
39
|
function segmentAssistantTurn(events, options = {}) {
|
|
37
40
|
const maxNarrationChars = options.maxNarrationChars ?? DEFAULT_NARRATION_CHARS;
|
package/dist/types/codex.d.ts
CHANGED
|
@@ -16,6 +16,12 @@ export interface CodexRolloutLine {
|
|
|
16
16
|
timestamp: string;
|
|
17
17
|
/** Discriminator for the payload type */
|
|
18
18
|
type: 'session_meta' | 'response_item' | 'compacted' | 'turn_context' | 'event_msg';
|
|
19
|
+
/**
|
|
20
|
+
* Zero-based position of the record in its rollout (recent Codex versions).
|
|
21
|
+
* In a forked subagent rollout, records before the child's
|
|
22
|
+
* `session_meta.subagent_history_start_ordinal` are the parent's history.
|
|
23
|
+
*/
|
|
24
|
+
ordinal?: number;
|
|
19
25
|
/** Type-specific payload */
|
|
20
26
|
payload: CodexSessionMeta | CodexResponseItem | CodexCompacted | CodexTurnContext | CodexEventMsg;
|
|
21
27
|
}
|
|
@@ -37,13 +43,32 @@ export interface CodexSessionMeta {
|
|
|
37
43
|
dirty?: boolean;
|
|
38
44
|
};
|
|
39
45
|
forked_from_id?: string;
|
|
46
|
+
/** The root session of a subagent tree (recent Codex versions). */
|
|
47
|
+
session_id?: string;
|
|
48
|
+
/** Subagents: the thread that spawned this one. */
|
|
49
|
+
parent_thread_id?: string;
|
|
50
|
+
/** `user`, `subagent`, … (recent Codex versions). */
|
|
51
|
+
thread_source?: string;
|
|
52
|
+
/** Subagents: display nickname, e.g. `Banach`. */
|
|
53
|
+
agent_nickname?: string | null;
|
|
54
|
+
/** Subagents: agent path, e.g. `/root/review_builder`. */
|
|
55
|
+
agent_path?: string | null;
|
|
56
|
+
/** Subagents: requested role (`agent_type`), when one was given. */
|
|
57
|
+
agent_role?: string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Forked subagents: the ordinal of the first record that is the child's
|
|
60
|
+
* own; earlier records are the parent's history the fork embeds.
|
|
61
|
+
*/
|
|
62
|
+
subagent_history_start_ordinal?: number;
|
|
63
|
+
history_mode?: string;
|
|
64
|
+
multi_agent_version?: string;
|
|
40
65
|
}
|
|
41
66
|
/**
|
|
42
67
|
* A response item from the model.
|
|
43
68
|
* The payload IS the item directly (no .item wrapper).
|
|
44
69
|
* Tagged union on `type`.
|
|
45
70
|
*/
|
|
46
|
-
export type CodexResponseItem = CodexMessageItem | CodexReasoningItem | CodexFunctionCallItem | CodexFunctionCallOutputItem | CodexLocalShellCallItem | CodexWebSearchCallItem | CodexCustomToolCallItem | CodexCustomToolCallOutputItem;
|
|
71
|
+
export type CodexResponseItem = CodexMessageItem | CodexAgentMessageItem | CodexReasoningItem | CodexFunctionCallItem | CodexFunctionCallOutputItem | CodexLocalShellCallItem | CodexWebSearchCallItem | CodexCustomToolCallItem | CodexCustomToolCallOutputItem;
|
|
47
72
|
/** Chat message (user, assistant, or developer). */
|
|
48
73
|
export interface CodexMessageItem {
|
|
49
74
|
type: 'message';
|
|
@@ -53,6 +78,22 @@ export interface CodexMessageItem {
|
|
|
53
78
|
status?: string;
|
|
54
79
|
phase?: string;
|
|
55
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* A message between agents of a multi-agent session (`author` and
|
|
83
|
+
* `recipient` are agent paths such as `/root/review_builder` and `/root`).
|
|
84
|
+
* Its first text part starts `Message Type: MESSAGE | NEW_TASK |
|
|
85
|
+
* FINAL_ANSWER`, followed by `Task name:`, `Sender:`, and `Payload:` lines.
|
|
86
|
+
*/
|
|
87
|
+
export interface CodexAgentMessageItem {
|
|
88
|
+
type: 'agent_message';
|
|
89
|
+
id?: string;
|
|
90
|
+
author?: string;
|
|
91
|
+
recipient?: string;
|
|
92
|
+
content: Array<CodexContentPart | {
|
|
93
|
+
type: 'encrypted_content';
|
|
94
|
+
encrypted_content?: string;
|
|
95
|
+
}>;
|
|
96
|
+
}
|
|
56
97
|
/** Content part within a message. */
|
|
57
98
|
export interface CodexContentPart {
|
|
58
99
|
type: 'output_text' | 'input_text' | 'refusal' | 'text';
|
|
@@ -79,6 +120,8 @@ export interface CodexFunctionCallItem {
|
|
|
79
120
|
name: string;
|
|
80
121
|
arguments: string;
|
|
81
122
|
status?: string;
|
|
123
|
+
/** Tool namespace, e.g. `collaboration` for the multi-agent tools. */
|
|
124
|
+
namespace?: string;
|
|
82
125
|
}
|
|
83
126
|
/** Result of a function call. */
|
|
84
127
|
export interface CodexFunctionCallOutputItem {
|
|
@@ -140,7 +183,7 @@ export interface CodexTurnContext {
|
|
|
140
183
|
* Tagged union on `type`.
|
|
141
184
|
*/
|
|
142
185
|
export type CodexEventMsg = CodexEvent;
|
|
143
|
-
export type CodexEvent = CodexTurnStartedEvent | CodexTurnCompleteEvent | CodexTaskStartedEvent | CodexTaskCompleteEvent | CodexTurnAbortedEvent | CodexTokenCountEvent | CodexAgentMessageEvent | CodexAgentReasoningEvent | CodexUserMessageEvent | CodexExecCommandBeginEvent | CodexExecCommandEndEvent | CodexMcpToolCallBeginEvent | CodexMcpToolCallEndEvent | CodexErrorEvent | CodexContextCompactedEvent | CodexPatchAppliedEvent | CodexBackgroundEvent | CodexGenericEvent;
|
|
186
|
+
export type CodexEvent = CodexTurnStartedEvent | CodexTurnCompleteEvent | CodexTaskStartedEvent | CodexTaskCompleteEvent | CodexTurnAbortedEvent | CodexTokenCountEvent | CodexAgentMessageEvent | CodexAgentReasoningEvent | CodexUserMessageEvent | CodexExecCommandBeginEvent | CodexExecCommandEndEvent | CodexMcpToolCallBeginEvent | CodexMcpToolCallEndEvent | CodexErrorEvent | CodexContextCompactedEvent | CodexPatchAppliedEvent | CodexItemCompletedEvent | CodexBackgroundEvent | CodexGenericEvent;
|
|
144
187
|
export interface CodexTurnStartedEvent {
|
|
145
188
|
type: 'turn_started';
|
|
146
189
|
turn_id?: string;
|
|
@@ -264,6 +307,28 @@ export interface CodexPatchAppliedEvent {
|
|
|
264
307
|
additions?: number;
|
|
265
308
|
deletions?: number;
|
|
266
309
|
}
|
|
310
|
+
/**
|
|
311
|
+
* A completed turn item. `SubAgentActivity` items record the multi-agent
|
|
312
|
+
* lifecycle: `kind` `started` (id = the spawn call), `completed` (id =
|
|
313
|
+
* `subagent-completed-<child turn id>`), `interacted` (id = a
|
|
314
|
+
* `followup_task` / `send_message` call), `interrupted` (id = an
|
|
315
|
+
* `interrupt_agent` call).
|
|
316
|
+
*/
|
|
317
|
+
export interface CodexItemCompletedEvent {
|
|
318
|
+
type: 'item_completed';
|
|
319
|
+
thread_id?: string;
|
|
320
|
+
turn_id?: string;
|
|
321
|
+
item?: {
|
|
322
|
+
type?: string;
|
|
323
|
+
id?: string;
|
|
324
|
+
kind?: string;
|
|
325
|
+
agent_thread_id?: string;
|
|
326
|
+
agent_path?: string;
|
|
327
|
+
model?: string | null;
|
|
328
|
+
reasoning_effort?: string | null;
|
|
329
|
+
[key: string]: unknown;
|
|
330
|
+
};
|
|
331
|
+
}
|
|
267
332
|
export interface CodexBackgroundEvent {
|
|
268
333
|
type: 'background';
|
|
269
334
|
message?: string;
|
|
@@ -291,6 +356,10 @@ export interface CodexDbThread {
|
|
|
291
356
|
source?: string;
|
|
292
357
|
agent_nickname?: string | null;
|
|
293
358
|
agent_role?: string | null;
|
|
359
|
+
/** Subagents: agent path, e.g. `/root/review_builder` (recent schemas). */
|
|
360
|
+
agent_path?: string | null;
|
|
361
|
+
/** `user`, `subagent`, … (recent schemas). */
|
|
362
|
+
thread_source?: string | null;
|
|
294
363
|
/** 1 once the thread is archived; Codex then moves its rollout to `archived_sessions/`. */
|
|
295
364
|
archived?: number;
|
|
296
365
|
/** Unix seconds when the thread was archived. */
|