github code-yeongyu/oh-my-openagent v5.0.0-beta.53

3 hours ago

OMO 5.0.0-beta.53

Pick a model profile instead of hand-wiring a chain, the curated agents are named for what they do instead of who they were in mythology, native workflows survive a session switch, and a process leak that could eventually stop a Mac from spawning anything at all is gone. The engine underneath is senpi 2026.9.10-2.

Model profiles pick your session model

Say what kind of work it is; OMO picks the model. omo.json gains model_profiles (a record of fallback chains) and model_profile (the active one), with three builtin profiles that choose the MAIN session model at session start:

  • capableclaude-fable-5-1 -> claude-opus-5 -> kimi-k3 -> glm-5.3
  • simple workgpt-5.6-luna-fast -> deepseek-v4-flash -> claude-haiku-4-5
  • deep workgpt-6-astra -> gpt-5.6-sol

The first rung the live registry can actually serve wins, and the applied notice names the model it picked along with the rungs it skipped. model_profile also accepts a literal provider/model pin, and you can define your own profiles or override a builtin one.

It stays out of the way. No profile is active by default. A profile applies only at session start for a new or startup session, through the session-scoped model setter — it never writes your harness settings, and an explicit --model, a scoped model, a pinned value, or a resumed session is left alone. Profiles are documented in the config reference and the agent-model-matching guide, and omo.dev now tells the model story the same way.

The curated agents are roles now

metis is plan-consultant, momus is plan-reviewer. The omo-senpi runtime, its skills, config keys, telemetry, and the shipped ultrawork directive all speak in roles: the main agent (your session model), plan-consultant, plan-reviewer, explore, librarian, the Ultrawork Planner persona, and the category roster. Docs, the READMEs in five locales, and omo.dev were re-keyed in the same release.

The old ids keep working for exactly one release. subagent_type: "metis" | "momus", DAG routes, team member specs, and omo.json agents.metis|momus / allowed_subagents entries all canonicalize through a single alias module, and every entry point that accepts a legacy id now prints a deprecation notice — task start, DAG lint, team member validation, and a config-startup warning. Only the canonical id is ever persisted, so DAG fingerprints and telemetry never carry the old name forward. Plan frontmatter moves from review.momus to review.plan_reviewer. The alias is removed in the next tagged release, so update your config now rather than later.

If you query telemetry, this is a breaking change. delegation_started.name and delegation_completed.agent_type report the new ids, so dashboards filtering on metis or momus stop matching new events. A repo gate now fails CI if a retired name reappears in a governed surface. The OpenCode and Codex editions keep their own agent ids; nothing named boulder changed.

Memory and long-running hosts

A shared host no longer fills the machine's process table. The memory lock protocol fingerprints a process start time to detect PID reuse, and on macOS it resolved that by spawning /bin/ps on every check — every lock record, every reflection and facts reservation, every stale-lock recovery. A long-lived shared RPC host never reaps those children, so they accumulated as defunct entries until posix_spawn failed machine-wide with EAGAIN: one workstation reached 10,981 process-table entries with 9,750 zombies, 9,386 of them ps, after which shells and ordinary tooling could no longer start. The value now comes from libproc in-process, so there is no child to leak regardless of how the embedding host handles SIGCHLD. Dead PIDs are rejected by a fork-free liveness probe first, so stale-lock recovery no longer forks either, and the identity is recorded as an epoch rather than formatted local time, which also removes a timezone-dependent mismatch. Older lock records stay compatible, so an upgrade never steals a live owner's lock.

Memory children stop inheriting a stranger's package root. Reflection and dream children were dying about six tenths of a second after launch with an ENOENT on a theme asset, and the health alert repeated every session with a hint that could not work. The child is frequently a different senpi install than the engine that exported OMO_PACKAGE_DIR / SENPI_PACKAGE_DIR / PI_PACKAGE_DIR, and it read that inherited root as its own. Those variables are now dropped unless the resolved launcher actually lives inside the root they name, with both sides canonicalized so symlinked installs still compare correctly, and the filter covers the reflection spawn payload, the model preflight probe, and the people-ask runner. A deliberate relocation still works. The remediation hint is honest again: SENPI_BIN is offered only for pre-spawn resolution failures, while a child that started and then crashed points at its own log instead of a variable the launcher deletes.

Reflection health alerts describe this session, not history. Binding a session to a shared memory identity could replay that identity's old failure streak even when the new session consumed nothing. Alerting is now edge-triggered — a bind that consumes no unsuccessful completion is silent — and completion records carry launcher provenance, so a notice names the runtime that actually failed, the current runtime when it differs, and how many runtimes the streak spans. Legacy records without that metadata still render.

Kibitzer stops calling non-failures failures. A judge that answers only through its nudge tool and then stops silently was being settled as an error by empty-response recovery; the nudge result now ends the turn once it reaches its item cap, and a settled empty-response error counts as completed when nudges were accepted and as empty when none were. Run-directory artifacts are auditable output rather than inputs, so a failed write warns and continues instead of failing the fire as a session-creation error. A missing persona asset is reported as persona_unavailable and names the file. The task runtime is primed at registration alongside the personas, and a failed import is not cached so a repaired tree recovers.

Workflows, tasks, and continuation

Native workflows survive a session switch. Switching sessions used to cancel active DAGs from a vetoable pre-switch hook before shutdown could pause them, and recovery then rejected even an explicitly released lease held by the same process. Retirement moves to committed shutdown, which awaits scheduler quiescence before persisting the pause and suspending child sessions; a single-shot suspension drains in-flight admission and journal delivery without cancelling child records; and a released own lease can be reclaimed while active self-claims and live foreign owners stay protected. Returning to the session in the same host process resumes the run, reuses completed output, keeps the running child's identity, and admits a pending dependent exactly once. Opening /session or opening and cancelling /resume never caused teardown and still does not. Explicit workflow cancellation stays destructive.

Builtin Claude work tries your subscription first. All fourteen builtin Claude rungs — nine category rungs and five builtin-agent rungs — now list senpi's Claude Pro/Max lane ahead of the metered providers. A machine logged into that lane while also holding a marketplace key had been paying per token for every delegated Claude turn, because rung provider order is the ranking and the subscription lane was not in the list. Relatedly, when two providers expose the same model id, the tie is broken by the rung's own provider order and then the shorter model id; provider name length no longer decides. With the subscription lane absent, resolution is byte-identical to before.

A child that dies before its first prompt now says why. Task records carried only status=error for a child that never started, because the classifier's detail was collapsed into one sentence before it reached the record. That collapse is deliberate — the message is untrusted child stderr and durable-log redaction matches key names, not values — so instead of persisting the text, the record now carries closed enums and numbers: the failure kind, and the exit kind, code, and signal when the child reached a real exit. That distinguishes a crash from a spawn error from a kill. The runtime-fallback launch path records the same facts, which it previously omitted entirely.

Windows: a compiled engine launches itself. When the running process embeds the engine, resolution returns that executable — but on Windows any candidate not ending in .exe was read as an npm shim, and a compiled single-file binary may be named anything. The shim reader found no adjacent entry script, discarded the one candidate guaranteed to match the running version and its embedded assets, and fell through to guessing an entry script. The running compiled executable is now returned directly and never re-interpreted; the shim reader still handles PATH and sibling candidates.

Queued completions survive a session reload. The idle-injection coordinator's deferred flush could fire after a reload invalidated the extension runtime and take the process down with a stale-generation throw. Retiring a coordinator now cancels its timer and fails queued entries explicitly, the task layer rolls back the failed notification epoch and re-enters its retry path, and producers handle the refusal instead of dropping the work.

Plan continuation only continues successes. The ulw-loop and ulw-execute hooks ignored the outcome of the turn they were continuing, so they could resubmit a turn that errored, was aborted, was already owned by a host retry, or was refused. Both producers now record at turn end and decide at the settle edge that guarantees no retry, compaction, or queued continuation will follow, skipping failures without consuming a continuation slot and logging the reason. Successful continuation, caps, and deduplication are unchanged, and ordinary assistant prose that merely discusses an error still continues.

Engine: senpi 2026.9.10-2

Kimi For Coding sessions identify themselves as a Kimi client. The Kimi Code endpoint recognizes its clients by a product User-Agent plus a six-header X-Msh-* device set — platform, version, device name, device model, OS version, and a per-install device id — which the official Kimi client sends on device authorization, token polling, token refresh, and every request. senpi sent none of them, so a subscription session presented itself as an anonymous Anthropic-protocol client that happened to hold a Kimi bearer token. The OAuth subscription path now sends the full set on all four request paths, with printable-ASCII sanitized values and a device id persisted under the agent dir that degrades to a per-process id rather than throwing when that directory cannot be written. The api-key path is deliberately untouched: it authenticates with a platform key rather than a client session.

The manual-continue shortcut stops appearing as your message. A bare . submitted on a session that already has messages is the hidden continuation it was always meant to be, and nothing is painted for it in the TUI.

Reasoning warnings fire at the level that warrants them. GPT-6 Astra's high-reasoning warning now appears only at max, and the GPT-5.6 Sol levels are documented alongside it.

Claude subscription resumes are steadier. A completed resumed query no longer has its abort listener left attached, so reattaching does not close a healthy query, and a resumed query is pinned across completed-request cleanup.

A refused model switch is visible and inert. When a session declines a model switch, the refusal is recorded rather than silently applied or silently dropped.

Install

npm i -g omo-ai@beta
Commits (118)
  • 7918f24 Merge pull request #8101 from code-yeongyu/release/v5.0.0-beta.53-source-state
  • bb698fd release: v5.0.0-beta.53
  • 4212d35 Merge pull request #8088 from code-yeongyu/docs/omo-model-profiles
  • ca8db37 Merge remote-tracking branch 'origin/dev' into docs/omo-model-profiles
  • cc1007a Merge pull request #8084 from code-yeongyu/feat/omo-model-profiles
  • 9efd54a build(omo-senpi): regenerate the plugin bundle on the dev-merged tree
  • 90df269 Merge remote-tracking branch 'origin/dev' into feat/omo-model-profiles
  • e1ef0a0 test(omo-senpi): budget the model-profile component's first-party bundle growth
  • af6ab23 Merge pull request #8076 from code-yeongyu/docs/omo-senpi-role-names
  • 2aa3c4b Merge pull request #8028 from rlaope/fix/session-dag-suspend-resume
  • c5c1f0a Merge pull request #8099 from code-yeongyu/chore/senpi-pin-2026.9.10-2
  • bda4231 build(omo-senpi): regenerate extension bundles on Linux after rebase
  • 2518df2 fix(omo-senpi): actually await scheduler quiescence on committed shutdown
  • 0c04724 fix(omo-senpi): suspend native workflows across session switches
  • 234127b chore(deps): adopt senpi 2026.9.10-2
  • b850afc build(omo-senpi): regenerate the plugin bundle on the dev-merged tree
  • b8d5f0b Merge remote-tracking branch 'origin/dev' into docs/omo-senpi-role-names
  • 1bbfdc5 Merge remote-tracking branch 'origin/dev' into feat/omo-model-profiles
  • b03c579 Merge pull request #8085 from code-yeongyu/refactor/omo-senpi-role-names
  • 3f3c97c build(omo-senpi): regenerate the plugin bundle on the dev-merged tree
  • 9649fa0 Merge remote-tracking branch 'origin/dev' into refactor/omo-senpi-role-names
  • 6c15fa8 Merge pull request #8027 from rlaope/fix/policy-continuation-hooks
  • 7801085 fix(omo-senpi): match the canceller-returning FlushScheduler in the terminal-outcome fixture
  • d9c5113 build(omo-senpi): regenerate the plugin bundle on the dev-merged tree
  • aead84d build(omo-senpi): regenerate extension bundles on Linux after rebase
  • 6ba0497 fix(omo-senpi): decide plan continuation on agent_settled
  • dedf45b fix(omo-senpi): gate plan continuation on successful turns
  • 7f66132 Merge remote-tracking branch 'origin/dev' into refactor/omo-senpi-role-names
  • 594e769 docs(changes): drop a stray merge-marker line from the changelogs
  • 715212e build(omo-senpi): regenerate the plugin bundle on the dev-merged tree
  • f63126c Merge remote-tracking branch 'origin/dev' into refactor/omo-senpi-role-names
  • 73dd51c Merge pull request #8062 from code-yeongyu/fix/8052-kibitzer-fire-hardening
  • 0ab14a6 build(omo-senpi): regenerate extension bundles on Linux after rebase
  • 6c4fc13 docs(omo-senpi): QA evidence for the Kibitzer fire hardening
  • 53ff13a docs(omo-senpi): record the Kibitzer fire hardening
  • 61ab84b fix(omo-senpi): prime the Kibitzer task runtime at memory registration
  • eaa062d fix(omo-senpi): report a missing Kibitzer persona as persona_unavailable
  • 0894ac0 fix(omo-senpi): keep Kibitzer run-dir artifacts best-effort
  • 12603e8 fix(omo-senpi): complete a silent Kibitzer judge instead of failing it
  • 87f5207 Merge pull request #7933 from code-yeongyu/fix/idle-injection-dispose-7932
  • 32f9d4f chore(omo-senpi): rebuild senpi plugin bundles on linux
  • 124b193 fix(omo-senpi): hand back dropped idle injections instead of losing completions
  • 75c45a8 Merge pull request #8097 from code-yeongyu/fix/8096-spawn-free-process-identity
  • feb54da chore(omo-senpi): rebuild the plugin bundle with the CI-pinned bun 1.4.2
  • 19238cb chore(omo-senpi): refresh the committed Senpi plugin bundle
  • 80dbb6c test(memory-core): pin pid-reuse recovery to a same-scheme start identity
  • 35dc9c3 fix(memory-core): make the start identity timezone-independent
  • 5c6c260 fix(memory-core): read darwin process start time in-process instead of forking /bin/ps
  • 446b0e3 Merge pull request #8059 from code-yeongyu/fix/8051-claude-sdk-oauth-lane-first
  • 985e50d build(omo-senpi): regenerate the plugin bundle on the dev-merged tree
  • 3699fa7 Merge remote-tracking branch 'origin/dev' into refactor/omo-senpi-role-names
  • a2328ed build(omo-senpi): regenerate extension bundles on Linux after rebase
  • ab2ceb2 build(omo-senpi): regenerate extension bundles on Linux after rebase
  • 83a9c79 fix(model-core): never let provider name length decide a fuzzy model tie
  • 6ba87ec fix(senpi-task): head builtin Claude rungs with the claude-sdk-oauth lane
  • 8a3751a fix(omo-senpi): export claude-sdk-oauth as a known telemetry provider
  • 77d8003 Merge pull request #8094
  • 68b67ec build(omo-senpi): regenerate the plugin bundle on the dev-merged tree
  • 84f580a Merge remote-tracking branch 'origin/dev' into refactor/omo-senpi-role-names
  • d60249e build(omo-senpi): refresh health attribution bundles on current dev
  • 2d5926c test(memory): cover launcher attribution rendering
  • 12809be fix(memory): attribute reflection health to its launcher
  • c9d90b5 fix(memory): scope health alerts and record launcher provenance
  • 1e5ddba test(memory): specify reflection launcher provenance
  • 6a35ad5 Merge pull request #8093 from code-yeongyu/fix/6976-rpc-e2e-child-diagnostics
  • 1da8b43 build(omo-senpi): regenerate extension bundles on Linux for the start-failure facts
  • 7b87476 fix(senpi-task): record why a child failed to start, without leaking its stderr
  • 23b99a4 build(omo-senpi): regenerate the plugin bundle on the dev-merged tree
  • 9e3af02 Merge remote-tracking branch 'origin/dev' into refactor/omo-senpi-role-names
  • b343e2c Merge pull request #8091 from code-yeongyu/fix/windows-senpi-launcher-flake
  • 6855e9c build(omo-senpi): regenerate extension bundle on Linux after rebase
  • 10f7a90 build(omo-senpi): regenerate extension bundles on Linux for the launcher fix
  • ac70d98 fix(senpi-task): keep the compiled engine when its binary has no .exe suffix
  • cb3d88e Merge pull request #8070 from code-yeongyu/fix/memory-child-foreign-package-dir-env
  • 0bed01a build(omo-senpi): refresh memory env bundle on current dev
  • 3f1c86f fix(memory): use resilient fs for package-root canonicalization
  • 5782f32 fix(memory): stop memory children from inheriting a foreign package root
  • 6147d0e test(omo-senpi): compare synced-skill exemption paths with forward slashes on every platform
  • daa9fcd build(omo-senpi): regenerate the plugin bundle on the dev-merged tree
  • 689071c Merge remote-tracking branch 'origin/dev' into refactor/omo-senpi-role-names
  • d5e321f build(omo-senpi): regenerate the plugin bundle for the renamed curated agents
  • 3135114 docs(reference): regenerate the telemetry schema block for the renamed curated agents
  • 46b7860 test(web): landing e2e covers the Profiles section
  • c960559 test(omo-senpi): QA drivers exercise plan-consultant/plan-reviewer and the legacy aliases
  • 12bf5e2 feat(web): tell the model story through profiles in four locales
  • b9c5223 docs: document model profiles and how they pick the session model
  • d3d2f87 test(script): keep overlay-rerouted OpenCode literals legal in shared-skill sources
  • 24a4b89 docs(guide): keep the Codex agent-role install path in the installation guide
  • 638f6e8 test(script): gate retired myth agent names out of user-facing surfaces
  • ab27ab5 refactor: drop the retired curated ids from code comments and mark the Codex role list
  • 2d86c99 refactor(omo-senpi): ultrawork directive names the plan-consultant and plan-reviewer
  • 5dfb50a docs(changelog): record the role-based agent rename and the one-release alias window
  • b49efe2 build(omo-senpi): regenerate the plugin bundle for model profiles
  • 910576d fix(omo-senpi): keep an explicit --model when senpi omits the session provenance
  • de028bc feat(omo-senpi): model-profile QA driver and changelog entries
  • e378ad2 test(senpi-task): retire myth agent names from fixtures and package docs
  • 7d4c9cb feat(omo-senpi): honor legacy agents.momus/metis config keys with a deprecation notice
  • 05afdec refactor(senpi-task): describe category routing and the plan reviewer by role
  • 9649152 feat(omo-senpi): apply the active model profile to the main session
  • 3a11406 refactor(omo-senpi): retire persona names from shared-skill prose and the senpi sync scripts
  • 00afeac refactor(senpi-task): key the plan gate and reviewer policy on plan-consultant/plan-reviewer
  • 17a179a feat(senpi-task): surface a deprecation notice for legacy curated agent ids
  • 8b301e4 style(web): format the cognitive-load manifesto section
  • d8ab818 refactor(omo-senpi): ulw-plan speaks as the Ultrawork Planner with plan-consultant/plan-reviewer
  • 9dc58a0 feat(omo-senpi): builtin model profiles and chain resolution
  • 6de3d52 refactor(senpi-task): rename curated agents to plan-consultant and plan-reviewer
  • c93cb11 test(web): showcase and landing e2e follow the role-based roster
  • aabc233 refactor(senpi-task): add legacy agent-name aliases for the curated tier
  • bbcb581 feat(omo-config-core): add model_profiles and the active model_profile key
  • 706124b feat(web): role-based roster, orchestration and core-loop copy in four locales
  • 0dc3bbe docs(reference): configuration and features describe the omo-senpi agent surface
  • ded517f docs(guide): installation, team mode and senpi-task pages use role-based agent names
  • f6db19e docs(guide): reframe model matching and overview around the main agent and curated roles
  • 00775dc docs(reference): known issues, CLI, telemetry, manifesto, templates and examples use role names
  • a40fde3 docs(guide): rewrite orchestration around the omo-senpi delegation model
  • 5258823 refactor(web): re-key the agent roster and graph to role-based nodes
  • 8a711dd refactor(omo-senpi): describe ulw-execute continuation without the planner persona name
  • 470dd60 docs(readme): describe the main agent, planner and executor by role in all locales

Don't miss a new oh-my-openagent release

NewReleases is sending notifications on new releases.