@psiclawops/hypermem 0.9.3 → 0.9.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.
- package/CHANGELOG.md +27 -2
- package/INSTALL.md +75 -68
- package/README.md +18 -36
- package/assets/default-config.json +41 -0
- package/bench/data-access-bench.mjs +1 -1
- package/bin/hypermem-doctor.mjs +76 -2
- package/bin/hypermem-status.mjs +255 -7
- package/dist/adaptive-lifecycle.d.ts +39 -0
- package/dist/adaptive-lifecycle.d.ts.map +1 -1
- package/dist/adaptive-lifecycle.js +87 -9
- package/dist/background-indexer.d.ts.map +1 -1
- package/dist/background-indexer.js +16 -14
- package/dist/compositor.d.ts.map +1 -1
- package/dist/compositor.js +239 -20
- package/dist/cross-agent.d.ts +1 -1
- package/dist/cross-agent.js +17 -17
- package/dist/hybrid-retrieval.d.ts +8 -0
- package/dist/hybrid-retrieval.d.ts.map +1 -1
- package/dist/hybrid-retrieval.js +112 -10
- package/dist/index.d.ts +16 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -4
- package/dist/message-store.d.ts +62 -1
- package/dist/message-store.d.ts.map +1 -1
- package/dist/message-store.js +355 -2
- package/dist/open-domain.d.ts.map +1 -1
- package/dist/open-domain.js +3 -2
- package/dist/proactive-pass.d.ts +42 -2
- package/dist/proactive-pass.d.ts.map +1 -1
- package/dist/proactive-pass.js +294 -39
- package/dist/seed.d.ts +1 -1
- package/dist/seed.js +1 -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.map +1 -1
- package/dist/topic-synthesizer.js +10 -4
- package/dist/trigger-registry.d.ts +1 -1
- package/dist/trigger-registry.js +4 -4
- package/dist/types.d.ts +101 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-store.d.ts +10 -1
- package/dist/vector-store.d.ts.map +1 -1
- package/dist/vector-store.js +45 -9
- package/docs/DIAGNOSTICS.md +88 -1
- package/docs/INTEGRATION_VALIDATION.md +40 -1
- package/docs/MIGRATION.md +1 -1
- package/docs/TUNING.md +47 -6
- package/install.sh +5 -60
- package/memory-plugin/dist/index.js +192 -0
- package/memory-plugin/openclaw.plugin.json +199 -2
- package/memory-plugin/package.json +2 -2
- package/package.json +29 -10
- package/plugin/dist/index.d.ts +2 -0
- package/plugin/dist/index.d.ts.map +1 -1
- package/plugin/dist/index.js +178 -11
- package/plugin/dist/index.js.map +1 -1
- package/plugin/openclaw.plugin.json +199 -2
- package/plugin/package.json +2 -2
- package/scripts/install-packed-runtime.mjs +99 -0
- package/scripts/install-runtime.mjs +164 -4
- package/ARCHITECTURE.md +0 -298
- package/docs/KNOWN_LIMITATIONS.md +0 -35
- package/docs/PHASE1-VALIDATION.md +0 -132
- package/docs/RELEASE_0.8.0_VALIDATION.md +0 -70
- package/docs/RELEASE_PROCESS.md +0 -10
- package/docs/ROADMAP.md +0 -266
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. The recommended install path writes a starter `config.json` with
|
|
3
|
+
Configuration reference for operators and agents. All settings are optional. The recommended install path writes a starter `config.json` with the 0.9.4 recall-friendly standard context profile and `embedding.provider: "none"` so first install has no external service dependency. Tune from that verified baseline, then opt into Ollama or a hosted embedding provider when you want semantic vector recall.
|
|
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
|
|
|
@@ -56,7 +56,7 @@ That said, not every deployment needs full context richness. If you're running a
|
|
|
56
56
|
|
|
57
57
|
| Situation | Preset | Reason |
|
|
58
58
|
|---|---|---|
|
|
59
|
-
| First install, trying it out |
|
|
59
|
+
| First install, trying it out | Installed baseline | FTS5/no-embedding mode verifies cleanly before provider tuning |
|
|
60
60
|
| Single conversational agent | `standard` | Richer memory without fleet overhead |
|
|
61
61
|
| Multi-agent fleet, long-running sessions | `full` | Full continuity, keystone recall, cross-session context |
|
|
62
62
|
| CI pipelines, one-shot tasks | Custom light | Disable indexer, keep only history |
|
|
@@ -114,13 +114,38 @@ Estimated context per turn: **12–35k tokens** on a 200k model (lower on smalle
|
|
|
114
114
|
|
|
115
115
|
### Standard setup
|
|
116
116
|
|
|
117
|
-
The
|
|
117
|
+
The standard semantic configuration. All memory layers are active with 0.9.4 recall preservation turned on. Good for most single-agent deployments after the baseline FTS5 install is verified.
|
|
118
118
|
|
|
119
119
|
```json
|
|
120
120
|
{
|
|
121
|
+
"embedding": {
|
|
122
|
+
"provider": "ollama",
|
|
123
|
+
"model": "nomic-embed-text",
|
|
124
|
+
"dims": 768,
|
|
125
|
+
"dimensions": 768,
|
|
126
|
+
"ollamaUrl": "http://localhost:11434"
|
|
127
|
+
},
|
|
121
128
|
"compositor": {
|
|
122
|
-
"
|
|
129
|
+
"turnBudget": {
|
|
130
|
+
"budgetFraction": 0.6,
|
|
131
|
+
"minContextFraction": 0.18
|
|
132
|
+
},
|
|
133
|
+
"warming": {
|
|
134
|
+
"protectedFloorEnabled": true,
|
|
135
|
+
"shapedWarmupDecay": true
|
|
136
|
+
},
|
|
137
|
+
"adjacency": {
|
|
138
|
+
"enabled": true,
|
|
139
|
+
"boostMultiplier": 1.3,
|
|
140
|
+
"maxLookback": 5,
|
|
141
|
+
"maxClockDeltaMin": 10,
|
|
142
|
+
"evictionGuardMessages": 3,
|
|
143
|
+
"evictionGuardTokenCap": 4000
|
|
144
|
+
},
|
|
145
|
+
"budgetFraction": 0.6,
|
|
123
146
|
"contextWindowReserve": 0.25,
|
|
147
|
+
"targetBudgetFraction": 0.5,
|
|
148
|
+
"warmHistoryBudgetFraction": 0.45,
|
|
124
149
|
"maxFacts": 28,
|
|
125
150
|
"maxHistoryMessages": 250,
|
|
126
151
|
"maxCrossSessionContext": 0,
|
|
@@ -129,13 +154,29 @@ The default out-of-the-box configuration. All memory layers active with balanced
|
|
|
129
154
|
"hyperformProfile": "standard"
|
|
130
155
|
},
|
|
131
156
|
"indexer": {
|
|
157
|
+
"enabled": true,
|
|
132
158
|
"factExtractionMode": "tiered",
|
|
133
159
|
"periodicInterval": 300000
|
|
134
160
|
}
|
|
135
161
|
}
|
|
136
162
|
```
|
|
137
163
|
|
|
138
|
-
Estimated context per turn: **35–80k tokens** on a 200k model.
|
|
164
|
+
Estimated context per turn: **35–80k tokens** on a 200k model. `hypermem-install` writes these context and recall-preservation knobs when no existing config is present, but leaves embeddings disabled by default for installation safety. Existing config files are preserved, so run `hypermem-doctor --fix-plan` after upgrades to see whether older installs are missing the 0.9.4 recall-surface knobs.
|
|
165
|
+
|
|
166
|
+
### 0.9.4 recall preservation knobs
|
|
167
|
+
|
|
168
|
+
These settings prevent the regression class that motivated 0.9.4: the direct antecedent or topic-bearing warm context being trimmed away while the system still had enough usable budget.
|
|
169
|
+
|
|
170
|
+
| Knob | Default | What it protects | Health signal |
|
|
171
|
+
|---|---:|---|---|
|
|
172
|
+
| `compositor.turnBudget.budgetFraction` | `0.6` | Keeps the active turn budget below the old over-warming posture | `hypermem-status --master` recall surface line |
|
|
173
|
+
| `compositor.turnBudget.minContextFraction` | `0.18` | Guarantees a minimum context allocation on constrained windows | `hypermem-doctor --fix-plan` |
|
|
174
|
+
| `compositor.warming.protectedFloorEnabled` | `true` | Prevents afterTurn trim from evicting bootstrap/warmup floor content before elevated pressure | `node test/afterturn-protected-floor.mjs` |
|
|
175
|
+
| `compositor.warming.shapedWarmupDecay` | `true` | Uses topic-bearing turn count instead of blind fixed-turn decay | `node test/adaptive-lifecycle.mjs` |
|
|
176
|
+
| `compositor.adjacency.enabled` | `true` | Boosts recent antecedents during fused retrieval | `node test/hybrid-retrieval.mjs` |
|
|
177
|
+
| `compositor.adjacency.evictionGuardTokenCap` | `4000` | Caps the literal antecedent guard so it cannot consume the whole budget | `node test/compositor.mjs` |
|
|
178
|
+
|
|
179
|
+
Do not tune these off to save tokens until you have evidence. Lower `maxFacts`, `maxCrossSessionContext`, or wiki caps first. Disabling adjacency or protected warming is a correctness trade, not a cost preset.
|
|
139
180
|
|
|
140
181
|
### Full performance setup
|
|
141
182
|
|
|
@@ -208,7 +249,7 @@ const custom = mergeProfile('standard', {
|
|
|
208
249
|
});
|
|
209
250
|
```
|
|
210
251
|
|
|
211
|
-
Start
|
|
252
|
+
Start from the installed baseline. Move to `light` only when you need lower first-turn cost, and move to `standard` or `full` when richer context is worth the token spend.
|
|
212
253
|
|
|
213
254
|
---
|
|
214
255
|
|
package/install.sh
CHANGED
|
@@ -166,7 +166,7 @@ stage_runtime() {
|
|
|
166
166
|
write_minimal_config_if_missing() {
|
|
167
167
|
echo -e "\n${BOLD} Config check${NC}"
|
|
168
168
|
if $DRY_RUN; then
|
|
169
|
-
dryrun "would preserve existing config or write
|
|
169
|
+
dryrun "would preserve existing config or write FTS5 starter config: $CONFIG_FILE"
|
|
170
170
|
return
|
|
171
171
|
fi
|
|
172
172
|
|
|
@@ -175,66 +175,11 @@ write_minimal_config_if_missing() {
|
|
|
175
175
|
return
|
|
176
176
|
fi
|
|
177
177
|
|
|
178
|
+
local default_config="$INSTALL_DIR/node_modules/@psiclawops/hypermem/assets/default-config.json"
|
|
179
|
+
[[ -f "$default_config" ]] || die "missing packaged default config: $default_config"
|
|
178
180
|
mkdir -p "$(dirname "$CONFIG_FILE")"
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
"contextWindowSize": 128000,
|
|
182
|
-
"contextWindowReserve": 0.25,
|
|
183
|
-
"deferToolPruning": false,
|
|
184
|
-
"verboseLogging": false,
|
|
185
|
-
"contextWindowOverrides": {},
|
|
186
|
-
"warmCacheReplayThresholdMs": 120000,
|
|
187
|
-
"subagentWarming": "light",
|
|
188
|
-
"embedding": {
|
|
189
|
-
"provider": "none"
|
|
190
|
-
},
|
|
191
|
-
"compositor": {
|
|
192
|
-
"budgetFraction": 0.55,
|
|
193
|
-
"reserveFraction": 0.25,
|
|
194
|
-
"historyFraction": 0.4,
|
|
195
|
-
"memoryFraction": 0.4,
|
|
196
|
-
"defaultTokenBudget": 90000,
|
|
197
|
-
"maxHistoryMessages": 500,
|
|
198
|
-
"maxFacts": 25,
|
|
199
|
-
"maxExpertisePatterns": 6,
|
|
200
|
-
"maxCrossSessionContext": 4000,
|
|
201
|
-
"maxTotalTriggerTokens": 4000,
|
|
202
|
-
"maxRecentToolPairs": 3,
|
|
203
|
-
"maxProseToolPairs": 10,
|
|
204
|
-
"warmHistoryBudgetFraction": 0.27,
|
|
205
|
-
"contextWindowReserve": 0.25,
|
|
206
|
-
"dynamicReserveTurnHorizon": 5,
|
|
207
|
-
"dynamicReserveMax": 0.5,
|
|
208
|
-
"dynamicReserveEnabled": true,
|
|
209
|
-
"keystoneHistoryFraction": 0.15,
|
|
210
|
-
"keystoneMaxMessages": 12,
|
|
211
|
-
"keystoneMinSignificance": 0.5,
|
|
212
|
-
"targetBudgetFraction": 0.50,
|
|
213
|
-
"enableFOS": true,
|
|
214
|
-
"enableMOD": true,
|
|
215
|
-
"hyperformProfile": "standard",
|
|
216
|
-
"wikiTokenCap": 500,
|
|
217
|
-
"zigzagOrdering": true
|
|
218
|
-
},
|
|
219
|
-
"eviction": {
|
|
220
|
-
"enabled": true,
|
|
221
|
-
"imageAgeTurns": 2,
|
|
222
|
-
"toolResultAgeTurns": 4,
|
|
223
|
-
"minTokensToEvict": 200,
|
|
224
|
-
"keepPreviewChars": 120
|
|
225
|
-
},
|
|
226
|
-
"maintenance": {
|
|
227
|
-
"periodicInterval": 300000,
|
|
228
|
-
"maxActiveConversations": 5,
|
|
229
|
-
"recentConversationCooldownMs": 30000,
|
|
230
|
-
"maxCandidatesPerPass": 200
|
|
231
|
-
},
|
|
232
|
-
"vectorStore": {
|
|
233
|
-
"enabled": false
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
JSON
|
|
237
|
-
success "lightweight starter config written: $CONFIG_FILE"
|
|
181
|
+
cp "$default_config" "$CONFIG_FILE"
|
|
182
|
+
success "FTS5 starter config written: $CONFIG_FILE"
|
|
238
183
|
}
|
|
239
184
|
|
|
240
185
|
verify_stage() {
|
|
@@ -18,6 +18,7 @@ import { definePluginEntry, emptyPluginConfigSchema } from 'openclaw/plugin-sdk/
|
|
|
18
18
|
import { matchTriggers, TRIGGER_REGISTRY } from '@psiclawops/hypermem';
|
|
19
19
|
import path from 'path';
|
|
20
20
|
import fs from 'fs/promises';
|
|
21
|
+
import fsSync from 'fs';
|
|
21
22
|
import os from 'os';
|
|
22
23
|
import { fileURLToPath } from 'url';
|
|
23
24
|
// ─── HyperMem singleton ────────────────────────────────────────
|
|
@@ -283,6 +284,196 @@ function createMemorySearchManager(hm, agentId, workspaceDir) {
|
|
|
283
284
|
},
|
|
284
285
|
};
|
|
285
286
|
}
|
|
287
|
+
// ─── history.query agent tool ───────────────────────────────────
|
|
288
|
+
const HISTORY_QUERY_MODES = [
|
|
289
|
+
'runtime_chain',
|
|
290
|
+
'transcript_tail',
|
|
291
|
+
'tool_events',
|
|
292
|
+
'by_topic',
|
|
293
|
+
'by_context',
|
|
294
|
+
'cross_session',
|
|
295
|
+
];
|
|
296
|
+
const HISTORY_QUERY_TOOL_PARAMETERS = {
|
|
297
|
+
type: 'object',
|
|
298
|
+
additionalProperties: false,
|
|
299
|
+
properties: {
|
|
300
|
+
mode: {
|
|
301
|
+
type: 'string',
|
|
302
|
+
enum: HISTORY_QUERY_MODES,
|
|
303
|
+
description: 'History query mode. cross_session is scoped to the current agent by default.',
|
|
304
|
+
},
|
|
305
|
+
sessionKey: {
|
|
306
|
+
type: 'string',
|
|
307
|
+
description: 'Optional session key. Defaults to the active session when available.',
|
|
308
|
+
},
|
|
309
|
+
conversationId: {
|
|
310
|
+
type: 'number',
|
|
311
|
+
description: 'Optional direct conversation id. Must belong to the current agent.',
|
|
312
|
+
},
|
|
313
|
+
contextId: {
|
|
314
|
+
type: 'number',
|
|
315
|
+
description: 'Required for by_context mode. Must belong to the current agent.',
|
|
316
|
+
},
|
|
317
|
+
topicId: {
|
|
318
|
+
type: 'string',
|
|
319
|
+
description: 'Required for by_topic mode.',
|
|
320
|
+
},
|
|
321
|
+
limit: {
|
|
322
|
+
type: 'number',
|
|
323
|
+
description: 'Optional result limit. HyperMem clamps this to the hard cap for the selected mode.',
|
|
324
|
+
},
|
|
325
|
+
minMessageId: {
|
|
326
|
+
type: 'number',
|
|
327
|
+
description: 'Optional lower message id bound for supported modes.',
|
|
328
|
+
},
|
|
329
|
+
since: {
|
|
330
|
+
type: 'string',
|
|
331
|
+
description: 'Optional ISO timestamp lower bound for cross_session mode.',
|
|
332
|
+
},
|
|
333
|
+
includeArchived: {
|
|
334
|
+
type: 'boolean',
|
|
335
|
+
description: 'Allow archived/forked contexts for by_context mode.',
|
|
336
|
+
},
|
|
337
|
+
includeToolPayloads: {
|
|
338
|
+
type: 'boolean',
|
|
339
|
+
description: 'Return raw tool payloads for tool_events. Requires owner context; default is redacted.',
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
required: ['mode'],
|
|
343
|
+
};
|
|
344
|
+
function asRecord(value) {
|
|
345
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
346
|
+
? value
|
|
347
|
+
: {};
|
|
348
|
+
}
|
|
349
|
+
function optionalString(params, key) {
|
|
350
|
+
const value = params[key];
|
|
351
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
352
|
+
}
|
|
353
|
+
function optionalNumber(params, key) {
|
|
354
|
+
const value = params[key];
|
|
355
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
356
|
+
return undefined;
|
|
357
|
+
return value;
|
|
358
|
+
}
|
|
359
|
+
function optionalBoolean(params, key) {
|
|
360
|
+
return typeof params[key] === 'boolean' ? params[key] : undefined;
|
|
361
|
+
}
|
|
362
|
+
function isHistoryQueryMode(value) {
|
|
363
|
+
return typeof value === 'string' && HISTORY_QUERY_MODES.includes(value);
|
|
364
|
+
}
|
|
365
|
+
function historyQueryTelemetryEnabled() {
|
|
366
|
+
return process.env.HYPERMEM_TELEMETRY === '1';
|
|
367
|
+
}
|
|
368
|
+
function emitHistoryQueryTelemetry(event) {
|
|
369
|
+
if (!historyQueryTelemetryEnabled())
|
|
370
|
+
return;
|
|
371
|
+
const telemetryPath = process.env.HYPERMEM_TELEMETRY_PATH || './hypermem-telemetry.jsonl';
|
|
372
|
+
try {
|
|
373
|
+
fsSync.appendFileSync(telemetryPath, `${JSON.stringify(event)}\n`, 'utf8');
|
|
374
|
+
}
|
|
375
|
+
catch {
|
|
376
|
+
// Telemetry must never break the tool path.
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
function createHistoryQueryTool(ctx) {
|
|
380
|
+
return {
|
|
381
|
+
name: 'history_query',
|
|
382
|
+
label: 'history.query',
|
|
383
|
+
description: [
|
|
384
|
+
'Query HyperMem SQLite-backed message history for the current agent.',
|
|
385
|
+
'Use this when exact conversation state is needed instead of semantic recall.',
|
|
386
|
+
'Modes: runtime_chain, transcript_tail, tool_events, by_topic, by_context, cross_session.',
|
|
387
|
+
'Tool payloads are redacted by default; raw payloads require owner context.',
|
|
388
|
+
].join(' '),
|
|
389
|
+
parameters: HISTORY_QUERY_TOOL_PARAMETERS,
|
|
390
|
+
displaySummary: 'Query HyperMem message history',
|
|
391
|
+
async execute(_toolCallId, rawParams) {
|
|
392
|
+
const started = Date.now();
|
|
393
|
+
const params = asRecord(rawParams);
|
|
394
|
+
const mode = params.mode;
|
|
395
|
+
const agentId = ctx.agentId || 'main';
|
|
396
|
+
const includeToolPayloads = optionalBoolean(params, 'includeToolPayloads') === true;
|
|
397
|
+
const baseTelemetry = {
|
|
398
|
+
ts: new Date().toISOString(),
|
|
399
|
+
agentId,
|
|
400
|
+
hasSessionKey: Boolean(optionalString(params, 'sessionKey') ?? ctx.sessionKey),
|
|
401
|
+
hasConversationId: optionalNumber(params, 'conversationId') !== undefined,
|
|
402
|
+
includeToolPayloads,
|
|
403
|
+
};
|
|
404
|
+
if (!isHistoryQueryMode(mode)) {
|
|
405
|
+
emitHistoryQueryTelemetry({
|
|
406
|
+
event: 'history-query',
|
|
407
|
+
status: 'error',
|
|
408
|
+
...baseTelemetry,
|
|
409
|
+
durationMs: Date.now() - started,
|
|
410
|
+
errorCode: 'invalid-mode',
|
|
411
|
+
});
|
|
412
|
+
throw new Error(`history.query: mode must be one of ${HISTORY_QUERY_MODES.join(', ')}`);
|
|
413
|
+
}
|
|
414
|
+
if (includeToolPayloads && !ctx.senderIsOwner) {
|
|
415
|
+
emitHistoryQueryTelemetry({
|
|
416
|
+
event: 'history-query',
|
|
417
|
+
status: 'error',
|
|
418
|
+
mode,
|
|
419
|
+
...baseTelemetry,
|
|
420
|
+
durationMs: Date.now() - started,
|
|
421
|
+
errorCode: 'owner-required',
|
|
422
|
+
});
|
|
423
|
+
throw new Error('history.query: includeToolPayloads requires owner context');
|
|
424
|
+
}
|
|
425
|
+
const query = {
|
|
426
|
+
agentId,
|
|
427
|
+
mode,
|
|
428
|
+
sessionKey: optionalString(params, 'sessionKey') ?? ctx.sessionKey,
|
|
429
|
+
conversationId: optionalNumber(params, 'conversationId'),
|
|
430
|
+
contextId: optionalNumber(params, 'contextId'),
|
|
431
|
+
topicId: optionalString(params, 'topicId'),
|
|
432
|
+
limit: optionalNumber(params, 'limit'),
|
|
433
|
+
minMessageId: optionalNumber(params, 'minMessageId'),
|
|
434
|
+
since: optionalString(params, 'since'),
|
|
435
|
+
includeArchived: optionalBoolean(params, 'includeArchived'),
|
|
436
|
+
includeToolPayloads,
|
|
437
|
+
};
|
|
438
|
+
for (const [key, value] of Object.entries(query)) {
|
|
439
|
+
if (value === undefined)
|
|
440
|
+
delete query[key];
|
|
441
|
+
}
|
|
442
|
+
try {
|
|
443
|
+
const hm = await getHyperMem();
|
|
444
|
+
const result = hm.queryHistory(query);
|
|
445
|
+
emitHistoryQueryTelemetry({
|
|
446
|
+
event: 'history-query',
|
|
447
|
+
status: 'ok',
|
|
448
|
+
mode,
|
|
449
|
+
...baseTelemetry,
|
|
450
|
+
messageCount: result.messages.length,
|
|
451
|
+
truncated: Boolean(result.truncated),
|
|
452
|
+
redacted: Boolean(result.redacted),
|
|
453
|
+
durationMs: Date.now() - started,
|
|
454
|
+
});
|
|
455
|
+
const summary = `history.query ${mode}: ${result.messages.length} message(s)`
|
|
456
|
+
+ (result.truncated ? ' (truncated)' : '')
|
|
457
|
+
+ (result.redacted ? ' (redacted)' : '');
|
|
458
|
+
return {
|
|
459
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
460
|
+
details: { status: 'ok', summary, result },
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
catch (err) {
|
|
464
|
+
emitHistoryQueryTelemetry({
|
|
465
|
+
event: 'history-query',
|
|
466
|
+
status: 'error',
|
|
467
|
+
mode,
|
|
468
|
+
...baseTelemetry,
|
|
469
|
+
durationMs: Date.now() - started,
|
|
470
|
+
errorCode: 'query-failed',
|
|
471
|
+
});
|
|
472
|
+
throw err;
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
};
|
|
476
|
+
}
|
|
286
477
|
// ─── Manager cache ──────────────────────────────────────────────
|
|
287
478
|
// One manager per agentId; closed on plugin dispose.
|
|
288
479
|
const _managers = new Map();
|
|
@@ -294,6 +485,7 @@ export default definePluginEntry({
|
|
|
294
485
|
kind: 'memory',
|
|
295
486
|
configSchema: emptyPluginConfigSchema(),
|
|
296
487
|
register(api) {
|
|
488
|
+
api.registerTool((ctx) => createHistoryQueryTool(ctx), { name: 'history_query', optional: true });
|
|
297
489
|
api.registerMemoryCapability({
|
|
298
490
|
runtime: {
|
|
299
491
|
async getMemorySearchManager(params) {
|
|
@@ -3,11 +3,208 @@
|
|
|
3
3
|
"enabledByDefault": false,
|
|
4
4
|
"kind": "memory",
|
|
5
5
|
"activation": {
|
|
6
|
-
"onCapabilities": [
|
|
6
|
+
"onCapabilities": [
|
|
7
|
+
"memory"
|
|
8
|
+
]
|
|
7
9
|
},
|
|
8
10
|
"configSchema": {
|
|
9
11
|
"type": "object",
|
|
10
12
|
"additionalProperties": false,
|
|
11
|
-
"properties": {
|
|
13
|
+
"properties": {
|
|
14
|
+
"hyperMemPath": {
|
|
15
|
+
"type": "string"
|
|
16
|
+
},
|
|
17
|
+
"dataDir": {
|
|
18
|
+
"type": "string"
|
|
19
|
+
},
|
|
20
|
+
"contextWindowSize": {
|
|
21
|
+
"type": "integer",
|
|
22
|
+
"minimum": 1
|
|
23
|
+
},
|
|
24
|
+
"contextWindowReserve": {
|
|
25
|
+
"type": "number",
|
|
26
|
+
"minimum": 0,
|
|
27
|
+
"maximum": 0.5
|
|
28
|
+
},
|
|
29
|
+
"deferToolPruning": {
|
|
30
|
+
"type": "boolean"
|
|
31
|
+
},
|
|
32
|
+
"verboseLogging": {
|
|
33
|
+
"type": "boolean"
|
|
34
|
+
},
|
|
35
|
+
"warmCacheReplayThresholdMs": {
|
|
36
|
+
"type": "integer",
|
|
37
|
+
"minimum": 0
|
|
38
|
+
},
|
|
39
|
+
"subagentWarming": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"enum": [
|
|
42
|
+
"full",
|
|
43
|
+
"light",
|
|
44
|
+
"off"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
"contextWindowOverrides": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"additionalProperties": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"additionalProperties": false,
|
|
52
|
+
"properties": {
|
|
53
|
+
"contextTokens": {
|
|
54
|
+
"type": "integer",
|
|
55
|
+
"minimum": 1
|
|
56
|
+
},
|
|
57
|
+
"contextWindow": {
|
|
58
|
+
"type": "integer",
|
|
59
|
+
"minimum": 1
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"compositor": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"additionalProperties": true
|
|
67
|
+
},
|
|
68
|
+
"eviction": {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"additionalProperties": false,
|
|
71
|
+
"properties": {
|
|
72
|
+
"enabled": {
|
|
73
|
+
"type": "boolean"
|
|
74
|
+
},
|
|
75
|
+
"imageAgeTurns": {
|
|
76
|
+
"type": "integer",
|
|
77
|
+
"minimum": 0
|
|
78
|
+
},
|
|
79
|
+
"toolResultAgeTurns": {
|
|
80
|
+
"type": "integer",
|
|
81
|
+
"minimum": 0
|
|
82
|
+
},
|
|
83
|
+
"minTokensToEvict": {
|
|
84
|
+
"type": "integer",
|
|
85
|
+
"minimum": 0
|
|
86
|
+
},
|
|
87
|
+
"keepPreviewChars": {
|
|
88
|
+
"type": "integer",
|
|
89
|
+
"minimum": 0
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"embedding": {
|
|
94
|
+
"type": "object",
|
|
95
|
+
"additionalProperties": false,
|
|
96
|
+
"properties": {
|
|
97
|
+
"provider": {
|
|
98
|
+
"type": "string",
|
|
99
|
+
"enum": [
|
|
100
|
+
"none",
|
|
101
|
+
"ollama",
|
|
102
|
+
"openai",
|
|
103
|
+
"gemini"
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
"ollamaUrl": {
|
|
107
|
+
"type": "string"
|
|
108
|
+
},
|
|
109
|
+
"openaiApiKey": {
|
|
110
|
+
"type": "string"
|
|
111
|
+
},
|
|
112
|
+
"openaiBaseUrl": {
|
|
113
|
+
"type": "string"
|
|
114
|
+
},
|
|
115
|
+
"geminiApiKey": {
|
|
116
|
+
"type": "string"
|
|
117
|
+
},
|
|
118
|
+
"geminiBaseUrl": {
|
|
119
|
+
"type": "string"
|
|
120
|
+
},
|
|
121
|
+
"geminiIndexTaskType": {
|
|
122
|
+
"type": "string"
|
|
123
|
+
},
|
|
124
|
+
"geminiQueryTaskType": {
|
|
125
|
+
"type": "string"
|
|
126
|
+
},
|
|
127
|
+
"queryInputType": {
|
|
128
|
+
"type": "string"
|
|
129
|
+
},
|
|
130
|
+
"documentInputType": {
|
|
131
|
+
"type": "string"
|
|
132
|
+
},
|
|
133
|
+
"queryPrefix": {
|
|
134
|
+
"type": "string"
|
|
135
|
+
},
|
|
136
|
+
"documentPrefix": {
|
|
137
|
+
"type": "string"
|
|
138
|
+
},
|
|
139
|
+
"model": {
|
|
140
|
+
"type": "string"
|
|
141
|
+
},
|
|
142
|
+
"dimensions": {
|
|
143
|
+
"type": "integer",
|
|
144
|
+
"minimum": 1
|
|
145
|
+
},
|
|
146
|
+
"timeout": {
|
|
147
|
+
"type": "integer",
|
|
148
|
+
"minimum": 1
|
|
149
|
+
},
|
|
150
|
+
"batchSize": {
|
|
151
|
+
"type": "integer",
|
|
152
|
+
"minimum": 1
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
"reranker": {
|
|
157
|
+
"type": "object",
|
|
158
|
+
"additionalProperties": false,
|
|
159
|
+
"required": [
|
|
160
|
+
"provider"
|
|
161
|
+
],
|
|
162
|
+
"properties": {
|
|
163
|
+
"provider": {
|
|
164
|
+
"type": "string",
|
|
165
|
+
"enum": [
|
|
166
|
+
"zeroentropy",
|
|
167
|
+
"openrouter",
|
|
168
|
+
"local",
|
|
169
|
+
"none"
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
"minCandidates": {
|
|
173
|
+
"type": "integer",
|
|
174
|
+
"minimum": 0
|
|
175
|
+
},
|
|
176
|
+
"maxDocuments": {
|
|
177
|
+
"type": "integer",
|
|
178
|
+
"minimum": 1
|
|
179
|
+
},
|
|
180
|
+
"topK": {
|
|
181
|
+
"type": "integer",
|
|
182
|
+
"minimum": 1
|
|
183
|
+
},
|
|
184
|
+
"timeoutMs": {
|
|
185
|
+
"type": "integer",
|
|
186
|
+
"minimum": 1
|
|
187
|
+
},
|
|
188
|
+
"zeroEntropyApiKey": {
|
|
189
|
+
"type": "string"
|
|
190
|
+
},
|
|
191
|
+
"zeroEntropyModel": {
|
|
192
|
+
"type": "string"
|
|
193
|
+
},
|
|
194
|
+
"openrouterApiKey": {
|
|
195
|
+
"type": "string"
|
|
196
|
+
},
|
|
197
|
+
"openrouterModel": {
|
|
198
|
+
"type": "string"
|
|
199
|
+
},
|
|
200
|
+
"ollamaUrl": {
|
|
201
|
+
"type": "string"
|
|
202
|
+
},
|
|
203
|
+
"ollamaModel": {
|
|
204
|
+
"type": "string"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
12
209
|
}
|
|
13
210
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@psiclawops/hypermem-memory",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"description": "HyperMem memory plugin for OpenClaw \u2014 bridges HyperMem retrieval into the memory slot",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"typecheck": "tsc --noEmit"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@psiclawops/hypermem": "0.9.
|
|
43
|
+
"@psiclawops/hypermem": "0.9.5"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"openclaw": "*",
|