From 0c9bcd405734752764ac0c406aeffcc8b8d71951 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Fri, 6 Mar 2026 14:08:11 +0000 Subject: [PATCH] chore(orchestrator): Bootstrap PRD + TASKS.md v0.0.1 (#1) Co-authored-by: Jason Woltje Co-committed-by: Jason Woltje --- docs/PRD.md | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ docs/TASKS.md | 12 ++++++ 2 files changed, 129 insertions(+) create mode 100644 docs/PRD.md create mode 100644 docs/TASKS.md diff --git a/docs/PRD.md b/docs/PRD.md new file mode 100644 index 0000000..8e415c2 --- /dev/null +++ b/docs/PRD.md @@ -0,0 +1,117 @@ +# PRD: openclaw-openbrain-context + +**Version:** 0.0.1 +**Status:** Approved + +--- + +## Problem Statement + +OpenClaw compacts context when sessions grow long, causing information loss. The new `ContextEngine` plugin interface (merged in PR #22201) allows replacing the default compaction strategy with a persistent, lossless alternative. OpenBrain (brain.woltje.com) is a live pgvector + REST API service that can store and semantically retrieve conversation context indefinitely. + +## Solution + +An OpenClaw plugin that implements the `ContextEngine` interface and stores all context in OpenBrain using semantic embeddings. Sessions become effectively lossless — context is archived, not discarded. On reassembly, relevant context is retrieved via semantic search. + +## Reference Implementation + +lossless-claw (https://github.com/Martian-Engineering/lossless-claw) is the primary reference. It uses SQLite; we use OpenBrain (Postgres + pgvector via REST). Our implementation is simpler: no local DB, no migrations — everything goes through the OpenBrain REST API. + +## OpenBrain API + +``` +Base: https://brain.woltje.com +Auth: Bearer + +POST /v1/thoughts { content, source, metadata } +POST /v1/search { query, limit } +GET /v1/thoughts/recent ?limit=N&source=X +PATCH /v1/thoughts/:id { content?, metadata? } +DELETE /v1/thoughts/:id +DELETE /v1/thoughts ?source=X&metadata_id=Y (bulk) +``` + +## Plugin Architecture + +### ContextEngine interface lifecycle hooks to implement: +- `bootstrap(sessionId)` — init session context, retrieve prior context from OpenBrain +- `ingest(message)` — store each message turn to OpenBrain +- `ingestBatch(messages)` — bulk store (e.g., on session import) +- `afterTurn()` — post-turn hook (optional: summarize/compress) +- `assemble(maxTokens)` — retrieve relevant context for next turn via semantic search +- `compact(params)` — archive current context to OpenBrain, return minimal summary +- `prepareSubagentSpawn(subagentId)` — pass relevant context to spawned subagent +- `onSubagentEnded(subagentId, reason)` — integrate subagent results back +- `dispose()` — cleanup + +### Source tagging strategy +Each thought stored in OpenBrain: +- `source`: `openclaw:` (e.g., `openclaw:main`) +- `metadata.sessionId`: session key +- `metadata.turn`: turn index +- `metadata.role`: `user` | `assistant` | `tool` +- `metadata.type`: `message` | `summary` | `subagent-result` + +### Retrieval strategy +On `assemble()`: +1. Fetch recent N messages (ordered, for continuity) +2. Semantic search with last user message as query +3. Merge + deduplicate, trim to maxTokens + +## Plugin Registration + +```typescript +// index.ts +import { OpenBrainContextEngine } from "./src/engine.js"; + +export function register(api: OpenClawPluginApi) { + api.registerContextEngine("openbrain", (config) => + new OpenBrainContextEngine(config) + ); +} +``` + +## Configuration (openclaw.json) + +```json +{ + "agents": { + "defaults": { + "contextEngine": "openbrain" + } + }, + "plugins": { + "entries": { + "openclaw-openbrain-context": { + "enabled": true, + "config": { + "baseUrl": "https://brain.woltje.com", + "apiKey": "${OPENBRAIN_API_KEY}", + "recentMessages": 20, + "semanticSearchLimit": 10, + "source": "openclaw" + } + } + } + } +} +``` + +## Tech Stack +- TypeScript strict +- No local DB (pure REST calls to OpenBrain) +- openclaw/plugin-sdk for ContextEngine interface +- pnpm, vitest, ESLint + +## Acceptance Criteria (v0.0.1) +1. Plugin registers as a ContextEngine with id `openbrain` +2. `ingest()` stores messages to OpenBrain with correct metadata +3. `assemble()` retrieves recent + semantically relevant context within token budget +4. `compact()` archives turn summary, returns minimal prompt-injection +5. `bootstrap()` loads prior session context on restart +6. Tests pass, TypeScript strict, ESLint clean +7. openclaw.plugin.json with correct manifest +8. README: install + config + usage + +## ASSUMPTION: ContextEngine interface shape +Based on lossless-claw source and PR #22201. Plugin SDK import path: `openclaw/plugin-sdk`. diff --git a/docs/TASKS.md b/docs/TASKS.md new file mode 100644 index 0000000..0f5bce8 --- /dev/null +++ b/docs/TASKS.md @@ -0,0 +1,12 @@ +# Tasks — openclaw-openbrain-context v0.0.1 + +| id | status | description | issue | repo | branch | depends_on | blocks | agent | started_at | completed_at | estimate | used | notes | +|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +| OBC-001 | not-started | Init: pnpm, TypeScript strict, ESLint, vitest, openclaw plugin-sdk dep | TASKS:P1 | openclaw-openbrain-context | feat/engine | | OBC-002 | | | | 8K | | | +| OBC-002 | not-started | OpenBrain REST client module (typed, auth, error handling) | TASKS:P1 | openclaw-openbrain-context | feat/engine | OBC-001 | OBC-003 | | | | 8K | | | +| OBC-003 | not-started | ContextEngine implementation: bootstrap + ingest + ingestBatch | TASKS:P1 | openclaw-openbrain-context | feat/engine | OBC-002 | OBC-004 | | | | 15K | | | +| OBC-004 | not-started | ContextEngine implementation: assemble (recent + semantic merge) | TASKS:P1 | openclaw-openbrain-context | feat/engine | OBC-003 | OBC-005 | | | | 15K | | | +| OBC-005 | not-started | ContextEngine implementation: compact + prepareSubagentSpawn + onSubagentEnded + dispose | TASKS:P1 | openclaw-openbrain-context | feat/engine | OBC-004 | OBC-006 | | | | 12K | | | +| OBC-006 | not-started | Plugin entrypoint: register(), openclaw.plugin.json manifest | TASKS:P1 | openclaw-openbrain-context | feat/engine | OBC-005 | OBC-007 | | | | 5K | | | +| OBC-007 | not-started | Unit tests: ingest/assemble/compact + mock OpenBrain responses | TASKS:P1 | openclaw-openbrain-context | feat/engine | OBC-006 | OBC-008 | | | | 15K | | | +| OBC-008 | not-started | README + install instructions + openclaw.json config example | TASKS:P1 | openclaw-openbrain-context | feat/engine | OBC-007 | | | | | 5K | | |