@psiclawops/hypermem 0.8.0 → 0.8.2
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/ARCHITECTURE.md +1 -1
- package/CHANGELOG.md +101 -0
- package/INSTALL.md +800 -0
- package/README.md +131 -31
- package/bin/hypermem-status.mjs +11 -1
- package/dist/background-indexer.js +9 -9
- package/dist/cross-agent.d.ts +1 -1
- package/dist/cross-agent.js +17 -17
- package/dist/dreaming-promoter.d.ts +1 -1
- package/dist/dreaming-promoter.js +2 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +5 -5
- package/dist/open-domain.js +1 -1
- 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/temporal-store.js +2 -2
- package/dist/topic-store.js +5 -5
- package/dist/topic-synthesizer.js +1 -1
- package/dist/trigger-registry.d.ts +1 -1
- package/dist/trigger-registry.js +4 -4
- package/dist/types.d.ts +2 -2
- package/dist/version.d.ts +4 -4
- package/dist/version.js +4 -4
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -32,6 +32,8 @@ The difference isn't intelligence. It's what was in the prompt. Two failure mode
|
|
|
32
32
|
|
|
33
33
|
**Compaction crunch.** Long sessions fill the context window. The runtime summarizes to make room. Specifics (tool output, exact decisions, file paths) are lost in the summary. The agent keeps running, but degraded.
|
|
34
34
|
|
|
35
|
+
**Bloated context.** 128k tokens doesn't mean 128k of useful prompt. Without active curation, agents fill the window with stale history, redundant instructions, and memory that isn't relevant to this turn. A bigger context window just means more room to waste. The information is in the prompt somewhere, buried under content irrelevant to this turn.
|
|
36
|
+
|
|
35
37
|
---
|
|
36
38
|
|
|
37
39
|
## What OpenClaw provides today
|
|
@@ -104,10 +106,10 @@ What's in storage, not in this prompt:
|
|
|
104
106
|
Change the topic, and the next turn pulls different content from the same storage.
|
|
105
107
|
```
|
|
106
108
|
|
|
107
|
-
###
|
|
109
|
+
### OpenClaw default vs. hypercompositor
|
|
108
110
|
|
|
109
111
|
```
|
|
110
|
-
|
|
112
|
+
OpenClaw default hypercompositor
|
|
111
113
|
──────────────────────────────── ────────────────────────────────
|
|
112
114
|
message → append to transcript message → detect active topic
|
|
113
115
|
transcript full → trim oldest query 4 storage layers in parallel
|
|
@@ -125,7 +127,7 @@ When it fills: When budget is exceeded:
|
|
|
125
127
|
no recovery path change topic back → retrieved again
|
|
126
128
|
```
|
|
127
129
|
|
|
128
|
-
| |
|
|
130
|
+
| | OpenClaw default | hypercompositor |
|
|
129
131
|
|---|---|---|
|
|
130
132
|
| Context source | Growing transcript only | Transcript + 3 additional storage layers |
|
|
131
133
|
| When context fills | Trim + summarize (lossy) | Budget allocation (lossless storage) |
|
|
@@ -164,9 +166,9 @@ Different models have different default behaviors. GPT-5.4 tends toward 2x verbo
|
|
|
164
166
|
|
|
165
167
|
Adaptation entries are stored in the `model_output_directives` table and matched by model ID using exact match, then glob pattern (longest wins), then wildcard fallback. Each entry contains:
|
|
166
168
|
|
|
167
|
-
- **Calibration
|
|
168
|
-
- **Corrections
|
|
169
|
-
- **Task overrides
|
|
169
|
+
- **Calibration:** known model tendencies and specific adjustments (e.g., "2x verbosity: cut first drafts in half")
|
|
170
|
+
- **Corrections:** hard/medium/soft severity rules applied in order (e.g., "No preamble before the answer")
|
|
171
|
+
- **Task overrides:** per-task-type adjustments
|
|
170
172
|
|
|
171
173
|
Model adaptation is only active at the `full` tier. At `light` and `standard`, model-specific corrections are suppressed.
|
|
172
174
|
|
|
@@ -196,7 +198,7 @@ Would you like me to go deeper on any of these?
|
|
|
196
198
|
WITH outputProfile: "light":
|
|
197
199
|
For a 128k window: reserve 14k for identity/system, target 46k for history, 10k for recent
|
|
198
200
|
tool context, and leave ~30k as allocator reserve. hypermem handles slot competition
|
|
199
|
-
automatically
|
|
201
|
+
automatically. Set `reserveFraction` to your preferred floor and let the compositor fill.
|
|
200
202
|
```
|
|
201
203
|
|
|
202
204
|
**Confabulation resistance** checks output against stored facts before claims are recorded. No LLM call. Pattern matching against the fact corpus, with confidence scoring and contradiction detection. Unsupported claims are flagged, contradictions surface in diagnostics, and a confabulation risk score is attached to the stored episode.
|
|
@@ -241,16 +243,7 @@ SQL queries that interpolate datetime values are fully parameterized. FTS5 trigg
|
|
|
241
243
|
|
|
242
244
|
## Pressure management
|
|
243
245
|
|
|
244
|
-
hypermem
|
|
245
|
-
|
|
246
|
-
| Path | Trigger | Action |
|
|
247
|
-
|---|---|---|
|
|
248
|
-
| **Pressure-tiered tool-loop trim** | Any tool-loop turn | Measures projected occupancy before results land; trims large results at 80%+ and truncates the messages[] array for the current turn |
|
|
249
|
-
| **AfterTurn trim** | Every turn at >80% | Pre-emptive headroom cut after the assistant replies, before the next turn arrives |
|
|
250
|
-
| **Deep compaction** | compact() at >85% | Cuts in-memory cache to 25% budget and truncates JSONL to ~20% depth. Bypasses the normal reshape guard |
|
|
251
|
-
| **Reshape guard** | Structured tool history on downshift | `canPersistReshapedHistory()` blocks a lower-context snapshot from overwriting the full JSONL history |
|
|
252
|
-
|
|
253
|
-
**The one thing these paths cannot fix:** a session whose JSONL transcript on disk is already at 98% when the gateway restarts. The JSONL loads into runtime context before any compaction runs. Check `session_status` on startup. If you're above 85%, start a fresh session.
|
|
246
|
+
hypermem manages context pressure automatically through four escalating paths. Most sessions never need manual intervention. For trigger thresholds and path details, see [Pressure management](#pressure-management-1) below.
|
|
254
247
|
|
|
255
248
|
---
|
|
256
249
|
|
|
@@ -332,7 +325,7 @@ FTS5 queries use compound indexes on `agentId + sort key` and prefix optimizatio
|
|
|
332
325
|
| Knowledge | Domain/key/value structured data with full-text search |
|
|
333
326
|
| Episodes | Significant events with impact scores and participant tracking |
|
|
334
327
|
| Topics | Cross-session thread tracking and synthesized wiki pages |
|
|
335
|
-
| Preferences |
|
|
328
|
+
| Preferences | Operator behavioral patterns |
|
|
336
329
|
| Fleet Registry | Agent registry with tier, org, and capability metadata |
|
|
337
330
|
| System Registry | Service state and lifecycle |
|
|
338
331
|
| Work Items | Work queue with status transitions and FTS5 |
|
|
@@ -383,7 +376,7 @@ Slot-level budget allocation is shown in the [hypercompositor diagram](#what-the
|
|
|
383
376
|
|
|
384
377
|
## Requirements
|
|
385
378
|
|
|
386
|
-
**Current release: hypermem 0.8.
|
|
379
|
+
**Current release: hypermem 0.8.1.** Changelog: [CHANGELOG.md](./CHANGELOG.md)
|
|
387
380
|
|
|
388
381
|
| Requirement | Version | Notes |
|
|
389
382
|
|---|---|---|
|
|
@@ -396,7 +389,7 @@ SQLite is a library, not a service. All four layers run in-process with no exter
|
|
|
396
389
|
**Runtime version constants** (importable from the package):
|
|
397
390
|
```typescript
|
|
398
391
|
import {
|
|
399
|
-
ENGINE_VERSION, // '0.8.
|
|
392
|
+
ENGINE_VERSION, // '0.8.1'
|
|
400
393
|
MIN_NODE_VERSION, // '22.0.0'
|
|
401
394
|
SQLITE_VEC_VERSION, // '0.1.9'
|
|
402
395
|
MAIN_SCHEMA_VERSION, // 10 (messages.db)
|
|
@@ -410,29 +403,95 @@ Schema versions are stamped into each database on startup and checked on open. A
|
|
|
410
403
|
|
|
411
404
|
## Installation
|
|
412
405
|
|
|
406
|
+
**Requirements:** Node.js 22+, OpenClaw with context engine plugin support. No standalone SQLite install needed (uses Node 22 built-in `node:sqlite`). Embedding provider is optional for first install.
|
|
407
|
+
|
|
408
|
+
hypermem works two ways:
|
|
409
|
+
- **As a library** — import directly into your own Node.js code. No OpenClaw required.
|
|
410
|
+
- **As an OpenClaw plugin** — replaces the default context engine. Requires a running OpenClaw gateway.
|
|
411
|
+
|
|
412
|
+
### Library usage (no OpenClaw required)
|
|
413
|
+
|
|
413
414
|
```bash
|
|
414
|
-
|
|
415
|
-
|
|
415
|
+
npm install @psiclawops/hypermem
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
import { HyperMem } from '@psiclawops/hypermem';
|
|
420
|
+
import { join } from 'node:path';
|
|
421
|
+
import { homedir } from 'node:os';
|
|
422
|
+
|
|
423
|
+
const hm = await HyperMem.create({
|
|
424
|
+
dataDir: join(homedir(), '.openclaw', 'hypermem'),
|
|
425
|
+
embedding: { provider: 'none' },
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
await hm.recordUserMessage('my-agent', 'session-1', 'Hello');
|
|
429
|
+
const composed = await hm.compose({
|
|
430
|
+
agentId: 'my-agent',
|
|
431
|
+
sessionKey: 'session-1',
|
|
432
|
+
prompt: 'Hello',
|
|
433
|
+
tokenBudget: 4000,
|
|
434
|
+
provider: 'anthropic',
|
|
435
|
+
});
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
That's it. No gateway, no plugins, no config files. See [API](#api) for the full interface.
|
|
439
|
+
|
|
440
|
+
### OpenClaw plugin install (from source)
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
git clone https://github.com/PsiClawOps/hypermem.git
|
|
444
|
+
cd hypermem
|
|
416
445
|
npm install && npm run build
|
|
417
446
|
npm --prefix plugin install && npm --prefix plugin run build
|
|
418
447
|
npm --prefix memory-plugin install && npm --prefix memory-plugin run build
|
|
448
|
+
npm run install:runtime
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
`install:runtime` stages the runtime payload into `~/.openclaw/plugins/hypermem` and prints the exact config commands to wire the plugins. Before running them, create the data directory and config:
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
mkdir -p ~/.openclaw/hypermem
|
|
455
|
+
cat > ~/.openclaw/hypermem/config.json <<'JSON'
|
|
456
|
+
{
|
|
457
|
+
"embedding": {
|
|
458
|
+
"provider": "none"
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
JSON
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
This sets lightweight mode (FTS5 keyword search, no embedding provider needed). Add an embedding provider later for semantic search without losing stored data. See [INSTALL.md](./INSTALL.md#embedding-providers) for options.
|
|
465
|
+
|
|
466
|
+
Wire the plugins into OpenClaw:
|
|
419
467
|
|
|
468
|
+
```bash
|
|
469
|
+
openclaw config set plugins.load.paths "[\"$HOME/.openclaw/plugins/hypermem/plugin\",\"$HOME/.openclaw/plugins/hypermem/memory-plugin\"]" --strict-json
|
|
420
470
|
openclaw config set plugins.slots.contextEngine hypercompositor
|
|
421
471
|
openclaw config set plugins.slots.memory hypermem
|
|
422
|
-
openclaw config set plugins.load.paths '["~/.openclaw/workspace/repo/hypermem/plugin","~/.openclaw/workspace/repo/hypermem/memory-plugin"]' --strict-json
|
|
423
472
|
openclaw config set plugins.allow '["hypercompositor","hypermem"]' --strict-json
|
|
424
473
|
openclaw gateway restart
|
|
425
474
|
```
|
|
426
475
|
|
|
427
|
-
|
|
476
|
+
Verify (run from the repo clone directory):
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
openclaw plugins list # hypercompositor and hypermem should show as loaded
|
|
480
|
+
node bin/hypermem-status.mjs --health # confirms database initialization
|
|
481
|
+
openclaw logs --limit 50 | grep hypermem # should show "hypermem initialized"
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
If you see `falling back to default engine "legacy"` in the logs, the install is not active. Check [INSTALL.md troubleshooting](./INSTALL.md#troubleshooting-clean-installs).
|
|
485
|
+
|
|
486
|
+
### One-line installer
|
|
428
487
|
|
|
429
488
|
```bash
|
|
430
489
|
curl -fsSL https://raw.githubusercontent.com/PsiClawOps/hypermem/main/install.sh | bash
|
|
431
490
|
```
|
|
432
491
|
|
|
433
|
-
|
|
492
|
+
Interactive: detects hardware, selects embedding tier, writes config, registers plugins.
|
|
434
493
|
|
|
435
|
-
Full guide with
|
|
494
|
+
Full guide with embedding tiers, reranker setup, fleet config, and tuning: **[INSTALL.md](./INSTALL.md)**
|
|
436
495
|
|
|
437
496
|
### Agent-assisted install
|
|
438
497
|
|
|
@@ -440,7 +499,7 @@ If you prefer, hand the install to your OpenClaw agent:
|
|
|
440
499
|
|
|
441
500
|
> "Install hypermem following INSTALL.md. I'm running a [solo / multi-agent] setup."
|
|
442
501
|
|
|
443
|
-
###
|
|
502
|
+
### Operator guides
|
|
444
503
|
|
|
445
504
|
- **[docs/MEMORY_MD_AUTHORING.md](./docs/MEMORY_MD_AUTHORING.md)**, how to keep `MEMORY.md` compact, durable, and reviewable
|
|
446
505
|
- **[docs/TUNING.md](./docs/TUNING.md)**, context assembly and output shaping profiles
|
|
@@ -448,7 +507,7 @@ If you prefer, hand the install to your OpenClaw agent:
|
|
|
448
507
|
|
|
449
508
|
### Tuning
|
|
450
509
|
|
|
451
|
-
Two independent surfaces: **context assembly** (what fills the context window) and **output shaping** (how the model writes). Pick a profile first
|
|
510
|
+
Two independent surfaces: **context assembly** (what fills the context window) and **output shaping** (how the model writes). Pick a profile first. Most deployments adjust one or two settings on top.
|
|
452
511
|
|
|
453
512
|
| Profile | Target window | Best for |
|
|
454
513
|
|---|---|---|
|
|
@@ -499,13 +558,15 @@ Full reference: **[docs/TUNING.md](./docs/TUNING.md)**
|
|
|
499
558
|
|
|
500
559
|
## API
|
|
501
560
|
|
|
502
|
-
> **Note:** The examples below use placeholder agent names (`my-agent`, `
|
|
561
|
+
> **Note:** The examples below use placeholder agent names (`my-agent`, `agent1`, etc.). Replace these with your actual agent IDs from your OpenClaw config. Single-agent installs typically use `main`. Multi-agent fleets use whatever IDs you've configured. See [INSTALL.md § "Configure your fleet"](./INSTALL.md#step-5--configure-your-fleet-multi-agent-only) for details.
|
|
503
562
|
|
|
504
563
|
```typescript
|
|
505
564
|
import { HyperMem } from '@psiclawops/hypermem';
|
|
565
|
+
import { join } from 'node:path';
|
|
566
|
+
import { homedir } from 'node:os';
|
|
506
567
|
|
|
507
568
|
const hm = await HyperMem.create({
|
|
508
|
-
dataDir: '
|
|
569
|
+
dataDir: join(homedir(), '.openclaw', 'hypermem'),
|
|
509
570
|
cache: { maxEntries: 10000 },
|
|
510
571
|
// Local (Ollama):
|
|
511
572
|
embedding: { ollamaUrl: 'http://localhost:11434', model: 'nomic-embed-text' },
|
|
@@ -554,6 +615,29 @@ node bin/hypermem-status.mjs --json # machine-readable output
|
|
|
554
615
|
node bin/hypermem-status.mjs --health # health checks only (exit 1 on failure)
|
|
555
616
|
```
|
|
556
617
|
|
|
618
|
+
By default, `hypermem-status` looks for data in `~/.openclaw/hypermem`. If your data directory is elsewhere (e.g. testing in an isolated environment), set:
|
|
619
|
+
|
|
620
|
+
```bash
|
|
621
|
+
HYPERMEM_DATA_DIR=/path/to/data node bin/hypermem-status.mjs --health
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
> **Fresh install note:** If no agent has run a session yet, `--health` will report "no sessions ingested" rather than a database error. This is expected. Send a test message to any agent, then re-run the health check.
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
## Pressure management
|
|
629
|
+
|
|
630
|
+
hypermem composes context fresh on every turn, but a long-running session still accumulates history in its JSONL transcript. When that grows large enough, incoming tool results have nowhere to land and get silently stripped. Four automatic paths handle this:
|
|
631
|
+
|
|
632
|
+
| Path | Trigger | Action |
|
|
633
|
+
|---|---|---|
|
|
634
|
+
| **Pressure-tiered tool-loop trim** | Any tool-loop turn | Measures projected occupancy before results land; trims large results at 80%+ and truncates the messages[] array for the current turn |
|
|
635
|
+
| **AfterTurn trim** | Every turn at >80% | Pre-emptive headroom cut after the assistant replies, before the next turn arrives |
|
|
636
|
+
| **Deep compaction** | compact() at >85% | Cuts in-memory cache to 25% budget and truncates JSONL to ~20% depth. Bypasses the normal reshape guard |
|
|
637
|
+
| **Reshape guard** | Structured tool history on downshift | `canPersistReshapedHistory()` blocks a lower-context snapshot from overwriting the full JSONL history |
|
|
638
|
+
|
|
639
|
+
**The one thing these paths cannot fix:** a session whose JSONL transcript on disk is already at 98% when the gateway restarts. The JSONL loads into runtime context before any compaction runs. Check `session_status` on startup. If you're above 85%, start a fresh session.
|
|
640
|
+
|
|
557
641
|
---
|
|
558
642
|
|
|
559
643
|
## Data directory
|
|
@@ -570,6 +654,22 @@ node bin/hypermem-status.mjs --health # health checks only (exit 1 on fai
|
|
|
570
654
|
|
|
571
655
|
---
|
|
572
656
|
|
|
657
|
+
## Common issues
|
|
658
|
+
|
|
659
|
+
| Symptom | Cause | Fix |
|
|
660
|
+
|---|---|---|
|
|
661
|
+
| `falling back to default engine "legacy"` in logs | Plugin not loaded or slot misconfigured | Check `openclaw config get plugins.slots.contextEngine` is `hypercompositor`, paths are correct, and both plugins are in `plugins.allow` |
|
|
662
|
+
| `openclaw gateway restart` says disabled/not configured | OpenClaw not fully onboarded | Complete OpenClaw setup first. `gateway restart` requires a running gateway. |
|
|
663
|
+
| `openclaw logs` fails with auth/token error | Gateway auth not set up for CLI | Run `openclaw gateway status` to confirm the gateway is accessible |
|
|
664
|
+
| `facts=0 semantic=0` every turn | Fresh install, no data yet | Expected. Facts accumulate over real conversations. |
|
|
665
|
+
| Health check says "no sessions ingested" | No agent has run a session yet | Send a test message, then re-run |
|
|
666
|
+
| JS code creates `./~/.openclaw/` directory | Used literal `~` in JS instead of `homedir()` | Use `join(homedir(), '.openclaw', 'hypermem')` from `node:path` and `node:os` |
|
|
667
|
+
| `INSTALL.md` not found in npm package | Older published version | Update to latest or read INSTALL.md on [GitHub](https://github.com/PsiClawOps/hypermem/blob/main/INSTALL.md) |
|
|
668
|
+
|
|
669
|
+
Full troubleshooting: **[INSTALL.md § Troubleshooting](./INSTALL.md#troubleshooting)**
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
573
673
|
## Migration
|
|
574
674
|
|
|
575
675
|
hypermem doesn't touch your existing memory data. Install it, switch the context engine, and migrate historical data on your own timeline.
|
|
@@ -578,7 +678,7 @@ The migration guide includes worked examples showing how to bring data from Open
|
|
|
578
678
|
|
|
579
679
|
All examples default to dry-run. Nothing is written until you add `--apply`.
|
|
580
680
|
|
|
581
|
-
|
|
681
|
+
Operator guide: **[docs/MIGRATION_GUIDE.md](./docs/MIGRATION_GUIDE.md)**
|
|
582
682
|
|
|
583
683
|
|
|
584
684
|
---
|
package/bin/hypermem-status.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
6
|
* node bin/hypermem-status.mjs # full dashboard
|
|
7
|
-
* node bin/hypermem-status.mjs --agent
|
|
7
|
+
* node bin/hypermem-status.mjs --agent forge # scoped to one agent
|
|
8
8
|
* node bin/hypermem-status.mjs --json # machine-readable output
|
|
9
9
|
* node bin/hypermem-status.mjs --health # health checks only (exit 1 on failure)
|
|
10
10
|
*
|
|
@@ -104,6 +104,16 @@ if (flags.agent) {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
if (!mainDbPath || !existsSync(mainDbPath)) {
|
|
107
|
+
if (args.includes('--health') || args.includes('--json')) {
|
|
108
|
+
const result = { status: 'no_sessions', message: 'Installed but no agent sessions ingested yet. Send a message to any agent, then re-run.' };
|
|
109
|
+
if (args.includes('--json')) {
|
|
110
|
+
console.log(JSON.stringify(result, null, 2));
|
|
111
|
+
} else {
|
|
112
|
+
console.log('Status: installed, no sessions ingested yet.');
|
|
113
|
+
console.log('Send a message to any agent, then re-run this health check.');
|
|
114
|
+
}
|
|
115
|
+
process.exit(0);
|
|
116
|
+
}
|
|
107
117
|
console.error('Error: no agent messages.db found. Has HyperMem ingested any sessions?');
|
|
108
118
|
process.exit(1);
|
|
109
119
|
}
|
|
@@ -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 (agent1, 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
|
+
agent1: 'infrastructure',
|
|
48
48
|
director2: 'infrastructure',
|
|
49
49
|
director1: 'infrastructure',
|
|
50
50
|
director3: 'infrastructure',
|
|
51
|
-
|
|
51
|
+
agent2: 'product',
|
|
52
52
|
director4: 'product',
|
|
53
53
|
director5: 'product',
|
|
54
54
|
director6: 'product',
|
|
55
|
-
|
|
55
|
+
agent3: 'security',
|
|
56
56
|
director7: 'security',
|
|
57
57
|
director8: 'security',
|
|
58
58
|
agent4: 'ux',
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
agent6: 'governance',
|
|
60
|
+
agent5: '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) (?:wants|prefers|likes|hates|dislikes) (.{10,150})/gi,
|
|
97
|
+
/(?:operator|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+(agent6|agent2|agent4|agent3|agent5|agent1)/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|ClawDash|ClawCanvas|ClawCouncil|ClawTomation|OpenClaw|ClawDispatch)\b/i);
|
|
397
397
|
if (productMatch)
|
|
398
398
|
return productMatch[1];
|
|
399
399
|
// Infrastructure topic detection
|
package/dist/cross-agent.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export interface OrgRegistry {
|
|
|
27
27
|
* Default fleet org structure.
|
|
28
28
|
*
|
|
29
29
|
* ── EXAMPLE DATA ──────────────────────────────────────────────────────────
|
|
30
|
-
* The agent names below (
|
|
30
|
+
* The agent names below (agent1, agent2, director1, etc.) are PLACEHOLDERS.
|
|
31
31
|
* Replace them with your own agent IDs to match your fleet configuration.
|
|
32
32
|
*
|
|
33
33
|
* Single-agent installs: you don't need to edit this. Your agent ID is
|
package/dist/cross-agent.js
CHANGED
|
@@ -21,7 +21,7 @@ import { FleetStore } from './fleet-store.js';
|
|
|
21
21
|
* Default fleet org structure.
|
|
22
22
|
*
|
|
23
23
|
* ── EXAMPLE DATA ──────────────────────────────────────────────────────────
|
|
24
|
-
* The agent names below (
|
|
24
|
+
* The agent names below (agent1, agent2, director1, etc.) are PLACEHOLDERS.
|
|
25
25
|
* Replace them with your own agent IDs to match your fleet configuration.
|
|
26
26
|
*
|
|
27
27
|
* Single-agent installs: you don't need to edit this. Your agent ID is
|
|
@@ -34,27 +34,27 @@ import { FleetStore } from './fleet-store.js';
|
|
|
34
34
|
*/
|
|
35
35
|
export function defaultOrgRegistry() {
|
|
36
36
|
const agents = {
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
agent1: { agentId: 'agent1', tier: 'council' },
|
|
38
|
+
agent2: { agentId: 'agent2', tier: 'council' },
|
|
39
39
|
agent4: { agentId: 'agent4', tier: 'council' },
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
director1: { agentId: 'director1', tier: 'director', org: '
|
|
44
|
-
director2: { agentId: 'director2', tier: 'director', org: '
|
|
45
|
-
director3: { agentId: 'director3', tier: 'director', org: '
|
|
46
|
-
director4: { agentId: 'director4', tier: 'director', org: '
|
|
47
|
-
director5: { agentId: 'director5', tier: 'director', org: '
|
|
48
|
-
director6: { agentId: 'director6', tier: 'director', org: '
|
|
49
|
-
director7: { agentId: 'director7', tier: 'director', org: '
|
|
50
|
-
director8: { agentId: 'director8', tier: 'director', org: '
|
|
40
|
+
agent3: { agentId: 'agent3', tier: 'council' },
|
|
41
|
+
agent6: { agentId: 'agent6', tier: 'council' },
|
|
42
|
+
agent5: { agentId: 'agent5', tier: 'council' },
|
|
43
|
+
director1: { agentId: 'director1', tier: 'director', org: 'agent1-org', councilLead: 'agent1' },
|
|
44
|
+
director2: { agentId: 'director2', tier: 'director', org: 'agent1-org', councilLead: 'agent1' },
|
|
45
|
+
director3: { agentId: 'director3', tier: 'director', org: 'agent1-org', councilLead: 'agent1' },
|
|
46
|
+
director4: { agentId: 'director4', tier: 'director', org: 'agent2-org', councilLead: 'agent2' },
|
|
47
|
+
director5: { agentId: 'director5', tier: 'director', org: 'agent2-org', councilLead: 'agent2' },
|
|
48
|
+
director6: { agentId: 'director6', tier: 'director', org: 'agent2-org', councilLead: 'agent2' },
|
|
49
|
+
director7: { agentId: 'director7', tier: 'director', org: 'agent3-org', councilLead: 'agent3' },
|
|
50
|
+
director8: { agentId: 'director8', tier: 'director', org: 'agent3-org', councilLead: 'agent3' },
|
|
51
51
|
specialist1: { agentId: 'specialist1', tier: 'specialist' },
|
|
52
52
|
specialist2: { agentId: 'specialist2', tier: 'specialist' },
|
|
53
53
|
};
|
|
54
54
|
const orgs = {
|
|
55
|
-
'
|
|
56
|
-
'
|
|
57
|
-
'
|
|
55
|
+
'agent1-org': ['agent1', 'director1', 'director2', 'director3'],
|
|
56
|
+
'agent2-org': ['agent2', 'director4', 'director5', 'director6'],
|
|
57
|
+
'agent3-org': ['agent3', 'director7', 'director8'],
|
|
58
58
|
};
|
|
59
59
|
return { orgs, agents };
|
|
60
60
|
}
|
|
@@ -67,7 +67,7 @@ export interface DreamerResult {
|
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
69
|
* Resolve the workspace directory for an agent.
|
|
70
|
-
* Council agents live at ~/.openclaw/workspace/{agentId}/
|
|
70
|
+
* Council agents live at ~/.openclaw/workspace-council/{agentId}/
|
|
71
71
|
* Other agents at ~/.openclaw/workspace/{agentId}/
|
|
72
72
|
*/
|
|
73
73
|
export declare function resolveAgentWorkspacePath(agentId: string): Promise<string | null>;
|
|
@@ -31,12 +31,12 @@ export const DEFAULT_DREAMER_CONFIG = {
|
|
|
31
31
|
// ─── Workspace path resolution ───────────────────────────────────────────────
|
|
32
32
|
/**
|
|
33
33
|
* Resolve the workspace directory for an agent.
|
|
34
|
-
* Council agents live at ~/.openclaw/workspace/{agentId}/
|
|
34
|
+
* Council agents live at ~/.openclaw/workspace-council/{agentId}/
|
|
35
35
|
* Other agents at ~/.openclaw/workspace/{agentId}/
|
|
36
36
|
*/
|
|
37
37
|
export async function resolveAgentWorkspacePath(agentId) {
|
|
38
38
|
const home = os.homedir();
|
|
39
|
-
const councilPath = path.join(home, '.openclaw', 'workspace', agentId);
|
|
39
|
+
const councilPath = path.join(home, '.openclaw', 'workspace-council', agentId);
|
|
40
40
|
const workspacePath = path.join(home, '.openclaw', 'workspace', agentId);
|
|
41
41
|
try {
|
|
42
42
|
await fs.access(councilPath);
|
package/dist/index.d.ts
CHANGED
|
@@ -126,8 +126,8 @@ export interface StartupFleetSeedResult {
|
|
|
126
126
|
*
|
|
127
127
|
* Usage:
|
|
128
128
|
* const hm = await hypermem.create({ dataDir: '~/.openclaw/hypermem' });
|
|
129
|
-
* await hm.record('
|
|
130
|
-
* const result = await hm.compose({ agentId: '
|
|
129
|
+
* await hm.record('agent1', 'agent:agent1:webchat:main', userMsg);
|
|
130
|
+
* const result = await hm.compose({ agentId: 'agent1', sessionKey: '...', ... });
|
|
131
131
|
*/
|
|
132
132
|
export declare class HyperMem {
|
|
133
133
|
readonly dbManager: DatabaseManager;
|
|
@@ -185,7 +185,7 @@ export declare class HyperMem {
|
|
|
185
185
|
/**
|
|
186
186
|
* List archived or forked contexts for an agent.
|
|
187
187
|
*
|
|
188
|
-
*
|
|
188
|
+
* Operator-safe enumeration path. This is the approved archived-context
|
|
189
189
|
* listing surface. Active composition remains separate.
|
|
190
190
|
*/
|
|
191
191
|
listArchivedContexts(agentId: string, opts?: {
|
package/dist/index.js
CHANGED
|
@@ -97,7 +97,7 @@ const DEFAULT_CONFIG = {
|
|
|
97
97
|
cache: {
|
|
98
98
|
keyPrefix: 'hm:',
|
|
99
99
|
sessionTTL: 14400, // 4 hours — system/identity/meta slots
|
|
100
|
-
historyTTL: 604800, // 7 days — extended for
|
|
100
|
+
historyTTL: 604800, // 7 days — extended for ClawCanvas display
|
|
101
101
|
},
|
|
102
102
|
compositor: {
|
|
103
103
|
// TUNE-010 (2026-04-02): Raised from 65000 → 90000.
|
|
@@ -217,7 +217,7 @@ function mergeStartupCandidate(target, partial) {
|
|
|
217
217
|
function discoverStartupFleetCandidates(dbManager, opts = {}) {
|
|
218
218
|
const homeDir = process.env.HOME || os.homedir();
|
|
219
219
|
const workspaceRoots = opts.workspaceRoots ?? [
|
|
220
|
-
path.join(homeDir, '.openclaw', 'workspace'),
|
|
220
|
+
path.join(homeDir, '.openclaw', 'workspace-council'),
|
|
221
221
|
path.join(homeDir, '.openclaw', 'workspace'),
|
|
222
222
|
];
|
|
223
223
|
const candidates = new Map();
|
|
@@ -331,8 +331,8 @@ function discoverStartupFleetCandidates(dbManager, opts = {}) {
|
|
|
331
331
|
*
|
|
332
332
|
* Usage:
|
|
333
333
|
* const hm = await hypermem.create({ dataDir: '~/.openclaw/hypermem' });
|
|
334
|
-
* await hm.record('
|
|
335
|
-
* const result = await hm.compose({ agentId: '
|
|
334
|
+
* await hm.record('agent1', 'agent:agent1:webchat:main', userMsg);
|
|
335
|
+
* const result = await hm.compose({ agentId: 'agent1', sessionKey: '...', ... });
|
|
336
336
|
*/
|
|
337
337
|
export class HyperMem {
|
|
338
338
|
dbManager;
|
|
@@ -531,7 +531,7 @@ export class HyperMem {
|
|
|
531
531
|
/**
|
|
532
532
|
* List archived or forked contexts for an agent.
|
|
533
533
|
*
|
|
534
|
-
*
|
|
534
|
+
* Operator-safe enumeration path. This is the approved archived-context
|
|
535
535
|
* listing surface. Active composition remains separate.
|
|
536
536
|
*/
|
|
537
537
|
listArchivedContexts(agentId, opts) {
|
package/dist/open-domain.js
CHANGED
package/dist/seed.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
8
|
* const seeder = new WorkspaceSeeder(hypermem);
|
|
9
|
-
* const result = await seeder.seedWorkspace('/path/to/workspace', { agentId: '
|
|
9
|
+
* const result = await seeder.seedWorkspace('/path/to/workspace', { agentId: 'agent1' });
|
|
10
10
|
*
|
|
11
11
|
* Idempotent: skips files whose source hash hasn't changed since last index.
|
|
12
12
|
* Atomic: each file's chunks are swapped in a single transaction.
|
package/dist/seed.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
8
|
* const seeder = new WorkspaceSeeder(hypermem);
|
|
9
|
-
* const result = await seeder.seedWorkspace('/path/to/workspace', { agentId: '
|
|
9
|
+
* const result = await seeder.seedWorkspace('/path/to/workspace', { agentId: 'agent1' });
|
|
10
10
|
*
|
|
11
11
|
* Idempotent: skips files whose source hash hasn't changed since last index.
|
|
12
12
|
* Atomic: each file's chunks are swapped in a single transaction.
|
|
@@ -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. "
|
|
37
|
-
* @param sessionKey Full session key (e.g. "agent:
|
|
36
|
+
* @param agentId Agent identifier (e.g. "agent1")
|
|
37
|
+
* @param sessionKey Full session key (e.g. "agent:agent1: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>;
|
package/dist/session-flusher.js
CHANGED
|
@@ -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. "
|
|
22
|
-
* @param sessionKey Full session key (e.g. "agent:
|
|
21
|
+
* @param agentId Agent identifier (e.g. "agent1")
|
|
22
|
+
* @param sessionKey Full session key (e.g. "agent:agent1:webchat:scratchpad")
|
|
23
23
|
* @param opts Optional flags
|
|
24
24
|
*/
|
|
25
25
|
export async function flushSession(cache, agentId, sessionKey, opts = {}) {
|
package/dist/spawn-context.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
8
|
* const ctx = await buildSpawnContext(messageStore, docChunkStore, agentId, {
|
|
9
|
-
* parentSessionKey: 'agent:
|
|
9
|
+
* parentSessionKey: 'agent:agent1:webchat:main',
|
|
10
10
|
* workingSnapshot: 10,
|
|
11
11
|
* documents: ['/path/to/spec.md'],
|
|
12
12
|
* });
|
package/dist/spawn-context.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
8
|
* const ctx = await buildSpawnContext(messageStore, docChunkStore, agentId, {
|
|
9
|
-
* parentSessionKey: 'agent:
|
|
9
|
+
* parentSessionKey: 'agent:agent1:webchat:main',
|
|
10
10
|
* workingSnapshot: 10,
|
|
11
11
|
* documents: ['/path/to/spec.md'],
|
|
12
12
|
* });
|
package/dist/temporal-store.js
CHANGED
|
@@ -59,11 +59,11 @@ export class TemporalStore {
|
|
|
59
59
|
const limit = opts.limit ?? 20;
|
|
60
60
|
const order = opts.order ?? 'DESC';
|
|
61
61
|
const minConf = opts.minConfidence ?? 0;
|
|
62
|
-
const params = [];
|
|
62
|
+
const params = [minConf];
|
|
63
63
|
const conditions = [
|
|
64
64
|
'f.superseded_by IS NULL',
|
|
65
65
|
'f.decay_score < 0.8',
|
|
66
|
-
|
|
66
|
+
't.confidence >= ?',
|
|
67
67
|
];
|
|
68
68
|
if (opts.agentId) {
|
|
69
69
|
conditions.push('t.agent_id = ?');
|
package/dist/topic-store.js
CHANGED
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
const KNOWN_NAMES = {
|
|
13
13
|
hypermem: 'HyperMem',
|
|
14
14
|
hyperbuilder: 'HyperBuilder',
|
|
15
|
-
clawcanvas: '
|
|
16
|
-
clawdash: '
|
|
17
|
-
clawdispatch: '
|
|
15
|
+
clawcanvas: 'ClawCanvas',
|
|
16
|
+
clawdash: 'ClawDash',
|
|
17
|
+
clawdispatch: 'ClawDispatch',
|
|
18
18
|
clawtext: 'ClawText',
|
|
19
|
-
clawtomation: '
|
|
20
|
-
clawcouncil: '
|
|
19
|
+
clawtomation: 'ClawTomation',
|
|
20
|
+
clawcouncil: 'ClawCouncil',
|
|
21
21
|
openclaw: 'OpenClaw',
|
|
22
22
|
clawhub: 'ClawHub',
|
|
23
23
|
};
|