@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.
- package/README.md +43 -0
- package/dist/AgentDataPreloader.d.ts +4 -0
- package/dist/AgentDataPreloader.d.ts.map +1 -1
- package/dist/AgentDataPreloader.js +10 -2
- package/dist/AgentDataPreloader.js.map +1 -1
- package/dist/AgentDecisionService.d.ts +83 -0
- package/dist/AgentDecisionService.d.ts.map +1 -0
- package/dist/AgentDecisionService.js +155 -0
- package/dist/AgentDecisionService.js.map +1 -0
- package/dist/AgentRunner.d.ts +16 -4
- package/dist/AgentRunner.d.ts.map +1 -1
- package/dist/AgentRunner.js +55 -32
- package/dist/AgentRunner.js.map +1 -1
- package/dist/ArtifactToolManager.d.ts +4 -4
- package/dist/ArtifactToolManager.js +10 -10
- package/dist/ConversationToolManager.d.ts +16 -3
- package/dist/ConversationToolManager.d.ts.map +1 -1
- package/dist/ConversationToolManager.js +28 -5
- package/dist/ConversationToolManager.js.map +1 -1
- package/dist/KnowledgeAgent.d.ts.map +1 -1
- package/dist/KnowledgeAgent.js +6 -6
- package/dist/KnowledgeAgent.js.map +1 -1
- package/dist/PayloadChangeAnalyzer.d.ts +4 -0
- package/dist/PayloadChangeAnalyzer.d.ts.map +1 -1
- package/dist/PayloadChangeAnalyzer.js +10 -2
- package/dist/PayloadChangeAnalyzer.js.map +1 -1
- package/dist/PayloadFeedbackManager.d.ts +120 -13
- package/dist/PayloadFeedbackManager.d.ts.map +1 -1
- package/dist/PayloadFeedbackManager.js +244 -88
- package/dist/PayloadFeedbackManager.js.map +1 -1
- package/dist/PayloadManager.d.ts +27 -0
- package/dist/PayloadManager.d.ts.map +1 -1
- package/dist/PayloadManager.js +47 -15
- package/dist/PayloadManager.js.map +1 -1
- package/dist/agent-context-injector.d.ts +47 -3
- package/dist/agent-context-injector.d.ts.map +1 -1
- package/dist/agent-context-injector.js +77 -10
- package/dist/agent-context-injector.js.map +1 -1
- package/dist/agent-memory-context-builder.d.ts +13 -0
- package/dist/agent-memory-context-builder.d.ts.map +1 -1
- package/dist/agent-memory-context-builder.js +24 -5
- package/dist/agent-memory-context-builder.js.map +1 -1
- package/dist/agent-types/base-agent-type.d.ts +16 -0
- package/dist/agent-types/base-agent-type.d.ts.map +1 -1
- package/dist/agent-types/base-agent-type.js +20 -1
- package/dist/agent-types/base-agent-type.js.map +1 -1
- package/dist/agent-types/flow-agent-type.d.ts +106 -0
- package/dist/agent-types/flow-agent-type.d.ts.map +1 -1
- package/dist/agent-types/flow-agent-type.js +299 -29
- package/dist/agent-types/flow-agent-type.js.map +1 -1
- package/dist/agent-types/flow-graph-executor.d.ts +12 -1
- package/dist/agent-types/flow-graph-executor.d.ts.map +1 -1
- package/dist/agent-types/flow-graph-executor.js +25 -1
- package/dist/agent-types/flow-graph-executor.js.map +1 -1
- package/dist/agent-types/loop-agent-prompt-params.d.ts +258 -11
- package/dist/agent-types/loop-agent-prompt-params.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-prompt-params.js +49 -2
- package/dist/agent-types/loop-agent-prompt-params.js.map +1 -1
- package/dist/agent-types/loop-agent-response-type.d.ts +12 -1
- package/dist/agent-types/loop-agent-response-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-response-type.js.map +1 -1
- package/dist/agent-types/loop-agent-type.d.ts +6 -0
- package/dist/agent-types/loop-agent-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-type.js +42 -3
- package/dist/agent-types/loop-agent-type.js.map +1 -1
- package/dist/artifact-target-plan.d.ts +2 -0
- package/dist/artifact-target-plan.d.ts.map +1 -1
- package/dist/artifact-target-plan.js +5 -1
- package/dist/artifact-target-plan.js.map +1 -1
- package/dist/base-agent.d.ts +886 -5
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +2567 -164
- package/dist/base-agent.js.map +1 -1
- package/dist/catalog-narrowing.d.ts +136 -0
- package/dist/catalog-narrowing.d.ts.map +1 -0
- package/dist/catalog-narrowing.js +212 -0
- package/dist/catalog-narrowing.js.map +1 -0
- package/dist/constants.d.ts +57 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +70 -0
- package/dist/constants.js.map +1 -0
- package/dist/decision-discovery.d.ts +401 -0
- package/dist/decision-discovery.d.ts.map +1 -0
- package/dist/decision-discovery.js +511 -0
- package/dist/decision-discovery.js.map +1 -0
- package/dist/finish-if-mode-warnings.d.ts +39 -0
- package/dist/finish-if-mode-warnings.d.ts.map +1 -0
- package/dist/finish-if-mode-warnings.js +78 -0
- package/dist/finish-if-mode-warnings.js.map +1 -0
- package/dist/finish-if-state.d.ts +72 -0
- package/dist/finish-if-state.d.ts.map +1 -0
- package/dist/finish-if-state.js +109 -0
- package/dist/finish-if-state.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/memory-manager-agent.d.ts +119 -13
- package/dist/memory-manager-agent.d.ts.map +1 -1
- package/dist/memory-manager-agent.js +237 -74
- package/dist/memory-manager-agent.js.map +1 -1
- package/dist/memory-note-gate.d.ts +208 -0
- package/dist/memory-note-gate.d.ts.map +1 -0
- package/dist/memory-note-gate.js +294 -0
- package/dist/memory-note-gate.js.map +1 -0
- package/dist/native-tools/action-tool-builder.d.ts +8 -0
- package/dist/native-tools/action-tool-builder.d.ts.map +1 -1
- package/dist/native-tools/action-tool-builder.js +22 -6
- package/dist/native-tools/action-tool-builder.js.map +1 -1
- package/dist/native-tools/control-tools.d.ts +8 -0
- package/dist/native-tools/control-tools.d.ts.map +1 -1
- package/dist/native-tools/control-tools.js +25 -9
- package/dist/native-tools/control-tools.js.map +1 -1
- package/dist/native-tools/dual-channel.d.ts +2 -0
- package/dist/native-tools/dual-channel.d.ts.map +1 -1
- package/dist/native-tools/dual-channel.js +5 -1
- package/dist/native-tools/dual-channel.js.map +1 -1
- package/dist/native-tools/tool-result-turns.d.ts +9 -0
- package/dist/native-tools/tool-result-turns.d.ts.map +1 -1
- package/dist/native-tools/tool-result-turns.js +15 -3
- package/dist/native-tools/tool-result-turns.js.map +1 -1
- package/dist/pipeline/coerce.d.ts +14 -0
- package/dist/pipeline/coerce.d.ts.map +1 -1
- package/dist/pipeline/coerce.js +37 -9
- package/dist/pipeline/coerce.js.map +1 -1
- package/dist/pipeline/jsonpath-eval.d.ts +4 -0
- package/dist/pipeline/jsonpath-eval.d.ts.map +1 -1
- package/dist/pipeline/jsonpath-eval.js +10 -2
- package/dist/pipeline/jsonpath-eval.js.map +1 -1
- package/dist/pipeline/operators.js +16 -16
- package/dist/pipeline/path.d.ts +6 -0
- package/dist/pipeline/path.d.ts.map +1 -1
- package/dist/pipeline/path.js +17 -5
- package/dist/pipeline/path.js.map +1 -1
- package/dist/pipeline/pipeline-executor.js +10 -10
- package/dist/pipeline/predicate.d.ts +4 -0
- package/dist/pipeline/predicate.d.ts.map +1 -1
- package/dist/pipeline/predicate.js +15 -7
- package/dist/pipeline/predicate.js.map +1 -1
- package/dist/pipeline/providers/action-provider.js +2 -2
- package/dist/pipeline/providers/artifact-tool-provider.js +2 -2
- package/dist/pipeline/providers/serialize.d.ts +4 -0
- package/dist/pipeline/providers/serialize.d.ts.map +1 -1
- package/dist/pipeline/providers/serialize.js +10 -2
- package/dist/pipeline/providers/serialize.js.map +1 -1
- package/dist/pipeline/template.d.ts +4 -0
- package/dist/pipeline/template.d.ts.map +1 -1
- package/dist/pipeline/template.js +15 -7
- package/dist/pipeline/template.js.map +1 -1
- package/dist/realtime/agent-media-library.d.ts +10 -0
- package/dist/realtime/agent-media-library.d.ts.map +1 -1
- package/dist/realtime/agent-media-library.js +29 -9
- package/dist/realtime/agent-media-library.js.map +1 -1
- package/dist/realtime/bridge-realtime-session-factory.d.ts +5 -2
- package/dist/realtime/bridge-realtime-session-factory.d.ts.map +1 -1
- package/dist/realtime/bridge-realtime-session-factory.js +7 -4
- package/dist/realtime/bridge-realtime-session-factory.js.map +1 -1
- package/dist/realtime/bridge-room-transcript-sink.d.ts.map +1 -1
- package/dist/realtime/bridge-room-transcript-sink.js +15 -9
- package/dist/realtime/bridge-room-transcript-sink.js.map +1 -1
- package/dist/realtime/media-channel-server.js +2 -2
- package/dist/realtime/meeting-controls-state.d.ts +2 -0
- package/dist/realtime/meeting-controls-state.d.ts.map +1 -1
- package/dist/realtime/meeting-controls-state.js +6 -2
- package/dist/realtime/meeting-controls-state.js.map +1 -1
- package/dist/realtime/realtime-channel-server-data-context.d.ts +2 -0
- package/dist/realtime/realtime-channel-server-data-context.d.ts.map +1 -1
- package/dist/realtime/realtime-channel-server-data-context.js +5 -1
- package/dist/realtime/realtime-channel-server-data-context.js.map +1 -1
- package/dist/realtime/realtime-channel-server-host.js +2 -2
- package/dist/realtime/realtime-client-session-service.d.ts +58 -12
- package/dist/realtime/realtime-client-session-service.d.ts.map +1 -1
- package/dist/realtime/realtime-client-session-service.js +91 -31
- package/dist/realtime/realtime-client-session-service.js.map +1 -1
- package/dist/realtime/realtime-coagent-config.d.ts +2 -0
- package/dist/realtime/realtime-coagent-config.d.ts.map +1 -1
- package/dist/realtime/realtime-coagent-config.js +6 -2
- package/dist/realtime/realtime-coagent-config.js.map +1 -1
- package/dist/realtime/realtime-recording-store.d.ts +15 -0
- package/dist/realtime/realtime-recording-store.d.ts.map +1 -1
- package/dist/realtime/realtime-recording-store.js +31 -7
- package/dist/realtime/realtime-recording-store.js.map +1 -1
- package/dist/realtime/realtime-session-runner.d.ts +4 -4
- package/dist/realtime/realtime-session-runner.js +9 -9
- package/dist/realtime/realtime-session-runner.js.map +1 -1
- package/dist/realtime/realtime-vendor-resolution.d.ts +8 -3
- package/dist/realtime/realtime-vendor-resolution.d.ts.map +1 -1
- package/dist/realtime/realtime-vendor-resolution.js +3 -3
- package/dist/realtime/realtime-vendor-resolution.js.map +1 -1
- package/dist/rubric-evaluation-agent-runner.d.ts +2 -0
- package/dist/rubric-evaluation-agent-runner.d.ts.map +1 -0
- package/dist/rubric-evaluation-agent-runner.js +38 -0
- package/dist/rubric-evaluation-agent-runner.js.map +1 -0
- package/dist/runtime-state-fragment.d.ts +101 -0
- package/dist/runtime-state-fragment.d.ts.map +1 -0
- package/dist/runtime-state-fragment.js +173 -0
- package/dist/runtime-state-fragment.js.map +1 -0
- package/dist/self-check.d.ts +98 -0
- package/dist/self-check.d.ts.map +1 -0
- package/dist/self-check.js +74 -0
- package/dist/self-check.js.map +1 -0
- package/dist/types/payload-operations.d.ts +8 -0
- package/dist/types/payload-operations.d.ts.map +1 -1
- package/dist/types/payload-operations.js +21 -5
- package/dist/types/payload-operations.js.map +1 -1
- package/dist/utils/ConversationMessageResolver.d.ts +4 -0
- package/dist/utils/ConversationMessageResolver.d.ts.map +1 -1
- package/dist/utils/ConversationMessageResolver.js +10 -2
- package/dist/utils/ConversationMessageResolver.js.map +1 -1
- package/dist/volatile-child-prompt.d.ts +33 -0
- package/dist/volatile-child-prompt.d.ts.map +1 -0
- package/dist/volatile-child-prompt.js +76 -0
- package/dist/volatile-child-prompt.js.map +1 -0
- 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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
563
|
-
const candidateNotes = this.
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
1129
|
+
async createNoteRecords(extractedNotes, contextUser) {
|
|
982
1130
|
// Step 7: Create Note Records
|
|
983
|
-
const step7 = await this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
2737
|
-
const decayStep = await this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
2954
|
+
async createExampleRecords(extractedExamples, contextUser) {
|
|
2807
2955
|
// Step 8: Create Example Records
|
|
2808
|
-
const step8 = await this.
|
|
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.
|
|
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.
|
|
2907
|
-
this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
2938
|
-
this.
|
|
2939
|
-
this.
|
|
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.
|
|
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.
|
|
3112
|
+
await this.finalizeRunStep(step2, true, {
|
|
2950
3113
|
runCount: agentRuns.length
|
|
2951
3114
|
});
|
|
2952
|
-
await this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
3028
|
-
examplesCreated = await this.
|
|
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
|
}
|