Skip to content

Commit 6f8f8c6

Browse files
authored
Parse providers individually (#2611)
* Parse providers individually * Remove .strict() * Clean up tests
1 parent b196489 commit 6f8f8c6

File tree

2 files changed

+66
-8
lines changed

2 files changed

+66
-8
lines changed

src/core/config/ProviderSettingsManager.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ExtensionContext } from "vscode"
22
import { z, ZodError } from "zod"
33

4-
import { providerSettingsSchema, ApiConfigMeta } from "../../schemas"
4+
import { providerSettingsSchema, ApiConfigMeta, ProviderSettings } from "../../schemas"
55
import { Mode, modes } from "../../shared/modes"
66
import { telemetryService } from "../../services/telemetry/TelemetryService"
77

@@ -115,20 +115,15 @@ export class ProviderSettingsManager {
115115
}
116116

117117
if (rateLimitSeconds === undefined) {
118-
// Failed to get the existing value, use the default
118+
// Failed to get the existing value, use the default.
119119
rateLimitSeconds = 0
120120
}
121121

122122
for (const [name, apiConfig] of Object.entries(providerProfiles.apiConfigs)) {
123123
if (apiConfig.rateLimitSeconds === undefined) {
124-
console.log(
125-
`[MigrateRateLimitSeconds] Applying rate limit ${rateLimitSeconds}s to profile: ${name}`,
126-
)
127124
apiConfig.rateLimitSeconds = rateLimitSeconds
128125
}
129126
}
130-
131-
console.log(`[MigrateRateLimitSeconds] migration complete`)
132127
} catch (error) {
133128
console.error(`[MigrateRateLimitSeconds] Failed to migrate rate limit settings:`, error)
134129
}
@@ -321,7 +316,31 @@ export class ProviderSettingsManager {
321316
private async load(): Promise<ProviderProfiles> {
322317
try {
323318
const content = await this.context.secrets.get(this.secretsKey)
324-
return content ? providerProfilesSchema.parse(JSON.parse(content)) : this.defaultProviderProfiles
319+
320+
if (!content) {
321+
return this.defaultProviderProfiles
322+
}
323+
324+
const providerProfiles = providerProfilesSchema
325+
.extend({
326+
apiConfigs: z.record(z.string(), z.any()),
327+
})
328+
.parse(JSON.parse(content))
329+
330+
const apiConfigs = Object.entries(providerProfiles.apiConfigs).reduce(
331+
(acc, [key, apiConfig]) => {
332+
const result = providerSettingsWithIdSchema.safeParse(apiConfig)
333+
return result.success ? { ...acc, [key]: result.data } : acc
334+
},
335+
{} as Record<string, ProviderSettingsWithId>,
336+
)
337+
338+
return {
339+
...providerProfiles,
340+
apiConfigs: Object.fromEntries(
341+
Object.entries(apiConfigs).filter(([_, apiConfig]) => apiConfig !== null),
342+
),
343+
}
325344
} catch (error) {
326345
if (error instanceof ZodError) {
327346
telemetryService.captureSchemaValidationError({ schemaName: "ProviderProfiles", error })

src/core/config/__tests__/ProviderSettingsManager.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,45 @@ describe("ProviderSettingsManager", () => {
437437
"Failed to load config: Error: Failed to write provider profiles to secrets: Error: Storage failed",
438438
)
439439
})
440+
441+
it("should remove invalid profiles during load", async () => {
442+
const invalidConfig = {
443+
currentApiConfigName: "valid",
444+
apiConfigs: {
445+
valid: {
446+
apiProvider: "anthropic",
447+
apiKey: "valid-key",
448+
apiModelId: "claude-3-opus-20240229",
449+
rateLimitSeconds: 0,
450+
},
451+
invalid: {
452+
// Invalid API provider.
453+
id: "x.ai",
454+
apiProvider: "x.ai",
455+
},
456+
// Incorrect type.
457+
anotherInvalid: "not an object",
458+
},
459+
migrations: {
460+
rateLimitSecondsMigrated: true,
461+
},
462+
}
463+
464+
mockSecrets.get.mockResolvedValue(JSON.stringify(invalidConfig))
465+
466+
await providerSettingsManager.initialize()
467+
468+
const storeCalls = mockSecrets.store.mock.calls
469+
expect(storeCalls.length).toBeGreaterThan(0) // Ensure store was called at least once.
470+
const finalStoredConfigJson = storeCalls[storeCalls.length - 1][1]
471+
472+
const storedConfig = JSON.parse(finalStoredConfigJson)
473+
expect(storedConfig.apiConfigs.valid).toBeDefined()
474+
expect(storedConfig.apiConfigs.invalid).toBeUndefined()
475+
expect(storedConfig.apiConfigs.anotherInvalid).toBeUndefined()
476+
expect(Object.keys(storedConfig.apiConfigs)).toEqual(["valid"])
477+
expect(storedConfig.currentApiConfigName).toBe("valid")
478+
})
440479
})
441480

442481
describe("ResetAllConfigs", () => {

0 commit comments

Comments
 (0)