Skip to content

Apply managed agent config per-agent and honor default model - #276

Merged
asujithan merged 4 commits into
mainfrom
managed-agent-shapes
Aug 6, 2026
Merged

Apply managed agent config per-agent and honor default model#276
asujithan merged 4 commits into
mainfrom
managed-agent-shapes

Conversation

@asujithan

@asujithan asujithan commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Changes

Makes an admin-published managed coding-agent config work for every agent, not just Claude Code, and fixes three bugs found while testing it. All behavior stays behind ENABLE_MANAGED_AGENT_CONFIG; with it unset the launch path is unchanged.

  1. Per-agent model shapes. managed_state_overrides translates the manifest's model list into the shape each agent reads: provider-bucketed for opencode, per-agent keys for pi and copilot. Previously every non-claude agent got a flat list, which crashed opencode and was silently ignored by pi and copilot.
  2. pi and copilot get their own state keys (pi_models, copilot_models) instead of writing the shared claude_models/codex_models/gemini_models. Those are workspace-wide discovery that claude, codex, and gemini also read, so one agent's managed policy could change what another launched.
  3. The admin's default_model now survives the whole session. Non-claude agents applied it once at launch and then immediately overwrote it: pi/copilot's launch() and the 30-minute token refresh re-derive the model from state, which never held it, so they fell back to the allowlist's first entry. resolve_state now overlays <tool>_default_model and each agent prefers it. Claude was already correct – it pins the model as ANTHROPIC_MODEL and never re-derives. Family slots are unaffected: an unset family stays unset rather than inheriting default_model.
  4. Blocking error for agents the admin didn't enable. enabled_agents is an allowlist; launching outside it ran fully unmanaged. Checked before model discovery so a rejected launch fails fast instead of after a ~19s sweep.
  5. Model discovery is skipped when the managed config already names models, removing that sweep from most managed launches.
  6. The managed config is fetched before discovery instead of read from cache. The allowlist check and the skip-discovery decision are now made from the authoritative config; previously a stale local copy could suppress discovery for a config that no longer named models. --skip-preflight still reads the cache by design. This replaces managed_launch_state with a fetch plus a separate resolve_state, since the manifest has to be layered over post-discovery state.
  7. classify_model_family extracted so a model named in a config buckets exactly as discovery would.

Test Plan

  • uv run pytest --> 1257 passed, 36 skipped
  • ruff check + ruff format clean
  • added new unit tests all passing
Screen.Recording.2026-08-05.at.3.12.20.PM.mov

AarushiShah-db
AarushiShah-db previously approved these changes Aug 6, 2026
Comment thread src/ucode/agents/pi.py
Comment thread src/ucode/managed_resolve.py
@asujithan
asujithan merged commit 7d9043e into main Aug 6, 2026
2 checks passed
@asujithan
asujithan deleted the managed-agent-shapes branch August 6, 2026 17:42
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.

2 participants