@memberjunction/ai-agents 5.41.0 → 5.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +10 -0
  2. package/dist/agent-types/flow-agent-type.d.ts.map +1 -1
  3. package/dist/agent-types/flow-agent-type.js +10 -2
  4. package/dist/agent-types/flow-agent-type.js.map +1 -1
  5. package/dist/base-agent.d.ts +57 -51
  6. package/dist/base-agent.d.ts.map +1 -1
  7. package/dist/base-agent.js +239 -187
  8. package/dist/base-agent.js.map +1 -1
  9. package/dist/index.d.ts +3 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +3 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/memory-manager-agent.d.ts +44 -2
  14. package/dist/memory-manager-agent.d.ts.map +1 -1
  15. package/dist/memory-manager-agent.js +133 -100
  16. package/dist/memory-manager-agent.js.map +1 -1
  17. package/dist/realtime/bridge-realtime-session-factory.d.ts +111 -0
  18. package/dist/realtime/bridge-realtime-session-factory.d.ts.map +1 -0
  19. package/dist/realtime/bridge-realtime-session-factory.js +163 -0
  20. package/dist/realtime/bridge-realtime-session-factory.js.map +1 -0
  21. package/dist/realtime/bridge-room-transcript-sink.d.ts +63 -0
  22. package/dist/realtime/bridge-room-transcript-sink.d.ts.map +1 -0
  23. package/dist/realtime/bridge-room-transcript-sink.js +151 -0
  24. package/dist/realtime/bridge-room-transcript-sink.js.map +1 -0
  25. package/dist/realtime/realtime-client-session-service.d.ts +148 -6
  26. package/dist/realtime/realtime-client-session-service.d.ts.map +1 -1
  27. package/dist/realtime/realtime-client-session-service.js +241 -35
  28. package/dist/realtime/realtime-client-session-service.js.map +1 -1
  29. package/dist/realtime/realtime-coagent-config.d.ts +142 -7
  30. package/dist/realtime/realtime-coagent-config.d.ts.map +1 -1
  31. package/dist/realtime/realtime-coagent-config.js +176 -8
  32. package/dist/realtime/realtime-coagent-config.js.map +1 -1
  33. package/dist/realtime/realtime-tool-broker.d.ts +15 -0
  34. package/dist/realtime/realtime-tool-broker.d.ts.map +1 -1
  35. package/dist/realtime/realtime-tool-broker.js +22 -0
  36. package/dist/realtime/realtime-tool-broker.js.map +1 -1
  37. package/dist/realtime/realtime-turn-moderator.d.ts +103 -0
  38. package/dist/realtime/realtime-turn-moderator.d.ts.map +1 -0
  39. package/dist/realtime/realtime-turn-moderator.js +266 -0
  40. package/dist/realtime/realtime-turn-moderator.js.map +1 -0
  41. package/package.json +17 -17
package/dist/index.d.ts CHANGED
@@ -43,6 +43,9 @@ export * from './MJAIAgentRequestEntityServer.js';
43
43
  export * from './KnowledgeAgent.js';
44
44
  export * from './ClientToolRequestManager.js';
45
45
  export * from './realtime/realtime-session-runner.js';
46
+ export * from './realtime/bridge-realtime-session-factory.js';
47
+ export * from './realtime/bridge-room-transcript-sink.js';
48
+ export * from './realtime/realtime-turn-moderator.js';
46
49
  export { RealtimeToolBroker, RealtimeToolBrokerDeps, ExecutedToolCall, DelegatedRunArtifact } from './realtime/realtime-tool-broker.js';
47
50
  export * from './realtime/realtime-client-session-service.js';
48
51
  export * from './realtime/realtime-coagent-config.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,wCAAwC,CAAC;AACvD,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,0CAA0C,CAAC;AACzD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iCAAiC,CAAC;AAChD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AAKnD,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACrI,cAAc,4CAA4C,CAAC;AAC3D,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yCAAyC,CAAC;AACxD,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,4CAA4C,CAAC;AAG3D,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,0BAA0B,EAC1B,mBAAmB,EACnB,0BAA0B,EAC1B,WAAW,GACZ,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,wCAAwC,CAAC;AACvD,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,0CAA0C,CAAC;AACzD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iCAAiC,CAAC;AAChD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AACnD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AAKnD,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACrI,cAAc,4CAA4C,CAAC;AAC3D,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yCAAyC,CAAC;AACxD,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,4CAA4C,CAAC;AAG3D,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,0BAA0B,EAC1B,mBAAmB,EACnB,0BAA0B,EAC1B,WAAW,GACZ,MAAM,6BAA6B,CAAC"}
package/dist/index.js CHANGED
@@ -43,6 +43,9 @@ export * from './MJAIAgentRequestEntityServer.js';
43
43
  export * from './KnowledgeAgent.js';
44
44
  export * from './ClientToolRequestManager.js';
45
45
  export * from './realtime/realtime-session-runner.js';
46
+ export * from './realtime/bridge-realtime-session-factory.js';
47
+ export * from './realtime/bridge-room-transcript-sink.js';
48
+ export * from './realtime/realtime-turn-moderator.js';
46
49
  // Broker-unique exports. The shared tool-execution contract (INVOKE_TARGET_AGENT_TOOL_NAME,
47
50
  // DelegateToTargetRequest, DelegatedResult, ToolExecutionResult, loggers) is surfaced via the
48
51
  // runner's `export *` above, so only the broker-specific symbols are named here to avoid a
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,wCAAwC,CAAC;AACvD,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,0CAA0C,CAAC;AACzD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iCAAiC,CAAC;AAChD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AACnD,4FAA4F;AAC5F,8FAA8F;AAC9F,2FAA2F;AAC3F,8BAA8B;AAC9B,OAAO,EAAE,kBAAkB,EAAkE,MAAM,iCAAiC,CAAC;AACrI,cAAc,4CAA4C,CAAC;AAC3D,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yCAAyC,CAAC;AACxD,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,4CAA4C,CAAC;AAE3D,wDAAwD;AACxD,OAAO,EACL,eAAe,EAEf,0BAA0B,EAG1B,WAAW,GACZ,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,wCAAwC,CAAC;AACvD,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,0CAA0C,CAAC;AACzD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iCAAiC,CAAC;AAChD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AACnD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,4FAA4F;AAC5F,8FAA8F;AAC9F,2FAA2F;AAC3F,8BAA8B;AAC9B,OAAO,EAAE,kBAAkB,EAAkE,MAAM,iCAAiC,CAAC;AACrI,cAAc,4CAA4C,CAAC;AAC3D,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yCAAyC,CAAC;AACxD,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,4CAA4C,CAAC;AAE3D,wDAAwD;AACxD,OAAO,EACL,eAAe,EAEf,0BAA0B,EAG1B,WAAW,GACZ,MAAM,6BAA6B,CAAC"}
@@ -379,7 +379,20 @@ export declare class MemoryManagerAgent extends BaseAgent {
379
379
  */
380
380
  private pruneStaleReferences;
381
381
  /**
382
- * Load auto-generated, non-immutable Active notes that are candidates for orphan pruning.
382
+ * Collect auto-generated, non-immutable `Active` notes that are candidates for orphan
383
+ * pruning, oldest first.
384
+ *
385
+ * Served from the `AIEngine` cache rather than a `RunView`: `AIEngine.Instance.AgentNotes`
386
+ * holds the full note pool, loaded unfiltered as entity objects and kept current via
387
+ * `BaseEntity` save/delete events, so an equivalent in-memory filter/sort/cap avoids both a
388
+ * DB round-trip and the "Entity Already in Engine" redundancy-telemetry warning each cycle.
389
+ * Note `.filter()` returns a fresh array, so the subsequent `.sort()` never reorders the
390
+ * engine's cached array. The result is projected to plain {@link PruneCandidateNote} rows —
391
+ * we never hand a cached `BaseEntity` instance to a mutating caller; `pruneStaleReferences`
392
+ * re-`Load()`s a fresh, owned entity before archiving.
393
+ *
394
+ * @param maxRows Hard cap on candidates returned this cycle (oldest-`__mj_CreatedAt` first).
395
+ * @returns Lightweight projection rows for orphan-reference evaluation.
383
396
  */
384
397
  private loadPruneCandidateNotes;
385
398
  /**
@@ -426,6 +439,25 @@ export declare class MemoryManagerAgent extends BaseAgent {
426
439
  private summarizeDecayFactors;
427
440
  /** Archive notes and examples past their explicit ExpiresAt timestamp, regardless of decay score. */
428
441
  private archiveExpiredItems;
442
+ /**
443
+ * Find notes and examples whose explicit `ExpiresAt` timestamp has passed, so the
444
+ * archival pass can expire them regardless of decay score.
445
+ *
446
+ * Served from the `AIEngine` caches (`AgentNotes` / `AgentExamples`) instead of a batched
447
+ * `RunViews`: both pools are loaded unfiltered as entity objects and kept current via
448
+ * `BaseEntity` events, so an in-memory filter/cap reproduces the former queries while
449
+ * removing two DB round-trips and the pair of "Entity Already in Engine" redundancy
450
+ * warnings they emitted. Rows are projected to plain shapes; `archiveExpiredNote` /
451
+ * `archiveExpiredExample` re-`Load()` a fresh, owned entity before mutating.
452
+ *
453
+ * Notes include `Provisional` (via {@link IsInjectableNoteStatus} — the same Active+Provisional
454
+ * predicate used by the read-path injection queries) so the TTL safety net on in-flight
455
+ * agent writes is enforced: a provisional note the hardening pass never reaches must still
456
+ * expire.
457
+ *
458
+ * @param nowISO Current time as an ISO string; items with `ExpiresAt` strictly before this are expired.
459
+ * @returns A `[expiredNotes, expiredExamples]` tuple of projection rows (each capped at 200).
460
+ */
429
461
  private loadExpiredItems;
430
462
  private archiveExpiredNote;
431
463
  private archiveExpiredExample;
@@ -440,7 +472,17 @@ export declare class MemoryManagerAgent extends BaseAgent {
440
472
  */
441
473
  private applyProportionalDecay;
442
474
  /**
443
- * Fetch notes and examples in parallel — they're independent.
475
+ * Fetch decay-candidate notes and examples from the AIEngine caches.
476
+ *
477
+ * Served from `AIEngine.Instance.AgentNotes` / `AgentExamples` (loaded unfiltered as
478
+ * entity objects and kept current via BaseEntity events), filtered/capped in-memory to
479
+ * mirror the former RunViews — avoids two "Entity Already in Engine" redundancy warnings
480
+ * and a DB round-trip per maintenance cycle. We project to plain candidate rows; the
481
+ * actual decay/archival re-Loads fresh entities.
482
+ *
483
+ * @returns A `[activeNotes, activeExamples]` tuple of decay-candidate projection rows
484
+ * (auto-generated `Active` notes capped at 1000; auto-generated `Active` examples
485
+ * scoring below 50, capped at 500).
444
486
  */
445
487
  private loadDecayCandidates;
446
488
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"memory-manager-agent.d.ts","sourceRoot":"","sources":["../src/memory-manager-agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memory-manager-agent.d.ts","sourceRoot":"","sources":["../src/memory-manager-agent.ts"],"names":[],"mappings":"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"}
@@ -7,8 +7,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var MemoryManagerAgent_1;
8
8
  import { BaseAgent } from './base-agent.js';
9
9
  import { RegisterClass, CleanAndParseJSON } from '@memberjunction/global';
10
- import { RunView, RunQuery, LogError, LogStatus } from '@memberjunction/core';
11
- import { InjectableNoteStatusSQLList } from '@memberjunction/core-entities';
10
+ import { RunView, RunQuery, LogError, LogStatus, LogStatusEx } from '@memberjunction/core';
11
+ import { IsInjectableNoteStatus } from '@memberjunction/core-entities';
12
12
  import { AIPromptRunner } from '@memberjunction/ai-prompts';
13
13
  import { AIPromptParams } from '@memberjunction/ai-core-plus';
14
14
  import { AIEngine } from '@memberjunction/aiengine';
@@ -307,7 +307,9 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
307
307
  MaxRows: 1000 // Limit to 1000 conversations per run
308
308
  }, contextUser);
309
309
  if (!result.Success || !result.Results || result.Results.length === 0) {
310
- LogStatus('Memory Manager: No conversations with new activity found');
310
+ // Verbose-only: the common no-op outcome. The engine's "✅ Completed (Nms)" line already
311
+ // signals the run finished with no work; surfacing "why" is a verbose diagnostic detail.
312
+ LogStatusEx({ message: 'Memory Manager: No conversations with new activity found', verboseOnly: true });
311
313
  return [];
312
314
  }
313
315
  // Parse the query results into ConversationWithRatings objects
@@ -1266,20 +1268,26 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
1266
1268
  // Event-driven trigger: consolidate when at least `noteCountTrigger` new notes
1267
1269
  // have been added system-wide since the last Memory Manager run.
1268
1270
  //
1269
- // NOTE: this query intentionally does NOT filter by AgentID. The `agentId` parameter
1271
+ // NOTE: this count intentionally does NOT filter by AgentID. The `agentId` parameter
1270
1272
  // here is the Memory Manager's own ID (passed from `params.agent.ID` at the call
1271
1273
  // site), not the agent that owns the notes. Filtering the count by MM's own agent
1272
1274
  // ID would never match anything because MM doesn't own notes — it processes notes
1273
1275
  // belonging to other (memory-enabled) agents.
1274
- const rv = new RunView();
1275
- const newNoteResult = await rv.RunView({
1276
- EntityName: 'MJ: AI Agent Notes',
1277
- ExtraFilter: `IsAutoGenerated=1 AND Status='Active' AND __mj_CreatedAt > '${lastRun.toISOString()}'`,
1278
- ResultType: 'count_only'
1279
- }, contextUser);
1280
- if (newNoteResult.Success && (newNoteResult.TotalRowCount || 0) >= CONSOLIDATION_CONFIG.noteCountTrigger) {
1276
+ //
1277
+ // AIEngineBase caches `MJ: AI Agent Notes` unfiltered as full entity objects
1278
+ // (`AIEngine.Instance.AgentNotes`) and keeps that cache current via BaseEntity
1279
+ // save/delete events, so we count in-memory instead of a `count_only` RunView. This
1280
+ // avoids the "Entity Already in Engine" redundancy telemetry warning and a DB
1281
+ // round-trip on every maintenance cycle. Mirrors the cached-note filtering used
1282
+ // elsewhere in this class (e.g. buildMaintenanceSummary).
1283
+ const lastRunMs = lastRun.getTime();
1284
+ const newNoteCount = AIEngine.Instance.AgentNotes.filter(n => n.IsAutoGenerated &&
1285
+ n.Status === 'Active' &&
1286
+ n.__mj_CreatedAt != null &&
1287
+ new Date(n.__mj_CreatedAt).getTime() > lastRunMs).length;
1288
+ if (newNoteCount >= CONSOLIDATION_CONFIG.noteCountTrigger) {
1281
1289
  if (this._verbose) {
1282
- LogStatus(`Memory Manager: Event-driven consolidation trigger fired (${newNoteResult.TotalRowCount} new notes >= ${CONSOLIDATION_CONFIG.noteCountTrigger} threshold since last MM run)`);
1290
+ LogStatus(`Memory Manager: Event-driven consolidation trigger fired (${newNoteCount} new notes >= ${CONSOLIDATION_CONFIG.noteCountTrigger} threshold since last MM run)`);
1283
1291
  }
1284
1292
  return { shouldRun: true, triggerType: 'event' };
1285
1293
  }
@@ -1988,7 +1996,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
1988
1996
  async pruneStaleReferences(contextUser) {
1989
1997
  const maxPerCycle = STALE_PRUNING_CONFIG.maxNotesPerRun;
1990
1998
  const result = { notesArchived: 0, orphanedAgents: 0, orphanedUsers: 0, orphanedCompanies: 0, orphanedConversations: 0 };
1991
- const notes = await this.loadPruneCandidateNotes(contextUser, maxPerCycle * 2);
1999
+ const notes = this.loadPruneCandidateNotes(maxPerCycle * 2);
1992
2000
  if (notes.length === 0) {
1993
2001
  return result;
1994
2002
  }
@@ -2005,22 +2013,33 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2005
2013
  return result;
2006
2014
  }
2007
2015
  /**
2008
- * Load auto-generated, non-immutable Active notes that are candidates for orphan pruning.
2009
- */
2010
- async loadPruneCandidateNotes(contextUser, maxRows) {
2011
- const rv = new RunView();
2012
- const notesResult = await rv.RunView({
2013
- EntityName: 'MJ: AI Agent Notes',
2014
- ExtraFilter: `IsAutoGenerated = 1 AND Status = 'Active' AND ProtectionTier != 'Immutable'`,
2015
- Fields: ['ID', 'AgentID', 'UserID', 'CompanyID', 'SourceConversationID'],
2016
- OrderBy: '__mj_CreatedAt ASC',
2017
- MaxRows: maxRows,
2018
- ResultType: 'simple'
2019
- }, contextUser);
2020
- if (!notesResult.Success || !notesResult.Results?.length) {
2021
- return [];
2022
- }
2023
- return notesResult.Results;
2016
+ * Collect auto-generated, non-immutable `Active` notes that are candidates for orphan
2017
+ * pruning, oldest first.
2018
+ *
2019
+ * Served from the `AIEngine` cache rather than a `RunView`: `AIEngine.Instance.AgentNotes`
2020
+ * holds the full note pool, loaded unfiltered as entity objects and kept current via
2021
+ * `BaseEntity` save/delete events, so an equivalent in-memory filter/sort/cap avoids both a
2022
+ * DB round-trip and the "Entity Already in Engine" redundancy-telemetry warning each cycle.
2023
+ * Note `.filter()` returns a fresh array, so the subsequent `.sort()` never reorders the
2024
+ * engine's cached array. The result is projected to plain {@link PruneCandidateNote} rows —
2025
+ * we never hand a cached `BaseEntity` instance to a mutating caller; `pruneStaleReferences`
2026
+ * re-`Load()`s a fresh, owned entity before archiving.
2027
+ *
2028
+ * @param maxRows Hard cap on candidates returned this cycle (oldest-`__mj_CreatedAt` first).
2029
+ * @returns Lightweight projection rows for orphan-reference evaluation.
2030
+ */
2031
+ loadPruneCandidateNotes(maxRows) {
2032
+ return AIEngine.Instance.AgentNotes
2033
+ .filter(n => n.IsAutoGenerated && n.Status === 'Active' && (n.ProtectionTier || 'Standard') !== 'Immutable')
2034
+ .sort((a, b) => new Date(a.__mj_CreatedAt).getTime() - new Date(b.__mj_CreatedAt).getTime())
2035
+ .slice(0, maxRows)
2036
+ .map(n => ({
2037
+ ID: n.ID,
2038
+ AgentID: n.AgentID,
2039
+ UserID: n.UserID,
2040
+ CompanyID: n.CompanyID,
2041
+ SourceConversationID: n.SourceConversationID
2042
+ }));
2024
2043
  }
2025
2044
  /**
2026
2045
  * Build in-memory lookup caches of which referenced users/companies/conversations still
@@ -2199,7 +2218,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2199
2218
  const result = { notesExpired: 0, examplesExpired: 0 };
2200
2219
  const md = this.ProviderToUse;
2201
2220
  const nowISO = new Date().toISOString();
2202
- const [expiredNotes, expiredExamples] = await this.loadExpiredItems(contextUser, nowISO);
2221
+ const [expiredNotes, expiredExamples] = this.loadExpiredItems(nowISO);
2203
2222
  for (const note of expiredNotes) {
2204
2223
  if ((note.ProtectionTier || 'Standard') === 'Immutable')
2205
2224
  continue;
@@ -2212,31 +2231,36 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2212
2231
  }
2213
2232
  return result;
2214
2233
  }
2215
- async loadExpiredItems(contextUser, nowISO) {
2216
- const rv = new RunView();
2217
- const [notesResult, examplesResult] = await rv.RunViews([
2218
- {
2219
- EntityName: 'MJ: AI Agent Notes',
2220
- // Includes Provisional so the TTL safety net on in-flight agent writes is
2221
- // actually enforced — a provisional note the hardening pass never reaches
2222
- // must still expire.
2223
- ExtraFilter: `Status IN (${InjectableNoteStatusSQLList()}) AND ExpiresAt IS NOT NULL AND ExpiresAt < '${nowISO}'`,
2224
- Fields: ['ID', 'ExpiresAt', 'ProtectionTier'],
2225
- MaxRows: 200,
2226
- },
2227
- {
2228
- EntityName: 'MJ: AI Agent Examples',
2229
- ExtraFilter: `Status = 'Active' AND ExpiresAt IS NOT NULL AND ExpiresAt < '${nowISO}'`,
2230
- Fields: ['ID', 'ExpiresAt'],
2231
- MaxRows: 200,
2232
- }
2233
- ], contextUser);
2234
- return [
2235
- notesResult.Success && notesResult.Results
2236
- ? notesResult.Results.filter((r) => 'ProtectionTier' in r)
2237
- : [],
2238
- examplesResult.Success && examplesResult.Results ? examplesResult.Results : []
2239
- ];
2234
+ /**
2235
+ * Find notes and examples whose explicit `ExpiresAt` timestamp has passed, so the
2236
+ * archival pass can expire them regardless of decay score.
2237
+ *
2238
+ * Served from the `AIEngine` caches (`AgentNotes` / `AgentExamples`) instead of a batched
2239
+ * `RunViews`: both pools are loaded unfiltered as entity objects and kept current via
2240
+ * `BaseEntity` events, so an in-memory filter/cap reproduces the former queries while
2241
+ * removing two DB round-trips and the pair of "Entity Already in Engine" redundancy
2242
+ * warnings they emitted. Rows are projected to plain shapes; `archiveExpiredNote` /
2243
+ * `archiveExpiredExample` re-`Load()` a fresh, owned entity before mutating.
2244
+ *
2245
+ * Notes include `Provisional` (via {@link IsInjectableNoteStatus} — the same Active+Provisional
2246
+ * predicate used by the read-path injection queries) so the TTL safety net on in-flight
2247
+ * agent writes is enforced: a provisional note the hardening pass never reaches must still
2248
+ * expire.
2249
+ *
2250
+ * @param nowISO Current time as an ISO string; items with `ExpiresAt` strictly before this are expired.
2251
+ * @returns A `[expiredNotes, expiredExamples]` tuple of projection rows (each capped at 200).
2252
+ */
2253
+ loadExpiredItems(nowISO) {
2254
+ const nowMs = new Date(nowISO).getTime();
2255
+ const expiredNotes = AIEngine.Instance.AgentNotes
2256
+ .filter(n => IsInjectableNoteStatus(n.Status) && n.ExpiresAt != null && new Date(n.ExpiresAt).getTime() < nowMs)
2257
+ .slice(0, 200)
2258
+ .map(n => ({ ID: n.ID, ExpiresAt: n.ExpiresAt, ProtectionTier: n.ProtectionTier || 'Standard' }));
2259
+ const expiredExamples = AIEngine.Instance.AgentExamples
2260
+ .filter(e => e.Status === 'Active' && e.ExpiresAt != null && new Date(e.ExpiresAt).getTime() < nowMs)
2261
+ .slice(0, 200)
2262
+ .map(e => ({ ID: e.ID, ExpiresAt: e.ExpiresAt }));
2263
+ return [expiredNotes, expiredExamples];
2240
2264
  }
2241
2265
  async archiveExpiredNote(note, md, contextUser) {
2242
2266
  const noteToArchive = await md.GetEntityObject('MJ: AI Agent Notes', contextUser);
@@ -2267,7 +2291,7 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2267
2291
  const result = { notesDecayed: 0, notesArchived: 0, examplesDecayed: 0, examplesArchived: 0 };
2268
2292
  const stats = { decayFactors: [], protectedPreserved: 0, ephemeralAccelerated: 0 };
2269
2293
  const md = this.ProviderToUse;
2270
- const [activeNotes, activeExamples] = await this.loadDecayCandidates(contextUser);
2294
+ const [activeNotes, activeExamples] = this.loadDecayCandidates();
2271
2295
  for (const note of activeNotes) {
2272
2296
  await this.decayOneNote(note, archiveEnabledAgentIds, md, contextUser, result, stats);
2273
2297
  }
@@ -2277,36 +2301,43 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2277
2301
  return { ...result, stats };
2278
2302
  }
2279
2303
  /**
2280
- * Fetch notes and examples in parallel — they're independent.
2281
- */
2282
- async loadDecayCandidates(contextUser) {
2283
- // Batch into one RunViews round-trip — see loadExpiredItems for the rationale on why
2284
- // two parallel RunView calls are flagged sequential by the redundancy telemetry. The
2285
- // two projections differ, so the batch is typed with their union and narrowed by
2286
- // position (notes carry ProtectionTier, examples carry SuccessScore).
2287
- const rv = new RunView();
2288
- const [activeNotesResult, activeExamplesResult] = await rv.RunViews([
2289
- {
2290
- EntityName: 'MJ: AI Agent Notes',
2291
- ExtraFilter: `IsAutoGenerated = 1 AND Status = 'Active'`,
2292
- Fields: ['ID', 'ImportanceScore', 'ProtectionTier', 'LastAccessedAt', '__mj_CreatedAt', 'AccessCount', 'AgentID'],
2293
- MaxRows: 1000,
2294
- },
2295
- {
2296
- EntityName: 'MJ: AI Agent Examples',
2297
- ExtraFilter: `IsAutoGenerated = 1 AND Status = 'Active' AND SuccessScore < 50`,
2298
- Fields: ['ID', 'SuccessScore', 'LastAccessedAt', '__mj_CreatedAt', 'AccessCount', 'AgentID'],
2299
- MaxRows: 500,
2300
- }
2301
- ], contextUser);
2302
- return [
2303
- activeNotesResult.Success && activeNotesResult.Results
2304
- ? activeNotesResult.Results.filter((r) => 'ProtectionTier' in r)
2305
- : [],
2306
- activeExamplesResult.Success && activeExamplesResult.Results
2307
- ? activeExamplesResult.Results.filter((r) => 'SuccessScore' in r)
2308
- : []
2309
- ];
2304
+ * Fetch decay-candidate notes and examples from the AIEngine caches.
2305
+ *
2306
+ * Served from `AIEngine.Instance.AgentNotes` / `AgentExamples` (loaded unfiltered as
2307
+ * entity objects and kept current via BaseEntity events), filtered/capped in-memory to
2308
+ * mirror the former RunViews — avoids two "Entity Already in Engine" redundancy warnings
2309
+ * and a DB round-trip per maintenance cycle. We project to plain candidate rows; the
2310
+ * actual decay/archival re-Loads fresh entities.
2311
+ *
2312
+ * @returns A `[activeNotes, activeExamples]` tuple of decay-candidate projection rows
2313
+ * (auto-generated `Active` notes capped at 1000; auto-generated `Active` examples
2314
+ * scoring below 50, capped at 500).
2315
+ */
2316
+ loadDecayCandidates() {
2317
+ const activeNotes = AIEngine.Instance.AgentNotes
2318
+ .filter(n => n.IsAutoGenerated && n.Status === 'Active')
2319
+ .slice(0, 1000)
2320
+ .map(n => ({
2321
+ ID: n.ID,
2322
+ ImportanceScore: n.ImportanceScore,
2323
+ ProtectionTier: n.ProtectionTier || 'Standard',
2324
+ LastAccessedAt: n.LastAccessedAt,
2325
+ __mj_CreatedAt: n.__mj_CreatedAt,
2326
+ AccessCount: n.AccessCount,
2327
+ AgentID: n.AgentID
2328
+ }));
2329
+ const activeExamples = AIEngine.Instance.AgentExamples
2330
+ .filter(e => e.IsAutoGenerated && e.Status === 'Active' && (e.SuccessScore ?? 0) < 50)
2331
+ .slice(0, 500)
2332
+ .map(e => ({
2333
+ ID: e.ID,
2334
+ SuccessScore: e.SuccessScore,
2335
+ LastAccessedAt: e.LastAccessedAt,
2336
+ __mj_CreatedAt: e.__mj_CreatedAt,
2337
+ AccessCount: e.AccessCount,
2338
+ AgentID: e.AgentID
2339
+ }));
2340
+ return [activeNotes, activeExamples];
2310
2341
  }
2311
2342
  /**
2312
2343
  * Apply proportional decay to a single note. Archives if the decayed score drops below
@@ -2396,19 +2427,19 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2396
2427
  maxNotesPerRun: HARDENING_CONFIG.maxNotesPerRun
2397
2428
  });
2398
2429
  try {
2399
- const rv = new RunView();
2400
- const result = await rv.RunView({
2401
- EntityName: 'MJ: AI Agent Notes',
2402
- ExtraFilter: `Status = 'Provisional' AND AuthorType = 'Agent'`,
2403
- OrderBy: '__mj_CreatedAt ASC',
2404
- MaxRows: HARDENING_CONFIG.maxNotesPerRun,
2405
- ResultType: 'entity_object'
2406
- }, contextUser);
2407
- if (!result.Success) {
2408
- await this.FinalizeRunStep(step, false, counters, undefined, `Failed to load provisional notes: ${result.ErrorMessage}`);
2409
- return counters;
2410
- }
2411
- const provisionalNotes = result.Results || [];
2430
+ // Served from AIEngine.Instance.AgentNotes (loaded unfiltered as entity
2431
+ // objects and kept current via BaseEntity + remote-invalidate events),
2432
+ // filtered/ordered/capped in-memory to mirror the former RunView. This
2433
+ // avoids the "Entity Already in Engine" redundancy warning and a DB
2434
+ // round-trip every MM cycle, matching loadDecayCandidates/loadExpiredItems.
2435
+ // Provisional agent notes are in-flight writes already reflected in the
2436
+ // cache, and hardenSingleNote mutates+saves these entities directly —
2437
+ // consistent with the dedupe path, which already saves cached note
2438
+ // instances returned by FindSimilarAgentNotes.
2439
+ const provisionalNotes = AIEngine.Instance.AgentNotes
2440
+ .filter(n => n.Status === 'Provisional' && n.AuthorType === 'Agent')
2441
+ .sort((a, b) => new Date(a.__mj_CreatedAt).getTime() - new Date(b.__mj_CreatedAt).getTime())
2442
+ .slice(0, HARDENING_CONFIG.maxNotesPerRun);
2412
2443
  if (provisionalNotes.length === 0) {
2413
2444
  await this.FinalizeRunStep(step, true, { ...counters, provisionalCount: 0 });
2414
2445
  return counters;
@@ -2766,7 +2797,9 @@ let MemoryManagerAgent = MemoryManagerAgent_1 = class MemoryManagerAgent extends
2766
2797
  this._agentRunID = this.AgentRun?.ID || null;
2767
2798
  this._stepCounter = 0;
2768
2799
  this._contextUser = params.contextUser || null;
2769
- LogStatus('Memory Manager: Starting analysis cycle');
2800
+ // Verbose-only: the scheduling engine's always-on "▶️ Starting / ✅ Completed" lines already
2801
+ // mark that this run began/ended. On routine no-op runs this internal trace is just noise.
2802
+ LogStatusEx({ message: 'Memory Manager: Starting analysis cycle', verboseOnly: true });
2770
2803
  // Phase 1: the last-run-time and the memory-enabled agent set are independent — load in
2771
2804
  // parallel (avoids two back-to-back sequential RunViews flagged by the parallelization telemetry).
2772
2805
  const [lastRunTime, agentsUsingMemory] = await Promise.all([