Skip to content

[AIGTWY-4876] Support managed CUJ1 setup - #1004

Merged
JTSIV1 merged 1 commit into
mainfrom
JTSIV1/aigtwy-4876-cuj1-prerequisite
Oct 7, 2026
Merged

JTSIV1 merged 1 commit into
mainfrom
JTSIV1/aigtwy-4876-cuj1-prerequisite

Conversation

@JTSIV1

@JTSIV1 JTSIV1 commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

Preserve the workspace URL scheme and port in managed-config and model-discovery requests so local recorder gateways receive them. Helps for local running without breaking how the CI works. Keep explicit Claude model selections scoped to a launch, using Claude's catalog selector for managed models and temporary aliases for others.

@JTSIV1
JTSIV1 added this pull request to stack #1005 October 6, 2026 13:51
@JTSIV1
JTSIV1 marked this pull request as ready for review October 6, 2026 13:58
Comment thread src/ucode/databricks.py
david-siqi-liu added a commit that referenced this pull request Oct 6, 2026
…recorder

These helpers rebuilt the workspace URL as `https://{hostname}`, so the TUI
request recorder at `http://127.0.0.1:<port>` was dialed at port 443. Carries
#1004's `workspace_origin` hunks verbatim so the two merge cleanly; the probe
hunk is omitted because #999 already fixed it.

Co-authored-by: Isaac <no-reply@databricks.com>
david-siqi-liu added a commit that referenced this pull request Oct 6, 2026
…recorder

These helpers rebuilt the workspace URL as `https://{hostname}`, so the TUI
request recorder at `http://127.0.0.1:<port>` was dialed at port 443. Carries
#1004's `workspace_origin` hunks verbatim so the two merge cleanly; the probe
hunk is omitted because #999 already fixed it.

Co-authored-by: Isaac <no-reply@databricks.com>

@david-siqi-liu david-siqi-liu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approving. One P1 to follow up on, not blocking:

P1

  • ug claude --model B for an out-of-catalog model (claude.py around 2104, _claude_launch_custom_model in cli.py) sets ANTHROPIC_MODEL=opus and passes the opus -> B mapping only through inline --settings. ug also writes ANTHROPIC_DEFAULT_OPUS_MODEL into /etc/claude-code/managed-settings.json on terminal launches. I couldn't find anything in the repo showing whether Claude ranks inline --settings env above OS-managed env (docs/os-managed-settings-design.md only covers user settings). Can we add a test for the case where an OS-managed Opus default already exists, so the launch provably uses B?

FYI: workspace_origin here fixes the same recorder-port problem CUJ 6 hit. #987 carries these databricks.py hunks verbatim (without the probe hunk, which #999 already fixed on main), and #993 makes overlapping edits with normalize_workspace_url. Whichever lands first, the other two should take workspace_origin as is.

@JTSIV1
JTSIV1 force-pushed the JTSIV1/aigtwy-4876-cuj1-prerequisite branch from dbc0fe4 to f023a7b Compare October 7, 2026 02:11
@JTSIV1
JTSIV1 added this pull request to the merge queue Oct 7, 2026
Merged via the queue into main with commit 3ac42a9 Oct 7, 2026
49 of 52 checks passed
@JTSIV1
JTSIV1 deleted the JTSIV1/aigtwy-4876-cuj1-prerequisite branch October 7, 2026 03:36
xsh310 pushed a commit to xsh310/ucode that referenced this pull request Oct 7, 2026
CUJ 6 (AIGTWY-4881, epic AIGTWY-4875) checks that a developer who
receives successive admin configs ends up with exactly the latest one:
no stale ug-managed values, and their own settings untouched. It runs
live on main's dedicated-workspace CUJ framework (databricks#1000) with the TUI
request recorder (databricks#994), against the CUJ 6 plan in the [UG Configure E2E
doc](https://docs.google.com/document/d/1WKd1fdWD0Y4tAV1H9Si-SGx2UZFL7iZ2S3HtBjidmS0/edit).

Workspace configs are read only, because parallel CI jobs share them.
Each phase is the single published config of its own pre-provisioned
workspace, and one shared home moves through them:
- A: `dbc-8c38ce9b-634b`, CUJ 1's config plus the named MCP
`ug_e2e.tools.fixture_reader`
- B: `dbc-175bc4a3-a511`, Claude on the Bedrock MPS
`ug_e2e.providers.bedrock`, Codex on UC discovery `ug_e2e.models`, Codex
as the default agent
- C: `dbc-998133ab-de86`, Codex only, on the static list
`system.ai.gpt-5-6-luna`

All three share one metastore, the `ug_e2e` fixtures, and one trace
table. The test never writes workspace config; it checks each published
config against the plan at the start and asserts it is unchanged at
teardown. A to B to C also exercises ug's cross-workspace switch.

Builds on databricks#1010 (merged), and on databricks#1004 (merged), whose
`workspace_origin` keeps the TUI request recorder's
`http://127.0.0.1:<port>` origin for the workspace API calls CUJ 6
routes through it.

Changes:
- `tests/e2e_cuj/test_cuj_repeated_config.py`: one class, phases as
ordered class-scoped fixtures (`phase_a` -> `phase_b` -> `phase_c`)
returning frozen evidence, 28 small tests on top.
- Setup: seeds user-owned Claude and Codex prefs, a user stdio MCP, and
a hand-written skill, with no ug state.
- Readback: each phase workspace publishes exactly the plan's config
(agents, model sources, defaults, headers, tracing, MCP selector).
- Phase A: configures twice; identical settings and registrations, no
duplicates; both agents complete a task with their phase headers and
default models at gateway ingress (recorder) and in the native turn.
- Phase B: Claude carries `databricks-model-provider-service` and no
Phase A headers; Codex carries `databricks-model-service-parent-schema`
and only the Phase B header; request and turn models match the sources.
Bare `ug` in a real terminal launches Codex and completes a task on
`ug_e2e.models.codex_primary`, and writes the Phase B header into
`/etc/codex/managed_config.toml`. Static picker, family defaults,
tracing keys, static Codex catalog, and the managed MCP are gone and
stay gone after launches. Codex emits a span; Claude emits none.
- Phase C: configures in a terminal (Phase B's terminal launch made ug
own the machine-wide files) and clears Phase B's headers from `/etc`.
Codex requests carry no Phase B headers, the picker is exactly Luna,
Codex and bare `ug` both run Luna, `ug claude` is rejected with no
inference request, and no Codex span is emitted while the Phase B span
proves the trace query works.
- Every phase: user prefs, MCP registrations, and skill files are
unchanged, and each agent's registered user MCP still starts and lists
its tool.
- `tests/e2e_cuj/helpers/constants.py`: the CUJ 6 metastore fixtures.
The Claude tracing keys come from
`ucode.agents.claude.CLAUDE_OTEL_TRACE_ENV_KEYS`.
- `tests/e2e_cuj/helpers/tui_request_recorder.py`: `retarget_session` is
public so a terminal configure can be retargeted to the recorder.

Known gaps (tracked in AIGTWY-4972):
- Managed skills are not covered: UC skill bundles can't be uploaded on
these workspaces' Default Storage catalog (Files API HTTP 501).

Validation: ruff check and format pass; related unit tests pass. Live:
`E2E CUJs` on this head passed 48 tests (CUJ 6's 28, plus CUJ 1, 2, 4,
and 5) in 11m36s:
https://github.com/databricks/unity-gateway/actions/runs/37567899055/job/112619786676

This pull request and its description were written by Isaac.

Co-authored-by: Isaac <no-reply@databricks.com>
Pzharyuk pushed a commit to Pzharyuk/unity-gateway that referenced this pull request Oct 8, 2026
## Summary

Fix `ug claude --model <id>` without a managed catalog by forwarding the
exact ID to Claude's native `--model`. Remove databricks#1004's catalog-gated
alias fallback, which could resolve to the OS-managed Opus default
instead. Keep selection launch-scoped and preserve family defaults,
model restrictions, and databricks#1004's URL fixes.

Merged current main and trimmed duplicate catalog permutations and
documentation. Production diff: **4 additions / 46 deletions**.
Regression coverage retains Claude/GPT IDs, both flag spellings, saved
settings, managed restrictions, and native argument precedence. The
existing live journey now covers both sides of UG's separator and checks
JSON `modelUsage`.

## Verification

- Focused Claude launch, CLI, smart-routing, managed
lifecycle/resolution, and integration-contract suites: **965 passed**,
one existing `forkpty` warning.
- The four CLI-to-launcher regression cases previously failed on
baseline `7deeaf7a`; all four pass with the fix.
- Ruff lint/format on `src/ tests/`, `ty check src/`, runner help, and
`git diff --check`: passed.
- Integration collection: **103 selected cases**, including all four
explicit-model variants. **Live inference not run locally.**
- Extended Ruff check on the unchanged `scripts/run_integration.py`
reports two existing TID251 violations (lines 212 and 242), reproduced
on current main. Left out of scope.


https://github.com/user-attachments/assets/7cf76aeb-06c0-41ec-88c4-0fa48186a913
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