Repository navigation
perf(agent): share one Arc<Config> across per-build tool/provider/reflection (#5050) - #5062
Conversation
…lection (tinyhumansai#5050) Stop deep-cloning the large `Config` at each heavyweight consumer inside `build_session_agent_inner`. The tool registry, the reflection hook, and the turn provider now share a single `Arc<Config>` (`base_config`) — refcount bumps instead of full deep clones. `Config` is immutable after construction, so this is behaviour-identical. The App-UI-Control / App-Automation features toggle (tinyhumansai#3762), the one consumer that needs a mutated config, is extracted into `resolve_tool_config`: it clones at most once and only when the toggle actually fires, scoping the `ax_interact_mutations` grant to the tool registry so the provider and reflection hook keep the ungranted base. Unit tests pin the Arc-sharing and grant-scoping invariants (the grant must never leak to the base config). Scoped to this issue's Fix 1 acceptance criterion (the config clones the issue names at :396 / :409 / :1170). The owned-Config consumers (ArchivistHook, integration_runtime_config) and the lazy tool-surface refactor (Fix 3/4) are deferred; Fix 2's per-agent-roster premise is unproven in-repo (the built-in subagent path already Arc-shares one session).
📝 WalkthroughWalkthroughThe session builder now shares ChangesShared configuration resolution
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@src/openhuman/agent/harness/session/builder/factory.rs`:
- Around line 1230-1241: The base-config resolution flow needs diagnostics for
the no-op path as well as the grant branch. Update the resolver around the
ax_interact_mutations check to log grep-friendly entry, reuse-base branch, and
exit diagnostics, while preserving the existing grant behavior and its log.
🪄 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: 9291ba3c-b27e-4161-8be9-b855d5e77b56
📒 Files selected for processing (2)
src/openhuman/agent/harness/session/builder/builder_tests.rssrc/openhuman/agent/harness/session/builder/factory.rs
…inyhumansai#5050) Per the repo logging guideline (verbose, grep-friendly diagnostics on new/changed flows: entry/exit + branches) and CodeRabbit review: resolve_tool_config now emits an entry trace and an exit debug log on BOTH branches — the granted-mutations path and the common reuse-base path — instead of only logging the grant branch.
CodeGhost21
left a comment
There was a problem hiding this comment.
LGTM — clean, well-scoped perf refactor.
Shares one Arc<Config> across the tool registry, reflection hook, and turn provider instead of deep-cloning the large Config at each site. Verified:
- Behavior-identical:
resolve_tool_configscopes the App-UI-Control grant to the tool registry only; provider + reflection stay on the ungranted base — matching the oldadjusted_configsemantics. The scoping invariant is directly test-pinned. - Type-checks:
Arc::clone(&tool_config)for theArc<Config>param and&tool_configderef-coerces to&Configforroot_config(all_tools_with_runtime). - Clone reduction holds in both branches (toggle-off 3→1, toggle-on ~3–4→2);
Configimmutability premise is sound. - Tests cover all three helper branches with
Arc::ptr_eq— the right assertion for a refcount-sharing refactor. - Logging follows the grep-friendly-diagnostics convention.
Non-blocking: the single residual config.clone() into base_config could be eliminated by threading ownership from the caller in the deferred pass; a // TODO(#5050) breadcrumb would help. Deferral of Fix 2/3/4 is well-argued.
Review — approve ✅Focused, well-tested performance refactor. Verified the diff against the pre-PR code. Correctness — solid
Conventions
Minor (non-blocking)
RiskLow. No behaviour change, no new deps, no public API change. The only conceivable regression (grant leaking beyond the tool registry) is explicitly tested. Deferred Fix 2/3/4 are clearly scoped out. |
Reconcile dep-gating with main (now incl. tinyhumansai#5052/tinyhumansai#5060/tinyhumansai#5061/tinyhumansai#5062): - Cargo.toml: union gating (optional axum/sentry/ppt-rs + http-server/ inference/documents/crash-reporting features) with main's tower + tui deps and desktop-automation/tui features; default = union of both feature sets. - app/src-tauri: shell forwards crash-reporting/http-server/desktop-automation (feature-forwarding gate passes; tui allowlisted). - all_tests.rs: union of http-server + desktop-automation gate tests. - types.rs: keep main's redirect_links security denylist entry (tinyhumansai#5052). Cargo.lock + app/src-tauri/Cargo.lock resynced (--locked passes); cargo fmt, feature-forwarding gate, and clippy -D warnings all clean locally.
Summary
Configat each heavyweight consumer insidebuild_session_agent_inner: the tool registry, the reflection hook, and the turn provider now share oneArc<Config>(base_config) — refcount bumps instead of full clones.resolve_tool_confighelper.ax_interact_mutationsgrant is scoped to the tool registry and never leaks into the base config.Configis immutable after construction, so this is behaviour-identical.Problem
build_session_agent_innerdeep-cloned the fullConfig(117pubitems plus ~20 sub-schema modules) once per heavyweight consumer — at the tool-registry build, the reflection hook, and the turn provider. That is the per-agent-construction cost called out in #5050 (## Related).Scope note (important): the issue's headline "lazy tool surface" refactor is sized against a per-agent-roster premise that does not exist in this repo — the built-in multi-agent path (subagent delegation) already
Arc-shares oneAgentSession's tool registry, config, memory, and provider. So this PR delivers the issue's Fix 1 (theConfig-clone reduction, which pays off regardless of roster shape) and defers the lazy tool-surface refactor and the SQLite pool until the embedding pattern is confirmed. See Deferred below.Solution
base_config: Arc<Config>once at the top of the build; feed it (asArc::clone) to the tool registry, the reflection hook, and thecrate_native_providercall.resolve_tool_config(&base_config, &enabled_tools)returns the base Arc unchanged in the common case; only when the toggle actually fires does it clone-and-grant once, keeping that grant scoped to the tool registry so the provider/reflection keep the ungranted base.:396/:409/:1170). The owned-Configconsumers (ArchivistHook::with_config,integration_runtime_config) are not in that list and live in the turn/archivist subsystems; they are left for the deferred fuller pass.Deferred (out of scope here, by design)
DomainSetfilter before construction. These are one coupled refactor (a clean filter-before-construct needs the descriptor infrastructure; the naive alternative would hard-code ~325 tool names). Gated on confirming OpenCompany's embedding pattern.Mutexdeadlock surface.Submission Checklist
tool_config_shares_base_arc_when_ui_control_toggle_off,tool_config_grant_is_scoped_and_leaves_base_untouched,tool_config_reuses_base_when_mutations_already_granted_globally; existingbuild_session_agent_*tests continue to pass (regression).resolve_tool_confighelper (fully covered by the three unit tests) and theArc::clonesites (exercised by the existing build-path tests).N/A: internal performance refactor, no behaviour/feature change.N/A.N/A: behaviour-identical.Closes #NNN—N/A: delivers Fix 1 only; Fix 2/3/4 deferred (see Deferred).Impact
Configclones per agent construction (more when reflection is enabled), replacing them with refcount bumps. No behaviour change —Configis immutable post-build and the App-UI-Control grant stays scoped.Related
Changes since initial submission (review-driven)
62859aadd, CodeRabbit) —resolve_tool_confignow logs an entrytraceplus an exitdebugline on both branches (granted vs reused-base), per the repo's grep-friendly-diagnostics guideline. CodeRabbit subsequently approved the PR.AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch