Skip to content

feat: add --model flag to ucode copilot - #385

Open
larsmoan wants to merge 6 commits into
databricks:mainfrom
larsmoan:feat/copilot-model-flag
Open

feat: add --model flag to ucode copilot#385
larsmoan wants to merge 6 commits into
databricks:mainfrom
larsmoan:feat/copilot-model-flag

Conversation

@larsmoan

Copy link
Copy Markdown

Copilot has no way to pick a model per launch: there's no --model flag (unlike claude), Copilot's own /models picker can't be trusted against the Databricks gateway, and ucode overwrites COPILOT_MODEL on every 30-minute token refresh anyway. The only override today is an admin-only managed config.

Adds --model to ucode copilot, mirroring claude. The explicit model is threaded past the refresh loop (_refresh_forever/_refresh_token_once) so it stays pinned for the whole session instead of being silently reclaimed by default_model() at the next refresh.

Closes #384.

Copilot had no way to pick a model per launch or per session: the
CLI had no --model flag (unlike claude), and Copilot's own /models
picker can't be trusted to work against the Databricks gateway, plus
ucode overwrites COPILOT_MODEL on every token refresh anyway. The
only override was an admin-only managed config.

Thread an explicit model through past that refresh loop so it stays
pinned for the whole session, instead of writing it once at config
time and letting default_model() silently reclaim it 30 minutes later.

Closes databricks#384
Copilot AI lite review requested due to automatic review settings August 25, 2026 12:59

Copilot AI 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.

Pull request overview

Adds per-launch --model selection to ucode copilot and preserves it across token refreshes.

Changes:

  • Adds the --model CLI option.
  • Threads model overrides through Copilot dispatch and refresh logic.
  • Adds CLI, dispatch, and refresh-loop tests.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Summary Findings
tests/test_cli.py Tests CLI model handling. None
tests/test_agents_init.py Tests dispatch behavior. None
tests/test_agent_copilot.py Tests model selection and refresh pinning. None
src/ucode/cli.py Defines and forwards --model. Critical (2 votes): Explicit models can fail when no fallback model exists because resolution occurs before the explicit override.
src/ucode/agents/copilot.py Pins the model across refreshes. None
src/ucode/agents/__init__.py Dispatches Copilot model overrides. None
Suppressed comments (1)

src/ucode/cli.py:1961

  • resolved_model can differ from the raw CLI model: for example, a managed budget recommendation is selected by managed_launch_model, written by configure_tool, but not stored in state. Passing None for a Copilot launch without an explicit --model makes copilot.launch call default_model(state) again and immediately rewrite that selection, and refreshes keep doing so. Pass the already resolved model here so managed/recommended choices survive the initial write and refresh loop.
        launch_agent(tool, state, ctx.args, model=model if tool == "copilot" else None)

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/ucode/cli.py
@larsmoan
larsmoan marked this pull request as draft August 25, 2026 13:09
Without an explicit --model, this passed None to launch_agent, so
copilot.launch() recomputed default_model(state) from scratch instead
of reusing what configure_tool had already written — silently
diverging from a managed config's default or a budget recommendation,
and repeating that drift on every 30-minute token refresh.

resolved_model already absorbs --model, the managed default, and any
budget recommendation, so it's the correct value to pin.

Flagged by review on databricks#385.
@larsmoan

Copy link
Copy Markdown
Author

Fixed in 0ff75e7launch_agent now gets resolved_model (which already absorbs --model, a managed default, and any budget recommendation) instead of the raw --model flag. Manually tested end-to-end against a real workspace: ucode copilot --model system.ai.claude-opus-4-8 launches and pins correctly.

@larsmoan
larsmoan marked this pull request as ready for review August 25, 2026 13:16
Copilot AI review requested due to automatic review settings August 25, 2026 13:16

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/ucode/cli.py:2284

  • This option is applied only after _launch_tool has completed its setup and model resolution. On a first ucode copilot --model X (or when Copilot is not yet in available_tools), _auto_configure_tool("copilot") runs first, and configure_single_tool/validate_env select and validate default_model(state) without seeing X; if discovery has no default or the automatic model is unsupported, the command exits before the requested model is ever written or launched. Thread the explicit model through the auto-config/validation path, or skip default-model setup when --model is supplied.
            help="Launch on a specific Databricks model id (e.g. a UC "
            "`<catalog>.<schema>.<name>`). Outranks the automatic sonnet/opus/haiku/codex "
            "pick and stays pinned across ucode's automatic token refreshes.",

tests/test_agents_init.py:182

  • This class is inserted before the existing test_pi_available_* methods, so those availability tests are now collected under TestLaunch instead of TestCheckGatewayEndpoint. They still run, but the grouping is misleading and makes future fixture/setup changes error-prone; place the new TestLaunch class after the complete gateway-endpoint test class.
class TestLaunch:

On a first-time `ucode copilot --model X` (copilot not yet in
available_tools, or no workspace configured), _auto_configure_tool ran
before the --model handling further down _launch_tool, so it wrote and
smoke-tested the automatic sonnet/opus/haiku/codex default instead of
X. If that automatic pick failed validation, the launch aborted before
X was ever tried — even though X itself may have been perfectly valid.

Thread the explicit model through configure_single_tool/_configure_one
(so resolve_launch_model's explicit_model wins) and through
validate_tool (so copilot.validate_env smoke-tests X, not the default).

Also fixes a test-ordering issue: TestLaunch had been inserted in the
middle of TestCheckGatewayEndpoint, splitting its test_pi_available_*
tests into a misleadingly-named group.

Flagged by review on databricks#385.
Copilot AI review requested due to automatic review settings August 25, 2026 13:40
@larsmoan

Copy link
Copy Markdown
Author

Addressed both review findings in 321e693:

  1. Critical: a first-time ucode copilot --model X (copilot not yet in available_tools) ran _auto_configure_tool before the --model handling in _launch_tool, so it configured and smoke-tested the automatic sonnet/opus/haiku/codex default instead of X. Threaded the explicit model through configure_single_tool/_configure_one (config write) and validate_tool/copilot.validate_env (smoke test) so X is what's actually configured and validated.
  2. Test ordering: moved TestLaunch out of the middle of TestCheckGatewayEndpoint, which had split off its test_pi_available_* tests into a misleadingly-grouped class.

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/ucode/cli.py:1742

  • This forwards the explicit model into first-time setup, but the normal launch path still calls resolve_launch_model(tool, state, managed_model) before applying model at line 1900. If discovery/state has no fallback model (for example with --skip-preflight or a failed model listing), that resolver raises before the requested Copilot model is ever considered, so ucode copilot --model X cannot launch. Pass the Copilot override into model resolution or bypass the fallback resolution when it is present.
            _auto_configure_tool(tool, model=model if tool == "copilot" else None)

Copilot AI review requested due to automatic review settings August 25, 2026 20:33

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread src/ucode/agents/__init__.py
Copilot AI review requested due to automatic review settings August 25, 2026 22:12

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread src/ucode/agents/__init__.py Outdated
The docstring claimed explicit_model keeps a bad automatic pick from
failing the availability check. It does not: check_gateway_endpoint runs
before _configure_one sees explicit_model, and takes no model at all.
explicit_model only changes what gets written and smoke-tested.

Flagged by review on databricks#385.
Copilot AI review requested due to automatic review settings August 25, 2026 23:22

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

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.

Add --model flag to ucode copilot for manual model selection

2 participants