feat: switch LLM to OpenWebUI with live model selection
Rebuild & Deploy / rebuild (push) Successful in 3m18s
Rebuild & Deploy / rebuild (push) Successful in 3m18s
- Point the agent at OpenWebUI's OpenAI-compatible API (LLM_BASE_URL,
LLM_API_KEY, LLM_MODEL) with GEMMA_* env fallbacks
- Add list_available_models() fetching {base_url}/models, filtering
non-chat ids (embedding/reranker)
- Rename GemmaLLM -> HopeLLM with update_options(model=...) for runtime
model switching (mutates _opts.model) and instance-based compaction
- Data channel: agent publishes {type: models} after connect and on
get_models; set_model switches live and acks model_changed
- Web UI: Brain section in the settings sheet with a model picker that
persists the choice in localStorage
- Update tests, CI workflow env, and docs for the new endpoint
This commit is contained in:
1 parent
024c42ffb1
commit
360e3276b0
14 files changed
+334
-76
No files matched your search
+12
-11
@@ -1,26 +1,27 @@
|
||||
"""Tests for GemmaLLM context compaction (agent.GemmaLLM._compact_context).
|
||||
"""Tests for HopeLLM context compaction (agent.HopeLLM._compact_context).
|
||||
|
||||
Compaction runs a real side LLM call to the xNAS, so these are marked slow.
|
||||
The agent module is imported inside the container via docker exec.
|
||||
Compaction runs a real side LLM call to the configured endpoint, so these
|
||||
are marked slow. The agent module is imported inside the container via
|
||||
docker exec.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from conftest import GEMMA_BASE_URL, GEMMA_MODEL, docker_exec_python
|
||||
from conftest import LLM_BASE_URL, LLM_MODEL, docker_exec_python
|
||||
|
||||
# {num_messages} and {do_chat} are filled per test; all other braces are literal.
|
||||
TEMPLATE = '''
|
||||
import logging, sys
|
||||
import logging, os, sys
|
||||
from livekit.agents import llm as lk_llm
|
||||
sys.path.insert(0, "/opt/voice-agent")
|
||||
from agent import GemmaLLM
|
||||
from agent import HopeLLM
|
||||
|
||||
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
|
||||
|
||||
llm = GemmaLLM(
|
||||
llm = HopeLLM(
|
||||
model="{model}",
|
||||
base_url="{base_url}",
|
||||
api_key="not-needed",
|
||||
api_key=os.environ.get("LLM_API_KEY", "not-needed"),
|
||||
max_completion_tokens=100,
|
||||
extra_body={{"chat_template_kwargs": {{"enable_thinking": False}}}},
|
||||
)
|
||||
@@ -44,7 +45,7 @@ async def main():
|
||||
print("AFTER items=" + str(len(compacted.items)))
|
||||
for it in compacted.items:
|
||||
role = getattr(it, "role", None)
|
||||
content = GemmaLLM._msg_content_text(it)
|
||||
content = HopeLLM._msg_content_text(it)
|
||||
print("ITEM " + str(role) + ": " + content[:120])
|
||||
|
||||
{do_chat}
|
||||
@@ -57,8 +58,8 @@ CHAT_SNIPPET = ' stream = llm.chat(chat_ctx=compacted)\n collected = await
|
||||
|
||||
def _run(num_messages: int, *, do_chat: bool = False) -> str:
|
||||
code = TEMPLATE.format(
|
||||
model=GEMMA_MODEL,
|
||||
base_url=GEMMA_BASE_URL,
|
||||
model=LLM_MODEL,
|
||||
base_url=LLM_BASE_URL,
|
||||
num_messages=num_messages,
|
||||
do_chat=CHAT_SNIPPET if do_chat else "pass",
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user