Skip to content

feat(agent): tinyagents 1.5 migration wave — vendored SDK, dual-write sessions, goals/todos shadows, journals, middleware dedupe#4473

Merged
senamakel merged 24 commits into
tinyhumansai:mainfrom
senamakel:feat/tinyagents-c0-15-baseline
Jul 3, 2026
Merged

feat(agent): tinyagents 1.5 migration wave — vendored SDK, dual-write sessions, goals/todos shadows, journals, middleware dedupe#4473
senamakel merged 24 commits into
tinyhumansai:mainfrom
senamakel:feat/tinyagents-c0-15-baseline

Conversation

@senamakel

@senamakel senamakel commented Jul 3, 2026

Copy link
Copy Markdown
Member

Summary

  • TinyAgents migration wave 1+2 — executes docs/tinyagents-full-migration-plan/CONTINUATION-2026-07.md (C0 baseline + parallel adapter-first slices), all landing in this PR.
  • C0: bumps tinyagents 1.3 → 1.5.0, vendors the SDK as a submodule at vendor/tinyagents with [patch.crates-io] in both Cargo worlds; RepeatedToolFailureMiddleware becomes a thin driver over crate NoProgressTracker; crate with_node_retry seam on delegation + spawn-parallel graphs; docker CI carries the submodule.
  • C1 (04.1): live turns dual-write into the tinyagents Store (session.{stem}.messages + descriptor), flag agent.session_dual_write (default ON) with env kill switch; write-side parity test proves legacy JSONL ↔ store render identical transcripts.
  • C2: thread goals mirrored into crate graph.goals (byte-identical keys, idempotent migration helper) and task board mirrored into crate graph.todos with claim_card CAS shadow — both shadow-mode, legacy authoritative, divergence warn-logged.
  • C3 (partial by design): CacheAlignMiddleware deleted (−147 lines; crate cache guard already installed). Microcompact deletion refused — NOT crate-superseded (corrected in plan); unknown-tool sentinel already gone, ReturnToolError kept deliberately (fix(tinyagents): keep attempted tool name in the timeline for unavailable tools #4419 UX).
  • C4 (05.1): restart-stable {run_id}-evt-{offset} journal event ids, durable status store answering list_by_thread, late-attach replay proven from the store alone.
  • Docs: continuation plan, coverage sweep of previously unreferenced harness files, execution corrections, wave-1 handoff.

Problem

The tinyagents migration (#4249) landed on 1.3; the crate has since shipped 1.4/1.5 with primitives that replace in-house code (graph::goals, graph::todos, NoProgressTracker, resumable graph failures, durable journals). Remaining migration work also needs to modify SDK source and test against OpenHuman in one tree.

Solution

  • Submodule pinned at released v1.5.0; path patch keeps manifest requirement and vendored source in lockstep. Agents/devs can change SDK source in-tree and PR upstream from the submodule.
  • Every runtime slice is adapter-first and flag-gated: dual-writes/shadows mirror into crate stores while legacy stays authoritative; divergence is logged, cutover is a later, isolated flip per slice.
  • Behavior-preserving seams (retry max_attempts=1, tracker-driven nudge/halt with identical steering semantics) adopted now; escalation later.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy — per-slice focused tests: middleware nudge/halt/reset, dual-write parity + kill-switch matrix, goals adapter round-trip via crate reader, todos claim CAS shadow, journal late-attach replay + redaction
  • Diff coverage ≥ 80% — enforced by the coverage-gate job on this PR; targeted module suites run locally per slice
  • Coverage matrix updated — N/A: adapter-first mirrors + dependency vendoring; no user-facing feature rows added/removed
  • All affected feature IDs from the matrix are listed in the PR description under ## RelatedN/A: no matrix rows affected
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • Manual smoke checklist updated if this touches release-cut surfaces — N/A: shadow/dual-write paths flag-gated with kill switches; legacy paths authoritative
  • Linked issue closed via Closes #NNN in the ## Related section — N/A: follow-up wave to #4249; no dedicated issue

Impact

  • Runtime: legacy behavior authoritative everywhere; new writes are additive (store mirrors, journals) with per-flag kill switches (OPENHUMAN_SESSION_DUAL_WRITE, shadow flags default OFF where risky).
  • Build: both Cargo worlds resolve tinyagents v1.5.0 (path: vendor/tinyagents); fresh clones/worktrees need git submodule update --init vendor/tinyagents; docker core image build handled in release workflows.
  • Wave 2 (in flight, will extend this PR): 04.2 shadow reads, UsageRecorded dedupe + crate BudgetMiddleware (observe-only), microcompact extraction into the SDK, journal replay RPC.

Related

https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4

Summary by CodeRabbit

  • New Features

    • Added support for a newer vendored dependency version and updated build/release pipelines to include required source content during Docker builds.
    • Introduced session mirroring with a default-on toggle and an environment-based kill switch.
    • Added live shadow syncing for goals and task boards to keep mirrored data aligned.
  • Bug Fixes

    • Improved retry and progress handling for agent workflows.
    • Made journal/event tracking more stable for replay and late reattachment.
    • Tightened cache drift handling and removed outdated alignment behavior.

senamakel added 17 commits July 3, 2026 11:36
…os, no-progress, session cutover)

Ground-truth audit of post-tinyhumansai#4249 main + re-inventory of tinyagents 1.4.0/1.5.0.
Re-evaluates the deletion ledger's 'never delete' list, adds thread goals /
thread tasks migration onto graph::goals / graph::todos, and sequences the
remaining ~29k-line reclaim (C0-C7).

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
…iles

Adds verdicts for extract_tool/handoff, the four task-local context
carriers, turn_checkpoint, memory_protocol, definition loader/builtins,
and subagent_runner residuals; wires the carriers into C6.

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
…ignore

Bumps the tinyagents dependency from 1.3.0 to 1.5.0 across Cargo.toml and Cargo.lock files. Updates related documentation to reflect the new version. Additionally, adds *.diff to .gitignore to exclude diff files from version control.
…to in-tree source

vendor/tinyagents pinned at v1.5.0 (matches the crates.io requirement);
[patch.crates-io] path override in root and app/src-tauri manifests so
migration agents can modify SDK source in-tree and PR upstream from the
submodule. Both worlds resolve tinyagents v1.5.0 (path); crate checks clean.

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
…NoProgressTracker

Rewrite the repeated-tool-failure circuit breaker as a thin driver over
tinyagents 1.5.0 harness::no_progress::NoProgressTracker instead of the
in-house identical/varied/hard-reject failure ladder it replaces.

The middleware now owns only OpenHuman-side policy: capture the per-call
argument fingerprint in before_tool, feed each outcome into
NoProgressTracker::record, and lower the returned NoProgress verdict into
steering — Nudge -> SteeringCommand::Redirect (structured 'no progress since
step X' corrective), Halt -> record root-cause summary in HaltSummarySlot +
SteeringCommand::Pause + tracker.reset(). Continue is a no-op.

Deletes the duplicated crate-side ladder constants/logic
(NO_PROGRESS_FAILURE_THRESHOLD, HARD_REJECT_REPEAT_THRESHOLD, inline
same_count/consecutive counters + summary wording). Unit tests adapted to the
tracker-driven behavior (halt now emits Pause; a nudge Redirect precedes it).

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
The [patch.crates-io] path override made vendor/tinyagents part of the
cargo graph; the Dockerfile now COPYs vendor/ (needed already at the
dep-cache stage) and both docker jobs init just that submodule after
checkout (targeted init skips the large tauri-cef fork the core image
does not need). All other cargo-running CI jobs already checkout with
submodules: recursive/true; the mobile crates do not depend on the core
crate, so their submodules:false stays.

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
…ion + spawn-parallel graphs

Adopt tinyagents 1.5.0 CompiledGraph::with_node_retry(RetryPolicy) on the
delegation graph (build_delegation_graph) and the live spawn-parallel execution
graph (run_spawn_parallel_execution_graph).

Adapter-first and behavior-preserving: neither graph carried bespoke retry glue,
so the policy is RetryPolicy::default().with_max_attempts(1) — a single attempt,
identical to today's semantics — with backoff sleeping left off (the default).
This lands the crate seam so raising the attempt cap or enabling backoff becomes
a one-line gated follow-up rather than a rewrite.

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
…5.1)

Seed the per-turn EventSink with with_stream_id(run_id) so every durable
observation persists a restart-stable {run_id}-evt-{offset} event_id — the
id a late-attach replay reconstructs the timeline from. Mint the run id
once before the sink and thread it into attach_turn_journal (no longer
minted internally), and record the sub-agent task scope as the status
thread_id so FileStatusStore::list_by_thread answers.

Journal test now asserts ordered, stable {stream_id}-evt-{offset} ids, an
offset>0 late-attach tail replay, and list_by_thread/list_active/list_by_root
over the durable status store.

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
CacheAlignMiddleware was a warn-only KV-cache-prefix diagnostic that scanned
the system prompt for volatile tokens (uuid/jwt/iso8601/hex) and emitted a
free-text `log::warn!`. Its structured, crate-native successor —
`PromptCacheSegmentMiddleware` stamping content-fingerprinted `PromptSegment`s
plus the crate `PromptCacheGuardMiddleware` recording `CacheLayoutEvent`s — is
already installed on the shared runner and drained via
`observability::surface_cache_layout_events`. The shadow was explicitly a
"kept installed in parallel until parity is shown; deletion is a gated
follow-up"; C3 lands that deletion.

Removed:
- `CacheAlignMiddleware` struct + `Middleware` impl and its install in
  `TurnContextMiddleware::install`.
- The `cache_align` config field (+ its wiring in the session turn builder,
  `defaults()`, `is_empty()`).
- The exclusive helper machinery: `VolatileFinding`,
  `detect_volatile_prompt_tokens`, `warn_if_cache_prompt_volatile`,
  `redact_volatile_token`, `is_uuid`/`is_jwt`/`is_hex_hash`/`is_iso8601`.

MicrocompactMiddleware is intentionally retained (see report): the vendored
tinyagents 1.5.0 ships no Microcompact equivalent and the local one is live on
the session path (default keep_recent=5), so deleting it would drop
tool-body-clearing behavior with no crate replacement.

Updated the `defaults_enable_cache_align_and_the_byte_cap_only` test (now
`defaults_enable_the_byte_cap_only`) and refreshed the now-stale
"kept installed in parallel" comments across mod.rs / observability.rs.

Gate: GGML_NATIVE=OFF cargo check (clean) + `cargo test --lib
tinyagents::middleware` (25 passed).

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
…Rewrite (C3)

C3 step 4 asked to adopt `UnknownToolPolicy::Rewrite` and delete the
`__openhuman_unknown_tool__` sentinel + `UnknownToolRewriteMiddleware`. Ground
truth on this baseline: that deletion already landed in 01.2 — the sentinel
tool, its registration, and the rewrite middleware are gone from src/ and
tests (only historical comments remain). The live policy is already
`ReturnToolError`.

Flipping to `Rewrite { tool_name }` would be a regression, not a cleanup:
Rewrite needs a real catch-all target tool (the deleted sentinel was exactly
that) and, when it hits, silently retargets + executes that tool, emitting
`AgentEvent::UnknownToolCall { recovery: "rewrite:.." }` with NO injected tool
message. Two live consumers depend on the `ReturnToolError` path's injected
`unknown tool `<name>` (arguments: ..); valid tools: [..]` message:
- the tinyhumansai#4419 attempted-tool-name UX, and
- `agent::hooks::sanitize_tool_output`, which classifies the failure as
  `unknown_tool` by matching the "unknown tool" substring.
The crate already preserves the original requested name + arguments verbatim on
`AgentEvent::UnknownToolCall`, projected by `OpenhumanEventBridge`.

No functional change — documents the decision at the `run_policy_for` site so a
future reader does not "finish" C3 by flipping to Rewrite and silently break
both consumers.

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
…rst slice)

Adapter-first, log-only. Adds src/openhuman/todos/graph_shadow.rs which
mirrors every authoritative task-board write into the vendored
tinyagents::graph::todos crate Store (ns graph.todos) and shadow-replays
the crate claim_card CAS, warn-logging any divergence. Legacy TaskBoardStore
+ todos::ops stay the single source of truth; RPC shapes and product
behavior are untouched.

- graph_shadow.rs: total status mapping (7 variants, 1:1), full TaskBoardCard
  conversion, FileStore-backed crate store, spawn_mirror + spawn_shadow_claim
  (best-effort, tokio-runtime-guarded, no-op for scratch boards).
- ops.rs: save_cards mirrors the persisted board; claim_card refactored to
  compute one ok/err verdict via an extracted apply_claim helper so the crate
  shadow observes the same not-found/wrong-status/single-InProgress outcomes.
  Legacy claim result and all existing tests unchanged.
- Unit tests cover status mapping round-trip, card-field preservation,
  approval-mode mapping, scratch skip, crate mirror round-trip, the shared
  single-InProgress rejection, and the crate claim_card CAS contract.

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
Records the graph::todos adapter surface: what maps (dispatch, thread binding,
CRUD ops, status aliases, single-InProgress, claim_card CAS) and what stays
product residue (approval gate, DomainEvent emissions, threads.task_board_* /
openhuman.todos_* RPC projections, scratch board, run lifecycle). Documents the
single-writer constraint and the not-in-this-slice cutover steps.

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
Adapter-first mirror of the thread_goals domain onto the tinyagents 1.5.0
`graph::goals` crate store (issue tinyhumansai#4249, plan §C2). Legacy per-thread
file-JSON store stays authoritative for reads; every goal mutation is also
mirrored, faithfully (same goal_id/timestamps/counters), into the crate
`Store` ns `graph.goals` at `{workspace}/tinyagents_store/kv`, byte-for-byte
under the key the crate's own reader computes.

- `crate_adapter.rs`: status/goal projections (Active/Paused/BudgetLimited/
  Complete, completion contract, token-budget fields), put/get/delete mirror,
  a one-time idempotent migration helper (callable + logged, NOT wired to
  boot), and a shadow-mode surface gated OFF behind
  OPENHUMAN_THREAD_GOALS_CRATE_SHADOW (acts on legacy, logs divergence).
- Wire flag-gated shadow mirror into the tool surface (goal_set/goal_complete)
  and host surface (set/complete/pause/resume/clear); RPC schemas untouched.
- Single-writer constraint documented (core is the only mutator; crate Store
  has no cross-process CAS).
- Focused unit tests for the adapter mapping + migration idempotency
  (thread_goals module: 37 passed).

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
Introduces AgentConfig::session_dual_write (serde default true) — the
config knob that gates the live session-store dual-write (issue tinyhumansai#4249,
sessions 04.1). The OPENHUMAN_SESSION_DUAL_WRITE env var remains a pure
kill switch layered on top; this field is the default-driving flag so the
store is populated by live turns for the 04.2 read cutover.

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
… config flag + kill switch (04.1)

Mirrors each already-persisted turn into {workspace}/tinyagents_store/
{kv,journal} alongside the authoritative legacy session_raw/*.jsonl
transcript, reusing session_import/convert.rs normalization so live and
imported records are shape-identical (per-session stream
session.{stem}.messages + sessions-ns descriptor upsert).

- live::write_live_turn performs the best-effort, non-fatal mirror after
  the legacy JSONL append in session/turn/session_io.rs; store-write
  failures are logged ([session-store]) and swallowed, never touching the
  chat turn or legacy path.
- live::session_kv_store registers the session KV FileStore on each turn's
  RunContext.stores (assemble path) under TINYAGENTS_SESSION_KV_STORE, so
  the harness carries a handle to the same tree; reads stay 100% legacy
  until 04.2.
- Gating unified on AgentConfig::session_dual_write (default ON) via
  live::dual_write_enabled(config_enabled), with OPENHUMAN_SESSION_DUAL_WRITE
  as a pure kill switch; session_kv_store self-gates on the same decision.
- Write-side parity test: drives the legacy JSONL writer and the live
  mirror with the same turn and asserts the store journal renders the
  identical JournalMessages the importer reads back (incl. reconstructed
  openhuman_turn_usage + tool-call id), plus the config/kill-switch matrix.

Claude-Session: https://claude.ai/code/session_013uVSkcdR2eP7hW4xm54wb4
@senamakel
senamakel requested a review from a team July 3, 2026 20:45
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 725d4d47-3f82-4513-b487-9b8b163e0d13

📥 Commits

Reviewing files that changed from the base of the PR and between 5a1227d and e7bdbb7.

📒 Files selected for processing (19)
  • docs/tinyagents-full-migration-plan/C2b-todos-parity.md
  • docs/tinyagents-full-migration-plan/HANDOFF-2026-07-03.md
  • src/openhuman/agent/harness/session/turn/core.rs
  • src/openhuman/agent/harness/session/turn/session_io.rs
  • src/openhuman/config/schema/agent.rs
  • src/openhuman/session_import/live.rs
  • src/openhuman/session_import/live_tests.rs
  • src/openhuman/session_import/mod.rs
  • src/openhuman/thread_goals/crate_adapter.rs
  • src/openhuman/thread_goals/mod.rs
  • src/openhuman/thread_goals/ops.rs
  • src/openhuman/thread_goals/tools.rs
  • src/openhuman/tinyagents/journal.rs
  • src/openhuman/tinyagents/middleware.rs
  • src/openhuman/tinyagents/mod.rs
  • src/openhuman/tinyagents/observability.rs
  • src/openhuman/todos/graph_shadow.rs
  • src/openhuman/todos/mod.rs
  • src/openhuman/todos/ops.rs

📝 Walkthrough

Walkthrough

This PR vendors tinyagents, updates release and Docker build wiring, bumps Cargo resolution to 1.5.0, refreshes migration documentation, and adds crate-backed session, retry, goals, and todos integrations.

Changes

TinyAgents vendoring and integration rollout

Layer / File(s) Summary
Submodule and build wiring
.gitmodules, .gitignore, vendor/tinyagents, .github/workflows/release-production.yml, .github/workflows/release-staging.yml, Dockerfile, Cargo.toml, app/src-tauri/Cargo.toml
Registers the vendored submodule, initializes it in release workflows, copies vendor sources into Docker, and patches Cargo resolution to the vendored path while bumping tinyagents to 1.5.0.
Migration plan updates
docs/tinyagents-full-migration-plan/*, docs/tinyagents-migration-spec.md, docs/tinyagents-session-migration-design.md, gitbooks/developing/architecture/agent-harness.md
Updates TinyAgents migration docs and handoff notes to reflect version 1.5.0, current workstream ordering, and continuation planning.
Session dual-write and journal plumbing
src/openhuman/config/schema/agent.rs, src/openhuman/session_import/*, src/openhuman/agent/harness/session/turn/*, src/openhuman/tinyagents/journal.rs, src/openhuman/tinyagents/mod.rs, src/openhuman/tinyagents/observability.rs
Adds default-on session dual-write config, live store registration, stable journal run/thread IDs, and matching tests and call-site wiring.
Retry policy and failure ladder
src/openhuman/agent_orchestration/spawn_parallel_graph.rs, src/openhuman/tinyagents/delegation.rs, src/openhuman/tinyagents/middleware.rs, src/openhuman/tinyagents/mod.rs
Wires per-node retry policy into compiled graphs and replaces repeated-tool failure state with the crate no-progress ladder.
Thread goals shadow adapter
src/openhuman/thread_goals/*
Adds a crate-backed thread-goals shadow adapter and mirrors goal mutations and clears into the vendored store.
Task board shadow adapter
src/openhuman/todos/*
Adds a crate-backed task-board shadow adapter and mirrors saved boards and claims into the vendored graph.todos store.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AgentConfig
  participant LiveImport
  participant SessionIO
  participant EventSink
  participant Journal

  AgentConfig->>LiveImport: session_dual_write enabled
  SessionIO->>LiveImport: dual_write_enabled(config_enabled)
  LiveImport-->>SessionIO: mirror allowed or killed
  Journal->>EventSink: with_stream_id(run_id)
  SessionIO->>Journal: attach_turn_journal(run_id, thread_id)
Loading
sequenceDiagram
  participant Tool as Tool Call
  participant Middleware as RepeatedToolFailureMiddleware
  participant Tracker as NoProgressTracker
  participant Steering as SteeringHandle

  Tool->>Middleware: after_tool(result/error)
  Middleware->>Tracker: record(step, ToolAttempt)
  Tracker-->>Middleware: NoProgress::Continue/Nudge/Halt
  alt Nudge
    Middleware->>Steering: SteeringCommand::Redirect
  else Halt
    Middleware->>Middleware: store halt summary
    Middleware->>Steering: SteeringCommand::Pause
    Middleware->>Tracker: reset
  end
Loading

Possibly related PRs

Suggested labels: rust-core, feature, agent

Suggested reviewers: sanil-23, M3gA-Mind

Poem

A rabbit found a vendor'd way,
with tinyagents bright as day.
It hopped through retries, journal trails,
and shadow stores with careful tails. 🐰
New docs, new paths, new crates in tune—
the burrow hums a migration tune.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: migrating TinyAgents to 1.5 with vendoring and related graph/middleware updates.

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

@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. labels Jul 3, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5a1227ddf2

ℹ️ 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".

Comment thread Cargo.toml
# immediately, and PR the diff upstream from the submodule. Keep the submodule
# version in lockstep with the `tinyagents` requirement above. After cloning:
# `git submodule update --init vendor/tinyagents` (worktrees included).
tinyagents = { path = "vendor/tinyagents" }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Run Rust CI when vendored TinyAgents changes

Because this patch makes both Cargo worlds resolve tinyagents from vendor/tinyagents, SDK changes can now change the compiled product without touching Cargo.toml, Cargo.lock, or src/**. I checked the PR CI path filters in .github/workflows/pr-ci.yml and they do not include vendor/tinyagents or .gitmodules, so a PR that only bumps the submodule pointer would skip the Rust quality/coverage lanes and the Playwright artifact build/cache despite changing a compiled dependency. Add the submodule path (and usually .gitmodules) to the Rust/Tauri/playwright filters and related artifact cache keys so vendored SDK updates are actually built and tested.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
Cargo.toml (1)

334-339: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Automate the tinyagents lockstep check

The submodule pin and tinyagents = "1.5.0" requirement are coupled only by comment today; add a CI assertion that compares vendor/tinyagents/Cargo.toml’s version with the root and app/src-tauri/Cargo.toml requirements.

🤖 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 `@Cargo.toml` around lines 334 - 339, Add a CI assertion for the tinyagents
lockstep contract so it no longer relies on the comment in Cargo.toml. Create a
check that reads the version from vendor/tinyagents/Cargo.toml and compares it
against both the root tinyagents requirement and the app/src-tauri/Cargo.toml
requirement, failing the build when they diverge. Use the existing tinyagents
dependency declarations and the vendored submodule path as the identifiers to
wire this into the current CI/test flow.
🤖 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 `@docs/tinyagents-full-migration-plan/00-baseline.md`:
- Around line 3-18: Update the baseline doc to match the current tinyagents
1.5.0 state: the section still references a 1.3.0 delta and an inventory
refreshed against 1.3.0, so rename that delta section in 00-baseline.md and
revise the gap notes for the newer API surface. Make sure the updated plan
explicitly covers the 1.4/1.5 additions referenced by the review, including
CompiledGraph::with_node_retry and NoProgressTracker.

In `@docs/tinyagents-full-migration-plan/CONTINUATION-2026-07.md`:
- Around line 15-19: The plan text is inconsistent with the repo’s pinned
baseline: the 00 baseline row and the C0 wording still reference 1.3.0/1.4/1.5
migration steps. Update the `CONTINUATION-2026-07` markdown so the baseline
section and any surrounding “ground truth” notes reflect the already-pinned
`tinyagents = 1.5.0`, and remove or rephrase the stale bump language to match
the current state. Focus on the baseline table entries and any adjacent
narrative that describes the version target.

---

Nitpick comments:
In `@Cargo.toml`:
- Around line 334-339: Add a CI assertion for the tinyagents lockstep contract
so it no longer relies on the comment in Cargo.toml. Create a check that reads
the version from vendor/tinyagents/Cargo.toml and compares it against both the
root tinyagents requirement and the app/src-tauri/Cargo.toml requirement,
failing the build when they diverge. Use the existing tinyagents dependency
declarations and the vendored submodule path as the identifiers to wire this
into the current CI/test flow.
🪄 Autofix (Beta)

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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c011176f-f29e-406f-a23f-cc273e072b5c

📥 Commits

Reviewing files that changed from the base of the PR and between 1de7506 and 5a1227d.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • app/src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (21)
  • .github/workflows/release-production.yml
  • .github/workflows/release-staging.yml
  • .gitignore
  • .gitmodules
  • Cargo.toml
  • Dockerfile
  • app/src-tauri/Cargo.toml
  • docs/tinyagents-full-migration-plan/00-baseline.md
  • docs/tinyagents-full-migration-plan/01-tooling/README.md
  • docs/tinyagents-full-migration-plan/04-sessions/03-checkpointer.md
  • docs/tinyagents-full-migration-plan/10-registry.md
  • docs/tinyagents-full-migration-plan/CONTINUATION-2026-07.md
  • docs/tinyagents-full-migration-plan/HANDOFF-2026-07-03.md
  • docs/tinyagents-full-migration-plan/README.md
  • docs/tinyagents-migration-spec.md
  • docs/tinyagents-session-migration-design.md
  • gitbooks/developing/architecture/agent-harness.md
  • src/openhuman/agent_orchestration/spawn_parallel_graph.rs
  • src/openhuman/tinyagents/delegation.rs
  • src/openhuman/tinyagents/middleware.rs
  • vendor/tinyagents

Comment on lines +3 to +18
Current status (2026-07-03): baseline dependency alignment is complete in both
Cargo worlds. `tinyagents 1.5.0` is resolved with the `sqlite` feature,
OpenHuman pins `rusqlite = "=0.40.0"`, both worlds patch through
`vendor/rusqlite-0.40.0` and `vendor/libsqlite3-sys-0.38.0`, and the SDK-gaps
inventory has been refreshed against the published 1.3.0 crate source.

## Steps

1. **Bump `tinyagents` to `"1.3"`** (done in both Cargo worlds — root and
1. **Bump `tinyagents` to `"1.5.0"`** (done in both Cargo worlds — root and
`app/src-tauri/`). Known 1.1→1.2 break already handled
(`MessageDelta::text` ctor). Note: the `openai` crate feature was removed
after 1.2.0 (1.2.1+ features are only `sqlite`/`repl`) — we never enabled
it, so no impact. See "1.3.0 delta" below for new API this plan uses.
2. **Align rusqlite to 0.40** in both worlds (`Cargo.toml` root and
`app/src-tauri/Cargo.toml`). OpenHuman pins `rusqlite = "=0.40.0"` and
enables `tinyagents = { version = "1.3", features = ["sqlite"] }`.
enables `tinyagents = { version = "1.5.0", features = ["sqlite"] }`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n 'NoProgressTracker|with_node_retry|1\.4\.0|1\.5\.0' docs/tinyagents-full-migration-plan/CONTINUATION-2026-07.md docs/tinyagents-full-migration-plan/HANDOFF-2026-07-03.md 2>/dev/null

Repository: tinyhumansai/openhuman

Length of output: 4144


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== baseline excerpts ==\n'
sed -n '1,120p' docs/tinyagents-full-migration-plan/00-baseline.md | cat -n

printf '\n== continuation excerpts ==\n'
sed -n '1,120p' docs/tinyagents-full-migration-plan/CONTINUATION-2026-07.md | cat -n

printf '\n== handoff excerpts ==\n'
sed -n '1,120p' docs/tinyagents-full-migration-plan/HANDOFF-2026-07-03.md | cat -n

Repository: tinyhumansai/openhuman

Length of output: 31494


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== baseline references to delta/gaps ==\n'
rg -n '1\.3\.0 delta|SDK-gaps|NoProgressTracker|with_node_retry|1\.4\.0|1\.5\.0' docs/tinyagents-full-migration-plan/00-baseline.md docs/tinyagents-full-migration-plan/CONTINUATION-2026-07.md docs/tinyagents-full-migration-plan/HANDOFF-2026-07-03.md

Repository: tinyhumansai/openhuman

Length of output: 5066


Update 00-baseline.md to the 1.4/1.5 delta.
The baseline still points readers to a 1.3.0 delta and says the SDK-gaps inventory was refreshed against 1.3.0, but this plan is already on tinyagents 1.5.0. Rename that section and refresh the gap notes so the newer APIs (CompiledGraph::with_node_retry, NoProgressTracker) are covered.

🤖 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 `@docs/tinyagents-full-migration-plan/00-baseline.md` around lines 3 - 18,
Update the baseline doc to match the current tinyagents 1.5.0 state: the section
still references a 1.3.0 delta and an inventory refreshed against 1.3.0, so
rename that delta section in 00-baseline.md and revise the gap notes for the
newer API surface. Make sure the updated plan explicitly covers the 1.4/1.5
additions referenced by the review, including CompiledGraph::with_node_retry and
NoProgressTracker.

Comment on lines +15 to +19
| 00 baseline | Done (1.3.0 + sqlite, rusqlite 0.40) — **needs re-bump to 1.4/1.5** |
| 01 tooling | Mostly done. Live: crate-internal tool side-lookup (01.1), `tool_filter.rs` 299 + `tool_prep.rs` 344 (01.3) |
| 02 models | Mostly done. Live: `reliable.rs` 900 (gated on re-architecture), `ThinkingForwarder` residual seams |
| 03 context/cache | Done. `context/` is 1.3k of product prompt/stats state |
| 04 sessions | **Primary unfinished work.** Live path is 100% legacy: `transcript.rs` 1347, `migration.rs` 373, `session_io.rs` 463, `session_db/` 4.5k, `subagent_sessions/` 653, `session_import/` 1.9k. Crate `Store`/`AppendStore` used only by the write-only importer. 04.3 checkpointer swap IS done in code (`tinyagents/checkpoint.rs` deleted) — the 04.3 doc text is stale |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the plan text to match the already-pinned 1.5.0 baseline.

This still describes C0 as a 1.4 bump / later 1.5 bump and labels 00 baseline as 1.3.0, but the repo and handoff already pin tinyagents = 1.5.0. That makes the “ground truth” section self-contradictory for the next reader.

Also applies to: 135-143

🤖 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 `@docs/tinyagents-full-migration-plan/CONTINUATION-2026-07.md` around lines 15
- 19, The plan text is inconsistent with the repo’s pinned baseline: the 00
baseline row and the C0 wording still reference 1.3.0/1.4/1.5 migration steps.
Update the `CONTINUATION-2026-07` markdown so the baseline section and any
surrounding “ground truth” notes reflect the already-pinned `tinyagents =
1.5.0`, and remove or rephrase the stale bump language to match the current
state. Focus on the baseline table entries and any adjacent narrative that
describes the version target.

@senamakel
senamakel marked this pull request as draft July 3, 2026 20:57
@senamakel senamakel changed the title feat(core): tinyagents 1.5.0 baseline — vendored submodule, NoProgressTracker, graph node-retry seam (C0) feat(agent): tinyagents 1.5 migration wave — vendored SDK, dual-write sessions, goals/todos shadows, journals, middleware dedupe Jul 3, 2026
@senamakel
senamakel marked this pull request as ready for review July 3, 2026 22:54
@senamakel
senamakel merged commit 4d71702 into tinyhumansai:main Jul 3, 2026
11 of 14 checks passed
@coderabbitai coderabbitai Bot added the agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. label Jul 3, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e7bdbb7a1d

ℹ️ 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".

if !live::dual_write_enabled() {
// Config flag (default ON) gates the mirror; the env kill switch can
// still force it off. `self.config` is the effective per-agent config.
if !live::dual_write_enabled(self.config.session_dual_write) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Serialize live session-store rewrites

Enabling the dual-write by default makes the existing fire-and-forget mirror run for normal turns, but write_live_turn rewrites the whole journal by deleting the stream file and re-appending all messages. If a user starts the next turn before the previous background task finishes, the older task can run last and replace the newer TinyAgents stream with a stale, shorter transcript even though the legacy JSONL is correct. Please serialize/queue these writes per session (or await them) before making the mirror default-on.

Useful? React with 👍 / 👎.

log::debug!("[thread_goals] rpc=set thread_id={thread_id}");
let goal = store::set(workspace_dir, thread_id, objective, token_budget).await?;
emit_updated(&goal);
super::crate_adapter::shadow_mirror_goal(workspace_dir, &goal).await;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Mirror all thread-goal writers

This mirrors the RPC/tool mutation path, but existing goal mutations bypass these ops entirely: the runtime calls store::resume, store::pause, store::account_usage, and continuation-suppression helpers directly, and agent_prepare_context bootstraps goals with store::set_if_absent. With OPENHUMAN_THREAD_GOALS_CRATE_SHADOW=1, a normal turn can advance usage or move a goal to budget_limited only in the legacy store, leaving graph.goals stale and making the shadow/parity corpus unreliable for cutover. Centralize the mirror in the store layer or add it after every direct writer.

Useful? React with 👍 / 👎.

senamakel added a commit to senamakel/openhuman that referenced this pull request Jul 3, 2026
… so interactive turns don't crash (tinyhumansai#4089)

The tinyagents 1.5 migration (tinyhumansai#4473) moved the no-progress escalation
ladder into the crate (`no_progress::NoProgressTracker`), which feeds a
structured "no progress since step X" corrective back into the loop as a
`NoProgress::Nudge` — giving the model one chance to change strategy
before the same-strategy retry cap. OpenHuman's
`RepeatedToolFailureMiddleware` delivered that nudge via
`SteeringCommand::Redirect`.

But `Redirect` is Background (sub-agent) only: the interactive-turn
steering policy deliberately permits just `InjectMessage`/`Pause` so the
user's live turn can't be redirected out from under them by a rogue steer
(`orchestration.rs`). The middleware runs on *every* turn, so every
interactive turn that hit the nudge aborted with `steering command
redirect is not permitted by the run policy` — a tinyhumansai#4473 regression that
red-lines the raw-tool-loop / monitor E2E coverage suites.

Deliver the nudge as a system message via the `InjectMessage` lane
instead. The corrective is trusted, system-generated advisory text, so
`InjectMessage` is both permitted (on interactive *and* background) and
semantically correct — the change-strategy steering tinyhumansai#4089 asks for now
actually reaches the model on interactive chat instead of crashing it.

Tests: the nudge fires once (as an InjectMessage carrying the "no
progress" signal + the failing call name) on the 2nd identical failure,
before the halt; and a regression assertion that the interactive steering
policy permits the `InjectMessage` lane the nudge now uses (and still
refuses `Redirect`).

Closes tinyhumansai#4089.

Claude-Session: https://claude.ai/code/session_01KcmdqJVpjmnH31HqTHRLwG
senamakel added a commit to senamakel/openhuman that referenced this pull request Jul 4, 2026
…teering

Six Rust test failures surfaced by clean CI (merged without test parity):

- middleware (production regression, tinyhumansai#4473): the no-progress ladder's Nudge
  sent SteeringCommand::Redirect, which is NOT in the Interactive steering
  allowlist (InjectMessage + Pause only). Every interactive turn where a tool
  failed twice with identical args or four times with varied errors aborted the
  whole turn with a Steering error instead of nudging then halting gracefully.
  Switch the nudge to InjectMessage(system) — equivalent (append + Continue) but
  within the interactive policy. Fixes the three agent *_raw_coverage_e2e panics
  (turn_xml_failures…, bus_turn_halts_on_repeated_tool_error…,
  no_progress_guard_uses_default_iteration_fallback_when_zero).

- config schema catalog test: privacy-mode controllers (config_get/set_privacy_mode,
  added by tinyhumansai#4435/tinyhumansai#4446) were registered but the hand-maintained golden list in
  config_auth_app_state_connectivity_e2e.rs wasn't updated. Add the two entries.

- api::config backend_url test: tinyhumansai#4153 intentionally made a bare `/v1` base on an
  unknown host classify as an OpenAI-compatible inference base (with its own
  passing sibling test); the older contradictory assertion wasn't updated. Align
  it to expect the fallback.

- tinyagents middleware inventory tests: tinyhumansai#4444 added MemoryProtocolMiddleware
  (+1) and tinyhumansai#4473 removed CacheAlignMiddleware (-1), but the count literals were
  left at 13/11. Correct to 12/10 and drop cache-align from the comment.

Claude-Session: https://claude.ai/code/session_014RLnG2QbdL3n9TLtfomdhB
senamakel added a commit to senamakel/openhuman that referenced this pull request Jul 4, 2026
…enial assertion

`turn_xml_failures_...` asserts the transcript surfaces a policy denial
("denied by policy 'round17-deny'"). The test set tool_result_budget_bytes: 96;
before the tinyagents 1.5 migration (tinyhumansai#4473) policy denials bypassed the
per-result budget, but the migration now routes them through
ToolOutputMiddleware.after_tool, so 96 bytes truncated the ~400-byte denial to a
stub and the assertion no longer matched. (This assertion was unreachable until
the steering fix in this branch let the turn run to completion.)

Raise the budget above the denial size — no assertion here depends on truncation
actually happening, and production's default budget is 16 KiB so real denials
are never truncated. Documented the underlying regression (denials should be
exempt from the budget) + the dead hard_reject fast-path as a follow-up in code.

Claude-Session: https://claude.ai/code/session_014RLnG2QbdL3n9TLtfomdhB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant