Skip to content

chore: release v0.86.0 - #613

Merged
stamp-build[bot] merged 1 commit into
mainfrom
agent/cindy/release-0.86.0
Nov 2, 2026
Merged

stamp-build[bot] merged 1 commit into
mainfrom
agent/cindy/release-0.86.0

Conversation

@stamp-build

@stamp-build stamp-build Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Cindy from open-agent-runtime opened this pull request through Stamp
View in Stamp →


Minor release: a host can now ask a runtime to compact its context and wait until the runtime confirms it. This completes the 0.85.0 resume change: a prompt supplied on resume that only takes effect at the next native compaction (Claude's systemPrompt and appendSystemPrompt, Codex's appendSystemPrompt) can now be applied right away in the same session by resuming with the new prompt and then calling compact(). Codex's replacement systemPrompt already applies immediately. Stream-json turn ends also carry the native input identities.

New: manual compaction (#610)

  • Optional Runtime.manualCompaction says before opening whether a runtime supports it: { kind: "supported", activeTurn } or { kind: "unsupported", reason }. An absent declaration means untested, not unsupported. Supported now: Claude, Codex and Pi (in-process and subprocess). Declared unsupported with reasons: Kimi, Qwen, Antigravity, CodeBuddy. Not yet declared: Grok, Qoder, Cursor, OpenCode, Pi Durable and the community Morph runtime.
  • Optional Session.compact({ timeoutMs?, signal? }) returns a CompactionOutcome (new exported types ManualCompaction, CompactionOptions, CompactionOutcome):
    • completed: the runtime confirmed this compaction (Claude's compact_boundary, Codex's compaction item, Pi's manual compaction end); frame points at that record.
    • rejected: the compaction was not admitted, with a typed code and reason. Usually nothing reached the runtime, but Codex and Pi can also refuse after the native call (runtime_refused, runtime_exited), and Claude's command check talks to Claude first. Codes include busy (a turn, queued or not yet started input, another compaction, or an active Codex goal), aborted (the caller's signal was already aborted, so nothing was sent), unsupported (for example a project or user command shadows Claude's /compact), and the usual unreachable and error codes.
    • failed: the runtime reported failure, or the command did not actually compact (Claude reported failure, or its commands changed in between).
    • aborted: the runtime itself reported the compaction cancelled.
    • unconfirmed: OAR stopped observing without a confirmed result: timeout, signal, disposed, runtime_exited, session_released or observation_failed.
  • compact() throws RangeError when timeoutMs is negative or not finite.
  • All current implementations require an idle session. Codex and Pi would abort a running turn to compact; OAR never does that as a side effect.
  • Waiting limits only stop waiting. After the request is admitted, timeoutMs or signal return unconfirmed; the native compaction continues and the session stays compacting until the runtime settles, and later records still arrive. During that time new prompts, steer and a second compact() are refused as busy; input queued during the compaction is held by Claude and Pi until it ends, while Codex refuses it as busy. timeoutMs: 0 sends the request without waiting.
  • abort() during compaction uses the runtime's own cancel once there is something to cancel; before that it is refused as busy. A queued Claude /compact cancelled before it starts ends aborted. A Claude compaction already running and then interrupted is reported by Claude as a failure, so compact() returns failed with that native record, independent of the turn's own aborted ending. Codex refuses abort() as busy until its compaction item names the turn.
  • Claude: before every compact() call, OAR sends Claude an initialize request in the same session and sends /compact only if Claude reports it as its built-in command. On Claude 2.1.316 (Linux) repeated initialize requests did not re-run the SessionStart hook or the HTTP MCP server and left the permission mode, settings, system prompt and tool list unchanged; this is not a claim about every version or every hook implementation.
  • Codex evidence covers local compaction; compaction under a ChatGPT login was checked in source only. Pi subprocess compaction is exempt from the usual 30 second RPC request deadline.
  • Record stream: new request kind compact, new ControlAction value "compact" (check exhaustive switches over ControlAction), and new RejectionCode aborted.

Status checkpoint for incremental consumers

  • StatusState and statusValue are exported from the package root and @botiverse/oar/observe; reduceStatus and initialStatus now take and return StatusState. Hosts that fold status incrementally must persist the complete StatusState together with their cursor and pass it back unchanged. The displayed AgentStatus (statusValue, Session.status()) alone cannot continue a fold through a manual compaction.
  • The same applies to the observe helpers: TaskState.status is now a StatusState, and SessionView gains statusState?. Persist these whole as well.
  • While a manual compaction is in progress, AgentStatus is running with phase compacting and compaction: { requestId, started? }.

Turn input identities

  • turn_ended.inputId? and turn_ended.inputIds? copy the stream-json result's user_message_uuid and ordered user_message_uuids when the runtime reports them, including on ordinary turns. Neither is derived from the other. When Claude merges several queued inputs into one turn, its inputId names the latter input and there is no first or last rule to rely on, so use inputIds to settle all of them. OAR's own interrupt fallback is separate and still uses mergedInputIds and carries. Claude reports these fields; Qwen 0.26.5 and Qoder 1.1.81 currently do not.
  • Stored OAR records do not change. Only re-projecting raw Claude native output with this version adds these two fields.

Docs and experiments

  • Qwen compaction attribution (docs(qwen): record compaction attribution limits #609): in Qwen's stream-json output, the manual compaction status goes through the same assistant text frames as model output, so OAR cannot tell them apart; automatic compression emits no frame at all; and a user compress.toml can replace /compress. OAR emits no Qwen compaction events and does not guess from text.
  • DeepSeek Harness plugin bridge probe (test(dsh): probe an external native plugin bridge #607): an external plugin shipped outside DSH can drive DSH's native controls and events without ACP, on DSH 0.2.1-rc.5 and 0.2.2-alpha.2. Experiment only; no DSH runtime yet.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@stamp-build
stamp-build Bot merged commit 47c2c3f into main Nov 2, 2026
36 checks passed
@stamp-build
stamp-build Bot deleted the agent/cindy/release-0.86.0 branch November 2, 2026 23:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants