Skip to content

Commit eef2922

Browse files
committed
refactor(providers): finish canonical identifier audit
1 parent 5e8fcc8 commit eef2922

10 files changed

Lines changed: 48 additions & 16 deletions

File tree

‎packages/config-eslint/provider-identifiers.js‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export function createProviderIdentifierConfig({ providerIdentifiers, retiredPro
8080
return undefined
8181
}
8282

83-
function getProviderExpressionBranches(node) {
83+
function getProviderExpressionChildren(node) {
8484
node = unwrapExpression(node)
8585

8686
if (node?.type === "LogicalExpression") {
@@ -95,6 +95,14 @@ export function createProviderIdentifierConfig({ providerIdentifiers, retiredPro
9595
return [node.right]
9696
}
9797

98+
if (node?.type === "CallExpression") {
99+
return node.arguments
100+
}
101+
102+
if (node?.type === "ArrayExpression") {
103+
return node.elements.filter((element) => element !== null)
104+
}
105+
98106
return []
99107
}
100108

@@ -119,8 +127,8 @@ export function createProviderIdentifierConfig({ providerIdentifiers, retiredPro
119127
},
120128
create(context) {
121129
function reportIfRawProvider(node) {
122-
for (const branch of getProviderExpressionBranches(node)) {
123-
reportIfRawProvider(branch)
130+
for (const child of getProviderExpressionChildren(node)) {
131+
reportIfRawProvider(child)
124132
}
125133

126134
const provider = getRawProvider(node)

‎packages/config-eslint/provider-identifiers.test.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,16 @@ ruleTester.run("no-raw-provider-identifiers provider-like values", rule, {
200200
},
201201
],
202202
},
203+
{
204+
code: 'const schema = { imageGenerationProvider: z.enum(["openrouter"]) }',
205+
errors: [
206+
{
207+
messageId: "useCanonical",
208+
data: { replacement: "providerIdentifiers.openrouter", value: "openrouter" },
209+
type: "Literal",
210+
},
211+
],
212+
},
203213
{
204214
code: 'const imageProvider = useGemini ? "gemini" : "openrouter"',
205215
errors: [

‎packages/types/src/__tests__/provider-identifiers.test.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import {
2121
retiredProviderNamesSchema,
2222
} from "../index.js"
2323

24+
// Raw values are intentional here: these fixtures protect the persisted provider identifier contract.
25+
/* eslint-disable zoo/no-raw-provider-identifiers */
2426
const expectedProviderIdentifiers = [
2527
"openrouter",
2628
"vercel-ai-gateway",
@@ -70,6 +72,7 @@ const expectedRetiredProviderIdentifiers = [
7072
"io-intelligence",
7173
"roo",
7274
]
75+
/* eslint-enable zoo/no-raw-provider-identifiers */
7376

7477
describe("provider identifiers", () => {
7578
it("preserves active provider serialized values", () => {

‎packages/types/src/global-settings.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { telemetrySettingsSchema } from "./telemetry.js"
1414
import { toolNamesSchema } from "./tool.js"
1515
import { type Keys } from "./type-fu.js"
1616
import { languagesSchema } from "./vscode.js"
17+
import { providerIdentifiers } from "./provider-identifiers.js"
1718

1819
/**
1920
* Default delay in milliseconds after writes to allow diagnostics to detect potential problems.
@@ -114,7 +115,7 @@ export const globalSettingsSchema = z.object({
114115
dismissedUpsells: z.array(z.string()).optional(),
115116

116117
// Image generation settings (experimental) - flattened for simplicity
117-
imageGenerationProvider: z.enum(["openrouter"]).optional(),
118+
imageGenerationProvider: z.enum([providerIdentifiers.openrouter]).optional(),
118119
openRouterImageApiKey: z.string().optional(),
119120
openRouterImageGenerationSelectedModel: z.string().optional(),
120121

‎src/api/providers/vscode-lm.ts‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@ import { Anthropic } from "@anthropic-ai/sdk"
22
import * as vscode from "vscode"
33
import OpenAI from "openai"
44

5-
import { type ModelInfo, openAiModelInfoSaneDefaults, vscodeLlmDefaultModelId, vscodeLlmModels } from "@roo-code/types"
5+
import {
6+
type ModelInfo,
7+
openAiModelInfoSaneDefaults,
8+
providerIdentifiers,
9+
vscodeLlmDefaultModelId,
10+
vscodeLlmModels,
11+
} from "@roo-code/types"
612

713
import type { ApiHandlerOptions } from "../../shared/api"
814
import { SELECTOR_SEPARATOR, stringifyVsCodeLmModelSelector } from "../../shared/vsCodeSelectorUtils"
@@ -555,7 +561,7 @@ export class VsCodeLmHandler extends BaseProvider implements SingleCompletionHan
555561
// Fallback when no client is available
556562
const fallbackId = this.options.vsCodeLmModelSelector
557563
? stringifyVsCodeLmModelSelector(this.options.vsCodeLmModelSelector)
558-
: "vscode-lm"
564+
: providerIdentifiers.vscodeLm
559565

560566
console.debug("Zoo Code <Language Model API>: No client available, using fallback model info")
561567

‎src/core/config/importExport.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
globalSettingsSchema,
1111
providerSettingsWithIdSchema,
1212
isProviderName,
13+
retiredProviderIdentifiers,
1314
type GlobalSettings,
1415
type ProviderSettingsWithId,
1516
} from "@roo-code/types"
@@ -106,7 +107,7 @@ function sanitizeGlobalSettings(rawGlobalSettings: unknown): {
106107

107108
let valueToValidate = rawValue
108109

109-
if (key === "imageGenerationProvider" && rawValue === "roo") {
110+
if (key === "imageGenerationProvider" && rawValue === retiredProviderIdentifiers.roo) {
110111
warnings.push(`Setting "${path}" used unsupported value "roo" and was cleared during import.`)
111112
valueToValidate = undefined
112113
}

‎src/integrations/kimi-code/oauth.ts‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { ExtensionContext } from "vscode"
22
import { z } from "zod"
3+
import { providerIdentifiers } from "@roo-code/types"
34

45
export const KIMI_CODE_OAUTH_CONFIG = {
56
authHost: "https://auth.kimi.com",
@@ -16,7 +17,7 @@ const TOKEN_EXPIRY_BUFFER_MS = 60_000
1617
const OAUTH_REQUEST_TIMEOUT_MS = 30_000
1718

1819
const credentialsSchema = z.object({
19-
type: z.literal("kimi-code"),
20+
type: z.literal(providerIdentifiers.kimiCode),
2021
accessToken: z.string().min(1),
2122
refreshToken: z.string().min(1),
2223
expiresAt: z.number(),
@@ -130,7 +131,7 @@ async function requestDeviceToken(deviceCode: string, signal?: AbortSignal): Pro
130131
const tokens = tokenResponseSchema.parse(await response.json())
131132
if (!tokens.refresh_token) throw new Error("Kimi Code OAuth did not return a refresh token")
132133
return {
133-
type: "kimi-code",
134+
type: providerIdentifiers.kimiCode,
134135
accessToken: tokens.access_token,
135136
refreshToken: tokens.refresh_token,
136137
expiresAt: Date.now() + tokens.expires_in * 1000,
@@ -147,7 +148,7 @@ export async function refreshKimiCodeAccessToken(credentials: KimiCodeCredential
147148
if (!response.ok) throw await readOAuthError(response)
148149
const tokens = tokenResponseSchema.parse(await response.json())
149150
return {
150-
type: "kimi-code",
151+
type: providerIdentifiers.kimiCode,
151152
accessToken: tokens.access_token,
152153
refreshToken: tokens.refresh_token ?? credentials.refreshToken,
153154
expiresAt: Date.now() + tokens.expires_in * 1000,

‎src/integrations/openai-codex/oauth.ts‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as http from "http"
33
import { URL } from "url"
44
import type { ExtensionContext } from "vscode"
55
import { z } from "zod"
6+
import { providerIdentifiers } from "@roo-code/types"
67

78
/**
89
* OpenAI Codex OAuth Configuration
@@ -28,7 +29,7 @@ const OPENAI_CODEX_CREDENTIALS_KEY = "openai-codex-oauth-credentials"
2829

2930
// Credentials schema
3031
const openAiCodexCredentialsSchema = z.object({
31-
type: z.literal("openai-codex"),
32+
type: z.literal(providerIdentifiers.openaiCodex),
3233
access_token: z.string().min(1),
3334
refresh_token: z.string().min(1),
3435
// expires is in milliseconds since epoch
@@ -264,7 +265,7 @@ export async function exchangeCodeForTokens(code: string, codeVerifier: string):
264265
})
265266

266267
return {
267-
type: "openai-codex",
268+
type: providerIdentifiers.openaiCodex,
268269
access_token: tokenResponse.access_token,
269270
refresh_token: tokenResponse.refresh_token,
270271
expires: expiresAt,
@@ -316,7 +317,7 @@ export async function refreshAccessToken(credentials: OpenAiCodexCredentials): P
316317
})
317318

318319
return {
319-
type: "openai-codex",
320+
type: providerIdentifiers.openaiCodex,
320321
access_token: tokenResponse.access_token,
321322
refresh_token: tokenResponse.refresh_token ?? credentials.refresh_token,
322323
expires: expiresAt,

‎webview-ui/src/components/settings/ImageGenerationSettings.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export const ImageGenerationSettings = ({
115115
value={currentProvider}
116116
onChange={(e: any) => handleProviderChange(e.target.value)}
117117
className="w-full">
118-
<VSCodeOption value="openrouter" className="py-2 px-3">
118+
<VSCodeOption value={providerIdentifiers.openrouter} className="py-2 px-3">
119119
OpenRouter
120120
</VSCodeOption>
121121
</VSCodeDropdown>

‎webview-ui/src/oauth/urls.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1+
import { providerIdentifiers } from "@roo-code/types"
12
import { Package } from "@roo/package"
23

34
export function getCallbackUrl(provider: string, uriScheme?: string) {
45
return encodeURIComponent(`${uriScheme || "vscode"}://${Package.publisher}.${Package.name}/${provider}`)
56
}
67

78
export function getOpenRouterAuthUrl(uriScheme?: string) {
8-
return `https://openrouter.ai/auth?callback_url=${getCallbackUrl("openrouter", uriScheme)}`
9+
return `https://openrouter.ai/auth?callback_url=${getCallbackUrl(providerIdentifiers.openrouter, uriScheme)}`
910
}
1011

1112
export function getRequestyAuthUrl(uriScheme?: string) {
12-
return `https://app.requesty.ai/oauth/authorize?callback_url=${getCallbackUrl("requesty", uriScheme)}`
13+
return `https://app.requesty.ai/oauth/authorize?callback_url=${getCallbackUrl(providerIdentifiers.requesty, uriScheme)}`
1314
}
1415

1516
const ZOO_CODE_DEFAULT_BASE_URL = "https://www.zoocode.dev"

0 commit comments

Comments
 (0)