perf: memo GridCard, fuse save fns, fix slash tab active color
Some checks failed
CI / Lint, Unit Tests & Build (push) Failing after 1m32s
CI / Deploy production (on server) (push) Has been skipped

This commit is contained in:
Antigravity
2026-06-14 14:06:05 +00:00
parent a8785ed4f1
commit a623454347
120 changed files with 12301 additions and 785 deletions

View File

@@ -1,8 +1,9 @@
import {
getProviderInstance,
getProviderConfigKeys,
type ProviderType,
} from '@/lib/ai/factory';
import { applyByokToConfig } from '@/lib/byok';
import { getAnyActiveByokForUser, hasAnyActiveByok, ByokUnavailableError } from '@/lib/byok';
import {
resolveAiRoute,
type AiFeatureLane,
@@ -17,78 +18,87 @@ export interface ProviderForUserResult {
route: ResolvedAiRoute;
}
/** Resolve the best AI provider for a user's lane — BYOK first, then admin config. */
async function resolveProviderForLane(
lane: AiFeatureLane,
config: Record<string, string>,
billingUserId?: string,
): Promise<ProviderForUserResult> {
const cfg = { ...config };
const route = resolveAiRoute(lane, cfg);
let usedByok = false;
let byokModel: string | null = null;
const adminRoute = resolveAiRoute(lane, cfg);
if (billingUserId) {
const overlay = await applyByokToConfig(
billingUserId,
route.providerType,
cfg,
);
Object.assign(cfg, overlay.config);
usedByok = overlay.usedByok;
byokModel = overlay.model;
// Prefer admin's provider, fallback to any active BYOK key
const byok = await getAnyActiveByokForUser(billingUserId, adminRoute.providerType, lane);
if (byok) {
const { apiKeyConfigKey, baseUrlConfigKey } = getProviderConfigKeys(byok.provider);
const byokCfg: Record<string, string> = { ...cfg };
if (apiKeyConfigKey) byokCfg[apiKeyConfigKey] = byok.plaintext;
if (baseUrlConfigKey && byok.baseUrl) byokCfg[baseUrlConfigKey] = byok.baseUrl;
const resolvedModel = (byok.model && byok.model.trim()) ? byok.model : adminRoute.modelName;
console.log(`[byok] Using BYOK key: provider=${byok.provider} model=${resolvedModel} user=${billingUserId}`);
const provider = getProviderInstance(
byok.provider as ProviderType,
byokCfg,
resolvedModel,
adminRoute.embeddingModelName,
adminRoute.ollamaBaseUrl,
);
return {
provider,
usedByok: true,
route: {
...adminRoute,
providerType: byok.provider as ResolvedAiRoute['providerType'],
modelName: resolvedModel,
},
};
}
// No key resolved — if user HAS active BYOK rows, decryption failed → throw, no silent fallback
const hasByok = await hasAnyActiveByok(billingUserId);
if (hasByok) {
throw new ByokUnavailableError();
}
}
const resolvedModel = byokModel && byokModel.trim() !== '' ? byokModel : route.modelName;
// No BYOK configured → use admin config
const provider = getProviderInstance(
route.providerType as ProviderType,
adminRoute.providerType as ProviderType,
cfg,
resolvedModel,
route.embeddingModelName,
route.ollamaBaseUrl,
adminRoute.modelName,
adminRoute.embeddingModelName,
adminRoute.ollamaBaseUrl,
);
const updatedRoute = { ...route, modelName: resolvedModel };
return { provider, usedByok, route: updatedRoute };
return { provider, usedByok: false, route: adminRoute };
}
async function getChatProviderForBillingUser(
config: Record<string, string>,
billingUserId?: string,
): Promise<ProviderForUserResult> {
return resolveProviderForLane('chat', config, billingUserId);
}
async function getTagsProviderForBillingUser(
config: Record<string, string>,
billingUserId?: string,
): Promise<ProviderForUserResult> {
return resolveProviderForLane('tags', config, billingUserId);
}
async function getEmbeddingsProviderForBillingUser(
config: Record<string, string>,
billingUserId?: string,
): Promise<ProviderForUserResult> {
return resolveProviderForLane('embedding', config, billingUserId);
}
/** Run a lane with BYOK overlay; skips system fallback when user key is active. */
/** Check if a lane will use BYOK for a given user. */
export async function willUseByokForLane(
lane: AiFeatureLane,
config: Record<string, string>,
billingUserId?: string,
): Promise<{ providerType: string; usedByok: boolean }> {
if (!billingUserId) {
const route = resolveAiRoute(lane, config)
return { providerType: route.providerType, usedByok: false }
const route = resolveAiRoute(lane, config);
return { providerType: route.providerType, usedByok: false };
}
const route = resolveAiRoute(lane, config)
const overlay = await applyByokToConfig(billingUserId, route.providerType, config)
return { providerType: route.providerType, usedByok: overlay.usedByok }
const route = resolveAiRoute(lane, config);
const byok = await getAnyActiveByokForUser(billingUserId, route.providerType);
return { providerType: byok?.provider ?? route.providerType, usedByok: !!byok };
}
/**
* Run an AI lane with BYOK priority.
* - If user has active BYOK → uses it, no quota counted.
* - If user has BYOK configured but it can't be loaded → throws ByokUnavailableError (no fallback).
* - If user has no BYOK → uses admin config with system fallback.
*/
export async function runLaneWithBillingUser<T>(
lane: AiFeatureLane,
config: Record<string, string>,
@@ -96,12 +106,8 @@ export async function runLaneWithBillingUser<T>(
run: (provider: AIProvider) => Promise<T>,
): Promise<{ result: T; usedByok: boolean }> {
if (billingUserId) {
const resolved =
lane === 'chat'
? await getChatProviderForBillingUser(config, billingUserId)
: lane === 'tags'
? await getTagsProviderForBillingUser(config, billingUserId)
: await getEmbeddingsProviderForBillingUser(config, billingUserId);
// May throw ByokUnavailableError — let it propagate, callers should handle it
const resolved = await resolveProviderForLane(lane, config, billingUserId);
if (resolved.usedByok) {
const result = await run(resolved.provider);
@@ -109,6 +115,7 @@ export async function runLaneWithBillingUser<T>(
}
}
// No BYOK configured → use admin config with system fallback
const result = await withAiProviderFallback(lane, config, run);
return { result, usedByok: false };
}