Skip to content

Commit 5f9046e

Browse files
fix(providers): respect user-provided key over hosted pool in hosted-key-llm path
1 parent 03f9159 commit 5f9046e

2 files changed

Lines changed: 12 additions & 4 deletions

File tree

apps/sim/lib/api-key/byok.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,9 @@ export async function getApiKeyWithBYOK(
104104
userId?: string | null
105105
): Promise<ApiKeyResolution> {
106106
// Unified hosted-key path (flag-gated). For any provider with a hosting config:
107-
// BYOK workspace key wins; otherwise acquire a platform key through the shared
108-
// hosted-key framework with no rate limiting. Falls through to the legacy
107+
// workspace BYOK key wins, then a user-provided key (never billed via the pool),
108+
// otherwise acquire a platform key through the shared hosted-key framework with no
109+
// rate limiting. Mirrors tool hosted-key precedence. Falls through to the legacy
109110
// per-provider logic when the flag is off or no platform keys are configured,
110111
// keeping flag-off behavior identical.
111112
if (isHosted && workspaceId) {
@@ -117,6 +118,12 @@ export async function getApiKeyWithBYOK(
117118
return byokResult
118119
}
119120

121+
// A user-supplied key takes precedence over the platform pool — use it as-is
122+
// and never bill it through hosted-key metrics/cost.
123+
if (userProvidedKey) {
124+
return { apiKey: userProvidedKey, isBYOK: false }
125+
}
126+
120127
const acquired = await getHostedKeyRateLimiter().acquireKey(
121128
hosting.byokProviderId,
122129
hosting.envKeyPrefix,

apps/sim/providers/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,9 @@ export async function executeProviderRequest(
229229
if (isBYOK) {
230230
zeroCostForBYOK(response)
231231
} else if (hostedKeyEnvVar) {
232-
// Hosted key used: record usage now; cost is settled on stream drain
233-
// inside createStreamingExecution (the single streaming cost seam).
232+
// Hosted key used: record usage now; cost is settled on stream drain via
233+
// settleStreamingLlmCost (from createStreamingExecution, or the provider's
234+
// bespoke stream finalizer for gemini).
234235
hostedKeyMetrics.recordUsed({
235236
provider: providerId,
236237
tool: response.execution.output?.model ?? request.model,

0 commit comments

Comments
 (0)