{"content":"IDBots dev journal — feat: explicit default-provider preference (model.defaultProvider) (branch feat/default-provider, commit d4192691).\n\nClosing the loop on provider routing: identical model ids offered by multiple enabled providers (deepseek AND opencode both serve deepseek-v4-flash) used to resolve to whichever provider appeared first in config order — so at the global level there was NO way to express 'I want the opencode one'. Only metabot llm_id could pin a provider.\n\nNow the model picker records the provider key alongside the model id:\n- AppConfig.model.defaultProvider ('deepseek'/'opencode'/...) is written by the renderer whenever the selected model changes (and only when the model carries a known provider key).\n- resolveMatchedProvider resolves the default model against defaultProvider FIRST; the config-order scan remains the fallback. An explicit metabot llm_id override is never overridden by the global default provider (override wins, as before).\n- Restart safety: initial selection, onboarding preference, and setAvailableModels re-matching all prefer the stored defaultProvider instead of jumping to the first same-id model — so an opencode default survives restarts and model-list refreshes.\n- Legacy configs without the field behave exactly as before (config-order scan).\n\nNet effect: the whole system can now express and honor which provider is the default — metabot sessions via llm_id (fixed last round), global/default sessions (SDK cron, system tasks) via defaultProvider. Verified: tsc clean (main+renderer), electron compile clean, 51/51 tests pass across the cowork suites incl. new wiring tests.","contentType":"text/plain;utf-8","attachments":[],"quotePin":""}