diff options
Diffstat (limited to 'app/ui/hub.py')
| -rw-r--r-- | app/ui/hub.py | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/app/ui/hub.py b/app/ui/hub.py index 7a6bfcc..1b6b5bd 100644 --- a/app/ui/hub.py +++ b/app/ui/hub.py @@ -2294,9 +2294,25 @@ def _sglomni_fields(stdscr, api_url: Optional[str] = None, voice_field["value"] = "" def instructions_validate(value) -> Optional[str]: - if model_capability(fields) != "design" or str(value).strip(): + """Required on design entries (the voice comes from it); an + optional delivery/style control on entries that support one.""" + if str(value or "").strip(): return None - return "Describe the voice, e.g. 'A warm female narrator'" + if model_capability(fields) == "design": + return "Describe the voice, e.g. 'A warm female narrator'" + return None + + def instructions_help(entry) -> list: + if entry.capability == "design": + return ["Describe the voice to design, e.g.", + '"A warm adult female narrator with a British accent".'] + return ["Delivery/style instruction (supported by this model), e.g.", + '"Speak in a calm, soothing, and happy tone."'] + + def instructions_visible(fs) -> bool: + entry = model_entry(fs) + return (entry.capability == "design" + or getattr(entry, "supports_instructions", False)) # The Model picker reads as a table, like the audio.cpp one: pad every # label to the widest one, then render each entry's capabilities as @@ -2357,10 +2373,9 @@ def _sglomni_fields(stdscr, api_url: Optional[str] = None, "clone")}, {"key": prefix + "instructions", "label": "Instructions", "kind": "text", "value": "", - "help": ["Describe the voice to design, e.g.", - '"A warm adult female narrator with a British accent".'], + "help": lambda fs: instructions_help(model_entry(fs)), "validate": instructions_validate, - "visible": lambda fs: model_capability(fs) == "design"}, + "visible": instructions_visible}, ] def mapper(result) -> Optional[tuple]: @@ -2380,6 +2395,13 @@ def _sglomni_fields(stdscr, api_url: Optional[str] = None, kwargs["voice"] = pick else: kwargs["instructions"] = result[prefix + "instructions"] + # Style/delivery instructions forward on every entry that takes + # them (design required, supported entries optional — the client + # rejects unsupported combinations instead of dropping the text). + instructions = ((result.get(prefix + "instructions") + or "").strip() or None) + if instructions: + kwargs["instructions"] = instructions # The run view's Model/Voice rows: the catalog label, and the # pick — or the clone reference's file name (the .wav stems, # like the narrator tags). Design models describe the voice, @@ -2442,6 +2464,12 @@ def _settings_fields() -> list: "validate": _validate_language}, {"key": "chunk_size", "label": "Chunk size (words)", "kind": "text", "value": str(config.CHUNK_SIZE), "validate": _validate_chunk_size}, + {"key": "smart_chunking", "label": "Smart chunking", "kind": "bool", + "value": config.SMART_CHUNKING, + "help": ["End each request at the end of a sentence or " + "quotation instead of mid-sentence.", + "Chunks may be shorter than Chunk size; it stays " + "the maximum."]}, {"key": "input_dir", "label": "Input Directory", "kind": "dir", "value": converter_mod.resolve_dir(config.INPUT_DIR, "input"), "validate": _validate_dir}, @@ -2622,6 +2650,7 @@ def _apply_settings(values: dict) -> None: "AUDIO_BITRATE": bitrate, "LANGUAGE": normalize_language(values["language"]), "CHUNK_SIZE": chunk_size, + "SMART_CHUNKING": bool(values["smart_chunking"]), "INPUT_DIR": input_dir, "OUTPUT_DIR": output_dir, "CLONE_WAV_DIR": clone_dir, |
