@opengeni/react 0.23.0 → 0.25.5
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/{chunk-UQS7OQDE.js → chunk-F4CFWKVI.js} +334 -64
- package/dist/chunk-F4CFWKVI.js.map +1 -0
- package/dist/chunk-GQN2QIR2.js +3767 -0
- package/dist/chunk-GQN2QIR2.js.map +1 -0
- package/dist/{chunk-I3BJZIG5.js → chunk-HIWPQYWI.js} +2 -120
- package/dist/chunk-HIWPQYWI.js.map +1 -0
- package/dist/chunk-M7X4JZOD.js +121 -0
- package/dist/chunk-M7X4JZOD.js.map +1 -0
- package/dist/{chunk-UAHPKLB6.js → chunk-MP6237JB.js} +571 -975
- package/dist/chunk-MP6237JB.js.map +1 -0
- package/dist/chunk-OZDLELJQ.js +937 -0
- package/dist/chunk-OZDLELJQ.js.map +1 -0
- package/dist/{chunk-CATATY77.js → chunk-TMH6HZWF.js} +8 -7
- package/dist/chunk-TMH6HZWF.js.map +1 -0
- package/dist/{chunk-6XUS5VFM.js → chunk-YU5PGUK7.js} +6 -4
- package/dist/{chunk-6XUS5VFM.js.map → chunk-YU5PGUK7.js.map} +1 -1
- package/dist/{composer-CVm5uoUI.d.ts → composer-DoC4veX1.d.ts} +6 -63
- package/dist/composer.d.ts +3 -2
- package/dist/composer.js +4 -3
- package/dist/fleet-decision-projection-SLNZMS42.js +241 -0
- package/dist/fleet-decision-projection-SLNZMS42.js.map +1 -0
- package/dist/fleet-decision-row-GGCAT4E4.js +351 -0
- package/dist/fleet-decision-row-GGCAT4E4.js.map +1 -0
- package/dist/index.d.ts +17 -259
- package/dist/index.js +1042 -5058
- package/dist/index.js.map +1 -1
- package/dist/machines.js +3 -2
- package/dist/session-Du_FsrZ1.d.ts +264 -0
- package/dist/session-ui-BqQDH7YV.d.ts +183 -0
- package/dist/session-ui.d.ts +7 -0
- package/dist/session-ui.js +17 -0
- package/dist/session-ui.js.map +1 -0
- package/dist/session.d.ts +4 -2
- package/dist/session.js +26 -9
- package/dist/{use-composer-By1wn3MM.d.ts → use-composer-BnEzheSk.d.ts} +8 -2
- package/dist/use-file-attachments-C0kpHrs9.d.ts +76 -0
- package/dist/use-turn-queue-3rkJwjFv.d.ts +290 -0
- package/package.json +6 -2
- package/src/components/composer.tsx +7 -6
- package/src/components/message-timeline.tsx +94 -54
- package/src/hooks/use-composer.ts +470 -73
- package/src/hooks/use-file-attachments.ts +96 -3
- package/src/hooks/use-goal.ts +23 -5
- package/src/hooks/use-session-events.ts +5 -0
- package/src/hooks/use-session-lineage.ts +1 -1
- package/src/hooks/use-session.ts +9 -6
- package/src/hooks/use-workspace-sessions.ts +30 -5
- package/src/session-ui.ts +13 -0
- package/src/session.ts +15 -0
- package/src/timeline/activity-rail.tsx +18 -2
- package/src/timeline/fleet-decision-projection.ts +366 -0
- package/src/timeline/fleet-decision-row.tsx +412 -0
- package/src/timeline/index.ts +2 -0
- package/src/timeline/projection.ts +19 -8
- package/src/timeline/tool-display-name.ts +16 -0
- package/src/timeline/tool-renderers.tsx +1 -1
- package/src/timeline/types.ts +68 -1
- package/dist/chunk-CATATY77.js.map +0 -1
- package/dist/chunk-I3BJZIG5.js.map +0 -1
- package/dist/chunk-UAHPKLB6.js.map +0 -1
- package/dist/chunk-UQS7OQDE.js.map +0 -1
- package/dist/session-Db00TRwl.d.ts +0 -446
|
@@ -0,0 +1,937 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CREDIT_EXHAUSTION_MESSAGE,
|
|
3
|
+
humanizeFailureReason,
|
|
4
|
+
isCreditExhaustion,
|
|
5
|
+
tryParseJson
|
|
6
|
+
} from "./chunk-M7X4JZOD.js";
|
|
7
|
+
|
|
8
|
+
// src/timeline/projection.ts
|
|
9
|
+
var { default: fleetDecisionItem } = await import("./fleet-decision-projection-SLNZMS42.js");
|
|
10
|
+
function toolDisplayName(name) {
|
|
11
|
+
const boundary = name.indexOf("__");
|
|
12
|
+
const toolPart = boundary >= 0 ? name.slice(boundary + 2) : name;
|
|
13
|
+
return toolPart.replace(/[_-]+/g, " ").trim();
|
|
14
|
+
}
|
|
15
|
+
var WORKER_SPAWN_TOOL = "session_create";
|
|
16
|
+
var WORKER_MESSAGE_TOOL = "session_send_message";
|
|
17
|
+
function buildTimeline(events) {
|
|
18
|
+
const items = [];
|
|
19
|
+
const prescan = prescanTurnAnchors(events);
|
|
20
|
+
const ordered = orderTimelineEvents(events, prescan);
|
|
21
|
+
const last = () => items[items.length - 1];
|
|
22
|
+
const closeStreamingTail = () => {
|
|
23
|
+
const open = last();
|
|
24
|
+
if ((open?.kind === "agent-message" || open?.kind === "reasoning") && open.streaming) {
|
|
25
|
+
open.streaming = false;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const finalizeOpen = (turnId, disposition = "complete") => {
|
|
29
|
+
for (const item of items) {
|
|
30
|
+
if (turnId !== void 0 && "turnId" in item && item.turnId && turnId && item.turnId !== turnId) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if ((item.kind === "agent-message" || item.kind === "reasoning") && item.streaming) {
|
|
34
|
+
item.streaming = false;
|
|
35
|
+
}
|
|
36
|
+
if ((item.kind === "tool-call" || item.kind === "worker") && item.status === "running") {
|
|
37
|
+
item.status = disposition;
|
|
38
|
+
}
|
|
39
|
+
if (item.kind === "sandbox" && item.status === "running") {
|
|
40
|
+
item.status = disposition;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
for (const event of ordered) {
|
|
45
|
+
const payload = asRecord(event.payload);
|
|
46
|
+
const turnId = event.turnId ?? null;
|
|
47
|
+
switch (event.type) {
|
|
48
|
+
case "user.message": {
|
|
49
|
+
closeStreamingTail();
|
|
50
|
+
const childCompletion = workerCompletionPayload(payload.childCompletion);
|
|
51
|
+
if (childCompletion) {
|
|
52
|
+
items.push({
|
|
53
|
+
kind: "worker-completion",
|
|
54
|
+
id: event.id,
|
|
55
|
+
turnId,
|
|
56
|
+
occurredAt: event.occurredAt,
|
|
57
|
+
childSessionId: childCompletion.childSessionId,
|
|
58
|
+
childStatus: childCompletion.childStatus,
|
|
59
|
+
goalStatus: childCompletion.goalStatus,
|
|
60
|
+
goalText: childCompletion.goalText,
|
|
61
|
+
evidence: childCompletion.evidence,
|
|
62
|
+
pausedReason: childCompletion.pausedReason,
|
|
63
|
+
text: typeof payload.text === "string" ? payload.text : ""
|
|
64
|
+
});
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
items.push({
|
|
68
|
+
kind: "user-message",
|
|
69
|
+
id: event.id,
|
|
70
|
+
text: typeof payload.text === "string" ? payload.text : "",
|
|
71
|
+
resources: resourceRefs(payload.resources),
|
|
72
|
+
tools: toolRefs(payload.tools),
|
|
73
|
+
occurredAt: event.occurredAt
|
|
74
|
+
});
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case "agent.message.delta": {
|
|
78
|
+
const text = typeof payload.text === "string" ? payload.text : "";
|
|
79
|
+
if (!text) {
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
const open = last();
|
|
83
|
+
if (open?.kind === "agent-message" && open.streaming && open.turnId === turnId) {
|
|
84
|
+
open.text += text;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
closeStreamingTail();
|
|
88
|
+
items.push({
|
|
89
|
+
kind: "agent-message",
|
|
90
|
+
id: event.id,
|
|
91
|
+
turnId,
|
|
92
|
+
text,
|
|
93
|
+
streaming: true,
|
|
94
|
+
occurredAt: event.occurredAt
|
|
95
|
+
});
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case "agent.message.completed": {
|
|
99
|
+
const text = typeof payload.text === "string" ? payload.text : "";
|
|
100
|
+
const open = [...items].reverse().find(
|
|
101
|
+
(item) => item.kind === "agent-message" && item.turnId === turnId
|
|
102
|
+
);
|
|
103
|
+
if (open && (open.streaming || !open.text || text === open.text || text.startsWith(open.text))) {
|
|
104
|
+
if (!open.text || text && text.startsWith(open.text)) {
|
|
105
|
+
open.text = text || open.text;
|
|
106
|
+
}
|
|
107
|
+
open.streaming = false;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
if (text) {
|
|
111
|
+
items.push({
|
|
112
|
+
kind: "agent-message",
|
|
113
|
+
id: event.id,
|
|
114
|
+
turnId,
|
|
115
|
+
text,
|
|
116
|
+
streaming: false,
|
|
117
|
+
occurredAt: event.occurredAt
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
case "agent.reasoning.delta": {
|
|
123
|
+
const text = reasoningText(event.payload);
|
|
124
|
+
if (!text) {
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
const open = last();
|
|
128
|
+
if (open?.kind === "reasoning" && open.streaming && open.turnId === turnId) {
|
|
129
|
+
open.text += text;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
closeStreamingTail();
|
|
133
|
+
items.push({
|
|
134
|
+
kind: "reasoning",
|
|
135
|
+
id: event.id,
|
|
136
|
+
turnId,
|
|
137
|
+
text,
|
|
138
|
+
streaming: true,
|
|
139
|
+
occurredAt: event.occurredAt
|
|
140
|
+
});
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case "agent.toolCall.created": {
|
|
144
|
+
const name = typeof payload.name === "string" ? payload.name : "tool";
|
|
145
|
+
const callId = typeof payload.id === "string" ? payload.id : null;
|
|
146
|
+
const args = payload.arguments ?? null;
|
|
147
|
+
closeStreamingTail();
|
|
148
|
+
if (name === WORKER_SPAWN_TOOL || name === WORKER_MESSAGE_TOOL) {
|
|
149
|
+
items.push({
|
|
150
|
+
kind: "worker",
|
|
151
|
+
id: event.id,
|
|
152
|
+
turnId,
|
|
153
|
+
callId,
|
|
154
|
+
action: name === WORKER_SPAWN_TOOL ? "spawn" : "message",
|
|
155
|
+
prompt: workerPrompt(args),
|
|
156
|
+
workerSessionId: extractSessionRef(args),
|
|
157
|
+
status: "running",
|
|
158
|
+
occurredAt: event.occurredAt
|
|
159
|
+
});
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
items.push({
|
|
163
|
+
kind: "tool-call",
|
|
164
|
+
id: event.id,
|
|
165
|
+
turnId,
|
|
166
|
+
callId,
|
|
167
|
+
name,
|
|
168
|
+
arguments: args,
|
|
169
|
+
output: void 0,
|
|
170
|
+
// The provider-native item drives the per-tool renderers (apply_patch
|
|
171
|
+
// operation, computer_call action, web_search providerData, …).
|
|
172
|
+
raw: payload.raw,
|
|
173
|
+
status: "running",
|
|
174
|
+
occurredAt: event.occurredAt
|
|
175
|
+
});
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
case "agent.toolCall.output": {
|
|
179
|
+
const callId = typeof payload.id === "string" ? payload.id : null;
|
|
180
|
+
const target = findOpenCall(items, callId);
|
|
181
|
+
if (!target) {
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
if (target.kind === "worker") {
|
|
185
|
+
target.status = isErrorOutput(payload) ? "failed" : "complete";
|
|
186
|
+
target.workerSessionId = target.workerSessionId ?? extractSessionRef(payload.output);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
target.status = isErrorOutput(payload) ? "failed" : "complete";
|
|
190
|
+
target.output = payload.output;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
case "sandbox.operation.started":
|
|
194
|
+
case "sandbox.operation.completed":
|
|
195
|
+
case "sandbox.operation.failed": {
|
|
196
|
+
const name = typeof payload.name === "string" ? payload.name : "sandbox";
|
|
197
|
+
const status = event.type.endsWith(".failed") ? "failed" : event.type.endsWith(".completed") ? "complete" : "running";
|
|
198
|
+
if ((name === "repository-clone" || name === "file-resource-download") && status !== "failed") {
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
const existing = findOpenSandbox(items, name);
|
|
202
|
+
if (existing && status !== "running") {
|
|
203
|
+
existing.status = status;
|
|
204
|
+
if (payload.origin === "created" || payload.origin === "restored" || payload.origin === "resumed") {
|
|
205
|
+
existing.origin = payload.origin;
|
|
206
|
+
}
|
|
207
|
+
const message = failureMessage(payload);
|
|
208
|
+
if (message) {
|
|
209
|
+
existing.output = existing.output ? `${existing.output}
|
|
210
|
+
${message}` : message;
|
|
211
|
+
}
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
if (!existing) {
|
|
215
|
+
closeStreamingTail();
|
|
216
|
+
items.push({
|
|
217
|
+
kind: "sandbox",
|
|
218
|
+
id: event.id,
|
|
219
|
+
turnId,
|
|
220
|
+
name,
|
|
221
|
+
command: typeof payload.command === "string" ? payload.command : null,
|
|
222
|
+
output: failureMessage(payload) ?? "",
|
|
223
|
+
origin: payload.origin === "created" || payload.origin === "restored" || payload.origin === "resumed" ? payload.origin : null,
|
|
224
|
+
status,
|
|
225
|
+
occurredAt: event.occurredAt
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
case "sandbox.command.output.delta": {
|
|
231
|
+
const text = typeof payload.chunk === "string" ? payload.chunk : typeof payload.text === "string" ? payload.text : typeof payload.output === "string" ? payload.output : "";
|
|
232
|
+
if (!text) {
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
const open = (typeof payload.name === "string" ? findOpenSandbox(items, payload.name) : void 0) ?? [...items].reverse().find(
|
|
236
|
+
(item) => item.kind === "sandbox" && item.status === "running"
|
|
237
|
+
);
|
|
238
|
+
if (open) {
|
|
239
|
+
open.output += text;
|
|
240
|
+
}
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
case "session.status.changed": {
|
|
244
|
+
const status = payload.status;
|
|
245
|
+
if (!isSessionStatus(status)) {
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
if (!ATTENTION_STATUSES.has(status)) {
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
const previous = [...items].reverse().find((item) => item.kind === "session-status");
|
|
252
|
+
if (previous?.status === status) {
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
items.push({ kind: "session-status", id: event.id, status, occurredAt: event.occurredAt });
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
case "session.requiresAction": {
|
|
259
|
+
finalizeOpen(turnId);
|
|
260
|
+
items.push({
|
|
261
|
+
kind: "notice",
|
|
262
|
+
id: event.id,
|
|
263
|
+
tone: "waiting",
|
|
264
|
+
text: "Approval needed \u2014 the turn is paused until someone decides.",
|
|
265
|
+
occurredAt: event.occurredAt
|
|
266
|
+
});
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
case "session.context.compacted": {
|
|
270
|
+
closeStreamingTail();
|
|
271
|
+
const before = typeof payload.estimatedTokensBefore === "number" ? Math.round(payload.estimatedTokensBefore).toLocaleString("en-US") : null;
|
|
272
|
+
const after = typeof payload.estimatedTokensAfter === "number" ? Math.round(payload.estimatedTokensAfter).toLocaleString("en-US") : null;
|
|
273
|
+
items.push({
|
|
274
|
+
kind: "notice",
|
|
275
|
+
id: event.id,
|
|
276
|
+
tone: "waiting",
|
|
277
|
+
text: before && after ? `Active conversation history compacted from approximately ${before} to ${after} tokens.` : "Context compacted so the turn could continue.",
|
|
278
|
+
occurredAt: event.occurredAt
|
|
279
|
+
});
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
case "session.context.compaction.skipped": {
|
|
283
|
+
closeStreamingTail();
|
|
284
|
+
const reason = typeof payload.reason === "string" ? payload.reason : null;
|
|
285
|
+
items.push({
|
|
286
|
+
kind: "notice",
|
|
287
|
+
id: event.id,
|
|
288
|
+
tone: reason === "summarization_failed" ? "failed" : "waiting",
|
|
289
|
+
text: reason === "no_history" ? "Context compaction skipped because there is no active history to compact." : reason === "replacement_not_smaller" ? "Context compaction skipped because the generated checkpoint would not reduce the context." : reason === "replacement_unchanged" ? "Context compaction stopped because it reproduced the same checkpoint without making progress." : reason === "summarization_failed" ? "Context compaction failed without replacing the active conversation history. Request it again to retry." : "Context compaction was not needed.",
|
|
290
|
+
occurredAt: event.occurredAt
|
|
291
|
+
});
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
case "turn.recovery.requested": {
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
case "turn.event.rejected_late": {
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
case "tool.auth_needed":
|
|
301
|
+
case "credential.auth_needed": {
|
|
302
|
+
closeStreamingTail();
|
|
303
|
+
items.push({
|
|
304
|
+
kind: "auth-needed",
|
|
305
|
+
id: event.id,
|
|
306
|
+
turnId,
|
|
307
|
+
providerDomain: typeof payload.providerDomain === "string" ? payload.providerDomain : "",
|
|
308
|
+
connectionId: typeof payload.connectionId === "string" ? payload.connectionId : null,
|
|
309
|
+
reason: authNeededReason(payload.reason),
|
|
310
|
+
scopes: stringList(payload.scopes),
|
|
311
|
+
resource: typeof payload.resource === "string" ? payload.resource : null,
|
|
312
|
+
toolName: typeof payload.toolName === "string" ? payload.toolName : null,
|
|
313
|
+
authorizationUrl: typeof payload.authorizationUrl === "string" ? payload.authorizationUrl : null,
|
|
314
|
+
occurredAt: event.occurredAt
|
|
315
|
+
});
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
case "turn.completed": {
|
|
319
|
+
if (payload.maintenance === "context_compaction") {
|
|
320
|
+
finalizeOpen(turnId);
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
if (isCreditExhaustionPayload(payload)) {
|
|
324
|
+
finalizeOpen(turnId);
|
|
325
|
+
items.push(turnEndItem(event, "failed", CREDIT_EXHAUSTION_MESSAGE));
|
|
326
|
+
items.push({
|
|
327
|
+
kind: "notice",
|
|
328
|
+
id: event.id,
|
|
329
|
+
tone: "failed",
|
|
330
|
+
text: CREDIT_EXHAUSTION_MESSAGE,
|
|
331
|
+
occurredAt: event.occurredAt
|
|
332
|
+
});
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
finalizeOpen(turnId);
|
|
336
|
+
items.push(turnEndItem(event, "complete", null));
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
case "turn.failed": {
|
|
340
|
+
const hadActivity = hasTurnActivity(items, turnId);
|
|
341
|
+
const failureText = isCreditExhaustionPayload(payload) ? CREDIT_EXHAUSTION_MESSAGE : failureMessage(payload);
|
|
342
|
+
finalizeOpen(turnId, "cancelled");
|
|
343
|
+
items.push(turnEndItem(event, "failed", failureText));
|
|
344
|
+
if (!hadActivity) {
|
|
345
|
+
items.push({
|
|
346
|
+
kind: "notice",
|
|
347
|
+
id: event.id,
|
|
348
|
+
tone: "failed",
|
|
349
|
+
text: failureText ?? "The turn failed.",
|
|
350
|
+
occurredAt: event.occurredAt
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
case "turn.cancelled": {
|
|
356
|
+
if (turnId && !prescan.startedTurnIds.has(turnId)) {
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
const hadActivity = hasTurnActivity(items, turnId);
|
|
360
|
+
finalizeOpen(turnId, "cancelled");
|
|
361
|
+
items.push(turnEndItem(event, "cancelled", null));
|
|
362
|
+
if (!hadActivity) {
|
|
363
|
+
items.push({
|
|
364
|
+
kind: "notice",
|
|
365
|
+
id: event.id,
|
|
366
|
+
tone: "cancelled",
|
|
367
|
+
text: "Interrupted.",
|
|
368
|
+
occurredAt: event.occurredAt
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
case "memory.saved":
|
|
374
|
+
case "memory.corrected": {
|
|
375
|
+
const memory = memoryItem(event.id, event.type, turnId, payload, event.occurredAt);
|
|
376
|
+
if (memory) {
|
|
377
|
+
closeStreamingTail();
|
|
378
|
+
items.push(memory);
|
|
379
|
+
}
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
case "codex.fleet.decision": {
|
|
383
|
+
const decision = fleetDecisionItem(event, payload);
|
|
384
|
+
if (decision) {
|
|
385
|
+
closeStreamingTail();
|
|
386
|
+
items.push(decision);
|
|
387
|
+
}
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
case "goal.set":
|
|
391
|
+
case "goal.updated":
|
|
392
|
+
case "goal.completed":
|
|
393
|
+
case "goal.paused":
|
|
394
|
+
case "goal.resumed":
|
|
395
|
+
case "goal.cleared":
|
|
396
|
+
case "goal.continuation": {
|
|
397
|
+
items.push({
|
|
398
|
+
kind: "goal",
|
|
399
|
+
id: event.id,
|
|
400
|
+
action: event.type.slice("goal.".length),
|
|
401
|
+
text: goalText(payload),
|
|
402
|
+
occurredAt: event.occurredAt
|
|
403
|
+
});
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
default:
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return items;
|
|
411
|
+
}
|
|
412
|
+
function isCreditExhaustionPayload(payload) {
|
|
413
|
+
return isCreditExhaustion({
|
|
414
|
+
error: typeof payload.error === "string" ? payload.error : null,
|
|
415
|
+
detail: typeof payload.detail === "string" ? payload.detail : null,
|
|
416
|
+
segmentLimit: typeof payload.segmentLimit === "string" ? payload.segmentLimit : null
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
function creditExhaustedFromEvents(events) {
|
|
420
|
+
const ordered = [...events].sort((a, b) => a.sequence - b.sequence);
|
|
421
|
+
for (let index = ordered.length - 1; index >= 0; index -= 1) {
|
|
422
|
+
const event = ordered[index];
|
|
423
|
+
if (event?.type !== "turn.completed" && event?.type !== "turn.failed" && event?.type !== "turn.cancelled") {
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
return isCreditExhaustionPayload(asRecord(event.payload));
|
|
427
|
+
}
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
function sessionStatusFromEvents(events) {
|
|
431
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
432
|
+
const event = events[index];
|
|
433
|
+
if (event?.type !== "session.status.changed") {
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
const status = asRecord(event.payload).status;
|
|
437
|
+
if (isSessionStatus(status)) {
|
|
438
|
+
return status;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
function isActivityItem(item) {
|
|
444
|
+
switch (item.kind) {
|
|
445
|
+
case "reasoning":
|
|
446
|
+
case "tool-call":
|
|
447
|
+
case "worker":
|
|
448
|
+
case "sandbox":
|
|
449
|
+
case "memory":
|
|
450
|
+
case "fleet-decision":
|
|
451
|
+
return true;
|
|
452
|
+
default:
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
function groupTimeline(items) {
|
|
457
|
+
const groups = [];
|
|
458
|
+
for (const item of items) {
|
|
459
|
+
if (isActivityItem(item)) {
|
|
460
|
+
const open = groups[groups.length - 1];
|
|
461
|
+
if (open?.kind === "activity" && open.outcome === void 0) {
|
|
462
|
+
open.items.push(item);
|
|
463
|
+
} else {
|
|
464
|
+
groups.push({ kind: "activity", id: `activity-${item.id}`, items: [item] });
|
|
465
|
+
}
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
if (item.kind === "turn-end") {
|
|
469
|
+
stampTurnOutcome(groups, item);
|
|
470
|
+
foldSettledTurn(groups, item);
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
groups.push({ kind: "item", item });
|
|
474
|
+
}
|
|
475
|
+
return groups;
|
|
476
|
+
}
|
|
477
|
+
function prescanTurnAnchors(events) {
|
|
478
|
+
const ordered = [...events].sort((a, b) => a.sequence - b.sequence);
|
|
479
|
+
const queuedTurnByTrigger = /* @__PURE__ */ new Map();
|
|
480
|
+
const startSeqByTrigger = /* @__PURE__ */ new Map();
|
|
481
|
+
const cancelledTurnIds = /* @__PURE__ */ new Set();
|
|
482
|
+
const fallbackSeqByTurn = /* @__PURE__ */ new Map();
|
|
483
|
+
const startedTurnIds = /* @__PURE__ */ new Set();
|
|
484
|
+
for (const event of ordered) {
|
|
485
|
+
const payload = asRecord(event.payload);
|
|
486
|
+
const turnId = event.turnId ?? null;
|
|
487
|
+
if (event.type === "turn.queued") {
|
|
488
|
+
const triggerEventId = typeof payload.triggerEventId === "string" ? payload.triggerEventId : null;
|
|
489
|
+
const queuedTurnId = typeof payload.turnId === "string" ? payload.turnId : turnId;
|
|
490
|
+
if (triggerEventId && queuedTurnId) {
|
|
491
|
+
queuedTurnByTrigger.set(triggerEventId, queuedTurnId);
|
|
492
|
+
}
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
if (event.type === "turn.started") {
|
|
496
|
+
const triggerEventId = typeof payload.triggerEventId === "string" ? payload.triggerEventId : null;
|
|
497
|
+
if (triggerEventId && !startSeqByTrigger.has(triggerEventId)) {
|
|
498
|
+
startSeqByTrigger.set(triggerEventId, event.sequence);
|
|
499
|
+
}
|
|
500
|
+
if (turnId) {
|
|
501
|
+
startedTurnIds.add(turnId);
|
|
502
|
+
}
|
|
503
|
+
} else if (event.type === "turn.cancelled" && turnId) {
|
|
504
|
+
cancelledTurnIds.add(turnId);
|
|
505
|
+
}
|
|
506
|
+
if (turnId && isTurnExecutionEvidence(event.type)) {
|
|
507
|
+
const previous = fallbackSeqByTurn.get(turnId);
|
|
508
|
+
if (previous === void 0 || event.sequence < previous) {
|
|
509
|
+
fallbackSeqByTurn.set(turnId, event.sequence);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
if (turnId && isTurnExecutionEvidence(event.type)) {
|
|
513
|
+
startedTurnIds.add(turnId);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
for (const [triggerEventId, turnId] of queuedTurnByTrigger) {
|
|
517
|
+
if (!startSeqByTrigger.has(triggerEventId)) {
|
|
518
|
+
const fallbackSeq = fallbackSeqByTurn.get(turnId);
|
|
519
|
+
if (fallbackSeq !== void 0) {
|
|
520
|
+
startSeqByTrigger.set(triggerEventId, fallbackSeq);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
const cancelledBeforeStartTriggers = /* @__PURE__ */ new Set();
|
|
525
|
+
for (const [triggerEventId, turnId] of queuedTurnByTrigger) {
|
|
526
|
+
if (cancelledTurnIds.has(turnId) && !startSeqByTrigger.has(triggerEventId) && !fallbackSeqByTurn.has(turnId)) {
|
|
527
|
+
cancelledBeforeStartTriggers.add(triggerEventId);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return { queuedTurnByTrigger, startSeqByTrigger, cancelledBeforeStartTriggers, startedTurnIds };
|
|
531
|
+
}
|
|
532
|
+
function orderTimelineEvents(events, prescan) {
|
|
533
|
+
const ordered = [...events].sort((a, b) => a.sequence - b.sequence);
|
|
534
|
+
const insertions = /* @__PURE__ */ new Map();
|
|
535
|
+
for (const event of ordered) {
|
|
536
|
+
if (event.type !== "user.message") {
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
const queuedTurnId = prescan.queuedTurnByTrigger.get(event.id);
|
|
540
|
+
if (!queuedTurnId) {
|
|
541
|
+
pushInsertion(insertions, event.sequence, event);
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
if (prescan.cancelledBeforeStartTriggers.has(event.id)) {
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
const startSeq = prescan.startSeqByTrigger.get(event.id);
|
|
548
|
+
if (startSeq !== void 0) {
|
|
549
|
+
pushInsertion(insertions, startSeq, event);
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
const projected = [];
|
|
554
|
+
for (const event of ordered) {
|
|
555
|
+
const before = insertions.get(event.sequence);
|
|
556
|
+
if (before) {
|
|
557
|
+
projected.push(...before);
|
|
558
|
+
}
|
|
559
|
+
if (event.type !== "user.message") {
|
|
560
|
+
projected.push(event);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return projected;
|
|
564
|
+
}
|
|
565
|
+
function pushInsertion(insertions, sequence, event) {
|
|
566
|
+
const bucket = insertions.get(sequence);
|
|
567
|
+
if (bucket) {
|
|
568
|
+
bucket.push(event);
|
|
569
|
+
} else {
|
|
570
|
+
insertions.set(sequence, [event]);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
function isAgentActivityEvent(type) {
|
|
574
|
+
return type.startsWith("agent.") || type.startsWith("sandbox.");
|
|
575
|
+
}
|
|
576
|
+
function isTurnExecutionEvidence(type) {
|
|
577
|
+
return isAgentActivityEvent(type) || type === "turn.completed" || type === "turn.failed" || type === "turn.recovery.requested" || type === "turn.capacity_waiting" || type === "session.requiresAction" || type === "tool.auth_needed" || type === "credential.auth_needed" || type.startsWith("rig.setup.") || type === "codex.capacity.waiting" || type === "codex.capacity.resumed" || type === "codex.fleet.decision";
|
|
578
|
+
}
|
|
579
|
+
function turnEndItem(event, outcome, failureText) {
|
|
580
|
+
return {
|
|
581
|
+
kind: "turn-end",
|
|
582
|
+
id: `${event.id}-turn-end`,
|
|
583
|
+
turnId: event.turnId ?? null,
|
|
584
|
+
outcome,
|
|
585
|
+
failureText,
|
|
586
|
+
occurredAt: event.occurredAt
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
function hasTurnActivity(items, turnId) {
|
|
590
|
+
if (turnId) {
|
|
591
|
+
return items.some((item) => isActivityItem(item) && item.turnId === turnId);
|
|
592
|
+
}
|
|
593
|
+
for (let index = items.length - 1; index >= 0; index -= 1) {
|
|
594
|
+
const item = items[index];
|
|
595
|
+
if (!item || item.kind === "turn-end" || item.kind === "user-message") {
|
|
596
|
+
return false;
|
|
597
|
+
}
|
|
598
|
+
if (isActivityItem(item)) {
|
|
599
|
+
return true;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
function stampTurnOutcome(groups, turnEnd) {
|
|
605
|
+
if (turnEnd.turnId === null) {
|
|
606
|
+
const trailing = groups[groups.length - 1];
|
|
607
|
+
if (trailing?.kind === "activity" && trailing.outcome === void 0) {
|
|
608
|
+
applyTurnOutcome(trailing, turnEnd);
|
|
609
|
+
}
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
for (const group of groups) {
|
|
613
|
+
if (group.kind !== "activity" || group.outcome !== void 0) {
|
|
614
|
+
continue;
|
|
615
|
+
}
|
|
616
|
+
if (group.items.some((activity) => activity.turnId === turnEnd.turnId)) {
|
|
617
|
+
applyTurnOutcome(group, turnEnd);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
function applyTurnOutcome(group, turnEnd) {
|
|
622
|
+
if (turnEnd.outcome === "complete") {
|
|
623
|
+
group.outcome = "complete";
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
const hasFailed = group.items.some((item) => "status" in item && item.status === "failed");
|
|
627
|
+
const hasInterrupted = group.items.some(
|
|
628
|
+
(item) => "status" in item && item.status === "cancelled"
|
|
629
|
+
);
|
|
630
|
+
group.outcome = hasFailed ? "failed" : hasInterrupted ? "cancelled" : "complete";
|
|
631
|
+
if (turnEnd.failureText && hasFailed) {
|
|
632
|
+
group.failureText = turnEnd.failureText;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
function foldSettledTurn(groups, turnEnd) {
|
|
636
|
+
let startIndex = groups.length;
|
|
637
|
+
let stoppedAtForeignTurn = false;
|
|
638
|
+
while (startIndex > 0) {
|
|
639
|
+
const previous = groups[startIndex - 1];
|
|
640
|
+
if (isTurnBoundary(previous)) {
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
if (belongsToDifferentTurn(previous, turnEnd.turnId)) {
|
|
644
|
+
stoppedAtForeignTurn = true;
|
|
645
|
+
break;
|
|
646
|
+
}
|
|
647
|
+
startIndex -= 1;
|
|
648
|
+
}
|
|
649
|
+
if (stoppedAtForeignTurn) {
|
|
650
|
+
while (startIndex < groups.length && isBetweenTurnDivider(groups[startIndex])) {
|
|
651
|
+
startIndex += 1;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
const collected = groups.slice(startIndex);
|
|
655
|
+
if (collected.length === 0) {
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
const finalMessage = extractFinalAgentMessage(collected, turnEnd);
|
|
659
|
+
const body = finalMessage ? collected.slice(0, -1) : collected;
|
|
660
|
+
if (body.length === 0) {
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
const firstOccurredAt = groupStartedAt(body[0]) ?? turnEnd.occurredAt;
|
|
664
|
+
const turnGroup = {
|
|
665
|
+
kind: "turn",
|
|
666
|
+
id: `turn-${turnEnd.turnId ?? turnEnd.id}`,
|
|
667
|
+
outcome: turnEnd.outcome,
|
|
668
|
+
startedAt: firstOccurredAt,
|
|
669
|
+
endedAt: turnEnd.occurredAt,
|
|
670
|
+
groups: body
|
|
671
|
+
};
|
|
672
|
+
if (turnEnd.failureText) {
|
|
673
|
+
turnGroup.failureText = turnEnd.failureText;
|
|
674
|
+
}
|
|
675
|
+
groups.splice(
|
|
676
|
+
startIndex,
|
|
677
|
+
collected.length,
|
|
678
|
+
...finalMessage ? [turnGroup, finalMessage] : [turnGroup]
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
function isTurnBoundary(group) {
|
|
682
|
+
return group?.kind === "turn" || group?.kind === "item" && group.item.kind === "user-message";
|
|
683
|
+
}
|
|
684
|
+
function belongsToDifferentTurn(group, turnId) {
|
|
685
|
+
if (!group || !turnId) {
|
|
686
|
+
return false;
|
|
687
|
+
}
|
|
688
|
+
if (group.kind === "activity") {
|
|
689
|
+
return group.items.length > 0 && group.items.every((item) => item.turnId !== null && item.turnId !== turnId);
|
|
690
|
+
}
|
|
691
|
+
return group.kind === "item" && group.item.kind === "agent-message" && group.item.turnId !== null && group.item.turnId !== turnId;
|
|
692
|
+
}
|
|
693
|
+
function isBetweenTurnDivider(group) {
|
|
694
|
+
return group?.kind === "item" && group.item.kind === "session-status" && group.item.status !== "running";
|
|
695
|
+
}
|
|
696
|
+
function extractFinalAgentMessage(groups, turnEnd) {
|
|
697
|
+
const tail = groups[groups.length - 1];
|
|
698
|
+
if (tail?.kind !== "item" || tail.item.kind !== "agent-message" || tail.item.streaming) {
|
|
699
|
+
return null;
|
|
700
|
+
}
|
|
701
|
+
if (tail.item.turnId && turnEnd.turnId && tail.item.turnId !== turnEnd.turnId) {
|
|
702
|
+
return null;
|
|
703
|
+
}
|
|
704
|
+
return tail;
|
|
705
|
+
}
|
|
706
|
+
function groupStartedAt(group) {
|
|
707
|
+
if (!group) {
|
|
708
|
+
return void 0;
|
|
709
|
+
}
|
|
710
|
+
switch (group.kind) {
|
|
711
|
+
case "item":
|
|
712
|
+
return group.item.occurredAt;
|
|
713
|
+
case "activity":
|
|
714
|
+
return group.items[0]?.occurredAt;
|
|
715
|
+
case "turn":
|
|
716
|
+
return group.startedAt;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
function asRecord(value) {
|
|
720
|
+
return value !== null && typeof value === "object" ? value : {};
|
|
721
|
+
}
|
|
722
|
+
var SESSION_STATUSES = [
|
|
723
|
+
"queued",
|
|
724
|
+
"running",
|
|
725
|
+
"idle",
|
|
726
|
+
"requires_action",
|
|
727
|
+
"failed",
|
|
728
|
+
"cancelled"
|
|
729
|
+
];
|
|
730
|
+
var ATTENTION_STATUSES = /* @__PURE__ */ new Set([
|
|
731
|
+
"requires_action",
|
|
732
|
+
"failed",
|
|
733
|
+
"cancelled"
|
|
734
|
+
]);
|
|
735
|
+
function resourceRefs(value) {
|
|
736
|
+
if (!Array.isArray(value)) {
|
|
737
|
+
return [];
|
|
738
|
+
}
|
|
739
|
+
return value.filter((entry) => {
|
|
740
|
+
const record = asRecord(entry);
|
|
741
|
+
if (record.kind === "repository") {
|
|
742
|
+
return typeof record.uri === "string" && typeof record.ref === "string";
|
|
743
|
+
}
|
|
744
|
+
return record.kind === "file" && typeof record.fileId === "string";
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
function toolRefs(value) {
|
|
748
|
+
if (!Array.isArray(value)) {
|
|
749
|
+
return [];
|
|
750
|
+
}
|
|
751
|
+
return value.filter((entry) => {
|
|
752
|
+
const record = asRecord(entry);
|
|
753
|
+
return record.kind === "mcp" && typeof record.id === "string";
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
function workerCompletionPayload(value) {
|
|
757
|
+
const payload = asRecord(value);
|
|
758
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
759
|
+
if (typeof payload.childSessionId !== "string" || !uuidPattern.test(payload.childSessionId) || typeof payload.status !== "string" || payload.status.trim() === "") {
|
|
760
|
+
return null;
|
|
761
|
+
}
|
|
762
|
+
const goal = asRecord(payload.goal);
|
|
763
|
+
return {
|
|
764
|
+
childSessionId: payload.childSessionId,
|
|
765
|
+
childStatus: payload.status,
|
|
766
|
+
goalStatus: typeof goal.status === "string" ? goal.status : null,
|
|
767
|
+
goalText: typeof goal.text === "string" ? goal.text : null,
|
|
768
|
+
evidence: typeof goal.evidence === "string" ? goal.evidence : null,
|
|
769
|
+
// Console pauses and several server paths put the human explanation on
|
|
770
|
+
// `rationale`, not `pausedReason` — same fallback the goal pill uses, so a
|
|
771
|
+
// paused worker card never shows "Worker paused" with the reason missing.
|
|
772
|
+
pausedReason: typeof goal.pausedReason === "string" ? goal.pausedReason : typeof goal.rationale === "string" ? goal.rationale : null
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
function isSessionStatus(value) {
|
|
776
|
+
return typeof value === "string" && SESSION_STATUSES.includes(value);
|
|
777
|
+
}
|
|
778
|
+
function isErrorOutput(payload) {
|
|
779
|
+
if (payload.error === true || payload.failed === true) {
|
|
780
|
+
return true;
|
|
781
|
+
}
|
|
782
|
+
const output = payload.output;
|
|
783
|
+
return !!output && typeof output === "object" && output.isError === true;
|
|
784
|
+
}
|
|
785
|
+
function findOpenCall(items, callId) {
|
|
786
|
+
const reversed = [...items].reverse();
|
|
787
|
+
const isCall = (item) => item.kind === "tool-call" || item.kind === "worker";
|
|
788
|
+
if (callId) {
|
|
789
|
+
const byId = reversed.find((item) => isCall(item) && item.callId === callId);
|
|
790
|
+
if (byId) {
|
|
791
|
+
return byId;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
return reversed.find(
|
|
795
|
+
(item) => isCall(item) && item.status === "running"
|
|
796
|
+
);
|
|
797
|
+
}
|
|
798
|
+
function findOpenSandbox(items, name) {
|
|
799
|
+
return [...items].reverse().find(
|
|
800
|
+
(item) => item.kind === "sandbox" && item.name === name && item.status === "running"
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
function failureMessage(payload) {
|
|
804
|
+
for (const key of ["error", "message"]) {
|
|
805
|
+
const value = payload[key];
|
|
806
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
807
|
+
return humanizeFailureReason(value);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
function goalText(payload) {
|
|
813
|
+
if (typeof payload.text === "string" && payload.text) {
|
|
814
|
+
return payload.text;
|
|
815
|
+
}
|
|
816
|
+
const goal = asRecord(payload.goal);
|
|
817
|
+
if (typeof goal.text === "string" && goal.text) {
|
|
818
|
+
return goal.text;
|
|
819
|
+
}
|
|
820
|
+
if (typeof payload.prompt === "string" && payload.prompt) {
|
|
821
|
+
return payload.prompt;
|
|
822
|
+
}
|
|
823
|
+
return null;
|
|
824
|
+
}
|
|
825
|
+
function memoryItem(id, type, turnId, payload, occurredAt) {
|
|
826
|
+
const memoryId = typeof payload.memoryId === "string" && payload.memoryId ? payload.memoryId : null;
|
|
827
|
+
if (!memoryId) {
|
|
828
|
+
return null;
|
|
829
|
+
}
|
|
830
|
+
const replacementPreview = typeof payload.replacementPreview === "string" ? payload.replacementPreview : void 0;
|
|
831
|
+
const replacementMemoryId = typeof payload.replacementMemoryId === "string" ? payload.replacementMemoryId : void 0;
|
|
832
|
+
const action = typeof payload.action === "string" ? payload.action : void 0;
|
|
833
|
+
return {
|
|
834
|
+
kind: "memory",
|
|
835
|
+
id,
|
|
836
|
+
turnId,
|
|
837
|
+
variant: type === "memory.corrected" ? "corrected" : "saved",
|
|
838
|
+
memoryKind: typeof payload.kind === "string" ? payload.kind : "",
|
|
839
|
+
preview: typeof payload.preview === "string" ? payload.preview : "",
|
|
840
|
+
...payload.deduped === true ? { deduped: true } : {},
|
|
841
|
+
...replacementPreview ? { replacementPreview } : {},
|
|
842
|
+
...action ? { action } : {},
|
|
843
|
+
memoryId,
|
|
844
|
+
...replacementMemoryId ? { replacementMemoryId } : {},
|
|
845
|
+
occurredAt
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
var AUTH_NEEDED_REASONS = /* @__PURE__ */ new Set([
|
|
849
|
+
"missing_connection",
|
|
850
|
+
"expired",
|
|
851
|
+
"insufficient_scope",
|
|
852
|
+
"refresh_failed",
|
|
853
|
+
"unsupported_auth",
|
|
854
|
+
"resource_scope_unavailable"
|
|
855
|
+
]);
|
|
856
|
+
function authNeededReason(value) {
|
|
857
|
+
return typeof value === "string" && AUTH_NEEDED_REASONS.has(value) ? value : null;
|
|
858
|
+
}
|
|
859
|
+
function stringList(value) {
|
|
860
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
|
|
861
|
+
}
|
|
862
|
+
function reasoningText(payload) {
|
|
863
|
+
const record = asRecord(payload);
|
|
864
|
+
if (typeof record.text === "string") {
|
|
865
|
+
return record.text;
|
|
866
|
+
}
|
|
867
|
+
const content = asRecord(asRecord(record.item).rawItem).content;
|
|
868
|
+
if (!Array.isArray(content)) {
|
|
869
|
+
return "";
|
|
870
|
+
}
|
|
871
|
+
return content.map((part) => {
|
|
872
|
+
const text = asRecord(part).text;
|
|
873
|
+
return typeof text === "string" ? text : "";
|
|
874
|
+
}).join("");
|
|
875
|
+
}
|
|
876
|
+
function workerPrompt(args) {
|
|
877
|
+
const record = asRecord(typeof args === "string" ? tryParseJson(args) : args);
|
|
878
|
+
for (const key of ["initialMessage", "message", "text", "prompt"]) {
|
|
879
|
+
const value = record[key];
|
|
880
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
881
|
+
return value;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
return null;
|
|
885
|
+
}
|
|
886
|
+
function extractSessionRef(value, depth = 0) {
|
|
887
|
+
if (depth > 6 || value === null || value === void 0) {
|
|
888
|
+
return null;
|
|
889
|
+
}
|
|
890
|
+
if (typeof value === "string") {
|
|
891
|
+
return extractSessionRef(tryParseJson(value), depth + 1);
|
|
892
|
+
}
|
|
893
|
+
if (Array.isArray(value)) {
|
|
894
|
+
for (const entry of value) {
|
|
895
|
+
const found = extractSessionRef(entry, depth + 1);
|
|
896
|
+
if (found) {
|
|
897
|
+
return found;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
return null;
|
|
901
|
+
}
|
|
902
|
+
if (typeof value !== "object") {
|
|
903
|
+
return null;
|
|
904
|
+
}
|
|
905
|
+
const record = value;
|
|
906
|
+
if (typeof record.sessionId === "string" && looksLikeId(record.sessionId)) {
|
|
907
|
+
return record.sessionId;
|
|
908
|
+
}
|
|
909
|
+
if (typeof record.id === "string" && looksLikeId(record.id) && ("status" in record || "workspaceId" in record || "initialMessage" in record)) {
|
|
910
|
+
return record.id;
|
|
911
|
+
}
|
|
912
|
+
for (const key of ["structuredContent", "session", "result", "content"]) {
|
|
913
|
+
if (key in record) {
|
|
914
|
+
const found = extractSessionRef(record[key], depth + 1);
|
|
915
|
+
if (found) {
|
|
916
|
+
return found;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
if (typeof record.text === "string") {
|
|
921
|
+
return extractSessionRef(tryParseJson(record.text), depth + 1);
|
|
922
|
+
}
|
|
923
|
+
return null;
|
|
924
|
+
}
|
|
925
|
+
function looksLikeId(value) {
|
|
926
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
export {
|
|
930
|
+
toolDisplayName,
|
|
931
|
+
buildTimeline,
|
|
932
|
+
creditExhaustedFromEvents,
|
|
933
|
+
sessionStatusFromEvents,
|
|
934
|
+
groupTimeline,
|
|
935
|
+
extractSessionRef
|
|
936
|
+
};
|
|
937
|
+
//# sourceMappingURL=chunk-OZDLELJQ.js.map
|