cogmem 3.6.4 → 3.6.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 +12 -0
- package/README.md +29 -9
- package/RELEASE_CHECKLIST.md +6 -4
- package/dist/agent/AgentMemoryBackend.d.ts +6 -1
- package/dist/agent/AgentMemoryBackend.js +51 -1
- package/dist/agent/AgentRecallQueryCompiler.d.ts +1 -1
- package/dist/agent/AgentRecallQueryCompiler.js +12 -0
- package/dist/atlas/MemoryAtlasService.d.ts +1 -0
- package/dist/atlas/MemoryAtlasService.js +39 -5
- package/dist/atlas/MemoryAtlasTypes.d.ts +14 -0
- package/dist/bin/connect.js +85 -13
- package/dist/bin/memory.js +217 -17
- package/dist/factory.d.ts +2 -0
- package/dist/factory.js +36 -18
- package/dist/host/openclaw/AutoMemoryPluginInstaller.js +6 -2
- package/dist/mcp/server.js +1 -1
- package/dist/store/EventStore.d.ts +6 -0
- package/dist/store/EventStore.js +28 -2
- package/dist/types/index.d.ts +3 -0
- package/examples/hermes-backend/AGENTS.md +11 -5
- package/examples/hermes-backend/README.md +5 -3
- package/examples/hermes-backend/SKILL.md +24 -3
- package/examples/hermes-backend/references/operations.md +13 -5
- package/examples/openclaw-backend/AGENTS.md +8 -3
- package/examples/openclaw-backend/README.md +7 -2
- package/examples/openclaw-backend/SKILL.md +14 -6
- package/examples/openclaw-backend/references/operations.md +16 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.6.5
|
|
4
|
+
|
|
5
|
+
- Added `cogmem memory plan` as a read-only agent operations summary with queue state, blocking/non-blocking next actions, Dream backlog hints, and vector fallback state.
|
|
6
|
+
- Made default `cogmem memory candidates --json` return grouped ordinary, `needs_confirmation`, and deferred queues with actionable `nextActions`, while explicit `--status` still lists one queue.
|
|
7
|
+
- Fixed `cogmem memory list --since/--until/--order` so raw-ledger inspection can resume from global sequence cursors instead of silently ignoring the filters.
|
|
8
|
+
- Added `sourceLocator` drill-down commands to raw ledger list rows and Atlas search/explore evidence so agents can move from summaries to exact `memory show` context before quoting or claiming absence.
|
|
9
|
+
- Added a `historical_discussion` recall intent for “did we discuss this before?” questions, with raw-ledger-first routing and expanded cues for Cogmem/OpenClaw memory-black-box discussions.
|
|
10
|
+
- Changed Memory Binding backfill to scan raw events by cursor across the historical ledger rather than only the latest page, so old imported high-value user events can be bound after upgrade.
|
|
11
|
+
- Changed `cogmem connect ... --json` to expose structured `nextSteps` and keep unsafe operator/host actions such as interactive init and host restart out of agent-safe `nextCommands`.
|
|
12
|
+
- Fixed `cogmem memory plan` so Raw Ledger dream coverage lag is reported as non-blocking `raw_dream_ledger_lag` with `resolvableByDreamTick:false` instead of misleading agents into looping `dream tick` when no sealed episode backlog exists.
|
|
13
|
+
- Updated the auto-installed OpenClaw/Hermes skills and operations handbooks with the full npm install, update, migration, import, `memory plan`, historical recall, source drill-down, governance, and maintenance command playbook.
|
|
14
|
+
|
|
3
15
|
## 3.6.4
|
|
4
16
|
|
|
5
17
|
- Fixed OpenClaw/Hermes imports so empty imported episode boundaries are not batch-sealed into Dream work, and mature empty soft seals no longer abort `dream tick`.
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ It is not a knowledge-base app, a note-taking app, a vector RAG wrapper, an Obsi
|
|
|
11
11
|
|
|
12
12
|
## Status
|
|
13
13
|
|
|
14
|
-
Current version: `3.6.
|
|
14
|
+
Current version: `3.6.5`
|
|
15
15
|
|
|
16
16
|
Distribution: npm registry. GitHub remains the source mirror and hosts this installer, but package install and upgrade resolve `cogmem` from npm by default.
|
|
17
17
|
|
|
@@ -229,7 +229,7 @@ cogmem migrate --dry-run --json
|
|
|
229
229
|
|
|
230
230
|
For a manual migration, run `cogmem migrate --yes --backup`. The migration runner adopts the existing `_meta.schema_version`, applies only later idempotent migrations, preserves Raw Ledger rows, and creates a timestamped, transaction-consistent standalone database backup before changing an on-disk database. The backup includes committed SQLite WAL pages instead of copying only the main database file.
|
|
231
231
|
|
|
232
|
-
Upgrade a 3.5.2 database, a 3.6.0 database, or a pre-release schema-25 test database into the 3.6.
|
|
232
|
+
Upgrade a 3.5.2 database, a 3.6.0 database, or a pre-release schema-25 test database into the 3.6.5 schema set with one command:
|
|
233
233
|
|
|
234
234
|
```bash
|
|
235
235
|
cogmem migrate --yes --backup --json
|
|
@@ -270,7 +270,7 @@ cogmem memory candidates --project my-agent --status needs_confirmation --json
|
|
|
270
270
|
cogmem memory review --project my-agent --id <candidate-id> --action approve --actor <operator> --reason "confirmed" --confirmation-event <user-event-id> --json
|
|
271
271
|
```
|
|
272
272
|
|
|
273
|
-
For a host timer, call `dream tick`; the timer only wakes the scheduler. An empty backlog performs no Dream work
|
|
273
|
+
For a host timer, call `dream tick`; the timer only wakes the sealed-episode scheduler. An empty episode backlog performs no Dream work, and `undreamedRawCount` by itself is not a reason to loop `dream tick`:
|
|
274
274
|
|
|
275
275
|
```bash
|
|
276
276
|
cogmem dream tick --project my-agent --mode auto --max-episodes 10 --json
|
|
@@ -278,7 +278,7 @@ cogmem dream tick --project my-agent --mode auto --max-episodes 10 --json
|
|
|
278
278
|
|
|
279
279
|
Raw events are always written first. `KernelAgentMemoryBackend` and OpenClaw plugin 0.6.3 assemble live turns automatically. The foreground hook uses deterministic rules and previous assistant/user context; background import and repair paths may use the advisory hybrid classifier. Advisory output is allow-listed and cannot directly mutate durable memory. Unknown turns now fail closed as ambiguous. Continuation requires explicit continuation language or project/topic/entity/semantic overlap; Cogmem does not route domains with an expanding hard-coded keyword dictionary.
|
|
280
280
|
|
|
281
|
-
Hookless MCP agents can call `cogmem_episode_append` or bounded `cogmem_episode_import`. Existing OpenClaw/Hermes import commands use stable content identities and the same episode schema. Low-confidence imported groups soft-seal for review unless an operator explicitly forces sealing. Cogmem 3.6.4
|
|
281
|
+
Hookless MCP agents can call `cogmem_episode_append` or bounded `cogmem_episode_import`. Existing OpenClaw/Hermes import commands use stable content identities and the same episode schema. Low-confidence imported groups soft-seal for review unless an operator explicitly forces sealing. Cogmem 3.6.4 and later skip import batch sealing for empty episode boundaries and skip legacy empty Dream jobs so one bad imported episode cannot block the queue. Episode semantic summaries and closure receipts are control hints, never durable evidence; every Dream candidate must cite a non-empty subset of the episode's raw event IDs and still pass CPU governance.
|
|
282
282
|
|
|
283
283
|
User-shaped topic state is project-scoped. Explicit user operations become active and auditable; model-proposed topics, aliases, and relations remain candidates. Use MCP `cogmem_topic_list` to inspect nodes, `cogmem_topic_operate` to create, rename, alias, move, merge, split, or relate topics, and `cogmem_topic_rollback` to reverse an audited operation. Alias collisions fail closed as `needs_review`; applications can also call `TopicGovernance.rollback()` through the public API.
|
|
284
284
|
|
|
@@ -287,13 +287,17 @@ Episode surgery is available through `cogmem episode split|merge|move-event|recl
|
|
|
287
287
|
Inspect queue state:
|
|
288
288
|
|
|
289
289
|
```bash
|
|
290
|
+
cogmem memory plan --project my-agent --json
|
|
290
291
|
cogmem memory status --project my-agent --json
|
|
292
|
+
cogmem memory candidates --project my-agent --json
|
|
291
293
|
cogmem memory candidates --project my-agent --status candidate --json
|
|
292
294
|
cogmem memory govern --project my-agent --json
|
|
293
295
|
cogmem memory candidates --project my-agent --status needs_confirmation --json
|
|
294
296
|
cogmem memory review --project my-agent --id <candidate-id> --action approve --actor <operator> --reason "confirmed" --confirmation-event <user-event-id> --json
|
|
295
297
|
```
|
|
296
298
|
|
|
299
|
+
`memory plan` is the read-only agent operations summary. It returns queue counts, Dream backlog, vector fallback state, blocking actions, and safe next commands. Only run `dream_tick` when it appears in `nextActions`; `nonBlocking[].type === "raw_dream_ledger_lag"` reports Raw Ledger coverage lag with `resolvableByDreamTick: false`, so inspect sources or episode/import boundaries instead of retrying `dream tick`. Default `memory candidates --json` groups ordinary, `needs_confirmation`, and deferred work in one payload; pass `--status candidate` or `--status needs_confirmation` only when the user asks for one queue.
|
|
300
|
+
|
|
297
301
|
`memory govern` intentionally promotes only `candidate`. With `--status needs_confirmation` it lists the review queue and prints the `memory review` command instead of silently promoting the wrong status. Review actions are approve, reject, defer, supersede, and correction relink; every action stores operator identity, reason, and evidence requirements in an immutable audit row. `defer` keeps the candidate in `needs_confirmation` and records `reviewAfter` plus a status reason.
|
|
298
302
|
|
|
299
303
|
## Memory Atlas: let an agent see what it remembers
|
|
@@ -314,6 +318,8 @@ Atlas filtering is not limited to entity + time + action. The query compiler com
|
|
|
314
318
|
|
|
315
319
|
Defaults are 8 nodes, one hop, and two evidence IDs per node. Hard limits are 30 nodes, two hops, ten evidence IDs, six path hops, and 2,000 visited nodes. Raw excerpts are omitted unless `--include-evidence` or `includeEvidence: true` is explicit. `evidenceTotal` reports all known evidence while `evidenceReturned` reports the bounded payload. Every returned evidence item carries an `eventId` and a `cogmem memory show` drilldown command.
|
|
316
320
|
|
|
321
|
+
In 3.6.5, Atlas search and explore evidence also carries `sourceLocator.command` and `sourceLocator.contextCommand`. Agents should run that locator before quoting exact wording, before claiming a historical topic is absent, or when a graph summary looks relevant but underspecified.
|
|
322
|
+
|
|
317
323
|
Atlas reads do not brighten everything they display. MCP graph queries are read-only/idempotent; call `cogmem_graph_touch` only after the agent actually uses selected nodes. Maintenance decays activation, refreshes dirty projections only, and prunes old access telemetry.
|
|
318
324
|
|
|
319
325
|
Agents should use Atlas for broad inventory, history, and relationship questions; use normal recall for a direct fact. See [MEMORY_ATLAS.md](./MEMORY_ATLAS.md) for the complete CLI, MCP, OpenClaw, activation, and provenance contract.
|
|
@@ -351,7 +357,7 @@ Operational cost classes:
|
|
|
351
357
|
|
|
352
358
|
Never overlap maintenance writers against one database. Wait for each command to exit, use returned `durationMs`, backlog, and failure details to set the next interval, and keep routine status/candidate inspection on the read-only path. A `vectors` count of zero is not by itself a failure: `memory status --json` includes `vectorState.recallAvailableWithoutVectors` and the active fallback status.
|
|
353
359
|
|
|
354
|
-
`memory bind` backfills Memory Binding for raw user events written outside the agent turn path, including imported OpenClaw/Hermes history and adapter-written raw events. Use `--since <globalSeq>` to resume from a known ledger sequence.
|
|
360
|
+
`memory bind` backfills Memory Binding for raw user events written outside the agent turn path, including imported OpenClaw/Hermes history and adapter-written raw events. In 3.6.5 it scans by Raw Ledger cursor rather than only the latest page. Use `--since <globalSeq>` to resume from a known ledger sequence.
|
|
355
361
|
|
|
356
362
|
`memory map` includes Memory Binding and Graph Recall counters. Bindings attach valuable user raw events to stable topic/entity paths before any fact promotion, fuse same-claim evidence into claim-key clusters, and create graph anchors for source drill-down. Correction events create explicit correction edges and review flags instead of poisoning the active cluster. Treat bindings, clusters, and graph edges as organization hints, not as verified long-term facts.
|
|
357
363
|
|
|
@@ -374,6 +380,8 @@ cogmem strategy outcomes --project hermes --json
|
|
|
374
380
|
|
|
375
381
|
OpenClaw plugin 0.6.3 skips Cogmem entirely for greetings, uses only session state/turn bridge for short continuations, and applies Strategy Cortex before full recall. Navigation turns use one bridge/kernel lifecycle for Atlas exploration, evidence-bearing node/timeline drill-down, and recall. The bounded volatile `<COGMEM_MEMORY_ATLAS>` block includes evidence event IDs and drill-down commands; OpenClaw does not need MCP for this path.
|
|
376
382
|
|
|
383
|
+
`cogmem connect openclaw --auto --force --json` and `cogmem connect hermes --auto --force --json` now return structured `nextSteps`. Only `nextSteps` with `actor: "agent"` and `safeForAutomation: true` are mirrored into `nextCommands`. Interactive setup, gateway restart, and Hermes reload remain visible as operator/host steps but are intentionally absent from `nextCommands`.
|
|
384
|
+
|
|
377
385
|
`ProspectiveMemoryService` stores future intentions, commitments, reminders, open loops, and plans as candidates only. A candidate is not actionable until an explicit user event confirms it. Rejected candidates stay suppressed unless genuinely new evidence creates a new version. The service and `cogmem prospective` CLI manage state only; they expose no task or tool execution capability.
|
|
378
386
|
|
|
379
387
|
```bash
|
|
@@ -459,9 +467,9 @@ From the OpenClaw workspace:
|
|
|
459
467
|
|
|
460
468
|
```bash
|
|
461
469
|
cd ~/.openclaw/workspace
|
|
462
|
-
|
|
470
|
+
npm install cogmem@latest --save
|
|
471
|
+
./node_modules/.bin/cogmem connect openclaw --workspace . --auto --force
|
|
463
472
|
cogmem doctor
|
|
464
|
-
cogmem connect openclaw --workspace . --auto --force
|
|
465
473
|
```
|
|
466
474
|
|
|
467
475
|
Import existing OpenClaw memory:
|
|
@@ -500,7 +508,9 @@ By default, `selective_compile` uses user text as the durable compile signal, ex
|
|
|
500
508
|
After updates or config drift:
|
|
501
509
|
|
|
502
510
|
```bash
|
|
503
|
-
cogmem
|
|
511
|
+
cogmem update --yes
|
|
512
|
+
cogmem doctor --fix --agent openclaw --workspace . --plugin-only
|
|
513
|
+
openclaw gateway restart
|
|
504
514
|
```
|
|
505
515
|
|
|
506
516
|
## Hermes
|
|
@@ -622,6 +632,7 @@ Useful intents:
|
|
|
622
632
|
```bash
|
|
623
633
|
cogmem memory recall --query "上个会话我们聊了什么" --intent previous_session_summary --project openclaw --agent openclaw --json
|
|
624
634
|
cogmem memory recall --query "我当时关于记忆黑盒的原话是什么" --intent forensic_quote --project openclaw --agent openclaw --json
|
|
635
|
+
cogmem memory recall --query "几个月前我们是不是讨论过 Cogmem 的记忆黑盒" --intent historical_discussion --project openclaw --agent openclaw --json
|
|
625
636
|
```
|
|
626
637
|
|
|
627
638
|
Recall results include:
|
|
@@ -647,6 +658,15 @@ cogmem memory show --event <eventId> --before 2 --after 2 --json
|
|
|
647
658
|
|
|
648
659
|
Raw-ledger fallback is not limited to the latest fixed event window. When Chinese FTS cannot match a cue directly, Cogmem runs a project/workspace/thread/time-scoped ledger text fallback and prefers an original user event over an assistant retelling when both match equally. Imported OpenClaw Markdown also accepts empty `user:` / `assistant:` headers whose body follows on later lines and collapses only adjacent exact duplicate exports.
|
|
649
660
|
|
|
661
|
+
For ledger audits or resumable import/binding checks, use global sequence cursors:
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
cogmem memory list --project openclaw --since <global-seq> --order asc --json
|
|
665
|
+
cogmem memory list --project openclaw --since <global-seq> --until <global-seq> --order asc --json
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
Each listed event includes a `sourceLocator` with a `memory show` command. Use it before saying an event ID or exact source is unavailable.
|
|
669
|
+
|
|
650
670
|
## TypeScript API
|
|
651
671
|
|
|
652
672
|
```ts
|
|
@@ -770,7 +790,7 @@ npm pack --dry-run --json
|
|
|
770
790
|
npm publish --dry-run --access public
|
|
771
791
|
```
|
|
772
792
|
|
|
773
|
-
Create a GitHub Release from the matching version tag, for example `v3.6.
|
|
793
|
+
Create a GitHub Release from the matching version tag, for example `v3.6.5`. The `.github/workflows/publish.yml` workflow publishes to npm only when the release is published, not when a tag is pushed. The npm Trusted Publisher entry must match repository `liuqin164/cogmem`, workflow file `publish.yml`, and environment `npm publish`.
|
|
774
794
|
|
|
775
795
|
Publish manually only for emergency fallback:
|
|
776
796
|
|
package/RELEASE_CHECKLIST.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# cogmem 3.6.
|
|
1
|
+
# cogmem 3.6.5 Release Checklist
|
|
2
2
|
|
|
3
3
|
This release is distributed through the npm registry. GitHub remains the source and review mirror.
|
|
4
4
|
|
|
5
5
|
## Required Metadata
|
|
6
6
|
|
|
7
7
|
- `package.json` name is `cogmem`.
|
|
8
|
-
- `package.json` version is `3.6.
|
|
8
|
+
- `package.json` version is `3.6.5`.
|
|
9
9
|
- `package.json` has `publishConfig.access = public`.
|
|
10
10
|
- Public export `.` points to `dist/public.js` and `dist/public.d.ts`.
|
|
11
11
|
- Internal subpath `./internal` exists only as an explicit advanced subpath.
|
|
@@ -60,7 +60,9 @@ MCP `tools/list` includes strategy, episode append/import/status/seal/repair, to
|
|
|
60
60
|
- README and skills explain Strategy Cortex templates, no-instruction-authority lifecycle, one-retry replanning, strategy-conditioned retrieval, offline-only rollout comparison, and read-only MemoryUseJudge telemetry.
|
|
61
61
|
- README and skills explain Raw Ledger-first episode assembly, soft/hard sealing, explicit conditional Dream ticks, raw-event evidence grounding, repair/retry, and hookless Hermes MCP/import usage.
|
|
62
62
|
- README and skills give the full post-import maintenance sequence: status, episode status, Dream status, bounded Dream tick, candidate listing, govern candidate, needs-confirmation listing, explicit review, and recall verification.
|
|
63
|
-
- README and skills explain that 3.6.4 skips empty imported episode boundaries and legacy empty Dream jobs instead of letting them abort `dream tick`.
|
|
63
|
+
- README and skills explain that 3.6.4+ skips empty imported episode boundaries and legacy empty Dream jobs instead of letting them abort `dream tick`.
|
|
64
|
+
- README and skills explain the 3.6.5 agent operations protocol: `memory plan` for next actions, default grouped `memory candidates --json`, `memory list --since/--until/--order`, historical-discussion recall intent, Atlas evidence `sourceLocator`, and cursor-based `memory bind`.
|
|
65
|
+
- `connect openclaw|hermes --json` documents structured `nextSteps`; `nextCommands` must contain only agent-safe, non-interactive commands and must not include `cogmem init`, `cogmem-init`, gateway restart, or Hermes reload.
|
|
64
66
|
- README and skills document `cogmem mcp` as the preferred MCP server command for new configs while preserving `cogmem-mcp` as a compatibility bin.
|
|
65
67
|
- README and skills explain CPU foreground versus hybrid background classification, contextual short replies, registry-aware topic boundaries, safe reopen, semantic-summary non-evidence status, per-job Dream modes/failures, stable import identity, and schema migration 24.
|
|
66
68
|
- README and skills explain user-shaped topic operations, user-explicit versus model-candidate authority, alias collision review, operation rollback, and project isolation.
|
|
@@ -91,7 +93,7 @@ npm publish --dry-run --access public
|
|
|
91
93
|
|
|
92
94
|
The pack dry-run must include built public API files, CLI files, examples, docs, and `install.sh`. It must not include local databases or machine-specific files.
|
|
93
95
|
|
|
94
|
-
After verification, create a GitHub Release from the matching version tag, for example `v3.6.
|
|
96
|
+
After verification, create a GitHub Release from the matching version tag, for example `v3.6.5`. The release workflow publishes through npm Trusted Publishing when the release is published. It must not publish on tag push alone.
|
|
95
97
|
|
|
96
98
|
Emergency manual fallback:
|
|
97
99
|
|
|
@@ -61,6 +61,7 @@ export interface AgentRecallSourceAnchor {
|
|
|
61
61
|
}
|
|
62
62
|
export interface AgentRecallSourceContextEvent {
|
|
63
63
|
eventId: string;
|
|
64
|
+
globalSeq?: number;
|
|
64
65
|
label: string;
|
|
65
66
|
role?: MemoryEvent['role'];
|
|
66
67
|
rawEventType?: MemoryEvent['rawEventType'];
|
|
@@ -89,7 +90,10 @@ export interface AgentRecallSourceContext {
|
|
|
89
90
|
window: SourceContextWindowMetadata;
|
|
90
91
|
locator: {
|
|
91
92
|
eventId: string;
|
|
93
|
+
globalSeq?: number;
|
|
94
|
+
projectId?: string;
|
|
92
95
|
command: string;
|
|
96
|
+
contextCommand?: string;
|
|
93
97
|
threadId?: string;
|
|
94
98
|
sessionId?: string;
|
|
95
99
|
localDate?: string;
|
|
@@ -172,7 +176,7 @@ export interface AgentRecallResult {
|
|
|
172
176
|
export interface AgentRecallDecisionTrace {
|
|
173
177
|
version: 'agent_recall_decision.v1';
|
|
174
178
|
selectedLane: 'graph' | 'compiled' | 'brain_fallback' | 'raw_ledger' | 'mixed' | 'none';
|
|
175
|
-
reason: 'previous_session' | 'forensic_quote' | 'graph_selected' | 'raw_cue_match_preferred' | 'compiled_cue_match' | 'brain_fallback_selected' | 'raw_ledger_only' | 'no_recall_evidence';
|
|
179
|
+
reason: 'previous_session' | 'forensic_quote' | 'historical_discussion' | 'graph_selected' | 'raw_cue_match_preferred' | 'compiled_cue_match' | 'brain_fallback_selected' | 'raw_ledger_only' | 'no_recall_evidence';
|
|
176
180
|
candidateCounts: {
|
|
177
181
|
graph: number;
|
|
178
182
|
navigation: number;
|
|
@@ -242,6 +246,7 @@ export declare class KernelAgentMemoryBackend {
|
|
|
242
246
|
recallPack(query: AgentRecallQuery): AgentRecallPackResult;
|
|
243
247
|
private recallPreviousSession;
|
|
244
248
|
private recallForensicQuote;
|
|
249
|
+
private recallHistoricalDiscussion;
|
|
245
250
|
private recallForensicAnchor;
|
|
246
251
|
private searchRawEventsByQueryPlan;
|
|
247
252
|
private rawLedgerFallbackItemsForQuery;
|
|
@@ -254,6 +254,9 @@ export class KernelAgentMemoryBackend {
|
|
|
254
254
|
if (query.intent === 'forensic_quote') {
|
|
255
255
|
return this.recallForensicQuote(query, queryPlan);
|
|
256
256
|
}
|
|
257
|
+
if (queryPlan.intent === 'historical_discussion') {
|
|
258
|
+
return this.recallHistoricalDiscussion(query, queryPlan);
|
|
259
|
+
}
|
|
257
260
|
const limit = query.limit ?? 5;
|
|
258
261
|
const allowsGraph = laneAllowed(query.retrievalPolicy, 'graph');
|
|
259
262
|
const allowsCompiled = laneAllowed(query.retrievalPolicy, 'compiled');
|
|
@@ -490,6 +493,46 @@ export class KernelAgentMemoryBackend {
|
|
|
490
493
|
}, items.length),
|
|
491
494
|
};
|
|
492
495
|
}
|
|
496
|
+
recallHistoricalDiscussion(query, queryPlan) {
|
|
497
|
+
const limit = query.limit ?? 5;
|
|
498
|
+
const allowsGraph = laneAllowed(query.retrievalPolicy, 'graph');
|
|
499
|
+
const allowsCompiled = laneAllowed(query.retrievalPolicy, 'compiled');
|
|
500
|
+
const allowsRawSource = laneAllowed(query.retrievalPolicy, 'raw_source');
|
|
501
|
+
const graphItems = allowsGraph ? this.memoryBindingGraphItemsForQuery(query, queryPlan, limit) : [];
|
|
502
|
+
const rawItems = allowsRawSource ? this.rawLedgerFallbackItemsForQuery(queryPlan, query, Math.max(limit * 2, 10)) : [];
|
|
503
|
+
const retrievalLimit = Math.max(limit * 4, 24);
|
|
504
|
+
const compiledItems = allowsCompiled
|
|
505
|
+
? this.filterAgentEvidence(this.kernel.navigateMemory(queryPlan.primarySearchText, {
|
|
506
|
+
projectId: query.projectId,
|
|
507
|
+
limit: retrievalLimit,
|
|
508
|
+
startTime: query.startTime,
|
|
509
|
+
endTime: query.endTime,
|
|
510
|
+
}).rawEvidence, query.agentId, query.collection, query.excludeSessionId)
|
|
511
|
+
.slice(0, limit)
|
|
512
|
+
.map((neuron) => this.toAgentRecallItem(neuron))
|
|
513
|
+
: [];
|
|
514
|
+
const items = this.mergeRecallItems(rawItems, this.mergeRecallItems(graphItems, compiledItems, limit), limit);
|
|
515
|
+
const selectedLane = rawItems.length > 0
|
|
516
|
+
? 'raw_ledger'
|
|
517
|
+
: graphItems.length > 0
|
|
518
|
+
? 'graph'
|
|
519
|
+
: compiledItems.length > 0
|
|
520
|
+
? 'compiled'
|
|
521
|
+
: 'none';
|
|
522
|
+
return {
|
|
523
|
+
recallMode: rawItems.length > 0 ? 'raw_ledger_fallback' : 'brain_recall_fallback',
|
|
524
|
+
items,
|
|
525
|
+
fallbackUsed: true,
|
|
526
|
+
queryPlan,
|
|
527
|
+
decisionTrace: recallDecisionTrace(selectedLane, 'historical_discussion', {
|
|
528
|
+
graph: graphItems.length,
|
|
529
|
+
navigation: compiledItems.length,
|
|
530
|
+
scopedNavigation: compiledItems.length,
|
|
531
|
+
brainFallback: 0,
|
|
532
|
+
rawLedger: rawItems.length,
|
|
533
|
+
}, items.length),
|
|
534
|
+
};
|
|
535
|
+
}
|
|
493
536
|
recallForensicAnchor(query, limit) {
|
|
494
537
|
if (!query.anchorEventId)
|
|
495
538
|
return [];
|
|
@@ -928,7 +971,10 @@ export class KernelAgentMemoryBackend {
|
|
|
928
971
|
window: normalized.window,
|
|
929
972
|
locator: {
|
|
930
973
|
eventId: event.eventId,
|
|
931
|
-
|
|
974
|
+
globalSeq: event.globalSeq,
|
|
975
|
+
projectId: event.projectId,
|
|
976
|
+
command: `cogmem memory show --event ${cliArg(event.eventId)}${event.projectId ? ` --project ${cliArg(event.projectId)}` : ''} --before 2 --after 2 --json`,
|
|
977
|
+
contextCommand: `cogmem memory show --event ${cliArg(event.eventId)}${event.projectId ? ` --project ${cliArg(event.projectId)}` : ''} --before 3 --after 3 --json`,
|
|
932
978
|
threadId: event.threadId,
|
|
933
979
|
sessionId: event.sessionId,
|
|
934
980
|
localDate: event.localDate,
|
|
@@ -939,6 +985,7 @@ export class KernelAgentMemoryBackend {
|
|
|
939
985
|
const text = this.eventText(event);
|
|
940
986
|
return {
|
|
941
987
|
eventId: event.eventId,
|
|
988
|
+
globalSeq: event.globalSeq,
|
|
942
989
|
label: memoryEventLabel(event),
|
|
943
990
|
role: event.role,
|
|
944
991
|
rawEventType: event.rawEventType,
|
|
@@ -1270,3 +1317,6 @@ function uniqueNonEmpty(values) {
|
|
|
1270
1317
|
function laneAllowed(policy, lane) {
|
|
1271
1318
|
return !policy || policy.allowedLanes.includes(lane);
|
|
1272
1319
|
}
|
|
1320
|
+
function cliArg(value) {
|
|
1321
|
+
return /^[A-Za-z0-9._:/=@+-]+$/u.test(value) ? value : `'${value.replace(/'/g, `'\\''`)}'`;
|
|
1322
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type AgentRecallIntent = 'memory_recall' | 'previous_session_summary' | 'forensic_quote';
|
|
1
|
+
export type AgentRecallIntent = 'memory_recall' | 'previous_session_summary' | 'forensic_quote' | 'historical_discussion';
|
|
2
2
|
export interface AgentRecallQueryCompileInput {
|
|
3
3
|
query: string;
|
|
4
4
|
intent?: AgentRecallIntent;
|
|
@@ -99,6 +99,9 @@ export function inferAgentRecallIntent(query) {
|
|
|
99
99
|
if (/原话|怎么说的|完整对话|上一句|下一句|exact quote|verbatim/.test(text)) {
|
|
100
100
|
return 'forensic_quote';
|
|
101
101
|
}
|
|
102
|
+
if (/记得.{0,12}(聊过|讨论过|说过)|还记得|之前.{0,12}(聊过|讨论过|说过)|以前.{0,12}(聊过|讨论过|说过)|(过去|几个月前|半年前|上个月|前几天|昨天|上次|上个).{0,20}(聊过|讨论过|说过)|当时.{0,12}(聊|说|问)|那次.{0,12}(聊|说|问)|有没有.{0,12}(记录|聊过|讨论过)|have we discussed|did we talk about|previously discussed/.test(text)) {
|
|
103
|
+
return 'historical_discussion';
|
|
104
|
+
}
|
|
102
105
|
return 'memory_recall';
|
|
103
106
|
}
|
|
104
107
|
export function extractRecallKeywords(text) {
|
|
@@ -168,10 +171,19 @@ function buildSemanticCuePhrases(keywords, query, anchorText) {
|
|
|
168
171
|
const hasBlackBox = merged.includes('黑盒') || /黑盒|black\s*box/iu.test(text);
|
|
169
172
|
if (hasMemory && hasBlackBox) {
|
|
170
173
|
out.push('记忆 黑盒');
|
|
174
|
+
out.push('记忆黑盒');
|
|
175
|
+
out.push('CogMem Memory Context');
|
|
176
|
+
out.push('Memory Context');
|
|
177
|
+
out.push('上下文注入');
|
|
178
|
+
out.push('sourceContext 原文下钻');
|
|
171
179
|
out.push('存档 黑盒');
|
|
172
180
|
out.push('对话 存档 黑盒');
|
|
173
181
|
out.push('上下文 黑盒');
|
|
174
182
|
out.push('黑盒');
|
|
183
|
+
if (/graph|图|卡死|database locked|zombie|锁/iu.test(text)) {
|
|
184
|
+
out.push('memory graph 黑盒');
|
|
185
|
+
out.push('database locked zombie');
|
|
186
|
+
}
|
|
175
187
|
}
|
|
176
188
|
else if (hasBlackBox) {
|
|
177
189
|
out.push('黑盒');
|
|
@@ -16,6 +16,7 @@ export declare class MemoryAtlasService {
|
|
|
16
16
|
maxHops?: number;
|
|
17
17
|
}): MemoryAtlasPathResult;
|
|
18
18
|
timeline(query: string, options: MemoryAtlasQueryOptions): MemoryAtlasTimelineResult;
|
|
19
|
+
private attachEvidence;
|
|
19
20
|
private evidence;
|
|
20
21
|
private edgesFor;
|
|
21
22
|
private safeEdges;
|
|
@@ -15,7 +15,8 @@ export class MemoryAtlasService {
|
|
|
15
15
|
search(query, options) {
|
|
16
16
|
const projectId = requiredProject(options.projectId);
|
|
17
17
|
const nodes = this.store.search(boundedQuery(query), projectId, boundedLimit(options.limit));
|
|
18
|
-
|
|
18
|
+
const withEvidence = this.attachEvidence(nodes, projectId, options);
|
|
19
|
+
return slice(projectId, withEvidence, this.edgesFor(withEvidence, projectId), query);
|
|
19
20
|
}
|
|
20
21
|
explore(query, options) {
|
|
21
22
|
const projectId = requiredProject(options.projectId);
|
|
@@ -32,8 +33,9 @@ export class MemoryAtlasService {
|
|
|
32
33
|
from: compiled.range?.from, to: compiled.range?.to, limit });
|
|
33
34
|
nodes = uniqueNodes([...actions.map((action) => this.store.getNode(action.id, projectId)).filter((node) => Boolean(node)), ...nodes]).slice(0, limit);
|
|
34
35
|
}
|
|
35
|
-
const
|
|
36
|
-
const
|
|
36
|
+
const nodesWithEvidence = this.attachEvidence(nodes, projectId, options);
|
|
37
|
+
const edges = this.edgesFor(nodesWithEvidence, projectId);
|
|
38
|
+
const result = slice(projectId, nodesWithEvidence, edges, query);
|
|
37
39
|
result.facets = { time: compiled.range, target: target.labels.join(', ') || compiled.target, memoryKinds: compiled.memoryKinds, keywords: compiled.keywords };
|
|
38
40
|
const hasFacet = Boolean(compiled.range || compiled.target || compiled.memoryKinds.length || compiled.tokens.length);
|
|
39
41
|
result.coldMemoryResurrected = hasFacet && nodes.some((node) => node.activation <= 0.1);
|
|
@@ -155,14 +157,28 @@ export class MemoryAtlasService {
|
|
|
155
157
|
return { version: 'memory_atlas.v1', projectId, query, range: compiled.range,
|
|
156
158
|
temporalResurrection: Boolean(compiled.range && [...nodes, ...actions].length), nodes, actions, warnings: [] };
|
|
157
159
|
}
|
|
160
|
+
attachEvidence(nodes, projectId, options) {
|
|
161
|
+
return nodes.map((node) => {
|
|
162
|
+
const evidence = this.evidence(node.id, projectId, options.evidenceLimit, options.includeEvidence);
|
|
163
|
+
const evidenceTotal = this.store.evidenceTotal(node.id, projectId);
|
|
164
|
+
return { ...node, evidenceCount: evidenceTotal, evidenceTotal, evidenceReturned: evidence.length, evidence };
|
|
165
|
+
});
|
|
166
|
+
}
|
|
158
167
|
evidence(nodeId, projectId, requested, includeExcerpt) {
|
|
159
168
|
const limit = Math.max(1, Math.min(requested ?? 2, 10));
|
|
160
169
|
return this.store.evidenceIds(nodeId, projectId, limit).flatMap((eventId) => {
|
|
161
170
|
const event = this.eventStore.getEvent(eventId);
|
|
162
171
|
if (!event || event.projectId !== projectId)
|
|
163
172
|
return [];
|
|
164
|
-
|
|
165
|
-
|
|
173
|
+
const sourceLocator = atlasSourceLocator(event, projectId);
|
|
174
|
+
return [{
|
|
175
|
+
eventId,
|
|
176
|
+
globalSeq: event.globalSeq,
|
|
177
|
+
projectId,
|
|
178
|
+
drilldown: sourceLocator.command,
|
|
179
|
+
sourceLocator,
|
|
180
|
+
excerpt: includeExcerpt ? eventTextForMemory(event).slice(0, 500) : undefined,
|
|
181
|
+
}];
|
|
166
182
|
});
|
|
167
183
|
}
|
|
168
184
|
edgesFor(nodes, projectId) {
|
|
@@ -214,3 +230,21 @@ function chunked(values, size) {
|
|
|
214
230
|
return chunks;
|
|
215
231
|
}
|
|
216
232
|
function slice(projectId, nodes, edges, query) { return { version: 'memory_atlas.v1', projectId, query, nodes, edges, nextActions: nodes.slice(0, 5).map((node) => ({ label: `Inspect ${node.label}`, tool: 'cogmem_graph_node', args: { id: node.id, projectId } })), warnings: [] }; }
|
|
233
|
+
function atlasSourceLocator(event, projectId) {
|
|
234
|
+
const project = projectId || event.projectId;
|
|
235
|
+
const projectArg = project ? ` --project ${cliArg(project)}` : '';
|
|
236
|
+
const base = `cogmem memory show --event ${cliArg(event.eventId)}${projectArg}`;
|
|
237
|
+
return {
|
|
238
|
+
eventId: event.eventId,
|
|
239
|
+
globalSeq: event.globalSeq,
|
|
240
|
+
projectId: project,
|
|
241
|
+
threadId: event.threadId,
|
|
242
|
+
sessionId: event.sessionId,
|
|
243
|
+
localDate: event.localDate,
|
|
244
|
+
command: `${base} --before 2 --after 2 --json`,
|
|
245
|
+
contextCommand: `${base} --before 3 --after 3 --json`,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function cliArg(value) {
|
|
249
|
+
return /^[A-Za-z0-9._:/=@+-]+$/u.test(value) ? value : `'${value.replace(/'/g, `'\\''`)}'`;
|
|
250
|
+
}
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
export type MemoryAtlasNodeType = 'project' | 'topic' | 'entity' | 'cluster' | 'episode' | 'belief' | 'action' | 'time' | 'event';
|
|
2
2
|
export interface MemoryAtlasEvidence {
|
|
3
3
|
eventId: string;
|
|
4
|
+
globalSeq?: number;
|
|
5
|
+
projectId?: string;
|
|
4
6
|
drilldown: string;
|
|
7
|
+
sourceLocator?: {
|
|
8
|
+
eventId: string;
|
|
9
|
+
globalSeq?: number;
|
|
10
|
+
projectId?: string;
|
|
11
|
+
threadId?: string;
|
|
12
|
+
sessionId?: string;
|
|
13
|
+
localDate?: string;
|
|
14
|
+
command: string;
|
|
15
|
+
contextCommand: string;
|
|
16
|
+
};
|
|
5
17
|
excerpt?: string;
|
|
6
18
|
}
|
|
7
19
|
export interface MemoryAtlasNode {
|
|
@@ -24,6 +36,8 @@ export interface MemoryAtlasNode {
|
|
|
24
36
|
evidenceTotal: number;
|
|
25
37
|
/** Number of evidence records returned in this response. */
|
|
26
38
|
evidenceReturned?: number;
|
|
39
|
+
/** Bounded first-hop raw evidence locators for agent-facing graph search/explore responses. */
|
|
40
|
+
evidence?: MemoryAtlasEvidence[];
|
|
27
41
|
}
|
|
28
42
|
export interface MemoryAtlasEdge {
|
|
29
43
|
source: string;
|
package/dist/bin/connect.js
CHANGED
|
@@ -90,21 +90,92 @@ function defaultSkillPath(agent, workspaceRoot) {
|
|
|
90
90
|
return join(process.env.HOME || homedir(), '.hermes', 'skills', 'cogmem-memory', 'SKILL.md');
|
|
91
91
|
}
|
|
92
92
|
function nextCommands(agent) {
|
|
93
|
+
return nextSteps(agent)
|
|
94
|
+
.filter((step) => step.safeForAutomation && step.actor === 'agent')
|
|
95
|
+
.map((step) => step.command);
|
|
96
|
+
}
|
|
97
|
+
function nextSteps(agent) {
|
|
98
|
+
const project = agent === 'openclaw' ? 'openclaw' : 'hermes';
|
|
99
|
+
const importCommand = agent === 'openclaw' ? 'import-openclaw' : 'import-hermes';
|
|
100
|
+
const steps = [
|
|
101
|
+
{
|
|
102
|
+
id: 'doctor',
|
|
103
|
+
actor: 'agent',
|
|
104
|
+
safeForAutomation: true,
|
|
105
|
+
command: './node_modules/.bin/cogmem doctor',
|
|
106
|
+
when: 'after installation or update',
|
|
107
|
+
purpose: 'verify package, config, and database access',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: 'import_dry_run',
|
|
111
|
+
actor: 'agent',
|
|
112
|
+
safeForAutomation: true,
|
|
113
|
+
command: `./node_modules/.bin/cogmem ${importCommand} --workspace . --project ${project} --dry-run --json`,
|
|
114
|
+
when: 'before importing legacy memory',
|
|
115
|
+
purpose: 'preview source discovery and import counts',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: 'import_apply',
|
|
119
|
+
actor: 'agent',
|
|
120
|
+
safeForAutomation: true,
|
|
121
|
+
command: `./node_modules/.bin/cogmem ${importCommand} --workspace . --project ${project} --json`,
|
|
122
|
+
when: 'after dry-run looks correct',
|
|
123
|
+
purpose: 'idempotently import legacy memory into Cogmem',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: 'memory_plan',
|
|
127
|
+
actor: 'agent',
|
|
128
|
+
safeForAutomation: true,
|
|
129
|
+
command: `./node_modules/.bin/cogmem memory plan --project ${project} --json`,
|
|
130
|
+
when: 'after import, update, or user asks for governance progress',
|
|
131
|
+
purpose: 'read agent-safe next actions instead of guessing from raw counters',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 'memory_status',
|
|
135
|
+
actor: 'agent',
|
|
136
|
+
safeForAutomation: true,
|
|
137
|
+
command: `./node_modules/.bin/cogmem memory status --project ${project} --json`,
|
|
138
|
+
when: 'for read-only health checks',
|
|
139
|
+
purpose: 'inspect raw ledger, vector fallback, dream backlog, and queue summary',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
id: 'interactive_init',
|
|
143
|
+
actor: 'operator',
|
|
144
|
+
safeForAutomation: false,
|
|
145
|
+
command: `./node_modules/.bin/cogmem init --agent ${agent} --scope project`,
|
|
146
|
+
when: 'only if no Cogmem config exists and a human operator is present',
|
|
147
|
+
purpose: 'interactive first-time config wizard; agents must not run this unattended',
|
|
148
|
+
},
|
|
149
|
+
];
|
|
93
150
|
if (agent === 'openclaw') {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
'./node_modules/.bin/cogmem
|
|
99
|
-
'
|
|
100
|
-
|
|
151
|
+
steps.splice(1, 0, {
|
|
152
|
+
id: 'openclaw_diagnose',
|
|
153
|
+
actor: 'agent',
|
|
154
|
+
safeForAutomation: true,
|
|
155
|
+
command: './node_modules/.bin/cogmem openclaw diagnose --workspace . --json',
|
|
156
|
+
when: 'after connect --auto --force or before investigating injection failures',
|
|
157
|
+
purpose: 'verify generated plugin files, audit log, queue lock, and hook diagnostics',
|
|
158
|
+
});
|
|
159
|
+
steps.push({
|
|
160
|
+
id: 'restart_gateway',
|
|
161
|
+
actor: 'host',
|
|
162
|
+
safeForAutomation: false,
|
|
163
|
+
command: 'openclaw gateway restart',
|
|
164
|
+
when: 'after plugin files or OpenClaw config changed',
|
|
165
|
+
purpose: 'reload OpenClaw hooks so the refreshed Cogmem plugin is active',
|
|
166
|
+
});
|
|
101
167
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
168
|
+
else {
|
|
169
|
+
steps.push({
|
|
170
|
+
id: 'reload_hermes',
|
|
171
|
+
actor: 'host',
|
|
172
|
+
safeForAutomation: false,
|
|
173
|
+
command: 'restart or reload Hermes MCP server',
|
|
174
|
+
when: 'after Hermes MCP config changed',
|
|
175
|
+
purpose: 'reload the cogmem MCP server entry',
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return steps;
|
|
108
179
|
}
|
|
109
180
|
function usage() {
|
|
110
181
|
return [
|
|
@@ -238,6 +309,7 @@ function installSkill(args) {
|
|
|
238
309
|
installed: !args.dryRun && !alreadyCurrent,
|
|
239
310
|
alreadyCurrent,
|
|
240
311
|
nextCommands: nextCommands(args.agent),
|
|
312
|
+
nextSteps: nextSteps(args.agent),
|
|
241
313
|
hostConfigSnippet: hostConfigSnippet(args.agent, args.workspaceRoot, args.auto),
|
|
242
314
|
autoMemory,
|
|
243
315
|
hermesMcp,
|