@psiclawops/hypermem 0.7.0 → 0.8.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 (87) hide show
  1. package/ARCHITECTURE.md +31 -39
  2. package/README.md +20 -14
  3. package/bin/hypermem-status.mjs +1 -1
  4. package/dist/background-indexer.d.ts +14 -3
  5. package/dist/background-indexer.d.ts.map +1 -1
  6. package/dist/background-indexer.js +135 -27
  7. package/dist/budget-policy.d.ts +22 -0
  8. package/dist/budget-policy.d.ts.map +1 -0
  9. package/dist/budget-policy.js +27 -0
  10. package/dist/cache.d.ts +11 -0
  11. package/dist/cache.d.ts.map +1 -1
  12. package/dist/compositor-utils.d.ts +31 -0
  13. package/dist/compositor-utils.d.ts.map +1 -0
  14. package/dist/compositor-utils.js +47 -0
  15. package/dist/compositor.d.ts +163 -1
  16. package/dist/compositor.d.ts.map +1 -1
  17. package/dist/compositor.js +862 -130
  18. package/dist/content-hash.d.ts +43 -0
  19. package/dist/content-hash.d.ts.map +1 -0
  20. package/dist/content-hash.js +75 -0
  21. package/dist/context-store.d.ts +54 -0
  22. package/dist/context-store.d.ts.map +1 -1
  23. package/dist/context-store.js +102 -0
  24. package/dist/contradiction-audit-store.d.ts +54 -0
  25. package/dist/contradiction-audit-store.d.ts.map +1 -0
  26. package/dist/contradiction-audit-store.js +88 -0
  27. package/dist/contradiction-resolution-policy.d.ts +21 -0
  28. package/dist/contradiction-resolution-policy.d.ts.map +1 -0
  29. package/dist/contradiction-resolution-policy.js +17 -0
  30. package/dist/cross-agent.d.ts +1 -1
  31. package/dist/cross-agent.js +17 -17
  32. package/dist/degradation.d.ts +102 -0
  33. package/dist/degradation.d.ts.map +1 -0
  34. package/dist/degradation.js +141 -0
  35. package/dist/dreaming-promoter.d.ts +39 -1
  36. package/dist/dreaming-promoter.d.ts.map +1 -1
  37. package/dist/dreaming-promoter.js +70 -4
  38. package/dist/index.d.ts +70 -8
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +405 -29
  41. package/dist/knowledge-lint.d.ts +2 -0
  42. package/dist/knowledge-lint.d.ts.map +1 -1
  43. package/dist/knowledge-lint.js +40 -1
  44. package/dist/library-schema.d.ts +7 -2
  45. package/dist/library-schema.d.ts.map +1 -1
  46. package/dist/library-schema.js +236 -1
  47. package/dist/message-store.d.ts +64 -1
  48. package/dist/message-store.d.ts.map +1 -1
  49. package/dist/message-store.js +137 -1
  50. package/dist/proactive-pass.d.ts +2 -2
  51. package/dist/proactive-pass.d.ts.map +1 -1
  52. package/dist/proactive-pass.js +66 -12
  53. package/dist/replay-recovery.d.ts +29 -0
  54. package/dist/replay-recovery.d.ts.map +1 -0
  55. package/dist/replay-recovery.js +82 -0
  56. package/dist/reranker.d.ts +95 -0
  57. package/dist/reranker.d.ts.map +1 -0
  58. package/dist/reranker.js +308 -0
  59. package/dist/schema.d.ts +1 -1
  60. package/dist/schema.d.ts.map +1 -1
  61. package/dist/schema.js +46 -1
  62. package/dist/seed.d.ts +1 -1
  63. package/dist/seed.js +1 -1
  64. package/dist/session-flusher.d.ts +4 -4
  65. package/dist/session-flusher.d.ts.map +1 -1
  66. package/dist/session-flusher.js +3 -3
  67. package/dist/spawn-context.d.ts +1 -1
  68. package/dist/spawn-context.js +1 -1
  69. package/dist/tool-artifact-store.d.ts +98 -0
  70. package/dist/tool-artifact-store.d.ts.map +1 -0
  71. package/dist/tool-artifact-store.js +244 -0
  72. package/dist/topic-detector.js +2 -2
  73. package/dist/topic-store.d.ts +6 -0
  74. package/dist/topic-store.d.ts.map +1 -1
  75. package/dist/topic-store.js +39 -0
  76. package/dist/topic-synthesizer.js +1 -1
  77. package/dist/trigger-registry.d.ts +1 -1
  78. package/dist/trigger-registry.js +4 -4
  79. package/dist/types.d.ts +235 -3
  80. package/dist/types.d.ts.map +1 -1
  81. package/dist/vector-store.d.ts +2 -1
  82. package/dist/vector-store.d.ts.map +1 -1
  83. package/dist/vector-store.js +3 -0
  84. package/dist/version.d.ts +10 -10
  85. package/dist/version.d.ts.map +1 -1
  86. package/dist/version.js +10 -10
  87. package/package.json +6 -4
@@ -26,6 +26,9 @@ import { EpisodeStore } from './episode-store.js';
26
26
  import { TopicStore } from './topic-store.js';
27
27
  import { KnowledgeStore } from './knowledge-store.js';
28
28
  import { TemporalStore } from './temporal-store.js';
29
+ import { ContradictionDetector } from './contradiction-detector.js';
30
+ import { ContradictionAuditStore } from './contradiction-audit-store.js';
31
+ import { DEFAULT_CONTRADICTION_POLICY } from './contradiction-resolution-policy.js';
29
32
  import { isSafeForSharedVisibility } from './secret-scanner.js';
30
33
  // ─── Agent-to-Domain Map ────────────────────────────────────────
31
34
  // Maps well-known agent IDs to their primary domain.
@@ -34,27 +37,27 @@ import { isSafeForSharedVisibility } from './secret-scanner.js';
34
37
  // returns results. New agents default to 'general'.
35
38
  //
36
39
  // ── EXAMPLE DATA ──────────────────────────────────────────────────
37
- // The agent names below (agent1, director1, etc.) are PLACEHOLDERS.
40
+ // The agent names below (alice, director1, etc.) are PLACEHOLDERS.
38
41
  // Replace them with your own agent IDs and domain labels to match
39
42
  // your fleet. Single-agent installs don't need to edit this:
40
43
  // unknown agents fall through to 'general' automatically.
41
44
  // See INSTALL.md § "Configure your fleet" for details.
42
45
  // ─────────────────────────────────────────────────────────────────
43
46
  const AGENT_DOMAIN_MAP = {
44
- agent1: 'infrastructure',
47
+ alice: 'infrastructure',
45
48
  director2: 'infrastructure',
46
49
  director1: 'infrastructure',
47
50
  director3: 'infrastructure',
48
- agent2: 'product',
51
+ bob: 'product',
49
52
  director4: 'product',
50
53
  director5: 'product',
51
54
  director6: 'product',
52
- agent3: 'security',
55
+ dave: 'security',
53
56
  director7: 'security',
54
57
  director8: 'security',
55
58
  agent4: 'ux',
56
- agent6: 'governance',
57
- agent5: 'strategy',
59
+ carol: 'governance',
60
+ oscar: 'strategy',
58
61
  specialist1: 'development',
59
62
  specialist2: 'communications',
60
63
  main: 'general',
@@ -91,7 +94,7 @@ function extractFactCandidates(content) {
91
94
  // Preference patterns — medium confidence (0.60)
92
95
  const preferencePatterns = [
93
96
  /(?:prefer|always use|never use|don't use|avoid) (.{10,150})/gi,
94
- /(?:operator|operator) (?:wants|prefers|likes|hates|dislikes) (.{10,150})/gi,
97
+ /(?:operator) (?:wants|prefers|likes|hates|dislikes) (.{10,150})/gi,
95
98
  ];
96
99
  // Operational patterns: deployments, incidents, fixes — high confidence (0.70)
97
100
  const operationalPatterns = [
@@ -145,7 +148,7 @@ const OPERATIONAL_BOILERPLATE = [
145
148
  /still\s*waiting/i,
146
149
  /will\s*pick\s*(it\s*)?up\s*(on\s*(next|the))?/i,
147
150
  /message\s*is\s*in\s*(his|her|their|the)\s*queue/i,
148
- /sent\s+to\s+(agent6|agent2|agent4|agent3|agent5|agent1)/i,
151
+ /sent\s+to\s+(carol|bob|agent4|dave|oscar|alice)/i,
149
152
  /dispatched\s+(it\s+)?to/i,
150
153
  /timed\s*out\s*after/i,
151
154
  /\bNO_REPLY\b/,
@@ -390,7 +393,7 @@ function detectTopic(content) {
390
393
  if (!content || content.length < 50)
391
394
  return null;
392
395
  // Product/project name detection
393
- const productMatch = content.match(/\b(HyperMem|ClawText|ClawDash|ClawCanvas|ClawCouncil|ClawTomation|OpenClaw|ClawDispatch)\b/i);
396
+ const productMatch = content.match(/\b(HyperMem|ClawText|dashboard|canvas|council|automation|OpenClaw|dispatch)\b/i);
394
397
  if (productMatch)
395
398
  return productMatch[1];
396
399
  // Infrastructure topic detection
@@ -411,6 +414,8 @@ export class BackgroundIndexer {
411
414
  getCursor;
412
415
  config;
413
416
  dreamerConfig;
417
+ globalWritePolicy;
418
+ contradictionPolicy;
414
419
  intervalHandle = null;
415
420
  running = false;
416
421
  vectorStore = null;
@@ -420,7 +425,9 @@ export class BackgroundIndexer {
420
425
  consecutiveFailures = 0;
421
426
  /** True when the indexer is running in backoff mode due to repeated failures. */
422
427
  inBackoff = false;
423
- constructor(config, getMessageDb, getLibraryDb, listAgents, getCursor, dreamerConfig) {
428
+ _conversationLastProcessed = new Map();
429
+ lastMaintenanceDiagnostics = null;
430
+ constructor(config, getMessageDb, getLibraryDb, listAgents, getCursor, dreamerConfig, globalWritePolicy, contradictionPolicy) {
424
431
  this.getMessageDb = getMessageDb;
425
432
  this.getLibraryDb = getLibraryDb;
426
433
  this.listAgents = listAgents;
@@ -451,8 +458,13 @@ export class BackgroundIndexer {
451
458
  periodicInterval: config?.periodicInterval ?? 60000, // 1 minute
452
459
  batchSize: config?.batchSize ?? 128,
453
460
  maxMessagesPerTick: config?.maxMessagesPerTick ?? 500,
461
+ maxActiveConversations: config?.maxActiveConversations ?? 5,
462
+ recentConversationCooldownMs: config?.recentConversationCooldownMs ?? 30000,
463
+ maxCandidatesPerPass: config?.maxCandidatesPerPass ?? 200,
454
464
  };
455
465
  this.dreamerConfig = dreamerConfig ?? {};
466
+ this.globalWritePolicy = globalWritePolicy ?? 'deny';
467
+ this.contradictionPolicy = contradictionPolicy ?? DEFAULT_CONTRADICTION_POLICY;
456
468
  }
457
469
  /**
458
470
  * Set the vector store for embedding new facts/episodes at index time.
@@ -686,27 +698,72 @@ export class BackgroundIndexer {
686
698
  }
687
699
  }
688
700
  // Run proactive passes on each agent's message DB
701
+ const maintStart = Date.now();
702
+ let maintConsidered = 0;
703
+ let maintSkipped = 0;
704
+ let maintScanned = 0;
705
+ let maintMutated = 0;
706
+ let maintExitReason = 'complete';
707
+ const maxConvs = this.config.maxActiveConversations ?? 5;
708
+ const cooldownMs = this.config.recentConversationCooldownMs ?? 30000;
709
+ const maxCandidates = this.config.maxCandidatesPerPass ?? 200;
710
+ const now = Date.now();
689
711
  for (const agentId of agents) {
690
712
  const messageDb = this.getMessageDb(agentId);
691
713
  if (!messageDb)
692
714
  continue;
693
- // Get active conversations for this agent
694
715
  let convRows;
695
716
  try {
696
- convRows = messageDb.prepare(`SELECT id FROM conversations WHERE agent_id = ? AND status = 'active' ORDER BY updated_at DESC LIMIT 10`).all(agentId);
717
+ convRows = messageDb.prepare(`SELECT id FROM conversations WHERE agent_id = ? AND status = 'active' ORDER BY updated_at DESC LIMIT ?`).all(agentId, maxConvs);
697
718
  }
698
719
  catch {
699
720
  continue;
700
721
  }
722
+ if (convRows.length === 0) {
723
+ if (maintExitReason === 'complete')
724
+ maintExitReason = 'no-conversations';
725
+ continue;
726
+ }
701
727
  for (const conv of convRows) {
702
- const noiseSweepResult = runNoiseSweep(messageDb, conv.id);
703
- const toolDecayResult = runToolDecay(messageDb, conv.id);
704
- // Log only if something changed
705
- if (noiseSweepResult.messagesDeleted > 0 || toolDecayResult.messagesUpdated > 0) {
728
+ maintConsidered++;
729
+ const lastProcessed = this._conversationLastProcessed.get(conv.id) ?? 0;
730
+ if (now - lastProcessed < cooldownMs) {
731
+ maintSkipped++;
732
+ continue;
733
+ }
734
+ maintScanned++;
735
+ // Any successful scan means we're in a real working state —
736
+ // clear any stale 'no-conversations' marker from an earlier agent.
737
+ if (maintExitReason === 'no-conversations')
738
+ maintExitReason = 'complete';
739
+ const noiseSweepResult = runNoiseSweep(messageDb, conv.id, 20, maxCandidates);
740
+ const toolDecayResult = runToolDecay(messageDb, conv.id, 40, maxCandidates);
741
+ const changed = noiseSweepResult.messagesDeleted + toolDecayResult.messagesUpdated;
742
+ if (changed > 0) {
743
+ maintMutated += changed;
706
744
  console.log(`[indexer] Proactive pass (conv ${conv.id}): swept ${noiseSweepResult.messagesDeleted} noise msgs, ` +
707
745
  `decayed ${toolDecayResult.messagesUpdated} tool results (${toolDecayResult.bytesFreed} bytes freed)`);
708
746
  }
747
+ this._conversationLastProcessed.set(conv.id, now);
748
+ if (maintMutated >= maxCandidates) {
749
+ maintExitReason = 'cap-reached';
750
+ break;
751
+ }
709
752
  }
753
+ if (maintExitReason === 'cap-reached')
754
+ break;
755
+ }
756
+ this.lastMaintenanceDiagnostics = {
757
+ considered: maintConsidered,
758
+ skipped: maintSkipped,
759
+ scanned: maintScanned,
760
+ mutated: maintMutated,
761
+ durationMs: Date.now() - maintStart,
762
+ exitReason: maintExitReason,
763
+ };
764
+ if (maintScanned > 0) {
765
+ console.log(`[indexer] Maintenance: considered=${maintConsidered} skipped=${maintSkipped} scanned=${maintScanned} mutated=${maintMutated} ` +
766
+ `duration=${this.lastMaintenanceDiagnostics.durationMs}ms exit=${maintExitReason}`);
710
767
  }
711
768
  // If we reach here, the tick completed without throwing.
712
769
  tickSucceeded = true;
@@ -758,6 +815,9 @@ export class BackgroundIndexer {
758
815
  knowledgeUpserted: 0,
759
816
  tombstoned,
760
817
  postCursorMessages: 0,
818
+ contradictionAuditsLogged: 0,
819
+ contradictionsAutoSuperseded: 0,
820
+ contradictionsAutoInvalidated: 0,
761
821
  elapsedMs: Date.now() - start,
762
822
  };
763
823
  }
@@ -791,7 +851,16 @@ export class BackgroundIndexer {
791
851
  let topicsUpdated = 0;
792
852
  let knowledgeUpserted = 0;
793
853
  let supersededFacts = 0;
854
+ let contradictionAuditsLogged = 0;
855
+ let contradictionsAutoSuperseded = 0;
856
+ let contradictionsAutoInvalidated = 0;
794
857
  let maxMessageId = lastProcessedId;
858
+ const contradictionDetector = new ContradictionDetector(factStore, this.vectorStore ?? undefined, {
859
+ autoResolve: false,
860
+ maxCandidates: 6,
861
+ minSimilarity: 0.45,
862
+ });
863
+ const contradictionAuditStore = new ContradictionAuditStore(libraryDb);
795
864
  for (const msg of ordered) {
796
865
  const content = msg.textContent || '';
797
866
  if (msg.id > maxMessageId)
@@ -803,15 +872,50 @@ export class BackgroundIndexer {
803
872
  const factCandidates = extractFactCandidates(content);
804
873
  for (const { content: factContent, confidence: factConfidence } of factCandidates) {
805
874
  try {
875
+ const factDomain = domainForAgent(agentId);
876
+ // 1. Detect contradictions BEFORE addFact (operates on existing facts only)
877
+ const contradictionResult = await contradictionDetector.detectOnIngest(agentId, {
878
+ content: factContent,
879
+ domain: factDomain,
880
+ });
881
+ const topContradictions = contradictionResult.contradictions.slice(0, 3);
882
+ // 2. addFact first — we need fact.id for supersede linkage
806
883
  const fact = factStore.addFact(agentId, factContent, {
807
884
  scope: 'agent',
808
- domain: domainForAgent(agentId),
885
+ domain: factDomain,
809
886
  confidence: factConfidence,
810
887
  sourceType: 'indexer',
811
888
  sourceSessionKey: this.getSessionKeyForMessage(messageDb, msg.conversationId),
812
889
  sourceRef: `msg:${msg.id}`,
813
890
  });
814
891
  factsExtracted++;
892
+ // 3. Apply contradiction policy for each candidate (now we have fact.id)
893
+ for (const candidate of topContradictions) {
894
+ const score = candidate.contradictionScore;
895
+ let auditStatus = 'pending';
896
+ if (score >= this.contradictionPolicy.autoSupersedeThreshold) {
897
+ const didSupersede = factStore.markSuperseded(candidate.existingFactId, fact.id);
898
+ if (didSupersede) {
899
+ contradictionsAutoSuperseded++;
900
+ // Immediately remove stale vector so it cannot surface in KNN recall
901
+ if (this.vectorStore) {
902
+ this.vectorStore.removeItem('facts', candidate.existingFactId);
903
+ }
904
+ }
905
+ auditStatus = 'auto-superseded';
906
+ }
907
+ else if (score >= this.contradictionPolicy.autoInvalidateThreshold) {
908
+ const didInvalidate = factStore.invalidateFact(candidate.existingFactId);
909
+ if (didInvalidate) {
910
+ contradictionsAutoInvalidated++;
911
+ }
912
+ auditStatus = 'auto-invalidated';
913
+ }
914
+ if (this.contradictionPolicy.alwaysAudit || auditStatus === 'pending') {
915
+ contradictionAuditStore.recordFactAudit(agentId, { content: factContent, domain: factDomain }, candidate, { sourceRef: `msg:${msg.id}`, status: auditStatus });
916
+ contradictionAuditsLogged++;
917
+ }
918
+ }
815
919
  // ── Supersedes detection ─────────────────────────────────
816
920
  // Check if the newly extracted fact supersedes an existing one.
817
921
  // A supersede is detected when an existing active fact shares the
@@ -868,17 +972,18 @@ export class BackgroundIndexer {
868
972
  }
869
973
  // 3. Detect and update topics
870
974
  const topicName = detectTopic(content);
871
- if (topicName) {
975
+ if (topicName && topicName.trim().length >= 3) {
872
976
  try {
873
- const existingTopics = topicStore.getActive(agentId, 100);
874
- const existingTopic = existingTopics.find((t) => t.name.toLowerCase() === topicName.toLowerCase());
875
- if (!existingTopic) {
876
- topicStore.create(agentId, topicName, `Auto-detected from conversation`);
877
- topicsUpdated++;
878
- }
977
+ const msgSessionKey = this.getSessionKeyForMessage(messageDb, msg.conversationId) || '';
978
+ // findOrCreate handles case-insensitive dedup at the schema level;
979
+ // always touch afterward so message_count reflects real activity
980
+ // rather than sitting at 0 forever (which made every topic an orphan).
981
+ const topic = topicStore.findOrCreate(agentId, topicName, `Auto-detected from conversation`);
982
+ topicStore.touch(topic.id, msgSessionKey, 1);
983
+ topicsUpdated++;
879
984
  }
880
985
  catch {
881
- // Skip topic creation errors
986
+ // Skip topic creation/touch errors
882
987
  }
883
988
  }
884
989
  // 4. Extract knowledge candidates
@@ -912,6 +1017,9 @@ export class BackgroundIndexer {
912
1017
  topicsUpdated,
913
1018
  knowledgeUpserted,
914
1019
  tombstoned,
1020
+ contradictionAuditsLogged,
1021
+ contradictionsAutoSuperseded,
1022
+ contradictionsAutoInvalidated,
915
1023
  postCursorMessages: postCursor.length,
916
1024
  elapsedMs: Date.now() - start,
917
1025
  };
@@ -1146,8 +1254,8 @@ export class BackgroundIndexer {
1146
1254
  * Create and start a background indexer connected to hypermem databases.
1147
1255
  * Used by the hook or a standalone daemon.
1148
1256
  */
1149
- export function createIndexer(getMessageDb, getLibraryDb, listAgents, config, getCursor, vectorStore, dreamerConfig) {
1150
- const indexer = new BackgroundIndexer(config, getMessageDb, getLibraryDb, listAgents, getCursor, dreamerConfig);
1257
+ export function createIndexer(getMessageDb, getLibraryDb, listAgents, config, getCursor, vectorStore, dreamerConfig, globalWritePolicy) {
1258
+ const indexer = new BackgroundIndexer(config, getMessageDb, getLibraryDb, listAgents, getCursor, dreamerConfig, globalWritePolicy);
1151
1259
  if (vectorStore)
1152
1260
  indexer.setVectorStore(vectorStore);
1153
1261
  return indexer;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Canonical budget policy for history-window trim and steady-state gradient caps.
3
+ *
4
+ * Phase C C0.1 centralizes these values so compose, afterTurn refresh, plugin
5
+ * trim guards, and regression tests all consume the same source of truth.
6
+ */
7
+ export declare const TRIM_SOFT_TARGET = 0.65;
8
+ export declare const TRIM_GROWTH_THRESHOLD = 0.05;
9
+ export declare const TRIM_HEADROOM_FRACTION = 0.1;
10
+ export interface TrimBudgetPolicy {
11
+ trimSoftTarget: number;
12
+ trimGrowthThreshold: number;
13
+ trimHeadroomFraction: number;
14
+ }
15
+ export interface ResolvedTrimBudgets extends TrimBudgetPolicy {
16
+ softBudget: number;
17
+ triggerBudget: number;
18
+ targetBudget: number;
19
+ }
20
+ export declare const TRIM_BUDGET_POLICY: TrimBudgetPolicy;
21
+ export declare function resolveTrimBudgets(effectiveBudget: number): ResolvedTrimBudgets;
22
+ //# sourceMappingURL=budget-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget-policy.d.ts","sourceRoot":"","sources":["../src/budget-policy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,eAAO,MAAM,sBAAsB,MAAO,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,kBAAkB,EAAE,gBAI/B,CAAC;AAEH,wBAAgB,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,mBAAmB,CAW/E"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Canonical budget policy for history-window trim and steady-state gradient caps.
3
+ *
4
+ * Phase C C0.1 centralizes these values so compose, afterTurn refresh, plugin
5
+ * trim guards, and regression tests all consume the same source of truth.
6
+ */
7
+ export const TRIM_SOFT_TARGET = 0.65;
8
+ export const TRIM_GROWTH_THRESHOLD = 0.05;
9
+ export const TRIM_HEADROOM_FRACTION = 0.10;
10
+ export const TRIM_BUDGET_POLICY = Object.freeze({
11
+ trimSoftTarget: TRIM_SOFT_TARGET,
12
+ trimGrowthThreshold: TRIM_GROWTH_THRESHOLD,
13
+ trimHeadroomFraction: TRIM_HEADROOM_FRACTION,
14
+ });
15
+ export function resolveTrimBudgets(effectiveBudget) {
16
+ const safeBudget = Math.max(0, Math.floor(effectiveBudget || 0));
17
+ const softBudget = Math.floor(safeBudget * TRIM_SOFT_TARGET);
18
+ const triggerBudget = Math.floor(softBudget * (1 + TRIM_GROWTH_THRESHOLD));
19
+ const targetBudget = Math.floor(softBudget * (1 - TRIM_HEADROOM_FRACTION));
20
+ return {
21
+ ...TRIM_BUDGET_POLICY,
22
+ softBudget,
23
+ triggerBudget,
24
+ targetBudget,
25
+ };
26
+ }
27
+ //# sourceMappingURL=budget-policy.js.map
package/dist/cache.d.ts CHANGED
@@ -19,6 +19,17 @@ export interface WindowCacheMeta {
19
19
  warnings: string[];
20
20
  diagnostics: ComposeDiagnostics;
21
21
  composedAt: string;
22
+ /**
23
+ * Deterministic SHA-256 hash of the stable cacheable prefix at compose time.
24
+ * Stored so the C4 fast-exit can detect stable-prefix mutations even when
25
+ * the cursor (message id) has not advanced (e.g. system prompt / identity changed).
26
+ */
27
+ prefixHash?: string;
28
+ /**
29
+ * SHA-256 hash of the system + identity slot contents that fed the stable prefix.
30
+ * Used by C4 to cheaply detect slot mutations without re-running full compose.
31
+ */
32
+ prefixInputHash?: string;
22
33
  }
23
34
  export declare class CacheLayer {
24
35
  private db;
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * compositor-utils.ts — Utility functions for context window composition.
3
+ *
4
+ * Provides ordering strategies that improve LLM attention over retrieved
5
+ * documents placed into a prompt.
6
+ */
7
+ /**
8
+ * Reorder documents using zigzag placement to mitigate
9
+ * "Lost in the Middle" attention degradation in LLMs.
10
+ *
11
+ * LLMs exhibit a U-shaped attention curve: items at the beginning and end
12
+ * of context receive ~30% more attention than items in the middle.
13
+ * This function places the most relevant items at the edges and the least
14
+ * relevant items near the center, maximising effective attention on the
15
+ * information that matters most.
16
+ *
17
+ * Reference: Liu et al., "Lost in the Middle: How Language Models Use Long
18
+ * Contexts", ICLR 2025. https://arxiv.org/abs/2307.03172
19
+ *
20
+ * Input: [d1, d2, d3, d4, d5] (sorted by relevance, descending)
21
+ * Output: [d1, d3, d5, d4, d2] (most relevant at edges, least in middle)
22
+ *
23
+ * Algorithm:
24
+ * - Items at even positions in the input (0, 2, 4, …) fill from the front.
25
+ * - Items at odd positions in the input (1, 3, 5, …) fill from the back.
26
+ *
27
+ * @param docs - Array sorted by relevance (most relevant first).
28
+ * @returns A new array reordered so the most relevant items sit at the edges.
29
+ */
30
+ export declare function zigzagOrder<T>(docs: T[]): T[];
31
+ //# sourceMappingURL=compositor-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compositor-utils.d.ts","sourceRoot":"","sources":["../src/compositor-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAkB7C"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * compositor-utils.ts — Utility functions for context window composition.
3
+ *
4
+ * Provides ordering strategies that improve LLM attention over retrieved
5
+ * documents placed into a prompt.
6
+ */
7
+ /**
8
+ * Reorder documents using zigzag placement to mitigate
9
+ * "Lost in the Middle" attention degradation in LLMs.
10
+ *
11
+ * LLMs exhibit a U-shaped attention curve: items at the beginning and end
12
+ * of context receive ~30% more attention than items in the middle.
13
+ * This function places the most relevant items at the edges and the least
14
+ * relevant items near the center, maximising effective attention on the
15
+ * information that matters most.
16
+ *
17
+ * Reference: Liu et al., "Lost in the Middle: How Language Models Use Long
18
+ * Contexts", ICLR 2025. https://arxiv.org/abs/2307.03172
19
+ *
20
+ * Input: [d1, d2, d3, d4, d5] (sorted by relevance, descending)
21
+ * Output: [d1, d3, d5, d4, d2] (most relevant at edges, least in middle)
22
+ *
23
+ * Algorithm:
24
+ * - Items at even positions in the input (0, 2, 4, …) fill from the front.
25
+ * - Items at odd positions in the input (1, 3, 5, …) fill from the back.
26
+ *
27
+ * @param docs - Array sorted by relevance (most relevant first).
28
+ * @returns A new array reordered so the most relevant items sit at the edges.
29
+ */
30
+ export function zigzagOrder(docs) {
31
+ if (docs.length <= 2) {
32
+ return docs.slice();
33
+ }
34
+ const result = new Array(docs.length);
35
+ let front = 0;
36
+ let back = docs.length - 1;
37
+ for (let i = 0; i < docs.length; i++) {
38
+ if (i % 2 === 0) {
39
+ result[front++] = docs[i];
40
+ }
41
+ else {
42
+ result[back--] = docs[i];
43
+ }
44
+ }
45
+ return result;
46
+ }
47
+ //# sourceMappingURL=compositor-utils.js.map