feat(ai): AI setup UX: empty-state entry, lean newest-first model lists, Test connection, retired cleanup, sync status - #1818
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (25)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying quickadd with
|
| Latest commit: |
eb05aca
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://9533eb5f.quickadd.pages.dev |
| Branch Preview URL: | https://feat-ai-setup-ux.quickadd.pages.dev |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 20de4af608
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
7a0e272 to
4231bb7
Compare
|
Macroscope's four findings (retired cleanup scope, provider identity, empty error message, delete after a concurrent sync) are covered by the Cursor Agent commit 7a0e272. I had fixed the same four independently, and my regression tests for them also pass against that commit, so I kept it and dropped my duplicate. |
f7c926f to
4231bb7
Compare
|
Reverted the branch to 4231bb7 (force-push). That drops the concurrency fixes added after it (Cursor Agent commits 75f2f49, 298b302, 50a9265, 47148ca, b47fd85 and f7c926f) and my follow-up to them. None of those races had been reproduced in Obsidian: each one needs an edit or a click during a sub-second request, and the fixes kept adding fingerprints and generation counters to the providers modal, which drew new findings each round. My reply that cites a2643f05 is void; that commit never reached the branch. The validated fixes stay: the CLI seam ( |
The AI Assistant button lived only in the choice list's bottom bar, which the "No choices yet" state does not render, so a new vault had no way into AI settings. The empty state now shows a Configure AI Assistant button while AI and online features are on. Amp-Thread-ID: https://ampcode.com/threads/T-01a0df48-9e0d-75cc-af45-26ec84217b88 Co-authored-by: Christian Bager Bach Houmann <christian@bagerbach.com>
Syncs imported every directory entry, so the OpenAI list grew to 42 models in no useful order, including retired, pinned-snapshot, and realtime models: - Models now carry releaseDate and a deprecated flag from models.dev. - Syncs never add a model the directory marks deprecated, but they do flag one the user already has. - Dated snapshots (gpt-4o-2024-11-20) are dropped when their undated id is listed. - Realtime models are filtered on the models.dev path too; gpt-realtime-2.1 returns 404 "not a chat model" live. - Each sync records lastModelSync (time, or the error) on the provider. sortModelsForDisplay orders the model dropdown and the "Ask me" picker newest first, with undated (hand-added) models next and retired ones last, labelled as retired. Stored order is unchanged. Amp-Thread-ID: https://ampcode.com/threads/T-01a0df48-9e0d-75cc-af45-26ec84217b88 Co-authored-by: Christian Bager Bach Houmann <christian@bagerbach.com>
…ction test, and sync status In the provider edit view: - The model list is newest first and has a filter box. - Deletion works by model identity, not display index. - Retired models are badged, and "Remove retired models (N)" clears them. Cancel still restores them. - Test connection asks the provider's own models endpoint with the linked key, even for a models.dev-sourced provider, and shows the model count or the provider's error. - A status line under Auto-sync shows when the provider last synced or why the last sync failed, including quiet background failures. The test stub gains Setting.addSearch and Element.setText. Amp-Thread-ID: https://ampcode.com/threads/T-01a0df48-9e0d-75cc-af45-26ec84217b88 Co-authored-by: Christian Bager Bach Houmann <christian@bagerbach.com>
… sync status Amp-Thread-ID: https://ampcode.com/threads/T-01a0df48-9e0d-75cc-af45-26ec84217b88 Co-authored-by: Christian Bager Bach Houmann <christian@bagerbach.com>
Key auto-sync merge by provider id so duplicate name+endpoint accounts do not share lastModelSync. Store a nonempty failure message when Error.message is empty. Delete and Remove-retired act on the confirmed model names, not live object identity or the live deprecated set. Co-authored-by: Christian Bager Bach Houmann <christian@bagerbach.com>
…status Review follow-ups: - Test connection now lives in src/ai/providerConnection.ts. The settings button and a new `quickadd:ai-test-connection provider=<id|name>` CLI command both call it, which gives the check a CLI-verifiable seam (per AGENTS.md). The result reports whether a key is linked, never the key. - Changing a provider's endpoint, linked key, type, or model source clears its last-sync status and connection result, because they described the old configuration. Cancel restores both. Amp-Thread-ID: https://ampcode.com/threads/T-01a0df48-9e0d-75cc-af45-26ec84217b88 Co-authored-by: Christian Bager Bach Houmann <christian@bagerbach.com>
4231bb7 to
eb05aca
Compare
Summary
These are the AI setup UX items from the review of #1811. A fresh user can now reach AI settings, the synced model lists are shorter and ordered usefully, keys can be checked in place, and sync state is visible.
releaseDateand adeprecatedflag from models.dev.gpt-4o-2024-11-20) are dropped when the undated id is listed.gpt-realtime-2.1returns 404 "not a chat model" on Chat Completions live.quickadd:ai-test-connection provider=<id|name>, which returns{ok, modelCount | error, apiKeyLinked}and never the key.lastModelSyncon the provider. A line under Auto-sync shows "Last synced 5 minutes ago · 29 model(s)." or "Last sync failed …: ". Background failures used to be visible only in the log. Changing the endpoint, linked key, type, or model source clears the status and the connection result, because they described the old configuration; Cancel restores both.Evidence (Obsidian 1.13.7, isolated e2e vault with made-up content, fresh install, online features on)
Empty state, before on
masterand after on this branch:Provider edit view after the on-open sync, reached through that button:
Test connection with the real key linked from SecretStorage. Only the result text is shown:
Same check through the CLI (key-occurrence count taken with
grep -cFon the output):Editing the endpoint in Obsidian:
{"before":{"status":"Last synced just now · 29 model(s).","conn":"✓ Connected. The provider lists 64 model(s)."},"after":{"status":"Not synced yet.","conn":""}}A key linked through the UI persists to
data.jsonafter closing the dialogs with Escape, via both the empty-state button and the bar button, whether the dialogs open immediately after reload or 10 s later. I checked this because the new code runs around the settings writes.dev:errors: no errors captured.Tests
New tests, each aimed at a plausible wrong implementation:
ChoiceView.aiEntry.test.ts: the empty state shows the button with online features on and hides it with them off. It fails onmaster.AIAssistantProvidersModal.ux.test.ts(7 tests): newest-first display without reordering storage; delete removes the clicked row even when the stored index differs (fails with index-based delete); filter; retired cleanup plus Cancel; Test connection usesproviderApieven for a models.dev provider (fails without the override); connection error text; status line for a failed background sync and a successful Sync now.modelsDirectory.test.ts: snapshot dropping keeps a lone snapshot and version numbers;deprecatedis set only when true; a sync merge never adds deprecated models but flags existing ones, while an explicit import can still add one; realtime filtering.modelSyncService.test.ts: a failed background sync is recorded without touching models; deprecated models are never added by auto-sync; success recordslastModelSync; results are keyed by provider id; an empty error message is still recorded as a failure.aiConnectionCli.test.ts: selection by id or name (case-insensitive), the providerApi override, the error path, unknown and missing selectors, and a check that the result never contains the key.AIAssistantProvidersModal.ux.test.ts: delete and retired cleanup act on what the user confirmed, even when a sync lands mid-prompt; a connection-affecting edit clears the stale status and Cancel restores it.Provider.test.ts(sortModelsForDisplay) andsyncStatus.test.ts(time-unit boundaries, clock skew).Decisions to veto
gpt-5.6are not collapsed. No metadata links an alias to its target, and guessing by name would be wrong in general.deprecated: falseon every model.Release / migration impact
This is a
feat:release with no migration. New optional fields are persisted:Model.releaseDate,Model.deprecated, andAIProvider.lastModelSync. Existing lists gain the metadata on their next sync, so the first "Sync now" after upgrading reports existing models as "updated" once. The test stub gainsSetting.addSearchandElement.setText. Adds a CLI command,quickadd:ai-test-connection. Docs are updated inAIAssistant.md.Follow-ups split out from the same list: the Responses API for OpenAI tool turns merged as #1816; the models.dev disk cache with ETag merged as #1817. Moving provider editing to a settings sub-page waits for this PR to merge.
Note
Add AI setup UX: empty-state entry, newest-first model lists, Test connection, sync status
sortModelsForDisplayin Provider.ts anddropDatedSnapshotsin modelsDirectory.ts.lastModelSync(syncProviderModelsin modelSyncService.ts), never newly adds deprecated models, preserves existing models on failure, and displays relative-time sync status in the providers modal.NON_CHAT_MODEL_ID_REfilter now also excludes realtime and audio endpoint model ids.Macroscope summarized eb05aca.