Skip to content

OMP (oh-my-pi) is not a first-class harness: aft_* tools mount under xd:// and per-tool prompt guidance never reaches the system prompt #300

Description

@Qiiks

AFT issue: OMP (oh-my-pi) is not a first-class harness — tools mount under xd:// and prompt-injection paths degrade

Summary

@cortexkit/aft-pi targets upstream Pi (@earendil-works/pi-coding-agent). It works on OMP (oh-my-pi, a Pi-compatible harness) only because OMP implements a large subset of the Pi extension API — but two Pi-specific assumptions silently degrade the experience on OMP. Reporting both with evidence, plus what a fix would look like.

Repro environment: OMP 18.x (@oh-my-pi/pi-coding-agent), @cortexkit/aft-pi@0.55.1, hoist_builtin_tools: false, tool_surface: "all", semantic_search: true.

1. All AFT tools mount under xd:// instead of registering top-level

Mechanism

OMP decides per tool whether it ships in the request's tools array (top-level) or mounts as an xd:// device invoked via write xd://<tool>:

  • isMountableUnderXdev (oh-my-pi packages/coding-agent/src/tools/xdev.ts:84-87): mounts everything with loadMode === "discoverable".
  • Extension-registered tools resolve their loadMode in RegisteredToolAdapter (extensibility/extensions/wrapper.ts:48) via defaultLoadModeForToolName (tools/essential-tools.ts:42-45): an explicitly declared mode wins; undeclared → "discoverable" unless the name is one of 10 hardcoded essentials (read, write, bash, edit, glob, eval, task, hub, learn, manage_skill).
  • packages/pi-plugin/src never passes loadMode to registerTool (zero occurrences in dist/index.js and in the current source tree). Result: every aft_*/ast_grep_* tool mounts under xd:// on OMP, regardless of config.

On OpenCode the same tools are all top-level (OpenCode has no xdev mounting and its own hoisting model), and on upstream Pi there is no mount mechanism at all — so this gap is OMP-specific and invisible to the author's testing surface.

Impact

  • Every AFT call costs a write xd://aft_zoom round-trip instead of a direct tool call.
  • AFT's carefully tuned promptSnippet/promptGuidelines fields (see issue 2) never reach the system prompt on OMP: the device catalog shows a one-line summary (first description line, capped at 200 bytes for third-party tools — xdev.ts:186-205), not the guidelines.
  • Partial workaround exists user-side (tools.xdevInlineDevices: ["aft_*", "ast_grep*"] inlines docs+schema into the prompt), but calls still ride the device transport, and nothing makes the tools top-level.

Suggested fix

Declare presentation intent on registration, falling back sensibly per harness:

pi.registerTool(withPathAliasPreparation({
  name: "aft_zoom",
  loadMode: "essential",   // or a config-gated choice
  ...
}))

Since OMP honors a declared loadMode and Pi (upstream) ignores unknown fields, adding loadMode: "essential" to the register calls is backward-compatible with both. A config gate ("tool_presentation": "top_level" | "host_default", default host_default) would let users choose without forking.

2. System-prompt injection works, but per-tool guidance fields are dead on OMP

What AFT injects today

  • Workflow hints block: packages/pi-plugin/src/workflow-hints.ts registers a before_agent_start handler that appends the "IMPORTANT NOTICE about your tools" block (bash-compression tips, code-exploration routing, aft_inspect guidance, callgraph ops, background-bash rules). Gated by absentTools/toolSurface/hoistBuiltins so absent tools aren't advertised (workflow-hints.ts:203-227).
  • Per-tool guidance: promptSnippet and promptGuidelines on registered tools (tools/hoisted.ts:6-10 — "teach the model our argument shape in Pi's system prompt"; tools/bash.ts:489-498 — the "DO NOT use bash for code search … use aft_search" steer).
  • Tool-result steering: withBashHints (index.ts:37165 in dist) appends grep/rewrite hints to bash output, and the Rust bridge emits a grep-rewrite footer steered by the aft_search_registered configure flag (index.ts:683-688).

The OMP gap

Upstream Pi renders promptSnippet/promptGuidelines into its system prompt (that's why the fields exist — hoisted.ts:7-8: "Pi's built-ins use generic one-liners otherwise"). OMP does not consume them: its system-prompt builder uses tool description only; promptGuidelines appears exactly once in OMP's codebase as an unused type field (extensibility/extensions/types.ts:696), and promptSnippet has zero references. AFT's bash-search prohibition and per-tool usage rules therefore never reach the model's system prompt on OMP.

The before_agent_start chain DOES work on OMP (OMP fires the event with systemPrompt: string[] and chains string results — extensibility/extensions/runner.ts:1730-1755 normalizes a returned string into the array), so the workflow-hints block lands. That's why the symptoms are subtle: routing guidance arrives, but the per-tool argument-shape teaching and the bash-search STOP steer don't. Net effect on OMP: the agent sees AFT's tool names and descriptions but none of the per-tool behavioral guidance that makes the surface feel first-class on Pi/OpenCode.

Suggested fix

Either (a) move critical per-tool rules (the bash-search STOP steer especially) into the workflow-hints block, which is harness-portable, or (b) accept a small per-harness shim: on OMP, fold promptSnippet/promptGuidelines into each tool's description at registration time (OMP renders descriptions verbatim). (b) is a ~10-line change in the shared registration helper (withPathAliasPreparation or the surface registry) gated on harness detection.

3. Harness awareness today

The repo has zero OMP-specific code: no oh-my-pi/OMP references in packages/ (the only mentions are hashline-oracle provenance notes in crates/ — credit for the hashline format OMP authored); no OMP harness detection in the pi-plugin; README.md:52,66-67 documents exactly two harnesses (OpenCode, Pi). The author's own design makes this rational: the adapters are deliberately thin, per-harness, and hoisting-centric; OMP's mount model is a third presentation regime the adapter never had to consider. This issue is meant to close that visibility gap, not to relitigate the architecture.

Happy to test any fix against OMP — we run OMP as the primary harness with hoist_builtin_tools: false + full aft_* surface daily.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions