Mark completed: email_send + allowlist UI, model inline edit, cross-session
search. Remove completed items from active lists (distill review, model edit,
session search). Update ROADMAP Phase 3 tool suite line and last-updated date.
Remove resolved Unsloth entry from Deferred.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Inline edit form per model row (label, model name/ID, host/account, context, tags)
- Fetch models button in edit form for local models — same live-picker UX as Add Model
- POST /settings/local/models/{id}/edit route in local_llm.py
- Admin role badge (ADMIN/USER pill) in Account Settings page
- HELP.md updated: new tools table with admin/confirm markers, PWA install section
- TODO updated: tool expansions marked done, distill review and Unsloth resolved,
role-based access and admin badge added to completed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add shell_exec to orchestrator tool suite (system.py + __init__.py)
Runs arbitrary shell commands on the Cortex host with timeout (1–120s),
combined stdout/stderr output, optional working_dir, and exit code reporting.
Enables system diagnostics (df, ls, ps, journalctl, etc.) from Agent mode.
- Fix orchestrator_engine.run() to use model_name from resolved registry entry
Previously used settings.orchestrator_model (.env hardcode) regardless of
what model was assigned to the orchestrator role. Now accepts model_name param
and falls back to settings value only when registry has no model_name.
- Update ARCH__FUTURE.md: date, running host, local orchestrator status,
model registry V2 progress, added Cortex Mesh concept (section 9)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend toggle now cycles through chat role models by label instead of
cycling service type strings (auto/claude/gemini/local).
- model_registry: get_model_for_slot() — resolves a specific priority
slot without walking the fallback chain
- llm_client: complete() gains slot param; explicit slot selection
dispatches directly to that model with no silent fallback
- routers/chat.py: ChatRequest.slot; GET /backend returns chat_models
[{slot, label, type}] for the UI; _stream_chat uses resolved model
label for the response tag when a slot is pinned
- app.js: toggle loads chat_models from /backend, cycles by label,
sends slot in chat payload; legacy model field removed from payload
- app.js: fix Gap B — agent mode placeholder no longer says "Gemini
tool loop"; now says "orchestrator"
- DESIGN doc: updated to reflect phases 1+2 complete, catalog-as-code
decision, Gap A/B documented, Phase 3 implementation details
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds cloud provider management to /settings/models:
- Google Accounts section: add/remove Gemini API keys with labels
- Add Model form: provider tabs (Local / Google / Anthropic) with
catalog dropdowns that auto-fill label and context_k
- Provider badges on model rows (Anthropic / Google / Local)
- /settings/local now redirects to /settings/models (canonical URL)
- save_cloud_model() in model_registry for Anthropic/Google entries
- Distill role migration restored in _migrate_from_local_llm
- Test fixes: version assertions updated to V2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a providers section to the per-user model registry for Anthropic and
Google as first-class providers alongside local hosts. Google accounts
(API keys) are now stored as a list so multiple Google accounts can coexist.
Changes:
- model_registry.py: V2 schema, auto migration V1→V2 (pulls gemini_api_key
from auth.json into providers.google.accounts), _resolve_model() merges
account API key for gemini_api type models
- routers/orchestrator.py: uses model-resolved api_key when orchestrator
role resolves to a gemini_api model with account_id
- ANTHROPIC_CATALOG and GOOGLE_CATALOG constants for model picker (Phase 2)
- New functions: get_google_api_key(), save/remove_google_account(), get_catalog()
- Documentation: ARCH__BACKENDS.md updated to V2 schema, DESIGN doc added
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>
WAN port forward confirmed end-to-end. Clone URL:
ssh://git@cortex.dgrzone.com:2222/<user>/<repo>.git
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moved to completed: token expiry restart, Holly onboarding, per-user
channel config, Google OAuth, per-user Gemini key, session persistence,
persona picker, Lucide icons, favicon, Help shared base, reminders tools,
Brian onboarding.
Updated in-progress: knowledge consolidation tools (ae_journal_* done,
import script still pending). NC Talk and Google Chat notes updated for
per-user routing. Removed stale "default user only" notes.
High priority now: Ollama backend, Gitea SSH verification.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>