formative-memory 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -158,8 +158,8 @@ Configuration goes in `openclaw.json` under the plugin entry:
158
158
  | `autoRecall` | `true` | Inject relevant memories into context before every response |
159
159
  | `autoCapture` | `true` | Automatically capture conversations for consolidation |
160
160
  | `requireEmbedding` | `true` | Require a working embedding provider. Set `false` to allow BM25-only fallback |
161
- | `embedding.provider` | `"auto"` | Embedding provider: `auto`, `openai`, `gemini`, `voyage`, `mistral`, `ollama`, `local` |
162
- | `embedding.model` | — | Override the provider's default embedding model |
161
+ | `embedding.provider` | `"auto"` | Embedding provider: `auto`, `openai`, `gemini`. Additional providers (`voyage`, `mistral`, `ollama`, `local`) are also accepted when memory-core embedding adapters are installed as a fallback registry |
162
+ | `embedding.model` | — | Override the provider's default embedding model. Only takes effect with an explicit `embedding.provider` — ignored in `"auto"` mode to avoid passing a provider-specific model name to the wrong provider |
163
163
  | `dbPath` | `~/.openclaw/memory/associative` | SQLite database location |
164
164
  | `verbose` | `false` | Enable debug logging |
165
165
  | `logQueries` | `false` | Include raw query text in debug logs (disabled by default for privacy) |
@@ -169,6 +169,40 @@ your configured API keys. When `requireEmbedding` is `true` (the
169
169
  default), the plugin will not start without a working embedding provider.
170
170
  Set it to `false` to allow graceful degradation to keyword-only search.
171
171
 
172
+ ### API Keys
173
+
174
+ API keys are read from OpenClaw's `auth-profiles.json`. Environment
175
+ variables are **not** used. Configure a profile under the standard
176
+ OpenClaw setup:
177
+
178
+ ```json
179
+ {
180
+ "version": 1,
181
+ "profiles": {
182
+ "openai:default": { "type": "api_key", "key": "sk-..." },
183
+ "google:default": { "type": "api_key", "key": "AIza..." }
184
+ }
185
+ }
186
+ ```
187
+
188
+ The `openai:default` and `google:default` profile names are picked up
189
+ automatically. If you have multiple profiles for the same provider
190
+ (e.g. `openai:work` and `openai:personal`), the plugin warns and picks
191
+ the first one — add a `:default` profile to select explicitly.
192
+
193
+ ### Provider pinning
194
+
195
+ The plugin pins the selected provider and model to the database on
196
+ first successful resolution. On subsequent runs, the same provider and
197
+ model are used regardless of `embedding.provider` in config — this
198
+ prevents silent drift that would corrupt the vector store when a
199
+ different provider (producing different-dimension vectors) takes over.
200
+
201
+ If you intentionally want to switch providers or models for an
202
+ existing database, you must re-embed all memories via migration.
203
+ Attempting to change the configured provider mid-life produces a
204
+ clear error at startup rather than silent corruption.
205
+
172
206
  ## Architecture
173
207
 
174
208
  ```
@@ -190,8 +224,10 @@ OpenClaw Runtime
190
224
  **Storage:** SQLite with FTS5 for full-text search. Single file, no
191
225
  external services.
192
226
 
193
- **Embedding:** Auto-detected from configured API keys. Supports OpenAI,
194
- Gemini, Voyage, Mistral, Ollama. Circuit breaker with graceful fallback
227
+ **Embedding:** Standalone fetch-based clients for OpenAI and Gemini
228
+ read keys from `auth-profiles.json`. Additional providers (Voyage,
229
+ Mistral, Ollama, local) resolve through memory-core's embedding
230
+ adapter registry when installed. Circuit breaker with graceful fallback
195
231
  to keyword-only search when `requireEmbedding` is `false`.
196
232
 
197
233
  **Consolidation LLM:** Uses Anthropic (Claude) or OpenAI for memory
package/dist/cli.js CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { n as MemorySourceGuard, r as TemporalStateGuard, t as MemoryDatabase } from "./db-D1Sc76VE.js";
2
+ import { n as MemorySourceGuard, r as TemporalStateGuard, t as MemoryDatabase } from "./db-Cqpy00Ox.js";
3
3
  import { join } from "node:path";
4
4
  import { existsSync, readFileSync } from "node:fs";
5
+
5
6
  //#region src/cli.ts
6
7
  /**
7
8
  * Associative Memory CLI
@@ -516,5 +517,6 @@ List filters:
516
517
  --limit <n> Max results (default: 50)
517
518
  `.trim());
518
519
  }
520
+
519
521
  //#endregion
520
- export {};
522
+ export { };
@@ -1,4 +1,5 @@
1
1
  import { DatabaseSync } from "node:sqlite";
2
+
2
3
  //#region src/types.ts
3
4
  const TEMPORAL_STATES = [
4
5
  "future",
@@ -50,6 +51,7 @@ function assertIsoUtcTimestamp(v, label) {
50
51
  if (typeof v !== "string" || !ISO_UTC_RE.test(v)) throw new Error(`Invalid ${label}: expected ISO-8601 UTC timestamp, got ${String(v)}`);
51
52
  if (!Number.isFinite(Date.parse(v))) throw new Error(`Invalid ${label}: unparseable calendar date ${v}`);
52
53
  }
54
+
53
55
  //#endregion
54
56
  //#region src/db.ts
55
57
  /**
@@ -625,5 +627,6 @@ var MemoryDatabase = class {
625
627
  this.db.close();
626
628
  }
627
629
  };
630
+
628
631
  //#endregion
629
- export { MemorySourceGuard as n, TemporalStateGuard as r, MemoryDatabase as t };
632
+ export { MemorySourceGuard as n, TemporalStateGuard as r, MemoryDatabase as t };