[multi-team P3a] Parse and store the team catalog into UserWorkspaces - #15463
Merged
Conversation
Contributor
Author
|
This PR was generated with Warp. Comment |
warp-agent-staging
Bot
force-pushed
the
factory/multi-team-pr3a-catalog-team-scope
branch
2 times, most recently
from
August 23, 2026 04:32
fc2b37d to
84f9212
Compare
warp-agent-staging
Bot
force-pushed
the
factory/multi-team-pr3a-catalog-team-scope
branch
from
August 24, 2026 22:29
84f9212 to
49ca77f
Compare
warp-agent-staging Bot
added a commit
that referenced
this pull request
Aug 24, 2026
…metadata Rebuilds #15463 on top of master (its old base, #15461, was closed and absorbed into #15446). Partitions LLMPreferences' model catalog by team scope (models_by_team, keyed by team UID with None as the resolved-teamless scope) so every catalog accessor takes a TeamScope instead of reading one ambient, process-wide catalog. Replaces the standalone per-team catalog fetch (which called get_feature_model_choices() with no team and wrote the unscoped result into every team's bucket) with a fold into the existing polled workspaces-metadata query: get_workspaces_metadata_for_user now selects teams[].featureModelChoice for the per-team map, plus the existing workspace-level featureModelChoice for the resolved-teamless case. Both halves arrive on one response, replacing the broken standalone fetch. Trigger disposition: - UserWorkspacesEvent::TeamsChanged no longer triggers a catalog refetch (a workspaces response landing now already carries the catalog); it still runs local custom-model-preference sanitization. - Network-online and AuthComplete no longer trigger a separate catalog fetch: TeamUpdateManager already restarts its poll on network online, and login already kicks off the poller's first tick before AuthComplete fires. - The two ai/blocklist/controller.rs mid-conversation refresh triggers are kept as a narrow, single-scope standalone refresh. Deletes the TODO in llms.rs that asked for exactly this change.
warp-agent-staging
Bot
changed the base branch from
factory/multi-team-p1b-llms-migration
to
master
August 24, 2026 22:29
Contributor
Author
|
Converting back to draft — under revision following review (eval-build fix plus four blocking findings). Will mark ready again once addressed and CI is green. |
Contributor
Author
|
@IsaiahWitzke one question for you while this is under revision: the review wants visual proof of two teams resolving different catalogs before merge. That needs a staging account whose teams have genuinely different Responding as wilson: Open session · View in factory |
warp-agent-staging Bot
added a commit
that referenced
this pull request
Aug 26, 2026
…old changes Reduces this PR to PR 1 of a two-PR stack: the model catalog keyed by team (models_by_team, ResolvedTeamScope, the scoped models_by_feature family and its call sites), the fold into the workspaces-metadata query (apply_feature_model_choices, pruning, leave_team), the GraphQL query/schema, the two blocklist refresh triggers rerouted off the unscoped get_feature_model_choices, and the two-team distinctness/ pruning/conversion-level tests. PR 2 (stacked on this branch) adds get_llm_info_for_scope/for_team_uid and threads live TeamScope through the AIExecutionProfileAppExt context-window helpers and RequestParams's request-limit clamp.
2 tasks
warp-agent-staging
Bot
force-pushed
the
factory/multi-team-pr3a-catalog-team-scope
branch
from
August 26, 2026 04:56
f1246dc to
1d8e82a
Compare
2 tasks
Adds Team.feature_model_choice and Workspace.feature_model_choice, sourced from the server's per-team/workspace Team.featureModelChoice (new teams[].featureModelChoice query field, schema mirror line) and the existing Workspace.featureModelChoice, via gql_convert's new feature_model_choice_from_gql. Persisted through new feature_model_choice_json sqlite columns (migration included) so the warm-start cache round-trips it too. Nothing reads this yet -- LLMPreferences keeps master's flat models_by_feature and behaves exactly as today. This PR is inert by design: dead data plus a conversion test (team_feature_model_choices_conversion_keeps_each_teams_choice_distinct) proving each team keeps its own payload through the fold.
warp-agent-staging
Bot
force-pushed
the
factory/multi-team-pr3a-catalog-team-scope
branch
from
August 26, 2026 06:02
1d8e82a to
fc3d9d1
Compare
This was referenced Aug 26, 2026
IsaiahWitzke
approved these changes
Aug 26, 2026
IsaiahWitzke
enabled auto-merge (squash)
August 26, 2026 15:53
… home (#15565) ## Description Stacked on #15463 (PR 1 of the three-PR stack — "Parse and store the team catalog into UserWorkspaces"). PR 1 added `Team`/`Workspace.feature_model_choice` but nothing populates it for a user restored from a pre-upgrade SQLite cache. PR 3 (to follow, stacked on this branch) moves `LLMPreferences` off its flat catalog onto these fields; this PR makes sure a warm-started, pre-upgrade cache has something real to read once that happens. Seeds `Team`/`Workspace.feature_model_choice` from the legacy, pre-team-keyed `MODELS_BY_FEATURE_CACHE_KEY` cache as a one-release migration in `UserWorkspaces::new`: a `Workspace` restored from the SQLite cache predates the `feature_model_choice` column (or the app hasn't fetched since upgrading), so its catalog is still the bare default. This seeds it from the last-known model list instead, so an offline launch right after upgrading isn't stuck on just the `auto` default for the rest of the offline session. `migrate_legacy_feature_model_choices_cache` understands both real shapes an older client could have written: the (more recent) single `ModelsByFeature`, and (older still) a bare `AvailableLLMs`, which becomes the `agent_mode` field. Still nothing reads `Team`/`Workspace.feature_model_choice` for model selection — `LLMPreferences` keeps master's flat `models_by_feature`. `legacy_cache_migration_yields_a_usable_teamless_catalog` proves the older bare-`AvailableLLMs` shape migrates to a catalog whose `agent_mode` bucket resolves the cached model. ## Testing - `cargo check --workspace --all-targets` — clean. - `cargo clippy -p warp --lib --tests -- -D warnings` — clean. - `./script/format` — clean. - `./script/bundle --channel oss --nouniversal --check-only` — clean. - `cargo clippy --locked --target wasm32-unknown-unknown --profile release-wasm-debug_assertions -- -D warnings` — clean. - `cargo nextest run -p warp -E 'test(user_workspaces) or test(legacy_cache) or test(gql_convert)'` — 107 passed. - No UI surface changed; this is a data-layer change, so no screenshots. - This branch is stacked on a non-default base, so it does not get a real CI matrix in this repo; the above was run locally on this exact branch tip. ## Linked Issue - [x] N/A — stacked continuation of #15463. ## Agent Mode - [x] Warp Agent Mode - This PR was created via Warp's AI Agent Mode --------- Co-authored-by: warp-agent-staging[bot] <240773466+warp-agent-staging[bot]@users.noreply.github.com> Co-authored-by: Oz <oz-agent@warp.dev>
IsaiahWitzke
disabled auto-merge
August 26, 2026 16:43
IsaiahWitzke
enabled auto-merge (squash)
August 26, 2026 16:43
tylerlam-warp
added a commit
that referenced
this pull request
Aug 27, 2026
…orkspace (#15567) ## Description Stacked on #15565 (PR 2), which is stacked on #15463 (PR 1). This is the third and final PR of the stack: it deletes `LLMPreferences`'s flat, non-team-aware `models_by_feature` field and its `MODELS_BY_FEATURE_CACHE_KEY` read/write, and the old `WorkspacesMetadataResponse.feature_model_choices` field PR 1 deliberately left alone. Every accessor now reads through `UserWorkspaces` instead, resolved against a caller-supplied `TeamScope` (or a raw team uid). - `UserWorkspaces` gains `feature_model_choice_for_scope`/`_for_team_uid` (reads, via the same `scoped_or_workspace_setting` pattern every other team-scoped setting uses; the absent/no-workspace-at-all case falls back to the resolved-teamless `pre_login_models_by_feature` seeded by PR 1/PR 2's migration or a pre-login fetch) and `set_feature_model_choice_for_team_uid` (the narrow one-off authed-refresh write path). - `get_llm_info`/`_for_team_uid`/`_for_scope`, `get_active_base_model`, and the various choice/default getters gained an app/ctx parameter and a `TeamScope` parameter accordingly, with the ~85 call sites across the app updated: `terminal/`, `settings_view/`, `ai/blocklist/`, `ai/agent_sdk/`, `pane_group/`, `search/`, `workspace/`, and `crates/warp_tui/`. - Preserves the earlier review-round behavioral fixes carried since PR 1's first draft: teamless eager fetch for `agent_mode_evals` builds, refresh-through-workspace-metadata (not the unscoped `get_feature_model_choices`) for blocklist triggers, cross-team `get_llm_info` display lookups, and stale-bucket eviction (implied by the wholesale `Team`/`Workspace` replacement on every response). This is the bulk of the three-PR stack by line count, but every design decision here — the storage shape, the legacy-cache conversion — was already reviewed in PR 1 and PR 2; this should read as fan-out from those two, not new design. ### Note on ancestry This branch's only ancestors beyond `master` are PR 1's and PR 2's commits — verified with `git merge-base --is-ancestor` in both directions before pushing, since a three-deep stack is easy to get backwards. ## Testing Since this branch is stacked on a non-default base, it does not get a real CI matrix in this repo (only PR 1 does); all of the below was run locally on this exact branch tip: - `cargo check --workspace --all-targets` — clean. - `cargo clippy -p warp --lib --tests -- -D warnings` — clean. - `./script/format` — clean (2 files needed reformatting, included). - `./script/bundle --channel oss --nouniversal --check-only` — clean. - `cargo clippy --locked --target wasm32-unknown-unknown --profile release-wasm-debug_assertions -- -D warnings` — clean (no dead-code-on-wasm surprises from the call-site fan-out). - `cargo nextest run -p warp -E 'test(llms) or test(execution_profile) or test(update_manager) or test(gql_convert) or test(user_workspaces) or test(profile_model_selector) or test(agent_profiles_page) or test(legacy_cache)'` — 262 passed. - `cargo nextest run --workspace -E 'package(warp_tui) and (test(terminal_session_view) or test(model_menu))'` — 187 passed. - No UI surface changed; this is a data-layer change, so no screenshots. ## Linked Issue - [x] N/A — stacked continuation of #15463 and #15565. ## Agent Mode - [x] Warp Agent Mode - This PR was created via Warp's AI Agent Mode --------- Co-authored-by: warp-agent-staging[bot] <240773466+warp-agent-staging[bot]@users.noreply.github.com> Co-authored-by: Oz <oz-agent@warp.dev> Co-authored-by: Tyler Lam <tyler.lam@warp.dev> Co-authored-by: Warp <agent@warp.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Description
Parses and stores the per-team/workspace model catalog into
UserWorkspaces. Nothing reads it.LLMPreferencesis untouched: it keepsmaster's flatmodels_by_featureand behaves exactly as today. This PR is inert by design — dead data plus a conversion test.Team/Workspacegain afeature_model_choice: ModelsByFeaturefield.crates/graphql'sget_workspaces_metadata_for_userquery gainsteams[].featureModelChoice(the workspace-levelfeatureModelChoicealready existed), with the matching schema mirror line.gql_convert::feature_model_choice_from_gqlconverts the server payload; a malformed catalog is reported and falls back toModelsByFeature::default()rather than failing the wholeTeam/Workspaceconversion.feature_model_choice_jsonsqlite columns (migration included) persist it through the warm-start cache, so the round trip works before any reader exists.team_feature_model_choices_conversion_keeps_each_teams_choice_distinctproves each team's uid maps to its own catalog payload, never a shared or swapped one.Testing
cargo check --workspace --all-targets— clean.cargo clippy -p warp --lib --tests -- -D warnings— clean../script/format— clean (no changes)../script/bundle --channel oss --nouniversal --check-only— clean.cargo clippy --locked --target wasm32-unknown-unknown --profile release-wasm-debug_assertions -- -D warnings— clean.cargo nextest run -p warp -E 'test(gql_convert) or test(user_workspaces) or test(update_manager) or test(team_feature_model_choices)'— 182 passed.Linked Issue
Agent Mode