Skip to content

Improve endpoint model setup UX#778

Merged
FuJacob merged 1 commit into
mainfrom
codex/endpoint-settings-ux
Jul 11, 2026
Merged

Improve endpoint model setup UX#778
FuJacob merged 1 commit into
mainfrom
codex/endpoint-settings-ux

Conversation

@FuJacob

@FuJacob FuJacob commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

Simplify Local Endpoint setup by keeping one always-visible model control, automatically selecting a stable discovered model, and presenting the API format explicitly. Fix the underlying state bug where choosing a model or API format cleared the discovered catalog and reset the connection to Not connected.

The settings UI also removes duplicate SwiftUI field labels, keeps manual model entry available, shows compact inline connection feedback, and updates settings-search terminology.

Validation

  • xcodebuild -project Cotabby.xcodeproj -scheme Cotabby -destination platform=macOS test -derivedDataPath build/DerivedData CODE_SIGNING_ALLOWED=NO
    • TEST SUCCEEDED — 1,688 tests, 7 skipped, 0 failures
  • xcodebuild -project Cotabby.xcodeproj -scheme Cotabby -destination platform=macOS build-for-testing -derivedDataPath build/DerivedData CODE_SIGNING_ALLOWED=NO
    • TEST BUILD SUCCEEDED
  • swiftlint --strict
    • 0 violations in 249 files

Linked issues

No linked issue.

Risk / rollout notes

When discovery returns models and the saved selection is missing or stale, Cotabby now chooses the alphabetically first discovered model. A manual identifier is preserved when the endpoint returns an empty catalog. No settings migration is required.

Greptile Summary

This PR improves the OpenAI-compatible endpoint setup flow. The main changes are:

  • Keeps the endpoint catalog connected while model and API format change.
  • Adds a resolver for choosing a discovered model after refresh.
  • Reworks the settings pane into one manual model field with a discovered-model menu.
  • Renames endpoint settings search text around Server URL and API Format.
  • Adds tests for model selection resolver behavior.

Confidence Score: 4/5

The endpoint setup flow has one persisted-model selection bug to fix before merging.

  • A non-empty manual model can be replaced by the first discovered model after refresh.
  • The UI refactor and connection-state changes otherwise keep the same settings bindings and request-time configuration flow.
  • No security issue was found in the changed code.

Cotabby/Models/OpenAICompatibleEndpointModels.swift

Important Files Changed

Filename Overview
Cotabby/App/Core/CotabbyAppEnvironment.swift Stops invalidating endpoint discovery for model and API-format edits; generation still reads current settings at request time.
Cotabby/Models/OpenAICompatibleEndpointModels.swift Adds model selection reconciliation, but the fallback can overwrite manual model IDs that are absent from a non-empty catalog.
Cotabby/UI/Settings/Panes/EngineAndModelPaneView.swift Refactors endpoint settings UI and persists resolver output after refresh.
Cotabby/UI/Settings/SettingsIndex.swift Updates endpoint settings labels, descriptions, and search keywords.
CotabbyTests/OpenAICompatibleAPIClientTests.swift Adds resolver tests for empty, preserved, stale, and empty-catalog selections.

Fix All in Codex Fix All in Claude Code

Reviews (1): Last reviewed commit: "Improve endpoint model setup UX" | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

@FuJacob FuJacob marked this pull request as ready for review July 11, 2026 00:14
@FuJacob FuJacob merged commit 0a47f3f into main Jul 11, 2026
4 checks passed
return matchingModel.id
}

return firstModel.id

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Manual Model Gets Overwritten

When a user has a non-empty manual model that is not returned by /models, this fallback returns the first discovered model and refreshEndpointModels() persists it. Servers can return a filtered catalog while still accepting hidden model IDs, so opening the pane or pressing Refresh can silently move future completions to a different model.

Suggested change
return firstModel.id
return current.isEmpty ? firstModel.id : nil

Fix in Codex Fix in Claude Code

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.

1 participant