@memberjunction/ng-core-entity-forms 5.43.0 → 5.44.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.
Files changed (259) hide show
  1. package/dist/__tests__/model-prediction.logic.test.d.ts +2 -0
  2. package/dist/__tests__/model-prediction.logic.test.d.ts.map +1 -0
  3. package/dist/__tests__/model-prediction.logic.test.js +140 -0
  4. package/dist/__tests__/model-prediction.logic.test.js.map +1 -0
  5. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js +79 -105
  6. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js.map +1 -1
  7. package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js +7 -10
  8. package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js.map +1 -1
  9. package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts.map +1 -1
  10. package/dist/lib/custom/AIAgents/add-action-dialog.component.js +46 -51
  11. package/dist/lib/custom/AIAgents/add-action-dialog.component.js.map +1 -1
  12. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +2 -0
  13. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
  14. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +300 -378
  15. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  16. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +22 -29
  17. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js.map +1 -1
  18. package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +15 -17
  19. package/dist/lib/custom/AIAgents/new-agent-dialog.component.js.map +1 -1
  20. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +27 -34
  21. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js.map +1 -1
  22. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts +11 -0
  23. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts.map +1 -1
  24. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js +48 -47
  25. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js.map +1 -1
  26. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +438 -454
  27. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
  28. package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js +48 -51
  29. package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js.map +1 -1
  30. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +253 -282
  31. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
  32. package/dist/lib/custom/Actions/action-execution-log-form.component.js +24 -33
  33. package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
  34. package/dist/lib/custom/Actions/action-form.component.js +263 -311
  35. package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
  36. package/dist/lib/custom/Entities/entity-form.component.d.ts +6 -0
  37. package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
  38. package/dist/lib/custom/Entities/entity-form.component.js +475 -493
  39. package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
  40. package/dist/lib/custom/Lists/list-form.component.js +122 -173
  41. package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
  42. package/dist/lib/custom/Queries/query-form.component.js +190 -248
  43. package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
  44. package/dist/lib/custom/Queries/query-run-dialog.component.js +19 -23
  45. package/dist/lib/custom/Queries/query-run-dialog.component.js.map +1 -1
  46. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js +23 -24
  47. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js.map +1 -1
  48. package/dist/lib/custom/Templates/template-param-dialog.component.js +14 -23
  49. package/dist/lib/custom/Templates/template-param-dialog.component.js.map +1 -1
  50. package/dist/lib/custom/Tests/test-form.component.js +100 -130
  51. package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
  52. package/dist/lib/custom/Tests/test-run-form.component.js +187 -205
  53. package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
  54. package/dist/lib/custom/Tests/test-suite-form.component.d.ts +8 -0
  55. package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
  56. package/dist/lib/custom/Tests/test-suite-form.component.js +412 -489
  57. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  58. package/dist/lib/custom/Tests/test-suite-run-form.component.js +100 -126
  59. package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
  60. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +166 -184
  61. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js.map +1 -1
  62. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js +42 -61
  63. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js.map +1 -1
  64. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +8 -17
  65. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js.map +1 -1
  66. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts +0 -2
  67. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
  68. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +183 -188
  69. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
  70. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts +108 -0
  71. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts.map +1 -0
  72. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js +665 -0
  73. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js.map +1 -0
  74. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts +94 -0
  75. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts.map +1 -0
  76. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js +257 -0
  77. package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js.map +1 -0
  78. package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts +38 -0
  79. package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts.map +1 -0
  80. package/dist/lib/custom/ai-agent-run/flow/constellation.component.js +200 -0
  81. package/dist/lib/custom/ai-agent-run/flow/constellation.component.js.map +1 -0
  82. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts +44 -0
  83. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts.map +1 -0
  84. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js +180 -0
  85. package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js.map +1 -0
  86. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts +12 -0
  87. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts.map +1 -0
  88. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js +46 -0
  89. package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js.map +1 -0
  90. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts +64 -0
  91. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts.map +1 -0
  92. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js +267 -0
  93. package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js.map +1 -0
  94. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts +53 -0
  95. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts.map +1 -0
  96. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js +111 -0
  97. package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js.map +1 -0
  98. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts +42 -0
  99. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts.map +1 -0
  100. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js +193 -0
  101. package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js.map +1 -0
  102. package/dist/lib/custom/custom-forms.module.d.ts +58 -51
  103. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  104. package/dist/lib/custom/custom-forms.module.js +52 -13
  105. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  106. package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts +2 -0
  107. package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts.map +1 -1
  108. package/dist/lib/custom/shared/entity-selector-dialog.component.js +25 -25
  109. package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
  110. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
  111. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +280 -216
  112. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  113. package/dist/lib/generated/Entities/MJAIAgentChannel/mjaiagentchannel.form.component.js +25 -21
  114. package/dist/lib/generated/Entities/MJAIAgentChannel/mjaiagentchannel.form.component.js.map +1 -1
  115. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.d.ts.map +1 -1
  116. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js +68 -14
  117. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js.map +1 -1
  118. package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.d.ts.map +1 -1
  119. package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js +44 -32
  120. package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js.map +1 -1
  121. package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.d.ts +10 -0
  122. package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.d.ts.map +1 -0
  123. package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.js +66 -0
  124. package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.js.map +1 -0
  125. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.d.ts.map +1 -1
  126. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js +55 -19
  127. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js.map +1 -1
  128. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.d.ts.map +1 -1
  129. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +28 -10
  130. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
  131. package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.d.ts +10 -0
  132. package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.d.ts.map +1 -0
  133. package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.js +167 -0
  134. package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.js.map +1 -0
  135. package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.d.ts +10 -0
  136. package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.d.ts.map +1 -0
  137. package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.js +64 -0
  138. package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.js.map +1 -0
  139. package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.d.ts +10 -0
  140. package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.d.ts.map +1 -0
  141. package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.js +82 -0
  142. package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.js.map +1 -0
  143. package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.d.ts +10 -0
  144. package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.d.ts.map +1 -0
  145. package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.js +64 -0
  146. package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.js.map +1 -0
  147. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.d.ts.map +1 -1
  148. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js +35 -17
  149. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js.map +1 -1
  150. package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.d.ts.map +1 -1
  151. package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js +59 -51
  152. package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js.map +1 -1
  153. package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.d.ts.map +1 -1
  154. package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js +25 -7
  155. package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js.map +1 -1
  156. package/dist/lib/generated/Entities/MJCollectionArtifact/mjcollectionartifact.form.component.js +11 -7
  157. package/dist/lib/generated/Entities/MJCollectionArtifact/mjcollectionartifact.form.component.js.map +1 -1
  158. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.d.ts.map +1 -1
  159. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js +56 -46
  160. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js.map +1 -1
  161. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.d.ts.map +1 -1
  162. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js +73 -59
  163. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js.map +1 -1
  164. package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.d.ts.map +1 -1
  165. package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js +24 -4
  166. package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js.map +1 -1
  167. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
  168. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +137 -87
  169. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  170. package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.d.ts.map +1 -1
  171. package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js +47 -29
  172. package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js.map +1 -1
  173. package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.d.ts +10 -0
  174. package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.d.ts.map +1 -0
  175. package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.js +99 -0
  176. package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.js.map +1 -0
  177. package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.d.ts +10 -0
  178. package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.d.ts.map +1 -0
  179. package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.js +101 -0
  180. package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.js.map +1 -0
  181. package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.d.ts +10 -0
  182. package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.d.ts.map +1 -0
  183. package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.js +115 -0
  184. package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.js.map +1 -0
  185. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.d.ts.map +1 -1
  186. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js +63 -9
  187. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js.map +1 -1
  188. package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.d.ts.map +1 -1
  189. package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js +32 -14
  190. package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js.map +1 -1
  191. package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.d.ts +10 -0
  192. package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.d.ts.map +1 -0
  193. package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.js +161 -0
  194. package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.js.map +1 -0
  195. package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.d.ts +10 -0
  196. package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.d.ts.map +1 -0
  197. package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.js +89 -0
  198. package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.js.map +1 -0
  199. package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.d.ts +10 -0
  200. package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.d.ts.map +1 -0
  201. package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.js +76 -0
  202. package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.js.map +1 -0
  203. package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.d.ts +10 -0
  204. package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.d.ts.map +1 -0
  205. package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js +141 -0
  206. package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js.map +1 -0
  207. package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.d.ts +10 -0
  208. package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.d.ts.map +1 -0
  209. package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.js +88 -0
  210. package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.js.map +1 -0
  211. package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.d.ts +10 -0
  212. package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.d.ts.map +1 -0
  213. package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js +143 -0
  214. package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js.map +1 -0
  215. package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.d.ts +10 -0
  216. package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.d.ts.map +1 -0
  217. package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js +110 -0
  218. package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js.map +1 -0
  219. package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.d.ts.map +1 -1
  220. package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.js +54 -24
  221. package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.js.map +1 -1
  222. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.d.ts.map +1 -1
  223. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js +24 -6
  224. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js.map +1 -1
  225. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.d.ts.map +1 -1
  226. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js +36 -18
  227. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js.map +1 -1
  228. package/dist/lib/generated/Entities/MJSchemaInfo/mjschemainfo.form.component.js +8 -6
  229. package/dist/lib/generated/Entities/MJSchemaInfo/mjschemainfo.form.component.js.map +1 -1
  230. package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.d.ts +10 -0
  231. package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.d.ts.map +1 -0
  232. package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.js +78 -0
  233. package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.js.map +1 -0
  234. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
  235. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +145 -109
  236. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  237. package/dist/lib/generated/generated-forms.module.d.ts +356 -335
  238. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  239. package/dist/lib/generated/generated-forms.module.js +304 -226
  240. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  241. package/dist/lib/panels/ai-agents/agent-realtime.panel.js +44 -44
  242. package/dist/lib/panels/ai-agents/agent-realtime.panel.js.map +1 -1
  243. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts +43 -0
  244. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts.map +1 -0
  245. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js +240 -0
  246. package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js.map +1 -0
  247. package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts +69 -0
  248. package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts.map +1 -0
  249. package/dist/lib/panels/model-predictions/model-prediction.logic.js +130 -0
  250. package/dist/lib/panels/model-predictions/model-prediction.logic.js.map +1 -0
  251. package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts +83 -0
  252. package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts.map +1 -0
  253. package/dist/lib/panels/model-predictions/model-prediction.panel.js +293 -0
  254. package/dist/lib/panels/model-predictions/model-prediction.panel.js.map +1 -0
  255. package/package.json +38 -37
  256. package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts +0 -82
  257. package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts.map +0 -1
  258. package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js +0 -1033
  259. package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js.map +0 -1
@@ -0,0 +1,200 @@
1
+ import { Component, Input, Output, EventEmitter, ViewChild, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
2
+ import { FLOW_COLORS, shortLabel } from './agent-run-flow.model';
3
+ import { svgEl, clip, appendIcon, appendTitle } from './flow-svg.util';
4
+ import { PanZoomController } from './pan-zoom';
5
+ import * as i0 from "@angular/core";
6
+ const _c0 = ["svg"];
7
+ /**
8
+ * Constellation — the agent tree as a star map. Leaves spread evenly around the
9
+ * circle (radial dendrogram) so dense sub-agents don't clump; stars carry the real
10
+ * step/agent icon, ignite in execution order, and pulse energy down curved edges.
11
+ * Labels stay clutter-free (root + top level + active by default, hover to reveal).
12
+ */
13
+ export class ConstellationComponent {
14
+ constructor() {
15
+ this.nodeSelected = new EventEmitter();
16
+ this._model = null;
17
+ this.built = false;
18
+ this.stars = new Map();
19
+ this.edges = [];
20
+ this.hoveredId = -1;
21
+ this.selectedId = -1;
22
+ this.VW = 1200;
23
+ this.VH = 720;
24
+ this.CX = 600;
25
+ this.CY = 360;
26
+ }
27
+ SetSelected(id) { this.selectedId = id ?? -1; }
28
+ ZoomIn() { this.pz?.ZoomIn(); }
29
+ ZoomOut() { this.pz?.ZoomOut(); }
30
+ FitReset() { this.pz?.Reset(); }
31
+ ReapplyView() { this.pz?.Reapply(); }
32
+ ngOnDestroy() { this.pz?.Detach(); }
33
+ set Model(m) { this._model = m; this.built = false; this.clear(); }
34
+ Render(p, ts) {
35
+ if (!this._model)
36
+ return;
37
+ if (!this.built) {
38
+ this.build();
39
+ this.built = true;
40
+ }
41
+ this.update(p, ts);
42
+ }
43
+ clear() {
44
+ this.pz?.Detach();
45
+ this.pz = undefined;
46
+ const svg = this.svgRef?.nativeElement;
47
+ if (svg)
48
+ while (svg.firstChild)
49
+ svg.removeChild(svg.firstChild);
50
+ this.stars.clear();
51
+ this.edges = [];
52
+ this.hoveredId = -1;
53
+ }
54
+ build() {
55
+ const svg = this.svgRef.nativeElement;
56
+ const m = this._model;
57
+ svg.setAttribute('viewBox', `0 0 ${this.VW} ${this.VH}`);
58
+ const bg = svgEl('g', {}, svg);
59
+ let seed = 7;
60
+ const rnd = () => { seed = (seed * 9301 + 49297) % 233280; return seed / 233280; };
61
+ for (let i = 0; i < 150; i++) {
62
+ svgEl('circle', { cx: rnd() * this.VW, cy: rnd() * this.VH, r: rnd() * 1.3 + 0.3, class: 'fstar-bg', opacity: rnd() * 0.3 + 0.04 }, bg);
63
+ }
64
+ const main = svgEl('g', {}, svg);
65
+ const edgeG = svgEl('g', {}, main);
66
+ const nodeG = svgEl('g', {}, main);
67
+ const step = Math.min(150, 300 / Math.max(1, m.maxDepth));
68
+ const leafCount = Math.max(1, m.leaves.length);
69
+ let li = 0;
70
+ const assignAngle = (n) => {
71
+ if (!n.children.length) {
72
+ const a = (li + 0.5) / leafCount * 2 * Math.PI;
73
+ li++;
74
+ n._ang = a;
75
+ return a;
76
+ }
77
+ const cs = n.children.map(c => assignAngle(c));
78
+ n._ang = cs.reduce((s, a) => s + a, 0) / cs.length;
79
+ return n._ang;
80
+ };
81
+ assignAngle(m.root);
82
+ for (const n of m.nodes) {
83
+ const cn = n, r = n.depth * step;
84
+ cn._x = this.CX + r * Math.cos(cn._ang - Math.PI / 2);
85
+ cn._y = this.CY + r * Math.sin(cn._ang - Math.PI / 2);
86
+ }
87
+ for (const n of m.nodes) {
88
+ if (!n.parent)
89
+ continue;
90
+ const pn = n.parent, cn = n;
91
+ const mx = (pn._x + cn._x) / 2, my = (pn._y + cn._y) / 2;
92
+ const ctrlX = mx + (this.CX - mx) * 0.16, ctrlY = my + (this.CY - my) * 0.16;
93
+ const col = FLOW_COLORS[n.type];
94
+ const path = svgEl('path', { d: `M${pn._x},${pn._y} Q${ctrlX},${ctrlY} ${cn._x},${cn._y}`, fill: 'none', stroke: col, 'stroke-width': 1.4, opacity: 0.12 }, edgeG);
95
+ const part = svgEl('circle', { r: 3.2, class: 'fhand-dot', opacity: 0 }, edgeG);
96
+ this.edges.push({ path, part, node: n, len: path.getTotalLength() });
97
+ }
98
+ for (const n of m.nodes) {
99
+ const cn = n;
100
+ const rad = n.depth === 0 ? 22 : Math.min(24, 9 + Math.pow(n.realDur, 0.55) * 2.6);
101
+ const col = FLOW_COLORS[n.type];
102
+ const grp = svgEl('g', {}, nodeG);
103
+ grp.style.color = col;
104
+ grp.style.cursor = 'pointer';
105
+ appendTitle(grp, `${n.name}`);
106
+ const halo = svgEl('circle', { cx: cn._x, cy: cn._y, r: rad + 7, fill: col, opacity: 0 }, grp);
107
+ const ring = svgEl('circle', { cx: cn._x, cy: cn._y, r: rad, fill: col, 'fill-opacity': 0.16, stroke: col, 'stroke-width': 1.6 }, grp);
108
+ const icon = appendIcon(grp, cn._x - rad * 0.6, cn._y - rad * 0.6, rad * 1.2, n.iconClass, n.logoUrl, col);
109
+ icon.setAttribute('opacity', '0');
110
+ // angle each label along its radial spoke (flip on the left half so it stays upright)
111
+ const dir = cn._ang - Math.PI / 2;
112
+ const lx = cn._x + Math.cos(dir) * (rad + 8), ly = cn._y + Math.sin(dir) * (rad + 8);
113
+ const flip = Math.cos(dir) < 0;
114
+ const deg = dir * 180 / Math.PI + (flip ? 180 : 0);
115
+ const lab = n.depth === 0
116
+ ? svgEl('text', { x: cn._x, y: cn._y + rad + 18, 'font-size': 13, 'font-weight': 700, 'text-anchor': 'middle', class: 'fhalo', opacity: 0, text: clip(shortLabel(n), 22) }, grp)
117
+ : svgEl('text', {
118
+ x: lx, y: ly, 'font-size': 10.5, 'font-weight': 600, 'dominant-baseline': 'middle',
119
+ 'text-anchor': flip ? 'end' : 'start', transform: `rotate(${deg} ${lx} ${ly})`,
120
+ class: 'fhalo', opacity: 0, text: clip(shortLabel(n), 22)
121
+ }, grp);
122
+ grp.addEventListener('mouseenter', () => { this.hoveredId = n.id; });
123
+ grp.addEventListener('mouseleave', () => { if (this.hoveredId === n.id)
124
+ this.hoveredId = -1; });
125
+ grp.addEventListener('click', () => { if (!this.pz?.moved)
126
+ this.nodeSelected.emit(n); });
127
+ this.stars.set(n.id, { halo, ring, icon, lab, node: n, rad });
128
+ }
129
+ this.pz = new PanZoomController(svg, main, 'mj.agentRunFlow.view.constellation.v1');
130
+ this.pz.Load();
131
+ this.pz.Attach();
132
+ }
133
+ update(p, ts) {
134
+ this.stars.forEach(({ halo, ring, icon, lab, node, rad }) => {
135
+ const started = p >= node.t0 || node.depth === 0;
136
+ const active = p >= node.t0 && p < node.t1;
137
+ const hovered = this.hoveredId === node.id;
138
+ const selected = this.selectedId === node.id;
139
+ if (started) {
140
+ const tw = 0.6 + 0.4 * Math.sin(ts / (420 + node.realDur * 70));
141
+ ring.setAttribute('fill-opacity', active || hovered || selected ? '0.32' : String(0.16 + 0.06 * tw));
142
+ ring.setAttribute('class', selected ? 'glow2' : active ? 'glow' + Math.max(1, node.heat) : hovered ? 'glow2' : 'glow1');
143
+ ring.setAttribute('stroke-width', selected ? '3' : '1.6');
144
+ icon.setAttribute('opacity', active || hovered || selected ? '1' : '0.8');
145
+ halo.setAttribute('opacity', active ? String(0.16 + 0.12 * Math.sin(ts / 230)) : selected ? '0.16' : hovered ? '0.14' : '0');
146
+ halo.setAttribute('r', String(rad + 7 + (active ? 4 * Math.abs(Math.sin(ts / 240)) : 0)));
147
+ }
148
+ else {
149
+ ring.setAttribute('fill-opacity', '0.06');
150
+ ring.setAttribute('class', hovered ? 'glow2' : '');
151
+ ring.setAttribute('stroke-width', '1.6');
152
+ icon.setAttribute('opacity', hovered ? '0.7' : '0.25');
153
+ halo.setAttribute('opacity', hovered ? '0.1' : '0');
154
+ }
155
+ const showLabel = node.depth <= 1 || active || hovered || selected;
156
+ lab.setAttribute('opacity', showLabel ? (active || hovered || selected ? '1' : node.depth === 0 ? '1' : '0.62') : '0');
157
+ });
158
+ this.edges.forEach(({ path, part, node, len }) => {
159
+ const flowing = p >= node.t0 && p < node.t1;
160
+ const lit = p >= node.t0;
161
+ path.setAttribute('opacity', lit ? (flowing ? '0.6' : '0.2') : '0.1');
162
+ path.setAttribute('stroke-width', flowing ? '2.4' : '1.4');
163
+ if (flowing) {
164
+ const ph = (ts / 700) % 1;
165
+ const pt = path.getPointAtLength(ph * len);
166
+ part.setAttribute('cx', String(pt.x));
167
+ part.setAttribute('cy', String(pt.y));
168
+ part.setAttribute('opacity', '1');
169
+ part.setAttribute('class', 'glow2');
170
+ part.style.color = FLOW_COLORS[node.type];
171
+ }
172
+ else {
173
+ part.setAttribute('opacity', '0');
174
+ }
175
+ });
176
+ }
177
+ static { this.ɵfac = function ConstellationComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ConstellationComponent)(); }; }
178
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConstellationComponent, selectors: [["mj-agent-flow-constellation"]], viewQuery: function ConstellationComponent_Query(rf, ctx) { if (rf & 1) {
179
+ i0.ɵɵviewQuery(_c0, 7);
180
+ } if (rf & 2) {
181
+ let _t;
182
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.svgRef = _t.first);
183
+ } }, inputs: { Model: "Model" }, outputs: { nodeSelected: "nodeSelected" }, standalone: false, decls: 2, vars: 0, consts: [["svg", ""], ["preserveAspectRatio", "xMidYMid meet", 1, "flow-svg"]], template: function ConstellationComponent_Template(rf, ctx) { if (rf & 1) {
184
+ i0.ɵɵnamespaceSVG();
185
+ i0.ɵɵelement(0, "svg", 1, 0);
186
+ } }, styles: ["/* Shared chrome for every flow renderer's <svg> host.\n These components use ViewEncapsulation.None so this CSS reaches SVG nodes\n created imperatively via createElementNS (which never receive Angular's\n emulated-encapsulation scoping attribute). Everything is namespaced under\n `.flow-svg` to avoid leaking into the rest of the app. */\n.flow-svg {\n width: 100%;\n height: 100%;\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n.flow-svg text { fill: var(--mj-text-primary); }\n.flow-svg .ftxt-secondary { fill: var(--mj-text-secondary); }\n.flow-svg .ftxt-muted { fill: var(--mj-text-muted); }\n.flow-svg .ftxt-on { fill: var(--mj-text-inverse); }\n.flow-svg .fgrid { stroke: var(--mj-border-subtle); }\n.flow-svg .fhand { stroke: var(--mj-text-secondary); }\n.flow-svg .fhand-dot { fill: var(--mj-text-primary); }\n.flow-svg .fstar-bg { fill: var(--mj-text-muted); }\n/* outlined label for legibility over edges / busy fields */\n.flow-svg .fhalo { paint-order: stroke; stroke: var(--mj-bg-page); stroke-width: 3.5px; stroke-linejoin: round; }\n\n/* Heat / activity glow tiers \u2014 driven by `currentColor` (the node's category color). */\n.flow-svg .glow1 { filter: drop-shadow(0 0 4px currentColor); }\n.flow-svg .glow2 { filter: drop-shadow(0 0 9px currentColor); }\n.flow-svg .glow3 { filter: drop-shadow(0 0 16px currentColor); }\n"], encapsulation: 2, changeDetection: 0 }); }
187
+ }
188
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConstellationComponent, [{
189
+ type: Component,
190
+ args: [{ standalone: false, selector: 'mj-agent-flow-constellation', template: `<svg #svg class="flow-svg" preserveAspectRatio="xMidYMid meet"></svg>`, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["/* Shared chrome for every flow renderer's <svg> host.\n These components use ViewEncapsulation.None so this CSS reaches SVG nodes\n created imperatively via createElementNS (which never receive Angular's\n emulated-encapsulation scoping attribute). Everything is namespaced under\n `.flow-svg` to avoid leaking into the rest of the app. */\n.flow-svg {\n width: 100%;\n height: 100%;\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n.flow-svg text { fill: var(--mj-text-primary); }\n.flow-svg .ftxt-secondary { fill: var(--mj-text-secondary); }\n.flow-svg .ftxt-muted { fill: var(--mj-text-muted); }\n.flow-svg .ftxt-on { fill: var(--mj-text-inverse); }\n.flow-svg .fgrid { stroke: var(--mj-border-subtle); }\n.flow-svg .fhand { stroke: var(--mj-text-secondary); }\n.flow-svg .fhand-dot { fill: var(--mj-text-primary); }\n.flow-svg .fstar-bg { fill: var(--mj-text-muted); }\n/* outlined label for legibility over edges / busy fields */\n.flow-svg .fhalo { paint-order: stroke; stroke: var(--mj-bg-page); stroke-width: 3.5px; stroke-linejoin: round; }\n\n/* Heat / activity glow tiers \u2014 driven by `currentColor` (the node's category color). */\n.flow-svg .glow1 { filter: drop-shadow(0 0 4px currentColor); }\n.flow-svg .glow2 { filter: drop-shadow(0 0 9px currentColor); }\n.flow-svg .glow3 { filter: drop-shadow(0 0 16px currentColor); }\n"] }]
191
+ }], null, { svgRef: [{
192
+ type: ViewChild,
193
+ args: ['svg', { static: true }]
194
+ }], nodeSelected: [{
195
+ type: Output
196
+ }], Model: [{
197
+ type: Input
198
+ }] }); })();
199
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConstellationComponent, { className: "ConstellationComponent", filePath: "src/lib/custom/ai-agent-run/flow/constellation.component.ts", lineNumber: 24 }); })();
200
+ //# sourceMappingURL=constellation.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constellation.component.js","sourceRoot":"","sources":["../../../../../src/lib/custom/ai-agent-run/flow/constellation.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ElementRef, Input, Output, EventEmitter, ViewChild, OnDestroy, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';\nimport { FlowModel, FlowNode, FLOW_COLORS, shortLabel } from './agent-run-flow.model';\nimport { svgEl, clip, appendIcon, appendTitle } from './flow-svg.util';\nimport { PanZoomController } from './pan-zoom';\n\ninterface Star { halo: SVGElement; ring: SVGElement; icon: SVGElement; lab: SVGElement; node: FlowNode; rad: number; }\ninterface Edge { path: SVGGraphicsElement; part: SVGElement; node: FlowNode; len: number; }\ntype Placed = FlowNode & { _x?: number; _y?: number; _ang?: number };\n\n/**\n * Constellation — the agent tree as a star map. Leaves spread evenly around the\n * circle (radial dendrogram) so dense sub-agents don't clump; stars carry the real\n * step/agent icon, ignite in execution order, and pulse energy down curved edges.\n * Labels stay clutter-free (root + top level + active by default, hover to reveal).\n */\n@Component({\n standalone: false,\n selector: 'mj-agent-flow-constellation',\n template: `<svg #svg class=\"flow-svg\" preserveAspectRatio=\"xMidYMid meet\"></svg>`,\n styleUrls: ['./flow-shared.css'],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ConstellationComponent {\n @ViewChild('svg', { static: true }) svgRef!: ElementRef<SVGSVGElement>;\n @Output() nodeSelected = new EventEmitter<FlowNode>();\n\n private _model: FlowModel | null = null;\n private built = false;\n private stars = new Map<number, Star>();\n private edges: Edge[] = [];\n private hoveredId = -1;\n private selectedId = -1;\n private pz?: PanZoomController;\n\n private readonly VW = 1200;\n private readonly VH = 720;\n private readonly CX = 600;\n private readonly CY = 360;\n\n public SetSelected(id: number | null): void { this.selectedId = id ?? -1; }\n public ZoomIn(): void { this.pz?.ZoomIn(); }\n public ZoomOut(): void { this.pz?.ZoomOut(); }\n public FitReset(): void { this.pz?.Reset(); }\n public ReapplyView(): void { this.pz?.Reapply(); }\n ngOnDestroy(): void { this.pz?.Detach(); }\n\n @Input() set Model(m: FlowModel | null) { this._model = m; this.built = false; this.clear(); }\n\n public Render(p: number, ts: number): void {\n if (!this._model) return;\n if (!this.built) { this.build(); this.built = true; }\n this.update(p, ts);\n }\n\n private clear(): void {\n this.pz?.Detach(); this.pz = undefined;\n const svg = this.svgRef?.nativeElement;\n if (svg) while (svg.firstChild) svg.removeChild(svg.firstChild);\n this.stars.clear(); this.edges = []; this.hoveredId = -1;\n }\n\n private build(): void {\n const svg = this.svgRef.nativeElement;\n const m = this._model!;\n svg.setAttribute('viewBox', `0 0 ${this.VW} ${this.VH}`);\n\n const bg = svgEl('g', {}, svg);\n let seed = 7; const rnd = () => { seed = (seed * 9301 + 49297) % 233280; return seed / 233280; };\n for (let i = 0; i < 150; i++) {\n svgEl('circle', { cx: rnd() * this.VW, cy: rnd() * this.VH, r: rnd() * 1.3 + 0.3, class: 'fstar-bg', opacity: rnd() * 0.3 + 0.04 }, bg);\n }\n const main = svgEl('g', {}, svg);\n const edgeG = svgEl('g', {}, main);\n const nodeG = svgEl('g', {}, main);\n\n const step = Math.min(150, 300 / Math.max(1, m.maxDepth));\n const leafCount = Math.max(1, m.leaves.length);\n let li = 0;\n const assignAngle = (n: Placed): number => {\n if (!n.children.length) { const a = (li + 0.5) / leafCount * 2 * Math.PI; li++; n._ang = a; return a; }\n const cs = n.children.map(c => assignAngle(c as Placed));\n n._ang = cs.reduce((s, a) => s + a, 0) / cs.length; return n._ang;\n };\n assignAngle(m.root as Placed);\n for (const n of m.nodes) {\n const cn = n as Placed, r = n.depth * step;\n cn._x = this.CX + r * Math.cos(cn._ang! - Math.PI / 2);\n cn._y = this.CY + r * Math.sin(cn._ang! - Math.PI / 2);\n }\n\n for (const n of m.nodes) {\n if (!n.parent) continue;\n const pn = n.parent as Placed, cn = n as Placed;\n const mx = (pn._x! + cn._x!) / 2, my = (pn._y! + cn._y!) / 2;\n const ctrlX = mx + (this.CX - mx) * 0.16, ctrlY = my + (this.CY - my) * 0.16;\n const col = FLOW_COLORS[n.type];\n const path = svgEl('path', { d: `M${pn._x},${pn._y} Q${ctrlX},${ctrlY} ${cn._x},${cn._y}`, fill: 'none', stroke: col, 'stroke-width': 1.4, opacity: 0.12 }, edgeG) as SVGGraphicsElement;\n const part = svgEl('circle', { r: 3.2, class: 'fhand-dot', opacity: 0 }, edgeG);\n this.edges.push({ path, part, node: n, len: (path as unknown as SVGPathElement).getTotalLength() });\n }\n\n for (const n of m.nodes) {\n const cn = n as Placed;\n const rad = n.depth === 0 ? 22 : Math.min(24, 9 + Math.pow(n.realDur, 0.55) * 2.6);\n const col = FLOW_COLORS[n.type];\n const grp = svgEl('g', {}, nodeG);\n (grp as SVGElement & { style: CSSStyleDeclaration }).style.color = col;\n (grp as SVGElement & { style: CSSStyleDeclaration }).style.cursor = 'pointer';\n appendTitle(grp, `${n.name}`);\n const halo = svgEl('circle', { cx: cn._x!, cy: cn._y!, r: rad + 7, fill: col, opacity: 0 }, grp);\n const ring = svgEl('circle', { cx: cn._x!, cy: cn._y!, r: rad, fill: col, 'fill-opacity': 0.16, stroke: col, 'stroke-width': 1.6 }, grp);\n const icon = appendIcon(grp, cn._x! - rad * 0.6, cn._y! - rad * 0.6, rad * 1.2, n.iconClass, n.logoUrl, col);\n icon.setAttribute('opacity', '0');\n // angle each label along its radial spoke (flip on the left half so it stays upright)\n const dir = cn._ang! - Math.PI / 2;\n const lx = cn._x! + Math.cos(dir) * (rad + 8), ly = cn._y! + Math.sin(dir) * (rad + 8);\n const flip = Math.cos(dir) < 0;\n const deg = dir * 180 / Math.PI + (flip ? 180 : 0);\n const lab = n.depth === 0\n ? svgEl('text', { x: cn._x!, y: cn._y! + rad + 18, 'font-size': 13, 'font-weight': 700, 'text-anchor': 'middle', class: 'fhalo', opacity: 0, text: clip(shortLabel(n), 22) }, grp)\n : svgEl('text', {\n x: lx, y: ly, 'font-size': 10.5, 'font-weight': 600, 'dominant-baseline': 'middle',\n 'text-anchor': flip ? 'end' : 'start', transform: `rotate(${deg} ${lx} ${ly})`,\n class: 'fhalo', opacity: 0, text: clip(shortLabel(n), 22)\n }, grp);\n grp.addEventListener('mouseenter', () => { this.hoveredId = n.id; });\n grp.addEventListener('mouseleave', () => { if (this.hoveredId === n.id) this.hoveredId = -1; });\n grp.addEventListener('click', () => { if (!this.pz?.moved) this.nodeSelected.emit(n); });\n this.stars.set(n.id, { halo, ring, icon, lab, node: n, rad });\n }\n\n this.pz = new PanZoomController(svg, main, 'mj.agentRunFlow.view.constellation.v1');\n this.pz.Load(); this.pz.Attach();\n }\n\n private update(p: number, ts: number): void {\n this.stars.forEach(({ halo, ring, icon, lab, node, rad }) => {\n const started = p >= node.t0 || node.depth === 0;\n const active = p >= node.t0 && p < node.t1;\n const hovered = this.hoveredId === node.id;\n const selected = this.selectedId === node.id;\n if (started) {\n const tw = 0.6 + 0.4 * Math.sin(ts / (420 + node.realDur * 70));\n ring.setAttribute('fill-opacity', active || hovered || selected ? '0.32' : String(0.16 + 0.06 * tw));\n ring.setAttribute('class', selected ? 'glow2' : active ? 'glow' + Math.max(1, node.heat) : hovered ? 'glow2' : 'glow1');\n ring.setAttribute('stroke-width', selected ? '3' : '1.6');\n icon.setAttribute('opacity', active || hovered || selected ? '1' : '0.8');\n halo.setAttribute('opacity', active ? String(0.16 + 0.12 * Math.sin(ts / 230)) : selected ? '0.16' : hovered ? '0.14' : '0');\n halo.setAttribute('r', String(rad + 7 + (active ? 4 * Math.abs(Math.sin(ts / 240)) : 0)));\n } else {\n ring.setAttribute('fill-opacity', '0.06'); ring.setAttribute('class', hovered ? 'glow2' : '');\n ring.setAttribute('stroke-width', '1.6');\n icon.setAttribute('opacity', hovered ? '0.7' : '0.25');\n halo.setAttribute('opacity', hovered ? '0.1' : '0');\n }\n const showLabel = node.depth <= 1 || active || hovered || selected;\n lab.setAttribute('opacity', showLabel ? (active || hovered || selected ? '1' : node.depth === 0 ? '1' : '0.62') : '0');\n });\n this.edges.forEach(({ path, part, node, len }) => {\n const flowing = p >= node.t0 && p < node.t1;\n const lit = p >= node.t0;\n path.setAttribute('opacity', lit ? (flowing ? '0.6' : '0.2') : '0.1');\n path.setAttribute('stroke-width', flowing ? '2.4' : '1.4');\n if (flowing) {\n const ph = (ts / 700) % 1;\n const pt = (path as unknown as SVGPathElement).getPointAtLength(ph * len);\n part.setAttribute('cx', String(pt.x)); part.setAttribute('cy', String(pt.y));\n part.setAttribute('opacity', '1'); part.setAttribute('class', 'glow2');\n (part as SVGElement & { style: CSSStyleDeclaration }).style.color = FLOW_COLORS[node.type];\n } else {\n part.setAttribute('opacity', '0');\n }\n });\n }\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import { ElementRef, EventEmitter, OnDestroy } from '@angular/core';
2
+ import { FlowModel, FlowNode } from './agent-run-flow.model';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Flame Cascade — a static icicle of the whole run that's always visible (depth =
6
+ * hierarchy, x = order, bar width = compressed time). Translucent **swimlane bands**
7
+ * sit behind each sub-agent/loop so you can see which steps belong to which. As the
8
+ * clock plays, a fill sweeps each bar and a playhead crosses the chart; longer steps
9
+ * burn hotter.
10
+ */
11
+ export declare class FlameCascadeComponent implements OnDestroy {
12
+ svgRef: ElementRef<SVGSVGElement>;
13
+ nodeSelected: EventEmitter<FlowNode>;
14
+ private static seq;
15
+ private uid;
16
+ private _model;
17
+ private built;
18
+ private cells;
19
+ private playhead?;
20
+ private playMark?;
21
+ private selectedId;
22
+ private pz?;
23
+ SetSelected(id: number | null): void;
24
+ ZoomIn(): void;
25
+ ZoomOut(): void;
26
+ FitReset(): void;
27
+ ReapplyView(): void;
28
+ ngOnDestroy(): void;
29
+ private readonly VW;
30
+ private readonly ROW;
31
+ private readonly GAP;
32
+ private readonly PAD;
33
+ private readonly TOP;
34
+ private get IW();
35
+ set Model(m: FlowModel | null);
36
+ Render(p: number, ts: number): void;
37
+ private clear;
38
+ private subtreeMaxDepth;
39
+ private build;
40
+ private update;
41
+ static ɵfac: i0.ɵɵFactoryDeclaration<FlameCascadeComponent, never>;
42
+ static ɵcmp: i0.ɵɵComponentDeclaration<FlameCascadeComponent, "mj-agent-flow-flame", never, { "Model": { "alias": "Model"; "required": false; }; }, { "nodeSelected": "nodeSelected"; }, never, never, false, never>;
43
+ }
44
+ //# sourceMappingURL=flame-cascade.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flame-cascade.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/custom/ai-agent-run/flow/flame-cascade.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAiB,YAAY,EAAa,SAAS,EAA8C,MAAM,eAAe,CAAC;AACrJ,OAAO,EAAE,SAAS,EAAE,QAAQ,EAA2C,MAAM,wBAAwB,CAAC;;AAYtG;;;;;;GAMG;AACH,qBAQa,qBAAsB,YAAW,SAAS;IACjB,MAAM,EAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IAC7D,YAAY,yBAAgC;IAEtD,OAAO,CAAC,MAAM,CAAC,GAAG,CAAK;IACvB,OAAO,CAAC,GAAG,CAA2C;IAEtD,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,QAAQ,CAAC,CAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,CAAa;IAC9B,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,EAAE,CAAC,CAAoB;IAExB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IACpC,MAAM,IAAI,IAAI;IACd,OAAO,IAAI,IAAI;IACf,QAAQ,IAAI,IAAI;IAChB,WAAW,IAAI,IAAI;IAC1B,WAAW,IAAI,IAAI;IAEnB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAQ;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,KAAK,EAAE,GAA6C;IAE3D,IAAa,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,EAAwD;IAEvF,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAM1C,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,KAAK;IA8Eb,OAAO,CAAC,MAAM;yCA9HH,qBAAqB;2CAArB,qBAAqB;CAmJjC"}
@@ -0,0 +1,180 @@
1
+ import { Component, Input, Output, EventEmitter, ViewChild, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
2
+ import { FLOW_COLORS, shortLabel, formatDuration } from './agent-run-flow.model';
3
+ import { svgEl, appendIcon, appendTitle } from './flow-svg.util';
4
+ import { PanZoomController } from './pan-zoom';
5
+ import * as i0 from "@angular/core";
6
+ const _c0 = ["svg"];
7
+ /**
8
+ * Flame Cascade — a static icicle of the whole run that's always visible (depth =
9
+ * hierarchy, x = order, bar width = compressed time). Translucent **swimlane bands**
10
+ * sit behind each sub-agent/loop so you can see which steps belong to which. As the
11
+ * clock plays, a fill sweeps each bar and a playhead crosses the chart; longer steps
12
+ * burn hotter.
13
+ */
14
+ export class FlameCascadeComponent {
15
+ constructor() {
16
+ this.nodeSelected = new EventEmitter();
17
+ this.uid = 'flame' + (FlameCascadeComponent.seq++);
18
+ this._model = null;
19
+ this.built = false;
20
+ this.cells = new Map();
21
+ this.selectedId = -1;
22
+ this.VW = 1200;
23
+ this.ROW = 46;
24
+ this.GAP = 9;
25
+ this.PAD = 26;
26
+ this.TOP = 44;
27
+ }
28
+ static { this.seq = 0; }
29
+ SetSelected(id) { this.selectedId = id ?? -1; }
30
+ ZoomIn() { this.pz?.ZoomIn(); }
31
+ ZoomOut() { this.pz?.ZoomOut(); }
32
+ FitReset() { this.pz?.Reset(); }
33
+ ReapplyView() { this.pz?.Reapply(); }
34
+ ngOnDestroy() { this.pz?.Detach(); }
35
+ get IW() { return this.VW - this.PAD * 2; }
36
+ set Model(m) { this._model = m; this.built = false; this.clear(); }
37
+ Render(p, ts) {
38
+ if (!this._model)
39
+ return;
40
+ if (!this.built) {
41
+ this.build();
42
+ this.built = true;
43
+ }
44
+ this.update(p, ts);
45
+ }
46
+ clear() {
47
+ this.pz?.Detach();
48
+ this.pz = undefined;
49
+ const svg = this.svgRef?.nativeElement;
50
+ if (svg)
51
+ while (svg.firstChild)
52
+ svg.removeChild(svg.firstChild);
53
+ this.cells.clear();
54
+ }
55
+ subtreeMaxDepth(n) {
56
+ return n.children.length ? Math.max(...n.children.map(c => this.subtreeMaxDepth(c))) : n.depth;
57
+ }
58
+ build() {
59
+ const svg = this.svgRef.nativeElement;
60
+ const m = this._model;
61
+ const VH = this.TOP + (m.maxDepth + 1) * this.ROW + 26;
62
+ svg.setAttribute('viewBox', `0 0 ${this.VW} ${VH}`);
63
+ const defs = svgEl('defs', {}, svg);
64
+ const main = svgEl('g', {}, svg);
65
+ const bands = svgEl('g', {}, main);
66
+ const grid = svgEl('g', {}, main);
67
+ const g = svgEl('g', {}, main);
68
+ // time axis
69
+ for (let i = 0; i <= 10; i++) {
70
+ const x = this.PAD + this.IW * i / 10;
71
+ svgEl('line', { x1: x, y1: this.TOP - 8, x2: x, y2: VH - 18, 'stroke-width': 1, class: 'fgrid' }, grid);
72
+ if (i % 2 === 0)
73
+ svgEl('text', { x, y: this.TOP - 16, 'font-size': 9.5, 'text-anchor': 'middle', class: 'ftxt-muted', text: i * 10 + '%' }, grid);
74
+ }
75
+ // swimlane bands behind sub-agent / loop containers (nested grouping)
76
+ for (const n of m.nodes) {
77
+ if (n.children.length === 0 || n.depth === 0)
78
+ continue;
79
+ const x = this.PAD + n.t0 * this.IW;
80
+ const w = Math.max(2, (n.t1 - n.t0) * this.IW);
81
+ const y = this.TOP + n.depth * this.ROW - 3;
82
+ const h = (this.subtreeMaxDepth(n) - n.depth + 1) * this.ROW - this.GAP + 6;
83
+ const band = svgEl('rect', { x: x - 3, y, width: w + 6, height: h, rx: 12, fill: FLOW_COLORS[n.type], opacity: 0.07 }, bands);
84
+ band.setAttribute('stroke', FLOW_COLORS[n.type]);
85
+ band.setAttribute('stroke-width', '1');
86
+ band.setAttribute('stroke-opacity', '0.18');
87
+ }
88
+ for (const n of m.nodes) {
89
+ const x = this.PAD + n.t0 * this.IW;
90
+ const fw = Math.max(2, (n.t1 - n.t0) * this.IW);
91
+ const y = this.TOP + n.depth * this.ROW;
92
+ const h = this.ROW - this.GAP;
93
+ const col = FLOW_COLORS[n.type];
94
+ const grp = svgEl('g', {}, g);
95
+ grp.style.color = col;
96
+ grp.style.cursor = 'pointer';
97
+ appendTitle(grp, `${n.name} · ${formatDuration(n.realDur)}`);
98
+ // outline = always-visible structure; fill = animated progress overlay
99
+ const outline = svgEl('rect', { x, y, width: fw, height: h, rx: 8, fill: col, 'fill-opacity': 0.14, stroke: col, 'stroke-width': 1.4, 'stroke-opacity': 0.7 }, grp);
100
+ const fill = svgEl('rect', { x, y, width: 0, height: h, rx: 8, fill: col, opacity: 0 }, grp);
101
+ // label group, clipped to the bar so it never bleeds into neighbours
102
+ const clipId = `${this.uid}-${n.id}`;
103
+ const cp = svgEl('clipPath', { id: clipId }, defs);
104
+ svgEl('rect', { x, y, width: fw, height: h, rx: 8 }, cp);
105
+ const content = svgEl('g', { 'clip-path': `url(#${clipId})` }, grp);
106
+ const cy = y + h / 2;
107
+ const name = shortLabel(n);
108
+ const showIcon = fw > 22;
109
+ const iconRight = showIcon ? 30 : 9;
110
+ if (showIcon)
111
+ appendIcon(content, x + 7, cy - 9, 18, n.iconClass, n.logoUrl, col);
112
+ // shrink the font until the (already abbreviated) label fits, before giving up
113
+ let fontSize = 0;
114
+ for (const fs of [12.5, 11.5, 10.5, 9.5, 8.5]) {
115
+ if (iconRight + name.length * fs * 0.56 + 8 <= fw) {
116
+ fontSize = fs;
117
+ break;
118
+ }
119
+ }
120
+ if (fontSize > 0) {
121
+ svgEl('text', { x: x + iconRight, y: cy + 1, 'font-size': fontSize, 'font-weight': 600, 'dominant-baseline': 'middle', class: 'ftxt-on', text: name }, content);
122
+ if (n.realDur && iconRight + name.length * fontSize * 0.56 + 52 <= fw) {
123
+ svgEl('text', { x: x + fw - 12, y: cy + 1, 'font-size': 10.5, 'text-anchor': 'end', 'dominant-baseline': 'middle', class: 'ftxt-on', opacity: 0.72, text: formatDuration(n.realDur) }, content);
124
+ }
125
+ }
126
+ grp.addEventListener('click', () => { if (!this.pz?.moved)
127
+ this.nodeSelected.emit(n); });
128
+ this.cells.set(n.id, { outline, fill, x, fw, node: n });
129
+ }
130
+ this.playhead = svgEl('line', { x1: this.PAD, y1: this.TOP - 8, x2: this.PAD, y2: VH - 16, 'stroke-width': 1.5, opacity: 0, class: 'fhand' }, g);
131
+ this.playMark = svgEl('path', { d: `M${this.PAD - 5},${this.TOP - 14} L${this.PAD + 5},${this.TOP - 14} L${this.PAD},${this.TOP - 6} Z`, opacity: 0, class: 'fhand-dot' }, g);
132
+ this.pz = new PanZoomController(svg, main, 'mj.agentRunFlow.view.flame.v1');
133
+ this.pz.Load();
134
+ this.pz.Attach();
135
+ }
136
+ update(p, ts) {
137
+ this.cells.forEach(({ outline, fill, fw, node }) => {
138
+ const started = p >= node.t0;
139
+ const active = started && p < node.t1;
140
+ const selected = node.id === this.selectedId;
141
+ const cw = p >= node.t1 ? fw : started ? (p - node.t0) / (node.t1 - node.t0) * fw : 0;
142
+ fill.setAttribute('width', String(Math.max(0, cw)));
143
+ const fillOp = active ? 0.92 + 0.08 * Math.sin(ts / 170) : started ? 0.6 : 0;
144
+ fill.setAttribute('opacity', String(fillOp));
145
+ outline.setAttribute('class', selected ? 'glow2' : active && node.heat ? 'glow' + node.heat : '');
146
+ outline.setAttribute('stroke-width', selected ? '3' : '1.4');
147
+ outline.setAttribute('stroke-opacity', selected || active ? '1' : started ? '0.85' : '0.55');
148
+ });
149
+ const live = p > 0 && p < 1;
150
+ const ph = this.PAD + p * this.IW;
151
+ this.playhead?.setAttribute('x1', String(ph));
152
+ this.playhead?.setAttribute('x2', String(ph));
153
+ this.playhead?.setAttribute('opacity', live ? '0.8' : '0');
154
+ this.playMark?.setAttribute('transform', `translate(${ph - this.PAD},0)`);
155
+ this.playMark?.setAttribute('opacity', live ? '1' : '0');
156
+ }
157
+ static { this.ɵfac = function FlameCascadeComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FlameCascadeComponent)(); }; }
158
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FlameCascadeComponent, selectors: [["mj-agent-flow-flame"]], viewQuery: function FlameCascadeComponent_Query(rf, ctx) { if (rf & 1) {
159
+ i0.ɵɵviewQuery(_c0, 7);
160
+ } if (rf & 2) {
161
+ let _t;
162
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.svgRef = _t.first);
163
+ } }, inputs: { Model: "Model" }, outputs: { nodeSelected: "nodeSelected" }, standalone: false, decls: 2, vars: 0, consts: [["svg", ""], ["preserveAspectRatio", "xMinYMin meet", 1, "flow-svg"]], template: function FlameCascadeComponent_Template(rf, ctx) { if (rf & 1) {
164
+ i0.ɵɵnamespaceSVG();
165
+ i0.ɵɵelement(0, "svg", 1, 0);
166
+ } }, styles: ["/* Shared chrome for every flow renderer's <svg> host.\n These components use ViewEncapsulation.None so this CSS reaches SVG nodes\n created imperatively via createElementNS (which never receive Angular's\n emulated-encapsulation scoping attribute). Everything is namespaced under\n `.flow-svg` to avoid leaking into the rest of the app. */\n.flow-svg {\n width: 100%;\n height: 100%;\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n.flow-svg text { fill: var(--mj-text-primary); }\n.flow-svg .ftxt-secondary { fill: var(--mj-text-secondary); }\n.flow-svg .ftxt-muted { fill: var(--mj-text-muted); }\n.flow-svg .ftxt-on { fill: var(--mj-text-inverse); }\n.flow-svg .fgrid { stroke: var(--mj-border-subtle); }\n.flow-svg .fhand { stroke: var(--mj-text-secondary); }\n.flow-svg .fhand-dot { fill: var(--mj-text-primary); }\n.flow-svg .fstar-bg { fill: var(--mj-text-muted); }\n/* outlined label for legibility over edges / busy fields */\n.flow-svg .fhalo { paint-order: stroke; stroke: var(--mj-bg-page); stroke-width: 3.5px; stroke-linejoin: round; }\n\n/* Heat / activity glow tiers \u2014 driven by `currentColor` (the node's category color). */\n.flow-svg .glow1 { filter: drop-shadow(0 0 4px currentColor); }\n.flow-svg .glow2 { filter: drop-shadow(0 0 9px currentColor); }\n.flow-svg .glow3 { filter: drop-shadow(0 0 16px currentColor); }\n"], encapsulation: 2, changeDetection: 0 }); }
167
+ }
168
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FlameCascadeComponent, [{
169
+ type: Component,
170
+ args: [{ standalone: false, selector: 'mj-agent-flow-flame', template: `<svg #svg class="flow-svg" preserveAspectRatio="xMinYMin meet"></svg>`, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["/* Shared chrome for every flow renderer's <svg> host.\n These components use ViewEncapsulation.None so this CSS reaches SVG nodes\n created imperatively via createElementNS (which never receive Angular's\n emulated-encapsulation scoping attribute). Everything is namespaced under\n `.flow-svg` to avoid leaking into the rest of the app. */\n.flow-svg {\n width: 100%;\n height: 100%;\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n}\n\n.flow-svg text { fill: var(--mj-text-primary); }\n.flow-svg .ftxt-secondary { fill: var(--mj-text-secondary); }\n.flow-svg .ftxt-muted { fill: var(--mj-text-muted); }\n.flow-svg .ftxt-on { fill: var(--mj-text-inverse); }\n.flow-svg .fgrid { stroke: var(--mj-border-subtle); }\n.flow-svg .fhand { stroke: var(--mj-text-secondary); }\n.flow-svg .fhand-dot { fill: var(--mj-text-primary); }\n.flow-svg .fstar-bg { fill: var(--mj-text-muted); }\n/* outlined label for legibility over edges / busy fields */\n.flow-svg .fhalo { paint-order: stroke; stroke: var(--mj-bg-page); stroke-width: 3.5px; stroke-linejoin: round; }\n\n/* Heat / activity glow tiers \u2014 driven by `currentColor` (the node's category color). */\n.flow-svg .glow1 { filter: drop-shadow(0 0 4px currentColor); }\n.flow-svg .glow2 { filter: drop-shadow(0 0 9px currentColor); }\n.flow-svg .glow3 { filter: drop-shadow(0 0 16px currentColor); }\n"] }]
171
+ }], null, { svgRef: [{
172
+ type: ViewChild,
173
+ args: ['svg', { static: true }]
174
+ }], nodeSelected: [{
175
+ type: Output
176
+ }], Model: [{
177
+ type: Input
178
+ }] }); })();
179
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FlameCascadeComponent, { className: "FlameCascadeComponent", filePath: "src/lib/custom/ai-agent-run/flow/flame-cascade.component.ts", lineNumber: 29 }); })();
180
+ //# sourceMappingURL=flame-cascade.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flame-cascade.component.js","sourceRoot":"","sources":["../../../../../src/lib/custom/ai-agent-run/flow/flame-cascade.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ElementRef, Input, Output, EventEmitter, ViewChild, OnDestroy, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';\nimport { FlowModel, FlowNode, FLOW_COLORS, shortLabel, formatDuration } from './agent-run-flow.model';\nimport { svgEl, clip, appendIcon, appendTitle } from './flow-svg.util';\nimport { PanZoomController } from './pan-zoom';\n\ninterface FlameCell {\n outline: SVGElement;\n fill: SVGElement;\n x: number;\n fw: number;\n node: FlowNode;\n}\n\n/**\n * Flame Cascade — a static icicle of the whole run that's always visible (depth =\n * hierarchy, x = order, bar width = compressed time). Translucent **swimlane bands**\n * sit behind each sub-agent/loop so you can see which steps belong to which. As the\n * clock plays, a fill sweeps each bar and a playhead crosses the chart; longer steps\n * burn hotter.\n */\n@Component({\n standalone: false,\n selector: 'mj-agent-flow-flame',\n template: `<svg #svg class=\"flow-svg\" preserveAspectRatio=\"xMinYMin meet\"></svg>`,\n styleUrls: ['./flow-shared.css'],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class FlameCascadeComponent implements OnDestroy {\n @ViewChild('svg', { static: true }) svgRef!: ElementRef<SVGSVGElement>;\n @Output() nodeSelected = new EventEmitter<FlowNode>();\n\n private static seq = 0;\n private uid = 'flame' + (FlameCascadeComponent.seq++);\n\n private _model: FlowModel | null = null;\n private built = false;\n private cells = new Map<number, FlameCell>();\n private playhead?: SVGElement;\n private playMark?: SVGElement;\n private selectedId = -1;\n private pz?: PanZoomController;\n\n public SetSelected(id: number | null): void { this.selectedId = id ?? -1; }\n public ZoomIn(): void { this.pz?.ZoomIn(); }\n public ZoomOut(): void { this.pz?.ZoomOut(); }\n public FitReset(): void { this.pz?.Reset(); }\n public ReapplyView(): void { this.pz?.Reapply(); }\n ngOnDestroy(): void { this.pz?.Detach(); }\n\n private readonly VW = 1200;\n private readonly ROW = 46;\n private readonly GAP = 9;\n private readonly PAD = 26;\n private readonly TOP = 44;\n private get IW(): number { return this.VW - this.PAD * 2; }\n\n @Input() set Model(m: FlowModel | null) { this._model = m; this.built = false; this.clear(); }\n\n public Render(p: number, ts: number): void {\n if (!this._model) return;\n if (!this.built) { this.build(); this.built = true; }\n this.update(p, ts);\n }\n\n private clear(): void {\n this.pz?.Detach(); this.pz = undefined;\n const svg = this.svgRef?.nativeElement;\n if (svg) while (svg.firstChild) svg.removeChild(svg.firstChild);\n this.cells.clear();\n }\n\n private subtreeMaxDepth(n: FlowNode): number {\n return n.children.length ? Math.max(...n.children.map(c => this.subtreeMaxDepth(c))) : n.depth;\n }\n\n private build(): void {\n const svg = this.svgRef.nativeElement;\n const m = this._model!;\n const VH = this.TOP + (m.maxDepth + 1) * this.ROW + 26;\n svg.setAttribute('viewBox', `0 0 ${this.VW} ${VH}`);\n const defs = svgEl('defs', {}, svg);\n const main = svgEl('g', {}, svg);\n const bands = svgEl('g', {}, main);\n const grid = svgEl('g', {}, main);\n const g = svgEl('g', {}, main);\n\n // time axis\n for (let i = 0; i <= 10; i++) {\n const x = this.PAD + this.IW * i / 10;\n svgEl('line', { x1: x, y1: this.TOP - 8, x2: x, y2: VH - 18, 'stroke-width': 1, class: 'fgrid' }, grid);\n if (i % 2 === 0) svgEl('text', { x, y: this.TOP - 16, 'font-size': 9.5, 'text-anchor': 'middle', class: 'ftxt-muted', text: i * 10 + '%' }, grid);\n }\n\n // swimlane bands behind sub-agent / loop containers (nested grouping)\n for (const n of m.nodes) {\n if (n.children.length === 0 || n.depth === 0) continue;\n const x = this.PAD + n.t0 * this.IW;\n const w = Math.max(2, (n.t1 - n.t0) * this.IW);\n const y = this.TOP + n.depth * this.ROW - 3;\n const h = (this.subtreeMaxDepth(n) - n.depth + 1) * this.ROW - this.GAP + 6;\n const band = svgEl('rect', { x: x - 3, y, width: w + 6, height: h, rx: 12, fill: FLOW_COLORS[n.type], opacity: 0.07 }, bands);\n band.setAttribute('stroke', FLOW_COLORS[n.type]);\n band.setAttribute('stroke-width', '1');\n band.setAttribute('stroke-opacity', '0.18');\n }\n\n for (const n of m.nodes) {\n const x = this.PAD + n.t0 * this.IW;\n const fw = Math.max(2, (n.t1 - n.t0) * this.IW);\n const y = this.TOP + n.depth * this.ROW;\n const h = this.ROW - this.GAP;\n const col = FLOW_COLORS[n.type];\n const grp = svgEl('g', {}, g);\n (grp as SVGElement & { style: CSSStyleDeclaration }).style.color = col;\n (grp as SVGElement & { style: CSSStyleDeclaration }).style.cursor = 'pointer';\n appendTitle(grp, `${n.name} · ${formatDuration(n.realDur)}`);\n\n // outline = always-visible structure; fill = animated progress overlay\n const outline = svgEl('rect', { x, y, width: fw, height: h, rx: 8, fill: col, 'fill-opacity': 0.14, stroke: col, 'stroke-width': 1.4, 'stroke-opacity': 0.7 }, grp);\n const fill = svgEl('rect', { x, y, width: 0, height: h, rx: 8, fill: col, opacity: 0 }, grp);\n\n // label group, clipped to the bar so it never bleeds into neighbours\n const clipId = `${this.uid}-${n.id}`;\n const cp = svgEl('clipPath', { id: clipId }, defs);\n svgEl('rect', { x, y, width: fw, height: h, rx: 8 }, cp);\n const content = svgEl('g', { 'clip-path': `url(#${clipId})` }, grp);\n const cy = y + h / 2;\n const name = shortLabel(n);\n const showIcon = fw > 22;\n const iconRight = showIcon ? 30 : 9;\n if (showIcon) appendIcon(content, x + 7, cy - 9, 18, n.iconClass, n.logoUrl, col);\n // shrink the font until the (already abbreviated) label fits, before giving up\n let fontSize = 0;\n for (const fs of [12.5, 11.5, 10.5, 9.5, 8.5]) {\n if (iconRight + name.length * fs * 0.56 + 8 <= fw) { fontSize = fs; break; }\n }\n if (fontSize > 0) {\n svgEl('text', { x: x + iconRight, y: cy + 1, 'font-size': fontSize, 'font-weight': 600, 'dominant-baseline': 'middle', class: 'ftxt-on', text: name }, content);\n if (n.realDur && iconRight + name.length * fontSize * 0.56 + 52 <= fw) {\n svgEl('text', { x: x + fw - 12, y: cy + 1, 'font-size': 10.5, 'text-anchor': 'end', 'dominant-baseline': 'middle', class: 'ftxt-on', opacity: 0.72, text: formatDuration(n.realDur) }, content);\n }\n }\n grp.addEventListener('click', () => { if (!this.pz?.moved) this.nodeSelected.emit(n); });\n this.cells.set(n.id, { outline, fill, x, fw, node: n });\n }\n\n this.playhead = svgEl('line', { x1: this.PAD, y1: this.TOP - 8, x2: this.PAD, y2: VH - 16, 'stroke-width': 1.5, opacity: 0, class: 'fhand' }, g);\n this.playMark = svgEl('path', { d: `M${this.PAD - 5},${this.TOP - 14} L${this.PAD + 5},${this.TOP - 14} L${this.PAD},${this.TOP - 6} Z`, opacity: 0, class: 'fhand-dot' }, g);\n\n this.pz = new PanZoomController(svg, main, 'mj.agentRunFlow.view.flame.v1');\n this.pz.Load(); this.pz.Attach();\n }\n\n private update(p: number, ts: number): void {\n this.cells.forEach(({ outline, fill, fw, node }) => {\n const started = p >= node.t0;\n const active = started && p < node.t1;\n const selected = node.id === this.selectedId;\n const cw = p >= node.t1 ? fw : started ? (p - node.t0) / (node.t1 - node.t0) * fw : 0;\n fill.setAttribute('width', String(Math.max(0, cw)));\n const fillOp = active ? 0.92 + 0.08 * Math.sin(ts / 170) : started ? 0.6 : 0;\n fill.setAttribute('opacity', String(fillOp));\n outline.setAttribute('class', selected ? 'glow2' : active && node.heat ? 'glow' + node.heat : '');\n outline.setAttribute('stroke-width', selected ? '3' : '1.4');\n outline.setAttribute('stroke-opacity', selected || active ? '1' : started ? '0.85' : '0.55');\n });\n const live = p > 0 && p < 1;\n const ph = this.PAD + p * this.IW;\n this.playhead?.setAttribute('x1', String(ph));\n this.playhead?.setAttribute('x2', String(ph));\n this.playhead?.setAttribute('opacity', live ? '0.8' : '0');\n this.playMark?.setAttribute('transform', `translate(${ph - this.PAD},0)`);\n this.playMark?.setAttribute('opacity', live ? '1' : '0');\n }\n}\n"]}
@@ -0,0 +1,12 @@
1
+ export declare function svgEl(tag: string, attrs: Record<string, string | number>, parent?: SVGElement): SVGElement;
2
+ /** Truncate a label to fit, with an ellipsis. */
3
+ export declare function clip(text: string, max: number): string;
4
+ /**
5
+ * Append an icon centered in a `size`×`size` box at (x,y): an agent logo `<image>`
6
+ * when `logoUrl` is set, otherwise a Font Awesome glyph via `<foreignObject>` (FA's
7
+ * global stylesheet renders it; we just set colour + size).
8
+ */
9
+ export declare function appendIcon(parent: SVGElement, x: number, y: number, size: number, iconClass: string, logoUrl: string | null, color: string): SVGElement;
10
+ /** Native hover tooltip on an SVG element (works without any JS). */
11
+ export declare function appendTitle(parent: SVGElement, text: string): void;
12
+ //# sourceMappingURL=flow-svg.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-svg.util.d.ts","sourceRoot":"","sources":["../../../../../src/lib/custom/ai-agent-run/flow/flow-svg.util.ts"],"names":[],"mappings":"AAGA,wBAAgB,KAAK,CACnB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EACtC,MAAM,CAAC,EAAE,UAAU,GAClB,UAAU,CAQZ;AAED,iDAAiD;AACjD,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAID;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EACtD,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GACvD,UAAU,CAgBZ;AAED,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAElE"}
@@ -0,0 +1,46 @@
1
+ /** Tiny SVG element factory shared by all flow renderers. */
2
+ const SVG_NS = 'http://www.w3.org/2000/svg';
3
+ export function svgEl(tag, attrs, parent) {
4
+ const e = document.createElementNS(SVG_NS, tag);
5
+ for (const k in attrs) {
6
+ if (k === 'text')
7
+ e.textContent = String(attrs[k]);
8
+ else
9
+ e.setAttribute(k, String(attrs[k]));
10
+ }
11
+ if (parent)
12
+ parent.appendChild(e);
13
+ return e;
14
+ }
15
+ /** Truncate a label to fit, with an ellipsis. */
16
+ export function clip(text, max) {
17
+ return text.length <= max ? text : text.slice(0, max - 1) + '…';
18
+ }
19
+ const XHTML_NS = 'http://www.w3.org/1999/xhtml';
20
+ /**
21
+ * Append an icon centered in a `size`×`size` box at (x,y): an agent logo `<image>`
22
+ * when `logoUrl` is set, otherwise a Font Awesome glyph via `<foreignObject>` (FA's
23
+ * global stylesheet renders it; we just set colour + size).
24
+ */
25
+ export function appendIcon(parent, x, y, size, iconClass, logoUrl, color) {
26
+ if (logoUrl) {
27
+ const img = svgEl('image', { x, y, width: size, height: size, preserveAspectRatio: 'xMidYMid slice' }, parent);
28
+ img.setAttribute('href', logoUrl);
29
+ img.setAttribute('clip-path', `inset(0 round ${size / 2}px)`);
30
+ return img;
31
+ }
32
+ const fo = svgEl('foreignObject', { x, y, width: size, height: size }, parent);
33
+ const div = document.createElementNS(XHTML_NS, 'div');
34
+ div.setAttribute('style', `width:${size}px;height:${size}px;display:flex;align-items:center;justify-content:center;color:${color}`);
35
+ const i = document.createElementNS(XHTML_NS, 'i');
36
+ i.setAttribute('class', `fa-solid ${iconClass}`);
37
+ i.setAttribute('style', `font-size:${Math.round(size * 0.82)}px;line-height:1`);
38
+ div.appendChild(i);
39
+ fo.appendChild(div);
40
+ return fo;
41
+ }
42
+ /** Native hover tooltip on an SVG element (works without any JS). */
43
+ export function appendTitle(parent, text) {
44
+ svgEl('title', { text }, parent);
45
+ }
46
+ //# sourceMappingURL=flow-svg.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-svg.util.js","sourceRoot":"","sources":["../../../../../src/lib/custom/ai-agent-run/flow/flow-svg.util.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,MAAM,MAAM,GAAG,4BAA4B,CAAC;AAE5C,MAAM,UAAU,KAAK,CACnB,GAAW,EACX,KAAsC,EACtC,MAAmB;IAEnB,MAAM,CAAC,GAAG,QAAQ,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,MAAM;YAAE,CAAC,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;;YAC9C,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,MAAM;QAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,CAAC;AACX,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,GAAW;IAC5C,OAAO,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AAClE,CAAC;AAED,MAAM,QAAQ,GAAG,8BAA8B,CAAC;AAEhD;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,MAAkB,EAAE,CAAS,EAAE,CAAS,EAAE,IAAY,EACtD,SAAiB,EAAE,OAAsB,EAAE,KAAa;IAExD,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/G,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAClC,GAAG,CAAC,YAAY,CAAC,WAAW,EAAE,iBAAiB,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,GAAG,CAAC;IACb,CAAC;IACD,MAAM,EAAE,GAAG,KAAK,CAAC,eAAe,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;IAC/E,MAAM,GAAG,GAAG,QAAQ,CAAC,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACtD,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,SAAS,IAAI,aAAa,IAAI,mEAAmE,KAAK,EAAE,CAAC,CAAC;IACpI,MAAM,CAAC,GAAG,QAAQ,CAAC,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAClD,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,SAAS,EAAE,CAAC,CAAC;IACjD,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,aAAa,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAChF,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACnB,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACpB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,WAAW,CAAC,MAAkB,EAAE,IAAY;IAC1D,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;AACnC,CAAC","sourcesContent":["/** Tiny SVG element factory shared by all flow renderers. */\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n\nexport function svgEl(\n tag: string,\n attrs: Record<string, string | number>,\n parent?: SVGElement\n): SVGElement {\n const e = document.createElementNS(SVG_NS, tag);\n for (const k in attrs) {\n if (k === 'text') e.textContent = String(attrs[k]);\n else e.setAttribute(k, String(attrs[k]));\n }\n if (parent) parent.appendChild(e);\n return e;\n}\n\n/** Truncate a label to fit, with an ellipsis. */\nexport function clip(text: string, max: number): string {\n return text.length <= max ? text : text.slice(0, max - 1) + '…';\n}\n\nconst XHTML_NS = 'http://www.w3.org/1999/xhtml';\n\n/**\n * Append an icon centered in a `size`×`size` box at (x,y): an agent logo `<image>`\n * when `logoUrl` is set, otherwise a Font Awesome glyph via `<foreignObject>` (FA's\n * global stylesheet renders it; we just set colour + size).\n */\nexport function appendIcon(\n parent: SVGElement, x: number, y: number, size: number,\n iconClass: string, logoUrl: string | null, color: string\n): SVGElement {\n if (logoUrl) {\n const img = svgEl('image', { x, y, width: size, height: size, preserveAspectRatio: 'xMidYMid slice' }, parent);\n img.setAttribute('href', logoUrl);\n img.setAttribute('clip-path', `inset(0 round ${size / 2}px)`);\n return img;\n }\n const fo = svgEl('foreignObject', { x, y, width: size, height: size }, parent);\n const div = document.createElementNS(XHTML_NS, 'div');\n div.setAttribute('style', `width:${size}px;height:${size}px;display:flex;align-items:center;justify-content:center;color:${color}`);\n const i = document.createElementNS(XHTML_NS, 'i');\n i.setAttribute('class', `fa-solid ${iconClass}`);\n i.setAttribute('style', `font-size:${Math.round(size * 0.82)}px;line-height:1`);\n div.appendChild(i);\n fo.appendChild(div);\n return fo;\n}\n\n/** Native hover tooltip on an SVG element (works without any JS). */\nexport function appendTitle(parent: SVGElement, text: string): void {\n svgEl('title', { text }, parent);\n}\n"]}