···4343OPENAI_BASE_URL = "https://api.openai.com/v1"
4444DEFAULT_MODEL = "gpt-live-1"
4545DEFAULT_VOICE = "marin"
4646-# gpt-live-1 built-in voices (live-conversations guide voice table, plus the
4747-# realtime defaults marin and cedar).
4848-BUILT_IN_VOICES = (
4949- "marin", "cedar", "quartz", "ripple", "vesper", "willow", "stone", "gleam",
5050- "meridian", "bossa", "tempo", "beacon", "delta", "cinder",
5151-)
4646+# gpt-live-1 voices as OpenAI's voice picker lists them: language, regional
4747+# influence, presentation and character, natural voices first, then the
4848+# generated ones. The docs' voice table and the openai SDK (3.28.0) list only
4949+# part of them; /v1/live/sessions accepts the German, French, Hindi, Japanese
5050+# and Korean voices as well, while an unknown name is refused with 403.
5151+BUILT_IN_VOICES = {
5252+ "gleam": "English, North American, female: warm and conversational",
5353+ "ripple": "English, Australian, male: warm and conversational",
5454+ "vesper": "English, British, male: clear and direct",
5555+ "willow": "English, Irish, female: expressive and bright",
5656+ "stone": "English, Irish, male: calm and precise",
5757+ "meridian": "English, North American, male: grounded and measured",
5858+ "bossa": "Portuguese, Brazilian, female: clear and direct",
5959+ "tempo": "Portuguese, Brazilian, male: grounded and measured",
6060+ "cedar": "English, North American, male: open and upbeat",
6161+ "marin": "English, North American, female: animated and earnest",
6262+ "nuri": "German, female: warm and animated",
6363+ "juni": "German, female: bright and expressive",
6464+ "flitz": "German, male: rich and playful",
6565+ "brise": "French, female: clear and conversational",
6666+ "sillage": "French, male: warm and grounded",
6767+ "nira": "Hindi, female: soft and thoughtful",
6868+ "harema": "Japanese, female: gentle and engaging",
6969+ "shida": "Japanese, male: quiet and grounded",
7070+ "noeul": "Korean, female: airy and expressive",
7171+ "quartz": "English, Australian, female, generated: warm and conversational",
7272+ "alloy": "English, North American, male, generated: balanced and clear",
7373+ "ash": "English, North American, male, generated: savvy and relaxed",
7474+ "ballad": "English, North American, male, generated: cheerful and candid",
7575+ "coral": "English, North American, female, generated: easygoing and versatile",
7676+ "echo": "English, North American, male, generated: bright and inquisitive",
7777+ "sage": "English, North American, female, generated: confident and optimistic",
7878+ "shimmer": "English, North American, female, generated: composed and direct",
7979+ "verse": "English, North American, male, generated: calm and affirming",
8080+ "beacon": "English, Filipino, male, generated: clear and personable",
8181+ "delta": "English, Southern U.S., female, generated: warm and easygoing",
8282+ "cinder": "English, Southern U.S., male, generated: steady and grounded",
8383+}
5284# gpt-live-1 bills every second a session is open, silence included; the page
5385# closes the session after this much inactivity.
5486DEFAULT_IDLE_SECONDS = 90
···137169 )
138170139171 def voices(self):
140140- """Voices the page may pick: the built-ins plus the configured one
141141- (which may be a custom voice id)."""
142142- return list(dict.fromkeys([self.voice, *BUILT_IN_VOICES]))
172172+ """Voices the page may pick, name -> description: the built-ins plus
173173+ the configured one (which may be a custom voice id)."""
174174+ voices = dict(BUILT_IN_VOICES)
175175+ voices.setdefault(self.voice, "custom voice")
176176+ return voices
143177144178145179def voice_param(voice):