@memberjunction/ng-flow-editor 6.2.0-edge.0 → 6.2.0-edge.2

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 (46) hide show
  1. package/dist/lib/agent-editor/agent-flow-transformer.service.d.ts +17 -5
  2. package/dist/lib/agent-editor/agent-flow-transformer.service.d.ts.map +1 -1
  3. package/dist/lib/agent-editor/agent-flow-transformer.service.js +70 -12
  4. package/dist/lib/agent-editor/agent-flow-transformer.service.js.map +1 -1
  5. package/dist/lib/agent-editor/agent-properties-panel.component.d.ts +250 -7
  6. package/dist/lib/agent-editor/agent-properties-panel.component.d.ts.map +1 -1
  7. package/dist/lib/agent-editor/agent-properties-panel.component.js +1769 -272
  8. package/dist/lib/agent-editor/agent-properties-panel.component.js.map +1 -1
  9. package/dist/lib/agent-editor/agent-step-list.component.d.ts +2 -0
  10. package/dist/lib/agent-editor/agent-step-list.component.d.ts.map +1 -1
  11. package/dist/lib/agent-editor/agent-step-list.component.js +15 -2
  12. package/dist/lib/agent-editor/agent-step-list.component.js.map +1 -1
  13. package/dist/lib/agent-editor/decision-step-config.d.ts +27 -0
  14. package/dist/lib/agent-editor/decision-step-config.d.ts.map +1 -0
  15. package/dist/lib/agent-editor/decision-step-config.js +70 -0
  16. package/dist/lib/agent-editor/decision-step-config.js.map +1 -0
  17. package/dist/lib/agent-editor/flow-agent-editor.component.d.ts +39 -5
  18. package/dist/lib/agent-editor/flow-agent-editor.component.d.ts.map +1 -1
  19. package/dist/lib/agent-editor/flow-agent-editor.component.js +182 -46
  20. package/dist/lib/agent-editor/flow-agent-editor.component.js.map +1 -1
  21. package/dist/lib/agent-editor/flow-run-check.d.ts +32 -0
  22. package/dist/lib/agent-editor/flow-run-check.d.ts.map +1 -0
  23. package/dist/lib/agent-editor/flow-run-check.js +146 -0
  24. package/dist/lib/agent-editor/flow-run-check.js.map +1 -0
  25. package/dist/lib/components/flow-editor.component.d.ts +2 -0
  26. package/dist/lib/components/flow-editor.component.d.ts.map +1 -1
  27. package/dist/lib/components/flow-editor.component.js +22 -9
  28. package/dist/lib/components/flow-editor.component.js.map +1 -1
  29. package/dist/lib/components/flow-node.component.js.map +1 -1
  30. package/dist/lib/components/flow-palette.component.d.ts +2 -0
  31. package/dist/lib/components/flow-palette.component.d.ts.map +1 -1
  32. package/dist/lib/components/flow-palette.component.js +5 -1
  33. package/dist/lib/components/flow-palette.component.js.map +1 -1
  34. package/dist/lib/flow-editor.module.d.ts +1 -1
  35. package/dist/lib/flow-editor.module.d.ts.map +1 -1
  36. package/dist/lib/flow-editor.module.js +4 -1
  37. package/dist/lib/flow-editor.module.js.map +1 -1
  38. package/dist/lib/interfaces/flow-types.d.ts +5 -0
  39. package/dist/lib/interfaces/flow-types.d.ts.map +1 -1
  40. package/dist/lib/interfaces/flow-types.js +0 -4
  41. package/dist/lib/interfaces/flow-types.js.map +1 -1
  42. package/dist/public-api.d.ts +1 -0
  43. package/dist/public-api.d.ts.map +1 -1
  44. package/dist/public-api.js +1 -0
  45. package/dist/public-api.js.map +1 -1
  46. package/package.json +10 -9
@@ -1,5 +1,6 @@
1
1
  import { MJAIAgentStepEntity, MJAIAgentStepPathEntity } from '@memberjunction/core-entities';
2
2
  import { FlowNode, FlowConnection, FlowNodeTypeConfig } from '../interfaces/flow-types';
3
+ import { type FlowRunProblem } from './flow-run-check';
3
4
  import * as i0 from "@angular/core";
4
5
  /** Picker item shape for Actions with optional icon */
5
6
  export interface ActionPickerItem {
@@ -20,10 +21,16 @@ export declare const AGENT_STEP_TYPE_CONFIGS: FlowNodeTypeConfig[];
20
21
  * Transforms MJ AIAgentStep/Path entities to/from generic FlowNode/FlowConnection models.
21
22
  */
22
23
  export declare class AgentFlowTransformerService {
23
- /** Convert MJ step entities to generic FlowNodes */
24
- StepsToNodes(steps: MJAIAgentStepEntity[], actions?: ActionPickerItem[], agents?: AgentPickerItem[]): FlowNode[];
25
- /** Convert MJ path entities to generic FlowConnections */
26
- PathsToConnections(paths: MJAIAgentStepPathEntity[]): FlowConnection[];
24
+ /** Convert MJ step entities to generic FlowNodes, each warning about its share of `problems` */
25
+ StepsToNodes(steps: MJAIAgentStepEntity[], actions?: ActionPickerItem[], agents?: AgentPickerItem[], problems?: readonly FlowRunProblem[]): FlowNode[];
26
+ /** Convert MJ path entities to generic FlowConnections, each flagging its share of `problems` */
27
+ PathsToConnections(paths: MJAIAgentStepPathEntity[], problems?: readonly FlowRunProblem[]): FlowConnection[];
28
+ /**
29
+ * What a step's node warns about: its own missing configuration, then each flow-check problem on the
30
+ * step that is not already that. A path's problem is flagged on the path instead. Nothing for a
31
+ * disabled step, which the author has taken out of the flow.
32
+ */
33
+ BuildNodeWarning(step: MJAIAgentStepEntity, problems?: readonly FlowRunProblem[]): string | null;
27
34
  /** Build the subtitle for a step based on its configured action/prompt/agent */
28
35
  BuildStepSubtitle(step: MJAIAgentStepEntity): string;
29
36
  /** Apply FlowNode position changes back to a step entity */
@@ -57,7 +64,7 @@ export declare class AgentFlowTransformerService {
57
64
  };
58
65
  private resolveLoopBodyIcon;
59
66
  /** Convert a single MJ step entity to a FlowNode (public for direct use when adding nodes) */
60
- StepToNode(step: MJAIAgentStepEntity, actions?: ActionPickerItem[], agents?: AgentPickerItem[]): FlowNode;
67
+ StepToNode(step: MJAIAgentStepEntity, actions?: ActionPickerItem[], agents?: AgentPickerItem[], problems?: readonly FlowRunProblem[]): FlowNode;
61
68
  private pathToConnection;
62
69
  /**
63
70
  * What an edge says on the canvas, and what it says on inspection.
@@ -72,6 +79,11 @@ export declare class AgentFlowTransformerService {
72
79
  * rule removes most of the clutter on a real graph, because most edges are unconditional.
73
80
  */
74
81
  private buildPathVisuals;
82
+ /**
83
+ * An edge the flow check refuses keeps its label but turns red with a warning icon, and its detail
84
+ * leads with why — so a broken condition is visible on the canvas without selecting the path.
85
+ */
86
+ private withPathProblems;
75
87
  /**
76
88
  * This path's position among its conditional siblings, in the order the dispatcher checks them.
77
89
  *
@@ -1 +1 @@
1
- {"version":3,"file":"agent-flow-transformer.service.d.ts","sourceRoot":"","sources":["../../../src/lib/agent-editor/agent-flow-transformer.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAuB,kBAAkB,EAAgB,MAAM,0BAA0B,CAAC;;AAG3H,uDAAuD;AACvD,MAAM,WAAW,gBAAgB;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAAE;AAE1F,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAAE;AAElH,gDAAgD;AAChD,eAAO,MAAM,uBAAuB,EAAE,kBAAkB,EAwDvD,CAAC;AASF;;GAEG;AACH,qBACa,2BAA2B;IAEtC,oDAAoD;IACpD,YAAY,CACV,KAAK,EAAE,mBAAmB,EAAE,EAC5B,OAAO,CAAC,EAAE,gBAAgB,EAAE,EAC5B,MAAM,CAAC,EAAE,eAAe,EAAE,GACzB,QAAQ,EAAE;IAIb,0DAA0D;IAC1D,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,EAAE,GAAG,cAAc,EAAE;IAItE,gFAAgF;IAChF,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM;IAiBpD,4DAA4D;IAC5D,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI;IASlE,kDAAkD;IAClD,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC;IASrD;;;OAGG;IACH,yBAAyB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI;IAgBnE,OAAO,CAAC,uBAAuB;IAW/B;;;OAGG;IACH,0BAA0B,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO;IAgB9D,OAAO,CAAC,0BAA0B;IAWlC;;;;;;;;OAQG;IACH,eAAe,CACb,IAAI,EAAE,mBAAmB,EACzB,OAAO,CAAC,EAAE,gBAAgB,EAAE,EAC5B,MAAM,CAAC,EAAE,eAAe,EAAE,GACzB;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;IAwB5C,OAAO,CAAC,mBAAmB;IAsB3B,8FAA8F;IAC9F,UAAU,CACR,IAAI,EAAE,mBAAmB,EACzB,OAAO,CAAC,EAAE,gBAAgB,EAAE,EAC5B,MAAM,CAAC,EAAE,eAAe,EAAE,GACzB,QAAQ;IA0DX,OAAO,CAAC,gBAAgB;IAgDxB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,gBAAgB;IAuDxB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,eAAe;IAavB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IASrB,qEAAqE;IACrE,OAAO,CAAC,gBAAgB;IA4BxB,wEAAwE;IACxE,OAAO,CAAC,2BAA2B;IAmBnC,oCAAoC;IACpC,OAAO,CAAC,eAAe;IASvB,qCAAqC;IACrC,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,iBAAiB;IAOzB,2DAA2D;IAC3D,OAAO,CAAC,mBAAmB;IAS3B,8DAA8D;IAC9D,OAAO,CAAC,eAAe;IASvB,gEAAgE;IAChE,yBAAyB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM;IAa5D,OAAO,CAAC,iBAAiB;yCA3fd,2BAA2B;6CAA3B,2BAA2B;CAggBvC"}
1
+ {"version":3,"file":"agent-flow-transformer.service.d.ts","sourceRoot":"","sources":["../../../src/lib/agent-editor/agent-flow-transformer.service.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  import { Injectable } from '@angular/core';
2
2
  import { UUIDsEqual } from '@memberjunction/global';
3
+ import { ReadFlowDecisionStepConfiguration } from '@memberjunction/ai-core-plus';
4
+ import { PathRunProblems, StepRunProblems } from './flow-run-check';
3
5
  import * as i0 from "@angular/core";
4
6
  /** Step types mapped to visual configuration */
5
7
  export const AGENT_STEP_TYPE_CONFIGS = [
@@ -25,6 +27,17 @@ export const AGENT_STEP_TYPE_CONFIGS = [
25
27
  { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }
26
28
  ]
27
29
  },
30
+ {
31
+ Type: 'Decision',
32
+ Label: 'Decision',
33
+ Icon: 'fa-scale-balanced',
34
+ Color: '#0891b2',
35
+ Category: 'Steps',
36
+ DefaultPorts: [
37
+ { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },
38
+ { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }
39
+ ]
40
+ },
28
41
  {
29
42
  Type: 'Sub-Agent',
30
43
  Label: 'Sub-Agent',
@@ -69,13 +82,25 @@ function ordinal(n) {
69
82
  * Transforms MJ AIAgentStep/Path entities to/from generic FlowNode/FlowConnection models.
70
83
  */
71
84
  export class AgentFlowTransformerService {
72
- /** Convert MJ step entities to generic FlowNodes */
73
- StepsToNodes(steps, actions, agents) {
74
- return steps.map(step => this.StepToNode(step, actions, agents));
85
+ /** Convert MJ step entities to generic FlowNodes, each warning about its share of `problems` */
86
+ StepsToNodes(steps, actions, agents, problems = []) {
87
+ return steps.map(step => this.StepToNode(step, actions, agents, problems));
75
88
  }
76
- /** Convert MJ path entities to generic FlowConnections */
77
- PathsToConnections(paths) {
78
- return paths.map(path => this.pathToConnection(path, paths));
89
+ /** Convert MJ path entities to generic FlowConnections, each flagging its share of `problems` */
90
+ PathsToConnections(paths, problems = []) {
91
+ return paths.map(path => this.pathToConnection(path, paths, problems));
92
+ }
93
+ /**
94
+ * What a step's node warns about: its own missing configuration, then each flow-check problem on the
95
+ * step that is not already that. A path's problem is flagged on the path instead. Nothing for a
96
+ * disabled step, which the author has taken out of the flow.
97
+ */
98
+ BuildNodeWarning(step, problems = []) {
99
+ if (this.MapStepStatus(step.Status) === 'disabled')
100
+ return null;
101
+ const flow = StepRunProblems(problems, step.ID).map(p => p.Message);
102
+ const messages = [this.BuildConfigWarningMessage(step), ...flow].filter((m) => !!m);
103
+ return messages.length > 0 ? messages.join('\n') : null;
79
104
  }
80
105
  /** Build the subtitle for a step based on its configured action/prompt/agent */
81
106
  BuildStepSubtitle(step) {
@@ -90,6 +115,14 @@ export class AgentFlowTransformerService {
90
115
  return this.buildLoopSubtitle(step, 'For Each');
91
116
  case 'While':
92
117
  return this.buildLoopSubtitle(step, 'While');
118
+ case 'Decision': {
119
+ const read = ReadFlowDecisionStepConfiguration(step.Configuration);
120
+ if ('Config' in read) {
121
+ const count = Object.keys(read.Config.questions || {}).length;
122
+ return `${read.Config.key} · ${count} ${count === 1 ? 'question' : 'questions'}`;
123
+ }
124
+ return 'Unconfigured';
125
+ }
93
126
  default:
94
127
  return step.StepType;
95
128
  }
@@ -127,6 +160,10 @@ export class AgentFlowTransformerService {
127
160
  case 'ForEach':
128
161
  case 'While':
129
162
  return this.buildLoopWarningMessage(step);
163
+ case 'Decision': {
164
+ const read = ReadFlowDecisionStepConfiguration(step.Configuration);
165
+ return 'Error' in read ? read.Error : null;
166
+ }
130
167
  default:
131
168
  return null;
132
169
  }
@@ -157,6 +194,10 @@ export class AgentFlowTransformerService {
157
194
  case 'ForEach':
158
195
  case 'While':
159
196
  return this.isLoopBodyMissingReference(step);
197
+ case 'Decision': {
198
+ const read = ReadFlowDecisionStepConfiguration(step.Configuration);
199
+ return 'Error' in read;
200
+ }
160
201
  default:
161
202
  return false;
162
203
  }
@@ -216,7 +257,7 @@ export class AgentFlowTransformerService {
216
257
  }
217
258
  // ── Public Conversion Methods ───────────────────────────────
218
259
  /** Convert a single MJ step entity to a FlowNode (public for direct use when adding nodes) */
219
- StepToNode(step, actions, agents) {
260
+ StepToNode(step, actions, agents, problems = []) {
220
261
  const stepId = step.ID;
221
262
  const ports = [
222
263
  {
@@ -233,10 +274,10 @@ export class AgentFlowTransformerService {
233
274
  Multiple: true
234
275
  }
235
276
  ];
236
- // Show warning status when the step is missing its required configuration,
237
- // unless the step is explicitly disabled (respect the user's intent).
277
+ // Show warning status when the step is missing its required configuration or the flow check
278
+ // refuses something on it, unless the step is explicitly disabled (respect the user's intent).
238
279
  const baseStatus = this.MapStepStatus(step.Status);
239
- const warningMessage = (baseStatus !== 'disabled') ? this.BuildConfigWarningMessage(step) : null;
280
+ const warningMessage = this.BuildNodeWarning(step, problems);
240
281
  const effectiveStatus = warningMessage ? 'warning' : baseStatus;
241
282
  // Build loop-specific data for ForEach/While nodes
242
283
  const data = { StepEntityID: stepId };
@@ -269,7 +310,7 @@ export class AgentFlowTransformerService {
269
310
  Data: data
270
311
  };
271
312
  }
272
- pathToConnection(path, allPaths) {
313
+ pathToConnection(path, allPaths, problems = []) {
273
314
  const hasCondition = path.Condition != null && path.Condition.trim().length > 0;
274
315
  const isAlwaysPath = !hasCondition;
275
316
  // Analyze sibling paths from the same origin step
@@ -288,7 +329,8 @@ export class AgentFlowTransformerService {
288
329
  ? this.rankWithinGroup(path, conditionalSiblings)
289
330
  : null;
290
331
  // Build label, icon, and visual style
291
- const visual = this.buildPathVisuals(path, hasCondition, isOnlyPath, hasAmbiguousAlways, rank);
332
+ const pathProblems = PathRunProblems(problems, path.ID).map(p => p.Message);
333
+ const visual = this.withPathProblems(this.buildPathVisuals(path, hasCondition, isOnlyPath, hasAmbiguousAlways, rank), pathProblems);
292
334
  return {
293
335
  ID: path.ID,
294
336
  SourceNodeID: path.OriginStepID,
@@ -367,6 +409,22 @@ export class AgentFlowTransformerService {
367
409
  style: 'solid'
368
410
  };
369
411
  }
412
+ /**
413
+ * An edge the flow check refuses keeps its label but turns red with a warning icon, and its detail
414
+ * leads with why — so a broken condition is visible on the canvas without selecting the path.
415
+ */
416
+ withPathProblems(visual, problems) {
417
+ if (problems.length === 0)
418
+ return visual;
419
+ const why = problems.join('\n\n');
420
+ return {
421
+ ...visual,
422
+ labelIcon: 'fa-triangle-exclamation',
423
+ labelIconColor: '#ef4444',
424
+ labelDetail: visual.labelDetail ? `${why}\n\n${visual.labelDetail}` : why,
425
+ color: '#ef4444'
426
+ };
427
+ }
370
428
  /**
371
429
  * This path's position among its conditional siblings, in the order the dispatcher checks them.
372
430
  *
@@ -1 +1 @@
1
- {"version":3,"file":"agent-flow-transformer.service.js","sourceRoot":"","sources":["../../../src/lib/agent-editor/agent-flow-transformer.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { MJAIAgentStepEntity, MJAIAgentStepPathEntity } from '@memberjunction/core-entities';\nimport { FlowNode, FlowConnection, FlowConnectionStyle, FlowNodeTypeConfig, FlowNodePort } from '../interfaces/flow-types';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/** Picker item shape for Actions with optional icon */\nexport interface ActionPickerItem { ID: string; Name: string; IconClass?: string | null; }\n\n/** Picker item shape for Agents with optional icon and logo */\nexport interface AgentPickerItem { ID: string; Name: string; IconClass?: string | null; LogoURL?: string | null; }\n\n/** Step types mapped to visual configuration */\nexport const AGENT_STEP_TYPE_CONFIGS: FlowNodeTypeConfig[] = [\n {\n Type: 'Action',\n Label: 'Action',\n Icon: 'fa-bolt',\n Color: '#3B82F6',\n Category: 'Steps',\n DefaultPorts: [\n { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },\n { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }\n ]\n },\n {\n Type: 'Prompt',\n Label: 'Prompt',\n Icon: 'fa-comment-dots',\n Color: '#8B5CF6',\n Category: 'Steps',\n DefaultPorts: [\n { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },\n { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }\n ]\n },\n {\n Type: 'Sub-Agent',\n Label: 'Sub-Agent',\n Icon: 'fa-robot',\n Color: '#10B981',\n Category: 'Steps',\n DefaultPorts: [\n { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },\n { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }\n ]\n },\n {\n Type: 'ForEach',\n Label: 'For Each',\n Icon: 'fa-arrows-repeat',\n Color: '#F59E0B',\n Category: 'Loops',\n DefaultPorts: [\n { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },\n { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }\n ]\n },\n {\n Type: 'While',\n Label: 'While',\n Icon: 'fa-rotate',\n Color: '#F97316',\n Category: 'Loops',\n DefaultPorts: [\n { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },\n { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }\n ]\n }\n];\n\n/** \"1st\", \"2nd\", \"3rd\", … for the precedence note on an exclusive branch. */\nfunction ordinal(n: number): string {\n const suffix = n % 100 >= 11 && n % 100 <= 13 ? 'th'\n : ['th', 'st', 'nd', 'rd'][n % 10] ?? 'th';\n return `${n}${suffix}`;\n}\n\n/**\n * Transforms MJ AIAgentStep/Path entities to/from generic FlowNode/FlowConnection models.\n */\n@Injectable()\nexport class AgentFlowTransformerService {\n\n /** Convert MJ step entities to generic FlowNodes */\n StepsToNodes(\n steps: MJAIAgentStepEntity[],\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[]\n ): FlowNode[] {\n return steps.map(step => this.StepToNode(step, actions, agents));\n }\n\n /** Convert MJ path entities to generic FlowConnections */\n PathsToConnections(paths: MJAIAgentStepPathEntity[]): FlowConnection[] {\n return paths.map(path => this.pathToConnection(path, paths));\n }\n\n /** Build the subtitle for a step based on its configured action/prompt/agent */\n BuildStepSubtitle(step: MJAIAgentStepEntity): string {\n switch (step.StepType) {\n case 'Action':\n return step.Action ? `Action: ${step.Action}` : 'No action selected';\n case 'Prompt':\n return step.Prompt ? `Prompt: ${step.Prompt}` : 'No prompt selected';\n case 'Sub-Agent':\n return step.SubAgent ? `Agent: ${step.SubAgent}` : 'No sub-agent selected';\n case 'ForEach':\n return this.buildLoopSubtitle(step, 'For Each');\n case 'While':\n return this.buildLoopSubtitle(step, 'While');\n default:\n return step.StepType;\n }\n }\n\n /** Apply FlowNode position changes back to a step entity */\n ApplyNodePosition(step: MJAIAgentStepEntity, node: FlowNode): void {\n step.PositionX = Math.round(node.Position.X);\n step.PositionY = Math.round(node.Position.Y);\n if (node.Size) {\n step.Width = Math.round(node.Size.Width);\n step.Height = Math.round(node.Size.Height);\n }\n }\n\n /** Map FlowNode status from step entity status */\n MapStepStatus(stepStatus: string): FlowNode['Status'] {\n switch (stepStatus) {\n case 'Active': return 'default';\n case 'Disabled': return 'disabled';\n case 'Pending': return 'pending';\n default: return 'default';\n }\n }\n\n /**\n * Returns a short human-readable message describing what's missing,\n * or null if the step is fully configured.\n */\n BuildConfigWarningMessage(step: MJAIAgentStepEntity): string | null {\n switch (step.StepType) {\n case 'Action':\n return !step.ActionID ? 'No action selected' : null;\n case 'Prompt':\n return !step.PromptID ? 'No prompt selected' : null;\n case 'Sub-Agent':\n return !step.SubAgentID ? 'No sub-agent selected' : null;\n case 'ForEach':\n case 'While':\n return this.buildLoopWarningMessage(step);\n default:\n return null;\n }\n }\n\n private buildLoopWarningMessage(step: MJAIAgentStepEntity): string | null {\n const bodyType = step.LoopBodyType;\n if (!bodyType) return 'No loop body type selected';\n switch (bodyType) {\n case 'Action': return !step.ActionID ? 'No action selected for loop body' : null;\n case 'Prompt': return !step.PromptID ? 'No prompt selected for loop body' : null;\n case 'Sub-Agent': return !step.SubAgentID ? 'No sub-agent selected for loop body' : null;\n default: return null;\n }\n }\n\n /**\n * Returns true when a step is missing its required configuration reference\n * (e.g., an Action step with no ActionID, a Prompt step with no PromptID).\n */\n IsStepMissingConfiguration(step: MJAIAgentStepEntity): boolean {\n switch (step.StepType) {\n case 'Action':\n return !step.ActionID;\n case 'Prompt':\n return !step.PromptID;\n case 'Sub-Agent':\n return !step.SubAgentID;\n case 'ForEach':\n case 'While':\n return this.isLoopBodyMissingReference(step);\n default:\n return false;\n }\n }\n\n private isLoopBodyMissingReference(step: MJAIAgentStepEntity): boolean {\n const bodyType = step.LoopBodyType;\n if (!bodyType) return true; // No body type selected at all\n switch (bodyType) {\n case 'Action': return !step.ActionID;\n case 'Prompt': return !step.PromptID;\n case 'Sub-Agent': return !step.SubAgentID;\n default: return false;\n }\n }\n\n /**\n * Resolve the best icon and optional logo URL for a step based on its\n * configured action/agent and available picker data.\n *\n * Resolution chain:\n * - Action step: action's IconClass -> step-type fallback\n * - Sub-Agent step: agent's LogoURL (stored in Data) -> agent's IconClass -> step-type fallback\n * - Other steps: step-type icon\n */\n ResolveStepIcon(\n step: MJAIAgentStepEntity,\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[]\n ): { Icon: string; LogoURL?: string | null } {\n const fallbackIcon = this.getIconForType(step.StepType);\n\n if (step.StepType === 'Action' && step.ActionID && actions) {\n const action = actions.find(a => UUIDsEqual(a.ID, step.ActionID));\n return { Icon: action?.IconClass || fallbackIcon };\n }\n\n if (step.StepType === 'Sub-Agent' && step.SubAgentID && agents) {\n const agent = agents.find(a => UUIDsEqual(a.ID, step.SubAgentID));\n if (agent?.LogoURL) {\n return { Icon: agent.IconClass || fallbackIcon, LogoURL: agent.LogoURL };\n }\n return { Icon: agent?.IconClass || fallbackIcon };\n }\n\n // For loop steps, resolve based on loop body type\n if ((step.StepType === 'ForEach' || step.StepType === 'While') && step.LoopBodyType) {\n return this.resolveLoopBodyIcon(step, actions, agents);\n }\n\n return { Icon: fallbackIcon };\n }\n\n private resolveLoopBodyIcon(\n step: MJAIAgentStepEntity,\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[]\n ): { Icon: string; LogoURL?: string | null } {\n const fallbackIcon = this.getIconForType(step.StepType);\n\n if (step.LoopBodyType === 'Action' && step.ActionID && actions) {\n const action = actions.find(a => UUIDsEqual(a.ID, step.ActionID));\n if (action?.IconClass) return { Icon: fallbackIcon }; // Loop keeps its own icon; body icon handled separately\n }\n\n if (step.LoopBodyType === 'Sub-Agent' && step.SubAgentID && agents) {\n const agent = agents.find(a => UUIDsEqual(a.ID, step.SubAgentID));\n if (agent?.LogoURL) return { Icon: fallbackIcon, LogoURL: agent.LogoURL };\n }\n\n return { Icon: fallbackIcon };\n }\n\n // ── Public Conversion Methods ───────────────────────────────\n\n /** Convert a single MJ step entity to a FlowNode (public for direct use when adding nodes) */\n StepToNode(\n step: MJAIAgentStepEntity,\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[]\n ): FlowNode {\n const stepId = step.ID;\n const ports: FlowNodePort[] = [\n {\n ID: `${stepId}-input`,\n Direction: 'input',\n Side: 'top',\n Multiple: true,\n Disabled: step.StartingStep === true\n },\n {\n ID: `${stepId}-output`,\n Direction: 'output',\n Side: 'bottom',\n Multiple: true\n }\n ];\n\n // Show warning status when the step is missing its required configuration,\n // unless the step is explicitly disabled (respect the user's intent).\n const baseStatus = this.MapStepStatus(step.Status);\n const warningMessage = (baseStatus !== 'disabled') ? this.BuildConfigWarningMessage(step) : null;\n const effectiveStatus = warningMessage ? 'warning' : baseStatus;\n\n // Build loop-specific data for ForEach/While nodes\n const data: Record<string, unknown> = { StepEntityID: stepId };\n if (step.StepType === 'ForEach' || step.StepType === 'While') {\n this.populateLoopData(step, data, actions, agents);\n }\n\n // Resolve icon (and optional logo URL) from picker data\n const resolved = this.ResolveStepIcon(step, actions, agents);\n if (resolved.LogoURL) {\n data['LogoURL'] = resolved.LogoURL;\n }\n\n return {\n ID: stepId,\n Type: step.StepType,\n Label: step.Name,\n Subtitle: this.BuildStepSubtitle(step),\n Icon: resolved.Icon,\n Status: effectiveStatus,\n StatusMessage: warningMessage ?? undefined,\n IsStartNode: step.StartingStep === true,\n Position: {\n X: step.PositionX ?? 0,\n Y: step.PositionY ?? 0\n },\n Size: {\n Width: step.Width ?? 220,\n Height: step.Height ?? 100\n },\n Ports: ports,\n Data: data\n };\n }\n\n private pathToConnection(path: MJAIAgentStepPathEntity, allPaths: MJAIAgentStepPathEntity[]): FlowConnection {\n const hasCondition = path.Condition != null && path.Condition.trim().length > 0;\n const isAlwaysPath = !hasCondition;\n\n // Analyze sibling paths from the same origin step\n const siblingPaths = allPaths.filter(p => UUIDsEqual(p.OriginStepID, path.OriginStepID));\n const isOnlyPath = siblingPaths.length === 1;\n const unconditionalSiblings = siblingPaths.filter(\n p => !p.Condition || p.Condition.trim().length === 0\n );\n // Flag as ambiguous when 2+ unconditional paths exist from the same source.\n // Multiple unconditional paths are always ambiguous because only the\n // highest-priority one will execute — regardless of whether they have descriptions.\n const hasAmbiguousAlways = isAlwaysPath && unconditionalSiblings.length > 1;\n\n // Where this path sits in its exclusive group, when it is IN one. Highest Priority wins, ties\n // broken by path ID — and none of that precedence is visible on the canvas today, so someone\n // debugging a fork cannot tell which branch takes it when two conditions are both true.\n const conditionalSiblings = siblingPaths.filter(p => p.Condition && p.Condition.trim().length > 0);\n const rank = hasCondition && conditionalSiblings.length > 1\n ? this.rankWithinGroup(path, conditionalSiblings)\n : null;\n\n // Build label, icon, and visual style\n const visual = this.buildPathVisuals(path, hasCondition, isOnlyPath, hasAmbiguousAlways, rank);\n\n return {\n ID: path.ID,\n SourceNodeID: path.OriginStepID,\n SourcePortID: `${path.OriginStepID}-output`,\n TargetNodeID: path.DestinationStepID,\n TargetPortID: `${path.DestinationStepID}-input`,\n Label: visual.label,\n LabelIcon: visual.labelIcon,\n LabelIconColor: visual.labelIconColor,\n LabelDetail: visual.labelDetail,\n Condition: path.Condition ?? undefined,\n Priority: path.Priority,\n Style: visual.style,\n Color: visual.color,\n Data: {\n PathEntityID: path.ID,\n IsAlwaysPath: !hasCondition,\n HasAmbiguousAlways: hasAmbiguousAlways\n }\n };\n }\n\n /**\n * What an edge says on the canvas, and what it says on inspection.\n *\n * **An edge label answers one question: WHEN is this path taken?** That is the condition. The\n * `Description` is the author's rationale — genuinely useful, and inspection-time content: it is\n * prose, it is arbitrarily long, and rendering it always turned the least important element on the\n * canvas into the most visually dominant one, overlapping nodes and other labels.\n *\n * So the condition is the LABEL (truncated), the description is the DETAIL (the hover tooltip),\n * and an unconditional edge says nothing at all — a plain line already means \"then\". That last\n * rule removes most of the clutter on a real graph, because most edges are unconditional.\n */\n private buildPathVisuals(\n path: MJAIAgentStepPathEntity,\n hasCondition: boolean,\n isOnlyPath: boolean,\n hasAmbiguousAlways: boolean,\n rank: { position: number; total: number } | null = null\n ): { label?: string; labelIcon?: string; labelIconColor?: string; labelDetail?: string; color: string; style: FlowConnectionStyle } {\n const rationale = path.Description?.trim();\n\n // Conditional path — amber dashed, labelled with the RULE.\n if (hasCondition) {\n const condition = path.Condition!.trim();\n // The rank prefix is tiny and always fits, so it survives truncation — which matters, because\n // precedence is exactly what a truncated condition would otherwise hide.\n const prefix = rank ? `${rank.position}/${rank.total} ` : '';\n const precedence = rank\n ? `\\n\\nChecked ${ordinal(rank.position)} of ${rank.total}: highest priority wins, ties by path ID.`\n : '';\n return {\n label: prefix + this.truncateLabel(condition, rank ? 28 : 32),\n labelIcon: 'fa-code-branch',\n labelIconColor: '#f59e0b',\n // Full condition first — a truncated label is only safe if the whole thing is one hover\n // away — then the rationale, then how this branch is chosen against its siblings.\n labelDetail: (rationale ? `${condition}\\n\\n${rationale}` : condition) + precedence,\n color: '#f59e0b',\n style: 'dashed'\n };\n }\n\n // Ambiguous: multiple unconditional paths from the same step. This one KEEPS its label, because\n // it is a defect the author needs to see without hovering anything.\n if (hasAmbiguousAlways) {\n return {\n label: 'Duplicate default',\n labelIcon: 'fa-triangle-exclamation',\n labelIconColor: '#ef4444',\n labelDetail: rationale\n ? `Duplicate default paths: only the highest-priority one will execute.\\n\\n${rationale}`\n : 'Duplicate default paths: only the highest-priority one will execute',\n color: '#ef4444',\n style: 'solid'\n };\n }\n\n // Every other unconditional path — NO LABEL. The line already means \"then\", and \"Default\" on\n // every edge of a linear flow is a caption on each arrow of a diagram saying \"arrow\".\n // The rationale stays reachable on hover.\n return {\n labelDetail: rationale || undefined,\n color: isOnlyPath ? '#64748b' : '#16a34a',\n style: 'solid'\n };\n }\n\n /**\n * This path's position among its conditional siblings, in the order the dispatcher checks them.\n *\n * Mirrors the COMPILER, which is where the order is actually decided: `buildDependencies` sorts a\n * fan-out by `Priority` descending, then path ID ascending, and writes that ordinal into\n * `TaskDependency.Sequence` — which is what `ResolveExclusiveGroups` then reads at runtime. A path\n * row has no `Sequence` of its own and deliberately never has: a compiled edge gets a fresh UUID\n * and needs a stored ordinal to stay deterministic across machines, while a design-time path still\n * has its own stable ID to break the tie with. Ranking here by anything else would disagree with\n * the engine precisely on ties — and `Priority` defaults to 0, so ties are the common case.\n */\n private rankWithinGroup(\n path: MJAIAgentStepPathEntity,\n siblings: MJAIAgentStepPathEntity[]\n ): { position: number; total: number } {\n const ordered = [...siblings].sort((a, b) =>\n (b.Priority ?? 0) - (a.Priority ?? 0) || a.ID.localeCompare(b.ID)\n );\n return {\n position: ordered.findIndex(p => UUIDsEqual(p.ID, path.ID)) + 1,\n total: ordered.length\n };\n }\n\n /**\n * Trims a condition to what fits on an edge without covering its neighbours.\n *\n * Breaks on a word boundary when there is one near the limit, so the visible part stays readable\n * rather than ending mid-identifier. The full text is always in `labelDetail`.\n */\n private truncateLabel(text: string, limit = 32): string {\n const flat = text.replace(/\\s+/g, ' ').trim();\n if (flat.length <= limit) return flat;\n\n const cut = flat.slice(0, limit);\n const lastSpace = cut.lastIndexOf(' ');\n return `${(lastSpace > limit * 0.6 ? cut.slice(0, lastSpace) : cut).trimEnd()}…`;\n }\n\n /** Populate loop-specific display data on the node's Data payload */\n private populateLoopData(\n step: MJAIAgentStepEntity,\n data: Record<string, unknown>,\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[]\n ): void {\n const bodyType = step.LoopBodyType;\n data['LoopBodyType'] = bodyType ?? null;\n data['LoopBodyName'] = bodyType ? this.resolveLoopBodyName(step) : null;\n data['LoopBodyIcon'] = bodyType ? this.resolveLoopBodySpecificIcon(step, actions, agents) : null;\n data['LoopBodyColor'] = bodyType ? this.getBodyTypeColor(bodyType) : null;\n data['LoopIterationSummary'] = this.BuildLoopIterationSummary(step);\n\n // Store logo URL for loop body sub-agents\n if (bodyType === 'Sub-Agent' && step.SubAgentID && agents) {\n const agent = agents.find(a => UUIDsEqual(a.ID, step.SubAgentID));\n if (agent?.LogoURL) {\n data['LoopBodyLogoURL'] = agent.LogoURL;\n }\n }\n\n const config = this.parseLoopConfig(step);\n if (config) {\n data['MaxIterations'] = config['maxIterations'] ?? null;\n data['LoopItemVariable'] = config['itemVariable'] ?? null;\n }\n }\n\n /** Resolve the best icon for a loop body, checking picker data first */\n private resolveLoopBodySpecificIcon(\n step: MJAIAgentStepEntity,\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[]\n ): string {\n const bodyType = step.LoopBodyType;\n const fallback = this.getBodyTypeIcon(bodyType ?? '');\n\n if (bodyType === 'Action' && step.ActionID && actions) {\n const action = actions.find(a => UUIDsEqual(a.ID, step.ActionID));\n return action?.IconClass || fallback;\n }\n if (bodyType === 'Sub-Agent' && step.SubAgentID && agents) {\n const agent = agents.find(a => UUIDsEqual(a.ID, step.SubAgentID));\n return agent?.IconClass || fallback;\n }\n return fallback;\n }\n\n /** Get icon for a loop body type */\n private getBodyTypeIcon(bodyType: string): string {\n switch (bodyType) {\n case 'Action': return 'fa-bolt';\n case 'Prompt': return 'fa-comment-dots';\n case 'Sub-Agent': return 'fa-robot';\n default: return 'fa-circle-nodes';\n }\n }\n\n /** Get color for a loop body type */\n private getBodyTypeColor(bodyType: string): string {\n switch (bodyType) {\n case 'Action': return '#3B82F6';\n case 'Prompt': return '#8B5CF6';\n case 'Sub-Agent': return '#10B981';\n default: return '#6B7280';\n }\n }\n\n private getIconForType(stepType: string): string {\n const config = AGENT_STEP_TYPE_CONFIGS.find(c => c.Type === stepType);\n return config?.Icon ?? 'fa-circle-nodes';\n }\n\n private buildLoopSubtitle(step: MJAIAgentStepEntity, prefix: string): string {\n const bodyType = step.LoopBodyType;\n if (!bodyType) return `${prefix} (no body type)`;\n const bodyName = this.resolveLoopBodyName(step);\n return bodyName ? `${prefix} → ${bodyName}` : `${prefix} → ${bodyType}`;\n }\n\n /** Resolve the display name for the loop body operation */\n private resolveLoopBodyName(step: MJAIAgentStepEntity): string | null {\n switch (step.LoopBodyType) {\n case 'Action': return step.Action ?? null;\n case 'Prompt': return step.Prompt ?? null;\n case 'Sub-Agent': return step.SubAgent ?? null;\n default: return null;\n }\n }\n\n /** Parse the Configuration JSON, returning null on failure */\n private parseLoopConfig(step: MJAIAgentStepEntity): Record<string, unknown> | null {\n if (!step.Configuration) return null;\n try {\n return JSON.parse(step.Configuration) as Record<string, unknown>;\n } catch {\n return null;\n }\n }\n\n /** Build a short iteration summary for display on loop nodes */\n BuildLoopIterationSummary(step: MJAIAgentStepEntity): string {\n const config = this.parseLoopConfig(step);\n if (step.StepType === 'ForEach') {\n const collection = config?.['collectionPath'] as string | undefined;\n return collection ? `over ${collection}` : 'over collection';\n }\n if (step.StepType === 'While') {\n const condition = config?.['condition'] as string | undefined;\n return condition ? `while ${this.truncateCondition(condition)}` : 'while condition';\n }\n return '';\n }\n\n private truncateCondition(condition: string): string {\n const maxLen = 30;\n if (condition.length <= maxLen) return condition;\n return condition.substring(0, maxLen) + '...';\n }\n}\n"]}
1
+ {"version":3,"file":"agent-flow-transformer.service.js","sourceRoot":"","sources":["../../../src/lib/agent-editor/agent-flow-transformer.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { MJAIAgentStepEntity, MJAIAgentStepPathEntity } from '@memberjunction/core-entities';\nimport { FlowNode, FlowConnection, FlowConnectionStyle, FlowNodeTypeConfig, FlowNodePort } from '../interfaces/flow-types';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { ReadFlowDecisionStepConfiguration } from '@memberjunction/ai-core-plus';\nimport { PathRunProblems, StepRunProblems, type FlowRunProblem } from './flow-run-check';\n\n/** Picker item shape for Actions with optional icon */\nexport interface ActionPickerItem { ID: string; Name: string; IconClass?: string | null; }\n\n/** Picker item shape for Agents with optional icon and logo */\nexport interface AgentPickerItem { ID: string; Name: string; IconClass?: string | null; LogoURL?: string | null; }\n\n/** Step types mapped to visual configuration */\nexport const AGENT_STEP_TYPE_CONFIGS: FlowNodeTypeConfig[] = [\n {\n Type: 'Action',\n Label: 'Action',\n Icon: 'fa-bolt',\n Color: '#3B82F6',\n Category: 'Steps',\n DefaultPorts: [\n { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },\n { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }\n ]\n },\n {\n Type: 'Prompt',\n Label: 'Prompt',\n Icon: 'fa-comment-dots',\n Color: '#8B5CF6',\n Category: 'Steps',\n DefaultPorts: [\n { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },\n { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }\n ]\n },\n {\n Type: 'Decision',\n Label: 'Decision',\n Icon: 'fa-scale-balanced',\n Color: '#0891b2',\n Category: 'Steps',\n DefaultPorts: [\n { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },\n { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }\n ]\n },\n {\n Type: 'Sub-Agent',\n Label: 'Sub-Agent',\n Icon: 'fa-robot',\n Color: '#10B981',\n Category: 'Steps',\n DefaultPorts: [\n { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },\n { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }\n ]\n },\n {\n Type: 'ForEach',\n Label: 'For Each',\n Icon: 'fa-arrows-repeat',\n Color: '#F59E0B',\n Category: 'Loops',\n DefaultPorts: [\n { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },\n { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }\n ]\n },\n {\n Type: 'While',\n Label: 'While',\n Icon: 'fa-rotate',\n Color: '#F97316',\n Category: 'Loops',\n DefaultPorts: [\n { ID: 'input', Direction: 'input', Side: 'top', Multiple: true },\n { ID: 'output', Direction: 'output', Side: 'bottom', Multiple: true }\n ]\n }\n];\n\n/** \"1st\", \"2nd\", \"3rd\", … for the precedence note on an exclusive branch. */\nfunction ordinal(n: number): string {\n const suffix = n % 100 >= 11 && n % 100 <= 13 ? 'th'\n : ['th', 'st', 'nd', 'rd'][n % 10] ?? 'th';\n return `${n}${suffix}`;\n}\n\n/** How an edge reads on the canvas. */\ntype PathVisual = {\n label?: string;\n labelIcon?: string;\n labelIconColor?: string;\n labelDetail?: string;\n color: string;\n style: FlowConnectionStyle;\n};\n\n/**\n * Transforms MJ AIAgentStep/Path entities to/from generic FlowNode/FlowConnection models.\n */\n@Injectable()\nexport class AgentFlowTransformerService {\n\n /** Convert MJ step entities to generic FlowNodes, each warning about its share of `problems` */\n StepsToNodes(\n steps: MJAIAgentStepEntity[],\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[],\n problems: readonly FlowRunProblem[] = []\n ): FlowNode[] {\n return steps.map(step => this.StepToNode(step, actions, agents, problems));\n }\n\n /** Convert MJ path entities to generic FlowConnections, each flagging its share of `problems` */\n PathsToConnections(paths: MJAIAgentStepPathEntity[], problems: readonly FlowRunProblem[] = []): FlowConnection[] {\n return paths.map(path => this.pathToConnection(path, paths, problems));\n }\n\n /**\n * What a step's node warns about: its own missing configuration, then each flow-check problem on the\n * step that is not already that. A path's problem is flagged on the path instead. Nothing for a\n * disabled step, which the author has taken out of the flow.\n */\n BuildNodeWarning(step: MJAIAgentStepEntity, problems: readonly FlowRunProblem[] = []): string | null {\n if (this.MapStepStatus(step.Status) === 'disabled') return null;\n const flow = StepRunProblems(problems, step.ID).map(p => p.Message);\n const messages = [this.BuildConfigWarningMessage(step), ...flow].filter((m): m is string => !!m);\n return messages.length > 0 ? messages.join('\\n') : null;\n }\n\n /** Build the subtitle for a step based on its configured action/prompt/agent */\n BuildStepSubtitle(step: MJAIAgentStepEntity): string {\n switch (step.StepType) {\n case 'Action':\n return step.Action ? `Action: ${step.Action}` : 'No action selected';\n case 'Prompt':\n return step.Prompt ? `Prompt: ${step.Prompt}` : 'No prompt selected';\n case 'Sub-Agent':\n return step.SubAgent ? `Agent: ${step.SubAgent}` : 'No sub-agent selected';\n case 'ForEach':\n return this.buildLoopSubtitle(step, 'For Each');\n case 'While':\n return this.buildLoopSubtitle(step, 'While');\n case 'Decision': {\n const read = ReadFlowDecisionStepConfiguration(step.Configuration);\n if ('Config' in read) {\n const count = Object.keys(read.Config.questions || {}).length;\n return `${read.Config.key} · ${count} ${count === 1 ? 'question' : 'questions'}`;\n }\n return 'Unconfigured';\n }\n default:\n return step.StepType;\n }\n }\n\n /** Apply FlowNode position changes back to a step entity */\n ApplyNodePosition(step: MJAIAgentStepEntity, node: FlowNode): void {\n step.PositionX = Math.round(node.Position.X);\n step.PositionY = Math.round(node.Position.Y);\n if (node.Size) {\n step.Width = Math.round(node.Size.Width);\n step.Height = Math.round(node.Size.Height);\n }\n }\n\n /** Map FlowNode status from step entity status */\n MapStepStatus(stepStatus: string): FlowNode['Status'] {\n switch (stepStatus) {\n case 'Active': return 'default';\n case 'Disabled': return 'disabled';\n case 'Pending': return 'pending';\n default: return 'default';\n }\n }\n\n /**\n * Returns a short human-readable message describing what's missing,\n * or null if the step is fully configured.\n */\n BuildConfigWarningMessage(step: MJAIAgentStepEntity): string | null {\n switch (step.StepType) {\n case 'Action':\n return !step.ActionID ? 'No action selected' : null;\n case 'Prompt':\n return !step.PromptID ? 'No prompt selected' : null;\n case 'Sub-Agent':\n return !step.SubAgentID ? 'No sub-agent selected' : null;\n case 'ForEach':\n case 'While':\n return this.buildLoopWarningMessage(step);\n case 'Decision': {\n const read = ReadFlowDecisionStepConfiguration(step.Configuration);\n return 'Error' in read ? read.Error : null;\n }\n default:\n return null;\n }\n }\n\n private buildLoopWarningMessage(step: MJAIAgentStepEntity): string | null {\n const bodyType = step.LoopBodyType;\n if (!bodyType) return 'No loop body type selected';\n switch (bodyType) {\n case 'Action': return !step.ActionID ? 'No action selected for loop body' : null;\n case 'Prompt': return !step.PromptID ? 'No prompt selected for loop body' : null;\n case 'Sub-Agent': return !step.SubAgentID ? 'No sub-agent selected for loop body' : null;\n default: return null;\n }\n }\n\n /**\n * Returns true when a step is missing its required configuration reference\n * (e.g., an Action step with no ActionID, a Prompt step with no PromptID).\n */\n IsStepMissingConfiguration(step: MJAIAgentStepEntity): boolean {\n switch (step.StepType) {\n case 'Action':\n return !step.ActionID;\n case 'Prompt':\n return !step.PromptID;\n case 'Sub-Agent':\n return !step.SubAgentID;\n case 'ForEach':\n case 'While':\n return this.isLoopBodyMissingReference(step);\n case 'Decision': {\n const read = ReadFlowDecisionStepConfiguration(step.Configuration);\n return 'Error' in read;\n }\n default:\n return false;\n }\n }\n\n private isLoopBodyMissingReference(step: MJAIAgentStepEntity): boolean {\n const bodyType = step.LoopBodyType;\n if (!bodyType) return true; // No body type selected at all\n switch (bodyType) {\n case 'Action': return !step.ActionID;\n case 'Prompt': return !step.PromptID;\n case 'Sub-Agent': return !step.SubAgentID;\n default: return false;\n }\n }\n\n /**\n * Resolve the best icon and optional logo URL for a step based on its\n * configured action/agent and available picker data.\n *\n * Resolution chain:\n * - Action step: action's IconClass -> step-type fallback\n * - Sub-Agent step: agent's LogoURL (stored in Data) -> agent's IconClass -> step-type fallback\n * - Other steps: step-type icon\n */\n ResolveStepIcon(\n step: MJAIAgentStepEntity,\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[]\n ): { Icon: string; LogoURL?: string | null } {\n const fallbackIcon = this.getIconForType(step.StepType);\n\n if (step.StepType === 'Action' && step.ActionID && actions) {\n const action = actions.find(a => UUIDsEqual(a.ID, step.ActionID));\n return { Icon: action?.IconClass || fallbackIcon };\n }\n\n if (step.StepType === 'Sub-Agent' && step.SubAgentID && agents) {\n const agent = agents.find(a => UUIDsEqual(a.ID, step.SubAgentID));\n if (agent?.LogoURL) {\n return { Icon: agent.IconClass || fallbackIcon, LogoURL: agent.LogoURL };\n }\n return { Icon: agent?.IconClass || fallbackIcon };\n }\n\n // For loop steps, resolve based on loop body type\n if ((step.StepType === 'ForEach' || step.StepType === 'While') && step.LoopBodyType) {\n return this.resolveLoopBodyIcon(step, actions, agents);\n }\n\n return { Icon: fallbackIcon };\n }\n\n private resolveLoopBodyIcon(\n step: MJAIAgentStepEntity,\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[]\n ): { Icon: string; LogoURL?: string | null } {\n const fallbackIcon = this.getIconForType(step.StepType);\n\n if (step.LoopBodyType === 'Action' && step.ActionID && actions) {\n const action = actions.find(a => UUIDsEqual(a.ID, step.ActionID));\n if (action?.IconClass) return { Icon: fallbackIcon }; // Loop keeps its own icon; body icon handled separately\n }\n\n if (step.LoopBodyType === 'Sub-Agent' && step.SubAgentID && agents) {\n const agent = agents.find(a => UUIDsEqual(a.ID, step.SubAgentID));\n if (agent?.LogoURL) return { Icon: fallbackIcon, LogoURL: agent.LogoURL };\n }\n\n return { Icon: fallbackIcon };\n }\n\n // ── Public Conversion Methods ───────────────────────────────\n\n /** Convert a single MJ step entity to a FlowNode (public for direct use when adding nodes) */\n StepToNode(\n step: MJAIAgentStepEntity,\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[],\n problems: readonly FlowRunProblem[] = []\n ): FlowNode {\n const stepId = step.ID;\n const ports: FlowNodePort[] = [\n {\n ID: `${stepId}-input`,\n Direction: 'input',\n Side: 'top',\n Multiple: true,\n Disabled: step.StartingStep === true\n },\n {\n ID: `${stepId}-output`,\n Direction: 'output',\n Side: 'bottom',\n Multiple: true\n }\n ];\n\n // Show warning status when the step is missing its required configuration or the flow check\n // refuses something on it, unless the step is explicitly disabled (respect the user's intent).\n const baseStatus = this.MapStepStatus(step.Status);\n const warningMessage = this.BuildNodeWarning(step, problems);\n const effectiveStatus = warningMessage ? 'warning' : baseStatus;\n\n // Build loop-specific data for ForEach/While nodes\n const data: Record<string, unknown> = { StepEntityID: stepId };\n if (step.StepType === 'ForEach' || step.StepType === 'While') {\n this.populateLoopData(step, data, actions, agents);\n }\n\n // Resolve icon (and optional logo URL) from picker data\n const resolved = this.ResolveStepIcon(step, actions, agents);\n if (resolved.LogoURL) {\n data['LogoURL'] = resolved.LogoURL;\n }\n\n return {\n ID: stepId,\n Type: step.StepType,\n Label: step.Name,\n Subtitle: this.BuildStepSubtitle(step),\n Icon: resolved.Icon,\n Status: effectiveStatus,\n StatusMessage: warningMessage ?? undefined,\n IsStartNode: step.StartingStep === true,\n Position: {\n X: step.PositionX ?? 0,\n Y: step.PositionY ?? 0\n },\n Size: {\n Width: step.Width ?? 220,\n Height: step.Height ?? 100\n },\n Ports: ports,\n Data: data\n };\n }\n\n private pathToConnection(\n path: MJAIAgentStepPathEntity,\n allPaths: MJAIAgentStepPathEntity[],\n problems: readonly FlowRunProblem[] = []\n ): FlowConnection {\n const hasCondition = path.Condition != null && path.Condition.trim().length > 0;\n const isAlwaysPath = !hasCondition;\n\n // Analyze sibling paths from the same origin step\n const siblingPaths = allPaths.filter(p => UUIDsEqual(p.OriginStepID, path.OriginStepID));\n const isOnlyPath = siblingPaths.length === 1;\n const unconditionalSiblings = siblingPaths.filter(\n p => !p.Condition || p.Condition.trim().length === 0\n );\n // Flag as ambiguous when 2+ unconditional paths exist from the same source.\n // Multiple unconditional paths are always ambiguous because only the\n // highest-priority one will execute — regardless of whether they have descriptions.\n const hasAmbiguousAlways = isAlwaysPath && unconditionalSiblings.length > 1;\n\n // Where this path sits in its exclusive group, when it is IN one. Highest Priority wins, ties\n // broken by path ID — and none of that precedence is visible on the canvas today, so someone\n // debugging a fork cannot tell which branch takes it when two conditions are both true.\n const conditionalSiblings = siblingPaths.filter(p => p.Condition && p.Condition.trim().length > 0);\n const rank = hasCondition && conditionalSiblings.length > 1\n ? this.rankWithinGroup(path, conditionalSiblings)\n : null;\n\n // Build label, icon, and visual style\n const pathProblems = PathRunProblems(problems, path.ID).map(p => p.Message);\n const visual = this.withPathProblems(\n this.buildPathVisuals(path, hasCondition, isOnlyPath, hasAmbiguousAlways, rank),\n pathProblems\n );\n\n return {\n ID: path.ID,\n SourceNodeID: path.OriginStepID,\n SourcePortID: `${path.OriginStepID}-output`,\n TargetNodeID: path.DestinationStepID,\n TargetPortID: `${path.DestinationStepID}-input`,\n Label: visual.label,\n LabelIcon: visual.labelIcon,\n LabelIconColor: visual.labelIconColor,\n LabelDetail: visual.labelDetail,\n Condition: path.Condition ?? undefined,\n Priority: path.Priority,\n Style: visual.style,\n Color: visual.color,\n Data: {\n PathEntityID: path.ID,\n IsAlwaysPath: !hasCondition,\n HasAmbiguousAlways: hasAmbiguousAlways\n }\n };\n }\n\n /**\n * What an edge says on the canvas, and what it says on inspection.\n *\n * **An edge label answers one question: WHEN is this path taken?** That is the condition. The\n * `Description` is the author's rationale — genuinely useful, and inspection-time content: it is\n * prose, it is arbitrarily long, and rendering it always turned the least important element on the\n * canvas into the most visually dominant one, overlapping nodes and other labels.\n *\n * So the condition is the LABEL (truncated), the description is the DETAIL (the hover tooltip),\n * and an unconditional edge says nothing at all — a plain line already means \"then\". That last\n * rule removes most of the clutter on a real graph, because most edges are unconditional.\n */\n private buildPathVisuals(\n path: MJAIAgentStepPathEntity,\n hasCondition: boolean,\n isOnlyPath: boolean,\n hasAmbiguousAlways: boolean,\n rank: { position: number; total: number } | null = null\n ): PathVisual {\n const rationale = path.Description?.trim();\n\n // Conditional path — amber dashed, labelled with the RULE.\n if (hasCondition) {\n const condition = path.Condition!.trim();\n // The rank prefix is tiny and always fits, so it survives truncation — which matters, because\n // precedence is exactly what a truncated condition would otherwise hide.\n const prefix = rank ? `${rank.position}/${rank.total} ` : '';\n const precedence = rank\n ? `\\n\\nChecked ${ordinal(rank.position)} of ${rank.total}: highest priority wins, ties by path ID.`\n : '';\n return {\n label: prefix + this.truncateLabel(condition, rank ? 28 : 32),\n labelIcon: 'fa-code-branch',\n labelIconColor: '#f59e0b',\n // Full condition first — a truncated label is only safe if the whole thing is one hover\n // away — then the rationale, then how this branch is chosen against its siblings.\n labelDetail: (rationale ? `${condition}\\n\\n${rationale}` : condition) + precedence,\n color: '#f59e0b',\n style: 'dashed'\n };\n }\n\n // Ambiguous: multiple unconditional paths from the same step. This one KEEPS its label, because\n // it is a defect the author needs to see without hovering anything.\n if (hasAmbiguousAlways) {\n return {\n label: 'Duplicate default',\n labelIcon: 'fa-triangle-exclamation',\n labelIconColor: '#ef4444',\n labelDetail: rationale\n ? `Duplicate default paths: only the highest-priority one will execute.\\n\\n${rationale}`\n : 'Duplicate default paths: only the highest-priority one will execute',\n color: '#ef4444',\n style: 'solid'\n };\n }\n\n // Every other unconditional path — NO LABEL. The line already means \"then\", and \"Default\" on\n // every edge of a linear flow is a caption on each arrow of a diagram saying \"arrow\".\n // The rationale stays reachable on hover.\n return {\n labelDetail: rationale || undefined,\n color: isOnlyPath ? '#64748b' : '#16a34a',\n style: 'solid'\n };\n }\n\n /**\n * An edge the flow check refuses keeps its label but turns red with a warning icon, and its detail\n * leads with why — so a broken condition is visible on the canvas without selecting the path.\n */\n private withPathProblems(visual: PathVisual, problems: readonly string[]): PathVisual {\n if (problems.length === 0) return visual;\n const why = problems.join('\\n\\n');\n return {\n ...visual,\n labelIcon: 'fa-triangle-exclamation',\n labelIconColor: '#ef4444',\n labelDetail: visual.labelDetail ? `${why}\\n\\n${visual.labelDetail}` : why,\n color: '#ef4444'\n };\n }\n\n /**\n * This path's position among its conditional siblings, in the order the dispatcher checks them.\n *\n * Mirrors the COMPILER, which is where the order is actually decided: `buildDependencies` sorts a\n * fan-out by `Priority` descending, then path ID ascending, and writes that ordinal into\n * `TaskDependency.Sequence` — which is what `ResolveExclusiveGroups` then reads at runtime. A path\n * row has no `Sequence` of its own and deliberately never has: a compiled edge gets a fresh UUID\n * and needs a stored ordinal to stay deterministic across machines, while a design-time path still\n * has its own stable ID to break the tie with. Ranking here by anything else would disagree with\n * the engine precisely on ties — and `Priority` defaults to 0, so ties are the common case.\n */\n private rankWithinGroup(\n path: MJAIAgentStepPathEntity,\n siblings: MJAIAgentStepPathEntity[]\n ): { position: number; total: number } {\n const ordered = [...siblings].sort((a, b) =>\n (b.Priority ?? 0) - (a.Priority ?? 0) || a.ID.localeCompare(b.ID)\n );\n return {\n position: ordered.findIndex(p => UUIDsEqual(p.ID, path.ID)) + 1,\n total: ordered.length\n };\n }\n\n /**\n * Trims a condition to what fits on an edge without covering its neighbours.\n *\n * Breaks on a word boundary when there is one near the limit, so the visible part stays readable\n * rather than ending mid-identifier. The full text is always in `labelDetail`.\n */\n private truncateLabel(text: string, limit = 32): string {\n const flat = text.replace(/\\s+/g, ' ').trim();\n if (flat.length <= limit) return flat;\n\n const cut = flat.slice(0, limit);\n const lastSpace = cut.lastIndexOf(' ');\n return `${(lastSpace > limit * 0.6 ? cut.slice(0, lastSpace) : cut).trimEnd()}…`;\n }\n\n /** Populate loop-specific display data on the node's Data payload */\n private populateLoopData(\n step: MJAIAgentStepEntity,\n data: Record<string, unknown>,\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[]\n ): void {\n const bodyType = step.LoopBodyType;\n data['LoopBodyType'] = bodyType ?? null;\n data['LoopBodyName'] = bodyType ? this.resolveLoopBodyName(step) : null;\n data['LoopBodyIcon'] = bodyType ? this.resolveLoopBodySpecificIcon(step, actions, agents) : null;\n data['LoopBodyColor'] = bodyType ? this.getBodyTypeColor(bodyType) : null;\n data['LoopIterationSummary'] = this.BuildLoopIterationSummary(step);\n\n // Store logo URL for loop body sub-agents\n if (bodyType === 'Sub-Agent' && step.SubAgentID && agents) {\n const agent = agents.find(a => UUIDsEqual(a.ID, step.SubAgentID));\n if (agent?.LogoURL) {\n data['LoopBodyLogoURL'] = agent.LogoURL;\n }\n }\n\n const config = this.parseLoopConfig(step);\n if (config) {\n data['MaxIterations'] = config['maxIterations'] ?? null;\n data['LoopItemVariable'] = config['itemVariable'] ?? null;\n }\n }\n\n /** Resolve the best icon for a loop body, checking picker data first */\n private resolveLoopBodySpecificIcon(\n step: MJAIAgentStepEntity,\n actions?: ActionPickerItem[],\n agents?: AgentPickerItem[]\n ): string {\n const bodyType = step.LoopBodyType;\n const fallback = this.getBodyTypeIcon(bodyType ?? '');\n\n if (bodyType === 'Action' && step.ActionID && actions) {\n const action = actions.find(a => UUIDsEqual(a.ID, step.ActionID));\n return action?.IconClass || fallback;\n }\n if (bodyType === 'Sub-Agent' && step.SubAgentID && agents) {\n const agent = agents.find(a => UUIDsEqual(a.ID, step.SubAgentID));\n return agent?.IconClass || fallback;\n }\n return fallback;\n }\n\n /** Get icon for a loop body type */\n private getBodyTypeIcon(bodyType: string): string {\n switch (bodyType) {\n case 'Action': return 'fa-bolt';\n case 'Prompt': return 'fa-comment-dots';\n case 'Sub-Agent': return 'fa-robot';\n default: return 'fa-circle-nodes';\n }\n }\n\n /** Get color for a loop body type */\n private getBodyTypeColor(bodyType: string): string {\n switch (bodyType) {\n case 'Action': return '#3B82F6';\n case 'Prompt': return '#8B5CF6';\n case 'Sub-Agent': return '#10B981';\n default: return '#6B7280';\n }\n }\n\n private getIconForType(stepType: string): string {\n const config = AGENT_STEP_TYPE_CONFIGS.find(c => c.Type === stepType);\n return config?.Icon ?? 'fa-circle-nodes';\n }\n\n private buildLoopSubtitle(step: MJAIAgentStepEntity, prefix: string): string {\n const bodyType = step.LoopBodyType;\n if (!bodyType) return `${prefix} (no body type)`;\n const bodyName = this.resolveLoopBodyName(step);\n return bodyName ? `${prefix} → ${bodyName}` : `${prefix} → ${bodyType}`;\n }\n\n /** Resolve the display name for the loop body operation */\n private resolveLoopBodyName(step: MJAIAgentStepEntity): string | null {\n switch (step.LoopBodyType) {\n case 'Action': return step.Action ?? null;\n case 'Prompt': return step.Prompt ?? null;\n case 'Sub-Agent': return step.SubAgent ?? null;\n default: return null;\n }\n }\n\n /** Parse the Configuration JSON, returning null on failure */\n private parseLoopConfig(step: MJAIAgentStepEntity): Record<string, unknown> | null {\n if (!step.Configuration) return null;\n try {\n return JSON.parse(step.Configuration) as Record<string, unknown>;\n } catch {\n return null;\n }\n }\n\n /** Build a short iteration summary for display on loop nodes */\n BuildLoopIterationSummary(step: MJAIAgentStepEntity): string {\n const config = this.parseLoopConfig(step);\n if (step.StepType === 'ForEach') {\n const collection = config?.['collectionPath'] as string | undefined;\n return collection ? `over ${collection}` : 'over collection';\n }\n if (step.StepType === 'While') {\n const condition = config?.['condition'] as string | undefined;\n return condition ? `while ${this.truncateCondition(condition)}` : 'while condition';\n }\n return '';\n }\n\n private truncateCondition(condition: string): string {\n const maxLen = 30;\n if (condition.length <= maxLen) return condition;\n return condition.substring(0, maxLen) + '...';\n }\n}\n"]}