(params: ResolvePiModelKeyParams)
| 37 | |
| 38 | /** Resolves the provider and a usable API key for the selected model. */ |
| 39 | export async function resolvePiModelKey(params: ResolvePiModelKeyParams): Promise<PiKeyResolution> { |
| 40 | const providerId = getProviderFromModel(params.model) |
| 41 | |
| 42 | if (providerId === 'vertex' && params.vertexCredential) { |
| 43 | const apiKey = await resolveVertexCredential( |
| 44 | params.vertexCredential, |
| 45 | params.userId, |
| 46 | 'vertex-pi' |
| 47 | ) |
| 48 | return { providerId, apiKey, isBYOK: true } |
| 49 | } |
| 50 | |
| 51 | // Cloud hands the model key to an untrusted sandbox, so it must be the user's |
| 52 | // own key — never a Sim-hosted/rotating key. Prefer the block's API Key field, |
| 53 | // then a stored workspace BYOK key; refuse to fall back to a hosted key. |
| 54 | if (params.mode === 'cloud') { |
| 55 | if (params.apiKey) { |
| 56 | return { providerId, apiKey: params.apiKey, isBYOK: true } |
| 57 | } |
| 58 | if (params.workspaceId && WORKSPACE_BYOK_PROVIDERS.has(providerId)) { |
| 59 | const byok = await getBYOKKey(params.workspaceId, providerId as BYOKProviderId) |
| 60 | if (byok) { |
| 61 | return { providerId, apiKey: byok.apiKey, isBYOK: true } |
| 62 | } |
| 63 | } |
| 64 | throw new Error( |
| 65 | WORKSPACE_BYOK_PROVIDERS.has(providerId) |
| 66 | ? 'Cloud mode requires your own provider API key (BYOK). Enter it in the API Key field, or store one in Settings > BYOK.' |
| 67 | : 'Cloud mode requires your own provider API key (BYOK). Enter it in the API Key field.' |
| 68 | ) |
| 69 | } |
| 70 | |
| 71 | const { apiKey, isBYOK } = await getApiKeyWithBYOK( |
| 72 | providerId, |
| 73 | params.model, |
| 74 | params.workspaceId, |
| 75 | params.apiKey |
| 76 | ) |
| 77 | return { providerId, apiKey, isBYOK } |
| 78 | } |
| 79 | |
| 80 | /** Run cost, zeroed for BYOK keys and models Sim does not bill. */ |
| 81 | export function computePiCost( |
no test coverage detected