Files
Cortex-Inara/cortex/static/HELP.md
Scott Idem 658c508925 feat: multi-level agent management — background agents, lifecycle tools, 3-level hierarchy
agent_manager.py (new):
- AgentRecord dataclass: agent_id, level (1/2/3), role, task, status, started,
  parent_id (lineage), finished, result, notify, _task_ref
- register() / finish() / cancel_agent() / list_agents() / get() / set_task_ref()
- Calls notification.notify() on completion when notify=True (same channel as
  reminders and cron completions)
- 24-hour pruning of completed records on each new registration

spawn_agent (tools/agents.py):
- background=True: fires asyncio.create_task(), registers in agent_manager, returns
  agent_id string immediately — sync path unchanged (no regression)
- notify=True: push/Talk notification when the background task completes
- Level enforcement: _agent_level param tracks hierarchy depth; when spawning from
  Level 2, child automatically gets spawn_agent + aider_run denied so Level 3 agents
  cannot delegate further

New lifecycle tools (tools/agents.py + __init__.py):
- agent_status(agent_id) — status, role, level, elapsed, task, result preview; user-level
- agent_list(status, limit) — all agents for current user, newest first; user-level
- agent_cancel(agent_id) — kills background task; admin-only, confirm-required

tests/test_agent_manager.py (new, 41 tests):
- agent_manager CRUD, pruning, notification hook
- spawn_agent background: returns immediately, completes async, timeout, failure
- Level enforcement: L1→L2 permits spawn, L2→L3 auto-denies; explicit tool_list path
- agent_status / agent_list / agent_cancel output formatting
- aider_run background: returns agent_id, completes async, sync path unchanged
- All tests run without browser or Cortex service (~2.5s total)
  Run: cd cortex && .venv/bin/python -m pytest tests/test_agent_manager.py -v

Docs: ARCH__FUTURE.md §13 (full design), ROADMAP.md, TODO__Agents.md, MASTER.md,
HELP.md (orchestrator description corrected, tool schema line updated to reflect
keyword routing), CLAUDE.md tool count 66→69.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 22:40:20 -04:00

25 KiB
Raw Permalink Blame History

Cortex UI — Help & Reference

Last updated: 2026-05-13


Getting Started

If this is your first time using Cortex, you need one thing before the chat will work: an AI model connected to your account.

Fastest path — OpenRouter: OpenRouter gives you access to Claude, Gemini, and dozens of other models with a single API key.

  1. Get a free API key at openrouter.ai/keys
  2. Go to ☰ → Account → [Set up OpenRouter →] (shown automatically if no model is configured)
  3. Paste your key, pick a starting model, click Connect

That's it — you're ready to chat.

Already past setup but seeing errors? Go to ☰ → Account → Model Registry → Manage models and confirm a model is assigned to the Chat role (Primary slot). If all slots are empty, add a model first.


Header Controls

Button What it does
Sessions Open the sessions panel — list, resume, or start sessions
N (sliders icon) Open the Context & Memory panel (N = current context tier)
Settings menu — Files, push notification toggle, Account, Sign Out
? Open this help panel

The Context & Memory panel (sliders icon with tier number) contains all configuration options:

Section Controls
Context Tier T1 T4 context depth
Memory Layers Toggle Long / Mid / Short memory on/off
Distill Memory Manually trigger Short / Mid / Long / All distillation
Model Active chat model — click to cycle through your configured slot models (Primary → Backup 1 → …)
Display Aa cycles font size · toggles theme · S/M/L cycles input area height · ⌃↵ toggles send shortcut

All settings persist in localStorage across page refreshes.


Chat

  • Send: Ctrl+Enter by default. Click ⌃↵ in the input controls to toggle to plain Enter mode.
  • Stop: Click Stop to cancel an in-progress response at any time.
  • Edit a message: Hover over any message → click edit. Ctrl+Enter saves, Esc cancels.
  • Delete a message: Hover over any message → click del, then confirm delete.
  • Copy: Hover over any message → click copy.
  • New line while typing: Shift+Enter (in Ctrl+Enter mode) or Shift+Enter / Enter (in Enter mode).

Each assistant response shows a small model tag below the message identifying which model and host responded.


Tools ()

Click the button in the input row to enable the Tools toggle. When lit (amber), Send changes to Run and messages are routed through the orchestrator instead of directly to the chat model.

The orchestrator runs a multi-step tool loop:

  1. The orchestrator model reasons about the request and calls tools as needed
  2. Tool results are fed back into the conversation; the loop continues until the model has what it needs
  3. The model produces the final user-facing reply — when the orchestrator role uses Gemini, Claude writes the final response; when it uses a local model, that same model writes it
  4. Expandable tool-call cards appear above the response — click any card to see the arguments sent and the result returned

The toggle is independent of the Role selector — you can use any role (chat, coder, research, etc.) with or without tools. The orchestrator model is configured in Account → Model Registry → Role Assignments → Orchestrator.

Tools mode is best for tasks requiring research, multi-step reasoning, or side effects (e.g. "search for X", "add a task", "what's on my list?", "append this to my journal"). Regular chat is faster for conversational turns.

Orchestrated sessions persist to history exactly like regular chat.

Available Tools

69 tools across 17 categories. Tool schemas are narrowed per-message using keyword routing — only categories relevant to your request are sent, keeping token overhead low. Per-role tool sets provide additional filtering.

Category Tools
Web web_search, http_fetch, web_read, http_post
Project Files project_file_read, project_file_list, file_stat, file_grep, file_diff, file_syntax_check
Files (admin) file_read, file_list, file_write, session_read, session_search
Git git_status, git_log, git_diff
Shell shell_exec, claude_allow_dir
System cortex_restart, cortex_logs, cortex_status, cortex_update
Tasks task_list, task_create, task_update, task_complete
Cron cron_list, cron_add, cron_remove, cron_toggle
Reminders reminders_add, reminders_list, reminders_remove, reminders_clear
Scratchpad scratch_read, scratch_write, scratch_append, scratch_clear
Notifications web_push, email_send, nc_talk_send, nc_talk_history
Aether Journals ae_journal_list/search, ae_journal_entries_list, ae_journal_entry_read/create/update/disable/append/prepend
Aether Tasks ae_task_list
Aether Database (admin) ae_db_query, ae_db_describe, ae_db_show_view
Agent Notes agent_notes_read, agent_notes_write, agent_notes_append, agent_notes_clear
Agents spawn_agent, aider_run
Home Assistant ha_get_state, ha_get_states, ha_call_service

Files, Shell, System, Aether Database, Agents, and some Notification/Web tools are admin-only and not visible to regular users. http_post requires a URL prefix allowlist in home/{user}/http_allowlist.json. nc_talk_history requires nc_username and nc_app_password in channels.json under nextcloud. ae_db_* tools require Aether DB credentials configured in Integrations settings. All queries are SELECT-only — no writes possible. aider_run requires Aider installed (pip install aider-chat) and a model configured via AIDER_MODEL env var or the project's .aider.conf.yml. Supports any OpenAI-compatible backend — DeepSeek, OpenRouter, Ollama, etc.

Per-Role Tool Sets

Each role can be configured with a specific subset of tool categories. When a role has a tool subset configured, only those tools are sent to the orchestrator — the rest are invisible to the model for that session.

Example: a Coder role might only need Web, Files, Shell, and Agent Notes. A Research role might only need Web. Configuring this avoids sending schemas for 30+ irrelevant tools on every call.

Configure per-role tool sets in Account → Model Registry → Role Assignments — expand a role card to see the category checkboxes. The default (no checkboxes selected) sends all tools the user has access to.


Sessions

Sessions are named conversation threads that persist across page refreshes.

  • Click Sessions+ New to start a fresh session.
  • Click any listed session to resume it — full history loads instantly.
  • Sessions from Nextcloud Talk appear as nct_* prefixed IDs.
  • A blue badge appears on the Sessions button when Talk activity arrives in a session you're not currently viewing.

Notes

Notes are injected into a session without triggering an LLM response.

  • Click Note to toggle note mode. The input border changes colour.
  • Private note (amber border) — visible only in the UI, never sent to the LLM.
  • Context note (teal border) — persisted to session history so the LLM sees it on the next turn. Useful for nudging context without a full message.
  • Click the private / public label to switch between note types.

Install as App (PWA)

Cortex supports installation as a Progressive Web App — it runs in its own window with no browser chrome.

  • Chrome / Edge (desktop): Look for the install icon in the address bar, or open the browser menu → Install Cortex…
  • Android (Chrome): Tap ⋮ → Add to Home Screen
  • iOS (Safari): Tap the Share button → Add to Home Screen

Once installed, opening Cortex from the home screen or app launcher skips the browser UI entirely.


Switching Models

The Model button in the Context & Memory panel cycles through the slot models configured for your active role (Primary → Backup 1). Click it to switch between models mid-session.

  • The button label shows the active model (e.g. "GPT-4o", "Gemini 2.5 Flash")
  • The selected slot is sent with each chat request so the correct model is used
  • If only one model is configured, the toggle does nothing
  • A system message appears in the chat when you switch models

If the active model fails, the next configured backup slot is tried automatically.

Each response shows a model tag (bottom-right of message) with the model label and host, so you always know what responded.


Account Settings

Navigate to: ☰ (top-right menu) → Account

Section What you can do
Account View your username, role badge (Admin / User), rename your username
Connected Accounts See which Google account is linked for OAuth sign-in
Email Allowlist Regex patterns controlling which addresses the email_send tool can reach
Notifications Dedicated page — set channel (Browser Push, NC Talk, Google Chat, email) for proactive messages; configure Home Assistant inbound webhook; test buttons for instant verification
Schedules View, add, edit, pause, and delete scheduled jobs directly — without going through the AI
Tool Permissions Allow or block specific orchestrator tools for your account
Usage Token consumption by model — see below
Browser Cache Clear UI preferences stored locally (theme, font size, session ID, etc.)
Model Registry Configure AI providers, local hosts, and role assignments
Change Password Update your login password
Personas List and rename your personas

Usage

Token consumption is tracked automatically for API-backed models. Navigate to: ☰ → AccountUsage section.

The table shows all-time totals per model key, with columns for:

Column Meaning
Model backend/model-name key (e.g. gemini_api/gemini-2.5-flash, local/deepseek-v4)
Calls Number of API calls made
Prompt Input tokens sent
Output Completion tokens received
Total Prompt + Output

Values ≥ 1,000 are displayed as k (e.g. 24.3k).

What is and isn't tracked:

  • Gemini API calls (orchestrator, distillation)
  • Local OpenAI-compatible calls (Open WebUI, Ollama, OpenRouter)
  • ✗ Claude CLI — no structured token data is returned by the subprocess
  • ✗ Gemini CLI — same reason

The raw data lives in home/{username}/usage.json and is also accessible via the Files panel or the API.


Model Registry

Configure which AI models are available and which handles each task type.

New user quick path: ☰ → AccountSet up OpenRouter → (the guided wizard adds a host, model, and role assignment in one step).

Full manual path: ☰ → Account → scroll to Model RegistryManage models →


Step 1 — Set up providers and hosts

Do this before adding models — models need a provider account or local host to attach to.

Anthropic (Claude): Two options:

  • CLI (OAuth): Nothing to configure — uses your existing claude auth login session. If Claude isn't working, run claude auth login in a terminal.
  • Direct API key: Scroll to Cloud Providers → Anthropic → click + Add API key. Enter a label and your sk-ant-… key from console.anthropic.com/keys. When you add a model using an API key credential, it routes through the Anthropic SDK instead of the CLI.

Google (Gemini): Add one entry per API key you want to use:

  1. Scroll to Cloud Providers → Google → click + Add Google account
  2. Enter a label (e.g. "Work", "Personal") and your API key
  3. Get a free key at aistudio.google.com/apikey

OpenRouter (recommended for new users — one key for many models):

  1. Get a key at openrouter.ai/keys
  2. Scroll to Local Hosts+ Add host
  3. Label: "OpenRouter", URL: https://openrouter.ai/api/v1, paste your key, Type: OpenAI-compatible
  4. Click Fetch models to verify, then add models from the fetched list

Other local hosts (Open WebUI, Ollama, LM Studio, etc.):

  1. Scroll to Local Hosts → click + Add host to expand the form
  2. Enter a label, the API URL (e.g. http://192.168.1.100:3000), and optional API key
  3. Set Type: Open WebUI / Ollama, or OpenAI-compatible
  4. Click Fetch models on the saved host card to verify connectivity

Step 2 — Add models

Scroll to Add Model. Select the provider tab, fill in the details, click Add Model:

Tab What you need
Local Select a host (from Step 1) → enter model name, or use Fetch from host to pick from a live list
Google Select a Gemini model from the catalog → select a Google account (from Step 1)
Anthropic Select a credential (CLI OAuth or an API key added in Step 1) → select a Claude model from the catalog

The label and context window size auto-fill from the catalog — edit them if you want. Tags are optional.


Step 3 — Assign models to roles

Scroll to Role Assignments at the bottom of the page. Each role has Primary and Backup 1 slots — Primary is tried first, then Backup 1. Changes save automatically.

Required roles (always present, cannot be removed):

Role Used for
Chat Regular conversation
Orchestrator Agent mode tool loop
Distill Memory distillation (short / mid / long)

Custom roles — Click + Add custom role to create your own. Each custom role gets its own model selection, tool set, and system prompt addition. Good examples:

Example Purpose
Coder Code-focused tasks — larger context window, code-aware model
Research Long-context research — high-token model, web tools prioritized

Switch roles via the Role selector in the Context & Memory panel (⚙). Leave all slots empty to use the server default.

Per-role tool sets: Expand any role card to configure which tool categories the orchestrator can use when that role is active. Unchecked categories are hidden from the model entirely — reducing token overhead on every orchestrated call. Leaving all categories unchecked means all tools the user has access to are available (the default).

Inject timestamp: Each role card has an "Inject current date & time into system prompt" checkbox (default on). Disable it for pure processing roles (summarizer, classifier, translator) that don't need clock awareness.


Nextcloud Talk Bot

The Cortex bot is registered in Nextcloud Talk.

  • Messages sent in enabled Talk conversations are received by Cortex, processed, and replied to.
  • The webhook returns 200 OK immediately; the reply happens asynchronously.
  • Real-time updates stream to the web UI via SSE — you see Talk messages and responses appear live.
  • To enable the bot in a conversation: open Talk conversation settings → Bots → enable the bot.

Google Chat Bot

The Cortex bot is available in Google Chat (One Sky IT Workspace).

  • Send the bot a direct message in Google Chat to start a conversation.
  • Each DM thread is its own session (gc_spaces/* prefix) — history persists across messages.
  • Responses are synchronous — Google Chat displays the reply directly in the thread.
  • To add the bot to a space: open the space, click Add people & apps, and search for the Cortex bot.
  • Sessions from Google Chat appear as gc_* prefixed IDs in the Sessions panel.

Files (Identity Editor)

The Files button opens an editor for your persona's identity and memory files:

File Purpose
SOUL.md Core personality, values, and voice
IDENTITY.md Role, capabilities, and context
USER.md Your profile, preferences, and history
PROTOCOLS.md Behavioural rules and communication protocols
CONTEXT_TIERS.md Defines what gets loaded at each context tier
MEMORY_LONG.md Permanent curated long-term memory
MEMORY_MID.md Rolling mid-term digest (LLM-distilled)
MEMORY_SHORT.md Recent session rollup (auto-aggregated)
HELP.md This file — persona-specific additions appended below
email_allowlist.json Regex patterns for permitted email_send recipients (one per line)

Toggle preview / edit to switch between rendered markdown and raw text. Ctrl+S saves, Esc closes.

The Audit Log group at the bottom of the sidebar (collapsed by default) lists tool call logs by date (YYYY-MM-DD.jsonl). Click any date to view a read-only table of every orchestrator tool call: time, tool name, status, model, args, and result snippet. Status is colour-coded: green = ok, red = error, amber = denied.


Push Notifications

Cortex can send browser push notifications — even when the tab is closed.

  • Open ☰ → Enable notifications and accept the browser permission prompt.
  • Once enabled, the button shows Notifications on (in accent colour).
  • Click again to disable. Subscriptions are stored per-device.
  • The orchestrator's web_push tool lets your persona send you a push proactively (e.g. when a long task completes).

Notification channel settings: ☰ → AccountNotification settings → — choose Browser Push, Email, Nextcloud Talk, or Google Chat as the channel your persona uses for scheduled reminders, cron job completions, and memory digests. Use the Send Test Notification button to verify your setup, or Check Reminders Now to trigger the reminder check immediately.


Context & Memory ( ⚙ panel )

Context Tiers

Controls how much context is prepended to each LLM call:

Tier Loads ~Tokens
Min SOUL + IDENTITY + USER summary ~1,500
Std + USER full + PROTOCOLS + HELP + memory layers ~5,000
Ext + last 2 raw session logs ~15,000
Full + last 7 raw session logs ~50,000

Default is Std. Use Min for small/local models. Use Ext or Full for complex multi-session tasks.

Memory Layers

Three independently toggleable memory files, loaded Long → Mid → Short:

Layer File Contents
Long MEMORY_LONG.md Permanent facts — origin, key decisions, profile highlights
Mid MEMORY_MID.md Rolling digest of recent weeks — LLM-distilled from Short
Short MEMORY_SHORT.md Recent session rollup — auto-aggregated from session logs

Toggle any layer off to save tokens for a focused conversation.

Memory Distillation

Distillation builds up the memory layers from raw session logs. Runs automatically on a schedule; trigger manually via the ⚙ panel:

Button What it does
short Rolls recent session log files → MEMORY_SHORT.md (fast, no LLM)
mid LLM summarizes MEMORY_SHORT.mdMEMORY_MID.md
long LLM integrates MEMORY_MID.mdMEMORY_LONG.md
all Runs short → mid → long in sequence

Recommended workflow: run short after any productive session; mid weekly; long monthly.


Scheduled Jobs

Cortex can run recurring jobs on a schedule — reminders, daily briefings, automated research, and more. Manage them by asking your persona to set them up, or go directly to ☰ → Account → Schedules.

Job Types

Type What it does
remind Appends to REMINDERS.md — automatically surfaced in chat context
note Appends to SCRATCH.md — read on demand via the scratchpad
message Sends the payload text directly to your notification channel
brief Calls the AI with your payload as the prompt, sends the response to your notification channel. Good for morning briefings, check-ins.
task Runs the full orchestrator tool loop with your payload as the request, sends Claude's response to your notification channel. Use this for agentic scheduled work: research, file updates, summaries that need tool access.

For task jobs: tools that require confirmation are skipped in scheduled context. Pre-approve them in Settings → Tools to allow them in scheduled tasks.

Schedule Formats

Format When it runs
hourly Every hour at :00
daily Every day at 09:00
daily:HH:MM Every day at the specified time
weekly:DOW Every specified day at 09:00 (e.g. weekly:mon)
weekly:DOW:HH:MM Every specified day at the specified time (e.g. weekly:fri:17:00)
monthly 1st of every month at 09:00
monthly:DD Specific day of month at 09:00 (e.g. monthly:15)
monthly:DD:HH:MM Specific day of month at the specified time
yearly:MM:DD Every year on that date at 09:00 — for birthdays, anniversaries (e.g. yearly:03:15)
yearly:MM:DD:HH:MM Every year on that date at the specified time

DOW values: mon tue wed thu fri sat sun. All times are server-local.

Schedules take effect immediately when added or edited — no restart needed. Paused jobs stay in the list and can be resumed at any time.

Home Assistant Integration

HA automations can trigger your persona via webhook. Configure in Notifications → Home Assistant → Inbound webhook:

  • Set a Webhook ID (long random string — this is your secret URL component)
  • Your endpoint: https://cortex.dgrzone.com/webhook/ha/{username}/{webhook_id}
  • Enable orchestrator tools — when checked, HA events trigger the full tool loop; when unchecked, events get a direct LLM response (faster, no tools)

HA payload fields recognized: message, entity_id, state, trigger, event, area.


Keyboard Shortcuts

Keys Action
Ctrl+Enter Send message (default mode)
Enter Send (when in Enter mode)
Shift+Enter New line in message input
Ctrl+Enter Save inline message edit
Esc Cancel inline edit / close any open modal
Ctrl+S Save file (Files modal)

API Reference

For direct access or scripting:

Method Endpoint Description
POST /chat Send a message — returns SSE stream
GET /backend Get current primary/fallback backends
POST /backend Set primary backend ({"primary": "claude"})
GET /sessions List all sessions
GET /history/{id} Get session message history
PUT /history/{id} Replace full session history
GET /events SSE stream for real-time Talk activity
POST /note Inject a context note into a session
GET /files List identity files
GET /files/{name} Read a file
PUT /files/{name} Write a file
POST /distill/short Aggregate session logs → MEMORY_SHORT
POST /distill/mid Summarize short → MEMORY_MID (LLM)
POST /distill/long Integrate mid → MEMORY_LONG (LLM)
POST /distill/all Run all three distillation steps
GET /distill/status Scheduler status and next run times
POST /orchestrate Submit an agent task — returns {"job_id": "..."}
GET /orchestrate/{job_id} Poll job status and result
GET /settings/models Model registry UI
POST /api/models/role Set a role assignment (JSON body)
POST /api/models/role-config Set per-role tool list and system prompt append
GET /api/push/vapid-key VAPID public key (for push subscription)
POST /api/push/subscribe Register a push subscription
DELETE /api/push/subscribe Remove a push subscription
POST /api/push/test Send a test notification via configured channel
POST /api/push/reminders/check Run reminder check immediately; returns {"reminders_found": n}
GET /api/audit/files List available audit log dates (own data)
GET /api/audit/day?date= Tool call entries for a specific date (own data)
GET /api/audit/recent Recent tool calls across days (admin)
GET /api/audit/stats Tool call counts by tool/status/user (admin)
GET /api/usage Full daily token usage log (own data)
GET /api/usage/summary Per-model token totals, all time (own data)
GET /api/usage/all Per-model totals for all users (admin)
GET /setup/model Guided OpenRouter setup form (Step 3 / standalone)
POST /setup/model Save OpenRouter host + model + assign to chat role
GET /health Health check — returns {"status": "ok"}

Chat request body (POST /chat):

{
  "message": "string",
  "session_id": "string | null",
  "tier": 2,
  "chat_role": "chat",
  "slot": "primary | backup_1 | backup_2 | null",
  "include_long": true,
  "include_mid": true,
  "include_short": true,
  "off_record": false
}

Cortex is a self-hosted personal AI platform. Named after the 'verse-wide communications network in Firefly.