diff --git a/.env.example b/.env.example index 9989df977..5614024ed 100644 --- a/.env.example +++ b/.env.example @@ -1,13 +1,11 @@ # [Recommended for local deployments] Backend API key for OpenAI, so that users don't need one (UI > this > '') OPENAI_API_KEY= - # [Not needed] Set the backend host for the OpenAI API, to enable platforms such as Helicone (UI > this > api.openai.com) OPENAI_API_HOST= - # [Not needed] Sets the "OpenAI-Organization" header field to support organization users (UI > this > '') OPENAI_API_ORG_ID= -# [Optional] Sets the API Key and Host for ElevenLabs, for optional text-to-speech +# [Optional] Enables ElevenLabs credentials on the server side - for optional text-to-speech ELEVENLABS_API_KEY= ELEVENLABS_API_HOST= ELEVENLABS_VOICE_ID= \ No newline at end of file diff --git a/components/dialogs/SettingsModal.tsx b/components/dialogs/SettingsModal.tsx index 53f0c38d7..15308e344 100644 --- a/components/dialogs/SettingsModal.tsx +++ b/components/dialogs/SettingsModal.tsx @@ -14,6 +14,11 @@ import { Link } from '@/components/util/Link'; import { useSettingsStore } from '@/lib/store-settings'; +export const requireUserKeyOpenAI = !process.env.HAS_SERVER_KEY_OPENAI; + +export const requireUserKeyElevenLabs = !process.env.HAS_SERVER_KEY_ELEVENLABS; + + export const isValidOpenAIApiKey = (apiKey?: string) => !!apiKey && apiKey.startsWith('sk-') && apiKey.length > 40; @@ -97,8 +102,7 @@ export function SettingsModal({ open, onClose }: { open: boolean, onClose: () => const handleMaxTokensChange = (event: Event, newValue: number | number[]) => setModelMaxResponseTokens(newValue as number); - const needsApiKey = !!process.env.REQUIRE_USER_API_KEYS; - const isValidKey = isValidOpenAIApiKey(apiKey); + const isValidOpenAIKey = isValidOpenAIApiKey(apiKey); const hideOnMobile = { display: { xs: 'none', md: 'flex' } }; @@ -114,10 +118,10 @@ export function SettingsModal({ open, onClose }: { open: boolean, onClose: () => - OpenAI API Key {needsApiKey ? '' : '(optional)'} + OpenAI API Key {requireUserKeyOpenAI ? '' : '(optional)'} } endDecorator={!!apiKey && ( @@ -128,7 +132,7 @@ export function SettingsModal({ open, onClose }: { open: boolean, onClose: () => /> - {needsApiKey + {requireUserKeyOpenAI ? <>Create Key, then apply to the GPT-4 waitlist : `This key will take precedence over the server's.`} Check usage here. @@ -261,7 +265,7 @@ export function SettingsModal({ open, onClose }: { open: boolean, onClose: () => - diff --git a/next.config.js b/next.config.js index 2a57ad882..e2b00a1f4 100644 --- a/next.config.js +++ b/next.config.js @@ -3,7 +3,8 @@ const nextConfig = { reactStrictMode: true, env: { // defaults to TRUE, unless API Keys are set at build time; this flag is used by the UI - REQUIRE_USER_API_KEYS: !process.env.OPENAI_API_KEY, + HAS_SERVER_KEY_OPENAI: !!process.env.OPENAI_API_KEY, + HAS_SERVER_KEY_ELEVENLABS: !!process.env.ELEVENLABS_API_KEY, }, webpack(config, { isServer, dev }) { // @mui/joy: anything material gets redirected to Joy diff --git a/pages/index.tsx b/pages/index.tsx index cdba83983..8e2d1c999 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -20,7 +20,7 @@ export default function Home() { // show the Settings Dialog at startup if the API key is required but not set React.useEffect(() => { - if (!!process.env.REQUIRE_USER_API_KEYS && !isValidOpenAIApiKey(apiKey)) + if (!process.env.HAS_SERVER_KEY_OPENAI && !isValidOpenAIApiKey(apiKey)) setSettingsShown(true); }, [apiKey]); diff --git a/tsconfig.json b/tsconfig.json index bd5ac8432..f46d49283 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,6 +22,6 @@ "@/types/*": ["types/*"] }, }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "include": ["next-env.d.ts", "types/**/*.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules"] } diff --git a/types/env.d.ts b/types/env.d.ts new file mode 100644 index 000000000..3b387c82b --- /dev/null +++ b/types/env.d.ts @@ -0,0 +1,27 @@ +// noinspection JSUnusedGlobalSymbols + +declare namespace NodeJS { + + // available to the server-side + interface ProcessEnv { + + // OpenAI - chat.ts + OPENAI_API_KEY: string; + OPENAI_API_HOST: string; + OPENAI_API_ORG_ID: string; + + // ElevenLabs - speech.ts + ELEVENLABS_API_KEY: string; + ELEVENLABS_API_HOST: string; + ELEVENLABS_VOICE_ID: string; + + } + + interface ProcessEnv { + + // set in next.config.js and available to the client-side + HAS_SERVER_KEY_OPENAI: boolean; + HAS_SERVER_KEY_ELEVENLABS: boolean; + + } +}