feat: add local audio test mode

This commit is contained in:
2026-04-30 02:37:54 +09:00
parent 9dee708b64
commit cf6398f50a
12 changed files with 766 additions and 256 deletions

View File

@@ -4,17 +4,20 @@ import { z } from "zod";
loadDotenv();
const envSchema = z.object({
DISCORD_BOT_TOKEN: z.string().min(1),
DISCORD_APPLICATION_ID: z.string().min(1),
DISCORD_BOT_TOKEN: z.string().min(1).optional(),
DISCORD_APPLICATION_ID: z.string().min(1).optional(),
DISCORD_COMMAND_GUILD_ID: z.string().min(1).optional(),
OPENAI_API_KEY: z.string().min(1),
OPENAI_API_KEY: z.string().min(1).optional(),
OPENAI_MODEL: z.string().min(1).default("gpt-5.4-mini"),
ELEVENLABS_API_KEY: z.string().min(1),
ELEVENLABS_VOICE_ID: z.string().min(1),
ELEVENLABS_API_KEY: z.string().min(1).optional(),
ELEVENLABS_VOICE_ID: z.string().min(1).optional(),
ELEVENLABS_STT_MODEL: z.string().min(1).default("scribe_v2_realtime"),
ELEVENLABS_TTS_MODEL: z.string().min(1).default("eleven_flash_v2_5"),
BOT_DEFAULT_LANGUAGE: z.string().min(2).default("ko"),
MAX_CONVERSATION_TURNS: z.coerce.number().int().min(4).max(30).default(12),
LOCAL_AUDIO_SOURCE: z.string().min(1).optional(),
LOCAL_AUDIO_SINK: z.string().min(1).optional(),
LOCAL_SPEAKER_NAME: z.string().min(1).default("local-user"),
DEBUG_TEXT_EVENTS: z
.string()
.optional()
@@ -23,7 +26,41 @@ const envSchema = z.object({
});
export type AppConfig = z.infer<typeof envSchema>;
export type AssistantRuntimeConfig = AppConfig & {
OPENAI_API_KEY: string;
ELEVENLABS_API_KEY: string;
ELEVENLABS_VOICE_ID: string;
};
export type DiscordRuntimeConfig = AssistantRuntimeConfig & {
DISCORD_BOT_TOKEN: string;
DISCORD_APPLICATION_ID: string;
};
export function loadConfig(): AppConfig {
return envSchema.parse(process.env);
}
function requirePresent(value: string | undefined, name: string): string {
if (!value) {
throw new Error(`${name} 환경변수가 필요합니다.`);
}
return value;
}
export function requireAssistantRuntimeConfig(config: AppConfig): AssistantRuntimeConfig {
return {
...config,
OPENAI_API_KEY: requirePresent(config.OPENAI_API_KEY, "OPENAI_API_KEY"),
ELEVENLABS_API_KEY: requirePresent(config.ELEVENLABS_API_KEY, "ELEVENLABS_API_KEY"),
ELEVENLABS_VOICE_ID: requirePresent(config.ELEVENLABS_VOICE_ID, "ELEVENLABS_VOICE_ID"),
};
}
export function requireDiscordRuntimeConfig(config: AppConfig): DiscordRuntimeConfig {
const assistant = requireAssistantRuntimeConfig(config);
return {
...assistant,
DISCORD_BOT_TOKEN: requirePresent(config.DISCORD_BOT_TOKEN, "DISCORD_BOT_TOKEN"),
DISCORD_APPLICATION_ID: requirePresent(config.DISCORD_APPLICATION_ID, "DISCORD_APPLICATION_ID"),
};
}