fix: background tasks follow the live model selection
TaskWorker resolved its model from LLM_MODEL env (frozen at MCP spawn), so after a live set_model switch in the UI, dispatched background tasks still asked for the old model. On local-vl-models (llama-swap --models-max 1) that forces a swap against the loaded conversation model; a force-kill mid-load surfaces as 400 'model failed to load'. The agent now writes the selected model to <task_dir>/model.txt at session start and on every switch; TaskWorker reads it with the env value as fallback.
This commit is contained in:
1 parent
436b3fc8b1
commit
b01ee6478d
3 files changed
+37
-1
No files matched your search
@@ -750,6 +750,20 @@ def build_mcp_toolsets(user_profile: dict, task_dir: str) -> list[mcp.MCPToolset
|
||||
return toolsets
|
||||
|
||||
|
||||
def _sync_task_model(task_dir: str, model: str) -> None:
|
||||
"""Record the live model choice where background task workers can read it.
|
||||
|
||||
The dispatch MCP subprocess inherits its environment at spawn time, so it
|
||||
can never see later UI model switches. The worker instead reads
|
||||
<task_dir>/model.txt (falling back to LLM_MODEL env) when it starts a task.
|
||||
"""
|
||||
try:
|
||||
os.makedirs(task_dir, exist_ok=True)
|
||||
with open(os.path.join(task_dir, "model.txt"), "w") as f:
|
||||
f.write((model or "").strip())
|
||||
except OSError as e:
|
||||
logger.warning("failed to record selected model for background tasks: %s", e)
|
||||
|
||||
class VoiceAssistant(Agent):
|
||||
"""The conversational agent. LLM is the brain; STT/TTS are senses."""
|
||||
|
||||
@@ -824,6 +838,10 @@ async def handle_job(ctx: JobContext) -> None:
|
||||
# into it for live model switching.
|
||||
voice_assistant = VoiceAssistant(user_profile, task_dir)
|
||||
|
||||
# Background task workers (dispatch MCP subprocess) read this file so
|
||||
# they use the same model as the conversation, even after live switches.
|
||||
_sync_task_model(task_dir, voice_assistant.llm.model)
|
||||
|
||||
# Publish the chat-capable model list so the web UI can offer a picker.
|
||||
async def _publish_models() -> None:
|
||||
models = await list_available_models()
|
||||
@@ -1009,6 +1027,7 @@ async def handle_job(ctx: JobContext) -> None:
|
||||
ack, reliable=True, topic="voice-control"
|
||||
)
|
||||
)
|
||||
_sync_task_model(task_dir, llm.model)
|
||||
except Exception as e: # noqa: BLE001
|
||||
logger.warning("Failed to update model: %s", e)
|
||||
|
||||
|
||||
Reference in new issue
Block a user