@tanstack/ai
Version:
Type-safe TypeScript AI SDK for streaming chat, tool calling, agents, structured outputs, and multimodal generation.
58 lines (57 loc) • 2.09 kB
JavaScript
import { byokHeaderName, resolveProviderId } from "./providers.js";
//#region src/byok/get-key.ts
/**
* Read a key on the relay. Import from `@tanstack/ai/byok/server` so this
* `process.env` access is not in the client graph.
*
* The header wins. A {@link ByokProvider} then tries `provider.env` in order.
* A slug is header-only.
*/
function getByokKey(request, provider) {
const value = request.headers.get(byokHeaderName(resolveProviderId(provider)));
if (typeof value === "string") {
const trimmed = value.trim();
if (trimmed.length > 0) return trimmed;
}
if (typeof provider === "string") return null;
for (const name of provider.env ?? []) {
const envValue = process.env[name];
if (typeof envValue === "string" && envValue.length > 0) return envValue;
}
return null;
}
/**
* Read several keys at once, one per name. Same rules as {@link getByokKey}
* for each entry. Use it for a credential made of more than one value.
*/
function getByokKeys(request, providers) {
return Object.fromEntries(Object.entries(providers).map(([name, provider]) => [name, getByokKey(request, provider)]));
}
/**
* Build the adapter of the first provider that has a key. The user's own key
* (the `x-byok-<id>` header) wins, in order. Then each keyed adapter made with
* a BYOK descriptor tries its `env` names, in order. Gives `null` when no
* provider has a key, so the route can answer with `byokMissing`.
*
* @example
* ```ts
* const adapter = keyedAdapterFromRequest(request, models)
* if (!adapter) return byokMissing('openai')
* return toServerSentEventsResponse(chat({ adapter, messages }))
* ```
*/
function keyedAdapterFromRequest(request, adapters) {
const list = Object.values(adapters);
for (const keyed of list) {
const key = getByokKey(request, resolveProviderId(keyed.provider));
if (key) return keyed.create(key);
}
for (const keyed of list) {
const key = getByokKey(request, keyed.provider);
if (key) return keyed.create(key);
}
return null;
}
//#endregion
export { getByokKey, getByokKeys, keyedAdapterFromRequest };
//# sourceMappingURL=get-key.js.map