feat(agent): TinyAgents migration wave 2 — microcompact upstream, session shadow reads, budget dedupe, replay RPC - #4483
Conversation
…iddleware Deletes the in-house MicrocompactMiddleware (struct + impl) and constructs the crate `tinyagents::harness::middleware::MicrocompactMiddleware`, upstreamed to tinyagents (branch feat/microcompact-middleware, commit ac73382; gitlink bumped here). Constructed with OpenHuman's CLEARED_PLACEHOLDER and events off, so behavior is byte-identical to the deleted local version. The retained OpenHuman tests assert that parity against the crate type. Claude-Session: https://claude.ai/code/session_01Bgv25hEkC6nP3DYdat91PV
…gence (04.2 phase 2) Adds a store-backed shadow reader beside the legacy transcript reader: on the read path the session is also read back from the crate store and compared, logging `[session_shadow_read]` divergence. Legacy stays authoritative. Gated by config flag `agent.session_shadow_reads` (default OFF) with `OPENHUMAN_SESSION_SHADOW_READS` as a pure kill switch. Claude-Session: https://claude.ai/code/session_01Bgv25hEkC6nP3DYdat91PV
…dgetMiddleware observe-only Establishes a single owner for UsageRecorded recording via a dedupe guard, installs the crate BudgetMiddleware in observe-only mode, and demotes the local CostBudgetMiddleware to a divergence-logging shadow (`[budget_shadow]`). Local enforcement stays authoritative; flip criteria documented. Claude-Session: https://claude.ai/code/session_01Bgv25hEkC6nP3DYdat91PV
…ournal seams Adds read-only controllers openhuman.agent_run_events (paged via next_offset), agent_run_status, and agent_runs_active over the C4 journal/status seams, wired via the controller registry in src/core/all.rs. Claude-Session: https://claude.ai/code/session_01Bgv25hEkC6nP3DYdat91PV
Ticks the microcompact-middleware upstream-extraction row (deleted locally, now the crate type), records 04.2 phase-2 shadow-reads landing as the gate for the phase-4 session deletions, and updates the handoff to reflect all four wave-2 slices done on feat/tinyagents-wave2 with next-steps for wave 3. Claude-Session: https://claude.ai/code/session_01Bgv25hEkC6nP3DYdat91PV
`HarnessEventJournal as _` was unused in the replay ops test module (rustc `unused_imports`); the fan-out seam is exercised via `StoreEventJournal` / `JournalSink` directly. Claude-Session: https://claude.ai/code/session_01Bgv25hEkC6nP3DYdat91PV
rustfmt-only reflow of the wave-2 additions the slice agents left unformatted. Claude-Session: https://claude.ai/code/session_01Bgv25hEkC6nP3DYdat91PV
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 12 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (15)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a4023a1d8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| controllers | ||
| .extend(crate::openhuman::tinyagents::replay::all_agent_replay_registered_controllers()); |
There was a problem hiding this comment.
Keep replay controllers out of agent-facing registry
When these desktop replay controllers are added to build_registered_controllers(), they are included in the agent-facing schema/tool catalog; this file already has build_internal_only_controllers() for RPC-callable renderer-only surfaces. In a run with active IDs from agent_runs_active, an agent can call agent_run_events and receive raw AgentObservation records, including event variants such as model deltas/tool-call fragments and unknown-tool arguments from the journaled EventSink. Register these under the internal-only registry, or return a deliberately sanitized DTO if they must be agent-facing.
Useful? React with 👍 / 👎.
| // Read one extra record to detect whether a further page exists without a | ||
| // second store round-trip. | ||
| let mut events = journal.read_from(run_id, offset).await.map_err(|e| { |
There was a problem hiding this comment.
Avoid loading the full event stream for each page
For runs with a large journal, the page limit does not bound the read: read_from(run_id, offset) materializes every observation after offset before this function truncates to effective_limit. A reconnect with limit=200 on a long run can still read and deserialize the whole stream, causing latency/memory spikes and defeating the RPC's page cap; use a bounded read/iterator or stop after limit + 1 records.
Useful? React with 👍 / 👎.
Summary
MicrocompactMiddlewareinto the vendoredtinyagentscrate (tinyhumansai/tinyagents@feat/microcompact-middleware) and swapped OpenHuman onto it; local copy + impl deleted, behavior byte-identical (placeholder-configured, events off).[session_shadow_read]divergence; legacy stays authoritative (flagagent.session_shadow_reads, default OFF + env kill switch).UsageRecordedrecording (dedupe guard) + observe-only crateBudgetMiddleware; localCostBudgetMiddlewaredemoted to a[budget_shadow]divergence logger, still authoritative for enforcement; flip criteria documented.openhuman.agent_run_events(paged),agent_run_status,agent_runs_activecontrollers over the C4 journal/status seams, wired via the controller registry.Problem
Wave 1 landed the vendored SDK, session dual-writes, goals/todos shadows, journals, and middleware dedupe, but left several convergence items open: the local microcompact middleware had no crate equivalent (blocking its deletion), session reads were still 100% legacy with no parity signal, cost accounting could double-count once a crate budget middleware was added, and the restart-stable journal/status seams (C4) had no RPC surface for the desktop to replay/inspect runs.
Solution
Adapter-first throughout — legacy authoritative, crate features shadow and log divergence, deletions gated on proven parity:
MicrocompactMiddlewarein the crate (caller-supplied placeholder, opt-inCompressedevent, idempotent tool-body clearing) with the ported OpenHuman tests as the byte-for-byte parity contract. Pushed totinyhumansai/tinyagentsbefore bumping the submodule gitlink. OpenHuman constructs it withCLEARED_PLACEHOLDERand events off → identical behavior; the local struct/impl are deleted and the retained OpenHuman tests assert parity against the crate type.{workspace}/tinyagents_storeand compared to the legacy render, logging a compact (no-PII) divergence summary. Gated OFF by default with a pure env kill switch, mirroring the wave-1 dual-write pattern.BudgetMiddleware(emptyBudgetLimits, never enforces) can be installed without double-counting. The local gate is demoted to a shadow that logs[budget_shadow]divergence but still enforces. Three concrete flip criteria are documented at the registration site and in the deletion ledger.AgentObservation/HarnessRunStatusserde shapes directly (guaranteed round-trip stable, never prompt/tool/payload text), with paging (next_offset), capped limits, and[rpc]logging. Registered viasrc/core/all.rsper the controller-migration checklist.Submission Checklist
diff-cover) meet the gate enforced by.github/workflows/pr-ci.yml. Focused Rust module tests cover every new/changed flow (microcompact parity, shadow round-trip + kill switch, usage dedupe, replay paging/status/active); the coverage-gate job verifies the merged number.docs/TEST-COVERAGE-MATRIX.mdreflect this change —N/A: no new user-facing feature; internal harness shadows + read-only replay RPC over existing persisted data.N/A: no release-cut surface changed (internal harness shadows + read-only RPC, all off/additive by default).Closes #NNNin the## Relatedsection —N/A: continuation work tracked by the migration plan docs, no single issue.Impact
tinyhumansai/tinyagents@ac73382(feature branch, pushed). Fresh clones/worktrees mustgit submodule update --init vendor/tinyagents.Related
docs/tinyagents-full-migration-plan/)BudgetMiddlewareto enforcing owner once the 3 documented criteria hold; flip session reads to authoritative once[session_shadow_read]logs are divergence-clean (unlocks the 04.2 phase-4 legacy-session deletions).AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
senamakel:feat/tinyagents-wave20a4023a1d(+ vendoredtinyhumansai/tinyagents@ac73382)Validation Run
pnpm --filter openhuman-app format:check—N/A: noapp/(frontend) files changed.pnpm typecheck—N/A: no TypeScript changed.RUST_MIN_STACK=16777216 GGML_NATIVE=OFF cargo test --lib -- --test-threads=1 microcompact shadow_read run_events run_status runs_active duplicate_usage unobserved_turn(+ cratecargo test --lib microcompactinvendor/tinyagents).cargo fmtapplied (core + crate);cargo checkgreen.N/A: noapp/src-taurifiles changed.Validation Blocked
command:N/Aerror:N/Aimpact:N/ABehavior Changes
Parity Contract
Duplicate / Superseded PR Handling