@psiclawops/hypermem 0.8.4 → 0.9.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.
- package/CHANGELOG.md +33 -0
- package/INSTALL.md +203 -23
- package/README.md +139 -216
- package/bench/README.md +42 -0
- package/bench/data-access-bench.mjs +380 -0
- package/bin/hypermem-bench.mjs +2 -0
- package/bin/hypermem-doctor.mjs +412 -0
- package/bin/hypermem-model-audit.mjs +339 -0
- package/bin/hypermem-status.mjs +491 -70
- package/dist/adaptive-lifecycle.d.ts +81 -0
- package/dist/adaptive-lifecycle.d.ts.map +1 -0
- package/dist/adaptive-lifecycle.js +190 -0
- package/dist/background-indexer.js +9 -9
- package/dist/budget-policy.d.ts +1 -1
- package/dist/budget-policy.d.ts.map +1 -1
- package/dist/budget-policy.js +10 -5
- package/dist/cache.d.ts +4 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +2 -0
- package/dist/composition-snapshot-integrity.d.ts +36 -0
- package/dist/composition-snapshot-integrity.d.ts.map +1 -0
- package/dist/composition-snapshot-integrity.js +131 -0
- package/dist/composition-snapshot-runtime.d.ts +59 -0
- package/dist/composition-snapshot-runtime.d.ts.map +1 -0
- package/dist/composition-snapshot-runtime.js +250 -0
- package/dist/composition-snapshot-store.d.ts +44 -0
- package/dist/composition-snapshot-store.d.ts.map +1 -0
- package/dist/composition-snapshot-store.js +117 -0
- package/dist/compositor.d.ts +125 -1
- package/dist/compositor.d.ts.map +1 -1
- package/dist/compositor.js +692 -44
- package/dist/cross-agent.d.ts +1 -1
- package/dist/cross-agent.js +17 -17
- package/dist/doc-chunk-store.d.ts +19 -0
- package/dist/doc-chunk-store.d.ts.map +1 -1
- package/dist/doc-chunk-store.js +56 -6
- package/dist/dreaming-promoter.d.ts +1 -1
- package/dist/dreaming-promoter.js +2 -2
- package/dist/hybrid-retrieval.d.ts +38 -0
- package/dist/hybrid-retrieval.d.ts.map +1 -1
- package/dist/hybrid-retrieval.js +86 -1
- package/dist/index.d.ts +15 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -7
- package/dist/knowledge-store.d.ts +4 -1
- package/dist/knowledge-store.d.ts.map +1 -1
- package/dist/knowledge-store.js +27 -4
- package/dist/library-schema.d.ts +12 -8
- package/dist/library-schema.d.ts.map +1 -1
- package/dist/library-schema.js +22 -8
- package/dist/message-store.d.ts.map +1 -1
- package/dist/message-store.js +7 -3
- package/dist/metrics-dashboard.d.ts +18 -1
- package/dist/metrics-dashboard.d.ts.map +1 -1
- package/dist/metrics-dashboard.js +52 -14
- package/dist/reranker.d.ts +1 -1
- package/dist/reranker.js +2 -2
- package/dist/schema.d.ts +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +28 -1
- package/dist/seed.d.ts +1 -1
- package/dist/seed.d.ts.map +1 -1
- package/dist/seed.js +3 -1
- package/dist/session-flusher.d.ts +2 -2
- package/dist/session-flusher.js +2 -2
- package/dist/spawn-context.d.ts +1 -1
- package/dist/spawn-context.js +1 -1
- package/dist/topic-store.js +5 -5
- package/dist/topic-synthesizer.d.ts +20 -0
- package/dist/topic-synthesizer.d.ts.map +1 -1
- package/dist/topic-synthesizer.js +114 -4
- package/dist/trigger-registry.d.ts +1 -1
- package/dist/trigger-registry.d.ts.map +1 -1
- package/dist/trigger-registry.js +14 -6
- package/dist/types.d.ts +273 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +7 -7
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +17 -7
- package/docs/DIAGNOSTICS.md +205 -0
- package/docs/INTEGRATION_VALIDATION.md +186 -0
- package/docs/MIGRATION.md +9 -6
- package/docs/MIGRATION_GUIDE.md +125 -101
- package/docs/ROADMAP.md +238 -20
- package/docs/TUNING.md +30 -6
- package/install.sh +159 -408
- package/memory-plugin/LICENSE +190 -0
- package/memory-plugin/README.md +20 -0
- package/memory-plugin/dist/index.js +50 -0
- package/memory-plugin/package.json +2 -2
- package/package.json +18 -4
- package/plugin/LICENSE +190 -0
- package/plugin/README.md +20 -0
- package/plugin/dist/index.d.ts +55 -0
- package/plugin/dist/index.d.ts.map +1 -1
- package/plugin/dist/index.js +362 -42
- package/plugin/dist/index.js.map +1 -1
- package/plugin/package.json +2 -2
- package/scripts/install-runtime.mjs +13 -3
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HyperMem 0.9.0 adaptive context lifecycle policy kernel.
|
|
3
|
+
*
|
|
4
|
+
* This module intentionally stays pure: it does not fetch history, mutate
|
|
5
|
+
* stores, or own trimming. Runtime paths can call it to choose warming,
|
|
6
|
+
* recall, trim, compaction, and eviction posture from the same pressure band
|
|
7
|
+
* so 0.9.0 does not grow another independent trim brain.
|
|
8
|
+
*/
|
|
9
|
+
export type AdaptiveLifecycleBand = 'bootstrap' | 'warmup' | 'steady' | 'elevated' | 'high' | 'critical';
|
|
10
|
+
export interface AdaptiveLifecycleInput {
|
|
11
|
+
/** Tokens already resident or projected in the active context. */
|
|
12
|
+
usedTokens?: number;
|
|
13
|
+
/** Effective context budget after model-aware reserve handling. */
|
|
14
|
+
effectiveBudget?: number;
|
|
15
|
+
/** Optional precomputed pressure fraction. Overrides usedTokens/effectiveBudget. */
|
|
16
|
+
pressureFraction?: number;
|
|
17
|
+
/** Number of user turns observed in the session. */
|
|
18
|
+
userTurnCount?: number;
|
|
19
|
+
/** True when the incoming user turn explicitly starts with /new. */
|
|
20
|
+
explicitNewSession?: boolean;
|
|
21
|
+
/** Topic-shift confidence from the detector, 0..1. */
|
|
22
|
+
topicShiftConfidence?: number;
|
|
23
|
+
/** True when this context was forked from a parent OpenClaw session. */
|
|
24
|
+
forkedContext?: boolean;
|
|
25
|
+
/** Parent-session pressure observed when the fork was prepared, 0..1+. */
|
|
26
|
+
forkedParentPressureFraction?: number;
|
|
27
|
+
/** Parent-session user turns observed when the fork was prepared. */
|
|
28
|
+
forkedParentUserTurnCount?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Eviction-pipeline step labels. The order in `AdaptiveEvictionPlan.steps`
|
|
32
|
+
* is the order the compose-window cluster-drop path should attempt them.
|
|
33
|
+
*
|
|
34
|
+
* `tool-gradient`, `oversized-artifacts`, and `stale-tool-stubs` are
|
|
35
|
+
* ballast-reduction steps already implemented in the compositor; the plan
|
|
36
|
+
* just records that they precede cluster drop. `topic-aware-cluster-drop`
|
|
37
|
+
* and `oldest-cluster-drop` describe how the compositor's existing
|
|
38
|
+
* cluster-drop pass should be ordered: topic-aware-first when the band
|
|
39
|
+
* elevates, otherwise the historical newest-first/oldest-drop sweep.
|
|
40
|
+
*/
|
|
41
|
+
export type AdaptiveEvictionStep = 'tool-gradient' | 'oversized-artifacts' | 'stale-tool-stubs' | 'topic-aware-cluster-drop' | 'oldest-cluster-drop';
|
|
42
|
+
export interface AdaptiveEvictionPlan {
|
|
43
|
+
band: AdaptiveLifecycleBand;
|
|
44
|
+
steps: readonly AdaptiveEvictionStep[];
|
|
45
|
+
/** Drop inactive-topic clusters before falling back to oldest-first. */
|
|
46
|
+
preferTopicAwareDrop: boolean;
|
|
47
|
+
/** Ballast-reduction steps run before any cluster drop. Always true today. */
|
|
48
|
+
preferBallastFirst: boolean;
|
|
49
|
+
}
|
|
50
|
+
export interface AdaptiveLifecyclePolicy {
|
|
51
|
+
band: AdaptiveLifecycleBand;
|
|
52
|
+
pressureFraction: number;
|
|
53
|
+
pressurePct: number;
|
|
54
|
+
warmHistoryBudgetFraction: number;
|
|
55
|
+
smartRecallMultiplier: number;
|
|
56
|
+
trimSoftTarget: number;
|
|
57
|
+
compactionTargetFraction: number;
|
|
58
|
+
emitBreadcrumbPackage: boolean;
|
|
59
|
+
enableTopicCentroidEviction: boolean;
|
|
60
|
+
triggerProactiveCompaction: boolean;
|
|
61
|
+
evictionPlan: AdaptiveEvictionPlan;
|
|
62
|
+
reasons: string[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Pure helper: derive the eviction plan from band only. No new pressure
|
|
66
|
+
* constants — every band-sensitive decision routes through the existing
|
|
67
|
+
* AdaptiveLifecycleBand classification.
|
|
68
|
+
*
|
|
69
|
+
* - bootstrap/warmup/steady: preserve the historical eviction order.
|
|
70
|
+
* - elevated: prefer topic-aware stale cluster drop before generic
|
|
71
|
+
* oldest-first cluster drop.
|
|
72
|
+
* - high/critical: same plan shape as elevated. Ballast-first is already
|
|
73
|
+
* the default order in the compositor; topic-aware drop kicks in to
|
|
74
|
+
* avoid evicting active-topic recent clusters under saturation.
|
|
75
|
+
*/
|
|
76
|
+
export declare function resolveAdaptiveEvictionPlan(band: AdaptiveLifecycleBand): AdaptiveEvictionPlan;
|
|
77
|
+
/**
|
|
78
|
+
* Resolve the adaptive lifecycle posture for one compose/afterTurn cycle.
|
|
79
|
+
*/
|
|
80
|
+
export declare function resolveAdaptiveLifecyclePolicy(input?: AdaptiveLifecycleInput): AdaptiveLifecyclePolicy;
|
|
81
|
+
//# sourceMappingURL=adaptive-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adaptive-lifecycle.d.ts","sourceRoot":"","sources":["../src/adaptive-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,qBAAqB,GAC7B,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,MAAM,GACN,UAAU,CAAC;AAEf,MAAM,WAAW,sBAAsB;IACrC,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,sDAAsD;IACtD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wEAAwE;IACxE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,0EAA0E;IAC1E,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,qEAAqE;IACrE,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,oBAAoB,GAC5B,eAAe,GACf,qBAAqB,GACrB,kBAAkB,GAClB,0BAA0B,GAC1B,qBAAqB,CAAC;AAE1B,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,KAAK,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACvC,wEAAwE;IACxE,oBAAoB,EAAE,OAAO,CAAC;IAC9B,8EAA8E;IAC9E,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB,EAAE,MAAM,CAAC;IAClC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB,EAAE,MAAM,CAAC;IACjC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,2BAA2B,EAAE,OAAO,CAAC;IACrC,0BAA0B,EAAE,OAAO,CAAC;IACpC,YAAY,EAAE,oBAAoB,CAAC;IACnC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAiBD;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,qBAAqB,GAAG,oBAAoB,CAsB7F;AAyGD;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,GAAE,sBAA2B,GACjC,uBAAuB,CAoBzB"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HyperMem 0.9.0 adaptive context lifecycle policy kernel.
|
|
3
|
+
*
|
|
4
|
+
* This module intentionally stays pure: it does not fetch history, mutate
|
|
5
|
+
* stores, or own trimming. Runtime paths can call it to choose warming,
|
|
6
|
+
* recall, trim, compaction, and eviction posture from the same pressure band
|
|
7
|
+
* so 0.9.0 does not grow another independent trim brain.
|
|
8
|
+
*/
|
|
9
|
+
const BASELINE_EVICTION_STEPS = Object.freeze([
|
|
10
|
+
'tool-gradient',
|
|
11
|
+
'oversized-artifacts',
|
|
12
|
+
'stale-tool-stubs',
|
|
13
|
+
'oldest-cluster-drop',
|
|
14
|
+
]);
|
|
15
|
+
const TOPIC_AWARE_EVICTION_STEPS = Object.freeze([
|
|
16
|
+
'tool-gradient',
|
|
17
|
+
'oversized-artifacts',
|
|
18
|
+
'stale-tool-stubs',
|
|
19
|
+
'topic-aware-cluster-drop',
|
|
20
|
+
'oldest-cluster-drop',
|
|
21
|
+
]);
|
|
22
|
+
/**
|
|
23
|
+
* Pure helper: derive the eviction plan from band only. No new pressure
|
|
24
|
+
* constants — every band-sensitive decision routes through the existing
|
|
25
|
+
* AdaptiveLifecycleBand classification.
|
|
26
|
+
*
|
|
27
|
+
* - bootstrap/warmup/steady: preserve the historical eviction order.
|
|
28
|
+
* - elevated: prefer topic-aware stale cluster drop before generic
|
|
29
|
+
* oldest-first cluster drop.
|
|
30
|
+
* - high/critical: same plan shape as elevated. Ballast-first is already
|
|
31
|
+
* the default order in the compositor; topic-aware drop kicks in to
|
|
32
|
+
* avoid evicting active-topic recent clusters under saturation.
|
|
33
|
+
*/
|
|
34
|
+
export function resolveAdaptiveEvictionPlan(band) {
|
|
35
|
+
switch (band) {
|
|
36
|
+
case 'bootstrap':
|
|
37
|
+
case 'warmup':
|
|
38
|
+
case 'steady':
|
|
39
|
+
return Object.freeze({
|
|
40
|
+
band,
|
|
41
|
+
steps: BASELINE_EVICTION_STEPS,
|
|
42
|
+
preferTopicAwareDrop: false,
|
|
43
|
+
preferBallastFirst: true,
|
|
44
|
+
});
|
|
45
|
+
case 'elevated':
|
|
46
|
+
case 'high':
|
|
47
|
+
case 'critical':
|
|
48
|
+
default:
|
|
49
|
+
return Object.freeze({
|
|
50
|
+
band,
|
|
51
|
+
steps: TOPIC_AWARE_EVICTION_STEPS,
|
|
52
|
+
preferTopicAwareDrop: true,
|
|
53
|
+
preferBallastFirst: true,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const PRESSURE_BANDS = Object.freeze({
|
|
58
|
+
steadyMax: 0.65,
|
|
59
|
+
elevatedMax: 0.75,
|
|
60
|
+
highMax: 0.85,
|
|
61
|
+
});
|
|
62
|
+
const WARMING_BY_BAND = Object.freeze({
|
|
63
|
+
bootstrap: 0.55,
|
|
64
|
+
warmup: 0.48,
|
|
65
|
+
steady: 0.40,
|
|
66
|
+
elevated: 0.34,
|
|
67
|
+
high: 0.28,
|
|
68
|
+
critical: 0.20,
|
|
69
|
+
});
|
|
70
|
+
const TRIM_TARGET_BY_BAND = Object.freeze({
|
|
71
|
+
bootstrap: 0.72,
|
|
72
|
+
warmup: 0.68,
|
|
73
|
+
steady: 0.65,
|
|
74
|
+
elevated: 0.60,
|
|
75
|
+
high: 0.54,
|
|
76
|
+
critical: 0.48,
|
|
77
|
+
});
|
|
78
|
+
const COMPACTION_TARGET_BY_BAND = Object.freeze({
|
|
79
|
+
bootstrap: 0.70,
|
|
80
|
+
warmup: 0.66,
|
|
81
|
+
steady: 0.62,
|
|
82
|
+
elevated: 0.56,
|
|
83
|
+
high: 0.50,
|
|
84
|
+
critical: 0.42,
|
|
85
|
+
});
|
|
86
|
+
function clampPressure(value) {
|
|
87
|
+
if (!Number.isFinite(value) || value < 0)
|
|
88
|
+
return 0;
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
function pressureFromInput(input) {
|
|
92
|
+
if (input.pressureFraction != null) {
|
|
93
|
+
return clampPressure(input.pressureFraction);
|
|
94
|
+
}
|
|
95
|
+
const used = Math.max(0, Math.floor(input.usedTokens ?? 0));
|
|
96
|
+
const budget = Math.max(0, Math.floor(input.effectiveBudget ?? 0));
|
|
97
|
+
if (budget <= 0)
|
|
98
|
+
return 0;
|
|
99
|
+
return clampPressure(used / budget);
|
|
100
|
+
}
|
|
101
|
+
function isTopicShift(input) {
|
|
102
|
+
return (input.topicShiftConfidence ?? 0) >= 0.75;
|
|
103
|
+
}
|
|
104
|
+
function classifyBand(input, pressure) {
|
|
105
|
+
const userTurns = Math.max(0, Math.floor(input.userTurnCount ?? 0));
|
|
106
|
+
if (input.explicitNewSession)
|
|
107
|
+
return 'bootstrap';
|
|
108
|
+
if (input.forkedContext) {
|
|
109
|
+
const parentPressure = clampPressure(input.forkedParentPressureFraction ?? pressure);
|
|
110
|
+
const parentTurns = Math.max(0, Math.floor(input.forkedParentUserTurnCount ?? 0));
|
|
111
|
+
// A forked child is not cold: it starts with inherited working context.
|
|
112
|
+
// Keep initial posture conservative and bounded to warmup/steady so a
|
|
113
|
+
// saturated parent does not immediately trigger child compaction before the
|
|
114
|
+
// child has produced its own post-fork turns. Callers should only pass this
|
|
115
|
+
// seed for the initial forked assemble.
|
|
116
|
+
if (parentTurns >= 5 || parentPressure >= 0.35)
|
|
117
|
+
return 'steady';
|
|
118
|
+
return 'warmup';
|
|
119
|
+
}
|
|
120
|
+
if (userTurns === 0)
|
|
121
|
+
return 'bootstrap';
|
|
122
|
+
if (userTurns <= 4 && pressure < PRESSURE_BANDS.elevatedMax)
|
|
123
|
+
return 'warmup';
|
|
124
|
+
if (pressure < PRESSURE_BANDS.steadyMax)
|
|
125
|
+
return 'steady';
|
|
126
|
+
if (pressure < PRESSURE_BANDS.elevatedMax)
|
|
127
|
+
return 'elevated';
|
|
128
|
+
if (pressure < PRESSURE_BANDS.highMax)
|
|
129
|
+
return 'high';
|
|
130
|
+
return 'critical';
|
|
131
|
+
}
|
|
132
|
+
function smartRecallMultiplier(input, band) {
|
|
133
|
+
if (input.explicitNewSession || isTopicShift(input))
|
|
134
|
+
return 1.5;
|
|
135
|
+
if (band === 'bootstrap' || band === 'warmup')
|
|
136
|
+
return 1.25;
|
|
137
|
+
if (band === 'high')
|
|
138
|
+
return 0.85;
|
|
139
|
+
if (band === 'critical')
|
|
140
|
+
return 0.65;
|
|
141
|
+
return 1.0;
|
|
142
|
+
}
|
|
143
|
+
function reasonsFor(input, band, pressure) {
|
|
144
|
+
const reasons = [`band:${band}`, `pressure:${Math.round(pressure * 100)}%`];
|
|
145
|
+
const turns = Math.max(0, Math.floor(input.userTurnCount ?? 0));
|
|
146
|
+
if (input.explicitNewSession)
|
|
147
|
+
reasons.push('explicit-new-session');
|
|
148
|
+
if (input.forkedContext) {
|
|
149
|
+
reasons.push('forked-context');
|
|
150
|
+
if (input.forkedParentPressureFraction != null) {
|
|
151
|
+
reasons.push(`forked-parent-pressure:${Math.round(clampPressure(input.forkedParentPressureFraction) * 100)}%`);
|
|
152
|
+
}
|
|
153
|
+
if (input.forkedParentUserTurnCount != null) {
|
|
154
|
+
reasons.push(`forked-parent-turns:${Math.max(0, Math.floor(input.forkedParentUserTurnCount))}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (turns === 0)
|
|
158
|
+
reasons.push('cold-start');
|
|
159
|
+
if (turns > 0 && turns <= 4)
|
|
160
|
+
reasons.push(`early-session:${turns}`);
|
|
161
|
+
if (isTopicShift(input))
|
|
162
|
+
reasons.push(`topic-shift:${(input.topicShiftConfidence ?? 0).toFixed(2)}`);
|
|
163
|
+
if (band === 'high' || band === 'critical')
|
|
164
|
+
reasons.push('pressure-gated-recall');
|
|
165
|
+
return reasons;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Resolve the adaptive lifecycle posture for one compose/afterTurn cycle.
|
|
169
|
+
*/
|
|
170
|
+
export function resolveAdaptiveLifecyclePolicy(input = {}) {
|
|
171
|
+
const pressureFraction = pressureFromInput(input);
|
|
172
|
+
const band = classifyBand(input, pressureFraction);
|
|
173
|
+
const pressurePct = Math.round(pressureFraction * 100);
|
|
174
|
+
const triggerProactiveCompaction = band === 'high' || band === 'critical';
|
|
175
|
+
return Object.freeze({
|
|
176
|
+
band,
|
|
177
|
+
pressureFraction,
|
|
178
|
+
pressurePct,
|
|
179
|
+
warmHistoryBudgetFraction: WARMING_BY_BAND[band],
|
|
180
|
+
smartRecallMultiplier: smartRecallMultiplier(input, band),
|
|
181
|
+
trimSoftTarget: TRIM_TARGET_BY_BAND[band],
|
|
182
|
+
compactionTargetFraction: COMPACTION_TARGET_BY_BAND[band],
|
|
183
|
+
emitBreadcrumbPackage: Boolean(input.explicitNewSession || band === 'bootstrap'),
|
|
184
|
+
enableTopicCentroidEviction: band === 'elevated' || triggerProactiveCompaction,
|
|
185
|
+
triggerProactiveCompaction,
|
|
186
|
+
evictionPlan: resolveAdaptiveEvictionPlan(band),
|
|
187
|
+
reasons: reasonsFor(input, band, pressureFraction),
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=adaptive-lifecycle.js.map
|
|
@@ -37,27 +37,27 @@ import { isSafeForSharedVisibility } from './secret-scanner.js';
|
|
|
37
37
|
// returns results. New agents default to 'general'.
|
|
38
38
|
//
|
|
39
39
|
// ── EXAMPLE DATA ──────────────────────────────────────────────────
|
|
40
|
-
// The agent names below (
|
|
40
|
+
// The agent names below (alice, director1, etc.) are PLACEHOLDERS.
|
|
41
41
|
// Replace them with your own agent IDs and domain labels to match
|
|
42
42
|
// your fleet. Single-agent installs don't need to edit this:
|
|
43
43
|
// unknown agents fall through to 'general' automatically.
|
|
44
44
|
// See INSTALL.md § "Configure your fleet" for details.
|
|
45
45
|
// ─────────────────────────────────────────────────────────────────
|
|
46
46
|
const AGENT_DOMAIN_MAP = {
|
|
47
|
-
|
|
47
|
+
alice: 'infrastructure',
|
|
48
48
|
director2: 'infrastructure',
|
|
49
49
|
director1: 'infrastructure',
|
|
50
50
|
director3: 'infrastructure',
|
|
51
|
-
|
|
51
|
+
bob: 'product',
|
|
52
52
|
director4: 'product',
|
|
53
53
|
director5: 'product',
|
|
54
54
|
director6: 'product',
|
|
55
|
-
|
|
55
|
+
dave: 'security',
|
|
56
56
|
director7: 'security',
|
|
57
57
|
director8: 'security',
|
|
58
58
|
agent4: 'ux',
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
carol: 'governance',
|
|
60
|
+
oscar: 'strategy',
|
|
61
61
|
specialist1: 'development',
|
|
62
62
|
specialist2: 'communications',
|
|
63
63
|
main: 'general',
|
|
@@ -94,7 +94,7 @@ function extractFactCandidates(content) {
|
|
|
94
94
|
// Preference patterns — medium confidence (0.60)
|
|
95
95
|
const preferencePatterns = [
|
|
96
96
|
/(?:prefer|always use|never use|don't use|avoid) (.{10,150})/gi,
|
|
97
|
-
/(?:operator
|
|
97
|
+
/(?:operator) (?:wants|prefers|likes|hates|dislikes) (.{10,150})/gi,
|
|
98
98
|
];
|
|
99
99
|
// Operational patterns: deployments, incidents, fixes — high confidence (0.70)
|
|
100
100
|
const operationalPatterns = [
|
|
@@ -148,7 +148,7 @@ const OPERATIONAL_BOILERPLATE = [
|
|
|
148
148
|
/still\s*waiting/i,
|
|
149
149
|
/will\s*pick\s*(it\s*)?up\s*(on\s*(next|the))?/i,
|
|
150
150
|
/message\s*is\s*in\s*(his|her|their|the)\s*queue/i,
|
|
151
|
-
/sent\s+to\s+(
|
|
151
|
+
/sent\s+to\s+(carol|bob|agent4|dave|oscar|alice)/i,
|
|
152
152
|
/dispatched\s+(it\s+)?to/i,
|
|
153
153
|
/timed\s*out\s*after/i,
|
|
154
154
|
/\bNO_REPLY\b/,
|
|
@@ -393,7 +393,7 @@ function detectTopic(content) {
|
|
|
393
393
|
if (!content || content.length < 50)
|
|
394
394
|
return null;
|
|
395
395
|
// Product/project name detection
|
|
396
|
-
const productMatch = content.match(/\b(HyperMem|ClawText|
|
|
396
|
+
const productMatch = content.match(/\b(HyperMem|ClawText|dashboard|canvas|council|automation|OpenClaw|dispatch)\b/i);
|
|
397
397
|
if (productMatch)
|
|
398
398
|
return productMatch[1];
|
|
399
399
|
// Infrastructure topic detection
|
package/dist/budget-policy.d.ts
CHANGED
|
@@ -18,5 +18,5 @@ export interface ResolvedTrimBudgets extends TrimBudgetPolicy {
|
|
|
18
18
|
targetBudget: number;
|
|
19
19
|
}
|
|
20
20
|
export declare const TRIM_BUDGET_POLICY: TrimBudgetPolicy;
|
|
21
|
-
export declare function resolveTrimBudgets(effectiveBudget: number): ResolvedTrimBudgets;
|
|
21
|
+
export declare function resolveTrimBudgets(effectiveBudget: number, policy?: Partial<TrimBudgetPolicy>): ResolvedTrimBudgets;
|
|
22
22
|
//# sourceMappingURL=budget-policy.d.ts.map
|
|
@@ -1 +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,
|
|
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,CAChC,eAAe,EAAE,MAAM,EACvB,MAAM,GAAE,OAAO,CAAC,gBAAgB,CAAM,GACrC,mBAAmB,CAgBrB"}
|
package/dist/budget-policy.js
CHANGED
|
@@ -12,13 +12,18 @@ export const TRIM_BUDGET_POLICY = Object.freeze({
|
|
|
12
12
|
trimGrowthThreshold: TRIM_GROWTH_THRESHOLD,
|
|
13
13
|
trimHeadroomFraction: TRIM_HEADROOM_FRACTION,
|
|
14
14
|
});
|
|
15
|
-
export function resolveTrimBudgets(effectiveBudget) {
|
|
15
|
+
export function resolveTrimBudgets(effectiveBudget, policy = {}) {
|
|
16
16
|
const safeBudget = Math.max(0, Math.floor(effectiveBudget || 0));
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
17
|
+
const trimSoftTarget = policy.trimSoftTarget ?? TRIM_SOFT_TARGET;
|
|
18
|
+
const trimGrowthThreshold = policy.trimGrowthThreshold ?? TRIM_GROWTH_THRESHOLD;
|
|
19
|
+
const trimHeadroomFraction = policy.trimHeadroomFraction ?? TRIM_HEADROOM_FRACTION;
|
|
20
|
+
const softBudget = Math.floor(safeBudget * trimSoftTarget);
|
|
21
|
+
const triggerBudget = Math.floor(softBudget * (1 + trimGrowthThreshold));
|
|
22
|
+
const targetBudget = Math.floor(softBudget * (1 - trimHeadroomFraction));
|
|
20
23
|
return {
|
|
21
|
-
|
|
24
|
+
trimSoftTarget,
|
|
25
|
+
trimGrowthThreshold,
|
|
26
|
+
trimHeadroomFraction,
|
|
22
27
|
softBudget,
|
|
23
28
|
triggerBudget,
|
|
24
29
|
targetBudget,
|
package/dist/cache.d.ts
CHANGED
|
@@ -8,6 +8,9 @@ import { DatabaseSync } from 'node:sqlite';
|
|
|
8
8
|
import type { CacheConfig, ComposeDiagnostics, SessionMeta, SessionCursor, StoredMessage, NeutralMessage } from './types.js';
|
|
9
9
|
export interface ModelState {
|
|
10
10
|
model: string;
|
|
11
|
+
modelKey?: string;
|
|
12
|
+
provider?: string;
|
|
13
|
+
modelId?: string;
|
|
11
14
|
tokenBudget: number;
|
|
12
15
|
composedAt: string;
|
|
13
16
|
historyDepth: number;
|
|
@@ -106,6 +109,7 @@ export declare class CacheLayer {
|
|
|
106
109
|
warmSession(agentId: string, sessionKey: string, slots: {
|
|
107
110
|
system?: string;
|
|
108
111
|
identity?: string;
|
|
112
|
+
repairNotice?: string;
|
|
109
113
|
context?: string;
|
|
110
114
|
facts?: string;
|
|
111
115
|
tools?: string;
|
package/dist/cache.d.ts.map
CHANGED
|
@@ -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":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAiB,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7H,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,kBAAkB,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAYD,qBAAa,UAAU;IACrB,OAAO,CAAC,EAAE,CAA6B;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,gBAAgB,CAAiB;IACzC,OAAO,CAAC,gBAAgB,CAAiB;IACzC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,mBAAmB,CAAiB;IAC5C,OAAO,CAAC,qBAAqB,CAAiB;IAC9C,OAAO,CAAC,qBAAqB,CAAiB;IAC9C,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,gBAAgB,CAAiB;IACzC,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,mBAAmB,CAAiB;IAC5C,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,oBAAoB,CAAiB;IAC7C,OAAO,CAAC,qBAAqB,CAAiB;IAC9C,OAAO,CAAC,0BAA0B,CAAiB;IACnD,OAAO,CAAC,gBAAgB,CAAiB;IACzC,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,wBAAwB,CAAiB;IACjD,OAAO,CAAC,gBAAgB,CAAiB;IACzC,OAAO,CAAC,gBAAgB,CAAiB;IACzC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,YAAY,CAAiB;gBAEzB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC;IAInC,OAAO,CAAC,EAAE,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBlD,OAAO,CAAC,kBAAkB;IAkD1B,IAAI,WAAW,IAAI,OAAO,CAEzB;IAIK,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5E,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IASpE,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpE,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvE,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAQrD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxF,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAMlF,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrF,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAShF,WAAW,CACf,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,aAAa,EAAE,EACzB,WAAW,GAAE,MAAY,GACxB,OAAO,CAAC,IAAI,CAAC;IAuBV,cAAc,CAClB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,EAAE,EAC1B,WAAW,GAAE,MAAY,GACxB,OAAO,CAAC,IAAI,CAAC;IASV,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAWzF,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMpE,wBAAwB,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC;IAyGZ,SAAS,CACb,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,EAAE,EAC1B,UAAU,GAAE,MAAY,GACvB,OAAO,CAAC,IAAI,CAAC;IAKV,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,GAAG,IAAI,CAAC;IAMhF,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1E;;;;OAIG;IACG,oBAAoB,CACxB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC;QAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,GAAG,IAAI,CAAC;IA2BxE;;;OAGG;IACG,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC;IASV,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAW5B,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IASpF,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAW7E,WAAW,CACf,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,WAAW,CAAC;QACnB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;KAC3B,GACA,OAAO,CAAC,IAAI,CAAC;IAcV,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAahE,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhE,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAe9B,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,MAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3E,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAMlD,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzC,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9E,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAK7E,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlE,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAKhE,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOpD,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9F,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAiBpF,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9G,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAMxG,cAAc,CAClB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,cAAc,EAAE,EAC1B,GAAG,GAAE,MAAY,GAChB,OAAO,CAAC,IAAI,CAAC;IAKV,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,GAAG,IAAI,CAAC;IAMtG,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1F,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE;QACL,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;QAC1B,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;QAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GACA,OAAO,CAAC,IAAI,CAAC;IAmBV,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IASpF,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAS9E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAIlC"}
|
package/dist/cache.js
CHANGED
|
@@ -400,6 +400,8 @@ export class CacheLayer {
|
|
|
400
400
|
this.stmtSetSlot.run(agentId, sessionKey, 'system', slots.system, exp);
|
|
401
401
|
if (slots.identity)
|
|
402
402
|
this.stmtSetSlot.run(agentId, sessionKey, 'identity', slots.identity, exp);
|
|
403
|
+
if (slots.repairNotice)
|
|
404
|
+
this.stmtSetSlot.run(agentId, sessionKey, 'repair_notice', slots.repairNotice, exp);
|
|
403
405
|
if (slots.context)
|
|
404
406
|
this.stmtSetSlot.run(agentId, sessionKey, 'context', slots.context, exp);
|
|
405
407
|
if (slots.facts)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type SnapshotJsonPrimitive = string | number | boolean | null;
|
|
2
|
+
export type SnapshotJsonValue = SnapshotJsonPrimitive | SnapshotJsonValue[] | SnapshotJsonObject;
|
|
3
|
+
export interface SnapshotJsonObject {
|
|
4
|
+
[key: string]: SnapshotJsonValue;
|
|
5
|
+
}
|
|
6
|
+
export type SnapshotSlotsRecord = Record<string, SnapshotJsonValue>;
|
|
7
|
+
export type InlineSnapshotSlotPayload = SnapshotJsonObject & {
|
|
8
|
+
kind?: string | null;
|
|
9
|
+
source?: string | null;
|
|
10
|
+
inline?: boolean | null;
|
|
11
|
+
content?: SnapshotJsonValue;
|
|
12
|
+
integrity_hash?: string | null;
|
|
13
|
+
};
|
|
14
|
+
export type SnapshotIntegrityFailureReason = 'malformed_slots_json' | 'invalid_slots_root' | 'missing_inline_integrity_hash' | 'inline_hash_mismatch' | 'slots_hash_mismatch';
|
|
15
|
+
export interface SnapshotIntegrityFailure {
|
|
16
|
+
slotKey: string;
|
|
17
|
+
reason: SnapshotIntegrityFailureReason;
|
|
18
|
+
expected?: string;
|
|
19
|
+
actual?: string;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface SnapshotIntegrityVerification {
|
|
23
|
+
ok: boolean;
|
|
24
|
+
slots: SnapshotSlotsRecord | null;
|
|
25
|
+
actualSlotsHash: string | null;
|
|
26
|
+
failures: SnapshotIntegrityFailure[];
|
|
27
|
+
}
|
|
28
|
+
export declare function canonicalizeSnapshotJson(value: unknown): string;
|
|
29
|
+
export declare function hashSnapshotJson(value: unknown): string;
|
|
30
|
+
export declare function parseSnapshotSlotsJson(raw: string): SnapshotSlotsRecord;
|
|
31
|
+
export declare function isInlineSnapshotSlotPayload(value: SnapshotJsonValue): value is InlineSnapshotSlotPayload;
|
|
32
|
+
export declare function computeInlineIntegrityHash(payload: InlineSnapshotSlotPayload): string;
|
|
33
|
+
export declare function attachInlineIntegrityHash(payload: InlineSnapshotSlotPayload): InlineSnapshotSlotPayload;
|
|
34
|
+
export declare function computeSlotsIntegrityHash(slots: SnapshotSlotsRecord): string;
|
|
35
|
+
export declare function verifySnapshotSlotsIntegrity(slotsInput: SnapshotSlotsRecord | string, expectedSlotsHash?: string): SnapshotIntegrityVerification;
|
|
36
|
+
//# sourceMappingURL=composition-snapshot-integrity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composition-snapshot-integrity.d.ts","sourceRoot":"","sources":["../src/composition-snapshot-integrity.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AACrE,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG,iBAAiB,EAAE,GAAG,kBAAkB,CAAC;AACjG,MAAM,WAAW,kBAAkB;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAAC;CAClC;AACD,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAEpE,MAAM,MAAM,yBAAyB,GAAG,kBAAkB,GAAG;IAC3D,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,8BAA8B,GACtC,sBAAsB,GACtB,oBAAoB,GACpB,+BAA+B,GAC/B,sBAAsB,GACtB,qBAAqB,CAAC;AAE1B,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,8BAA8B,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,6BAA6B;IAC5C,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,wBAAwB,EAAE,CAAC;CACtC;AAsCD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE/D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEvD;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAcvE;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,iBAAiB,GAAG,KAAK,IAAI,yBAAyB,CAGxG;AAOD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,yBAAyB,GAAG,MAAM,CAErF;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,yBAAyB,GAAG,yBAAyB,CAKvG;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAE5E;AAED,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,mBAAmB,GAAG,MAAM,EACxC,iBAAiB,CAAC,EAAE,MAAM,GACzB,6BAA6B,CA4D/B"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
function isFiniteNumber(value) {
|
|
3
|
+
return typeof value === 'number' && Number.isFinite(value);
|
|
4
|
+
}
|
|
5
|
+
function isPlainObject(value) {
|
|
6
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
7
|
+
return false;
|
|
8
|
+
const proto = Object.getPrototypeOf(value);
|
|
9
|
+
return proto === Object.prototype || proto === null;
|
|
10
|
+
}
|
|
11
|
+
function normalizeSnapshotJson(value) {
|
|
12
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean') {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
if (isFiniteNumber(value)) {
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
if (Array.isArray(value)) {
|
|
19
|
+
return value.map(entry => normalizeSnapshotJson(entry));
|
|
20
|
+
}
|
|
21
|
+
if (isPlainObject(value)) {
|
|
22
|
+
const out = {};
|
|
23
|
+
for (const key of Object.keys(value).sort()) {
|
|
24
|
+
const next = value[key];
|
|
25
|
+
if (next === undefined)
|
|
26
|
+
continue;
|
|
27
|
+
out[key] = normalizeSnapshotJson(next);
|
|
28
|
+
}
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
throw new TypeError(`Unsupported snapshot JSON value: ${String(value)}`);
|
|
32
|
+
}
|
|
33
|
+
export function canonicalizeSnapshotJson(value) {
|
|
34
|
+
return JSON.stringify(normalizeSnapshotJson(value));
|
|
35
|
+
}
|
|
36
|
+
export function hashSnapshotJson(value) {
|
|
37
|
+
return createHash('sha256').update(canonicalizeSnapshotJson(value)).digest('hex');
|
|
38
|
+
}
|
|
39
|
+
export function parseSnapshotSlotsJson(raw) {
|
|
40
|
+
let parsed;
|
|
41
|
+
try {
|
|
42
|
+
parsed = JSON.parse(raw);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
46
|
+
throw new Error(`Malformed slots_json: ${message}`);
|
|
47
|
+
}
|
|
48
|
+
if (!isPlainObject(parsed)) {
|
|
49
|
+
throw new Error('Invalid slots_json root: expected object');
|
|
50
|
+
}
|
|
51
|
+
return normalizeSnapshotJson(parsed);
|
|
52
|
+
}
|
|
53
|
+
export function isInlineSnapshotSlotPayload(value) {
|
|
54
|
+
if (!isPlainObject(value))
|
|
55
|
+
return false;
|
|
56
|
+
return value.kind === 'inline' || value.source === 'inline' || value.inline === true;
|
|
57
|
+
}
|
|
58
|
+
function stripInlineIntegrityHash(payload) {
|
|
59
|
+
const { integrity_hash: _integrityHash, ...rest } = payload;
|
|
60
|
+
return normalizeSnapshotJson(rest);
|
|
61
|
+
}
|
|
62
|
+
export function computeInlineIntegrityHash(payload) {
|
|
63
|
+
return hashSnapshotJson(stripInlineIntegrityHash(payload));
|
|
64
|
+
}
|
|
65
|
+
export function attachInlineIntegrityHash(payload) {
|
|
66
|
+
return {
|
|
67
|
+
...payload,
|
|
68
|
+
integrity_hash: computeInlineIntegrityHash(payload),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export function computeSlotsIntegrityHash(slots) {
|
|
72
|
+
return hashSnapshotJson(slots);
|
|
73
|
+
}
|
|
74
|
+
export function verifySnapshotSlotsIntegrity(slotsInput, expectedSlotsHash) {
|
|
75
|
+
let slots;
|
|
76
|
+
try {
|
|
77
|
+
slots = typeof slotsInput === 'string'
|
|
78
|
+
? parseSnapshotSlotsJson(slotsInput)
|
|
79
|
+
: normalizeSnapshotJson(slotsInput);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
83
|
+
const reason = message.startsWith('Invalid slots_json root')
|
|
84
|
+
? 'invalid_slots_root'
|
|
85
|
+
: 'malformed_slots_json';
|
|
86
|
+
return {
|
|
87
|
+
ok: false,
|
|
88
|
+
slots: null,
|
|
89
|
+
actualSlotsHash: null,
|
|
90
|
+
failures: [{ slotKey: '$slots', reason, error: message }],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const failures = [];
|
|
94
|
+
for (const [slotKey, slotValue] of Object.entries(slots)) {
|
|
95
|
+
if (!isInlineSnapshotSlotPayload(slotValue))
|
|
96
|
+
continue;
|
|
97
|
+
const actualField = slotValue.integrity_hash;
|
|
98
|
+
if (typeof actualField !== 'string' || actualField.length === 0) {
|
|
99
|
+
failures.push({
|
|
100
|
+
slotKey,
|
|
101
|
+
reason: 'missing_inline_integrity_hash',
|
|
102
|
+
});
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const expectedField = computeInlineIntegrityHash(slotValue);
|
|
106
|
+
if (actualField !== expectedField) {
|
|
107
|
+
failures.push({
|
|
108
|
+
slotKey,
|
|
109
|
+
reason: 'inline_hash_mismatch',
|
|
110
|
+
expected: expectedField,
|
|
111
|
+
actual: actualField,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const actualSlotsHash = computeSlotsIntegrityHash(slots);
|
|
116
|
+
if (expectedSlotsHash && actualSlotsHash !== expectedSlotsHash) {
|
|
117
|
+
failures.push({
|
|
118
|
+
slotKey: '$slots',
|
|
119
|
+
reason: 'slots_hash_mismatch',
|
|
120
|
+
expected: expectedSlotsHash,
|
|
121
|
+
actual: actualSlotsHash,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
ok: failures.length === 0,
|
|
126
|
+
slots,
|
|
127
|
+
actualSlotsHash,
|
|
128
|
+
failures,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=composition-snapshot-integrity.js.map
|