- auth_utils: get_user_role() reads role from auth.json (admin|user, default user)
- manage_passwords: new `role` command to promote/demote users (admin-only by convention)
- tools/__init__: TOOL_ROLES map, CONFIRM_REQUIRED set, get_tools_for_role(),
get_openai_tools_for_role() — both orchestrators now filter tools by caller's role
- tools/system: cortex_restart (detached subprocess, 5s delay), cortex_logs (admin-only)
- tools/web: http_fetch — direct URL fetch, distinct from web_search
- tools/files: file_list (directory listing), file_write (restricted paths, admin-only)
- tools/notify: nc_talk_send — proactive outbound via notification.py
- orchestrator_engine + openai_orchestrator: user_role param; CONFIRM_REQUIRED tools
return a confirmation-request result instead of executing — loop breaks after Claude
asks user to confirm in a follow-up message
- home/scott/auth.json: role set to admin
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The AsyncOpenAI client always appends /chat/completions to base_url.
Open WebUI's endpoint is at /api/chat/completions, so for openwebui
host_type the base_url must include the /api prefix — same logic as
_local() in llm_client.py.
Also strip non-standard metadata fields (backend, host, etc.) from
session_messages before passing them to the API.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- openai_orchestrator.py — new ReAct tool loop engine for any
OpenAI-compatible endpoint (OpenRouter, Open WebUI, Ollama, LiteLLM);
model handles both tool loop and final response, no Claude handoff needed
- tools/__init__.py — auto-derive OpenAI JSON Schema from existing Gemini
FunctionDeclarations so tool definitions have a single source of truth
- routers/orchestrator.py — route to openai_orchestrator when model registry
"orchestrator" role resolves to a local_openai type host
- routers/chat.py — pass role to _backend_label(); fix fallback_used logic
(only meaningful for explicit backend overrides, not auto-routing)
- static/app.js — add null/"auto" to backend cycle; fetch local model hint
without overriding the auto default on page load
- model_registry.py — _normalize() back-fills host_type on old registry files
- requirements.txt — add openai>=1.0.0
- ARCH__BACKENDS.md — document OpenAI-compat backend and routing logic
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>