@ellipsis-dev/sdk 0.14.0 → 0.15.1
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 +298 -125
- package/dist/stream/index.d.ts +1 -1
- package/dist/{types-egqnpL5C.d.ts → types-D9g-eZui.d.ts} +1346 -196
- package/package.json +1 -1
- package/schema/frames.schema.json +2604 -614
- package/schema/openapi.v1.json +5210 -3431
- 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,153 @@ 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
|
+
}
|
|
369
|
+
default:
|
|
370
|
+
return [];
|
|
281
371
|
}
|
|
282
|
-
if (record.source !== "claude_code") return [];
|
|
283
|
-
return eventToItems(record.payload, keyBase, options);
|
|
284
372
|
}
|
|
285
373
|
function isConnectVisibleRecord(record) {
|
|
286
374
|
return record.source !== "lifecycle" || record.record_type === "sandbox_ready";
|
|
@@ -341,19 +429,18 @@ function clampLines(text, maxLines) {
|
|
|
341
429
|
};
|
|
342
430
|
}
|
|
343
431
|
function resultCostUsd(event) {
|
|
344
|
-
if (event.
|
|
345
|
-
return typeof event.
|
|
432
|
+
if (event.kind !== "result") return null;
|
|
433
|
+
return typeof event.cost_usd === "number" ? event.cost_usd : null;
|
|
346
434
|
}
|
|
347
435
|
function foldCosts(events) {
|
|
348
|
-
let prev = null;
|
|
349
436
|
let total = null;
|
|
437
|
+
let lastStep = null;
|
|
350
438
|
for (const event of events) {
|
|
351
439
|
const cost = resultCostUsd(event);
|
|
352
440
|
if (cost == null) continue;
|
|
353
|
-
|
|
354
|
-
|
|
441
|
+
total = (total ?? 0) + cost;
|
|
442
|
+
lastStep = cost;
|
|
355
443
|
}
|
|
356
|
-
const lastStep = total != null && prev != null ? Math.max(0, total - prev) : total;
|
|
357
444
|
return { total, lastStep };
|
|
358
445
|
}
|
|
359
446
|
function statusActivityText(status) {
|
|
@@ -370,36 +457,19 @@ function statusActivityText(status) {
|
|
|
370
457
|
}
|
|
371
458
|
|
|
372
459
|
// 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
|
-
]);
|
|
460
|
+
var isInitEvent = (data) => data.kind === "system" && data.subtype === "init";
|
|
379
461
|
var SANDBOX_RECORD_TYPES = /* @__PURE__ */ new Set([
|
|
380
462
|
"sandbox_starting",
|
|
381
463
|
"sandbox_phase",
|
|
382
464
|
"sandbox_output",
|
|
383
465
|
"sandbox_ready"
|
|
384
466
|
]);
|
|
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
467
|
function groupRecordsToChatTurns(records) {
|
|
397
468
|
const turns = [];
|
|
398
469
|
const toolNodeByUseId = /* @__PURE__ */ new Map();
|
|
399
470
|
let seq = 0;
|
|
400
471
|
const nextKey = (base) => `${base}:${seq++}`;
|
|
401
472
|
let openIdx = -1;
|
|
402
|
-
let prevCumulativeCostUsd = 0;
|
|
403
473
|
let initCount = 0;
|
|
404
474
|
let pendingResume = false;
|
|
405
475
|
const openAgentTurn = (record) => {
|
|
@@ -421,7 +491,7 @@ function groupRecordsToChatTurns(records) {
|
|
|
421
491
|
return turns[openIdx];
|
|
422
492
|
};
|
|
423
493
|
for (const record of records) {
|
|
424
|
-
if (record.
|
|
494
|
+
if (record.record_format === "ellipsis_lifecycle@1") {
|
|
425
495
|
const text = lifecycleText(record.record_type, record.payload);
|
|
426
496
|
if (!text) continue;
|
|
427
497
|
const isSandbox = SANDBOX_RECORD_TYPES.has(record.record_type);
|
|
@@ -483,43 +553,49 @@ function groupRecordsToChatTurns(records) {
|
|
|
483
553
|
});
|
|
484
554
|
continue;
|
|
485
555
|
}
|
|
486
|
-
if (record.
|
|
556
|
+
if (record.record_format === "codex_jsonl@1") {
|
|
557
|
+
codexEventIntoTurns(record, record.payload, {
|
|
558
|
+
openAgentTurn,
|
|
559
|
+
closeTurn: (completedAt) => {
|
|
560
|
+
if (openIdx >= 0) {
|
|
561
|
+
turns[openIdx].completedAt = completedAt;
|
|
562
|
+
openIdx = -1;
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
nextKey
|
|
566
|
+
});
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
487
569
|
const data = record.payload;
|
|
488
|
-
if (data.
|
|
570
|
+
if (data.kind === "system") {
|
|
489
571
|
if (isInitEvent(data)) {
|
|
490
572
|
initCount += 1;
|
|
491
573
|
if (initCount > 1) pendingResume = true;
|
|
492
574
|
}
|
|
493
575
|
continue;
|
|
494
576
|
}
|
|
495
|
-
if (data.
|
|
577
|
+
if (data.kind === "result") {
|
|
496
578
|
if (openIdx >= 0) {
|
|
497
579
|
turns[openIdx].completedAt = record.created_at;
|
|
498
580
|
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;
|
|
581
|
+
if (typeof data.cost_usd === "number") {
|
|
582
|
+
turns[openIdx].costUsd = data.cost_usd;
|
|
505
583
|
}
|
|
506
584
|
openIdx = -1;
|
|
507
585
|
}
|
|
508
586
|
continue;
|
|
509
587
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
if (typeof content2 === "string") {
|
|
515
|
-
if (content2.trim()) {
|
|
588
|
+
if (data.kind === "user") {
|
|
589
|
+
const content = data.content;
|
|
590
|
+
if (typeof content === "string") {
|
|
591
|
+
if (content.trim()) {
|
|
516
592
|
openIdx = -1;
|
|
517
593
|
turns.push({
|
|
518
594
|
resumed: false,
|
|
519
595
|
key: nextKey(record.id),
|
|
520
596
|
role: "user",
|
|
521
597
|
nodes: [
|
|
522
|
-
{ key: nextKey(record.id), kind: "user", text:
|
|
598
|
+
{ key: nextKey(record.id), kind: "user", text: content.trim() }
|
|
523
599
|
],
|
|
524
600
|
startedAt: record.created_at,
|
|
525
601
|
completedAt: record.created_at,
|
|
@@ -530,12 +606,11 @@ function groupRecordsToChatTurns(records) {
|
|
|
530
606
|
}
|
|
531
607
|
continue;
|
|
532
608
|
}
|
|
533
|
-
|
|
534
|
-
for (const block of content2) {
|
|
609
|
+
for (const block of content) {
|
|
535
610
|
if (block.type !== "tool_result") continue;
|
|
536
|
-
const body =
|
|
537
|
-
const useId = block.tool_use_id
|
|
538
|
-
const node =
|
|
611
|
+
const body = toolResultText(block.content) || "(no output)";
|
|
612
|
+
const useId = block.tool_use_id;
|
|
613
|
+
const node = toolNodeByUseId.get(useId);
|
|
539
614
|
if (node) {
|
|
540
615
|
node.result = body;
|
|
541
616
|
node.isError = !!block.is_error;
|
|
@@ -553,41 +628,38 @@ function groupRecordsToChatTurns(records) {
|
|
|
553
628
|
completedAt: record.created_at
|
|
554
629
|
};
|
|
555
630
|
openAgentTurn(record).nodes.push(orphan);
|
|
556
|
-
|
|
631
|
+
toolNodeByUseId.set(useId, orphan);
|
|
557
632
|
}
|
|
558
633
|
}
|
|
559
634
|
continue;
|
|
560
635
|
}
|
|
561
|
-
|
|
562
|
-
if (!Array.isArray(content)) continue;
|
|
636
|
+
if (data.kind !== "assistant") continue;
|
|
563
637
|
const turn = openAgentTurn(record);
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
turn.tokens = (turn.tokens ?? 0) + usage.output_tokens;
|
|
638
|
+
if (data.usage && typeof data.usage.output_tokens === "number") {
|
|
639
|
+
turn.tokens = (turn.tokens ?? 0) + data.usage.output_tokens;
|
|
567
640
|
}
|
|
568
|
-
for (const block of content) {
|
|
569
|
-
if (
|
|
641
|
+
for (const block of data.content) {
|
|
642
|
+
if (block.type === "thinking" && block.thinking.trim()) {
|
|
570
643
|
turn.nodes.push({
|
|
571
644
|
key: nextKey(record.id),
|
|
572
645
|
kind: "thinking",
|
|
573
646
|
text: block.thinking.trim()
|
|
574
647
|
});
|
|
575
|
-
} else if (block.type
|
|
576
|
-
const name = block.name ?? "tool";
|
|
648
|
+
} else if (block.type === "tool_use" || block.type === "server_tool_use") {
|
|
577
649
|
const node = {
|
|
578
650
|
key: nextKey(record.id),
|
|
579
651
|
kind: "tool",
|
|
580
|
-
name,
|
|
581
|
-
input: block.input
|
|
582
|
-
summary: summarizeToolInput(name, block.input
|
|
652
|
+
name: block.name,
|
|
653
|
+
input: block.input,
|
|
654
|
+
summary: summarizeToolInput(block.name, block.input),
|
|
583
655
|
result: null,
|
|
584
656
|
isError: false,
|
|
585
657
|
startedAt: record.created_at,
|
|
586
658
|
completedAt: null
|
|
587
659
|
};
|
|
588
660
|
turn.nodes.push(node);
|
|
589
|
-
|
|
590
|
-
} else if (block.type === "text" &&
|
|
661
|
+
toolNodeByUseId.set(block.id, node);
|
|
662
|
+
} else if (block.type === "text" && block.text.trim()) {
|
|
591
663
|
turn.nodes.push({
|
|
592
664
|
key: nextKey(record.id),
|
|
593
665
|
kind: "assistant",
|
|
@@ -598,6 +670,105 @@ function groupRecordsToChatTurns(records) {
|
|
|
598
670
|
}
|
|
599
671
|
return turns;
|
|
600
672
|
}
|
|
673
|
+
function codexEventIntoTurns(record, event, ops) {
|
|
674
|
+
if (event.type === "turn.completed" || event.type === "turn.failed") {
|
|
675
|
+
ops.closeTurn(record.created_at);
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
if (event.type === "error") {
|
|
679
|
+
const turn2 = ops.openAgentTurn(record);
|
|
680
|
+
turn2.nodes.push({
|
|
681
|
+
key: ops.nextKey(record.id),
|
|
682
|
+
kind: "assistant",
|
|
683
|
+
text: event.message?.trim() || "error"
|
|
684
|
+
});
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
if (event.type !== "item.completed") return;
|
|
688
|
+
const item = event.item;
|
|
689
|
+
const turn = () => ops.openAgentTurn(record);
|
|
690
|
+
switch (item.type) {
|
|
691
|
+
case "agent_message": {
|
|
692
|
+
const text = item.text.trim();
|
|
693
|
+
if (text)
|
|
694
|
+
turn().nodes.push({
|
|
695
|
+
key: ops.nextKey(record.id),
|
|
696
|
+
kind: "assistant",
|
|
697
|
+
text
|
|
698
|
+
});
|
|
699
|
+
break;
|
|
700
|
+
}
|
|
701
|
+
case "reasoning": {
|
|
702
|
+
const r = item;
|
|
703
|
+
const text = (r.text ?? r.summary ?? "").trim();
|
|
704
|
+
if (text)
|
|
705
|
+
turn().nodes.push({
|
|
706
|
+
key: ops.nextKey(record.id),
|
|
707
|
+
kind: "thinking",
|
|
708
|
+
text
|
|
709
|
+
});
|
|
710
|
+
break;
|
|
711
|
+
}
|
|
712
|
+
case "command_execution": {
|
|
713
|
+
const c = item;
|
|
714
|
+
turn().nodes.push({
|
|
715
|
+
key: ops.nextKey(record.id),
|
|
716
|
+
kind: "tool",
|
|
717
|
+
name: "Bash",
|
|
718
|
+
input: { command: c.command },
|
|
719
|
+
summary: oneLine(c.command, 100),
|
|
720
|
+
result: (c.aggregated_output ?? "").trim() || "(no output)",
|
|
721
|
+
isError: typeof c.exit_code === "number" && c.exit_code !== 0,
|
|
722
|
+
startedAt: record.created_at,
|
|
723
|
+
completedAt: record.created_at
|
|
724
|
+
});
|
|
725
|
+
break;
|
|
726
|
+
}
|
|
727
|
+
case "file_change": {
|
|
728
|
+
const paths = codexChangedPaths(item);
|
|
729
|
+
turn().nodes.push({
|
|
730
|
+
key: ops.nextKey(record.id),
|
|
731
|
+
kind: "tool",
|
|
732
|
+
name: "Edit",
|
|
733
|
+
input: null,
|
|
734
|
+
summary: paths.length ? oneLine(paths.join(", "), 100) : "",
|
|
735
|
+
result: null,
|
|
736
|
+
isError: false,
|
|
737
|
+
startedAt: record.created_at,
|
|
738
|
+
completedAt: record.created_at
|
|
739
|
+
});
|
|
740
|
+
break;
|
|
741
|
+
}
|
|
742
|
+
case "mcp_tool_call":
|
|
743
|
+
turn().nodes.push({
|
|
744
|
+
key: ops.nextKey(record.id),
|
|
745
|
+
kind: "tool",
|
|
746
|
+
name: codexMcpToolName(item),
|
|
747
|
+
input: null,
|
|
748
|
+
summary: "",
|
|
749
|
+
result: null,
|
|
750
|
+
isError: false,
|
|
751
|
+
startedAt: record.created_at,
|
|
752
|
+
completedAt: record.created_at
|
|
753
|
+
});
|
|
754
|
+
break;
|
|
755
|
+
case "web_search": {
|
|
756
|
+
const query = item.query;
|
|
757
|
+
turn().nodes.push({
|
|
758
|
+
key: ops.nextKey(record.id),
|
|
759
|
+
kind: "tool",
|
|
760
|
+
name: "WebSearch",
|
|
761
|
+
input: query ? { query } : null,
|
|
762
|
+
summary: query ? oneLine(query, 100) : "",
|
|
763
|
+
result: null,
|
|
764
|
+
isError: false,
|
|
765
|
+
startedAt: record.created_at,
|
|
766
|
+
completedAt: record.created_at
|
|
767
|
+
});
|
|
768
|
+
break;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
601
772
|
|
|
602
773
|
// src/store/index.ts
|
|
603
774
|
var TERMINAL_SESSION_STATUSES = /* @__PURE__ */ new Set([
|
|
@@ -791,10 +962,12 @@ var SessionTranscriptStore = class {
|
|
|
791
962
|
};
|
|
792
963
|
};
|
|
793
964
|
export {
|
|
794
|
-
LineBuffer,
|
|
795
965
|
SessionTranscriptStore,
|
|
796
966
|
cacheTierLabel,
|
|
797
967
|
clampLines,
|
|
968
|
+
codexChangedPaths,
|
|
969
|
+
codexEventToItems,
|
|
970
|
+
codexMcpToolName,
|
|
798
971
|
collapseToolRuns,
|
|
799
972
|
emptySessionTranscriptSnapshot,
|
|
800
973
|
eventToItems,
|
|
@@ -805,7 +978,6 @@ export {
|
|
|
805
978
|
isConversationOver,
|
|
806
979
|
lifecycleText,
|
|
807
980
|
oneLine,
|
|
808
|
-
parseEventLine,
|
|
809
981
|
pendingToolCalls,
|
|
810
982
|
recordToItems,
|
|
811
983
|
resultCostUsd,
|
|
@@ -814,5 +986,6 @@ export {
|
|
|
814
986
|
sandboxOutputStep,
|
|
815
987
|
sandboxPhaseLabel,
|
|
816
988
|
statusActivityText,
|
|
817
|
-
summarizeToolInput
|
|
989
|
+
summarizeToolInput,
|
|
990
|
+
toolResultText
|
|
818
991
|
};
|
package/dist/stream/index.d.ts
CHANGED