Skip to main content

Runtime overview

Asymptote supports Senpi, the standalone edition of oh-my-openagent (OMO), through a managed local extension.
oh-my-openagent ships three editions. Ultimate is a plugin riding OpenCode; Light is a plugin riding Codex CLI; both already flow through Asymptote’s existing OpenCode and Codex CLI integrations, so no separate work is needed for them. Senpi is the one edition with no host of its own: an in-flight fork of pi-mono that OMO brands and bundles its own extension into, distributed as the omo command. This page covers that edition only.
Senpi is a hard fork of pi-mono, as Pi, Oh My Pi, and Prime Agent are. All four are supported separately and recorded under their own harness names, because they are separately installed products that one machine can run side by side. Senpi fits neither of Asymptote’s two usual integration shapes. It has no hooks configuration file to merge a managed hook block into, and no OpenTelemetry export to point at the local collector. Its documented observation surface is the TypeScript extension API it inherited from Pi, so the integration is extension-shaped: one Asymptote-owned extension file forwards runtime events to beacon-hooks, the same shape as the Pi, Oh My Pi, Prime Agent, OpenCode and Cline integrations.

Kept pi-mono’s tool set

Unlike Prime Agent, which routes essentially everything through a single Python kernel, Senpi kept pi-mono’s ordinary built-in tools — bash, read, edit, write, grep, find, and ls — alongside its own additions. So its telemetry shape looks like Pi’s and Oh My Pi’s rather than Prime Agent’s: a shell command is command.executed with a real command line, an edit is file.modified with the unified patch, and a read is file.read. Senpi’s own ExtensionEvent surface is larger than Pi’s — it adds tool_execution_start/tool_execution_end for execution progress, turn_start/turn_end for turn bookkeeping, agent_start/agent_end/agent_settled, model_select, and more — but none of those describe a new kind of agent action that tool_call/tool_result do not already cover, so the managed extension leaves them unsubscribed for the same reason it ignores streaming and provider internals on every other pi-mono fork.

Prerequisites

Before enabling Senpi telemetry, make sure:
  • Senpi’s omo edition is installed (bun add -g omo-ai@beta) and available as the omo executable, or has a local state directory at ~/.omo/agent.
  • beacon endpoint install has run so shared endpoint config and runtime log paths exist.
  • Senpi is restarted after install or removal so new sessions load the updated extension.

Collection path

Asymptote’s managed Senpi extension is a single TypeScript file at one of two auto-discovered extension locations: User level is the default, because it follows the operator rather than one checkout. beacon endpoint discover reports on the user path only, so a project-level extension does not appear in discovery output.
The project path keeps the agent segment, the same shape Prime Agent uses. Senpi’s config directory name for this brand is .omo, and its own directory resolver joins the agent segment under the working directory just as it does under the home directory — where Pi uses .pi/extensions and Oh My Pi uses .omp/extensions at project scope. A file written to ./.omo/extensions/ is never loaded.
OMO_CODING_AGENT_DIR replaces the user-level agent directory outright, and Asymptote honors it — including a leading ~, which the runtime expands before use. When it is unset, Asymptote falls back to SENPI_CODING_AGENT_DIR and then PI_CODING_AGENT_DIR, the same two legacy prefixes Senpi’s own brand profile keeps readable: SENPI is the upstream engine’s own name, and PI is pi-mono’s. None of the three moves the project path, because Senpi does not consult any of them there. Asymptote identifies its own extension file by the marker beacon-managed-omo-extension:v1. The version suffix is part of the contract with the extension source: it is what lets a repair recognize a stale file instead of leaving it in place. A beacon.ts without the marker belongs to somebody else, so install will not overwrite it and discovery does not report it as Asymptote telemetry. The marker is distinct from Pi’s, Oh My Pi’s, and Prime Agent’s, so a file found at any of the four paths is attributed to the runtime that actually loads it. Senpi has no OpenTelemetry export for Asymptote to configure, so there is no OTLP path for this runtime.

Discovery and status

Asymptote detects Senpi through the omo executable, and treats the ~/.omo/agent state directory as an additional signal. Senpi installed through npm into a directory this process did not inherit on PATH is not visible as an executable, because a shell alias, a version manager, or a per-project install can all hide it while the state directory is still present. The Pi, Oh My Pi, Prime Agent, OpenCode, Cursor, and Hermes probes use the same fallback. senpi is deliberately not probed for. It is the upstream engine’s own binary name, and a machine can have plain, un-OMO’d Senpi installed without oh-my-openagent at all — probing for it here would claim an install this integration did not verify.
Show Senpi discovery state
Senpi reports as the omo_senpi harness with capability plugin: An unmarked extension file reports disabled rather than enabled, because reporting it as enabled would show the runtime as covered while no events arrive.

Install or configuration support

beacon endpoint install prepares shared endpoint config and runtime log paths. The extension is installed separately, because Senpi loads it from the user’s own profile rather than from a machine-wide location:
omo, omo_senpi, and omo-senpi all resolve to this runtime. Bare senpi and oh-my-openagent are deliberately not accepted: plain Senpi is a separately installable engine you can run without OMO at all, and oh-my-openagent also names OMO’s OpenCode and Codex CLI editions, which install through the existing OpenCode and hook-config paths rather than through this extension. Accepting either spelling here would claim a name that belongs to a different install. Install writes one file and refuses to touch a beacon.ts it did not write, so an extension of your own that happens to share the filename is left alone and the install fails loudly rather than replacing it. Uninstall removes only a file carrying this runtime’s marker. status reports installed=false when the extension exists but points at a hook binary that is no longer there, which happens after a Beacon uninstall, a partly applied update, or a home directory restored onto a different machine. In each case Senpi loads an extension that spawns nothing.

Telemetry coverage

Harness names are matched against a closed set of spellings rather than by substring. omo is an ordinary three-letter string that could appear inside an unrelated harness attribute, so a substring rule would misattribute sessions that are not Senpi’s.

Data handling

Senpi content is handled like every other runtime. Prompts, command lines, command output, tool arguments, paths, diffs, and reasoning text are retained in local or customer-controlled logs, with local secret redaction and per-string limits applied before writing, and a hash and byte count on each content-bearing event. Events over the 64 KiB limit drop raw and retained content, preserve stable metadata, and set field_truncated. The extension itself sends nothing over the network. It spawns the local beacon-hooks binary with a fixed argv and writes the event to its stdin. A send that has not completed in two seconds is abandoned so Beacon cannot stall Senpi’s agent loop, and a failure to spawn costs the event rather than the run. Senpi’s own telemetry — the anonymous, PostHog-backed “OmO Native” analytics pipeline documented in its senpi-telemetry.md — is unrelated to this integration. It reports only aggregated buckets and counters with no raw content, and Asymptote neither reads from it nor writes to it.

Known gaps

  • No approval telemetry. Senpi’s tool_call event lets an extension block a call, but that is an extension deciding rather than an operator being asked. Its own permission-system builtin owns the real approval prompt without publishing it as an extension event, so Beacon records these as tool activity and writes no approval events. Pi and Prime Agent work the same way for the same reason; Oh My Pi is the fork that does report real ones. Detections in rules/approval-abuse/ do not fire on Senpi activity.
  • No enforcement. As with every other runtime, enforcement stays behind the optional, off-by-default policy provider seam (BEACON_POLICY_PROVIDER), which is not wired to Senpi.
  • Streaming and progress events are not collected. The extension subscribes to seven of Senpi’s event types and ignores the rest — provider request and response internals, streaming message and tool-execution updates, turn bookkeeping, compaction, model-select, and TUI plumbing. Assistant output is recorded once when a message finalizes rather than token by token, so Beacon stays out of the streaming path.
  • The OpenCode and Codex CLI editions are out of scope for this page. They ride the existing OpenCode and Codex CLI integrations rather than this extension, and are not separately attributed as omo-branded sessions today.

Deployment notes

The extension is loaded when Senpi starts, so an install taken while it is running takes effect on the next launch. Confirm discovery sees the runtime, then generate one Senpi event and check the log:

Pi

The upstream runtime Senpi forked, supported through the same extension shape.

Prime Agent

Another pi-mono fork, this one routing everything through a single Python kernel.

Supported agent harnesses

Return to the runtime support overview.