This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

tools.hermes-voice: list all gpt-live-1 voices with language and character

+52 -11
+43 -9
tools/hermes-voice/hermes_voice.py
··· 43 43 OPENAI_BASE_URL = "https://api.openai.com/v1" 44 44 DEFAULT_MODEL = "gpt-live-1" 45 45 DEFAULT_VOICE = "marin" 46 - # gpt-live-1 built-in voices (live-conversations guide voice table, plus the 47 - # realtime defaults marin and cedar). 48 - BUILT_IN_VOICES = ( 49 - "marin", "cedar", "quartz", "ripple", "vesper", "willow", "stone", "gleam", 50 - "meridian", "bossa", "tempo", "beacon", "delta", "cinder", 51 - ) 46 + # gpt-live-1 voices as OpenAI's voice picker lists them: language, regional 47 + # influence, presentation and character, natural voices first, then the 48 + # generated ones. The docs' voice table and the openai SDK (3.28.0) list only 49 + # part of them; /v1/live/sessions accepts the German, French, Hindi, Japanese 50 + # and Korean voices as well, while an unknown name is refused with 403. 51 + BUILT_IN_VOICES = { 52 + "gleam": "English, North American, female: warm and conversational", 53 + "ripple": "English, Australian, male: warm and conversational", 54 + "vesper": "English, British, male: clear and direct", 55 + "willow": "English, Irish, female: expressive and bright", 56 + "stone": "English, Irish, male: calm and precise", 57 + "meridian": "English, North American, male: grounded and measured", 58 + "bossa": "Portuguese, Brazilian, female: clear and direct", 59 + "tempo": "Portuguese, Brazilian, male: grounded and measured", 60 + "cedar": "English, North American, male: open and upbeat", 61 + "marin": "English, North American, female: animated and earnest", 62 + "nuri": "German, female: warm and animated", 63 + "juni": "German, female: bright and expressive", 64 + "flitz": "German, male: rich and playful", 65 + "brise": "French, female: clear and conversational", 66 + "sillage": "French, male: warm and grounded", 67 + "nira": "Hindi, female: soft and thoughtful", 68 + "harema": "Japanese, female: gentle and engaging", 69 + "shida": "Japanese, male: quiet and grounded", 70 + "noeul": "Korean, female: airy and expressive", 71 + "quartz": "English, Australian, female, generated: warm and conversational", 72 + "alloy": "English, North American, male, generated: balanced and clear", 73 + "ash": "English, North American, male, generated: savvy and relaxed", 74 + "ballad": "English, North American, male, generated: cheerful and candid", 75 + "coral": "English, North American, female, generated: easygoing and versatile", 76 + "echo": "English, North American, male, generated: bright and inquisitive", 77 + "sage": "English, North American, female, generated: confident and optimistic", 78 + "shimmer": "English, North American, female, generated: composed and direct", 79 + "verse": "English, North American, male, generated: calm and affirming", 80 + "beacon": "English, Filipino, male, generated: clear and personable", 81 + "delta": "English, Southern U.S., female, generated: warm and easygoing", 82 + "cinder": "English, Southern U.S., male, generated: steady and grounded", 83 + } 52 84 # gpt-live-1 bills every second a session is open, silence included; the page 53 85 # closes the session after this much inactivity. 54 86 DEFAULT_IDLE_SECONDS = 90 ··· 137 169 ) 138 170 139 171 def voices(self): 140 - """Voices the page may pick: the built-ins plus the configured one 141 - (which may be a custom voice id).""" 142 - return list(dict.fromkeys([self.voice, *BUILT_IN_VOICES])) 172 + """Voices the page may pick, name -> description: the built-ins plus 173 + the configured one (which may be a custom voice id).""" 174 + voices = dict(BUILT_IN_VOICES) 175 + voices.setdefault(self.voice, "custom voice") 176 + return voices 143 177 144 178 145 179 def voice_param(voice):
+4 -2
tools/hermes-voice/static/app.js
··· 625 625 setStatus("Idle"); 626 626 const saved = localStorage.getItem(VOICE_KEY); 627 627 voiceSelect.replaceChildren( 628 - ...config.voices.map((name) => new Option(name, name)), 628 + ...Object.entries(config.voices).map( 629 + ([name, description]) => new Option(`${name} — ${description}`, name), 630 + ), 629 631 ); 630 - voiceSelect.value = config.voices.includes(saved) ? saved : config.voice; 632 + voiceSelect.value = saved in config.voices ? saved : config.voice; 631 633 } 632 634 633 635 loadConfig();
+5
tools/hermes-voice/static/style.css
··· 27 27 28 28 header { 29 29 display: flex; 30 + flex-wrap: wrap; 30 31 align-items: baseline; 31 32 justify-content: space-between; 32 33 } ··· 37 38 } 38 39 39 40 #voice-select { 41 + /* Labels carry the language and accent: a full-width row under the title. */ 42 + order: 3; 43 + flex-basis: 100%; 44 + margin-bottom: 0.5rem; 40 45 background: #222; 41 46 color: var(--fg); 42 47 border: 1px solid #444;