Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ The agent can read memory files directly using `memory://` URLs with the `read`
| `view` | Show the current backend injection payload |
| `stats` | Show backend-specific memory statistics, when supported |
| `diagnose` | Show backend-specific diagnostics, when supported |
| `clear` / `reset` | Delete active backend memory data/artifacts |
| `clear` / `reset` | Clear backend-owned data where supported |
| `enqueue` / `rebuild` | Force consolidation/retention work for the active backend |

OpenViking memories live on the server and must be deleted by specific resource URI. Consequently, `/memory clear` and `/memory reset` fail for that backend without detaching the active OpenViking session state.

## How it works

Local summary memories are built by a background pipeline that runs at startup; `/memory enqueue` marks consolidation work that the next startup picks up. The pipeline is skipped for subagents and for sessions that are not persisted to a session file.
Expand Down
8 changes: 5 additions & 3 deletions docs/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ This only controls the startup splash animation. It does not rerun setup or chan

`omp config` with no subcommand, or `--help`, prints the help and lists settings. The `--json` flag is accepted by `list`, `get`, `set`, and `reset`.

Secret settings are never returned verbatim. Text output shows `(configured)` or `(not set)`; JSON keeps `value: null` and adds `configured` plus `redacted: true` so callers can distinguish presence without receiving the secret. Presence checks include supported environment overrides; OpenViking also includes the matching `ovcli.conf` profile.

### Value parsing

`omp config set` parses the value string according to the target key's schema type. The string is trimmed first.
Expand Down Expand Up @@ -540,7 +542,7 @@ compaction:
remoteEnabled: true

memory:
backend: off # off, local, hindsight, mnemopi
backend: off # off, local, hindsight, mnemopi, openviking
```

| Key | Type | Default | Notes |
Expand All @@ -555,7 +557,7 @@ memory:
| `compaction.keepRecentTokens` | number | `20000` | Recent tokens always preserved. |
| `compaction.remoteEnabled` | boolean | `true` | Allow remote compaction service. |
| `compaction.autoContinue` | boolean | `true` | Continue automatically after compaction. |
| `memory.backend` | enum | `off` | `off`, `local`, `hindsight`, `mnemopi`. Each backend has its own `hindsight.*` / `mnemopi.*` / `memories.*` tuning keys. |
| `memory.backend` | enum | `off` | `off`, `local`, `hindsight`, `mnemopi`, `openviking`. Each backend has its own `hindsight.*` / `mnemopi.*` / `openviking.*` / `memories.*` tuning keys. |
| `autolearn.enabled` | boolean | `false` | Experimental: after the agent stops, nudge it to capture lessons to memory and create/enhance isolated managed skills under `~/.omp/agent/managed-skills`. Enables the `manage_skill` tool (and `learn` when a memory backend is active). |
| `autolearn.autoContinue` | boolean | `false` | When `autolearn.enabled`, auto-run one capture turn at stop (uses extra tokens). Off = a passive reminder rides your next turn. |
| `autolearn.minToolCalls` | number | `5` | Only nudge after a turn that used at least this many tools. |
Expand Down Expand Up @@ -672,7 +674,7 @@ Provider credentials and custom model definitions are configured separately —

### Other groups

`omp config list` exposes many more grouped settings, including: `task.*` (subagent concurrency, isolation, model overrides), `skills.*` and `commands.*` (discovery toggles), `mcp.*`, `github.*`, `async.*`, `goal.*`, `loop.*`, `todo.*`, `magicKeywords.*`, `ttsr.*` (time-traveling stream rules), `display.*`, `startup.*`, `share.*`, `collab.*`, `stt.*`/`tts.*`, `memories.*`/`hindsight.*`/`mnemopi.*` (memory backends), and `bashInterceptor.*`. Each follows the same type/default rules shown above.
`omp config list` exposes many more grouped settings, including: `task.*` (subagent concurrency, isolation, model overrides), `skills.*` and `commands.*` (discovery toggles), `mcp.*`, `github.*`, `async.*`, `goal.*`, `loop.*`, `todo.*`, `magicKeywords.*`, `ttsr.*` (time-traveling stream rules), `display.*`, `startup.*`, `share.*`, `collab.*`, `stt.*`/`tts.*`, `memories.*`/`hindsight.*`/`mnemopi.*`/`openviking.*` (memory backends), and `bashInterceptor.*`. Each follows the same type/default rules shown above.

## Legacy migration

Expand Down
14 changes: 9 additions & 5 deletions docs/tools/learn.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@

## Outputs
- Lesson only:
- `content[0].text = "Lesson stored."` or `"Lesson queued for retention."`
- `content[0].text` distinguishes stored, queued, zero-memory completion, unavailable/interrupted extraction status, and completed extraction without a reported count.
- `details = { skill: null }`
- Lesson plus skill:
- `content[0].text = "<lesson result>. Created managed skill \"<name>\"."` or `"... Updated ..."`
- `details = { skill: "<name>" }`
- Authored-skill name conflict returns `isError: true` after storing/queueing the lesson and reports `details = { skill: null, shadowed: true }`.

## Flow
1. `LearnTool.createIf(...)` exposes the tool only when `autolearn.enabled` is true and `memory.backend` is `"hindsight"`, `"mnemopi"`, or `"local"`.
1. `LearnTool.createIf(...)` exposes the tool only when `autolearn.enabled` is true and `memory.backend` is `"hindsight"`, `"mnemopi"`, `"openviking"`, or `"local"`.
2. `execute(...)` stores the lesson first:
- Mnemopi: calls `rememberScoped(...)` with `source: "coding-agent-learn"`, `importance: 0.8`, `scope: "bank"`, extraction enabled, `veracity: "tool"`, and `memoryType: "fact"`.
- Local backend: appends through `localBackend.save(...)` with the same source and importance.
- OpenViking: follows [`retain`'s two-phase archive/extraction contract](./retain.md#flow) and maps the resulting state to the lesson output.
- Hindsight: enqueues retention with `state.enqueueRetain(memory, context)`.
3. If `skill` is absent, the tool returns after the memory write/queue.
4. If `skill` is present, the tool refuses `create` when an authored skill already claims the same sanitized name.
Expand All @@ -38,16 +39,17 @@
## Modes / Variants
- Memory-only lesson capture.
- Lesson plus managed skill create/update for repeatable procedures worth codifying as `SKILL.md`.
- Backend-specific memory persistence: queued Hindsight, scoped Mnemopi SQLite, or local file backend.
- Backend-specific memory persistence: queued Hindsight, scoped Mnemopi SQLite, two-phase OpenViking archive/extraction, or local files.

## Side Effects
- Filesystem: local memory backend writes under the agent directory; managed skills write to `~/.omp/agent/managed-skills/<name>/SKILL.md`.
- Network: Hindsight retention queues server-side work; Mnemopi/local paths do not make a network call from this tool directly.
- Network: Hindsight retention queues server-side work; OpenViking uses the remote archive/extraction path documented for [`retain`](./retain.md#side-effects); Mnemopi/local paths do not make a network call from this tool directly.
- Session state: reads memory backend state, settings, cwd, and session id.
- Background work: Hindsight retention may flush later.
- Background work: Hindsight retention may flush later. OpenViking continues monitoring unfinished extraction after the tool returns.

## Limits & Caps
- Availability requires both `autolearn.enabled` and a supported memory backend.
- OpenViking's explicit extraction wait is bounded by `openviking.captureTimeoutMs`; reaching the bound means queued, not failed.
- Managed skill names are sanitized to lowercase kebab-case, max 64 chars, starting with a letter or digit.
- Managed skill final file size is capped at `64_000` UTF-8 bytes.
- Managed skills never override authored skills; authored skills win discovery.
Expand All @@ -57,6 +59,8 @@
- `Mnemopi did not store the lesson (no memory id returned).` when Mnemopi silently fails to write.
- `Lesson was empty after sanitization; nothing stored.` for an empty local-backend lesson.
- `Hindsight backend is not initialised for this session.` when Hindsight state is missing.
- `OpenViking backend is not initialised for this session.` when OpenViking state is missing.
- OpenViking request, protocol, and extraction failures are surfaced as tool errors. Ambiguous archive acknowledgement remains pending reconciliation rather than resending the lesson; bounded waits and unavailable task status use the non-error outputs described above.
- Managed-skill write failures are rethrown as `<lesson result>, but the managed skill could not be written: <reason>`.

## Notes
Expand Down
18 changes: 12 additions & 6 deletions docs/tools/recall.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
- `packages/coding-agent/src/mnemopi/state.ts` — scoped local recall and result formatting with ids.
- `packages/coding-agent/src/mnemopi/config.ts` — local bank scoping and recall limits.
- `docs/tools/retain.md` — shared backend, storage, scoping, and retention behavior.
- OpenViking collaborators:
- `packages/coding-agent/src/openviking/state.ts` — scoped search, score filtering, content budgets, and memory URI formatting.
- `packages/coding-agent/src/openviking/client.ts` — authenticated search and content reads.

## Inputs

Expand All @@ -40,24 +43,25 @@ When no matches exist:
- `details = {}`

## Flow
1. `MemoryRecallTool.createIf(...)` exposes the tool when `memory.backend` is either `"hindsight"` or `"mnemopi"`.
1. `MemoryRecallTool.createIf(...)` exposes the tool when `memory.backend` is `"hindsight"`, `"mnemopi"`, or `"openviking"`.
2. `execute(...)` wraps the operation in `untilAborted(...)`.
3. If the backend is `mnemopi`:
- it reads `session.getMnemopiSessionState()` and throws if the backend was not started;
- it calls `state.recallResultsScoped(params.query)`;
- scoped recall queries each configured recall bank with `recallEnhanced(query, recallLimit, { includeFacts: true, channelId: bank })`, merges/deduplicates results by id/content, sorts them, and truncates to `recallLimit`;
- in `per-project-tagged`, the shared bank may receive one extra fallback query with project-bank literal tokens stripped so broad global memories still match;
- results are formatted with ids for later `memory_edit` use.
4. If the backend is `hindsight`:
4. If the backend is `openviking`, it searches the active parent state, applies the configured score threshold, resolves bounded content, and returns `memory://` ids for follow-up reads.
5. If the backend is `hindsight`:
- it reads `session.getHindsightSessionState()` and throws if the backend was not started;
- it calls `state.client.recall(...)` with `bankId`, query, configured `budget`, `maxTokens`, `types`, and bank-scope tag filters;
- `HindsightApi.recall(...)` POSTs `/v1/default/banks/{bank_id}/memories/recall`;
- results are formatted into a plain-text list with `formatMemories(...)`.
5. Backend failures are logged with `logger.warn("recall failed", ...)` and rethrown as `Error` instances when needed.
6. Backend failures are logged with `logger.warn("recall failed", ...)` and rethrown as `Error` instances when needed.

## Modes / Variants
- Tool path: explicit query-only recall. It does not compose context from recent turns.
- Backend auto-recall has a richer query-composition path in `HindsightSessionState.beforeAgentStartPrompt(...)` / `maybeRecallOnAgentStart(...)` and `MnemopiSessionState.beforeAgentStartPrompt(...)` / `maybeRecallOnAgentStart(...)`.
- Backend auto-recall has a richer query-composition path in `HindsightSessionState.beforeAgentStartPrompt(...)` / `maybeRecallOnAgentStart(...)`, `MnemopiSessionState.beforeAgentStartPrompt(...)` / `maybeRecallOnAgentStart(...)`, and `OpenVikingSessionState.beforeAgentStartPrompt(...)`. OpenViking refreshes its injected context before every agent turn while auto-recall is enabled.
- Hindsight bank scoping:
- `global` — no tag filter.
- `per-project` — separate bank id per project label (git primary checkout root basename; cwd basename outside a repo).
Expand All @@ -72,13 +76,14 @@ When no matches exist:
- Network
- Hindsight: `POST /v1/default/banks/{bank_id}/memories/recall`.
- Mnemopi: none unless configured local runtime providers perform embedding/LLM work during recall.
- OpenViking: `POST /api/v1/search/recall` plus skill enrichment through `POST /api/v1/search/find`. OpenViking 0.4.8 rejects the newer `peer_scope` field but already scopes recall to the actor header, so that exact extra-field rejection is retried without the field. Other actor-scope failures remain fail-closed. When no actor peer isolation is required, servers without the recall endpoint may use `/api/v1/search/find` for global memories. Selected results without embedded content may also require `GET /api/v1/content/read`.
- Session state
- None on success for the explicit tool path. Unlike backend auto-recall, this tool does not update `lastRecallSnippet` or refresh the system prompt.
- Background work / cancellation
- Aborts through `untilAborted(...)` if the tool call signal is cancelled.
- Aborts through `untilAborted(...)` if the tool call signal is cancelled. OpenViking also forwards that signal into remote search and content-read requests.

## Limits & Caps
- Tool availability requires `memory.backend` to be `"hindsight"` or `"mnemopi"`; default `memory.backend` is `"off"`.
- Tool availability requires `memory.backend` to be `"hindsight"`, `"mnemopi"`, or `"openviking"`; default `memory.backend` is `"off"`.
- Hindsight client default budget for raw `HindsightApi.recall(...)` is `"mid"`; this tool overrides from config.
- Hindsight recall settings:
- `hindsight.recallBudget = "mid"`
Expand All @@ -92,6 +97,7 @@ When no matches exist:
## Errors
- Throws `Mnemopi backend is not initialised for this session.` when `memory.backend == "mnemopi"` but no state exists.
- Throws `Hindsight backend is not initialised for this session.` when `memory.backend == "hindsight"` but no state exists.
- Throws `OpenViking backend is not initialised for this session.` when `memory.backend == "openviking"` but no state exists.
- Hindsight HTTP and fetch failures become `HindsightError` with `statusCode` and parsed `details` when available.
- Mnemopi recall target failures inside `collectScopedRecallResults(...)` are caught per bank and logged only when `mnemopi.debug` is enabled; if all targets fail, the tool can return `No relevant memories found.`
- Non-`Error` failures caught by the tool are normalized to `new Error(String(err))` before rethrow.
Expand Down
16 changes: 11 additions & 5 deletions docs/tools/reflect.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,26 @@ Mnemopi:
- `details = {}`
- The local path performs recall plus formatting; it does not call a separate synthesis endpoint.

OpenViking:
- Searches the active remote scope and returns `Based on recalled OpenViking memories:` followed by bounded context with `memory://` ids.

## Flow
1. `MemoryReflectTool.createIf(...)` exposes the tool when `memory.backend` is either `"hindsight"` or `"mnemopi"`.
1. `MemoryReflectTool.createIf(...)` exposes the tool when `memory.backend` is `"hindsight"`, `"mnemopi"`, or `"openviking"`.
2. `execute(...)` runs under `untilAborted(...)`.
3. If the backend is `mnemopi`:
- it reads `session.getMnemopiSessionState()` and throws if the backend was not started;
- if `context` has non-whitespace content, it recalls with `<query>\n\nAdditional context:\n<context>`; otherwise it recalls with `query`;
- it calls `state.recallResultsScoped(...)` using the same local scoping and merge behavior as `recall`;
- if results exist, it renders them through `state.formatContextScoped(...)` and prefixes `Based on recalled memories:`.
4. If the backend is `hindsight`:
4. If the backend is `openviking`, it appends optional context to the query, searches the active parent state, and formats matching resources with ids.
5. If the backend is `hindsight`:
- it reads `session.getHindsightSessionState()` and throws if the backend was not started;
- it calls `ensureBankExists(...)` with the current `bankId`, config, and the session state's `banksSet`;
- `ensureBankExists(...)` best-effort `PUT`s `/v1/default/banks/{bank_id}` (`createBank`) with optional `reflect_mission` / `retain_mission` once per bank per session state; failures are swallowed;
- it calls `state.client.reflect(...)` with `query`, optional `context`, configured recall budget, and bank-scope tag filters;
- `HindsightApi.reflect(...)` POSTs `/v1/default/banks/{bank_id}/reflect` and defaults its own budget to `"low"` when callers omit one; this tool always passes the configured budget;
- blank or whitespace-only responses are replaced with `No relevant information found to reflect on.`
5. Backend failures are logged with `logger.warn("reflect failed", ...)` and rethrown as `Error` instances when needed.
6. Backend failures are logged with `logger.warn("reflect failed", ...)` and rethrown as `Error` instances when needed.

## Modes / Variants
- Hindsight tool path: one remote reflect request, optionally focused by `context`.
Expand All @@ -69,13 +73,14 @@ Mnemopi:
- Network
- Hindsight: optional `PUT /v1/default/banks/{bank_id}` from `ensureBankExists(...)`, then `POST /v1/default/banks/{bank_id}/reflect`.
- Mnemopi: none unless configured embedding or LLM providers are used by the local runtime during recall.
- OpenViking: the remote search and optional content-read requests documented for [`recall`](./recall.md#side-effects).
- Session state
- Reads session-held backend scope and config only. Does not update `lastRecallSnippet`, Hindsight mental-model cache, or retain queues.
- Background work / cancellation
- Aborts through `untilAborted(...)` if the tool call signal is cancelled.
- Aborts through `untilAborted(...)` if the tool call signal is cancelled. OpenViking also forwards that signal into remote search and content-read requests.

## Limits & Caps
- Tool availability requires `memory.backend` to be `"hindsight"` or `"mnemopi"`; default `memory.backend` is `"off"`.
- Tool availability requires `memory.backend` to be `"hindsight"`, `"mnemopi"`, or `"openviking"`; default `memory.backend` is `"off"`.
- Tool-level params: only `query` is required; `context` is optional.
- Hindsight budget setting comes from `hindsight.recallBudget`, default `"mid"`.
- Hindsight `reflect` has no client-side token cap parameter here; unlike `recall`, the tool does not pass `maxTokens`.
Expand All @@ -85,6 +90,7 @@ Mnemopi:
## Errors
- Throws `Mnemopi backend is not initialised for this session.` when `memory.backend == "mnemopi"` but no state exists.
- Throws `Hindsight backend is not initialised for this session.` when `memory.backend == "hindsight"` but no state exists.
- Throws `OpenViking backend is not initialised for this session.` when `memory.backend == "openviking"` but no state exists.
- Hindsight HTTP and fetch failures become `HindsightError` with `statusCode` and parsed `details` when available.
- Hindsight `ensureBankExists(...)` failures are silent to the tool caller; only the later reflect request can fail visibly.
- Mnemopi recall target failures inside `collectScopedRecallResults(...)` are caught per bank and logged only when `mnemopi.debug` is enabled; if all targets fail, the tool can return the no-information text.
Expand Down
Loading