@synergenius/flow-weaver-pack-weaver 0.9.140 → 0.9.144

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 (85) hide show
  1. package/dist/bot/assistant-tools.d.ts.map +1 -1
  2. package/dist/bot/assistant-tools.js +5 -11
  3. package/dist/bot/assistant-tools.js.map +1 -1
  4. package/dist/bot/behavior-defaults.d.ts +2 -2
  5. package/dist/bot/behavior-defaults.d.ts.map +1 -1
  6. package/dist/bot/behavior-defaults.js +11 -6
  7. package/dist/bot/behavior-defaults.js.map +1 -1
  8. package/dist/bot/capability-registry.d.ts +2 -0
  9. package/dist/bot/capability-registry.d.ts.map +1 -1
  10. package/dist/bot/capability-registry.js +282 -15
  11. package/dist/bot/capability-registry.js.map +1 -1
  12. package/dist/bot/dashboard.js +3 -3
  13. package/dist/bot/dashboard.js.map +1 -1
  14. package/dist/bot/hierarchy-event-log.d.ts +37 -0
  15. package/dist/bot/hierarchy-event-log.d.ts.map +1 -0
  16. package/dist/bot/hierarchy-event-log.js +58 -0
  17. package/dist/bot/hierarchy-event-log.js.map +1 -0
  18. package/dist/bot/operations.d.ts +2 -0
  19. package/dist/bot/operations.d.ts.map +1 -1
  20. package/dist/bot/operations.js +5 -0
  21. package/dist/bot/operations.js.map +1 -1
  22. package/dist/bot/profile-store.d.ts.map +1 -1
  23. package/dist/bot/profile-store.js +46 -0
  24. package/dist/bot/profile-store.js.map +1 -1
  25. package/dist/bot/runner.d.ts.map +1 -1
  26. package/dist/bot/runner.js +51 -16
  27. package/dist/bot/runner.js.map +1 -1
  28. package/dist/bot/step-executor.d.ts.map +1 -1
  29. package/dist/bot/step-executor.js +36 -1
  30. package/dist/bot/step-executor.js.map +1 -1
  31. package/dist/bot/swarm-controller.d.ts +1 -0
  32. package/dist/bot/swarm-controller.d.ts.map +1 -1
  33. package/dist/bot/swarm-controller.js +64 -6
  34. package/dist/bot/swarm-controller.js.map +1 -1
  35. package/dist/bot/task-store.d.ts +1 -1
  36. package/dist/bot/task-store.d.ts.map +1 -1
  37. package/dist/bot/task-store.js +21 -36
  38. package/dist/bot/task-store.js.map +1 -1
  39. package/dist/bot/task-types.d.ts +5 -1
  40. package/dist/bot/task-types.d.ts.map +1 -1
  41. package/dist/bot/types.d.ts +4 -0
  42. package/dist/bot/types.d.ts.map +1 -1
  43. package/dist/node-types/bot-report.d.ts +3 -1
  44. package/dist/node-types/bot-report.d.ts.map +1 -1
  45. package/dist/node-types/bot-report.js +62 -11
  46. package/dist/node-types/bot-report.js.map +1 -1
  47. package/dist/node-types/build-context.d.ts.map +1 -1
  48. package/dist/node-types/build-context.js +32 -0
  49. package/dist/node-types/build-context.js.map +1 -1
  50. package/dist/node-types/report.d.ts +2 -0
  51. package/dist/node-types/report.d.ts.map +1 -1
  52. package/dist/node-types/report.js +61 -7
  53. package/dist/node-types/report.js.map +1 -1
  54. package/dist/ui/capability-editor.js +268 -15
  55. package/dist/ui/profile-editor.js +271 -18
  56. package/dist/ui/swarm-dashboard.js +340 -51
  57. package/dist/ui/task-detail-view.js +69 -33
  58. package/dist/ui/trace-to-timeline.d.ts +2 -0
  59. package/dist/ui/trace-to-timeline.d.ts.map +1 -1
  60. package/dist/ui/trace-to-timeline.js.map +1 -1
  61. package/dist/ui/use-stream-timeline.d.ts +2 -0
  62. package/dist/ui/use-stream-timeline.d.ts.map +1 -1
  63. package/dist/ui/use-stream-timeline.js +76 -34
  64. package/dist/ui/use-stream-timeline.js.map +1 -1
  65. package/flowweaver.manifest.json +1 -1
  66. package/package.json +1 -1
  67. package/src/bot/assistant-tools.ts +5 -11
  68. package/src/bot/behavior-defaults.ts +12 -5
  69. package/src/bot/capability-registry.ts +300 -18
  70. package/src/bot/dashboard.ts +3 -3
  71. package/src/bot/hierarchy-event-log.ts +64 -0
  72. package/src/bot/operations.ts +7 -0
  73. package/src/bot/profile-store.ts +46 -0
  74. package/src/bot/runner.ts +51 -16
  75. package/src/bot/step-executor.ts +32 -1
  76. package/src/bot/swarm-controller.ts +67 -6
  77. package/src/bot/task-store.ts +22 -38
  78. package/src/bot/task-types.ts +7 -1
  79. package/src/bot/types.ts +4 -0
  80. package/src/node-types/bot-report.ts +63 -12
  81. package/src/node-types/build-context.ts +32 -0
  82. package/src/node-types/report.ts +60 -8
  83. package/src/ui/task-detail-view.tsx +3 -0
  84. package/src/ui/trace-to-timeline.ts +2 -0
  85. package/src/ui/use-stream-timeline.ts +81 -38
@@ -68,6 +68,8 @@ export interface HistoricalRun {
68
68
  durationMs?: number;
69
69
  duration?: number; // fallback
70
70
  summary?: string;
71
+ /** Markdown report for rich UI display. */
72
+ report?: string;
71
73
  outputs?: Record<string, unknown>;
72
74
  startedAt?: string;
73
75
  finishedAt?: string;
@@ -42,6 +42,8 @@ export interface StreamTimelineState {
42
42
  steps: Array<{ id: string; operation: string; description: string }>;
43
43
  } | null;
44
44
  awaitingApproval: boolean;
45
+ /** Markdown report from bot-completed event. */
46
+ report: string | null;
45
47
  }
46
48
 
47
49
  export function useStreamTimeline(events: StreamEvent[], isDone: boolean): StreamTimelineState {
@@ -76,6 +78,9 @@ export function useStreamTimeline(events: StreamEvent[], isDone: boolean): Strea
76
78
  // Map nodeId → index in entries[] so we can replace start with complete
77
79
  const nodeEntryIndex = new Map<string, number>();
78
80
  const nodeStarts = new Map<string, number>();
81
+ // Track completed/failed nodes to skip duplicate completion events
82
+ // (FW runtime emits 2x STATUS_CHANGED per node transition)
83
+ const completedNodes = new Set<string>();
79
84
  let idCounter = 0;
80
85
 
81
86
  for (const event of events) {
@@ -95,6 +100,17 @@ export function useStreamTimeline(events: StreamEvent[], isDone: boolean): Strea
95
100
  case 'node-start': {
96
101
  const nodeId = d.nodeId as string;
97
102
  if (nodeId) nodeStarts.set(nodeId, event.timestamp);
103
+
104
+ // If we already have an in-flight entry for this node (duplicate
105
+ // STATUS_CHANGED from the FW runtime), skip the duplicate.
106
+ const existingStartIdx = nodeEntryIndex.get(nodeId);
107
+ if (existingStartIdx != null && entries[existingStartIdx]?.type === 'node-started') {
108
+ break;
109
+ }
110
+
111
+ // Clear completed tracking so retry loops work (node can re-enter)
112
+ completedNodes.delete(nodeId);
113
+
98
114
  const idx = entries.length;
99
115
  nodeEntryIndex.set(nodeId, idx);
100
116
  entries.push({
@@ -111,65 +127,91 @@ export function useStreamTimeline(events: StreamEvent[], isDone: boolean): Strea
111
127
 
112
128
  case 'node-complete': {
113
129
  const nodeId = d.nodeId as string;
130
+ // Skip duplicate completion events for the same node
131
+ if (completedNodes.has(nodeId)) break;
132
+
114
133
  const startTs = nodeStarts.get(nodeId);
115
134
  const duration =
116
135
  (d.durationMs as number) ?? (startTs ? event.timestamp - startTs : undefined);
117
136
  if (nodeId) nodeStarts.delete(nodeId);
118
-
119
- const rawOutputs = d.outputs as Array<{ portLabel: string; value: unknown }> | undefined;
120
-
121
- const completed: TimelineEntry = {
122
- id: `s-${idCounter++}`,
123
- timestamp: new Date(startTs ?? event.timestamp),
124
- type: 'node-completed',
125
- nodeId,
126
- label: (d.label as string) ?? (d.nodeType as string) ?? nodeId ?? 'Node',
127
- duration,
128
- color: d.color as string | undefined,
129
- icon: d.icon as string | undefined,
130
- outputs: rawOutputs && rawOutputs.length > 0 ? rawOutputs : undefined,
131
- };
137
+ completedNodes.add(nodeId);
132
138
 
133
139
  // Replace the node-started entry in-place
134
140
  const existingIdx = nodeEntryIndex.get(nodeId);
135
141
  if (existingIdx != null && entries[existingIdx]) {
136
- entries[existingIdx] = completed;
142
+ const rawOutputs = d.outputs as Array<{ portLabel: string; value: unknown }> | undefined;
143
+ entries[existingIdx] = {
144
+ id: entries[existingIdx]!.id,
145
+ timestamp: new Date(startTs ?? event.timestamp),
146
+ type: 'node-completed',
147
+ nodeId,
148
+ label: (d.label as string) ?? (d.nodeType as string) ?? nodeId ?? 'Node',
149
+ duration,
150
+ color: d.color as string | undefined,
151
+ icon: d.icon as string | undefined,
152
+ outputs: rawOutputs && rawOutputs.length > 0 ? rawOutputs : undefined,
153
+ };
137
154
  nodeEntryIndex.delete(nodeId);
138
155
  } else {
139
- entries.push(completed);
156
+ // No matching start entry — standalone complete (e.g. Start node)
157
+ const rawOutputs = d.outputs as Array<{ portLabel: string; value: unknown }> | undefined;
158
+ entries.push({
159
+ id: `s-${idCounter++}`,
160
+ timestamp: new Date(startTs ?? event.timestamp),
161
+ type: 'node-completed',
162
+ nodeId,
163
+ label: (d.label as string) ?? (d.nodeType as string) ?? nodeId ?? 'Node',
164
+ duration,
165
+ color: d.color as string | undefined,
166
+ icon: d.icon as string | undefined,
167
+ outputs: rawOutputs && rawOutputs.length > 0 ? rawOutputs : undefined,
168
+ });
140
169
  }
141
170
  break;
142
171
  }
143
172
 
144
173
  case 'node-error': {
145
174
  const nodeId = d.nodeId as string;
175
+ if (completedNodes.has(nodeId)) break; // skip duplicate
176
+
146
177
  const startTs = nodeStarts.get(nodeId);
147
178
  const duration =
148
179
  (d.durationMs as number) ?? (startTs ? event.timestamp - startTs : undefined);
149
180
  if (nodeId) nodeStarts.delete(nodeId);
150
-
151
- const rawOutputs = d.outputs as Array<{ portLabel: string; value: unknown }> | undefined;
152
-
153
- const failed: TimelineEntry = {
154
- id: `s-${idCounter++}`,
155
- timestamp: new Date(startTs ?? event.timestamp),
156
- type: 'node-failed',
157
- nodeId,
158
- label: (d.label as string) ?? (d.nodeType as string) ?? nodeId ?? 'Node',
159
- detail: d.error as string | undefined,
160
- duration,
161
- color: d.color as string | undefined,
162
- icon: d.icon as string | undefined,
163
- outputs: rawOutputs && rawOutputs.length > 0 ? rawOutputs : undefined,
164
- };
181
+ completedNodes.add(nodeId);
165
182
 
166
183
  // Replace the node-started entry in-place
167
184
  const existingIdx = nodeEntryIndex.get(nodeId);
168
185
  if (existingIdx != null && entries[existingIdx]) {
169
- entries[existingIdx] = failed;
186
+
187
+ const rawOutputs = d.outputs as Array<{ portLabel: string; value: unknown }> | undefined;
188
+ entries[existingIdx] = {
189
+ id: entries[existingIdx]!.id,
190
+ timestamp: new Date(startTs ?? event.timestamp),
191
+ type: 'node-failed',
192
+ nodeId,
193
+ label: (d.label as string) ?? (d.nodeType as string) ?? nodeId ?? 'Node',
194
+ detail: d.error as string | undefined,
195
+ duration,
196
+ color: d.color as string | undefined,
197
+ icon: d.icon as string | undefined,
198
+ outputs: rawOutputs && rawOutputs.length > 0 ? rawOutputs : undefined,
199
+ };
170
200
  nodeEntryIndex.delete(nodeId);
171
201
  } else {
172
- entries.push(failed);
202
+ const rawOutputs = d.outputs as Array<{ portLabel: string; value: unknown }> | undefined;
203
+ entries.push({
204
+ id: `s-${idCounter++}`,
205
+ timestamp: new Date(startTs ?? event.timestamp),
206
+ type: 'node-failed',
207
+ nodeId,
208
+ label: (d.label as string) ?? (d.nodeType as string) ?? nodeId ?? 'Node',
209
+ detail: d.error as string | undefined,
210
+ duration,
211
+ color: d.color as string | undefined,
212
+ icon: d.icon as string | undefined,
213
+ outputs: rawOutputs && rawOutputs.length > 0 ? rawOutputs : undefined,
214
+ });
173
215
  }
174
216
  break;
175
217
  }
@@ -204,12 +246,13 @@ export function useStreamTimeline(events: StreamEvent[], isDone: boolean): Strea
204
246
  }, [events]);
205
247
 
206
248
  // Extract metadata from events
207
- const { phase, instruction, cost, plan, awaitingApproval } = useMemo(() => {
249
+ const { phase, instruction, cost, plan, awaitingApproval, report } = useMemo(() => {
208
250
  let phase: StreamTimelineState['phase'] = 'idle';
209
251
  let instruction: string | null = null;
210
252
  let cost: number | null = null;
211
253
  let plan: StreamTimelineState['plan'] = null;
212
254
  let awaitingApproval = false;
255
+ let report: string | null = null;
213
256
 
214
257
  for (const event of events) {
215
258
  const d = event.data ?? {};
@@ -221,12 +264,12 @@ export function useStreamTimeline(events: StreamEvent[], isDone: boolean): Strea
221
264
  phase = 'executing';
222
265
  } else if (event.type === 'bot-completed') {
223
266
  phase = (d.success as boolean) ? 'completed' : 'failed';
267
+ if (typeof d.report === 'string') report = d.report;
224
268
  } else if (event.type === 'bot-failed') {
225
269
  phase = 'failed';
226
270
  } else if (event.type === 'cost-update') {
227
271
  cost = (d.totalCost as number) ?? cost;
228
272
  } else if (event.type === 'audit:plan-created' || event.type === 'plan-created') {
229
- // Plan data may be at d.plan (structured) or directly on d (audit event)
230
273
  const planData = (d.plan as Record<string, unknown>) ?? d;
231
274
  const summary = (planData.summary as string) ?? '';
232
275
  const steps =
@@ -242,11 +285,11 @@ export function useStreamTimeline(events: StreamEvent[], isDone: boolean): Strea
242
285
  }
243
286
 
244
287
  if (isDone && phase !== 'completed' && phase !== 'failed') {
245
- phase = 'completed'; // Stream ended but no explicit completion event
288
+ phase = 'completed';
246
289
  }
247
290
 
248
- return { phase, instruction, cost, plan, awaitingApproval };
291
+ return { phase, instruction, cost, plan, awaitingApproval, report };
249
292
  }, [events, isDone]);
250
293
 
251
- return { timeline, phase, instruction, elapsed, cost, plan, awaitingApproval };
294
+ return { timeline, phase, instruction, elapsed, cost, plan, awaitingApproval, report };
252
295
  }