import { useEffect, useMemo, useRef, useState, type FormEvent } from 'react'; import type { BaseModelCatalogItem, CatalogProvider, GatewayAccessRuleBatchRequest, GatewayAccessRule, GatewayAccessRuleUpsertRequest, GatewayApiKey, GatewayAuditLog, GatewayTenantUpsertRequest, GatewayTask, GatewayUserUpsertRequest, GatewayTenant, GatewayUser, IntegrationPlatform, ModelCatalogResponse, PlatformModel, PricingRule, PricingRuleSet, RateLimitWindow, RuntimePolicySet, UserGroupUpsertRequest, UserGroup, WalletBalanceAdjustmentRequest, } from '@easyai-ai-gateway/contracts'; import { batchAccessRules, batchApiKeyAccessRules, createAccessRule, createApiKey, createGatewayUser, createPlatform, createTenant, createUserGroup, deleteAccessRule, deleteApiKey, deleteGatewayUser, deletePlatform, deleteTenant, deleteUserGroup, getHealth, getTask, listAuditLogs, listAccessRules, listApiKeyAccessRules, listApiKeys, listBaseModels, listCatalogProviders, listModelCatalog, listModels, listPlayableApiKeys, listPlayableModels, listPlatforms, listPricingRules, listPricingRuleSets, listRuntimePolicySets, listTasks, listPublicBaseModels, listPublicCatalogProviders, listRateLimitWindows, listTenants, listUserGroups, listUsers, loginLocalAccount, registerLocalAccount, replacePlatformModels, setUserWalletBalance, type HealthResponse, updateAccessRule, updateGatewayUser, updatePlatform, updateTenant, updateUserGroup, } from './api'; import type { ConsoleData, StatItem } from './app-state'; import { AppShell } from './components/layout/AppShell'; import { LoginRequiredPanel } from './components/LoginRequiredPanel'; import { useCatalogOperations } from './hooks/useCatalogOperations'; import { usePricingRuleSetOperations } from './hooks/usePricingRuleSetOperations'; import { useRuntimePolicySetOperations } from './hooks/useRuntimePolicySetOperations'; import { persistAccessToken, readStoredAccessToken } from './lib/auth-storage'; import { runTask } from './lib/run-task'; import { AdminPage } from './pages/AdminPage'; import { ApiDocsPage } from './pages/ApiDocsPage'; import { HomePage } from './pages/HomePage'; import { ModelsPage } from './pages/ModelsPage'; import { PlaygroundPage } from './pages/PlaygroundPage'; import { WorkspacePage } from './pages/WorkspacePage'; import { parseAppRoute, pathForAdminSection, pathForApiDocSection, pathForPage, pathForPlaygroundMode, pathForWorkspaceSection, pathForWorkspaceTaskQuery, workspaceTaskQueryKey, type AppRouteState, } from './routing'; import type { AdminSection, ApiDocSection, ApiKeyForm, AuthMode, LoadState, LoginForm, PageKey, PlaygroundMode, PlatformCreateInput, PlatformModelBindingInput, PlatformWithModelsInput, RegisterForm, TaskForm, WorkspaceTaskQuery, WorkspaceSection, } from './types'; type DataKey = | 'health' | 'publicCatalog' | 'playgroundApiKeys' | 'playgroundModels' | 'modelCatalog' | 'platforms' | 'models' | 'providers' | 'baseModels' | 'pricingRules' | 'pricingRuleSets' | 'runtimePolicySets' | 'rateLimitWindows' | 'tenants' | 'users' | 'userGroups' | 'tasks' | 'accessRules' | 'auditLogs' | 'apiKeys'; export function App() { const initialRoute = parseAppRoute(); const [activePage, setActivePage] = useState(initialRoute.activePage); const [adminSection, setAdminSection] = useState(initialRoute.adminSection); const [workspaceSection, setWorkspaceSection] = useState(initialRoute.workspaceSection); const [workspaceTaskQuery, setWorkspaceTaskQuery] = useState(initialRoute.workspaceTaskQuery); const [apiDocSection, setApiDocSection] = useState(initialRoute.apiDocSection); const [playgroundMode, setPlaygroundMode] = useState(initialRoute.playgroundMode); const [token, setToken] = useState(readStoredAccessToken); const [externalToken, setExternalToken] = useState(''); const [authMode, setAuthMode] = useState('login'); const [loginForm, setLoginForm] = useState({ account: '', password: '' }); const [registerForm, setRegisterForm] = useState({ username: '', email: '', password: '', displayName: '', invitationCode: '' }); const [health, setHealth] = useState(null); const [platforms, setPlatforms] = useState([]); const [models, setModels] = useState([]); const [modelCatalog, setModelCatalog] = useState({ items: [], filters: { capabilities: [], providers: [] }, summary: { modelCount: 0, sourceCount: 0 }, }); const [playgroundModels, setPlaygroundModels] = useState([]); const [providers, setProviders] = useState([]); const [baseModels, setBaseModels] = useState([]); const [pricingRules, setPricingRules] = useState([]); const [pricingRuleSets, setPricingRuleSets] = useState([]); const [runtimePolicySets, setRuntimePolicySets] = useState([]); const [accessRules, setAccessRules] = useState([]); const [auditLogs, setAuditLogs] = useState([]); const [rateLimitWindows, setRateLimitWindows] = useState([]); const [tenants, setTenants] = useState([]); const [users, setUsers] = useState([]); const [userGroups, setUserGroups] = useState([]); const [apiKeys, setApiKeys] = useState([]); const [apiKeyForm, setApiKeyForm] = useState({ name: 'Local smoke key', expiresAt: '' }); const [apiKeySecret, setApiKeySecret] = useState(''); const [apiKeySecretsById, setApiKeySecretsById] = useState>({}); const [selectedPlaygroundApiKeyId, setSelectedPlaygroundApiKeyId] = useState(''); const [taskForm, setTaskForm] = useState({ kind: 'chat.completions', model: 'gpt-4o-mini', prompt: '用一句话确认 AI Gateway simulation 链路正常。' }); const [taskResult, setTaskResult] = useState(null); const [tasks, setTasks] = useState([]); const [taskTotal, setTaskTotal] = useState(0); const [coreState, setCoreState] = useState('idle'); const [coreMessage, setCoreMessage] = useState(''); const [state, setState] = useState('idle'); const [error, setError] = useState(''); const loadedDataKeysRef = useRef(new Set()); const loadingDataKeysRef = useRef(new Set()); const loadedTaskQueryKeyRef = useRef(''); const currentTaskQueryKeyRef = useRef(''); const { removeBaseModel, removeProvider, resetAllBaseModelsToDefault, resetBaseModelToDefault, saveBaseModel, saveProvider } = useCatalogOperations({ setBaseModels, setCoreMessage, setCoreState, setProviders, token, }); const { removePricingRuleSet, savePricingRuleSet } = usePricingRuleSetOperations({ setCoreMessage, setCoreState, setPricingRuleSets, token, }); const { removeRuntimePolicySet, saveRuntimePolicySet } = useRuntimePolicySetOperations({ setCoreMessage, setCoreState, setRuntimePolicySets, token, }); const taskListRequestKey = workspaceTaskQueryKey(workspaceTaskQuery); currentTaskQueryKeyRef.current = taskListRequestKey; useEffect(() => { void ensureData(['health']); }, []); useEffect(() => { void ensureRouteData(token); }, [activePage, adminSection, taskListRequestKey, workspaceSection, token]); useEffect(() => { function handlePopState() { applyRoute(parseAppRoute()); } window.addEventListener('popstate', handlePopState); return () => window.removeEventListener('popstate', handlePopState); }, []); const stats = useMemo(() => { const enabledPlatforms = platforms.filter((item) => item.status === 'enabled').length; const enabledModels = models.filter((item) => item.enabled).length; const activeProviders = providers.filter((item) => item.status === 'active').length; const activeRateWindows = rateLimitWindows.filter((item) => item.resetAt >= new Date().toISOString()).length; return [ { label: '租户', value: tenants.length, tone: 'cyan' }, { label: '用户', value: users.length, tone: 'green' }, { label: '用户组', value: userGroups.length, tone: 'blue' }, { label: '平台', value: platforms.length, tone: 'blue' }, { label: '启用平台', value: enabledPlatforms, tone: 'green' }, { label: '平台模型', value: enabledModels, tone: 'violet' }, { label: 'Provider', value: activeProviders || providers.length, tone: 'amber' }, { label: '定价规则', value: pricingRules.length, tone: 'cyan' }, { label: '运行策略', value: runtimePolicySets.length, tone: 'slate' }, { label: '访问规则', value: accessRules.length, tone: 'amber' }, { label: '限流窗口', value: activeRateWindows, tone: 'rose' }, ]; }, [accessRules.length, models, platforms, pricingRules.length, providers, rateLimitWindows, runtimePolicySets.length, tenants.length, userGroups.length, users.length]); const data = useMemo(() => ({ accessRules, auditLogs, apiKeys, baseModels, modelCatalog, models, platforms, pricingRules, pricingRuleSets, providers, rateLimitWindows, runtimePolicySets, taskResult, tasks, tenants, userGroups, users, }), [accessRules, apiKeys, auditLogs, baseModels, modelCatalog, models, platforms, pricingRuleSets, pricingRules, providers, rateLimitWindows, runtimePolicySets, taskResult, tasks, tenants, userGroups, users]); async function refresh(nextToken = token) { await ensureRouteData(nextToken, true); } function invalidateDataKeys(...keys: DataKey[]) { keys.forEach((key) => loadedDataKeysRef.current.delete(key)); } async function ensureRouteData(nextToken = token, force = false) { if (activePage === 'workspace' && workspaceSection === 'tasks' && loadedTaskQueryKeyRef.current !== taskListRequestKey) { loadedDataKeysRef.current.delete('tasks'); loadingDataKeysRef.current.delete('tasks'); } await ensureData(dataKeysForRoute(activePage, adminSection, workspaceSection, Boolean(nextToken)), nextToken, force); } async function ensureData(keys: DataKey[], nextToken = token, force = false) { const uniqueKeys = Array.from(new Set(keys)); const requestKeys = uniqueKeys.filter((key) => { if (!force && loadedDataKeysRef.current.has(key)) return false; if (loadingDataKeysRef.current.has(key)) return false; return key === 'health' || key === 'publicCatalog' || Boolean(nextToken); }); if (requestKeys.length === 0) return; requestKeys.forEach((key) => loadingDataKeysRef.current.add(key)); setState('loading'); setError(''); try { await Promise.all(requestKeys.map((key) => loadDataKey(key, nextToken))); requestKeys.forEach((key) => loadedDataKeysRef.current.add(key)); setState('ready'); } catch (err) { setState('error'); setError(err instanceof Error ? err.message : '加载失败'); } finally { requestKeys.forEach((key) => loadingDataKeysRef.current.delete(key)); } } async function loadDataKey(key: DataKey, nextToken: string) { switch (key) { case 'health': { setHealth(await getHealth()); return; } case 'publicCatalog': { const [providersResult, baseModelsResult] = await Promise.all([ listPublicCatalogProviders(), listPublicBaseModels(), ]); setProviders(providersResult.items); setBaseModels(baseModelsResult.items); return; } case 'platforms': setPlatforms((await listPlatforms(nextToken)).items); return; case 'models': setModels((await listModels(nextToken)).items); return; case 'modelCatalog': setModelCatalog(await listModelCatalog(nextToken)); return; case 'playgroundModels': setPlaygroundModels((await listPlayableModels(nextToken)).items); return; case 'playgroundApiKeys': { const response = await listPlayableApiKeys(nextToken); setApiKeys(response.items); setApiKeySecretsById(Object.fromEntries(response.items.map((item) => [item.id, item.secret]))); setSelectedPlaygroundApiKeyId((current) => current && response.items.some((item) => item.id === current) ? current : response.items[0]?.id ?? ''); return; } case 'providers': setProviders((await listCatalogProviders(nextToken)).items); return; case 'baseModels': setBaseModels((await listBaseModels(nextToken)).items); return; case 'pricingRules': setPricingRules((await listPricingRules(nextToken)).items); return; case 'pricingRuleSets': setPricingRuleSets((await listPricingRuleSets(nextToken)).items); return; case 'runtimePolicySets': setRuntimePolicySets((await listRuntimePolicySets(nextToken)).items); return; case 'rateLimitWindows': setRateLimitWindows((await listRateLimitWindows(nextToken)).items); return; case 'tenants': setTenants((await listTenants(nextToken)).items); return; case 'users': setUsers((await listUsers(nextToken)).items); return; case 'userGroups': setUserGroups((await listUserGroups(nextToken)).items); return; case 'tasks': { const requestKey = taskListRequestKey; const response = await listTasks(nextToken, workspaceTaskQuery); if (requestKey !== currentTaskQueryKeyRef.current) return; setTasks(response.items); setTaskTotal(response.total ?? response.items.length); loadedTaskQueryKeyRef.current = requestKey; } return; case 'accessRules': setAccessRules((await (activePage === 'workspace' && workspaceSection === 'apiKeys' ? listApiKeyAccessRules(nextToken) : listAccessRules(nextToken))).items); return; case 'auditLogs': setAuditLogs((await listAuditLogs(nextToken)).items); return; case 'apiKeys': setApiKeys((await listApiKeys(nextToken)).items); } } async function submitLogin(event: FormEvent) { event.preventDefault(); await authenticate(() => loginLocalAccount(loginForm), '登录失败'); } async function submitRegister(event: FormEvent) { event.preventDefault(); await authenticate(() => registerLocalAccount(registerForm), '注册失败'); } async function submitExternalToken(event: FormEvent) { event.preventDefault(); const nextToken = externalToken.trim(); if (!nextToken) { setError('请填写 access token'); return; } persistAccessToken(nextToken); setToken(nextToken); await ensureRouteData(nextToken, true); } async function authenticate(request: () => Promise<{ accessToken: string }>, fallback: string) { setState('loading'); setError(''); try { const response = await request(); persistAccessToken(response.accessToken); setToken(response.accessToken); await ensureRouteData(response.accessToken, true); } catch (err) { setState('error'); setError(err instanceof Error ? err.message : fallback); } } async function submitAPIKey(event: FormEvent) { event.preventDefault(); setCoreState('loading'); setCoreMessage(''); try { const response = await createApiKey(token, { name: apiKeyForm.name, scopes: ['chat', 'image', 'video'], expiresAt: apiKeyForm.expiresAt ? new Date(apiKeyForm.expiresAt).toISOString() : undefined, }); setApiKeySecret(response.secret); setApiKeySecretsById((current) => ({ ...current, [response.apiKey.id]: response.secret })); setSelectedPlaygroundApiKeyId(response.apiKey.id); setApiKeys((current) => [response.apiKey, ...current.filter((item) => item.id !== response.apiKey.id)]); setApiKeyForm({ name: '', expiresAt: '' }); setCoreState('ready'); setCoreMessage('API Key 已创建,secret 仅展示一次。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : '创建 API Key 失败'); throw err; } } async function savePlatformWithModels(input: PlatformWithModelsInput) { setCoreState('loading'); setCoreMessage(''); try { const platform = input.platformId ? await updatePlatform(token, input.platformId, input.platform) : await createPlatform(token, input.platform); const platformForState = withCredentialPreviewFallback( platform, input.platform, input.platformId ? platforms.find((item) => item.id === input.platformId) : undefined, ); const modelBindings = input.models.map((modelInput) => mergeExistingPlatformModelInput(modelInput, models, platform.id)); const modelsResponse = await replacePlatformModels(token, platform.id, modelBindings); setPlatforms((current) => [platformForState, ...current.filter((item) => item.id !== platform.id)]); setModels((current) => [...current.filter((model) => model.platformId !== platform.id), ...modelsResponse.items]); invalidateDataKeys('modelCatalog'); setCoreState('ready'); setCoreMessage(input.platformId ? `平台已更新,当前绑定 ${input.models.length} 个模型。` : `平台已创建,已绑定 ${input.models.length} 个模型。`); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : input.platformId ? '更新平台失败' : '创建平台失败'); throw err; } } async function removePlatform(platformId: string) { setCoreState('loading'); setCoreMessage(''); try { await deletePlatform(token, platformId); setPlatforms((current) => current.filter((item) => item.id !== platformId)); setModels((current) => current.filter((item) => item.platformId !== platformId)); invalidateDataKeys('modelCatalog'); setCoreState('ready'); setCoreMessage('平台已删除。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : '删除平台失败'); throw err; } } async function saveTenant(input: GatewayTenantUpsertRequest, tenantId?: string) { setCoreState('loading'); setCoreMessage(''); try { const item = tenantId ? await updateTenant(token, tenantId, input) : await createTenant(token, input); setTenants((current) => [item, ...current.filter((tenant) => tenant.id !== item.id)]); setCoreState('ready'); setCoreMessage(tenantId ? '租户已更新。' : '租户已创建。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : tenantId ? '更新租户失败' : '创建租户失败'); throw err; } } async function removeTenant(tenantId: string) { setCoreState('loading'); setCoreMessage(''); try { await deleteTenant(token, tenantId); setTenants((current) => current.filter((tenant) => tenant.id !== tenantId)); setCoreState('ready'); setCoreMessage('租户已删除。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : '删除租户失败'); throw err; } } async function saveUser(input: GatewayUserUpsertRequest, userId?: string) { setCoreState('loading'); setCoreMessage(''); try { const item = userId ? await updateGatewayUser(token, userId, input) : await createGatewayUser(token, input); setUsers((current) => [item, ...current.filter((user) => user.id !== item.id)]); invalidateDataKeys('playgroundModels'); setCoreState('ready'); setCoreMessage(userId ? '用户已更新。' : '用户已创建。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : userId ? '更新用户失败' : '创建用户失败'); throw err; } } async function saveUserWalletBalance(userId: string, input: WalletBalanceAdjustmentRequest) { setCoreState('loading'); setCoreMessage(''); try { const response = await setUserWalletBalance(token, userId, input); setUsers((current) => current.map((user) => user.id === userId ? { ...user, walletAccounts: [ response.account, ...(user.walletAccounts ?? []).filter((account) => account.id !== response.account.id), ], } : user)); setAuditLogs((current) => [response.auditLog, ...current.filter((item) => item.id !== response.auditLog.id)]); invalidateDataKeys('auditLogs'); setCoreState('ready'); setCoreMessage('用户余额已更新,审计日志已记录。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : '更新用户余额失败'); throw err; } } async function removeUser(userId: string) { setCoreState('loading'); setCoreMessage(''); try { await deleteGatewayUser(token, userId); setUsers((current) => current.filter((user) => user.id !== userId)); setCoreState('ready'); setCoreMessage('用户已删除。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : '删除用户失败'); throw err; } } async function saveUserGroup(input: UserGroupUpsertRequest, groupId?: string) { setCoreState('loading'); setCoreMessage(''); try { const item = groupId ? await updateUserGroup(token, groupId, input) : await createUserGroup(token, input); setUserGroups((current) => [item, ...current.filter((group) => group.id !== item.id)]); invalidateDataKeys('modelCatalog'); setCoreState('ready'); setCoreMessage(groupId ? '用户组已更新。' : '用户组已创建。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : groupId ? '更新用户组失败' : '创建用户组失败'); throw err; } } async function removeUserGroup(groupId: string) { setCoreState('loading'); setCoreMessage(''); try { await deleteUserGroup(token, groupId); setUserGroups((current) => current.filter((group) => group.id !== groupId)); setTenants((current) => current.map((tenant) => tenant.defaultUserGroupId === groupId ? { ...tenant, defaultUserGroupId: undefined } : tenant)); setUsers((current) => current.map((user) => user.defaultUserGroupId === groupId ? { ...user, defaultUserGroupId: undefined } : user)); invalidateDataKeys('modelCatalog'); invalidateDataKeys('playgroundModels'); setCoreState('ready'); setCoreMessage('用户组已删除。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : '删除用户组失败'); throw err; } } async function removeAPIKey(apiKeyId: string) { setCoreState('loading'); setCoreMessage(''); try { await deleteApiKey(token, apiKeyId); setApiKeys((current) => current.filter((item) => item.id !== apiKeyId)); setAccessRules((current) => current.filter((rule) => !(rule.subjectType === 'api_key' && rule.subjectId === apiKeyId))); setApiKeySecretsById((current) => { const next = { ...current }; delete next[apiKeyId]; return next; }); if (selectedPlaygroundApiKeyId === apiKeyId) setSelectedPlaygroundApiKeyId(''); setCoreState('ready'); setCoreMessage('API Key 已删除,对应权限策略已同步清理。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : '删除 API Key 失败'); throw err; } } async function saveAccessRule(input: GatewayAccessRuleUpsertRequest, ruleId?: string) { setCoreState('loading'); setCoreMessage(''); try { const item = ruleId ? await updateAccessRule(token, ruleId, input) : await createAccessRule(token, input); setAccessRules((current) => [item, ...current.filter((rule) => rule.id !== item.id)]); invalidateDataKeys('playgroundModels', 'modelCatalog'); setCoreState('ready'); setCoreMessage(ruleId ? '访问权限规则已更新。' : '访问权限规则已创建。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : ruleId ? '更新访问权限失败' : '创建访问权限失败'); throw err; } } async function removeAccessRule(ruleId: string) { setCoreState('loading'); setCoreMessage(''); try { await deleteAccessRule(token, ruleId); setAccessRules((current) => current.filter((rule) => rule.id !== ruleId)); invalidateDataKeys('playgroundModels', 'modelCatalog'); setCoreState('ready'); setCoreMessage('访问权限规则已删除。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : '删除访问权限失败'); throw err; } } async function batchSaveAccessRules(input: GatewayAccessRuleBatchRequest) { setCoreState('loading'); setCoreMessage(''); try { const response = await batchAccessRules(token, input); setAccessRules(response.items); invalidateDataKeys('playgroundModels', 'modelCatalog'); setCoreState('ready'); setCoreMessage('访问权限已更新。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : '批量更新访问权限失败'); throw err; } } async function batchSaveAPIKeyAccessRules(input: GatewayAccessRuleBatchRequest) { setCoreState('loading'); setCoreMessage(''); try { const response = await batchApiKeyAccessRules(token, input); setAccessRules(response.items); setCoreState('ready'); setCoreMessage('API Key 权限已更新。'); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : '批量更新 API Key 权限失败'); throw err; } } async function submitTask(event: FormEvent) { event.preventDefault(); const credential = apiKeySecret || token; setCoreState('loading'); setCoreMessage(''); try { const response = await runTask(credential, taskForm); const detail = await getTask(credential, response.task.id); setTaskResult(detail); setTasks((current) => [detail, ...current.filter((item) => item.id !== detail.id)]); invalidateDataKeys('tasks'); setCoreState('ready'); setCoreMessage(`${taskForm.kind} 已通过 ${apiKeySecret ? '本地 API Key' : '当前 Access Token'} 完成 simulation。`); } catch (err) { setCoreState('error'); setCoreMessage(err instanceof Error ? err.message : '测试任务失败'); } } function signOut() { persistAccessToken(''); setToken(''); loadedDataKeysRef.current = new Set(health ? ['health'] : []); loadingDataKeysRef.current.clear(); setState('idle'); setPlatforms([]); setModels([]); setModelCatalog({ items: [], filters: { capabilities: [], providers: [] }, summary: { modelCount: 0, sourceCount: 0 } }); setPlaygroundModels([]); setProviders([]); setBaseModels([]); setPricingRules([]); setPricingRuleSets([]); setRuntimePolicySets([]); setAccessRules([]); setAuditLogs([]); setRateLimitWindows([]); setTenants([]); setUsers([]); setUserGroups([]); setApiKeys([]); setApiKeySecret(''); setApiKeySecretsById({}); setSelectedPlaygroundApiKeyId(''); setTaskResult(null); setTasks([]); setTaskTotal(0); setCoreMessage(''); navigatePath('/'); } function showLogin() { setAuthMode('login'); navigatePath(pathForWorkspaceSection('overview')); } function currentRouteState(): AppRouteState { return { activePage, adminSection, apiDocSection, playgroundMode, workspaceSection, workspaceTaskQuery }; } function applyRoute(route: AppRouteState) { setActivePage(route.activePage); setAdminSection(route.adminSection); setApiDocSection(route.apiDocSection); setPlaygroundMode(route.playgroundMode); setWorkspaceSection(route.workspaceSection); setWorkspaceTaskQuery(route.workspaceTaskQuery); } function navigatePath(path: string) { if (`${window.location.pathname}${window.location.search}` !== path) { window.history.pushState(null, '', path); } applyRoute(parseAppRoute(path)); } function navigatePage(page: PageKey) { navigatePath(pathForPage(page, currentRouteState())); } function navigateAdminSection(section: AdminSection) { navigatePath(pathForAdminSection(section)); } function navigateWorkspaceSection(section: WorkspaceSection) { navigatePath(pathForWorkspaceSection(section)); } function navigateWorkspaceTaskQuery(query: WorkspaceTaskQuery) { navigatePath(pathForWorkspaceTaskQuery(query)); } function navigateApiDocSection(section: ApiDocSection) { navigatePath(pathForApiDocSection(section)); } function navigatePlaygroundMode(mode: PlaygroundMode) { navigatePath(pathForPlaygroundMode(mode)); } function openApiKeyCreation() { navigatePath(pathForWorkspaceSection('apiKeys')); } function useApiKeyForPlayground(apiKeyId?: string) { if (apiKeyId) setSelectedPlaygroundApiKeyId(apiKeyId); navigatePath(pathForPlaygroundMode('chat')); } const isAuthenticated = Boolean(token); return ( void refresh()} onSignOut={signOut} > {error &&
{error}
} {activePage === 'home' && } {activePage === 'playground' && ( )} {activePage === 'models' && } {activePage === 'workspace' && ( isAuthenticated ? ( ) : ( ) )} {activePage === 'admin' && ( isAuthenticated ? ( ) : ( ) )} {activePage === 'docs' && ( )}
); } function platformModelIsSelected(model: PlatformModel, selectedModels: PlatformModelBindingInput[]) { return selectedModels.some((selected) => { if (selected.baseModelId && model.baseModelId) return selected.baseModelId === model.baseModelId; return selected.modelName === model.modelName && sameModelTypes(selected.modelType, model.modelType); }); } function sameModelTypes(left: string[], right: string[]) { if (left.length !== right.length) return false; const rightSet = new Set(right); return left.every((type) => rightSet.has(type)); } function mergeExistingPlatformModelInput(input: PlatformModelBindingInput, currentModels: PlatformModel[], platformId: string): PlatformModelBindingInput { const existing = currentModels.find((model) => model.platformId === platformId && platformModelIsSelected(model, [input])); if (!existing) return input; return { ...input, providerModelName: input.providerModelName ?? existing.providerModelName, discountFactor: (input.discountFactor ?? existing.discountFactor) || undefined, pricingRuleSetId: input.pricingRuleSetId ?? existing.pricingRuleSetId, rateLimitPolicy: input.rateLimitPolicy ?? existing.rateLimitPolicy, retryPolicy: input.retryPolicy ?? existing.retryPolicy, runtimePolicyOverride: input.runtimePolicyOverride ?? (existing.runtimePolicyOverride as Record | undefined), runtimePolicySetId: input.runtimePolicySetId ?? existing.runtimePolicySetId, }; } function withCredentialPreviewFallback( platform: IntegrationPlatform, input: PlatformCreateInput, existing?: IntegrationPlatform, ): IntegrationPlatform { const responsePreview = nonEmptyRecord(platform.credentialsPreview); if (responsePreview) return platform; if (input.credentials !== undefined) { const inputPreview = maskCredentialsPreview(input.credentials); return { ...platform, credentialsPreview: inputPreview ?? {} }; } const existingPreview = nonEmptyRecord(existing?.credentialsPreview); return existingPreview ? { ...platform, credentialsPreview: existingPreview } : platform; } function maskCredentialsPreview(credentials: Record | undefined) { if (!credentials || Object.keys(credentials).length === 0) return undefined; return Object.fromEntries(Object.entries(credentials).map(([key, value]) => [key, maskCredentialValue(value)])); } function maskCredentialValue(value: unknown): unknown { if (typeof value === 'string') return maskSecret(value); if (Array.isArray(value)) return value.map(maskCredentialValue); if (value && typeof value === 'object') { return Object.fromEntries(Object.entries(value as Record).map(([key, nested]) => [key, maskCredentialValue(nested)])); } return value; } function maskSecret(value: string) { const trimmed = value.trim(); if (!trimmed) return ''; if (trimmed.length <= 6) return '*'.repeat(trimmed.length); return `${trimmed.slice(0, 3)}${'*'.repeat(trimmed.length - 6)}${trimmed.slice(-3)}`; } function nonEmptyRecord(value: Record | undefined) { return value && Object.keys(value).length > 0 ? value : undefined; } function dataKeysForRoute( activePage: PageKey, adminSection: AdminSection, workspaceSection: WorkspaceSection, isAuthenticated: boolean, ): DataKey[] { if (activePage === 'playground') return isAuthenticated ? ['playgroundModels', 'playgroundApiKeys'] : []; if (activePage === 'models') { return isAuthenticated ? ['modelCatalog'] : ['publicCatalog']; } if (activePage === 'home' || activePage === 'docs') return []; if (!isAuthenticated) return []; if (activePage === 'workspace') { if (workspaceSection === 'overview') return ['users', 'userGroups', 'apiKeys']; if (workspaceSection === 'apiKeys') return ['apiKeys', 'accessRules', 'playgroundModels']; if (workspaceSection === 'tasks') return ['tasks']; return []; } if (activePage !== 'admin') return []; switch (adminSection) { case 'overview': return ['platforms', 'models', 'providers', 'pricingRules', 'runtimePolicySets', 'rateLimitWindows', 'tenants', 'users', 'userGroups', 'accessRules']; case 'globalModels': return ['providers']; case 'pricing': return ['pricingRuleSets']; case 'runtime': return ['runtimePolicySets']; case 'baseModels': return ['baseModels', 'providers', 'pricingRuleSets', 'runtimePolicySets']; case 'platforms': return ['platforms', 'models', 'providers', 'baseModels', 'pricingRuleSets']; case 'tenants': return ['tenants', 'userGroups']; case 'users': return ['users', 'tenants', 'userGroups']; case 'userGroups': return ['userGroups']; case 'auditLogs': return ['auditLogs']; case 'accessRules': return ['accessRules', 'userGroups', 'platforms', 'models']; default: return []; } }