Skip to content

release: v0.3.7 session context convergence - #27

Merged
echoVic merged 1 commit into
mainfrom
feat/ask-user-question
Aug 6, 2026
Merged

release: v0.3.7 session context convergence#27
echoVic merged 1 commit into
mainfrom
feat/ask-user-question

Conversation

@echoVic

@echoVic echoVic commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Orca v0.3.7

Orca v0.3.7 completes the session-context and TUI projection reliability
slice on top of v0.3.6's delegated execution and durable task-state work.

What Changed

  • Recorded sessions restore the latest provider prompt occupancy before the
    first resumed turn. The context limit is derived from the configured model
    window, while legacy usage records remain readable.
  • The TUI carries a typed context revision and does not let an older surface
    snapshot overwrite a newer provider context observation. The context footer
    therefore remains accurate while the next durable surface batch arrives.
  • Assistant reasoning, message, and plan streams retain their opened order
    during snapshot and foreground hydration. A completed response that exactly
    matches already streamed items is not projected a second time.
  • Existing v0.3.6 behavior remains included: delegated child agents inherit
    one immutable policy snapshot; transcript appends and rewrites share a
    cross-process lock; retry and truncation diagnostics remain in task state;
    and session completion publishes the complete task registry first.

Compatibility

Saved transcripts with older usage records remain readable. New context
revision and projection fields are runtime-internal and do not change CLI,
JSONL, app-server, ACP, provider, or task identifier contracts.

Verification

  • cargo fmt --all -- --check
  • cargo check --workspace --all-targets --locked
  • Focused runtime and TUI tests for resumed context, repeated usage snapshots,
    revision-safe projection, assistant stream ordering, and duplicate response
    suppression
  • cargo nextest run --workspace --all-targets --locked --profile ci --no-fail-fast
  • Runtime surface, repository adapter, version synchronization, npm staging,
    website build, SEO, and published-release verification gates
  • git diff --check

Upgrade

npm install -g @blade-ai/orca@0.3.7

macOS and Linux native installer:

curl -fsSL https://orcaagent.dev/install.sh | \
  INSTALL_DIR=/usr/local/bin ORCA_VERSION=0.3.7 sh

Windows PowerShell, including workspace sandbox setup:

& ([scriptblock]::Create((irm https://orcaagent.dev/install.ps1))) -Version 0.3.7 -SetupSandbox

Summary by CodeRabbit

  • New Features

    • Restored provider context usage when resuming recorded sessions.
    • Preserved assistant stream order during session replay.
    • Prevented duplicate completion events in streamed responses.
    • Improved context updates by ignoring stale projection data.
  • Bug Fixes

    • Fixed resumed sessions displaying incorrect context limits or usage.
    • Fixed newer context information being overwritten by older updates.
  • Documentation

    • Added v0.3.7 release notes and updated product documentation and changelogs.
  • Release

    • Updated the application and package version to v0.3.7.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The release restores recorded-session context usage, derives model context limits, protects TUI context updates with revisions, preserves assistant stream order during hydration, and suppresses duplicate completed responses. Release metadata and documentation now target v0.3.7.

Changes

Runtime context restoration

Layer / File(s) Summary
Usage snapshot reading and surface initialization
crates/orca-runtime/src/thread_store*, crates/orca-runtime/src/runtime_host.rs, crates/orca-runtime/src/runtime_host.rs tests
Recorded sessions read the latest provider input-token delta. Resume failures become ThreadStartFailed. Surface context usage uses restored tokens and the configured model context limit. Ephemeral threads pass no restored usage.
TUI history synchronization
crates/orca-tui/src/app.rs
History loading emits SurfaceProjectionSynced with the runtime surface snapshot. Tests verify restored usage and the configured limit.

Revision-safe projection and ordered replay

Layer / File(s) Summary
Assistant stream hydration and completion matching
crates/orca-tui/src/surface_projection.rs
Assistant streams retain opening order during snapshot and post-watermark hydration. Completion events are suppressed when streamed items already exactly match the completed response.
Context revision tracking
crates/orca-tui/src/types.rs, crates/orca-tui/src/ui.rs
Surface snapshots apply only when their revision advances. Newer legacy ContextUpdated values remain protected from stale snapshots. Tests cover revision advancement and status rendering.

Release updates

Layer / File(s) Summary
v0.3.7 metadata and documentation
Cargo.toml, npm/orca/package.json, docs/*, site/src/*
Package versions, roadmap data, release notes, harness contract text, and English and Chinese changelog entries now describe v0.3.7.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RecordedSession
  participant RuntimeHost
  participant ThreadStore
  participant TuiApp
  participant SurfaceProjection
  RecordedSession->>RuntimeHost: resume recorded thread
  RuntimeHost->>ThreadStore: read latest context tokens
  ThreadStore-->>RuntimeHost: return restored token usage
  RuntimeHost->>SurfaceProjection: initialize usage and context limit
  TuiApp->>SurfaceProjection: apply SurfaceProjectionSynced
  SurfaceProjection-->>TuiApp: preserve newer context and ordered streams
Loading

Possibly related PRs

  • echoVic/orca-agent#17: Related TUI surface projection, usage revision tracking, and session restoration changes.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.89% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the v0.3.7 release and its main session-context convergence changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ask-user-question

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@echoVic
echoVic force-pushed the feat/ask-user-question branch from 2a33be1 to 85f9601 Compare August 6, 2026 05:21

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
crates/orca-tui/src/types.rs (1)

1746-1758: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Clarify the context-revision/legacy-observation interaction.

should_apply_context = revision_advanced && (!self.context_observed || self.context_revision.is_some()) is correct per the tests at Lines 5729-5771 (a stale snapshot never overwrites a newer legacy ContextUpdated value, and any snapshot after the first one always wins once a revision has been applied). The condition is hard to read from the code alone: the second clause exists only to let a legacy observation block exactly the first-ever typed snapshot, not later ones.

Add an inline comment above this block naming the two intentional outcomes:

  1. A stale snapshot revision never overwrites a legacy context observation.
  2. Once one typed snapshot has been applied, the next advancing revision always wins over any legacy observation.
♻️ Proposed clarifying comment
+        // Legacy provider context events set `context_observed`. A snapshot with an
+        // advanced revision always wins once at least one snapshot has been applied
+        // (`context_revision.is_some()`); only the very first snapshot for a session
+        // can be blocked by a legacy observation that arrived before it.
         let revision_advanced = self
             .context_revision
             .is_none_or(|revision| projection.context_revision > revision);

As per coding guidelines, this reasoning was already partly captured in the field doc comment on context_revision (Lines 932-935); extending it to the exact boolean expression that implements it reduces the risk of a future regression to this correctness-sensitive path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/orca-tui/src/types.rs` around lines 1746 - 1758, Add an inline comment
immediately above the context-revision logic in the relevant method, documenting
that stale snapshots never overwrite legacy context observations and that, after
the first typed snapshot is applied, every advancing revision takes precedence
over legacy observations. Keep the existing boolean expression and behavior
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/orca-tui/src/surface_projection.rs`:
- Around line 559-569: Update the live reduction logic in reduce_typed_batch to
track whether any assistant stream for response.turn_id has state Discarded.
Even when response_matches_streamed_items returns true, emit
response_completed_event unless no discarded stream exists, preserving
reconciliation for discarded retries. Add a regression test covering a discarded
stream and a surviving stream matching the final response, asserting
AssistantResponseCompleted is emitted.

---

Nitpick comments:
In `@crates/orca-tui/src/types.rs`:
- Around line 1746-1758: Add an inline comment immediately above the
context-revision logic in the relevant method, documenting that stale snapshots
never overwrite legacy context observations and that, after the first typed
snapshot is applied, every advancing revision takes precedence over legacy
observations. Keep the existing boolean expression and behavior unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e987664-fec8-4732-8d36-2c5d47cf7187

📥 Commits

Reviewing files that changed from the base of the PR and between 9516569 and 85f9601.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • Cargo.toml
  • crates/orca-core/src/config/mod.rs
  • crates/orca-runtime/src/runtime_host.rs
  • crates/orca-runtime/src/thread_store.rs
  • crates/orca-runtime/src/thread_store/writer.rs
  • crates/orca-tui/src/app.rs
  • crates/orca-tui/src/surface_projection.rs
  • crates/orca-tui/src/types.rs
  • crates/orca-tui/src/ui.rs
  • docs/harness-contract.md
  • docs/production-roadmap.md
  • docs/releases/v0.3.7.md
  • npm/orca/package.json
  • site/src/changelog/Changelog.tsx
  • site/src/shared.ts

Comment on lines +559 to +569
let response_matches_streams =
response_matches_streamed_items(response, assistant_streams.values());
for stream in assistant_streams.values_mut().filter(|stream| {
stream.turn_id == response.turn_id
&& stream.state == SurfaceAssistantStreamState::Open
}) {
stream.state = SurfaceAssistantStreamState::Completed;
}
projected.push(response_completed_event(response));
if !response_matches_streams {
projected.push(response_completed_event(response));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix: dedup check ignores discarded-stream retries and can suppress needed cleanup.

response_matches_streamed_items filters out Discarded streams before comparing them to the response's message/reasoning/plan items. When a turn has an earlier Discarded stream (a retry) whose partial content was already pushed into AppState.messages through ReasoningDelta/MessageDelta, and the surviving (non-discarded) stream happens to match the final response exactly, this function returns true and response_completed_event is not pushed.

AssistantResponseCompleted is the only mechanism that reconciles this in the live path: its handler, reconcile_assistant_response, calls retain_messages to remove all Reasoning/Assistant/ProposedPlan messages after the last user message and re-adds the canonical text. Skipping this event leaves the discarded stream's stale content visible in the transcript alongside the final content.

The existing test foreground_hydration_reconciles_completed_item_for_discarded_stream (in this same file) confirms that discarded-stream content requires exactly this reconciliation through AssistantResponseCompleted in the reconnect path. The live reduce_typed_batch path now has a gap: it can skip that same reconciliation.

Track whether any stream for this turn_id was discarded, and do not suppress the event in that case.

🐛 Proposed fix
 SurfaceEvent::Assistant(AssistantPatch::ResponseCompleted { response }) => {
-    let response_matches_streams =
-        response_matches_streamed_items(response, assistant_streams.values());
+    let has_discarded_stream_for_turn = assistant_streams.values().any(|stream| {
+        stream.turn_id == response.turn_id
+            && stream.state == SurfaceAssistantStreamState::Discarded
+    });
+    let response_matches_streams = !has_discarded_stream_for_turn
+        && response_matches_streamed_items(response, assistant_streams.values());
     for stream in assistant_streams.values_mut().filter(|stream| {
         stream.turn_id == response.turn_id
             && stream.state == SurfaceAssistantStreamState::Open
     }) {
         stream.state = SurfaceAssistantStreamState::Completed;
     }
     if !response_matches_streams {
         projected.push(response_completed_event(response));
     }
 }

Add a regression test with a Discarded stream plus a surviving stream whose content exactly matches the response, and assert that AssistantResponseCompleted is still emitted.

Also applies to: 1376-1422

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/orca-tui/src/surface_projection.rs` around lines 559 - 569, Update the
live reduction logic in reduce_typed_batch to track whether any assistant stream
for response.turn_id has state Discarded. Even when
response_matches_streamed_items returns true, emit response_completed_event
unless no discarded stream exists, preserving reconciliation for discarded
retries. Add a regression test covering a discarded stream and a surviving
stream matching the final response, asserting AssistantResponseCompleted is
emitted.

@echoVic
echoVic merged commit 6088d85 into main Aug 6, 2026
4 of 6 checks passed
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.

1 participant