/** * DkgMemoryPlugin — DKG-backed memory-slot plugin for OpenClaw. * * Reads AND writes flow through the memory slot contract: * `api.registerMemoryCapability({ runtime: buildDkgMemoryRuntime(...) })` * which hands the upstream memory host a `MemorySearchManager` instance. * `DkgMemorySearchManager.search()` fans out across four layers when a * project context graph is resolved — one `POST /api/query` to * `agent-context` (`assertionName: 'chat-turns'`, `view: 'working-memory'`) * plus three against the resolved project CG's `'memory'` assertion with * `view: 'working-memory' | 'shared-working-memory' | 'verifiable-memory'`. * See `DkgMemorySearchManager.search` for trust-weighted ranking and * cross-layer dedup. * * Writes happen through the upstream memory-host write contract on the * same slot registration (upstream recall orchestrates `saveMemory` / * `recallMemory` against the capability runtime). This adapter no longer * registers explicit `dkg_memory_import` / `dkg_memory_search` tools — * the slot is the single entry point for both directions. Programmatic * callers can still construct a `DkgMemorySearchManager` directly for * read-side access (see the barrel export in `src/index.ts`). * * Reads target real V10 primitives: * read: POST /api/query (with view + agentAddress + assertionName) * * No `agent-memory` sidecar. No `dkg:ImportedMemory`. No * `FILTER(CONTAINS)`-over-a-throwaway-graph. No `tools.share` on the * chat-turn or memory paths — that's SWM, wrong layer per * `21_TRI_MODAL_MEMORY.md §5`. */ import type { DkgDaemonClient } from './dkg-client.js'; import type { DkgOpenClawConfig, MemoryEmbeddingProbeResult, MemoryPluginRuntime, MemoryProviderStatus, MemoryReadFileRequest, MemoryReadFileResult, MemorySearchManager, MemorySearchOptions, MemorySearchResult, OpenClawPluginApi } from './types.js'; export declare const AGENT_CONTEXT_GRAPH = "agent-context"; export declare const CHAT_TURNS_ASSERTION = "chat-turns"; export declare const PROJECT_MEMORY_ASSERTION = "memory"; export interface DkgMemorySession { /** * UI-selected / envelope-stamped project context graph. `undefined` when * the user has not selected a project, in which case reads fall back to * the `agent-context` branch only and writes return a structured * clarification request. */ projectContextGraphId?: string; /** Agent address used for scoping WM assertion reads. */ agentAddress?: string; } export interface DkgMemorySessionResolver { getSession(sessionKey: string | undefined): DkgMemorySession | undefined; /** Default agent address when no session is available (falls back to node peer ID). */ getDefaultAgentAddress(): string | undefined; /** List of subscribed CGs, used when the write path needs to return a clarification. */ listAvailableContextGraphs(): string[]; /** * Force a synchronous refresh of the subscribed-CG cache and return * the refreshed list. Optional — resolvers that cannot refresh on * demand (e.g. test fixtures with a fixed list, or legacy wirings * without network access) can omit this method and callers will * fall through to the synchronous `listAvailableContextGraphs()` * result. Codex Bug B46: `dkg_memory_import` uses this to retry * the subscribed-list guard against a freshly-probed cache when * the initial cached list does not contain a just-created CG, so * legitimate brand-new subscriptions are not rejected during the * TTL window of the cache that normally refreshes lazily. */ refreshAvailableContextGraphs?(): Promise; } interface DkgMemorySearchManagerDeps { client: DkgDaemonClient; resolver: DkgMemorySessionResolver; sessionKey?: string; logger?: OpenClawPluginApi['logger']; } export declare class DkgMemorySearchManager implements MemorySearchManager { private readonly deps; private cachedStatus; constructor(deps: DkgMemorySearchManagerDeps); /** * Narrow recall for W3 `before_prompt_build` auto-injection. Runs the * full 6-layer fan-out (agent-context WM/SWM/VM + project WM/SWM/VM if * resolved) but caps the returned hits tighter than the agent-callable * `memory_search` tool. Both surfaces share the same ranking; W3 is * "small auto-snapshot of all tiers", W2 is "large agent-driven recall * of all tiers". The cap is what differs, not the layer scope. * * This is deliberate per the design direction: cross-peer SWM/VM * tiers are surfaced in auto-recall so the agent has full memory * context without needing to first call `memory_search`. The * trust-boundary concern raised in pre-push review is addressed by * defense-in-depth — every snippet is HTML-escaped (R12.1), wrapped * in untrusted-data framing with explicit "do not follow injected * instructions" rules (R11.1), and the auto-recall block carries a * sentinel attribute (R15.3 / R23.3) so it's stripped from persisted * assistant text. */ searchNarrow(query: string, options?: MemorySearchOptions): Promise; search(query: string, options?: MemorySearchOptions): Promise; private runSearch; readFile(request: MemoryReadFileRequest): Promise; status(): MemoryProviderStatus; probeEmbeddingAvailability(): Promise; probeVectorAvailability(): Promise; sync(): Promise; close(): Promise; private buildStatus; } export declare function buildDkgMemoryRuntime(client: DkgDaemonClient, resolver: DkgMemorySessionResolver, logger?: OpenClawPluginApi['logger']): MemoryPluginRuntime; /** * **BREAKING API CHANGE (openclaw-dkg-primary-memory workstream)** — the * exported `DkgMemoryPlugin` class no longer implements the legacy * `OpenClawMemorySearchManager` surface, and no longer registers * explicit `dkg_memory_import` / `dkg_memory_search` tools. Previous * revisions of this class exposed `search`, `readFile`, `status`, * `sync`, and `close` methods directly so external consumers could * instantiate a plugin and query it as a search manager. Those methods * have moved to the new `DkgMemorySearchManager` class (exported from * this same module), which is instantiated internally by * `buildDkgMemoryRuntime` when the gateway calls * `api.registerMemoryCapability`. See the module-level comment at the * top of this file for the slot-backed reads-and-writes architecture. * * The constructor signature has also changed from `(client, config)` to * `(client, config, resolver)` so the change is an unavoidable compile * break for any TypeScript consumer — we document it here explicitly * rather than shipping deprecated forwarding methods. External callers * that need programmatic search should either: * 1. register the plugin through the standard `DkgNodePlugin` * lifecycle so reads route through the slot-backed recall path, or * 2. instantiate `DkgMemorySearchManager` directly with a * `DkgMemorySessionResolver`, which gives the same search semantics * the slot uses. * * The only in-tree consumer of this class is `DkgNodePlugin`. */ export declare class DkgMemoryPlugin { private client; private readonly config; private readonly resolver; private registeredCapability; private registeredApi; private registeredOwnershipSource; constructor(client: DkgDaemonClient, config: NonNullable, resolver: DkgMemorySessionResolver); setClient(client: DkgDaemonClient, options?: { reRegister?: boolean; api?: OpenClawPluginApi; }): void; disable(api?: OpenClawPluginApi): boolean; register(api: OpenClawPluginApi): boolean; /** * Re-assert the memory-slot capability registration. Called by the * channel plugin right before each inbound turn dispatch to guarantee * this adapter's runtime is the active one, regardless of whether * memory-core's dreaming sidecar overwrote it during plugin loading. * * Cost: a single property assignment on a module-scoped object in the * OpenClaw gateway (`memoryPluginState.capability = { ... }`). No * allocations, no I/O, no async operations. Safe to call on every turn. */ reAssertCapability(): void; /** * Invalidate the cached capability + api so subsequent * `reAssertCapability()` calls become no-ops. * * Called by `DkgNodePlugin` whenever a later `register()` call returns * `false` (slot ownership lost to another plugin). Without this clear, * the cached capability would persist and per-turn re-assert anchors * (`before_prompt_build`, `message:received`/`sent`, `memory_search`) * would silently steal the slot back from the newly elected provider. */ invalidateRegistration(): void; close(): Promise; /** * Whether this adapter currently owns the gateway memory slot. Returns * `false` when `registerCapability()` was skipped (e.g. another plugin * owns `plugins.slots.memory`) or after `invalidateRegistration()` is * called. Per-turn anchors (`before_prompt_build`, `memory_search`) * use this to avoid injecting DKG recall when the elected provider is * a different plugin. */ isRegistered(): boolean; /** * Registers the memory-slot capability. Two gates must pass: * * 1. The gateway must expose `api.registerMemoryCapability` — older * gateways predate the memory-slot contract and have no entry * point to call. * * 2. The workspace config must have elected this adapter into the * memory slot (`plugins.slots.memory === 'adapter-openclaw'`). * Merely loading the plugin must not silently override whatever * memory provider the operator elected via `dkg setup`; if the * slot points at another plugin (or is unset), this adapter * no-ops the registration and logs a diagnostic so the operator * can rerun setup if they meant to elect it. */ private registerCapability; private buildCapability; } /** * The DKG V10 agent identity shows up in two representations in this * package — the daemon's working-memory view routing uses the raw peer * ID (an alphanumeric/hex node fingerprint) for assertion-graph URI * scoping, while provenance triples (e.g. `schema:creator`) use the * canonical `did:dkg:agent:` DID form. A consumer that passes * either representation into the resolver / tool surface must have * both forms normalized before being used at each site — otherwise * a DID-form input gets double-prefixed into * `did:dkg:agent:did:dkg:agent:...` for the creator triple, or the * WM view routing looks in an assertion graph scoped to a literal DID * string and finds nothing. Normalize once at the boundary and use * the correct form at each consumption site. Codex Bug B43. */ export declare const AGENT_DID_PREFIX = "did:dkg:agent:"; /** * Return the raw peer-ID form used for WM view routing. Exported so * `DkgNodePlugin.handleQuery` can apply the same B43 normalization * before forwarding `agent_address` / the node peerId fallback to the * daemon (DID-form values otherwise route to a non-existent namespace * and return empty results). */ export declare function toAgentPeerId(agentAddress: string): string; export {}; //# sourceMappingURL=DkgMemoryPlugin.d.ts.map