Skip to content

feat: add config model pins for agents#1905

Merged
senamakel merged 6 commits into
tinyhumansai:mainfrom
honor2030:feat/agent-config-model-defaults
May 17, 2026
Merged

feat: add config model pins for agents#1905
senamakel merged 6 commits into
tinyhumansai:mainfrom
honor2030:feat/agent-config-model-defaults

Conversation

@honor2030
Copy link
Copy Markdown
Contributor

@honor2030 honor2030 commented May 16, 2026

Summary

  • add [orchestrator] model = ... and [teams.<team>] lead_model/agent_model config tables for agent model defaults
  • apply config-level pins in orchestrator session creation and delegated sub-agent model resolution
  • keep precedence deterministic: inline model override > config-level pin > existing model spec / workload routing

Notes

  • Stacked after feat: allow inline model pinning for subagents #1896, which adds the inline model parameter plumbing used by the highest-precedence override path.
  • This PR keeps provider selection unchanged and only replaces the final exact model id when a pin is configured.

Refs #1837

Test Plan

  • cargo fmt --all
  • RUSTC=/Users/lee/.rustup/toolchains/1.93.0-aarch64-apple-darwin/bin/rustc GGML_NATIVE=OFF cargo test -p openhuman --lib subagent_runner -- --nocapture
  • RUSTC=/Users/lee/.rustup/toolchains/1.93.0-aarch64-apple-darwin/bin/rustc GGML_NATIVE=OFF cargo test -p openhuman --lib model_pin_tests -- --nocapture
  • RUSTC=/Users/lee/.rustup/toolchains/1.93.0-aarch64-apple-darwin/bin/rustc GGML_NATIVE=OFF cargo check -p openhuman
  • git diff --check

Summary by CodeRabbit

  • New Features

    • Added configurable model pinning for orchestrator, teams, and per-role agents, with blank pins treated as unset.
    • Model resolution now follows explicit precedence: inline override → config pins (orchestrator/team/role) → existing defaults/aliases; supports team aliases and "_agent" suffix handling.
  • Tests

    • Added and expanded tests and an end-to-end scenario to validate override/pin precedence and recorded model usage.

Review Change Stack

@honor2030 honor2030 requested a review from a team May 16, 2026 09:17
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d051b3c7-b8cf-4493-977b-2f4acefa5f0f

📥 Commits

Reviewing files that changed from the base of the PR and between 2d52dd0 and 964ea33.

📒 Files selected for processing (1)
  • src/openhuman/agent/harness/session/builder.rs

📝 Walkthrough

Walkthrough

This PR adds optional orchestrator and per-team model pinning in config, implements deterministic precedence for model resolution (inline override → config pin → existing spec fallback), applies pins in session/provider flows, and adds tests validating precedence and routing.

Changes

Model Pinning for Agent Routing

Layer / File(s) Summary
Config types, model resolution, and unit tests
src/openhuman/config/schema/agent.rs, src/openhuman/config/schema/types.rs, src/openhuman/config/schema/mod.rs, src/openhuman/config/mod.rs
Introduces OrchestratorModelConfig and TeamModelConfig with model_for_role; extends Config with orchestrator and teams; adds Config::configured_agent_model implementing precedence (orchestrator, team lead/agent, aliases, *_agent suffix) and unit tests for parsing and precedence.
Provider resolution with model precedence
src/openhuman/agent/harness/subagent_runner/ops.rs
Updates resolve_subagent_provider signature to accept is_team_lead and model_override; enforces precedence: inline override → config pin via configured_agent_model → existing ModelSpec fallback; documents behavior and updates run_typed_mode call sites.
Session builder model pinning
src/openhuman/agent/harness/session/builder.rs
Binds provider model_name as mutable, derives target_agent_id/target_is_lead from target definition, applies configured_agent_model pinning and logs when a pin is used.
Test harness updates and precedence validation
src/openhuman/agent/harness/subagent_runner/ops_tests.rs
Adds model to CapturedRequest and captures it in ScriptedProvider::chat; updates typed-mode tests to include model_override fields; adds E2E and regression tests asserting model precedence and alias/team routing; updates existing tests to new resolver signature.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant Resolver as resolve_subagent_provider
  participant Config as configured_agent_model
  Caller->>Resolver: call(agent_id, is_team_lead, model_override)
  alt model_override present
    Resolver->>Caller: return (parent_provider, model_override)
  else no override
    Resolver->>Config: configured_agent_model(agent_id, is_team_lead)
    alt config pin found
      Config->>Resolver: pinned_model
      Resolver->>Caller: return (parent_provider, pinned_model)
    else no pin
      Resolver->>Resolver: ModelSpec fallback logic
      Resolver->>Caller: return (resolved_provider, resolved_model)
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • senamakel

Poem

🐰 I hopped through configs, trimmed each pin,

Override first, then the team’s choice wins.
Sessions now know which model to send,
Tests hop in to prove the flow to the end. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately and concisely summarizes the main change—adding configuration-level model pins for agents.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label May 16, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/openhuman/agent/harness/subagent_runner/ops.rs (1)

119-133: ⚡ Quick win

Use debug/trace for pin-resolution branch diagnostics instead of info.

These logs are per-spawn branch diagnostics and can get very noisy at info level in normal runs. Switching them to structured tracing::debug! (or trace!) keeps observability useful without inflating baseline logs.

As per coding guidelines: “Rust core code must use log / tracing at debug / trace levels for verbose diagnostics on new/changed flows…”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/agent/harness/subagent_runner/ops.rs` around lines 119 - 133,
Replace the noisy info-level logging in the subagent model-pin branches with a
debug/trace call: change the two log::info! invocations that report the inline
model override (the branch that returns (parent_provider, model.to_string())
after checking the inline override) and the config-level model pin (the branch
using cfg.configured_agent_model(agent_id, is_team_lead)) to tracing::debug! (or
tracing::trace! if you want even finer granularity) so these per-spawn
diagnostics are emitted at a lower verbosity; keep the same message structure
and argument values (agent_id and model) when swapping the macro names.
🤖 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/config/schema/agent.rs`:
- Around line 30-37: The current model_for_role prefers
self.lead_model/self.agent_model as-is so an option containing only whitespace
(e.g., "   ") prevents fallback; change the selection so lead_model and
agent_model are first normalized to None if they are empty or whitespace before
applying or(...) logic. Specifically, in model_for_role trim and filter each
Option from self.lead_model.as_deref() and self.agent_model.as_deref() (e.g.,
map(str::trim).filter(|s| !s.is_empty())) and then use that cleaned Option in
the existing preferred logic (referencing model_for_role, lead_model,
agent_model, preferred) so blank strings no longer block cross-tier fallback.

---

Nitpick comments:
In `@src/openhuman/agent/harness/subagent_runner/ops.rs`:
- Around line 119-133: Replace the noisy info-level logging in the subagent
model-pin branches with a debug/trace call: change the two log::info!
invocations that report the inline model override (the branch that returns
(parent_provider, model.to_string()) after checking the inline override) and the
config-level model pin (the branch using cfg.configured_agent_model(agent_id,
is_team_lead)) to tracing::debug! (or tracing::trace! if you want even finer
granularity) so these per-spawn diagnostics are emitted at a lower verbosity;
keep the same message structure and argument values (agent_id and model) when
swapping the macro names.
🪄 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: 04f9a014-78e5-44ef-8c2f-feb8a2401a3c

📥 Commits

Reviewing files that changed from the base of the PR and between 8f93ca0 and 2cc6ed2.

📒 Files selected for processing (14)
  • src/openhuman/agent/harness/session/builder.rs
  • src/openhuman/agent/harness/subagent_runner/ops.rs
  • src/openhuman/agent/harness/subagent_runner/ops_tests.rs
  • src/openhuman/agent/harness/subagent_runner/types.rs
  • src/openhuman/config/mod.rs
  • src/openhuman/config/schema/agent.rs
  • src/openhuman/config/schema/mod.rs
  • src/openhuman/config/schema/types.rs
  • src/openhuman/tools/impl/agent/archetype_delegation.rs
  • src/openhuman/tools/impl/agent/dispatch.rs
  • src/openhuman/tools/impl/agent/skill_delegation.rs
  • src/openhuman/tools/impl/agent/spawn_parallel_agents.rs
  • src/openhuman/tools/impl/agent/spawn_subagent.rs
  • src/openhuman/tools/impl/agent/spawn_worker_thread.rs

Comment thread src/openhuman/config/schema/agent.rs
@senamakel
Copy link
Copy Markdown
Member

@coderabbitai can u explain to me what's the benefit of pinning the config to agents? or explain this PR in more detail?

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

Tip

For best results, initiate chat on the files or code changes.

@senamakel Great question! Here's a detailed breakdown of what this PR does and why config-level model pinning is useful.


What Problem Does This Solve?

In a multi-agent system like OpenHuman, different agents (an orchestrator, team leads, sub-agents) can run on different AI models. Previously, the only way to control which model an agent used was through workload routing or inline model specs — meaning you had to change code or per-call options. This PR lets you set model preferences once in a config file and have them automatically apply every time an agent is created.


What Does the PR Add?

1. New Config Options

You can now add entries like this to your config:

[orchestrator]
model = "gpt-4o"

[teams.research_team]
lead_model = "gpt-4o"
agent_model = "gpt-4o-mini"
  • [orchestrator] model — pins the front-line orchestrator to a specific model.
  • [teams.<team>] lead_model — pins the team lead agent's model for a named team.
  • [teams.<team>] agent_model — pins the regular (non-lead) sub-agents in that team.

2. Deterministic Model Selection Precedence

The PR establishes a clear, three-tier priority chain:

flowchart TD
    A["1. Inline model override\n(per-call, highest priority)"] --> B["2. Config-level pin\n(orchestrator / team)"]
    B --> C["3. Existing ModelSpec / workload routing\n(fallback)"]
    style A fill:rgba(255,100,100,0.5)
    style B fill:rgba(255,180,50,0.5)
    style C fill:rgba(100,200,100,0.5)
Loading

This means you always know exactly which model will be used and why.

3. New Structs & Config Resolution Logic

Two new structs are introduced in config/schema/agent.rs:

  • OrchestratorModelConfig — holds the optional orchestrator model override.
  • TeamModelConfig — holds lead_model and agent_model per team, plus a model_for_role(is_team_lead) helper to pick the right one.

A new method Config::configured_agent_model(agent_id, is_team_lead) in config/schema/types.rs resolves the pinned model for any given agent role. It also handles built-in alias mappings (e.g., researcher, code_executor, tool_maker, integrations_agent).

4. Tools That Benefit

  • spawn_subagent tool — now accepts an optional model argument so callers can pin a model for a single spawn.
  • archetype_delegation tool — similarly gains an optional model field.
  • Provider resolution in subagent_runner/ops.rs — checks for inline override first, then config pin, then falls back to existing routing.

Why Is Config-Level Pinning Useful?

Benefit Explanation
Reproducibility Running the same config always uses the same models — no surprises from workload routing changes.
Cost control You can assign cheaper models to sub-agents (agent_model) and reserve expensive models only for team leads or the orchestrator.
Centralized management One config change propagates to all agents in a team, instead of updating every call site.
Predictable testing You can pin models in test configs to get deterministic behavior.
Flexibility Per-call inline overrides still win, so you can always escape the config pin when needed.

This PR is stacked on #1896 (which added inline model parameter plumbing) and references issue #1837. Together they form a complete model pinning story: config-level as the default, inline override for one-off control.

senamakel added 3 commits May 16, 2026 22:15
# Conflicts:
#	src/openhuman/agent/harness/session/builder.rs
#	src/openhuman/agent/harness/subagent_runner/ops.rs
#	src/openhuman/agent/harness/subagent_runner/ops_tests.rs
#	src/openhuman/config/mod.rs
#	src/openhuman/tools/impl/agent/archetype_delegation.rs
…role before fallback

A lead_model/agent_model value containing only whitespace (e.g. "   ")
was treated as Some(_) by or(...), blocking cross-tier fallback to the
other field. Normalize each field individually via map(str::trim).filter
before applying the or logic so blank strings fall through correctly.

Addresses @coderabbitai on src/openhuman/config/schema/agent.rs:37.
…to debug

Per-spawn branch diagnostics (inline model override, config-level pin)
were logged at info level, making them noisy on normal runs. Switch to
debug so they stay visible when needed without inflating baseline logs.

Addresses @coderabbitai nitpick on ops.rs:119-133.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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.rs`:
- Around line 786-790: Change the diagnostic log in the session builder from
info to debug so model-pin selection doesn't flood logs: replace the log::info!
call that prints "[session-builder] agent_id={} using config-level model pin
model={}" (which references target_agent_id and pinned_model) with log::debug!
so this branch-level model-selection message is emitted at debug level instead
of info.
🪄 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: 7447224b-5c0f-418a-965a-5c7c1d743b5c

📥 Commits

Reviewing files that changed from the base of the PR and between 2cc6ed2 and 0742b03.

📒 Files selected for processing (5)
  • src/openhuman/agent/harness/session/builder.rs
  • src/openhuman/config/mod.rs
  • src/openhuman/config/schema/agent.rs
  • src/openhuman/config/schema/mod.rs
  • src/openhuman/config/schema/types.rs
✅ Files skipped from review due to trivial changes (1)
  • src/openhuman/config/schema/mod.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/openhuman/config/mod.rs
  • src/openhuman/config/schema/agent.rs
  • src/openhuman/config/schema/types.rs

Comment thread src/openhuman/agent/harness/session/builder.rs Outdated
Model-pin selection is a per-session branch diagnostic; info level
floods logs on normal runs. Switch to debug to match the ops.rs change.

Addresses @coderabbitai on builder.rs:786-790.
@senamakel senamakel merged commit 3297cf0 into tinyhumansai:main May 17, 2026
25 checks passed
AusAgentSmith pushed a commit to AusAgentSmith/openhuman that referenced this pull request May 23, 2026
Co-authored-by: honor2030 <19909783+honor2030@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants