feat: settings web UI (models / STT / TTS speed / language / LLM instructions)
Adds /settings (served by the bridge) to change the LLM model (from installed Ollama models), Whisper model, TTS engine + MeloTTS speed, output language, agentic max-turns, thinking mode, and free-form LLM instructions — live, with a 'apply' that restarts the bridge + TTS worker. Settings persist to the runtime config JSON; engine reads output_language + llm_instructions and the TTS worker reads melo_speed from it. Bridge port publishable for access.
This commit is contained in:
@@ -826,6 +826,20 @@ def _build_enrichment_context_hint(cfg, recent_messages: list) -> Optional[str]:
|
||||
|
||||
|
||||
# Site tokens (proper nouns, not language patterns) → controlBrowser search site.
|
||||
def _extra_config(key: str, default=""):
|
||||
"""Read a key from the runtime config JSON (JARVIS_CONFIG_PATH) for settings
|
||||
the settings-web UI manages but that aren't on the Settings dataclass
|
||||
(llm_instructions, output_language override). Cheap + fail-open."""
|
||||
try:
|
||||
import json as _json
|
||||
from pathlib import Path as _Path
|
||||
p = os.environ.get("JARVIS_CONFIG_PATH")
|
||||
path = _Path(p).expanduser() if p else (_Path.home() / ".config" / "jarvis" / "config.json")
|
||||
return _json.loads(path.read_text("utf-8")).get(key, default) or default
|
||||
except Exception:
|
||||
return default
|
||||
|
||||
|
||||
_SITE_TOKEN_MAP = {
|
||||
"네이버": "naver", "naver": "naver",
|
||||
"구글": "google", "google": "google",
|
||||
@@ -1683,7 +1697,7 @@ def run_reply_engine(db: "Database", cfg, tts: Optional[Any],
|
||||
# it primacy over the persona's "use the user's language" lines — a tail
|
||||
# instruction loses to those when the query itself is in another language.
|
||||
_lang_directive = reply_language_directive(
|
||||
os.environ.get("OUTPUT_LANGUAGE"),
|
||||
os.environ.get("OUTPUT_LANGUAGE") or _extra_config("output_language", ""),
|
||||
getattr(cfg, "tts_engine", "piper"),
|
||||
)
|
||||
if _lang_directive:
|
||||
@@ -1768,6 +1782,11 @@ def run_reply_engine(db: "Database", cfg, tts: Optional[Any],
|
||||
# else: tools are passed via the native tools API parameter — do not include tools_desc
|
||||
# here as well, since that confuses the model and causes it to not use tools properly.
|
||||
|
||||
# User-defined extra LLM instructions from the settings UI.
|
||||
_user_instructions = str(_extra_config("llm_instructions", "")).strip()
|
||||
if _user_instructions:
|
||||
guidance.append("Additional instructions from the operator:\n" + _user_instructions)
|
||||
|
||||
# Recency reinforcement: repeat the language lock at the very END too.
|
||||
# In a ~5k-token prompt the front-placed rule gets "lost in the middle";
|
||||
# bigger models (qwen2.5:7b) otherwise leak Chinese/Cyrillic mid-reply.
|
||||
|
||||
Reference in New Issue
Block a user