@fragno-dev/pi-harness 0.0.0-stage → 0.0.3

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.
Files changed (140) hide show
  1. package/LICENSE.md +16 -0
  2. package/README.md +181 -2
  3. package/dist/browser/agent-harness-event-protocol-CuKubox1.js +666 -0
  4. package/dist/browser/agent-harness-event-protocol-CuKubox1.js.map +1 -0
  5. package/dist/browser/agent-harness-event-protocol-d6mH_9n3.d.ts +261 -0
  6. package/dist/browser/agent-harness-event-protocol-d6mH_9n3.d.ts.map +1 -0
  7. package/dist/browser/client/clients.d.ts +2 -0
  8. package/dist/browser/client/clients.js +2 -0
  9. package/dist/browser/client/pi-workflow-emission-stream.d.ts +13 -0
  10. package/dist/browser/client/pi-workflow-emission-stream.d.ts.map +1 -0
  11. package/dist/browser/client/pi-workflow-emission-stream.js +29 -0
  12. package/dist/browser/client/pi-workflow-emission-stream.js.map +1 -0
  13. package/dist/browser/client/react.d.ts +147 -0
  14. package/dist/browser/client/react.d.ts.map +1 -0
  15. package/dist/browser/client/react.js +187 -0
  16. package/dist/browser/client/react.js.map +1 -0
  17. package/dist/browser/client/solid.d.ts +150 -0
  18. package/dist/browser/client/solid.d.ts.map +1 -0
  19. package/dist/browser/client/solid.js +130 -0
  20. package/dist/browser/client/solid.js.map +1 -0
  21. package/dist/browser/client/svelte.d.ts +150 -0
  22. package/dist/browser/client/svelte.d.ts.map +1 -0
  23. package/dist/browser/client/svelte.js +132 -0
  24. package/dist/browser/client/svelte.js.map +1 -0
  25. package/dist/browser/client/vanilla.d.ts +177 -0
  26. package/dist/browser/client/vanilla.d.ts.map +1 -0
  27. package/dist/browser/client/vanilla.js +159 -0
  28. package/dist/browser/client/vanilla.js.map +1 -0
  29. package/dist/browser/client/vue.d.ts +150 -0
  30. package/dist/browser/client/vue.d.ts.map +1 -0
  31. package/dist/browser/client/vue.js +128 -0
  32. package/dist/browser/client/vue.js.map +1 -0
  33. package/dist/browser/client/workflow-lofi-session-projection.d.ts +17 -0
  34. package/dist/browser/client/workflow-lofi-session-projection.d.ts.map +1 -0
  35. package/dist/browser/client/workflow-lofi-session-projection.js +107 -0
  36. package/dist/browser/client/workflow-lofi-session-projection.js.map +1 -0
  37. package/dist/browser/clients-DYXj19je.d.ts +247 -0
  38. package/dist/browser/clients-DYXj19je.d.ts.map +1 -0
  39. package/dist/browser/clients-pIAk6ClP.js +1853 -0
  40. package/dist/browser/clients-pIAk6ClP.js.map +1 -0
  41. package/dist/browser/pi/context-usage.d.ts +20 -0
  42. package/dist/browser/pi/context-usage.d.ts.map +1 -0
  43. package/dist/browser/pi/context-usage.js +84 -0
  44. package/dist/browser/pi/context-usage.js.map +1 -0
  45. package/dist/browser/pi/harness/agent-harness-event-protocol.d.ts +2 -0
  46. package/dist/browser/pi/harness/agent-harness-event-protocol.js +2 -0
  47. package/dist/browser/pi/route-schemas.d.ts +2 -0
  48. package/dist/browser/pi/route-schemas.js +130 -0
  49. package/dist/browser/pi/route-schemas.js.map +1 -0
  50. package/dist/browser/pi/workflow-session-projection.d.ts +2 -0
  51. package/dist/browser/pi/workflow-session-projection.js +2 -0
  52. package/dist/browser/route-schemas-DQB5ZR1E.d.ts +109 -0
  53. package/dist/browser/route-schemas-DQB5ZR1E.d.ts.map +1 -0
  54. package/dist/browser/types-8q4RWFXT.js +23 -0
  55. package/dist/browser/types-8q4RWFXT.js.map +1 -0
  56. package/dist/browser/types-Dk856kV1.d.ts +527 -0
  57. package/dist/browser/types-Dk856kV1.d.ts.map +1 -0
  58. package/dist/browser/workflow-session-projection-CJ4MUkpJ.js +443 -0
  59. package/dist/browser/workflow-session-projection-CJ4MUkpJ.js.map +1 -0
  60. package/dist/browser/workflow-session-projection-Dj_a79GF.d.ts +93 -0
  61. package/dist/browser/workflow-session-projection-Dj_a79GF.d.ts.map +1 -0
  62. package/dist/node/pi/compact-command-outcome-projection.js +41 -0
  63. package/dist/node/pi/compact-command-outcome-projection.js.map +1 -0
  64. package/dist/node/pi/context-usage.d.ts +20 -0
  65. package/dist/node/pi/context-usage.d.ts.map +1 -0
  66. package/dist/node/pi/context-usage.js +84 -0
  67. package/dist/node/pi/context-usage.js.map +1 -0
  68. package/dist/node/pi/definition.d.ts +535 -0
  69. package/dist/node/pi/definition.d.ts.map +1 -0
  70. package/dist/node/pi/definition.js +71 -0
  71. package/dist/node/pi/definition.js.map +1 -0
  72. package/dist/node/pi/factory.d.ts +142 -0
  73. package/dist/node/pi/factory.d.ts.map +1 -0
  74. package/dist/node/pi/factory.js +22 -0
  75. package/dist/node/pi/factory.js.map +1 -0
  76. package/dist/node/pi/harness/agent-harness-event-protocol.d.ts +261 -0
  77. package/dist/node/pi/harness/agent-harness-event-protocol.d.ts.map +1 -0
  78. package/dist/node/pi/harness/agent-harness-event-protocol.js +588 -0
  79. package/dist/node/pi/harness/agent-harness-event-protocol.js.map +1 -0
  80. package/dist/node/pi/harness/json-value.js +82 -0
  81. package/dist/node/pi/harness/json-value.js.map +1 -0
  82. package/dist/node/pi/harness/pi-operation-completed.d.ts +16 -0
  83. package/dist/node/pi/harness/pi-operation-completed.d.ts.map +1 -0
  84. package/dist/node/pi/harness/pi-operation-completed.js +71 -0
  85. package/dist/node/pi/harness/pi-operation-completed.js.map +1 -0
  86. package/dist/node/pi/harness/session-storage.d.ts +62 -0
  87. package/dist/node/pi/harness/session-storage.d.ts.map +1 -0
  88. package/dist/node/pi/harness/session-storage.js +174 -0
  89. package/dist/node/pi/harness/session-storage.js.map +1 -0
  90. package/dist/node/pi/pi-jsonl-export.d.ts +11 -0
  91. package/dist/node/pi/pi-jsonl-export.d.ts.map +1 -0
  92. package/dist/node/pi/pi-jsonl-export.js +31 -0
  93. package/dist/node/pi/pi-jsonl-export.js.map +1 -0
  94. package/dist/node/pi/route-schemas.d.ts +109 -0
  95. package/dist/node/pi/route-schemas.d.ts.map +1 -0
  96. package/dist/node/pi/route-schemas.js +130 -0
  97. package/dist/node/pi/route-schemas.js.map +1 -0
  98. package/dist/node/pi/session-command-protocol.d.ts +14 -0
  99. package/dist/node/pi/session-command-protocol.d.ts.map +1 -0
  100. package/dist/node/pi/session-command-protocol.js +25 -0
  101. package/dist/node/pi/session-command-protocol.js.map +1 -0
  102. package/dist/node/pi/session-entry-projection.js +79 -0
  103. package/dist/node/pi/session-entry-projection.js.map +1 -0
  104. package/dist/node/pi/skills.d.ts +70 -0
  105. package/dist/node/pi/skills.d.ts.map +1 -0
  106. package/dist/node/pi/skills.js +150 -0
  107. package/dist/node/pi/skills.js.map +1 -0
  108. package/dist/node/pi/tools.d.ts +12 -0
  109. package/dist/node/pi/tools.d.ts.map +1 -0
  110. package/dist/node/pi/tools.js +8 -0
  111. package/dist/node/pi/tools.js.map +1 -0
  112. package/dist/node/pi/types.d.ts +165 -0
  113. package/dist/node/pi/types.d.ts.map +1 -0
  114. package/dist/node/pi/types.js +49 -0
  115. package/dist/node/pi/types.js.map +1 -0
  116. package/dist/node/pi/wait-for-command-step.js +46 -0
  117. package/dist/node/pi/wait-for-command-step.js.map +1 -0
  118. package/dist/node/pi/workflow-session-live-projection.js +220 -0
  119. package/dist/node/pi/workflow-session-live-projection.js.map +1 -0
  120. package/dist/node/pi/workflow-session-projection.d.ts +84 -0
  121. package/dist/node/pi/workflow-session-projection.d.ts.map +1 -0
  122. package/dist/node/pi/workflow-session-projection.js +100 -0
  123. package/dist/node/pi/workflow-session-projection.js.map +1 -0
  124. package/dist/node/pi/workflows/interactive-chat-workflow.d.ts +37 -0
  125. package/dist/node/pi/workflows/interactive-chat-workflow.d.ts.map +1 -0
  126. package/dist/node/pi/workflows/interactive-chat-workflow.js +219 -0
  127. package/dist/node/pi/workflows/interactive-chat-workflow.js.map +1 -0
  128. package/dist/node/pi/workflows/workflow-agent-harness.d.ts +142 -0
  129. package/dist/node/pi/workflows/workflow-agent-harness.d.ts.map +1 -0
  130. package/dist/node/pi/workflows/workflow-agent-harness.js +450 -0
  131. package/dist/node/pi/workflows/workflow-agent-harness.js.map +1 -0
  132. package/dist/node/routes.d.ts +631 -0
  133. package/dist/node/routes.d.ts.map +1 -0
  134. package/dist/node/routes.js +355 -0
  135. package/dist/node/routes.js.map +1 -0
  136. package/dist/node/schema.d.ts +5 -0
  137. package/dist/node/schema.d.ts.map +1 -0
  138. package/dist/node/schema.js +7 -0
  139. package/dist/node/schema.js.map +1 -0
  140. package/package.json +175 -3
@@ -0,0 +1,443 @@
1
+ import { r as PiSessionDataIntegrityError } from "./types-8q4RWFXT.js";
2
+ import { a as piToolCallArgumentsText, r as PiHarnessEventStreamDecoders } from "./agent-harness-event-protocol-CuKubox1.js";
3
+ import { z } from "zod";
4
+ import { buildSessionContext } from "@earendil-works/pi-agent-core";
5
+ //#region src/pi/session-entry-projection.ts
6
+ const dataIntegrityError = (identity, message, cause) => new PiSessionDataIntegrityError(identity.workflowName, identity.sessionId, new Error(message, cause === void 0 ? void 0 : { cause }));
7
+ /**
8
+ * Workflow history exposes step results as `unknown`, but harness-run results are written by
9
+ * `withWorkflowAgentHarness`. This is the single trust boundary for that internally owned data.
10
+ */
11
+ const asPersistedPiHarnessStepResult = (value) => {
12
+ const result = value;
13
+ return result?.type === "harness-run" ? result : null;
14
+ };
15
+ const mergePiSessionEntries = (...entryGroups) => {
16
+ const entries = [];
17
+ const indexes = /* @__PURE__ */ new Map();
18
+ for (const entryGroup of entryGroups) for (const entry of entryGroup) {
19
+ const index = indexes.get(entry.id);
20
+ if (index === void 0) {
21
+ indexes.set(entry.id, entries.length);
22
+ entries.push(entry);
23
+ } else entries[index] = entry;
24
+ }
25
+ return entries;
26
+ };
27
+ const latestCompletedPiHarnessEntries = (steps) => mergePiSessionEntries(...steps.flatMap((step) => {
28
+ if (step.status !== "completed") return [];
29
+ const result = asPersistedPiHarnessStepResult(step.result);
30
+ return result ? [result.appendedEntries] : [];
31
+ }));
32
+ const resolveActiveSessionPath = (entries, identity) => {
33
+ let leafId = null;
34
+ for (const entry of entries) leafId = entry.type === "leaf" ? entry.targetId : entry.id;
35
+ if (leafId === null) return [];
36
+ const entriesById = /* @__PURE__ */ new Map();
37
+ for (const entry of entries) {
38
+ if (entriesById.has(entry.id)) throw dataIntegrityError(identity, `Pi session tree contains duplicate entry ${entry.id}.`);
39
+ entriesById.set(entry.id, entry);
40
+ }
41
+ const reversePath = [];
42
+ const visitedEntryIds = /* @__PURE__ */ new Set();
43
+ let currentId = leafId;
44
+ while (currentId !== null) {
45
+ if (visitedEntryIds.has(currentId)) throw dataIntegrityError(identity, `Pi session tree contains a parent cycle at ${currentId}.`);
46
+ visitedEntryIds.add(currentId);
47
+ const entry = entriesById.get(currentId);
48
+ if (!entry) throw dataIntegrityError(identity, `Pi session tree references missing entry ${currentId}.`);
49
+ reversePath.push(entry);
50
+ currentId = entry.parentId;
51
+ }
52
+ return reversePath.reverse();
53
+ };
54
+ const projectPiSessionEntries = (entries, identity, options = {}) => {
55
+ const activePath = resolveActiveSessionPath(entries, identity);
56
+ let contextMessages;
57
+ try {
58
+ contextMessages = buildSessionContext(activePath).messages;
59
+ } catch (error) {
60
+ throw dataIntegrityError(identity, "Pi session entries cannot build a valid context.", error);
61
+ }
62
+ const timelineMessages = [...options.timelineMessagesAfterEntryId?.get(null) ?? []];
63
+ for (const entry of activePath) {
64
+ if (entry.type === "message") timelineMessages.push(entry.message);
65
+ else if (entry.type === "compaction") timelineMessages.push({
66
+ role: "compactionSummary",
67
+ summary: entry.summary,
68
+ tokensBefore: entry.tokensBefore,
69
+ timestamp: new Date(entry.timestamp).getTime()
70
+ });
71
+ timelineMessages.push(...options.timelineMessagesAfterEntryId?.get(entry.id) ?? []);
72
+ }
73
+ return {
74
+ contextMessages,
75
+ timelineMessages
76
+ };
77
+ };
78
+ //#endregion
79
+ //#region src/pi/compact-command-outcome-projection.ts
80
+ const compactCommandOutcomeSchema = z.discriminatedUnion("status", [z.object({
81
+ kind: z.literal("compact"),
82
+ commandId: z.string(),
83
+ status: z.literal("succeeded")
84
+ }), z.object({
85
+ kind: z.literal("compact"),
86
+ commandId: z.string(),
87
+ status: z.literal("rejected"),
88
+ code: z.enum(["nothing_to_compact", "compaction_failed"]),
89
+ message: z.string()
90
+ })]);
91
+ const parseCompactCommandOutcome = (value, identity) => {
92
+ if (typeof value !== "object" || value === null || value.kind !== "compact") return null;
93
+ const outcome = compactCommandOutcomeSchema.safeParse(value);
94
+ if (!outcome.success) throw new PiSessionDataIntegrityError(identity.workflowName, identity.sessionId, new Error("Persisted Pi compact command outcome is invalid.", { cause: outcome.error }));
95
+ return outcome.data;
96
+ };
97
+ const projectPiCompactCommandOutcomes = (steps, identity) => {
98
+ const byCommandId = {};
99
+ let latestCommandCompactOutcome = null;
100
+ for (const step of steps) {
101
+ if (step.status !== "completed" || !step.stepKey.startsWith("command:")) continue;
102
+ const result = asPersistedPiHarnessStepResult(step.result);
103
+ if (!result) throw new PiSessionDataIntegrityError(identity.workflowName, identity.sessionId, /* @__PURE__ */ new Error(`Pi command step ${step.stepKey} does not contain a harness result.`));
104
+ if (result.outcome !== "completed") continue;
105
+ latestCommandCompactOutcome = parseCompactCommandOutcome(result.value, identity);
106
+ if (latestCommandCompactOutcome) byCommandId[latestCommandCompactOutcome.commandId] = latestCommandCompactOutcome;
107
+ }
108
+ return {
109
+ byCommandId,
110
+ latestCommandCompactOutcome
111
+ };
112
+ };
113
+ //#endregion
114
+ //#region src/pi/workflow-session-live-projection.ts
115
+ const isPiWorkflowStepActive = (step) => step.status !== "completed" && !(step.status === "waiting" && step.type === "waitForEvent" && step.waitEventType === "command");
116
+ const createPiWorkflowSessionLiveState = (activeLiveWork = false) => ({
117
+ inFlightMessagesByStepKey: /* @__PURE__ */ new Map(),
118
+ inFlightStepKeys: [],
119
+ draftAgentMessage: null,
120
+ activeCommand: null,
121
+ hasOpenMessageDraft: false,
122
+ activeLiveWork
123
+ });
124
+ const draftActivityForAssistantEvent = (type) => {
125
+ if (type === "start") return "starting";
126
+ if (type.startsWith("thinking_")) return "thinking";
127
+ if (type.startsWith("toolcall_")) return "tool_calling";
128
+ if (type.startsWith("text_")) return "writing";
129
+ return null;
130
+ };
131
+ const updateDraftTool = (tools, toolCall) => {
132
+ const argsText = piToolCallArgumentsText(toolCall);
133
+ tools[toolCall.id] = {
134
+ ...tools[toolCall.id],
135
+ id: toolCall.id,
136
+ name: toolCall.name,
137
+ args: toolCall.arguments,
138
+ ...argsText === void 0 ? {} : { argsText },
139
+ status: tools[toolCall.id]?.status ?? "starting"
140
+ };
141
+ };
142
+ const ensureDraftAgentMessage = (state, emission) => {
143
+ const eventTime = new Date(emission.createdAt).getTime();
144
+ if (!Number.isFinite(eventTime)) throw new Error(`Pi workflow emission ${emission.stepKey} has an invalid timestamp.`);
145
+ state.draftStepKey = emission.stepKey;
146
+ if (!state.draftAgentMessage) state.draftAgentMessage = {
147
+ activity: "starting",
148
+ tools: {},
149
+ startedAt: eventTime,
150
+ updatedAt: eventTime
151
+ };
152
+ else state.draftAgentMessage.updatedAt = eventTime;
153
+ return state.draftAgentMessage;
154
+ };
155
+ const recordInFlightMessage = (state, stepKey, message) => {
156
+ let messages = state.inFlightMessagesByStepKey.get(stepKey);
157
+ if (!messages) {
158
+ messages = [];
159
+ state.inFlightMessagesByStepKey.set(stepKey, messages);
160
+ state.inFlightStepKeys.push(stepKey);
161
+ }
162
+ messages.push(message);
163
+ };
164
+ const createPiWorkflowSessionEmissionReducer = (activeLiveWork = false) => ({
165
+ live: createPiWorkflowSessionLiveState(activeLiveWork),
166
+ eventDecoders: new PiHarnessEventStreamDecoders()
167
+ });
168
+ const reducePiWorkflowSessionEmission = (reducer, emission) => {
169
+ const state = reducer.live;
170
+ const payload = emission.payload;
171
+ if (!payload?.kind) return;
172
+ state.activeLiveWork = true;
173
+ if (payload.kind === "harness-operation-start") {
174
+ if (!emission.executionId || !emission.epoch) throw new Error(`Pi workflow emission ${emission.stepKey} is missing its stream identity.`);
175
+ reducer.eventDecoders.start({
176
+ stepKey: emission.stepKey,
177
+ executionId: emission.executionId,
178
+ epoch: emission.epoch
179
+ });
180
+ return;
181
+ }
182
+ if (payload.kind === "pi-session-command-start") {
183
+ state.activeCommand = payload.command;
184
+ state.activeCommandStepKey = emission.stepKey;
185
+ return;
186
+ }
187
+ if (payload.kind === "harness-operation-complete") {
188
+ if (!emission.executionId || !emission.epoch) throw new Error(`Pi workflow emission ${emission.stepKey} is missing its stream identity.`);
189
+ reducer.eventDecoders.finish({
190
+ stepKey: emission.stepKey,
191
+ executionId: emission.executionId,
192
+ epoch: emission.epoch
193
+ });
194
+ return;
195
+ }
196
+ if (payload.kind !== "harness-event") return;
197
+ if (!emission.executionId || !emission.epoch) throw new Error(`Pi workflow emission ${emission.stepKey} is missing its stream identity.`);
198
+ const event = reducer.eventDecoders.decode({
199
+ stepKey: emission.stepKey,
200
+ executionId: emission.executionId,
201
+ epoch: emission.epoch
202
+ }, payload.event);
203
+ const draft = ensureDraftAgentMessage(state, emission);
204
+ switch (event.type) {
205
+ case "message_start":
206
+ draft.activity = "starting";
207
+ if (event.message.role === "assistant") {
208
+ draft.assistant = void 0;
209
+ draft.tools = {};
210
+ state.currentAssistantMessage = {
211
+ ...event.message,
212
+ content: [...event.message.content]
213
+ };
214
+ }
215
+ state.hasOpenMessageDraft = true;
216
+ return;
217
+ case "message_update": {
218
+ state.hasOpenMessageDraft = true;
219
+ if (event.message.role !== "assistant") throw new Error("Pi harness message_update did not contain an assistant message.");
220
+ const assistantMessage = structuredClone(event.message);
221
+ state.currentAssistantMessage = assistantMessage;
222
+ draft.assistant = assistantMessage;
223
+ const activity = draftActivityForAssistantEvent(event.assistantMessageEvent.type);
224
+ if (activity) draft.activity = activity;
225
+ if ("contentIndex" in event.assistantMessageEvent) {
226
+ const toolCall = assistantMessage.content[event.assistantMessageEvent.contentIndex];
227
+ if (toolCall?.type === "toolCall") updateDraftTool(draft.tools, toolCall);
228
+ }
229
+ return;
230
+ }
231
+ case "message_end":
232
+ recordInFlightMessage(state, emission.stepKey, event.message);
233
+ if (event.message.role === "assistant") {
234
+ state.currentAssistantMessage = event.message;
235
+ draft.assistant = event.message;
236
+ } else if (event.message.role === "toolResult") draft.tools[event.message.toolCallId] = {
237
+ ...draft.tools[event.message.toolCallId],
238
+ id: event.message.toolCallId,
239
+ name: event.message.toolName,
240
+ args: draft.tools[event.message.toolCallId]?.args,
241
+ resultMessage: event.message,
242
+ status: "done"
243
+ };
244
+ state.hasOpenMessageDraft = false;
245
+ return;
246
+ case "tool_execution_start":
247
+ draft.activity = "running_tools";
248
+ draft.tools[event.toolCallId] = {
249
+ ...draft.tools[event.toolCallId],
250
+ id: event.toolCallId,
251
+ name: event.toolName,
252
+ args: event.args,
253
+ status: "running"
254
+ };
255
+ return;
256
+ case "tool_execution_update":
257
+ draft.activity = "running_tools";
258
+ draft.tools[event.toolCallId] = {
259
+ ...draft.tools[event.toolCallId],
260
+ id: event.toolCallId,
261
+ name: event.toolName,
262
+ args: event.args,
263
+ partialResult: event.partialResult,
264
+ status: "running"
265
+ };
266
+ return;
267
+ case "tool_execution_end":
268
+ draft.tools[event.toolCallId] = {
269
+ ...draft.tools[event.toolCallId],
270
+ id: event.toolCallId,
271
+ name: event.toolName,
272
+ args: draft.tools[event.toolCallId]?.args,
273
+ result: event.result,
274
+ isError: event.isError,
275
+ status: "done"
276
+ };
277
+ return;
278
+ case "abort":
279
+ case "after_provider_response":
280
+ case "agent_end":
281
+ case "agent_start":
282
+ case "before_agent_start":
283
+ case "before_provider_payload":
284
+ case "before_provider_request":
285
+ case "context":
286
+ case "model_update":
287
+ case "queue_update":
288
+ case "resources_update":
289
+ case "retry_attempt_start":
290
+ case "retry_finished":
291
+ case "retry_scheduled":
292
+ case "save_point":
293
+ case "session_before_compact":
294
+ case "session_before_tree":
295
+ case "session_compact":
296
+ case "session_tree":
297
+ case "settled":
298
+ case "thinking_level_update":
299
+ case "tool_call":
300
+ case "tool_result":
301
+ case "tools_update":
302
+ case "turn_end":
303
+ case "turn_start": return;
304
+ }
305
+ };
306
+ const settleCompletedPiWorkflowSessionLiveSteps = (state, completedStepKeys) => {
307
+ state.inFlightStepKeys = state.inFlightStepKeys.filter((stepKey) => {
308
+ if (!completedStepKeys.has(stepKey)) return true;
309
+ state.inFlightMessagesByStepKey.delete(stepKey);
310
+ return false;
311
+ });
312
+ if (state.draftStepKey && completedStepKeys.has(state.draftStepKey)) {
313
+ state.draftAgentMessage = null;
314
+ state.currentAssistantMessage = void 0;
315
+ state.draftStepKey = void 0;
316
+ state.hasOpenMessageDraft = false;
317
+ }
318
+ if (state.activeCommandStepKey && completedStepKeys.has(state.activeCommandStepKey)) {
319
+ state.activeCommand = null;
320
+ state.activeCommandStepKey = void 0;
321
+ }
322
+ };
323
+ const projectPiWorkflowSessionLiveOverlay = ({ contextMessages: durableContextMessages, timelineMessages: durableTimelineMessages, instanceStatus, workflowSteps, live }) => {
324
+ const contextMessages = [...durableContextMessages];
325
+ const timelineMessages = [...durableTimelineMessages];
326
+ for (const stepKey of live.inFlightStepKeys) {
327
+ const messages = live.inFlightMessagesByStepKey.get(stepKey) ?? [];
328
+ contextMessages.push(...messages);
329
+ timelineMessages.push(...messages);
330
+ }
331
+ const liveTools = Object.values(live.draftAgentMessage?.tools ?? {});
332
+ const hasLiveTools = liveTools.some((tool) => tool.status !== "done");
333
+ const draftAgentMessage = live.draftAgentMessage && (live.hasOpenMessageDraft || liveTools.length > 0) ? live.draftAgentMessage : null;
334
+ const waitingForCommand = workflowSteps.some((step) => step.status === "waiting" && step.type === "waitForEvent" && step.waitEventType === "command");
335
+ const readyForInput = (instanceStatus === "active" || instanceStatus === "waiting") && !live.hasOpenMessageDraft && !hasLiveTools && (!live.activeLiveWork || waitingForCommand);
336
+ const activity = draftAgentMessage && (live.hasOpenMessageDraft || hasLiveTools) ? draftAgentMessage.activity : live.activeLiveWork && !readyForInput ? "working" : null;
337
+ return {
338
+ contextMessages,
339
+ timelineMessages,
340
+ draftAgentMessage,
341
+ activeCommand: live.activeCommand,
342
+ readyForInput,
343
+ activity
344
+ };
345
+ };
346
+ //#endregion
347
+ //#region src/pi/workflow-session-projection.ts
348
+ const zeroUsage = () => ({
349
+ input: 0,
350
+ output: 0,
351
+ cacheRead: 0,
352
+ cacheWrite: 0,
353
+ totalTokens: 0,
354
+ cost: {
355
+ input: 0,
356
+ output: 0,
357
+ cacheRead: 0,
358
+ cacheWrite: 0,
359
+ total: 0
360
+ }
361
+ });
362
+ const interruptionTimestamp = (entry) => {
363
+ if (!entry) return 0;
364
+ if (entry.type === "message") return entry.message.timestamp;
365
+ const timestamp = new Date(entry.timestamp).getTime();
366
+ return Number.isFinite(timestamp) ? timestamp : 0;
367
+ };
368
+ const interruptedTimelineMessages = (steps, sessionEntries) => {
369
+ const entriesById = new Map(sessionEntries.map((entry) => [entry.id, entry]));
370
+ const messagesByLeafId = /* @__PURE__ */ new Map();
371
+ for (const step of steps) {
372
+ if (step.status !== "completed") continue;
373
+ const result = asPersistedPiHarnessStepResult(step.result);
374
+ if (result?.outcome !== "aborted") continue;
375
+ const leafEntry = result.leafId === null ? void 0 : entriesById.get(result.leafId);
376
+ if (leafEntry?.type === "message" && leafEntry.message.role === "assistant" && leafEntry.message.stopReason === "aborted") continue;
377
+ const messages = messagesByLeafId.get(result.leafId) ?? [];
378
+ messages.push({
379
+ role: "assistant",
380
+ content: [],
381
+ usage: zeroUsage(),
382
+ stopReason: "aborted",
383
+ timestamp: interruptionTimestamp(leafEntry)
384
+ });
385
+ messagesByLeafId.set(result.leafId, messages);
386
+ }
387
+ return messagesByLeafId;
388
+ };
389
+ const emptyProjectionData = () => ({
390
+ contextMessages: [],
391
+ timelineMessages: [],
392
+ completedStepKeys: [],
393
+ draftAgentMessage: null,
394
+ activeCommand: null,
395
+ compactOutcomesByCommandId: {},
396
+ latestCommandCompactOutcome: null
397
+ });
398
+ const createLoadingPiWorkflowSessionProjection = () => ({
399
+ ...emptyProjectionData(),
400
+ status: "loading",
401
+ error: null,
402
+ readyForInput: false,
403
+ activity: null
404
+ });
405
+ const projectPiWorkflowSession = ({ workflowName, sessionId, instance, workflowSteps, workflowStepEmissions = [] }) => {
406
+ const identity = {
407
+ workflowName,
408
+ sessionId
409
+ };
410
+ const completedSteps = workflowSteps.filter((step) => step.status === "completed");
411
+ const completedStepKeys = new Set(completedSteps.map((step) => step.stepKey));
412
+ const sessionEntries = latestCompletedPiHarnessEntries(completedSteps);
413
+ const projectedEntries = projectPiSessionEntries(sessionEntries, identity, { timelineMessagesAfterEntryId: interruptedTimelineMessages(completedSteps, sessionEntries) });
414
+ if (instance === null) return {
415
+ ...emptyProjectionData(),
416
+ ...projectedEntries,
417
+ completedStepKeys: [...completedStepKeys],
418
+ status: "not-found",
419
+ error: /* @__PURE__ */ new Error(`Pi session ${workflowName}/${sessionId} was not found.`),
420
+ readyForInput: false,
421
+ activity: null
422
+ };
423
+ const compactCommandOutcomes = projectPiCompactCommandOutcomes(workflowSteps, identity);
424
+ const emissionReducer = createPiWorkflowSessionEmissionReducer(workflowSteps.some(isPiWorkflowStepActive));
425
+ for (const emission of workflowStepEmissions) if (!completedStepKeys.has(emission.stepKey)) reducePiWorkflowSessionEmission(emissionReducer, emission);
426
+ return {
427
+ ...projectPiWorkflowSessionLiveOverlay({
428
+ ...projectedEntries,
429
+ instanceStatus: instance.status,
430
+ workflowSteps,
431
+ live: emissionReducer.live
432
+ }),
433
+ status: "ready",
434
+ error: null,
435
+ completedStepKeys: [...completedStepKeys],
436
+ compactOutcomesByCommandId: compactCommandOutcomes.byCommandId,
437
+ latestCommandCompactOutcome: compactCommandOutcomes.latestCommandCompactOutcome
438
+ };
439
+ };
440
+ //#endregion
441
+ export { projectPiWorkflowSessionLiveOverlay as a, isPiWorkflowStepActive as i, projectPiWorkflowSession as n, reducePiWorkflowSessionEmission as o, createPiWorkflowSessionEmissionReducer as r, settleCompletedPiWorkflowSessionLiveSteps as s, createLoadingPiWorkflowSessionProjection as t };
442
+
443
+ //# sourceMappingURL=workflow-session-projection-CJ4MUkpJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-session-projection-CJ4MUkpJ.js","names":["buildSessionContext","AgentMessage","SessionTreeEntry","PiHarnessFrontendAgentMessage","PiSessionDataIntegrityError","PiHarnessStepResult","PiProjectionSessionIdentity","workflowName","sessionId","PersistedPiHarnessStepResult","outcome","value","dataIntegrityError","identity","message","cause","Error","undefined","asPersistedPiHarnessStepResult","result","type","mergePiSessionEntries","entryGroups","entries","indexes","Map","entryGroup","entry","index","get","id","set","length","push","latestCompletedPiHarnessEntries","steps","status","flatMap","step","appendedEntries","resolveActiveSessionPath","leafId","targetId","entriesById","has","reversePath","visitedEntryIds","Set","currentId","add","parentId","reverse","ProjectedPiSessionEntries","contextMessages","timelineMessages","ProjectPiSessionEntriesOptions","timelineMessagesAfterEntryId","ReadonlyMap","projectPiSessionEntries","options","activePath","messages","error","role","summary","tokensBefore","timestamp","Date","getTime","z","asPersistedPiHarnessStepResult","PiProjectionSessionIdentity","PI_SESSION_COMMAND_STEP_PREFIX","PiSessionDataIntegrityError","PiCompactCommandOutcome","compactCommandOutcomeSchema","discriminatedUnion","object","kind","literal","commandId","string","status","code","enum","message","ZodType","parseCompactCommandOutcome","value","identity","outcome","safeParse","success","workflowName","sessionId","Error","cause","error","data","projectPiCompactCommandOutcomes","steps","stepKey","result","byCommandId","Readonly","Record","latestCommandCompactOutcome","step","startsWith","ToolCall","PiHarnessEventStreamDecoders","piToolCallArgumentsText","PiHarnessFrontendAgentMessage","PiHarnessFrontendAssistantMessage","PiHarnessFrontendEvent","PiSessionActiveCommand","PiWorkflowStatus","DraftAgentActivity","DraftAgentMessage","DraftTool","PiWorkflowSessionProjectionEmission","PiWorkflowSessionProjectionStep","PiWorkflowSessionLiveState","inFlightMessagesByStepKey","Map","inFlightStepKeys","draftAgentMessage","currentAssistantMessage","draftStepKey","activeCommand","activeCommandStepKey","hasOpenMessageDraft","activeLiveWork","PiWorkflowSessionEmissionReducer","live","eventDecoders","isPiWorkflowStepActive","step","status","type","waitEventType","createPiWorkflowSessionLiveState","draftActivityForAssistantEvent","Extract","startsWith","updateDraftTool","tools","Record","toolCall","argsText","id","name","args","arguments","undefined","ensureDraftAgentMessage","state","emission","Pick","eventTime","Date","createdAt","getTime","Number","isFinite","Error","stepKey","activity","startedAt","updatedAt","recordInFlightMessage","message","messages","get","set","push","createPiWorkflowSessionEmissionReducer","reducePiWorkflowSessionEmission","reducer","payload","kind","executionId","epoch","start","command","finish","event","decode","draft","role","assistant","content","assistantMessage","structuredClone","assistantMessageEvent","contentIndex","toolCallId","toolName","resultMessage","partialResult","result","isError","settleCompletedPiWorkflowSessionLiveSteps","completedStepKeys","ReadonlySet","filter","has","delete","PiWorkflowSessionLiveOverlay","contextMessages","timelineMessages","readyForInput","projectPiWorkflowSessionLiveOverlay","durableContextMessages","durableTimelineMessages","instanceStatus","workflowSteps","liveTools","Object","values","hasLiveTools","some","tool","length","waitingForCommand","workflowAcceptsCommands","SessionTreeEntry","ToolResultMessage","projectPiCompactCommandOutcomes","PiHarnessEncodedEventEmission","PiHarnessFrontendAgentMessage","PiHarnessFrontendAssistantMessage","PiSessionActiveCommand","PiSessionCommandStartEmission","asPersistedPiHarnessStepResult","latestCompletedPiHarnessEntries","projectPiSessionEntries","PiCompactCommandOutcome","PiWorkflowStatus","createPiWorkflowSessionEmissionReducer","isPiWorkflowStepActive","projectPiWorkflowSessionLiveOverlay","reducePiWorkflowSessionEmission","PiHarnessOperationCompleteEmission","PiHarnessOperationStartEmission","PiHarnessSessionEntryEmission","PiSessionProjectionStatus","DraftAgentActivity","DraftTool","id","name","args","argsText","status","partialResult","result","resultMessage","isError","DraftAgentMessage","activity","assistant","tools","Record","startedAt","updatedAt","PiSessionActivity","PiWorkflowSessionProjectionData","contextMessages","timelineMessages","completedStepKeys","draftAgentMessage","activeCommand","compactOutcomesByCommandId","Readonly","latestCommandCompactOutcome","PiWorkflowSessionProjectionState","error","readyForInput","Error","PiWorkflowSessionProjectionStep","stepKey","type","waitEventType","PiWorkflowSessionProjectionEmission","executionId","epoch","sequence","payload","kind","control","createdAt","Date","PiWorkflowSessionProjectionInstance","zeroUsage","input","output","cacheRead","cacheWrite","totalTokens","cost","total","interruptionTimestamp","entry","message","timestamp","getTime","Number","isFinite","interruptedTimelineMessages","steps","sessionEntries","ReadonlyMap","entriesById","Map","map","messagesByLeafId","step","outcome","leafEntry","leafId","undefined","get","role","stopReason","messages","push","content","usage","set","emptyProjectionData","createLoadingPiWorkflowSessionProjection","projectPiWorkflowSession","workflowName","sessionId","instance","workflowSteps","workflowStepEmissions","identity","completedSteps","filter","Set","projectedEntries","timelineMessagesAfterEntryId","compactCommandOutcomes","emissionReducer","some","emission","has","liveOverlay","instanceStatus","live","byCommandId"],"sources":["../../src/pi/session-entry-projection.ts","../../src/pi/compact-command-outcome-projection.ts","../../src/pi/workflow-session-live-projection.ts","../../src/pi/workflow-session-projection.ts"],"sourcesContent":["import {\n buildSessionContext,\n type AgentMessage,\n type SessionTreeEntry,\n} from \"@earendil-works/pi-agent-core\";\n\nimport type { PiHarnessFrontendAgentMessage } from \"./harness/agent-harness-event-protocol\";\nimport { PiSessionDataIntegrityError } from \"./types\";\nimport type { PiHarnessStepResult } from \"./workflows/workflow-agent-harness\";\n\nexport type PiProjectionSessionIdentity = {\n workflowName: string;\n sessionId: string;\n};\n\nexport type PersistedPiHarnessStepResult = PiHarnessStepResult & {\n outcome?: \"completed\" | \"aborted\";\n value?: unknown;\n};\n\nconst dataIntegrityError = (\n identity: PiProjectionSessionIdentity,\n message: string,\n cause?: unknown,\n): PiSessionDataIntegrityError =>\n new PiSessionDataIntegrityError(\n identity.workflowName,\n identity.sessionId,\n new Error(message, cause === undefined ? undefined : { cause }),\n );\n\n/**\n * Workflow history exposes step results as `unknown`, but harness-run results are written by\n * `withWorkflowAgentHarness`. This is the single trust boundary for that internally owned data.\n */\nexport const asPersistedPiHarnessStepResult = (\n value: unknown,\n): PersistedPiHarnessStepResult | null => {\n const result = value as PersistedPiHarnessStepResult | undefined;\n return result?.type === \"harness-run\" ? result : null;\n};\n\nexport const mergePiSessionEntries = (\n ...entryGroups: readonly (readonly SessionTreeEntry[])[]\n): SessionTreeEntry[] => {\n const entries: SessionTreeEntry[] = [];\n const indexes = new Map<string, number>();\n\n for (const entryGroup of entryGroups) {\n for (const entry of entryGroup) {\n const index = indexes.get(entry.id);\n if (index === undefined) {\n indexes.set(entry.id, entries.length);\n entries.push(entry);\n } else {\n entries[index] = entry;\n }\n }\n }\n\n return entries;\n};\n\nexport const latestCompletedPiHarnessEntries = (\n steps: readonly { status: string; result: unknown }[],\n): SessionTreeEntry[] =>\n mergePiSessionEntries(\n ...steps.flatMap((step) => {\n if (step.status !== \"completed\") {\n return [];\n }\n const result = asPersistedPiHarnessStepResult(step.result);\n return result ? [result.appendedEntries] : [];\n }),\n );\n\nconst resolveActiveSessionPath = (\n entries: readonly SessionTreeEntry[],\n identity: PiProjectionSessionIdentity,\n): SessionTreeEntry[] => {\n let leafId: string | null = null;\n for (const entry of entries) {\n leafId = entry.type === \"leaf\" ? entry.targetId : entry.id;\n }\n if (leafId === null) {\n return [];\n }\n\n const entriesById = new Map<string, SessionTreeEntry>();\n for (const entry of entries) {\n if (entriesById.has(entry.id)) {\n throw dataIntegrityError(identity, `Pi session tree contains duplicate entry ${entry.id}.`);\n }\n entriesById.set(entry.id, entry);\n }\n const reversePath: SessionTreeEntry[] = [];\n const visitedEntryIds = new Set<string>();\n let currentId: string | null = leafId;\n\n while (currentId !== null) {\n if (visitedEntryIds.has(currentId)) {\n throw dataIntegrityError(\n identity,\n `Pi session tree contains a parent cycle at ${currentId}.`,\n );\n }\n visitedEntryIds.add(currentId);\n\n const entry = entriesById.get(currentId);\n if (!entry) {\n throw dataIntegrityError(identity, `Pi session tree references missing entry ${currentId}.`);\n }\n reversePath.push(entry);\n currentId = entry.parentId;\n }\n\n return reversePath.reverse();\n};\n\nexport type ProjectedPiSessionEntries = {\n contextMessages: AgentMessage[];\n timelineMessages: PiHarnessFrontendAgentMessage[];\n};\n\nexport type ProjectPiSessionEntriesOptions = {\n timelineMessagesAfterEntryId?: ReadonlyMap<\n string | null,\n readonly PiHarnessFrontendAgentMessage[]\n >;\n};\n\nexport const projectPiSessionEntries = (\n entries: readonly SessionTreeEntry[],\n identity: PiProjectionSessionIdentity,\n options: ProjectPiSessionEntriesOptions = {},\n): ProjectedPiSessionEntries => {\n const activePath = resolveActiveSessionPath(entries, identity);\n\n let contextMessages: AgentMessage[];\n try {\n contextMessages = buildSessionContext(activePath).messages;\n } catch (error) {\n throw dataIntegrityError(identity, \"Pi session entries cannot build a valid context.\", error);\n }\n\n const timelineMessages: PiHarnessFrontendAgentMessage[] = [\n ...(options.timelineMessagesAfterEntryId?.get(null) ?? []),\n ];\n for (const entry of activePath) {\n if (entry.type === \"message\") {\n timelineMessages.push(entry.message);\n } else if (entry.type === \"compaction\") {\n timelineMessages.push({\n role: \"compactionSummary\",\n summary: entry.summary,\n tokensBefore: entry.tokensBefore,\n timestamp: new Date(entry.timestamp).getTime(),\n });\n }\n timelineMessages.push(...(options.timelineMessagesAfterEntryId?.get(entry.id) ?? []));\n }\n\n return { contextMessages, timelineMessages };\n};\n","import { z } from \"zod\";\n\nimport {\n asPersistedPiHarnessStepResult,\n type PiProjectionSessionIdentity,\n} from \"./session-entry-projection\";\nimport {\n PI_SESSION_COMMAND_STEP_PREFIX,\n PiSessionDataIntegrityError,\n type PiCompactCommandOutcome,\n} from \"./types\";\n\nconst compactCommandOutcomeSchema = z.discriminatedUnion(\"status\", [\n z.object({\n kind: z.literal(\"compact\"),\n commandId: z.string(),\n status: z.literal(\"succeeded\"),\n }),\n z.object({\n kind: z.literal(\"compact\"),\n commandId: z.string(),\n status: z.literal(\"rejected\"),\n code: z.enum([\"nothing_to_compact\", \"compaction_failed\"]),\n message: z.string(),\n }),\n]) satisfies z.ZodType<PiCompactCommandOutcome>;\n\nconst parseCompactCommandOutcome = (\n value: unknown,\n identity: PiProjectionSessionIdentity,\n): PiCompactCommandOutcome | null => {\n if (\n typeof value !== \"object\" ||\n value === null ||\n (value as { kind?: unknown }).kind !== \"compact\"\n ) {\n return null;\n }\n\n const outcome = compactCommandOutcomeSchema.safeParse(value);\n if (!outcome.success) {\n throw new PiSessionDataIntegrityError(\n identity.workflowName,\n identity.sessionId,\n new Error(\"Persisted Pi compact command outcome is invalid.\", { cause: outcome.error }),\n );\n }\n return outcome.data;\n};\n\nexport const projectPiCompactCommandOutcomes = (\n steps: readonly { stepKey: string; status: string; result: unknown }[],\n identity: PiProjectionSessionIdentity,\n): {\n byCommandId: Readonly<Record<string, PiCompactCommandOutcome>>;\n latestCommandCompactOutcome: PiCompactCommandOutcome | null;\n} => {\n const byCommandId: Record<string, PiCompactCommandOutcome> = {};\n let latestCommandCompactOutcome: PiCompactCommandOutcome | null = null;\n\n for (const step of steps) {\n if (step.status !== \"completed\" || !step.stepKey.startsWith(PI_SESSION_COMMAND_STEP_PREFIX)) {\n continue;\n }\n\n const result = asPersistedPiHarnessStepResult(step.result);\n if (!result) {\n throw new PiSessionDataIntegrityError(\n identity.workflowName,\n identity.sessionId,\n new Error(`Pi command step ${step.stepKey} does not contain a harness result.`),\n );\n }\n if (result.outcome !== \"completed\") {\n continue;\n }\n\n latestCommandCompactOutcome = parseCompactCommandOutcome(result.value, identity);\n if (latestCommandCompactOutcome) {\n byCommandId[latestCommandCompactOutcome.commandId] = latestCommandCompactOutcome;\n }\n }\n\n return { byCommandId, latestCommandCompactOutcome };\n};\n","import type { ToolCall } from \"@earendil-works/pi-ai\";\n\nimport { PiHarnessEventStreamDecoders } from \"./harness/agent-harness-event-protocol\";\nimport {\n piToolCallArgumentsText,\n type PiHarnessFrontendAgentMessage,\n type PiHarnessFrontendAssistantMessage,\n type PiHarnessFrontendEvent,\n} from \"./harness/agent-harness-event-protocol\";\nimport type { PiSessionActiveCommand } from \"./session-command-protocol\";\nimport type { PiWorkflowStatus } from \"./types\";\nimport type {\n DraftAgentActivity,\n DraftAgentMessage,\n DraftTool,\n PiWorkflowSessionProjectionEmission,\n PiWorkflowSessionProjectionStep,\n} from \"./workflow-session-projection\";\n\nexport type PiWorkflowSessionLiveState = {\n inFlightMessagesByStepKey: Map<string, PiHarnessFrontendAgentMessage[]>;\n inFlightStepKeys: string[];\n draftAgentMessage: DraftAgentMessage | null;\n currentAssistantMessage?: PiHarnessFrontendAssistantMessage;\n draftStepKey?: string;\n activeCommand: PiSessionActiveCommand | null;\n activeCommandStepKey?: string;\n hasOpenMessageDraft: boolean;\n activeLiveWork: boolean;\n};\n\nexport type PiWorkflowSessionEmissionReducer = {\n live: PiWorkflowSessionLiveState;\n eventDecoders: PiHarnessEventStreamDecoders;\n};\n\nexport const isPiWorkflowStepActive = (step: PiWorkflowSessionProjectionStep): boolean =>\n step.status !== \"completed\" &&\n !(step.status === \"waiting\" && step.type === \"waitForEvent\" && step.waitEventType === \"command\");\n\nexport const createPiWorkflowSessionLiveState = (\n activeLiveWork = false,\n): PiWorkflowSessionLiveState => ({\n inFlightMessagesByStepKey: new Map(),\n inFlightStepKeys: [],\n draftAgentMessage: null,\n activeCommand: null,\n hasOpenMessageDraft: false,\n activeLiveWork,\n});\n\nconst draftActivityForAssistantEvent = (\n type: Extract<\n PiHarnessFrontendEvent,\n { type: \"message_update\" }\n >[\"assistantMessageEvent\"][\"type\"],\n): DraftAgentActivity | null => {\n if (type === \"start\") {\n return \"starting\";\n }\n if (type.startsWith(\"thinking_\")) {\n return \"thinking\";\n }\n if (type.startsWith(\"toolcall_\")) {\n return \"tool_calling\";\n }\n if (type.startsWith(\"text_\")) {\n return \"writing\";\n }\n return null;\n};\n\nconst updateDraftTool = (tools: Record<string, DraftTool>, toolCall: ToolCall): void => {\n const argsText = piToolCallArgumentsText(toolCall);\n tools[toolCall.id] = {\n ...tools[toolCall.id],\n id: toolCall.id,\n name: toolCall.name,\n args: toolCall.arguments,\n ...(argsText === undefined ? {} : { argsText }),\n status: tools[toolCall.id]?.status ?? \"starting\",\n };\n};\n\nconst ensureDraftAgentMessage = (\n state: PiWorkflowSessionLiveState,\n emission: Pick<PiWorkflowSessionProjectionEmission, \"createdAt\" | \"stepKey\">,\n): DraftAgentMessage => {\n const eventTime = new Date(emission.createdAt).getTime();\n if (!Number.isFinite(eventTime)) {\n throw new Error(`Pi workflow emission ${emission.stepKey} has an invalid timestamp.`);\n }\n\n state.draftStepKey = emission.stepKey;\n if (!state.draftAgentMessage) {\n state.draftAgentMessage = {\n activity: \"starting\",\n tools: {},\n startedAt: eventTime,\n updatedAt: eventTime,\n };\n } else {\n state.draftAgentMessage.updatedAt = eventTime;\n }\n return state.draftAgentMessage;\n};\n\nconst recordInFlightMessage = (\n state: PiWorkflowSessionLiveState,\n stepKey: string,\n message: PiHarnessFrontendAgentMessage,\n): void => {\n let messages = state.inFlightMessagesByStepKey.get(stepKey);\n if (!messages) {\n messages = [];\n state.inFlightMessagesByStepKey.set(stepKey, messages);\n state.inFlightStepKeys.push(stepKey);\n }\n messages.push(message);\n};\n\nexport const createPiWorkflowSessionEmissionReducer = (\n activeLiveWork = false,\n): PiWorkflowSessionEmissionReducer => ({\n live: createPiWorkflowSessionLiveState(activeLiveWork),\n eventDecoders: new PiHarnessEventStreamDecoders(),\n});\n\nexport const reducePiWorkflowSessionEmission = (\n reducer: PiWorkflowSessionEmissionReducer,\n emission: PiWorkflowSessionProjectionEmission,\n): void => {\n const state = reducer.live;\n const payload = emission.payload;\n if (!payload?.kind) {\n return;\n }\n\n state.activeLiveWork = true;\n if (payload.kind === \"harness-operation-start\") {\n if (!emission.executionId || !emission.epoch) {\n throw new Error(`Pi workflow emission ${emission.stepKey} is missing its stream identity.`);\n }\n reducer.eventDecoders.start({\n stepKey: emission.stepKey,\n executionId: emission.executionId,\n epoch: emission.epoch,\n });\n return;\n }\n if (payload.kind === \"pi-session-command-start\") {\n state.activeCommand = payload.command;\n state.activeCommandStepKey = emission.stepKey;\n return;\n }\n if (payload.kind === \"harness-operation-complete\") {\n if (!emission.executionId || !emission.epoch) {\n throw new Error(`Pi workflow emission ${emission.stepKey} is missing its stream identity.`);\n }\n reducer.eventDecoders.finish({\n stepKey: emission.stepKey,\n executionId: emission.executionId,\n epoch: emission.epoch,\n });\n return;\n }\n if (payload.kind !== \"harness-event\") {\n return;\n }\n\n if (!emission.executionId || !emission.epoch) {\n throw new Error(`Pi workflow emission ${emission.stepKey} is missing its stream identity.`);\n }\n const event = reducer.eventDecoders.decode(\n {\n stepKey: emission.stepKey,\n executionId: emission.executionId,\n epoch: emission.epoch,\n },\n payload.event,\n );\n const draft = ensureDraftAgentMessage(state, emission);\n switch (event.type) {\n case \"message_start\":\n draft.activity = \"starting\";\n if (event.message.role === \"assistant\") {\n draft.assistant = undefined;\n draft.tools = {};\n state.currentAssistantMessage = {\n ...event.message,\n content: [...event.message.content],\n };\n }\n state.hasOpenMessageDraft = true;\n return;\n case \"message_update\": {\n state.hasOpenMessageDraft = true;\n if (event.message.role !== \"assistant\") {\n throw new Error(\"Pi harness message_update did not contain an assistant message.\");\n }\n const assistantMessage = structuredClone(event.message);\n state.currentAssistantMessage = assistantMessage;\n draft.assistant = assistantMessage;\n const activity = draftActivityForAssistantEvent(event.assistantMessageEvent.type);\n if (activity) {\n draft.activity = activity;\n }\n if (\"contentIndex\" in event.assistantMessageEvent) {\n const toolCall = assistantMessage.content[event.assistantMessageEvent.contentIndex];\n if (toolCall?.type === \"toolCall\") {\n updateDraftTool(draft.tools, toolCall);\n }\n }\n return;\n }\n case \"message_end\":\n recordInFlightMessage(state, emission.stepKey, event.message);\n if (event.message.role === \"assistant\") {\n state.currentAssistantMessage = event.message;\n draft.assistant = event.message;\n } else if (event.message.role === \"toolResult\") {\n draft.tools[event.message.toolCallId] = {\n ...draft.tools[event.message.toolCallId],\n id: event.message.toolCallId,\n name: event.message.toolName,\n args: draft.tools[event.message.toolCallId]?.args,\n resultMessage: event.message,\n status: \"done\",\n };\n }\n state.hasOpenMessageDraft = false;\n return;\n case \"tool_execution_start\":\n draft.activity = \"running_tools\";\n draft.tools[event.toolCallId] = {\n ...draft.tools[event.toolCallId],\n id: event.toolCallId,\n name: event.toolName,\n args: event.args,\n status: \"running\",\n };\n return;\n case \"tool_execution_update\":\n draft.activity = \"running_tools\";\n draft.tools[event.toolCallId] = {\n ...draft.tools[event.toolCallId],\n id: event.toolCallId,\n name: event.toolName,\n args: event.args,\n partialResult: event.partialResult,\n status: \"running\",\n };\n return;\n case \"tool_execution_end\":\n draft.tools[event.toolCallId] = {\n ...draft.tools[event.toolCallId],\n id: event.toolCallId,\n name: event.toolName,\n args: draft.tools[event.toolCallId]?.args,\n result: event.result,\n isError: event.isError,\n status: \"done\",\n };\n return;\n case \"abort\":\n case \"after_provider_response\":\n case \"agent_end\":\n case \"agent_start\":\n case \"before_agent_start\":\n case \"before_provider_payload\":\n case \"before_provider_request\":\n case \"context\":\n case \"model_update\":\n case \"queue_update\":\n case \"resources_update\":\n case \"retry_attempt_start\":\n case \"retry_finished\":\n case \"retry_scheduled\":\n case \"save_point\":\n case \"session_before_compact\":\n case \"session_before_tree\":\n case \"session_compact\":\n case \"session_tree\":\n case \"settled\":\n case \"thinking_level_update\":\n case \"tool_call\":\n case \"tool_result\":\n case \"tools_update\":\n case \"turn_end\":\n case \"turn_start\":\n return;\n }\n};\n\nexport const settleCompletedPiWorkflowSessionLiveSteps = (\n state: PiWorkflowSessionLiveState,\n completedStepKeys: ReadonlySet<string>,\n): void => {\n state.inFlightStepKeys = state.inFlightStepKeys.filter((stepKey) => {\n if (!completedStepKeys.has(stepKey)) {\n return true;\n }\n state.inFlightMessagesByStepKey.delete(stepKey);\n return false;\n });\n\n if (state.draftStepKey && completedStepKeys.has(state.draftStepKey)) {\n state.draftAgentMessage = null;\n state.currentAssistantMessage = undefined;\n state.draftStepKey = undefined;\n state.hasOpenMessageDraft = false;\n }\n\n if (state.activeCommandStepKey && completedStepKeys.has(state.activeCommandStepKey)) {\n state.activeCommand = null;\n state.activeCommandStepKey = undefined;\n }\n};\n\nexport type PiWorkflowSessionLiveOverlay = {\n contextMessages: PiHarnessFrontendAgentMessage[];\n timelineMessages: PiHarnessFrontendAgentMessage[];\n draftAgentMessage: DraftAgentMessage | null;\n activeCommand: PiSessionActiveCommand | null;\n readyForInput: boolean;\n activity: DraftAgentActivity | \"working\" | null;\n};\n\nexport const projectPiWorkflowSessionLiveOverlay = ({\n contextMessages: durableContextMessages,\n timelineMessages: durableTimelineMessages,\n instanceStatus,\n workflowSteps,\n live,\n}: {\n contextMessages: readonly PiHarnessFrontendAgentMessage[];\n timelineMessages: readonly PiHarnessFrontendAgentMessage[];\n instanceStatus: PiWorkflowStatus;\n workflowSteps: readonly PiWorkflowSessionProjectionStep[];\n live: PiWorkflowSessionLiveState;\n}): PiWorkflowSessionLiveOverlay => {\n const contextMessages = [...durableContextMessages];\n const timelineMessages = [...durableTimelineMessages];\n for (const stepKey of live.inFlightStepKeys) {\n const messages = live.inFlightMessagesByStepKey.get(stepKey) ?? [];\n contextMessages.push(...messages);\n timelineMessages.push(...messages);\n }\n\n const liveTools = Object.values(live.draftAgentMessage?.tools ?? {});\n const hasLiveTools = liveTools.some((tool) => tool.status !== \"done\");\n const draftAgentMessage =\n live.draftAgentMessage && (live.hasOpenMessageDraft || liveTools.length > 0)\n ? live.draftAgentMessage\n : null;\n const waitingForCommand = workflowSteps.some(\n (step) =>\n step.status === \"waiting\" && step.type === \"waitForEvent\" && step.waitEventType === \"command\",\n );\n const workflowAcceptsCommands = instanceStatus === \"active\" || instanceStatus === \"waiting\";\n const readyForInput =\n workflowAcceptsCommands &&\n !live.hasOpenMessageDraft &&\n !hasLiveTools &&\n (!live.activeLiveWork || waitingForCommand);\n const activity =\n draftAgentMessage && (live.hasOpenMessageDraft || hasLiveTools)\n ? draftAgentMessage.activity\n : live.activeLiveWork && !readyForInput\n ? \"working\"\n : null;\n\n return {\n contextMessages,\n timelineMessages,\n draftAgentMessage,\n activeCommand: live.activeCommand,\n readyForInput,\n activity,\n };\n};\n","import type { SessionTreeEntry } from \"@earendil-works/pi-agent-core\";\nimport type { ToolResultMessage } from \"@earendil-works/pi-ai\";\n\nimport { projectPiCompactCommandOutcomes } from \"./compact-command-outcome-projection\";\nimport type { PiHarnessEncodedEventEmission } from \"./harness/agent-harness-event-protocol\";\nimport type {\n PiHarnessFrontendAgentMessage,\n PiHarnessFrontendAssistantMessage,\n} from \"./harness/agent-harness-event-protocol\";\nimport type {\n PiSessionActiveCommand,\n PiSessionCommandStartEmission,\n} from \"./session-command-protocol\";\nimport {\n asPersistedPiHarnessStepResult,\n latestCompletedPiHarnessEntries,\n projectPiSessionEntries,\n} from \"./session-entry-projection\";\nimport type { PiCompactCommandOutcome, PiWorkflowStatus } from \"./types\";\nimport {\n createPiWorkflowSessionEmissionReducer,\n isPiWorkflowStepActive,\n projectPiWorkflowSessionLiveOverlay,\n reducePiWorkflowSessionEmission,\n} from \"./workflow-session-live-projection\";\nimport type {\n PiHarnessOperationCompleteEmission,\n PiHarnessOperationStartEmission,\n PiHarnessSessionEntryEmission,\n} from \"./workflows/workflow-agent-harness\";\n\nexport type PiSessionProjectionStatus = \"loading\" | \"ready\" | \"not-found\";\n\nexport type DraftAgentActivity =\n | \"starting\"\n | \"thinking\"\n | \"writing\"\n | \"tool_calling\"\n | \"running_tools\";\n\nexport interface DraftTool {\n id: string;\n name: string;\n args: unknown;\n argsText?: string;\n status: \"starting\" | \"running\" | \"done\";\n partialResult?: unknown;\n result?: unknown;\n resultMessage?: ToolResultMessage;\n isError?: boolean;\n}\n\nexport interface DraftAgentMessage {\n activity: DraftAgentActivity;\n assistant?: PiHarnessFrontendAssistantMessage;\n tools: Record<string, DraftTool>;\n startedAt: number;\n updatedAt: number;\n}\n\nexport type PiSessionActivity = DraftAgentActivity | \"working\" | null;\n\ntype PiWorkflowSessionProjectionData = {\n contextMessages: PiHarnessFrontendAgentMessage[];\n timelineMessages: PiHarnessFrontendAgentMessage[];\n completedStepKeys: string[];\n draftAgentMessage: DraftAgentMessage | null;\n activeCommand: PiSessionActiveCommand | null;\n compactOutcomesByCommandId: Readonly<Record<string, PiCompactCommandOutcome>>;\n latestCommandCompactOutcome: PiCompactCommandOutcome | null;\n};\n\nexport type PiWorkflowSessionProjectionState =\n | (PiWorkflowSessionProjectionData & {\n status: \"loading\";\n error: null;\n readyForInput: false;\n activity: null;\n })\n | (PiWorkflowSessionProjectionData & {\n status: \"ready\";\n error: null;\n readyForInput: boolean;\n activity: PiSessionActivity;\n })\n | (PiWorkflowSessionProjectionData & {\n status: \"not-found\";\n error: Error;\n readyForInput: false;\n activity: null;\n });\n\nexport type PiWorkflowSessionProjectionStep = {\n stepKey: string;\n type: string;\n status: string;\n waitEventType: string | null;\n result: unknown;\n};\n\nexport type PiWorkflowSessionProjectionEmission = {\n stepKey: string;\n executionId: string;\n epoch: string;\n sequence: number;\n payload:\n | PiHarnessEncodedEventEmission\n | PiHarnessSessionEntryEmission\n | PiHarnessOperationStartEmission\n | PiHarnessOperationCompleteEmission\n | PiSessionCommandStartEmission\n | { kind: undefined; control: string }\n | null;\n createdAt: Date;\n};\n\nexport type PiWorkflowSessionProjectionInstance = {\n status: PiWorkflowStatus;\n};\n\nconst zeroUsage = (): PiHarnessFrontendAssistantMessage[\"usage\"] => ({\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n total: 0,\n },\n});\n\nconst interruptionTimestamp = (entry: SessionTreeEntry | undefined): number => {\n if (!entry) {\n return 0;\n }\n if (entry.type === \"message\") {\n return entry.message.timestamp;\n }\n\n const timestamp = new Date(entry.timestamp).getTime();\n return Number.isFinite(timestamp) ? timestamp : 0;\n};\n\nconst interruptedTimelineMessages = (\n steps: readonly PiWorkflowSessionProjectionStep[],\n sessionEntries: readonly SessionTreeEntry[],\n): ReadonlyMap<string | null, readonly PiHarnessFrontendAgentMessage[]> => {\n const entriesById = new Map(sessionEntries.map((entry) => [entry.id, entry]));\n const messagesByLeafId = new Map<string | null, PiHarnessFrontendAgentMessage[]>();\n\n for (const step of steps) {\n if (step.status !== \"completed\") {\n continue;\n }\n const result = asPersistedPiHarnessStepResult(step.result);\n if (result?.outcome !== \"aborted\") {\n continue;\n }\n\n const leafEntry = result.leafId === null ? undefined : entriesById.get(result.leafId);\n if (\n leafEntry?.type === \"message\" &&\n leafEntry.message.role === \"assistant\" &&\n leafEntry.message.stopReason === \"aborted\"\n ) {\n continue;\n }\n\n const messages = messagesByLeafId.get(result.leafId) ?? [];\n messages.push({\n role: \"assistant\",\n content: [],\n usage: zeroUsage(),\n stopReason: \"aborted\",\n timestamp: interruptionTimestamp(leafEntry),\n });\n messagesByLeafId.set(result.leafId, messages);\n }\n\n return messagesByLeafId;\n};\n\nconst emptyProjectionData = (): PiWorkflowSessionProjectionData => ({\n contextMessages: [],\n timelineMessages: [],\n completedStepKeys: [],\n draftAgentMessage: null,\n activeCommand: null,\n compactOutcomesByCommandId: {},\n latestCommandCompactOutcome: null,\n});\n\nexport const createLoadingPiWorkflowSessionProjection = (): PiWorkflowSessionProjectionState => ({\n ...emptyProjectionData(),\n status: \"loading\",\n error: null,\n readyForInput: false,\n activity: null,\n});\n\nexport const projectPiWorkflowSession = ({\n workflowName,\n sessionId,\n instance,\n workflowSteps,\n workflowStepEmissions = [],\n}: {\n workflowName: string;\n sessionId: string;\n instance: PiWorkflowSessionProjectionInstance | null;\n workflowSteps: readonly PiWorkflowSessionProjectionStep[];\n workflowStepEmissions?: readonly PiWorkflowSessionProjectionEmission[];\n}): PiWorkflowSessionProjectionState => {\n const identity = { workflowName, sessionId };\n const completedSteps = workflowSteps.filter((step) => step.status === \"completed\");\n const completedStepKeys = new Set(completedSteps.map((step) => step.stepKey));\n const sessionEntries = latestCompletedPiHarnessEntries(completedSteps);\n const projectedEntries = projectPiSessionEntries(sessionEntries, identity, {\n timelineMessagesAfterEntryId: interruptedTimelineMessages(completedSteps, sessionEntries),\n });\n\n if (instance === null) {\n return {\n ...emptyProjectionData(),\n ...projectedEntries,\n completedStepKeys: [...completedStepKeys],\n status: \"not-found\",\n error: new Error(`Pi session ${workflowName}/${sessionId} was not found.`),\n readyForInput: false,\n activity: null,\n };\n }\n\n const compactCommandOutcomes = projectPiCompactCommandOutcomes(workflowSteps, identity);\n const emissionReducer = createPiWorkflowSessionEmissionReducer(\n workflowSteps.some(isPiWorkflowStepActive),\n );\n for (const emission of workflowStepEmissions) {\n if (!completedStepKeys.has(emission.stepKey)) {\n reducePiWorkflowSessionEmission(emissionReducer, emission);\n }\n }\n const liveOverlay = projectPiWorkflowSessionLiveOverlay({\n ...projectedEntries,\n instanceStatus: instance.status,\n workflowSteps,\n live: emissionReducer.live,\n });\n\n return {\n ...liveOverlay,\n status: \"ready\",\n error: null,\n completedStepKeys: [...completedStepKeys],\n compactOutcomesByCommandId: compactCommandOutcomes.byCommandId,\n latestCommandCompactOutcome: compactCommandOutcomes.latestCommandCompactOutcome,\n };\n};\n"],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { a as PiHarnessOperationCompleteEmission, i as PiWorkflowStatus, n as PiCompactCommandOutcome, o as PiHarnessOperationStartEmission, r as PiSessionCommandPayload, s as PiHarnessSessionEntryEmission } from "./types-Dk856kV1.js";
2
+ import { d as PiHarnessFrontendAgentMessage, p as PiHarnessFrontendAssistantMessage, r as PiHarnessEncodedEventEmission } from "./agent-harness-event-protocol-d6mH_9n3.js";
3
+ import { ToolResultMessage } from "@earendil-works/pi-ai";
4
+ //#region src/pi/session-command-protocol.d.ts
5
+ type PiSessionDurableCommand = Extract<PiSessionCommandPayload, {
6
+ kind: "prompt" | "skill" | "promptFromTemplate" | "compact";
7
+ }>;
8
+ type PiSessionActiveCommand = Pick<PiSessionDurableCommand, "commandId" | "kind">;
9
+ /** Identifies the interactive command owning an active workflow step. */
10
+ type PiSessionCommandStartEmission = {
11
+ kind: "pi-session-command-start";
12
+ command: PiSessionActiveCommand;
13
+ };
14
+ //#endregion
15
+ //#region src/pi/workflow-session-projection.d.ts
16
+ type PiSessionProjectionStatus = "loading" | "ready" | "not-found";
17
+ type DraftAgentActivity = "starting" | "thinking" | "writing" | "tool_calling" | "running_tools";
18
+ interface DraftTool {
19
+ id: string;
20
+ name: string;
21
+ args: unknown;
22
+ argsText?: string;
23
+ status: "starting" | "running" | "done";
24
+ partialResult?: unknown;
25
+ result?: unknown;
26
+ resultMessage?: ToolResultMessage;
27
+ isError?: boolean;
28
+ }
29
+ interface DraftAgentMessage {
30
+ activity: DraftAgentActivity;
31
+ assistant?: PiHarnessFrontendAssistantMessage;
32
+ tools: Record<string, DraftTool>;
33
+ startedAt: number;
34
+ updatedAt: number;
35
+ }
36
+ type PiSessionActivity = DraftAgentActivity | "working" | null;
37
+ type PiWorkflowSessionProjectionData = {
38
+ contextMessages: PiHarnessFrontendAgentMessage[];
39
+ timelineMessages: PiHarnessFrontendAgentMessage[];
40
+ completedStepKeys: string[];
41
+ draftAgentMessage: DraftAgentMessage | null;
42
+ activeCommand: PiSessionActiveCommand | null;
43
+ compactOutcomesByCommandId: Readonly<Record<string, PiCompactCommandOutcome>>;
44
+ latestCommandCompactOutcome: PiCompactCommandOutcome | null;
45
+ };
46
+ type PiWorkflowSessionProjectionState = (PiWorkflowSessionProjectionData & {
47
+ status: "loading";
48
+ error: null;
49
+ readyForInput: false;
50
+ activity: null;
51
+ }) | (PiWorkflowSessionProjectionData & {
52
+ status: "ready";
53
+ error: null;
54
+ readyForInput: boolean;
55
+ activity: PiSessionActivity;
56
+ }) | (PiWorkflowSessionProjectionData & {
57
+ status: "not-found";
58
+ error: Error;
59
+ readyForInput: false;
60
+ activity: null;
61
+ });
62
+ type PiWorkflowSessionProjectionStep = {
63
+ stepKey: string;
64
+ type: string;
65
+ status: string;
66
+ waitEventType: string | null;
67
+ result: unknown;
68
+ };
69
+ type PiWorkflowSessionProjectionEmission = {
70
+ stepKey: string;
71
+ executionId: string;
72
+ epoch: string;
73
+ sequence: number;
74
+ payload: PiHarnessEncodedEventEmission | PiHarnessSessionEntryEmission | PiHarnessOperationStartEmission | PiHarnessOperationCompleteEmission | PiSessionCommandStartEmission | {
75
+ kind: undefined;
76
+ control: string;
77
+ } | null;
78
+ createdAt: Date;
79
+ };
80
+ type PiWorkflowSessionProjectionInstance = {
81
+ status: PiWorkflowStatus;
82
+ };
83
+ declare const createLoadingPiWorkflowSessionProjection: () => PiWorkflowSessionProjectionState;
84
+ declare const projectPiWorkflowSession: ({ workflowName, sessionId, instance, workflowSteps, workflowStepEmissions }: {
85
+ workflowName: string;
86
+ sessionId: string;
87
+ instance: PiWorkflowSessionProjectionInstance | null;
88
+ workflowSteps: readonly PiWorkflowSessionProjectionStep[];
89
+ workflowStepEmissions?: readonly PiWorkflowSessionProjectionEmission[];
90
+ }) => PiWorkflowSessionProjectionState;
91
+ //#endregion
92
+ export { PiSessionProjectionStatus as a, PiWorkflowSessionProjectionState as c, projectPiWorkflowSession as d, PiSessionActivity as i, PiWorkflowSessionProjectionStep as l, DraftAgentMessage as n, PiWorkflowSessionProjectionEmission as o, DraftTool as r, PiWorkflowSessionProjectionInstance as s, DraftAgentActivity as t, createLoadingPiWorkflowSessionProjection as u };
93
+ //# sourceMappingURL=workflow-session-projection-Dj_a79GF.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-session-projection-Dj_a79GF.d.ts","names":[],"sources":["../../src/pi/session-command-protocol.ts","../../src/pi/workflow-session-projection.ts"],"mappings":";;;;KA8BY,0BAA0B,QACpC;EACE;;KAGQ,yBAAyB,KAAK;;KAG9B;EACV;EACA,SAAS;;;;KCTC;KAEA;UAOK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA,gBAAgB;EAChB;;UAGe;EACf,UAAU;EACV,YAAY;EACZ,OAAO,eAAe;EACtB;EACA;;KAGU,oBAAoB;KAE3B;EACH,iBAAiB;EACjB,kBAAkB;EAClB;EACA,mBAAmB;EACnB,eAAe;EACf,4BAA4B,SAAS,eAAe;EACpD,6BAA6B;;KAGnB,oCACP;EACC;EACA;EACA;EACA;MAED;EACC;EACA;EACA;EACA,UAAU;MAEX;EACC;EACA,OAAO;EACP;EACA;;KAGM;EACV;EACA;EACA;EACA;EACA;;KAGU;EACV;EACA;EACA;EACA;EACA,SACI,gCACA,gCACA,kCACA,qCACA;IACE;IAAiB;;EAEvB,WAAW;;KAGD;EACV,QAAQ;;cA+EG,gDAA+C;cAQ/C,6BAA4B,cAAA,WAAA,UAAA,eAAA;EAOvC;EACA;EACA,UAAU;EACV,wBAAwB;EACxB,iCAAiC;MAC/B"}