From 30fdf549e6ffd251b86e9ba0f3566b2864e19868 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 23 Apr 2026 02:52:31 -0700 Subject: [PATCH] docs: document per-request config_override in README + consuming-core The feature landed on main in PR #41 but README and consuming-core.md still described the pre-override HTTP surface. Add: - README: a "Per-request config override" subsection under API Overview with a curl example and a table of the four X-Atomicmem-* response headers (Applied, Effective-Config-Hash, Override-Keys, Unknown-Override-Keys). - docs/consuming-core.md: a TS fetch example in the HTTP section that reads the four observability headers, plus a permissive-schema note explaining that unknown keys ride through and surface via the Unknown-Override-Keys header rather than 400. No code changes. --- README.md | 30 ++++++++++++++++++++++++++++++ docs/consuming-core.md | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/README.md b/README.md index a1fd6bc..f06deb3 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,36 @@ Health check: `curl http://localhost:3050/health` See the [HTTP API reference](https://docs.atomicmemory.ai/api-reference/http/conventions) for full endpoint documentation. +### Per-request config override + +Search and ingest routes accept an optional `config_override` body field that +overlays the startup `RuntimeConfig` for that single request. Useful for +A/B tests, experiments, or dial-turning without restarting the server. + +```bash +curl -X POST http://localhost:3050/v1/memories/search \ + -H 'Content-Type: application/json' \ + -d '{ + "user_id": "alice", + "query": "what stack does alice use?", + "config_override": { "hybridSearchEnabled": true, "maxSearchResults": 20 } + }' +``` + +Responses from requests carrying an override emit four observability headers: + +| Header | Emitted when | Value | +|--------|--------------|-------| +| `X-Atomicmem-Config-Override-Applied` | Override present | `true` | +| `X-Atomicmem-Effective-Config-Hash` | Override present | `sha256:` of the merged config | +| `X-Atomicmem-Config-Override-Keys` | Override present | Comma-joined sorted override keys | +| `X-Atomicmem-Unknown-Override-Keys` | One or more keys don't match a current `RuntimeConfig` field | Comma-joined sorted unknown keys | + +The schema is permissive — unknown keys don't 400. They ride through on the +effective config and surface via the fourth header plus a server-side warning +log, so callers catch typos without gating new runtime fields behind a schema +release. + ## Environment Variables ### Required diff --git a/docs/consuming-core.md b/docs/consuming-core.md index 55838df..567b791 100644 --- a/docs/consuming-core.md +++ b/docs/consuming-core.md @@ -44,6 +44,43 @@ const { count, injection_text, memories } = await res.json(); The full endpoint surface and response shapes are documented at https://docs.atomicmemory.ai/api-reference/http/conventions (rendered from `openapi.yaml` at this repo's root). +### Per-request `config_override` + +All four memory routes (`/search`, `/search/fast`, `/ingest`, `/ingest/quick`) +accept an optional `config_override` body field that overlays the startup +`RuntimeConfig` for the scope of that one request. Scope is strictly +per-request — the startup singleton is not mutated. + +```ts +const res = await fetch('http://localhost:3050/v1/memories/search', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + user_id: 'alice', + query: 'what stack?', + config_override: { hybridSearchEnabled: true, maxSearchResults: 20 }, + }), +}); + +// Observability headers (only emitted when an override is present) +res.headers.get('X-Atomicmem-Config-Override-Applied'); // 'true' +res.headers.get('X-Atomicmem-Effective-Config-Hash'); // 'sha256:' +res.headers.get('X-Atomicmem-Config-Override-Keys'); // 'hybridSearchEnabled,maxSearchResults' +res.headers.get('X-Atomicmem-Unknown-Override-Keys'); // null unless a key doesn't match a current RuntimeConfig field +``` + +Shape: a flat object whose values are primitives (boolean, number, string, +null). Keys should be `RuntimeConfig` field names. The schema is permissive: +unknown keys are accepted and carried through, and surface via the +`X-Atomicmem-Unknown-Override-Keys` response header plus a server-side +warning log rather than a 400 — so adding a new overlay-eligible +`RuntimeConfig` field in a future release doesn't require a matching +schema landing before consumers can use it. + +Effective config semantics: `{ ...startup, ...override }` (shallow merge). +`maxSearchResults` in an override is fully respected — the request-limit +clamp uses the post-override value, not the startup snapshot. + ## In-process Import the composition root and call services directly. Useful when a Node