/** Mask shown in the API key field when a key is already stored. The real * token never leaves the server; this is only so the field looks filled. */ export const STORED_API_KEY_MASK = "••••••••"; export type ProviderDraft = { modelId: string; baseUrl: string; apiKey: string; keyEdited: boolean; clearKey: boolean; }; export function emptyProviderDraft(modelId = "", baseUrl = ""): ProviderDraft { return { modelId, baseUrl, apiKey: "", keyEdited: false, clearKey: false }; } export function storedApiKeyFieldValue( stored: boolean, draft: Pick, ): string { if (stored && !draft.keyEdited && !draft.clearKey) return STORED_API_KEY_MASK; return draft.apiKey; } export function applyApiKeyInput( showingMask: boolean, next: string, ): Pick { if (showingMask) { const value = next.split("•").join(""); return { apiKey: value, keyEdited: value.length > 0, clearKey: false }; } return { apiKey: next, keyEdited: true, clearKey: false }; } /** What to send on save. `apiKey: null` means keep the stored secret. */ export function apiKeySavePayload( draft: Pick, ): { apiKey: string | null; clearApiKey: boolean } { if (draft.clearKey) return { apiKey: "", clearApiKey: true }; if (!draft.keyEdited) return { apiKey: null, clearApiKey: false }; const value = draft.apiKey.trim(); if (!value || value === STORED_API_KEY_MASK) return { apiKey: null, clearApiKey: false }; return { apiKey: value, clearApiKey: false }; } export function providerHasStoredKey( settings: { apiKeySet: boolean; provider: string; providers?: { id: string; apiKeySet?: boolean }[]; } | null, provider: string, ): boolean { const listed = settings?.providers?.find((item) => item.id === provider); if (listed && typeof listed.apiKeySet === "boolean") return listed.apiKeySet; return Boolean(settings?.apiKeySet && settings.provider === provider); }