From 0c17b4b1ab51b7aa43879697232f89905df6d252 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Sun, 29 Mar 2026 21:44:56 -0400 Subject: [PATCH] docs: overhaul TODO__Agents.md to reflect current state 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 --- documentation/TODO__Agents.md | 201 ++++++++++++++++++---------------- 1 file changed, 105 insertions(+), 96 deletions(-) diff --git a/documentation/TODO__Agents.md b/documentation/TODO__Agents.md index 2294cb6..d7cc9d8 100644 --- a/documentation/TODO__Agents.md +++ b/documentation/TODO__Agents.md @@ -7,11 +7,6 @@ ## 🔴 High Priority -### [Auth] Token expiry — sudo restart -- Cortex currently requires `sudo systemctl restart cortex` after OAuth token refresh -- This must be done manually by the user (cannot run interactively from Claude Code) -- **Future:** Explore hot-reload or token-passing mechanism so restart isn't required - ### [Backend] Ollama local model backend - Add Ollama as a third LLM backend option (direct Ollama API, no CLI wrapper) - Endpoint: `http://scott-gaming:/api/` (WireGuard) @@ -27,37 +22,22 @@ ## 🟡 Medium Priority -### [Intelligence] Orchestrator service — Phase 1 ✅ Complete -See `ARCH__Intelligence_Layer.md` for full design. Committed: `ed472ce` (2026-03-18) -- [x] Add Gemini API (google-generativeai SDK) as a library dependency (not CLI) -- [x] Create `cortex/routers/orchestrator.py` — `POST /orchestrate` endpoint -- [x] Basic tool registry: web search (DuckDuckGo), AE API query, file read, task list -- [x] ReAct loop: Gemini calls tools, assembles context, hands off to Claude for final response -- [x] `GET /orchestrate/{job_id}` — poll for status/result -- [x] Cron can trigger via HTTP POST (same endpoint) -- **Note:** Default model is `gemini-2.5-flash` — free tier key required (AI Studio) - ### [Intelligence] Knowledge consolidation — Phase 1 -See `ARCH__Intelligence_Layer.md` for full design. Initial scope: -- [ ] Tool: `ae_journal_search` — search before creating to avoid duplicates -- [ ] Tool: `ae_journal_entry_create` — write a new entry with source metadata +See `ARCH__Intelligence_Layer.md` for full design. +- [x] Tool: `ae_journal_search` — search before creating to avoid duplicates +- [x] Tool: `ae_journal_entry_create` — write a new entry with source metadata - [ ] Import script: walk a markdown directory, chunk by H2 section, create entries - [ ] Target: markdown files from `~/DgrZone_Nextcloud/` and `~/OSIT_Nextcloud/` - [ ] Tag strategy: source path, date, topic tags from frontmatter or filename -### [Channel] Nextcloud Talk integration ✅ Complete -- NC Talk bot is implemented (`cortex/routers/nextcloud_talk.py`) -- HMAC: incoming uses `random + raw_body`; outgoing reply uses `random + message_text` — both correct -- [x] Test end-to-end after any Cortex restart — confirmed working 2026-03-20 -- [x] Bot registration docs completed in `docs/NEXTCLOUD_TALK_BOT.md` — 2026-03-20 -- **Note:** Currently uses default user/persona only — per-conversation persona routing is a future enhancement +### [Distill] Monitor first auto_distill_long run +- Scheduled for ~April 1 at 04:00 +- Manually review `inara/MEMORY_LONG.md` output before fully trusting +- Adjust distill prompts if needed -### [Multi-user] Holly onboarding -- Multi-user is built into Cortex — single instance, multiple users under `home/` -- `home/holly/persona/tina/` directory created from template (stub content — needs real persona files) -- [ ] Send Holly's invite email: `python manage_passwords.py invite holly holly.danner@gmail.com` -- [ ] Walk Holly through onboarding flow (`/setup/{token}` → persona creation) -- [ ] Review and flesh out Tina's persona files (IDENTITY.md, SOUL.md, PROTOCOLS.md, USER.md) +### [Distill] Distill quality review +- Short/mid/long distill prompts live in `cortex/memory_distiller.py` +- After first few automatic runs, review quality and tune --- @@ -81,36 +61,6 @@ See `ARCH__Intelligence_Layer.md`. Full design not yet started. - `cortex/routers/` already has pattern; add `gitea.py` - Gitea Actions (CI) for "run tests on push" — simpler than custom runner -### [Auth] Session auth + persona onboarding ✅ Complete -- bcrypt passwords stored in `home/{username}/auth.json` -- JWT session cookies (HS256, 30-day expiry) — `auth_utils.py`, `auth_middleware.py` -- Login/logout at `/login`, `/logout` -- Invite tokens (72h, one-time-use) — admin generates via `manage_passwords.py invite [email]` -- Self-service onboarding: `/setup/{token}` (set password) → `/setup/persona` (create persona) -- Multi-persona switcher in UI header — `/api/personas` endpoint -- SMTP invite email — `noreply@oneskyit.com`, HTML + plain text body -- CSS routing fix — `app.mount("/static")` must precede `app.include_router(ui.router)` -- Committed: 2026-03-20 - -### [Channel] Google Chat integration ✅ Complete -See `cortex/routers/google_chat.py`. Committed: 2026-03-20 -- [x] JWT verification via `authorizationEventObject.systemIdToken` (audience = endpoint URL, issuer = accounts.google.com) -- [x] Workspace Add-on event format: event type inferred from payload key (`messagePayload`, `addedToSpacePayload`, etc.) -- [x] Response format: `hostAppDataAction.chatDataAction.createMessageAction.message.text` -- [x] Session management, LLM pipeline, session logging — same pattern as NC Talk -- [x] Nginx: `/channels/` prefix exposed without basic auth (covers all future channel integrations) -- **Note:** Google Chat API now forces the Workspace Add-on framework — legacy standalone bot format is gone. - `{"text": "..."}` and `renderActions` do NOT work; `hostAppDataAction` is required. - -### [Distill] Monitor first auto_distill_long run -- Scheduled for ~April 1 at 04:00 -- Manually review `inara/MEMORY_LONG.md` output before fully trusting -- Adjust distill prompts if needed - -### [Distill] Distill quality review -- Short/mid/long distill prompts live in `cortex/memory_distiller.py` -- After first few automatic runs, review quality and tune - ### [Backend] Intelligent model routing - Currently hardcoded: Claude default, Gemini fallback - Future: route by task type (code → Claude, search → Gemini, private → Ollama) @@ -120,45 +70,104 @@ See `cortex/routers/google_chat.py`. Committed: 2026-03-20 ## ✅ Completed -### [UI] Mobile-friendly header +### [Multi-user] Brian onboarding — 2026-03-29 +- Invite sent to `memedrift@gmail.com` +- Brian completed onboarding, created `wintermute` persona +- Google OAuth registered (`google-add brian memedrift@gmail.com`) + +### [Tools] Reminders tools — 2026-03-29 +- `reminders_add`, `reminders_list`, `reminders_clear` added to orchestrator tool suite +- Tools live in `cortex/tools/reminders.py` +- All persona PROTOCOLS.md updated with Tools & Modes reference (direct chat vs Agent mode) +- `persona_template.py` updated so new personas get the protocol automatically + +### [Auth] Token expiry — no restart needed — 2026-03-27 +- `llm_client._fresh_claude_token()` reads live from `~/.claude/.credentials.json` on every call +- systemd service is a user unit (no sudo) — `systemctl --user restart cortex` is sufficient +- No manual token sync required after `claude auth login` + +### [Multi-user] Per-user channel config — 2026-03-27 +- Google Chat and NC Talk secrets/config moved from `.env` to `home/{username}/channels.json` +- New endpoints: `POST /channels/google-chat/{username}` and `POST /webhook/nextcloud/{username}` +- No channel access by default — each user configures their own `channels.json` +- Setup guides: `docs/GOOGLE_CHAT_BOT.md` and `docs/NEXTCLOUD_TALK_BOT.md` + +### [Auth] Google OAuth sign-in — 2026-03-27 +- `GET /auth/google` → Google consent → `GET /auth/google/callback` flow +- Users pre-registered via `manage_passwords.py google-add ` +- Google sign-in button on `/login`; auth.json stores `google_sub` + `google_email` +- Active users: scott (scott.idem@oneskyit.com), holly (holly.danner@gmail.com), brian (memedrift@gmail.com) + +### [Settings] Per-user Gemini API key — 2026-03-27 +- Stored in `home/{username}/auth.json` as `gemini_api_key` +- Orchestrator uses user key if set, falls back to server-level `GEMINI_API_KEY` +- Manageable via `/settings` UI (add, remove, masked hint) + +### [UI] Session persistence across navigation — 2026-03-26 +- localStorage keyed to `cx_sid_{user}_{persona}` with 30-min inactivity TTL +- Auto-restored silently on page load; cleared on "New session" or session delete + +### [UI] Persona picker page — 2026-03-26 +- `GET /{username}` shows a card grid of available personas instead of 404 +- Each card links directly to `/{username}/{persona}` + +### [UI] Lucide icons — 2026-03-25 +- Icons throughout: mode selector, send/stop buttons, edit/del/copy, save/cancel +- Loaded via UMD CDN; `icon_html()` + `render_icons()` helpers in `app.js` + +### [UI] Persona-specific favicon — 2026-03-25 +- Emoji SVG favicon generated from persona config at load time + +### [Multi-user] Holly onboarding — 2026-03-20 +- Holly's invite sent; onboarding completed via `/setup/{token}` +- `home/holly/persona/tina/` created from template +- Google OAuth registered (`holly.danner@gmail.com`) + +### [Channel] Nextcloud Talk integration ✅ — 2026-03-20, updated 2026-03-27 +- HMAC verification: incoming uses `random + raw_body`; outgoing reply uses `random + message_text` +- Per-user routing added 2026-03-27 (endpoint: `/webhook/nextcloud/{username}`) +- Docs: `docs/NEXTCLOUD_TALK_BOT.md` + +### [Channel] Google Chat integration ✅ — 2026-03-20, updated 2026-03-27 +- JWT verification via `authorizationEventObject.systemIdToken` +- Workspace Add-on format: `hostAppDataAction.chatDataAction.createMessageAction` +- Per-user routing added 2026-03-27 (endpoint: `/channels/google-chat/{username}`) +- Docs: `docs/GOOGLE_CHAT_BOT.md` + +### [Intelligence] Orchestrator service — Phase 1 — 2026-03-18 +- Gemini API (google-genai SDK) tool loop → Claude final response +- `POST /orchestrate` (async job), `GET /orchestrate/{job_id}` (poll) +- Tools: web search, AE API, file read, task list, scratch, reminders, cron +- Default model: `gemini-2.5-flash` + +### [Auth] Session auth + persona onboarding — 2026-03-20 +- bcrypt passwords in `home/{username}/auth.json` +- JWT session cookies (HS256, 30-day expiry) +- Invite tokens (72h, one-time-use) — `manage_passwords.py invite [email]` +- Self-service onboarding: `/setup/{token}` → `/setup/persona` +- SMTP invite email via `noreply@oneskyit.com` + +### [UI] Mobile-friendly header — 2026-03 - Backend toggle, font size, theme buttons moved into ⚙ settings panel -- Header reduced to 4 buttons: Sessions, Files, ⚙, ? -- Committed: `mobile_header` (2026-03) +- Header reduced to core buttons -### [UI] Mobile text input -- `flex-direction: column` on `#input-area` at ≤520px -- `font-size: 16px` on `#input` (prevents iOS Safari auto-zoom) -- `body { height: 100dvh }` (handles soft keyboard) -- Committed: `23f8659` (2026-03) +### [UI] Help & Reference — 2026-03-27 +- Shared base at `cortex/static/HELP.md` (served to all users) +- Persona-specific additions appended from `home/{username}/persona/{name}/HELP.md` if present +- Collapsible H2 sections via `
` elements -### [UI] Auth warning banner -- Claude CLI token expiry check (`~/.claude/.credentials.json`) -- Gemini CLI auth check (warns only if no `refresh_token`) -- Dismissible amber/red banner with re-auth instructions -- Committed: `fe6561b` (2026-03) +### [Backend] Gemini CLI backend — 2026-03 +- `gemini -p` subprocess, streaming output; auth check at `/auth/status` -### [UI] Distill schedule in ⚙ panel -- Shows next_run times for short/mid/long distill jobs -- Fetches from existing `/distill/status` endpoint +### [Backend] Memory distiller — 2026-03 +- APScheduler: `distill_short` (daily 03:00), `distill_mid` (weekly Sun 03:30), `distill_long` (monthly 1st 04:00) +- Writes to `MEMORY_SHORT.md`, `MEMORY_MID.md`, `MEMORY_LONG.md` per persona -### [UI] Help modal collapsible sections -- H2 sections collapse/expand via `
` elements -- Top 4 sections (Header Controls, Chat, Sessions, Notes) open by default +### [Backend] Session logging + file browser — 2026-03 +- Sessions saved to `home/{user}/persona/{name}/sessions/` +- Files panel in UI browses persona directory -### [Backend] Gemini CLI backend -- `gemini -p` subprocess, streaming output -- Auth check endpoint `/auth/status` - -### [Backend] Memory distiller -- APScheduler jobs: `distill_short` (6h), `distill_mid` (24h), `distill_long` (weekly) -- Writes to `inara/MEMORY_SHORT.md`, `MEMORY_MID.md`, `MEMORY_LONG.md` - -### [Backend] Session logging + file browser -- Sessions saved to `inara/sessions/` -- Files panel in UI browses `inara/` directory - -### [Backend] Dispatcher core -- FastAPI service with streaming response -- `claude -p` and `gemini -p` subprocess backends -- Session context management (rolling window) -- Nextcloud Talk webhook handler +### [Backend] Dispatcher core — 2026-03-04 +- FastAPI service with streaming SSE response +- Claude CLI and Gemini CLI subprocess backends +- Session context management (rolling window, `MAX_HISTORY_MESSAGES`)