diff --git a/README.md b/README.md index a9d03c0f5..db1309caa 100644 --- a/README.md +++ b/README.md @@ -219,7 +219,7 @@ Stealth's on by default, so pages see a normal user instead of a headless bot. T ## Whatever the task needs, _it's already in the box_. -32 tools live in the same namespace as `read` and `bash`. Pin the active set with `--tools read,edit,bash,…` and the rest stay hidden but indexed — `search_tool_bm25` pulls them back in mid-session when `tools.discoveryMode` says so. +32 tools live in the same namespace as `read` and `bash`. Pin the active set with `--tools read,edit,bash,…`; rarely used discoverable tools stay behind `xd://` devices. `read xd://` lists them, and `write xd://` runs one when `tools.xdev` is enabled. **Files & search** @@ -245,9 +245,8 @@ Stealth's on by default, so pages see a normal user instead of a headless bot. T **Coordination** - `task` — fan out subagents in parallel, optionally workspace-isolated. -- `irc` — short prose between live agents in this process. +- `hub` — message live agents, wait on or cancel background jobs, and supervise long-running processes. - `todo` — ordered mutations over the session todo list with phase tracking. -- `job` — wait on or cancel background jobs. - `ask` — structured follow-up questions for interactive runs. **Outside the box** @@ -270,9 +269,8 @@ Stealth's on by default, so pages see a normal user instead of a headless bot. T **Misc** - `resolve` — apply or discard a queued preview action. -- `search_tool_bm25` — BM25 over the hidden tool index; activates top matches mid-session. -Setting-gated, off by default: `github`, `inspect_image`, `tts`, `checkpoint`, `rewind`, `search_tool_bm25`, `retain`, `recall`, `reflect`. Flip them on once, scoped per project. +Setting-gated, off by default: `github`, `inspect_image`, `tts`, `checkpoint`, `rewind`, `retain`, `recall`, `reflect`. Flip them on once, scoped per project. [Full reference →](https://omp.sh/docs/tools) diff --git a/docs/advisor-watchdog.md b/docs/advisor-watchdog.md index a4881fa5c..65870bf11 100644 --- a/docs/advisor-watchdog.md +++ b/docs/advisor-watchdog.md @@ -80,7 +80,7 @@ Every advisor has the `advise` tool for surfacing notes into the primary transcr - `grep` - `glob` -A `WATCHDOG.yml` roster entry may broaden this with `tools: [...]`, selecting any subset of the built-in pool the session actually built (a factory that returned `null`, e.g. `lsp` with no matching servers, is absent). Grantable tools include mutating ones: `edit`, `write`, `bash`, `eval`, `browser`, `debug`, `ast_edit`, `task`, `job`, and the memory tools. Tool names outside [`BUILTIN_TOOL_NAMES`](../packages/coding-agent/src/tools/builtin-names.ts) are dropped with a warning. +A `WATCHDOG.yml` roster entry may broaden this with `tools: [...]`, selecting any subset of the built-in pool the session actually built (a factory that returned `null`, e.g. `lsp` with no matching servers, is absent). Grantable tools include mutating ones: `edit`, `write`, `bash`, `eval`, `browser`, `debug`, `ast_edit`, `task`, `hub`, and the memory tools. Tool names outside [`BUILTIN_TOOL_NAMES`](../packages/coding-agent/src/tools/builtin-names.ts) are dropped with a warning. Advisor grants are not routed through the primary agent's approval wrapper. The advisor pool is built from the built-in tool factories against its own `-advisor` `ToolSession` and then filtered by `WATCHDOG.yml`; it is not the primary `toolRegistry` wrapped with `ExtensionToolWrapper`. Granting write- or exec-tier tools therefore lets the advisor invoke those tools directly, subject to the tool's own runtime guards but not to `tools.approvalMode` / `tools.approval.` prompts. Keep mutating grants narrow and trusted. @@ -233,7 +233,7 @@ Fields: - `instructions` (top level): shared prompt prepended to every advisor's system prompt alongside `WATCHDOG.md`. Concatenated across all discovered `WATCHDOG.yml` files. - `advisors[].name`: human label; slugified for the session id and the `/__advisor.jsonl` filename. Duplicate slugs across files are resolved by the same specificity rule as `WATCHDOG.md` discovery (project leaf > project ancestor > user). - `advisors[].model`: optional model selector with optional `:level` thinking suffix (e.g. `x-ai/grok-code-fast:high`). Omitted → the advisor uses `modelRoles.advisor`. -- `advisors[].tools`: optional list of built-in tool names to grant. Omitted or empty → the default `read`/`grep`/`glob` subset. Any name in [`BUILTIN_TOOL_NAMES`](../packages/coding-agent/src/tools/builtin-names.ts) is accepted, including mutating tools (`edit`, `write`, `bash`, `eval`, `browser`, `debug`, `ast_edit`, `task`, `job`, and the memory tools). Legacy aliases (`search`→`grep`, `find`→`glob`) are normalized. Unknown names are dropped with a warning. See [Tools and isolation](#tools-and-isolation) for the safety implications of granting mutating tools. +- `advisors[].tools`: optional list of built-in tool names to grant. Omitted or empty → the default `read`/`grep`/`glob` subset. Any name in [`BUILTIN_TOOL_NAMES`](../packages/coding-agent/src/tools/builtin-names.ts) is accepted, including mutating tools (`edit`, `write`, `bash`, `eval`, `browser`, `debug`, `ast_edit`, `task`, `hub`, and the memory tools). Legacy aliases (`search`→`grep`, `find`→`glob`) are normalized. Unknown names are dropped with a warning. See [Tools and isolation](#tools-and-isolation) for the safety implications of granting mutating tools. - `advisors[].instructions`: this advisor's specialization, appended after the shared baseline. Both instruction fields expand `@path` imports like `WATCHDOG.md`. ### Discovery locations @@ -277,4 +277,4 @@ Why a file: The file follows session switches: on `/new`, resume/switch, and branch the recorder reopens at the new session's path on the next advisor turn; before a `/drop` deletes the old artifacts dir the recorder feed is detached and drained so a queued write cannot recreate the deleted file. The on-disk log is append-only and independent of the in-memory context — re-primes and compaction never truncate it. -The advisor is never a peer. The `advisor`-kind registry ref is excluded from every agent-facing surface — the `irc` peer roster and broadcast targets, the subagent peer prompt, and the `history://` index/lookup/completions — and cannot be messaged (`irc send` and collab chat refuse it) or revived/killed from the Agent Hub or collab. It is not addressable as a peer, regardless of what tools it has been granted. +The advisor is never a peer. The `advisor`-kind registry ref is excluded from every agent-facing surface — the `hub` peer roster and broadcast targets, the subagent peer prompt, and the `history://` index/lookup/completions — and cannot be messaged (`hub` send and collab chat refuse it) or revived/killed from the Agent Hub or collab. It is not addressable as a peer, regardless of what tools it has been granted. diff --git a/docs/compaction.md b/docs/compaction.md index 186d53054..3d9790691 100644 --- a/docs/compaction.md +++ b/docs/compaction.md @@ -164,7 +164,7 @@ If pruning changes entries, session storage is rewritten and agent message state ### Useless-result elision -Tools can flag a finished result as contextually useless — a search with zero matches, a `job` poll that timed out with everything still running, an empty `irc` inbox drain. The flag originates on the tool result (`AgentToolResult.useless`, set via `ToolResultBuilder.useless()` or directly on the returned object), is copied by the agent loop onto the persisted `ToolResultMessage` (never together with `isError` — errors always win), and is consumed in three places: +Tools can flag a finished result as contextually useless — a search with zero matches, a `hub` wait that timed out with everything still running, an empty `hub` inbox drain. The flag originates on the tool result (`AgentToolResult.useless`, set via `ToolResultBuilder.useless()` or directly on the returned object), is copied by the agent loop onto the persisted `ToolResultMessage` (never together with `isError` — errors always win), and is consumed in three places: - **Per-turn stale-result pass** (`pruneSupersededToolResults`, gated by `compaction.dropUseless`, default on): flagged results are blanked to the exact placeholder `[Uneventful result elided]` (`USELESS_NOTICE`) with the same cache-aware timing as superseded reads — only when the suffix after the candidate is small (≤ ~8k tokens) or the session has idled past the provider prompt-cache lifetime. Results smaller than the notice itself are never blanked (no savings), and protected tools are exempt. - **Threshold prune** (`pruneToolOutputs`): flagged results bypass the protect-recent window, same as superseded reads, and receive `USELESS_NOTICE` instead of the token-count placeholder. diff --git a/docs/custom-tools.md b/docs/custom-tools.md index 9f74137fd..9c6d63e0c 100644 --- a/docs/custom-tools.md +++ b/docs/custom-tools.md @@ -129,7 +129,7 @@ From `types.ts` and `loader.ts`: - `typebox`: zod-backed compatibility shim for legacy TypeBox-style schemas - `zod`: injected `zod/v4` module (canonical for new schemas) - `pi`: injected `@oh-my-pi/pi-coding-agent` exports -- `pushPendingAction(action)`: register a preview action for hidden `resolve` tool (`docs/resolve-tool-runtime.md`) +- `pushPendingAction(action)`: register a preview action finalized via plain-text writes to `/xdev/resolve` or `/xdev/reject` (`docs/resolve-tool-runtime.md`) Loader starts with a no-op UI context and requires host code to call `setUIContext(...)` when real UI is ready. ## Execution contract and typing diff --git a/docs/resolve-tool-runtime.md b/docs/resolve-tool-runtime.md index 6aadf6168..97001b01e 100644 --- a/docs/resolve-tool-runtime.md +++ b/docs/resolve-tool-runtime.md @@ -1,145 +1,53 @@ -# Resolve tool runtime internals +# Resolution devices runtime -This document explains how preview/apply workflows are modeled in coding-agent and how built-in or custom tools can participate via the pending-invoker registry and `pushPendingAction`. (Pending previews live in a separate non-forcing registry inside `ToolChoiceQueue`; only genuine hard forces use the consuming directive queue.) +Pending previews and plan approval no longer use a `resolve` tool. They finalize through three plain-text writes handled by `packages/coding-agent/src/tools/resolve.ts`: -## Scope and key files +- `/xdev/resolve` — apply the pending staged preview; body = reason text +- `/xdev/reject` — discard the pending staged preview; body = reason text +- `/xdev/propose` — submit the plan for approval while plan mode is active; body = the plan slug/title (`` for `local://-plan.md`) -- [`src/tools/resolve.ts`](../packages/coding-agent/src/tools/resolve.ts) -- [`src/tools/ast-edit.ts`](../packages/coding-agent/src/tools/ast-edit.ts) -- [`src/extensibility/custom-tools/types.ts`](../packages/coding-agent/src/extensibility/custom-tools/types.ts) -- [`src/extensibility/custom-tools/loader.ts`](../packages/coding-agent/src/extensibility/custom-tools/loader.ts) -- [`src/sdk.ts`](../packages/coding-agent/src/sdk.ts) +## Preview flows -## What `resolve` does +Preview producers call `queueResolveHandler(...)` with `apply(reason)` and optional `reject(reason)` callbacks. That registers a non-forcing pending invoker in `ToolChoiceQueue`. -`resolve` is a hidden tool that finalizes a pending preview action. +While a preview is pending, `AgentSession.nextToolChoiceDirective()` returns a soft requirement: -- `action: "apply"` executes the queued action's `apply(reason, extra)` callback and returns that result with resolve metadata. -- `action: "discard"` invokes `reject(reason, extra)` if provided; otherwise returns `Discarded: