github code-yeongyu/oh-my-openagent v5.1.13

3 hours ago

MCP tools work again when memory is on. Since 5.1.10, a finished memory child or delegated task shut the shared MCP servers down for the whole process, so every MCP call failed with MCP server <name> is disabled. This release runs on senpi 2026.10.3, which gives each session its own binding to the shared servers; it was verified with the shipped bundle. If you can't update yet, turn memory off until you do: set "memory": { "enabled": false } in ~/.omo/omo.json, or start omo with --omo-senpi-memory-disabled=true.

Fixed

MCP calls no longer fail with MCP server <name> is disabled after a child session ends. A memory child or a delegated task that finished released the MCP service for every session in the process; now it releases only its own binding, and the shared servers stay up. Thanks to @Tygb99 for the report. (#9461, senpi#2524)

Codex edition (LazyCodex): a project's own registered agent roles can be spawned. The spawn guard accepted only LazyCodex's 12 bundled roles, so a role registered in .codex/agents or $CODEX_HOME/agents was refused even though Codex offered it; it now accepts any role with a registered role file and still refuses unregistered ones. Thanks to @aconley-vultr for the report. (lazycodex#171, lazycodex#164, #9462)

Cancelling a delegated task while its host can't list its sessions keeps the cancel pending instead of finishing it with the session still open; it completes once the host answers again. (#9450, #9459)

Skills are listed in a stable order, so the tool prefix of a prompt stays the same between turns and keeps hitting the prompt cache. (#9433)

OpenCode edition fixes, thanks to @cynkai: an explicitly chosen model no longer falls back through the built-in chain (#8808); a plugin-load telemetry failure no longer prints into the TUI (#8804); a background task whose session stopped on an error is finalized (#8814) and skips fallback models no connected provider serves (#8844); Sisyphus stays available when Hephaestus isn't registered (#8841); and omo.schema.json embeds the [opencode] schema once and no longer marks defaulted fields as required (#8871, #8873). Tool argument rewrites in the OpenCode edition also keep the original arguments object (#9466).

omo host status --all and omo thread list no longer show an older session entry as the latest activity when the final JSONL entry is large, partial or invalid. Both surfaces use the same bounded final-record policy, show null when freshness cannot be proved, and list known activity newest-first with unknown activity last. (#9222)

A message to a published terminal session that the engine still reports as not answering is kept offline instead of being sent straight to its socket, so omo thread list, a send and a steer always agree on whether that session can be reached right now; the message is delivered once a later check lists the session live again. A bound send that names its session no longer pays the same lookup twice. (#9222)

Changed

omo runs on senpi 2026.10.3 (the MCP fix above, plus the Bun -e host-launch and WebView readiness fixes). Full list: senpi 2026.10.3.

OpenGateway tasks run without a concurrency limit by default. (#9427)

Added

The session gateway entries below are its store foundation; the thread tools become usable with 5.1.14.

Every session can reach every other one, terminal sessions included. (#9143) Messages between sessions now go through a session gateway: one small database in the agent directory, with no daemon to run and nothing to configure. A terminal session opens a private control socket, so a Desktop thread, a task child or a script can list it, read it and send to it; the thread tools list terminal sessions with their real names and times. A message never interrupts what you are doing: while you are typing, or a submission of yours is on its way, it waits, and the session shows one line saying a remote message is queued. A message to a session that is not running is kept for 24 hours and taken when the session runs again. Fixed limits stop runaway loops: a session cannot message itself or reply straight back into the chain that messaged it, a chain of messages stops after 4 hops or 64 messages, one turn reaches at most 16 sessions, and one sender gets a burst of 8 messages to a session, then one every 5 seconds.

omo thread talks to running sessions from scripts and chat connectors. (#9143) omo thread list|send|read|bind|unbind|rebind|bindings|report|answer|outbox|ack runs the thread tools' operations without an agent session, with --json output that is one JSON value (also on failure) and exit codes a script can branch on: 0 done, 1 refused, 2 usage, 3 nothing answering, 4 unsupported here, 5 internal error. JavaScript can import the same operations from the plugin (runtime/thread-sdk/sdk.js) without spawning omo. It never starts a host. Reference: docs/reference/omo-thread.md.

A session can be bound to a chat thread, and report back through it. (#9143) A binding attaches one session to one external thread (any platform; OmO ships no chat connector itself). Messages from the thread arrive with omo thread send --binding, admitted once per platform event. The session posts milestones, reports, questions and its completion to the binding's outbox with thread_report, and a connector reads them with omo thread outbox and acknowledges them. A question carries a reply token that only an answer through the same binding can use. A completion is written only when you ask for one, and survives a restart. At most one active binding holds a thread; unbinding and rebinding name the revision they expect, and a rebind never extends the binding's lifetime.

A chat connector can say who wrote each message, and how it should land. (#9143) omo thread send --binding takes --author-id and --author-name (and --author-user-id). The session sees the author as quoted fields in the message's provenance header, outside the text, so a message cannot pretend to come from someone else. Each author gets their own rate budget in a busy thread. --mode follow_up lets one message land more gently than its binding allows, and never more strongly. answer takes the same author flags, and the outbox records who answered a question. A connector can watch <agent dir>/gateway/outbox.marker to learn about new outbox rows. The reference now spells out that outbox delivery is at-least-once, and that (binding_id, cursor) is the key to dedupe by.

omo host status --all shows when each terminal session was last active. (#9143) Every terminal (tui) row now carries last_activity_at: the time of the newest entry in its session file, the same time omo thread list shows, or null when it is not known.

omo daemon adopt moves a session from a host into your terminal. (#9143) omo daemon adopt <session> asks the host holding a Desktop thread or a background session to hand it over, then resumes it in the current terminal, in the session's own directory. A session in the middle of a turn is refused unless you pass --interrupt, and input the interrupt took out of its queue becomes your first prompts. A session a Desktop window has open is refused unless you pass --force. omo daemon status now lists terminal sessions as tui rows, and handoff and stop --all leave them alone.

Removed

omo daemon attach and the shared-host opt-in env (OMO_ENABLE_SHARED_HOST) are removed; interactive sessions always run standalone. (#9143) A terminal session no longer joins an engine host; it always runs its own session in its own process, and other sessions reach it through the gateway. OMO_ENABLE_SHARED_HOST no longer changes anything. To continue a session that lives on a host in a terminal, use omo daemon adopt.

  • 294a165 Merge pull request #9488 from code-yeongyu/release/v5.1.13-source-state
  • 35aa2fd Merge pull request #9479 from code-yeongyu/fix/9477-isolation-git-tests-no-wallclock
  • 96dfa60 test(isolation-core): prove git tree teardown without a wall-clock bound
  • c37f9ef Merge pull request #9462 from code-yeongyu/fix/lcx171-registered-spawn-roles
  • 14fcbfc Merge pull request #9222 from code-yeongyu/feat/session-gateway
  • 3e622df test(thread): give every published-endpoint test an explicit 15 s budget
  • c2650d7 fix(thread): list a published owner the way thread_list does, so list, send and steer agree
  • c51d8c2 fix(thread): keep legacy discovery and live owners on the published send path
  • 15cf5a5 docs(changelog): keep the session gateway entries under [Unreleased] after 5.1.10
  • d33d52f test(thread): cover an owner killed uncleanly with its socket file left behind
  • 55ec7b8 fix(thread): let an exact durable id outrank a live session's name
  • 2541250 test(thread): associate originating events with tool entry
  • 6d17016 test(thread): narrow the published ownership assertion
  • 06a2a9d fix(thread): validate published targets once and model persisted ownership
  • 39783cc test(thread): capture originating turn and message events separately
  • 72097e4 fix(thread): preserve scoped ownership resolution for bound sends
  • feed483 test(thread): measure tool entry through originating target acceptance
  • 1365909 perf(thread): resolve exact-id sends through the published target endpoint
  • d3fddd0 feat(thread): publish and fence session control endpoint ownership
  • 42e384d docs(omo-thread): document claimant liveness on win32 and the binding trust model
  • 0391ca6 fix(omo-native): answer omo daemon adopt usage errors in JSON
  • c5230a9 docs(omo-thread): scope closed-elsewhere answers to a takeover
  • 4b6534d feat(thread): reserve the question_closed outbox event kind
  • 57a9a3e test(thread): hold the receipt-write lock through bun:sqlite
  • 52910c7 test(thread): rewrite raw gateway rows only while no store writes the file
  • 55281ed fix(thread): replay a completion report without arm_seq through the durable arm
  • 3afa1f2 fix(thread): hold the recovery bound across overlapping admissions
  • d91d3fb fix(thread): bound the tool surface's receipt-recovery keys
  • 48a8af4 fix(thread): each settled run owns its completion arms by sequence, not by clock reading
  • 538e1f0 fix(thread): a call reusing an expired key deletes at most one receipt batch
  • dff9be5 test(gateway): state that the matcher ban covers unawaited calls too
  • 9241031 test(thread): observe the git probe with a restorable spy, not mock.module
  • 284e291 test(thread): await gateway store promises through settled() and audit the matcher form
  • 48f2411 test(thread): receipt-write failures keep the gateway store serving
  • 060786f fix(thread): a retried tool call recovers a receipt whose admission reply was lost
  • f60ae59 fix(thread): a decided event replays after an unbind even when its receipt stayed prepared
  • fe5d0df fix(thread): a re-armed binding keeps the earlier run's completion
  • 00ab369 fix(thread): peer tool calls sweep expired receipts again
  • ffb394d test(thread): bound the CLI-arm test's wait for the control endpoint
  • cae641f fix(thread): only the legacy turn-N spelling migrates a steer's turn
  • ba22a23 fix(thread): a retried connector event replays its result after an unbind
  • eb7a87c fix(thread): a bindings snapshot never takes in a binding made after it
  • fc6164a fix(thread): binding identifiers refuse C1 controls and line separators
  • 5cddaa4 fix(thread): keep a tail-window line that starts on the window boundary
  • 0baaa55 fix(thread): a run's send continues a consumed delivery whose outcome write failed
  • 52055df fix(thread): delete expired receipts a batch at a time
  • 0f26984 test(thread): retention scheduling is exercised on one store
  • 7667164 fix(thread): a retried send replays a decided delivery its own process began
  • b2ea6ea fix(thread): a steer into a session waiting on a question is not_steerable
  • f69b1c7 fix(thread): a receipted tool answers a failed receipt start as data
  • e1e316d fix(thread): record every settled run's completion with its own outcome
  • be61ed2 fix(thread): record a session's incarnation before its endpoint goes live
  • c18b6b5 fix(thread): an outbox ack refuses another binding's cursor
  • 3dbf5ae fix(thread): a run's send continues the chain of the message it consumed
  • f9c6cab fix(thread): list a degraded legacy host's threads from disk
  • 5b12ad6 fix(thread): a migrated legacy steer keeps the turn it was meant for
  • 1c7ab49 docs(thread): name the inputs that make a report without binding_id refuse
  • c2cf1b7 fix(thread): a report without binding_id goes to the only thread a user message can be answered in
  • 9812cbc fix(thread): refuse a report without binding_id when a typed prompt shares a thread's answer
  • e48728d fix(thread): send a report without binding_id to the thread the session is answering
  • 4dffb4d test(thread): type the fake host's reply table and pass a store to the list fixture
  • 29f9028 fix(omo-native): point omo daemon attach at adopt, and keep adopt's outcome when the store fails to close
  • f38c73d fix(omo-native): print the messages omo daemon adopt replays before relaunching
  • 4dbc598 fix(omo-native): keep omo thread's --json contract when the SDK fails to load or close
  • 44a262d refactor(omo-native): drop the compiled launcher's dead attach branch
  • 68f2f68 test(thread): drive the cancelled release retry on a fake clock
  • cccb529 fix(thread): treat a release reply without a session path as a failed release
  • 189e2ae refactor(thread): require the gateway store in the tool surface options
  • 6b255a8 perf(thread): page outbox rows and bindings in SQL
  • ea13eac refactor(thread): delete the uncalled requeueReleased store operation
  • a69fda3 docs(thread): outbox cursors are store-wide, so a binding sees gaps
  • 30628ef feat(thread): reserve expired and cancelled outbox question states
  • 511ba85 feat(thread): accept notion and feishu as binding platforms
  • 8d6bcec docs(thread): session lifecycle, completion text and the author rate key
  • aa3c8ea fix(thread): resolve sessions for bind, rebind, report and bindings without a running host
  • 5d9a674 fix(thread): send a report without binding_id to the thread that started the run
  • 5634de6 fix(thread): prune the gateway tables that grew without bound
  • 3e7b34b fix(thread): record claimant start times independent of locale and time zone
  • 8ffa096 fix(thread): import the pre-gateway mailbox in production and report the items it skips
  • df819d8 fix(thread): reopen the gateway store after a failed open or a worker exit
  • 40727c1 docs(changelog): move the session gateway entries back under [Unreleased]
  • 11e2bc5 test(omo-native): assert the win32 answer of omo daemon adopt
  • 8ac70d3 test(thread): suspend the lock holder with real job-control signals, and run the gateway tests on win32
  • 3eadb52 docs(changelog): move the session gateway entries back under [Unreleased]
  • 2257b99 fix(thread): align activity readers and ordering
  • 9cdb4ab fix(thread): validate final entry structure
  • 53defe9 fix(thread): reject moving activity snapshots
  • c3e2cc9 fix(thread): preserve unknown list activity
  • 277aa55 fix(thread): keep newest activity truthful
  • c7624f4 test(thread): the thread SDK entry also exports readSessionFacts
  • e4d5a63 build: regenerate bundles in a linux/amd64 container (node:24-bookworm, bun 1.4.2)
  • 789feff feat(thread): binding authors, a per-message mode, the outbox wake marker, and last_activity_at on tui status rows
  • f1cd7e0 build: regenerate bundles in a local linux/amd64 container (node:24-bookworm, bun 1.4.2)
  • 7853cb9 build: regenerate bundles in a local linux/amd64 container (node:24-bookworm, bun 1.4.2)
  • a444986 docs(changelog): keep the session gateway entries under [Unreleased] after rebasing onto 5.1.5
  • 2f72744 test(script): categorize the gateway QA harness's command-string hits
  • 77a1e50 docs(omo): omo thread send queues offline when nothing is live or the target was never seen
  • 6af68b0 test(omo-native): the packed payload must carry the gateway store worker
  • 6324462 docs(changelog): keep the session gateway entries under [Unreleased]
  • b7e7512 docs(omo): thread answer: undeclared yes/no goes out as confirmed; a refused takeover of an answered question stays delivered
  • d688086 docs(omo): thread answer: an abandoned attempt the session accepted after all is the delivered answer
  • be3cb07 docs(omo): thread answer without a request kind, confirm trimming, pre-v3 claims, and late settles
  • 6256799 docs(omo): thread answer: refusals, answer_in_progress, and the answer forms per request kind
  • 9378198 docs(omo): session gateway, thread CLI, daemon adopt; drop attach and shared-host prose
  • aa78dab feat(omo-native): omo thread report --request-kind; the thread SDK passes the question's request kind
  • 10a6062 fix(omo-native): adopt's replayed messages are never launch flags; omo thread rejects bad --mode/--direction
  • 025dddc feat(omo-native): omo thread CLI and omo daemon adopt
  • 7c294e8 docs(changelog): note the attach removal and delete the dead thread-policy test
  • 33ae6d9 chore(omo-native): remove omo daemon attach and the shared-host opt-in
  • 1f89f26 Merge dev into fix/lcx171-registered-spawn-roles
  • 0920cad Merge pull request #9466 from code-yeongyu/fix/9448-replace-tool-args-in-place
  • 2e858cc test(lazycodex): accept object agent_type on the flat v2 spawn_agent
  • 10c6c7f Merge pull request #8808 from cynkai/fix/8536-call-omo-agent-explicit-model-no-builtin-chain
  • 0022e02 Merge pull request #8804 from cynkai/fix/8795-plugin-telemetry-no-console-dump
  • 34355b5 fix(opencode): preserve tool argument identity
  • ce8e7fa Merge pull request #8814 from cynkai/fix/background-agent-terminal-retryable-error
  • 28eaf89 Merge pull request #8867 from cynkai/fix/8852-poll-stabilization-virtual-abort
  • 26cc522 Merge pull request #9453 from cynkai/fix/9149-doctor-test-host-isolation
  • 2c6dc9c Merge pull request #9436 from cynkai/fix/9386-release-test-timeouts
  • d476770 Merge pull request #9452 from cynkai/fix/9447-stale-sweep-test-host-pids
  • 1df38ab Merge pull request #8871 from cynkai/fix/6444-omo-schema-single-opencode-id
  • 91604ed Merge pull request #8841 from cynkai/fix/8491-no-sisyphus-gpt-unregistered-hephaestus
  • 0f41d57 Merge pull request #8844 from cynkai/fix/8540-skip-unserved-fallback-models
  • 31cee54 fix(lazycodex): let the spawn guard accept a project's own registered agent roles
  • 91ff6f0 Merge dev into fix/8795-plugin-telemetry-no-console-dump
  • 5edb4e4 Merge dev into fix/8536-call-omo-agent-explicit-model-no-builtin-chain
  • afb1204 Merge dev into fix/background-agent-terminal-retryable-error
  • 775db1b Merge dev into fix/8491-no-sisyphus-gpt-unregistered-hephaestus
  • 2545f3e Merge dev into fix/8540-skip-unserved-fallback-models
  • e3c3ec9 Merge dev into fix/8852-poll-stabilization-virtual-abort
  • 9bb82f8 Merge dev into fix/9386-release-test-timeouts
  • ac083f0 Merge dev into fix/9447-stale-sweep-test-host-pids
  • a5b79b7 Merge dev into fix/9149-doctor-test-host-isolation
  • 5cc35af Merge dev into the [opencode] schema embed fix
  • ecd0018 Merge pull request #8873 from cynkai/fix/6445-schema-defaulted-fields-optional
  • 2aa9149 Merge pull request #9433 from code-yeongyu/fix/9432-stable-skill-order
  • 3216b80 Merge pull request #8690 from Dante-dan/fix/8682-publish-tarball-readiness
  • f33983c Merge dev into fix/6445-schema-defaulted-fields-optional
  • 402830b Merge dev into fix/8682-publish-tarball-readiness
  • be766aa test(skills): pin code-unit name order so a locale-aware tie-break would fail
  • b1f91cb Merge dev into fix/9432-stable-skill-order
  • 5496407 Merge pull request #9459 from code-yeongyu/fix/9450-pending-cancel-unknown-liveness
  • 6d92cf6 Merge dev into fix/9450-pending-cancel-unknown-liveness
  • 0045ffe Merge pull request #9427 from code-yeongyu/fix/opengateway-unlimited-default
  • 285493b Merge dev into fix/9450-pending-cancel-unknown-liveness
  • 77454dd test(omo-native): keep the host's engine processes out of doctor test output
  • 8073d1d test(tmux): drive the stale-session sweep runtime test with PIDs it controls
  • 9d5bbc6 fix(schema): reference the embedded [opencode] schema with a local $ref
  • 6e1aaab test(release): bound each spawned child so a hung one is killed
  • 206da0f fix(skills): list skills in a stable order so the tool prefix stays cacheable
  • 9726d91 test(omob): use real provenance for absent binary regression
  • f865f49 test(release): give the subprocess-spawning release tests a hang watchdog
  • 8972b7f fix(schema): stop listing defaulted config fields as required
  • 4a449b1 test(omob): keep the missing-binary check meaningful with a matching sidecar
  • 1679009 test(publish): bound Windows readiness fixture execution
  • b3af312 fix(publish): bound tarball readiness probes and explain exhaustion
  • 3942b3a Merge dev and preserve release-channel tarball readiness checks
  • 1dc0150 fix(schema): embed the [opencode] schema once in omo.schema.json
  • 6102189 test(cli-run): drive poll stabilization aborts from the virtual clock
  • 8e705a1 fix(background-agent): skip fallback entries no connected provider serves
  • 5fd04b5 fix(no-sisyphus-gpt): keep Sisyphus when Hephaestus is not registered
  • a0b2e96 fix(background-agent): finalize tasks whose session stopped on an error
  • 5a9bb74 fix(call-omo-agent): skip the built-in fallback chain for explicit user models
  • f40a928 fix(telemetry): keep plugin-load PostHog failures out of the TUI
  • 21e79e9 fix(publish): wait for tarball readiness

Thank you to 1 community contributor:

  • @effortprogrammer:
    • fix(thread): keep legacy discovery and live owners on the published send path
bun add -g omo-ai

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

NewReleases is sending notifications on new releases.