@memberjunction/ng-ai-test-harness 2.59.0 → 2.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,5 @@
1
- import { Component, Input, Output, EventEmitter } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
1
+ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
3
2
  import * as i0 from "@angular/core";
4
- const _forTrack0 = ($index, $item) => $item.id;
5
3
  function ExecutionNodeComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
6
4
  const _r1 = i0.ɵɵgetCurrentView();
7
5
  i0.ɵɵelementStart(0, "i", 19);
@@ -9,7 +7,7 @@ function ExecutionNodeComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
9
7
  i0.ɵɵelementEnd();
10
8
  } if (rf & 2) {
11
9
  const ctx_r1 = i0.ɵɵnextContext();
12
- i0.ɵɵclassProp("fa-chevron-down", ctx_r1.node.expanded)("fa-chevron-right", !ctx_r1.node.expanded);
10
+ i0.ɵɵclassProp("fa-chevron-down", ctx_r1.expanded)("fa-chevron-right", !ctx_r1.expanded);
13
11
  } }
14
12
  function ExecutionNodeComponent_Case_4_Template(rf, ctx) { if (rf & 1) {
15
13
  i0.ɵɵelement(0, "i", 4);
@@ -33,7 +31,7 @@ function ExecutionNodeComponent_Case_11_Conditional_0_Template(rf, ctx) { if (rf
33
31
  i0.ɵɵelement(0, "i");
34
32
  } if (rf & 2) {
35
33
  const ctx_r1 = i0.ɵɵnextContext(2);
36
- i0.ɵɵclassMap(ctx_r1.node.actionIconClass);
34
+ i0.ɵɵclassMap(ctx_r1.getActionIconClass());
37
35
  } }
38
36
  function ExecutionNodeComponent_Case_11_Conditional_1_Template(rf, ctx) { if (rf & 1) {
39
37
  i0.ɵɵelement(0, "i", 21);
@@ -42,19 +40,19 @@ function ExecutionNodeComponent_Case_11_Template(rf, ctx) { if (rf & 1) {
42
40
  i0.ɵɵtemplate(0, ExecutionNodeComponent_Case_11_Conditional_0_Template, 1, 2, "i", 20)(1, ExecutionNodeComponent_Case_11_Conditional_1_Template, 1, 0, "i", 21);
43
41
  } if (rf & 2) {
44
42
  const ctx_r1 = i0.ɵɵnextContext();
45
- i0.ɵɵconditional(ctx_r1.node.actionIconClass ? 0 : 1);
43
+ i0.ɵɵconditional(ctx_r1.getActionIconClass() ? 0 : 1);
46
44
  } }
47
45
  function ExecutionNodeComponent_Case_12_Conditional_0_Template(rf, ctx) { if (rf & 1) {
48
46
  i0.ɵɵelement(0, "img", 22);
49
47
  } if (rf & 2) {
50
48
  const ctx_r1 = i0.ɵɵnextContext(2);
51
- i0.ɵɵproperty("src", ctx_r1.node.agentLogoURL, i0.ɵɵsanitizeUrl)("alt", ctx_r1.node.agentName || "Agent");
49
+ i0.ɵɵproperty("src", ctx_r1.getAgentLogoURL(), i0.ɵɵsanitizeUrl)("alt", ctx_r1.getAgentName() || "Agent");
52
50
  } }
53
51
  function ExecutionNodeComponent_Case_12_Conditional_1_Template(rf, ctx) { if (rf & 1) {
54
52
  i0.ɵɵelement(0, "i");
55
53
  } if (rf & 2) {
56
54
  const ctx_r1 = i0.ɵɵnextContext(2);
57
- i0.ɵɵclassMap(ctx_r1.node.agentIconClass);
55
+ i0.ɵɵclassMap(ctx_r1.getAgentIconClass());
58
56
  } }
59
57
  function ExecutionNodeComponent_Case_12_Conditional_2_Template(rf, ctx) { if (rf & 1) {
60
58
  i0.ɵɵelement(0, "i", 23);
@@ -63,7 +61,7 @@ function ExecutionNodeComponent_Case_12_Template(rf, ctx) { if (rf & 1) {
63
61
  i0.ɵɵtemplate(0, ExecutionNodeComponent_Case_12_Conditional_0_Template, 1, 2, "img", 22)(1, ExecutionNodeComponent_Case_12_Conditional_1_Template, 1, 2, "i", 20)(2, ExecutionNodeComponent_Case_12_Conditional_2_Template, 1, 0, "i", 23);
64
62
  } if (rf & 2) {
65
63
  const ctx_r1 = i0.ɵɵnextContext();
66
- i0.ɵɵconditional(ctx_r1.node.agentLogoURL ? 0 : ctx_r1.node.agentIconClass ? 1 : 2);
64
+ i0.ɵɵconditional(ctx_r1.getAgentLogoURL() ? 0 : ctx_r1.getAgentIconClass() ? 1 : 2);
67
65
  } }
68
66
  function ExecutionNodeComponent_Case_13_Template(rf, ctx) { if (rf & 1) {
69
67
  i0.ɵɵelement(0, "i", 11);
@@ -78,7 +76,7 @@ function ExecutionNodeComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
78
76
  } if (rf & 2) {
79
77
  const ctx_r1 = i0.ɵɵnextContext();
80
78
  i0.ɵɵadvance();
81
- i0.ɵɵtextInterpolate1("[Level ", ctx_r1.node.depth, "]");
79
+ i0.ɵɵtextInterpolate1("[Level ", ctx_r1.depth, "]");
82
80
  } }
83
81
  function ExecutionNodeComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
84
82
  i0.ɵɵelementStart(0, "span", 15);
@@ -87,7 +85,7 @@ function ExecutionNodeComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
87
85
  } if (rf & 2) {
88
86
  const ctx_r1 = i0.ɵɵnextContext();
89
87
  i0.ɵɵadvance();
90
- i0.ɵɵtextInterpolate(ctx_r1.formatDuration(ctx_r1.node.duration));
88
+ i0.ɵɵtextInterpolate(ctx_r1.formatDuration(ctx_r1.getDuration()));
91
89
  } }
92
90
  function ExecutionNodeComponent_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
93
91
  i0.ɵɵelementStart(0, "span", 24);
@@ -96,7 +94,7 @@ function ExecutionNodeComponent_Conditional_19_Conditional_1_Template(rf, ctx) {
96
94
  } if (rf & 2) {
97
95
  const ctx_r1 = i0.ɵɵnextContext(2);
98
96
  i0.ɵɵadvance();
99
- i0.ɵɵtextInterpolate1("", ctx_r1.node.tokensUsed, " tokens");
97
+ i0.ɵɵtextInterpolate1("", ctx_r1.getTokensUsed(), " tokens");
100
98
  } }
101
99
  function ExecutionNodeComponent_Conditional_19_Conditional_2_Template(rf, ctx) { if (rf & 1) {
102
100
  i0.ɵɵelementStart(0, "span", 25);
@@ -105,7 +103,7 @@ function ExecutionNodeComponent_Conditional_19_Conditional_2_Template(rf, ctx) {
105
103
  } if (rf & 2) {
106
104
  const ctx_r1 = i0.ɵɵnextContext(2);
107
105
  i0.ɵɵadvance();
108
- i0.ɵɵtextInterpolate1("$", ctx_r1.node.cost.toFixed(4), "");
106
+ i0.ɵɵtextInterpolate1("$", ctx_r1.getCost().toFixed(4), "");
109
107
  } }
110
108
  function ExecutionNodeComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
111
109
  i0.ɵɵelementStart(0, "span", 16);
@@ -114,9 +112,9 @@ function ExecutionNodeComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
114
112
  } if (rf & 2) {
115
113
  const ctx_r1 = i0.ɵɵnextContext();
116
114
  i0.ɵɵadvance();
117
- i0.ɵɵconditional(ctx_r1.node.tokensUsed ? 1 : -1);
115
+ i0.ɵɵconditional(ctx_r1.getTokensUsed() ? 1 : -1);
118
116
  i0.ɵɵadvance();
119
- i0.ɵɵconditional(ctx_r1.node.cost ? 2 : -1);
117
+ i0.ɵɵconditional(ctx_r1.getCost() ? 2 : -1);
120
118
  } }
121
119
  function ExecutionNodeComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
122
120
  const _r3 = i0.ɵɵgetCurrentView();
@@ -126,9 +124,9 @@ function ExecutionNodeComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
126
124
  i0.ɵɵelementEnd();
127
125
  } if (rf & 2) {
128
126
  const ctx_r1 = i0.ɵɵnextContext();
129
- i0.ɵɵproperty("title", ctx_r1.node.detailsExpanded ? "Hide details" : "Show details");
127
+ i0.ɵɵproperty("title", ctx_r1.detailsExpanded ? "Hide details" : "Show details");
130
128
  i0.ɵɵadvance();
131
- i0.ɵɵclassProp("fa-info", !ctx_r1.node.detailsExpanded)("fa-times", ctx_r1.node.detailsExpanded);
129
+ i0.ɵɵclassProp("fa-info", !ctx_r1.detailsExpanded)("fa-times", ctx_r1.detailsExpanded);
132
130
  } }
133
131
  function ExecutionNodeComponent_Conditional_21_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
134
132
  i0.ɵɵelementStart(0, "div", 31);
@@ -137,13 +135,13 @@ function ExecutionNodeComponent_Conditional_21_Conditional_0_Conditional_1_Templ
137
135
  } if (rf & 2) {
138
136
  const ctx_r1 = i0.ɵɵnextContext(3);
139
137
  i0.ɵɵadvance();
140
- i0.ɵɵtextInterpolate(ctx_r1.node.name);
138
+ i0.ɵɵtextInterpolate(ctx_r1.step.StepName);
141
139
  } }
142
140
  function ExecutionNodeComponent_Conditional_21_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
143
141
  i0.ɵɵelement(0, "div", 32);
144
142
  } if (rf & 2) {
145
143
  const ctx_r1 = i0.ɵɵnextContext(3);
146
- i0.ɵɵproperty("innerHTML", ctx_r1.formatMarkdown(ctx_r1.node.detailsMarkdown), i0.ɵɵsanitizeHtml);
144
+ i0.ɵɵproperty("innerHTML", ctx_r1.formatMarkdown(ctx_r1.getDetailsMarkdown()), i0.ɵɵsanitizeHtml);
147
145
  } }
148
146
  function ExecutionNodeComponent_Conditional_21_Conditional_0_Template(rf, ctx) { if (rf & 1) {
149
147
  i0.ɵɵelementStart(0, "div", 28);
@@ -154,7 +152,7 @@ function ExecutionNodeComponent_Conditional_21_Conditional_0_Template(rf, ctx) {
154
152
  i0.ɵɵadvance();
155
153
  i0.ɵɵconditional(ctx_r1.isNameTruncated() ? 1 : -1);
156
154
  i0.ɵɵadvance();
157
- i0.ɵɵconditional(ctx_r1.node.detailsMarkdown ? 2 : -1);
155
+ i0.ɵɵconditional(ctx_r1.getDetailsMarkdown() ? 2 : -1);
158
156
  } }
159
157
  function ExecutionNodeComponent_Conditional_21_Conditional_2_Template(rf, ctx) { if (rf & 1) {
160
158
  i0.ɵɵelementStart(0, "div", 29)(1, "div", 33);
@@ -167,7 +165,7 @@ function ExecutionNodeComponent_Conditional_21_Conditional_2_Template(rf, ctx) {
167
165
  } if (rf & 2) {
168
166
  const ctx_r1 = i0.ɵɵnextContext(2);
169
167
  i0.ɵɵadvance(5);
170
- i0.ɵɵtextInterpolate(ctx_r1.node.error);
168
+ i0.ɵɵtextInterpolate(ctx_r1.step.ErrorMessage);
171
169
  } }
172
170
  function ExecutionNodeComponent_Conditional_21_Conditional_3_Template(rf, ctx) { if (rf & 1) {
173
171
  i0.ɵɵelementStart(0, "div", 30)(1, "div", 33);
@@ -180,7 +178,7 @@ function ExecutionNodeComponent_Conditional_21_Conditional_3_Template(rf, ctx) {
180
178
  } if (rf & 2) {
181
179
  const ctx_r1 = i0.ɵɵnextContext(2);
182
180
  i0.ɵɵadvance(5);
183
- i0.ɵɵtextInterpolate(ctx_r1.node.inputPreview);
181
+ i0.ɵɵtextInterpolate(ctx_r1.getInputPreview());
184
182
  } }
185
183
  function ExecutionNodeComponent_Conditional_21_Conditional_4_Template(rf, ctx) { if (rf & 1) {
186
184
  i0.ɵɵelementStart(0, "div", 30)(1, "div", 33);
@@ -193,7 +191,7 @@ function ExecutionNodeComponent_Conditional_21_Conditional_4_Template(rf, ctx) {
193
191
  } if (rf & 2) {
194
192
  const ctx_r1 = i0.ɵɵnextContext(2);
195
193
  i0.ɵɵadvance(5);
196
- i0.ɵɵtextInterpolate(ctx_r1.node.outputPreview);
194
+ i0.ɵɵtextInterpolate(ctx_r1.getOutputPreview());
197
195
  } }
198
196
  function ExecutionNodeComponent_Conditional_21_Conditional_5_Template(rf, ctx) { if (rf & 1) {
199
197
  i0.ɵɵelementStart(0, "div", 30)(1, "div", 35);
@@ -207,57 +205,37 @@ function ExecutionNodeComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
207
205
  i0.ɵɵelementEnd();
208
206
  } if (rf & 2) {
209
207
  const ctx_r1 = i0.ɵɵnextContext();
210
- i0.ɵɵconditional(ctx_r1.node.detailsMarkdown || ctx_r1.isNameTruncated() ? 0 : -1);
208
+ i0.ɵɵconditional(ctx_r1.getDetailsMarkdown() || ctx_r1.isNameTruncated() ? 0 : -1);
211
209
  i0.ɵɵadvance(2);
212
- i0.ɵɵconditional(ctx_r1.node.error ? 2 : -1);
210
+ i0.ɵɵconditional(ctx_r1.step.ErrorMessage ? 2 : -1);
213
211
  i0.ɵɵadvance();
214
- i0.ɵɵconditional(ctx_r1.node.inputPreview ? 3 : -1);
212
+ i0.ɵɵconditional(ctx_r1.getInputPreview() ? 3 : -1);
215
213
  i0.ɵɵadvance();
216
- i0.ɵɵconditional(ctx_r1.node.outputPreview ? 4 : -1);
214
+ i0.ɵɵconditional(ctx_r1.getOutputPreview() ? 4 : -1);
217
215
  i0.ɵɵadvance();
218
- i0.ɵɵconditional(!ctx_r1.node.error && !ctx_r1.node.inputPreview && !ctx_r1.node.outputPreview && !ctx_r1.node.detailsMarkdown && !ctx_r1.isNameTruncated() ? 5 : -1);
219
- } }
220
- function ExecutionNodeComponent_Conditional_22_For_1_Template(rf, ctx) { if (rf & 1) {
221
- const _r4 = i0.ɵɵgetCurrentView();
222
- i0.ɵɵelementStart(0, "mj-execution-node", 39);
223
- i0.ɵɵlistener("toggleNode", function ExecutionNodeComponent_Conditional_22_For_1_Template_mj_execution_node_toggleNode_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleNode.emit($event)); })("userInteracted", function ExecutionNodeComponent_Conditional_22_For_1_Template_mj_execution_node_userInteracted_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.userInteracted.emit()); });
224
- i0.ɵɵelementEnd();
225
- } if (rf & 2) {
226
- const child_r5 = ctx.$implicit;
227
- i0.ɵɵproperty("node", child_r5)("depth", child_r5.depth);
228
- } }
229
- function ExecutionNodeComponent_Conditional_22_Template(rf, ctx) { if (rf & 1) {
230
- i0.ɵɵrepeaterCreate(0, ExecutionNodeComponent_Conditional_22_For_1_Template, 1, 2, "mj-execution-node", 38, _forTrack0);
231
- } if (rf & 2) {
232
- const ctx_r1 = i0.ɵɵnextContext();
233
- i0.ɵɵrepeater(ctx_r1.node.children);
216
+ i0.ɵɵconditional(!ctx_r1.step.ErrorMessage && !ctx_r1.getInputPreview() && !ctx_r1.getOutputPreview() && !ctx_r1.getDetailsMarkdown() && !ctx_r1.isNameTruncated() ? 5 : -1);
234
217
  } }
235
218
  export class ExecutionNodeComponent {
236
219
  constructor() {
237
- this.depth = 0; // Add depth input
220
+ this.depth = 0;
221
+ this.agentPath = [];
222
+ this.expanded = false;
223
+ this.detailsExpanded = false;
238
224
  this.toggleNode = new EventEmitter();
225
+ this.toggleDetails = new EventEmitter();
239
226
  this.userInteracted = new EventEmitter();
240
227
  }
241
- // NEW: Add events for node navigation
242
- // Note: Removed navigateToStep functionality
243
- hasExpandableContent() {
244
- return !!(this.node.children && this.node.children.length > 0) ||
245
- this.node.type === 'sub-agent' ||
246
- this.node.type === 'action' ||
247
- !!this.node.inputPreview ||
248
- !!this.node.outputPreview ||
249
- !!this.node.error ||
250
- !!this.node.detailsMarkdown;
251
- }
252
228
  hasChildren() {
253
- return !!(this.node.children && this.node.children.length > 0);
229
+ return this.step.StepType === 'Sub-Agent' &&
230
+ !!this.step.SubAgentRun?.Steps &&
231
+ this.step.SubAgentRun.Steps.length > 0;
254
232
  }
255
233
  onToggleChildren(event) {
256
234
  if (event) {
257
235
  event.stopPropagation();
258
236
  }
259
237
  if (this.hasChildren()) {
260
- this.toggleNode.emit(this.node);
238
+ this.toggleNode.emit();
261
239
  this.userInteracted.emit();
262
240
  }
263
241
  }
@@ -266,32 +244,33 @@ export class ExecutionNodeComponent {
266
244
  event.stopPropagation();
267
245
  }
268
246
  if (this.hasNodeDetails()) {
269
- this.node.detailsExpanded = !this.node.detailsExpanded;
247
+ this.toggleDetails.emit();
270
248
  this.userInteracted.emit();
271
249
  }
272
250
  }
273
251
  onDoubleClick() {
274
252
  if (this.hasChildren()) {
275
- this.toggleNode.emit(this.node);
253
+ this.toggleNode.emit();
276
254
  this.userInteracted.emit();
277
255
  }
278
256
  }
279
257
  hasNodeDetails() {
280
- return !!this.node.inputPreview ||
281
- !!this.node.outputPreview ||
282
- !!this.node.error ||
283
- !!this.node.detailsMarkdown ||
258
+ return !!this.step.InputData ||
259
+ !!this.step.OutputData ||
260
+ !!this.step.ErrorMessage ||
261
+ !!this.getDetailsMarkdown() ||
284
262
  this.isNameTruncated();
285
263
  }
286
264
  getTruncatedName() {
287
265
  const maxLength = 120;
288
- if (this.node.name.length <= maxLength) {
289
- return this.node.name;
266
+ const name = this.getStepName();
267
+ if (name.length <= maxLength) {
268
+ return name;
290
269
  }
291
- return this.node.name.substring(0, maxLength) + '...';
270
+ return name.substring(0, maxLength) + '...';
292
271
  }
293
272
  isNameTruncated() {
294
- return this.node.name.length > 120;
273
+ return this.step.StepName.length > 120;
295
274
  }
296
275
  formatDuration(ms) {
297
276
  if (ms < 1000)
@@ -303,13 +282,170 @@ export class ExecutionNodeComponent {
303
282
  return `${minutes}m ${seconds}s`;
304
283
  }
305
284
  getNodeTitle() {
306
- if (this.node.type === 'sub-agent' && this.node.agentName) {
307
- return `Sub-agent: ${this.node.agentName}`;
285
+ if (this.step.StepType === 'Sub-Agent' && this.getAgentName()) {
286
+ return `Sub-agent: ${this.getAgentName()}`;
308
287
  }
309
- if (this.node.type === 'action' && this.node.actionName) {
310
- return `Action: ${this.node.actionName}`;
288
+ if (this.step.StepType === 'Actions' && this.getActionName()) {
289
+ return `Action: ${this.getActionName()}`;
290
+ }
291
+ return this.step.StepType;
292
+ }
293
+ // Getter methods for step data
294
+ getStepName() {
295
+ // Extract just the first line if the name contains markdown
296
+ const lines = this.step.StepName.split('\n');
297
+ return lines[0].trim();
298
+ }
299
+ getStepTypeClass() {
300
+ const typeMap = {
301
+ 'Validation': 'validation',
302
+ 'Prompt': 'prompt',
303
+ 'Actions': 'action',
304
+ 'Sub-Agent': 'sub-agent',
305
+ 'Decision': 'decision',
306
+ 'Chat': 'chat'
307
+ };
308
+ return typeMap[this.step.StepType] || 'prompt';
309
+ }
310
+ getStatusClass() {
311
+ const statusMap = {
312
+ 'Pending': 'pending',
313
+ 'Running': 'running',
314
+ 'Completed': 'completed',
315
+ 'Failed': 'failed',
316
+ 'Cancelled': 'failed',
317
+ 'Paused': 'pending'
318
+ };
319
+ // Use override if provided, otherwise use actual status
320
+ const status = this.overrideDisplayStatus || this.step.Status;
321
+ return statusMap[status] || 'pending';
322
+ }
323
+ getDuration() {
324
+ if (!this.step.StartedAt || !this.step.CompletedAt)
325
+ return 0;
326
+ return new Date(this.step.CompletedAt).getTime() - new Date(this.step.StartedAt).getTime();
327
+ }
328
+ getTokensUsed() {
329
+ // Check if this is a prompt step with token data
330
+ if (this.step.StepType === 'Prompt' && this.step.PromptRun) {
331
+ return this.step.PromptRun.TokensUsed || undefined;
332
+ }
333
+ return undefined;
334
+ }
335
+ getCost() {
336
+ // Check if this is a prompt step with cost data
337
+ if (this.step.StepType === 'Prompt' && this.step.PromptRun) {
338
+ return this.step.PromptRun.TotalCost || undefined;
339
+ }
340
+ return undefined;
341
+ }
342
+ getDetailsMarkdown() {
343
+ // Check if the step name contains markdown details after the first line
344
+ const lines = this.step.StepName.split('\n');
345
+ if (lines.length > 1) {
346
+ return lines.slice(1).join('\n').trim();
347
+ }
348
+ return undefined;
349
+ }
350
+ getInputPreview() {
351
+ if (!this.step.InputData)
352
+ return undefined;
353
+ try {
354
+ const parsed = JSON.parse(this.step.InputData);
355
+ // Extract meaningful preview
356
+ if (parsed.promptName)
357
+ return `Prompt: ${parsed.promptName}`;
358
+ if (parsed.actionName)
359
+ return `Action: ${parsed.actionName}`;
360
+ if (parsed.subAgentName)
361
+ return `Sub-agent: ${parsed.subAgentName}`;
362
+ if (parsed.message)
363
+ return parsed.message;
364
+ if (parsed.userMessage)
365
+ return parsed.userMessage;
366
+ // Fallback to stringified preview
367
+ const str = JSON.stringify(parsed, null, 2);
368
+ return str.length > 500 ? str.substring(0, 500) + '...' : str;
369
+ }
370
+ catch {
371
+ return typeof this.step.InputData === 'string' ? this.step.InputData : JSON.stringify(this.step.InputData);
372
+ }
373
+ }
374
+ getOutputPreview() {
375
+ if (!this.step.OutputData)
376
+ return undefined;
377
+ try {
378
+ const parsed = JSON.parse(this.step.OutputData);
379
+ // Show action results clearly
380
+ if (parsed.actionResult) {
381
+ const result = parsed.actionResult;
382
+ let preview = '';
383
+ if (result.success !== undefined) {
384
+ preview += `Success: ${result.success}\n`;
385
+ }
386
+ if (result.resultCode) {
387
+ preview += `Result Code: ${result.resultCode}\n`;
388
+ }
389
+ if (result.message) {
390
+ preview += `Message: ${result.message}\n`;
391
+ }
392
+ if (result.result) {
393
+ preview += `Result: ${typeof result.result === 'object' ? JSON.stringify(result.result, null, 2) : result.result}`;
394
+ }
395
+ return preview.trim();
396
+ }
397
+ // Show prompt results
398
+ if (parsed.promptResult) {
399
+ const result = parsed.promptResult;
400
+ let preview = '';
401
+ if (result.success !== undefined) {
402
+ preview += `Success: ${result.success}\n`;
403
+ }
404
+ if (result.content) {
405
+ preview += `Content: ${result.content}`;
406
+ }
407
+ return preview;
408
+ }
409
+ // Fallback
410
+ const str = JSON.stringify(parsed, null, 2);
411
+ return str.length > 500 ? str.substring(0, 500) + '...' : str;
412
+ }
413
+ catch {
414
+ return typeof this.step.OutputData === 'string' ? this.step.OutputData : JSON.stringify(this.step.OutputData);
415
+ }
416
+ }
417
+ // Methods to extract metadata from input/output data
418
+ getAgentName() {
419
+ if (this.step.StepType === 'Sub-Agent' && this.step.SubAgentRun) {
420
+ return this.step.SubAgentRun.Agent || undefined;
421
+ }
422
+ return this.parseMetadata('subAgentName');
423
+ }
424
+ getAgentIconClass() {
425
+ return this.parseMetadata('subAgentIconClass') || this.parseMetadata('agentIconClass');
426
+ }
427
+ getAgentLogoURL() {
428
+ return this.parseMetadata('subAgentLogoURL') || this.parseMetadata('agentLogoURL');
429
+ }
430
+ getActionName() {
431
+ if (this.step.StepType === 'Actions' && this.step.ActionExecutionLog) {
432
+ return this.step.ActionExecutionLog.Action;
433
+ }
434
+ return this.parseMetadata('actionName');
435
+ }
436
+ getActionIconClass() {
437
+ return this.parseMetadata('actionIconClass');
438
+ }
439
+ parseMetadata(key) {
440
+ if (!this.step.InputData)
441
+ return undefined;
442
+ try {
443
+ const parsed = JSON.parse(this.step.InputData);
444
+ return parsed[key];
445
+ }
446
+ catch {
447
+ return undefined;
311
448
  }
312
- return this.node.type;
313
449
  }
314
450
  formatMarkdown(markdown) {
315
451
  // Basic markdown formatting
@@ -340,7 +476,7 @@ export class ExecutionNodeComponent {
340
476
  return html;
341
477
  }
342
478
  static { this.ɵfac = function ExecutionNodeComponent_Factory(t) { return new (t || ExecutionNodeComponent)(); }; }
343
- static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ExecutionNodeComponent, selectors: [["mj-execution-node"]], inputs: { node: "node", depth: "depth" }, outputs: { toggleNode: "toggleNode", userInteracted: "userInteracted" }, standalone: true, features: [i0.ɵɵStandaloneFeature], decls: 23, vars: 19, consts: [[1, "tree-node"], [1, "node-header", 3, "dblclick"], ["title", "Toggle children", 1, "expand-icon", "fa-solid", 3, "fa-chevron-down", "fa-chevron-right"], [1, "status-icon"], [1, "fa-regular", "fa-circle"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-check-circle"], [1, "fa-solid", "fa-times-circle"], [1, "type-icon", 3, "title"], [1, "fa-solid", "fa-shield-halved"], [1, "fa-solid", "fa-brain"], [1, "fa-solid", "fa-code-branch"], [1, "fa-solid", "fa-comments"], [1, "node-name"], [2, "color", "#666", "margin-right", "8px"], [1, "node-duration"], [1, "node-metrics"], [1, "details-toggle-btn", 3, "title"], [1, "node-details"], ["title", "Toggle children", 1, "expand-icon", "fa-solid", 3, "click"], [3, "class"], [1, "fa-solid", "fa-bolt"], [1, "agent-logo-icon", 3, "src", "alt"], [1, "fa-solid", "fa-sitemap"], [1, "tokens"], [1, "cost"], [1, "details-toggle-btn", 3, "click", "title"], [1, "fa-solid"], [1, "markdown-details"], [1, "detail-section", "error"], [1, "detail-section"], [1, "full-name"], [1, "detail-content", "markdown", 3, "innerHTML"], [1, "detail-label"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "detail-content"], [1, "fa-solid", "fa-sign-in-alt"], [1, "fa-solid", "fa-sign-out-alt"], [3, "node", "depth"], [3, "toggleNode", "userInteracted", "node", "depth"]], template: function ExecutionNodeComponent_Template(rf, ctx) { if (rf & 1) {
479
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ExecutionNodeComponent, selectors: [["mj-execution-node"]], inputs: { step: "step", depth: "depth", agentPath: "agentPath", expanded: "expanded", detailsExpanded: "detailsExpanded", overrideDisplayStatus: "overrideDisplayStatus" }, outputs: { toggleNode: "toggleNode", toggleDetails: "toggleDetails", userInteracted: "userInteracted" }, decls: 22, vars: 20, consts: [[1, "tree-node"], [1, "node-header", 3, "dblclick"], ["title", "Toggle children", 1, "expand-icon", "fa-solid", 3, "fa-chevron-down", "fa-chevron-right"], [1, "status-icon"], [1, "fa-regular", "fa-circle"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-check-circle"], [1, "fa-solid", "fa-times-circle"], [1, "type-icon", 3, "title"], [1, "fa-solid", "fa-shield-halved"], [1, "fa-solid", "fa-brain"], [1, "fa-solid", "fa-code-branch"], [1, "fa-solid", "fa-comments"], [1, "node-name"], [2, "color", "#666", "margin-right", "8px"], [1, "node-duration"], [1, "node-metrics"], [1, "details-toggle-btn", 3, "title"], [1, "node-details"], ["title", "Toggle children", 1, "expand-icon", "fa-solid", 3, "click"], [3, "class"], [1, "fa-solid", "fa-bolt"], [1, "agent-logo-icon", 3, "src", "alt"], [1, "fa-solid", "fa-sitemap"], [1, "tokens"], [1, "cost"], [1, "details-toggle-btn", 3, "click", "title"], [1, "fa-solid"], [1, "markdown-details"], [1, "detail-section", "error"], [1, "detail-section"], [1, "full-name"], [1, "detail-content", "markdown", 3, "innerHTML"], [1, "detail-label"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "detail-content"], [1, "fa-solid", "fa-sign-in-alt"], [1, "fa-solid", "fa-sign-out-alt"]], template: function ExecutionNodeComponent_Template(rf, ctx) { if (rf & 1) {
344
480
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1);
345
481
  i0.ɵɵlistener("dblclick", function ExecutionNodeComponent_Template_div_dblclick_1_listener() { return ctx.onDoubleClick(); });
346
482
  i0.ɵɵtemplate(2, ExecutionNodeComponent_Conditional_2_Template, 1, 4, "i", 2);
@@ -356,46 +492,45 @@ export class ExecutionNodeComponent {
356
492
  i0.ɵɵelementEnd();
357
493
  i0.ɵɵtemplate(18, ExecutionNodeComponent_Conditional_18_Template, 2, 1, "span", 15)(19, ExecutionNodeComponent_Conditional_19_Template, 3, 2, "span", 16)(20, ExecutionNodeComponent_Conditional_20_Template, 2, 5, "button", 17);
358
494
  i0.ɵɵelementEnd();
359
- i0.ɵɵtemplate(21, ExecutionNodeComponent_Conditional_21_Template, 6, 5, "div", 18)(22, ExecutionNodeComponent_Conditional_22_Template, 2, 0);
495
+ i0.ɵɵtemplate(21, ExecutionNodeComponent_Conditional_21_Template, 6, 5, "div", 18);
360
496
  i0.ɵɵelementEnd();
361
497
  } if (rf & 2) {
362
- let tmp_5_0;
363
- let tmp_7_0;
364
- i0.ɵɵclassMap("depth-" + ctx.node.depth + " type-" + ctx.node.type);
365
- i0.ɵɵclassProp("expanded", ctx.node.expanded)("has-children", ctx.hasChildren());
498
+ let tmp_6_0;
499
+ let tmp_8_0;
500
+ i0.ɵɵclassMap("depth-" + ctx.depth + " type-" + ctx.getStepTypeClass());
501
+ i0.ɵɵclassProp("expanded", ctx.expanded)("has-children", ctx.hasChildren())("details-expanded", ctx.detailsExpanded);
366
502
  i0.ɵɵadvance(2);
367
503
  i0.ɵɵconditional(ctx.hasChildren() ? 2 : -1);
368
504
  i0.ɵɵadvance();
369
- i0.ɵɵclassMap("status-" + ctx.node.status);
505
+ i0.ɵɵclassMap("status-" + ctx.getStatusClass());
370
506
  i0.ɵɵadvance();
371
- i0.ɵɵconditional((tmp_5_0 = ctx.node.status) === "pending" ? 4 : tmp_5_0 === "running" ? 5 : tmp_5_0 === "completed" ? 6 : tmp_5_0 === "failed" ? 7 : -1);
507
+ i0.ɵɵconditional((tmp_6_0 = ctx.getStatusClass()) === "pending" ? 4 : tmp_6_0 === "running" ? 5 : tmp_6_0 === "completed" ? 6 : tmp_6_0 === "failed" ? 7 : -1);
372
508
  i0.ɵɵadvance(4);
373
509
  i0.ɵɵproperty("title", ctx.getNodeTitle());
374
510
  i0.ɵɵadvance();
375
- i0.ɵɵconditional((tmp_7_0 = ctx.node.type) === "validation" ? 9 : tmp_7_0 === "prompt" ? 10 : tmp_7_0 === "action" ? 11 : tmp_7_0 === "sub-agent" ? 12 : tmp_7_0 === "decision" ? 13 : tmp_7_0 === "chat" ? 14 : -1);
511
+ i0.ɵɵconditional((tmp_8_0 = ctx.getStepTypeClass()) === "validation" ? 9 : tmp_8_0 === "prompt" ? 10 : tmp_8_0 === "action" ? 11 : tmp_8_0 === "sub-agent" ? 12 : tmp_8_0 === "decision" ? 13 : tmp_8_0 === "chat" ? 14 : -1);
376
512
  i0.ɵɵadvance(7);
377
- i0.ɵɵconditional(ctx.node.type === "sub-agent" && ctx.node.depth > 0 ? 16 : -1);
513
+ i0.ɵɵconditional(ctx.step.StepType === "Sub-Agent" && ctx.depth > 0 ? 16 : -1);
378
514
  i0.ɵɵadvance();
379
515
  i0.ɵɵtextInterpolate1(" ", ctx.getTruncatedName(), " ");
380
516
  i0.ɵɵadvance();
381
- i0.ɵɵconditional(ctx.node.duration ? 18 : -1);
517
+ i0.ɵɵconditional(ctx.getDuration() ? 18 : -1);
382
518
  i0.ɵɵadvance();
383
- i0.ɵɵconditional(ctx.node.tokensUsed || ctx.node.cost ? 19 : -1);
519
+ i0.ɵɵconditional(ctx.getTokensUsed() || ctx.getCost() ? 19 : -1);
384
520
  i0.ɵɵadvance();
385
521
  i0.ɵɵconditional(ctx.hasNodeDetails() ? 20 : -1);
386
522
  i0.ɵɵadvance();
387
- i0.ɵɵconditional(ctx.node.detailsExpanded ? 21 : -1);
388
- i0.ɵɵadvance();
389
- i0.ɵɵconditional(ctx.node.expanded && ctx.node.children && ctx.node.children.length > 0 ? 22 : -1);
390
- } }, dependencies: [ExecutionNodeComponent, CommonModule], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n }\n \n \n\n .tree-node[_ngcontent-%COMP%] {\n margin: 4px 0;\n position: relative;\n }\n \n \n\n .depth-0[_ngcontent-%COMP%] { \n margin-left: 0;\n position: relative;\n z-index: 2;\n }\n .depth-0[_ngcontent-%COMP%]::after {\n display: none;\n }\n .depth-0[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] { \n background: #f8f9fa;\n border: 2px solid #e0e0e0;\n font-weight: 600;\n position: relative;\n z-index: 10;\n }\n \n \n\n .depth-1[_ngcontent-%COMP%] {\n margin-left: 24px;\n }\n .depth-1[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fafafa;\n border-color: #d0d0d0;\n }\n \n .depth-2[_ngcontent-%COMP%] {\n margin-left: 48px;\n }\n .depth-2[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fcfcfc;\n border-color: #c0c0c0;\n }\n \n .depth-3[_ngcontent-%COMP%] {\n margin-left: 72px;\n }\n .depth-3[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fdfdfd;\n border-color: #b0b0b0;\n }\n \n .depth-4[_ngcontent-%COMP%] {\n margin-left: 96px;\n }\n .depth-4[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n \n .depth-5[_ngcontent-%COMP%] {\n margin-left: 120px;\n }\n .depth-5[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n \n .depth-6[_ngcontent-%COMP%] {\n margin-left: 144px;\n }\n .depth-6[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n\n \n\n .depth-0[_ngcontent-%COMP%] { \n position: relative;\n overflow: hidden;\n z-index: 2;\n }\n .depth-0[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] { \n background: #f8f9fa;\n position: relative;\n z-index: 2;\n }\n \n \n\n .depth-0.has-children[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: 12px;\n top: 0;\n width: 2px;\n height: 100%;\n border-left: 2px dotted #c0c7d0;\n z-index: 0; \n\n }\n \n \n\n .depth-1[_ngcontent-%COMP%] { \n margin-left: 30px;\n padding-left: 12px;\n position: relative;\n z-index: 1;\n }\n .depth-1[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] { \n background: #fafbfc;\n position: relative;\n z-index: 1;\n }\n \n \n\n .depth-1[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n left: -15px;\n top: 12px;\n width: 25px;\n height: 2px;\n border-bottom: 2px dotted #c0c7d0;\n z-index: 1;\n }\n \n \n\n .tree-node.details-expanded[_ngcontent-%COMP%] > .node-header[_ngcontent-%COMP%] {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n border-bottom: 1px solid #2196f3;\n }\n \n .node-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n transition: all 0.2s ease;\n user-select: none;\n position: relative;\n z-index: 5;\n background: white;\n }\n \n .node-header[_ngcontent-%COMP%]:hover {\n background: var(--gray-700);\n border-color: var(--mj-blue) !important;\n }\n \n \n\n .tree-node.type-sub-agent[_ngcontent-%COMP%] > .node-header[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-blue);\n }\n \n \n\n .tree-node.type-action[_ngcontent-%COMP%] > .node-header[_ngcontent-%COMP%] {\n border-left: 4px solid #4caf50;\n }\n \n .expand-icon[_ngcontent-%COMP%] {\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n color: #666;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n transition: all 0.2s ease;\n z-index: 10; \n\n position: relative;\n }\n \n .expand-icon[_ngcontent-%COMP%]:hover {\n background: #e0e0e0;\n color: #333;\n }\n \n .status-icon[_ngcontent-%COMP%] {\n width: 20px;\n text-align: center;\n font-size: 14px;\n }\n \n .status-pending[_ngcontent-%COMP%] { color: #999; }\n .status-running[_ngcontent-%COMP%] { color: #2196f3; }\n .status-completed[_ngcontent-%COMP%] { color: #4caf50; }\n .status-failed[_ngcontent-%COMP%] { color: #f44336; }\n \n .type-icon[_ngcontent-%COMP%] {\n width: 20px;\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: #666;\n }\n \n .agent-logo-icon[_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n object-fit: cover;\n border-radius: 3px;\n }\n \n .node-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13px;\n font-weight: 500;\n color: #1a1a1a;\n }\n \n \n .node-duration[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #666;\n font-weight: 500;\n }\n \n .node-metrics[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n font-size: 12px;\n }\n \n .tokens[_ngcontent-%COMP%] {\n color: #666;\n }\n \n .cost[_ngcontent-%COMP%] {\n color: #2196f3;\n font-weight: 500;\n }\n \n \n\n .details-toggle-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 12px;\n color: #666;\n margin-left: 4px;\n }\n \n .details-toggle-btn[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n border-color: #2196f3;\n color: #2196f3;\n }\n \n .details-toggle-btn[_ngcontent-%COMP%]:active {\n background: #e3f2fd;\n }\n \n \n\n .tree-node.details-expanded[_ngcontent-%COMP%] .details-toggle-btn[_ngcontent-%COMP%] {\n background: #2196f3;\n border-color: #2196f3;\n color: white;\n }\n \n .tree-node.details-expanded[_ngcontent-%COMP%] .details-toggle-btn[_ngcontent-%COMP%]:hover {\n background: #1976d2;\n border-color: #1976d2;\n }\n \n .node-details[_ngcontent-%COMP%] {\n margin: 0 5px;\n padding: 16px;\n background: var(--gray-600);\n border: 1px solid var(--gray-700);\n border-top: none;\n border-radius: 0 0 6px 6px;\n font-size: 12px;\n position: relative;\n z-index: 4;\n }\n \n .detail-section[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n }\n \n .detail-section[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n }\n \n .detail-section.error[_ngcontent-%COMP%] {\n color: #d32f2f;\n }\n \n .detail-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n margin-bottom: 4px;\n color: #555;\n }\n \n .detail-content[_ngcontent-%COMP%] {\n white-space: pre-wrap;\n word-break: break-word;\n color: #333;\n line-height: 1.4;\n }\n \n .markdown-details[_ngcontent-%COMP%] {\n margin: 8px 0 8px 44px;\n padding: 12px;\n background: #f9f9f9;\n border-left: 3px solid #2196f3;\n border-radius: 0 4px 4px 0;\n font-size: 13px;\n }\n \n .markdown[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .markdown[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 8px 0 4px 0;\n color: #1a1a1a;\n }\n \n .markdown[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n \n .markdown[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n \n .markdown[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] {\n margin: 4px 0;\n padding-left: 20px;\n }\n \n .markdown[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n margin: 2px 0;\n }\n \n .markdown[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: #e8e8e8;\n padding: 1px 4px;\n border-radius: 3px;\n font-size: 12px;\n }\n \n .markdown[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n background: #f5f5f5;\n padding: 8px;\n border-radius: 4px;\n overflow-x: auto;\n margin: 4px 0;\n }\n \n .markdown[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: none;\n padding: 0;\n }\n \n .markdown[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-weight: 600;\n color: #1a1a1a;\n }\n \n .markdown[_ngcontent-%COMP%] em[_ngcontent-%COMP%] {\n font-style: italic;\n color: #555;\n }\n \n .full-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: #1a1a1a;\n margin-bottom: 8px;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n word-wrap: break-word;\n }"] }); }
523
+ i0.ɵɵconditional(ctx.detailsExpanded ? 21 : -1);
524
+ } }, styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n }\n \n \n\n .tree-node[_ngcontent-%COMP%] {\n margin: 4px 0;\n position: relative;\n }\n \n \n\n .depth-0[_ngcontent-%COMP%] { \n margin-left: 0;\n position: relative;\n z-index: 2;\n }\n .depth-0[_ngcontent-%COMP%]::after {\n display: none;\n }\n .depth-0[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] { \n background: #f8f9fa;\n border: 2px solid #e0e0e0;\n font-weight: 600;\n position: relative;\n z-index: 10;\n }\n \n \n\n .depth-1[_ngcontent-%COMP%] {\n margin-left: 24px;\n }\n .depth-1[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fafafa;\n border-color: #d0d0d0;\n }\n \n .depth-2[_ngcontent-%COMP%] {\n margin-left: 48px;\n }\n .depth-2[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fcfcfc;\n border-color: #c0c0c0;\n }\n \n .depth-3[_ngcontent-%COMP%] {\n margin-left: 72px;\n }\n .depth-3[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fdfdfd;\n border-color: #b0b0b0;\n }\n \n .depth-4[_ngcontent-%COMP%] {\n margin-left: 96px;\n }\n .depth-4[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n \n .depth-5[_ngcontent-%COMP%] {\n margin-left: 120px;\n }\n .depth-5[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n \n .depth-6[_ngcontent-%COMP%] {\n margin-left: 144px;\n }\n .depth-6[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n\n \n\n .depth-0[_ngcontent-%COMP%] { \n position: relative;\n overflow: hidden;\n z-index: 2;\n }\n .depth-0[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] { \n background: #f8f9fa;\n position: relative;\n z-index: 2;\n }\n \n \n\n .depth-0.has-children[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: 12px;\n top: 0;\n width: 2px;\n height: 100%;\n border-left: 2px dotted #c0c7d0;\n z-index: 0; \n\n }\n \n \n\n .depth-1[_ngcontent-%COMP%] { \n margin-left: 30px;\n padding-left: 12px;\n position: relative;\n z-index: 1;\n }\n .depth-1[_ngcontent-%COMP%] .node-header[_ngcontent-%COMP%] { \n background: #fafbfc;\n position: relative;\n z-index: 1;\n }\n \n \n\n .depth-1[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n left: -15px;\n top: 12px;\n width: 25px;\n height: 2px;\n border-bottom: 2px dotted #c0c7d0;\n z-index: 1;\n }\n \n \n\n .tree-node.details-expanded[_ngcontent-%COMP%] > .node-header[_ngcontent-%COMP%] {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n border-bottom: 1px solid #2196f3;\n }\n \n .node-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n transition: all 0.2s ease;\n user-select: none;\n position: relative;\n z-index: 5;\n background: white;\n }\n \n .node-header[_ngcontent-%COMP%]:hover {\n background: var(--gray-700);\n border-color: var(--mj-blue) !important;\n }\n \n \n\n .tree-node.type-sub-agent[_ngcontent-%COMP%] > .node-header[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-blue);\n }\n \n \n\n .tree-node.type-action[_ngcontent-%COMP%] > .node-header[_ngcontent-%COMP%] {\n border-left: 4px solid #4caf50;\n }\n \n .expand-icon[_ngcontent-%COMP%] {\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n color: #666;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n transition: all 0.2s ease;\n z-index: 10; \n\n position: relative;\n }\n \n .expand-icon[_ngcontent-%COMP%]:hover {\n background: #e0e0e0;\n color: #333;\n }\n \n .status-icon[_ngcontent-%COMP%] {\n width: 20px;\n text-align: center;\n font-size: 14px;\n }\n \n .status-pending[_ngcontent-%COMP%] { color: #999; }\n .status-running[_ngcontent-%COMP%] { color: #2196f3; }\n .status-completed[_ngcontent-%COMP%] { color: #4caf50; }\n .status-failed[_ngcontent-%COMP%] { color: #f44336; }\n \n .type-icon[_ngcontent-%COMP%] {\n width: 20px;\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: #666;\n }\n \n .agent-logo-icon[_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n object-fit: cover;\n border-radius: 3px;\n }\n \n .node-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13px;\n font-weight: 500;\n color: #1a1a1a;\n }\n \n \n .node-duration[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #666;\n font-weight: 500;\n }\n \n .node-metrics[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n font-size: 12px;\n }\n \n .tokens[_ngcontent-%COMP%] {\n color: #666;\n }\n \n .cost[_ngcontent-%COMP%] {\n color: #2196f3;\n font-weight: 500;\n }\n \n \n\n .details-toggle-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 12px;\n color: #666;\n margin-left: 4px;\n }\n \n .details-toggle-btn[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n border-color: #2196f3;\n color: #2196f3;\n }\n \n .details-toggle-btn[_ngcontent-%COMP%]:active {\n background: #e3f2fd;\n }\n \n \n\n .tree-node.details-expanded[_ngcontent-%COMP%] .details-toggle-btn[_ngcontent-%COMP%] {\n background: #2196f3;\n border-color: #2196f3;\n color: white;\n }\n \n .tree-node.details-expanded[_ngcontent-%COMP%] .details-toggle-btn[_ngcontent-%COMP%]:hover {\n background: #1976d2;\n border-color: #1976d2;\n }\n \n .node-details[_ngcontent-%COMP%] {\n margin: 0 5px;\n padding: 16px;\n background: var(--gray-600);\n border: 1px solid var(--gray-700);\n border-top: none;\n border-radius: 0 0 6px 6px;\n font-size: 12px;\n position: relative;\n z-index: 4;\n }\n \n .detail-section[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n }\n \n .detail-section[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n }\n \n .detail-section.error[_ngcontent-%COMP%] {\n color: #d32f2f;\n }\n \n .detail-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n margin-bottom: 4px;\n color: #555;\n }\n \n .detail-content[_ngcontent-%COMP%] {\n white-space: pre-wrap;\n word-break: break-word;\n color: #333;\n line-height: 1.4;\n }\n \n .markdown-details[_ngcontent-%COMP%] {\n padding: 16px 16px 0 16px;\n background: var(--gray-600);\n border: 1px solid var(--gray-700);\n border-bottom: none;\n border-top: none;\n margin: 0 5px;\n }\n \n .markdown[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .markdown[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 8px 0 4px 0;\n color: #1a1a1a;\n }\n \n .markdown[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n \n .markdown[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n \n .markdown[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] {\n margin: 4px 0;\n padding-left: 20px;\n }\n \n .markdown[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n margin: 2px 0;\n }\n \n .markdown[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: #e8e8e8;\n padding: 1px 4px;\n border-radius: 3px;\n font-size: 12px;\n }\n \n .markdown[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n background: #f5f5f5;\n padding: 8px;\n border-radius: 4px;\n overflow-x: auto;\n margin: 4px 0;\n }\n \n .markdown[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: none;\n padding: 0;\n }\n \n .markdown[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-weight: 600;\n color: #1a1a1a;\n }\n \n .markdown[_ngcontent-%COMP%] em[_ngcontent-%COMP%] {\n font-style: italic;\n color: #555;\n }\n \n .full-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: #1a1a1a;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n word-wrap: break-word;\n }"], changeDetection: 0 }); }
391
525
  }
392
526
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ExecutionNodeComponent, [{
393
527
  type: Component,
394
- args: [{ selector: 'mj-execution-node', standalone: true, imports: [CommonModule], template: `
528
+ args: [{ selector: 'mj-execution-node', changeDetection: ChangeDetectionStrategy.OnPush, template: `
395
529
  <div class="tree-node"
396
- [class.expanded]="node.expanded"
530
+ [class.expanded]="expanded"
397
531
  [class.has-children]="hasChildren()"
398
- [class]="'depth-' + node.depth + ' type-' + node.type">
532
+ [class.details-expanded]="detailsExpanded"
533
+ [class]="'depth-' + depth + ' type-' + getStepTypeClass()">
399
534
 
400
535
  <!-- Node Header -->
401
536
  <div class="node-header"
@@ -403,15 +538,15 @@ export class ExecutionNodeComponent {
403
538
  <!-- Expand/Collapse Icon - Only show if node has children -->
404
539
  @if (hasChildren()) {
405
540
  <i class="expand-icon fa-solid"
406
- [class.fa-chevron-down]="node.expanded"
407
- [class.fa-chevron-right]="!node.expanded"
541
+ [class.fa-chevron-down]="expanded"
542
+ [class.fa-chevron-right]="!expanded"
408
543
  (click)="onToggleChildren($event)"
409
544
  title="Toggle children"></i>
410
545
  }
411
546
 
412
547
  <!-- Status Icon -->
413
- <span class="status-icon" [class]="'status-' + node.status">
414
- @switch (node.status) {
548
+ <span class="status-icon" [class]="'status-' + getStatusClass()">
549
+ @switch (getStatusClass()) {
415
550
  @case ('pending') {
416
551
  <i class="fa-regular fa-circle"></i>
417
552
  }
@@ -429,7 +564,7 @@ export class ExecutionNodeComponent {
429
564
 
430
565
  <!-- Type Icon -->
431
566
  <span class="type-icon" [title]="getNodeTitle()">
432
- @switch (node.type) {
567
+ @switch (getStepTypeClass()) {
433
568
  @case ('validation') {
434
569
  <i class="fa-solid fa-shield-halved"></i>
435
570
  }
@@ -437,17 +572,17 @@ export class ExecutionNodeComponent {
437
572
  <i class="fa-solid fa-brain"></i>
438
573
  }
439
574
  @case ('action') {
440
- @if (node.actionIconClass) {
441
- <i [class]="node.actionIconClass"></i>
575
+ @if (getActionIconClass()) {
576
+ <i [class]="getActionIconClass()"></i>
442
577
  } @else {
443
578
  <i class="fa-solid fa-bolt"></i>
444
579
  }
445
580
  }
446
581
  @case ('sub-agent') {
447
- @if (node.agentLogoURL) {
448
- <img [src]="node.agentLogoURL" [alt]="node.agentName || 'Agent'" class="agent-logo-icon">
449
- } @else if (node.agentIconClass) {
450
- <i [class]="node.agentIconClass"></i>
582
+ @if (getAgentLogoURL()) {
583
+ <img [src]="getAgentLogoURL()" [alt]="getAgentName() || 'Agent'" class="agent-logo-icon">
584
+ } @else if (getAgentIconClass()) {
585
+ <i [class]="getAgentIconClass()"></i>
451
586
  } @else {
452
587
  <i class="fa-solid fa-sitemap"></i>
453
588
  }
@@ -463,25 +598,25 @@ export class ExecutionNodeComponent {
463
598
 
464
599
  <!-- Node Name with depth indicator for sub-agents -->
465
600
  <span class="node-name">
466
- @if (node.type === 'sub-agent' && node.depth > 0) {
467
- <small style="color: #666; margin-right: 8px;">[Level {{ node.depth }}]</small>
601
+ @if (step.StepType === 'Sub-Agent' && depth > 0) {
602
+ <small style="color: #666; margin-right: 8px;">[Level {{ depth }}]</small>
468
603
  }
469
604
  {{ getTruncatedName() }}
470
605
  </span>
471
606
 
472
607
  <!-- Duration -->
473
- @if (node.duration) {
474
- <span class="node-duration">{{ formatDuration(node.duration) }}</span>
608
+ @if (getDuration()) {
609
+ <span class="node-duration">{{ formatDuration(getDuration()) }}</span>
475
610
  }
476
611
 
477
612
  <!-- Tokens/Cost -->
478
- @if (node.tokensUsed || node.cost) {
613
+ @if (getTokensUsed() || getCost()) {
479
614
  <span class="node-metrics">
480
- @if (node.tokensUsed) {
481
- <span class="tokens">{{ node.tokensUsed }} tokens</span>
615
+ @if (getTokensUsed()) {
616
+ <span class="tokens">{{ getTokensUsed() }} tokens</span>
482
617
  }
483
- @if (node.cost) {
484
- <span class="cost">\${{ node.cost.toFixed(4) }}</span>
618
+ @if (getCost()) {
619
+ <span class="cost">\${{ getCost()!.toFixed(4) }}</span>
485
620
  }
486
621
  </span>
487
622
  }
@@ -490,55 +625,55 @@ export class ExecutionNodeComponent {
490
625
  @if (hasNodeDetails()) {
491
626
  <button class="details-toggle-btn"
492
627
  (click)="onToggleDetails($event)"
493
- [title]="node.detailsExpanded ? 'Hide details' : 'Show details'">
628
+ [title]="detailsExpanded ? 'Hide details' : 'Show details'">
494
629
  <i class="fa-solid"
495
- [class.fa-info]="!node.detailsExpanded"
496
- [class.fa-times]="node.detailsExpanded"></i>
630
+ [class.fa-info]="!detailsExpanded"
631
+ [class.fa-times]="detailsExpanded"></i>
497
632
  </button>
498
633
  }
499
634
  </div>
500
635
 
501
636
  <!-- Node Details (when details are expanded) -->
502
- @if (node.detailsExpanded) {
637
+ @if (detailsExpanded) {
503
638
  <!-- Show markdown details first if available -->
504
- @if (node.detailsMarkdown || isNameTruncated()) {
639
+ @if (getDetailsMarkdown() || isNameTruncated()) {
505
640
  <div class="markdown-details">
506
641
  @if (isNameTruncated()) {
507
- <div class="full-name">{{ node.name }}</div>
642
+ <div class="full-name">{{ step.StepName }}</div>
508
643
  }
509
- @if (node.detailsMarkdown) {
510
- <div class="detail-content markdown" [innerHTML]="formatMarkdown(node.detailsMarkdown)"></div>
644
+ @if (getDetailsMarkdown()) {
645
+ <div class="detail-content markdown" [innerHTML]="formatMarkdown(getDetailsMarkdown()!)"></div>
511
646
  }
512
647
  </div>
513
648
  }
514
649
 
515
650
  <!-- Always show details section if node is expanded, even if some content is empty -->
516
651
  <div class="node-details">
517
- @if (node.error) {
652
+ @if (step.ErrorMessage) {
518
653
  <div class="detail-section error">
519
654
  <div class="detail-label">
520
655
  <i class="fa-solid fa-exclamation-triangle"></i> Error
521
656
  </div>
522
- <div class="detail-content">{{ node.error }}</div>
657
+ <div class="detail-content">{{ step.ErrorMessage }}</div>
523
658
  </div>
524
659
  }
525
- @if (node.inputPreview) {
660
+ @if (getInputPreview()) {
526
661
  <div class="detail-section">
527
662
  <div class="detail-label">
528
663
  <i class="fa-solid fa-sign-in-alt"></i> Input
529
664
  </div>
530
- <div class="detail-content">{{ node.inputPreview }}</div>
665
+ <div class="detail-content">{{ getInputPreview() }}</div>
531
666
  </div>
532
667
  }
533
- @if (node.outputPreview) {
668
+ @if (getOutputPreview()) {
534
669
  <div class="detail-section">
535
670
  <div class="detail-label">
536
671
  <i class="fa-solid fa-sign-out-alt"></i> Output
537
672
  </div>
538
- <div class="detail-content">{{ node.outputPreview }}</div>
673
+ <div class="detail-content">{{ getOutputPreview() }}</div>
539
674
  </div>
540
675
  }
541
- @if (!node.error && !node.inputPreview && !node.outputPreview && !node.detailsMarkdown && !isNameTruncated()) {
676
+ @if (!step.ErrorMessage && !getInputPreview() && !getOutputPreview() && !getDetailsMarkdown() && !isNameTruncated()) {
542
677
  <div class="detail-section">
543
678
  <div class="detail-content">No additional details available for this step.</div>
544
679
  </div>
@@ -546,27 +681,27 @@ export class ExecutionNodeComponent {
546
681
  </div>
547
682
  }
548
683
 
549
- <!-- Children (when children are expanded) - HIERARCHICAL DISPLAY -->
550
- @if (node.expanded && node.children && node.children.length > 0) {
551
- @for (child of node.children; track child.id) {
552
- <mj-execution-node
553
- [node]="child"
554
- [depth]="child.depth"
555
- (toggleNode)="toggleNode.emit($event)"
556
- (userInteracted)="userInteracted.emit()">
557
- </mj-execution-node>
558
- }
559
- }
684
+ <!-- Note: Sub-agent children are rendered by the parent component to maintain proper depth tracking -->
560
685
  </div>
561
- `, styles: ["\n :host {\n display: block;\n width: 100%;\n }\n \n /* Depth-based indentation - each level indents by 24px */\n .tree-node {\n margin: 4px 0;\n position: relative;\n }\n \n /* Root level nodes (depth 0) */\n .depth-0 { \n margin-left: 0;\n position: relative;\n z-index: 2;\n }\n .depth-0::after {\n display: none;\n }\n .depth-0 .node-header { \n background: #f8f9fa;\n border: 2px solid #e0e0e0;\n font-weight: 600;\n position: relative;\n z-index: 10;\n }\n \n /* Sub-level nodes with increasing indentation */\n .depth-1 {\n margin-left: 24px;\n }\n .depth-1 .node-header {\n background: #fafafa;\n border-color: #d0d0d0;\n }\n \n .depth-2 {\n margin-left: 48px;\n }\n .depth-2 .node-header {\n background: #fcfcfc;\n border-color: #c0c0c0;\n }\n \n .depth-3 {\n margin-left: 72px;\n }\n .depth-3 .node-header {\n background: #fdfdfd;\n border-color: #b0b0b0;\n }\n \n .depth-4 {\n margin-left: 96px;\n }\n .depth-4 .node-header {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n \n .depth-5 {\n margin-left: 120px;\n }\n .depth-5 .node-header {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n \n .depth-6 {\n margin-left: 144px;\n }\n .depth-6 .node-header {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n\n /* Root level - higher z-index to hide lines behind it */\n .depth-0 { \n position: relative;\n overflow: hidden;\n z-index: 2;\n }\n .depth-0 .node-header { \n background: #f8f9fa;\n position: relative;\n z-index: 2;\n }\n \n /* Only add left padding for nodes with children (that show chevrons) */\n .depth-0.has-children::before {\n content: '';\n position: absolute;\n left: 12px;\n top: 0;\n width: 2px;\n height: 100%;\n border-left: 2px dotted #c0c7d0;\n z-index: 0; /* Behind everything */\n }\n \n /* Child level - only for nodes that actually have parent chevrons */\n .depth-1 { \n margin-left: 30px;\n padding-left: 12px;\n position: relative;\n z-index: 1;\n }\n .depth-1 .node-header { \n background: #fafbfc;\n position: relative;\n z-index: 1;\n }\n \n /* Horizontal line connecting to each child node - only when parent has children */\n .depth-1::after {\n content: '';\n position: absolute;\n left: -15px;\n top: 12px;\n width: 25px;\n height: 2px;\n border-bottom: 2px dotted #c0c7d0;\n z-index: 1;\n }\n \n /* Visual indicator when details are expanded */\n .tree-node.details-expanded > .node-header {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n border-bottom: 1px solid #2196f3;\n }\n \n .node-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n transition: all 0.2s ease;\n user-select: none;\n position: relative;\n z-index: 5;\n background: white;\n }\n \n .node-header:hover {\n background: var(--gray-700);\n border-color: var(--mj-blue) !important;\n }\n \n /* Sub-agent specific styling */\n .tree-node.type-sub-agent > .node-header {\n border-left: 4px solid var(--mj-blue);\n }\n \n /* Action specific styling */\n .tree-node.type-action > .node-header {\n border-left: 4px solid #4caf50;\n }\n \n .expand-icon {\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n color: #666;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n transition: all 0.2s ease;\n z-index: 10; /* Ensure expand icon is clickable */\n position: relative;\n }\n \n .expand-icon:hover {\n background: #e0e0e0;\n color: #333;\n }\n \n .status-icon {\n width: 20px;\n text-align: center;\n font-size: 14px;\n }\n \n .status-pending { color: #999; }\n .status-running { color: #2196f3; }\n .status-completed { color: #4caf50; }\n .status-failed { color: #f44336; }\n \n .type-icon {\n width: 20px;\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: #666;\n }\n \n .agent-logo-icon {\n width: 16px;\n height: 16px;\n object-fit: cover;\n border-radius: 3px;\n }\n \n .node-name {\n flex: 1;\n font-size: 13px;\n font-weight: 500;\n color: #1a1a1a;\n }\n \n \n .node-duration {\n font-size: 12px;\n color: #666;\n font-weight: 500;\n }\n \n .node-metrics {\n display: flex;\n gap: 12px;\n font-size: 12px;\n }\n \n .tokens {\n color: #666;\n }\n \n .cost {\n color: #2196f3;\n font-weight: 500;\n }\n \n /* Details Toggle Button */\n .details-toggle-btn {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 12px;\n color: #666;\n margin-left: 4px;\n }\n \n .details-toggle-btn:hover {\n background: #f0f0f0;\n border-color: #2196f3;\n color: #2196f3;\n }\n \n .details-toggle-btn:active {\n background: #e3f2fd;\n }\n \n /* When details are expanded, style the button differently */\n .tree-node.details-expanded .details-toggle-btn {\n background: #2196f3;\n border-color: #2196f3;\n color: white;\n }\n \n .tree-node.details-expanded .details-toggle-btn:hover {\n background: #1976d2;\n border-color: #1976d2;\n }\n \n .node-details {\n margin: 0 5px;\n padding: 16px;\n background: var(--gray-600);\n border: 1px solid var(--gray-700);\n border-top: none;\n border-radius: 0 0 6px 6px;\n font-size: 12px;\n position: relative;\n z-index: 4;\n }\n \n .detail-section {\n margin-bottom: 8px;\n }\n \n .detail-section:last-child {\n margin-bottom: 0;\n }\n \n .detail-section.error {\n color: #d32f2f;\n }\n \n .detail-label {\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n margin-bottom: 4px;\n color: #555;\n }\n \n .detail-content {\n white-space: pre-wrap;\n word-break: break-word;\n color: #333;\n line-height: 1.4;\n }\n \n .markdown-details {\n margin: 8px 0 8px 44px;\n padding: 12px;\n background: #f9f9f9;\n border-left: 3px solid #2196f3;\n border-radius: 0 4px 4px 0;\n font-size: 13px;\n }\n \n .markdown h3, .markdown h4 {\n margin: 8px 0 4px 0;\n color: #1a1a1a;\n }\n \n .markdown h3 {\n font-size: 14px;\n }\n \n .markdown h4 {\n font-size: 13px;\n }\n \n .markdown ul {\n margin: 4px 0;\n padding-left: 20px;\n }\n \n .markdown li {\n margin: 2px 0;\n }\n \n .markdown code {\n background: #e8e8e8;\n padding: 1px 4px;\n border-radius: 3px;\n font-size: 12px;\n }\n \n .markdown pre {\n background: #f5f5f5;\n padding: 8px;\n border-radius: 4px;\n overflow-x: auto;\n margin: 4px 0;\n }\n \n .markdown pre code {\n background: none;\n padding: 0;\n }\n \n .markdown strong {\n font-weight: 600;\n color: #1a1a1a;\n }\n \n .markdown em {\n font-style: italic;\n color: #555;\n }\n \n .full-name {\n font-weight: 600;\n color: #1a1a1a;\n margin-bottom: 8px;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n word-wrap: break-word;\n }\n "] }]
562
- }], null, { node: [{
686
+ `, styles: ["\n :host {\n display: block;\n width: 100%;\n }\n \n /* Depth-based indentation - each level indents by 24px */\n .tree-node {\n margin: 4px 0;\n position: relative;\n }\n \n /* Root level nodes (depth 0) */\n .depth-0 { \n margin-left: 0;\n position: relative;\n z-index: 2;\n }\n .depth-0::after {\n display: none;\n }\n .depth-0 .node-header { \n background: #f8f9fa;\n border: 2px solid #e0e0e0;\n font-weight: 600;\n position: relative;\n z-index: 10;\n }\n \n /* Sub-level nodes with increasing indentation */\n .depth-1 {\n margin-left: 24px;\n }\n .depth-1 .node-header {\n background: #fafafa;\n border-color: #d0d0d0;\n }\n \n .depth-2 {\n margin-left: 48px;\n }\n .depth-2 .node-header {\n background: #fcfcfc;\n border-color: #c0c0c0;\n }\n \n .depth-3 {\n margin-left: 72px;\n }\n .depth-3 .node-header {\n background: #fdfdfd;\n border-color: #b0b0b0;\n }\n \n .depth-4 {\n margin-left: 96px;\n }\n .depth-4 .node-header {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n \n .depth-5 {\n margin-left: 120px;\n }\n .depth-5 .node-header {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n \n .depth-6 {\n margin-left: 144px;\n }\n .depth-6 .node-header {\n background: #fefefe;\n border-color: #a0a0a0;\n }\n\n /* Root level - higher z-index to hide lines behind it */\n .depth-0 { \n position: relative;\n overflow: hidden;\n z-index: 2;\n }\n .depth-0 .node-header { \n background: #f8f9fa;\n position: relative;\n z-index: 2;\n }\n \n /* Only add left padding for nodes with children (that show chevrons) */\n .depth-0.has-children::before {\n content: '';\n position: absolute;\n left: 12px;\n top: 0;\n width: 2px;\n height: 100%;\n border-left: 2px dotted #c0c7d0;\n z-index: 0; /* Behind everything */\n }\n \n /* Child level - only for nodes that actually have parent chevrons */\n .depth-1 { \n margin-left: 30px;\n padding-left: 12px;\n position: relative;\n z-index: 1;\n }\n .depth-1 .node-header { \n background: #fafbfc;\n position: relative;\n z-index: 1;\n }\n \n /* Horizontal line connecting to each child node - only when parent has children */\n .depth-1::after {\n content: '';\n position: absolute;\n left: -15px;\n top: 12px;\n width: 25px;\n height: 2px;\n border-bottom: 2px dotted #c0c7d0;\n z-index: 1;\n }\n \n /* Visual indicator when details are expanded */\n .tree-node.details-expanded > .node-header {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n border-bottom: 1px solid #2196f3;\n }\n \n .node-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n transition: all 0.2s ease;\n user-select: none;\n position: relative;\n z-index: 5;\n background: white;\n }\n \n .node-header:hover {\n background: var(--gray-700);\n border-color: var(--mj-blue) !important;\n }\n \n /* Sub-agent specific styling */\n .tree-node.type-sub-agent > .node-header {\n border-left: 4px solid var(--mj-blue);\n }\n \n /* Action specific styling */\n .tree-node.type-action > .node-header {\n border-left: 4px solid #4caf50;\n }\n \n .expand-icon {\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n color: #666;\n font-size: 10px;\n cursor: pointer;\n border-radius: 3px;\n transition: all 0.2s ease;\n z-index: 10; /* Ensure expand icon is clickable */\n position: relative;\n }\n \n .expand-icon:hover {\n background: #e0e0e0;\n color: #333;\n }\n \n .status-icon {\n width: 20px;\n text-align: center;\n font-size: 14px;\n }\n \n .status-pending { color: #999; }\n .status-running { color: #2196f3; }\n .status-completed { color: #4caf50; }\n .status-failed { color: #f44336; }\n \n .type-icon {\n width: 20px;\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: #666;\n }\n \n .agent-logo-icon {\n width: 16px;\n height: 16px;\n object-fit: cover;\n border-radius: 3px;\n }\n \n .node-name {\n flex: 1;\n font-size: 13px;\n font-weight: 500;\n color: #1a1a1a;\n }\n \n \n .node-duration {\n font-size: 12px;\n color: #666;\n font-weight: 500;\n }\n \n .node-metrics {\n display: flex;\n gap: 12px;\n font-size: 12px;\n }\n \n .tokens {\n color: #666;\n }\n \n .cost {\n color: #2196f3;\n font-weight: 500;\n }\n \n /* Details Toggle Button */\n .details-toggle-btn {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 12px;\n color: #666;\n margin-left: 4px;\n }\n \n .details-toggle-btn:hover {\n background: #f0f0f0;\n border-color: #2196f3;\n color: #2196f3;\n }\n \n .details-toggle-btn:active {\n background: #e3f2fd;\n }\n \n /* When details are expanded, style the button differently */\n .tree-node.details-expanded .details-toggle-btn {\n background: #2196f3;\n border-color: #2196f3;\n color: white;\n }\n \n .tree-node.details-expanded .details-toggle-btn:hover {\n background: #1976d2;\n border-color: #1976d2;\n }\n \n .node-details {\n margin: 0 5px;\n padding: 16px;\n background: var(--gray-600);\n border: 1px solid var(--gray-700);\n border-top: none;\n border-radius: 0 0 6px 6px;\n font-size: 12px;\n position: relative;\n z-index: 4;\n }\n \n .detail-section {\n margin-bottom: 8px;\n }\n \n .detail-section:last-child {\n margin-bottom: 0;\n }\n \n .detail-section.error {\n color: #d32f2f;\n }\n \n .detail-label {\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n margin-bottom: 4px;\n color: #555;\n }\n \n .detail-content {\n white-space: pre-wrap;\n word-break: break-word;\n color: #333;\n line-height: 1.4;\n }\n \n .markdown-details {\n padding: 16px 16px 0 16px;\n background: var(--gray-600);\n border: 1px solid var(--gray-700);\n border-bottom: none;\n border-top: none;\n margin: 0 5px;\n }\n \n .markdown h3, .markdown h4 {\n margin: 8px 0 4px 0;\n color: #1a1a1a;\n }\n \n .markdown h3 {\n font-size: 14px;\n }\n \n .markdown h4 {\n font-size: 13px;\n }\n \n .markdown ul {\n margin: 4px 0;\n padding-left: 20px;\n }\n \n .markdown li {\n margin: 2px 0;\n }\n \n .markdown code {\n background: #e8e8e8;\n padding: 1px 4px;\n border-radius: 3px;\n font-size: 12px;\n }\n \n .markdown pre {\n background: #f5f5f5;\n padding: 8px;\n border-radius: 4px;\n overflow-x: auto;\n margin: 4px 0;\n }\n \n .markdown pre code {\n background: none;\n padding: 0;\n }\n \n .markdown strong {\n font-weight: 600;\n color: #1a1a1a;\n }\n \n .markdown em {\n font-style: italic;\n color: #555;\n }\n \n .full-name {\n font-weight: 600;\n color: #1a1a1a;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n word-wrap: break-word;\n }\n "] }]
687
+ }], null, { step: [{
563
688
  type: Input
564
689
  }], depth: [{
565
690
  type: Input
691
+ }], agentPath: [{
692
+ type: Input
693
+ }], expanded: [{
694
+ type: Input
695
+ }], detailsExpanded: [{
696
+ type: Input
697
+ }], overrideDisplayStatus: [{
698
+ type: Input
566
699
  }], toggleNode: [{
567
700
  type: Output
701
+ }], toggleDetails: [{
702
+ type: Output
568
703
  }], userInteracted: [{
569
704
  type: Output
570
705
  }] }); })();
571
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ExecutionNodeComponent, { className: "ExecutionNodeComponent", filePath: "lib/agent-execution-node.component.ts", lineNumber: 568 }); })();
706
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ExecutionNodeComponent, { className: "ExecutionNodeComponent", filePath: "lib/agent-execution-node.component.ts", lineNumber: 556 }); })();
572
707
  //# sourceMappingURL=agent-execution-node.component.js.map