|
| 1 | +# Oh My Pi (omp) Integration |
| 2 | + |
| 3 | +[Oh My Pi](https://omp.sh) (`omp`, [`can1357/oh-my-pi`](https://github.com/can1357/oh-my-pi)) |
| 4 | +is a terminal coding agent forked from [Pi](https://pi.dev). Because omp |
| 5 | +preserves Pi's extension API — the same `context`, `turn_end`, |
| 6 | +`session_shutdown`, and `session_before_compact` hooks — the existing |
| 7 | +`@remnic/plugin-pi` runtime extension runs on omp unchanged. Only the |
| 8 | +*installer* differs (omp keeps its agent files under `~/.omp/agent` instead of |
| 9 | +`~/.pi/agent`), so Remnic ships a dedicated **`omp` connector** that writes into |
| 10 | +the right place. |
| 11 | + |
| 12 | +There are two ways to give omp the **same** governed memory that OpenClaw, |
| 13 | +Claude Code, Codex, ChatGPT, and Pi already share. Both point omp at the *same* |
| 14 | +Remnic daemon + memory directory, so memory written by any agent is recalled by |
| 15 | +every agent. |
| 16 | + |
| 17 | +> **One brain, many front-ends.** Shared memory only requires that every agent |
| 18 | +> talks to one Remnic instance (one daemon URL + one `memoryDir`). omp joins as |
| 19 | +> another front-end; it does not get a private store. |
| 20 | +
|
| 21 | +--- |
| 22 | + |
| 23 | +## Path 1 — Register Remnic as an MCP server (fast, no extension) |
| 24 | + |
| 25 | +omp is a first-class MCP client. This is the quickest way to validate shared |
| 26 | +read/write and needs no Remnic extension files. |
| 27 | + |
| 28 | +First start the Remnic server (it serves the MCP endpoint on port 4318) and mint |
| 29 | +a token — the same HTTP/MCP surface every other MCP client uses (see |
| 30 | +[connector-setup.md](./connector-setup.md)): |
| 31 | + |
| 32 | +```bash |
| 33 | +remnic daemon start # serves http://localhost:4318/mcp |
| 34 | +remnic connectors install generic-mcp # mints the connector token ($REMNIC_AUTH_TOKEN) |
| 35 | +``` |
| 36 | + |
| 37 | +Then point omp at it via `~/.omp/agent/mcp.json` (user scope) or `.omp/mcp.json` |
| 38 | +(project scope) using the HTTP transport: |
| 39 | + |
| 40 | +```json |
| 41 | +{ |
| 42 | + "$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/config/mcp-schema.json", |
| 43 | + "mcpServers": { |
| 44 | + "remnic": { |
| 45 | + "type": "http", |
| 46 | + "url": "http://localhost:4318/mcp", |
| 47 | + "headers": { |
| 48 | + "Authorization": "Bearer ${REMNIC_AUTH_TOKEN}", |
| 49 | + "X-Engram-Namespace": "my-project" |
| 50 | + } |
| 51 | + } |
| 52 | + } |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +This exposes Remnic's MCP tools (`remnic_recall`, `remnic_memory_store`, |
| 57 | +`remnic_briefing`, `remnic_observe`, …) to omp against the same store the other |
| 58 | +agents use. The optional `X-Engram-Namespace` header scopes memory to a |
| 59 | +project/team. |
| 60 | + |
| 61 | +> **Transport note.** The `remnic` binary does not serve MCP over stdio — the |
| 62 | +> daemon's HTTP `/mcp` endpoint is the supported transport for every MCP client |
| 63 | +> (OpenClaw plugin mode uses `openclaw engram access http-serve --port 4318`). |
| 64 | +
|
| 65 | +**Trade-off:** MCP recall is *tool-gated* — the model must decide to call |
| 66 | +`remnic_recall`/`remnic_briefing`. There is no automatic system-prompt |
| 67 | +injection. Use an omp rule/skill to nudge a `remnic_briefing` call at session |
| 68 | +start, or use Path 2 for automatic recall. |
| 69 | + |
| 70 | +--- |
| 71 | + |
| 72 | +## Path 2 — Install the native omp extension (recommended) |
| 73 | + |
| 74 | +Start the Remnic daemon, then install the `omp` connector: |
| 75 | + |
| 76 | +```bash |
| 77 | +remnic daemon start |
| 78 | +remnic connectors install omp |
| 79 | +``` |
| 80 | + |
| 81 | +The installer writes (mirroring the Pi connector, under omp's agent home): |
| 82 | + |
| 83 | +- `~/.omp/agent/extensions/remnic/index.ts` — omp auto-discovery wrapper |
| 84 | +- `~/.omp/agent/extensions/remnic/remnic.config.json` — private daemon URL, namespace, and auth token (`0600`) |
| 85 | +- `~/.omp/agent/extensions/remnic/README.md` — local operator notes |
| 86 | + |
| 87 | +To skip writing the extension and only create the connector/token: |
| 88 | + |
| 89 | +```bash |
| 90 | +remnic connectors install omp --config installExtension=false |
| 91 | +``` |
| 92 | + |
| 93 | +To target a non-default daemon or namespace: |
| 94 | + |
| 95 | +```bash |
| 96 | +remnic connectors install omp \ |
| 97 | + --config remnicDaemonUrl=http://127.0.0.1:4318 \ |
| 98 | + --config namespace=work |
| 99 | +``` |
| 100 | + |
| 101 | +### Install location |
| 102 | + |
| 103 | +The connector writes into the same agent directory omp auto-discovers |
| 104 | +extensions from, resolved the way omp's own `DirResolver` does: |
| 105 | + |
| 106 | +- The config dir name is `PI_CONFIG_DIR` (default `.omp`). |
| 107 | +- An active profile (`OMP_PROFILE`, falling back to `PI_PROFILE`) wins and |
| 108 | + targets `<configRoot>/profiles/<name>/agent`; omp discards `PI_CODING_AGENT_DIR` |
| 109 | + while a profile is active. |
| 110 | +- Otherwise `PI_CODING_AGENT_DIR` overrides the whole agent dir. |
| 111 | +- Otherwise the base is `~/.omp/agent`. |
| 112 | + |
| 113 | +Install under the same profile/env you launch omp with (e.g. |
| 114 | +`OMP_PROFILE=work remnic connectors install omp`) so the extension lands where |
| 115 | +that profile scans. `remnic connectors remove omp` sweeps the base agent dir and |
| 116 | +every `profiles/<name>/agent` under the config root, so removal cleans up a |
| 117 | +profile-scoped install even if the profile env is not set at remove time. omp's |
| 118 | +XDG redirection (`XDG_DATA_HOME`, …) relocates *data* dirs (sessions/state/cache), |
| 119 | +**not** the extension dir, so it does not affect where the connector installs. |
| 120 | + |
| 121 | +### Turn off omp's built-in memory |
| 122 | + |
| 123 | +omp ships its own memory backends (`memory.backend: local` and |
| 124 | +`memory.backend: mnemopi`). Those are **separate, per-project stores** that are |
| 125 | +*not* shared with other agents. To make Remnic the single source of truth, leave |
| 126 | +omp's backend off in `~/.omp/agent/config.yml`: |
| 127 | + |
| 128 | +```yaml |
| 129 | +memory: |
| 130 | + backend: off |
| 131 | +``` |
| 132 | +
|
| 133 | +Running both means two disjoint memories; pick Remnic (shared) or Mnemopi |
| 134 | +(local-only), not both. |
| 135 | +
|
| 136 | +## What The Extension Does |
| 137 | +
|
| 138 | +- Uses the `context` hook to recall relevant Remnic context before an agent turn. |
| 139 | +- Uses `message_end`, `turn_end`, and `session_shutdown` hooks to observe user, assistant, and tool activity with `sourceFormat: "pi"`. |
| 140 | +- Uses `session_before_compact` to flush Remnic LCM for the active session before omp compacts context, then records the compaction token delta. |
| 141 | +- Registers Remnic MCP tools as omp tools when the Remnic daemon token is configured. |
| 142 | +- Persists lightweight dedupe state with omp `custom` entries so repeated turns are not re-observed. |
| 143 | + |
| 144 | +All of these hooks exist in omp's extension event surface (it is a superset of |
| 145 | +Pi's), so the shared runtime extension binds without modification. |
| 146 | + |
| 147 | +## omp Commands |
| 148 | + |
| 149 | +The extension registers these slash commands: |
| 150 | + |
| 151 | +- `/remnic-status` — check daemon health |
| 152 | +- `/remnic-recall <query>` — recall Remnic context for a query |
| 153 | +- `/remnic-remember <memory>` — explicitly store a memory |
| 154 | +- `/remnic-lcm-search <query>` — search archived context |
| 155 | +- `/remnic-why` — inspect the last recall explanation |
| 156 | +- `/remnic-compact` — request compaction |
| 157 | + |
| 158 | +## Configuration |
| 159 | + |
| 160 | +The extension loads configuration from: |
| 161 | + |
| 162 | +1. `REMNIC_OMP_CONFIG` (or `REMNIC_PI_CONFIG`, which takes precedence if both are set) |
| 163 | +2. The explicit `configPath` written into the auto-discovery wrapper (`~/.omp/agent/extensions/remnic/remnic.config.json`) |
| 164 | + |
| 165 | +Supported config keys: |
| 166 | + |
| 167 | +| Key | Default | Description | |
| 168 | +|-----|---------|-------------| |
| 169 | +| `remnicDaemonUrl` | `http://127.0.0.1:4318` | Remnic HTTP/MCP daemon URL | |
| 170 | +| `authToken` | unset | Connector token generated by `remnic connectors install omp` | |
| 171 | +| `namespace` | unset | Remnic namespace for recall/observe/store requests | |
| 172 | +| `recallMode` | `auto` | Recall mode: `auto`, `minimal`, `full`, `graph_mode`, or `no_recall` | |
| 173 | +| `recallTopK` | `8` | Max recalled results | |
| 174 | +| `recallBudgetChars` | `12000` | Max recalled context injected into omp | |
| 175 | +| `recallEnabled` | `true` | Enable context-hook recall | |
| 176 | +| `observeEnabled` | `true` | Enable turn observation | |
| 177 | +| `observeSkipExtraction` | `false` | Archive observed messages without extraction | |
| 178 | +| `compactionEnabled` | `true` | Enable LCM flush/checkpoint coordination | |
| 179 | +| `mcpToolsEnabled` | `true` | Register Remnic MCP tools as omp tools | |
| 180 | +| `statusEnabled` | `true` | Set omp UI status from daemon health | |
| 181 | +| `requestTimeoutMs` | `60000` | HTTP/MCP request timeout for recall/observe/compaction/commands | |
| 182 | +| `startupRequestTimeoutMs` | `1000` | Shorter timeout for startup-sensitive probes so a slow or offline daemon can't stall omp boot | |
| 183 | + |
| 184 | +Boolean-like strings such as `"false"`, `"0"`, `"no"`, and `"off"` are treated as false. |
| 185 | + |
| 186 | +### Direct load (without the connector installer) |
| 187 | + |
| 188 | +You can load the package directly, pointing it at a config via `REMNIC_OMP_CONFIG`: |
| 189 | + |
| 190 | +```bash |
| 191 | +REMNIC_OMP_CONFIG=~/.omp/agent/extensions/remnic/remnic.config.json \ |
| 192 | + omp -e npm:@remnic/plugin-pi |
| 193 | +``` |
| 194 | + |
| 195 | +## API Surface |
| 196 | + |
| 197 | +omp uses the shared Remnic access layer, identical to Pi: |
| 198 | + |
| 199 | +- `POST /engram/v1/recall` |
| 200 | +- `POST /engram/v1/observe` |
| 201 | +- `POST /engram/v1/lcm/search` |
| 202 | +- `POST /engram/v1/lcm/compaction/flush` |
| 203 | +- `POST /engram/v1/lcm/compaction/record` |
| 204 | +- `POST /mcp` for MCP tool discovery and calls |
| 205 | + |
| 206 | +Both canonical `remnic.*` MCP tools and legacy `engram.*` aliases remain available through the daemon. |
| 207 | + |
| 208 | +## See Also |
| 209 | + |
| 210 | +- [Pi Coding Agent Integration](./pi.md) — the upstream Pi connector this shares its runtime with. |
| 211 | +- [Connector Setup Guide](./connector-setup.md) — MCP/HTTP config snippets for other agents. |
0 commit comments