mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-05-17 04:01:13 +00:00
Render custom per-chat model overrides in the model switcher instead of hiding them behind a generic Custom label. Mark model override updates dirty so an already-open Web UI refreshes after CLI or Web UI changes, without exposing API key values in labels. Add focused regression coverage for switcher rendering hooks and state-sync notifications.
73 lines
3 KiB
Python
73 lines
3 KiB
Python
import time
|
|
|
|
from helpers.api import ApiHandler, Request, Response
|
|
from helpers.persist_chat import save_tmp_chat
|
|
from agent import AgentContext
|
|
from plugins._model_config.helpers import model_config
|
|
|
|
_MODEL_OVERRIDE_REVISION_KEY = "_model_config_override_revision"
|
|
|
|
|
|
def _notify_model_override_changed(ctx: AgentContext) -> None:
|
|
ctx.set_output_data(_MODEL_OVERRIDE_REVISION_KEY, time.time())
|
|
|
|
try:
|
|
from helpers.state_monitor_integration import mark_dirty_for_context
|
|
|
|
mark_dirty_for_context(ctx.id, reason="model_config.model_override")
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
class ModelOverride(ApiHandler):
|
|
async def process(self, input: dict, request: Request) -> dict | Response:
|
|
context_id = input.get("context_id", "")
|
|
action = input.get("action", "get") # get | set | set_preset | clear
|
|
|
|
if not context_id:
|
|
return Response(status=400, response="Missing context_id")
|
|
|
|
ctx = AgentContext.get(context_id)
|
|
if not ctx:
|
|
return Response(status=404, response="Context not found")
|
|
|
|
if action == "get":
|
|
override = ctx.get_data("chat_model_override")
|
|
allowed = model_config.is_chat_override_allowed(ctx.agent0)
|
|
return {"override": override, "allowed": allowed}
|
|
|
|
elif action == "set":
|
|
if not model_config.is_chat_override_allowed(ctx.agent0):
|
|
return Response(status=403, response="Per-chat override is disabled")
|
|
override_config = input.get("override")
|
|
if not override_config or not isinstance(override_config, dict):
|
|
return Response(status=400, response="Missing or invalid override config")
|
|
ctx.set_data("chat_model_override", override_config)
|
|
save_tmp_chat(ctx)
|
|
_notify_model_override_changed(ctx)
|
|
return {"ok": True, "override": override_config}
|
|
|
|
elif action == "set_preset":
|
|
if not model_config.is_chat_override_allowed(ctx.agent0):
|
|
return Response(status=403, response="Per-chat override is disabled")
|
|
preset_name = input.get("preset_name", "")
|
|
if not preset_name:
|
|
return Response(status=400, response="Missing preset_name")
|
|
# Verify preset exists
|
|
preset = model_config.get_preset_by_name(preset_name)
|
|
if not preset:
|
|
return Response(status=404, response=f"Preset '{preset_name}' not found")
|
|
# Store as a preset reference
|
|
override_value = {"preset_name": preset_name}
|
|
ctx.set_data("chat_model_override", override_value)
|
|
save_tmp_chat(ctx)
|
|
_notify_model_override_changed(ctx)
|
|
return {"ok": True, "preset_name": preset_name}
|
|
|
|
elif action == "clear":
|
|
ctx.set_data("chat_model_override", None)
|
|
save_tmp_chat(ctx)
|
|
_notify_model_override_changed(ctx)
|
|
return {"ok": True, "override": None}
|
|
|
|
return Response(status=400, response=f"Unknown action: {action}")
|