Skip to content

v2026.10.15

Choose a tag to compare

@github-actions github-actions released this 15 Oct 03:13
· 1056 commits to main since this release

@code-yeongyu/senpi

Breaking Changes

Added

  • Shared RPC hosts publish each session holder's public socket and host instance in validated lease evidence. Clients can pass open_session.expectedHostInstance to attach only to that live host generation; a changed owner or released path returns a typed refusal with a rediscovery action instead of creating another writer (#3255, #3257).

  • Dual-era MCP client: servers speaking the 2026-07-28 stateless spec revision (no initialize, per-request _meta, MCP-Protocol-Version / Mcp-Method / Mcp-Name headers, server/discover) now connect, while legacy initialize-handshake servers keep working through spec-driven auto-negotiation (HTTP: modern request first with 400-body classification; stdio: discover-first probe; era cached per origin/process). Modern-only servers receive zero legacy handshake traffic through an SDK-compatibility bridge that answers the SDK client's initialize locally from the discovery result. Connect diagnostics log the negotiated era and protocol version per server. Modern-only stdio servers work too: the spawned process answers server/discover first, then every request carries the per-request _meta, with no initialize sent (#3304, reported by @changeroa).

  • RPC effect ledger (capability effect_ledger): abort, set_model and set_thinking_level take an optional effectId and get a durable receipt written before the effect is applied; a retry with the same id replays the receipt instead of acting twice, and a different request under that id is refused with effect_id_conflict. get_effect_status answers any receipt by id, including inputs by clientMessageId, from a loaded session or from a transcript on disk. Input receipts now say how their turn ended (completed, aborted and by whom, error), a reopened session seals receipts its dead process left running, and queued input dropped by new_session/switch_session reads failed instead of vanishing (#3199).

Changed

Fixed

  • senpi host gc, and the cleanup pass that runs after starting a host, now stop a host left behind by an older engine once it holds no session, no reservation and no client and has outlived its own idle window plus 10 minutes. Such hosts used to linger for days after an update, because their old idle logic was the only thing that could end them. senpi host status --all marks them stale_old_engine. A host with any session or connected client is never stopped (#3268).

  • A fallback chain that lists one model at several thinking levels now walks every one of those levels. A rung that hard-errors parks only itself, so models: [X:high, X:off, X:low, Y] tries X:low after X:off fails instead of jumping to Y; a rate limit, quota or overload still skips every level of that model, so after one the walk moves on to the next model. This replaces the per-turn limit described in the previous entry. A model you pick by hand gets all its levels back (#3311, reported by @tw-yshuang).

  • senpi host session commands now return only after the host has dropped their attachment: on a host that advertises the new detach_connection capability the client asks for the detach and waits for the answer (bounded at 5 s, with one plain line if it never comes), so a listing right after open no longer shows the short-lived client as still attached. A connection leaving a session that another client also holds now releases its attachment at once, even while a turn runs; only the last attachment of a non-retained session still waits for the turn to settle. After a request timed out or the connection was lost, the client closes without asking for the detach. Older hosts keep the release on socket close. (#3238)

  • A flaky network no longer strands a session on a fallback model. A timeout or connection reset that outlasts the same-model retries may finish that one turn on the next model in the chain, but it no longer puts the primary on a cooldown or opens its circuit, so the next turn goes back to the primary. A rate limit, quota or overload error keeps its existing fallback behavior (#3306, reported in the OmO community).

  • A model that hit a usage limit and fell back now returns when that limit's own reset passes ("resets 3pm", resets_at, or "resets in 9 minutes"), instead of staying on the fallback for a cooldown that doubled past the window with every failed retry. A short hint such as "retry in 7s", even on a spent quota, and a plain Retry-After still keep the doubling cooldown, so a failing provider is not retried every few seconds (#3314, reported in the OmO community).

  • Local extensions keep loading after a runtime update on Bun 1.4.2 and older. Bun's transpile cache had stored the previous runtime's path to extension-runtime-module.js, so once that runtime was pruned an unchanged extension failed with Cannot find module. The cache entry now changes whenever the runtime moves, and a cache that is already broken heals on the next start, with nothing to clear by hand (#3300, reported in the OmO community).

  • A credential-pool account blocked for an authentication error is no longer excluded until someone logs in again. The block now lasts 15 minutes, then one request tries the account again (refreshing its saved login first when it can), so accounts whose token was renewed elsewhere come back on their own. A goal whose provider is down no longer fires eight retries within seconds and gives up: retries back off from 15 seconds up to 30 minutes, and when the pool names the time an account frees up, the goal waits until then and continues (#3264).

  • A Claude Pro/Max subscription signed in through the Anthropic provider is moved to the Anthropic Subscription (Claude Agent SDK) lane on startup, together with saved model selections, because Anthropic bills direct-API subscription requests to extra usage and refused them. The rejection now ends the turn once with the reason and what to do, instead of replaying it on every Anthropic model (#3259).

  • A tool named eval with its own permissionParser could answer for itself with a narrower class (for example read), so a preset that allows reads would run an arbitrary-code cell without asking. The eval permission request is now always carried alongside any tool-owned requests, so only a preset that allows everything allows a cell (#3211, requested by @code-yeongyu).

  • A provider whose credentials were locked when the store was first read no longer reports "not configured" to get_auth_providers after the lock clears, while its models already work. The status now re-reads the store the same way model availability does (#3273, reported from the OmO desktop app).

  • A fallback chain can walk to a rung that runs the same model at another thinking level. Such an entry used to disappear twice over: the chain scan consumed it as the entry in flight and then skipped it as a self-reference, and a model's remaining rungs were suppressed once one of them had been taken - so a chain written as models: [X:high, X:off, Y], which is how the OMO/senpi adapter ships it (the entries [X:off, Y] under the bare X key), jumped straight to Y. Chain validation no longer reports X:off under the X key as referencing the same model. Cooldowns and circuits stay keyed by the model, because a rate-limited or spent account is unhealthy at every level, so one same-model rung remains reachable per turn before the current model's cooldown expires.

Removed

  • Removed the Codex app-server command, daemon, generated protocol and compatibility QA harness. Process integrations use Native RPC (senpi --mode rpc or senpi host); OpenAI API and ChatGPT subscription models remain supported, and historical model-change records remain readable. Extensions that compared ctx.mode with "app-server" must drop that branch: ExtensionMode no longer includes it (#3167, requested by @code-yeongyu).

@code-yeongyu/senpi-ai

Breaking Changes

Added

Changed

  • The bundled model catalog is refreshed from models.dev and the providers' model listings (github-copilot, google, google-vertex, meta, opencode, opencode-go, opengateway, openrouter, vercel-ai-gateway).

Fixed

  • OpenCode Go models served over the Google Generative AI API now have a working transport; the refreshed catalog had added one, which broke the typed catalog. Two entries the provider no longer offers are removed from OpenCode Go.
  • Venice deepseek models (deepseek-v4-1-flash, deepseek-v4-pro-0813 and the other deepseek-v4 entries) work again: requests no longer carry DeepSeek's thinking key, which Venice rejected with 400 on every call, and thinking runs through Venice's reasoning_effort instead (#3308).
  • Anthropic's "Third-party apps now draw from your extra usage" rejection is classified as terminal account exhaustion with a plain explanation of the billing path, and the anthropic provider no longer offers a Claude subscription OAuth login; subscriptions use the Agent SDK lane (#3259).

Removed

@code-yeongyu/senpi-agent-core

Breaking Changes

Added

Changed

Fixed

Removed

@code-yeongyu/senpi-codemode

Breaking Changes

Added

Changed

Fixed

  • display() of a large object, such as a screenshot result that wraps a multi-MB Buffer, no longer writes megabytes into the session file or breaks the session render. The stored copy is trimmed inside the value instead of dropped: every top-level key is kept, Buffers become a <Buffer N MB> summary, long strings, arrays and keys keep a prefix with a visible marker, and the entry stays within the display budget, emoji included. Older sessions holding such entries render a short summary, and an object whose buffer holds image bytes now displays as the image with its metadata (#3320).

Removed

@code-yeongyu/senpi-tui

Breaking Changes

Added

Changed

Fixed

Removed