Skip to content

feat(tinyagents): Phase 0/1 port cutover — pin v1.7.1, crate-back SchemaCleanr / model-context / observed stream#4539

Merged
senamakel merged 23 commits into
tinyhumansai:mainfrom
senamakel:docs/tinyagents-port-plan
Jul 5, 2026
Merged

feat(tinyagents): Phase 0/1 port cutover — pin v1.7.1, crate-back SchemaCleanr / model-context / observed stream#4539
senamakel merged 23 commits into
tinyhumansai:mainfrom
senamakel:docs/tinyagents-port-plan

Conversation

@senamakel

@senamakel senamakel commented Jul 5, 2026

Copy link
Copy Markdown
Member

Summary

  • Advance the TinyAgents port to Phase 1 partial host cutover: pin the host to TinyAgents v1.7.1 (both Cargo.locks + vendor/tinyagents submodule) and route real host paths through crate primitives.
  • tools/schema.rs now re-exports tinyagents::harness::tool::{SchemaCleanr, CleaningStrategy, GEMINI_UNSUPPORTED_KEYWORDS} (the in-tree SchemaCleanr is deleted; import path preserved).
  • inference/model_context.rs delegates the generic context-window fallback to tinyagents::harness::model::context_window_for_model_id after checking OpenHuman tier aliases + the cost catalog first.
  • The observed run path drives the context-preserving invoke_stream_in_context (the Send-stream fix landed in tinyagents#28 / v1.7.1); reasoning is written to typed ContentBlock::Thinking instead of the ProviderExtension smuggle.
  • Adds the migration's living docs: docs/tinyagents-port-plan.md (audit + phased plan) and docs/tinyagents-drift-ledger.md (per-row upstream/host/delete tracking).

Problem

The host carries a large parallel implementation of things TinyAgents already ships (provider wire client, schema cleaning, retry, tool/subagent model). The audit (see the plan doc) establishes that most of the "bulky" code is duplication, not portable logic, and lays out a phased consolidation so each deletion is gated behind a released crate API + a crate-backed seam test. This PR lands Phase 0 (version alignment) and the Phase 1 partial cutover — the pieces that are safe to switch on now — without deleting any host code that still lacks a released crate replacement.

Solution

  • Every engine change was made upstream in vendor/tinyagents, released to crates.io, then pinned here in standalone chore(vendor) commits (v1.6.0 → v1.7.1); host PRs contain no engine source edits.
  • Phase 0 closed the baseline seam fallout: ToolCompleted outcome projection, SHA-256 prompt-cache fingerprinting over the full ToolSchema list, and the redaction-layer audit.
  • Phase 1 cutovers that are crate-backed today: SchemaCleanr, generic model-context lookup, typed reasoning channel, and the context-preserving observed stream. Worktree / time / error-classification / display-metadata APIs are released but host-wrapper/call-site retained (documented per drift-ledger row) until their Phase 2 model reconciliation.
  • The drift ledger records each row's disposition (CLOSED / RELEASED-host-pending / HOST-OWNED / DELETE) and the gate rule: no phase deletes host code until its rows are upstreamed+bumped, reclassified host-owned, or covered by a seam test.
  • Two stale references in the plan doc were corrected after an audit against current code (all_tools_with_runtime owns the 12-arg too_many_arguments; the reasoning-channel row no longer claims "smuggled via ProviderExtension").
  • Merged upstream/main into the branch to keep it mergeable: unioned Cargo.toml (kept the branch's tinyagents 1.7.1 bump + restored the repl feature main added for its new rlm tool + main's tinyjuice/tinycortex deps); both lockfiles reconciled via cargo metadata.

Submission Checklist

  • Tests added or updated — N/A for host code in this PR: Phase 0/1 changes are crate re-exports, delegation, and a stream-path swap; the ported logic's tests live upstream with the code (per the plan's §4 test-migration strategy). No host behavior deleted. Existing host seam suites (schema_, context_window, tinyagents/* conversion) continue to guard the seam.
  • Diff coverage ≥ 80% — the host diff is dominated by deletions (in-tree SchemaCleanr), docs, and lockfile/manifest bumps; the remaining changed host lines are exercised by existing seam tests. Full validation deferred to CI runners per request.
  • Coverage matrix updated — N/A: no new user-facing feature rows (internal engine consolidation; wire surface unchanged).
  • All affected feature IDs listed under ## RelatedN/A: behaviour-preserving consolidation.
  • No new external network dependencies introduced — confirmed; new crate deps (tinyagents bump, plus main's tinyjuice/tinycortex) are vendored submodules patched to local paths.
  • Manual smoke checklist updated — N/A: no release-cut surface change.
  • Linked issue closed — see ## Related (tracking issue Improve agent harness with LangGraph-style state machine or Polaris-like architecture #4249 workstream; not auto-closed by this partial phase).

Impact

  • Runtime: desktop core (Rust). No JSON-RPC method names or payload shapes change; provider factory grammar, local AI runtime, voice, product tool catalog, and UI are untouched.
  • Compatibility: reasoning is now persisted as typed ContentBlock::Thinking for new messages while legacy ProviderExtension reasoning is still read from existing transcripts.
  • Security: no change to SecurityPolicy/approval gating; upstreamed code is generic (no product policy or backend phrases moved).
  • Migration: two Cargo worlds both bumped in lockstep; vendor/tinyagents pinned to the v1.7.1 tag (never floated).

Related

  • Closes: N/A (partial phase of the Improve agent harness with LangGraph-style state machine or Polaris-like architecture #4249 TinyAgents consolidation workstream — tracking, not closing)
  • Follow-up PR(s)/TODOs: Phase 2 (tool-model reconciliation + builtin tool families), Phase 3 (provider consolidation / compatible*.rs deletion), Phase 4 (orchestration onto graph::orchestration) — all enumerated in docs/tinyagents-port-plan.md §3 and the drift-ledger phase gates.

AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: docs/tinyagents-port-plan
  • Commit SHA: d968709ac63066179c97f0fbd9a201c740554555

Validation Run

  • pnpm --filter openhuman-app format:check — N/A (no app/src changes)
  • pnpm typecheck — N/A (no TypeScript changes)
  • Focused tests: cargo fmt --check passed; host cargo check --lib run locally on the merged tree (see Validation Blocked for the environment caveat); full suites deferred to CI.
  • Rust fmt/check (if changed): cargo fmt --check clean; dependency resolution succeeds on both Cargo worlds (cargo metadata exit 0 for root + app/src-tauri).
  • Tauri fmt/check (if changed): deferred to CI full lane.

Validation Blocked

  • command: cargo check --lib --manifest-path Cargo.toml
  • error: earlier local runs hit a transient couldn't create a temp dir in target/debug/deps under concurrent-build contention (not a code error); full compile/test validation intentionally deferred to GitHub runners per the requester.
  • impact: CI (CI Lite on the PR, CI Full on the release lane) is the authoritative gate before merge.

Behavior Changes

  • Intended behavior change: none functional — internal engine consolidation onto crate primitives.
  • User-visible effect: none (reasoning persistence format is the only observable change, and it is backward-read-compatible).

Parity Contract

  • Legacy behavior preserved: JSON-RPC surface, provider grammar, tool catalog, reasoning read-back from legacy transcripts.
  • Guard/fallback/dispatch parity checks: model-context lookup keeps OpenHuman tier/cost-catalog arms ahead of the crate fallback; schema-clean import path preserved via re-export.

Duplicate / Superseded PR Handling

senamakel added 17 commits July 4, 2026 16:48
Use the crate-backed schema cleaner and generic model context hints, adopt context-preserving invoke_stream for observed runs, and record the remaining Phase 1 host wrapper boundaries.
Audit of the plan against current code surfaced two inaccuracies:

- §5: the 12-positional-arg `#[allow(too_many_arguments)]` is on
  `all_tools_with_runtime`, not `all_tools` (the thin `all_tools` shim
  forwards 9). Re-attribute so the "builder overdue" note points at the
  real offender.
- §1.1: the reasoning-content row still said the channel is "today
  smuggled via ProviderExtension", contradicting the CLOSED status in
  §3 Phase 1.4 / ledger P1-5. The host now writes ContentBlock::Thinking
  for new messages and only reads legacy ProviderExtension from persisted
  transcripts; mark the motion as largely done.

Claude-Session: https://claude.ai/code/session_01LHbWHHV8MAFsv8aLi9XSbB
Reconcile the TinyAgents v1.7.1 port branch with main so the PR is
mergeable and CI can run. Conflicts resolved:

- Cargo.toml: union of both dependency sets — keep the branch's
  tinyagents 1.7.1 bump AND main's new tinyjuice/tinycortex deps and
  tokenjuice-treesitter refactor. Restored the `repl` feature main added
  to tinyagents (powers main's new `rlm` language-workflow tool) on top
  of the 1.7.1 pin: features = ["sqlite", "repl"]. Verified v1.7.1 still
  exposes `repl = ["dep:rhai"]`.
- docs/tinyagents-port-plan.md: add/add conflict — kept the branch's
  evolved plan (main only had the original draft from squash-merged
  tinyhumansai#4525).
- vendor/tinyagents submodule: kept the branch's v1.7.1 / 3e81e493 pin.
- vendor/tinycortex, vendor/tinyjuice: adopted main's pins; submodules
  initialized.
- Both Cargo.lock files reconciled via `cargo metadata` (resolution
  succeeds on both Cargo worlds; rhai now present in the tauri lockfile).

Claude-Session: https://claude.ai/code/session_01LHbWHHV8MAFsv8aLi9XSbB
@senamakel senamakel requested a review from a team July 5, 2026 05:12
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 29 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b1c22c8f-2d5d-4d80-b9f5-fa6db289be45

📥 Commits

Reviewing files that changed from the base of the PR and between a8115e8 and dcd1a0b.

📒 Files selected for processing (8)
  • docs/tinyagents-drift-ledger.md
  • docs/tinyagents-port-plan.md
  • src/openhuman/inference/model_context.rs
  • src/openhuman/tinyagents/convert.rs
  • src/openhuman/tinyagents/middleware.rs
  • src/openhuman/tinyagents/mod.rs
  • src/openhuman/tinyagents/model.rs
  • src/openhuman/tools/schema.rs

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

@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: d968709ac6

ℹ️ 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 on lines +785 to +786
AgentStreamItem::Failed(error) => {
terminal = Some(Err(tinyagents::TinyAgentsError::Model(error)));

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 Preserve typed failures from observed streams

When on_progress is set, this wrapped value is now the only terminal error that reaches the existing error mapper; converting every AgentStreamItem::Failed into TinyAgentsError::Model discards harness variants such as LimitExceeded and SubAgentDepth/RecursionLimit. The handler just below only translates those concrete variants into MaxIterationsExceeded or the spawn-depth error when the variant is preserved, so an interactive streamed run that fails for one of those harness conditions now surfaces as a generic harness/model failure instead of the typed error callers downcast and render specially.

Useful? React with 👍 / 👎.

Audit against current code found the arm is not globally dead: the
agent-tool running_subagents::steer path enforces parent ownership and
returns NotOwned (with a passing test). Only the trusted RPC steer_control
path skips the check, making the arm unreachable there. Reword §5 to
reflect this and point at the Phase 4 SteeringRegistry consolidation.
The matching code comment is clarified in fix/tinyagents-audit-fixes (PR tinyhumansai#4542).

Claude-Session: https://claude.ai/code/session_01LHbWHHV8MAFsv8aLi9XSbB

@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: 634ded9b01

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

);
return Some(*window);
}
if let Some(window) = tinyagents::harness::model::context_window_for_model_id(normalized) {

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 Preserve later o1/o3 segment matches

For raw model ids where o1/o3 is a delimiter-bounded segment but not the first segment after the provider prefix, such as ollama/mistral-for-o1-benchmark (the regression guard in this file still expects this to resolve), this delegation drops the match when there is no cost-catalog row. TinyAgents v1.7.1 only compares the first -/_/. segment of the final model name, so these ids now return None and skip the 200k pre-dispatch budget (or fall back to a much smaller local profile), letting long histories reach providers without the intended trimming and fail with context-window errors.

Useful? React with 👍 / 👎.

The Rust Core Coverage job (which compiles `cargo test`, unlike the
`cargo check --lib` used for the earlier local validation) surfaced three
test-only E0063 errors against TinyAgents 1.7.x:

- middleware.rs test ToolRuntime literals missing `timeout` → set
  `ToolTimeout::Inherit` (matches the source-side seam mapping).
- observability.rs ToolCompleted test event missing `started_at_ms` →
  `None` (mirrors the sibling test at line 1273 that already had it).

Source (non-test) constructors already carried these fields, so
`cargo check --lib` passed while the test build did not. Verified by a
`cargo check --tests` run that clears the E0063s.

Claude-Session: https://claude.ai/code/session_01LHbWHHV8MAFsv8aLi9XSbB

@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: 5a3b74cdd3

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

#[cfg(test)]
#[path = "schema_tests.rs"]
mod tests;
pub use tinyagents::harness::tool::{CleaningStrategy, SchemaCleanr, GEMINI_UNSUPPORTED_KEYWORDS};

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 Keep the schema cleaner tests wired

With this replacement the old #[path = "schema_tests.rs"] mod tests; hook is gone, and rg "schema_tests" shows no remaining include for src/openhuman/tools/schema_tests.rs. That means the host seam tests for Gemini ref resolution, union flattening, null stripping, and validation no longer run in cargo test; a mismatch in the new TinyAgents re-export can ship unnoticed even though the test file is still present. Please reattach these tests or remove/port them explicitly.

Useful? React with 👍 / 👎.

senamakel added 2 commits July 5, 2026 07:20
The port delegated generic model-context fallback to the crate's
context_window_for_model_id, which resolves canonical o1/o3 ids but does
not match an o1/o3 token embedded mid-name (e.g.
ollama/mistral-for-o1-benchmark). That regressed
o1_o3_segment_match_does_not_overmatch (surfaced by the full-suite
coverage run, which the port's Cargo.toml/lock change triggers).

Restore a minimal host-side segment heuristic that runs only when the
crate returns None: an o1/o3 token bounded by non-alphanumeric characters
maps to the 200K window, while substrings (solo1-7b, proto3-chat,
octo3thing) do not over-match. Preserves the pre-port behavior (PR tinyhumansai#2100
regression guard) until the crate matcher covers internal segments.

Claude-Session: https://claude.ai/code/session_01LHbWHHV8MAFsv8aLi9XSbB
Main merged tinyhumansai#4552 (tinyflows integration) which independently bumped
tinyagents to v1.7.1 and updated the seam. Reconcile:

- Cargo.toml: take main's `tinyagents = "1.7"` line (semver-equivalent to
  the branch's "1.7.1"; the [patch] pins the vendored submodule anyway).
- tinyagents/observability.rs, tinyagents/tools.rs: take main's version —
  its tinyhumansai#4552 seam update is the authoritative 1.7.1 adaptation (ignores the
  new ToolCompleted fields via `..` in favour of its own capture side
  channel). The branch's redundant test-constructor field fills are
  dropped in favour of main's.
- Kept this branch's unique work (no conflict): tools/schema.rs re-export
  of the crate SchemaCleanr, model_context.rs delegation to the crate +
  the host o1/o3 segment fallback, reasoning ContentBlock::Thinking, and
  the port-plan/drift-ledger docs.
- Both Cargo.lock files reconciled via `cargo metadata`.

Claude-Session: https://claude.ai/code/session_01LHbWHHV8MAFsv8aLi9XSbB

@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: 92e3bb95f7

ℹ️ 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.lock Outdated
[[package]]
name = "tinyflows"
version = "0.3.2"
version = "0.3.0"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore the TinyFlows lockfile version

This lockfile-only downgrade selects tinyflows 0.3.0 even though the checked-in tree already uses the observed journal APIs added after 0.3.0 (for example run_with_checkpointer_journaled_observed / resume_with_checkpointer_journaled_observed in src/openhuman/flows/ops.rs). Since neither Cargo.toml nor the vendor/tinyflows submodule changes in this commit, keeping the older lock entry will either make cargo --locked reject the stale path-package version or compile against a crate version that lacks those flow-run APIs; please keep both lockfiles on the version from the parent lock.

Useful? React with 👍 / 👎.

senamakel added 2 commits July 5, 2026 08:35
Main's tinyhumansai#4552 already bumped tinyagents to v1.7.1 in both lockfiles, so
this branch no longer needs to touch Cargo.toml/Cargo.lock at all. Reset
both lockfiles to main's so the PR diff is source + docs only — which
keeps CI on the domain-scoped lane (inference/tinyagents/tools) instead
of the config-level full-suite fallback. The full suite was failing to
compile the pre-existing-broken tests/subconscious_e2e.rs (stale
SubconsciousEngine::new / with_connection call sites that are also broken
on main but never compiled by main's scoped CI) — unrelated to this port.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant