@memberjunction/ng-core-entity-forms 6.2.0-edge.4 → 6.2.0-edge.6

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 (248) hide show
  1. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.d.ts +2 -0
  2. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.d.ts.map +1 -1
  3. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js +103 -95
  4. package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js.map +1 -1
  5. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +13 -0
  6. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
  7. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +37 -17
  8. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  9. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts +9 -1
  10. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts.map +1 -1
  11. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +193 -178
  12. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
  13. package/dist/lib/custom/AIPromptRuns/prompt-run-data-capture-note.component.d.ts +48 -0
  14. package/dist/lib/custom/AIPromptRuns/prompt-run-data-capture-note.component.d.ts.map +1 -0
  15. package/dist/lib/custom/AIPromptRuns/prompt-run-data-capture-note.component.js +195 -0
  16. package/dist/lib/custom/AIPromptRuns/prompt-run-data-capture-note.component.js.map +1 -0
  17. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts +2 -0
  18. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts.map +1 -1
  19. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +345 -323
  20. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
  21. package/dist/lib/custom/Actions/action-form.component.d.ts +2 -0
  22. package/dist/lib/custom/Actions/action-form.component.d.ts.map +1 -1
  23. package/dist/lib/custom/Actions/action-form.component.js +29 -11
  24. package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
  25. package/dist/lib/custom/EntityActions/entityaction.form.component.d.ts +2 -0
  26. package/dist/lib/custom/EntityActions/entityaction.form.component.d.ts.map +1 -1
  27. package/dist/lib/custom/EntityActions/entityaction.form.component.js +2 -0
  28. package/dist/lib/custom/EntityActions/entityaction.form.component.js.map +1 -1
  29. package/dist/lib/custom/MLModels/ml-model-view-models.d.ts +11 -4
  30. package/dist/lib/custom/MLModels/ml-model-view-models.d.ts.map +1 -1
  31. package/dist/lib/custom/MLModels/ml-model-view-models.js +14 -0
  32. package/dist/lib/custom/MLModels/ml-model-view-models.js.map +1 -1
  33. package/dist/lib/custom/MLModels/ps-model-detail.component.d.ts +15 -0
  34. package/dist/lib/custom/MLModels/ps-model-detail.component.d.ts.map +1 -1
  35. package/dist/lib/custom/MLModels/ps-model-detail.component.js +186 -92
  36. package/dist/lib/custom/MLModels/ps-model-detail.component.js.map +1 -1
  37. package/dist/lib/custom/Queries/query-form.component.d.ts +2 -0
  38. package/dist/lib/custom/Queries/query-form.component.d.ts.map +1 -1
  39. package/dist/lib/custom/Queries/query-form.component.js +2 -0
  40. package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
  41. package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts.map +1 -1
  42. package/dist/lib/custom/RecordProcesses/record-process-form.component.js +6 -3
  43. package/dist/lib/custom/RecordProcesses/record-process-form.component.js.map +1 -1
  44. package/dist/lib/custom/SearchScopes/searchscope-form.component.d.ts +3 -3
  45. package/dist/lib/custom/SearchScopes/searchscope-form.component.d.ts.map +1 -1
  46. package/dist/lib/custom/SearchScopes/searchscope-form.component.js +5 -7
  47. package/dist/lib/custom/SearchScopes/searchscope-form.component.js.map +1 -1
  48. package/dist/lib/custom/Templates/templates-form.component.d.ts +19 -1
  49. package/dist/lib/custom/Templates/templates-form.component.d.ts.map +1 -1
  50. package/dist/lib/custom/Templates/templates-form.component.js +20 -27
  51. package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
  52. package/dist/lib/custom/Tests/entity-link-pill.component.d.ts.map +1 -1
  53. package/dist/lib/custom/Tests/entity-link-pill.component.js +14 -6
  54. package/dist/lib/custom/Tests/entity-link-pill.component.js.map +1 -1
  55. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts.map +1 -1
  56. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js +8 -8
  57. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js.map +1 -1
  58. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts +37 -5
  59. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts.map +1 -1
  60. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js +155 -79
  61. package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js.map +1 -1
  62. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts +8 -0
  63. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts.map +1 -1
  64. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +59 -8
  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 +34 -9
  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 +281 -150
  69. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
  70. package/dist/lib/custom/ai-agent-run/run-tree-timeline-projection.js +3 -1
  71. package/dist/lib/custom/ai-agent-run/run-tree-timeline-projection.js.map +1 -1
  72. package/dist/lib/custom/custom-forms.module.d.ts +82 -80
  73. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  74. package/dist/lib/custom/custom-forms.module.js +10 -0
  75. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  76. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
  77. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +65 -47
  78. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  79. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js +17 -17
  80. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js.map +1 -1
  81. package/dist/lib/generated/Entities/MJAIAgentRunStep/mjaiagentrunstep.form.component.d.ts.map +1 -1
  82. package/dist/lib/generated/Entities/MJAIAgentRunStep/mjaiagentrunstep.form.component.js +64 -24
  83. package/dist/lib/generated/Entities/MJAIAgentRunStep/mjaiagentrunstep.form.component.js.map +1 -1
  84. package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js +74 -52
  85. package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js.map +1 -1
  86. package/dist/lib/generated/Entities/MJAIAgentSessionRecordingShard/mjaiagentsessionrecordingshard.form.component.d.ts +10 -0
  87. package/dist/lib/generated/Entities/MJAIAgentSessionRecordingShard/mjaiagentsessionrecordingshard.form.component.d.ts.map +1 -0
  88. package/dist/lib/generated/Entities/MJAIAgentSessionRecordingShard/mjaiagentsessionrecordingshard.form.component.js +86 -0
  89. package/dist/lib/generated/Entities/MJAIAgentSessionRecordingShard/mjaiagentsessionrecordingshard.form.component.js.map +1 -0
  90. package/dist/lib/generated/Entities/MJAIAgentUserPolicy/mjaiagentuserpolicy.form.component.d.ts +10 -0
  91. package/dist/lib/generated/Entities/MJAIAgentUserPolicy/mjaiagentuserpolicy.form.component.d.ts.map +1 -0
  92. package/dist/lib/generated/Entities/MJAIAgentUserPolicy/mjaiagentuserpolicy.form.component.js +132 -0
  93. package/dist/lib/generated/Entities/MJAIAgentUserPolicy/mjaiagentuserpolicy.form.component.js.map +1 -0
  94. package/dist/lib/generated/Entities/MJAIBridgeAgentIdentity/mjaibridgeagentidentity.form.component.js +12 -10
  95. package/dist/lib/generated/Entities/MJAIBridgeAgentIdentity/mjaibridgeagentidentity.form.component.js.map +1 -1
  96. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.d.ts.map +1 -1
  97. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js +86 -32
  98. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js.map +1 -1
  99. package/dist/lib/generated/Entities/MJAIPersona/mjaipersona.form.component.d.ts.map +1 -1
  100. package/dist/lib/generated/Entities/MJAIPersona/mjaipersona.form.component.js +25 -7
  101. package/dist/lib/generated/Entities/MJAIPersona/mjaipersona.form.component.js.map +1 -1
  102. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.d.ts.map +1 -1
  103. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js +180 -160
  104. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js.map +1 -1
  105. package/dist/lib/generated/Entities/MJActionParam/mjactionparam.form.component.js +16 -14
  106. package/dist/lib/generated/Entities/MJActionParam/mjactionparam.form.component.js.map +1 -1
  107. package/dist/lib/generated/Entities/MJArchiveConfiguration/mjarchiveconfiguration.form.component.js +23 -21
  108. package/dist/lib/generated/Entities/MJArchiveConfiguration/mjarchiveconfiguration.form.component.js.map +1 -1
  109. package/dist/lib/generated/Entities/MJArchiveRun/mjarchiverun.form.component.js +21 -19
  110. package/dist/lib/generated/Entities/MJArchiveRun/mjarchiverun.form.component.js.map +1 -1
  111. package/dist/lib/generated/Entities/MJCalendarEventLink/mjcalendareventlink.form.component.d.ts +10 -0
  112. package/dist/lib/generated/Entities/MJCalendarEventLink/mjcalendareventlink.form.component.d.ts.map +1 -0
  113. package/dist/lib/generated/Entities/MJCalendarEventLink/mjcalendareventlink.form.component.js +74 -0
  114. package/dist/lib/generated/Entities/MJCalendarEventLink/mjcalendareventlink.form.component.js.map +1 -0
  115. package/dist/lib/generated/Entities/MJCalendarSyncState/mjcalendarsyncstate.form.component.d.ts +10 -0
  116. package/dist/lib/generated/Entities/MJCalendarSyncState/mjcalendarsyncstate.form.component.d.ts.map +1 -0
  117. package/dist/lib/generated/Entities/MJCalendarSyncState/mjcalendarsyncstate.form.component.js +64 -0
  118. package/dist/lib/generated/Entities/MJCalendarSyncState/mjcalendarsyncstate.form.component.js.map +1 -0
  119. package/dist/lib/generated/Entities/MJCommunicationProvider/mjcommunicationprovider.form.component.d.ts.map +1 -1
  120. package/dist/lib/generated/Entities/MJCommunicationProvider/mjcommunicationprovider.form.component.js +77 -21
  121. package/dist/lib/generated/Entities/MJCommunicationProvider/mjcommunicationprovider.form.component.js.map +1 -1
  122. package/dist/lib/generated/Entities/MJCompanyIntegration/mjcompanyintegration.form.component.d.ts.map +1 -1
  123. package/dist/lib/generated/Entities/MJCompanyIntegration/mjcompanyintegration.form.component.js +28 -10
  124. package/dist/lib/generated/Entities/MJCompanyIntegration/mjcompanyintegration.form.component.js.map +1 -1
  125. package/dist/lib/generated/Entities/MJCompanyIntegrationObject/mjcompanyintegrationobject.form.component.d.ts +10 -0
  126. package/dist/lib/generated/Entities/MJCompanyIntegrationObject/mjcompanyintegrationobject.form.component.d.ts.map +1 -0
  127. package/dist/lib/generated/Entities/MJCompanyIntegrationObject/mjcompanyintegrationobject.form.component.js +189 -0
  128. package/dist/lib/generated/Entities/MJCompanyIntegrationObject/mjcompanyintegrationobject.form.component.js.map +1 -0
  129. package/dist/lib/generated/Entities/MJCompanyIntegrationObjectField/mjcompanyintegrationobjectfield.form.component.d.ts +10 -0
  130. package/dist/lib/generated/Entities/MJCompanyIntegrationObjectField/mjcompanyintegrationobjectfield.form.component.d.ts.map +1 -0
  131. package/dist/lib/generated/Entities/MJCompanyIntegrationObjectField/mjcompanyintegrationobjectfield.form.component.js +116 -0
  132. package/dist/lib/generated/Entities/MJCompanyIntegrationObjectField/mjcompanyintegrationobjectfield.form.component.js.map +1 -0
  133. package/dist/lib/generated/Entities/MJComponent/mjcomponent.form.component.d.ts.map +1 -1
  134. package/dist/lib/generated/Entities/MJComponent/mjcomponent.form.component.js +51 -35
  135. package/dist/lib/generated/Entities/MJComponent/mjcomponent.form.component.js.map +1 -1
  136. package/dist/lib/generated/Entities/MJContentFileType/mjcontentfiletype.form.component.d.ts.map +1 -1
  137. package/dist/lib/generated/Entities/MJContentFileType/mjcontentfiletype.form.component.js +36 -18
  138. package/dist/lib/generated/Entities/MJContentFileType/mjcontentfiletype.form.component.js.map +1 -1
  139. package/dist/lib/generated/Entities/MJContentItem/mjcontentitem.form.component.d.ts.map +1 -1
  140. package/dist/lib/generated/Entities/MJContentItem/mjcontentitem.form.component.js +74 -60
  141. package/dist/lib/generated/Entities/MJContentItem/mjcontentitem.form.component.js.map +1 -1
  142. package/dist/lib/generated/Entities/MJContentItemChunk/mjcontentitemchunk.form.component.d.ts.map +1 -1
  143. package/dist/lib/generated/Entities/MJContentItemChunk/mjcontentitemchunk.form.component.js +30 -32
  144. package/dist/lib/generated/Entities/MJContentItemChunk/mjcontentitemchunk.form.component.js.map +1 -1
  145. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js +43 -35
  146. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js.map +1 -1
  147. package/dist/lib/generated/Entities/MJContentType/mjcontenttype.form.component.js +21 -19
  148. package/dist/lib/generated/Entities/MJContentType/mjcontenttype.form.component.js.map +1 -1
  149. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js +69 -75
  150. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js.map +1 -1
  151. package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.d.ts.map +1 -1
  152. package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js +35 -17
  153. package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js.map +1 -1
  154. package/dist/lib/generated/Entities/MJDashboard/mjdashboard.form.component.d.ts.map +1 -1
  155. package/dist/lib/generated/Entities/MJDashboard/mjdashboard.form.component.js +45 -29
  156. package/dist/lib/generated/Entities/MJDashboard/mjdashboard.form.component.js.map +1 -1
  157. package/dist/lib/generated/Entities/MJDuplicateRun/mjduplicaterun.form.component.js +19 -17
  158. package/dist/lib/generated/Entities/MJDuplicateRun/mjduplicaterun.form.component.js.map +1 -1
  159. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
  160. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +128 -92
  161. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  162. package/dist/lib/generated/Entities/MJEntityAlternateBaseView/mjentityalternatebaseview.form.component.d.ts +10 -0
  163. package/dist/lib/generated/Entities/MJEntityAlternateBaseView/mjentityalternatebaseview.form.component.d.ts.map +1 -0
  164. package/dist/lib/generated/Entities/MJEntityAlternateBaseView/mjentityalternatebaseview.form.component.js +129 -0
  165. package/dist/lib/generated/Entities/MJEntityAlternateBaseView/mjentityalternatebaseview.form.component.js.map +1 -0
  166. package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.d.ts.map +1 -1
  167. package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js +27 -9
  168. package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js.map +1 -1
  169. package/dist/lib/generated/Entities/MJFeaturePipelineVersion/mjfeaturepipelineversion.form.component.d.ts +10 -0
  170. package/dist/lib/generated/Entities/MJFeaturePipelineVersion/mjfeaturepipelineversion.form.component.d.ts.map +1 -0
  171. package/dist/lib/generated/Entities/MJFeaturePipelineVersion/mjfeaturepipelineversion.form.component.js +130 -0
  172. package/dist/lib/generated/Entities/MJFeaturePipelineVersion/mjfeaturepipelineversion.form.component.js.map +1 -0
  173. package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.js +26 -14
  174. package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.js.map +1 -1
  175. package/dist/lib/generated/Entities/MJFeatureValueCache/mjfeaturevaluecache.form.component.js +23 -19
  176. package/dist/lib/generated/Entities/MJFeatureValueCache/mjfeaturevaluecache.form.component.js.map +1 -1
  177. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.d.ts.map +1 -1
  178. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js +30 -12
  179. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js.map +1 -1
  180. package/dist/lib/generated/Entities/MJIntegration/mjintegration.form.component.d.ts.map +1 -1
  181. package/dist/lib/generated/Entities/MJIntegration/mjintegration.form.component.js +26 -8
  182. package/dist/lib/generated/Entities/MJIntegration/mjintegration.form.component.js.map +1 -1
  183. package/dist/lib/generated/Entities/MJIntegrationObject/mjintegrationobject.form.component.d.ts.map +1 -1
  184. package/dist/lib/generated/Entities/MJIntegrationObject/mjintegrationobject.form.component.js +24 -6
  185. package/dist/lib/generated/Entities/MJIntegrationObject/mjintegrationobject.form.component.js.map +1 -1
  186. package/dist/lib/generated/Entities/MJIntegrationObjectField/mjintegrationobjectfield.form.component.d.ts.map +1 -1
  187. package/dist/lib/generated/Entities/MJIntegrationObjectField/mjintegrationobjectfield.form.component.js +25 -6
  188. package/dist/lib/generated/Entities/MJIntegrationObjectField/mjintegrationobjectfield.form.component.js.map +1 -1
  189. package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js +29 -27
  190. package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js.map +1 -1
  191. package/dist/lib/generated/Entities/MJProcessRunDetail/mjprocessrundetail.form.component.js +17 -15
  192. package/dist/lib/generated/Entities/MJProcessRunDetail/mjprocessrundetail.form.component.js.map +1 -1
  193. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.d.ts.map +1 -1
  194. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js +73 -59
  195. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js.map +1 -1
  196. package/dist/lib/generated/Entities/MJQueryEntity/mjqueryentity.form.component.js +10 -8
  197. package/dist/lib/generated/Entities/MJQueryEntity/mjqueryentity.form.component.js.map +1 -1
  198. package/dist/lib/generated/Entities/MJQueryParameter/mjqueryparameter.form.component.d.ts.map +1 -1
  199. package/dist/lib/generated/Entities/MJQueryParameter/mjqueryparameter.form.component.js +12 -4
  200. package/dist/lib/generated/Entities/MJQueryParameter/mjqueryparameter.form.component.js.map +1 -1
  201. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.d.ts.map +1 -1
  202. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js +27 -9
  203. package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js.map +1 -1
  204. package/dist/lib/generated/Entities/MJTest/mjtest.form.component.d.ts.map +1 -1
  205. package/dist/lib/generated/Entities/MJTest/mjtest.form.component.js +24 -6
  206. package/dist/lib/generated/Entities/MJTest/mjtest.form.component.js.map +1 -1
  207. package/dist/lib/generated/Entities/MJTestRun/mjtestrun.form.component.d.ts.map +1 -1
  208. package/dist/lib/generated/Entities/MJTestRun/mjtestrun.form.component.js +29 -11
  209. package/dist/lib/generated/Entities/MJTestRun/mjtestrun.form.component.js.map +1 -1
  210. package/dist/lib/generated/Entities/MJTheme/mjtheme.form.component.d.ts.map +1 -1
  211. package/dist/lib/generated/Entities/MJTheme/mjtheme.form.component.js +13 -3
  212. package/dist/lib/generated/Entities/MJTheme/mjtheme.form.component.js.map +1 -1
  213. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
  214. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +256 -130
  215. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  216. package/dist/lib/generated/Entities/MJUserRoutine/mjuserroutine.form.component.js +31 -25
  217. package/dist/lib/generated/Entities/MJUserRoutine/mjuserroutine.form.component.js.map +1 -1
  218. package/dist/lib/generated/Entities/MJUserView/mjuserview.form.component.js +50 -38
  219. package/dist/lib/generated/Entities/MJUserView/mjuserview.form.component.js.map +1 -1
  220. package/dist/lib/generated/generated-forms.module.d.ts +446 -438
  221. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  222. package/dist/lib/generated/generated-forms.module.js +24 -0
  223. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  224. package/dist/lib/panels/feature-values/feature-values.logic.d.ts +55 -0
  225. package/dist/lib/panels/feature-values/feature-values.logic.d.ts.map +1 -0
  226. package/dist/lib/panels/feature-values/feature-values.logic.js +88 -0
  227. package/dist/lib/panels/feature-values/feature-values.logic.js.map +1 -0
  228. package/dist/lib/panels/feature-values/feature-values.panel.d.ts +39 -0
  229. package/dist/lib/panels/feature-values/feature-values.panel.d.ts.map +1 -0
  230. package/dist/lib/panels/feature-values/feature-values.panel.js +303 -0
  231. package/dist/lib/panels/feature-values/feature-values.panel.js.map +1 -0
  232. package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts +10 -0
  233. package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts.map +1 -1
  234. package/dist/lib/panels/model-predictions/model-prediction.logic.js +15 -1
  235. package/dist/lib/panels/model-predictions/model-prediction.logic.js.map +1 -1
  236. package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts +4 -0
  237. package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts.map +1 -1
  238. package/dist/lib/panels/model-predictions/model-prediction.panel.js +77 -61
  239. package/dist/lib/panels/model-predictions/model-prediction.panel.js.map +1 -1
  240. package/dist/lib/shared/components/template-editor.component.d.ts +37 -0
  241. package/dist/lib/shared/components/template-editor.component.d.ts.map +1 -1
  242. package/dist/lib/shared/components/template-editor.component.js +425 -286
  243. package/dist/lib/shared/components/template-editor.component.js.map +1 -1
  244. package/dist/public-api.d.ts +1 -0
  245. package/dist/public-api.d.ts.map +1 -1
  246. package/dist/public-api.js +1 -0
  247. package/dist/public-api.js.map +1 -1
  248. package/package.json +48 -48
@@ -697,6 +697,7 @@ function MJAIAgentFormComponentExtended_Conditional_0_Conditional_6_Conditional_
697
697
  i0.ɵɵelementEnd();
698
698
  } if (rf & 2) {
699
699
  const execution_r17 = i0.ɵɵnextContext().$implicit;
700
+ const ctx_r1 = i0.ɵɵnextContext(6);
700
701
  i0.ɵɵadvance(9);
701
702
  i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(10, 9, execution_r17.StartedAt, "medium"));
702
703
  i0.ɵɵadvance(2);
@@ -712,7 +713,7 @@ function MJAIAgentFormComponentExtended_Conditional_0_Conditional_6_Conditional_
712
713
  i0.ɵɵadvance();
713
714
  i0.ɵɵconditional(execution_r17.ConversationID ? 16 : -1);
714
715
  i0.ɵɵadvance();
715
- i0.ɵɵconditional(execution_r17.Result ? 17 : -1);
716
+ i0.ɵɵconditional(ctx_r1.HasExecutionResult(execution_r17) ? 17 : -1);
716
717
  i0.ɵɵadvance();
717
718
  i0.ɵɵconditional(execution_r17.ErrorMessage ? 18 : -1);
718
719
  } }
@@ -1685,11 +1686,11 @@ function MJAIAgentFormComponentExtended_Conditional_0_Conditional_6_Conditional_
1685
1686
  } }
1686
1687
  function MJAIAgentFormComponentExtended_Conditional_0_Conditional_6_Conditional_10_Conditional_34_Conditional_25_For_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1687
1688
  i0.ɵɵelementStart(0, "div", 323);
1688
- i0.ɵɵtext(1, " No explicit permissions. Access falls back to this agent's ");
1689
+ i0.ɵɵtext(1, " No explicit permissions. Users need a Search grant (directly or through a role) unless this agent's access is ");
1689
1690
  i0.ɵɵelementStart(2, "code");
1690
- i0.ɵɵtext(3, "SearchScopeAccess");
1691
+ i0.ɵɵtext(3, "All");
1691
1692
  i0.ɵɵelementEnd();
1692
- i0.ɵɵtext(4, " setting. ");
1693
+ i0.ɵɵtext(4, ". ");
1693
1694
  i0.ɵɵelementEnd();
1694
1695
  } }
1695
1696
  function MJAIAgentFormComponentExtended_Conditional_0_Conditional_6_Conditional_10_Conditional_34_Conditional_25_For_1_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
@@ -1754,7 +1755,7 @@ function MJAIAgentFormComponentExtended_Conditional_0_Conditional_6_Conditional_
1754
1755
  i0.ɵɵelementStart(3, "p", 60)(4, "strong");
1755
1756
  i0.ɵɵtext(5, "Pre-Execution");
1756
1757
  i0.ɵɵelementEnd();
1757
- i0.ɵɵtext(6, " scopes are injected automatically before the first LLM call. ");
1758
+ i0.ɵɵtext(6, " scopes are searched before the first LLM call, for users who may search them. ");
1758
1759
  i0.ɵɵelementStart(7, "strong");
1759
1760
  i0.ɵɵtext(8, "Agent-Invoked");
1760
1761
  i0.ɵɵelementEnd();
@@ -1816,7 +1817,7 @@ function MJAIAgentFormComponentExtended_Conditional_0_Conditional_6_Conditional_
1816
1817
  i0.ɵɵtext(23, "Assigned");
1817
1818
  i0.ɵɵelementEnd();
1818
1819
  i0.ɵɵelementStart(24, "div", 307);
1819
- i0.ɵɵtext(25, "Can use ONLY scopes listed below. Other scopes are rejected with ACCESS_DENIED.");
1820
+ i0.ɵɵtext(25, "Can use ONLY scopes listed below, for users with a Search grant on the scope (directly or through a role). Other scopes are rejected with ACCESS_DENIED.");
1820
1821
  i0.ɵɵelementEnd()()();
1821
1822
  i0.ɵɵelementStart(26, "label", 302)(27, "input", 310);
1822
1823
  i0.ɵɵlistener("change", function MJAIAgentFormComponentExtended_Conditional_0_Conditional_6_Conditional_10_Template_input_change_27_listener() { i0.ɵɵrestoreView(_r48); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.record.SearchScopeAccess = "None"); });
@@ -1826,7 +1827,7 @@ function MJAIAgentFormComponentExtended_Conditional_0_Conditional_6_Conditional_
1826
1827
  i0.ɵɵtext(31, "None");
1827
1828
  i0.ɵɵelementEnd();
1828
1829
  i0.ɵɵelementStart(32, "div", 307);
1829
- i0.ɵɵtext(33, "No search capability. The Scoped Search action is disabled for this agent.");
1830
+ i0.ɵɵtext(33, "No search capability. The Scoped Search action and pre-execution retrieval are disabled for this agent.");
1830
1831
  i0.ɵɵelementEnd()()()();
1831
1832
  i0.ɵɵconditionalCreate(34, MJAIAgentFormComponentExtended_Conditional_0_Conditional_6_Conditional_10_Conditional_34_Template, 26, 4);
1832
1833
  i0.ɵɵelementEnd()();
@@ -2684,6 +2685,12 @@ let MJAIAgentFormComponentExtended = class MJAIAgentFormComponentExtended extend
2684
2685
  }
2685
2686
  /** Custom-layout AI Agent form looks best full-width on first open. */
2686
2687
  getDefaultFormWidthMode() { return 'full-width'; }
2688
+ /**
2689
+ * This form renders its own complete layout (header + custom accordion sections
2690
+ * for Sub-Agents, Prompts, Actions, Execution History, and Configuration), so
2691
+ * `<mj-record-form-container>` must not auto-append stock related-entity sections.
2692
+ */
2693
+ get OwnsEntireFormBody() { return true; }
2687
2694
  /** Helper method to create tracked setTimeout calls */
2688
2695
  setTrackedTimeout(callback, delay) {
2689
2696
  const timeoutId = setTimeout(() => {
@@ -3534,7 +3541,7 @@ let MJAIAgentFormComponentExtended = class MJAIAgentFormComponentExtended extend
3534
3541
  Fields: [
3535
3542
  "ID", "AgentID", "ParentRunID", "Status", "StartedAt", "CompletedAt",
3536
3543
  "Success", "TotalTokensUsed", "TotalCost", "TotalCostRollUp", "TotalTokensUsedRollUp",
3537
- "Configuration", "ConversationID", "Result", "ErrorMessage", "__mj_CreatedAt"
3544
+ "Configuration", "ConversationID", "FinalPayload", "Result", "ErrorMessage", "__mj_CreatedAt"
3538
3545
  ],
3539
3546
  ExtraFilter: `AgentID='${this.record.ID}'`,
3540
3547
  OrderBy: '__mj_CreatedAt DESC',
@@ -3669,7 +3676,7 @@ let MJAIAgentFormComponentExtended = class MJAIAgentFormComponentExtended extend
3669
3676
  Fields: [
3670
3677
  "ID", "AgentID", "ParentRunID", "Status", "StartedAt", "CompletedAt",
3671
3678
  "Success", "TotalTokensUsed", "TotalCost", "TotalCostRollUp", "TotalTokensUsedRollUp",
3672
- "Configuration", "ConversationID", "Result", "ErrorMessage", "__mj_CreatedAt"
3679
+ "Configuration", "ConversationID", "FinalPayload", "Result", "ErrorMessage", "__mj_CreatedAt"
3673
3680
  ],
3674
3681
  ExtraFilter: `AgentID='${this.record.ID}'`,
3675
3682
  OrderBy: '__mj_CreatedAt DESC',
@@ -4747,7 +4754,7 @@ let MJAIAgentFormComponentExtended = class MJAIAgentFormComponentExtended extend
4747
4754
  Fields: [
4748
4755
  "ID", "AgentID", "ParentRunID", "Status", "StartedAt", "CompletedAt",
4749
4756
  "Success", "TotalTokensUsed", "TotalCost", "TotalCostRollUp", "TotalTokensUsedRollUp",
4750
- "Configuration", "ConversationID", "Result", "ErrorMessage", "__mj_CreatedAt"
4757
+ "Configuration", "ConversationID", "FinalPayload", "Result", "ErrorMessage", "__mj_CreatedAt"
4751
4758
  ],
4752
4759
  ExtraFilter: `AgentID='${this.record.ID}' AND ID LIKE '%${searchText}%'`,
4753
4760
  OrderBy: '__mj_CreatedAt DESC',
@@ -4776,15 +4783,27 @@ let MJAIAgentFormComponentExtended = class MJAIAgentFormComponentExtended extend
4776
4783
  openExecutionRecord(executionId) {
4777
4784
  return this.OpenExecutionRecord(executionId);
4778
4785
  }
4786
+ /**
4787
+ * Whether to show a run's result: the run is no longer Running and has a result. A running run can
4788
+ * already have a partial `FinalPayload`.
4789
+ */
4790
+ HasExecutionResult(execution) {
4791
+ return execution.Status !== 'Running' && !!this.executionResultJSON(execution);
4792
+ }
4793
+ /** A run's result JSON: `FinalPayload`, or `Result` on older runs. */
4794
+ executionResultJSON(execution) {
4795
+ return execution.FinalPayload ?? execution.Result;
4796
+ }
4779
4797
  /**
4780
4798
  * Gets a preview of the execution result for collapsed view
4781
4799
  */
4782
4800
  GetExecutionResultPreview(execution, trimLongMessages) {
4801
+ const resultJSON = this.executionResultJSON(execution);
4783
4802
  try {
4784
- if (!execution.Result)
4803
+ if (!resultJSON)
4785
4804
  return 'No result';
4786
4805
  // Try to parse the result as JSON
4787
- const parsed = JSON.parse(execution.Result);
4806
+ const parsed = JSON.parse(resultJSON);
4788
4807
  // Extract the user message if it exists
4789
4808
  if (parsed.returnValue?.nextStep?.userMessage) {
4790
4809
  const message = parsed.returnValue.nextStep.userMessage;
@@ -4802,7 +4821,7 @@ let MJAIAgentFormComponentExtended = class MJAIAgentFormComponentExtended extend
4802
4821
  }
4803
4822
  catch {
4804
4823
  // If not JSON, just return the string
4805
- const result = execution.Result || '';
4824
+ const result = resultJSON || '';
4806
4825
  if (trimLongMessages)
4807
4826
  return result.length > 120 ? result.substring(0, 120) + '...' : result;
4808
4827
  else
@@ -4817,11 +4836,12 @@ let MJAIAgentFormComponentExtended = class MJAIAgentFormComponentExtended extend
4817
4836
  * Gets the full execution result message for expanded view
4818
4837
  */
4819
4838
  GetExecutionResultMessage(execution) {
4839
+ const resultJSON = this.executionResultJSON(execution);
4820
4840
  try {
4821
- if (!execution.Result)
4841
+ if (!resultJSON)
4822
4842
  return 'No result';
4823
4843
  // Try to parse the result as JSON
4824
- const parsed = JSON.parse(execution.Result);
4844
+ const parsed = JSON.parse(resultJSON);
4825
4845
  // Extract the user message if it exists
4826
4846
  if (parsed.returnValue?.nextStep?.userMessage) {
4827
4847
  return parsed.returnValue.nextStep.userMessage;
@@ -4831,7 +4851,7 @@ let MJAIAgentFormComponentExtended = class MJAIAgentFormComponentExtended extend
4831
4851
  }
4832
4852
  catch {
4833
4853
  // If not JSON, just return the string
4834
- return execution.Result || '';
4854
+ return resultJSON || '';
4835
4855
  }
4836
4856
  }
4837
4857
  /** @deprecated Use {@link GetExecutionResultMessage}. */
@@ -5786,7 +5806,7 @@ MJAIAgentFormComponentExtended = MJAIAgentFormComponentExtended_1 = __decorate([
5786
5806
  export { MJAIAgentFormComponentExtended };
5787
5807
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJAIAgentFormComponentExtended, [{
5788
5808
  type: Component,
5789
- args: [{ standalone: false, selector: 'mj-ai-agent-form', template: "@if (record) {\n<mj-record-form-container [Record]=\"record\" [FormComponent]=\"this\"\n [ToolbarConfig]=\"toolbarConfig\"\n [WidthMode]=\"'full-width'\"\n (Navigate)=\"OnFormNavigate($event)\"\n (DeleteRequested)=\"OnDeleteRequested()\"\n (FavoriteToggled)=\"OnFavoriteToggled()\"\n (HistoryRequested)=\"OnHistoryRequested()\"\n (ListManagementRequested)=\"OnListManagementRequested()\">\n <form class=\"record-form\" #form=\"ngForm\">\n <!-- Agent Header \u2014 expanded view -->\n @if (!HeaderCollapsed) {\n <div class=\"agent-header\">\n <div class=\"agent-header-content\">\n <button class=\"agent-header-toggle\" (click)=\"ToggleHeaderCollapsed()\"\n title=\"Minimize header\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <div class=\"agent-overview\">\n <div class=\"agent-icon-wrapper\">\n @if (hasLogoURL()) {\n <img [src]=\"record.LogoURL\" [alt]=\"record.Name + ' logo'\" class=\"agent-logo\">\n } @else {\n <i [class]=\"getAgentIcon()\"></i>\n }\n </div>\n <div class=\"agent-info\">\n @if (EditMode) {\n <input type=\"text\" class=\"mj-input agent-name-input\"\n [(ngModel)]=\"record.Name\"\n name=\"agentName\"\n placeholder=\"Enter agent name...\">\n } @else {\n <h1 class=\"agent-name\">{{ record.Name || 'Untitled AI Agent' }}</h1>\n }\n <div class=\"agent-meta\">\n @if (record.Status) {\n <span class=\"status-badge\" [style.background-color]=\"getStatusBadgeColor()\">\n <i class=\"fa-solid fa-circle\"></i>\n {{ record.Status }}\n </span>\n }\n @if (record.Type) {\n <span class=\"execution-mode\">\n Agent Type: {{ record.Type }}\n </span>\n }\n @if (record.Parent) {\n <span class=\"parent-agent clickable\"\n (click)=\"navigateToParentAgent()\"\n title=\"Open parent agent: {{ record.Parent }}\">\n <i class=\"fa-solid fa-sitemap\"></i>\n Child of {{ record.Parent }}\n <i class=\"fa-solid fa-external-link\" style=\"margin-left: 4px; font-size: 10px;\"></i>\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"agent-actions\">\n @if (record.ID) {\n <button mjButton variant=\"primary\" size=\"lg\"\n (click)=\"openTestHarness()\"\n [disabled]=\"record.Status !== 'Active'\"\n title=\"Run this AI agent\">\n <i class=\"fa-solid fa-play\"></i> Run\n </button>\n <button mjButton size=\"lg\"\n (click)=\"openPermissionsDialog()\"\n [title]=\"IsOpenToEveryone ? 'Open to everyone \u2014 click to manage permissions' : 'Restricted \u2014 click to manage permissions'\">\n <i class=\"fa-solid\" [class.fa-lock-open]=\"IsOpenToEveryone\" [class.fa-lock]=\"!IsOpenToEveryone\"\n [style.color]=\"IsOpenToEveryone ? 'var(--mj-status-success)' : null\"></i>\n {{ IsOpenToEveryone ? 'Open' : 'Restricted' }}\n </button>\n }\n <button mjButton variant=\"outline\" size=\"sm\" (click)=\"refreshRelatedData()\" title=\"Refresh all data\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n <!-- Agent Header \u2014 minimized floating bar -->\n @if (HeaderCollapsed) {\n <div class=\"agent-header-mini\">\n <button class=\"agent-header-mini-expand\" (click)=\"ToggleHeaderCollapsed()\"\n title=\"Expand header\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <span class=\"agent-header-mini-name\">{{ record.Name || 'Untitled AI Agent' }}</span>\n @if (record.Status) {\n <span class=\"agent-header-mini-status\" [style.background-color]=\"getStatusBadgeColor()\">\n {{ record.Status }}\n </span>\n }\n <div class=\"agent-header-mini-spacer\"></div>\n @if (record.ID) {\n <button class=\"agent-header-mini-btn agent-header-mini-btn--primary\"\n (click)=\"openTestHarness()\"\n [disabled]=\"record.Status !== 'Active'\"\n title=\"Run agent\">\n <i class=\"fa-solid fa-play\"></i>\n </button>\n <button class=\"agent-header-mini-btn\"\n (click)=\"openPermissionsDialog()\"\n [title]=\"IsOpenToEveryone ? 'Open to everyone' : 'Restricted'\">\n <i class=\"fa-solid\" [class.fa-lock-open]=\"IsOpenToEveryone\" [class.fa-lock]=\"!IsOpenToEveryone\"\n [style.color]=\"IsOpenToEveryone ? 'var(--mj-status-success)' : null\"></i>\n </button>\n }\n <button class=\"agent-header-mini-btn\"\n (click)=\"refreshRelatedData()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n }\n <!-- The tab strip and every pane depend on the agent's TYPE, which loads asynchronously.\n Without this the form rendered its header over an empty area for the whole load \u2014\n no tabs, no designer, and the details pane hidden because no tab was active yet. -->\n @if (IsFormInitializing) {\n <div class=\"agent-form-loading\">\n <mj-loading text=\"Loading agent...\" size=\"medium\"></mj-loading>\n </div>\n } @else {\n <!-- Tabs, not accordions. For an agent type that ships a designer, the diagram IS the agent;\n leaving it as one collapsed panel among eleven made the record's most important view its\n least reachable one. Invocations is offered for every agent, because \"what runs this when\n I'm not looking?\" is a question you can ask of any of them. -->\n @if (FormTabs.length > 1) {\n <div class=\"agent-tabbar\">\n <mj-tab-nav [Tabs]=\"FormTabs\" [ActiveKey]=\"ActiveFormTab || ''\" (TabChange)=\"OnFormTabChange($event)\"></mj-tab-nav>\n </div>\n }\n\n @if (HasDesignerTab) {\n <!-- Hidden with CSS rather than removed with @if: the designer holds UNSAVED edits, and\n destroying it on a tab switch would discard them without a word. Keeping it mounted also\n means the canvas keeps its zoom and node positions across trips to Details. -->\n <div class=\"agent-pane agent-pane--designer\" [class.agent-pane--hidden]=\"ActiveFormTab !== 'designer'\">\n @if (loadingStates.customSection) {\n <mj-loading text=\"Loading {{ agentType?.Name }} configuration...\" size=\"medium\"></mj-loading>\n }\n <ng-container #customSectionContainer></ng-container>\n </div>\n }\n\n @if (record.ID) {\n <div class=\"agent-pane agent-pane--invocations\" [class.agent-pane--hidden]=\"ActiveFormTab !== 'invocations'\">\n <mj-agent-invocations\n [Provider]=\"Provider\"\n [AgentID]=\"record.ID\"\n [Active]=\"ActiveFormTab === 'invocations'\"\n [ExposeAsAction]=\"record.ExposeAsAction\"\n [ParentAgentName]=\"record.Parent\"\n [ParentAgentID]=\"record.ParentID\"\n (RecordOpenRequested)=\"OnInvocationOpenRequested($event)\">\n </mj-agent-invocations>\n </div>\n <div class=\"agent-pane agent-pane--rubrics\" [class.agent-pane--hidden]=\"ActiveFormTab !== 'rubrics'\">\n <mj-agent-rubrics\n [Provider]=\"Provider\"\n [AgentID]=\"record.ID\"\n [Active]=\"ActiveFormTab === 'rubrics'\">\n </mj-agent-rubrics>\n </div>\n }\n\n <!-- Single Pane Layout with Expander Panels -->\n <div class=\"form-content agent-pane\" [class.agent-pane--hidden]=\"ActiveFormTab !== 'details'\">\n <!-- Requests & History -->\n @if (record.ID) {\n <mj-accordion-panel id=\"history\"\n [Expanded]=\"GetSectionExpanded('history', false)\"\n [Disabled]=\"loadingStates.executionHistory\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-history\"></i> Execution History\n @if (loadingStates.executionHistory) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (executionHistoryCount > 0) {\n <span> ({{ executionHistoryCount }}@if (executionHistoryCount < totalExecutionHistoryCount) { of {{ totalExecutionHistoryCount }}})</span>\n }\n </ng-template>\n <div class=\"panel-content execution-history-panel\">\n <!-- Segmented toggle: agent runs vs. realtime voice sessions -->\n @if (UserCanViewSessions) {\n <div class=\"history-view-toggle\" role=\"tablist\">\n <button type=\"button\" class=\"history-toggle-option\"\n [class.active]=\"executionHistoryView === 'runs'\"\n (click)=\"setExecutionHistoryView('runs')\">\n <i class=\"fa-solid fa-person-running\"></i> Runs\n @if (totalExecutionHistoryCount > 0) {\n <span class=\"history-toggle-count\">{{ totalExecutionHistoryCount }}</span>\n }\n </button>\n <button type=\"button\" class=\"history-toggle-option\"\n [class.active]=\"executionHistoryView === 'sessions'\"\n (click)=\"setExecutionHistoryView('sessions')\">\n <i class=\"fa-solid fa-tower-broadcast\"></i> Sessions\n @if (totalSessionCount > 0) {\n <span class=\"history-toggle-count\">{{ totalSessionCount }}</span>\n }\n </button>\n </div>\n }\n @if (executionHistoryView === 'sessions') {\n <!-- Voice/realtime sessions list -->\n @if (loadingSessions) {\n <mj-loading text=\"Loading sessions...\" size=\"medium\"></mj-loading>\n } @else if (agentSessions.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-tower-broadcast\"\n Title=\"No Voice Sessions\"\n Message=\"This agent hasn't participated in any realtime voice sessions yet \u2014 neither as the co-agent nor as a delegation target.\"\n Size=\"compact\" />\n } @else {\n <div class=\"execution-history-list\">\n @for (item of agentSessions; track item.row.ID) {\n <div class=\"execution-card session-card\" (click)=\"openSessionRecord(item.row.ID)\" title=\"Open session\">\n <div class=\"execution-header\">\n <div class=\"execution-left-section\">\n <div class=\"execution-status\">\n <div class=\"status-indicator\" [style.background-color]=\"getSessionStatusColor(item.row.Status)\">\n <i [class]=\"getSessionStatusIcon(item.row.Status)\"></i>\n </div>\n <div class=\"execution-info\">\n <div class=\"execution-title\">\n Session #{{ item.row.ID.substring(0, 8) }}\n @if (item.isCoAgent) {\n <span class=\"session-role-chip\">as co-agent</span>\n }\n @if (item.isTarget) {\n <span class=\"session-role-chip session-role-chip--target\">as target</span>\n }\n </div>\n <div class=\"execution-date\">{{ item.row.__mj_CreatedAt | date:'MMM d, h:mm a' }}</div>\n </div>\n </div>\n <div class=\"execution-metrics\">\n <div class=\"metric-item\">\n <span class=\"session-status-pill\" [attr.data-status]=\"item.row.Status\">{{ item.row.Status }}</span>\n </div>\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-stopwatch\"></i>\n <span class=\"metric-label\">Duration:</span>\n <span class=\"metric-value\">{{ formatSessionDuration(item) }}</span>\n </div>\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-plug\"></i>\n <span class=\"metric-label\">Channels:</span>\n <span class=\"metric-value\">{{ item.channelCount }}</span>\n </div>\n @if (item.isCoAgent && item.targetAgentName) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-bullseye\"></i>\n <span class=\"metric-label\">Target:</span>\n <span class=\"metric-value\">{{ item.targetAgentName }}</span>\n </div>\n }\n @if (item.isTarget && !item.isCoAgent && item.row.Agent) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-tower-broadcast\"></i>\n <span class=\"metric-label\">Co-agent:</span>\n <span class=\"metric-value\">{{ item.row.Agent }}</span>\n </div>\n }\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-user\"></i>\n <span class=\"metric-label\">User:</span>\n <span class=\"metric-value\">{{ item.row.User }}</span>\n </div>\n </div>\n </div>\n <div class=\"execution-actions\">\n <button class=\"action-btn\" (click)=\"openSessionRecord(item.row.ID); $event.stopPropagation()\" title=\"View session details\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n }\n } @else {\n @if (loadingStates.executionHistory) {\n <mj-loading text=\"Loading execution history...\" size=\"medium\"></mj-loading>\n } @else if (executionHistoryCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-clock-rotate-left\"\n Title=\"No Execution History\"\n Message=\"This agent hasn't been executed yet. Use the Test Agent button to run the agent and see execution history here.\"\n Size=\"compact\" />\n } @else {\n <!-- Search Bar -->\n <div class=\"execution-search-bar\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\" class=\"mj-input\"\n [(ngModel)]=\"executionSearchText\"\n (ngModelChange)=\"onExecutionSearchChange()\"\n [ngModelOptions]=\"{standalone: true}\"\n placeholder=\"Search by Run ID...\">\n </div>\n </div>\n <div class=\"execution-history-list\">\n @if (filteredExecutions.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"No Matching Results\"\n [Message]=\"ExecutionSearchEmptyMessage\"\n Size=\"compact\" />\n }\n @for (execution of filteredExecutions; track execution.ID) {\n <div class=\"execution-card\" [class.expanded]=\"expandedExecutions[execution.ID]\">\n <div class=\"execution-header\" (click)=\"toggleExecutionExpanded(execution.ID)\">\n <div class=\"execution-left-section\">\n <div class=\"execution-status\">\n <div class=\"status-indicator\" [style.background-color]=\"getExecutionStatusColor(execution.Status)\">\n <i [class]=\"getExecutionStatusIcon(execution.Status)\"></i>\n </div>\n <div class=\"execution-info\">\n <div class=\"execution-title\">\n <i class=\"fa-solid fa-chevron-right expand-icon\" [class.expanded]=\"expandedExecutions[execution.ID]\"></i>\n Execution #{{ execution.ID.substring(0, 8) }}\n </div>\n <div class=\"execution-date\">{{ execution.__mj_CreatedAt | date:'MMM d, h:mm a' }}</div>\n </div>\n </div>\n <div class=\"execution-metrics\">\n @if (execution.Configuration) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-cog\"></i>\n <span class=\"metric-label\">Config:</span>\n <span class=\"metric-value\">{{ execution.Configuration }}</span>\n </div>\n }\n @if (execution.CompletedAt) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-stopwatch\"></i>\n <span class=\"metric-label\">Duration:</span>\n <span class=\"metric-value\">{{ formatExecutionTimeFromDates(execution.StartedAt, execution.CompletedAt) }}</span>\n </div>\n } @else if (execution.Status === 'Running') {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-clock\"></i>\n <span class=\"metric-label\">Running:</span>\n <!-- <span class=\"metric-value\">{{ execution.StartedAt | runningTime }}</span> -->\n </div>\n }\n @if (execution.TotalTokensUsedRollup || execution.TotalTokensUsed) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-microchip\"></i>\n <span class=\"metric-label\">Tokens:</span>\n <span class=\"metric-value\">{{ formatTokenCount(execution.TotalTokensUsedRollup || execution.TotalTokensUsed) }}</span>\n </div>\n }\n @if (execution.TotalCostRollup || execution.TotalCost) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-dollar-sign\"></i>\n <span class=\"metric-label\">Cost:</span>\n <span class=\"metric-value\">${{ formatCost(execution.TotalCostRollup || execution.TotalCost) }}</span>\n </div>\n }\n </div>\n </div>\n <div class=\"execution-actions\">\n <button class=\"action-btn\" (click)=\"openExecutionRecord(execution.ID); $event.stopPropagation()\" title=\"View details\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n </button>\n </div>\n </div>\n @if (expandedExecutions[execution.ID]) {\n <div class=\"execution-expanded-content\">\n <!-- Detailed Metrics -->\n <div class=\"detailed-metrics\">\n <div class=\"metrics-grid\">\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-clock\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Started</span>\n <span class=\"metric-data\">{{ execution.StartedAt | date:'medium' }}</span>\n </div>\n </div>\n @if (execution.CompletedAt) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Completed</span>\n <span class=\"metric-data\">{{ execution.CompletedAt | date:'medium' }}</span>\n </div>\n </div>\n }\n @if (execution.TotalTokensUsed) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-microchip\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Direct Tokens</span>\n <span class=\"metric-data\">{{ formatTokenCount(execution.TotalTokensUsed) }}</span>\n </div>\n </div>\n }\n @if (execution.TotalTokensUsedRollup && execution.TotalTokensUsedRollup !== execution.TotalTokensUsed) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Total + Sub-agents</span>\n <span class=\"metric-data\">{{ formatTokenCount(execution.TotalTokensUsedRollup) }}</span>\n </div>\n </div>\n }\n @if (execution.TotalCost) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-dollar-sign\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Direct Cost</span>\n <span class=\"metric-data\">${{ formatCost(execution.TotalCost) }}</span>\n </div>\n </div>\n }\n @if (execution.TotalCostRollup && execution.TotalCostRollup !== execution.TotalCost) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-calculator\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Total + Sub-agents</span>\n <span class=\"metric-data\">${{ formatCost(execution.TotalCostRollup) }}</span>\n </div>\n </div>\n }\n @if (execution.ConversationID) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-comments\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Conversation</span>\n <span class=\"metric-data\">{{ execution.ConversationID.substring(0, 8) }}...</span>\n </div>\n </div>\n }\n </div>\n </div>\n @if (execution.Result) {\n <div class=\"result-section\">\n <h5><i class=\"fa-solid fa-file-text\"></i> Result</h5>\n <mj-code-editor\n [value]=\"getExecutionResultPreview(execution, false)\"\n [readonly]=\"true\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"max-height: 200px; width: 100%;\">\n </mj-code-editor>\n </div>\n }\n @if (execution.ErrorMessage) {\n <div class=\"error-section\">\n <h5><i class=\"fa-solid fa-exclamation-triangle\"></i> Error</h5>\n <div class=\"error-content\">{{ execution.ErrorMessage }}</div>\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- Pagination Controls -->\n @if (totalPages > 1) {\n <div class=\"pagination-controls\">\n <button mjButton\n variant=\"outline\"\n (click)=\"goToPreviousPage()\"\n [disabled]=\"!hasPreviousPage || isLoadingPage\"\n class=\"page-nav-btn\">\n <i class=\"fa-solid fa-chevron-left\"></i>\n Previous\n </button>\n <div class=\"page-info\">\n @if (isLoadingPage) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Loading...\n } @else {\n Page {{ executionHistoryCurrentPage }} of {{ totalPages }}\n <span class=\"record-count\">({{ totalExecutionHistoryCount }} total)</span>\n }\n </div>\n <button mjButton\n variant=\"outline\"\n (click)=\"goToNextPage()\"\n [disabled]=\"!hasNextPage || isLoadingPage\"\n class=\"page-nav-btn\">\n Next\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"navigateToEntity('MJ: AI Agent Runs', '')\"\n class=\"view-all-btn\">\n <i class=\"fa-solid fa-external-link\"></i>\n View All in Grid\n </button>\n </div>\n }\n </div>\n }\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Actions -->\n @if (record.ID) {\n <mj-accordion-panel id=\"actions\"\n [Expanded]=\"GetSectionExpanded('actions', false)\"\n [Disabled]=\"loadingStates.actions\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-bolt\"></i> Actions\n @if (loadingStates.actions) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (actionCount > 0) {\n <span> ({{ actionCount }})</span>\n }\n </ng-template>\n <div class=\"panel-content\">\n @if (loadingStates.actions) {\n <div class=\"loading-state\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <p>Loading actions...</p>\n </div>\n } @else {\n <div class=\"section-header\">\n <div class=\"header-actions\">\n @if (EditMode && UserCanCreateActions) {\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"configureActions()\">\n <i class=\"fa-solid fa-plus\"></i> Add Action\n </button>\n }\n </div>\n </div>\n @if (actionCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-bolt\"\n Title=\"No Actions Configured\"\n Message=\"Add actions to enable this agent to perform specific tasks and operations.\"\n [ActionText]=\"(EditMode && UserCanCreateActions) ? 'Configure First Action' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"configureActions()\"\n Size=\"compact\" />\n } @else {\n <div class=\"entity-list\">\n @for (action of agentActions; track action.ID) {\n <div class=\"entity-item action-item\" (click)=\"navigateToEntity('MJ: Actions', action.ID)\">\n <div class=\"item-icon\">\n <i [class]=\"getActionIcon(action)\"></i>\n </div>\n <div class=\"item-content\">\n <div class=\"item-title\">{{ action.Name || 'Untitled Action' }}</div>\n @if (action.Description) {\n <div class=\"item-preview\">{{ action.Description }}</div>\n }\n <div class=\"item-meta\">\n @if (action.Type) {\n <span class=\"meta-tag\">{{ action.Type }}</span>\n }\n <span class=\"status-tag\" [class.active]=\"action.Status==='Active'\" [class.inactive]=\"action.Status!=='Active'\">\n <i class=\"fa-solid\" [class.fa-check-circle]=\"action.Status==='Active'\" [class.fa-times-circle]=\"action.Status!=='Active'\"></i>\n {{ action.Status }}\n </span>\n </div>\n </div>\n <div class=\"item-actions\">\n @if (EditMode && UserCanDeleteActions) {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"removeAction(action, $event)\"\n title=\"Remove action\"\n class=\"error-action\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n <i class=\"fa-solid fa-external-link\"></i>\n </div>\n </div>\n }\n @if (actionCount > agentActions.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('MJ: AI Agent Actions', '')\">\n <span>View all {{ actionCount }} actions...</span>\n </div>\n }\n </div>\n }\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Sub-Agents (Unified View with Filter) -->\n @if (record.ID) {\n <mj-accordion-panel id=\"subagents\"\n [Expanded]=\"GetSectionExpanded('subagents', false)\"\n [Disabled]=\"loadingStates.subAgents\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-sitemap\"></i> Sub-Agents\n @if (loadingStates.subAgents) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (totalSubAgentCount > 0) {\n <span> ({{ totalSubAgentCount }})</span>\n }\n </ng-template>\n <div class=\"panel-content\">\n <!-- Filter Controls -->\n <div class=\"section-header sub-agent-filter-header\">\n <div class=\"filter-controls\">\n <div class=\"mj-button-group\">\n <button mjButton\n size=\"sm\"\n [class.active]=\"subAgentFilter === 'all'\"\n (click)=\"setSubAgentFilter('all')\">\n <i class=\"fa-solid fa-layer-group\"></i>\n All ({{ totalSubAgentCount }})\n </button>\n <button mjButton\n size=\"sm\"\n [class.active]=\"subAgentFilter === 'child'\"\n (click)=\"setSubAgentFilter('child')\">\n <i class=\"fa-solid fa-link\"></i>\n Child ({{ childSubAgentCount }})\n </button>\n <button mjButton\n size=\"sm\"\n [class.active]=\"subAgentFilter === 'related'\"\n (click)=\"setSubAgentFilter('related')\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n Related ({{ relatedSubAgentCount }})\n </button>\n </div>\n </div>\n <div class=\"header-actions\">\n @if (EditMode && UserCanCreateSubAgents) {\n <button mjButton\n variant=\"primary\"\n size=\"sm\"\n (click)=\"createChildSubAgent()\"\n title=\"Create a new child sub-agent that shares this agent's payload\">\n <i class=\"fa-solid fa-link\"></i>\n Create Child\n </button>\n <button mjButton\n size=\"sm\"\n (click)=\"linkRelatedSubAgent()\"\n title=\"Link an existing agent as a related sub-agent with payload mapping\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n Link Related\n </button>\n }\n </div>\n </div>\n <!-- Empty State -->\n @if (totalSubAgentCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-sitemap\"\n Title=\"No Sub-Agents\"\n Message=\"Sub-agents help build complex workflows through hierarchical orchestration.\"\n Size=\"compact\">\n <div class=\"empty-state-info\">\n <div class=\"info-card\">\n <i class=\"fa-solid fa-link\" style=\"color: var(--mj-status-info);\"></i>\n <strong>Child Sub-Agents</strong>\n <p>Share payload structure, dedicated to parent</p>\n </div>\n <div class=\"info-card\">\n <i class=\"fa-solid fa-share-nodes\" style=\"color: var(--mj-brand-primary);\"></i>\n <strong>Related Sub-Agents</strong>\n <p>Reusable agents with payload mapping</p>\n </div>\n </div>\n </mj-empty-state>\n } @else {\n <!-- Unified Sub-Agent List -->\n <div class=\"entity-list\">\n @for (item of filteredSubAgents; track item.agent.ID) {\n <div class=\"entity-item sub-agent-item\"\n [class.child-sub-agent]=\"item.type === 'child'\"\n [class.related-sub-agent]=\"item.type === 'related'\"\n (click)=\"navigateToEntity('MJ: AI Agents', item.agent.ID)\">\n <!-- Type Badge -->\n <div class=\"sub-agent-type-badge\"\n [style.background-color]=\"getSubAgentBadgeColor(item)\">\n <i [class]=\"getSubAgentBadgeIcon(item)\"></i>\n {{ getSubAgentBadgeText(item) }}\n </div>\n <!-- Agent Icon -->\n <div class=\"item-icon\">\n @if (hasSubAgentLogoURL(item.agent)) {\n <img [src]=\"item.agent.LogoURL\"\n [alt]=\"item.agent.Name + ' logo'\"\n class=\"sub-agent-logo\">\n } @else {\n <i [class]=\"getSubAgentIcon(item.agent)\"></i>\n }\n </div>\n <!-- Agent Content -->\n <div class=\"item-content\">\n <div class=\"item-title\">{{ item.agent.Name || 'Untitled Sub-Agent' }}</div>\n @if (item.agent.Description) {\n <div class=\"item-preview\">{{ item.agent.Description }}</div>\n }\n <div class=\"item-meta\">\n <!-- Payload Info -->\n <span class=\"meta-tag payload-info\">\n <i class=\"fa-solid fa-database\"></i>\n {{ getSubAgentPayloadInfo(item) }}\n </span>\n <!-- Status -->\n @if (item.agent.Status) {\n <span class=\"status-tag\"\n [style.background-color]=\"getStatusBadgeColor()\">\n {{ item.agent.Status }}\n </span>\n }\n <!-- Agent Type -->\n @if (item.agent.Type) {\n <span class=\"meta-tag\">{{ item.agent.Type }}</span>\n }\n </div>\n </div>\n <!-- Actions -->\n <div class=\"item-actions\">\n @if (EditMode) {\n <!-- Output Mapping Config (Related only) -->\n @if (item.type === 'related') {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"configureOutputMapping(item, $event)\"\n title=\"Configure output mapping\">\n <i class=\"fa-solid fa-exchange-alt\"></i>\n </button>\n }\n <!-- Advanced Settings (Child only) -->\n @if (item.type === 'child' && UserCanCreateSubAgents) {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"openSubAgentAdvancedSettings(item.agent, $event)\"\n title=\"Advanced settings\">\n <i class=\"fa-solid fa-cog\"></i>\n </button>\n }\n <!-- Remove/Unlink -->\n @if (UserCanDeleteSubAgents) {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"item.type === 'child' ? removeChildSubAgent(item, $event) : unlinkRelatedSubAgent(item, $event)\"\n [title]=\"item.type === 'child' ? 'Delete child sub-agent' : 'Unlink related sub-agent'\"\n class=\"error-action\">\n <i [class]=\"item.type === 'child' ? 'fa-solid fa-trash' : 'fa-solid fa-unlink'\"></i>\n </button>\n }\n }\n <i class=\"fa-solid fa-external-link\"></i>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Prompts (With Model Selection) -->\n @if (record.ID) {\n <mj-accordion-panel id=\"prompts\"\n [Expanded]=\"GetSectionExpanded('prompts', false)\"\n [Disabled]=\"loadingStates.prompts\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-comments\"></i> Prompts\n @if (loadingStates.prompts) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (promptCount > 0) {\n <span> ({{ promptCount }})</span>\n }\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"prompt-controls\">\n <!-- Model Selection Mode Control -->\n <div class=\"model-selection-mode\">\n <label class=\"model-selection-label\">\n <i class=\"fa-solid fa-sliders\"></i>\n Model Selection:\n </label>\n @if (EditMode) {\n <mj-dropdown\n [(ngModel)]=\"record.ModelSelectionMode\"\n name=\"modelSelectionMode\"\n [Data]=\"modelSelectionModes\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n class=\"model-selection-dropdown\">\n </mj-dropdown>\n } @else {\n <span class=\"model-selection-value\">{{ record.ModelSelectionMode || 'Agent Type' }}</span>\n }\n </div>\n </div>\n <div class=\"header-actions\">\n @if (EditMode && UserCanCreateNewPrompts) {\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"addPrompt()\">\n <i class=\"fa-solid fa-plus\"></i> Add Prompt\n </button>\n }\n </div>\n </div>\n @if (promptCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-comments\"\n Title=\"No Prompts Configured\"\n Message=\"Add prompts to define how this agent processes requests and generates responses.\"\n [ActionText]=\"(EditMode && UserCanCreateNewPrompts) ? 'Create First Prompt' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"addPrompt()\"\n Size=\"compact\" />\n } @else {\n <div class=\"entity-list\">\n @for (prompt of agentPrompts; track prompt.ID) {\n <div class=\"entity-item prompt-item\" (click)=\"navigateToEntity('MJ: AI Prompts', prompt.ID)\">\n <div class=\"item-icon\">\n <i class=\"fa-solid fa-comment-dots\"></i>\n </div>\n <div class=\"item-content\">\n <div class=\"item-title\">{{ prompt.Name }}</div>\n @if (prompt.TemplateText) {\n <div class=\"item-preview\">{{ prompt.TemplateText.substring(0, 120) }}{{ prompt.TemplateText.length > 120 ? '...' : '' }}</div>\n }\n <div class=\"item-meta\">\n @if (prompt.PromptRole) {\n <span class=\"meta-tag\">{{ prompt.PromptRole }}</span>\n }\n </div>\n </div>\n <div class=\"item-actions\">\n @if (EditMode && UserCanCreatePrompts) {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"openPromptAdvancedSettings(prompt, $event)\"\n title=\"Advanced settings\">\n <i class=\"fa-solid fa-cog\"></i>\n </button>\n }\n @if (EditMode && UserCanDeletePrompts) {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"removePrompt(prompt, $event)\"\n title=\"Remove prompt\"\n class=\"error-action\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n <i class=\"fa-solid fa-external-link\"></i>\n </div>\n </div>\n }\n @if (promptCount > agentPrompts.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('MJ: AI Prompts', '')\">\n <span>View all {{ promptCount }} prompts...</span>\n </div>\n }\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Learning & Analytics -->\n @if (record.ID) {\n <mj-accordion-panel id=\"learning\"\n [Expanded]=\"GetSectionExpanded('learning', false)\"\n [Disabled]=\"loadingStates.learningCycles\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-brain\"></i> Learning Cycles\n @if (loadingStates.learningCycles) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (learningCycleCount > 0) {\n <span> ({{ learningCycleCount }})</span>\n }\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Monitor and manage learning cycles, training sessions, and performance analytics.\n </div>\n </div>\n @if (learningCycleCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-brain\"\n Title=\"No Learning Cycles\"\n Message=\"Learning cycles will appear here as the agent processes requests and improves over time.\"\n Size=\"compact\" />\n } @else {\n <div class=\"entity-list\">\n @for (cycle of learningCycles; track cycle.ID) {\n <div class=\"entity-item learning-item\" (click)=\"navigateToEntity('MJ: AI Agent Learning Cycles', cycle.ID)\">\n <div class=\"item-icon\">\n <i class=\"fa-solid fa-brain\"></i>\n </div>\n <div class=\"item-content\">\n <div class=\"item-title\">Learning Cycle {{ cycle.ID.substring(0, 8) }}</div>\n <div class=\"item-meta\">\n @if (cycle.StartedAt) {\n <span class=\"meta-tag\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ cycle.StartedAt | date:'short' }}\n </span>\n }\n @if (cycle.Status) {\n <span class=\"status-tag\">{{ cycle.Status }}</span>\n }\n </div>\n </div>\n <div class=\"item-actions\">\n <i class=\"fa-solid fa-external-link\"></i>\n </div>\n </div>\n }\n @if (learningCycleCount > learningCycles.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('MJ: AI Agent Learning Cycles', '')\">\n <span>View all {{ learningCycleCount }} cycles...</span>\n </div>\n }\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Notes & Documentation -->\n @if (record.ID) {\n <mj-accordion-panel id=\"notes\"\n [Expanded]=\"GetSectionExpanded('notes', false)\"\n [Disabled]=\"loadingStates.notes\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-sticky-note\"></i> Notes\n @if (loadingStates.notes) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (noteCount > 0) {\n <span> ({{ noteCount }})</span>\n }\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Manage notes, documentation, and annotations for this agent.\n </div>\n <div class=\"header-actions\">\n @if (EditMode && UserCanCreateNotes) {\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"addNote()\">\n <i class=\"fa-solid fa-plus\"></i> Add Note\n </button>\n }\n </div>\n </div>\n @if (noteCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-sticky-note\"\n Title=\"No Notes\"\n Message=\"Add notes to document important information, observations, or instructions for this agent.\"\n [ActionText]=\"(EditMode && UserCanCreateNotes) ? 'Create First Note' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"addNote()\"\n Size=\"compact\" />\n } @else {\n <div class=\"entity-list\">\n @for (note of agentNotes; track note.ID) {\n <div class=\"entity-item note-item\" (click)=\"navigateToEntity('MJ: AI Agent Notes', note.ID)\">\n <div class=\"item-icon\">\n <i class=\"fa-solid fa-sticky-note\"></i>\n </div>\n <div class=\"item-content\">\n <div class=\"item-title\">{{ note.Type || 'Note' }}</div>\n @if (note.Note) {\n <div class=\"item-preview\">{{ note.Note.substring(0, 100) }}{{ note.Note.length > 100 ? '...' : '' }}</div>\n }\n <div class=\"item-meta\">\n @if (note.__mj_CreatedAt) {\n <span class=\"meta-tag\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ note.__mj_CreatedAt | date:'short' }}\n </span>\n }\n </div>\n </div>\n <div class=\"item-actions\">\n <i class=\"fa-solid fa-external-link\"></i>\n </div>\n </div>\n }\n @if (noteCount > agentNotes.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('MJ: AI Agent Notes', '')\">\n <span>View all {{ noteCount }} notes...</span>\n </div>\n }\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Search -->\n @if (record.ID) {\n <mj-accordion-panel id=\"search\"\n [Expanded]=\"GetSectionExpanded('search', false)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-magnifying-glass\"></i> Search\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Control this agent's access to <strong>Scoped Search</strong> and assign the scopes it can use for pre-execution RAG or agent-invoked search.\n </div>\n </div>\n\n <!-- Scope Access mode -->\n <div class=\"agent-search-access\">\n <label class=\"agent-search-access-option\" [class.active]=\"record.SearchScopeAccess === 'All'\">\n <input type=\"radio\" name=\"SearchScopeAccess\" value=\"All\" [checked]=\"record.SearchScopeAccess === 'All'\" [disabled]=\"!EditMode\" (change)=\"record.SearchScopeAccess = 'All'\">\n <i class=\"fa-solid fa-globe\"></i>\n <div class=\"agent-search-access-text\">\n <div class=\"agent-search-access-title\">All</div>\n <div class=\"agent-search-access-desc\">Can use any scope including Global. No scope restriction.</div>\n </div>\n </label>\n <label class=\"agent-search-access-option\" [class.active]=\"record.SearchScopeAccess === 'Assigned'\">\n <input type=\"radio\" name=\"SearchScopeAccess\" value=\"Assigned\" [checked]=\"record.SearchScopeAccess === 'Assigned'\" [disabled]=\"!EditMode\" (change)=\"record.SearchScopeAccess = 'Assigned'\">\n <i class=\"fa-solid fa-user-check\"></i>\n <div class=\"agent-search-access-text\">\n <div class=\"agent-search-access-title\">Assigned</div>\n <div class=\"agent-search-access-desc\">Can use ONLY scopes listed below. Other scopes are rejected with ACCESS_DENIED.</div>\n </div>\n </label>\n <label class=\"agent-search-access-option\" [class.active]=\"record.SearchScopeAccess === 'None'\">\n <input type=\"radio\" name=\"SearchScopeAccess\" value=\"None\" [checked]=\"record.SearchScopeAccess === 'None'\" [disabled]=\"!EditMode\" (change)=\"record.SearchScopeAccess = 'None'\">\n <i class=\"fa-solid fa-ban\"></i>\n <div class=\"agent-search-access-text\">\n <div class=\"agent-search-access-title\">None</div>\n <div class=\"agent-search-access-desc\">No search capability. The Scoped Search action is disabled for this agent.</div>\n </div>\n </label>\n </div>\n\n <!-- Assigned scopes grid -->\n @if (record.SearchScopeAccess !== 'None') {\n <div class=\"agent-search-grid-header\">\n <h4>Assigned Scopes</h4>\n <p class=\"section-description\">\n <strong>Pre-Execution</strong> scopes are injected automatically before the first LLM call.\n <strong>Agent-Invoked</strong> scopes are callable via the Scoped Search tool during execution.\n <strong>Both</strong> covers both paths.\n </p>\n </div>\n <mj-search-scope-child-grid\n [ParentID]=\"record.ID\"\n ChildEntityName=\"MJ: AI Agent Search Scopes\"\n ParentFieldName=\"AgentID\"\n [Columns]=\"AgentSearchScopeColumns\"\n [Disabled]=\"!EditMode\"\n AddButtonLabel=\"+ Assign another scope\"\n EmptyMessage=\"No scopes assigned yet. Assign at least one if this agent will use Scoped Search.\"\n (RowsChanged)=\"LoadPermissionSummary()\">\n </mj-search-scope-child-grid>\n\n <!-- Phase 2A: read-only audit summary of who has\n permission on each of this agent's assigned scopes.\n Editing happens in the Knowledge Hub Config dashboard\n (see \"Permissions\" subtab under Search Scopes). -->\n <div class=\"agent-search-section\" style=\"margin-top: 16px;\">\n <h4 style=\"margin: 0 0 8px 0;\">\n <i class=\"fa-solid fa-shield-halved\"></i> Effective scope permissions\n </h4>\n <p class=\"section-description\" style=\"margin-bottom: 8px;\">\n Per-user / per-role grants on the scopes assigned above. Edit grants in\n <strong>Knowledge Hub Config &rarr; Search Scopes &rarr; Permissions</strong>.\n </p>\n @if (IsLoadingPermissions) {\n <div style=\"color: var(--mj-text-muted);\">Loading permissions&hellip;</div>\n } @else if (PermissionSummary.length === 0) {\n <div style=\"color: var(--mj-text-muted); font-style: italic;\">\n No scopes assigned yet \u2014 permissions will appear here once you add scopes above.\n </div>\n } @else {\n @for (s of PermissionSummary; track s.ScopeID) {\n <div style=\"margin-bottom: 12px; padding: 8px 12px; background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-subtle); border-radius: 4px;\">\n <div style=\"font-weight: 600; margin-bottom: 4px;\">{{ s.ScopeName }}</div>\n @if (s.Permissions.length === 0) {\n <div style=\"color: var(--mj-text-muted); font-size: 0.9em;\">\n No explicit permissions. Access falls back to this agent's <code>SearchScopeAccess</code> setting.\n </div>\n } @else {\n <ul style=\"margin: 4px 0 0 16px; padding: 0;\">\n @for (p of s.Permissions; track p.Principal + p.Level) {\n <li style=\"font-size: 0.9em; padding: 2px 0;\">\n <i class=\"fa-solid\" [class.fa-user]=\"p.PrincipalType === 'User'\" [class.fa-users]=\"p.PrincipalType === 'Role'\"></i>\n <strong>{{ p.Principal }}</strong>\n <span style=\"color: var(--mj-text-muted);\">({{ p.PrincipalType }})</span>\n &mdash; <span [style.color]=\"p.Level === 'None' ? 'var(--mj-status-error-text)' : 'var(--mj-text-primary)'\">{{ p.Level }}</span>\n </li>\n }\n </ul>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Payload -->\n <mj-accordion-panel id=\"payload\"\n [Expanded]=\"GetSectionExpanded('payload', false)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-exchange-alt\"></i> Payload Management\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Configure how this agent handles data payloads, path routing, and validation between parent and child agents.\n </div>\n </div>\n <!-- Payload Scope Section -->\n <div class=\"payload-section\">\n <h3 class=\"payload-section-title\">\n <i class=\"fa-solid fa-target\"></i>\n Payload Scope\n </h3>\n <div class=\"payload-field-container\">\n <div class=\"payload-field-info\">\n <label class=\"payload-field-label\">Payload Scope Path</label>\n <p class=\"payload-field-description\">\n Specify a path within the parent payload that this sub-agent should operate on.\n Leave empty to receive the entire payload.\n </p>\n </div>\n <div class=\"payload-field-input\">\n <mj-form-field\n FieldName=\"PayloadScope\"\n Type=\"textbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\"\n style=\"width: 100%;\">\n </mj-form-field>\n <div class=\"payload-field-example\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Example: <code>/customer/profile</code> or <code>/analysis/results</code></span>\n </div>\n </div>\n </div>\n </div>\n <!-- Path Configuration Section -->\n <div class=\"payload-section\">\n <h3 class=\"payload-section-title\">\n <i class=\"fa-solid fa-route\"></i>\n Path Configuration\n </h3>\n <div class=\"payload-paths-grid\">\n <!-- Downstream Paths -->\n <div class=\"payload-path-card\">\n <div class=\"payload-path-header\">\n <div class=\"payload-path-icon downstream\">\n <i class=\"fa-solid fa-arrow-down\"></i>\n </div>\n <div class=\"payload-path-info\">\n <h4>Downstream Paths</h4>\n <p>JSON array of paths to pass to sub-agents</p>\n </div>\n </div>\n <div class=\"payload-path-content\">\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"record.PayloadDownstreamPaths || '[&quot;*&quot;]'\"\n [readonly]=\"!EditMode\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"height: 100px; width: 100%;\"\n (valueChange)=\"updatePayloadField('PayloadDownstreamPaths', $event)\">\n </mj-code-editor>\n </div>\n <div class=\"payload-path-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Use <code>[\"*\"]</code> to pass entire payload or specify paths like <code>[\"user.id\", \"order.*\"]</code>\n </div>\n </div>\n </div>\n <!-- Upstream Paths -->\n <div class=\"payload-path-card\">\n <div class=\"payload-path-header\">\n <div class=\"payload-path-icon upstream\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n </div>\n <div class=\"payload-path-info\">\n <h4>Upstream Paths</h4>\n <p>JSON array of paths sub-agents can write back</p>\n </div>\n </div>\n <div class=\"payload-path-content\">\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"record.PayloadUpstreamPaths || '[&quot;*&quot;]'\"\n [readonly]=\"!EditMode\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"height: 100px; width: 100%;\"\n (valueChange)=\"updatePayloadField('PayloadUpstreamPaths', $event)\">\n </mj-code-editor>\n </div>\n <div class=\"payload-path-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Use <code>[\"*\"]</code> to allow all writes or limit to specific paths\n </div>\n </div>\n </div>\n <!-- Self Read Paths -->\n <div class=\"payload-path-card\">\n <div class=\"payload-path-header\">\n <div class=\"payload-path-icon self-read\">\n <i class=\"fa-solid fa-eye\"></i>\n </div>\n <div class=\"payload-path-info\">\n <h4>Self Read Paths</h4>\n <p>JSON array of paths this agent can read</p>\n </div>\n </div>\n <div class=\"payload-path-content\">\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"record.PayloadSelfReadPaths || '[]'\"\n [readonly]=\"!EditMode\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"height: 100px; width: 100%;\"\n (valueChange)=\"updatePayloadField('PayloadSelfReadPaths', $event)\">\n </mj-code-editor>\n </div>\n <div class=\"payload-path-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Paths this agent's prompts can read from the payload\n </div>\n </div>\n </div>\n <!-- Self Write Paths -->\n <div class=\"payload-path-card\">\n <div class=\"payload-path-header\">\n <div class=\"payload-path-icon self-write\">\n <i class=\"fa-solid fa-pen\"></i>\n </div>\n <div class=\"payload-path-info\">\n <h4>Self Write Paths</h4>\n <p>JSON array of paths this agent can write to</p>\n </div>\n </div>\n <div class=\"payload-path-content\">\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"record.PayloadSelfWritePaths || '[]'\"\n [readonly]=\"!EditMode\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"height: 100px; width: 100%;\"\n (valueChange)=\"updatePayloadField('PayloadSelfWritePaths', $event)\">\n </mj-code-editor>\n </div>\n <div class=\"payload-path-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Paths this agent's prompts can write back to the payload\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Validation Section -->\n <div class=\"payload-section\">\n <h3 class=\"payload-section-title\">\n <i class=\"fa-solid fa-shield-check\"></i>\n Final Payload Validation\n </h3>\n <div class=\"payload-validation-container\">\n <div class=\"payload-validation-settings\">\n <div class=\"validation-field-group\">\n <label class=\"validation-field-label\">Validation Mode</label>\n <p class=\"validation-field-description\">How to handle validation failures</p>\n <mj-form-field\n FieldName=\"FinalPayloadValidationMode\"\n Type=\"dropdownlist\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\"\n style=\"width: 100%;\">\n </mj-form-field>\n </div>\n <div class=\"validation-field-group\">\n <label class=\"validation-field-label\">Max Retries</label>\n <p class=\"validation-field-description\">Maximum validation retry attempts</p>\n <mj-form-field\n FieldName=\"FinalPayloadValidationMaxRetries\"\n Type=\"numerictextbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\"\n style=\"width: 100%;\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"payload-validation-schema\">\n <label class=\"validation-schema-label\">\n <i class=\"fa-solid fa-code\"></i>\n Validation Schema\n </label>\n <p class=\"validation-schema-description\">\n JSON schema or validation rules for the final payload structure\n </p>\n <div class=\"validation-schema-editor\">\n <mj-code-editor\n [value]=\"record.FinalPayloadValidation || '{}'\"\n [readonly]=\"!EditMode\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"height: 200px; width: 100%;\"\n (valueChange)=\"updatePayloadField('FinalPayloadValidation', $event)\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Execution Guardrails (New Separate Panel) -->\n <mj-accordion-panel id=\"guardrails\"\n [Expanded]=\"GetSectionExpanded('guardrails', false)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-shield-halved\"></i> Execution Guardrails\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Set limits to prevent runaway agent executions and control resource usage.\n </div>\n </div>\n <div class=\"form-fields-grid\">\n <mj-form-field\n FieldName=\"MaxCostPerRun\"\n Type=\"numerictextbox\"\n Caption=\"Max Cost ($)\"\n Description=\"Maximum cost per run\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <mj-form-field\n FieldName=\"MaxTokensPerRun\"\n Type=\"numerictextbox\"\n Caption=\"Max Tokens\"\n Description=\"Maximum tokens per run\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <mj-form-field\n FieldName=\"MaxIterationsPerRun\"\n Type=\"numerictextbox\"\n Caption=\"Max Iterations\"\n Description=\"Maximum prompt iterations\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <mj-form-field\n FieldName=\"MaxTimePerRun\"\n Type=\"numerictextbox\"\n Caption=\"Max Time (seconds)\"\n Description=\"Maximum execution time\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Configuration (Settings Panel) -->\n <mj-accordion-panel id=\"config\"\n [Expanded]=\"GetSectionExpanded('config', false)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-cogs\"></i> Configuration\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Configure agent behavior, execution settings, and advanced features.\n </div>\n </div>\n <!-- Identity & Behavior Section -->\n <div class=\"config-section\">\n <h3 class=\"config-section-title\">\n <i class=\"fa-solid fa-id-card\"></i>\n Identity & Behavior\n </h3>\n <div class=\"config-grid\">\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-toggle-on\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Agent Status</h4>\n <p>Current availability and operational status</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n @if (EditMode) {\n <mj-dropdown\n [(ngModel)]=\"record.Status\"\n [Data]=\"statusOptions\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n name=\"agentStatus\"\n class=\"config-field-input\">\n </mj-dropdown>\n } @else {\n <span class=\"config-field-display\">{{ record.Status || 'Not Set' }}</span>\n }\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-sitemap\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Agent Type</h4>\n <p>Category and system-level behavior</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n @if (EditMode) {\n <mj-dropdown\n [(ngModel)]=\"record.TypeID\"\n [Data]=\"agentTypes\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n name=\"agentTypeID\"\n class=\"config-field-input\">\n </mj-dropdown>\n } @else {\n <span class=\"config-field-display\">{{ record.Type || 'Not Set' }}</span>\n }\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Category</h4>\n <p>Organizational category for this agent</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n @if (EditMode) {\n <mj-tree-dropdown\n [BranchConfig]=\"CategoryBranchConfig\"\n [Value]=\"SelectedCategoryKey\"\n SelectionMode=\"single\"\n SelectableTypes=\"branch\"\n Placeholder=\"Select a category...\"\n [Clearable]=\"true\"\n [EnableSearch]=\"true\"\n (ValueChange)=\"OnCategoryChange($event)\">\n </mj-tree-dropdown>\n } @else {\n <span class=\"config-field-display\">{{ record.Category || 'Not Set' }}</span>\n }\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-bolt\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Expose as Action</h4>\n <p>Make available as an action for other agents</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"ExposeAsAction\"\n Type=\"checkbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"config-card full-width\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-align-left\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Description</h4>\n <p>Detailed agent description and purpose</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"Description\"\n Type=\"textarea\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\"\n style=\"width: 100%;\">\n </mj-form-field>\n </div>\n </div>\n </div>\n </div>\n <!-- Execution Settings Section -->\n <div class=\"config-section\">\n <h3 class=\"config-section-title\">\n <i class=\"fa-solid fa-play\"></i>\n Execution Settings\n </h3>\n <div class=\"config-grid\">\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-layer-group\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Execution Mode</h4>\n <p>How sub-agents are executed</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"ExecutionMode\"\n Type=\"dropdownlist\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-sort-numeric-down\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Execution Order</h4>\n <p>Order when run with siblings</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"ExecutionOrder\"\n Type=\"numerictextbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-tachometer-alt\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Default Effort Level</h4>\n <p>Default effort level for all prompts (1-100)</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"DefaultPromptEffortLevel\"\n Type=\"numerictextbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <div class=\"config-card-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Higher values request more thorough reasoning (1=minimal, 100=maximum)\n </div>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-code\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Driver Class</h4>\n <p>Custom implementation class</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"DriverClass\"\n Type=\"textbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n </div>\n </div>\n <!-- Visual Identity Section -->\n <div class=\"config-section\">\n <h3 class=\"config-section-title\">\n <i class=\"fa-solid fa-palette\"></i>\n Visual Identity\n </h3>\n <div class=\"config-grid\">\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-icons\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Icon Class</h4>\n <p>Font Awesome icon class</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"IconClass\"\n Type=\"textbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <div class=\"config-card-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Example: <code>fa-solid fa-robot</code>\n </div>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-image\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Logo URL</h4>\n <p>URL for agent logo image</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"LogoURL\"\n Type=\"textbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <div class=\"config-card-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Takes precedence over Icon Class\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Context Compression Section -->\n <div class=\"config-section\">\n <h3 class=\"config-section-title\">\n <i class=\"fa-solid fa-compress\"></i>\n Context Compression\n </h3>\n <div class=\"config-grid\">\n <div class=\"config-card full-width\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-toggle-on\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Enable Context Compression</h4>\n <p>Automatically compress conversation context when message threshold is reached</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"EnableContextCompression\"\n Type=\"checkbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\"\n (valueChange)=\"onContextCompressionToggle($event)\">\n </mj-form-field>\n </div>\n </div>\n @if (record.EnableContextCompression) {\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-hashtag\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Message Threshold</h4>\n <p>Messages before compression triggers</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"ContextCompressionMessageThreshold\"\n Type=\"numerictextbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-save\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Messages to Keep</h4>\n <p>Recent messages to retain uncompressed</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"ContextCompressionMessageRetentionCount\"\n Type=\"numerictextbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-comment-dots\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Compression Prompt</h4>\n <p>Prompt used for summarization</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n @if (EditMode) {\n <div class=\"prompt-selector-container\">\n <div class=\"prompt-display\">\n @if (selectedContextCompressionPrompt) {\n <span class=\"prompt-name\">{{ selectedContextCompressionPrompt.Name }}</span>\n } @else {\n <span class=\"no-prompt\">No prompt selected</span>\n }\n </div>\n <div class=\"prompt-actions\">\n <button type=\"button\"\n mjButton\n variant=\"outline\"\n size=\"sm\"\n (click)=\"openContextCompressionPromptSelector()\"\n class=\"prompt-select-btn\">\n <i class=\"fa-solid fa-search\"></i>\n {{ selectedContextCompressionPrompt ? 'Change' : 'Select' }} Prompt\n </button>\n @if (selectedContextCompressionPrompt) {\n <button type=\"button\"\n mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"clearContextCompressionPrompt()\"\n class=\"prompt-clear-btn\"\n title=\"Clear selection\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n </div>\n } @else {\n <span class=\"config-field-display\">{{ selectedContextCompressionPrompt?.Name || record.ContextCompressionPrompt || 'Not Set' }}</span>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </mj-accordion-panel>\n </div>\n }\n </form>\n</mj-record-form-container>\n}\n\n<!-- Permissions Dialog (from @memberjunction/ng-agents) -->\n@if (ShowPermissionsDialog) {\n <mj-agent-permissions-dialog\n [Agent]=\"record\"\n (Closed)=\"onPermissionsDialogClosed()\"\n (PermissionsChanged)=\"refreshRelatedData()\">\n </mj-agent-permissions-dialog>\n}", styles: ["/* AI Agent Form - Modern Redesign */\n.record-form-container {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n}\n\n.record-form {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n/* Agent Header Section - Compact Design */\n.agent-header {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);\n transition: padding 0.2s ease;\n}\n\n.agent-header-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n}\n\n/* Header collapse toggle button */\n.agent-header-toggle {\n background: none;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n padding: 0;\n transition: all 0.15s ease;\n}\n\n.agent-header-toggle:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-strong);\n}\n\n.agent-header-toggle i {\n font-size: 10px;\n}\n\n.agent-overview {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.agent-icon-wrapper {\n width: 36px;\n height: 36px;\n background: var(--mj-brand-primary);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n flex-shrink: 0;\n transition: all 0.2s ease;\n}\n\n.agent-icon-wrapper i {\n color: var(--mj-text-inverse);\n font-size: 18px;\n}\n\n/* \u2500\u2500 Minimized Floating Header Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.agent-header-mini {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 12px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n height: 32px;\n}\n\n.agent-header-mini-expand {\n background: none;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 0;\n flex-shrink: 0;\n transition: all 0.15s ease;\n}\n\n.agent-header-mini-expand:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-strong);\n}\n\n.agent-header-mini-expand i {\n font-size: 9px;\n}\n\n.agent-header-mini-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 300px;\n}\n\n.agent-header-mini-status {\n padding: 1px 7px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.agent-header-mini-spacer {\n flex: 1;\n}\n\n.agent-header-mini-btn {\n background: none;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 0;\n flex-shrink: 0;\n transition: all 0.15s ease;\n}\n\n.agent-header-mini-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-strong);\n}\n\n.agent-header-mini-btn:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.agent-header-mini-btn--primary {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.agent-header-mini-btn--primary:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.agent-header-mini-btn i {\n font-size: 11px;\n}\n\n.agent-icon-wrapper img.agent-logo {\n width: 100%;\n height: 100%;\n object-fit: cover;\n border-radius: 8px;\n}\n\n.agent-info {\n flex: 1;\n min-width: 0;\n}\n\n.agent-name {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n line-height: 1.2;\n}\n\n.agent-name-input {\n font-size: 16px !important;\n font-weight: 500 !important;\n height: 30px !important;\n width: 100% !important;\n max-width: 350px !important;\n}\n\n.agent-meta {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.status-badge.active {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n\n.status-badge.pending {\n background: var(--mj-status-warning);\n color: var(--mj-text-primary);\n}\n\n.status-badge.disabled {\n background: var(--mj-text-muted);\n color: var(--mj-text-inverse);\n}\n\n.execution-mode,\n.parent-agent {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.execution-mode i,\n.parent-agent i {\n font-size: 12px;\n opacity: 0.8;\n}\n\n.parent-agent.clickable {\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.parent-agent.clickable:hover {\n background: var(--mj-border-default);\n color: var(--mj-brand-primary);\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n}\n\n.parent-agent.clickable:active {\n transform: translateY(0);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n/* Prompt Controls Section */\n.prompt-controls {\n flex: 1;\n margin-right: 16px;\n}\n\n.agent-meta-info {\n display: flex;\n gap: 24px;\n margin-top: 12px;\n flex-wrap: wrap;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.meta-label {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-value {\n font-size: 14px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.agent-description {\n margin-top: 16px;\n color: var(--mj-text-muted);\n line-height: 1.6;\n font-size: 15px;\n}\n\n.agent-description-input {\n width: 100%;\n max-width: 600px;\n min-height: 80px;\n resize: vertical;\n}\n\n/* Action Buttons Section */\n.agent-actions {\n display: flex;\n flex-direction: row;\n gap: 8px;\n flex-shrink: 0;\n align-items: center;\n}\n\n.action-buttons-row {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.action-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border-radius: 8px;\n font-weight: 500;\n font-size: 14px;\n transition: all 0.2s ease;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n.action-button:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);\n}\n\n.action-button.primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.action-button.primary:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.action-button.secondary {\n background: var(--mj-text-muted);\n color: var(--mj-text-inverse);\n}\n\n.action-button.secondary:hover {\n background: var(--mj-text-secondary);\n}\n\n.action-warnings {\n margin-top: 8px;\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* Panel-Based Form Content */\n.form-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n overflow-x: hidden;\n background: var(--mj-bg-page);\n padding: 8px 12px;\n}\n\n/* Panel Content */\n.panel-content {\n padding: 16px;\n background: var(--mj-bg-surface);\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.section-description {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.6;\n margin-bottom: 16px;\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-shrink: 0;\n}\n\n.tab-section {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n padding: 24px;\n margin-bottom: 24px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n border: 1px solid var(--mj-border-default);\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 2px solid var(--mj-bg-surface-sunken);\n}\n\n.section-title {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0;\n color: var(--mj-text-primary);\n font-size: 18px;\n font-weight: 600;\n}\n\n.section-title i {\n color: var(--mj-brand-primary);\n font-size: 20px;\n}\n\n.section-description {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.6;\n margin-top: 8px;\n}\n\n/* Form Fields Grid */\n.form-fields-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 20px;\n margin-top: 20px;\n}\n\n.form-field-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.form-field-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Sub-grids styling (legacy) */\n.sub-grid-container {\n height: 500px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n display: none; /* Hidden as we now use cards */\n}\n\n/* Empty States */\n/* Loading State */\n.loading-state {\n text-align: center;\n padding: 60px 20px;\n color: var(--mj-text-muted);\n}\n\n.loading-state i {\n font-size: 36px;\n color: var(--mj-brand-primary);\n margin-bottom: 16px;\n display: block;\n}\n\n.loading-state p {\n margin: 0;\n font-size: 14px;\n color: var(--mj-text-disabled);\n}\n\n/* Loading State */\n.loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 90%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.loading-spinner {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n}\n\n.spinner-icon {\n width: 48px;\n height: 48px;\n border: 4px solid var(--mj-bg-surface-sunken);\n border-top: 4px solid var(--mj-brand-primary);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n/* Quick Actions */\n.quick-actions {\n display: flex;\n gap: 16px;\n margin-top: 20px;\n padding-top: 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.quick-action-card {\n flex: 1;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n transition: all 0.2s ease;\n text-align: center;\n}\n\n.quick-action-card:hover {\n background: var(--mj-bg-surface);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\n\n.quick-action-icon {\n font-size: 32px;\n color: var(--mj-brand-primary);\n margin-bottom: 8px;\n}\n\n.quick-action-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 4px;\n}\n\n.quick-action-description {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* Header Actions */\n.header-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n/* Entity List Interface */\n.entity-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin-top: 16px;\n}\n\n.entity-item {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.entity-item:hover {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-1px);\n}\n\n.item-icon {\n width: 40px;\n height: 40px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.prompt-item .item-icon {\n background: var(--mj-status-success);\n}\n\n.action-item .item-icon {\n background: var(--mj-status-warning);\n}\n\n.sub-agent-item .item-icon {\n background: var(--mj-brand-primary);\n}\n\n.model-item .item-icon {\n background: var(--mj-brand-primary);\n}\n\n.learning-item .item-icon {\n background: var(--mj-status-error);\n}\n\n.note-item .item-icon {\n background: var(--mj-status-warning);\n}\n\n.item-icon i {\n color: var(--mj-text-muted);\n font-size: 18px;\n}\n\n.prompt-item .item-icon i,\n.action-item .item-icon i,\n.sub-agent-item .item-icon i,\n.model-item .item-icon i,\n.learning-item .item-icon i,\n.note-item .item-icon i {\n color: var(--mj-text-inverse);\n}\n\n.item-icon img.sub-agent-logo {\n width: 100%;\n height: 100%;\n object-fit: cover;\n border-radius: 6px;\n}\n\n.item-content {\n flex: 1;\n min-width: 0;\n}\n\n.item-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n line-height: 1.3;\n}\n\n.item-preview {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.4;\n margin: 4px 0 8px 0;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.item-meta {\n display: flex;\n gap: 12px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.meta-tag,\n.priority-tag,\n.status-tag {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n padding: 3px 8px;\n border-radius: 6px;\n font-weight: 500;\n}\n\n.meta-tag {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.priority-tag {\n color: var(--mj-text-inverse);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.status-tag {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.status-tag.active {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.status-tag.inactive {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.item-actions {\n opacity: 0;\n transition: opacity 0.2s ease;\n color: var(--mj-text-muted);\n font-size: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.entity-item:hover .item-actions {\n opacity: 1;\n}\n\n.entity-item:hover .item-actions > i {\n color: var(--mj-brand-primary);\n}\n\n.view-more-item {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 2px dashed var(--mj-border-default);\n border-radius: 10px;\n text-align: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.view-more-item:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* Pagination Controls */\n.pagination-controls {\n display: flex;\n gap: 12px;\n align-items: center;\n justify-content: center;\n padding: 16px;\n margin-top: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n}\n\n.page-nav-btn {\n min-width: 120px;\n font-weight: 500;\n}\n\n.page-nav-btn i {\n font-size: 12px;\n}\n\n.page-nav-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.page-info {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding: 0 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n min-width: 200px;\n text-align: center;\n}\n\n.page-info .record-count {\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: normal;\n}\n\n.page-info .fa-spinner {\n margin-right: 8px;\n color: var(--mj-brand-primary);\n}\n\n.view-all-btn {\n color: var(--mj-text-muted);\n white-space: nowrap;\n margin-left: auto;\n}\n\n.view-all-btn:hover {\n color: var(--mj-brand-primary);\n}\n\n.view-all-btn i {\n margin-right: 4px;\n}\n\n/* Payload Section Styles */\n.payload-config-section,\n.payload-paths-section,\n.payload-validation-section {\n margin-bottom: 32px;\n}\n\n.subsection-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 16px 0;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.subsection-title i {\n color: var(--mj-brand-primary);\n}\n\n.subsection-divider {\n margin-top: 32px;\n margin-bottom: 16px;\n padding-top: 24px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.payload-config-grid {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.payload-field-group {\n margin-bottom: 20px;\n}\n\n.payload-field-label {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.payload-field-label i {\n color: var(--mj-text-muted);\n font-size: 16px;\n}\n\n.field-description {\n font-size: 12px;\n font-weight: normal;\n color: var(--mj-text-muted);\n margin-left: auto;\n}\n\n/* Code editor styling */\n.payload-field-group mj-code-editor {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.payload-field-group mj-code-editor:hover {\n border-color: var(--mj-brand-primary);\n}\n\n/* Payload textarea styling */\n.payload-field-group mj-form-field ::ng-deep textarea {\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 13px;\n line-height: 1.5;\n min-height: 120px;\n resize: vertical;\n}\n\n/* Execution History Panel */\n.execution-history-panel {\n max-height: 500px;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* Timeline List for Execution History */\n.timeline-list {\n display: flex;\n flex-direction: column;\n gap: 16px;\n margin-top: 16px;\n}\n\n.timeline-item {\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.timeline-item:hover {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n}\n\n.timeline-marker {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.timeline-marker i {\n color: var(--mj-text-inverse);\n font-size: 14px;\n}\n\n.timeline-content {\n flex: 1;\n min-width: 0;\n}\n\n.timeline-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n}\n\n.timeline-date {\n font-size: 12px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 6px;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.timeline-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.timeline-preview {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Modern Card-Based Interface (Legacy - Keep for backward compatibility) */\n.cards-container {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n gap: 20px;\n margin-top: 16px;\n}\n\n.entity-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 20px;\n cursor: pointer;\n transition: all 0.3s ease;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n position: relative;\n overflow: hidden;\n}\n\n.entity-card:hover {\n transform: translateY(-4px);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: var(--mj-brand-primary);\n opacity: 0;\n transition: opacity 0.3s ease;\n}\n\n.entity-card:hover::before {\n opacity: 1;\n}\n\n.card-header {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 12px;\n}\n\n.card-icon {\n width: 40px;\n height: 40px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sub-agent-card .card-icon {\n background: var(--mj-brand-primary);\n}\n\n.prompt-card .card-icon {\n background: var(--mj-status-success);\n}\n\n.action-card .card-icon {\n background: var(--mj-status-warning);\n}\n\n.card-icon i {\n font-size: 18px;\n color: var(--mj-text-muted);\n}\n\n.sub-agent-card .card-icon i,\n.prompt-card .card-icon i,\n.action-card .card-icon i {\n color: var(--mj-text-inverse);\n}\n\n.card-title-section {\n flex: 1;\n min-width: 0;\n}\n\n.card-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n line-height: 1.3;\n word-wrap: break-word;\n}\n\n.card-description {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.5;\n margin: 8px 0;\n display: -webkit-box;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.card-meta {\n display: flex;\n gap: 16px;\n margin-top: 12px;\n flex-wrap: wrap;\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n padding: 4px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n}\n\n.meta-item i {\n font-size: 11px;\n opacity: 0.8;\n}\n\n.meta-item.active {\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.meta-item.inactive {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n}\n\n.card-actions {\n opacity: 0;\n transition: opacity 0.3s ease;\n color: var(--mj-text-muted);\n}\n\n.entity-card:hover .card-actions {\n opacity: 1;\n color: var(--mj-brand-primary);\n}\n\n/* Badge Styles */\n.priority-badge {\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.type-badge {\n padding: 2px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* View All Card */\n.view-all-card {\n background: var(--mj-bg-surface-card);\n border: 2px dashed var(--mj-border-default);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 120px;\n cursor: pointer;\n transition: all 0.3s ease;\n}\n\n.view-all-card:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n transform: translateY(-2px);\n}\n\n.view-all-content {\n text-align: center;\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.view-all-content i {\n font-size: 24px;\n margin-bottom: 8px;\n display: block;\n}\n\n/* Timeline Interface for History */\n.timeline-container {\n position: relative;\n margin-top: 16px;\n}\n\n.timeline-item {\n display: flex;\n flex-direction: column;\n margin-bottom: 24px;\n transition: all 0.3s ease;\n border-radius: 12px;\n padding: 16px;\n background: transparent;\n border: 1px solid transparent;\n}\n\n.timeline-item:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n}\n\n.timeline-item.expanded {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.timeline-item.view-all {\n cursor: pointer;\n background: var(--mj-bg-surface-card);\n border: 2px dashed var(--mj-border-default);\n}\n\n.timeline-item.view-all:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n}\n\n.timeline-item > div:first-child {\n display: flex;\n align-items: flex-start;\n}\n\n.timeline-marker {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-right: 16px;\n flex-shrink: 0;\n position: relative;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.timeline-marker::after {\n content: '';\n position: absolute;\n top: 50px;\n left: 50%;\n transform: translateX(-50%);\n width: 2px;\n height: 24px;\n background: var(--mj-border-default);\n}\n\n.timeline-item:last-child .timeline-marker::after {\n display: none;\n}\n\n.timeline-marker i {\n color: var(--mj-text-inverse);\n font-size: 16px;\n}\n\n.timeline-marker.view-all-marker {\n background: var(--mj-text-muted);\n}\n\n.timeline-content {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: flex-start;\n}\n\n.timeline-header {\n flex: 1;\n cursor: pointer;\n}\n\n.timeline-header > div:first-child {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 8px;\n gap: 16px;\n}\n\n.expand-icon {\n transition: transform 0.3s ease;\n margin-right: 8px;\n color: var(--mj-text-muted);\n}\n\n.expand-icon.expanded {\n transform: rotate(90deg);\n}\n\n.timeline-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n line-height: 1.3;\n}\n\n.timeline-date {\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n background: var(--mj-bg-surface-card);\n padding: 4px 8px;\n border-radius: 6px;\n margin-left: auto;\n}\n\n.timeline-preview {\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n margin-top: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.timeline-status {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.execution-time {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n padding: 4px 8px;\n border-radius: 6px;\n}\n\n.timeline-description {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.5;\n margin: 8px 0;\n}\n\n.timeline-error {\n color: var(--mj-status-error);\n font-size: 13px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n padding: 8px 12px;\n border-radius: 6px;\n margin-top: 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.timeline-error i {\n flex-shrink: 0;\n}\n\n/* Expanded Content Styles */\n.timeline-expanded-content {\n margin-top: 20px;\n padding-top: 20px;\n border-top: 1px solid var(--mj-border-default);\n animation: fadeIn 0.3s ease;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.result-section,\n.error-section {\n margin-bottom: 20px;\n}\n\n.result-section h5,\n.error-section h5 {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-section h5 {\n color: var(--mj-status-error);\n}\n\n.result-content,\n.error-content {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 12px 16px;\n font-size: 14px;\n line-height: 1.6;\n color: var(--mj-text-secondary);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 200px;\n overflow-y: auto;\n}\n\n/* Code editor styling within result section */\n.result-section mj-code-editor {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.error-content {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.execution-details {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.detail-row {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n\n.detail-label {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n min-width: 80px;\n}\n\n.detail-value {\n font-size: 14px;\n color: var(--mj-text-secondary);\n word-break: break-all;\n}\n\n.timeline-actions {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n}\n\n.btn-primary {\n padding: 8px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 8px;\n transition: all 0.2s ease;\n}\n\n.btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-1px);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.btn-primary i {\n font-size: 12px;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n /* Header Responsiveness */\n .agent-header {\n padding: 16px;\n }\n\n .agent-header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .agent-overview {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .agent-meta {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .agent-actions {\n width: 100%;\n align-self: stretch;\n }\n\n .action-button {\n flex: 1;\n justify-content: center;\n }\n\n /* Panel Responsiveness */\n .form-content {\n padding: 12px;\n }\n\n ::ng-deep .k-panelbar > .k-panelbar-item > .k-header {\n padding: 16px 20px;\n font-size: 15px;\n }\n\n .panel-content {\n padding: 20px 16px;\n }\n\n .section-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .header-actions {\n flex-wrap: wrap;\n align-self: stretch;\n }\n\n /* Entity List Responsiveness */\n .entity-item {\n padding: 12px;\n gap: 12px;\n }\n\n .item-icon {\n width: 36px;\n height: 36px;\n }\n\n .item-icon i {\n font-size: 16px;\n }\n\n .item-title {\n font-size: 15px;\n }\n\n .item-preview {\n font-size: 13px;\n }\n\n .item-meta {\n gap: 8px;\n }\n\n /* Timeline Responsiveness */\n .timeline-item {\n padding: 12px;\n gap: 12px;\n }\n\n .timeline-marker {\n width: 28px;\n height: 28px;\n }\n\n .timeline-marker i {\n font-size: 12px;\n }\n\n .timeline-title {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .timeline-date {\n align-self: flex-start;\n }\n\n /* Form Field Responsiveness */\n .form-fields-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n /* Legacy card support */\n .cards-container {\n grid-template-columns: 1fr;\n }\n}\n\n/* Execution History Panel - Max Height and Scroll */\n.execution-history-panel {\n max-height: 500px;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* Custom scrollbar for execution history */\n.execution-history-panel::-webkit-scrollbar {\n width: 8px;\n}\n\n.execution-history-panel::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.execution-history-panel::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n.execution-history-panel::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n/* Execution History Search Bar */\n.execution-search-bar {\n margin-bottom: 16px;\n padding: 0 4px;\n}\n\n.execution-search-bar .fa-search {\n color: var(--mj-text-secondary);\n margin-right: 8px;\n font-size: 14px;\n}\n\n/* New Execution History Card Design */\n.execution-history-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin-top: 8px;\n}\n\n.execution-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.2s ease;\n cursor: pointer;\n}\n\n.execution-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n transform: translateY(-1px);\n}\n\n.execution-card.expanded {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 6px 20px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.execution-header {\n padding: 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.execution-left-section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.execution-status {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.status-indicator {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.status-indicator i {\n color: var(--mj-text-inverse);\n font-size: 14px;\n}\n\n.execution-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.execution-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.execution-date {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.execution-metrics {\n display: flex;\n align-items: flex-start;\n gap: 16px;\n flex-wrap: wrap;\n margin-left: 44px; /* Align with execution title text, accounting for status indicator + gap */\n}\n\n.metric-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n background: var(--mj-bg-surface-card);\n padding: 6px 10px;\n border-radius: 6px;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}\n\n.metric-item i {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.metric-label {\n font-weight: 500;\n}\n\n.metric-value {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.execution-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.action-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--mj-text-muted);\n}\n\n.action-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n transform: translateY(-1px);\n}\n\n.action-btn i {\n font-size: 12px;\n}\n\n.expand-icon {\n transition: transform 0.2s ease;\n color: var(--mj-text-muted);\n margin-right: 4px;\n}\n\n.expand-icon.expanded {\n transform: rotate(90deg);\n}\n\n/* Execution Expanded Content */\n.execution-expanded-content {\n padding: 16px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n background: var(--mj-bg-surface-card);\n animation: slideDown 0.2s ease;\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n padding-top: 0;\n padding-bottom: 0;\n }\n to {\n opacity: 1;\n max-height: 500px;\n padding-top: 16px;\n padding-bottom: 16px;\n }\n}\n\n.detailed-metrics {\n margin-bottom: 20px;\n}\n\n.metrics-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 12px;\n}\n\n.metric-detail {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.metric-detail i {\n color: var(--mj-brand-primary);\n font-size: 16px;\n width: 20px;\n text-align: center;\n}\n\n.metric-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n}\n\n.metric-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.metric-data {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.result-section {\n margin-top: 16px;\n}\n\n.result-section h5 {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-section h5 {\n color: var(--mj-status-error);\n}\n\n.error-content {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n border-radius: 8px;\n padding: 12px 16px;\n font-size: 14px;\n line-height: 1.6;\n color: var(--mj-status-error);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 150px;\n overflow-y: auto;\n}\n\n/* Responsive adjustments for execution history */\n@media (max-width: 768px) {\n .execution-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .execution-left-section {\n width: 100%;\n }\n\n .execution-metrics {\n margin-left: 0; /* Remove left margin on mobile */\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n width: 100%;\n }\n\n .metric-item {\n font-size: 11px;\n padding: 4px 8px;\n }\n\n .metrics-grid {\n grid-template-columns: 1fr;\n }\n}\n\n/* === PAYLOAD MANAGEMENT SECTION === */\n.payload-section {\n margin-bottom: 2rem;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n}\n\n.payload-section-title {\n margin: 0;\n padding: 1rem 1.5rem;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n font-size: 1.1rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.payload-section-title i {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n}\n\n/* Payload Scope Styling */\n.payload-field-container {\n padding: 1.5rem;\n display: grid;\n grid-template-columns: 1fr 2fr;\n gap: 2rem;\n align-items: start;\n}\n\n.payload-field-info {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.payload-field-label {\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 0.95rem;\n}\n\n.payload-field-description {\n color: var(--mj-text-muted);\n font-size: 0.9rem;\n line-height: 1.5;\n margin: 0;\n}\n\n.payload-field-input {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.payload-field-example {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n padding: 0.5rem 0.75rem;\n border-radius: 6px;\n border: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.payload-field-example i {\n color: var(--mj-status-warning);\n font-size: 0.9rem;\n}\n\n.payload-field-example code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.2rem 0.4rem;\n border-radius: 4px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n}\n\n/* Path Configuration Grid */\n.payload-paths-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));\n gap: 1.5rem;\n padding: 1.5rem;\n}\n\n.payload-path-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.2s ease;\n}\n\n.payload-path-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.payload-path-header {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.payload-path-icon {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.payload-path-icon.downstream {\n background: var(--mj-status-success);\n}\n\n.payload-path-icon.upstream {\n background: var(--mj-brand-primary);\n}\n\n.payload-path-icon.self-read {\n background: var(--mj-brand-primary);\n}\n\n.payload-path-icon.self-write {\n background: var(--mj-status-warning);\n}\n\n.payload-path-icon i {\n color: var(--mj-text-inverse);\n font-size: 1.2rem;\n}\n\n.payload-path-info h4 {\n margin: 0 0 0.25rem 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.payload-path-info p {\n margin: 0;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.payload-path-content {\n padding: 1rem;\n}\n\n.json-editor-container {\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n margin-bottom: 0.75rem;\n}\n\n.json-editor-container:hover {\n border-color: var(--mj-brand-primary);\n}\n\n.payload-path-hint {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.payload-path-hint i {\n color: var(--mj-brand-primary);\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.payload-path-hint code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 3px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n/* Payload Validation Container */\n.payload-validation-container {\n padding: 1.5rem;\n display: grid;\n grid-template-columns: 1fr 2fr;\n gap: 2rem;\n align-items: start;\n}\n\n.payload-validation-settings {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n}\n\n.validation-field-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.validation-field-label {\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 0.95rem;\n}\n\n.validation-field-description {\n color: var(--mj-text-muted);\n font-size: 0.9rem;\n line-height: 1.4;\n margin: 0 0 0.5rem 0;\n}\n\n.payload-validation-schema {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.validation-schema-label {\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 0.95rem;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.validation-schema-label i {\n color: var(--mj-brand-primary);\n}\n\n.validation-schema-description {\n color: var(--mj-text-muted);\n font-size: 0.9rem;\n line-height: 1.4;\n margin: 0;\n}\n\n.validation-schema-editor {\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.validation-schema-editor:hover {\n border-color: var(--mj-brand-primary);\n}\n\n/* === CONFIGURATION SECTION === */\n.config-section {\n margin-bottom: 2rem;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n}\n\n.config-section-title {\n margin: 0;\n padding: 1rem 1.5rem;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n font-size: 1.1rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.config-section-title i {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));\n gap: 1.5rem;\n padding: 1.5rem;\n width: 100%;\n}\n\n.config-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.2s ease;\n}\n\n.config-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-card.full-width {\n grid-column: 1 / -1;\n}\n\n.config-card-header {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.config-card-icon {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.config-card-icon i {\n color: var(--mj-text-inverse);\n font-size: 1.2rem;\n}\n\n.config-card-info h4 {\n margin: 0 0 0.25rem 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.config-card-info p {\n margin: 0;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.config-card-content {\n padding: 1rem;\n}\n\n/* Custom field styling for config cards */\n.config-field-input {\n width: 100%;\n min-width: 250px;\n}\n\n.config-card-content ::ng-deep mj-form-field {\n width: 100% !important;\n}\n\n.config-field-display {\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n padding: 8px 0;\n display: block;\n min-height: 20px;\n}\n\n/* Prompt selector styling */\n.prompt-selector-container {\n display: flex;\n align-items: center;\n gap: 12px;\n width: 100%;\n}\n\n.prompt-display {\n flex: 1;\n min-width: 0;\n padding: 8px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n}\n\n.prompt-name {\n color: var(--mj-text-secondary);\n font-weight: 500;\n font-size: 14px;\n}\n\n.no-prompt {\n color: var(--mj-text-muted);\n font-style: italic;\n font-size: 14px;\n}\n\n.prompt-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.prompt-select-btn {\n white-space: nowrap;\n}\n\n.prompt-clear-btn {\n min-width: 32px;\n}\n\n.config-card-hint {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n margin-top: 0.5rem;\n}\n\n.config-card-hint i {\n color: var(--mj-brand-primary);\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.config-card-hint code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 3px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n\n/* === RESPONSIVE DESIGN === */\n@media (max-width: 768px) {\n .payload-field-container,\n .payload-validation-container {\n grid-template-columns: 1fr;\n gap: 1rem;\n }\n\n .payload-paths-grid {\n grid-template-columns: 1fr;\n gap: 1rem;\n padding: 1rem;\n }\n\n .config-grid {\n grid-template-columns: 1fr;\n gap: 1rem;\n padding: 1rem;\n }\n\n .payload-section-title,\n .config-section-title {\n padding: 0.75rem 1rem;\n font-size: 1rem;\n }\n\n .payload-path-header,\n .config-card-header {\n padding: 0.75rem;\n }\n\n .payload-path-content,\n .config-card-content {\n padding: 0.75rem;\n }\n\n .payload-field-container,\n .payload-validation-container {\n padding: 1rem;\n }\n}\n\n/* ===================================\n Unified Sub-Agents with Filtering\n =================================== */\n\n/* Filter Controls */\n.sub-agent-filter-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.filter-controls {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n/* Sub-Agent Type Badge */\n.sub-agent-type-badge {\n position: absolute;\n top: 8px;\n right: 8px;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n display: flex;\n align-items: center;\n gap: 4px;\n z-index: 1;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n}\n\n/* Sub-Agent Item Styling */\n.sub-agent-item {\n position: relative;\n padding-left: 8px;\n transition: all 0.2s ease;\n}\n\n.sub-agent-item.child-sub-agent {\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.sub-agent-item.related-sub-agent {\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.sub-agent-item:hover {\n transform: translateX(4px);\n}\n\n/* Payload Info Tag */\n.payload-info {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n font-family: 'Roboto Mono', monospace;\n font-size: 11px;\n}\n\n/* Empty State Info Cards */\n.empty-state-info {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 16px;\n margin: 24px 0;\n max-width: 600px;\n margin-left: auto;\n margin-right: auto;\n}\n\n.info-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 16px;\n text-align: left;\n}\n\n.info-card i {\n font-size: 24px;\n margin-bottom: 8px;\n display: block;\n}\n\n.info-card strong {\n display: block;\n margin-bottom: 4px;\n font-size: 14px;\n}\n\n.info-card p {\n margin: 0;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n/* Responsive adjustments for sub-agent filters */\n@media (max-width: 768px) {\n .sub-agent-filter-header {\n flex-direction: column;\n align-items: stretch;\n }\n\n .filter-controls,\n .header-actions {\n width: 100%;\n justify-content: center;\n }\n\n .empty-state-info {\n grid-template-columns: 1fr;\n }\n}\n\n/* ===== Search Scope Access (mockup #5) ===== */\n.agent-search-access {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 12px;\n margin: 8px 0 20px;\n}\n\n.agent-search-access-option {\n display: grid;\n grid-template-columns: 24px 28px 1fr;\n align-items: start;\n gap: 10px;\n padding: 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease;\n}\n\n.agent-search-access-option:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n}\n\n.agent-search-access-option.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.agent-search-access-option input[type=\"radio\"] {\n accent-color: var(--mj-brand-primary);\n margin-top: 2px;\n}\n\n.agent-search-access-option > i {\n font-size: 20px;\n color: var(--mj-brand-primary);\n text-align: center;\n margin-top: 2px;\n}\n\n.agent-search-access-text {\n min-width: 0;\n}\n\n.agent-search-access-title {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.agent-search-access-desc {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n line-height: 1.3;\n}\n\n.agent-search-grid-header {\n margin: 8px 0 12px;\n}\n\n.agent-search-grid-header h4 {\n margin: 0 0 4px;\n color: var(--mj-text-primary);\n font-size: 1rem;\n font-weight: 600;\n}\n\n@media (max-width: 768px) {\n .agent-search-access {\n grid-template-columns: 1fr;\n }\n}\n\n/* \u2500\u2500 Execution History: Runs | Sessions segmented toggle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.history-view-toggle {\n display: inline-flex;\n gap: 2px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 3px;\n margin-bottom: 14px;\n}\n\n.history-toggle-option {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n padding: 6px 16px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.history-toggle-option:hover {\n color: var(--mj-text-secondary);\n}\n\n.history-toggle-option.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.history-toggle-count {\n font-size: 11px;\n font-weight: 600;\n padding: 1px 7px;\n border-radius: 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-secondary);\n}\n\n.history-toggle-option.active .history-toggle-count {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary);\n}\n\n/* \u2500\u2500 Voice session rows in Execution History \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.session-card {\n cursor: pointer;\n}\n\n.session-role-chip {\n display: inline-flex;\n align-items: center;\n margin-left: 8px;\n padding: 1px 8px;\n border-radius: 10px;\n font-size: 10.5px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 22%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.session-role-chip--target {\n background: color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-info) 22%, transparent);\n color: var(--mj-status-info);\n}\n\n.session-status-pill {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n.session-status-pill[data-status=\"Active\"] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 25%, transparent);\n}\n\n.session-status-pill[data-status=\"Idle\"] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n border-color: color-mix(in srgb, var(--mj-status-warning) 25%, transparent);\n}\n\n/* \u2500\u2500 Form tabs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Panes are hidden with `display: none`, never removed from the DOM. The\n designer pane holds UNSAVED canvas edits; @if-ing it away on a tab switch\n would discard them silently, and would also throw away the canvas's zoom and\n node positions on every trip to Details. */\n\n.agent-tabbar {\n flex: 0 0 auto;\n padding: 8px 12px 0;\n background: var(--mj-bg-page);\n}\n\n.agent-pane {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.agent-pane--hidden {\n display: none;\n}\n\n.agent-pane--designer {\n overflow: hidden;\n padding: 8px 12px 12px;\n background: var(--mj-bg-page);\n}\n\n/* The designer's dynamically-created section has no height of its own, so without\n this the flow canvas collapses to zero and renders as an empty strip. */\n.agent-pane--designer > ng-component,\n.agent-pane--designer > * {\n flex: 1;\n min-height: 0;\n}\n\n.agent-pane--invocations {\n overflow-y: auto;\n overflow-x: hidden;\n background: var(--mj-bg-page);\n}\n\n/* Initial load: the form's header renders as soon as the record arrives, but the tab strip and\n every pane wait on the agent TYPE. This fills that window so the page reads as loading rather\n than as broken. */\n.agent-form-loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 240px;\n padding: 32px;\n background: var(--mj-bg-page);\n}\n"] }]
5809
+ args: [{ standalone: false, selector: 'mj-ai-agent-form', template: "@if (record) {\n<mj-record-form-container [Record]=\"record\" [FormComponent]=\"this\"\n [ToolbarConfig]=\"toolbarConfig\"\n [WidthMode]=\"'full-width'\"\n (Navigate)=\"OnFormNavigate($event)\"\n (DeleteRequested)=\"OnDeleteRequested()\"\n (FavoriteToggled)=\"OnFavoriteToggled()\"\n (HistoryRequested)=\"OnHistoryRequested()\"\n (ListManagementRequested)=\"OnListManagementRequested()\">\n <form class=\"record-form\" #form=\"ngForm\">\n <!-- Agent Header \u2014 expanded view -->\n @if (!HeaderCollapsed) {\n <div class=\"agent-header\">\n <div class=\"agent-header-content\">\n <button class=\"agent-header-toggle\" (click)=\"ToggleHeaderCollapsed()\"\n title=\"Minimize header\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <div class=\"agent-overview\">\n <div class=\"agent-icon-wrapper\">\n @if (hasLogoURL()) {\n <img [src]=\"record.LogoURL\" [alt]=\"record.Name + ' logo'\" class=\"agent-logo\">\n } @else {\n <i [class]=\"getAgentIcon()\"></i>\n }\n </div>\n <div class=\"agent-info\">\n @if (EditMode) {\n <input type=\"text\" class=\"mj-input agent-name-input\"\n [(ngModel)]=\"record.Name\"\n name=\"agentName\"\n placeholder=\"Enter agent name...\">\n } @else {\n <h1 class=\"agent-name\">{{ record.Name || 'Untitled AI Agent' }}</h1>\n }\n <div class=\"agent-meta\">\n @if (record.Status) {\n <span class=\"status-badge\" [style.background-color]=\"getStatusBadgeColor()\">\n <i class=\"fa-solid fa-circle\"></i>\n {{ record.Status }}\n </span>\n }\n @if (record.Type) {\n <span class=\"execution-mode\">\n Agent Type: {{ record.Type }}\n </span>\n }\n @if (record.Parent) {\n <span class=\"parent-agent clickable\"\n (click)=\"navigateToParentAgent()\"\n title=\"Open parent agent: {{ record.Parent }}\">\n <i class=\"fa-solid fa-sitemap\"></i>\n Child of {{ record.Parent }}\n <i class=\"fa-solid fa-external-link\" style=\"margin-left: 4px; font-size: 10px;\"></i>\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"agent-actions\">\n @if (record.ID) {\n <button mjButton variant=\"primary\" size=\"lg\"\n (click)=\"openTestHarness()\"\n [disabled]=\"record.Status !== 'Active'\"\n title=\"Run this AI agent\">\n <i class=\"fa-solid fa-play\"></i> Run\n </button>\n <button mjButton size=\"lg\"\n (click)=\"openPermissionsDialog()\"\n [title]=\"IsOpenToEveryone ? 'Open to everyone \u2014 click to manage permissions' : 'Restricted \u2014 click to manage permissions'\">\n <i class=\"fa-solid\" [class.fa-lock-open]=\"IsOpenToEveryone\" [class.fa-lock]=\"!IsOpenToEveryone\"\n [style.color]=\"IsOpenToEveryone ? 'var(--mj-status-success)' : null\"></i>\n {{ IsOpenToEveryone ? 'Open' : 'Restricted' }}\n </button>\n }\n <button mjButton variant=\"outline\" size=\"sm\" (click)=\"refreshRelatedData()\" title=\"Refresh all data\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n <!-- Agent Header \u2014 minimized floating bar -->\n @if (HeaderCollapsed) {\n <div class=\"agent-header-mini\">\n <button class=\"agent-header-mini-expand\" (click)=\"ToggleHeaderCollapsed()\"\n title=\"Expand header\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <span class=\"agent-header-mini-name\">{{ record.Name || 'Untitled AI Agent' }}</span>\n @if (record.Status) {\n <span class=\"agent-header-mini-status\" [style.background-color]=\"getStatusBadgeColor()\">\n {{ record.Status }}\n </span>\n }\n <div class=\"agent-header-mini-spacer\"></div>\n @if (record.ID) {\n <button class=\"agent-header-mini-btn agent-header-mini-btn--primary\"\n (click)=\"openTestHarness()\"\n [disabled]=\"record.Status !== 'Active'\"\n title=\"Run agent\">\n <i class=\"fa-solid fa-play\"></i>\n </button>\n <button class=\"agent-header-mini-btn\"\n (click)=\"openPermissionsDialog()\"\n [title]=\"IsOpenToEveryone ? 'Open to everyone' : 'Restricted'\">\n <i class=\"fa-solid\" [class.fa-lock-open]=\"IsOpenToEveryone\" [class.fa-lock]=\"!IsOpenToEveryone\"\n [style.color]=\"IsOpenToEveryone ? 'var(--mj-status-success)' : null\"></i>\n </button>\n }\n <button class=\"agent-header-mini-btn\"\n (click)=\"refreshRelatedData()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n }\n <!-- The tab strip and every pane depend on the agent's TYPE, which loads asynchronously.\n Without this the form rendered its header over an empty area for the whole load \u2014\n no tabs, no designer, and the details pane hidden because no tab was active yet. -->\n @if (IsFormInitializing) {\n <div class=\"agent-form-loading\">\n <mj-loading text=\"Loading agent...\" size=\"medium\"></mj-loading>\n </div>\n } @else {\n <!-- Tabs, not accordions. For an agent type that ships a designer, the diagram IS the agent;\n leaving it as one collapsed panel among eleven made the record's most important view its\n least reachable one. Invocations is offered for every agent, because \"what runs this when\n I'm not looking?\" is a question you can ask of any of them. -->\n @if (FormTabs.length > 1) {\n <div class=\"agent-tabbar\">\n <mj-tab-nav [Tabs]=\"FormTabs\" [ActiveKey]=\"ActiveFormTab || ''\" (TabChange)=\"OnFormTabChange($event)\"></mj-tab-nav>\n </div>\n }\n\n @if (HasDesignerTab) {\n <!-- Hidden with CSS rather than removed with @if: the designer holds UNSAVED edits, and\n destroying it on a tab switch would discard them without a word. Keeping it mounted also\n means the canvas keeps its zoom and node positions across trips to Details. -->\n <div class=\"agent-pane agent-pane--designer\" [class.agent-pane--hidden]=\"ActiveFormTab !== 'designer'\">\n @if (loadingStates.customSection) {\n <mj-loading text=\"Loading {{ agentType?.Name }} configuration...\" size=\"medium\"></mj-loading>\n }\n <ng-container #customSectionContainer></ng-container>\n </div>\n }\n\n @if (record.ID) {\n <div class=\"agent-pane agent-pane--invocations\" [class.agent-pane--hidden]=\"ActiveFormTab !== 'invocations'\">\n <mj-agent-invocations\n [Provider]=\"Provider\"\n [AgentID]=\"record.ID\"\n [Active]=\"ActiveFormTab === 'invocations'\"\n [ExposeAsAction]=\"record.ExposeAsAction\"\n [ParentAgentName]=\"record.Parent\"\n [ParentAgentID]=\"record.ParentID\"\n (RecordOpenRequested)=\"OnInvocationOpenRequested($event)\">\n </mj-agent-invocations>\n </div>\n <div class=\"agent-pane agent-pane--rubrics\" [class.agent-pane--hidden]=\"ActiveFormTab !== 'rubrics'\">\n <mj-agent-rubrics\n [Provider]=\"Provider\"\n [AgentID]=\"record.ID\"\n [Active]=\"ActiveFormTab === 'rubrics'\">\n </mj-agent-rubrics>\n </div>\n }\n\n <!-- Single Pane Layout with Expander Panels -->\n <div class=\"form-content agent-pane\" [class.agent-pane--hidden]=\"ActiveFormTab !== 'details'\">\n <!-- Requests & History -->\n @if (record.ID) {\n <mj-accordion-panel id=\"history\"\n [Expanded]=\"GetSectionExpanded('history', false)\"\n [Disabled]=\"loadingStates.executionHistory\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-history\"></i> Execution History\n @if (loadingStates.executionHistory) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (executionHistoryCount > 0) {\n <span> ({{ executionHistoryCount }}@if (executionHistoryCount < totalExecutionHistoryCount) { of {{ totalExecutionHistoryCount }}})</span>\n }\n </ng-template>\n <div class=\"panel-content execution-history-panel\">\n <!-- Segmented toggle: agent runs vs. realtime voice sessions -->\n @if (UserCanViewSessions) {\n <div class=\"history-view-toggle\" role=\"tablist\">\n <button type=\"button\" class=\"history-toggle-option\"\n [class.active]=\"executionHistoryView === 'runs'\"\n (click)=\"setExecutionHistoryView('runs')\">\n <i class=\"fa-solid fa-person-running\"></i> Runs\n @if (totalExecutionHistoryCount > 0) {\n <span class=\"history-toggle-count\">{{ totalExecutionHistoryCount }}</span>\n }\n </button>\n <button type=\"button\" class=\"history-toggle-option\"\n [class.active]=\"executionHistoryView === 'sessions'\"\n (click)=\"setExecutionHistoryView('sessions')\">\n <i class=\"fa-solid fa-tower-broadcast\"></i> Sessions\n @if (totalSessionCount > 0) {\n <span class=\"history-toggle-count\">{{ totalSessionCount }}</span>\n }\n </button>\n </div>\n }\n @if (executionHistoryView === 'sessions') {\n <!-- Voice/realtime sessions list -->\n @if (loadingSessions) {\n <mj-loading text=\"Loading sessions...\" size=\"medium\"></mj-loading>\n } @else if (agentSessions.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-tower-broadcast\"\n Title=\"No Voice Sessions\"\n Message=\"This agent hasn't participated in any realtime voice sessions yet \u2014 neither as the co-agent nor as a delegation target.\"\n Size=\"compact\" />\n } @else {\n <div class=\"execution-history-list\">\n @for (item of agentSessions; track item.row.ID) {\n <div class=\"execution-card session-card\" (click)=\"openSessionRecord(item.row.ID)\" title=\"Open session\">\n <div class=\"execution-header\">\n <div class=\"execution-left-section\">\n <div class=\"execution-status\">\n <div class=\"status-indicator\" [style.background-color]=\"getSessionStatusColor(item.row.Status)\">\n <i [class]=\"getSessionStatusIcon(item.row.Status)\"></i>\n </div>\n <div class=\"execution-info\">\n <div class=\"execution-title\">\n Session #{{ item.row.ID.substring(0, 8) }}\n @if (item.isCoAgent) {\n <span class=\"session-role-chip\">as co-agent</span>\n }\n @if (item.isTarget) {\n <span class=\"session-role-chip session-role-chip--target\">as target</span>\n }\n </div>\n <div class=\"execution-date\">{{ item.row.__mj_CreatedAt | date:'MMM d, h:mm a' }}</div>\n </div>\n </div>\n <div class=\"execution-metrics\">\n <div class=\"metric-item\">\n <span class=\"session-status-pill\" [attr.data-status]=\"item.row.Status\">{{ item.row.Status }}</span>\n </div>\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-stopwatch\"></i>\n <span class=\"metric-label\">Duration:</span>\n <span class=\"metric-value\">{{ formatSessionDuration(item) }}</span>\n </div>\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-plug\"></i>\n <span class=\"metric-label\">Channels:</span>\n <span class=\"metric-value\">{{ item.channelCount }}</span>\n </div>\n @if (item.isCoAgent && item.targetAgentName) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-bullseye\"></i>\n <span class=\"metric-label\">Target:</span>\n <span class=\"metric-value\">{{ item.targetAgentName }}</span>\n </div>\n }\n @if (item.isTarget && !item.isCoAgent && item.row.Agent) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-tower-broadcast\"></i>\n <span class=\"metric-label\">Co-agent:</span>\n <span class=\"metric-value\">{{ item.row.Agent }}</span>\n </div>\n }\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-user\"></i>\n <span class=\"metric-label\">User:</span>\n <span class=\"metric-value\">{{ item.row.User }}</span>\n </div>\n </div>\n </div>\n <div class=\"execution-actions\">\n <button class=\"action-btn\" (click)=\"openSessionRecord(item.row.ID); $event.stopPropagation()\" title=\"View session details\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n }\n } @else {\n @if (loadingStates.executionHistory) {\n <mj-loading text=\"Loading execution history...\" size=\"medium\"></mj-loading>\n } @else if (executionHistoryCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-clock-rotate-left\"\n Title=\"No Execution History\"\n Message=\"This agent hasn't been executed yet. Use the Test Agent button to run the agent and see execution history here.\"\n Size=\"compact\" />\n } @else {\n <!-- Search Bar -->\n <div class=\"execution-search-bar\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\" class=\"mj-input\"\n [(ngModel)]=\"executionSearchText\"\n (ngModelChange)=\"onExecutionSearchChange()\"\n [ngModelOptions]=\"{standalone: true}\"\n placeholder=\"Search by Run ID...\">\n </div>\n </div>\n <div class=\"execution-history-list\">\n @if (filteredExecutions.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"No Matching Results\"\n [Message]=\"ExecutionSearchEmptyMessage\"\n Size=\"compact\" />\n }\n @for (execution of filteredExecutions; track execution.ID) {\n <div class=\"execution-card\" [class.expanded]=\"expandedExecutions[execution.ID]\">\n <div class=\"execution-header\" (click)=\"toggleExecutionExpanded(execution.ID)\">\n <div class=\"execution-left-section\">\n <div class=\"execution-status\">\n <div class=\"status-indicator\" [style.background-color]=\"getExecutionStatusColor(execution.Status)\">\n <i [class]=\"getExecutionStatusIcon(execution.Status)\"></i>\n </div>\n <div class=\"execution-info\">\n <div class=\"execution-title\">\n <i class=\"fa-solid fa-chevron-right expand-icon\" [class.expanded]=\"expandedExecutions[execution.ID]\"></i>\n Execution #{{ execution.ID.substring(0, 8) }}\n </div>\n <div class=\"execution-date\">{{ execution.__mj_CreatedAt | date:'MMM d, h:mm a' }}</div>\n </div>\n </div>\n <div class=\"execution-metrics\">\n @if (execution.Configuration) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-cog\"></i>\n <span class=\"metric-label\">Config:</span>\n <span class=\"metric-value\">{{ execution.Configuration }}</span>\n </div>\n }\n @if (execution.CompletedAt) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-stopwatch\"></i>\n <span class=\"metric-label\">Duration:</span>\n <span class=\"metric-value\">{{ formatExecutionTimeFromDates(execution.StartedAt, execution.CompletedAt) }}</span>\n </div>\n } @else if (execution.Status === 'Running') {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-clock\"></i>\n <span class=\"metric-label\">Running:</span>\n <!-- <span class=\"metric-value\">{{ execution.StartedAt | runningTime }}</span> -->\n </div>\n }\n @if (execution.TotalTokensUsedRollup || execution.TotalTokensUsed) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-microchip\"></i>\n <span class=\"metric-label\">Tokens:</span>\n <span class=\"metric-value\">{{ formatTokenCount(execution.TotalTokensUsedRollup || execution.TotalTokensUsed) }}</span>\n </div>\n }\n @if (execution.TotalCostRollup || execution.TotalCost) {\n <div class=\"metric-item\">\n <i class=\"fa-solid fa-dollar-sign\"></i>\n <span class=\"metric-label\">Cost:</span>\n <span class=\"metric-value\">${{ formatCost(execution.TotalCostRollup || execution.TotalCost) }}</span>\n </div>\n }\n </div>\n </div>\n <div class=\"execution-actions\">\n <button class=\"action-btn\" (click)=\"openExecutionRecord(execution.ID); $event.stopPropagation()\" title=\"View details\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n </button>\n </div>\n </div>\n @if (expandedExecutions[execution.ID]) {\n <div class=\"execution-expanded-content\">\n <!-- Detailed Metrics -->\n <div class=\"detailed-metrics\">\n <div class=\"metrics-grid\">\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-clock\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Started</span>\n <span class=\"metric-data\">{{ execution.StartedAt | date:'medium' }}</span>\n </div>\n </div>\n @if (execution.CompletedAt) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Completed</span>\n <span class=\"metric-data\">{{ execution.CompletedAt | date:'medium' }}</span>\n </div>\n </div>\n }\n @if (execution.TotalTokensUsed) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-microchip\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Direct Tokens</span>\n <span class=\"metric-data\">{{ formatTokenCount(execution.TotalTokensUsed) }}</span>\n </div>\n </div>\n }\n @if (execution.TotalTokensUsedRollup && execution.TotalTokensUsedRollup !== execution.TotalTokensUsed) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Total + Sub-agents</span>\n <span class=\"metric-data\">{{ formatTokenCount(execution.TotalTokensUsedRollup) }}</span>\n </div>\n </div>\n }\n @if (execution.TotalCost) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-dollar-sign\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Direct Cost</span>\n <span class=\"metric-data\">${{ formatCost(execution.TotalCost) }}</span>\n </div>\n </div>\n }\n @if (execution.TotalCostRollup && execution.TotalCostRollup !== execution.TotalCost) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-calculator\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Total + Sub-agents</span>\n <span class=\"metric-data\">${{ formatCost(execution.TotalCostRollup) }}</span>\n </div>\n </div>\n }\n @if (execution.ConversationID) {\n <div class=\"metric-detail\">\n <i class=\"fa-solid fa-comments\"></i>\n <div class=\"metric-info\">\n <span class=\"metric-title\">Conversation</span>\n <span class=\"metric-data\">{{ execution.ConversationID.substring(0, 8) }}...</span>\n </div>\n </div>\n }\n </div>\n </div>\n @if (HasExecutionResult(execution)) {\n <div class=\"result-section\">\n <h5><i class=\"fa-solid fa-file-text\"></i> Result</h5>\n <mj-code-editor\n [value]=\"getExecutionResultPreview(execution, false)\"\n [readonly]=\"true\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"max-height: 200px; width: 100%;\">\n </mj-code-editor>\n </div>\n }\n @if (execution.ErrorMessage) {\n <div class=\"error-section\">\n <h5><i class=\"fa-solid fa-exclamation-triangle\"></i> Error</h5>\n <div class=\"error-content\">{{ execution.ErrorMessage }}</div>\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- Pagination Controls -->\n @if (totalPages > 1) {\n <div class=\"pagination-controls\">\n <button mjButton\n variant=\"outline\"\n (click)=\"goToPreviousPage()\"\n [disabled]=\"!hasPreviousPage || isLoadingPage\"\n class=\"page-nav-btn\">\n <i class=\"fa-solid fa-chevron-left\"></i>\n Previous\n </button>\n <div class=\"page-info\">\n @if (isLoadingPage) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Loading...\n } @else {\n Page {{ executionHistoryCurrentPage }} of {{ totalPages }}\n <span class=\"record-count\">({{ totalExecutionHistoryCount }} total)</span>\n }\n </div>\n <button mjButton\n variant=\"outline\"\n (click)=\"goToNextPage()\"\n [disabled]=\"!hasNextPage || isLoadingPage\"\n class=\"page-nav-btn\">\n Next\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"navigateToEntity('MJ: AI Agent Runs', '')\"\n class=\"view-all-btn\">\n <i class=\"fa-solid fa-external-link\"></i>\n View All in Grid\n </button>\n </div>\n }\n </div>\n }\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Actions -->\n @if (record.ID) {\n <mj-accordion-panel id=\"actions\"\n [Expanded]=\"GetSectionExpanded('actions', false)\"\n [Disabled]=\"loadingStates.actions\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-bolt\"></i> Actions\n @if (loadingStates.actions) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (actionCount > 0) {\n <span> ({{ actionCount }})</span>\n }\n </ng-template>\n <div class=\"panel-content\">\n @if (loadingStates.actions) {\n <div class=\"loading-state\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <p>Loading actions...</p>\n </div>\n } @else {\n <div class=\"section-header\">\n <div class=\"header-actions\">\n @if (EditMode && UserCanCreateActions) {\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"configureActions()\">\n <i class=\"fa-solid fa-plus\"></i> Add Action\n </button>\n }\n </div>\n </div>\n @if (actionCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-bolt\"\n Title=\"No Actions Configured\"\n Message=\"Add actions to enable this agent to perform specific tasks and operations.\"\n [ActionText]=\"(EditMode && UserCanCreateActions) ? 'Configure First Action' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"configureActions()\"\n Size=\"compact\" />\n } @else {\n <div class=\"entity-list\">\n @for (action of agentActions; track action.ID) {\n <div class=\"entity-item action-item\" (click)=\"navigateToEntity('MJ: Actions', action.ID)\">\n <div class=\"item-icon\">\n <i [class]=\"getActionIcon(action)\"></i>\n </div>\n <div class=\"item-content\">\n <div class=\"item-title\">{{ action.Name || 'Untitled Action' }}</div>\n @if (action.Description) {\n <div class=\"item-preview\">{{ action.Description }}</div>\n }\n <div class=\"item-meta\">\n @if (action.Type) {\n <span class=\"meta-tag\">{{ action.Type }}</span>\n }\n <span class=\"status-tag\" [class.active]=\"action.Status==='Active'\" [class.inactive]=\"action.Status!=='Active'\">\n <i class=\"fa-solid\" [class.fa-check-circle]=\"action.Status==='Active'\" [class.fa-times-circle]=\"action.Status!=='Active'\"></i>\n {{ action.Status }}\n </span>\n </div>\n </div>\n <div class=\"item-actions\">\n @if (EditMode && UserCanDeleteActions) {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"removeAction(action, $event)\"\n title=\"Remove action\"\n class=\"error-action\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n <i class=\"fa-solid fa-external-link\"></i>\n </div>\n </div>\n }\n @if (actionCount > agentActions.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('MJ: AI Agent Actions', '')\">\n <span>View all {{ actionCount }} actions...</span>\n </div>\n }\n </div>\n }\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Sub-Agents (Unified View with Filter) -->\n @if (record.ID) {\n <mj-accordion-panel id=\"subagents\"\n [Expanded]=\"GetSectionExpanded('subagents', false)\"\n [Disabled]=\"loadingStates.subAgents\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-sitemap\"></i> Sub-Agents\n @if (loadingStates.subAgents) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (totalSubAgentCount > 0) {\n <span> ({{ totalSubAgentCount }})</span>\n }\n </ng-template>\n <div class=\"panel-content\">\n <!-- Filter Controls -->\n <div class=\"section-header sub-agent-filter-header\">\n <div class=\"filter-controls\">\n <div class=\"mj-button-group\">\n <button mjButton\n size=\"sm\"\n [class.active]=\"subAgentFilter === 'all'\"\n (click)=\"setSubAgentFilter('all')\">\n <i class=\"fa-solid fa-layer-group\"></i>\n All ({{ totalSubAgentCount }})\n </button>\n <button mjButton\n size=\"sm\"\n [class.active]=\"subAgentFilter === 'child'\"\n (click)=\"setSubAgentFilter('child')\">\n <i class=\"fa-solid fa-link\"></i>\n Child ({{ childSubAgentCount }})\n </button>\n <button mjButton\n size=\"sm\"\n [class.active]=\"subAgentFilter === 'related'\"\n (click)=\"setSubAgentFilter('related')\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n Related ({{ relatedSubAgentCount }})\n </button>\n </div>\n </div>\n <div class=\"header-actions\">\n @if (EditMode && UserCanCreateSubAgents) {\n <button mjButton\n variant=\"primary\"\n size=\"sm\"\n (click)=\"createChildSubAgent()\"\n title=\"Create a new child sub-agent that shares this agent's payload\">\n <i class=\"fa-solid fa-link\"></i>\n Create Child\n </button>\n <button mjButton\n size=\"sm\"\n (click)=\"linkRelatedSubAgent()\"\n title=\"Link an existing agent as a related sub-agent with payload mapping\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n Link Related\n </button>\n }\n </div>\n </div>\n <!-- Empty State -->\n @if (totalSubAgentCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-sitemap\"\n Title=\"No Sub-Agents\"\n Message=\"Sub-agents help build complex workflows through hierarchical orchestration.\"\n Size=\"compact\">\n <div class=\"empty-state-info\">\n <div class=\"info-card\">\n <i class=\"fa-solid fa-link\" style=\"color: var(--mj-status-info);\"></i>\n <strong>Child Sub-Agents</strong>\n <p>Share payload structure, dedicated to parent</p>\n </div>\n <div class=\"info-card\">\n <i class=\"fa-solid fa-share-nodes\" style=\"color: var(--mj-brand-primary);\"></i>\n <strong>Related Sub-Agents</strong>\n <p>Reusable agents with payload mapping</p>\n </div>\n </div>\n </mj-empty-state>\n } @else {\n <!-- Unified Sub-Agent List -->\n <div class=\"entity-list\">\n @for (item of filteredSubAgents; track item.agent.ID) {\n <div class=\"entity-item sub-agent-item\"\n [class.child-sub-agent]=\"item.type === 'child'\"\n [class.related-sub-agent]=\"item.type === 'related'\"\n (click)=\"navigateToEntity('MJ: AI Agents', item.agent.ID)\">\n <!-- Type Badge -->\n <div class=\"sub-agent-type-badge\"\n [style.background-color]=\"getSubAgentBadgeColor(item)\">\n <i [class]=\"getSubAgentBadgeIcon(item)\"></i>\n {{ getSubAgentBadgeText(item) }}\n </div>\n <!-- Agent Icon -->\n <div class=\"item-icon\">\n @if (hasSubAgentLogoURL(item.agent)) {\n <img [src]=\"item.agent.LogoURL\"\n [alt]=\"item.agent.Name + ' logo'\"\n class=\"sub-agent-logo\">\n } @else {\n <i [class]=\"getSubAgentIcon(item.agent)\"></i>\n }\n </div>\n <!-- Agent Content -->\n <div class=\"item-content\">\n <div class=\"item-title\">{{ item.agent.Name || 'Untitled Sub-Agent' }}</div>\n @if (item.agent.Description) {\n <div class=\"item-preview\">{{ item.agent.Description }}</div>\n }\n <div class=\"item-meta\">\n <!-- Payload Info -->\n <span class=\"meta-tag payload-info\">\n <i class=\"fa-solid fa-database\"></i>\n {{ getSubAgentPayloadInfo(item) }}\n </span>\n <!-- Status -->\n @if (item.agent.Status) {\n <span class=\"status-tag\"\n [style.background-color]=\"getStatusBadgeColor()\">\n {{ item.agent.Status }}\n </span>\n }\n <!-- Agent Type -->\n @if (item.agent.Type) {\n <span class=\"meta-tag\">{{ item.agent.Type }}</span>\n }\n </div>\n </div>\n <!-- Actions -->\n <div class=\"item-actions\">\n @if (EditMode) {\n <!-- Output Mapping Config (Related only) -->\n @if (item.type === 'related') {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"configureOutputMapping(item, $event)\"\n title=\"Configure output mapping\">\n <i class=\"fa-solid fa-exchange-alt\"></i>\n </button>\n }\n <!-- Advanced Settings (Child only) -->\n @if (item.type === 'child' && UserCanCreateSubAgents) {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"openSubAgentAdvancedSettings(item.agent, $event)\"\n title=\"Advanced settings\">\n <i class=\"fa-solid fa-cog\"></i>\n </button>\n }\n <!-- Remove/Unlink -->\n @if (UserCanDeleteSubAgents) {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"item.type === 'child' ? removeChildSubAgent(item, $event) : unlinkRelatedSubAgent(item, $event)\"\n [title]=\"item.type === 'child' ? 'Delete child sub-agent' : 'Unlink related sub-agent'\"\n class=\"error-action\">\n <i [class]=\"item.type === 'child' ? 'fa-solid fa-trash' : 'fa-solid fa-unlink'\"></i>\n </button>\n }\n }\n <i class=\"fa-solid fa-external-link\"></i>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Prompts (With Model Selection) -->\n @if (record.ID) {\n <mj-accordion-panel id=\"prompts\"\n [Expanded]=\"GetSectionExpanded('prompts', false)\"\n [Disabled]=\"loadingStates.prompts\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-comments\"></i> Prompts\n @if (loadingStates.prompts) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (promptCount > 0) {\n <span> ({{ promptCount }})</span>\n }\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"prompt-controls\">\n <!-- Model Selection Mode Control -->\n <div class=\"model-selection-mode\">\n <label class=\"model-selection-label\">\n <i class=\"fa-solid fa-sliders\"></i>\n Model Selection:\n </label>\n @if (EditMode) {\n <mj-dropdown\n [(ngModel)]=\"record.ModelSelectionMode\"\n name=\"modelSelectionMode\"\n [Data]=\"modelSelectionModes\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n class=\"model-selection-dropdown\">\n </mj-dropdown>\n } @else {\n <span class=\"model-selection-value\">{{ record.ModelSelectionMode || 'Agent Type' }}</span>\n }\n </div>\n </div>\n <div class=\"header-actions\">\n @if (EditMode && UserCanCreateNewPrompts) {\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"addPrompt()\">\n <i class=\"fa-solid fa-plus\"></i> Add Prompt\n </button>\n }\n </div>\n </div>\n @if (promptCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-comments\"\n Title=\"No Prompts Configured\"\n Message=\"Add prompts to define how this agent processes requests and generates responses.\"\n [ActionText]=\"(EditMode && UserCanCreateNewPrompts) ? 'Create First Prompt' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"addPrompt()\"\n Size=\"compact\" />\n } @else {\n <div class=\"entity-list\">\n @for (prompt of agentPrompts; track prompt.ID) {\n <div class=\"entity-item prompt-item\" (click)=\"navigateToEntity('MJ: AI Prompts', prompt.ID)\">\n <div class=\"item-icon\">\n <i class=\"fa-solid fa-comment-dots\"></i>\n </div>\n <div class=\"item-content\">\n <div class=\"item-title\">{{ prompt.Name }}</div>\n @if (prompt.TemplateText) {\n <div class=\"item-preview\">{{ prompt.TemplateText.substring(0, 120) }}{{ prompt.TemplateText.length > 120 ? '...' : '' }}</div>\n }\n <div class=\"item-meta\">\n @if (prompt.PromptRole) {\n <span class=\"meta-tag\">{{ prompt.PromptRole }}</span>\n }\n </div>\n </div>\n <div class=\"item-actions\">\n @if (EditMode && UserCanCreatePrompts) {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"openPromptAdvancedSettings(prompt, $event)\"\n title=\"Advanced settings\">\n <i class=\"fa-solid fa-cog\"></i>\n </button>\n }\n @if (EditMode && UserCanDeletePrompts) {\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"removePrompt(prompt, $event)\"\n title=\"Remove prompt\"\n class=\"error-action\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n <i class=\"fa-solid fa-external-link\"></i>\n </div>\n </div>\n }\n @if (promptCount > agentPrompts.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('MJ: AI Prompts', '')\">\n <span>View all {{ promptCount }} prompts...</span>\n </div>\n }\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Learning & Analytics -->\n @if (record.ID) {\n <mj-accordion-panel id=\"learning\"\n [Expanded]=\"GetSectionExpanded('learning', false)\"\n [Disabled]=\"loadingStates.learningCycles\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-brain\"></i> Learning Cycles\n @if (loadingStates.learningCycles) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (learningCycleCount > 0) {\n <span> ({{ learningCycleCount }})</span>\n }\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Monitor and manage learning cycles, training sessions, and performance analytics.\n </div>\n </div>\n @if (learningCycleCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-brain\"\n Title=\"No Learning Cycles\"\n Message=\"Learning cycles will appear here as the agent processes requests and improves over time.\"\n Size=\"compact\" />\n } @else {\n <div class=\"entity-list\">\n @for (cycle of learningCycles; track cycle.ID) {\n <div class=\"entity-item learning-item\" (click)=\"navigateToEntity('MJ: AI Agent Learning Cycles', cycle.ID)\">\n <div class=\"item-icon\">\n <i class=\"fa-solid fa-brain\"></i>\n </div>\n <div class=\"item-content\">\n <div class=\"item-title\">Learning Cycle {{ cycle.ID.substring(0, 8) }}</div>\n <div class=\"item-meta\">\n @if (cycle.StartedAt) {\n <span class=\"meta-tag\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ cycle.StartedAt | date:'short' }}\n </span>\n }\n @if (cycle.Status) {\n <span class=\"status-tag\">{{ cycle.Status }}</span>\n }\n </div>\n </div>\n <div class=\"item-actions\">\n <i class=\"fa-solid fa-external-link\"></i>\n </div>\n </div>\n }\n @if (learningCycleCount > learningCycles.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('MJ: AI Agent Learning Cycles', '')\">\n <span>View all {{ learningCycleCount }} cycles...</span>\n </div>\n }\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Notes & Documentation -->\n @if (record.ID) {\n <mj-accordion-panel id=\"notes\"\n [Expanded]=\"GetSectionExpanded('notes', false)\"\n [Disabled]=\"loadingStates.notes\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-sticky-note\"></i> Notes\n @if (loadingStates.notes) {\n <span><i class=\"fa-solid fa-spinner fa-spin\"></i></span>\n } @else if (noteCount > 0) {\n <span> ({{ noteCount }})</span>\n }\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Manage notes, documentation, and annotations for this agent.\n </div>\n <div class=\"header-actions\">\n @if (EditMode && UserCanCreateNotes) {\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"addNote()\">\n <i class=\"fa-solid fa-plus\"></i> Add Note\n </button>\n }\n </div>\n </div>\n @if (noteCount === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-sticky-note\"\n Title=\"No Notes\"\n Message=\"Add notes to document important information, observations, or instructions for this agent.\"\n [ActionText]=\"(EditMode && UserCanCreateNotes) ? 'Create First Note' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"addNote()\"\n Size=\"compact\" />\n } @else {\n <div class=\"entity-list\">\n @for (note of agentNotes; track note.ID) {\n <div class=\"entity-item note-item\" (click)=\"navigateToEntity('MJ: AI Agent Notes', note.ID)\">\n <div class=\"item-icon\">\n <i class=\"fa-solid fa-sticky-note\"></i>\n </div>\n <div class=\"item-content\">\n <div class=\"item-title\">{{ note.Type || 'Note' }}</div>\n @if (note.Note) {\n <div class=\"item-preview\">{{ note.Note.substring(0, 100) }}{{ note.Note.length > 100 ? '...' : '' }}</div>\n }\n <div class=\"item-meta\">\n @if (note.__mj_CreatedAt) {\n <span class=\"meta-tag\">\n <i class=\"fa-solid fa-calendar\"></i>\n {{ note.__mj_CreatedAt | date:'short' }}\n </span>\n }\n </div>\n </div>\n <div class=\"item-actions\">\n <i class=\"fa-solid fa-external-link\"></i>\n </div>\n </div>\n }\n @if (noteCount > agentNotes.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('MJ: AI Agent Notes', '')\">\n <span>View all {{ noteCount }} notes...</span>\n </div>\n }\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Search -->\n @if (record.ID) {\n <mj-accordion-panel id=\"search\"\n [Expanded]=\"GetSectionExpanded('search', false)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-magnifying-glass\"></i> Search\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Control this agent's access to <strong>Scoped Search</strong> and assign the scopes it can use for pre-execution RAG or agent-invoked search.\n </div>\n </div>\n\n <!-- Scope Access mode -->\n <div class=\"agent-search-access\">\n <label class=\"agent-search-access-option\" [class.active]=\"record.SearchScopeAccess === 'All'\">\n <input type=\"radio\" name=\"SearchScopeAccess\" value=\"All\" [checked]=\"record.SearchScopeAccess === 'All'\" [disabled]=\"!EditMode\" (change)=\"record.SearchScopeAccess = 'All'\">\n <i class=\"fa-solid fa-globe\"></i>\n <div class=\"agent-search-access-text\">\n <div class=\"agent-search-access-title\">All</div>\n <div class=\"agent-search-access-desc\">Can use any scope including Global. No scope restriction.</div>\n </div>\n </label>\n <label class=\"agent-search-access-option\" [class.active]=\"record.SearchScopeAccess === 'Assigned'\">\n <input type=\"radio\" name=\"SearchScopeAccess\" value=\"Assigned\" [checked]=\"record.SearchScopeAccess === 'Assigned'\" [disabled]=\"!EditMode\" (change)=\"record.SearchScopeAccess = 'Assigned'\">\n <i class=\"fa-solid fa-user-check\"></i>\n <div class=\"agent-search-access-text\">\n <div class=\"agent-search-access-title\">Assigned</div>\n <div class=\"agent-search-access-desc\">Can use ONLY scopes listed below, for users with a Search grant on the scope (directly or through a role). Other scopes are rejected with ACCESS_DENIED.</div>\n </div>\n </label>\n <label class=\"agent-search-access-option\" [class.active]=\"record.SearchScopeAccess === 'None'\">\n <input type=\"radio\" name=\"SearchScopeAccess\" value=\"None\" [checked]=\"record.SearchScopeAccess === 'None'\" [disabled]=\"!EditMode\" (change)=\"record.SearchScopeAccess = 'None'\">\n <i class=\"fa-solid fa-ban\"></i>\n <div class=\"agent-search-access-text\">\n <div class=\"agent-search-access-title\">None</div>\n <div class=\"agent-search-access-desc\">No search capability. The Scoped Search action and pre-execution retrieval are disabled for this agent.</div>\n </div>\n </label>\n </div>\n\n <!-- Assigned scopes grid -->\n @if (record.SearchScopeAccess !== 'None') {\n <div class=\"agent-search-grid-header\">\n <h4>Assigned Scopes</h4>\n <p class=\"section-description\">\n <strong>Pre-Execution</strong> scopes are searched before the first LLM call, for users who may search them.\n <strong>Agent-Invoked</strong> scopes are callable via the Scoped Search tool during execution.\n <strong>Both</strong> covers both paths.\n </p>\n </div>\n <mj-search-scope-child-grid\n [ParentID]=\"record.ID\"\n ChildEntityName=\"MJ: AI Agent Search Scopes\"\n ParentFieldName=\"AgentID\"\n [Columns]=\"AgentSearchScopeColumns\"\n [Disabled]=\"!EditMode\"\n AddButtonLabel=\"+ Assign another scope\"\n EmptyMessage=\"No scopes assigned yet. Assign at least one if this agent will use Scoped Search.\"\n (RowsChanged)=\"LoadPermissionSummary()\">\n </mj-search-scope-child-grid>\n\n <!-- Phase 2A: read-only audit summary of who has\n permission on each of this agent's assigned scopes.\n Editing happens in the Knowledge Hub Config dashboard\n (see \"Permissions\" subtab under Search Scopes). -->\n <div class=\"agent-search-section\" style=\"margin-top: 16px;\">\n <h4 style=\"margin: 0 0 8px 0;\">\n <i class=\"fa-solid fa-shield-halved\"></i> Effective scope permissions\n </h4>\n <p class=\"section-description\" style=\"margin-bottom: 8px;\">\n Per-user / per-role grants on the scopes assigned above. Edit grants in\n <strong>Knowledge Hub Config &rarr; Search Scopes &rarr; Permissions</strong>.\n </p>\n @if (IsLoadingPermissions) {\n <div style=\"color: var(--mj-text-muted);\">Loading permissions&hellip;</div>\n } @else if (PermissionSummary.length === 0) {\n <div style=\"color: var(--mj-text-muted); font-style: italic;\">\n No scopes assigned yet \u2014 permissions will appear here once you add scopes above.\n </div>\n } @else {\n @for (s of PermissionSummary; track s.ScopeID) {\n <div style=\"margin-bottom: 12px; padding: 8px 12px; background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-subtle); border-radius: 4px;\">\n <div style=\"font-weight: 600; margin-bottom: 4px;\">{{ s.ScopeName }}</div>\n @if (s.Permissions.length === 0) {\n <div style=\"color: var(--mj-text-muted); font-size: 0.9em;\">\n No explicit permissions. Users need a Search grant (directly or through a role) unless this agent's access is <code>All</code>.\n </div>\n } @else {\n <ul style=\"margin: 4px 0 0 16px; padding: 0;\">\n @for (p of s.Permissions; track p.Principal + p.Level) {\n <li style=\"font-size: 0.9em; padding: 2px 0;\">\n <i class=\"fa-solid\" [class.fa-user]=\"p.PrincipalType === 'User'\" [class.fa-users]=\"p.PrincipalType === 'Role'\"></i>\n <strong>{{ p.Principal }}</strong>\n <span style=\"color: var(--mj-text-muted);\">({{ p.PrincipalType }})</span>\n &mdash; <span [style.color]=\"p.Level === 'None' ? 'var(--mj-status-error-text)' : 'var(--mj-text-primary)'\">{{ p.Level }}</span>\n </li>\n }\n </ul>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Payload -->\n <mj-accordion-panel id=\"payload\"\n [Expanded]=\"GetSectionExpanded('payload', false)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-exchange-alt\"></i> Payload Management\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Configure how this agent handles data payloads, path routing, and validation between parent and child agents.\n </div>\n </div>\n <!-- Payload Scope Section -->\n <div class=\"payload-section\">\n <h3 class=\"payload-section-title\">\n <i class=\"fa-solid fa-target\"></i>\n Payload Scope\n </h3>\n <div class=\"payload-field-container\">\n <div class=\"payload-field-info\">\n <label class=\"payload-field-label\">Payload Scope Path</label>\n <p class=\"payload-field-description\">\n Specify a path within the parent payload that this sub-agent should operate on.\n Leave empty to receive the entire payload.\n </p>\n </div>\n <div class=\"payload-field-input\">\n <mj-form-field\n FieldName=\"PayloadScope\"\n Type=\"textbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\"\n style=\"width: 100%;\">\n </mj-form-field>\n <div class=\"payload-field-example\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Example: <code>/customer/profile</code> or <code>/analysis/results</code></span>\n </div>\n </div>\n </div>\n </div>\n <!-- Path Configuration Section -->\n <div class=\"payload-section\">\n <h3 class=\"payload-section-title\">\n <i class=\"fa-solid fa-route\"></i>\n Path Configuration\n </h3>\n <div class=\"payload-paths-grid\">\n <!-- Downstream Paths -->\n <div class=\"payload-path-card\">\n <div class=\"payload-path-header\">\n <div class=\"payload-path-icon downstream\">\n <i class=\"fa-solid fa-arrow-down\"></i>\n </div>\n <div class=\"payload-path-info\">\n <h4>Downstream Paths</h4>\n <p>JSON array of paths to pass to sub-agents</p>\n </div>\n </div>\n <div class=\"payload-path-content\">\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"record.PayloadDownstreamPaths || '[&quot;*&quot;]'\"\n [readonly]=\"!EditMode\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"height: 100px; width: 100%;\"\n (valueChange)=\"updatePayloadField('PayloadDownstreamPaths', $event)\">\n </mj-code-editor>\n </div>\n <div class=\"payload-path-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Use <code>[\"*\"]</code> to pass entire payload or specify paths like <code>[\"user.id\", \"order.*\"]</code>\n </div>\n </div>\n </div>\n <!-- Upstream Paths -->\n <div class=\"payload-path-card\">\n <div class=\"payload-path-header\">\n <div class=\"payload-path-icon upstream\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n </div>\n <div class=\"payload-path-info\">\n <h4>Upstream Paths</h4>\n <p>JSON array of paths sub-agents can write back</p>\n </div>\n </div>\n <div class=\"payload-path-content\">\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"record.PayloadUpstreamPaths || '[&quot;*&quot;]'\"\n [readonly]=\"!EditMode\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"height: 100px; width: 100%;\"\n (valueChange)=\"updatePayloadField('PayloadUpstreamPaths', $event)\">\n </mj-code-editor>\n </div>\n <div class=\"payload-path-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Use <code>[\"*\"]</code> to allow all writes or limit to specific paths\n </div>\n </div>\n </div>\n <!-- Self Read Paths -->\n <div class=\"payload-path-card\">\n <div class=\"payload-path-header\">\n <div class=\"payload-path-icon self-read\">\n <i class=\"fa-solid fa-eye\"></i>\n </div>\n <div class=\"payload-path-info\">\n <h4>Self Read Paths</h4>\n <p>JSON array of paths this agent can read</p>\n </div>\n </div>\n <div class=\"payload-path-content\">\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"record.PayloadSelfReadPaths || '[]'\"\n [readonly]=\"!EditMode\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"height: 100px; width: 100%;\"\n (valueChange)=\"updatePayloadField('PayloadSelfReadPaths', $event)\">\n </mj-code-editor>\n </div>\n <div class=\"payload-path-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Paths this agent's prompts can read from the payload\n </div>\n </div>\n </div>\n <!-- Self Write Paths -->\n <div class=\"payload-path-card\">\n <div class=\"payload-path-header\">\n <div class=\"payload-path-icon self-write\">\n <i class=\"fa-solid fa-pen\"></i>\n </div>\n <div class=\"payload-path-info\">\n <h4>Self Write Paths</h4>\n <p>JSON array of paths this agent can write to</p>\n </div>\n </div>\n <div class=\"payload-path-content\">\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"record.PayloadSelfWritePaths || '[]'\"\n [readonly]=\"!EditMode\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"height: 100px; width: 100%;\"\n (valueChange)=\"updatePayloadField('PayloadSelfWritePaths', $event)\">\n </mj-code-editor>\n </div>\n <div class=\"payload-path-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Paths this agent's prompts can write back to the payload\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Validation Section -->\n <div class=\"payload-section\">\n <h3 class=\"payload-section-title\">\n <i class=\"fa-solid fa-shield-check\"></i>\n Final Payload Validation\n </h3>\n <div class=\"payload-validation-container\">\n <div class=\"payload-validation-settings\">\n <div class=\"validation-field-group\">\n <label class=\"validation-field-label\">Validation Mode</label>\n <p class=\"validation-field-description\">How to handle validation failures</p>\n <mj-form-field\n FieldName=\"FinalPayloadValidationMode\"\n Type=\"dropdownlist\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\"\n style=\"width: 100%;\">\n </mj-form-field>\n </div>\n <div class=\"validation-field-group\">\n <label class=\"validation-field-label\">Max Retries</label>\n <p class=\"validation-field-description\">Maximum validation retry attempts</p>\n <mj-form-field\n FieldName=\"FinalPayloadValidationMaxRetries\"\n Type=\"numerictextbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\"\n style=\"width: 100%;\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"payload-validation-schema\">\n <label class=\"validation-schema-label\">\n <i class=\"fa-solid fa-code\"></i>\n Validation Schema\n </label>\n <p class=\"validation-schema-description\">\n JSON schema or validation rules for the final payload structure\n </p>\n <div class=\"validation-schema-editor\">\n <mj-code-editor\n [value]=\"record.FinalPayloadValidation || '{}'\"\n [readonly]=\"!EditMode\"\n language=\"json\"\n [lineWrapping]=\"true\"\n style=\"height: 200px; width: 100%;\"\n (valueChange)=\"updatePayloadField('FinalPayloadValidation', $event)\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Execution Guardrails (New Separate Panel) -->\n <mj-accordion-panel id=\"guardrails\"\n [Expanded]=\"GetSectionExpanded('guardrails', false)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-shield-halved\"></i> Execution Guardrails\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Set limits to prevent runaway agent executions and control resource usage.\n </div>\n </div>\n <div class=\"form-fields-grid\">\n <mj-form-field\n FieldName=\"MaxCostPerRun\"\n Type=\"numerictextbox\"\n Caption=\"Max Cost ($)\"\n Description=\"Maximum cost per run\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <mj-form-field\n FieldName=\"MaxTokensPerRun\"\n Type=\"numerictextbox\"\n Caption=\"Max Tokens\"\n Description=\"Maximum tokens per run\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <mj-form-field\n FieldName=\"MaxIterationsPerRun\"\n Type=\"numerictextbox\"\n Caption=\"Max Iterations\"\n Description=\"Maximum prompt iterations\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <mj-form-field\n FieldName=\"MaxTimePerRun\"\n Type=\"numerictextbox\"\n Caption=\"Max Time (seconds)\"\n Description=\"Maximum execution time\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Configuration (Settings Panel) -->\n <mj-accordion-panel id=\"config\"\n [Expanded]=\"GetSectionExpanded('config', false)\">\n <ng-template mjAccordionTitle>\n <i class=\"fa-solid fa-cogs\"></i> Configuration\n </ng-template>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Configure agent behavior, execution settings, and advanced features.\n </div>\n </div>\n <!-- Identity & Behavior Section -->\n <div class=\"config-section\">\n <h3 class=\"config-section-title\">\n <i class=\"fa-solid fa-id-card\"></i>\n Identity & Behavior\n </h3>\n <div class=\"config-grid\">\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-toggle-on\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Agent Status</h4>\n <p>Current availability and operational status</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n @if (EditMode) {\n <mj-dropdown\n [(ngModel)]=\"record.Status\"\n [Data]=\"statusOptions\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n name=\"agentStatus\"\n class=\"config-field-input\">\n </mj-dropdown>\n } @else {\n <span class=\"config-field-display\">{{ record.Status || 'Not Set' }}</span>\n }\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-sitemap\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Agent Type</h4>\n <p>Category and system-level behavior</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n @if (EditMode) {\n <mj-dropdown\n [(ngModel)]=\"record.TypeID\"\n [Data]=\"agentTypes\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n name=\"agentTypeID\"\n class=\"config-field-input\">\n </mj-dropdown>\n } @else {\n <span class=\"config-field-display\">{{ record.Type || 'Not Set' }}</span>\n }\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Category</h4>\n <p>Organizational category for this agent</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n @if (EditMode) {\n <mj-tree-dropdown\n [BranchConfig]=\"CategoryBranchConfig\"\n [Value]=\"SelectedCategoryKey\"\n SelectionMode=\"single\"\n SelectableTypes=\"branch\"\n Placeholder=\"Select a category...\"\n [Clearable]=\"true\"\n [EnableSearch]=\"true\"\n (ValueChange)=\"OnCategoryChange($event)\">\n </mj-tree-dropdown>\n } @else {\n <span class=\"config-field-display\">{{ record.Category || 'Not Set' }}</span>\n }\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-bolt\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Expose as Action</h4>\n <p>Make available as an action for other agents</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"ExposeAsAction\"\n Type=\"checkbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"config-card full-width\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-align-left\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Description</h4>\n <p>Detailed agent description and purpose</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"Description\"\n Type=\"textarea\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\"\n style=\"width: 100%;\">\n </mj-form-field>\n </div>\n </div>\n </div>\n </div>\n <!-- Execution Settings Section -->\n <div class=\"config-section\">\n <h3 class=\"config-section-title\">\n <i class=\"fa-solid fa-play\"></i>\n Execution Settings\n </h3>\n <div class=\"config-grid\">\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-layer-group\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Execution Mode</h4>\n <p>How sub-agents are executed</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"ExecutionMode\"\n Type=\"dropdownlist\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-sort-numeric-down\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Execution Order</h4>\n <p>Order when run with siblings</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"ExecutionOrder\"\n Type=\"numerictextbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-tachometer-alt\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Default Effort Level</h4>\n <p>Default effort level for all prompts (1-100)</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"DefaultPromptEffortLevel\"\n Type=\"numerictextbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <div class=\"config-card-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Higher values request more thorough reasoning (1=minimal, 100=maximum)\n </div>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-code\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Driver Class</h4>\n <p>Custom implementation class</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"DriverClass\"\n Type=\"textbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n </div>\n </div>\n <!-- Visual Identity Section -->\n <div class=\"config-section\">\n <h3 class=\"config-section-title\">\n <i class=\"fa-solid fa-palette\"></i>\n Visual Identity\n </h3>\n <div class=\"config-grid\">\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-icons\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Icon Class</h4>\n <p>Font Awesome icon class</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"IconClass\"\n Type=\"textbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <div class=\"config-card-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Example: <code>fa-solid fa-robot</code>\n </div>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-image\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Logo URL</h4>\n <p>URL for agent logo image</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"LogoURL\"\n Type=\"textbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n <div class=\"config-card-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Takes precedence over Icon Class\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Context Compression Section -->\n <div class=\"config-section\">\n <h3 class=\"config-section-title\">\n <i class=\"fa-solid fa-compress\"></i>\n Context Compression\n </h3>\n <div class=\"config-grid\">\n <div class=\"config-card full-width\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-toggle-on\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Enable Context Compression</h4>\n <p>Automatically compress conversation context when message threshold is reached</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"EnableContextCompression\"\n Type=\"checkbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\"\n (valueChange)=\"onContextCompressionToggle($event)\">\n </mj-form-field>\n </div>\n </div>\n @if (record.EnableContextCompression) {\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-hashtag\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Message Threshold</h4>\n <p>Messages before compression triggers</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"ContextCompressionMessageThreshold\"\n Type=\"numerictextbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-save\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Messages to Keep</h4>\n <p>Recent messages to retain uncompressed</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n <mj-form-field\n FieldName=\"ContextCompressionMessageRetentionCount\"\n Type=\"numerictextbox\"\n Caption=\"\"\n [EditMode]=\"EditMode\"\n [Record]=\"record\">\n </mj-form-field>\n </div>\n </div>\n <div class=\"config-card\">\n <div class=\"config-card-header\">\n <div class=\"config-card-icon\">\n <i class=\"fa-solid fa-comment-dots\"></i>\n </div>\n <div class=\"config-card-info\">\n <h4>Compression Prompt</h4>\n <p>Prompt used for summarization</p>\n </div>\n </div>\n <div class=\"config-card-content\">\n @if (EditMode) {\n <div class=\"prompt-selector-container\">\n <div class=\"prompt-display\">\n @if (selectedContextCompressionPrompt) {\n <span class=\"prompt-name\">{{ selectedContextCompressionPrompt.Name }}</span>\n } @else {\n <span class=\"no-prompt\">No prompt selected</span>\n }\n </div>\n <div class=\"prompt-actions\">\n <button type=\"button\"\n mjButton\n variant=\"outline\"\n size=\"sm\"\n (click)=\"openContextCompressionPromptSelector()\"\n class=\"prompt-select-btn\">\n <i class=\"fa-solid fa-search\"></i>\n {{ selectedContextCompressionPrompt ? 'Change' : 'Select' }} Prompt\n </button>\n @if (selectedContextCompressionPrompt) {\n <button type=\"button\"\n mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"clearContextCompressionPrompt()\"\n class=\"prompt-clear-btn\"\n title=\"Clear selection\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n </div>\n } @else {\n <span class=\"config-field-display\">{{ selectedContextCompressionPrompt?.Name || record.ContextCompressionPrompt || 'Not Set' }}</span>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </mj-accordion-panel>\n </div>\n }\n </form>\n</mj-record-form-container>\n}\n\n<!-- Permissions Dialog (from @memberjunction/ng-agents) -->\n@if (ShowPermissionsDialog) {\n <mj-agent-permissions-dialog\n [Agent]=\"record\"\n (Closed)=\"onPermissionsDialogClosed()\"\n (PermissionsChanged)=\"refreshRelatedData()\">\n </mj-agent-permissions-dialog>\n}", styles: ["/* AI Agent Form - Modern Redesign */\n.record-form-container {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n}\n\n.record-form {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n/* Agent Header Section - Compact Design */\n.agent-header {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);\n transition: padding 0.2s ease;\n}\n\n.agent-header-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n}\n\n/* Header collapse toggle button */\n.agent-header-toggle {\n background: none;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n padding: 0;\n transition: all 0.15s ease;\n}\n\n.agent-header-toggle:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-strong);\n}\n\n.agent-header-toggle i {\n font-size: 10px;\n}\n\n.agent-overview {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.agent-icon-wrapper {\n width: 36px;\n height: 36px;\n background: var(--mj-brand-primary);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n flex-shrink: 0;\n transition: all 0.2s ease;\n}\n\n.agent-icon-wrapper i {\n color: var(--mj-text-inverse);\n font-size: 18px;\n}\n\n/* \u2500\u2500 Minimized Floating Header Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.agent-header-mini {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 12px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n height: 32px;\n}\n\n.agent-header-mini-expand {\n background: none;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 0;\n flex-shrink: 0;\n transition: all 0.15s ease;\n}\n\n.agent-header-mini-expand:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-strong);\n}\n\n.agent-header-mini-expand i {\n font-size: 9px;\n}\n\n.agent-header-mini-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 300px;\n}\n\n.agent-header-mini-status {\n padding: 1px 7px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.agent-header-mini-spacer {\n flex: 1;\n}\n\n.agent-header-mini-btn {\n background: none;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 0;\n flex-shrink: 0;\n transition: all 0.15s ease;\n}\n\n.agent-header-mini-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-strong);\n}\n\n.agent-header-mini-btn:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.agent-header-mini-btn--primary {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.agent-header-mini-btn--primary:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.agent-header-mini-btn i {\n font-size: 11px;\n}\n\n.agent-icon-wrapper img.agent-logo {\n width: 100%;\n height: 100%;\n object-fit: cover;\n border-radius: 8px;\n}\n\n.agent-info {\n flex: 1;\n min-width: 0;\n}\n\n.agent-name {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n line-height: 1.2;\n}\n\n.agent-name-input {\n font-size: 16px !important;\n font-weight: 500 !important;\n height: 30px !important;\n width: 100% !important;\n max-width: 350px !important;\n}\n\n.agent-meta {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.status-badge.active {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n}\n\n.status-badge.pending {\n background: var(--mj-status-warning);\n color: var(--mj-text-primary);\n}\n\n.status-badge.disabled {\n background: var(--mj-text-muted);\n color: var(--mj-text-inverse);\n}\n\n.execution-mode,\n.parent-agent {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.execution-mode i,\n.parent-agent i {\n font-size: 12px;\n opacity: 0.8;\n}\n\n.parent-agent.clickable {\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.parent-agent.clickable:hover {\n background: var(--mj-border-default);\n color: var(--mj-brand-primary);\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n}\n\n.parent-agent.clickable:active {\n transform: translateY(0);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n/* Prompt Controls Section */\n.prompt-controls {\n flex: 1;\n margin-right: 16px;\n}\n\n.agent-meta-info {\n display: flex;\n gap: 24px;\n margin-top: 12px;\n flex-wrap: wrap;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.meta-label {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-value {\n font-size: 14px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.agent-description {\n margin-top: 16px;\n color: var(--mj-text-muted);\n line-height: 1.6;\n font-size: 15px;\n}\n\n.agent-description-input {\n width: 100%;\n max-width: 600px;\n min-height: 80px;\n resize: vertical;\n}\n\n/* Action Buttons Section */\n.agent-actions {\n display: flex;\n flex-direction: row;\n gap: 8px;\n flex-shrink: 0;\n align-items: center;\n}\n\n.action-buttons-row {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.action-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border-radius: 8px;\n font-weight: 500;\n font-size: 14px;\n transition: all 0.2s ease;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n.action-button:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);\n}\n\n.action-button.primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.action-button.primary:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.action-button.secondary {\n background: var(--mj-text-muted);\n color: var(--mj-text-inverse);\n}\n\n.action-button.secondary:hover {\n background: var(--mj-text-secondary);\n}\n\n.action-warnings {\n margin-top: 8px;\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* Panel-Based Form Content */\n.form-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n overflow-x: hidden;\n background: var(--mj-bg-page);\n padding: 8px 12px;\n}\n\n/* Panel Content */\n.panel-content {\n padding: 16px;\n background: var(--mj-bg-surface);\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.section-description {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.6;\n margin-bottom: 16px;\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-shrink: 0;\n}\n\n.tab-section {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n padding: 24px;\n margin-bottom: 24px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n border: 1px solid var(--mj-border-default);\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 2px solid var(--mj-bg-surface-sunken);\n}\n\n.section-title {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0;\n color: var(--mj-text-primary);\n font-size: 18px;\n font-weight: 600;\n}\n\n.section-title i {\n color: var(--mj-brand-primary);\n font-size: 20px;\n}\n\n.section-description {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.6;\n margin-top: 8px;\n}\n\n/* Form Fields Grid */\n.form-fields-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 20px;\n margin-top: 20px;\n}\n\n.form-field-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.form-field-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Sub-grids styling (legacy) */\n.sub-grid-container {\n height: 500px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n display: none; /* Hidden as we now use cards */\n}\n\n/* Empty States */\n/* Loading State */\n.loading-state {\n text-align: center;\n padding: 60px 20px;\n color: var(--mj-text-muted);\n}\n\n.loading-state i {\n font-size: 36px;\n color: var(--mj-brand-primary);\n margin-bottom: 16px;\n display: block;\n}\n\n.loading-state p {\n margin: 0;\n font-size: 14px;\n color: var(--mj-text-disabled);\n}\n\n/* Loading State */\n.loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 90%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.loading-spinner {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n}\n\n.spinner-icon {\n width: 48px;\n height: 48px;\n border: 4px solid var(--mj-bg-surface-sunken);\n border-top: 4px solid var(--mj-brand-primary);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n/* Quick Actions */\n.quick-actions {\n display: flex;\n gap: 16px;\n margin-top: 20px;\n padding-top: 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.quick-action-card {\n flex: 1;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n transition: all 0.2s ease;\n text-align: center;\n}\n\n.quick-action-card:hover {\n background: var(--mj-bg-surface);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-2px);\n}\n\n.quick-action-icon {\n font-size: 32px;\n color: var(--mj-brand-primary);\n margin-bottom: 8px;\n}\n\n.quick-action-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 4px;\n}\n\n.quick-action-description {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* Header Actions */\n.header-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n/* Entity List Interface */\n.entity-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin-top: 16px;\n}\n\n.entity-item {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.entity-item:hover {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n transform: translateY(-1px);\n}\n\n.item-icon {\n width: 40px;\n height: 40px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.prompt-item .item-icon {\n background: var(--mj-status-success);\n}\n\n.action-item .item-icon {\n background: var(--mj-status-warning);\n}\n\n.sub-agent-item .item-icon {\n background: var(--mj-brand-primary);\n}\n\n.model-item .item-icon {\n background: var(--mj-brand-primary);\n}\n\n.learning-item .item-icon {\n background: var(--mj-status-error);\n}\n\n.note-item .item-icon {\n background: var(--mj-status-warning);\n}\n\n.item-icon i {\n color: var(--mj-text-muted);\n font-size: 18px;\n}\n\n.prompt-item .item-icon i,\n.action-item .item-icon i,\n.sub-agent-item .item-icon i,\n.model-item .item-icon i,\n.learning-item .item-icon i,\n.note-item .item-icon i {\n color: var(--mj-text-inverse);\n}\n\n.item-icon img.sub-agent-logo {\n width: 100%;\n height: 100%;\n object-fit: cover;\n border-radius: 6px;\n}\n\n.item-content {\n flex: 1;\n min-width: 0;\n}\n\n.item-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n line-height: 1.3;\n}\n\n.item-preview {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.4;\n margin: 4px 0 8px 0;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.item-meta {\n display: flex;\n gap: 12px;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.meta-tag,\n.priority-tag,\n.status-tag {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n padding: 3px 8px;\n border-radius: 6px;\n font-weight: 500;\n}\n\n.meta-tag {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.priority-tag {\n color: var(--mj-text-inverse);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.status-tag {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.status-tag.active {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.status-tag.inactive {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.item-actions {\n opacity: 0;\n transition: opacity 0.2s ease;\n color: var(--mj-text-muted);\n font-size: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.entity-item:hover .item-actions {\n opacity: 1;\n}\n\n.entity-item:hover .item-actions > i {\n color: var(--mj-brand-primary);\n}\n\n.view-more-item {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 2px dashed var(--mj-border-default);\n border-radius: 10px;\n text-align: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.view-more-item:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* Pagination Controls */\n.pagination-controls {\n display: flex;\n gap: 12px;\n align-items: center;\n justify-content: center;\n padding: 16px;\n margin-top: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n}\n\n.page-nav-btn {\n min-width: 120px;\n font-weight: 500;\n}\n\n.page-nav-btn i {\n font-size: 12px;\n}\n\n.page-nav-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.page-info {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding: 0 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n min-width: 200px;\n text-align: center;\n}\n\n.page-info .record-count {\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: normal;\n}\n\n.page-info .fa-spinner {\n margin-right: 8px;\n color: var(--mj-brand-primary);\n}\n\n.view-all-btn {\n color: var(--mj-text-muted);\n white-space: nowrap;\n margin-left: auto;\n}\n\n.view-all-btn:hover {\n color: var(--mj-brand-primary);\n}\n\n.view-all-btn i {\n margin-right: 4px;\n}\n\n/* Payload Section Styles */\n.payload-config-section,\n.payload-paths-section,\n.payload-validation-section {\n margin-bottom: 32px;\n}\n\n.subsection-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 16px 0;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.subsection-title i {\n color: var(--mj-brand-primary);\n}\n\n.subsection-divider {\n margin-top: 32px;\n margin-bottom: 16px;\n padding-top: 24px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.payload-config-grid {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.payload-field-group {\n margin-bottom: 20px;\n}\n\n.payload-field-label {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.payload-field-label i {\n color: var(--mj-text-muted);\n font-size: 16px;\n}\n\n.field-description {\n font-size: 12px;\n font-weight: normal;\n color: var(--mj-text-muted);\n margin-left: auto;\n}\n\n/* Code editor styling */\n.payload-field-group mj-code-editor {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.payload-field-group mj-code-editor:hover {\n border-color: var(--mj-brand-primary);\n}\n\n/* Payload textarea styling */\n.payload-field-group mj-form-field ::ng-deep textarea {\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 13px;\n line-height: 1.5;\n min-height: 120px;\n resize: vertical;\n}\n\n/* Execution History Panel */\n.execution-history-panel {\n max-height: 500px;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* Timeline List for Execution History */\n.timeline-list {\n display: flex;\n flex-direction: column;\n gap: 16px;\n margin-top: 16px;\n}\n\n.timeline-item {\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.timeline-item:hover {\n background: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n}\n\n.timeline-marker {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.timeline-marker i {\n color: var(--mj-text-inverse);\n font-size: 14px;\n}\n\n.timeline-content {\n flex: 1;\n min-width: 0;\n}\n\n.timeline-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n}\n\n.timeline-date {\n font-size: 12px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 6px;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.timeline-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.timeline-preview {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Modern Card-Based Interface (Legacy - Keep for backward compatibility) */\n.cards-container {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n gap: 20px;\n margin-top: 16px;\n}\n\n.entity-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 20px;\n cursor: pointer;\n transition: all 0.3s ease;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n position: relative;\n overflow: hidden;\n}\n\n.entity-card:hover {\n transform: translateY(-4px);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: var(--mj-brand-primary);\n opacity: 0;\n transition: opacity 0.3s ease;\n}\n\n.entity-card:hover::before {\n opacity: 1;\n}\n\n.card-header {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n margin-bottom: 12px;\n}\n\n.card-icon {\n width: 40px;\n height: 40px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sub-agent-card .card-icon {\n background: var(--mj-brand-primary);\n}\n\n.prompt-card .card-icon {\n background: var(--mj-status-success);\n}\n\n.action-card .card-icon {\n background: var(--mj-status-warning);\n}\n\n.card-icon i {\n font-size: 18px;\n color: var(--mj-text-muted);\n}\n\n.sub-agent-card .card-icon i,\n.prompt-card .card-icon i,\n.action-card .card-icon i {\n color: var(--mj-text-inverse);\n}\n\n.card-title-section {\n flex: 1;\n min-width: 0;\n}\n\n.card-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n line-height: 1.3;\n word-wrap: break-word;\n}\n\n.card-description {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.5;\n margin: 8px 0;\n display: -webkit-box;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.card-meta {\n display: flex;\n gap: 16px;\n margin-top: 12px;\n flex-wrap: wrap;\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n padding: 4px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n}\n\n.meta-item i {\n font-size: 11px;\n opacity: 0.8;\n}\n\n.meta-item.active {\n color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.meta-item.inactive {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n}\n\n.card-actions {\n opacity: 0;\n transition: opacity 0.3s ease;\n color: var(--mj-text-muted);\n}\n\n.entity-card:hover .card-actions {\n opacity: 1;\n color: var(--mj-brand-primary);\n}\n\n/* Badge Styles */\n.priority-badge {\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.type-badge {\n padding: 2px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* View All Card */\n.view-all-card {\n background: var(--mj-bg-surface-card);\n border: 2px dashed var(--mj-border-default);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 120px;\n cursor: pointer;\n transition: all 0.3s ease;\n}\n\n.view-all-card:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n transform: translateY(-2px);\n}\n\n.view-all-content {\n text-align: center;\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.view-all-content i {\n font-size: 24px;\n margin-bottom: 8px;\n display: block;\n}\n\n/* Timeline Interface for History */\n.timeline-container {\n position: relative;\n margin-top: 16px;\n}\n\n.timeline-item {\n display: flex;\n flex-direction: column;\n margin-bottom: 24px;\n transition: all 0.3s ease;\n border-radius: 12px;\n padding: 16px;\n background: transparent;\n border: 1px solid transparent;\n}\n\n.timeline-item:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n}\n\n.timeline-item.expanded {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.timeline-item.view-all {\n cursor: pointer;\n background: var(--mj-bg-surface-card);\n border: 2px dashed var(--mj-border-default);\n}\n\n.timeline-item.view-all:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n}\n\n.timeline-item > div:first-child {\n display: flex;\n align-items: flex-start;\n}\n\n.timeline-marker {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-right: 16px;\n flex-shrink: 0;\n position: relative;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.timeline-marker::after {\n content: '';\n position: absolute;\n top: 50px;\n left: 50%;\n transform: translateX(-50%);\n width: 2px;\n height: 24px;\n background: var(--mj-border-default);\n}\n\n.timeline-item:last-child .timeline-marker::after {\n display: none;\n}\n\n.timeline-marker i {\n color: var(--mj-text-inverse);\n font-size: 16px;\n}\n\n.timeline-marker.view-all-marker {\n background: var(--mj-text-muted);\n}\n\n.timeline-content {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: flex-start;\n}\n\n.timeline-header {\n flex: 1;\n cursor: pointer;\n}\n\n.timeline-header > div:first-child {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 8px;\n gap: 16px;\n}\n\n.expand-icon {\n transition: transform 0.3s ease;\n margin-right: 8px;\n color: var(--mj-text-muted);\n}\n\n.expand-icon.expanded {\n transform: rotate(90deg);\n}\n\n.timeline-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n line-height: 1.3;\n}\n\n.timeline-date {\n font-size: 12px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n background: var(--mj-bg-surface-card);\n padding: 4px 8px;\n border-radius: 6px;\n margin-left: auto;\n}\n\n.timeline-preview {\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n margin-top: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.timeline-status {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.execution-time {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n padding: 4px 8px;\n border-radius: 6px;\n}\n\n.timeline-description {\n color: var(--mj-text-muted);\n font-size: 14px;\n line-height: 1.5;\n margin: 8px 0;\n}\n\n.timeline-error {\n color: var(--mj-status-error);\n font-size: 13px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n padding: 8px 12px;\n border-radius: 6px;\n margin-top: 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.timeline-error i {\n flex-shrink: 0;\n}\n\n/* Expanded Content Styles */\n.timeline-expanded-content {\n margin-top: 20px;\n padding-top: 20px;\n border-top: 1px solid var(--mj-border-default);\n animation: fadeIn 0.3s ease;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.result-section,\n.error-section {\n margin-bottom: 20px;\n}\n\n.result-section h5,\n.error-section h5 {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-section h5 {\n color: var(--mj-status-error);\n}\n\n.result-content,\n.error-content {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 12px 16px;\n font-size: 14px;\n line-height: 1.6;\n color: var(--mj-text-secondary);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 200px;\n overflow-y: auto;\n}\n\n/* Code editor styling within result section */\n.result-section mj-code-editor {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.error-content {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.execution-details {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.detail-row {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n\n.detail-label {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n min-width: 80px;\n}\n\n.detail-value {\n font-size: 14px;\n color: var(--mj-text-secondary);\n word-break: break-all;\n}\n\n.timeline-actions {\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n}\n\n.btn-primary {\n padding: 8px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 8px;\n transition: all 0.2s ease;\n}\n\n.btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-1px);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.btn-primary i {\n font-size: 12px;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n /* Header Responsiveness */\n .agent-header {\n padding: 16px;\n }\n\n .agent-header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .agent-overview {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .agent-meta {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .agent-actions {\n width: 100%;\n align-self: stretch;\n }\n\n .action-button {\n flex: 1;\n justify-content: center;\n }\n\n /* Panel Responsiveness */\n .form-content {\n padding: 12px;\n }\n\n ::ng-deep .k-panelbar > .k-panelbar-item > .k-header {\n padding: 16px 20px;\n font-size: 15px;\n }\n\n .panel-content {\n padding: 20px 16px;\n }\n\n .section-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .header-actions {\n flex-wrap: wrap;\n align-self: stretch;\n }\n\n /* Entity List Responsiveness */\n .entity-item {\n padding: 12px;\n gap: 12px;\n }\n\n .item-icon {\n width: 36px;\n height: 36px;\n }\n\n .item-icon i {\n font-size: 16px;\n }\n\n .item-title {\n font-size: 15px;\n }\n\n .item-preview {\n font-size: 13px;\n }\n\n .item-meta {\n gap: 8px;\n }\n\n /* Timeline Responsiveness */\n .timeline-item {\n padding: 12px;\n gap: 12px;\n }\n\n .timeline-marker {\n width: 28px;\n height: 28px;\n }\n\n .timeline-marker i {\n font-size: 12px;\n }\n\n .timeline-title {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .timeline-date {\n align-self: flex-start;\n }\n\n /* Form Field Responsiveness */\n .form-fields-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n /* Legacy card support */\n .cards-container {\n grid-template-columns: 1fr;\n }\n}\n\n/* Execution History Panel - Max Height and Scroll */\n.execution-history-panel {\n max-height: 500px;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* Custom scrollbar for execution history */\n.execution-history-panel::-webkit-scrollbar {\n width: 8px;\n}\n\n.execution-history-panel::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.execution-history-panel::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n.execution-history-panel::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n/* Execution History Search Bar */\n.execution-search-bar {\n margin-bottom: 16px;\n padding: 0 4px;\n}\n\n.execution-search-bar .fa-search {\n color: var(--mj-text-secondary);\n margin-right: 8px;\n font-size: 14px;\n}\n\n/* New Execution History Card Design */\n.execution-history-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin-top: 8px;\n}\n\n.execution-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n transition: all 0.2s ease;\n cursor: pointer;\n}\n\n.execution-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n transform: translateY(-1px);\n}\n\n.execution-card.expanded {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 6px 20px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.execution-header {\n padding: 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.execution-left-section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.execution-status {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.status-indicator {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.status-indicator i {\n color: var(--mj-text-inverse);\n font-size: 14px;\n}\n\n.execution-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.execution-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.execution-date {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.execution-metrics {\n display: flex;\n align-items: flex-start;\n gap: 16px;\n flex-wrap: wrap;\n margin-left: 44px; /* Align with execution title text, accounting for status indicator + gap */\n}\n\n.metric-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n background: var(--mj-bg-surface-card);\n padding: 6px 10px;\n border-radius: 6px;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}\n\n.metric-item i {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.metric-label {\n font-weight: 500;\n}\n\n.metric-value {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.execution-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.action-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--mj-text-muted);\n}\n\n.action-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n transform: translateY(-1px);\n}\n\n.action-btn i {\n font-size: 12px;\n}\n\n.expand-icon {\n transition: transform 0.2s ease;\n color: var(--mj-text-muted);\n margin-right: 4px;\n}\n\n.expand-icon.expanded {\n transform: rotate(90deg);\n}\n\n/* Execution Expanded Content */\n.execution-expanded-content {\n padding: 16px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n background: var(--mj-bg-surface-card);\n animation: slideDown 0.2s ease;\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n padding-top: 0;\n padding-bottom: 0;\n }\n to {\n opacity: 1;\n max-height: 500px;\n padding-top: 16px;\n padding-bottom: 16px;\n }\n}\n\n.detailed-metrics {\n margin-bottom: 20px;\n}\n\n.metrics-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 12px;\n}\n\n.metric-detail {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.metric-detail i {\n color: var(--mj-brand-primary);\n font-size: 16px;\n width: 20px;\n text-align: center;\n}\n\n.metric-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n}\n\n.metric-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.metric-data {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.result-section {\n margin-top: 16px;\n}\n\n.result-section h5 {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-section h5 {\n color: var(--mj-status-error);\n}\n\n.error-content {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n border-radius: 8px;\n padding: 12px 16px;\n font-size: 14px;\n line-height: 1.6;\n color: var(--mj-status-error);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 150px;\n overflow-y: auto;\n}\n\n/* Responsive adjustments for execution history */\n@media (max-width: 768px) {\n .execution-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .execution-left-section {\n width: 100%;\n }\n\n .execution-metrics {\n margin-left: 0; /* Remove left margin on mobile */\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n width: 100%;\n }\n\n .metric-item {\n font-size: 11px;\n padding: 4px 8px;\n }\n\n .metrics-grid {\n grid-template-columns: 1fr;\n }\n}\n\n/* === PAYLOAD MANAGEMENT SECTION === */\n.payload-section {\n margin-bottom: 2rem;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n}\n\n.payload-section-title {\n margin: 0;\n padding: 1rem 1.5rem;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n font-size: 1.1rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.payload-section-title i {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n}\n\n/* Payload Scope Styling */\n.payload-field-container {\n padding: 1.5rem;\n display: grid;\n grid-template-columns: 1fr 2fr;\n gap: 2rem;\n align-items: start;\n}\n\n.payload-field-info {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.payload-field-label {\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 0.95rem;\n}\n\n.payload-field-description {\n color: var(--mj-text-muted);\n font-size: 0.9rem;\n line-height: 1.5;\n margin: 0;\n}\n\n.payload-field-input {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.payload-field-example {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n padding: 0.5rem 0.75rem;\n border-radius: 6px;\n border: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.payload-field-example i {\n color: var(--mj-status-warning);\n font-size: 0.9rem;\n}\n\n.payload-field-example code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.2rem 0.4rem;\n border-radius: 4px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n}\n\n/* Path Configuration Grid */\n.payload-paths-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));\n gap: 1.5rem;\n padding: 1.5rem;\n}\n\n.payload-path-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.2s ease;\n}\n\n.payload-path-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.payload-path-header {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.payload-path-icon {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.payload-path-icon.downstream {\n background: var(--mj-status-success);\n}\n\n.payload-path-icon.upstream {\n background: var(--mj-brand-primary);\n}\n\n.payload-path-icon.self-read {\n background: var(--mj-brand-primary);\n}\n\n.payload-path-icon.self-write {\n background: var(--mj-status-warning);\n}\n\n.payload-path-icon i {\n color: var(--mj-text-inverse);\n font-size: 1.2rem;\n}\n\n.payload-path-info h4 {\n margin: 0 0 0.25rem 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.payload-path-info p {\n margin: 0;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.payload-path-content {\n padding: 1rem;\n}\n\n.json-editor-container {\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n margin-bottom: 0.75rem;\n}\n\n.json-editor-container:hover {\n border-color: var(--mj-brand-primary);\n}\n\n.payload-path-hint {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.payload-path-hint i {\n color: var(--mj-brand-primary);\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.payload-path-hint code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 3px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n/* Payload Validation Container */\n.payload-validation-container {\n padding: 1.5rem;\n display: grid;\n grid-template-columns: 1fr 2fr;\n gap: 2rem;\n align-items: start;\n}\n\n.payload-validation-settings {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n}\n\n.validation-field-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.validation-field-label {\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 0.95rem;\n}\n\n.validation-field-description {\n color: var(--mj-text-muted);\n font-size: 0.9rem;\n line-height: 1.4;\n margin: 0 0 0.5rem 0;\n}\n\n.payload-validation-schema {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.validation-schema-label {\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 0.95rem;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.validation-schema-label i {\n color: var(--mj-brand-primary);\n}\n\n.validation-schema-description {\n color: var(--mj-text-muted);\n font-size: 0.9rem;\n line-height: 1.4;\n margin: 0;\n}\n\n.validation-schema-editor {\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.validation-schema-editor:hover {\n border-color: var(--mj-brand-primary);\n}\n\n/* === CONFIGURATION SECTION === */\n.config-section {\n margin-bottom: 2rem;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n}\n\n.config-section-title {\n margin: 0;\n padding: 1rem 1.5rem;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n font-size: 1.1rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.config-section-title i {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));\n gap: 1.5rem;\n padding: 1.5rem;\n width: 100%;\n}\n\n.config-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.2s ease;\n}\n\n.config-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-card.full-width {\n grid-column: 1 / -1;\n}\n\n.config-card-header {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.config-card-icon {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.config-card-icon i {\n color: var(--mj-text-inverse);\n font-size: 1.2rem;\n}\n\n.config-card-info h4 {\n margin: 0 0 0.25rem 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.config-card-info p {\n margin: 0;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.config-card-content {\n padding: 1rem;\n}\n\n/* Custom field styling for config cards */\n.config-field-input {\n width: 100%;\n min-width: 250px;\n}\n\n.config-card-content ::ng-deep mj-form-field {\n width: 100% !important;\n}\n\n.config-field-display {\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n padding: 8px 0;\n display: block;\n min-height: 20px;\n}\n\n/* Prompt selector styling */\n.prompt-selector-container {\n display: flex;\n align-items: center;\n gap: 12px;\n width: 100%;\n}\n\n.prompt-display {\n flex: 1;\n min-width: 0;\n padding: 8px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n}\n\n.prompt-name {\n color: var(--mj-text-secondary);\n font-weight: 500;\n font-size: 14px;\n}\n\n.no-prompt {\n color: var(--mj-text-muted);\n font-style: italic;\n font-size: 14px;\n}\n\n.prompt-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.prompt-select-btn {\n white-space: nowrap;\n}\n\n.prompt-clear-btn {\n min-width: 32px;\n}\n\n.config-card-hint {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n margin-top: 0.5rem;\n}\n\n.config-card-hint i {\n color: var(--mj-brand-primary);\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.config-card-hint code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 3px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n\n/* === RESPONSIVE DESIGN === */\n@media (max-width: 768px) {\n .payload-field-container,\n .payload-validation-container {\n grid-template-columns: 1fr;\n gap: 1rem;\n }\n\n .payload-paths-grid {\n grid-template-columns: 1fr;\n gap: 1rem;\n padding: 1rem;\n }\n\n .config-grid {\n grid-template-columns: 1fr;\n gap: 1rem;\n padding: 1rem;\n }\n\n .payload-section-title,\n .config-section-title {\n padding: 0.75rem 1rem;\n font-size: 1rem;\n }\n\n .payload-path-header,\n .config-card-header {\n padding: 0.75rem;\n }\n\n .payload-path-content,\n .config-card-content {\n padding: 0.75rem;\n }\n\n .payload-field-container,\n .payload-validation-container {\n padding: 1rem;\n }\n}\n\n/* ===================================\n Unified Sub-Agents with Filtering\n =================================== */\n\n/* Filter Controls */\n.sub-agent-filter-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.filter-controls {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n/* Sub-Agent Type Badge */\n.sub-agent-type-badge {\n position: absolute;\n top: 8px;\n right: 8px;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n display: flex;\n align-items: center;\n gap: 4px;\n z-index: 1;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n}\n\n/* Sub-Agent Item Styling */\n.sub-agent-item {\n position: relative;\n padding-left: 8px;\n transition: all 0.2s ease;\n}\n\n.sub-agent-item.child-sub-agent {\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.sub-agent-item.related-sub-agent {\n border-left: 4px solid var(--mj-brand-primary);\n}\n\n.sub-agent-item:hover {\n transform: translateX(4px);\n}\n\n/* Payload Info Tag */\n.payload-info {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n font-family: 'Roboto Mono', monospace;\n font-size: 11px;\n}\n\n/* Empty State Info Cards */\n.empty-state-info {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 16px;\n margin: 24px 0;\n max-width: 600px;\n margin-left: auto;\n margin-right: auto;\n}\n\n.info-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 16px;\n text-align: left;\n}\n\n.info-card i {\n font-size: 24px;\n margin-bottom: 8px;\n display: block;\n}\n\n.info-card strong {\n display: block;\n margin-bottom: 4px;\n font-size: 14px;\n}\n\n.info-card p {\n margin: 0;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n/* Responsive adjustments for sub-agent filters */\n@media (max-width: 768px) {\n .sub-agent-filter-header {\n flex-direction: column;\n align-items: stretch;\n }\n\n .filter-controls,\n .header-actions {\n width: 100%;\n justify-content: center;\n }\n\n .empty-state-info {\n grid-template-columns: 1fr;\n }\n}\n\n/* ===== Search Scope Access (mockup #5) ===== */\n.agent-search-access {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 12px;\n margin: 8px 0 20px;\n}\n\n.agent-search-access-option {\n display: grid;\n grid-template-columns: 24px 28px 1fr;\n align-items: start;\n gap: 10px;\n padding: 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease;\n}\n\n.agent-search-access-option:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n}\n\n.agent-search-access-option.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.agent-search-access-option input[type=\"radio\"] {\n accent-color: var(--mj-brand-primary);\n margin-top: 2px;\n}\n\n.agent-search-access-option > i {\n font-size: 20px;\n color: var(--mj-brand-primary);\n text-align: center;\n margin-top: 2px;\n}\n\n.agent-search-access-text {\n min-width: 0;\n}\n\n.agent-search-access-title {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.agent-search-access-desc {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n line-height: 1.3;\n}\n\n.agent-search-grid-header {\n margin: 8px 0 12px;\n}\n\n.agent-search-grid-header h4 {\n margin: 0 0 4px;\n color: var(--mj-text-primary);\n font-size: 1rem;\n font-weight: 600;\n}\n\n@media (max-width: 768px) {\n .agent-search-access {\n grid-template-columns: 1fr;\n }\n}\n\n/* \u2500\u2500 Execution History: Runs | Sessions segmented toggle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.history-view-toggle {\n display: inline-flex;\n gap: 2px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 3px;\n margin-bottom: 14px;\n}\n\n.history-toggle-option {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n padding: 6px 16px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.history-toggle-option:hover {\n color: var(--mj-text-secondary);\n}\n\n.history-toggle-option.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.history-toggle-count {\n font-size: 11px;\n font-weight: 600;\n padding: 1px 7px;\n border-radius: 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-secondary);\n}\n\n.history-toggle-option.active .history-toggle-count {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary);\n}\n\n/* \u2500\u2500 Voice session rows in Execution History \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.session-card {\n cursor: pointer;\n}\n\n.session-role-chip {\n display: inline-flex;\n align-items: center;\n margin-left: 8px;\n padding: 1px 8px;\n border-radius: 10px;\n font-size: 10.5px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 22%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.session-role-chip--target {\n background: color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-info) 22%, transparent);\n color: var(--mj-status-info);\n}\n\n.session-status-pill {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n.session-status-pill[data-status=\"Active\"] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 25%, transparent);\n}\n\n.session-status-pill[data-status=\"Idle\"] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n border-color: color-mix(in srgb, var(--mj-status-warning) 25%, transparent);\n}\n\n/* \u2500\u2500 Form tabs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Panes are hidden with `display: none`, never removed from the DOM. The\n designer pane holds UNSAVED canvas edits; @if-ing it away on a tab switch\n would discard them silently, and would also throw away the canvas's zoom and\n node positions on every trip to Details. */\n\n.agent-tabbar {\n flex: 0 0 auto;\n padding: 8px 12px 0;\n background: var(--mj-bg-page);\n}\n\n.agent-pane {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.agent-pane--hidden {\n display: none;\n}\n\n.agent-pane--designer {\n overflow: hidden;\n padding: 8px 12px 12px;\n background: var(--mj-bg-page);\n}\n\n/* The designer's dynamically-created section has no height of its own, so without\n this the flow canvas collapses to zero and renders as an empty strip. */\n.agent-pane--designer > ng-component,\n.agent-pane--designer > * {\n flex: 1;\n min-height: 0;\n}\n\n.agent-pane--invocations {\n overflow-y: auto;\n overflow-x: hidden;\n background: var(--mj-bg-page);\n}\n\n/* Initial load: the form's header renders as soon as the record arrives, but the tab strip and\n every pane wait on the agent TYPE. This fills that window so the page reads as loading rather\n than as broken. */\n.agent-form-loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 240px;\n padding: 32px;\n background: var(--mj-bg-page);\n}\n"] }]
5790
5810
  }], null, { CustomSectionContainer: [{
5791
5811
  type: ViewChild,
5792
5812
  args: ['customSectionContainer', { read: ViewContainerRef }]