diff --git a/packages/core/src/plugin/models-dev.ts b/packages/core/src/plugin/models-dev.ts index 075a6ed093c6..17b1c03c2cb7 100644 --- a/packages/core/src/plugin/models-dev.ts +++ b/packages/core/src/plugin/models-dev.ts @@ -10,6 +10,19 @@ function released(date: string) { return Number.isFinite(time) ? time : 0 } +const CREDENTIAL_ENV_SUFFIXES = ["_API_KEY", "_TOKEN", "_PAT"] + +// models.dev lists env vars in setup order, so account/host/region/project names +// that configure a provider often precede the actual credential (e.g. Cloudflare's +// `[CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_KEY]`). Connection resolution picks the +// first set var, so an unfiltered list can hand a non-secret value out as the +// bearer key. Narrow to credential-shaped names when any exist; otherwise fall +// back to the full list rather than guess wrong for an unfamiliar naming scheme. +function credentialEnvNames(names: readonly string[]) { + const credentials = names.filter((name) => CREDENTIAL_ENV_SUFFIXES.some((suffix) => name.endsWith(suffix))) + return credentials.length > 0 ? credentials : [...names] +} + function cost(input: ModelsDev.Model["cost"]): ModelV2Info["cost"] { const base = { input: input?.input ?? 0, @@ -134,7 +147,7 @@ export const ModelsDevPlugin = define({ }) integrations.method.update({ integrationID, - method: { type: "env", names: [...item.env] }, + method: { type: "env", names: credentialEnvNames(item.env) }, }) } }), diff --git a/packages/core/test/plugin/fixtures/models-dev.json b/packages/core/test/plugin/fixtures/models-dev.json index fb8f2622be35..e307c35ed736 100644 --- a/packages/core/test/plugin/fixtures/models-dev.json +++ b/packages/core/test/plugin/fixtures/models-dev.json @@ -10,5 +10,11 @@ "name": "Local", "env": [], "models": {} + }, + "cloudy": { + "id": "cloudy", + "name": "Cloudy", + "env": ["CLOUDY_ACCOUNT_ID", "CLOUDY_API_KEY"], + "models": {} } } diff --git a/packages/core/test/plugin/models-dev.test.ts b/packages/core/test/plugin/models-dev.test.ts index 6c0f7e070296..4b3d15bf2f37 100644 --- a/packages/core/test/plugin/models-dev.test.ts +++ b/packages/core/test/plugin/models-dev.test.ts @@ -158,6 +158,19 @@ describe("ModelsDevPlugin", () => { ], connections: [], }), + new Integration.Info({ + id: Integration.ID.make("cloudy"), + name: "Cloudy", + methods: [ + { type: "key" }, + { + // CLOUDY_ACCOUNT_ID is not a credential; only the key-shaped name is registered. + type: "env", + names: ["CLOUDY_API_KEY"], + }, + ], + connections: [], + }), ]) }).pipe(Effect.provide(AppNodeBuilder.build(ModelsDev.node))), (previous) =>