@memberjunction/ng-core-entity-forms 2.95.0 → 2.97.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,9 @@ import { MJNotificationService } from '@memberjunction/ng-notifications';
12
12
  import { AIAgentFormComponent } from '../../generated/Entities/AIAgent/aiagent.form.component';
13
13
  import { firstValueFrom, Subject } from 'rxjs';
14
14
  import { takeUntil } from 'rxjs/operators';
15
+ import { AIEngineBase } from '@memberjunction/ai-engine-base';
16
+ import { ActionEngineBase } from '@memberjunction/actions-base';
17
+ import { PromptSelectorDialogComponent } from './prompt-selector-dialog.component';
15
18
  import * as i0 from "@angular/core";
16
19
  import * as i1 from "@memberjunction/ng-shared";
17
20
  import * as i2 from "@angular/router";
@@ -130,19 +133,28 @@ function AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_1_Condit
130
133
  i0.ɵɵelement(1, "i", 42);
131
134
  i0.ɵɵelementEnd();
132
135
  } }
136
+ function AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_1_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
137
+ i0.ɵɵtext(0);
138
+ } if (rf & 2) {
139
+ const ctx_r1 = i0.ɵɵnextContext(5);
140
+ i0.ɵɵtextInterpolate1(" of ", ctx_r1.totalExecutionHistoryCount, " ");
141
+ } }
133
142
  function AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
134
143
  i0.ɵɵelementStart(0, "span");
135
144
  i0.ɵɵtext(1);
145
+ i0.ɵɵtemplate(2, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_1_Conditional_3_Conditional_2_Template, 1, 1);
136
146
  i0.ɵɵelementEnd();
137
147
  } if (rf & 2) {
138
148
  const ctx_r1 = i0.ɵɵnextContext(4);
139
149
  i0.ɵɵadvance();
140
150
  i0.ɵɵtextInterpolate1(" (", ctx_r1.executionHistoryCount, ")");
151
+ i0.ɵɵadvance();
152
+ i0.ɵɵconditional(ctx_r1.executionHistoryCount < ctx_r1.totalExecutionHistoryCount ? 2 : -1);
141
153
  } }
142
154
  function AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_1_Template(rf, ctx) { if (rf & 1) {
143
155
  i0.ɵɵelement(0, "i", 40);
144
156
  i0.ɵɵtext(1, " Execution History ");
145
- i0.ɵɵtemplate(2, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_1_Conditional_2_Template, 2, 0, "span", 41)(3, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_1_Conditional_3_Template, 2, 1, "span");
157
+ i0.ɵɵtemplate(2, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_1_Conditional_2_Template, 2, 0, "span", 41)(3, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_1_Conditional_3_Template, 3, 2, "span");
146
158
  } if (rf & 2) {
147
159
  const ctx_r1 = i0.ɵɵnextContext(3);
148
160
  i0.ɵɵadvance(2);
@@ -192,15 +204,7 @@ function AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Condit
192
204
  i0.ɵɵelement(1, "i", 67);
193
205
  i0.ɵɵelementStart(2, "span", 64);
194
206
  i0.ɵɵtext(3, "Running:");
195
- i0.ɵɵelementEnd();
196
- i0.ɵɵelementStart(4, "span", 65);
197
- i0.ɵɵtext(5);
198
207
  i0.ɵɵelementEnd()();
199
- } if (rf & 2) {
200
- const execution_r7 = i0.ɵɵnextContext().$implicit;
201
- const ctx_r1 = i0.ɵɵnextContext(5);
202
- i0.ɵɵadvance(5);
203
- i0.ɵɵtextInterpolate(ctx_r1.getRunningTime(execution_r7.StartedAt));
204
208
  } }
205
209
  function AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
206
210
  i0.ɵɵelementStart(0, "div", 58);
@@ -398,7 +402,7 @@ function AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Condit
398
402
  i0.ɵɵpipe(12, "date");
399
403
  i0.ɵɵelementEnd()()();
400
404
  i0.ɵɵelementStart(13, "div", 57);
401
- i0.ɵɵtemplate(14, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Conditional_14_Template, 6, 1, "div", 58)(15, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Conditional_15_Template, 6, 1, "div", 58)(16, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Conditional_16_Template, 6, 1, "div", 58)(17, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Conditional_17_Template, 6, 1, "div", 58)(18, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Conditional_18_Template, 6, 1, "div", 58);
405
+ i0.ɵɵtemplate(14, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Conditional_14_Template, 6, 1, "div", 58)(15, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Conditional_15_Template, 6, 1, "div", 58)(16, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Conditional_16_Template, 4, 0, "div", 58)(17, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Conditional_17_Template, 6, 1, "div", 58)(18, AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Conditional_18_Template, 6, 1, "div", 58);
402
406
  i0.ɵɵelementEnd()();
403
407
  i0.ɵɵelementStart(19, "div", 59)(20, "button", 60);
404
408
  i0.ɵɵlistener("click", function AIAgentFormComponentExtended_form_3_Conditional_23_ng_template_2_Conditional_2_For_2_Template_button_click_20_listener($event) { const execution_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); ctx_r1.openExecutionRecord(execution_r7.ID); return i0.ɵɵresetView($event.stopPropagation()); });
@@ -1049,13 +1053,21 @@ function AIAgentFormComponentExtended_form_3_Conditional_26_Template(rf, ctx) {
1049
1053
  const ctx_r1 = i0.ɵɵnextContext(2);
1050
1054
  i0.ɵɵproperty("expanded", false)("disabled", ctx_r1.loadingStates.prompts);
1051
1055
  } }
1056
+ function AIAgentFormComponentExtended_form_3_Conditional_27_ng_template_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1057
+ i0.ɵɵelementStart(0, "span", 41);
1058
+ i0.ɵɵelement(1, "i", 42);
1059
+ i0.ɵɵelementEnd();
1060
+ } }
1052
1061
  function AIAgentFormComponentExtended_form_3_Conditional_27_ng_template_1_Template(rf, ctx) { if (rf & 1) {
1053
1062
  i0.ɵɵelement(0, "i", 136);
1054
1063
  i0.ɵɵtext(1);
1064
+ i0.ɵɵtemplate(2, AIAgentFormComponentExtended_form_3_Conditional_27_ng_template_1_Conditional_2_Template, 2, 0, "span", 41);
1055
1065
  } if (rf & 2) {
1056
1066
  const ctx_r1 = i0.ɵɵnextContext(3);
1057
1067
  i0.ɵɵadvance();
1058
1068
  i0.ɵɵtextInterpolate1(" Learning Cycles", ctx_r1.learningCycleCount > 0 ? " (" + ctx_r1.learningCycleCount + ")" : "", " ");
1069
+ i0.ɵɵadvance();
1070
+ i0.ɵɵconditional(ctx_r1.loadingStates.learningCycles ? 2 : -1);
1059
1071
  } }
1060
1072
  function AIAgentFormComponentExtended_form_3_Conditional_27_ng_template_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1061
1073
  i0.ɵɵelementStart(0, "div", 44);
@@ -1149,19 +1161,27 @@ function AIAgentFormComponentExtended_form_3_Conditional_27_ng_template_2_Templa
1149
1161
  } }
1150
1162
  function AIAgentFormComponentExtended_form_3_Conditional_27_Template(rf, ctx) { if (rf & 1) {
1151
1163
  i0.ɵɵelementStart(0, "kendo-panelbar-item", 28);
1152
- i0.ɵɵtemplate(1, AIAgentFormComponentExtended_form_3_Conditional_27_ng_template_1_Template, 2, 1, "ng-template", 29)(2, AIAgentFormComponentExtended_form_3_Conditional_27_ng_template_2_Template, 6, 1, "ng-template", 30);
1164
+ i0.ɵɵtemplate(1, AIAgentFormComponentExtended_form_3_Conditional_27_ng_template_1_Template, 3, 2, "ng-template", 29)(2, AIAgentFormComponentExtended_form_3_Conditional_27_ng_template_2_Template, 6, 1, "ng-template", 30);
1153
1165
  i0.ɵɵelementEnd();
1154
1166
  } if (rf & 2) {
1155
1167
  const ctx_r1 = i0.ɵɵnextContext(2);
1156
1168
  i0.ɵɵproperty("expanded", false)("disabled", ctx_r1.loadingStates.learningCycles);
1157
1169
  } }
1170
+ function AIAgentFormComponentExtended_form_3_Conditional_28_ng_template_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1171
+ i0.ɵɵelementStart(0, "span", 41);
1172
+ i0.ɵɵelement(1, "i", 42);
1173
+ i0.ɵɵelementEnd();
1174
+ } }
1158
1175
  function AIAgentFormComponentExtended_form_3_Conditional_28_ng_template_1_Template(rf, ctx) { if (rf & 1) {
1159
1176
  i0.ɵɵelement(0, "i", 140);
1160
1177
  i0.ɵɵtext(1);
1178
+ i0.ɵɵtemplate(2, AIAgentFormComponentExtended_form_3_Conditional_28_ng_template_1_Conditional_2_Template, 2, 0, "span", 41);
1161
1179
  } if (rf & 2) {
1162
1180
  const ctx_r1 = i0.ɵɵnextContext(3);
1163
1181
  i0.ɵɵadvance();
1164
1182
  i0.ɵɵtextInterpolate1(" Notes", ctx_r1.noteCount > 0 ? " (" + ctx_r1.noteCount + ")" : "", " ");
1183
+ i0.ɵɵadvance();
1184
+ i0.ɵɵconditional(ctx_r1.loadingStates.notes ? 2 : -1);
1165
1185
  } }
1166
1186
  function AIAgentFormComponentExtended_form_3_Conditional_28_ng_template_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1167
1187
  const _r33 = i0.ɵɵgetCurrentView();
@@ -1283,7 +1303,7 @@ function AIAgentFormComponentExtended_form_3_Conditional_28_ng_template_2_Templa
1283
1303
  } }
1284
1304
  function AIAgentFormComponentExtended_form_3_Conditional_28_Template(rf, ctx) { if (rf & 1) {
1285
1305
  i0.ɵɵelementStart(0, "kendo-panelbar-item", 28);
1286
- i0.ɵɵtemplate(1, AIAgentFormComponentExtended_form_3_Conditional_28_ng_template_1_Template, 2, 1, "ng-template", 29)(2, AIAgentFormComponentExtended_form_3_Conditional_28_ng_template_2_Template, 8, 2, "ng-template", 30);
1306
+ i0.ɵɵtemplate(1, AIAgentFormComponentExtended_form_3_Conditional_28_ng_template_1_Template, 3, 2, "ng-template", 29)(2, AIAgentFormComponentExtended_form_3_Conditional_28_ng_template_2_Template, 8, 2, "ng-template", 30);
1287
1307
  i0.ɵɵelementEnd();
1288
1308
  } if (rf & 2) {
1289
1309
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -1934,31 +1954,37 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
1934
1954
  this.customSectionComponent.EditMode = this.EditMode;
1935
1955
  }
1936
1956
  }
1957
+ // === Related Entity Counts ===
1958
+ /** Number of sub-agents under this agent */
1959
+ get subAgentCount() {
1960
+ return this.subAgents.length;
1961
+ }
1962
+ /** Number of prompts associated with this agent */
1963
+ get promptCount() {
1964
+ return this.agentPrompts.length;
1965
+ }
1966
+ /** Number of actions configured for this agent */
1967
+ get actionCount() {
1968
+ return this.agentActions.length;
1969
+ }
1970
+ /** Number of learning cycles for this agent */
1971
+ get learningCycleCount() {
1972
+ return this.learningCycles.length;
1973
+ }
1974
+ /** Number of notes associated with this agent */
1975
+ get noteCount() {
1976
+ return this.agentNotes.length;
1977
+ }
1978
+ /** Number of execution history records */
1979
+ get executionHistoryCount() {
1980
+ return this.recentExecutions.length;
1981
+ }
1937
1982
  /**
1938
1983
  * Loads agent types from the database for the dropdown
1939
1984
  * @private
1940
1985
  */
1941
1986
  async loadAgentTypes() {
1942
- try {
1943
- const rv = new RunView();
1944
- const result = await rv.RunView({
1945
- EntityName: 'MJ: AI Agent Types',
1946
- ExtraFilter: '',
1947
- OrderBy: 'Name ASC',
1948
- ResultType: 'entity_object'
1949
- });
1950
- if (result.Success) {
1951
- this.agentTypes = result.Results || [];
1952
- }
1953
- else {
1954
- console.error('Failed to load agent types:', result.ErrorMessage);
1955
- this.agentTypes = [];
1956
- }
1957
- }
1958
- catch (error) {
1959
- console.error('Error loading agent types:', error);
1960
- this.agentTypes = [];
1961
- }
1987
+ this.agentTypes = AIEngineBase.Instance.AgentTypes;
1962
1988
  }
1963
1989
  /**
1964
1990
  * Loads the context compression prompt details for display
@@ -1969,25 +1995,9 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
1969
1995
  this.selectedContextCompressionPrompt = null;
1970
1996
  return;
1971
1997
  }
1972
- try {
1973
- const rv = new RunView();
1974
- const result = await rv.RunView({
1975
- EntityName: 'AI Prompts',
1976
- ExtraFilter: `ID = '${this.record.ContextCompressionPromptID}'`,
1977
- ResultType: 'entity_object',
1978
- MaxRows: 1
1979
- });
1980
- if (result.Success && result.Results && result.Results.length > 0) {
1981
- this.selectedContextCompressionPrompt = result.Results[0];
1982
- }
1983
- else {
1984
- console.warn('Context compression prompt not found:', this.record.ContextCompressionPromptID);
1985
- this.selectedContextCompressionPrompt = null;
1986
- }
1987
- }
1988
- catch (error) {
1989
- console.error('Error loading context compression prompt:', error);
1990
- this.selectedContextCompressionPrompt = null;
1998
+ this.selectedContextCompressionPrompt = AIEngineBase.Instance.Prompts.find(p => p.ID === this.record.ContextCompressionPromptID);
1999
+ if (!this.selectedContextCompressionPrompt) {
2000
+ console.warn('Context compression prompt not found:', this.record.ContextCompressionPromptID);
1991
2001
  }
1992
2002
  }
1993
2003
  /**
@@ -1995,7 +2005,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
1995
2005
  */
1996
2006
  async openContextCompressionPromptSelector() {
1997
2007
  try {
1998
- const { PromptSelectorDialogComponent } = await import('./prompt-selector-dialog.component');
1999
2008
  const dialogRef = this.dialogService.open({
2000
2009
  title: 'Select Context Compression Prompt',
2001
2010
  content: PromptSelectorDialogComponent,
@@ -2177,19 +2186,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
2177
2186
  this.customSectionLoaded = false;
2178
2187
  /** Track the component reference to check if it still exists */
2179
2188
  this.customSectionComponentRef = null;
2180
- // === Related Entity Counts ===
2181
- /** Number of sub-agents under this agent */
2182
- this.subAgentCount = 0;
2183
- /** Number of prompts associated with this agent */
2184
- this.promptCount = 0;
2185
- /** Number of actions configured for this agent */
2186
- this.actionCount = 0;
2187
- /** Number of learning cycles for this agent */
2188
- this.learningCycleCount = 0;
2189
- /** Number of notes associated with this agent */
2190
- this.noteCount = 0;
2191
- /** Number of execution history records */
2192
- this.executionHistoryCount = 0;
2193
2189
  // === Related Entity Data for Display ===
2194
2190
  /** Array of sub-agent entities for card display */
2195
2191
  this.subAgents = [];
@@ -2203,19 +2199,20 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
2203
2199
  this.agentNotes = [];
2204
2200
  /** Array of recent execution records for history display */
2205
2201
  this.recentExecutions = [];
2202
+ this.totalExecutionHistoryCount = 0;
2206
2203
  /** Track which execution cards are expanded */
2207
2204
  this.expandedExecutions = {};
2208
2205
  // === Loading States ===
2209
2206
  /** Main loading state for initial data load */
2210
- this.isLoadingData = false;
2211
- /** Individual loading states for each section */
2207
+ this.isLoadingData = true;
2208
+ /** Individual loading states for each section, start off true until loading complete */
2212
2209
  this.loadingStates = {
2213
- executionHistory: false,
2214
- subAgents: false,
2215
- prompts: false,
2216
- actions: false,
2217
- learningCycles: false,
2218
- notes: false
2210
+ executionHistory: true,
2211
+ subAgents: true,
2212
+ prompts: true,
2213
+ actions: true,
2214
+ learningCycles: true,
2215
+ notes: true
2219
2216
  };
2220
2217
  // === Dropdown Data ===
2221
2218
  /** Model selection mode options for the dropdown */
@@ -2260,14 +2257,16 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
2260
2257
  async ngOnInit() {
2261
2258
  await super.ngOnInit();
2262
2259
  // Load agent types for dropdown (needed for both new and existing records)
2260
+ await AIEngineBase.Instance.Config(false); // in UI context user and provider default to global
2261
+ await ActionEngineBase.Instance.Config(false);
2263
2262
  await this.loadAgentTypes();
2264
2263
  // Load context compression prompt if one is set
2265
2264
  if (this.record?.ContextCompressionPromptID) {
2266
2265
  await this.loadContextCompressionPrompt();
2267
2266
  }
2268
2267
  if (this.record?.ID) {
2269
- await this.loadRelatedCounts();
2270
- await this.loadAgentType();
2268
+ await this.loadRelatedCounts(false); // no need to force refresh on initial load
2269
+ await this.loadCurrentAgentType();
2271
2270
  // Schedule change detection - safer than manual detectChanges()
2272
2271
  this.cdr.markForCheck();
2273
2272
  // Defer custom section loading to next tick after DOM updates
@@ -2284,7 +2283,7 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
2284
2283
  * This data populates the various expander panels in the enhanced form interface.
2285
2284
  * @private
2286
2285
  */
2287
- async loadRelatedCounts() {
2286
+ async loadRelatedCounts(forceRefresh) {
2288
2287
  if (!this.record?.ID)
2289
2288
  return;
2290
2289
  // Set loading state
@@ -2297,68 +2296,58 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
2297
2296
  learningCycles: true,
2298
2297
  notes: true
2299
2298
  };
2300
- this.cdr.detectChanges();
2299
+ this.cdr.detectChanges(); // update UI
2300
+ if (forceRefresh) {
2301
+ await AIEngineBase.Instance.Config(true); // force refresh
2302
+ }
2301
2303
  try {
2304
+ // pull stuff that doesn't change from AI Engine as it is pretty static and engine is smart
2305
+ // enough to refresh cache if something changes (via this process, exernal process changes require an update for now)
2306
+ this.subAgents = AIEngineBase.Instance.Agents.filter(a => a.ParentID === this.record.ID);
2307
+ this.agentPrompts = AIEngineBase.Instance.Prompts.filter(p => {
2308
+ const filteredAgentPrompts = AIEngineBase.Instance.AgentPrompts.filter(ap => ap.AgentID === this.record.ID);
2309
+ return filteredAgentPrompts.some(ap => ap.PromptID === p.ID);
2310
+ });
2311
+ this.agentActions = ActionEngineBase.Instance.Actions.filter(a => {
2312
+ const filteredAgentActions = AIEngineBase.Instance.AgentActions.filter(aa => aa.AgentID === this.record.ID);
2313
+ return filteredAgentActions.some(aa => aa.ActionID === a.ID);
2314
+ });
2302
2315
  const rv = new RunView();
2303
2316
  // Execute all queries in a single batch for better performance
2304
2317
  const results = await rv.RunViews([
2305
- // Sub-agents
2306
- {
2307
- EntityName: 'AI Agents',
2308
- ExtraFilter: `ParentID='${this.record.ID}'`,
2309
- OrderBy: 'Name ASC'
2310
- },
2311
- // Prompts
2312
- {
2313
- EntityName: 'AI Prompts',
2314
- ExtraFilter: `ID IN (SELECT PromptID FROM __mj.vwAIAgentPrompts WHERE AgentID='${this.record.ID}')`
2315
- },
2316
- // Actions
2317
- {
2318
- EntityName: 'Actions',
2319
- ExtraFilter: `ID IN (SELECT ActionID FROM __mj.vwAIAgentActions WHERE AgentID='${this.record.ID}')`,
2320
- OrderBy: 'Name ASC'
2321
- },
2322
2318
  // Learning cycles
2323
2319
  {
2324
2320
  EntityName: 'AI Agent Learning Cycles',
2321
+ // limit fields
2322
+ Fields: ["ID", "Name", "StartedAt", "EndedAt", "Status", "AgentID"],
2325
2323
  ExtraFilter: `AgentID='${this.record.ID}'`,
2326
2324
  OrderBy: 'StartedAt DESC'
2327
2325
  },
2328
2326
  // Notes
2329
2327
  {
2330
2328
  EntityName: 'AI Agent Notes',
2329
+ // limit fields
2330
+ Fields: ["ID", "Name", "AgentID", "AgentNoteType", "AgentNoteTypeID", "UserID"],
2331
2331
  ExtraFilter: `AgentID='${this.record.ID}'`
2332
2332
  },
2333
2333
  // Execution history
2334
2334
  {
2335
2335
  EntityName: 'MJ: AI Agent Runs',
2336
+ Fields: [
2337
+ "ID", "AgentID", "ParentRunID", "Status", "StartedAt", "CompletedAt",
2338
+ "Success", "TotalTokensUsed", "TotalCost", "TotalCostRollUp", "TotalTokensUsedRollUp"
2339
+ ],
2336
2340
  ExtraFilter: `AgentID='${this.record.ID}'`,
2337
- OrderBy: '__mj_CreatedAt DESC'
2341
+ OrderBy: '__mj_CreatedAt DESC',
2342
+ MaxRows: 100
2338
2343
  }
2339
2344
  ]);
2340
- // Load agent types for dropdown
2341
- await this.loadAgentTypes();
2342
2345
  // Process results in the same order as queries
2343
- if (results.length >= 6) {
2344
- // Sub-agents (index 0)
2345
- this.subAgents = results[0].Results || [];
2346
- this.subAgentCount = results[0].TotalRowCount || 0;
2347
- // Prompts (index 1)
2348
- this.agentPrompts = results[1].Results || [];
2349
- this.promptCount = results[1].TotalRowCount || 0;
2350
- // Actions (index 2)
2351
- this.agentActions = results[2].Results || [];
2352
- this.actionCount = results[2].TotalRowCount || 0;
2353
- // Learning cycles (index 3)
2354
- this.learningCycles = results[3].Results || [];
2355
- this.learningCycleCount = results[3].TotalRowCount || 0;
2356
- // Notes (index 4)
2357
- this.agentNotes = results[4].Results || [];
2358
- this.noteCount = results[4].TotalRowCount || 0;
2359
- // Execution history (index 5)
2360
- this.recentExecutions = results[5].Results || [];
2361
- this.executionHistoryCount = results[5].TotalRowCount || 0;
2346
+ if (results && results.length > 0) {
2347
+ this.learningCycles = results[0].Results || [];
2348
+ this.agentNotes = results[1].Results || [];
2349
+ this.recentExecutions = results[2].Results || [];
2350
+ this.totalExecutionHistoryCount = results[2].TotalRowCount;
2362
2351
  }
2363
2352
  // Create snapshot for cancel/revert functionality
2364
2353
  this.createOriginalSnapshot();
@@ -2366,12 +2355,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
2366
2355
  catch (error) {
2367
2356
  console.error('Error loading related data:', error);
2368
2357
  // Set all counts to 0 on error to ensure UI shows proper empty states
2369
- this.subAgentCount = 0;
2370
- this.promptCount = 0;
2371
- this.actionCount = 0;
2372
- this.learningCycleCount = 0;
2373
- this.noteCount = 0;
2374
- this.executionHistoryCount = 0;
2375
2358
  }
2376
2359
  finally {
2377
2360
  // Clear loading states
@@ -2408,7 +2391,7 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
2408
2391
  * Loads the agent type entity for this agent
2409
2392
  * @private
2410
2393
  */
2411
- async loadAgentType() {
2394
+ async loadCurrentAgentType() {
2412
2395
  if (!this.record?.TypeID) {
2413
2396
  return;
2414
2397
  }
@@ -2484,13 +2467,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
2484
2467
  this.agentPrompts = [...this.originalSnapshots.agentPrompts];
2485
2468
  this.agentActions = [...this.originalSnapshots.agentActions];
2486
2469
  this.subAgents = [...this.originalSnapshots.subAgents];
2487
- // Restore counts
2488
- this.promptCount = this.originalSnapshots.promptCount;
2489
- this.actionCount = this.originalSnapshots.actionCount;
2490
- this.subAgentCount = this.originalSnapshots.subAgentCount;
2491
- this.learningCycleCount = this.originalSnapshots.learningCycleCount;
2492
- this.noteCount = this.originalSnapshots.noteCount;
2493
- this.executionHistoryCount = this.originalSnapshots.executionHistoryCount;
2494
2470
  // Reset other UI state
2495
2471
  this.hasUnsavedChanges = false;
2496
2472
  // Mark for check instead of forcing immediate detection
@@ -2695,7 +2671,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
2695
2671
  }
2696
2672
  // Update UI to show the new sub-agent
2697
2673
  this.subAgents.push(result.subAgent);
2698
- this.subAgentCount = this.subAgents.length;
2699
2674
  this.hasUnsavedChanges = true;
2700
2675
  // Mark for check instead of forcing immediate detection
2701
2676
  this.cdr.markForCheck();
@@ -2762,7 +2737,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
2762
2737
  this.hasUnsavedChanges = true;
2763
2738
  // Update UI to show the new prompts (cast to extended type for display)
2764
2739
  this.agentPrompts.push(...newPrompts);
2765
- this.promptCount = this.agentPrompts.length;
2766
2740
  // Mark for check instead of forcing immediate detection
2767
2741
  this.cdr.markForCheck();
2768
2742
  // Show success notification
@@ -2838,7 +2812,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
2838
2812
  this.hasUnsavedChanges = true;
2839
2813
  // Update UI to show the new actions
2840
2814
  this.agentActions.push(...newActions);
2841
- this.actionCount = this.agentActions.length;
2842
2815
  // Mark for check instead of forcing immediate detection
2843
2816
  this.cdr.markForCheck();
2844
2817
  // Show success notification
@@ -3105,7 +3078,7 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
3105
3078
  */
3106
3079
  async refreshRelatedData() {
3107
3080
  if (this.record?.ID) {
3108
- await this.loadRelatedCounts();
3081
+ await this.loadRelatedCounts(true); // force refresh
3109
3082
  MJNotificationService.Instance.CreateSimpleNotification('Related data refreshed', 'success', 2000);
3110
3083
  }
3111
3084
  }
@@ -3187,7 +3160,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
3187
3160
  this.hasUnsavedChanges = true;
3188
3161
  // Update UI to show the new prompt
3189
3162
  this.agentPrompts.push(result.prompt);
3190
- this.promptCount = this.agentPrompts.length;
3191
3163
  // Trigger change detection to update UI
3192
3164
  this.cdr.detectChanges();
3193
3165
  MJNotificationService.Instance.CreateSimpleNotification(`New prompt "${result.prompt.Name}" will be created and linked when you save the agent`, 'success', 4000);
@@ -3260,7 +3232,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
3260
3232
  const promptIndex = this.agentPrompts.findIndex(p => p.ID === prompt.ID);
3261
3233
  if (promptIndex >= 0) {
3262
3234
  this.agentPrompts.splice(promptIndex, 1);
3263
- this.promptCount = this.agentPrompts.length;
3264
3235
  }
3265
3236
  this.hasUnsavedChanges = true;
3266
3237
  // Mark for check instead of forcing immediate detection
@@ -3331,7 +3302,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
3331
3302
  this.hasUnsavedChanges = true;
3332
3303
  // Update UI to show the new sub-agents
3333
3304
  this.subAgents.push(...newAgents);
3334
- this.subAgentCount = this.subAgents.length;
3335
3305
  // Mark for check instead of forcing immediate detection
3336
3306
  this.cdr.markForCheck();
3337
3307
  // Show success notification
@@ -3396,7 +3366,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
3396
3366
  const subAgentIndex = this.subAgents.findIndex(sa => sa.ID === subAgent.ID);
3397
3367
  if (subAgentIndex >= 0) {
3398
3368
  this.subAgents.splice(subAgentIndex, 1);
3399
- this.subAgentCount = this.subAgents.length;
3400
3369
  }
3401
3370
  this.hasUnsavedChanges = true;
3402
3371
  // Mark for check instead of forcing immediate detection
@@ -3464,7 +3433,6 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
3464
3433
  const actionIndex = this.agentActions.findIndex(a => a.ID === action.ID);
3465
3434
  if (actionIndex >= 0) {
3466
3435
  this.agentActions.splice(actionIndex, 1);
3467
- this.actionCount = this.agentActions.length;
3468
3436
  }
3469
3437
  this.hasUnsavedChanges = true;
3470
3438
  // Mark for check instead of forcing immediate detection
@@ -3488,24 +3456,13 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
3488
3456
  event.stopPropagation(); // Prevent navigation
3489
3457
  try {
3490
3458
  // Find the corresponding AIAgentPromptEntity for this prompt
3491
- const rv = new RunView();
3492
- const agentPromptResult = await rv.RunView({
3493
- EntityName: 'MJ: AI Agent Prompts',
3494
- ExtraFilter: `AgentID='${this.record.ID}' AND PromptID='${prompt.ID}'`,
3495
- ResultType: 'entity_object'
3496
- });
3497
- if (!agentPromptResult.Success || !agentPromptResult.Results?.length) {
3459
+ // Get all agent prompts for validation
3460
+ const allAgentPrompts = AIEngineBase.Instance.AgentPrompts.filter(ap => ap.AgentID === this.record.ID);
3461
+ const agentPrompt = allAgentPrompts.find(ap => ap.PromptID === prompt.ID);
3462
+ if (!agentPrompt) {
3498
3463
  MJNotificationService.Instance.CreateSimpleNotification('Unable to find prompt configuration for advanced settings', 'error', 3000);
3499
3464
  return;
3500
3465
  }
3501
- const agentPrompt = agentPromptResult.Results[0];
3502
- // Get all agent prompts for validation
3503
- const allAgentPromptsResult = await rv.RunView({
3504
- EntityName: 'MJ: AI Agent Prompts',
3505
- ExtraFilter: `AgentID='${this.record.ID}'`,
3506
- ResultType: 'entity_object'
3507
- });
3508
- const allAgentPrompts = allAgentPromptsResult.Success ? (allAgentPromptsResult.Results || []) : [];
3509
3466
  this.agentManagementService.openAgentPromptAdvancedSettingsDialog({
3510
3467
  agentPrompt: agentPrompt,
3511
3468
  allAgentPrompts: allAgentPrompts,
@@ -3526,7 +3483,7 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
3526
3483
  if (saveResult) {
3527
3484
  MJNotificationService.Instance.CreateSimpleNotification('Prompt settings updated successfully', 'success', 3000);
3528
3485
  // Refresh the related data to reflect changes
3529
- await this.loadRelatedCounts();
3486
+ await this.loadRelatedCounts(true);
3530
3487
  }
3531
3488
  else {
3532
3489
  MJNotificationService.Instance.CreateSimpleNotification('Failed to save prompt settings. Please try again.', 'error', 3000);
@@ -3552,21 +3509,11 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
3552
3509
  /**
3553
3510
  * Opens the advanced settings dialog for a sub-agent
3554
3511
  */
3555
- async openSubAgentAdvancedSettings(subAgent, event) {
3512
+ async openSubAgentAdvancedSettings(subAgentEntity, event) {
3556
3513
  event.stopPropagation(); // Prevent navigation
3557
3514
  try {
3558
- // Load the full sub-agent entity for editing
3559
- const md = new Metadata();
3560
- const subAgentEntity = await md.GetEntityObject('AI Agents');
3561
- await subAgentEntity.Load(subAgent.ID);
3562
3515
  // Get all sub-agents under the same parent for validation
3563
- const rv = new RunView();
3564
- const allSubAgentsResult = await rv.RunView({
3565
- EntityName: 'AI Agents',
3566
- ExtraFilter: `ParentID='${this.record.ID}'`,
3567
- ResultType: 'entity_object'
3568
- });
3569
- const allSubAgents = allSubAgentsResult.Success ? (allSubAgentsResult.Results || []) : [];
3516
+ const allSubAgents = AIEngineBase.Instance.Agents.filter(sa => sa.ParentID === subAgentEntity.ParentID);
3570
3517
  this.agentManagementService.openSubAgentAdvancedSettingsDialog({
3571
3518
  subAgent: subAgentEntity,
3572
3519
  allSubAgents: allSubAgents,
@@ -3586,7 +3533,7 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
3586
3533
  if (saveResult) {
3587
3534
  MJNotificationService.Instance.CreateSimpleNotification('Sub-agent settings updated successfully', 'success', 3000);
3588
3535
  // Update the local sub-agent data to reflect changes
3589
- const localSubAgent = this.subAgents.find(sa => sa.ID === subAgent.ID);
3536
+ const localSubAgent = this.subAgents.find(sa => sa.ID === subAgentEntity.ID);
3590
3537
  if (localSubAgent) {
3591
3538
  localSubAgent.ExecutionOrder = formData.executionOrder;
3592
3539
  localSubAgent.ExecutionMode = formData.executionMode;
@@ -3755,7 +3702,7 @@ let AIAgentFormComponentExtended = class AIAgentFormComponentExtended extends AI
3755
3702
  // Clear pending records since they've been saved
3756
3703
  this.PendingRecords.length = 0;
3757
3704
  // Reload related data to reflect database state
3758
- await this.loadRelatedCounts();
3705
+ await this.loadRelatedCounts(true);
3759
3706
  MJNotificationService.Instance.CreateSimpleNotification('AI Agent and all related changes saved successfully', 'success', 3000);
3760
3707
  return true;
3761
3708
  }
@@ -3828,12 +3775,12 @@ AIAgentFormComponentExtended = __decorate([
3828
3775
  export { AIAgentFormComponentExtended };
3829
3776
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AIAgentFormComponentExtended, [{
3830
3777
  type: Component,
3831
- args: [{ selector: 'mj-ai-agent-form', template: "<div class=\"record-form-container\">\n <!-- Dialog container for Kendo dialogs -->\n <div kendoDialogContainer></div>\n <!-- Window container for Kendo windows -->\n <div kendoWindowContainer></div>\n <form *ngIf=\"record\" class=\"record-form\" #form=\"ngForm\">\n <mj-form-toolbar [form]=\"this\"></mj-form-toolbar>\n\n <!-- Compact Header with Agent Overview -->\n <div class=\"agent-header\">\n <div class=\"agent-header-content\">\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 <kendo-textbox [(ngModel)]=\"record.Name\" \n name=\"agentName\"\n placeholder=\"Enter agent name...\"\n class=\"agent-name-input\">\n </kendo-textbox>\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\">\n <i class=\"fa-solid fa-sitemap\"></i>\n Child of {{ record.Parent }}\n </span>\n }\n </div>\n </div>\n </div>\n \n <!-- Action Buttons -->\n <div class=\"agent-actions\">\n @if (record.ID) {\n <button kendoButton themeColor=\"primary\" size=\"large\"\n (click)=\"openTestHarness()\"\n [disabled]=\"record.Status !== 'Active'\"\n title=\"Run this AI agent\">\n <i class=\"fa-solid fa-play\"></i>\n Run\n </button>\n }\n <button kendoButton fillMode=\"outline\" size=\"small\" (click)=\"refreshRelatedData()\" title=\"Refresh all data\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Single Pane Layout with Expander Panels -->\n <div class=\"form-content\">\n <kendo-panelbar [keepItemContent]=\"true\">\n <!-- Custom Agent Type Section (if defined) -->\n @if (record.ID && agentType && agentType.UIFormSectionKey) {\n <kendo-panelbar-item \n [expanded]=\"agentType.UIFormSectionExpandedByDefault\" \n (stateChange)=\"onCustomSectionStateChange($event)\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-puzzle-piece\"></i> {{ agentType.Name }} Configuration\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"panel-content custom-agent-type-section\" [style.display]=\"'block'\">\n <ng-container #customSectionContainer></ng-container>\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n <!-- Requests & History -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.executionHistory\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-history\"></i> Execution History\n @if (loadingStates.executionHistory) {\n <span style=\"margin-left: 8px;\"><i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 12px;\"></i></span>\n } @else if (executionHistoryCount > 0) {\n <span> ({{ executionHistoryCount }})</span>\n }\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"panel-content execution-history-panel\">\n \n @if (executionHistoryCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-history\"></i>\n <h4>No Execution History</h4>\n <p>This agent hasn't been executed yet. Use the Test Agent button to run the agent and see execution history here.</p>\n </div>\n } @else {\n <div class=\"execution-history-list\">\n @for (execution of recentExecutions; 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 \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 \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\">{{ getRunningTime(execution.StartedAt) }}</span>\n </div>\n }\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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 @if (executionHistoryCount > recentExecutions.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('MJ: AI Agent Runs', '')\">\n <span>View all {{ executionHistoryCount }} executions...</span>\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n <!-- Actions -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.actions\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-bolt\"></i> Actions\n @if (loadingStates.actions) {\n <span style=\"margin-left: 8px;\"><i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 12px;\"></i></span>\n } @else if (actionCount > 0) {\n <span> ({{ actionCount }})</span>\n }\n </ng-template>\n <ng-template kendoPanelBarContent>\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 kendoButton themeColor=\"primary\" size=\"small\" (click)=\"configureActions()\">\n <i class=\"fa-solid fa-plus\"></i> Add Action\n </button>\n }\n </div>\n </div>\n \n @if (actionCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-bolt\"></i>\n <h4>No Actions Configured</h4>\n <p>Add actions to enable this agent to perform specific tasks and operations.</p>\n @if (EditMode && UserCanCreateActions) {\n <button kendoButton themeColor=\"primary\" (click)=\"configureActions()\">\n <i class=\"fa-solid fa-plus\"></i> Configure First Action\n </button>\n }\n </div>\n } @else {\n <div class=\"entity-list\">\n @for (action of agentActions; track action.ID) {\n <div class=\"entity-item action-item\" (click)=\"navigateToEntity('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 kendoButton\n fillMode=\"flat\" \n themeColor=\"error\" \n size=\"small\"\n (click)=\"removeAction(action, $event)\"\n title=\"Remove 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('AI Agent Actions', '')\">\n <span>View all {{ actionCount }} actions...</span>\n </div>\n }\n </div>\n }\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n <!-- Sub-Agents -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.subAgents\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-sitemap\"></i> Sub-Agents\n @if (loadingStates.subAgents) {\n <span style=\"margin-left: 8px;\"><i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 12px;\"></i></span>\n } @else if (subAgentCount > 0) {\n <span> ({{ subAgentCount }})</span>\n }\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Manage hierarchical relationships with child agents that work under this agent.\n </div>\n <div class=\"header-actions\">\n @if (EditMode && UserCanCreateSubAgents) {\n <button kendoButton themeColor=\"primary\" size=\"small\" (click)=\"addSubAgents()\">\n <i class=\"fa-solid fa-plus\"></i> Add Subagent\n </button>\n <button kendoButton themeColor=\"secondary\" size=\"small\" (click)=\"createSubAgent()\">\n <i class=\"fa-solid fa-plus\"></i> Create Sub-Agent\n </button>\n }\n </div>\n </div>\n \n @if (subAgentCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <h4>No Sub-Agents</h4>\n <p>Create sub-agents to build a hierarchical structure for complex workflows.</p>\n @if (EditMode && UserCanCreateSubAgents) {\n <button kendoButton themeColor=\"primary\" (click)=\"addSubAgents()\">\n <i class=\"fa-solid fa-plus\"></i> Add Subagent\n </button>\n <button kendoButton themeColor=\"secondary\" (click)=\"createSubAgent()\">\n <i class=\"fa-solid fa-plus\"></i> Create First Sub-Agent\n </button>\n }\n </div>\n } @else {\n <div class=\"entity-list\">\n @for (subAgent of subAgents; track subAgent.ID) {\n <div class=\"entity-item sub-agent-item\" (click)=\"navigateToEntity('AI Agents', subAgent.ID)\">\n <div class=\"item-icon\">\n @if (hasSubAgentLogoURL(subAgent)) {\n <img [src]=\"subAgent.LogoURL\" [alt]=\"subAgent.Name + ' logo'\" class=\"sub-agent-logo\">\n } @else {\n <i [class]=\"getSubAgentIcon(subAgent)\"></i>\n }\n </div>\n <div class=\"item-content\">\n <div class=\"item-title\">{{ subAgent.Name || 'Untitled Sub-Agent' }}</div>\n @if (subAgent.Description) {\n <div class=\"item-preview\">{{ subAgent.Description }}</div>\n }\n <div class=\"item-meta\">\n @if (subAgent.Status) {\n <span class=\"status-tag\" [style.background-color]=\"getStatusBadgeColor()\">\n {{ subAgent.Status }}\n </span>\n }\n @if (subAgent.ExecutionMode) {\n <span class=\"meta-tag\">{{ subAgent.ExecutionMode }}</span>\n }\n </div>\n </div>\n <div class=\"item-actions\">\n @if (EditMode && UserCanCreateSubAgents) {\n <button kendoButton\n fillMode=\"flat\" \n themeColor=\"primary\" \n size=\"small\"\n (click)=\"openSubAgentAdvancedSettings(subAgent, $event)\"\n title=\"Advanced settings\">\n <i class=\"fa-solid fa-cog\"></i>\n </button>\n }\n @if (EditMode && UserCanDeleteSubAgents) {\n <button kendoButton\n fillMode=\"flat\" \n themeColor=\"error\" \n size=\"small\"\n (click)=\"removeSubAgent(subAgent, $event)\"\n title=\"Remove sub-agent\">\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 (subAgentCount > subAgents.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('AI Agents', '')\">\n <span>View all {{ subAgentCount }} sub-agents...</span>\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n <!-- Prompts (With Model Selection) -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.prompts\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-comments\"></i> Prompts\n @if (loadingStates.prompts) {\n <span style=\"margin-left: 8px;\"><i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 12px;\"></i></span>\n } @else if (promptCount > 0) {\n <span> ({{ promptCount }})</span>\n }\n </ng-template>\n <ng-template kendoPanelBarContent>\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 <kendo-dropdownlist\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 </kendo-dropdownlist>\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 kendoButton themeColor=\"primary\" size=\"small\" (click)=\"addPrompt()\">\n <i class=\"fa-solid fa-plus\"></i> Add Prompt\n </button>\n }\n </div>\n </div>\n \n @if (promptCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-comments\"></i>\n <h4>No Prompts Configured</h4>\n <p>Add prompts to define how this agent processes requests and generates responses.</p>\n @if (EditMode && UserCanCreateNewPrompts) {\n <button kendoButton themeColor=\"primary\" (click)=\"addPrompt()\">\n <i class=\"fa-solid fa-plus\"></i> Create First Prompt\n </button>\n }\n </div>\n } @else {\n <div class=\"entity-list\">\n @for (prompt of agentPrompts; track prompt.ID) {\n <div class=\"entity-item prompt-item\" (click)=\"navigateToEntity('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 kendoButton\n fillMode=\"flat\" \n themeColor=\"primary\" \n size=\"small\"\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 kendoButton\n fillMode=\"flat\" \n themeColor=\"error\" \n size=\"small\"\n (click)=\"removePrompt(prompt, $event)\"\n title=\"Remove prompt\">\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('AI Prompts', '')\">\n <span>View all {{ promptCount }} prompts...</span>\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n\n <!-- Learning & Analytics -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.learningCycles\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-brain\"></i> Learning Cycles{{ learningCycleCount > 0 ? ' (' + learningCycleCount + ')' : '' }}\n </ng-template>\n <ng-template kendoPanelBarContent>\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 \n @if (learningCycleCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-brain\"></i>\n <h4>No Learning Cycles</h4>\n <p>Learning cycles will appear here as the agent processes requests and improves over time.</p>\n </div>\n } @else {\n <div class=\"entity-list\">\n @for (cycle of learningCycles; track cycle.ID) {\n <div class=\"entity-item learning-item\" (click)=\"navigateToEntity('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('AI Agent Learning Cycles', '')\">\n <span>View all {{ learningCycleCount }} cycles...</span>\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n <!-- Notes & Documentation -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.notes\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-sticky-note\"></i> Notes{{ noteCount > 0 ? ' (' + noteCount + ')' : '' }}\n </ng-template>\n <ng-template kendoPanelBarContent>\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 kendoButton themeColor=\"primary\" size=\"small\" (click)=\"addNote()\">\n <i class=\"fa-solid fa-plus\"></i> Add Note\n </button>\n }\n </div>\n </div>\n \n @if (noteCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-sticky-note\"></i>\n <h4>No Notes</h4>\n <p>Add notes to document important information, observations, or instructions for this agent.</p>\n @if (EditMode && UserCanCreateNotes) {\n <button kendoButton themeColor=\"primary\" (click)=\"addNote()\">\n <i class=\"fa-solid fa-plus\"></i> Create First Note\n </button>\n }\n </div>\n } @else {\n <div class=\"entity-list\">\n @for (note of agentNotes; track note.ID) {\n <div class=\"entity-item note-item\" (click)=\"navigateToEntity('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('AI Agent Notes', '')\">\n <span>View all {{ noteCount }} notes...</span>\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n\n\n <!-- Payload -->\n <kendo-panelbar-item [expanded]=\"false\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-exchange-alt\"></i> Payload Management\n </ng-template>\n <ng-template kendoPanelBarContent>\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 \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 \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 \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\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 \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\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\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\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\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 \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 \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 \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 </ng-template>\n </kendo-panelbar-item>\n\n\n\n <!-- Execution Guardrails (New Separate Panel) -->\n <kendo-panelbar-item [expanded]=\"false\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-shield-halved\"></i> Execution Guardrails\n </ng-template>\n <ng-template kendoPanelBarContent>\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 \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\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\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\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 </ng-template>\n </kendo-panelbar-item>\n\n <!-- Configuration (Settings Panel) -->\n <kendo-panelbar-item [expanded]=\"false\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-cogs\"></i> Configuration\n </ng-template>\n <ng-template kendoPanelBarContent>\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 \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 \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 <kendo-dropdownlist \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 </kendo-dropdownlist>\n } @else {\n <span class=\"config-field-display\">{{ record.Status || 'Not Set' }}</span>\n }\n </div>\n </div>\n\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 <kendo-dropdownlist \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 </kendo-dropdownlist>\n } @else {\n <span class=\"config-field-display\">{{ record.Type || 'Not Set' }}</span>\n }\n </div>\n </div>\n\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\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\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 \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\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\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\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\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 \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\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\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 \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\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\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\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 kendoButton \n fillMode=\"outline\" \n size=\"small\"\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 kendoButton \n fillMode=\"flat\" \n size=\"small\"\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 </ng-template>\n </kendo-panelbar-item>\n\n\n\n\n </kendo-panelbar>\n </div>\n </form>\n\n</div>", styles: ["/* AI Agent Form - Modern Redesign */\n.record-form-container {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #f5f7fa;\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: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);\n border-bottom: 1px solid #e0e6ed;\n padding: 12px 20px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.04);\n}\n\n.agent-header-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 20px;\n}\n\n.agent-overview {\n display: flex;\n align-items: center;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n.agent-icon-wrapper {\n width: 48px;\n height: 48px;\n background: linear-gradient(135deg, #2196f3 0%, #1976d2 100%);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.2);\n flex-shrink: 0;\n}\n\n.agent-icon-wrapper i {\n color: white;\n font-size: 24px;\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: 22px;\n font-weight: 600;\n color: #2c3e50;\n margin: 0 0 8px 0;\n line-height: 1.2;\n}\n\n.agent-name-input {\n font-size: 18px !important;\n font-weight: 500 !important;\n height: 36px !important;\n width: 100% !important;\n max-width: 400px !important;\n}\n\n.agent-meta {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n padding: 6px 16px;\n border-radius: 20px;\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.status-badge.active {\n background: #28a745;\n color: white;\n}\n\n.status-badge.pending {\n background: #ffc107;\n color: #212529;\n}\n\n.status-badge.disabled {\n background: #6c757d;\n color: white;\n}\n\n.execution-mode,\n.parent-agent {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: #6c757d;\n background: #f8f9fa;\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/* 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: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-value {\n font-size: 14px;\n color: #495057;\n font-weight: 500;\n}\n\n.agent-description {\n margin-top: 16px;\n color: #6c757d;\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: column;\n gap: 12px;\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: #2196f3;\n color: white;\n}\n\n.action-button.primary:hover {\n background: #1976d2;\n}\n\n.action-button.secondary {\n background: #6c757d;\n color: white;\n}\n\n.action-button.secondary:hover {\n background: #5a6268;\n}\n\n.action-warnings {\n margin-top: 8px;\n font-size: 13px;\n color: #dc3545;\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: #f5f7fa;\n padding: 12px;\n}\n\n/* Kendo PanelBar Styling */\n::ng-deep .k-panelbar {\n border: none;\n background: transparent;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item {\n border: none;\n border-radius: 12px;\n margin-bottom: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.06);\n background: white;\n overflow: hidden;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item > .k-header {\n background: white;\n border: none;\n padding: 16px 20px;\n border-radius: 12px 12px 0 0;\n color: #2c3e50;\n font-weight: 600;\n font-size: 16px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item > .k-header:hover {\n background: #f8f9fa;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header {\n background: #2196f3;\n color: white;\n border-radius: 12px 12px 0 0;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle {\n position: absolute;\n right: 24px;\n color: inherit;\n font-size: 14px;\n transition: transform 0.2s ease;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header .k-panelbar-toggle {\n transform: rotate(180deg);\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle::before {\n content: '\\f107';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item > .k-content {\n padding: 0;\n border: none;\n background: white;\n border-radius: 0 0 12px 12px;\n}\n\n::ng-deep .k-panelbar .k-header .k-panelbar-icon {\n font-size: 18px;\n color: #2196f3;\n margin-right: 8px;\n}\n\n::ng-deep .k-panelbar .k-panelbar-expanded .k-header .k-panelbar-icon {\n color: white;\n}\n\n/* Panel Content */\n.panel-content {\n padding: 16px;\n background: white;\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: #6c757d;\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: white;\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 #e0e6ed;\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 #f0f4f8;\n}\n\n.section-title {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0;\n color: #2c3e50;\n font-size: 18px;\n font-weight: 600;\n}\n\n.section-title i {\n color: #2196f3;\n font-size: 20px;\n}\n\n.section-description {\n color: #6c757d;\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: #495057;\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 #e0e6ed;\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: #64748b;\n}\n\n.loading-state i {\n font-size: 36px;\n color: #2196f3;\n margin-bottom: 16px;\n display: block;\n}\n\n.loading-state p {\n margin: 0;\n font-size: 14px;\n color: #94a3b8;\n}\n\n.empty-state {\n text-align: center;\n padding: 60px 20px;\n color: #6c757d;\n}\n\n.empty-state i {\n font-size: 48px;\n color: #dee2e6;\n margin-bottom: 16px;\n}\n\n.empty-state h4 {\n color: #495057;\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.empty-state p {\n font-size: 15px;\n line-height: 1.6;\n max-width: 400px;\n margin: 0 auto;\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: rgba(255, 255, 255, 0.9);\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 #f3f3f3;\n border-top: 4px solid #2196f3;\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 #e0e6ed;\n}\n\n.quick-action-card {\n flex: 1;\n padding: 16px;\n background: #f8f9fa;\n border-radius: 8px;\n border: 1px solid #e0e6ed;\n cursor: pointer;\n transition: all 0.2s ease;\n text-align: center;\n}\n\n.quick-action-card:hover {\n background: white;\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: #2196f3;\n margin-bottom: 8px;\n}\n\n.quick-action-title {\n font-size: 14px;\n font-weight: 600;\n color: #495057;\n margin-bottom: 4px;\n}\n\n.quick-action-description {\n font-size: 12px;\n color: #6c757d;\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: #f8f9fa;\n border: 1px solid #e0e6ed;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.entity-item:hover {\n background: white;\n border-color: #2196f3;\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: linear-gradient(135deg, #e9ecef, #dee2e6);\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: linear-gradient(135deg, #20c997, #17a673);\n}\n\n.action-item .item-icon {\n background: linear-gradient(135deg, #ffc107, #e0a800);\n}\n\n.sub-agent-item .item-icon {\n background: linear-gradient(135deg, #2196f3, #1976d2);\n}\n\n.model-item .item-icon {\n background: linear-gradient(135deg, #6f42c1, #563d7c);\n}\n\n.learning-item .item-icon {\n background: linear-gradient(135deg, #e83e8c, #dc3545);\n}\n\n.note-item .item-icon {\n background: linear-gradient(135deg, #fd7e14, #e55a00);\n}\n\n.item-icon i {\n color: #6c757d;\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: white;\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: #2c3e50;\n margin: 0 0 4px 0;\n line-height: 1.3;\n}\n\n.item-preview {\n color: #6c757d;\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: #e9ecef;\n color: #495057;\n}\n\n.priority-tag {\n color: white;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.status-tag {\n background: #e9ecef;\n color: #495057;\n}\n\n.status-tag.active {\n background: #d4edda;\n color: #28a745;\n}\n\n.status-tag.inactive {\n background: #f8d7da;\n color: #dc3545;\n}\n\n.item-actions {\n opacity: 0;\n transition: opacity 0.2s ease;\n color: #6c757d;\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: #2196f3;\n}\n\n.view-more-item {\n padding: 16px;\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border: 2px dashed #dee2e6;\n border-radius: 10px;\n text-align: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #6c757d;\n font-weight: 500;\n}\n\n.view-more-item:hover {\n background: linear-gradient(135deg, #e9ecef, #dee2e6);\n border-color: #2196f3;\n color: #2196f3;\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: #2c3e50;\n margin: 0 0 16px 0;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.subsection-title i {\n color: #2196f3;\n}\n\n.subsection-divider {\n margin-top: 32px;\n margin-bottom: 16px;\n padding-top: 24px;\n border-top: 1px solid #e0e6ed;\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: #495057;\n margin-bottom: 8px;\n}\n\n.payload-field-label i {\n color: #6c757d;\n font-size: 16px;\n}\n\n.field-description {\n font-size: 12px;\n font-weight: normal;\n color: #6c757d;\n margin-left: auto;\n}\n\n/* Code editor styling */\n.payload-field-group mj-code-editor {\n border: 1px solid #dee2e6;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.payload-field-group mj-code-editor:hover {\n border-color: #2196f3;\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: #f8f9fa;\n border: 1px solid #e0e6ed;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.timeline-item:hover {\n background: white;\n border-color: #2196f3;\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: white;\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: #2c3e50;\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: #6c757d;\n background: #e9ecef;\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: #6c757d;\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: white;\n border: 1px solid #e0e6ed;\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: #2196f3;\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: linear-gradient(90deg, #2196f3, #42a5f5);\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: linear-gradient(135deg, #f8f9fa, #e9ecef);\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: linear-gradient(135deg, #2196f3, #1976d2);\n}\n\n.prompt-card .card-icon {\n background: linear-gradient(135deg, #20c997, #17a673);\n}\n\n.action-card .card-icon {\n background: linear-gradient(135deg, #ffc107, #e0a800);\n}\n\n.card-icon i {\n font-size: 18px;\n color: #6c757d;\n}\n\n.sub-agent-card .card-icon i,\n.prompt-card .card-icon i,\n.action-card .card-icon i {\n color: white;\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: #2c3e50;\n margin: 0 0 4px 0;\n line-height: 1.3;\n word-wrap: break-word;\n}\n\n.card-description {\n color: #6c757d;\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: #6c757d;\n padding: 4px 8px;\n background: #f8f9fa;\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: #28a745;\n background: #d4edda;\n}\n\n.meta-item.inactive {\n color: #dc3545;\n background: #f8d7da;\n}\n\n.card-actions {\n opacity: 0;\n transition: opacity 0.3s ease;\n color: #6c757d;\n}\n\n.entity-card:hover .card-actions {\n opacity: 1;\n color: #2196f3;\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: white;\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: #e9ecef;\n color: #495057;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* View All Card */\n.view-all-card {\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border: 2px dashed #dee2e6;\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: linear-gradient(135deg, #e9ecef, #dee2e6);\n border-color: #2196f3;\n transform: translateY(-2px);\n}\n\n.view-all-content {\n text-align: center;\n color: #6c757d;\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: #f8f9fa;\n border-color: #e0e6ed;\n}\n\n.timeline-item.expanded {\n background: #f8f9fa;\n border-color: #2196f3;\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.1);\n}\n\n.timeline-item.view-all {\n cursor: pointer;\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border: 2px dashed #dee2e6;\n}\n\n.timeline-item.view-all:hover {\n background: linear-gradient(135deg, #e9ecef, #dee2e6);\n border-color: #2196f3;\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: #e0e6ed;\n}\n\n.timeline-item:last-child .timeline-marker::after {\n display: none;\n}\n\n.timeline-marker i {\n color: white;\n font-size: 16px;\n}\n\n.timeline-marker.view-all-marker {\n background: #6c757d;\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: #6c757d;\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: #2c3e50;\n margin: 0;\n line-height: 1.3;\n}\n\n.timeline-date {\n font-size: 12px;\n color: #6c757d;\n white-space: nowrap;\n background: #f8f9fa;\n padding: 4px 8px;\n border-radius: 6px;\n margin-left: auto;\n}\n\n.timeline-preview {\n font-size: 13px;\n color: #6c757d;\n line-height: 1.5;\n margin-top: 8px;\n padding: 8px 12px;\n background: #f8f9fa;\n border-radius: 6px;\n border: 1px solid #e0e6ed;\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: #6c757d;\n background: #f8f9fa;\n padding: 4px 8px;\n border-radius: 6px;\n}\n\n.timeline-description {\n color: #6c757d;\n font-size: 14px;\n line-height: 1.5;\n margin: 8px 0;\n}\n\n.timeline-error {\n color: #dc3545;\n font-size: 13px;\n background: #f8d7da;\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 #e0e6ed;\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: #495057;\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-section h5 {\n color: #dc3545;\n}\n\n.result-content,\n.error-content {\n background: white;\n border: 1px solid #e0e6ed;\n border-radius: 8px;\n padding: 12px 16px;\n font-size: 14px;\n line-height: 1.6;\n color: #495057;\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 #e0e6ed;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.error-content {\n background: #f8d7da;\n border-color: #f5c6cb;\n color: #721c24;\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: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n min-width: 80px;\n}\n\n.detail-value {\n font-size: 14px;\n color: #495057;\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: #2196f3;\n color: white;\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: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.3);\n}\n\n.btn-primary i {\n font-size: 12px;\n}\n\n/* Enhanced Empty States */\n.empty-state {\n text-align: center;\n padding: 60px 20px;\n color: #6c757d;\n background: #f8f9fa;\n border-radius: 12px;\n border: 2px dashed #dee2e6;\n margin-top: 16px;\n}\n\n.empty-state i {\n font-size: 48px;\n color: #dee2e6;\n margin-bottom: 16px;\n}\n\n.empty-state h4 {\n color: #495057;\n font-weight: 600;\n margin-bottom: 8px;\n font-size: 18px;\n}\n\n.empty-state p {\n font-size: 15px;\n line-height: 1.6;\n max-width: 400px;\n margin: 0 auto 20px auto;\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: #f1f1f1;\n border-radius: 4px;\n}\n\n.execution-history-panel::-webkit-scrollbar-thumb {\n background: #c1c1c1;\n border-radius: 4px;\n}\n\n.execution-history-panel::-webkit-scrollbar-thumb:hover {\n background: #a0a0a0;\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: 16px;\n}\n\n.execution-card {\n background: white;\n border: 1px solid #e0e6ed;\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: #2196f3;\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.1);\n transform: translateY(-1px);\n}\n\n.execution-card.expanded {\n border-color: #2196f3;\n box-shadow: 0 6px 20px rgba(33, 150, 243, 0.15);\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: white;\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: #2c3e50;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.execution-date {\n font-size: 12px;\n color: #6c757d;\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: #f8f9fa;\n padding: 6px 10px;\n border-radius: 6px;\n color: #495057;\n white-space: nowrap;\n}\n\n.metric-item i {\n color: #6c757d;\n font-size: 12px;\n}\n\n.metric-label {\n font-weight: 500;\n}\n\n.metric-value {\n font-weight: 600;\n color: #2c3e50;\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: #f8f9fa;\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: #6c757d;\n}\n\n.action-btn:hover {\n background: #2196f3;\n color: white;\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: #6c757d;\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 #f0f4f8;\n background: #fafbfc;\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: white;\n border: 1px solid #e0e6ed;\n border-radius: 8px;\n}\n\n.metric-detail i {\n color: #2196f3;\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: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.metric-data {\n font-size: 14px;\n font-weight: 600;\n color: #2c3e50;\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: #495057;\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-section h5 {\n color: #dc3545;\n}\n\n.error-content {\n background: #f8d7da;\n border: 1px solid #f5c6cb;\n border-radius: 8px;\n padding: 12px 16px;\n font-size: 14px;\n line-height: 1.6;\n color: #721c24;\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: white;\n border-radius: 12px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n}\n\n.payload-section-title {\n margin: 0;\n padding: 1rem 1.5rem;\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border-bottom: 1px solid #e0e0e0;\n color: #495057;\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: #2196f3;\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: #495057;\n font-size: 0.95rem;\n}\n\n.payload-field-description {\n color: #6c757d;\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: #6c757d;\n background: #f8f9fa;\n padding: 0.5rem 0.75rem;\n border-radius: 6px;\n border: 1px solid #e9ecef;\n}\n\n.payload-field-example i {\n color: #ffc107;\n font-size: 0.9rem;\n}\n\n.payload-field-example code {\n background: #e9ecef;\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: #495057;\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: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.2s ease;\n}\n\n.payload-path-card:hover {\n border-color: #2196f3;\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.15);\n}\n\n.payload-path-header {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border-bottom: 1px solid #e0e0e0;\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: linear-gradient(135deg, #28a745, #20c997);\n}\n\n.payload-path-icon.upstream {\n background: linear-gradient(135deg, #007bff, #6610f2);\n}\n\n.payload-path-icon.self-read {\n background: linear-gradient(135deg, #17a2b8, #20c997);\n}\n\n.payload-path-icon.self-write {\n background: linear-gradient(135deg, #ffc107, #fd7e14);\n}\n\n.payload-path-icon i {\n color: white;\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: #495057;\n}\n\n.payload-path-info p {\n margin: 0;\n font-size: 0.85rem;\n color: #6c757d;\n line-height: 1.4;\n}\n\n.payload-path-content {\n padding: 1rem;\n}\n\n.json-editor-container {\n border: 1px solid #dee2e6;\n border-radius: 6px;\n overflow: hidden;\n margin-bottom: 0.75rem;\n}\n\n.json-editor-container:hover {\n border-color: #2196f3;\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: #6c757d;\n line-height: 1.4;\n}\n\n.payload-path-hint i {\n color: #17a2b8;\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.payload-path-hint code {\n background: #e9ecef;\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: #495057;\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: #495057;\n font-size: 0.95rem;\n}\n\n.validation-field-description {\n color: #6c757d;\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: #495057;\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: #2196f3;\n}\n\n.validation-schema-description {\n color: #6c757d;\n font-size: 0.9rem;\n line-height: 1.4;\n margin: 0;\n}\n\n.validation-schema-editor {\n border: 1px solid #dee2e6;\n border-radius: 6px;\n overflow: hidden;\n}\n\n.validation-schema-editor:hover {\n border-color: #2196f3;\n}\n\n/* === CONFIGURATION SECTION === */\n.config-section {\n margin-bottom: 2rem;\n background: white;\n border-radius: 12px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n}\n\n.config-section-title {\n margin: 0;\n padding: 1rem 1.5rem;\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border-bottom: 1px solid #e0e0e0;\n color: #495057;\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: #2196f3;\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: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.2s ease;\n}\n\n.config-card:hover {\n border-color: #2196f3;\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.15);\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: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border-bottom: 1px solid #e0e0e0;\n}\n\n.config-card-icon {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n background: linear-gradient(135deg, #2196f3, #1976d2);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.config-card-icon i {\n color: white;\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: #495057;\n}\n\n.config-card-info p {\n margin: 0;\n font-size: 0.85rem;\n color: #6c757d;\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/* Fix numeric textbox cutoff issue */\n.config-card-content ::ng-deep kendo-numerictextbox {\n width: 100% !important;\n}\n\n.config-card-content ::ng-deep kendo-numerictextbox .k-numerictextbox {\n width: 100% !important;\n}\n\n.config-card-content ::ng-deep kendo-numerictextbox .k-input {\n width: 100% !important;\n min-width: 200px !important;\n}\n\n.config-card-content ::ng-deep mj-form-field {\n width: 100% !important;\n}\n\n.config-card-content ::ng-deep mj-form-field kendo-numerictextbox {\n width: 100% !important;\n}\n\n.config-card-content ::ng-deep mj-form-field kendo-numerictextbox .k-numerictextbox {\n width: 100% !important;\n}\n\n.config-card-content ::ng-deep mj-form-field kendo-numerictextbox .k-input {\n width: 100% !important;\n min-width: 200px !important;\n}\n\n.config-field-display {\n color: #495057;\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: #f8f9fa;\n border: 1px solid #dee2e6;\n border-radius: 6px;\n}\n\n.prompt-name {\n color: #495057;\n font-weight: 500;\n font-size: 14px;\n}\n\n.no-prompt {\n color: #6c757d;\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: #6c757d;\n line-height: 1.4;\n margin-top: 0.5rem;\n}\n\n.config-card-hint i {\n color: #17a2b8;\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.config-card-hint code {\n background: #e9ecef;\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: #495057;\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"] }]
3778
+ args: [{ selector: 'mj-ai-agent-form', template: "<div class=\"record-form-container\">\n <!-- Dialog container for Kendo dialogs -->\n <div kendoDialogContainer></div>\n <!-- Window container for Kendo windows -->\n <div kendoWindowContainer></div>\n <form *ngIf=\"record\" class=\"record-form\" #form=\"ngForm\">\n <mj-form-toolbar [form]=\"this\"></mj-form-toolbar>\n\n <!-- Compact Header with Agent Overview -->\n <div class=\"agent-header\">\n <div class=\"agent-header-content\">\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 <kendo-textbox [(ngModel)]=\"record.Name\" \n name=\"agentName\"\n placeholder=\"Enter agent name...\"\n class=\"agent-name-input\">\n </kendo-textbox>\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\">\n <i class=\"fa-solid fa-sitemap\"></i>\n Child of {{ record.Parent }}\n </span>\n }\n </div>\n </div>\n </div>\n \n <!-- Action Buttons -->\n <div class=\"agent-actions\">\n @if (record.ID) {\n <button kendoButton themeColor=\"primary\" size=\"large\"\n (click)=\"openTestHarness()\"\n [disabled]=\"record.Status !== 'Active'\"\n title=\"Run this AI agent\">\n <i class=\"fa-solid fa-play\"></i>\n Run\n </button>\n }\n <button kendoButton fillMode=\"outline\" size=\"small\" (click)=\"refreshRelatedData()\" title=\"Refresh all data\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Single Pane Layout with Expander Panels -->\n <div class=\"form-content\">\n <kendo-panelbar [keepItemContent]=\"true\">\n <!-- Custom Agent Type Section (if defined) -->\n @if (record.ID && agentType && agentType.UIFormSectionKey) {\n <kendo-panelbar-item \n [expanded]=\"agentType.UIFormSectionExpandedByDefault\" \n (stateChange)=\"onCustomSectionStateChange($event)\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-puzzle-piece\"></i> {{ agentType.Name }} Configuration\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"panel-content custom-agent-type-section\" [style.display]=\"'block'\">\n <ng-container #customSectionContainer></ng-container>\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n <!-- Requests & History -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.executionHistory\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-history\"></i> Execution History\n @if (loadingStates.executionHistory) {\n <span style=\"margin-left: 8px;\"><i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 12px;\"></i></span>\n } @else if (executionHistoryCount > 0) {\n <span> ({{ executionHistoryCount }})@if(executionHistoryCount < totalExecutionHistoryCount){ of {{ totalExecutionHistoryCount }} }</span>\n }\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"panel-content execution-history-panel\">\n \n @if (executionHistoryCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-history\"></i>\n <h4>No Execution History</h4>\n <p>This agent hasn't been executed yet. Use the Test Agent button to run the agent and see execution history here.</p>\n </div>\n } @else {\n <div class=\"execution-history-list\">\n @for (execution of recentExecutions; 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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 @if (executionHistoryCount > recentExecutions.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('MJ: AI Agent Runs', '')\">\n <span>View all {{ executionHistoryCount }} executions...</span>\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n <!-- Actions -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.actions\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-bolt\"></i> Actions\n @if (loadingStates.actions) {\n <span style=\"margin-left: 8px;\"><i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 12px;\"></i></span>\n } @else if (actionCount > 0) {\n <span> ({{ actionCount }})</span>\n }\n </ng-template>\n <ng-template kendoPanelBarContent>\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 kendoButton themeColor=\"primary\" size=\"small\" (click)=\"configureActions()\">\n <i class=\"fa-solid fa-plus\"></i> Add Action\n </button>\n }\n </div>\n </div>\n \n @if (actionCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-bolt\"></i>\n <h4>No Actions Configured</h4>\n <p>Add actions to enable this agent to perform specific tasks and operations.</p>\n @if (EditMode && UserCanCreateActions) {\n <button kendoButton themeColor=\"primary\" (click)=\"configureActions()\">\n <i class=\"fa-solid fa-plus\"></i> Configure First Action\n </button>\n }\n </div>\n } @else {\n <div class=\"entity-list\">\n @for (action of agentActions; track action.ID) {\n <div class=\"entity-item action-item\" (click)=\"navigateToEntity('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 kendoButton\n fillMode=\"flat\" \n themeColor=\"error\" \n size=\"small\"\n (click)=\"removeAction(action, $event)\"\n title=\"Remove 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('AI Agent Actions', '')\">\n <span>View all {{ actionCount }} actions...</span>\n </div>\n }\n </div>\n }\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n <!-- Sub-Agents -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.subAgents\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-sitemap\"></i> Sub-Agents\n @if (loadingStates.subAgents) {\n <span style=\"margin-left: 8px;\"><i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 12px;\"></i></span>\n } @else if (subAgentCount > 0) {\n <span> ({{ subAgentCount }})</span>\n }\n </ng-template>\n <ng-template kendoPanelBarContent>\n <div class=\"panel-content\">\n <div class=\"section-header\">\n <div class=\"section-description\">\n Manage hierarchical relationships with child agents that work under this agent.\n </div>\n <div class=\"header-actions\">\n @if (EditMode && UserCanCreateSubAgents) {\n <button kendoButton themeColor=\"primary\" size=\"small\" (click)=\"addSubAgents()\">\n <i class=\"fa-solid fa-plus\"></i> Add Subagent\n </button>\n <button kendoButton themeColor=\"secondary\" size=\"small\" (click)=\"createSubAgent()\">\n <i class=\"fa-solid fa-plus\"></i> Create Sub-Agent\n </button>\n }\n </div>\n </div>\n \n @if (subAgentCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-sitemap\"></i>\n <h4>No Sub-Agents</h4>\n <p>Create sub-agents to build a hierarchical structure for complex workflows.</p>\n @if (EditMode && UserCanCreateSubAgents) {\n <button kendoButton themeColor=\"primary\" (click)=\"addSubAgents()\">\n <i class=\"fa-solid fa-plus\"></i> Add Subagent\n </button>\n <button kendoButton themeColor=\"secondary\" (click)=\"createSubAgent()\">\n <i class=\"fa-solid fa-plus\"></i> Create First Sub-Agent\n </button>\n }\n </div>\n } @else {\n <div class=\"entity-list\">\n @for (subAgent of subAgents; track subAgent.ID) {\n <div class=\"entity-item sub-agent-item\" (click)=\"navigateToEntity('AI Agents', subAgent.ID)\">\n <div class=\"item-icon\">\n @if (hasSubAgentLogoURL(subAgent)) {\n <img [src]=\"subAgent.LogoURL\" [alt]=\"subAgent.Name + ' logo'\" class=\"sub-agent-logo\">\n } @else {\n <i [class]=\"getSubAgentIcon(subAgent)\"></i>\n }\n </div>\n <div class=\"item-content\">\n <div class=\"item-title\">{{ subAgent.Name || 'Untitled Sub-Agent' }}</div>\n @if (subAgent.Description) {\n <div class=\"item-preview\">{{ subAgent.Description }}</div>\n }\n <div class=\"item-meta\">\n @if (subAgent.Status) {\n <span class=\"status-tag\" [style.background-color]=\"getStatusBadgeColor()\">\n {{ subAgent.Status }}\n </span>\n }\n @if (subAgent.ExecutionMode) {\n <span class=\"meta-tag\">{{ subAgent.ExecutionMode }}</span>\n }\n </div>\n </div>\n <div class=\"item-actions\">\n @if (EditMode && UserCanCreateSubAgents) {\n <button kendoButton\n fillMode=\"flat\" \n themeColor=\"primary\" \n size=\"small\"\n (click)=\"openSubAgentAdvancedSettings(subAgent, $event)\"\n title=\"Advanced settings\">\n <i class=\"fa-solid fa-cog\"></i>\n </button>\n }\n @if (EditMode && UserCanDeleteSubAgents) {\n <button kendoButton\n fillMode=\"flat\" \n themeColor=\"error\" \n size=\"small\"\n (click)=\"removeSubAgent(subAgent, $event)\"\n title=\"Remove sub-agent\">\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 (subAgentCount > subAgents.length) {\n <div class=\"view-more-item\" (click)=\"navigateToEntity('AI Agents', '')\">\n <span>View all {{ subAgentCount }} sub-agents...</span>\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n <!-- Prompts (With Model Selection) -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.prompts\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-comments\"></i> Prompts\n @if (loadingStates.prompts) {\n <span style=\"margin-left: 8px;\"><i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 12px;\"></i></span>\n } @else if (promptCount > 0) {\n <span> ({{ promptCount }})</span>\n }\n </ng-template>\n <ng-template kendoPanelBarContent>\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 <kendo-dropdownlist\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 </kendo-dropdownlist>\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 kendoButton themeColor=\"primary\" size=\"small\" (click)=\"addPrompt()\">\n <i class=\"fa-solid fa-plus\"></i> Add Prompt\n </button>\n }\n </div>\n </div>\n \n @if (promptCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-comments\"></i>\n <h4>No Prompts Configured</h4>\n <p>Add prompts to define how this agent processes requests and generates responses.</p>\n @if (EditMode && UserCanCreateNewPrompts) {\n <button kendoButton themeColor=\"primary\" (click)=\"addPrompt()\">\n <i class=\"fa-solid fa-plus\"></i> Create First Prompt\n </button>\n }\n </div>\n } @else {\n <div class=\"entity-list\">\n @for (prompt of agentPrompts; track prompt.ID) {\n <div class=\"entity-item prompt-item\" (click)=\"navigateToEntity('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 kendoButton\n fillMode=\"flat\" \n themeColor=\"primary\" \n size=\"small\"\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 kendoButton\n fillMode=\"flat\" \n themeColor=\"error\" \n size=\"small\"\n (click)=\"removePrompt(prompt, $event)\"\n title=\"Remove prompt\">\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('AI Prompts', '')\">\n <span>View all {{ promptCount }} prompts...</span>\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n\n <!-- Learning & Analytics -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.learningCycles\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-brain\"></i> Learning Cycles{{ learningCycleCount > 0 ? ' (' + learningCycleCount + ')' : '' }}\n @if (loadingStates.learningCycles) {\n <span style=\"margin-left: 8px;\"><i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 12px;\"></i></span>\n }\n </ng-template>\n <ng-template kendoPanelBarContent>\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 \n @if (learningCycleCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-brain\"></i>\n <h4>No Learning Cycles</h4>\n <p>Learning cycles will appear here as the agent processes requests and improves over time.</p>\n </div>\n } @else {\n <div class=\"entity-list\">\n @for (cycle of learningCycles; track cycle.ID) {\n <div class=\"entity-item learning-item\" (click)=\"navigateToEntity('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('AI Agent Learning Cycles', '')\">\n <span>View all {{ learningCycleCount }} cycles...</span>\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n <!-- Notes & Documentation -->\n @if (record.ID) {\n <kendo-panelbar-item [expanded]=\"false\" [disabled]=\"loadingStates.notes\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-sticky-note\"></i> Notes{{ noteCount > 0 ? ' (' + noteCount + ')' : '' }}\n @if (loadingStates.notes) {\n <span style=\"margin-left: 8px;\"><i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 12px;\"></i></span>\n }\n </ng-template>\n <ng-template kendoPanelBarContent>\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 kendoButton themeColor=\"primary\" size=\"small\" (click)=\"addNote()\">\n <i class=\"fa-solid fa-plus\"></i> Add Note\n </button>\n }\n </div>\n </div>\n \n @if (noteCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-sticky-note\"></i>\n <h4>No Notes</h4>\n <p>Add notes to document important information, observations, or instructions for this agent.</p>\n @if (EditMode && UserCanCreateNotes) {\n <button kendoButton themeColor=\"primary\" (click)=\"addNote()\">\n <i class=\"fa-solid fa-plus\"></i> Create First Note\n </button>\n }\n </div>\n } @else {\n <div class=\"entity-list\">\n @for (note of agentNotes; track note.ID) {\n <div class=\"entity-item note-item\" (click)=\"navigateToEntity('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('AI Agent Notes', '')\">\n <span>View all {{ noteCount }} notes...</span>\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n </kendo-panelbar-item>\n }\n\n\n\n <!-- Payload -->\n <kendo-panelbar-item [expanded]=\"false\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-exchange-alt\"></i> Payload Management\n </ng-template>\n <ng-template kendoPanelBarContent>\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 \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 \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 \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\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 \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\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\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\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\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 \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 \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 \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 </ng-template>\n </kendo-panelbar-item>\n\n\n\n <!-- Execution Guardrails (New Separate Panel) -->\n <kendo-panelbar-item [expanded]=\"false\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-shield-halved\"></i> Execution Guardrails\n </ng-template>\n <ng-template kendoPanelBarContent>\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 \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\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\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\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 </ng-template>\n </kendo-panelbar-item>\n\n <!-- Configuration (Settings Panel) -->\n <kendo-panelbar-item [expanded]=\"false\">\n <ng-template kendoPanelBarItemTitle>\n <i class=\"fa-solid fa-cogs\"></i> Configuration\n </ng-template>\n <ng-template kendoPanelBarContent>\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 \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 \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 <kendo-dropdownlist \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 </kendo-dropdownlist>\n } @else {\n <span class=\"config-field-display\">{{ record.Status || 'Not Set' }}</span>\n }\n </div>\n </div>\n\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 <kendo-dropdownlist \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 </kendo-dropdownlist>\n } @else {\n <span class=\"config-field-display\">{{ record.Type || 'Not Set' }}</span>\n }\n </div>\n </div>\n\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\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\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 \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\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\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\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\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 \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\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\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 \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\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\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\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 kendoButton \n fillMode=\"outline\" \n size=\"small\"\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 kendoButton \n fillMode=\"flat\" \n size=\"small\"\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 </ng-template>\n </kendo-panelbar-item>\n\n\n\n\n </kendo-panelbar>\n </div>\n </form>\n\n</div>", styles: ["/* AI Agent Form - Modern Redesign */\n.record-form-container {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #f5f7fa;\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: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);\n border-bottom: 1px solid #e0e6ed;\n padding: 12px 20px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.04);\n}\n\n.agent-header-content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 20px;\n}\n\n.agent-overview {\n display: flex;\n align-items: center;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n.agent-icon-wrapper {\n width: 48px;\n height: 48px;\n background: linear-gradient(135deg, #2196f3 0%, #1976d2 100%);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.2);\n flex-shrink: 0;\n}\n\n.agent-icon-wrapper i {\n color: white;\n font-size: 24px;\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: 22px;\n font-weight: 600;\n color: #2c3e50;\n margin: 0 0 8px 0;\n line-height: 1.2;\n}\n\n.agent-name-input {\n font-size: 18px !important;\n font-weight: 500 !important;\n height: 36px !important;\n width: 100% !important;\n max-width: 400px !important;\n}\n\n.agent-meta {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n padding: 6px 16px;\n border-radius: 20px;\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.status-badge.active {\n background: #28a745;\n color: white;\n}\n\n.status-badge.pending {\n background: #ffc107;\n color: #212529;\n}\n\n.status-badge.disabled {\n background: #6c757d;\n color: white;\n}\n\n.execution-mode,\n.parent-agent {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: #6c757d;\n background: #f8f9fa;\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/* 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: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-value {\n font-size: 14px;\n color: #495057;\n font-weight: 500;\n}\n\n.agent-description {\n margin-top: 16px;\n color: #6c757d;\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: column;\n gap: 12px;\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: #2196f3;\n color: white;\n}\n\n.action-button.primary:hover {\n background: #1976d2;\n}\n\n.action-button.secondary {\n background: #6c757d;\n color: white;\n}\n\n.action-button.secondary:hover {\n background: #5a6268;\n}\n\n.action-warnings {\n margin-top: 8px;\n font-size: 13px;\n color: #dc3545;\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: #f5f7fa;\n padding: 12px;\n}\n\n/* Kendo PanelBar Styling */\n::ng-deep .k-panelbar {\n border: none;\n background: transparent;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item {\n border: none;\n border-radius: 12px;\n margin-bottom: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.06);\n background: white;\n overflow: hidden;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item > .k-header {\n background: white;\n border: none;\n padding: 16px 20px;\n border-radius: 12px 12px 0 0;\n color: #2c3e50;\n font-weight: 600;\n font-size: 16px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item > .k-header:hover {\n background: #f8f9fa;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header {\n background: #2196f3;\n color: white;\n border-radius: 12px 12px 0 0;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle {\n position: absolute;\n right: 24px;\n color: inherit;\n font-size: 14px;\n transition: transform 0.2s ease;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item.k-panelbar-expanded > .k-header .k-panelbar-toggle {\n transform: rotate(180deg);\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item > .k-header .k-panelbar-toggle::before {\n content: '\\f107';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n}\n\n::ng-deep .k-panelbar > .k-panelbar-item > .k-content {\n padding: 0;\n border: none;\n background: white;\n border-radius: 0 0 12px 12px;\n}\n\n::ng-deep .k-panelbar .k-header .k-panelbar-icon {\n font-size: 18px;\n color: #2196f3;\n margin-right: 8px;\n}\n\n::ng-deep .k-panelbar .k-panelbar-expanded .k-header .k-panelbar-icon {\n color: white;\n}\n\n/* Panel Content */\n.panel-content {\n padding: 16px;\n background: white;\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: #6c757d;\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: white;\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 #e0e6ed;\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 #f0f4f8;\n}\n\n.section-title {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0;\n color: #2c3e50;\n font-size: 18px;\n font-weight: 600;\n}\n\n.section-title i {\n color: #2196f3;\n font-size: 20px;\n}\n\n.section-description {\n color: #6c757d;\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: #495057;\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 #e0e6ed;\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: #64748b;\n}\n\n.loading-state i {\n font-size: 36px;\n color: #2196f3;\n margin-bottom: 16px;\n display: block;\n}\n\n.loading-state p {\n margin: 0;\n font-size: 14px;\n color: #94a3b8;\n}\n\n.empty-state {\n text-align: center;\n padding: 60px 20px;\n color: #6c757d;\n}\n\n.empty-state i {\n font-size: 48px;\n color: #dee2e6;\n margin-bottom: 16px;\n}\n\n.empty-state h4 {\n color: #495057;\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.empty-state p {\n font-size: 15px;\n line-height: 1.6;\n max-width: 400px;\n margin: 0 auto;\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: rgba(255, 255, 255, 0.9);\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 #f3f3f3;\n border-top: 4px solid #2196f3;\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 #e0e6ed;\n}\n\n.quick-action-card {\n flex: 1;\n padding: 16px;\n background: #f8f9fa;\n border-radius: 8px;\n border: 1px solid #e0e6ed;\n cursor: pointer;\n transition: all 0.2s ease;\n text-align: center;\n}\n\n.quick-action-card:hover {\n background: white;\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: #2196f3;\n margin-bottom: 8px;\n}\n\n.quick-action-title {\n font-size: 14px;\n font-weight: 600;\n color: #495057;\n margin-bottom: 4px;\n}\n\n.quick-action-description {\n font-size: 12px;\n color: #6c757d;\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: #f8f9fa;\n border: 1px solid #e0e6ed;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.entity-item:hover {\n background: white;\n border-color: #2196f3;\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: linear-gradient(135deg, #e9ecef, #dee2e6);\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: linear-gradient(135deg, #20c997, #17a673);\n}\n\n.action-item .item-icon {\n background: linear-gradient(135deg, #ffc107, #e0a800);\n}\n\n.sub-agent-item .item-icon {\n background: linear-gradient(135deg, #2196f3, #1976d2);\n}\n\n.model-item .item-icon {\n background: linear-gradient(135deg, #6f42c1, #563d7c);\n}\n\n.learning-item .item-icon {\n background: linear-gradient(135deg, #e83e8c, #dc3545);\n}\n\n.note-item .item-icon {\n background: linear-gradient(135deg, #fd7e14, #e55a00);\n}\n\n.item-icon i {\n color: #6c757d;\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: white;\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: #2c3e50;\n margin: 0 0 4px 0;\n line-height: 1.3;\n}\n\n.item-preview {\n color: #6c757d;\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: #e9ecef;\n color: #495057;\n}\n\n.priority-tag {\n color: white;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.status-tag {\n background: #e9ecef;\n color: #495057;\n}\n\n.status-tag.active {\n background: #d4edda;\n color: #28a745;\n}\n\n.status-tag.inactive {\n background: #f8d7da;\n color: #dc3545;\n}\n\n.item-actions {\n opacity: 0;\n transition: opacity 0.2s ease;\n color: #6c757d;\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: #2196f3;\n}\n\n.view-more-item {\n padding: 16px;\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border: 2px dashed #dee2e6;\n border-radius: 10px;\n text-align: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #6c757d;\n font-weight: 500;\n}\n\n.view-more-item:hover {\n background: linear-gradient(135deg, #e9ecef, #dee2e6);\n border-color: #2196f3;\n color: #2196f3;\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: #2c3e50;\n margin: 0 0 16px 0;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.subsection-title i {\n color: #2196f3;\n}\n\n.subsection-divider {\n margin-top: 32px;\n margin-bottom: 16px;\n padding-top: 24px;\n border-top: 1px solid #e0e6ed;\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: #495057;\n margin-bottom: 8px;\n}\n\n.payload-field-label i {\n color: #6c757d;\n font-size: 16px;\n}\n\n.field-description {\n font-size: 12px;\n font-weight: normal;\n color: #6c757d;\n margin-left: auto;\n}\n\n/* Code editor styling */\n.payload-field-group mj-code-editor {\n border: 1px solid #dee2e6;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.payload-field-group mj-code-editor:hover {\n border-color: #2196f3;\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: #f8f9fa;\n border: 1px solid #e0e6ed;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.timeline-item:hover {\n background: white;\n border-color: #2196f3;\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: white;\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: #2c3e50;\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: #6c757d;\n background: #e9ecef;\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: #6c757d;\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: white;\n border: 1px solid #e0e6ed;\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: #2196f3;\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: linear-gradient(90deg, #2196f3, #42a5f5);\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: linear-gradient(135deg, #f8f9fa, #e9ecef);\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: linear-gradient(135deg, #2196f3, #1976d2);\n}\n\n.prompt-card .card-icon {\n background: linear-gradient(135deg, #20c997, #17a673);\n}\n\n.action-card .card-icon {\n background: linear-gradient(135deg, #ffc107, #e0a800);\n}\n\n.card-icon i {\n font-size: 18px;\n color: #6c757d;\n}\n\n.sub-agent-card .card-icon i,\n.prompt-card .card-icon i,\n.action-card .card-icon i {\n color: white;\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: #2c3e50;\n margin: 0 0 4px 0;\n line-height: 1.3;\n word-wrap: break-word;\n}\n\n.card-description {\n color: #6c757d;\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: #6c757d;\n padding: 4px 8px;\n background: #f8f9fa;\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: #28a745;\n background: #d4edda;\n}\n\n.meta-item.inactive {\n color: #dc3545;\n background: #f8d7da;\n}\n\n.card-actions {\n opacity: 0;\n transition: opacity 0.3s ease;\n color: #6c757d;\n}\n\n.entity-card:hover .card-actions {\n opacity: 1;\n color: #2196f3;\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: white;\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: #e9ecef;\n color: #495057;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* View All Card */\n.view-all-card {\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border: 2px dashed #dee2e6;\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: linear-gradient(135deg, #e9ecef, #dee2e6);\n border-color: #2196f3;\n transform: translateY(-2px);\n}\n\n.view-all-content {\n text-align: center;\n color: #6c757d;\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: #f8f9fa;\n border-color: #e0e6ed;\n}\n\n.timeline-item.expanded {\n background: #f8f9fa;\n border-color: #2196f3;\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.1);\n}\n\n.timeline-item.view-all {\n cursor: pointer;\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border: 2px dashed #dee2e6;\n}\n\n.timeline-item.view-all:hover {\n background: linear-gradient(135deg, #e9ecef, #dee2e6);\n border-color: #2196f3;\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: #e0e6ed;\n}\n\n.timeline-item:last-child .timeline-marker::after {\n display: none;\n}\n\n.timeline-marker i {\n color: white;\n font-size: 16px;\n}\n\n.timeline-marker.view-all-marker {\n background: #6c757d;\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: #6c757d;\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: #2c3e50;\n margin: 0;\n line-height: 1.3;\n}\n\n.timeline-date {\n font-size: 12px;\n color: #6c757d;\n white-space: nowrap;\n background: #f8f9fa;\n padding: 4px 8px;\n border-radius: 6px;\n margin-left: auto;\n}\n\n.timeline-preview {\n font-size: 13px;\n color: #6c757d;\n line-height: 1.5;\n margin-top: 8px;\n padding: 8px 12px;\n background: #f8f9fa;\n border-radius: 6px;\n border: 1px solid #e0e6ed;\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: #6c757d;\n background: #f8f9fa;\n padding: 4px 8px;\n border-radius: 6px;\n}\n\n.timeline-description {\n color: #6c757d;\n font-size: 14px;\n line-height: 1.5;\n margin: 8px 0;\n}\n\n.timeline-error {\n color: #dc3545;\n font-size: 13px;\n background: #f8d7da;\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 #e0e6ed;\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: #495057;\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-section h5 {\n color: #dc3545;\n}\n\n.result-content,\n.error-content {\n background: white;\n border: 1px solid #e0e6ed;\n border-radius: 8px;\n padding: 12px 16px;\n font-size: 14px;\n line-height: 1.6;\n color: #495057;\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 #e0e6ed;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.error-content {\n background: #f8d7da;\n border-color: #f5c6cb;\n color: #721c24;\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: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n min-width: 80px;\n}\n\n.detail-value {\n font-size: 14px;\n color: #495057;\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: #2196f3;\n color: white;\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: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.3);\n}\n\n.btn-primary i {\n font-size: 12px;\n}\n\n/* Enhanced Empty States */\n.empty-state {\n text-align: center;\n padding: 60px 20px;\n color: #6c757d;\n background: #f8f9fa;\n border-radius: 12px;\n border: 2px dashed #dee2e6;\n margin-top: 16px;\n}\n\n.empty-state i {\n font-size: 48px;\n color: #dee2e6;\n margin-bottom: 16px;\n}\n\n.empty-state h4 {\n color: #495057;\n font-weight: 600;\n margin-bottom: 8px;\n font-size: 18px;\n}\n\n.empty-state p {\n font-size: 15px;\n line-height: 1.6;\n max-width: 400px;\n margin: 0 auto 20px auto;\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: #f1f1f1;\n border-radius: 4px;\n}\n\n.execution-history-panel::-webkit-scrollbar-thumb {\n background: #c1c1c1;\n border-radius: 4px;\n}\n\n.execution-history-panel::-webkit-scrollbar-thumb:hover {\n background: #a0a0a0;\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: 16px;\n}\n\n.execution-card {\n background: white;\n border: 1px solid #e0e6ed;\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: #2196f3;\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.1);\n transform: translateY(-1px);\n}\n\n.execution-card.expanded {\n border-color: #2196f3;\n box-shadow: 0 6px 20px rgba(33, 150, 243, 0.15);\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: white;\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: #2c3e50;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.execution-date {\n font-size: 12px;\n color: #6c757d;\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: #f8f9fa;\n padding: 6px 10px;\n border-radius: 6px;\n color: #495057;\n white-space: nowrap;\n}\n\n.metric-item i {\n color: #6c757d;\n font-size: 12px;\n}\n\n.metric-label {\n font-weight: 500;\n}\n\n.metric-value {\n font-weight: 600;\n color: #2c3e50;\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: #f8f9fa;\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: #6c757d;\n}\n\n.action-btn:hover {\n background: #2196f3;\n color: white;\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: #6c757d;\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 #f0f4f8;\n background: #fafbfc;\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: white;\n border: 1px solid #e0e6ed;\n border-radius: 8px;\n}\n\n.metric-detail i {\n color: #2196f3;\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: #6c757d;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.metric-data {\n font-size: 14px;\n font-weight: 600;\n color: #2c3e50;\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: #495057;\n margin-bottom: 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-section h5 {\n color: #dc3545;\n}\n\n.error-content {\n background: #f8d7da;\n border: 1px solid #f5c6cb;\n border-radius: 8px;\n padding: 12px 16px;\n font-size: 14px;\n line-height: 1.6;\n color: #721c24;\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: white;\n border-radius: 12px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n}\n\n.payload-section-title {\n margin: 0;\n padding: 1rem 1.5rem;\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border-bottom: 1px solid #e0e0e0;\n color: #495057;\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: #2196f3;\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: #495057;\n font-size: 0.95rem;\n}\n\n.payload-field-description {\n color: #6c757d;\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: #6c757d;\n background: #f8f9fa;\n padding: 0.5rem 0.75rem;\n border-radius: 6px;\n border: 1px solid #e9ecef;\n}\n\n.payload-field-example i {\n color: #ffc107;\n font-size: 0.9rem;\n}\n\n.payload-field-example code {\n background: #e9ecef;\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: #495057;\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: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.2s ease;\n}\n\n.payload-path-card:hover {\n border-color: #2196f3;\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.15);\n}\n\n.payload-path-header {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border-bottom: 1px solid #e0e0e0;\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: linear-gradient(135deg, #28a745, #20c997);\n}\n\n.payload-path-icon.upstream {\n background: linear-gradient(135deg, #007bff, #6610f2);\n}\n\n.payload-path-icon.self-read {\n background: linear-gradient(135deg, #17a2b8, #20c997);\n}\n\n.payload-path-icon.self-write {\n background: linear-gradient(135deg, #ffc107, #fd7e14);\n}\n\n.payload-path-icon i {\n color: white;\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: #495057;\n}\n\n.payload-path-info p {\n margin: 0;\n font-size: 0.85rem;\n color: #6c757d;\n line-height: 1.4;\n}\n\n.payload-path-content {\n padding: 1rem;\n}\n\n.json-editor-container {\n border: 1px solid #dee2e6;\n border-radius: 6px;\n overflow: hidden;\n margin-bottom: 0.75rem;\n}\n\n.json-editor-container:hover {\n border-color: #2196f3;\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: #6c757d;\n line-height: 1.4;\n}\n\n.payload-path-hint i {\n color: #17a2b8;\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.payload-path-hint code {\n background: #e9ecef;\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: #495057;\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: #495057;\n font-size: 0.95rem;\n}\n\n.validation-field-description {\n color: #6c757d;\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: #495057;\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: #2196f3;\n}\n\n.validation-schema-description {\n color: #6c757d;\n font-size: 0.9rem;\n line-height: 1.4;\n margin: 0;\n}\n\n.validation-schema-editor {\n border: 1px solid #dee2e6;\n border-radius: 6px;\n overflow: hidden;\n}\n\n.validation-schema-editor:hover {\n border-color: #2196f3;\n}\n\n/* === CONFIGURATION SECTION === */\n.config-section {\n margin-bottom: 2rem;\n background: white;\n border-radius: 12px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n}\n\n.config-section-title {\n margin: 0;\n padding: 1rem 1.5rem;\n background: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border-bottom: 1px solid #e0e0e0;\n color: #495057;\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: #2196f3;\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: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.2s ease;\n}\n\n.config-card:hover {\n border-color: #2196f3;\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.15);\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: linear-gradient(135deg, #f8f9fa, #e9ecef);\n border-bottom: 1px solid #e0e0e0;\n}\n\n.config-card-icon {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n background: linear-gradient(135deg, #2196f3, #1976d2);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.config-card-icon i {\n color: white;\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: #495057;\n}\n\n.config-card-info p {\n margin: 0;\n font-size: 0.85rem;\n color: #6c757d;\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/* Fix numeric textbox cutoff issue */\n.config-card-content ::ng-deep kendo-numerictextbox {\n width: 100% !important;\n}\n\n.config-card-content ::ng-deep kendo-numerictextbox .k-numerictextbox {\n width: 100% !important;\n}\n\n.config-card-content ::ng-deep kendo-numerictextbox .k-input {\n width: 100% !important;\n min-width: 200px !important;\n}\n\n.config-card-content ::ng-deep mj-form-field {\n width: 100% !important;\n}\n\n.config-card-content ::ng-deep mj-form-field kendo-numerictextbox {\n width: 100% !important;\n}\n\n.config-card-content ::ng-deep mj-form-field kendo-numerictextbox .k-numerictextbox {\n width: 100% !important;\n}\n\n.config-card-content ::ng-deep mj-form-field kendo-numerictextbox .k-input {\n width: 100% !important;\n min-width: 200px !important;\n}\n\n.config-field-display {\n color: #495057;\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: #f8f9fa;\n border: 1px solid #dee2e6;\n border-radius: 6px;\n}\n\n.prompt-name {\n color: #495057;\n font-weight: 500;\n font-size: 14px;\n}\n\n.no-prompt {\n color: #6c757d;\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: #6c757d;\n line-height: 1.4;\n margin-top: 0.5rem;\n}\n\n.config-card-hint i {\n color: #17a2b8;\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.config-card-hint code {\n background: #e9ecef;\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: #495057;\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"] }]
3832
3779
  }], () => [{ type: i0.ElementRef }, { type: i1.SharedService }, { type: i2.Router }, { type: i2.ActivatedRoute }, { type: i0.ChangeDetectorRef }, { type: i3.DialogService }, { type: i0.ViewContainerRef }, { type: i4.AIAgentManagementService }, { type: i5.AITestHarnessDialogService }], { customSectionContainer: [{
3833
3780
  type: ViewChild,
3834
3781
  args: ['customSectionContainer', { read: ViewContainerRef }]
3835
3782
  }] }); })();
3836
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AIAgentFormComponentExtended, { className: "AIAgentFormComponentExtended", filePath: "src/lib/custom/AIAgents/ai-agent-form.component.ts", lineNumber: 54 }); })();
3783
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AIAgentFormComponentExtended, { className: "AIAgentFormComponentExtended", filePath: "src/lib/custom/AIAgents/ai-agent-form.component.ts", lineNumber: 58 }); })();
3837
3784
  export function LoadAIAgentFormComponentExtended() {
3838
3785
  // This function is called to ensure the component is loaded and registered
3839
3786
  }