@ellipsis-dev/sdk 0.14.0 → 0.15.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/dist/index.d.ts +3 -3
- package/dist/store/index.d.ts +9 -39
- package/dist/store/index.js +296 -125
- package/dist/stream/index.d.ts +1 -1
- package/dist/{types-egqnpL5C.d.ts → types-DtVn9Yj3.d.ts} +1291 -204
- package/package.json +1 -1
- package/schema/frames.schema.json +2543 -617
- package/schema/openapi.v1.json +5145 -3428
- package/schema/cc_step.schema.json +0 -6036
package/dist/store/index.js
CHANGED
|
@@ -116,32 +116,6 @@ function lifecycleText(recordType, payload) {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
// src/store/transcript.ts
|
|
119
|
-
var LineBuffer = class {
|
|
120
|
-
buf = "";
|
|
121
|
-
push(chunk) {
|
|
122
|
-
this.buf += chunk;
|
|
123
|
-
const parts = this.buf.split("\n");
|
|
124
|
-
this.buf = parts.pop() ?? "";
|
|
125
|
-
return parts;
|
|
126
|
-
}
|
|
127
|
-
flush() {
|
|
128
|
-
const rest = this.buf.trim();
|
|
129
|
-
this.buf = "";
|
|
130
|
-
return rest ? [rest] : [];
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
function parseEventLine(line) {
|
|
134
|
-
const trimmed = line.trim();
|
|
135
|
-
if (!trimmed) return null;
|
|
136
|
-
try {
|
|
137
|
-
const value = JSON.parse(trimmed);
|
|
138
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
139
|
-
return value;
|
|
140
|
-
}
|
|
141
|
-
} catch {
|
|
142
|
-
}
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
119
|
function oneLine(text, max) {
|
|
146
120
|
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
147
121
|
return collapsed.length <= max ? collapsed : `${collapsed.slice(0, max - 3)}...`;
|
|
@@ -176,35 +150,31 @@ function formatDuration(seconds) {
|
|
|
176
150
|
}
|
|
177
151
|
function blocksOf(content) {
|
|
178
152
|
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
179
|
-
|
|
180
|
-
return [];
|
|
153
|
+
return content;
|
|
181
154
|
}
|
|
182
|
-
function toolResultText(
|
|
183
|
-
|
|
184
|
-
if (
|
|
185
|
-
if (Array.isArray(c)) {
|
|
155
|
+
function toolResultText(content) {
|
|
156
|
+
if (typeof content === "string") return content.trim();
|
|
157
|
+
if (Array.isArray(content)) {
|
|
186
158
|
const parts = [];
|
|
187
|
-
for (const inner of
|
|
159
|
+
for (const inner of content) {
|
|
188
160
|
if (typeof inner.text === "string") parts.push(inner.text);
|
|
189
161
|
else parts.push(JSON.stringify(inner));
|
|
190
162
|
}
|
|
191
163
|
return parts.join("\n").trim();
|
|
192
164
|
}
|
|
193
|
-
if (
|
|
194
|
-
return JSON.stringify(
|
|
165
|
+
if (content === void 0 || content === null) return "";
|
|
166
|
+
return JSON.stringify(content);
|
|
195
167
|
}
|
|
196
168
|
function eventToItems(event, keyBase, options = {}) {
|
|
197
169
|
const items = [];
|
|
198
170
|
const push = (item) => {
|
|
199
171
|
items.push({ ...item, key: `${keyBase}:${items.length}` });
|
|
200
172
|
};
|
|
201
|
-
|
|
202
|
-
if (type === "result") {
|
|
173
|
+
if (event.kind === "result") {
|
|
203
174
|
const bits = [];
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
bits.push(`$${event.total_cost_usd.toFixed(2)}`);
|
|
175
|
+
bits.push(formatDuration(event.duration_ms / 1e3));
|
|
176
|
+
if (typeof event.cost_usd === "number")
|
|
177
|
+
bits.push(`$${event.cost_usd.toFixed(2)}`);
|
|
208
178
|
const label = event.is_error ? "turn ended with an error" : "turn complete";
|
|
209
179
|
push({
|
|
210
180
|
kind: "summary",
|
|
@@ -214,11 +184,12 @@ function eventToItems(event, keyBase, options = {}) {
|
|
|
214
184
|
});
|
|
215
185
|
return items;
|
|
216
186
|
}
|
|
217
|
-
if (
|
|
187
|
+
if (event.kind === "system") {
|
|
218
188
|
if (!options.systemInitLine || event.subtype !== "init") return items;
|
|
189
|
+
const data = event.data ?? {};
|
|
219
190
|
const bits = [];
|
|
220
|
-
if (typeof
|
|
221
|
-
if (typeof
|
|
191
|
+
if (typeof data.model === "string") bits.push(data.model);
|
|
192
|
+
if (typeof data.cwd === "string") bits.push(data.cwd);
|
|
222
193
|
push({
|
|
223
194
|
kind: "system",
|
|
224
195
|
text: bits.length ? `session started \xB7 ${bits.join(" \xB7 ")}` : "session started",
|
|
@@ -226,19 +197,20 @@ function eventToItems(event, keyBase, options = {}) {
|
|
|
226
197
|
});
|
|
227
198
|
return items;
|
|
228
199
|
}
|
|
229
|
-
|
|
230
|
-
|
|
200
|
+
if (event.kind === "rate_limit") return items;
|
|
201
|
+
const blocks = blocksOf(event.content);
|
|
202
|
+
if (event.kind === "user") {
|
|
231
203
|
for (const block of blocks) {
|
|
232
204
|
if (block.type === "tool_result") {
|
|
233
|
-
const body = toolResultText(block);
|
|
205
|
+
const body = toolResultText(block.content);
|
|
234
206
|
push({
|
|
235
207
|
kind: "tool_result",
|
|
236
208
|
gutter: "\u23BF",
|
|
237
209
|
text: body || "(no output)",
|
|
238
210
|
spaceBefore: false,
|
|
239
|
-
isError: block.is_error
|
|
211
|
+
isError: block.is_error ?? void 0
|
|
240
212
|
});
|
|
241
|
-
} else if (
|
|
213
|
+
} else if (block.type === "text" && block.text.trim()) {
|
|
242
214
|
push({
|
|
243
215
|
kind: "user",
|
|
244
216
|
gutter: "\u203A",
|
|
@@ -250,37 +222,151 @@ function eventToItems(event, keyBase, options = {}) {
|
|
|
250
222
|
return items;
|
|
251
223
|
}
|
|
252
224
|
for (const block of blocks) {
|
|
253
|
-
if (block.type === "thinking" &&
|
|
225
|
+
if (block.type === "thinking" && block.thinking.trim()) {
|
|
254
226
|
push({
|
|
255
227
|
kind: "thinking",
|
|
256
228
|
gutter: "\u273B",
|
|
257
229
|
text: block.thinking.trim(),
|
|
258
230
|
spaceBefore: true
|
|
259
231
|
});
|
|
260
|
-
} else if (block.type === "tool_use") {
|
|
261
|
-
const
|
|
262
|
-
const summary = summarizeToolInput(name, block.input);
|
|
232
|
+
} else if (block.type === "tool_use" || block.type === "server_tool_use") {
|
|
233
|
+
const summary = summarizeToolInput(block.name, block.input);
|
|
263
234
|
push({
|
|
264
235
|
kind: "tool",
|
|
265
236
|
gutter: "\u25CF",
|
|
266
|
-
text: name,
|
|
237
|
+
text: block.name,
|
|
267
238
|
detail: summary ? `(${summary})` : void 0,
|
|
268
239
|
spaceBefore: true,
|
|
269
|
-
tool: { name, input: block.input }
|
|
240
|
+
tool: { name: block.name, input: block.input }
|
|
270
241
|
});
|
|
271
|
-
} else if (
|
|
242
|
+
} else if (block.type === "text" && block.text.trim()) {
|
|
272
243
|
push({ kind: "assistant", text: block.text.trim(), spaceBefore: true });
|
|
273
244
|
}
|
|
274
245
|
}
|
|
275
246
|
return items;
|
|
276
247
|
}
|
|
248
|
+
function codexEventToItems(event, keyBase) {
|
|
249
|
+
const items = [];
|
|
250
|
+
const push = (item2) => {
|
|
251
|
+
items.push({ ...item2, key: `${keyBase}:${items.length}` });
|
|
252
|
+
};
|
|
253
|
+
if (event.type === "turn.failed") {
|
|
254
|
+
push({
|
|
255
|
+
kind: "summary",
|
|
256
|
+
text: "turn ended with an error",
|
|
257
|
+
spaceBefore: true,
|
|
258
|
+
isError: true
|
|
259
|
+
});
|
|
260
|
+
return items;
|
|
261
|
+
}
|
|
262
|
+
if (event.type === "error") {
|
|
263
|
+
push({
|
|
264
|
+
kind: "error",
|
|
265
|
+
text: event.message?.trim() || "error",
|
|
266
|
+
spaceBefore: true,
|
|
267
|
+
isError: true
|
|
268
|
+
});
|
|
269
|
+
return items;
|
|
270
|
+
}
|
|
271
|
+
if (event.type !== "item.completed") return items;
|
|
272
|
+
const item = event.item;
|
|
273
|
+
switch (item.type) {
|
|
274
|
+
case "agent_message": {
|
|
275
|
+
const text = item.text.trim();
|
|
276
|
+
if (text) push({ kind: "assistant", text, spaceBefore: true });
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
case "reasoning": {
|
|
280
|
+
const r = item;
|
|
281
|
+
const text = (r.text ?? r.summary ?? "").trim();
|
|
282
|
+
if (text)
|
|
283
|
+
push({ kind: "thinking", gutter: "\u273B", text, spaceBefore: true });
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
case "command_execution": {
|
|
287
|
+
const c = item;
|
|
288
|
+
const summary = oneLine(c.command, 100);
|
|
289
|
+
push({
|
|
290
|
+
kind: "tool",
|
|
291
|
+
gutter: "\u25CF",
|
|
292
|
+
text: "Bash",
|
|
293
|
+
detail: summary ? `(${summary})` : void 0,
|
|
294
|
+
spaceBefore: true,
|
|
295
|
+
tool: { name: "Bash", input: { command: c.command } }
|
|
296
|
+
});
|
|
297
|
+
const output = (c.aggregated_output ?? "").trim();
|
|
298
|
+
push({
|
|
299
|
+
kind: "tool_result",
|
|
300
|
+
gutter: "\u23BF",
|
|
301
|
+
text: output || "(no output)",
|
|
302
|
+
spaceBefore: false,
|
|
303
|
+
isError: typeof c.exit_code === "number" && c.exit_code !== 0
|
|
304
|
+
});
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
case "file_change": {
|
|
308
|
+
const paths = codexChangedPaths(item);
|
|
309
|
+
push({
|
|
310
|
+
kind: "tool",
|
|
311
|
+
gutter: "\u25CF",
|
|
312
|
+
text: "Edit",
|
|
313
|
+
detail: paths.length ? `(${oneLine(paths.join(", "), 100)})` : void 0,
|
|
314
|
+
spaceBefore: true,
|
|
315
|
+
tool: { name: "Edit" }
|
|
316
|
+
});
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
case "mcp_tool_call": {
|
|
320
|
+
const name = codexMcpToolName(item);
|
|
321
|
+
push({
|
|
322
|
+
kind: "tool",
|
|
323
|
+
gutter: "\u25CF",
|
|
324
|
+
text: name,
|
|
325
|
+
spaceBefore: true,
|
|
326
|
+
tool: { name }
|
|
327
|
+
});
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
case "web_search": {
|
|
331
|
+
const query = item.query;
|
|
332
|
+
push({
|
|
333
|
+
kind: "tool",
|
|
334
|
+
gutter: "\u25CF",
|
|
335
|
+
text: "WebSearch",
|
|
336
|
+
detail: query ? `(${oneLine(query, 100)})` : void 0,
|
|
337
|
+
spaceBefore: true,
|
|
338
|
+
tool: { name: "WebSearch" }
|
|
339
|
+
});
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
case "error":
|
|
343
|
+
push({
|
|
344
|
+
kind: "error",
|
|
345
|
+
text: item.message?.trim() || "error",
|
|
346
|
+
spaceBefore: true,
|
|
347
|
+
isError: true
|
|
348
|
+
});
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
return items;
|
|
352
|
+
}
|
|
353
|
+
function codexChangedPaths(item) {
|
|
354
|
+
return (item.changes ?? []).map((c) => typeof c.path === "string" ? c.path : null).filter((p) => p !== null);
|
|
355
|
+
}
|
|
356
|
+
function codexMcpToolName(item) {
|
|
357
|
+
return item.server && item.tool ? `mcp__${item.server}__${item.tool}` : item.tool ?? "mcp_tool_call";
|
|
358
|
+
}
|
|
277
359
|
function recordToItems(record, keyBase, options = {}) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
360
|
+
switch (record.record_format) {
|
|
361
|
+
case "claude_sdk@1":
|
|
362
|
+
return eventToItems(record.payload, keyBase, options);
|
|
363
|
+
case "codex_jsonl@1":
|
|
364
|
+
return codexEventToItems(record.payload, keyBase);
|
|
365
|
+
case "ellipsis_lifecycle@1": {
|
|
366
|
+
const text = lifecycleText(record.record_type, record.payload);
|
|
367
|
+
return text ? [{ key: keyBase, kind: "notice", text, spaceBefore: true }] : [];
|
|
368
|
+
}
|
|
281
369
|
}
|
|
282
|
-
if (record.source !== "claude_code") return [];
|
|
283
|
-
return eventToItems(record.payload, keyBase, options);
|
|
284
370
|
}
|
|
285
371
|
function isConnectVisibleRecord(record) {
|
|
286
372
|
return record.source !== "lifecycle" || record.record_type === "sandbox_ready";
|
|
@@ -341,19 +427,18 @@ function clampLines(text, maxLines) {
|
|
|
341
427
|
};
|
|
342
428
|
}
|
|
343
429
|
function resultCostUsd(event) {
|
|
344
|
-
if (event.
|
|
345
|
-
return typeof event.
|
|
430
|
+
if (event.kind !== "result") return null;
|
|
431
|
+
return typeof event.cost_usd === "number" ? event.cost_usd : null;
|
|
346
432
|
}
|
|
347
433
|
function foldCosts(events) {
|
|
348
|
-
let prev = null;
|
|
349
434
|
let total = null;
|
|
435
|
+
let lastStep = null;
|
|
350
436
|
for (const event of events) {
|
|
351
437
|
const cost = resultCostUsd(event);
|
|
352
438
|
if (cost == null) continue;
|
|
353
|
-
|
|
354
|
-
|
|
439
|
+
total = (total ?? 0) + cost;
|
|
440
|
+
lastStep = cost;
|
|
355
441
|
}
|
|
356
|
-
const lastStep = total != null && prev != null ? Math.max(0, total - prev) : total;
|
|
357
442
|
return { total, lastStep };
|
|
358
443
|
}
|
|
359
444
|
function statusActivityText(status) {
|
|
@@ -370,36 +455,19 @@ function statusActivityText(status) {
|
|
|
370
455
|
}
|
|
371
456
|
|
|
372
457
|
// src/store/chatTurns.ts
|
|
373
|
-
var isInitEvent = (data) => data.
|
|
374
|
-
var TOOL_USE_BLOCK_TYPES = /* @__PURE__ */ new Set([
|
|
375
|
-
"tool_use",
|
|
376
|
-
"server_tool_use",
|
|
377
|
-
"mcp_tool_use"
|
|
378
|
-
]);
|
|
458
|
+
var isInitEvent = (data) => data.kind === "system" && data.subtype === "init";
|
|
379
459
|
var SANDBOX_RECORD_TYPES = /* @__PURE__ */ new Set([
|
|
380
460
|
"sandbox_starting",
|
|
381
461
|
"sandbox_phase",
|
|
382
462
|
"sandbox_output",
|
|
383
463
|
"sandbox_ready"
|
|
384
464
|
]);
|
|
385
|
-
function toolResultText2(block) {
|
|
386
|
-
const c = block.content;
|
|
387
|
-
if (typeof c === "string") return c.trim();
|
|
388
|
-
if (Array.isArray(c)) {
|
|
389
|
-
return c.map(
|
|
390
|
-
(inner) => typeof inner.text === "string" ? inner.text : JSON.stringify(inner)
|
|
391
|
-
).join("\n").trim();
|
|
392
|
-
}
|
|
393
|
-
if (c === void 0 || c === null) return "";
|
|
394
|
-
return JSON.stringify(c);
|
|
395
|
-
}
|
|
396
465
|
function groupRecordsToChatTurns(records) {
|
|
397
466
|
const turns = [];
|
|
398
467
|
const toolNodeByUseId = /* @__PURE__ */ new Map();
|
|
399
468
|
let seq = 0;
|
|
400
469
|
const nextKey = (base) => `${base}:${seq++}`;
|
|
401
470
|
let openIdx = -1;
|
|
402
|
-
let prevCumulativeCostUsd = 0;
|
|
403
471
|
let initCount = 0;
|
|
404
472
|
let pendingResume = false;
|
|
405
473
|
const openAgentTurn = (record) => {
|
|
@@ -421,7 +489,7 @@ function groupRecordsToChatTurns(records) {
|
|
|
421
489
|
return turns[openIdx];
|
|
422
490
|
};
|
|
423
491
|
for (const record of records) {
|
|
424
|
-
if (record.
|
|
492
|
+
if (record.record_format === "ellipsis_lifecycle@1") {
|
|
425
493
|
const text = lifecycleText(record.record_type, record.payload);
|
|
426
494
|
if (!text) continue;
|
|
427
495
|
const isSandbox = SANDBOX_RECORD_TYPES.has(record.record_type);
|
|
@@ -483,43 +551,49 @@ function groupRecordsToChatTurns(records) {
|
|
|
483
551
|
});
|
|
484
552
|
continue;
|
|
485
553
|
}
|
|
486
|
-
if (record.
|
|
554
|
+
if (record.record_format === "codex_jsonl@1") {
|
|
555
|
+
codexEventIntoTurns(record, record.payload, {
|
|
556
|
+
openAgentTurn,
|
|
557
|
+
closeTurn: (completedAt) => {
|
|
558
|
+
if (openIdx >= 0) {
|
|
559
|
+
turns[openIdx].completedAt = completedAt;
|
|
560
|
+
openIdx = -1;
|
|
561
|
+
}
|
|
562
|
+
},
|
|
563
|
+
nextKey
|
|
564
|
+
});
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
487
567
|
const data = record.payload;
|
|
488
|
-
if (data.
|
|
568
|
+
if (data.kind === "system") {
|
|
489
569
|
if (isInitEvent(data)) {
|
|
490
570
|
initCount += 1;
|
|
491
571
|
if (initCount > 1) pendingResume = true;
|
|
492
572
|
}
|
|
493
573
|
continue;
|
|
494
574
|
}
|
|
495
|
-
if (data.
|
|
575
|
+
if (data.kind === "result") {
|
|
496
576
|
if (openIdx >= 0) {
|
|
497
577
|
turns[openIdx].completedAt = record.created_at;
|
|
498
578
|
turns[openIdx].durationMs = typeof data.duration_ms === "number" ? data.duration_ms : null;
|
|
499
|
-
if (typeof data.
|
|
500
|
-
turns[openIdx].costUsd =
|
|
501
|
-
0,
|
|
502
|
-
data.total_cost_usd - prevCumulativeCostUsd
|
|
503
|
-
);
|
|
504
|
-
prevCumulativeCostUsd = data.total_cost_usd;
|
|
579
|
+
if (typeof data.cost_usd === "number") {
|
|
580
|
+
turns[openIdx].costUsd = data.cost_usd;
|
|
505
581
|
}
|
|
506
582
|
openIdx = -1;
|
|
507
583
|
}
|
|
508
584
|
continue;
|
|
509
585
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
if (typeof content2 === "string") {
|
|
515
|
-
if (content2.trim()) {
|
|
586
|
+
if (data.kind === "user") {
|
|
587
|
+
const content = data.content;
|
|
588
|
+
if (typeof content === "string") {
|
|
589
|
+
if (content.trim()) {
|
|
516
590
|
openIdx = -1;
|
|
517
591
|
turns.push({
|
|
518
592
|
resumed: false,
|
|
519
593
|
key: nextKey(record.id),
|
|
520
594
|
role: "user",
|
|
521
595
|
nodes: [
|
|
522
|
-
{ key: nextKey(record.id), kind: "user", text:
|
|
596
|
+
{ key: nextKey(record.id), kind: "user", text: content.trim() }
|
|
523
597
|
],
|
|
524
598
|
startedAt: record.created_at,
|
|
525
599
|
completedAt: record.created_at,
|
|
@@ -530,12 +604,11 @@ function groupRecordsToChatTurns(records) {
|
|
|
530
604
|
}
|
|
531
605
|
continue;
|
|
532
606
|
}
|
|
533
|
-
|
|
534
|
-
for (const block of content2) {
|
|
607
|
+
for (const block of content) {
|
|
535
608
|
if (block.type !== "tool_result") continue;
|
|
536
|
-
const body =
|
|
537
|
-
const useId = block.tool_use_id
|
|
538
|
-
const node =
|
|
609
|
+
const body = toolResultText(block.content) || "(no output)";
|
|
610
|
+
const useId = block.tool_use_id;
|
|
611
|
+
const node = toolNodeByUseId.get(useId);
|
|
539
612
|
if (node) {
|
|
540
613
|
node.result = body;
|
|
541
614
|
node.isError = !!block.is_error;
|
|
@@ -553,41 +626,38 @@ function groupRecordsToChatTurns(records) {
|
|
|
553
626
|
completedAt: record.created_at
|
|
554
627
|
};
|
|
555
628
|
openAgentTurn(record).nodes.push(orphan);
|
|
556
|
-
|
|
629
|
+
toolNodeByUseId.set(useId, orphan);
|
|
557
630
|
}
|
|
558
631
|
}
|
|
559
632
|
continue;
|
|
560
633
|
}
|
|
561
|
-
|
|
562
|
-
if (!Array.isArray(content)) continue;
|
|
634
|
+
if (data.kind !== "assistant") continue;
|
|
563
635
|
const turn = openAgentTurn(record);
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
turn.tokens = (turn.tokens ?? 0) + usage.output_tokens;
|
|
636
|
+
if (data.usage && typeof data.usage.output_tokens === "number") {
|
|
637
|
+
turn.tokens = (turn.tokens ?? 0) + data.usage.output_tokens;
|
|
567
638
|
}
|
|
568
|
-
for (const block of content) {
|
|
569
|
-
if (
|
|
639
|
+
for (const block of data.content) {
|
|
640
|
+
if (block.type === "thinking" && block.thinking.trim()) {
|
|
570
641
|
turn.nodes.push({
|
|
571
642
|
key: nextKey(record.id),
|
|
572
643
|
kind: "thinking",
|
|
573
644
|
text: block.thinking.trim()
|
|
574
645
|
});
|
|
575
|
-
} else if (block.type
|
|
576
|
-
const name = block.name ?? "tool";
|
|
646
|
+
} else if (block.type === "tool_use" || block.type === "server_tool_use") {
|
|
577
647
|
const node = {
|
|
578
648
|
key: nextKey(record.id),
|
|
579
649
|
kind: "tool",
|
|
580
|
-
name,
|
|
581
|
-
input: block.input
|
|
582
|
-
summary: summarizeToolInput(name, block.input
|
|
650
|
+
name: block.name,
|
|
651
|
+
input: block.input,
|
|
652
|
+
summary: summarizeToolInput(block.name, block.input),
|
|
583
653
|
result: null,
|
|
584
654
|
isError: false,
|
|
585
655
|
startedAt: record.created_at,
|
|
586
656
|
completedAt: null
|
|
587
657
|
};
|
|
588
658
|
turn.nodes.push(node);
|
|
589
|
-
|
|
590
|
-
} else if (block.type === "text" &&
|
|
659
|
+
toolNodeByUseId.set(block.id, node);
|
|
660
|
+
} else if (block.type === "text" && block.text.trim()) {
|
|
591
661
|
turn.nodes.push({
|
|
592
662
|
key: nextKey(record.id),
|
|
593
663
|
kind: "assistant",
|
|
@@ -598,6 +668,105 @@ function groupRecordsToChatTurns(records) {
|
|
|
598
668
|
}
|
|
599
669
|
return turns;
|
|
600
670
|
}
|
|
671
|
+
function codexEventIntoTurns(record, event, ops) {
|
|
672
|
+
if (event.type === "turn.completed" || event.type === "turn.failed") {
|
|
673
|
+
ops.closeTurn(record.created_at);
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
if (event.type === "error") {
|
|
677
|
+
const turn2 = ops.openAgentTurn(record);
|
|
678
|
+
turn2.nodes.push({
|
|
679
|
+
key: ops.nextKey(record.id),
|
|
680
|
+
kind: "assistant",
|
|
681
|
+
text: event.message?.trim() || "error"
|
|
682
|
+
});
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
if (event.type !== "item.completed") return;
|
|
686
|
+
const item = event.item;
|
|
687
|
+
const turn = () => ops.openAgentTurn(record);
|
|
688
|
+
switch (item.type) {
|
|
689
|
+
case "agent_message": {
|
|
690
|
+
const text = item.text.trim();
|
|
691
|
+
if (text)
|
|
692
|
+
turn().nodes.push({
|
|
693
|
+
key: ops.nextKey(record.id),
|
|
694
|
+
kind: "assistant",
|
|
695
|
+
text
|
|
696
|
+
});
|
|
697
|
+
break;
|
|
698
|
+
}
|
|
699
|
+
case "reasoning": {
|
|
700
|
+
const r = item;
|
|
701
|
+
const text = (r.text ?? r.summary ?? "").trim();
|
|
702
|
+
if (text)
|
|
703
|
+
turn().nodes.push({
|
|
704
|
+
key: ops.nextKey(record.id),
|
|
705
|
+
kind: "thinking",
|
|
706
|
+
text
|
|
707
|
+
});
|
|
708
|
+
break;
|
|
709
|
+
}
|
|
710
|
+
case "command_execution": {
|
|
711
|
+
const c = item;
|
|
712
|
+
turn().nodes.push({
|
|
713
|
+
key: ops.nextKey(record.id),
|
|
714
|
+
kind: "tool",
|
|
715
|
+
name: "Bash",
|
|
716
|
+
input: { command: c.command },
|
|
717
|
+
summary: oneLine(c.command, 100),
|
|
718
|
+
result: (c.aggregated_output ?? "").trim() || "(no output)",
|
|
719
|
+
isError: typeof c.exit_code === "number" && c.exit_code !== 0,
|
|
720
|
+
startedAt: record.created_at,
|
|
721
|
+
completedAt: record.created_at
|
|
722
|
+
});
|
|
723
|
+
break;
|
|
724
|
+
}
|
|
725
|
+
case "file_change": {
|
|
726
|
+
const paths = codexChangedPaths(item);
|
|
727
|
+
turn().nodes.push({
|
|
728
|
+
key: ops.nextKey(record.id),
|
|
729
|
+
kind: "tool",
|
|
730
|
+
name: "Edit",
|
|
731
|
+
input: null,
|
|
732
|
+
summary: paths.length ? oneLine(paths.join(", "), 100) : "",
|
|
733
|
+
result: null,
|
|
734
|
+
isError: false,
|
|
735
|
+
startedAt: record.created_at,
|
|
736
|
+
completedAt: record.created_at
|
|
737
|
+
});
|
|
738
|
+
break;
|
|
739
|
+
}
|
|
740
|
+
case "mcp_tool_call":
|
|
741
|
+
turn().nodes.push({
|
|
742
|
+
key: ops.nextKey(record.id),
|
|
743
|
+
kind: "tool",
|
|
744
|
+
name: codexMcpToolName(item),
|
|
745
|
+
input: null,
|
|
746
|
+
summary: "",
|
|
747
|
+
result: null,
|
|
748
|
+
isError: false,
|
|
749
|
+
startedAt: record.created_at,
|
|
750
|
+
completedAt: record.created_at
|
|
751
|
+
});
|
|
752
|
+
break;
|
|
753
|
+
case "web_search": {
|
|
754
|
+
const query = item.query;
|
|
755
|
+
turn().nodes.push({
|
|
756
|
+
key: ops.nextKey(record.id),
|
|
757
|
+
kind: "tool",
|
|
758
|
+
name: "WebSearch",
|
|
759
|
+
input: query ? { query } : null,
|
|
760
|
+
summary: query ? oneLine(query, 100) : "",
|
|
761
|
+
result: null,
|
|
762
|
+
isError: false,
|
|
763
|
+
startedAt: record.created_at,
|
|
764
|
+
completedAt: record.created_at
|
|
765
|
+
});
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
}
|
|
601
770
|
|
|
602
771
|
// src/store/index.ts
|
|
603
772
|
var TERMINAL_SESSION_STATUSES = /* @__PURE__ */ new Set([
|
|
@@ -791,10 +960,12 @@ var SessionTranscriptStore = class {
|
|
|
791
960
|
};
|
|
792
961
|
};
|
|
793
962
|
export {
|
|
794
|
-
LineBuffer,
|
|
795
963
|
SessionTranscriptStore,
|
|
796
964
|
cacheTierLabel,
|
|
797
965
|
clampLines,
|
|
966
|
+
codexChangedPaths,
|
|
967
|
+
codexEventToItems,
|
|
968
|
+
codexMcpToolName,
|
|
798
969
|
collapseToolRuns,
|
|
799
970
|
emptySessionTranscriptSnapshot,
|
|
800
971
|
eventToItems,
|
|
@@ -805,7 +976,6 @@ export {
|
|
|
805
976
|
isConversationOver,
|
|
806
977
|
lifecycleText,
|
|
807
978
|
oneLine,
|
|
808
|
-
parseEventLine,
|
|
809
979
|
pendingToolCalls,
|
|
810
980
|
recordToItems,
|
|
811
981
|
resultCostUsd,
|
|
@@ -814,5 +984,6 @@ export {
|
|
|
814
984
|
sandboxOutputStep,
|
|
815
985
|
sandboxPhaseLabel,
|
|
816
986
|
statusActivityText,
|
|
817
|
-
summarizeToolInput
|
|
987
|
+
summarizeToolInput,
|
|
988
|
+
toolResultText
|
|
818
989
|
};
|
package/dist/stream/index.d.ts
CHANGED