fix: seed inference profiles only for configured providers#3440
Conversation
Default inference profiles were seeded unconditionally at startup, filling the profile picker with entries for providers that were never set up. - gate ProfileSeedingService.seedDefaults() per provider type: a default profile is only created once a usable provider of its type exists (non-blank API key, or non-blank base URL for keyless local providers) - re-run seeding after provider create/update and after FTUE setup so the profile appears the moment a provider becomes usable, including during onboarding where categories bind to the profile right after the key step - add removeOrphanedDefaultSeeds() startup pass that deletes untouched default seeds whose provider type has no usable provider; renamed, described, pinned, or rewired profiles are always preserved
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAI inference profiles are now seeded only when matching providers are usable. Startup removes untouched orphaned defaults, while provider saves, updates, and FTUE setup trigger seeding and upgrades. Tests and documentation cover the new lifecycle. ChangesAI profile seeding lifecycle
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant App as App startup
participant ProviderForm as Provider configuration
participant FTUE as FTUE setup
participant Seeding as ProfileSeedingService
participant Repository as Config repository
App->>Seeding: seedDefaults()
Seeding->>Repository: Read provider and model rows
Seeding->>Repository: Save eligible profiles
App->>Seeding: removeOrphanedDefaultSeeds()
Seeding->>Repository: Delete untouched orphaned seeds
ProviderForm->>Seeding: seedDefaults() after save/update
FTUE->>Seeding: seedDefaults() after setup
Seeding->>Repository: Upgrade existing profiles
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
Code Review
This pull request gates the seeding of default AI inference profiles so they only appear once a usable provider of the matching type is configured. It also introduces a cleanup routine to retroactively remove untouched default profiles whose providers are no longer present or usable. The review feedback suggests optimizing the orphaned seed cleanup pass by pre-building a set of usable model IDs, which reduces the lookup complexity from
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3440 +/- ##
=======================================
Coverage 99.26% 99.26%
=======================================
Files 1732 1732
Lines 124600 124661 +61
=======================================
+ Hits 123685 123746 +61
Misses 915 915
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
test/features/ai/util/profile_seeding_service_test.dart (1)
528-571: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winCover whitespace-only credentials in the provider gate tests.
The contract requires non-blank values, but empty-string cases would still pass if usability incorrectly used
isNotEmptywithout trimming.Proposed regression test
+ test('whitespace-only credentials do not open provider gates', () async { + when( + () => mockRepo.getConfigsByType(AiConfigType.inferenceProvider), + ).thenAnswer( + (_) async => [ + AiTestDataFactory.createTestProvider( + id: 'melious-blank', + type: InferenceProviderType.melious, + apiKey: ' ', + ), + AiTestDataFactory.createTestProvider( + id: 'ollama-blank', + type: InferenceProviderType.ollama, + apiKey: '', + baseUrl: ' ', + ), + ], + ); + + await service.seedDefaults(); + + verifyNever(() => mockRepo.saveConfig(any())); + });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/features/ai/util/profile_seeding_service_test.dart` around lines 528 - 571, Extend the provider gate tests around service.seedDefaults to include whitespace-only API credentials, especially the draft provider case and any local-provider credential checks. Assert that whitespace-only values are treated as blank and do not open the gate, preserving the existing behavior for genuinely usable providers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/features/ai/state/settings/inference_provider_form_controller.dart`:
- Around line 280-287: Update handleSave() so seedDefaults() and
upgradeExisting() are each wrapped in local best-effort error handling after the
provider save succeeds. Catch and log failures for both calls without
rethrowing, allowing successful addConfig()/updateConfig() saves to continue to
navigation instead of triggering the generic error toast.
---
Nitpick comments:
In `@test/features/ai/util/profile_seeding_service_test.dart`:
- Around line 528-571: Extend the provider gate tests around
service.seedDefaults to include whitespace-only API credentials, especially the
draft provider case and any local-provider credential checks. Assert that
whitespace-only values are treated as blank and do not open the gate, preserving
the existing behavior for genuinely usable providers.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 02bbf202-3536-488a-8887-15dbd8db7e55
📒 Files selected for processing (12)
CHANGELOG.mdflatpak/com.matthiasn.lotti.metainfo.xmllib/features/ai/README.mdlib/features/ai/state/ai_config_initialization.dartlib/features/ai/state/settings/inference_provider_form_controller.dartlib/features/ai/ui/settings/inference_provider_edit_page.dartlib/features/ai/ui/settings/services/alibaba_ftue_setup.dartlib/features/ai/util/profile_seeding_service.dartlib/features/onboarding/README.mdtest/features/ai/state/ai_config_initialization_test.darttest/features/ai/state/settings/inference_provider_form_controller_test.darttest/features/ai/util/profile_seeding_service_test.dart
- build the set of usable model slot values once in removeOrphanedDefaultSeeds() instead of scanning all model rows per profile slot, and drop the per-slot helper (Gemini review) - make post-save profile seeding best-effort in the provider form controller: the provider row is already persisted, so a seeding failure must not surface an error toast for a successful save (CodeRabbit)
Summary
Default inference profiles were seeded unconditionally at startup, so the profile picker filled up with entries for providers that were never set up (Chinese AI Profile, Mistral (EU), etc.). This PR gates seeding on provider setup and cleans up the leftovers:
ProfileSeedingService.seedDefaults()now maps every default profile template to a provider type (providerTypeByProfileId) and only seeds a profile once a usable provider of that type exists (non-blank API key, or non-blank base URL for keyless local providers). A fresh install starts with zero profiles; connecting Melious.ai seeds exactly the one Melious profile.addConfig), update (updateConfig, e.g. pasting an API key into a draft), and FTUE setup (runFtueSetupForType) — onboarding binds its categories to the profile right after the key step, so the profile must exist by then.removeOrphanedDefaultSeeds()startup pass (afterupgradeExisting()) deletes default seeds whose provider type has no usable provider — existing installs shed the never-configured profiles, and deleting a provider retires its untouched profile on next launch. Deliberately conservative: only rows still recognizable as untouched seeds (template name/flags, no description, no pinned host) with no model slot resolving to a usable provider's model row are removed; anything renamed, described, pinned, or rewired survives.Docs updated (AI + onboarding feature READMEs, stale FTUE doc comment), CHANGELOG + flatpak metainfo entry under 0.9.1037.
Test plan
dart analyzeclean onlib/features/ai,lib/features/onboarding, and their tests.test/features/ai/util,test/features/ai/state,test/features/ai/ui/settings(841),test/features/onboarding(~250),test/features/agents/state/agent_providers_test.dart.lib/is hit by the test suite.Summary by CodeRabbit