@memberjunction/ai-agents 6.2.0-edge.0 → 6.2.0-edge.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +43 -0
  2. package/dist/AgentDataPreloader.d.ts +4 -0
  3. package/dist/AgentDataPreloader.d.ts.map +1 -1
  4. package/dist/AgentDataPreloader.js +10 -2
  5. package/dist/AgentDataPreloader.js.map +1 -1
  6. package/dist/AgentDecisionService.d.ts +83 -0
  7. package/dist/AgentDecisionService.d.ts.map +1 -0
  8. package/dist/AgentDecisionService.js +155 -0
  9. package/dist/AgentDecisionService.js.map +1 -0
  10. package/dist/AgentRunner.d.ts +16 -4
  11. package/dist/AgentRunner.d.ts.map +1 -1
  12. package/dist/AgentRunner.js +55 -32
  13. package/dist/AgentRunner.js.map +1 -1
  14. package/dist/ArtifactToolManager.d.ts +4 -4
  15. package/dist/ArtifactToolManager.js +10 -10
  16. package/dist/ConversationToolManager.d.ts +16 -3
  17. package/dist/ConversationToolManager.d.ts.map +1 -1
  18. package/dist/ConversationToolManager.js +28 -5
  19. package/dist/ConversationToolManager.js.map +1 -1
  20. package/dist/KnowledgeAgent.d.ts.map +1 -1
  21. package/dist/KnowledgeAgent.js +6 -6
  22. package/dist/KnowledgeAgent.js.map +1 -1
  23. package/dist/PayloadChangeAnalyzer.d.ts +4 -0
  24. package/dist/PayloadChangeAnalyzer.d.ts.map +1 -1
  25. package/dist/PayloadChangeAnalyzer.js +10 -2
  26. package/dist/PayloadChangeAnalyzer.js.map +1 -1
  27. package/dist/PayloadFeedbackManager.d.ts +120 -13
  28. package/dist/PayloadFeedbackManager.d.ts.map +1 -1
  29. package/dist/PayloadFeedbackManager.js +244 -88
  30. package/dist/PayloadFeedbackManager.js.map +1 -1
  31. package/dist/PayloadManager.d.ts +27 -0
  32. package/dist/PayloadManager.d.ts.map +1 -1
  33. package/dist/PayloadManager.js +47 -15
  34. package/dist/PayloadManager.js.map +1 -1
  35. package/dist/agent-context-injector.d.ts +47 -3
  36. package/dist/agent-context-injector.d.ts.map +1 -1
  37. package/dist/agent-context-injector.js +77 -10
  38. package/dist/agent-context-injector.js.map +1 -1
  39. package/dist/agent-memory-context-builder.d.ts +13 -0
  40. package/dist/agent-memory-context-builder.d.ts.map +1 -1
  41. package/dist/agent-memory-context-builder.js +24 -5
  42. package/dist/agent-memory-context-builder.js.map +1 -1
  43. package/dist/agent-types/base-agent-type.d.ts +16 -0
  44. package/dist/agent-types/base-agent-type.d.ts.map +1 -1
  45. package/dist/agent-types/base-agent-type.js +20 -1
  46. package/dist/agent-types/base-agent-type.js.map +1 -1
  47. package/dist/agent-types/flow-agent-type.d.ts +106 -0
  48. package/dist/agent-types/flow-agent-type.d.ts.map +1 -1
  49. package/dist/agent-types/flow-agent-type.js +299 -29
  50. package/dist/agent-types/flow-agent-type.js.map +1 -1
  51. package/dist/agent-types/flow-graph-executor.d.ts +12 -1
  52. package/dist/agent-types/flow-graph-executor.d.ts.map +1 -1
  53. package/dist/agent-types/flow-graph-executor.js +25 -1
  54. package/dist/agent-types/flow-graph-executor.js.map +1 -1
  55. package/dist/agent-types/loop-agent-prompt-params.d.ts +258 -11
  56. package/dist/agent-types/loop-agent-prompt-params.d.ts.map +1 -1
  57. package/dist/agent-types/loop-agent-prompt-params.js +49 -2
  58. package/dist/agent-types/loop-agent-prompt-params.js.map +1 -1
  59. package/dist/agent-types/loop-agent-response-type.d.ts +12 -1
  60. package/dist/agent-types/loop-agent-response-type.d.ts.map +1 -1
  61. package/dist/agent-types/loop-agent-response-type.js.map +1 -1
  62. package/dist/agent-types/loop-agent-type.d.ts +6 -0
  63. package/dist/agent-types/loop-agent-type.d.ts.map +1 -1
  64. package/dist/agent-types/loop-agent-type.js +42 -3
  65. package/dist/agent-types/loop-agent-type.js.map +1 -1
  66. package/dist/artifact-target-plan.d.ts +2 -0
  67. package/dist/artifact-target-plan.d.ts.map +1 -1
  68. package/dist/artifact-target-plan.js +5 -1
  69. package/dist/artifact-target-plan.js.map +1 -1
  70. package/dist/base-agent.d.ts +886 -5
  71. package/dist/base-agent.d.ts.map +1 -1
  72. package/dist/base-agent.js +2567 -164
  73. package/dist/base-agent.js.map +1 -1
  74. package/dist/catalog-narrowing.d.ts +136 -0
  75. package/dist/catalog-narrowing.d.ts.map +1 -0
  76. package/dist/catalog-narrowing.js +212 -0
  77. package/dist/catalog-narrowing.js.map +1 -0
  78. package/dist/constants.d.ts +57 -0
  79. package/dist/constants.d.ts.map +1 -0
  80. package/dist/constants.js +70 -0
  81. package/dist/constants.js.map +1 -0
  82. package/dist/decision-discovery.d.ts +401 -0
  83. package/dist/decision-discovery.d.ts.map +1 -0
  84. package/dist/decision-discovery.js +511 -0
  85. package/dist/decision-discovery.js.map +1 -0
  86. package/dist/finish-if-mode-warnings.d.ts +39 -0
  87. package/dist/finish-if-mode-warnings.d.ts.map +1 -0
  88. package/dist/finish-if-mode-warnings.js +78 -0
  89. package/dist/finish-if-mode-warnings.js.map +1 -0
  90. package/dist/finish-if-state.d.ts +72 -0
  91. package/dist/finish-if-state.d.ts.map +1 -0
  92. package/dist/finish-if-state.js +109 -0
  93. package/dist/finish-if-state.js.map +1 -0
  94. package/dist/index.d.ts +9 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +10 -0
  97. package/dist/index.js.map +1 -1
  98. package/dist/memory-manager-agent.d.ts +119 -13
  99. package/dist/memory-manager-agent.d.ts.map +1 -1
  100. package/dist/memory-manager-agent.js +237 -74
  101. package/dist/memory-manager-agent.js.map +1 -1
  102. package/dist/memory-note-gate.d.ts +208 -0
  103. package/dist/memory-note-gate.d.ts.map +1 -0
  104. package/dist/memory-note-gate.js +294 -0
  105. package/dist/memory-note-gate.js.map +1 -0
  106. package/dist/native-tools/action-tool-builder.d.ts +8 -0
  107. package/dist/native-tools/action-tool-builder.d.ts.map +1 -1
  108. package/dist/native-tools/action-tool-builder.js +22 -6
  109. package/dist/native-tools/action-tool-builder.js.map +1 -1
  110. package/dist/native-tools/control-tools.d.ts +8 -0
  111. package/dist/native-tools/control-tools.d.ts.map +1 -1
  112. package/dist/native-tools/control-tools.js +25 -9
  113. package/dist/native-tools/control-tools.js.map +1 -1
  114. package/dist/native-tools/dual-channel.d.ts +2 -0
  115. package/dist/native-tools/dual-channel.d.ts.map +1 -1
  116. package/dist/native-tools/dual-channel.js +5 -1
  117. package/dist/native-tools/dual-channel.js.map +1 -1
  118. package/dist/native-tools/tool-result-turns.d.ts +9 -0
  119. package/dist/native-tools/tool-result-turns.d.ts.map +1 -1
  120. package/dist/native-tools/tool-result-turns.js +15 -3
  121. package/dist/native-tools/tool-result-turns.js.map +1 -1
  122. package/dist/pipeline/coerce.d.ts +14 -0
  123. package/dist/pipeline/coerce.d.ts.map +1 -1
  124. package/dist/pipeline/coerce.js +37 -9
  125. package/dist/pipeline/coerce.js.map +1 -1
  126. package/dist/pipeline/jsonpath-eval.d.ts +4 -0
  127. package/dist/pipeline/jsonpath-eval.d.ts.map +1 -1
  128. package/dist/pipeline/jsonpath-eval.js +10 -2
  129. package/dist/pipeline/jsonpath-eval.js.map +1 -1
  130. package/dist/pipeline/operators.js +16 -16
  131. package/dist/pipeline/path.d.ts +6 -0
  132. package/dist/pipeline/path.d.ts.map +1 -1
  133. package/dist/pipeline/path.js +17 -5
  134. package/dist/pipeline/path.js.map +1 -1
  135. package/dist/pipeline/pipeline-executor.js +10 -10
  136. package/dist/pipeline/predicate.d.ts +4 -0
  137. package/dist/pipeline/predicate.d.ts.map +1 -1
  138. package/dist/pipeline/predicate.js +15 -7
  139. package/dist/pipeline/predicate.js.map +1 -1
  140. package/dist/pipeline/providers/action-provider.js +2 -2
  141. package/dist/pipeline/providers/artifact-tool-provider.js +2 -2
  142. package/dist/pipeline/providers/serialize.d.ts +4 -0
  143. package/dist/pipeline/providers/serialize.d.ts.map +1 -1
  144. package/dist/pipeline/providers/serialize.js +10 -2
  145. package/dist/pipeline/providers/serialize.js.map +1 -1
  146. package/dist/pipeline/template.d.ts +4 -0
  147. package/dist/pipeline/template.d.ts.map +1 -1
  148. package/dist/pipeline/template.js +15 -7
  149. package/dist/pipeline/template.js.map +1 -1
  150. package/dist/realtime/agent-media-library.d.ts +10 -0
  151. package/dist/realtime/agent-media-library.d.ts.map +1 -1
  152. package/dist/realtime/agent-media-library.js +29 -9
  153. package/dist/realtime/agent-media-library.js.map +1 -1
  154. package/dist/realtime/bridge-realtime-session-factory.d.ts +5 -2
  155. package/dist/realtime/bridge-realtime-session-factory.d.ts.map +1 -1
  156. package/dist/realtime/bridge-realtime-session-factory.js +7 -4
  157. package/dist/realtime/bridge-realtime-session-factory.js.map +1 -1
  158. package/dist/realtime/bridge-room-transcript-sink.d.ts.map +1 -1
  159. package/dist/realtime/bridge-room-transcript-sink.js +15 -9
  160. package/dist/realtime/bridge-room-transcript-sink.js.map +1 -1
  161. package/dist/realtime/media-channel-server.js +2 -2
  162. package/dist/realtime/meeting-controls-state.d.ts +2 -0
  163. package/dist/realtime/meeting-controls-state.d.ts.map +1 -1
  164. package/dist/realtime/meeting-controls-state.js +6 -2
  165. package/dist/realtime/meeting-controls-state.js.map +1 -1
  166. package/dist/realtime/realtime-channel-server-data-context.d.ts +2 -0
  167. package/dist/realtime/realtime-channel-server-data-context.d.ts.map +1 -1
  168. package/dist/realtime/realtime-channel-server-data-context.js +5 -1
  169. package/dist/realtime/realtime-channel-server-data-context.js.map +1 -1
  170. package/dist/realtime/realtime-channel-server-host.js +2 -2
  171. package/dist/realtime/realtime-client-session-service.d.ts +58 -12
  172. package/dist/realtime/realtime-client-session-service.d.ts.map +1 -1
  173. package/dist/realtime/realtime-client-session-service.js +91 -31
  174. package/dist/realtime/realtime-client-session-service.js.map +1 -1
  175. package/dist/realtime/realtime-coagent-config.d.ts +2 -0
  176. package/dist/realtime/realtime-coagent-config.d.ts.map +1 -1
  177. package/dist/realtime/realtime-coagent-config.js +6 -2
  178. package/dist/realtime/realtime-coagent-config.js.map +1 -1
  179. package/dist/realtime/realtime-recording-store.d.ts +15 -0
  180. package/dist/realtime/realtime-recording-store.d.ts.map +1 -1
  181. package/dist/realtime/realtime-recording-store.js +31 -7
  182. package/dist/realtime/realtime-recording-store.js.map +1 -1
  183. package/dist/realtime/realtime-session-runner.d.ts +4 -4
  184. package/dist/realtime/realtime-session-runner.js +9 -9
  185. package/dist/realtime/realtime-session-runner.js.map +1 -1
  186. package/dist/realtime/realtime-vendor-resolution.d.ts +8 -3
  187. package/dist/realtime/realtime-vendor-resolution.d.ts.map +1 -1
  188. package/dist/realtime/realtime-vendor-resolution.js +3 -3
  189. package/dist/realtime/realtime-vendor-resolution.js.map +1 -1
  190. package/dist/rubric-evaluation-agent-runner.d.ts +2 -0
  191. package/dist/rubric-evaluation-agent-runner.d.ts.map +1 -0
  192. package/dist/rubric-evaluation-agent-runner.js +38 -0
  193. package/dist/rubric-evaluation-agent-runner.js.map +1 -0
  194. package/dist/runtime-state-fragment.d.ts +101 -0
  195. package/dist/runtime-state-fragment.d.ts.map +1 -0
  196. package/dist/runtime-state-fragment.js +173 -0
  197. package/dist/runtime-state-fragment.js.map +1 -0
  198. package/dist/self-check.d.ts +98 -0
  199. package/dist/self-check.d.ts.map +1 -0
  200. package/dist/self-check.js +74 -0
  201. package/dist/self-check.js.map +1 -0
  202. package/dist/types/payload-operations.d.ts +8 -0
  203. package/dist/types/payload-operations.d.ts.map +1 -1
  204. package/dist/types/payload-operations.js +21 -5
  205. package/dist/types/payload-operations.js.map +1 -1
  206. package/dist/utils/ConversationMessageResolver.d.ts +4 -0
  207. package/dist/utils/ConversationMessageResolver.d.ts.map +1 -1
  208. package/dist/utils/ConversationMessageResolver.js +10 -2
  209. package/dist/utils/ConversationMessageResolver.js.map +1 -1
  210. package/dist/volatile-child-prompt.d.ts +33 -0
  211. package/dist/volatile-child-prompt.d.ts.map +1 -0
  212. package/dist/volatile-child-prompt.js +76 -0
  213. package/dist/volatile-child-prompt.js.map +1 -0
  214. package/package.json +21 -18
@@ -6,13 +6,15 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  var MemoryManagerAgent_1;
8
8
  import { BaseAgent } from './base-agent.js';
9
- import { RegisterClass, CleanAndParseJSON } from '@memberjunction/global';
9
+ import { RegisterClass, CleanAndParseJSON, IsPlainObject } from '@memberjunction/global';
10
10
  import { RunView, RunQuery, LogError, LogStatus, LogStatusEx } from '@memberjunction/core';
11
11
  import { IsInjectableNoteStatus } from '@memberjunction/core-entities';
12
12
  import { AIPromptRunner } from '@memberjunction/ai-prompts';
13
- import { AIPromptParams } from '@memberjunction/ai-core-plus';
13
+ import { AIPromptParams, DescribeAnsweringModel } from '@memberjunction/ai-core-plus';
14
14
  import { AIEngine } from '@memberjunction/aiengine';
15
15
  import { UUIDsEqual } from '@memberjunction/global';
16
+ import { AgentDecisionService } from './AgentDecisionService.js';
17
+ import { BuildMemoryNoteQuestions, BuildMemoryNoteState, JudgeMemoryNotes, MemoryNotePromptQuestionCap, ChunkMemoryNotes, GroupMemoryNotesByConversation, MEMORY_NOTE_MIN_PROBABILITY } from './memory-note-gate.js';
16
18
  /**
17
19
  * Configuration for extraction limits to ensure sparsity
18
20
  */
@@ -131,7 +133,7 @@ const SOURCE_RUN_SCOPE_FIELDS = ['AgentID', 'CompanyID', 'UserID', 'PrimaryScope
131
133
  * This agent runs on a schedule (every 15 minutes) and analyzes high-quality conversations
132
134
  * and agent runs to extract learnings and example interactions.
133
135
  */
134
- let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends BaseAgent {
136
+ let MemoryManagerAgent = class MemoryManagerAgent extends BaseAgent {
135
137
  constructor() {
136
138
  super(...arguments);
137
139
  /** Verbose logging flag from params.verbose */
@@ -142,6 +144,21 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
142
144
  this._stepCounter = 0;
143
145
  /** Context user for step operations */
144
146
  this._contextUser = null;
147
+ /** Flag to enable typed decision gate instead of self-confidence threshold */
148
+ this._enableDecisionGate = false;
149
+ }
150
+ static { MemoryManagerAgent_1 = this; }
151
+ /**
152
+ * Whether the typed decision gate is enabled for filtering extracted memory notes.
153
+ * When false (default), uses the self-reported confidence filter (confidence >= 80).
154
+ * The gate also needs the master switch: the run's agent-type prompt params must set
155
+ * `decisionsEnabled: true` ({@link DecisionsEnabled}), or the confidence filter is used.
156
+ */
157
+ get EnableDecisionGate() {
158
+ return this._enableDecisionGate;
159
+ }
160
+ set EnableDecisionGate(value) {
161
+ this._enableDecisionGate = value;
145
162
  }
146
163
  /** Check if a string is a valid UUID format. Filters out LLM-generated placeholders like "user-uuid-here". */
147
164
  static isValidUUID(id) {
@@ -152,8 +169,9 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
152
169
  /**
153
170
  * Create an agent run step record for observability.
154
171
  * Returns null if agentRunID is not set (defensive check).
172
+ * Protected so a test can stand in for the database.
155
173
  */
156
- async CreateRunStep(stepType, stepName, inputData, targetId) {
174
+ async createRunStep(stepType, stepName, inputData, targetId) {
157
175
  if (!this._agentRunID || !this._contextUser) {
158
176
  return null;
159
177
  }
@@ -188,7 +206,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
188
206
  /**
189
207
  * Finalize an agent run step with success/failure status and output data.
190
208
  */
191
- async FinalizeRunStep(step, success, outputData, targetLogId, errorMessage) {
209
+ async finalizeRunStep(step, success, outputData, targetLogId, errorMessage) {
192
210
  if (!step) {
193
211
  return;
194
212
  }
@@ -217,7 +235,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
217
235
  * Get the last run timestamp for this agent to determine what to process.
218
236
  * For first run, returns null to process all history (limited by MaxRows).
219
237
  */
220
- async GetLastRunTime(agentId, contextUser) {
238
+ async getLastRunTime(agentId, contextUser) {
221
239
  // Read-only: we only need StartedAt, so use a 'simple' projection with a narrow Fields
222
240
  // list. Loading this as 'entity_object' would build a full MJAIAgentRunEntityExtended,
223
241
  // whose InnerLoad fires a secondary "MJ: AI Agent Run Steps" RunView (LoadRelatedData) —
@@ -263,7 +281,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
263
281
  * Load agents that have note or example injection enabled.
264
282
  * Only extract notes/examples for agents that actually use these features.
265
283
  */
266
- async LoadAgentsUsingMemory(contextUser) {
284
+ async loadAgentsUsingMemory(contextUser) {
267
285
  const allAgents = AIEngine.Instance.Agents;
268
286
  const filteredAgents = allAgents.filter(a => a.Status === 'Active' && (a.InjectNotes || a.InjectExamples));
269
287
  // Debug logging only in verbose mode
@@ -290,7 +308,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
290
308
  * Uses a single optimized RunQuery that replaces 4 separate database queries.
291
309
  * Returns conversations with their details, ratings, and agent run IDs for scope inheritance.
292
310
  */
293
- async LoadConversationsWithNewActivity(since, agentsUsingMemory, contextUser) {
311
+ async loadConversationsWithNewActivity(since, agentsUsingMemory, contextUser) {
294
312
  if (agentsUsingMemory.length === 0) {
295
313
  LogStatus('Memory Manager: No agents have memory injection enabled - skipping');
296
314
  return [];
@@ -362,7 +380,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
362
380
  * secondary "MJ: AI Agent Run Steps" RunView via InnerLoad/LoadRelatedData — exactly the
363
381
  * redundant round-trips the telemetry flagged. The simple projection skips all of them.
364
382
  */
365
- async LoadHighValueAgentRuns(since, contextUser) {
383
+ async loadHighValueAgentRuns(since, contextUser) {
366
384
  const rv = new RunView();
367
385
  // Use subquery to find agent runs with high-usage artifacts
368
386
  const sinceFilter = since ? `AND au.__mj_CreatedAt >= '${since.toISOString()}'` : '';
@@ -415,7 +433,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
415
433
  * matching the high-value loader's lightweight projection. The confidence gate (≥80) downstream
416
434
  * discards transient/low-signal failures that carry no generalizable lesson.
417
435
  */
418
- async LoadInstructiveFailedAgentRuns(since, contextUser) {
436
+ async loadInstructiveFailedAgentRuns(since, contextUser) {
419
437
  const rv = new RunView();
420
438
  const sinceFilter = since ? ` AND __mj_CreatedAt >= '${since.toISOString()}'` : '';
421
439
  const filter = `((Status IN ('Failed', 'Cancelled') AND ErrorMessage IS NOT NULL) OR (Success = 0 AND Status NOT IN ('Running', 'Paused')))${sinceFilter}`;
@@ -434,7 +452,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
434
452
  * This is the primary method that handles rated, unrated, positive, and negative feedback.
435
453
  * Uses LLM-based deduplication and applies sparsity controls.
436
454
  */
437
- async ExtractNotesFromConversations(conversations, contextUser) {
455
+ async extractNotesFromConversations(conversations, contextUser) {
438
456
  if (conversations.length === 0) {
439
457
  return [];
440
458
  }
@@ -468,7 +486,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
468
486
  companyId: n.CompanyID
469
487
  }))
470
488
  };
471
- return this.executeNoteExtraction(promptData, existingNotes, contextUser);
489
+ return this.executeNoteExtraction(promptData, existingNotes, contextUser, true);
472
490
  }
473
491
  /**
474
492
  * Mine corrective ("avoid this") memory from failed/cancelled agent runs. Each failed run
@@ -477,7 +495,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
477
495
  * to the corrective note types (Issue/Context only, never Constraint/Preference/Example) and
478
496
  * tagged 'Ephemeral' so a one-off transient failure decays unless reinforced by recurrence.
479
497
  */
480
- async ExtractNotesFromFailedRuns(failedRuns, contextUser) {
498
+ async extractNotesFromFailedRuns(failedRuns, contextUser) {
481
499
  if (failedRuns.length === 0) {
482
500
  return [];
483
501
  }
@@ -508,7 +526,9 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
508
526
  companyId: n.CompanyID
509
527
  }))
510
528
  };
511
- const extracted = await this.executeNoteExtraction(promptData, existingNotes, contextUser);
529
+ // The decision gate was measured on conversation notes only; a corrective lesson from a failed run
530
+ // is not the durable user fact its question asks about, so these keep the self-reported rule.
531
+ const extracted = await this.executeNoteExtraction(promptData, existingNotes, contextUser, false);
512
532
  return this.markCorrectiveNotes(extracted);
513
533
  }
514
534
  /**
@@ -546,7 +566,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
546
566
  *
547
567
  * Each step is its own private helper so the pipeline can be read top-to-bottom.
548
568
  */
549
- async executeNoteExtraction(promptData, existingNotes, contextUser) {
569
+ async executeNoteExtraction(promptData, existingNotes, contextUser, decisionGateApplies) {
550
570
  // Step 1: run the extraction prompt and parse out the raw notes
551
571
  const rawNotes = await this.runNoteExtractionPrompt(promptData, existingNotes.length, contextUser);
552
572
  if (!rawNotes)
@@ -559,11 +579,11 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
559
579
  LogStatus(`Memory Manager: Raw note: [${note.type}] "${note.content}" (confidence: ${note.confidence})${note.mergeWithExistingIds?.length ? ` mergeWith: ${note.mergeWithExistingIds.join(', ')}` : ''}`);
560
580
  }
561
581
  }
562
- // Step 3: filter by confidence and content length
563
- const candidateNotes = this.filterByConfidenceAndLength(rawNotes);
582
+ // Step 3: filter by decision gate or confidence/content length
583
+ const candidateNotes = await this.filterCandidateNotes(rawNotes, promptData.conversationThreads, contextUser, decisionGateApplies);
564
584
  if (candidateNotes.length === 0) {
565
585
  if (this._verbose)
566
- LogStatus('Memory Manager: No candidates passed confidence/length thresholds');
586
+ LogStatus('Memory Manager: No candidates passed gating thresholds');
567
587
  return [];
568
588
  }
569
589
  // Step 4: apply per-message and per-conversation sparsity caps
@@ -592,7 +612,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
592
612
  return null;
593
613
  const conversationThreads = promptData.conversationThreads;
594
614
  this.logExtractionPromptContext(prompt, conversationThreads);
595
- const step = await this.CreateRunStep('Prompt', 'Extract Notes from Conversations', {
615
+ const step = await this.createRunStep('Prompt', 'Extract Notes from Conversations', {
596
616
  conversationCount: conversationThreads.length,
597
617
  messageCount: conversationThreads.reduce((sum, t) => sum + t.messages.length, 0),
598
618
  existingNoteCount
@@ -605,7 +625,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
605
625
  params.attemptJSONRepair = true;
606
626
  params.additionalParameters = DETERMINISTIC_PROMPT_PARAMS;
607
627
  const result = await runner.ExecutePrompt(params);
608
- await this.FinalizeRunStep(step, result.success, {
628
+ await this.finalizeRunStep(step, result.success, {
609
629
  success: result.success,
610
630
  rawNoteCount: result.result && typeof result.result !== 'string' ? (result.result.notes?.length || 0) : 0
611
631
  }, result.promptRun?.ID, result.errorMessage || undefined);
@@ -689,6 +709,134 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
689
709
  }
690
710
  return filtered;
691
711
  }
712
+ /**
713
+ * Filters candidate notes using either the typed decision gate (if enabled, with the master switch
714
+ * on, and the notes are ones it was measured on) or the traditional self-reported confidence and
715
+ * length filters. Protected so a test can run the gate the way extraction does.
716
+ *
717
+ * @param decisionGateApplies Whether these notes may be gated: conversation notes only.
718
+ */
719
+ async filterCandidateNotes(notes, conversationThreads, contextUser, decisionGateApplies) {
720
+ if (!this._enableDecisionGate || !this.DecisionsEnabled(this._runPromptParams) || !decisionGateApplies) {
721
+ return this.filterByConfidenceAndLength(notes);
722
+ }
723
+ return this.filterWithDecisionGate(notes, conversationThreads, contextUser);
724
+ }
725
+ /**
726
+ * Evaluates candidate notes through the typed decision gate, one conversation at a time: each note
727
+ * is judged against the conversation it came from, as the gate was measured and calibrated, in
728
+ * batches no larger than the prompt models' declared MaxQuestionsPerCall. A note whose conversation
729
+ * can't be told keeps the self-reported rule. The kept notes keep their original order.
730
+ */
731
+ async filterWithDecisionGate(notes, conversationThreads, contextUser) {
732
+ const lengthFiltered = notes.filter(n => n.content && n.content.length >= EXTRACTION_CONFIG.minContentLength);
733
+ if (lengthFiltered.length === 0) {
734
+ if (this._verbose)
735
+ LogStatus('Memory Manager: No candidates passed content length check before decision gate');
736
+ return [];
737
+ }
738
+ const cap = MemoryNotePromptQuestionCap(AIEngine.Instance, 'Default Decision');
739
+ const grouping = GroupMemoryNotesByConversation(lengthFiltered, conversationThreads.map(t => ({
740
+ ConversationId: t.conversationId,
741
+ Turns: t.messages.map(m => ({ role: m.role, text: m.message }))
742
+ })));
743
+ const kept = new Set(this.filterByConfidenceAndLength(grouping.Unattributed));
744
+ if (grouping.Unattributed.length > 0) {
745
+ LogStatus(`Memory Manager: ${grouping.Unattributed.length} note(s) name no conversation of this batch, so they keep the confidence filter`);
746
+ }
747
+ for (const conversation of grouping.Batches) {
748
+ for (const batch of ChunkMemoryNotes(conversation.Notes, cap)) {
749
+ const batchPassed = await this.judgeDecisionBatch(batch, conversation.ConversationId, conversation.Excerpt, contextUser, cap);
750
+ batchPassed.forEach(note => kept.add(note));
751
+ }
752
+ }
753
+ return lengthFiltered.filter(note => kept.has(note));
754
+ }
755
+ /**
756
+ * Runs a decision prompt call for a single batch of candidate notes from one conversation, falling
757
+ * back to the confidence filter if the decision call fails. The call's step joins the agent run's
758
+ * steps, and carries the call's prompt run, so the run's cost and token totals count it.
759
+ */
760
+ async judgeDecisionBatch(batch, conversationId, excerpt, contextUser, modelCap) {
761
+ const questions = BuildMemoryNoteQuestions(batch);
762
+ const state = BuildMemoryNoteState(batch, excerpt);
763
+ const step = await this.createRunStep('Decision', 'Judge Extracted Notes', {
764
+ conversationId,
765
+ noteCount: batch.length,
766
+ modelCap
767
+ });
768
+ if (step) {
769
+ this.AgentRun?.Steps.push(step);
770
+ }
771
+ const decisionService = this._agentDecisionService ?? new AgentDecisionService();
772
+ const result = await decisionService.Ask({
773
+ ContextUser: contextUser,
774
+ PromptName: 'Default Decision',
775
+ State: state,
776
+ Questions: questions,
777
+ AgentID: this.AgentRun?.AgentID ?? undefined,
778
+ CancellationToken: this._cancellationToken
779
+ });
780
+ await this.recordDecisionStep(step, result);
781
+ if (!result.success) {
782
+ LogStatus(`Memory Manager: Decision call failed (${result.errorMessage ?? 'unknown error'}), falling back to confidence filter for batch`);
783
+ return this.filterByConfidenceAndLength(batch);
784
+ }
785
+ const answeredBy = { ModelName: result.modelInfo?.modelName, ResolvedModel: result.DecisionResult?.ResolvedModel };
786
+ return this.evaluateDecisionVerdict(batch, result.Answers, answeredBy);
787
+ }
788
+ /**
789
+ * Puts the decision's prompt run on its step, which is how the agent run counts the call's cost
790
+ * and tokens, and marks the step complete.
791
+ */
792
+ async recordDecisionStep(step, result) {
793
+ if (!step)
794
+ return;
795
+ this.attachDecisionPromptRun(step, result);
796
+ await this.finalizeRunStep(step, result.success, { answers: result.Answers, model: result.modelInfo?.modelName, resolvedModel: result.DecisionResult?.ResolvedModel }, result.promptRun?.ID, result.errorMessage);
797
+ }
798
+ /** The answering models already logged as having no memory-note calibration, so each is logged once per process. */
799
+ static { this._uncalibratedGateModelsLogged = new Set(); }
800
+ /**
801
+ * Logs, once per model, that the decision gate fell back to the confidence filter because the
802
+ * model that answered has no memory-note calibration. That happens on a failover, when a decision
803
+ * model is added or renamed, or when a vendor model moves to another version (Jev's `APIName`).
804
+ */
805
+ static logUncalibratedGateModel(answeredBy) {
806
+ const described = DescribeAnsweringModel(answeredBy);
807
+ if (MemoryManagerAgent_1._uncalibratedGateModelsLogged.has(described)) {
808
+ return;
809
+ }
810
+ MemoryManagerAgent_1._uncalibratedGateModelsLogged.add(described);
811
+ LogStatus(`Memory Manager: ${described} has no memory-note calibration (MEMORY_NOTE_DECISION_CALIBRATION), so the decision gate falls back to the confidence filter for its batches`);
812
+ }
813
+ /**
814
+ * Applies calibrated probabilities to judge which candidate notes to keep. A note the calibrated
815
+ * model gave no usable answer for keeps the self-reported rule, as a failed call's batch does.
816
+ */
817
+ evaluateDecisionVerdict(batch, answers, answeredBy) {
818
+ const verdict = JudgeMemoryNotes(answers, batch, answeredBy, MEMORY_NOTE_MIN_PROBABILITY);
819
+ // Only a calibrated model replaces the self-reported confidence: one that answered without a
820
+ // calibration (a failover, or a calibrated model at another version) has not been shown to
821
+ // beat it, so the batch falls back to it.
822
+ if (!verdict.Calibrated) {
823
+ MemoryManagerAgent_1.logUncalibratedGateModel(answeredBy);
824
+ return this.filterByConfidenceAndLength(batch);
825
+ }
826
+ if (this._verbose) {
827
+ LogStatus(`Memory Manager: Decision gate evaluated ${batch.length} notes (calibrated: ${verdict.Calibrated}): kept ${verdict.KeptNotes.length}`);
828
+ for (const judged of verdict.JudgedNotes) {
829
+ LogStatus(`Memory Manager: Note [${judged.Note.type}] "${judged.Note.content.slice(0, 50)}..." -> kept: ${judged.Kept} (prob: ${judged.CalibratedProbability ?? judged.RawProbability ?? 'none'}), reason: ${judged.Reason}`);
830
+ }
831
+ }
832
+ const unanswered = verdict.JudgedNotes.filter(j => j.CalibratedProbability === undefined).map(j => j.Note);
833
+ if (unanswered.length === 0) {
834
+ return verdict.KeptNotes;
835
+ }
836
+ LogStatus(`Memory Manager: ${DescribeAnsweringModel(answeredBy)} gave no usable answer for ${unanswered.length} of ${batch.length} note(s), which keep the confidence filter`);
837
+ const kept = new Set([...verdict.KeptNotes, ...this.filterByConfidenceAndLength(unanswered)]);
838
+ return batch.filter(note => kept.has(note));
839
+ }
692
840
  /**
693
841
  * Enforce per-message and per-conversation note caps from EXTRACTION_CONFIG.
694
842
  * Drops any candidates that would exceed either cap.
@@ -731,7 +879,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
731
879
  * replacing). Creates and finalizes its own observability run step.
732
880
  */
733
881
  async deduplicateCandidates(candidates, existingNotes, contextUser) {
734
- const step = await this.CreateRunStep('Decision', 'Deduplicate Note Candidates', {
882
+ const step = await this.createRunStep('Decision', 'Deduplicate Note Candidates', {
735
883
  candidateCount: candidates.length,
736
884
  existingNoteCount: existingNotes.length
737
885
  });
@@ -750,7 +898,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
750
898
  approved.push(candidate);
751
899
  }
752
900
  }
753
- await this.FinalizeRunStep(step, true, {
901
+ await this.finalizeRunStep(step, true, {
754
902
  approvedCount: approved.length,
755
903
  rejectedCount: stats.rejectedCount,
756
904
  llmCallCount: stats.llmCallCount
@@ -855,7 +1003,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
855
1003
  * Extract examples from conversation details with high ratings.
856
1004
  * Uses LLM-based deduplication to avoid adding redundant examples.
857
1005
  */
858
- async ExtractExamples(conversationDetails, contextUser) {
1006
+ async extractExamples(conversationDetails, contextUser) {
859
1007
  if (conversationDetails.length === 0) {
860
1008
  return [];
861
1009
  }
@@ -874,7 +1022,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
874
1022
  return [];
875
1023
  }
876
1024
  // Step 5: Execute AI extraction
877
- const step5 = await this.CreateRunStep('Prompt', 'Extract Examples from Conversations', {
1025
+ const step5 = await this.createRunStep('Prompt', 'Extract Examples from Conversations', {
878
1026
  qaPairCount: qaPairs.length
879
1027
  }, extractPrompt.ID);
880
1028
  const runner = new AIPromptRunner();
@@ -886,7 +1034,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
886
1034
  extractParams.additionalParameters = { temperature: 0 };
887
1035
  const extractResult = await runner.ExecutePrompt(extractParams);
888
1036
  if (!extractResult.success || !extractResult.result) {
889
- await this.FinalizeRunStep(step5, false, {
1037
+ await this.finalizeRunStep(step5, false, {
890
1038
  success: false
891
1039
  }, extractResult.promptRun?.ID, extractResult.errorMessage || undefined);
892
1040
  LogError('Failed to extract examples:', extractResult.errorMessage);
@@ -909,7 +1057,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
909
1057
  const candidateExamples = (parsedResult.examples || [])
910
1058
  .filter(e => e.successScore >= 70 && e.confidence >= 70);
911
1059
  // Finalize Step 5 after extraction parsing
912
- await this.FinalizeRunStep(step5, true, {
1060
+ await this.finalizeRunStep(step5, true, {
913
1061
  rawExampleCount: parsedResult.examples?.length || 0,
914
1062
  candidateCount: candidateExamples.length
915
1063
  }, extractResult.promptRun?.ID);
@@ -917,7 +1065,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
917
1065
  return [];
918
1066
  }
919
1067
  // Step 6: Deduplicate example candidates (summary step)
920
- const step6 = await this.CreateRunStep('Decision', 'Deduplicate Example Candidates', {
1068
+ const step6 = await this.createRunStep('Decision', 'Deduplicate Example Candidates', {
921
1069
  candidateCount: candidateExamples.length
922
1070
  });
923
1071
  const approvedExamples = [];
@@ -967,7 +1115,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
967
1115
  }
968
1116
  }
969
1117
  // Finalize Step 6 after deduplication loop
970
- await this.FinalizeRunStep(step6, true, {
1118
+ await this.finalizeRunStep(step6, true, {
971
1119
  approvedCount: approvedExamples.length,
972
1120
  rejectedCount: exampleDedupeRejectedCount,
973
1121
  llmCallCount: exampleDedupeLlmCallCount
@@ -978,9 +1126,9 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
978
1126
  * Create note records from extracted data.
979
1127
  * Inherits scope from source agent run and applies scopeLevel to determine scope specificity.
980
1128
  */
981
- async CreateNoteRecords(extractedNotes, contextUser) {
1129
+ async createNoteRecords(extractedNotes, contextUser) {
982
1130
  // Step 7: Create Note Records
983
- const step7 = await this.CreateRunStep('Decision', 'Create Note Records', {
1131
+ const step7 = await this.createRunStep('Decision', 'Create Note Records', {
984
1132
  noteCount: extractedNotes.length
985
1133
  });
986
1134
  let created = 0;
@@ -993,7 +1141,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
993
1141
  const aiNoteTypeId = AIEngine.Instance.AgenteNoteTypeIDByName('AI');
994
1142
  if (!aiNoteTypeId) {
995
1143
  LogError('Memory Manager: Could not find "AI" note type - cannot create notes');
996
- await this.FinalizeRunStep(step7, false, {
1144
+ await this.finalizeRunStep(step7, false, {
997
1145
  created: 0,
998
1146
  merged: 0,
999
1147
  failed: extractedNotes.length
@@ -1108,7 +1256,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
1108
1256
  }
1109
1257
  }
1110
1258
  // Finalize Step 7
1111
- await this.FinalizeRunStep(step7, failed === 0 || created > 0 || merged > 0, {
1259
+ await this.finalizeRunStep(step7, failed === 0 || created > 0 || merged > 0, {
1112
1260
  created,
1113
1261
  merged,
1114
1262
  failed
@@ -1865,7 +2013,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
1865
2013
  */
1866
2014
  async processConsolidationCluster(cluster, consolidatePrompt, aiNoteTypeId, runner, md, contextUser) {
1867
2015
  const maxGeneration = Math.max(...cluster.map(n => n.ConsolidationCount || 0));
1868
- const clusterStep = await this.CreateRunStep('Prompt', 'Process Consolidation Cluster', {
2016
+ const clusterStep = await this.createRunStep('Prompt', 'Process Consolidation Cluster', {
1869
2017
  clusterSize: cluster.length,
1870
2018
  noteIds: cluster.map(n => n.ID),
1871
2019
  maxGeneration
@@ -1918,7 +2066,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
1918
2066
  finally {
1919
2067
  // Treat skip (shouldConsolidate: false) as a successful completion rather than a
1920
2068
  // failure — the phase intentionally chose not to consolidate this cluster.
1921
- await this.FinalizeRunStep(clusterStep, outcome.consolidated === 1 || stepOutput.shouldConsolidate === false, stepOutput);
2069
+ await this.finalizeRunStep(clusterStep, outcome.consolidated === 1 || stepOutput.shouldConsolidate === false, stepOutput);
1922
2070
  }
1923
2071
  }
1924
2072
  /**
@@ -2523,7 +2671,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2523
2671
  */
2524
2672
  async runHardeningPhase(contextUser) {
2525
2673
  const counters = { hardened: 0, deduped: 0, failed: 0 };
2526
- const step = await this.CreateRunStep('Decision', 'Harden Provisional Notes', {
2674
+ const step = await this.createRunStep('Decision', 'Harden Provisional Notes', {
2527
2675
  maxNotesPerRun: HARDENING_CONFIG.maxNotesPerRun
2528
2676
  });
2529
2677
  try {
@@ -2541,7 +2689,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2541
2689
  .sort((a, b) => new Date(a.__mj_CreatedAt).getTime() - new Date(b.__mj_CreatedAt).getTime())
2542
2690
  .slice(0, HARDENING_CONFIG.maxNotesPerRun);
2543
2691
  if (provisionalNotes.length === 0) {
2544
- await this.FinalizeRunStep(step, true, { ...counters, provisionalCount: 0 });
2692
+ await this.finalizeRunStep(step, true, { ...counters, provisionalCount: 0 });
2545
2693
  return counters;
2546
2694
  }
2547
2695
  const runner = new AIPromptRunner();
@@ -2553,11 +2701,11 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2553
2701
  if (this._verbose) {
2554
2702
  LogStatus(`Memory Manager: Hardening pass — ${counters.hardened} hardened, ${counters.deduped} deduped, ${counters.failed} failed of ${provisionalNotes.length} provisional notes`);
2555
2703
  }
2556
- await this.FinalizeRunStep(step, counters.failed === 0, { ...counters, provisionalCount: provisionalNotes.length });
2704
+ await this.finalizeRunStep(step, counters.failed === 0, { ...counters, provisionalCount: provisionalNotes.length });
2557
2705
  }
2558
2706
  catch (error) {
2559
2707
  LogError('Memory Manager: Hardening pass failed, continuing with run:', error);
2560
- await this.FinalizeRunStep(step, false, counters, undefined, error instanceof Error ? error.message : String(error));
2708
+ await this.finalizeRunStep(step, false, counters, undefined, error instanceof Error ? error.message : String(error));
2561
2709
  }
2562
2710
  return counters;
2563
2711
  }
@@ -2634,7 +2782,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2634
2782
  return r;
2635
2783
  }
2636
2784
  async runImportancePhase(r, contextUser) {
2637
- const importanceStep = await this.CreateRunStep('Decision', 'Compute Importance Scores', {
2785
+ const importanceStep = await this.createRunStep('Decision', 'Compute Importance Scores', {
2638
2786
  activeNoteCount: AIEngine.Instance.AgentNotes.filter(n => n.Status === 'Active').length
2639
2787
  });
2640
2788
  try {
@@ -2643,7 +2791,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2643
2791
  r.tierPromotions = scoringResult.tierPromotions;
2644
2792
  if (this._verbose)
2645
2793
  LogStatus(`Memory Manager: Scored ${r.importanceScored} notes, ${r.tierPromotions} tier promotions`);
2646
- await this.FinalizeRunStep(importanceStep, true, {
2794
+ await this.finalizeRunStep(importanceStep, true, {
2647
2795
  notesScored: r.importanceScored,
2648
2796
  tierPromotions: r.tierPromotions,
2649
2797
  scoreDistribution: scoringResult.scoreDistribution
@@ -2651,12 +2799,12 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2651
2799
  }
2652
2800
  catch (error) {
2653
2801
  LogError('Memory Manager: Importance scoring failed, continuing with other phases:', error);
2654
- await this.FinalizeRunStep(importanceStep, false, undefined, undefined, error instanceof Error ? error.message : String(error));
2802
+ await this.finalizeRunStep(importanceStep, false, undefined, undefined, error instanceof Error ? error.message : String(error));
2655
2803
  }
2656
2804
  }
2657
2805
  async runConsolidationPhase(r, contextUser, triggerType) {
2658
2806
  const consolidatedNoteIds = new Set();
2659
- const consolidationStep = await this.CreateRunStep('Decision', 'Consolidate Related Notes', {
2807
+ const consolidationStep = await this.createRunStep('Decision', 'Consolidate Related Notes', {
2660
2808
  frequency: CONSOLIDATION_CONFIG.frequency,
2661
2809
  triggerType,
2662
2810
  activeNoteCount: AIEngine.Instance.AgentNotes.filter(n => n.Status === 'Active' && n.IsAutoGenerated).length
@@ -2671,7 +2819,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2671
2819
  if (r.consolidatedCount > 0 && this._verbose) {
2672
2820
  LogStatus(`Memory Manager: Consolidated ${r.consolidatedCount} clusters, archived ${r.consolidationArchived} source notes`);
2673
2821
  }
2674
- await this.FinalizeRunStep(consolidationStep, true, {
2822
+ await this.finalizeRunStep(consolidationStep, true, {
2675
2823
  consolidatedClusterCount: r.consolidatedCount,
2676
2824
  sourceNotesArchived: r.consolidationArchived,
2677
2825
  newConsolidatedNoteIds: Array.from(consolidatedNoteIds)
@@ -2679,7 +2827,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2679
2827
  }
2680
2828
  catch (error) {
2681
2829
  LogError('Memory Manager: Consolidation failed, continuing with other phases:', error);
2682
- await this.FinalizeRunStep(consolidationStep, false, undefined, undefined, error instanceof Error ? error.message : String(error));
2830
+ await this.finalizeRunStep(consolidationStep, false, undefined, undefined, error instanceof Error ? error.message : String(error));
2683
2831
  }
2684
2832
  // Emit the phase-level verification run step (spec Task 8c). Runs whether or not
2685
2833
  // any clusters were consolidated so "no items" runs still produce a visible step.
@@ -2688,14 +2836,14 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2688
2836
  }
2689
2837
  /** Aggregate per-cluster verification results into a single phase-level run step. */
2690
2838
  async emitVerificationRunStep(verifications) {
2691
- const verificationStep = await this.CreateRunStep('Validation', 'Verify Consolidation Output', {
2839
+ const verificationStep = await this.createRunStep('Validation', 'Verify Consolidation Output', {
2692
2840
  clustersVerified: verifications.length
2693
2841
  });
2694
2842
  const verificationsFlagged = verifications.filter(v => !v.passed).length;
2695
2843
  const verificationsPassed = verifications.filter(v => v.passed).length;
2696
2844
  const entitiesChecked = verifications.reduce((sum, v) => sum + v.entitiesChecked, 0);
2697
2845
  const entitiesMissing = verifications.flatMap(v => v.entitiesMissing);
2698
- await this.FinalizeRunStep(verificationStep, true, {
2846
+ await this.finalizeRunStep(verificationStep, true, {
2699
2847
  clustersVerified: verifications.length,
2700
2848
  entitiesChecked,
2701
2849
  entitiesMissing,
@@ -2704,7 +2852,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2704
2852
  });
2705
2853
  }
2706
2854
  async runContradictionPhase(r, contextUser, consolidatedNoteIds) {
2707
- const contradictionStep = await this.CreateRunStep('Decision', 'Detect Note Contradictions', {
2855
+ const contradictionStep = await this.createRunStep('Decision', 'Detect Note Contradictions', {
2708
2856
  consolidatedNoteIdsCount: consolidatedNoteIds.size
2709
2857
  });
2710
2858
  try {
@@ -2715,7 +2863,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2715
2863
  if (r.contradictionsFound > 0 && this._verbose) {
2716
2864
  LogStatus(`Memory Manager: Found ${r.contradictionsFound} contradictions — resolved ${r.contradictionsResolved}, flagged ${r.contradictionsFlagged}`);
2717
2865
  }
2718
- await this.FinalizeRunStep(contradictionStep, true, {
2866
+ await this.finalizeRunStep(contradictionStep, true, {
2719
2867
  pairsAnalyzed: contradictionResult.pairsAnalyzed,
2720
2868
  contradictionsFound: r.contradictionsFound,
2721
2869
  contradictionsResolved: r.contradictionsResolved,
@@ -2725,7 +2873,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2725
2873
  }
2726
2874
  catch (error) {
2727
2875
  LogError('Memory Manager: Contradiction detection failed, continuing with other phases:', error);
2728
- await this.FinalizeRunStep(contradictionStep, false, undefined, undefined, error instanceof Error ? error.message : String(error));
2876
+ await this.finalizeRunStep(contradictionStep, false, undefined, undefined, error instanceof Error ? error.message : String(error));
2729
2877
  }
2730
2878
  }
2731
2879
  /**
@@ -2733,8 +2881,8 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2733
2881
  * doesn't block the other.
2734
2882
  */
2735
2883
  async runPruneAndDecayPhases(r, contextUser) {
2736
- const pruneStep = await this.CreateRunStep('Decision', 'Prune Stale References', {});
2737
- const decayStep = await this.CreateRunStep('Decision', 'Decay-Based Archival', {});
2884
+ const pruneStep = await this.createRunStep('Decision', 'Prune Stale References', {});
2885
+ const decayStep = await this.createRunStep('Decision', 'Decay-Based Archival', {});
2738
2886
  await Promise.allSettled([
2739
2887
  this.runPrunePhase(r, contextUser, pruneStep),
2740
2888
  this.runDecayPhase(r, contextUser, decayStep),
@@ -2747,7 +2895,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2747
2895
  if (r.staleNotesArchived > 0 && this._verbose) {
2748
2896
  LogStatus(`Memory Manager: Pruned ${r.staleNotesArchived} orphaned notes`);
2749
2897
  }
2750
- await this.FinalizeRunStep(pruneStep, true, {
2898
+ await this.finalizeRunStep(pruneStep, true, {
2751
2899
  notesArchived: r.staleNotesArchived,
2752
2900
  orphanedAgents: pruneResult.orphanedAgents,
2753
2901
  orphanedUsers: pruneResult.orphanedUsers,
@@ -2757,7 +2905,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2757
2905
  }
2758
2906
  catch (error) {
2759
2907
  LogError('Memory Manager: Stale reference pruning failed:', error);
2760
- await this.FinalizeRunStep(pruneStep, false, undefined, undefined, error instanceof Error ? error.message : String(error));
2908
+ await this.finalizeRunStep(pruneStep, false, undefined, undefined, error instanceof Error ? error.message : String(error));
2761
2909
  }
2762
2910
  }
2763
2911
  async runDecayPhase(r, contextUser, decayStep) {
@@ -2769,7 +2917,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2769
2917
  if (totalDecayArchived > 0 && this._verbose) {
2770
2918
  LogStatus(`Memory Manager: Decay archival — ${decayResult.notesArchived} notes, ${decayResult.examplesArchived} examples, ${decayResult.notesExpired} expired notes, ${decayResult.examplesExpired} expired examples`);
2771
2919
  }
2772
- await this.FinalizeRunStep(decayStep, true, {
2920
+ await this.finalizeRunStep(decayStep, true, {
2773
2921
  notesArchived: decayResult.notesArchived,
2774
2922
  examplesArchived: decayResult.examplesArchived,
2775
2923
  notesExpired: decayResult.notesExpired,
@@ -2781,7 +2929,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2781
2929
  }
2782
2930
  catch (error) {
2783
2931
  LogError('Memory Manager: Decay-based archival failed:', error);
2784
- await this.FinalizeRunStep(decayStep, false, undefined, undefined, error instanceof Error ? error.message : String(error));
2932
+ await this.finalizeRunStep(decayStep, false, undefined, undefined, error instanceof Error ? error.message : String(error));
2785
2933
  }
2786
2934
  }
2787
2935
  /** Build a human-readable summary string from maintenance phase results. */
@@ -2803,9 +2951,9 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2803
2951
  * Create example records from extracted data.
2804
2952
  * Inherits scope from source agent run and applies scopeLevel to determine scope specificity.
2805
2953
  */
2806
- async CreateExampleRecords(extractedExamples, contextUser) {
2954
+ async createExampleRecords(extractedExamples, contextUser) {
2807
2955
  // Step 8: Create Example Records
2808
- const step8 = await this.CreateRunStep('Decision', 'Create Example Records', {
2956
+ const step8 = await this.createRunStep('Decision', 'Create Example Records', {
2809
2957
  exampleCount: extractedExamples.length
2810
2958
  });
2811
2959
  let created = 0;
@@ -2879,13 +3027,23 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2879
3027
  }
2880
3028
  }
2881
3029
  // Finalize Step 8
2882
- await this.FinalizeRunStep(step8, failed === 0 || created > 0, {
3030
+ await this.finalizeRunStep(step8, failed === 0 || created > 0, {
2883
3031
  created,
2884
3032
  skipped,
2885
3033
  failed
2886
3034
  });
2887
3035
  return created;
2888
3036
  }
3037
+ /**
3038
+ * The run's merged agent-type prompt params: the agent type's defaults, then the Memory Manager
3039
+ * agent's own `AgentTypePromptParams`, then the run's `data.__agentTypePromptParams`. This agent
3040
+ * renders no Loop prompt, so it merges them itself, once per run.
3041
+ */
3042
+ runPromptParams(params) {
3043
+ const agentType = AIEngine.Instance.AgentTypes.find(at => UUIDsEqual(at.ID, params.agent.TypeID));
3044
+ const override = params.data?.__agentTypePromptParams;
3045
+ return this.buildAgentTypePromptParams(agentType, params.agent, IsPlainObject(override) ? override : undefined);
3046
+ }
2889
3047
  /**
2890
3048
  * Main execution method called by scheduler
2891
3049
  */
@@ -2893,6 +3051,11 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2893
3051
  try {
2894
3052
  // Use verbose flag from agent execution params or data payload (UI passes it via data)
2895
3053
  this._verbose = params.verbose || params.data?.verbose || false;
3054
+ if (typeof params.data?.enableDecisionGate === 'boolean') {
3055
+ this._enableDecisionGate = params.data.enableDecisionGate;
3056
+ }
3057
+ this._runPromptParams = this.runPromptParams(params);
3058
+ this._cancellationToken = params.cancellationToken;
2896
3059
  // Initialize observability state for this run
2897
3060
  this._agentRunID = this.AgentRun?.ID || null;
2898
3061
  this._stepCounter = 0;
@@ -2903,8 +3066,8 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2903
3066
  // Phase 1: the last-run-time and the memory-enabled agent set are independent — load in
2904
3067
  // parallel (avoids two back-to-back sequential RunViews flagged by the parallelization telemetry).
2905
3068
  const [lastRunTime, agentsUsingMemory] = await Promise.all([
2906
- this.GetLastRunTime(params.agent.ID, params.contextUser),
2907
- this.LoadAgentsUsingMemory(params.contextUser)
3069
+ this.getLastRunTime(params.agent.ID, params.contextUser),
3070
+ this.loadAgentsUsingMemory(params.contextUser)
2908
3071
  ]);
2909
3072
  if (this._verbose) {
2910
3073
  const sinceMessage = lastRunTime ? `since ${lastRunTime.toISOString()}` : 'all history';
@@ -2922,34 +3085,34 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2922
3085
  // Phase 2: conversations-with-new-activity and high-value agent runs both depend only on
2923
3086
  // (lastRunTime, agentsUsingMemory) — never on each other — so load them in parallel, each
2924
3087
  // recorded in its own run step.
2925
- const step1 = await this.CreateRunStep('Decision', 'Load Conversations With New Activity', {
3088
+ const step1 = await this.createRunStep('Decision', 'Load Conversations With New Activity', {
2926
3089
  since: lastRunTime?.toISOString() || null,
2927
3090
  agentCount: agentsUsingMemory.length,
2928
3091
  agentIds: agentsUsingMemory.map(a => a.ID)
2929
3092
  });
2930
- const step2 = await this.CreateRunStep('Decision', 'Load High-Value Agent Runs', {
3093
+ const step2 = await this.createRunStep('Decision', 'Load High-Value Agent Runs', {
2931
3094
  since: lastRunTime?.toISOString() || null
2932
3095
  });
2933
- const step3 = await this.CreateRunStep('Decision', 'Load Instructive Failed Agent Runs', {
3096
+ const step3 = await this.createRunStep('Decision', 'Load Instructive Failed Agent Runs', {
2934
3097
  since: lastRunTime?.toISOString() || null
2935
3098
  });
2936
3099
  const [conversations, agentRuns, failedRuns] = await Promise.all([
2937
- this.LoadConversationsWithNewActivity(lastRunTime, agentsUsingMemory, params.contextUser),
2938
- this.LoadHighValueAgentRuns(lastRunTime, params.contextUser),
2939
- this.LoadInstructiveFailedAgentRuns(lastRunTime, params.contextUser)
3100
+ this.loadConversationsWithNewActivity(lastRunTime, agentsUsingMemory, params.contextUser),
3101
+ this.loadHighValueAgentRuns(lastRunTime, params.contextUser),
3102
+ this.loadInstructiveFailedAgentRuns(lastRunTime, params.contextUser)
2940
3103
  ]);
2941
3104
  const totalMessages = conversations.reduce((sum, c) => sum + c.messages.length, 0);
2942
- await this.FinalizeRunStep(step1, true, {
3105
+ await this.finalizeRunStep(step1, true, {
2943
3106
  conversationCount: conversations.length,
2944
3107
  totalMessages,
2945
3108
  positiveCount: conversations.filter(c => c.hasPositiveRating).length,
2946
3109
  negativeCount: conversations.filter(c => c.hasNegativeRating).length,
2947
3110
  unratedCount: conversations.filter(c => c.isUnrated).length
2948
3111
  });
2949
- await this.FinalizeRunStep(step2, true, {
3112
+ await this.finalizeRunStep(step2, true, {
2950
3113
  runCount: agentRuns.length
2951
3114
  });
2952
- await this.FinalizeRunStep(step3, true, {
3115
+ await this.finalizeRunStep(step3, true, {
2953
3116
  runCount: failedRuns.length
2954
3117
  });
2955
3118
  if (this._verbose) {
@@ -2968,12 +3131,12 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2968
3131
  let notesCreated = 0;
2969
3132
  let examplesCreated = 0;
2970
3133
  if (hasNewData) {
2971
- const extractedNotes = await this.ExtractNotesFromConversations(conversations, params.contextUser);
3134
+ const extractedNotes = await this.extractNotesFromConversations(conversations, params.contextUser);
2972
3135
  if (this._verbose) {
2973
3136
  LogStatus(`Memory Manager: Extracted ${extractedNotes.length} potential notes`);
2974
3137
  }
2975
3138
  // Mine corrective notes from failed runs (Issue/Context only, Ephemeral tier).
2976
- const correctiveNotes = await this.ExtractNotesFromFailedRuns(failedRuns, params.contextUser);
3139
+ const correctiveNotes = await this.extractNotesFromFailedRuns(failedRuns, params.contextUser);
2977
3140
  if (this._verbose) {
2978
3141
  LogStatus(`Memory Manager: Extracted ${correctiveNotes.length} corrective notes from failed runs`);
2979
3142
  }
@@ -2987,7 +3150,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2987
3150
  Message: msg.message,
2988
3151
  __mj_CreatedAt: msg.createdAt
2989
3152
  })));
2990
- const extractedExamples = await this.ExtractExamples(conversationDetails, params.contextUser);
3153
+ const extractedExamples = await this.extractExamples(conversationDetails, params.contextUser);
2991
3154
  if (this._verbose) {
2992
3155
  LogStatus(`Memory Manager: Extracted ${extractedExamples.length} potential examples`);
2993
3156
  }
@@ -3024,8 +3187,8 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
3024
3187
  example.agentId = '';
3025
3188
  }
3026
3189
  }
3027
- notesCreated = await this.CreateNoteRecords([...extractedNotes, ...correctiveNotes], params.contextUser);
3028
- examplesCreated = await this.CreateExampleRecords(extractedExamples, params.contextUser);
3190
+ notesCreated = await this.createNoteRecords([...extractedNotes, ...correctiveNotes], params.contextUser);
3191
+ examplesCreated = await this.createExampleRecords(extractedExamples, params.contextUser);
3029
3192
  if (this._verbose)
3030
3193
  LogStatus(`Memory Manager: Created ${notesCreated} notes and ${examplesCreated} examples`);
3031
3194
  }