MCPcopy
hub / github.com/simstudioai/sim / injectHostedKeyIfNeeded

Function injectHostedKeyIfNeeded

apps/sim/tools/index.ts:226–319  ·  view source on GitHub ↗

* Inject hosted API key if tool supports it and user didn't provide one. * Checks BYOK workspace keys first, then uses the HostedKeyRateLimiter for round-robin key selection. * Returns whether a hosted (billable) key was injected and which env var it came from.

(
  tool: ToolConfig,
  params: Record<string, unknown>,
  executionContext: ExecutionContext | undefined,
  requestId: string
)

Source from the content-addressed store, hash-verified

224 * Returns whether a hosted (billable) key was injected and which env var it came from.
225 */
226async function injectHostedKeyIfNeeded(
227 tool: ToolConfig,
228 params: Record<string, unknown>,
229 executionContext: ExecutionContext | undefined,
230 requestId: string
231): Promise<HostedKeyInjectionResult> {
232 if (!tool.hosting) return { isUsingHostedKey: false }
233 if (!isHosted) return { isUsingHostedKey: false }
234 if (tool.hosting.enabled && !tool.hosting.enabled(params)) {
235 return { isUsingHostedKey: false }
236 }
237
238 const { envKeyPrefix, apiKeyParam, byokProviderId, rateLimit } = tool.hosting
239 const userProvidedKey = params[apiKeyParam]
240 if (typeof userProvidedKey === 'string' && userProvidedKey.trim().length > 0) {
241 return { isUsingHostedKey: false }
242 }
243
244 const { workspaceId, userId, workflowId } = resolveToolScope(params, executionContext)
245
246 // Check BYOK workspace key first
247 if (byokProviderId && workspaceId) {
248 try {
249 const byokResult = await getBYOKKey(workspaceId, byokProviderId as BYOKProviderId)
250 if (byokResult) {
251 params[apiKeyParam] = byokResult.apiKey
252 logger.info(`[${requestId}] Using BYOK key for ${tool.id}`)
253 return { isUsingHostedKey: false } // Don't bill - user's own key
254 }
255 } catch (error) {
256 logger.error(`[${requestId}] Failed to get BYOK key for ${tool.id}:`, error)
257 // Fall through to hosted key
258 }
259 }
260
261 const rateLimiter = getHostedKeyRateLimiter()
262 const provider = byokProviderId || tool.id
263 const billingActorId = workspaceId
264
265 if (!billingActorId) {
266 logger.error(`[${requestId}] No workspace ID available for hosted key rate limiting`)
267 return { isUsingHostedKey: false }
268 }
269
270 const acquireResult = await rateLimiter.acquireKey(
271 provider,
272 envKeyPrefix,
273 rateLimit,
274 billingActorId,
275 executionContext?.abortSignal
276 )
277
278 if (!acquireResult.success && acquireResult.billingActorRateLimited) {
279 logger.warn(`[${requestId}] Billing actor ${billingActorId} rate limited for ${tool.id}`, {
280 provider,
281 retryAfterMs: acquireResult.retryAfterMs,
282 })
283

Callers 1

executeToolFunction · 0.85

Calls 7

getBYOKKeyFunction · 0.90
getHostedKeyRateLimiterFunction · 0.90
resolveToolScopeFunction · 0.85
infoMethod · 0.80
errorMethod · 0.80
acquireKeyMethod · 0.80
warnMethod · 0.65

Tested by

no test coverage detected