@memberjunction/ai-agent-manager 6.1.4 → 6.2.0-edge.1

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.
@@ -51,6 +51,14 @@ import { UUIDsEqual } from '@memberjunction/global';
51
51
  * @module @memberjunction/ai-agent-manager
52
52
  */
53
53
  export class AgentSpecSync {
54
+ /** @deprecated Use {@link Spec}. */
55
+ get spec() {
56
+ return this.Spec;
57
+ }
58
+ /** @deprecated Use {@link Spec}. */
59
+ set spec(value) {
60
+ this.Spec = value;
61
+ }
54
62
  /**
55
63
  * Returns the metadata provider to use for entity operations. Prefers a
56
64
  * caller-supplied provider for server isolation; otherwise falls back to
@@ -87,12 +95,12 @@ export class AgentSpecSync {
87
95
  */
88
96
  this._mutations = [];
89
97
  if (spec) {
90
- this.spec = this.initializeSpec(spec);
98
+ this.Spec = this.initializeSpec(spec);
91
99
  this._isDirty = true;
92
100
  }
93
101
  else {
94
102
  // Create minimal empty spec
95
- this.spec = {
103
+ this.Spec = {
96
104
  ID: '', // Will be set on save if empty
97
105
  Name: '',
98
106
  StartingPayloadValidationMode: 'Fail',
@@ -120,15 +128,23 @@ export class AgentSpecSync {
120
128
  * Get all mutations tracked during the last save operation
121
129
  * @returns Array of mutations
122
130
  */
123
- getMutations() {
131
+ GetMutations() {
124
132
  return [...this._mutations];
125
133
  }
134
+ /** @deprecated Use {@link GetMutations}. */
135
+ getMutations() {
136
+ return this.GetMutations();
137
+ }
126
138
  /**
127
139
  * Clear all tracked mutations
128
140
  */
129
- clearMutations() {
141
+ ClearMutations() {
130
142
  this._mutations = [];
131
143
  }
144
+ /** @deprecated Use {@link ClearMutations}. */
145
+ clearMutations() {
146
+ return this.ClearMutations();
147
+ }
132
148
  // ===== STATIC FACTORY METHODS =====
133
149
  /**
134
150
  * Load an agent and its complete hierarchy from the database by ID.
@@ -342,11 +358,11 @@ export class AgentSpecSync {
342
358
  };
343
359
  }
344
360
  // Step 3: Map entities to raw spec format
345
- this.spec = this.mapEntitiesToRawSpec(agentEntity, actionsResult.Results || [], childAgentsResult.Results || [], relatedAgentsResult.Results || [], promptsResult.Results || [], fullPromptsResult.Results || [], stepsResult.Results || [], pathsResult.Results || []);
361
+ this.Spec = this.mapEntitiesToRawSpec(agentEntity, actionsResult.Results || [], childAgentsResult.Results || [], relatedAgentsResult.Results || [], promptsResult.Results || [], fullPromptsResult.Results || [], stepsResult.Results || [], pathsResult.Results || []);
346
362
  // Step 4: Recursively load sub-agents if requested
347
- if (includeSubAgents && this.spec.SubAgents && this.spec.SubAgents.length > 0) {
363
+ if (includeSubAgents && this.Spec.SubAgents && this.Spec.SubAgents.length > 0) {
348
364
  // Recursively load complete specs for all sub-agents
349
- for (const subAgentSpec of this.spec.SubAgents) {
365
+ for (const subAgentSpec of this.Spec.SubAgents) {
350
366
  if (subAgentSpec.SubAgent && subAgentSpec.SubAgent.ID) {
351
367
  try {
352
368
  // Load the complete sub-agent spec recursively
@@ -604,22 +620,22 @@ export class AgentSpecSync {
604
620
  */
605
621
  async SaveToDatabase(validate = true) {
606
622
  // Clear previous mutations
607
- this.clearMutations();
623
+ this.ClearMutations();
608
624
  if (!this._isDirty && this._isLoaded) {
609
625
  // No changes to save
610
626
  return {
611
- agentId: this.spec.ID,
627
+ agentId: this.Spec.ID,
612
628
  success: true,
613
629
  mutations: []
614
630
  };
615
631
  }
616
632
  try {
617
633
  // Step 0: Delete orphaned records (if this is an update)
618
- if (this._isLoaded && this.spec.ID) {
619
- console.log(`🗑️ SaveToDatabase: Loading current database state for agent ${this.spec.ID}...`);
620
- const dbState = await this.loadCurrentDatabaseState(this.spec.ID);
634
+ if (this._isLoaded && this.Spec.ID) {
635
+ console.log(`🗑️ SaveToDatabase: Loading current database state for agent ${this.Spec.ID}...`);
636
+ const dbState = await this.loadCurrentDatabaseState(this.Spec.ID);
621
637
  console.log(`🔍 SaveToDatabase: Identifying orphaned records...`);
622
- const orphans = this.identifyOrphans(dbState, this.spec);
638
+ const orphans = this.identifyOrphans(dbState, this.Spec);
623
639
  console.log(`🗑️ SaveToDatabase: Deleting ${orphans.paths.length} paths, ${orphans.actions.length} actions, ${orphans.steps.length} steps, ${orphans.prompts.length} prompts, ${orphans.relationships.length} relationships, orphaning ${orphans.childAgents.length} child agents...`);
624
640
  await this.deleteOrphans(orphans);
625
641
  console.log(`✅ SaveToDatabase: Orphan cleanup complete`);
@@ -641,15 +657,15 @@ export class AgentSpecSync {
641
657
  return {
642
658
  agentId,
643
659
  success: true,
644
- mutations: this.getMutations()
660
+ mutations: this.GetMutations()
645
661
  };
646
662
  }
647
663
  catch (error) {
648
664
  // Return failure with whatever mutations were completed before error
649
665
  return {
650
- agentId: this.spec.ID || '',
666
+ agentId: this.Spec.ID || '',
651
667
  success: false,
652
- mutations: this.getMutations()
668
+ mutations: this.GetMutations()
653
669
  };
654
670
  }
655
671
  }
@@ -665,69 +681,69 @@ export class AgentSpecSync {
665
681
  const md = this.providerToUse;
666
682
  const agentEntity = await md.GetEntityObject('MJ: AI Agents', this._contextUser);
667
683
  // Track if this is an update or create
668
- const isUpdate = !!this.spec.ID;
684
+ const isUpdate = !!this.Spec.ID;
669
685
  // If ID exists, load existing record
670
- if (this.spec.ID) {
671
- const loaded = await agentEntity.Load(this.spec.ID);
686
+ if (this.Spec.ID) {
687
+ const loaded = await agentEntity.Load(this.Spec.ID);
672
688
  if (!loaded) {
673
- throw new Error(`Cannot update non-existent agent with ID ${this.spec.ID}`);
689
+ throw new Error(`Cannot update non-existent agent with ID ${this.Spec.ID}`);
674
690
  }
675
691
  }
676
692
  // Map spec to entity fields
677
- agentEntity.Name = this.spec.Name;
678
- agentEntity.Description = this.spec.Description || null;
679
- agentEntity.IconClass = this.spec.IconClass || null;
680
- agentEntity.LogoURL = this.spec.LogoURL || null;
681
- agentEntity.ParentID = this.spec.ParentID || null;
682
- agentEntity.DriverClass = this.spec.DriverClass || null;
683
- agentEntity.ModelSelectionMode = this.spec.ModelSelectionMode || 'Agent Type';
693
+ agentEntity.Name = this.Spec.Name;
694
+ agentEntity.Description = this.Spec.Description || null;
695
+ agentEntity.IconClass = this.Spec.IconClass || null;
696
+ agentEntity.LogoURL = this.Spec.LogoURL || null;
697
+ agentEntity.ParentID = this.Spec.ParentID || null;
698
+ agentEntity.DriverClass = this.Spec.DriverClass || null;
699
+ agentEntity.ModelSelectionMode = this.Spec.ModelSelectionMode || 'Agent Type';
684
700
  // Handle TypeID - supports lookup references or direct GUID
685
- if (this.spec.TypeID) {
686
- agentEntity.TypeID = this.spec.TypeID;
701
+ if (this.Spec.TypeID) {
702
+ agentEntity.TypeID = this.Spec.TypeID;
687
703
  }
688
704
  // Handle Status - defaults to Active if not specified. Typed rather than cast: the cast is
689
705
  // what let `'Inactive'` — a value the CHECK constraint rejects — reach the entity unchallenged.
690
- agentEntity.Status = this.spec.Status ?? 'Active';
706
+ agentEntity.Status = this.Spec.Status ?? 'Active';
691
707
  // Serialize JSON fields
692
- agentEntity.PayloadDownstreamPaths = JSON.stringify(this.spec.PayloadDownstreamPaths || ['*']);
693
- agentEntity.PayloadUpstreamPaths = JSON.stringify(this.spec.PayloadUpstreamPaths || ['*']);
694
- agentEntity.PayloadSelfReadPaths = this.spec.PayloadSelfReadPaths
695
- ? JSON.stringify(this.spec.PayloadSelfReadPaths)
708
+ agentEntity.PayloadDownstreamPaths = JSON.stringify(this.Spec.PayloadDownstreamPaths || ['*']);
709
+ agentEntity.PayloadUpstreamPaths = JSON.stringify(this.Spec.PayloadUpstreamPaths || ['*']);
710
+ agentEntity.PayloadSelfReadPaths = this.Spec.PayloadSelfReadPaths
711
+ ? JSON.stringify(this.Spec.PayloadSelfReadPaths)
696
712
  : null;
697
- agentEntity.PayloadSelfWritePaths = this.spec.PayloadSelfWritePaths
698
- ? JSON.stringify(this.spec.PayloadSelfWritePaths)
713
+ agentEntity.PayloadSelfWritePaths = this.Spec.PayloadSelfWritePaths
714
+ ? JSON.stringify(this.Spec.PayloadSelfWritePaths)
699
715
  : null;
700
- agentEntity.PayloadScope = this.spec.PayloadScope || null;
716
+ agentEntity.PayloadScope = this.Spec.PayloadScope || null;
701
717
  // Validation fields
702
- agentEntity.FinalPayloadValidation = this.spec.FinalPayloadValidation || null;
703
- agentEntity.FinalPayloadValidationMode = this.spec.FinalPayloadValidationMode || 'Retry';
704
- agentEntity.FinalPayloadValidationMaxRetries = this.spec.FinalPayloadValidationMaxRetries || 3;
705
- agentEntity.StartingPayloadValidation = this.spec.StartingPayloadValidation || null;
706
- agentEntity.StartingPayloadValidationMode = this.spec.StartingPayloadValidationMode || 'Fail';
718
+ agentEntity.FinalPayloadValidation = this.Spec.FinalPayloadValidation || null;
719
+ agentEntity.FinalPayloadValidationMode = this.Spec.FinalPayloadValidationMode || 'Retry';
720
+ agentEntity.FinalPayloadValidationMaxRetries = this.Spec.FinalPayloadValidationMaxRetries || 3;
721
+ agentEntity.StartingPayloadValidation = this.Spec.StartingPayloadValidation || null;
722
+ agentEntity.StartingPayloadValidationMode = this.Spec.StartingPayloadValidationMode || 'Fail';
707
723
  // Resource limits
708
- agentEntity.MaxCostPerRun = this.spec.MaxCostPerRun || null;
709
- agentEntity.MaxTokensPerRun = this.spec.MaxTokensPerRun || null;
710
- agentEntity.MaxIterationsPerRun = this.spec.MaxIterationsPerRun || null;
711
- agentEntity.MaxTimePerRun = this.spec.MaxTimePerRun || null;
724
+ agentEntity.MaxCostPerRun = this.Spec.MaxCostPerRun || null;
725
+ agentEntity.MaxTokensPerRun = this.Spec.MaxTokensPerRun || null;
726
+ agentEntity.MaxIterationsPerRun = this.Spec.MaxIterationsPerRun || null;
727
+ agentEntity.MaxTimePerRun = this.Spec.MaxTimePerRun || null;
712
728
  // Execution frequency
713
- agentEntity.MinExecutionsPerRun = this.spec.MinExecutionsPerRun || null;
714
- agentEntity.MaxExecutionsPerRun = this.spec.MaxExecutionsPerRun || null;
729
+ agentEntity.MinExecutionsPerRun = this.Spec.MinExecutionsPerRun || null;
730
+ agentEntity.MaxExecutionsPerRun = this.Spec.MaxExecutionsPerRun || null;
715
731
  // Other config
716
- agentEntity.DefaultPromptEffortLevel = this.spec.DefaultPromptEffortLevel || null;
717
- agentEntity.ChatHandlingOption = this.spec.ChatHandlingOption || null;
718
- agentEntity.DefaultArtifactTypeID = this.spec.DefaultArtifactTypeID || null;
732
+ agentEntity.DefaultPromptEffortLevel = this.Spec.DefaultPromptEffortLevel || null;
733
+ agentEntity.ChatHandlingOption = this.Spec.ChatHandlingOption || null;
734
+ agentEntity.DefaultArtifactTypeID = this.Spec.DefaultArtifactTypeID || null;
719
735
  // Set OwnerUserID - always use contextUser if available (user creating/modifying the agent)
720
736
  if (this._contextUser) {
721
737
  agentEntity.OwnerUserID = this._contextUser.ID;
722
738
  }
723
- else if (this.spec.OwnerUserID) {
739
+ else if (this.Spec.OwnerUserID) {
724
740
  // Fallback to spec value if no contextUser provided
725
- agentEntity.OwnerUserID = this.spec.OwnerUserID;
741
+ agentEntity.OwnerUserID = this.Spec.OwnerUserID;
726
742
  }
727
- agentEntity.InvocationMode = this.spec.InvocationMode || 'Any';
743
+ agentEntity.InvocationMode = this.Spec.InvocationMode || 'Any';
728
744
  // Requirements and design documentation
729
- agentEntity.FunctionalRequirements = this.spec.FunctionalRequirements || null;
730
- agentEntity.TechnicalDesign = this.spec.TechnicalDesign || null;
745
+ agentEntity.FunctionalRequirements = this.Spec.FunctionalRequirements || null;
746
+ agentEntity.TechnicalDesign = this.Spec.TechnicalDesign || null;
731
747
  // Validate if requested
732
748
  if (validate) {
733
749
  const validation = agentEntity.Validate();
@@ -742,9 +758,9 @@ export class AgentSpecSync {
742
758
  throw new Error('Failed to save agent entity');
743
759
  }
744
760
  // Update spec with saved ID
745
- this.spec.ID = agentEntity.ID;
761
+ this.Spec.ID = agentEntity.ID;
746
762
  // Track the mutation
747
- this.trackMutation('MJ: AI Agents', isUpdate ? 'Update' : 'Create', agentEntity.ID, `${isUpdate ? 'Updated' : 'Created'} agent: ${this.spec.Name}`);
763
+ this.trackMutation('MJ: AI Agents', isUpdate ? 'Update' : 'Create', agentEntity.ID, `${isUpdate ? 'Updated' : 'Created'} agent: ${this.Spec.Name}`);
748
764
  return agentEntity.ID;
749
765
  }
750
766
  /**
@@ -759,11 +775,11 @@ export class AgentSpecSync {
759
775
  * @throws {Error} If any action save fails
760
776
  */
761
777
  async saveActions(agentId) {
762
- if (!this.spec.Actions || this.spec.Actions.length === 0) {
778
+ if (!this.Spec.Actions || this.Spec.Actions.length === 0) {
763
779
  return;
764
780
  }
765
781
  const md = this.providerToUse;
766
- for (const actionSpec of this.spec.Actions) {
782
+ for (const actionSpec of this.Spec.Actions) {
767
783
  const actionEntity = await md.GetEntityObject('MJ: AI Agent Actions', this._contextUser);
768
784
  // Track if this is an update or create
769
785
  const isUpdate = !!actionSpec.AgentActionID;
@@ -803,10 +819,10 @@ export class AgentSpecSync {
803
819
  * @throws {Error} If any sub-agent save fails
804
820
  */
805
821
  async saveSubAgents(agentId) {
806
- if (!this.spec.SubAgents || this.spec.SubAgents.length === 0) {
822
+ if (!this.Spec.SubAgents || this.Spec.SubAgents.length === 0) {
807
823
  return;
808
824
  }
809
- for (const SubAgentSpec of this.spec.SubAgents) {
825
+ for (const SubAgentSpec of this.Spec.SubAgents) {
810
826
  if (SubAgentSpec.Type === 'child') {
811
827
  await this.saveChildSubAgent(agentId, SubAgentSpec);
812
828
  }
@@ -928,17 +944,17 @@ export class AgentSpecSync {
928
944
  * @throws {Error} If any prompt save fails
929
945
  */
930
946
  async savePrompts(agentId) {
931
- console.log(`💬 savePrompts: Called with agentId=${agentId}, Prompts=${this.spec.Prompts ? this.spec.Prompts.length : 'undefined'}`);
932
- if (!this.spec.Prompts || this.spec.Prompts.length === 0) {
947
+ console.log(`💬 savePrompts: Called with agentId=${agentId}, Prompts=${this.Spec.Prompts ? this.Spec.Prompts.length : 'undefined'}`);
948
+ if (!this.Spec.Prompts || this.Spec.Prompts.length === 0) {
933
949
  console.log('💬 savePrompts: No prompts to save, returning early');
934
950
  return;
935
951
  }
936
- console.log(`💬 savePrompts: Processing ${this.spec.Prompts.length} prompt(s)...`);
952
+ console.log(`💬 savePrompts: Processing ${this.Spec.Prompts.length} prompt(s)...`);
937
953
  const md = this.providerToUse;
938
954
  const rv = RunView.FromMetadataProvider(this._provider);
939
955
  // Step 1: Create or update AIPrompt records
940
- for (let i = 0; i < this.spec.Prompts.length; i++) {
941
- const promptSpec = this.spec.Prompts[i];
956
+ for (let i = 0; i < this.Spec.Prompts.length; i++) {
957
+ const promptSpec = this.Spec.Prompts[i];
942
958
  // Check if this is an update (has PromptID) or create (no PromptID)
943
959
  let promptEntity = await md.GetEntityObject('MJ: AI Prompts', this._contextUser);
944
960
  let isUpdate = false;
@@ -954,8 +970,8 @@ export class AgentSpecSync {
954
970
  }
955
971
  }
956
972
  // Set all required fields (both create and update)
957
- promptEntity.Name = `${this.spec.Name} - Prompt ${i + 1}`;
958
- promptEntity.Description = `Agent prompt ${i + 1} for ${this.spec.Name}`;
973
+ promptEntity.Name = `${this.Spec.Name} - Prompt ${i + 1}`;
974
+ promptEntity.Description = `Agent prompt ${i + 1} for ${this.Spec.Name}`;
959
975
  promptEntity.TypeID = 'a6da423e-f36b-1410-8dac-00021f8b792e'; // Chat type
960
976
  promptEntity.Status = 'Active';
961
977
  promptEntity.ResponseFormat = 'JSON';
@@ -981,7 +997,7 @@ export class AgentSpecSync {
981
997
  }
982
998
  const saved = await promptEntity.Save();
983
999
  if (!saved) {
984
- throw new Error(`Failed to save prompt ${i + 1} for agent ${this.spec.Name}`);
1000
+ throw new Error(`Failed to save prompt ${i + 1} for agent ${this.Spec.Name}`);
985
1001
  }
986
1002
  // Track mutation
987
1003
  this.trackMutation('MJ: AI Prompts', isUpdate ? 'Update' : 'Create', promptEntity.ID, `${isUpdate ? 'Updated' : 'Created'} prompt: ${promptEntity.Name}`);
@@ -1021,7 +1037,7 @@ export class AgentSpecSync {
1021
1037
  this.trackMutation('MJ: AI Agent Prompts', isJunctionUpdate ? 'Update' : 'Create', agentPromptEntity.ID, `${isJunctionUpdate ? 'Updated' : 'Created'} agent-prompt junction for prompt ${promptEntity.ID}`);
1022
1038
  console.log(`✅ savePrompts: ${isJunctionUpdate ? 'Updated' : 'Created'} AIAgentPrompt junction with ID: ${agentPromptEntity.ID}`);
1023
1039
  }
1024
- console.log(`✅ savePrompts: Successfully saved all ${this.spec.Prompts.length} prompt(s)`);
1040
+ console.log(`✅ savePrompts: Successfully saved all ${this.Spec.Prompts.length} prompt(s)`);
1025
1041
  }
1026
1042
  /**
1027
1043
  * Save all steps for this agent (Flow agents only).
@@ -1034,14 +1050,14 @@ export class AgentSpecSync {
1034
1050
  * @throws {Error} If any step save fails
1035
1051
  */
1036
1052
  async saveSteps(agentId) {
1037
- console.log(`🔷 saveSteps: Called with agentId=${agentId}, Steps=${this.spec.Steps ? this.spec.Steps.length : 'undefined'}`);
1038
- if (!this.spec.Steps || this.spec.Steps.length === 0) {
1053
+ console.log(`🔷 saveSteps: Called with agentId=${agentId}, Steps=${this.Spec.Steps ? this.Spec.Steps.length : 'undefined'}`);
1054
+ if (!this.Spec.Steps || this.Spec.Steps.length === 0) {
1039
1055
  console.log('🔷 saveSteps: No steps to save, returning early');
1040
1056
  return;
1041
1057
  }
1042
- console.log(`🔷 saveSteps: Processing ${this.spec.Steps.length} step(s)...`);
1058
+ console.log(`🔷 saveSteps: Processing ${this.Spec.Steps.length} step(s)...`);
1043
1059
  const md = this.providerToUse;
1044
- for (const stepSpec of this.spec.Steps) {
1060
+ for (const stepSpec of this.Spec.Steps) {
1045
1061
  const stepEntity = await md.GetEntityObject('MJ: AI Agent Steps', this._contextUser);
1046
1062
  // Load existing if ID provided
1047
1063
  const isUpdate = !!(stepSpec.ID && stepSpec.ID !== '');
@@ -1116,7 +1132,7 @@ export class AgentSpecSync {
1116
1132
  }
1117
1133
  const saved = await stepEntity.Save();
1118
1134
  if (!saved) {
1119
- throw new Error(`Failed to save step "${stepSpec.Name}" for agent ${this.spec.Name}`);
1135
+ throw new Error(`Failed to save step "${stepSpec.Name}" for agent ${this.Spec.Name}`);
1120
1136
  }
1121
1137
  // Track mutation
1122
1138
  this.trackMutation('AI Agent Steps', isUpdate ? 'Update' : 'Create', stepEntity.ID, `${isUpdate ? 'Updated' : 'Created'} step: ${stepSpec.Name}`);
@@ -1124,7 +1140,7 @@ export class AgentSpecSync {
1124
1140
  stepSpec.ID = stepEntity.ID;
1125
1141
  console.log(`✅ saveSteps: Created AIAgentStep with ID: ${stepEntity.ID}`);
1126
1142
  }
1127
- console.log(`✅ saveSteps: Successfully saved all ${this.spec.Steps.length} step(s)`);
1143
+ console.log(`✅ saveSteps: Successfully saved all ${this.Spec.Steps.length} step(s)`);
1128
1144
  }
1129
1145
  /**
1130
1146
  * Save all step paths for this agent (Flow agents only).
@@ -1137,23 +1153,23 @@ export class AgentSpecSync {
1137
1153
  * @throws {Error} If any path save fails
1138
1154
  */
1139
1155
  async saveStepPaths(agentId) {
1140
- console.log(`🔶 saveStepPaths: Called with agentId=${agentId}, Paths=${this.spec.Paths ? this.spec.Paths.length : 'undefined'}`);
1141
- if (!this.spec.Paths || this.spec.Paths.length === 0) {
1156
+ console.log(`🔶 saveStepPaths: Called with agentId=${agentId}, Paths=${this.Spec.Paths ? this.Spec.Paths.length : 'undefined'}`);
1157
+ if (!this.Spec.Paths || this.Spec.Paths.length === 0) {
1142
1158
  console.log('🔶 saveStepPaths: No paths to save, returning early');
1143
1159
  return;
1144
1160
  }
1145
- console.log(`🔶 saveStepPaths: Processing ${this.spec.Paths.length} path(s)...`);
1161
+ console.log(`🔶 saveStepPaths: Processing ${this.Spec.Paths.length} path(s)...`);
1146
1162
  const md = this.providerToUse;
1147
1163
  // Create a map of step names to IDs for easy lookup
1148
1164
  const stepNameToId = new Map();
1149
- if (this.spec.Steps) {
1150
- for (const step of this.spec.Steps) {
1165
+ if (this.Spec.Steps) {
1166
+ for (const step of this.Spec.Steps) {
1151
1167
  if (step.ID) {
1152
1168
  stepNameToId.set(step.Name, step.ID);
1153
1169
  }
1154
1170
  }
1155
1171
  }
1156
- for (const pathSpec of this.spec.Paths) {
1172
+ for (const pathSpec of this.Spec.Paths) {
1157
1173
  const pathEntity = await md.GetEntityObject('MJ: AI Agent Step Paths', this._contextUser);
1158
1174
  // Load existing if ID provided
1159
1175
  const isUpdate = !!(pathSpec.ID && pathSpec.ID !== '');
@@ -1188,7 +1204,7 @@ export class AgentSpecSync {
1188
1204
  pathSpec.ID = pathEntity.ID;
1189
1205
  console.log(`✅ saveStepPaths: Created AIAgentStepPath with ID: ${pathEntity.ID}`);
1190
1206
  }
1191
- console.log(`✅ saveStepPaths: Successfully saved all ${this.spec.Paths.length} path(s)`);
1207
+ console.log(`✅ saveStepPaths: Successfully saved all ${this.Spec.Paths.length} path(s)`);
1192
1208
  }
1193
1209
  // ===== UTILITY METHODS =====
1194
1210
  /**
@@ -1283,24 +1299,32 @@ export class AgentSpecSync {
1283
1299
  * ```
1284
1300
  */
1285
1301
  toJSON() {
1286
- return { ...this.spec };
1302
+ return { ...this.Spec };
1287
1303
  }
1288
1304
  /**
1289
1305
  * Check if this spec has unsaved changes.
1290
1306
  *
1291
1307
  * @returns True if there are unsaved changes, false otherwise
1292
1308
  */
1293
- get isDirty() {
1309
+ get IsDirty() {
1294
1310
  return this._isDirty;
1295
1311
  }
1312
+ /** @deprecated Use {@link IsDirty}. */
1313
+ get isDirty() {
1314
+ return this.IsDirty;
1315
+ }
1296
1316
  /**
1297
1317
  * Check if this spec has been loaded from the database.
1298
1318
  *
1299
1319
  * @returns True if loaded from database, false if created in memory
1300
1320
  */
1301
- get isLoaded() {
1321
+ get IsLoaded() {
1302
1322
  return this._isLoaded;
1303
1323
  }
1324
+ /** @deprecated Use {@link IsLoaded}. */
1325
+ get isLoaded() {
1326
+ return this.IsLoaded;
1327
+ }
1304
1328
  /**
1305
1329
  * Mark the spec as having changes.
1306
1330
  *
@@ -1316,9 +1340,13 @@ export class AgentSpecSync {
1316
1340
  * await spec.SaveToDatabase();
1317
1341
  * ```
1318
1342
  */
1319
- markDirty() {
1343
+ MarkDirty() {
1320
1344
  this._isDirty = true;
1321
1345
  }
1346
+ /** @deprecated Use {@link MarkDirty}. */
1347
+ markDirty() {
1348
+ return this.MarkDirty();
1349
+ }
1322
1350
  /**
1323
1351
  * Mark the spec as having been loaded from the database.
1324
1352
  *
@@ -1336,9 +1364,13 @@ export class AgentSpecSync {
1336
1364
  * await childSync.SaveToDatabase();
1337
1365
  * ```
1338
1366
  */
1339
- markLoaded() {
1367
+ MarkLoaded() {
1340
1368
  this._isLoaded = true;
1341
1369
  }
1370
+ /** @deprecated Use {@link MarkLoaded}. */
1371
+ markLoaded() {
1372
+ return this.MarkLoaded();
1373
+ }
1342
1374
  // ===== DELETE/ORPHAN METHODS =====
1343
1375
  /**
1344
1376
  * Load the current state of all agent-related records from the database.