From d245ce6a4d7c1e53ef43f271cc59db931835e063 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 22 Jul 2026 16:38:59 +0400 Subject: [PATCH 1/6] fix(flows): pass flow id when finalizing rejected resume --- src/openhuman/flows/ops.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/openhuman/flows/ops.rs b/src/openhuman/flows/ops.rs index 5f7c3fdaf9..f6ae6e6a40 100644 --- a/src/openhuman/flows/ops.rs +++ b/src/openhuman/flows/ops.rs @@ -4036,7 +4036,15 @@ pub async fn flows_resume( ); } let observed = current_persisted_steps(config, thread_id); - finish_flow_run_row(config, thread_id, "failed", &observed, &[], Some(&error)); + finish_flow_run_row( + config, + thread_id, + flow_id, + "failed", + &observed, + &[], + Some(&error), + ); tracing::warn!( target: "flows", flow_id = %flow_id, From 8be06fae64c37ef6914d8006f9b2c8174595eacd Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 22 Jul 2026 16:44:00 +0400 Subject: [PATCH 2/6] chore(deps): align tinyagents with v2.1 --- Cargo.toml | 6 ------ app/src-tauri/Cargo.toml | 5 ----- vendor/tinyagents | 2 +- vendor/tinyflows | 2 +- 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 837f5f41cd..c55e748637 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -684,12 +684,6 @@ tinyjuice = { path = "vendor/tinyjuice" } tinychannels = { path = "vendor/tinychannels" } tinyplace = { path = "vendor/tinyplace/sdk/rust" } -# TinyCortex temporarily pins the embedding API port while tinyagents #58 is -# pending. Resolve that git source to the same vendored crate so host adapters -# and TinyCortex share one `EmbeddingModel` trait identity. -[patch."https://github.com/senamakel/tinyagents"] -tinyagents = { path = "vendor/tinyagents" } - # Emit just enough DWARF in release builds for Sentry to symbolicate Rust # panics + render surrounding source lines. `line-tables-only` keeps the # binary small (only file+line tables, no full type info) while still diff --git a/app/src-tauri/Cargo.toml b/app/src-tauri/Cargo.toml index 349a355671..425065ebb8 100644 --- a/app/src-tauri/Cargo.toml +++ b/app/src-tauri/Cargo.toml @@ -294,11 +294,6 @@ tauri-plugin-global-shortcut = { git = "https://github.com/tauri-apps/plugins-wo tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", rev = "c6561ab6b4f9e7f650d4fc8c53fd8acc9b65b9b2" } tauri-plugin-notification = { path = "vendor/tauri-plugin-notification" } -# Match the root Cargo world: TinyCortex's temporary git pin must resolve to -# the vendored TinyAgents crate to preserve one embedding trait identity. -[patch."https://github.com/senamakel/tinyagents"] -tinyagents = { path = "../../vendor/tinyagents" } - [dev-dependencies] # `test-util` enables `#[tokio::test(start_paused = true)]` for the # idle-watchdog unit tests in `cdp/session.rs` (#1213). diff --git a/vendor/tinyagents b/vendor/tinyagents index 19dc2c438e..2583fccc21 160000 --- a/vendor/tinyagents +++ b/vendor/tinyagents @@ -1 +1 @@ -Subproject commit 19dc2c438e1f8b2715a45ba7030bc455e611dcb2 +Subproject commit 2583fccc213a00f2a3d94744ff1e0d1541368f97 diff --git a/vendor/tinyflows b/vendor/tinyflows index e5327de9f6..23dd23a06d 160000 --- a/vendor/tinyflows +++ b/vendor/tinyflows @@ -1 +1 @@ -Subproject commit e5327de9f602c1fbbf72d45150729f45b91fa3a8 +Subproject commit 23dd23a06ddf3124e486ce36841f3d879fc0141d From d4df050fe588ea0b364d2eb77c8030a9963b6d80 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 22 Jul 2026 16:44:31 +0400 Subject: [PATCH 3/6] docs(tinyagents): reconcile migration plan and ledgers --- docs/tinyagents-drift-ledger.md | 25 +- .../99-deletion-ledger.md | 29 ++ .../C4-journal-progress-parity-plan.md | 10 +- docs/tinyagents-inference-migration-plan.md | 26 +- docs/tinyagents-migration-plan-2026-07-22.md | 466 ++++++++++++++++++ ...inyagents-phase3-router-registry-design.md | 5 +- docs/tinyagents-port-plan.md | 7 +- docs/tinycortex-memory-migration-plan.md | 2 +- docs/tinycortex-migration-spec.md | 3 +- .../agent/harness/subagent_runner/mod.rs | 4 +- src/openhuman/agent_orchestration/mod.rs | 2 +- src/openhuman/inference/README.md | 4 +- src/openhuman/tinyagents/subagent_graph.rs | 4 +- 13 files changed, 556 insertions(+), 31 deletions(-) create mode 100644 docs/tinyagents-full-migration-plan/99-deletion-ledger.md create mode 100644 docs/tinyagents-migration-plan-2026-07-22.md diff --git a/docs/tinyagents-drift-ledger.md b/docs/tinyagents-drift-ledger.md index cdd7c4eef2..ff9d205270 100644 --- a/docs/tinyagents-drift-ledger.md +++ b/docs/tinyagents-drift-ledger.md @@ -1,4 +1,4 @@ -# TinyAgents Drift Ledger (Phase 0) +# TinyAgents Drift Ledger **Purpose.** The TinyAgents migration spans `inference`, `tools`, and `agent_orchestration`, while the OpenHuman host will keep evolving. This ledger @@ -22,12 +22,12 @@ be upstreamed, retained, or deleted before each phase cuts over. | Thing | Value | | --- | --- | | Host repo | `tinyhumansai/openhuman` | -| Host branch | `docs/tinyagents-port-plan` | -| Host audit base | `42ce5c0e9` (`origin/main`, 2026-07-04) | -| Plan commit | `24f200e49` (`docs: TinyAgents port plan`) | +| Host branch | `feat/tinyagents-migration-2026-07-22` | +| Host audit base | `5b8a9f269` (`upstream/main`, 2026-07-22) | +| Active plan | `docs/tinyagents-migration-plan-2026-07-22.md` | | TinyAgents submodule | `vendor/tinyagents` -> `tinyhumansai/tinyagents` | | Phase 0 target | `v1.6.0` / `e72036d847b589044aa9a4add1b34544b92a293d` | -| Current host pin | `v1.8.0-1-g7c6e81a` ([tinyagents#49](https://github.com/tinyhumansai/tinyagents/pull/49) **merged** onto v1.8.0 main) | +| Current host pin | `v2.1.0` / `2583fcc` (vendored tag; root requirement `2.1`) | | Verification PR | [openhuman#4769](https://github.com/tinyhumansai/openhuman/pull/4769) — Motion A + Motion B checkpoint. **CI fully green** (`PR CI Gate` + `Rust Core Coverage` + fmt/clippy); 14,437 Rust tests pass. First full CI verification of this branch. | ## Baseline Snapshot @@ -69,6 +69,16 @@ work started. Counts include Rust files only. ## Motion B — Provider-Build Cutover (crate-native `ChatModel` construction) +The closure rows below supersede older deferred/pending prose retained later in +this section as investigation history. + +| # | Area | Status | Evidence / action | +| --- | --- | --- | --- | +| P1-10 | Wire-equivalent BYOK cloud slugs | **CLOSED** | [openhuman#4780](https://github.com/tinyhumansai/openhuman/pull/4780) routed eligible slugs to crate-native `OpenAiModel`. | +| P1-11 | OpenAI/Codex/custom cloud slugs | **CLOSED** | [openhuman#4782](https://github.com/tinyhumansai/openhuman/pull/4782) completed the configured cloud-slug client cutover, including Responses API construction. | +| P1-12 | Host workload routing | **CLOSED** | [openhuman#4783](https://github.com/tinyhumansai/openhuman/pull/4783) adopted crate `ModelRouter` for fallback and capability decisions. | +| P1-13 | Crate-native registered turn models / `compatible*.rs` deletion | **CLOSED** | [openhuman#4784](https://github.com/tinyhumansai/openhuman/pull/4784) moved the hot turn path and deleted the former `compatible*.rs` cluster. The collapsed `legacy_provider.rs` facade and the broader legacy `Provider` stack remain WP-1 deletion work; see the deletion ledger. | + Motion A confined all `Provider` handling to the seam + factory. Motion B replaces the *construction* of host `Provider`s with crate-native `ChatModel`s at each build boundary, so `compatible*.rs` can eventually be @@ -166,7 +176,8 @@ of P1-9). Two sub-motions: | Step | Status | Evidence | | --- | --- | --- | | Crate high-level router | **DONE** | [tinyagents#54](https://github.com/tinyhumansai/tinyagents/pull/54) `registry::router::{ModelRouter, WorkloadRoute}` (merged `4fc8cd8`) — declarative workload-tier table (alias→model, `CapabilitySet` gate, same-family fallbacks) filling the long-declared `ComponentKind::Router`; holds no models, no I/O. | -| Host adopts `ModelRouter` for fallback + capability | **IN PROGRESS** | `tinyagents/routes.rs`: `OH_WORKLOAD_ROUTER` (`LazyLock`) now backs `route_fallback_policy` + `turn_required_capabilities`; deleted the hand-rolled `same_family_fallbacks`. Behavior-neutral (parity tests pin the exact chains + vision gate incl. `hint:vision`). `build_route_models`' per-tier `ProviderModel` construction (the P3-B client swap) is untouched. Host pin bumped `8e57665` → `4fc8cd8` (adds #53 langfuse run-tree + #54 router). | +| Host adopts `ModelRouter` for fallback + capability | **CLOSED** | [openhuman#4783](https://github.com/tinyhumansai/openhuman/pull/4783) made `tinyagents/routes.rs::OH_WORKLOAD_ROUTER` authoritative for fallback and required capabilities. | +| Registered tier models become crate-native | **CLOSED** | [openhuman#4784](https://github.com/tinyhumansai/openhuman/pull/4784) completed the P3-B hot-path client swap and deleted the former `compatible*.rs` cluster. Residual `ProviderModel` and the collapsed legacy facade are tracked separately in WP-1. | ## Host Validation Notes @@ -190,7 +201,7 @@ error emitted before the cap. | Phase 0 - version alignment | P0-1, P0-2, P0-3, P0-4, P0-5, P0-6 | **CLOSED** | | Phase 1 - quick upstream ports | SchemaCleanr, error classification, model context, reasoning channel, worktree isolation, display metadata, time tools | **PARTIAL HOST CUTOVER** | | Phase 2 - tool model and builtin families | ToolResult structure, permission model, ToolAccess, edit tracking, filesystem/network/time tools | **NOT STARTED** | -| Phase 3 - provider consolidation | OpenAI-compatible provider cutover, retry ownership, backend envelope split | **NOT STARTED** | +| Phase 3 - provider consolidation | OpenAI-compatible client cutover and crate router adoption | **CLIENT CUTOVER CLOSED; LEGACY STACK REMOVAL IN WP-1** | | Phase 4 - orchestration consolidation | TaskStore/SteeringRegistry lifecycle, status vocabulary, session durability | **NOT STARTED** | | Phase 5 - workflow/team generic slices | Validation/scheduling slice evaluation | **NOT STARTED** | | Phase 6 - cleanup and docs | Transitional shim deletion and architecture docs | **NOT STARTED** | diff --git a/docs/tinyagents-full-migration-plan/99-deletion-ledger.md b/docs/tinyagents-full-migration-plan/99-deletion-ledger.md new file mode 100644 index 0000000000..57c1e38b3c --- /dev/null +++ b/docs/tinyagents-full-migration-plan/99-deletion-ledger.md @@ -0,0 +1,29 @@ +# TinyAgents migration deletion ledger + +This ledger records host-side removals required by +[`tinyagents-migration-plan-2026-07-22.md`](../tinyagents-migration-plan-2026-07-22.md). +A row moves to `DELETED` only after its crate-backed replacement and the named +parity evidence are in place. Generic code moved into `vendor/tinyagents` must +also name its upstream PR before the host copy is removed. + +| Work package | Host artifact | Preconditions / replacement | Status | Evidence | +| --- | --- | --- | --- | --- | +| WP-1 | `inference/provider/router.rs` + tests | Crate `ModelRouter` owns live routing | PENDING | #4783 adopted the router; legacy provider consumers remain | +| WP-1 | `inference/provider/reliable.rs` + tests | Crate retry/fallback owns every model call | PENDING | Retargeted provider wire-parity tests | +| WP-1 | `inference/provider/legacy_provider.rs` and `compatible` alias | Every OpenAI-compatible slug uses crate `OpenAiModel` | PENDING | #4780/#4782/#4784 client cutover; residual legacy callers must be removed | +| WP-1 | `inference/provider/traits.rs` + tests | No `impl Provider`; consumers use crate model/message/usage types | PENDING | Consumer sweep + `inference_provider_e2e` and `agent_harness_e2e` | +| WP-1 | `tinyagents/model.rs::ProviderModel` / `MaxTokensModel` | Tier and bespoke models are direct `ChatModel`s | PENDING | `rg ProviderModel src` empty | +| WP-1 | `tinyagents/convert.rs` message conversion | No host `ChatMessage`; retain tool-schema conversion until WP-4 | PENDING | Conversion tests moved or retired | +| WP-1 | `inference/provider/crate_provider.rs` | No legacy `Provider` consumer needs the reverse adapter | PENDING | `rg 'impl Provider' src` empty | +| WP-2 | `routing/{policy,quality,factory}.rs` | Generic decisions use crate `ModelRouter`; host health signals remain | PENDING | Routing parity tests host/crate | +| WP-2 | `tool_timeout` implementation | Crate `ToolTimeout` owns timeout mechanics; host only projects config/env | PENDING | Timeout precedence tests | +| WP-2 | `model_council/{council,graph}.rs` | Generic ensemble graph released in tinyagents | PENDING | Upstream PR + offline graph tests | +| WP-3 | legacy `run_turn_engine` and graph escape hatches | All regression assertions exercise the crate turn path | PENDING | `rg OPENHUMAN_AGENT_GRAPH_` history-only | +| WP-4 | host tool trait/adapter artifacts selected by design | Approved tool-model decision preserves security and ungated result types | DESIGN GATE | Successor design document | +| WP-5 | generic seam middlewares | Equivalent crate middleware released and adopted | PENDING | Per-middleware drift rows + parity tests | +| WP-5 | detached subagent registry mechanics | Crate `TaskStore`/`SteeringRegistry` own lifecycle | PENDING | Upstream PR + orchestration tests | +| WP-5 | `agent/progress_tracing.rs` and `progress_tracing/langfuse.rs` | C4 S2-S6 gates pass; journal projection is self-sufficient | BLOCKED | One-release shadow parity and C4 §5 gate | + +Deletion totals are reconciled in WP-6 after all rows are terminal. The +original projection is approximately 30k host LOC deleted and 12–15k generic +LOC upstreamed; measured totals, not the estimate, are authoritative. diff --git a/docs/tinyagents-full-migration-plan/C4-journal-progress-parity-plan.md b/docs/tinyagents-full-migration-plan/C4-journal-progress-parity-plan.md index f7d3466bcd..2ffa5513b1 100644 --- a/docs/tinyagents-full-migration-plan/C4-journal-progress-parity-plan.md +++ b/docs/tinyagents-full-migration-plan/C4-journal-progress-parity-plan.md @@ -3,8 +3,8 @@ Status: execution plan (2026-07-04), written after a ground-truth code map of both the OpenHuman progress surface and the vendored crate observability primitives. This is the actionable plan for the C4 workstream's July 2026 -continuation notes, and it is the gated prerequisite for **doc 03 (V3) Step -5** — deleting the `ProviderDelta` bridge and `progress_tracing`. +continuation notes, and it is the gated prerequisite for **S6 below** — +deleting the `ProviderDelta` bridge and `progress_tracing`. ## 1. Corrected architecture (what the map found) @@ -171,13 +171,13 @@ span-projection slice. per-call charged USD awaits a journal-native event. Later delete `progress_tracing/langfuse.rs` (~825 + tests). 5. **S5 — delete `progress_tracing.rs` + `SpanCollector`** once S3 shadow shows - no divergence for one release **and** V3 projection parity holds (the doc 07 - gate). Tick the deletion ledger (~2k incl. tests). + no divergence for one release **and** journal projection parity holds (the + §5 gate). Tick the deletion ledger (~2k incl. tests). 6. **S6 (= V3 Step 5)** — with `AgentProgress` now a journal projection, delete the legacy `ProviderDelta` bridge in `session/tool_progress.rs` (253) and the `spawn_delta_forwarder`, since the crate event path is the only producer. -## 5. Gates (doc 07) +## 5. Gates - `progress_tracing` delete: **C4 shadow parity (S3) for one release AND V3 projection parity.** Langfuse (S4) may land earlier (independent shape parity). diff --git a/docs/tinyagents-inference-migration-plan.md b/docs/tinyagents-inference-migration-plan.md index fbe03e3fe9..51b4a0bacc 100644 --- a/docs/tinyagents-inference-migration-plan.md +++ b/docs/tinyagents-inference-migration-plan.md @@ -1,8 +1,14 @@ # Migrating `src/openhuman/inference/` onto `vendor/tinyagents/` -**Status:** plan (not started) -**Relates to:** #4249 (tinyagents migration), `docs/tinyagents-migration-spec.md` (Phase 2 — model registry / profiles / fallback), `docs/tinyagents-full-migration-plan/`, `docs/tinyagents-drift-ledger.md` -**tinyagents:** 1.7.1, vendored as a git submodule at `vendor/tinyagents/` and path-patched over the crates.io pin (root `Cargo.toml`: `tinyagents = { version = "1.7", features = ["sqlite", "repl"] }` + `[patch.crates-io] tinyagents = { path = "vendor/tinyagents" }`). +**Status:** superseded on 2026-07-22 by +[`tinyagents-migration-plan-2026-07-22.md`](tinyagents-migration-plan-2026-07-22.md). +This document is retained as historical model-layer design detail; its pins, +status, and present-tense inventory are not current. +**Relates to:** #4249 (tinyagents migration), +`docs/tinyagents-migration-plan-2026-07-22.md`, +`docs/tinyagents-full-migration-plan/`, and +`docs/tinyagents-drift-ledger.md`. +**tinyagents audit anchor:** 1.7.1. See the superseding plan for the active pin. --- @@ -74,7 +80,10 @@ Verified against 1.7.1 source; re-audit at Phase 0 since the crate moves fast. - **G3 — Auth-failure signal**: openhuman publishes `DomainEvent::SessionExpired` when a chat attempt fails auth. The crate client must classify 401/expired distinctly (as a `ProviderError` kind) so the host factory can hook it without string-sniffing. - **G4 — Request dump / wire observability**: `compatible_dump.rs` writes raw request/response dumps for debugging. Upstream a transport-level hook (or confirm the crate's observability exporters cover it) before deleting. - **G5 — Per-request timeout policy**: `compatible_timeout.rs` semantics vs. what the crate transport exposes. Upstream a per-call timeout on `ModelRequest`/`ProviderSpec` if missing. -- **G6 — BYOK auth styles**: the provider preset catalog (`docs/inference-provider-catalog.md`) supports multiple `AuthStyle`s (headers etc.). Confirm crate `ProviderSpec` can express every style in the catalog; upstream what's missing. +- **G6 — BYOK auth styles**: the authoritative provider catalog + (`src/openhuman/config/schema/cloud_providers.rs`) supports multiple + `AuthStyle`s (headers etc.). Confirm crate `ProviderSpec` can express every + style in the catalog; upstream what's missing. - **G7 — Repeat-output guard**: `compatible_repeat.rs` (degenerate-repetition detection). Decide: upstream as an optional stream guard, or accept the loss (note #4463 already tracks deleted repeat guards). Upstream flow: change in `vendor/tinyagents` (submodule working tree) → PR to `tinyhumansai/tinyagents` → publish → bump the crates.io pin in **both** Cargo worlds (root + `app/src-tauri`) and the submodule ref in lockstep. Nothing in openhuman may depend on unpublished vendored-only API at a merge point. @@ -87,7 +96,8 @@ Each phase compiles green in both Cargo worlds, keeps ≥80% diff coverage, and ### Phase 0 — Inventory & gap re-audit - Enumerate every consumer of `Provider` / `ChatRequest` / `ChatResponse` / `ChatMessage` outside `inference/` (151 files) and bucket them: (a) goes through the seam already, (b) direct one-shot `provider.chat(...)` callers (learning, memory, subconscious, screen_intelligence, sentiment, triage…), (c) type-only imports. -- Re-verify §3 gaps against current crate HEAD; file crate issues; update `docs/tinyagents-sdk-gaps.md`. +- Re-verify §3 gaps against current crate HEAD; file crate issues; update + `vendor/tinyagents/docs/sdk-gaps.md`. - Golden-transcript capture: record request/response wire dumps for the BYOK catalog matrix + Ollama + openhuman backend on the current stack, as fixtures for Phase 2 parity. **Exit:** disposition table confirmed per-file; crate gap PRs filed. @@ -133,7 +143,11 @@ Each phase compiles green in both Cargo worlds, keeps ≥80% diff coverage, and **Exit:** no ad-hoc prompt/parse loops outside the crate surface. ### Phase 7 — Cleanup, docs, deletion ledger -- Update `inference/README.md`, `gitbooks/developing/architecture/agent-harness.md`, `docs/inference-provider-catalog.md`; add deletions to `docs/tinyagents-full-migration-plan/99-deletion-ledger.md`; refresh `docs/tinyagents-drift-ledger.md`. +- Update `inference/README.md`, + `gitbooks/developing/architecture/agent-harness.md`, and the authoritative + provider catalog in `src/openhuman/config/schema/cloud_providers.rs`; add + deletions to `docs/tinyagents-full-migration-plan/99-deletion-ledger.md`; + refresh `docs/tinyagents-drift-ledger.md`. - Remove dead re-exports from `inference/mod.rs`; keep temporary `pub use` shims only where a follow-up PR is already open. - Sweep for stale doc-comments naming `Provider`/`CompatibleProvider`. diff --git a/docs/tinyagents-migration-plan-2026-07-22.md b/docs/tinyagents-migration-plan-2026-07-22.md new file mode 100644 index 0000000000..554fb87f3c --- /dev/null +++ b/docs/tinyagents-migration-plan-2026-07-22.md @@ -0,0 +1,466 @@ +# TinyAgents Migration — Current-State Audit & Consolidated Plan (2026-07-22) + +**Status:** audit + plan (supersedes the stale status/phasing in +`tinyagents-port-plan.md`, `tinyagents-inference-migration-plan.md`, and +`tinyagents-phase3-router-registry-design.md`; the drift ledger +`tinyagents-drift-ledger.md` remains the row-level ledger but its anchors are +behind — see §2). +**Scope:** move the remaining generic inference + agent-framework code from +`src/openhuman/` down into the vendored `tinyagents` crate +(`vendor/tinyagents`), delete the in-tree duplicates, migrate/retire the +affected tests, and clean up every dangling doc/code reference left behind by +earlier phases. +**Method:** fresh four-way audit of (1) the crate surface, (2) +`src/openhuman/inference/`, (3) the agent domains + the +`src/openhuman/tinyagents/` seam, (4) the existing docs/tests — all against the +working tree at `main` (`5b8a9f269`, 2026-07-22). + +**Execution status:** active on `feat/tinyagents-migration-2026-07-22`. +WP-0 discovered and corrected an additional cross-crate constraint: once the +vendored manifest honestly reports 2.1, `tinyflows` must also require +TinyAgents 2.1 or Cargo resolves a second 1.9 copy and splits trait identity. +The deletion ledger is +[`tinyagents-full-migration-plan/99-deletion-ledger.md`](tinyagents-full-migration-plan/99-deletion-ledger.md). + +--- + +## 1. Executive summary + +The migration is **much further along than any existing doc records**, and the +remaining work is now well-bounded: + +- The agent loop has run on `tinyagents` since #4249/#4399; the drift ledger's + Phase 0 rows are all CLOSED and Phase 1 is mostly closed. +- Since the docs were last touched, PRs **#4769, #4780, #4782, #4783, #4784** + landed the model-layer inversion: the managed backend, wire-equivalent BYOK + slugs, and openai/codex/custom slugs are all crate-native `ChatModel`s; the + crate `ModelRouter` is adopted; and **`compatible*.rs` is already deleted** + (collapsed into a single `legacy_provider.rs` facade). +- What remains falls into six work packages (§5): finish the model-layer + cutover and delete the legacy `Provider` stack (~9–10k LOC); retire the + legacy `run_turn_engine`; consolidate `routing/`, `tool_timeout/`, + `tool_status/`, `model_council/` onto crate primitives; reconcile the tool + model (the one genuinely design-gated package); shrink the seam; and a + housekeeping package (version-pin reconciliation + broken-link cleanup) that + should go **first** because the current pin state is misleading. + +Nothing in this plan touches the CEF shell, the frontend, or the compile-time +feature gates; the crate stays impossible to gate away (26+ domains consume it). + +--- + +## 2. Ground truth: version pins (WP-0 reconciled) + +| Fact | Value | Where | +| --- | --- | --- | +| Host requirement | `tinyagents = { version = "2.1", features = ["sqlite"] }` | root `Cargo.toml:107` | +| Path override | `[patch.crates-io] tinyagents = { path = "vendor/tinyagents" }` | `Cargo.toml:677` | +| Historical fork patch | Removed in WP-0; no dependency uses the former fork URL | root and Tauri manifests | +| Vendored crate | `version = "2.1.0"`, tag `v2.1.0` / `2583fcc`, edition 2024, GPL-3.0-only | `vendor/tinyagents/Cargo.toml`, gitlink | +| Included since the audit | `bytes` bump (#59), **`BarrierRelief` graph fan-in primitive (#62)**, v2.0/v2.1 release commits | submodule history | +| TinyFlows requirement | `tinyagents = "2.1"`; prevents Cargo resolving a second 1.9 crate | `vendor/tinyflows/Cargo.toml` | +| Drift ledger | Current pin `v2.1.0` / `2583fcc` | `docs/tinyagents-drift-ledger.md` §Anchors | + +WP-0 bumped the gitlink to the released v2.1.0 manifest, regenerated both Cargo +worlds, removed the unused fork-source patch, and aligned TinyFlows to 2.1. +Before that TinyFlows alignment, correct dependency resolution introduced a +second crates.io TinyAgents 1.9 package; `cargo tree` now proves the root and +TinyFlows both use the vendored 2.1 package. + +--- + +## 3. What the crate ships (v2.1.0) + +Full module map from the crate audit; the items relevant to the remaining work: + +- **Model layer:** `harness::model::{ChatModel, ModelRegistry, ProviderError}` + (`vendor/tinyagents/src/harness/model/types.rs:524,563,450`), + `MODEL_CONTEXT_PATTERNS` context-window table (`model/mod.rs:51`). +- **OpenAI-compatible client:** `harness::providers::openai::{OpenAiModel, AuthStyle, + ReasoningTagExtraction}` with SSE streaming, the `/v1/responses` API + codex + knobs (#51), configurable auth styles/static headers (#44), temperature + suppression (#47), `merge_system_into_user` (#48), prompt-guided tool calling + for non-native models (#55), stream→JSON fallback (#56), and the whole #57 + local-model hardening wave (inline `` extraction, 400-degrade of + `tool_choice`/`json_object`, malformed tool-call recovery). This is the + replacement for everything `legacy_provider.rs` still does. +- **Retry/fallback/error classification:** `harness::retry::{RetryPolicy, + FallbackPolicy, ProviderFailureClass, classify_provider_failure, is_retryable}` + (`harness/retry/types.rs:28`, `retry/mod.rs:170,396`) — already wired into the + crate's transport and SSE paths. +- **Routing:** `registry::router::{ModelRouter, WorkloadRoute}` (#54) — adopted + host-side by #4783; plus `registry::catalog::ModelCatalog` (windows, pricing, + capability flags, offline snapshot at + `docs/modules/registry/model-catalog.snapshot.json`). +- **Tools:** `harness::tool::{Tool, ToolSchema}` + schema validation + (`harness/tool/types.rs:344`, `tool/schema.rs`), `ToolTimeout`, tool-policy + middleware (`harness/middleware/library/tool_policy.rs`). +- **Subagents/orchestration:** `harness::subagent::{SubAgent, SubAgentSession, + SubAgentTool}`, `graph::orchestration::{TaskStore, SteeringRegistry, + OrchestrationTool, InMemoryTaskStore, JsonlTaskStore}`, + `graph::subagent_node`, `graph::parallel::map_reduce`, and (post-bump) + `BarrierRelief` fan-in. +- **Embeddings:** provider implementations ported at HEAD (#58 — `openai`, + `cohere`, `voyage`, `ollama`, `cloud`, rate-limit/retry-after helpers). +- **Observability:** harness + graph journals/status stores, `JsonlSink`, + `RedactingSink`, Langfuse client with nested run trees (#53). +- **Also present:** summarization (`Summarizer`, `CompressionFailurePolicy`), + steering, workspace isolation, response cache, cost/usage accounting + (parses `cached_tokens`), graph checkpointing (SQLite via the `sqlite` + feature the host enables), and offline `MockModel`/testkit conventions. + +~25 public traits are the extension points; the seam already implements 11 of +them (§4.3). + +--- + +## 4. Audit: what remains host-side + +### 4.1 `src/openhuman/inference/` — 112 files, ~46.5k LOC + +The model-layer inversion (#4727 "Motion B") is scaffolded and mostly cut over, +but the legacy `Provider` stack is still present and **still the default +construction path** in places: + +**Still-duplicating cluster (delete in WP-1):** + +| File | LOC | State | +| --- | --- | --- | +| `provider/traits.rs` (+`traits_tests.rs`) | 779 + 501 | The `Provider` trait + `ChatMessage`/`ChatRequest`/`ChatResponse`/`ProviderDelta`/`UsageInfo`. Still central; ~10 impls remain. | +| `provider/reliable.rs` (+`reliable_tests.rs`) | 952 + 1,228 | Retry/backoff `Provider` wrapper. Crate `RetryPolicy` covers it; the interactive turn path already stopped wrapping in `ReliableProvider` (`tinyagents/mod.rs:122`). | +| `provider/router.rs` (+`router_tests.rs`) | 310 + 524 | `RouterProvider` hint-table routing. Crate `ModelRouter` adopted by #4783; this is the residual legacy path. | +| `provider/legacy_provider.rs` | 343 | The collapsed remnant of the 15 `compatible*.rs` files (`provider/mod.rs:14` aliases `pub use legacy_provider as compatible;`). Superseded by crate `OpenAiModel` once WP-1 flips the default. | +| `provider/error_classify.rs` + `error_code.rs` | 1,001 + 349 | Split (WP-1): generic retryability/status classification → crate `classify_provider_failure`; openhuman semantics (Sentry demotion, budget messaging, `config_rejection.rs`, `billing_error.rs`) stay as a host classifier layered on crate errors. | +| `provider/crate_provider.rs` | 327 | `CrateBackedProvider` — the **temporary reverse adapter** (crate `ChatModel` → legacy `Provider`). Deleted last, when no consumer needs `Provider`. | + +**Crate-native scaffolding already in place (finish in WP-1):** + +- `provider/crate_openai.rs` (347) — host `AuthStyle` → crate `OpenAiModel` + builder; self-described "**Status: scaffolding**" — complete and unit-tested + but **not yet the factory default**. Flipping it (with per-provider wire + parity validation) is the gating step. +- `provider/openhuman_backend_model.rs` (325) — managed backend as crate + `ChatModel` (cut over; coexists with the legacy `openhuman_backend.rs` twin, + which can go once nothing constructs it). +- `provider/factory.rs` (2,850) — the host↔crate boundary; already returns + `Arc>` via `create_chat_model*`, but bespoke slugs still + route "→ a `ProviderModel` over the host provider" (`factory.rs:1458-1511`). +- `model_context.rs` — already falls through to the crate table + (`context_window_for_model_id`, `model_context.rs:77`); keeps host config + overrides. Done; keep the thin shim. +- `ops.rs`, `local/ops.rs`, `http/server.rs` already build crate + `ModelRequest`/`Message` types. + +**Seam concerns mis-housed under `provider/` (re-home in WP-1):** +`temperature.rs` (261), `thread_context.rs` (120), `resolved_route.rs` (113), +`auth_error_registry.rs` (166). + +**Host-owned, stays (no action):** all of `local/` (~14k — Ollama/LM Studio/ +Whisper/Piper runtime + installers + service admin), `voice/` (~2.4k), +`openai_oauth/` (~1.5k), `http/` (0.7k `/v1` server), `provider/ops/` (RPC), +bespoke `Provider`/`ChatModel` impls (`claude_code/` ~2.7k, +`claude_agent_sdk/`, `openai_codex.rs`, `openhuman_backend*.rs`), and the root +host files (`schemas.rs`, `presets.rs`, `model_ids.rs`, `paths.rs`, `parse.rs`, +`sentiment.rs`, `device.rs`). + +**Blast radius:** 187 files import `openhuman::inference`; 158 import +`inference::provider` (grown from the old plan's 170/151). Top consumers: +`agent/harness/session/tests.rs` (33 hits), `core/observability.rs` (31), +`tinyagents/mod.rs` (15), `web_chat/web_errors.rs`, `routing/factory.rs`, +`agent/harness/subagent_runner/ops/{graph,runner}.rs`, `voice/`, `flows/ops.rs`, +`config/ops/model.rs`, `channels/context.rs`. + +### 4.2 Agent domains + +| Domain | Files / LOC | Disposition | +| --- | --- | --- | +| `agent/` | 144 / 66.9k | **Mostly stays** (product brain). 37 files already crate-backed. One big deletion: the legacy `run_turn_engine` parallel loop (`agent/harness/session/turn/core.rs`, `agent/harness/subagent_runner/ops/graph.rs`) duplicating `harness::agent_loop` — WP-3. Heaviest coupling in the tree (config=31, memory=20, event_bus=13 files). | +| `agent_orchestration/` | 64 / 27.9k | Engine already on `tinyagents::graph` (workflow runs, teams, delegation, `map_reduce`); what remains is the product layer (ledgers, RPC). Residual upstream item: detached-subagent `TaskStore` lifecycle — WP-5. 25 files crate-backed. | +| `routing/` | 8 / 2.7k | **Zero crate refs — fully parallel implementation** of what `registry::router` + harness fallback now do. `policy.rs` (463), `quality.rs` (445), `factory.rs` migrate/upstream; `provider.rs`, `health.rs`, `telemetry.rs` (local-model health) stay host — WP-2. | +| `model_council/` | 4 / 1.1k | `council.rs` (573) + `graph.rs` (128, already graph-shaped) are a generic N-model ensemble → upstream as a crate graph pattern; `schemas.rs` (392, RPC) stays — WP-2. | +| `council_registry/` | 4 / 0.6k | Definitions-as-data + RPC. Stays. | +| `tool_timeout/` | 1 / 316 | Process-global timeout with env/config precedence; crate analogue `harness::tool::ToolTimeout` exists. Collapse to a host shim that pushes config into the crate — WP-2. | +| `tool_status/` | 3 / 0.7k | Pure failure-classification data+logic, parallel to crate tool-outcome handling. Upstream the generic classification; keep host taxonomy mapping — WP-2 (candidate, low priority). | +| `tools/` | 98 / 40.9k | The `Tool` trait + `ToolSpec` mechanics (`traits.rs:255`), `schema.rs`, `policy.rs`, `orchestrator_tools.rs`, `user_filter.rs` are framework-shaped; all of `tools/impl/*` + RPC (`schemas.rs` 985, `ops.rs` 1,407) are product. **Design-gated** (port-plan §2 blockers still apply) — WP-4. Note: `ToolResult`/`ToolContent` are re-exported from `skills::types` (~236 consumer files) — moving those types is the highest-blast-radius single step in the whole migration and must be its own slice. Security coupling: 49 files. | +| `tool_registry/` | 7 / 1.8k | Read-only cross-surface discovery + RPC. Stays. | +| `agent_registry/`, `agent_experience/`, `agent_memory/`, `agent_tool_policy/`, `agentbox/`, `orchestration/` | — | All host/product (definitions-as-data, RPC controllers, marketplace HTTP, remote-brain client — `orchestration/` talks to the hosted backend, not the local crate). Stay. `agent_tool_policy` overlaps crate `tool_policy` middleware mechanically but encodes host channel-permission policy — stays, mechanism may thin post-WP-4. | + +### 4.3 The seam — `src/openhuman/tinyagents/` (25 files, ~17.1k LOC) + +The seam is healthy: 23/25 files use the crate; it implements `Middleware` +(13×), `ToolMiddleware` (4×), `ModelMiddleware` (3×), `ChatModel` (2×), +`Summarizer`, `Tool`, `EventListener` (2×), `PayloadSummarizer`, +`HarnessStatusStore`, `EmbeddingModel`, and `GraphEventSink`. Post-migration it +**shrinks but remains host-owned**. Specific shrink targets: + +- **`model.rs` (1,004): `ProviderModel` still exists** (`struct` at :375, + `impl ChatModel<()>` at :542) and is referenced from ~7 modules — the Phase 1 + exit criterion ("constructed in exactly one place, then zero") is unmet. + Deleted in WP-1 along with `convert.rs`'s (655) message-translation layer + (`chat_message_to_message`, `spec_to_schema` split: tool-schema conversion + survives until WP-4; message conversion dies with `ChatMessage`). +- **`middleware.rs` (4,702):** audit each of the 17 middlewares for crate + analogues (`ArgRecovery` overlaps crate #45 arg-recovery; `SchemaGuard` + overlaps crate schema validation + `InvalidArgsPolicy` #42; `RepeatProgress` + overlaps `no_progress/`). Upstream the generic ones; host-policy ones + (ApprovalSecurity, CredentialScrub, CliRpcOnly, MemoryProtocol, CostBudget) + stay — WP-5. +- `routes.rs` `UsageCarry`/`FallbackObserver` thin out as usage/fallback become + fully crate-native. + +### 4.4 Broken/dangling references (resolved in WP-0) + +WP-0 retargeted SDK-gap references to +`vendor/tinyagents/docs/sdk-gaps.md`, made the provider schema +`src/openhuman/config/schema/cloud_providers.rs` authoritative, created +`docs/tinyagents-full-migration-plan/99-deletion-ledger.md`, replaced the +phantom numbered-plan links with this plan's WP-5/C4 sections, and retargeted +the TinyCortex analogy to this current audit. The three historical plans now +carry explicit superseded banners. + +### 4.5 Test inventory (what moves, dies, or stays) + +- **Dies with WP-1** (bound to the legacy `Provider` stack): + `provider/traits_tests.rs` (501), `reliable_tests.rs` (1,228), + `router_tests.rs` (524) — these define 10+ mock `impl Provider` doubles. + `factory_tests.rs` (3,149) shrinks and retargets to `ChatModel` construction. + In `tests/raw_coverage/`: the three `inference_compatible_*` files (~2.2k + LOC) are pinned to the deleted wire client — retire or rewrite the still- + meaningful assertions against `OpenAiModel` via wiremock. +- **Retargets:** `tests/inference_provider_e2e.rs` (568, wiremock-based — + OpenAI-compat chat/streaming, Anthropic auth headers, temperature + suppression, Ollama `/v1`) — keep the scenarios, point them at the crate- + native factory path; these become the **wire-parity gate** for flipping the + default. +- **Moves upstream (as crate tests, offline `MockModel` convention):** parity + coverage for anything upstreamed in WP-2/WP-5 (routing policy/quality, + council graph, middleware behaviors). The crate's CI is + fmt → clippy (`-D warnings`, both feature sets) → build → `cargo test` + + `--all-features`, no network. +- **Stays host-side:** seam tests (`tinyagents/tests.rs` 799 + 19 inline), + `tests/agent_harness_e2e.rs` (130 KB), `tests/json_rpc_e2e.rs` (576 KB), + `agentbox_e2e`, `orchestration_*`, `embeddings_rpc_e2e`, + `ollama_lifecycle_e2e`, `openai_oauth/flow_tests.rs`, all `local/*_tests`, + and the `raw_coverage` family except the compatible trio. +- **Runner impact:** `scripts/test-rust-with-mock.sh:52` still documents the + `OPENHUMAN_AGENT_GRAPH_{TINYAGENTS,CHANNEL,SUBAGENT}=0` escape hatches into + the legacy engine — these go away with WP-3. + +--- + +## 5. The plan — six work packages + +Ordering rationale: WP-0 is pure hygiene and unblocks honest review of +everything else; WP-1 is the largest deletion and already 80% scaffolded; +WP-2/WP-3 are independent of each other and of WP-1's tail; WP-4 is the only +design-gated package; WP-5 is opportunistic shrink; WP-6 is the exit gate. +Every WP follows the repo's standing rules: failing-before/passing-after +regression tests, small validated commits on a feature branch per submodule, +drift-ledger rows updated before deletions (the ledger's gate rule stays in +force). + +### WP-0 — Version + docs housekeeping (no behavior change) + +1. Bump `vendor/tinyagents` submodule to tag `v2.1.0` (fast-forward; picks up + `BarrierRelief` #62 and the bytes bump). Regenerate root and + `app/src-tauri` lockfiles. `cargo check` both worlds + + the slim disabled build (`--no-default-features --features + tokenjuice-treesitter`) per repo convention. +2. Update `tinyagents-drift-ledger.md` Anchors (pin row → v2.1.0; add rows + closing out #4780/#4782/#4783/#4784 which the ledger still lists as + pending/deferred; mark the Phase-3 "compatible*.rs remains" text CLOSED). +3. Stamp superseded-by banners on `tinyagents-port-plan.md`, + `tinyagents-inference-migration-plan.md`, + `tinyagents-phase3-router-registry-design.md` pointing here (keep them — + their disposition tables and gap lists are still the reference detail). +4. Fix the §4.4 broken references, create the deletion ledger, and replace the + phantom numbered-plan references with real WP-5/C4 anchors. +5. Remove the stale fork-source patch after verifying that no dependency uses + it. + +**Exit:** `Cargo.toml`, submodule, lockfiles, and ledger all agree on one +version; zero dangling `docs/tinyagents*` references (`grep -rn` clean). + +### WP-1 — Finish the model-layer cutover; delete the legacy `Provider` stack + +The continuation of #4727 Motion B / drift-ledger P1-8/P1-9. Slices: + +1. **Flip the factory default** to `crate_openai.rs` construction for every + OpenAI-compatible slug. Gate: the retargeted `inference_provider_e2e.rs` + wire-parity suite (§4.5) green against the crate path, per provider family + (managed, BYOK, ollama/lm-studio local, codex/responses). +2. **Route bespoke providers as `ChatModel`s** — `claude_code`, + `claude_agent_sdk`, `openai_codex`, `openhuman_backend` get direct + `ChatModel` impls (the pattern `openhuman_backend_model.rs` already + proves), removing the last `factory.rs:1458-1511` `ProviderModel` wraps. + Delete the legacy `openhuman_backend.rs` twin when nothing constructs it. +3. **Error-taxonomy split:** generic classification call sites move to crate + `classify_provider_failure`/`ProviderError`; `error_classify.rs` shrinks to + the openhuman-semantic layer (`config_rejection`, `billing_error`, Sentry + demotion). Upstream any status codes the crate misclassifies (drift-ledger + rows, then crate PR + version bump). +4. **Delete, in dependency order:** `router.rs` → `reliable.rs` → + `legacy_provider.rs` (+ the `as compatible` alias in `provider/mod.rs:14`) + → `provider/traits.rs` → seam `ProviderModel`/`MaxTokensModel` + (`tinyagents/model.rs`) + `convert.rs` message layer → the reverse adapter + `crate_provider.rs` last. Each deletion is its own commit with its test + fallout (§4.5) handled in the same commit. +5. **Consumer sweep:** migrate the 187 importing files to crate types + (`Message`, `ModelRequest`, `Usage`, `TinyAgentsError`). Mechanical for + most; the hot spots are `core/observability.rs`, `web_chat/web_errors.rs`, + `voice/`, `flows/ops.rs`, `config/ops/model.rs`. +6. **Re-home** `temperature.rs`, `thread_context.rs`, `resolved_route.rs`, + `auth_error_registry.rs` out of `provider/` into the seam (or the factory + module) so `provider/` ends as: factory + bespoke models + ops/RPC. + +**Exit criteria:** no `impl Provider` anywhere; `grep -rn "ProviderModel" +src/` empty; `inference/provider/` ≤ ~8k LOC (from ~15.9k + tests); +`inference_provider_e2e` + `agent_harness_e2e` + full +`scripts/test-rust-with-mock.sh` green. Estimated net deletion: **~9–10k LOC** +(code + dead tests). + +### WP-2 — Consolidate parallel implementations onto crate primitives + +Independent, individually shippable slices: + +1. **`routing/` → `registry::router`.** Map `policy.rs`/`quality.rs` tiering + onto `ModelRouter`/`WorkloadRoute` (adopted since #4783 — finish the "host + adopts" row IN PROGRESS in the ledger). Upstream generic scoring the crate + lacks; keep `health.rs`/`telemetry.rs`/`provider.rs` as the host + local-runtime signal source feeding router inputs. `routing/provider_tests.rs` + becomes seam tests; policy/quality parity tests go upstream. +2. **`tool_timeout/` → crate `ToolTimeout`.** Host keeps only the + config/env push (`OPENHUMAN_TOOL_TIMEOUT_SECS` precedence) into the crate + value. 316 LOC → ~50. +3. **`model_council/` ensemble → crate graph pattern.** `council.rs` + + `graph.rs` become a crate-side parallel-fanout + chair-synthesis graph + (natural fit for `map_reduce` + post-WP-0 `BarrierRelief`); host keeps + `schemas.rs` RPC + `council_registry/` definitions. +4. **`tool_status/` classification (low priority):** upstream the generic + failure-classification table into crate tool-outcome handling; host keeps + the RPC-facing taxonomy mapping. Skip if the crate's outcome model diverges + — reclassify HOST-OWNED in the ledger instead. + +**Exit:** `routing/policy|quality|factory` and `tool_timeout` deleted or +shimmed; ledger rows added per slice (DRIFT→PR or HOST-OWNED). + +### WP-3 — Retire the legacy turn engine + +`run_turn_engine` (`agent/harness/session/turn/core.rs`, +`agent/harness/subagent_runner/ops/graph.rs`) is the pre-#4249 loop kept as a +parity fallback; `run_turn_via_tinyagents_shared` has been default-ON in +production for the whole 4x-series. + +1. Confirm no production caller can reach the legacy path except via the + `OPENHUMAN_AGENT_GRAPH_{TINYAGENTS,CHANNEL,SUBAGENT}=0` escape hatches. +2. Delete the legacy engine + the escape hatches + the + `scripts/test-rust-with-mock.sh` documentation of them. +3. Port any legacy-only regression assertions in + `agent/harness/session/turn_tests.rs` / `subagent_runner/ops_tests.rs` to + the tinyagents path before deletion (failing-before/passing-after). + +**Exit:** one turn engine; `grep -rn "OPENHUMAN_AGENT_GRAPH_" ` returns only +changelog/history. + +### WP-4 — Tool-model reconciliation (design-gated; do not start on autopilot) + +The openhuman `Tool` trait (`tools/traits.rs:255`) vs crate `Tool` +unification. The port-plan §2 design blockers still stand, plus two audited +constraints: + +- `ToolResult`/`ToolContent` live in `skills::types` as the deliberately + ungated type carve-out consumed by ~236 files (MCP, runtime_node, every Tool + impl). Any move must preserve that carve-out property (inert, dep-free, + compiled in all feature combinations) — either the types move **into the + crate** and `skills::types` re-exports them, or they stay and the crate + bridge continues via `SharedToolAdapter`. +- `tools/` has the tree's heaviest security coupling (49 files) — execution + gating (`classify_command`, approval, sandbox) must stay host-side + regardless of where the trait lives. + +Recommended shape: a short design doc (successor to the port-plan §2 list) +deciding (a) trait unification vs permanent adapter, (b) the +`ToolResult`/`ToolContent` home, (c) `ToolScope::AgentOnly` gating (deferred +"Phase 2" per `traits.rs:14-19`) — then slices. Until then, the +`SharedToolAdapter` seam is cheap and correct; **do not delete it +prematurely.** + +### WP-5 — Seam shrink + orchestration lifecycle upstreaming + +1. Middleware audit (§4.3): per-middleware ledger rows; upstream + `ArgRecovery`/`SchemaGuard`/`RepeatProgress` equivalents where the crate's + #42/#45/no_progress machinery can absorb them; keep host-policy middlewares. +2. Detached-subagent lifecycle: move the generic detached-run registry + mechanics (`agent_orchestration/running_subagents.rs`, + `subagent_control.rs`) onto crate `TaskStore`/`SteeringRegistry` fully; + host keeps ledgers + RPC. This restores the lifecycle consolidation intent + recorded by the earlier audit without relying on a phantom design doc. +3. Finish the C4 journal-progress-parity plan (S2–S6): journal-backed progress + projection, then delete `agent/progress_tracing.rs` (1,272) + + `progress_tracing/langfuse.rs` (825) in favor of crate observability — + respecting the recorded S2a replayability blocker. + +### WP-6 — Exit gate + +- Full suite: `scripts/test-rust-with-mock.sh` (all targets incl. + `raw_coverage_all`), `cargo test --all-features` in `vendor/tinyagents`, + slim disabled build + `cargo test --lib --no-default-features --features + tokenjuice-treesitter core::` (repo standing rule), `pnpm rust:check`. +- Deletion ledger totals reconciled against the port-plan's projection + (~30k deleted / ~12–15k upstreamed). +- Docs: `inference/README.md`, `gitbooks/developing/architecture/ + {agent-harness,orchestration,flows-on-tinyagents}.md` updated to the + post-cutover reality; drift ledger phases marked CLOSED; this plan stamped + done. + +--- + +## 6. Risks and standing gotchas + +- **Wire parity is the whole risk in WP-1.** The legacy client accumulated + provider quirks for years; the crate's #44–#57 wave was built to match them, + but the flip must be gated on the wiremock parity suite per provider family, + not on unit tests. Keep `CrateBackedProvider` as the rollback seam until the + parity suite has soaked on `main`. +- **GPL/crates.io boundary:** tinyagents is publicly redistributed — only + genuinely generic code moves down; no product policy, backend phrasing as + API, or key material (port-plan rule, still in force). +- **Usage fidelity (old gap G1):** verify crate `Usage` carries the + USD/cached-token fields the cost tracker needs before deleting + `UsageInfo`; `routes.rs` `UsageCarry` is the current compensator. +- **`RUST_MIN_STACK=16777216`** in the mock runner exists because of the + subagent runner's large futures — deep-graph changes in WP-3/WP-5 can + resurface stack overflows on Apple Silicon (see + `composio_list_tools_stack_overflow_regression` test). +- **Whisper/GGML on Apple Silicon:** any `cargo` validation of the root crate + locally needs `GGML_NATIVE=OFF` (unrelated to this migration but will bite + every WP's validation loop). +- **Two Cargo worlds:** every vendor bump must update both the root and + `app/src-tauri` lockfiles (until the workspace convergence tracked in + #3877). + +--- + +## 7. Quick reference — disposition of every audited module + +| Module | Verdict | +| --- | --- | +| `inference/provider/{traits,reliable,router,legacy_provider,crate_provider}.rs` | DELETE (WP-1) | +| `inference/provider/{error_classify,error_code}.rs` | SPLIT: generic → crate; host semantics stay (WP-1) | +| `inference/provider/{crate_openai,openhuman_backend_model,factory}.rs` | KEEP — becomes the host↔crate boundary (WP-1 finishes) | +| `inference/provider/{temperature,thread_context,resolved_route,auth_error_registry}.rs` | RE-HOME to seam (WP-1) | +| `inference/{local,voice,http,openai_oauth}/`, `provider/ops/`, bespoke providers, root host files | STAYS | +| `tinyagents/model.rs` (`ProviderModel`), `convert.rs` message layer | DELETE (WP-1) | +| `tinyagents/middleware.rs` generic middlewares | UPSTREAM case-by-case (WP-5) | +| `tinyagents/` remainder (seam) | STAYS, shrinks | +| `agent/` legacy `run_turn_engine` + escape hatches | DELETE (WP-3) | +| `agent/` remainder, `agent_registry/`, `agent_experience/`, `agent_memory/`, `agent_tool_policy/`, `agentbox/`, `orchestration/`, `council_registry/`, `tool_registry/` | STAYS (product/host) | +| `routing/{policy,quality,factory}.rs` | MIGRATE to `registry::router` (WP-2) | +| `routing/{provider,health,telemetry}.rs` | STAYS (host signals) | +| `tool_timeout/` | COLLAPSE to shim over crate `ToolTimeout` (WP-2) | +| `tool_status/` classification | UPSTREAM candidate (WP-2, low priority) | +| `model_council/{council,graph}.rs` | UPSTREAM as crate graph pattern (WP-2) | +| `tools/` trait mechanics | DESIGN-GATED (WP-4) | +| `tools/impl/*`, all `schemas.rs` RPC controllers | STAYS | +| `agent_orchestration/` detached-run mechanics | UPSTREAM to `TaskStore` (WP-5) | +| `agent/progress_tracing*` | DELETE after C4 S2–S6 (WP-5) | diff --git a/docs/tinyagents-phase3-router-registry-design.md b/docs/tinyagents-phase3-router-registry-design.md index ff6a474ec2..98ed20b2fb 100644 --- a/docs/tinyagents-phase3-router-registry-design.md +++ b/docs/tinyagents-phase3-router-registry-design.md @@ -1,6 +1,9 @@ # Phase 3 — RouterProvider → crate ModelRegistry: design & ground truth -**Status:** design (starting Phase 3). Grounded in a full read of both the crate +**Status:** superseded on 2026-07-22 by +[`tinyagents-migration-plan-2026-07-22.md`](tinyagents-migration-plan-2026-07-22.md). +Phase 3's client cutover landed in #4783/#4784; this document is retained as +historical design rationale, not current status. Grounded in a full read of both the crate (`vendor/tinyagents/src/harness/model`, `harness/agent_loop`, `harness/retry`, `registry/`) and the host seam (`src/openhuman/tinyagents/{mod,routes,model}.rs`, `inference/provider/{router,factory}.rs`). diff --git a/docs/tinyagents-port-plan.md b/docs/tinyagents-port-plan.md index b117d4d345..19be648e8e 100644 --- a/docs/tinyagents-port-plan.md +++ b/docs/tinyagents-port-plan.md @@ -1,8 +1,9 @@ # TinyAgents Port — Plan & Audit (inference / tools / agent_orchestration) -**Status:** Phase 1 partial host cutover — TinyAgents `v1.7.1` is tagged and -the host now pins it; `SchemaCleanr`, the generic model-context table, and the -context-preserving `invoke_stream` path are crate-backed. +**Status:** superseded on 2026-07-22 by +[`tinyagents-migration-plan-2026-07-22.md`](tinyagents-migration-plan-2026-07-22.md). +This document is retained as historical design detail; its version pins, +phase status, and present-tense file inventory are not current. **Anchor precedent:** the TinyAgents harness migration (#4249 / #4399 / #4473) and the TinyCortex memory migration plan (`docs/tinycortex-memory-migration-plan.md`). **Target:** move the genuinely framework-shaped parts of `src/openhuman/inference/`, `src/openhuman/tools/`, and `src/openhuman/agent_orchestration/` down into the `tinyagents` crate (vendored git submodule at **`vendor/tinyagents`**, `https://github.com/tinyhumansai/tinyagents`), and delete the in-tree duplicates in favor of crate primitives. diff --git a/docs/tinycortex-memory-migration-plan.md b/docs/tinycortex-memory-migration-plan.md index c6f673aac4..5aeec7aeee 100644 --- a/docs/tinycortex-memory-migration-plan.md +++ b/docs/tinycortex-memory-migration-plan.md @@ -103,7 +103,7 @@ This phase produces documents and upstream issues only; it is the gate for every **0.5 Type-unification decision.** Host `memory::traits` types and crate types are wire-compatible twins. Decide: host re-exports crate types (preferred — one source of truth, 30+ consumer sites unchanged via `pub use`), vs. keeping host types + `From` conversions (fallback if serde/API divergence is found in 0.3). Special care: `MemoryTaint` is **security-critical provenance** (fails closed to `ExternalSync`, drives external-effect-tool gating) — its semantics, serde representation, and fail-closed defaults must be proven identical before re-exporting. -**0.6 Spec doc.** Write `docs/tinycortex-migration-spec.md` version-anchored to exact reviewed SHAs (host + tinycortex), with the ownership lists above, the drift/gap/parity ledgers, and a **deletion ledger** skeleton (every legacy file, with preconditions for deletion) — directly modeled on `docs/tinyagents-migration-spec.md` + `99-deletion-ledger.md`. +**0.6 Spec doc.** Write `docs/tinycortex-migration-spec.md` version-anchored to exact reviewed SHAs (host + tinycortex), with the ownership lists above, the drift/gap/parity ledgers, and a **deletion ledger** skeleton (every legacy file, with preconditions for deletion) — directly modeled on `docs/tinyagents-migration-plan-2026-07-22.md` + `docs/tinyagents-full-migration-plan/99-deletion-ledger.md`. --- diff --git a/docs/tinycortex-migration-spec.md b/docs/tinycortex-migration-spec.md index 0b8711438c..8963630dc7 100644 --- a/docs/tinycortex-migration-spec.md +++ b/docs/tinycortex-migration-spec.md @@ -4,7 +4,8 @@ is active (§0.4); W1 seam + W2 type re-export + W3-chunks partial landed; **drift closure COMPLETE** (**D3** via #59, **D2** via tinycortex#63, **D1** via tinycortex#64; gitlink `a8e10f7`) — so **W4 (queue) and W7 (conversations) are unblocked**. Anchors the migration to exact reviewed SHAs and ties -together the drift, gap, and parity ledgers. Modeled on `docs/tinyagents-migration-spec.md` + its +together the drift, gap, and parity ledgers. Modeled on +`docs/tinyagents-migration-plan-2026-07-22.md` and its deletion ledger. **Companion plan:** [`tinycortex-memory-migration-plan.md`](tinycortex-memory-migration-plan.md) diff --git a/src/openhuman/agent/harness/subagent_runner/mod.rs b/src/openhuman/agent/harness/subagent_runner/mod.rs index d1b0c80037..901e02dad8 100644 --- a/src/openhuman/agent/harness/subagent_runner/mod.rs +++ b/src/openhuman/agent/harness/subagent_runner/mod.rs @@ -22,8 +22,8 @@ //! run: definition lookup/allowlists, archetype prompt assembly, toolkit //! filtering, sandbox/action-root narrowing, checkpoint/handback, and //! worker-thread transcript mirroring. Mapping it onto TinyAgents -//! `SubAgent`/`SubAgentSession`/subgraph primitives is tracked in -//! `docs/tinyagents-full-migration-plan/07-subagents/`. +//! `SubAgent`/`SubAgentSession`/subgraph primitives is tracked in WP-5 of +//! `docs/tinyagents-migration-plan-2026-07-22.md`. //! //! ## Layout //! diff --git a/src/openhuman/agent_orchestration/mod.rs b/src/openhuman/agent_orchestration/mod.rs index b12ac415d8..021aeb14c7 100644 --- a/src/openhuman/agent_orchestration/mod.rs +++ b/src/openhuman/agent_orchestration/mod.rs @@ -14,7 +14,7 @@ //! compatibility events, and JSON-RPC/tool response formatting. //! [`running_subagents`] mirrors detached-sub-agent lifecycle into a //! TinyAgents task store; porting more of that lifecycle upstream is tracked -//! in `docs/tinyagents-full-migration-plan/07-subagents/02-detached-taskstore.md`. +//! in WP-5 of `docs/tinyagents-migration-plan-2026-07-22.md`. pub mod agent_teams; pub(crate) mod background_completions; diff --git a/src/openhuman/inference/README.md b/src/openhuman/inference/README.md index 2be35e1cfb..1342eea23d 100644 --- a/src/openhuman/inference/README.md +++ b/src/openhuman/inference/README.md @@ -13,8 +13,8 @@ Unified inference domain: the canonical home for everything LLM/STT/TTS/embeddin - Expose an OpenAI-compatible `/v1/*` HTTP endpoint guarded by a stable user-managed external bearer. - Detect device hardware profile and recommend/apply local model presets/tiers. - Maintain the built-in BYOK provider preset catalog used by Connections → API keys → LLM. - The current matrix lives in `docs/inference-provider-catalog.md`; credentials - are stored under `provider:` in the auth-profile store. + The current matrix is `config/schema/cloud_providers.rs`; credentials are + stored under `provider:` in the auth-profile store. ## Key files diff --git a/src/openhuman/tinyagents/subagent_graph.rs b/src/openhuman/tinyagents/subagent_graph.rs index 4b007610ed..b98d69584f 100644 --- a/src/openhuman/tinyagents/subagent_graph.rs +++ b/src/openhuman/tinyagents/subagent_graph.rs @@ -46,8 +46,8 @@ fn phase_node( /// Build the fixed sub-agent pipeline graph. /// -/// The node names intentionally match `docs/tinyagents-full-migration-plan/ -/// 07-subagents/01-subagent-pipeline.md`: +/// The node names are the stable sub-agent pipeline stages tracked by WP-5 of +/// `docs/tinyagents-migration-plan-2026-07-22.md`: /// /// `resolve_definition -> prepare_context -> assemble_prompt -> expose_tools -> /// run_child -> finalize` From ef8204b37fa4935e33f938587cc2212b11cc5f9a Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 22 Jul 2026 18:02:54 +0400 Subject: [PATCH 4/6] fix(deps): unify TinyCortex TinyAgents source --- Cargo.lock | 27 +++--------- app/src-tauri/Cargo.lock | 45 ++++++-------------- docs/tinyagents-migration-plan-2026-07-22.md | 16 ++++--- vendor/tinycortex | 2 +- 4 files changed, 30 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 92b1b3bcad..79c461f188 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3079,7 +3079,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.57.0", ] [[package]] @@ -4746,7 +4746,7 @@ dependencies = [ "tar", "tempfile", "thiserror 2.0.18", - "tinyagents 2.1.0", + "tinyagents", "tinychannels", "tinycortex", "tinyflows", @@ -7332,23 +7332,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "tinyagents" -version = "2.0.0" -dependencies = [ - "async-trait", - "bytes", - "chrono", - "futures", - "reqwest 0.12.28", - "serde", - "serde_json", - "sha2 0.11.0", - "thiserror 2.0.18", - "tokio", - "tracing", -] - [[package]] name = "tinyagents" version = "2.1.0" @@ -7433,7 +7416,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "thiserror 2.0.18", - "tinyagents 2.0.0", + "tinyagents", "tokio", "toml 0.8.23", "tracing", @@ -7453,7 +7436,7 @@ dependencies = [ "serde", "serde_json", "thiserror 2.0.18", - "tinyagents 2.1.0", + "tinyagents", "tracing", ] @@ -8864,7 +8847,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] diff --git a/app/src-tauri/Cargo.lock b/app/src-tauri/Cargo.lock index 2609cdc1cc..9ff6ce3b69 100644 --- a/app/src-tauri/Cargo.lock +++ b/app/src-tauri/Cargo.lock @@ -250,7 +250,7 @@ dependencies = [ "objc2-foundation 0.3.2", "parking_lot", "percent-encoding", - "windows-sys 0.60.2", + "windows-sys 0.59.0", "x11rb", ] @@ -2061,7 +2061,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2479,7 +2479,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3706,7 +3706,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.57.0", ] [[package]] @@ -4107,7 +4107,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -4991,7 +4991,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5603,7 +5603,7 @@ dependencies = [ "tar", "tempfile", "thiserror 2.0.18", - "tinyagents 2.1.0", + "tinyagents", "tinychannels", "tinycortex", "tinyflows", @@ -6547,7 +6547,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -7133,7 +7133,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -7192,7 +7192,7 @@ dependencies = [ "security-framework 3.7.0", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -8809,7 +8809,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -8968,23 +8968,6 @@ dependencies = [ "strict-num", ] -[[package]] -name = "tinyagents" -version = "2.0.0" -dependencies = [ - "async-trait", - "bytes", - "chrono", - "futures", - "reqwest 0.12.28", - "serde", - "serde_json", - "sha2 0.11.0", - "thiserror 2.0.18", - "tokio", - "tracing", -] - [[package]] name = "tinyagents" version = "2.1.0" @@ -9064,7 +9047,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "thiserror 2.0.18", - "tinyagents 2.0.0", + "tinyagents", "tokio", "toml 0.8.2", "tracing", @@ -9084,7 +9067,7 @@ dependencies = [ "serde", "serde_json", "thiserror 2.0.18", - "tinyagents 2.1.0", + "tinyagents", "tracing", ] @@ -10466,7 +10449,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] diff --git a/docs/tinyagents-migration-plan-2026-07-22.md b/docs/tinyagents-migration-plan-2026-07-22.md index 554fb87f3c..856610fbd3 100644 --- a/docs/tinyagents-migration-plan-2026-07-22.md +++ b/docs/tinyagents-migration-plan-2026-07-22.md @@ -55,17 +55,19 @@ feature gates; the crate stays impossible to gate away (26+ domains consume it). | --- | --- | --- | | Host requirement | `tinyagents = { version = "2.1", features = ["sqlite"] }` | root `Cargo.toml:107` | | Path override | `[patch.crates-io] tinyagents = { path = "vendor/tinyagents" }` | `Cargo.toml:677` | -| Historical fork patch | Removed in WP-0; no dependency uses the former fork URL | root and Tauri manifests | +| Historical fork patch | Removed in WP-0; TinyCortex now declares crates.io `2.1`, so the existing host path patch unifies its dependency too | root and Tauri manifests; TinyCortex #121 | | Vendored crate | `version = "2.1.0"`, tag `v2.1.0` / `2583fcc`, edition 2024, GPL-3.0-only | `vendor/tinyagents/Cargo.toml`, gitlink | | Included since the audit | `bytes` bump (#59), **`BarrierRelief` graph fan-in primitive (#62)**, v2.0/v2.1 release commits | submodule history | | TinyFlows requirement | `tinyagents = "2.1"`; prevents Cargo resolving a second 1.9 crate | `vendor/tinyflows/Cargo.toml` | +| TinyCortex requirement | `tinyagents = "2.1"`; its repo-local patch serves standalone development while host patches select the canonical copy | `vendor/tinycortex/Cargo.toml` | | Drift ledger | Current pin `v2.1.0` / `2583fcc` | `docs/tinyagents-drift-ledger.md` §Anchors | WP-0 bumped the gitlink to the released v2.1.0 manifest, regenerated both Cargo -worlds, removed the unused fork-source patch, and aligned TinyFlows to 2.1. -Before that TinyFlows alignment, correct dependency resolution introduced a -second crates.io TinyAgents 1.9 package; `cargo tree` now proves the root and -TinyFlows both use the vendored 2.1 package. +worlds, removed the unused fork-source patch, and aligned TinyFlows and +TinyCortex to 2.1. Before those transitive alignments, correct dependency +resolution introduced separate TinyAgents 1.9 and nested-path 2.0 packages; +the lockfiles now prove the root, TinyFlows, and TinyCortex all use the one +vendored 2.1 package. --- @@ -276,7 +278,9 @@ force). 4. Fix the §4.4 broken references, create the deletion ledger, and replace the phantom numbered-plan references with real WP-5/C4 anchors. 5. Remove the stale fork-source patch after verifying that no dependency uses - it. + it. Align TinyCortex's nested path dependency through a crates.io `2.1` + declaration plus its repo-local development patch, so the host's canonical + path patch produces one trait identity (TinyCortex #121). **Exit:** `Cargo.toml`, submodule, lockfiles, and ledger all agree on one version; zero dangling `docs/tinyagents*` references (`grep -rn` clean). diff --git a/vendor/tinycortex b/vendor/tinycortex index daaaf6ba5f..12caf4479a 160000 --- a/vendor/tinycortex +++ b/vendor/tinycortex @@ -1 +1 @@ -Subproject commit daaaf6ba5f02635c08deae2b2b2ed7fcc8c06b6a +Subproject commit 12caf4479aa2b9306b34b1d32a82da4bef27449c From 3ebe8d0588c6988fe2da0ea953af07de4ac53f96 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 22 Jul 2026 18:59:59 +0400 Subject: [PATCH 5/6] chore(deps): track exact TinyAgents selection --- vendor/tinycortex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/tinycortex b/vendor/tinycortex index 12caf4479a..18c91e19e5 160000 --- a/vendor/tinycortex +++ b/vendor/tinycortex @@ -1 +1 @@ -Subproject commit 12caf4479aa2b9306b34b1d32a82da4bef27449c +Subproject commit 18c91e19e5ea31a61cd6a4313d125b90d573b765 From b2154997c96c6d1b316885c11be2b4b19f910fa1 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Thu, 23 Jul 2026 13:01:48 +0400 Subject: [PATCH 6/6] fix(tools): update NodeExecTool test for new RuntimePoolConfig + workspace_dir params --- src/openhuman/tools/impl/system/node_exec.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/openhuman/tools/impl/system/node_exec.rs b/src/openhuman/tools/impl/system/node_exec.rs index 30385f29ff..ffb609a3d2 100644 --- a/src/openhuman/tools/impl/system/node_exec.rs +++ b/src/openhuman/tools/impl/system/node_exec.rs @@ -868,7 +868,13 @@ mod tests { temp.path().to_path_buf(), reqwest::Client::new(), )); - let tool = NodeExecTool::new(security, Arc::new(NativeRuntime::new()), bootstrap); + let tool = NodeExecTool::new( + security, + Arc::new(NativeRuntime::new()), + bootstrap, + crate::openhuman::config::RuntimePoolConfig::default(), + temp.path().join("state"), + ); let result = tool .execute(json!({