@psiclawops/hypermem 0.8.4 → 0.8.5

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.
@@ -33,8 +33,8 @@ export interface FlushSessionResult {
33
33
  * from those stores naturally.
34
34
  *
35
35
  * @param cache Connected CacheLayer instance
36
- * @param agentId Agent identifier (e.g. "agent1")
37
- * @param sessionKey Full session key (e.g. "agent:agent1:webchat:scratchpad")
36
+ * @param agentId Agent identifier (e.g. "alice")
37
+ * @param sessionKey Full session key (e.g. "agent:alice:webchat:scratchpad")
38
38
  * @param opts Optional flags
39
39
  */
40
40
  export declare function flushSession(cache: CacheLayer, agentId: string, sessionKey: string, opts?: FlushSessionOptions): Promise<FlushSessionResult>;
@@ -18,8 +18,8 @@
18
18
  * from those stores naturally.
19
19
  *
20
20
  * @param cache Connected CacheLayer instance
21
- * @param agentId Agent identifier (e.g. "agent1")
22
- * @param sessionKey Full session key (e.g. "agent:agent1:webchat:scratchpad")
21
+ * @param agentId Agent identifier (e.g. "alice")
22
+ * @param sessionKey Full session key (e.g. "agent:alice:webchat:scratchpad")
23
23
  * @param opts Optional flags
24
24
  */
25
25
  export async function flushSession(cache, agentId, sessionKey, opts = {}) {
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Usage:
8
8
  * const ctx = await buildSpawnContext(messageStore, docChunkStore, agentId, {
9
- * parentSessionKey: 'agent:agent1:webchat:main',
9
+ * parentSessionKey: 'agent:alice:webchat:main',
10
10
  * workingSnapshot: 10,
11
11
  * documents: ['/path/to/spec.md'],
12
12
  * });
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Usage:
8
8
  * const ctx = await buildSpawnContext(messageStore, docChunkStore, agentId, {
9
- * parentSessionKey: 'agent:agent1:webchat:main',
9
+ * parentSessionKey: 'agent:alice:webchat:main',
10
10
  * workingSnapshot: 10,
11
11
  * documents: ['/path/to/spec.md'],
12
12
  * });
@@ -12,12 +12,12 @@
12
12
  const KNOWN_NAMES = {
13
13
  hypermem: 'HyperMem',
14
14
  hyperbuilder: 'HyperBuilder',
15
- clawcanvas: 'ClawCanvas',
16
- clawdash: 'ClawDash',
17
- clawdispatch: 'ClawDispatch',
15
+ canvas: 'canvas',
16
+ dashboard: 'dashboard',
17
+ dispatch: 'dispatch',
18
18
  clawtext: 'ClawText',
19
- clawtomation: 'ClawTomation',
20
- clawcouncil: 'ClawCouncil',
19
+ automation: 'automation',
20
+ council: 'council',
21
21
  openclaw: 'OpenClaw',
22
22
  clawhub: 'ClawHub',
23
23
  };
@@ -35,7 +35,7 @@ function keystoneScore(msg) {
35
35
  const backtickMatches = text.match(/`[^`]+`/g) || [];
36
36
  score += backtickMatches.length * 0.2;
37
37
  // Agent mentions (known patterns)
38
- const agentMentions = text.match(/\b(agent1|agent2|agent4|agent3|agent5|agent6|director1|director2|director7|specialist2|specialist1)\b/gi) || [];
38
+ const agentMentions = text.match(/\b(alice|bob|agent4|dave|oscar|carol|director1|director2|director7|specialist2|specialist1)\b/gi) || [];
39
39
  score += agentMentions.length * 0.25;
40
40
  // Quoted content
41
41
  const quotedMatches = text.match(/"[^"]{10,}"/g) || [];
@@ -39,7 +39,7 @@ export interface CollectionTrigger {
39
39
  export declare const TRIGGER_REGISTRY_VERSION = "1.0.0";
40
40
  /**
41
41
  * Default trigger registry for standard ACA collections.
42
- * Covers the core ACA offload use case from agent6's spec.
42
+ * Covers the core ACA offload use case from carol's spec.
43
43
  */
44
44
  export declare const TRIGGER_REGISTRY: CollectionTrigger[];
45
45
  /** Backward-compat alias — same reference as TRIGGER_REGISTRY */
@@ -13,7 +13,7 @@ import { createHash } from 'node:crypto';
13
13
  export const TRIGGER_REGISTRY_VERSION = '1.0.0';
14
14
  /**
15
15
  * Default trigger registry for standard ACA collections.
16
- * Covers the core ACA offload use case from agent6's spec.
16
+ * Covers the core ACA offload use case from carol's spec.
17
17
  */
18
18
  export const TRIGGER_REGISTRY = [
19
19
  {
@@ -61,7 +61,7 @@ export const TRIGGER_REGISTRY = [
61
61
  ],
62
62
  maxTokens: 800,
63
63
  maxChunks: 2,
64
- owner: 'agent1',
64
+ owner: 'alice',
65
65
  category: 'operations',
66
66
  description: 'Agent operational procedures: boot sequence, heartbeat, work queue, session startup',
67
67
  },
@@ -98,7 +98,7 @@ export const TRIGGER_REGISTRY = [
98
98
  ],
99
99
  maxTokens: 1500,
100
100
  maxChunks: 4,
101
- owner: 'agent1',
101
+ owner: 'alice',
102
102
  category: 'memory',
103
103
  description: 'Decision history: past choices, previously agreed approaches, recalled context',
104
104
  },
@@ -124,7 +124,7 @@ export const TRIGGER_REGISTRY = [
124
124
  ],
125
125
  maxTokens: 1200,
126
126
  maxChunks: 3,
127
- owner: 'agent1',
127
+ owner: 'alice',
128
128
  category: 'operations',
129
129
  description: 'Agent tooling reference: CLI commands, config paths, deployment procedures, quick reference',
130
130
  },
package/dist/types.d.ts CHANGED
@@ -70,7 +70,7 @@ export type FactScope = 'agent' | 'session' | 'user';
70
70
  /**
71
71
  * Memory visibility levels:
72
72
  * - private: Only the owning agent can read. Identity, SOUL, personal reflections.
73
- * - org: Agents in the same org (e.g., agent1's directors: Pylon, Vigil, Plane).
73
+ * - org: Agents in the same org (e.g., alice's directors: Hank, Jack, Irene).
74
74
  * - council: All council seats can read.
75
75
  * - fleet: Any agent in the fleet can read.
76
76
  */
@@ -400,7 +400,7 @@ export interface ProviderMessage {
400
400
  * to identify high-signal unprocessed messages.
401
401
  *
402
402
  * Stored in Redis (hm:{a}:s:{s}:cursor) with dual-write to SQLite for
403
- * durability across Redis eviction (agent2 Gate 2).
403
+ * durability across Redis eviction (bob Gate 2).
404
404
  */
405
405
  export interface SessionCursor {
406
406
  /** StoredMessage.id of the newest message included in the last window */
package/docs/TUNING.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # hypermem Tuning Guide
2
2
 
3
- Configuration reference for operators and agents. All settings are optional, but the installer now writes a fully-expanded `config.json` so operators can see every default in one place.
3
+ Configuration reference for operators and agents. All settings are optional. The recommended install path writes a starter `config.json` with an explicit lightweight embedding choice and a declarative baseline compositor profile. Tune from that verified baseline, not from guesswork.
4
4
 
5
5
  Config lives in `~/.openclaw/hypermem/config.json` (takes effect on gateway restart) or is passed programmatically via `HyperMem.create()`:
6
6
 
@@ -23,6 +23,16 @@ Resolution order is:
23
23
  2. `~/.openclaw/hypermem/config.json`
24
24
  3. code defaults
25
25
 
26
+ ## Before you tune
27
+
28
+ Do not tune an install that is only staged. Verify these first:
29
+
30
+ 1. `openclaw plugins list` shows `hypercompositor` and `hypermem` loaded
31
+ 2. `openclaw logs --limit 50 | grep hypermem` shows `hypermem initialized`
32
+ 3. after a real agent message, logs show `[hypermem:compose]`
33
+
34
+ If any of those are missing, go back to `INSTALL.md`. That is an install-path problem, not a tuning problem.
35
+
26
36
  ---
27
37
 
28
38
  ## Token Cost Philosophy
package/install.sh CHANGED
@@ -323,31 +323,31 @@ write_config() {
323
323
  "warmCacheReplayThresholdMs": 120000,
324
324
  "subagentWarming": "light",
325
325
  "compositor": {
326
- "budgetFraction": 0.703,
326
+ "budgetFraction": 0.55,
327
327
  "reserveFraction": 0.25,
328
328
  "historyFraction": 0.4,
329
329
  "memoryFraction": 0.4,
330
330
  "defaultTokenBudget": 90000,
331
331
  "maxHistoryMessages": 500,
332
- "maxFacts": 30,
332
+ "maxFacts": 25,
333
333
  "maxExpertisePatterns": 6,
334
334
  "maxCrossSessionContext": 4000,
335
335
  "maxTotalTriggerTokens": 4000,
336
336
  "maxRecentToolPairs": 3,
337
337
  "maxProseToolPairs": 10,
338
- "warmHistoryBudgetFraction": 0.4,
338
+ "warmHistoryBudgetFraction": 0.27,
339
339
  "contextWindowReserve": 0.25,
340
340
  "dynamicReserveTurnHorizon": 5,
341
341
  "dynamicReserveMax": 0.5,
342
342
  "dynamicReserveEnabled": true,
343
- "keystoneHistoryFraction": 0.2,
344
- "keystoneMaxMessages": 15,
343
+ "keystoneHistoryFraction": 0.15,
344
+ "keystoneMaxMessages": 12,
345
345
  "keystoneMinSignificance": 0.5,
346
- "targetBudgetFraction": 0.65,
346
+ "targetBudgetFraction": 0.50,
347
347
  "enableFOS": true,
348
348
  "enableMOD": true,
349
349
  "hyperformProfile": "standard",
350
- "wikiTokenCap": 600,
350
+ "wikiTokenCap": 500,
351
351
  "zigzagOrdering": true
352
352
  },
353
353
  "eviction": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@psiclawops/hypermem-memory",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "HyperMem memory plugin for OpenClaw — bridges HyperMem retrieval into the memory slot",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@psiclawops/hypermem",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "Agent-centric memory and context composition engine for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -136,6 +136,32 @@ export declare function resolveEffectiveBudget(args: {
136
136
  budget: number;
137
137
  source: string;
138
138
  };
139
+ export interface ModelIdentity {
140
+ rawModel: string | null;
141
+ modelKey: string | null;
142
+ provider: string | null;
143
+ modelId: string | null;
144
+ }
145
+ export declare function resolveModelIdentity(model?: string): ModelIdentity;
146
+ export declare function diffModelState(previous: {
147
+ model?: string;
148
+ modelKey?: string | null;
149
+ provider?: string | null;
150
+ modelId?: string | null;
151
+ tokenBudget?: number;
152
+ } | null | undefined, current: {
153
+ model?: string;
154
+ tokenBudget?: number;
155
+ }): {
156
+ previousIdentity: ModelIdentity;
157
+ currentIdentity: ModelIdentity;
158
+ modelChanged: boolean;
159
+ providerChanged: boolean;
160
+ modelIdChanged: boolean;
161
+ budgetChanged: boolean;
162
+ budgetDownshift: boolean;
163
+ budgetUplift: boolean;
164
+ };
139
165
  /**
140
166
  * Bust the assembly cache for a specific agent+session.
141
167
  * Call this after writing to identity files (SOUL.md, IDENTITY.md, TOOLS.md,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAaH,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,aAAa,EAId,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAUL,kBAAkB,EAInB,MAAM,sBAAsB,CAAC;AAU9B,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;AAYlG,KAAK,iBAAiB,GAClB,iBAAiB,GACjB,mBAAmB,GACnB,mBAAmB,GACnB,SAAS,GACT,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,qBAAqB,GACrB,WAAW,CAAC;AAEhB,KAAK,wBAAwB,GAAG,SAAS,GAAG,UAAU,CAAC;AAEvD,UAAU,0BAA0B;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,wBAAwB,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,+BAA+B,CAAC,EAAE,MAAM,CAAC;IACzC,WAAW,CAAC,EAAE,UAAU,GAAG,aAAa,GAAG,QAAQ,CAAC;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA0BD,iBAAS,aAAa,CAAC,MAAM,EAAE;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAcP;AAED,iBAAS,aAAa,CAAC,MAAM,EAAE;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,CAcP;AAED,iBAAS,oBAAoB,CAAC,MAAM,EAAE,0BAA0B,GAAG,IAAI,CActE;AAED,iBAAS,UAAU,IAAI,MAAM,CAG5B;AA+CD,QAAA,MAAM,uBAAuB,+LAOnB,CAAC;AACX,KAAK,oBAAoB,GAAG,OAAO,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAqBnE,iBAAS,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAEpE;AAED,iBAAS,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAElE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,iBAAS,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAwB5F;AAED;;;;;;;;;;GAUG;AACH,iBAAS,cAAc,CAAC,MAAM,EAAE;IAC9B,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,oBAAoB,CAAC;CAC9B,GAAG,IAAI,CAcP;AAkBD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;aAerB,IAAI;CASd,CAAC;AAqEF,eAAO,MAAM,iCAAiC,QAAuB,CAAC;AACtE,MAAM,MAAM,qBAAqB,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAwBvF,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,OAAO,GAAG;IAC5D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAC7C,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CA4BA;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;CAChE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAoBrC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,CAkBlE;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,IAAI,GAAG,SAAS,EACpB,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA;IACD,gBAAgB,EAAE,aAAa,CAAC;IAChC,eAAe,EAAE,aAAa,CAAC;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;CACvB,CAyBA;AAg2FD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU1F;;;;;;;;AAsFD,wBA8FG"}
@@ -400,6 +400,48 @@ export function resolveEffectiveBudget(args) {
400
400
  source: 'fallback contextWindowSize',
401
401
  };
402
402
  }
403
+ export function resolveModelIdentity(model) {
404
+ const modelKey = normalizeModelKey(model);
405
+ if (!modelKey) {
406
+ return {
407
+ rawModel: model ?? null,
408
+ modelKey: null,
409
+ provider: null,
410
+ modelId: null,
411
+ };
412
+ }
413
+ const slash = modelKey.indexOf('/');
414
+ return {
415
+ rawModel: model ?? null,
416
+ modelKey,
417
+ provider: slash > 0 ? modelKey.slice(0, slash) : null,
418
+ modelId: slash > 0 && slash < modelKey.length - 1 ? modelKey.slice(slash + 1) : modelKey,
419
+ };
420
+ }
421
+ export function diffModelState(previous, current) {
422
+ const previousIdentity = previous?.modelKey || previous?.provider || previous?.modelId
423
+ ? {
424
+ rawModel: previous.model ?? null,
425
+ modelKey: previous.modelKey ?? normalizeModelKey(previous.model),
426
+ provider: previous.provider ?? resolveModelIdentity(previous.model).provider,
427
+ modelId: previous.modelId ?? resolveModelIdentity(previous.model).modelId,
428
+ }
429
+ : resolveModelIdentity(previous?.model);
430
+ const currentIdentity = resolveModelIdentity(current.model);
431
+ const previousBudget = previous?.tokenBudget;
432
+ const currentBudget = current.tokenBudget;
433
+ const budgetChanged = previousBudget != null && currentBudget != null && previousBudget !== currentBudget;
434
+ return {
435
+ previousIdentity,
436
+ currentIdentity,
437
+ modelChanged: previousIdentity.modelKey !== currentIdentity.modelKey,
438
+ providerChanged: previousIdentity.provider !== currentIdentity.provider,
439
+ modelIdChanged: previousIdentity.modelId !== currentIdentity.modelId,
440
+ budgetChanged,
441
+ budgetDownshift: previousBudget != null && currentBudget != null && currentBudget < previousBudget,
442
+ budgetUplift: previousBudget != null && currentBudget != null && currentBudget > previousBudget,
443
+ };
444
+ }
403
445
  function normalizeModelKey(model) {
404
446
  if (!model)
405
447
  return null;
@@ -1316,10 +1358,10 @@ function createHyperMemEngine() {
1316
1358
  // Non-fatal: missing files are silently skipped.
1317
1359
  let identityBlock;
1318
1360
  try {
1319
- // Council agents live at workspace-council/<agentId>/
1361
+ // Council agents live at workspace/<agentId>/
1320
1362
  // Other agents at workspace/<agentId>/ — try council path first
1321
1363
  const homedir = os.homedir();
1322
- const councilPath = path.join(homedir, '.openclaw', 'workspace-council', agentId);
1364
+ const councilPath = path.join(homedir, '.openclaw', 'workspace', agentId);
1323
1365
  const workspacePath = path.join(homedir, '.openclaw', 'workspace', agentId);
1324
1366
  let wsPath = councilPath;
1325
1367
  try {
@@ -1351,7 +1393,7 @@ function createHyperMemEngine() {
1351
1393
  let _wsPathForSeed;
1352
1394
  try {
1353
1395
  const homedir2 = os.homedir();
1354
- const councilPath2 = path.join(homedir2, '.openclaw', 'workspace-council', agentId);
1396
+ const councilPath2 = path.join(homedir2, '.openclaw', 'workspace', agentId);
1355
1397
  const workspacePath2 = path.join(homedir2, '.openclaw', 'workspace', agentId);
1356
1398
  try {
1357
1399
  await fs.access(councilPath2);
@@ -1386,7 +1428,7 @@ function createHyperMemEngine() {
1386
1428
  // Post-warm pressure check: if messages.db had accumulated history,
1387
1429
  // warm() may have loaded the session straight to 80%+. Pre-trim now
1388
1430
  // so the first turn has headroom instead of starting saturated.
1389
- // This is the "restart at 98%" failure mode reported by Helm 2026-04-05:
1431
+ // This is the "restart at 98%" failure mode reported by Eve 2026-04-05:
1390
1432
  // JSONL truncation + Redis flush isn't enough if messages.db is still full
1391
1433
  // and warm() reloads it. Trim here closes the loop.
1392
1434
  try {
@@ -2088,23 +2130,32 @@ function createHyperMemEngine() {
2088
2130
  console.warn('[hypermem-plugin] assemble: Redis trim failed (non-fatal):', trimErr.message);
2089
2131
  }
2090
2132
  // ── Budget downshift: proactive reshape pass ───────────────────────────────────────
2091
- // If this session previously composed at a higher token budget (e.g. gpt-5.4
2092
- // claude-sonnet model switch), the Redis window is still sized for the old
2093
- // budget. trimHistoryToTokenBudget above trims by count but skips tool
2094
- // gradient logic. A downshift >10% triggers a full reshape: apply tool
2095
- // gradient at the new budget + trim, then write back before compose runs.
2096
- // This prevents several turns of compaction churn after a model switch.
2097
- //
2098
- // Bug fix: previously read from getWindow() which is always null here
2099
- // (afterTurn invalidates it every turn). Also fixed: was doing setWindow()
2100
- // then invalidateWindow() which is a write-then-delete no-op. Now reads
2101
- // from history list and writes back via replaceHistory().
2133
+ // Detect provider/model identity changes as well as raw budget changes.
2134
+ // Provider routing matters operationally because the same model family can
2135
+ // land on a different effective context window, for example Copilot Sonnet
2136
+ // vs direct Anthropic Sonnet. Only budget downshifts trigger the demoted
2137
+ // reshape guard, but verbose logs now show provider/model swaps even when
2138
+ // the effective budget stays flat or increases.
2102
2139
  let lastState = null;
2103
2140
  try {
2104
2141
  lastState = await hm.cache.getModelState(agentId, sk);
2105
2142
  const DOWNSHIFT_THRESHOLD = 0.10;
2106
- const isDownshift = lastState &&
2107
- (lastState.tokenBudget - effectiveBudget) / lastState.tokenBudget > DOWNSHIFT_THRESHOLD;
2143
+ const modelDelta = diffModelState(lastState, {
2144
+ model,
2145
+ tokenBudget: effectiveBudget,
2146
+ });
2147
+ const downshiftFraction = lastState?.tokenBudget
2148
+ ? (lastState.tokenBudget - effectiveBudget) / lastState.tokenBudget
2149
+ : 0;
2150
+ const isDownshift = modelDelta.budgetDownshift && downshiftFraction > DOWNSHIFT_THRESHOLD;
2151
+ if (lastState && (modelDelta.modelChanged || modelDelta.budgetChanged)) {
2152
+ verboseLog(`[hypermem-plugin] model state change: ` +
2153
+ `prev=${modelDelta.previousIdentity.modelKey ?? 'unknown'} ` +
2154
+ `next=${modelDelta.currentIdentity.modelKey ?? 'unknown'} ` +
2155
+ `providerChanged=${modelDelta.providerChanged} ` +
2156
+ `modelIdChanged=${modelDelta.modelIdChanged} ` +
2157
+ `budget=${lastState.tokenBudget}->${effectiveBudget}`);
2158
+ }
2108
2159
  if (isDownshift && !_deferToolPruning) {
2109
2160
  // Sprint 2.2a: demote reshape to guard telemetry.
2110
2161
  //
@@ -2269,8 +2320,12 @@ ${replayRecovery.emittedText}`
2269
2320
  await persistReplayRecoveryState(hm, agentId, sk, replayRecovery.nextState);
2270
2321
  // Update model state for downshift detection on next turn
2271
2322
  try {
2323
+ const modelIdentity = resolveModelIdentity(model);
2272
2324
  await hm.cache.setModelState(agentId, sk, {
2273
2325
  model: model ?? 'unknown',
2326
+ modelKey: modelIdentity.modelKey ?? undefined,
2327
+ provider: modelIdentity.provider ?? undefined,
2328
+ modelId: modelIdentity.modelId ?? undefined,
2274
2329
  tokenBudget: effectiveBudget,
2275
2330
  composedAt: new Date().toISOString(),
2276
2331
  historyDepth,
@@ -2610,7 +2665,7 @@ ${replayRecovery.emittedText}`
2610
2665
  // gradient-compressed window to budget before writing to Redis. Without
2611
2666
  // this, afterTurn writes up to 250 messages regardless of budget, causing
2612
2667
  // trimHistoryToTokenBudget to fire and trim ~200 messages on every
2613
- // subsequent assemble() — the churn loop seen in Helm's logs.
2668
+ // subsequent assemble() — the churn loop seen in Eve's logs.
2614
2669
  if (hm.cache.isConnected) {
2615
2670
  try {
2616
2671
  const modelState = await hm.cache.getModelState(agentId, sk);
@@ -2634,7 +2689,7 @@ ${replayRecovery.emittedText}`
2634
2689
  // If a session just finished a turn at >80% pressure, the NEXT turn's
2635
2690
  // incoming tool results (parallel web searches, large exec output, etc.)
2636
2691
  // will hit a window with no headroom — the ingestion wave failure mode
2637
- // (reported by Helm, 2026-04-05). Pre-trim here so the tool-loop
2692
+ // (reported by Eve, 2026-04-05). Pre-trim here so the tool-loop
2638
2693
  // assemble() path starts the next turn with meaningful space.
2639
2694
  //
2640
2695
  // Uses modelState.tokenBudget if cached; skips if unavailable (non-fatal).