Skip to content

oxmux: Add model registry listing#44

Merged
nodnarbnitram merged 6 commits intomainfrom
add-oxmux-model-registry-listing
May 6, 2026
Merged

oxmux: Add model registry listing#44
nodnarbnitram merged 6 commits intomainfrom
add-oxmux-model-registry-listing

Conversation

@nodnarbnitram
Copy link
Copy Markdown
Contributor

@nodnarbnitram nodnarbnitram commented May 3, 2026

🔗 Linked Issue

Closes #26

✅ Type of Change

  • ✨ New Project/Feature
  • 🐞 Bug Fix
  • 📚 Documentation Update
  • 🔨 Refactor or Other

📝 Summary

  • Adds a headless oxmux model registry API for typed model identities, aliases, forks, provider/account applicability, capabilities, and disabled/degraded/unknown listing states.
  • Provides deterministic builders from routing policy and validated file configuration, plus a minimal OpenAI-compatible model-list projection without wiring an HTTP route.
  • Adds model registry and dependency-boundary tests covering deterministic listing, filters, aliases/forks, file-backed disabled/degraded metadata, fallback metadata, and unknown accounts.

📐 OpenSpec Evidence

  • OpenSpec change/spec: openspec/changes/add-oxmux-model-registry-listing
  • No OpenSpec required: N/A
  • Vision/boundary impact: Preserves oxmux as the shared headless owner for model registry/listing semantics while keeping oxidemux, GPUI, provider SDKs, OAuth, credential storage, live provider discovery, and outbound network behavior out of scope.

📖 Documentation Checklist

  • I updated README.md, CONTRIBUTING.md, or OpenSpec docs when needed.
  • I updated CHANGELOG.md for notable user-facing, compatibility, security, or workflow changes, or explained why it was not applicable.
    • Changelog not applicable: this is pre-release core API groundwork tracked by OpenSpec, with no user-facing release note yet.

✔️ Contributor Checklist

  • My code follows the project's coding standards.
  • I have added a .env.example file if environment variables are needed and ensured no secrets are committed.
    • Not applicable: no environment variables or secrets were added.
  • My pull request is focused on a single project or change.
  • I preserved the oxmux shared-core and oxidemux platform-shell boundary, or documented the OpenSpec-approved reason for changing it.
  • I ran mise run ci locally, or explained why it was not applicable.
  • I ran mise run security locally for dependency policy and vulnerability changes, or explained why it was not applicable.
    • Not applicable: no dependency or vulnerability-policy changes were made.
  • I ran relevant hk checks with mise run hk-check, or explained why they were not applicable.
    • Not applicable: mise run ci covered formatting, checking, clippy, tests, and docs for this code-only change.

💬 Additional Comments

Verification run locally:

  • openspec validate add-oxmux-model-registry-listing --strict
  • cargo fmt --all --check
  • cargo test -p oxmux
  • mise run ci
  • LSP diagnostics on modified Rust files: clean
  • Oracle review findings addressed before commit

Release Notes:

  • N/A

View in Codesmith
Need help on this PR? Tag @codesmith with what you need.

  • Let Codesmith autofix CI failures and bot reviews

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 3, 2026

Greptile Summary

This PR adds a headless model_registry module to oxmux that assembles routing policy, provider summaries, and file-backed configuration into a deterministic typed model catalog — covering aliases, forks, provider/account applicability, capability metadata, and disabled/degraded/unknown listing states — plus a minimal OpenAI-compatible projection. No network calls, provider SDKs, or app-shell dependencies are introduced.

  • New ModelRegistry type with four deterministic builders and listing filters for all-configured, visible, disabled, and degraded entries.
  • OpenAI-compatible projection (OpenAiModelListProjection) derived from visible registry entries, scoped as a future /v1/models serialization surface with a static created: 0 placeholder.
  • Comprehensive integration tests covering alias/fork preservation, availability metadata, filter semantics, file-backed registry construction, and a dependency-boundary scan confirming no app-shell or async-runtime imports.

Confidence Score: 4/5

Safe to merge with low risk; the registry is headless and does not touch existing routing or proxy paths.

The core logic is well-structured and thoroughly tested. One completeness gap exists in listing_state_for: when the availability snapshot reports Degraded, static provider.degraded_reasons and account.degraded_reasons are not merged into the resulting ModelListingState::Degraded.reasons, potentially hiding relevant context from listing consumers. The existing test sets up exactly this combination but only checks the variant, not the reasons list.

The listing_state_for function in crates/oxmux/src/model_registry.rs and the corresponding test in crates/oxmux/tests/model_registry.rs for the availability-degraded + static-degraded combination.

Important Files Changed

Filename Overview
crates/oxmux/src/model_registry.rs New headless model registry module; core logic is sound. One completeness gap: static provider/account degraded reasons are not merged into the Degraded listing state when the availability snapshot is also Degraded.
crates/oxmux/src/oxmux.rs Adds model_registry module declaration and re-exports all new public types; straightforward facade update.
crates/oxmux/tests/model_registry.rs Comprehensive integration tests for registry construction, filters, aliases, forks, and availability metadata; one test exercises combined static+dynamic degraded reasons but does not assert the merged reasons list.
crates/oxmux/tests/dependency_boundary.rs Adds a source-text scan confirming model_registry.rs carries no app-shell or runtime imports; straightforward boundary guard.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    RP[RoutingPolicy\nroutes + aliases]
    VFC[ValidatedFileConfiguration\nrouting_default_groups]
    PS[ProviderSummary\ncapabilities + accounts]
    RAS[RoutingAvailabilitySnapshot\noptional]

    RP --> FP[from_policy_with_availability]
    VFC --> FF[from_file_configuration_with_availability]
    PS --> FP
    PS --> FF
    RAS -->|optional| FP
    RAS -->|optional| FF

    FP --> MR[ModelRegistry\nentries: Vec]
    FF --> MR

    MR --> AE[all_entries]
    MR --> VE[visible_entries\nAvailable or Degraded]
    MR --> DE[disabled_entries\nDisabled / RoutingIneligible / UnknownProvider / UnknownAccount]
    MR --> GE[degraded_entries\nDegraded]
    MR --> OAI[open_ai_model_list\nOpenAiModelListProjection]

    MR --> MRE[ModelRegistryEntry\nidentity + alias + fork + candidates]
    MRE --> MRC[ModelRegistryCandidate\nnative_target + applicability + capabilities + listing_state]

    MRC --> LS{listing_state_for}
    LS -->|provider missing| UP[UnknownProvider]
    LS -->|account missing| UA[UnknownAccount]
    LS -->|routing_eligible=false| RI[RoutingIneligible]
    LS -->|availability Unavailable/Exhausted| DIS[Disabled]
    LS -->|availability Degraded| DG[Degraded]
    LS -->|static reasons empty| AV[Available]
    LS -->|static reasons present| DG
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
crates/oxmux/src/model_registry.rs:660-665
**Static degraded reasons silently dropped when availability is `Degraded`**

When the availability snapshot reports `RoutingAvailabilityState::Degraded`, `listing_state_for` creates a `ModelListingState::Degraded` with only the availability-derived reason, discarding any static `provider.degraded_reasons` or `account.degraded_reasons` that were set on the provider summary. By contrast, when the snapshot reports `Available`, the code correctly calls `degraded_or_available`, which merges both static layers.

This means a provider that has both a static quota-pressure warning (in `provider.degraded_reasons`) and a live-degraded signal from the snapshot will expose only the live reason. The test in `availability_metadata_marks_disabled_and_degraded_without_selecting_route` exercises this exact combination (`account.with_degraded("account", "reduced quota")` + `Degraded { "limited capacity" }`), but only asserts the variant, not the reasons list, so the gap is not caught.

Reviews (2): Last reviewed commit: "oxmux: Fix model registry account applic..." | Re-trigger Greptile

Comment thread crates/oxmux/src/model_registry.rs Outdated
Comment thread crates/oxmux/src/model_registry.rs
@nodnarbnitram nodnarbnitram merged commit eef17c9 into main May 6, 2026
5 checks passed
@nodnarbnitram nodnarbnitram deleted the add-oxmux-model-registry-listing branch May 6, 2026 19:58
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 oxmux model registry and listing contract

1 participant