Release/v6.8.6 - #130
Release/v6.8.6#130
Conversation
…count plan getKilocodeDefaultModel no longer returns the hardcoded openRouterDefaultModelId. It fetches /v1/web/models and /axoncode/profile in parallel and returns the entry the backend flags freePlan for free accounts, or the first catalog entry (index 0) for every other plan, with a 10-minute TTL cache and a fallback to openRouterDefaultModelId on failure. The stale-model reset paths in ClineProvider now pass the Kilocode token and organization id.
There was a problem hiding this comment.
🧪 PR Review is completed: The new live-catalog default model resolution is well structured (TTL cache, parallel fetches, safe fallback), but a malformed profile body can throw and defeat the documented 'profile failure must not block' guarantee, and the profile schema validates a field that is never read. Reviewed src/core/webview/ClineProvider.ts (token/orgId propagation to stale-model reset — good fix, no issues) and src/package.json (version bump, no issues).
Skipped files
CHANGELOG.md: Skipped file pattern
| const plan = profileResponse.ok | ||
| ? ((await profileSchema.parseAsync(await profileResponse.json())).plan ?? undefined) | ||
| : undefined |
There was a problem hiding this comment.
🟡 Logic Error / Error Handling
Issue: The comment above this code states "A failed profile fetch must not block the default", but that guarantee only covers a non-OK HTTP status. If profileResponse.ok is true but the body is malformed (invalid JSON, or a shape that fails profileSchema — e.g. tieredUsage present with a non-object value), parseAsync/json() throws, which propagates out of fetchCatalogDefaultModel, gets caught in fetchKilocodeDefaultModel, and silently discards the successfully fetched catalog in favor of the hardcoded openRouterDefaultModelId fallback.
Fix: Wrap the profile parse in a try/catch so any profile failure (status, JSON, or schema) degrades to plan = undefined (treated as free) instead of throwing away the catalog result.
Impact: The catalog-derived default is always used when the catalog fetch succeeds, matching the documented intent and avoiding unnecessary fallbacks to the hardcoded model on transient profile API glitches.
| const plan = profileResponse.ok | |
| ? ((await profileSchema.parseAsync(await profileResponse.json())).plan ?? undefined) | |
| : undefined | |
| let plan: string | undefined | |
| if (profileResponse.ok) { | |
| try { | |
| plan = (await profileSchema.parseAsync(await profileResponse.json())).plan ?? undefined | |
| } catch { | |
| plan = undefined | |
| } | |
| } |
Summary
Release v6.8.6.
Fixed
getKilocodeDefaultModelno longer returns the hardcodedopenRouterDefaultModelId. It now resolves the default from the live MatterAI catalog (/v1/web/models): free accounts get the entry the backend flagsfreePlan, every other plan gets the first catalog entry (index 0, ordered by the catalog'ssortOrder). The account plan comes from/axoncode/profile; a failed profile fetch is treated as free, and any catalog failure still falls back toopenRouterDefaultModelId. The stale-model reset paths inClineProvidernow pass the Kilocode token and organization id so they resolve the same plan-aware default instead of the hardcoded one.Verification
tsc --noEmitpasses.vitest run api/providers/__tests__/kilocode-openrouter.spec.ts api/providers/__tests__/kilocode-models.spec.ts— 31/31 pass.ClineProvider.spec.tshas 27 pre-existing failures, identical with and without these changes (verified by stashing them).After merge: tag
v6.8.6and run the Publish Extension workflow.