694 lines
35 KiB
Markdown
694 lines
35 KiB
Markdown
# Roadmap — Chat Switchboard
|
||
|
||
**See also:**
|
||
- [ARCHITECTURE.md](ARCHITECTURE.md) — Core services design, store layer, scope model
|
||
- [EXTENSIONS.md](EXTENSIONS.md) — Extension system spec (Browser/Starlark/Sidecar tiers,
|
||
manifests, browser tool bridge, surfaces/modes, model roles)
|
||
- [CHANGELOG.md](../CHANGELOG.md) — Detailed release notes for all completed versions
|
||
|
||
**Versioning (pre-1.0):** `0.<major>.<minor>` — hotfixes use quad: `0.x.y.z`
|
||
No compatibility guarantees before 1.0.
|
||
|
||
---
|
||
|
||
## Dependency Graph
|
||
|
||
Features have real dependencies. This ordering respects them.
|
||
|
||
```
|
||
v0.9.x Stability + Quick UX Wins ✅
|
||
│
|
||
v0.9.3 Content Visibility & Block Controls ✅
|
||
│
|
||
v0.9.4 API Key Encryption + Vault ✅
|
||
│
|
||
v0.10.0 Model Roles (utility + embedding) ✅
|
||
+ Usage Tracking
|
||
│
|
||
v0.10.2 Summarize & Continue ✅
|
||
│
|
||
v0.10.3 Frontend Refactor ✅
|
||
│
|
||
v0.10.4 Model Type Pipeline + Role Fixes ✅
|
||
│
|
||
v0.10.5 UI Primitives + Extension Surfaces ✅
|
||
│
|
||
v0.11.0 Extension Foundation (browser tier) ✅
|
||
│
|
||
┌───────┴──────────────┐
|
||
│ │
|
||
v0.12.0 File Handling v0.13.0 Admin Panel
|
||
+ Vision ✅ Refactor (fullscreen) ✅
|
||
│ │
|
||
│ v0.13.1 Web Search
|
||
│ + url_fetch ✅
|
||
│ │
|
||
└───────┬──────────────┘
|
||
│
|
||
v0.14.0 Knowledge Bases ✅ (embedding role + file storage + pgvector)
|
||
│
|
||
v0.15.0 Compaction ✅ (utility role + background job)
|
||
│
|
||
v0.15.1 Context Recall Tools ✅ (attachment_recall, conversation_search)
|
||
│
|
||
┌───────┴──────────────┐
|
||
│ │
|
||
v0.16.0 User Groups v0.17.0 Persona-KB Binding
|
||
+ Resource Grants ✅ + Enterprise KB Mode
|
||
│ + QOL / UX Wins
|
||
└───────┬──────────────┘
|
||
│
|
||
┌───────┴──────────────┐
|
||
│ │
|
||
v0.17.1 SQLite Backend ✅ v0.17.2 CodeMirror 6
|
||
(dual DB) (editor bundle, chat
|
||
│ input, ext editor)
|
||
└───────┬──────────────┘
|
||
│
|
||
v0.18.0 Memory (user + persona scopes, review pipeline)
|
||
│
|
||
v0.19.0 Projects / Workspaces + Notifications
|
||
│
|
||
v0.20.0 @mention Routing + Multi-model
|
||
│
|
||
v0.21.0 Extension Surfaces + Modes (depends on CM6 from v0.17.2)
|
||
│
|
||
v0.22.0 Smart Routing + Provider Extensions
|
||
│
|
||
v0.23.0 Multi-Participant Channels + Presence
|
||
│
|
||
v0.24.0 Auth Strategy (mTLS/OIDC) + Full RBAC + Group permissions
|
||
│
|
||
┌───────┴──────────────┐
|
||
│ │
|
||
v0.25.0 Workflow v0.26.0 Tasks /
|
||
Engine Autonomous Agents
|
||
(team-owned, (service channels,
|
||
staged processes, scheduler, unattended
|
||
human + AI collab) execution)
|
||
```
|
||
|
||
---
|
||
|
||
## Completed Releases
|
||
|
||
> Full details for all completed versions are in [CHANGELOG.md](../CHANGELOG.md).
|
||
|
||
### ✅ v0.9.0 — Schema Consolidation + BYOK
|
||
21 migrations → single schema, store layer abstraction, persona-as-trust-boundary,
|
||
BYOK with auto-fetch, composite model IDs, journey integration tests.
|
||
|
||
### ✅ v0.9.1 — Capability Architecture + Docs
|
||
Removed static known model table. Resolution chain: catalog → heuristic only.
|
||
Frontend relies solely on backend for capabilities. Docs rewrite.
|
||
|
||
### ✅ v0.9.2 — Quick UX Wins + Hardening
|
||
Collapsible code blocks, HTML preview, token counter, context warning, proxy
|
||
interception detection, environment injection, team admin audit scoping.
|
||
|
||
### ✅ v0.9.3 — Content Visibility & Block Controls
|
||
Button-driven code collapse, always-rendered thinking blocks, tool call
|
||
persistence in history, Notes panel → unified side panel, streaming refactor
|
||
(`streamWithToolLoop`), regenerate fix.
|
||
|
||
### ✅ v0.9.4 — API Key Encryption + Vault
|
||
Two-tier AES-256-GCM: env-var key for global/team, per-user UEK (Argon2id)
|
||
for personal BYOK. `server/crypto/` package. Migration 003. Startup backfill.
|
||
DOMPurify strict allowlist (XSS fix).
|
||
|
||
### ✅ v0.10.0 — Model Roles + Usage Tracking + Vault Debt
|
||
Named role slots (utility, embedding) with fallback. `Provider.Embed()` interface.
|
||
`usage_log` + `model_pricing` tables. Streaming token capture. Vault debt:
|
||
UEK re-wrap on password change, destruction on admin reset.
|
||
|
||
### ✅ v0.10.1 — Polish + UX
|
||
Admin system prompt injection, Personas tab, Team Management modal extraction,
|
||
preview pane enhancements, code download, personal usage scoped to BYOK.
|
||
|
||
### ✅ v0.10.2 — Summarize & Continue + Role Cleanup
|
||
User-triggered conversation compaction via utility role. Summary as tree node
|
||
with boundary metadata. BYOK role overrides (personal → team → global).
|
||
Utility rate limiting. Generation role removed.
|
||
|
||
### ✅ v0.10.3 — Frontend Refactor
|
||
2 monolith files → 13 domain-scoped files (~544 lines avg). Zero features,
|
||
no function renames. Vanilla JS, no build step.
|
||
See [REFACTOR-0.10.3.md](REFACTOR-0.10.3.md).
|
||
|
||
### ✅ v0.10.4 — Model Type Pipeline + Role Fixes
|
||
`model_type` (chat/embedding/image) captured end-to-end from provider API
|
||
through catalog to frontend. Role dropdowns filter by type.
|
||
|
||
### ✅ v0.10.5 — UI Primitives + Extension Surfaces
|
||
Shared `Providers`/`Roles` registries, 6 consolidated render primitives,
|
||
`showConfirm()` replacing native dialogs, `.popup-menu` CSS primitive.
|
||
Removed ~400 lines of duplication.
|
||
|
||
### ✅ v0.11.0 — Extension Foundation (Browser Tier)
|
||
Full extension lifecycle: manifest, loader, scoped `ctx.*` API, browser tool
|
||
bridge via WebSocket. Custom renderer pipeline. 2 server tools (calculator,
|
||
datetime), 6 built-in browser extensions (Mermaid, KaTeX, CSV, Diff, JS
|
||
Sandbox, Regex). See [EXTENSIONS.md](EXTENSIONS.md).
|
||
|
||
### ✅ v0.12.0 — File Handling + Vision
|
||
S3/PVC storage backend, image/file upload (📎, drag-drop, paste), multimodal
|
||
message assembly, text extraction pipeline (PDF/DOCX/XLSX/PPTX/ODT/RTF),
|
||
vault CLI (`rekey`/`status`), per-chat model persistence.
|
||
|
||
### ✅ v0.13.0 — Admin Panel Refactor
|
||
12-tab modal → fullscreen admin panel. 4 categories (People, AI, System,
|
||
Monitoring) × section sidebar. URL-based routing, responsive, banner-aware.
|
||
CSS design token cleanup.
|
||
|
||
### ✅ v0.13.1 — Web Search + URL Fetch
|
||
`web_search` + `url_fetch` tools. Search provider abstraction (DuckDuckGo,
|
||
SearXNG). Tool categories with per-tool toggle UI in chat bar.
|
||
|
||
### ✅ v0.14.0 — Knowledge Bases
|
||
RAG: upload → chunk → embed (pgvector) → `kb_search` tool. Channel KB toggle.
|
||
Team/personal KB scopes. Notes semantic search. Admin panel KB management.
|
||
See [DESIGN-0.14.0.md](DESIGN-0.14.0.md).
|
||
|
||
### ✅ v0.15.0 — Compaction
|
||
Background scanner with configurable thresholds. Automatic summarization via
|
||
utility role. Per-channel opt-in/out. Context budget guard rail (80% ceiling).
|
||
|
||
### ✅ v0.15.1 — Context Recall Tools
|
||
`attachment_recall` (list + read, channel-scoped), `conversation_search`
|
||
(full-text via `plainto_tsquery`). Token estimator attachment awareness.
|
||
|
||
### ✅ v0.16.0 — User Groups + Resource Grants
|
||
Groups (global/team-scoped ACLs) decoupled from team membership. Three-way
|
||
resource grants (team_only/global/groups) for Personas and KBs. Grant picker
|
||
UI. Schema consolidation: 9 migrations → single `001_v016_schema.sql`.
|
||
|
||
---
|
||
|
||
## v0.17.0 — Persona-KB Binding + Enterprise KB Mode + QOL ✅
|
||
|
||
Personas become **gateways** to knowledge. In enterprise deployments,
|
||
users don't interact with KBs directly — they talk to Personas that
|
||
have KBs attached. Plus quality-of-life improvements: chat rename,
|
||
token display, state persistence, utility model auto-naming.
|
||
|
||
Depends on: knowledge bases (v0.14.0), user groups (v0.16.0).
|
||
|
||
**Persona-KB Binding**
|
||
- [x] `persona_knowledge_bases` table: `persona_id`, `kb_id`, `auto_search` (bool — always search vs tool-only)
|
||
- [x] When a channel uses a Persona with bound KBs, `kb_search` is auto-scoped to those KBs
|
||
- [x] No user toggle needed — Persona carries its own KB context
|
||
- [x] Channel KB toggle becomes "additional KBs" on top of Persona-provided ones
|
||
- [x] Persona system prompt auto-includes KB listing hint (reuses `BuildKBHint` pattern)
|
||
- [x] Admin/team admin UI: KB picker on Persona create/edit form
|
||
|
||
**Enterprise KB Mode**
|
||
- [x] `discoverable` flag on knowledge_bases: `true` (default — appears in user's KB popup) or `false` (hidden, only accessible through Persona binding)
|
||
- [x] Hidden KBs don't appear in `GET /api/v1/knowledge-bases-discoverable` for non-admins
|
||
- [x] Hidden KBs still searchable by `kb_search` tool when accessed through a Persona
|
||
- [x] Admin panel: toggle discoverability per KB
|
||
- [x] Platform policy: `kb_direct_access` — when `false`, disables channel KB popup entirely (strict enterprise mode)
|
||
|
||
**Access Control Integration**
|
||
- [x] Persona grants (v0.16.0 groups) control who can *use* a Persona
|
||
- [x] KB grants control who can *manage* a KB (upload/delete docs)
|
||
- [x] Persona-KB binding grants implicit *search* access through the Persona
|
||
- [x] Users who can use a Persona can search its KBs, even if they can't see those KBs directly
|
||
|
||
**Team Admin Workflow**
|
||
- [x] Team admin creates KB → uploads documents → marks non-discoverable
|
||
- [x] Team admin creates Persona → binds KBs → sets access to Team Only or specific Groups
|
||
- [x] Team members see the Persona in their preset list, use it, get KB-powered answers
|
||
- [x] Team members never see or manage the underlying KBs
|
||
|
||
**Technical Debt (carried forward)**
|
||
- [x] **Security**: KB create handler authorization — team/global scope verified
|
||
- [x] **Test hygiene**: stripped DIAG diagnostics from `TestGroupBasedPersonaAccess`
|
||
- [x] **Architecture**: `KnowledgeBaseStore.UpdateDocumentStorageKey()` — moved to store layer
|
||
- [x] **UX**: Embedding dropdown fix — tolerant type filter, manual model ID fallback, auto-switch on empty _(already implemented in `ui-primitives.js`)_
|
||
- [x] **Minor**: Paste-to-file character threshold — synced from backend `PublicSettings` (`storage.paste_to_file_chars`), admin-configurable, default 2000
|
||
|
||
**Role Fallback Alerts** ([#69](https://git.gobha.me/xcaliber/chat-switchboard/issues/69))
|
||
- [x] Audit log entry on fallback fire: `action = "role.fallback"` with primary/fallback model IDs and error string
|
||
- [x] `role.fallback` WebSocket event via EventBus (`PublishAsync`, zero latency impact on completion path)
|
||
- [x] In-memory cooldown on `Resolver` (per-role, 5-minute TTL) to deduplicate repeated fallback alerts
|
||
- [x] Admin UI: persistent alert banner on `role.fallback` event (persists until dismissed)
|
||
- [x] Wire `*events.Bus` into `roles.NewResolver` via `.WithBus()` builder
|
||
|
||
**QOL / UX Wins**
|
||
- [x] **Chat rename**: inline edit on sidebar item — dblclick title → input → blur/Enter saves via `API.updateChannel(id, { title })`
|
||
- [x] **Chat token count**: display `Tokens.estimateConversation()` in model bar, update on `selectChat` and after each message
|
||
- [x] **State restore on refresh**: persist `App.currentChatId` to `sessionStorage` on select, restore on load
|
||
- [x] **Utility model auto-naming**: after first assistant response, background utility role request → `POST /channels/:id/generate-title` → re-render sidebar. Fallback to truncation when no utility model configured. Debounced via `_autoNamePending` set
|
||
- [x] **SW extension cache fix**: exclude `/extensions/` from service worker fetch handler
|
||
- [x] **Mermaid renderer**: promoted enhanced version (v2.0 — pan/zoom, SVG/PNG export, source copy) to `extensions/builtin/mermaid-renderer/`
|
||
|
||
---
|
||
|
||
## v0.17.1 — SQLite Backend ✅
|
||
|
||
Dual-database support. Every subsequent schema change is developed
|
||
against both Postgres and SQLite from day one — no retrofit. SQLite
|
||
enables single-binary deployment for dev, demo, edge, and single-user.
|
||
|
||
Depends on: v0.17.0 DB debt cleanup (store layer is sole DB interface).
|
||
|
||
**Store Layer**
|
||
- [x] 19 SQLite store implementations covering all domain interfaces
|
||
- [x] `DB_DRIVER` env var: `postgres` (default) | `sqlite`
|
||
- [x] Separate migration files per driver (`migrations/sqlite/`)
|
||
- [x] WAL mode + single-writer connection pooling for SQLite concurrency
|
||
- [x] CI matrix: full handler integration tests against both Postgres and SQLite
|
||
|
||
**Vector Search**
|
||
- [x] App-level cosine similarity in Go (pure Go, no CGO/sqlite-vec required)
|
||
- [x] Embeddings stored as JSON text in `kb_chunks.embedding` column
|
||
- [x] Full feature parity with pgvector: `SimilaritySearch`, `InsertChunks`
|
||
- [x] Graceful: adequate performance for SQLite-scale deployments (single-user, not millions of chunks)
|
||
|
||
**Schema Compatibility**
|
||
- [x] UUID generation: application-side `store.NewID()` (Go `uuid.New()`)
|
||
- [x] JSONB → JSON text columns with `ToJSON()`/`ScanJSON()` helpers
|
||
- [x] `UUID[]` arrays → JSON arrays with `ToJSONArray()`/`ScanJSONArray()`
|
||
- [x] `TIMESTAMPTZ` → SQLite `TEXT` with `datetime('now')`
|
||
- [x] `ON CONFLICT excluded.*` pattern (works in both dialects)
|
||
- [x] `INSERT RETURNING id` → separate query pattern for SQLite
|
||
|
||
**Test Infrastructure**
|
||
- [x] `dialectSQL()` converts `$N` → `?` and strips `::jsonb` at runtime
|
||
- [x] `database.PH(n)` returns dialect-appropriate placeholder
|
||
- [x] `database.TruncateAll()` dialect-aware (DELETE + PRAGMA vs TRUNCATE CASCADE)
|
||
- [x] Generic provider config: `PROVIDER`/`PROVIDER_KEY`/`PROVIDER_URL` (replaces `VENICE_API_KEY`)
|
||
- [x] Model selection prefers non-reasoning models in live tests
|
||
|
||
**What SQLite mode skips** (feature-gated, not broken):
|
||
- [x] `LISTEN/NOTIFY` — WebSocket event fan-out uses in-process EventBus (already works)
|
||
- [x] Full-text search `tsvector` — conversation_search uses LIKE fallback
|
||
|
||
---
|
||
|
||
## v0.17.2 — CodeMirror 6 Integration
|
||
|
||
Rich editor infrastructure for the frontend. CM6 is ESM-native; the build
|
||
step runs in Docker (esbuild → single IIFE bundle). No change to dev
|
||
experience for non-editor code — the rest of `src/js/` stays vanilla.
|
||
|
||
Depends on: nothing (frontend-only). Prerequisite for: extension surfaces
|
||
(v0.21.0 editor mode). See [DESIGN-CM6.md](DESIGN-CM6.md) for full spec.
|
||
|
||
**Build Pipeline**
|
||
- [ ] `src/editor/` directory: `package.json`, `build.mjs`, `index.mjs`, language/theme modules
|
||
- [ ] `scripts/build-editor.sh`: shared build script for both Dockerfiles and local dev
|
||
- [ ] New Docker stage (`cm6-build`): `npm ci` + `node build.mjs` → `vendor/codemirror/`
|
||
- [ ] Both `Dockerfile.frontend` and `Dockerfile` (unified) use the shared build script
|
||
- [ ] Bundle output: `codemirror.bundle.js` (~295KB min, ~90KB gzip) + `codemirror.bundle.css`
|
||
- [ ] Graceful degradation: all integration points check `window.CM` — falls back to `<textarea>` if bundle unavailable
|
||
|
||
**Languages (bundled)**
|
||
- [ ] Markdown, JavaScript, JSON, SQL, HTML, CSS, YAML, Go, Python, Rust
|
||
- [ ] Additional modes: one-line import + rebuild
|
||
|
||
**Phase 1: Extension Editor** (admin panel)
|
||
- [ ] `CM.codeEditor()` factory: line numbers, bracket matching, auto-indent, search/replace
|
||
- [ ] Replace manifest `<textarea>` → CM6 JSON mode
|
||
- [ ] Replace script `<textarea>` → CM6 JavaScript mode
|
||
- [ ] Remove manual Tab-key handler in `admin-handlers.js` (CM6 handles it)
|
||
- [ ] Update `saveAdminExtension()` to use `.getValue()`
|
||
|
||
**Phase 2: Chat Input** (markdown mode)
|
||
- [ ] `CM.chatInput()` factory: markdown highlighting, minimal chrome (no line numbers, no gutter)
|
||
- [ ] Enter=send, Shift+Enter=newline keybindings
|
||
- [ ] Auto-growing height, placeholder text
|
||
- [ ] Wire `onChange` → `updateInputTokens()`
|
||
- [ ] Update `chat.js`, `attachments.js`, `tokens.js` to use CM API
|
||
- [ ] Test paste handling (plain text, code, attachments) and mobile/touch input
|
||
|
||
**Phase 3: Polish**
|
||
- [ ] Theme integration: CSS variable overrides (`--bg`, `--border`, `--accent`, etc.)
|
||
- [ ] Dark/light mode switching (listen for theme toggle event)
|
||
- [ ] Vim/Emacs keybinding preference in appearance settings (`@replit/codemirror-vim`, `@replit/codemirror-emacs`)
|
||
- [ ] Vim/Emacs applies to code editor + extension editor only (never chat input)
|
||
- [ ] SW cache: exclude `vendor/codemirror/` or add to `SHELL_FILES` with version bust
|
||
- [ ] Update `debug.js` snapshot to include CM6 version
|
||
- [ ] Documentation in ARCHITECTURE.md
|
||
|
||
---
|
||
|
||
## v0.18.0 — Memory (User + Persona Scopes)
|
||
|
||
Long-term memory across conversations, with scope-aware isolation.
|
||
Unlike KB (static documents) or compaction (within-conversation), this
|
||
captures facts and preferences that persist across channels.
|
||
|
||
**Key differentiator: Persona-scoped memory.** Each Persona can build
|
||
its own memory independently of user memory, preventing cross-context
|
||
contamination and enabling specialized knowledge accumulation.
|
||
|
||
Depends on: compaction (v0.15.0), knowledge bases (v0.14.0), persona-KB binding (v0.17.0), SQLite backend (v0.17.1).
|
||
|
||
**Memory Scopes**
|
||
- [ ] `user` — personal facts/preferences, persists across all conversations (current industry standard)
|
||
- [ ] `persona` — shared across all users of that Persona, accumulated from conversations (differentiator)
|
||
- [ ] `persona+user` — per-user within a Persona context (e.g. tutoring progress per student)
|
||
- [ ] Configurable per Persona: which scopes are active, whether user memory is passed through
|
||
|
||
**Data Model**
|
||
- [ ] `memories` table: `id`, `scope` (user, persona, persona_user), `owner_id` (user_id or persona_id), `user_id` (nullable — for persona+user scope), `key`, `value`, `source_channel_id`, `confidence` (float), `status` (active, pending_review, archived), `created_at`, `updated_at`
|
||
- [ ] Index on `(scope, owner_id, user_id)` for fast lookup
|
||
- [ ] Embedding column (`vector(3072)`) for semantic memory search
|
||
|
||
**Tools**
|
||
- [ ] `memory_save` tool: LLM explicitly stores a fact
|
||
- Scope-aware: saves to the active memory scope for the current Persona context
|
||
- Structured: `key` (short label) + `value` (detail) + `confidence`
|
||
- [ ] `memory_recall` tool: LLM queries stored facts relevant to current context
|
||
- Merges results from applicable scopes (user + persona + persona+user)
|
||
- Semantic search via embeddings + keyword fallback
|
||
|
||
**Automatic Extraction**
|
||
- [ ] Background job: post-conversation analysis identifies memorable facts (opt-in)
|
||
- [ ] Configurable extraction prompt per Persona (e.g. "extract FAQ-worthy Q&A pairs")
|
||
- [ ] Extracted memories start in `pending_review` status
|
||
|
||
**Review Pipeline**
|
||
- [ ] Admin/team admin review queue: pending memories with approve/reject/edit
|
||
- [ ] Persona memory review: team admins see what Personas are "learning"
|
||
- [ ] User memory review: users see their own memories in Settings
|
||
|
||
**Memory Injection**
|
||
- [ ] At completion time: inject relevant memories into system prompt
|
||
- [ ] Context budget aware: limit injected memory tokens
|
||
- [ ] Scope priority: persona+user > persona > user (most specific wins on conflicts)
|
||
|
||
**Use Cases**
|
||
- [ ] Helpdesk Persona: builds FAQ from repeated questions, human-reviewable
|
||
- [ ] Roleplay Persona: isolated memory prevents tone/context bleeding from user's other conversations
|
||
- [ ] Tutoring Persona: tracks per-student progress, common misconceptions
|
||
- [ ] Sales Persona: accumulates objection responses from real conversations
|
||
- [ ] Onboarding Persona: learns what new hires commonly struggle with
|
||
|
||
**User Controls**
|
||
- [ ] Settings → Memory: view, edit, delete personal memories
|
||
- [ ] Per-Persona memory toggle: "Allow this persona to remember things about me"
|
||
- [ ] Admin: enable/disable, retention policies, per-team scoping
|
||
- [ ] Privacy: user memories never cross team boundaries; persona memories respect group access
|
||
|
||
---
|
||
|
||
## v0.19.0 — Projects / Workspaces + Notifications
|
||
|
||
Organizational containers that group related conversations, KBs, and
|
||
notes into a single workspace with shared access controls. Plus the
|
||
notification infrastructure that makes collaboration real-time.
|
||
|
||
Depends on: user groups (v0.16.0), knowledge bases (v0.14.0).
|
||
|
||
**Data Model**
|
||
- [ ] `projects` table: `id`, `name`, `description`, `scope` (personal, team, global), `owner_id`, `team_id`, `settings` (JSONB), `created_at`, `updated_at`
|
||
- [ ] `project_resources` table: `project_id`, `resource_type` (channel, knowledge_base, note), `resource_id`, `added_at`
|
||
- [ ] Projects use the same grant model (v0.16.0): team_only / global / groups
|
||
|
||
**Features**
|
||
- [ ] Channels can belong to a project (optional `project_id` FK)
|
||
- [ ] KBs can belong to a project → auto-linked to all channels in the project
|
||
- [ ] Notes can belong to a project → visible to all project members
|
||
- [ ] Project-level Persona default: all new channels in the project start with this Persona
|
||
- [ ] Project sidebar section: grouped view of conversations with folder-like nesting
|
||
|
||
**UI**
|
||
- [ ] Sidebar: projects as collapsible groups above/integrated with chat history
|
||
- [ ] Project creation dialog (name, description, default Persona, default KBs)
|
||
- [ ] Drag channels/notes into projects
|
||
- [ ] Folders within projects (lightweight — just a `path` column on project_resources)
|
||
- [ ] Project settings: manage resources, access, defaults
|
||
|
||
**Enterprise Use**
|
||
- [ ] Team admins create projects for their teams
|
||
- [ ] Project templates: pre-configured with specific Personas, KBs, and settings
|
||
- [ ] Cross-team projects via group grants
|
||
|
||
**Notifications**
|
||
- [ ] `notifications` table: `id`, `user_id`, `type`, `title`, `body`, `resource_type`, `resource_id`, `is_read`, `created_at`
|
||
- [ ] In-app notification bell (header bar, unread count badge)
|
||
- [ ] Notification dropdown: grouped by type, mark read, click-to-navigate
|
||
- [ ] WebSocket push: real-time delivery via existing EventBus (`notification.new` event)
|
||
- [ ] Notification sources: group membership changes, grant updates, KB processing complete, project invites, team invites
|
||
- [ ] Email transport (optional): SMTP config in admin settings, per-user opt-in/out
|
||
- [ ] Email templates: HTML + plaintext, branded with instance name
|
||
- [ ] Digest mode: batch low-priority notifications into periodic email (hourly/daily)
|
||
- [ ] Admin settings: enable/disable email, SMTP config, default notification preferences
|
||
- [ ] User preferences: per-type toggles (in-app, email, off)
|
||
|
||
---
|
||
|
||
## v0.20.0 — @mention Routing + Multi-model
|
||
|
||
The channel schema already supports multiple models. This adds routing.
|
||
|
||
_(Shifted from v0.17.0 — no content changes)_
|
||
|
||
- [ ] @mention parsing in messages (users and AI models)
|
||
- [ ] Resolve mentions against `channel_models`
|
||
- [ ] Multi-model channels: fire completions per mentioned model
|
||
- [ ] "Add a model" UI per channel
|
||
- [ ] Enables: second opinions, cross-model conversations
|
||
|
||
---
|
||
|
||
## v0.21.0 — Extension Surfaces + Modes
|
||
|
||
Depends on: extension foundation (v0.11.0), CodeMirror 6 (v0.17.2).
|
||
See [EXTENSIONS.md §6](EXTENSIONS.md#6-surfaces-modes).
|
||
|
||
_(Shifted from v0.18.0 — no content changes)_
|
||
|
||
- [ ] Surface registration and activation API
|
||
- [ ] Mode selector in sidebar (below brand, above chat history)
|
||
- [ ] `ctx.ui.replace()` / `ctx.ui.restore()` for region management
|
||
- [ ] `surface.activated` / `surface.deactivated` events
|
||
- [ ] Editor mode (extension: file tree + CM6 code editor + AI chat split pane)
|
||
- [ ] Article mode (extension: outline + rich text + AI assistant panel)
|
||
- [ ] Document generation output storage: extension → attachment → download pipeline _(prerequisite for editor/article output)_
|
||
|
||
**REPL / Debug Console** ([#70](https://git.gobha.me/xcaliber/chat-switchboard/issues/70))
|
||
- [ ] Fourth tab in debug modal (Ctrl+Shift+L): `[ Console | Network | State | REPL ⚠ ]`
|
||
- [ ] `AsyncFunction` wrapper for top-level `await` — injects `API`, `Events`, `Extensions`, `DebugLog` as globals
|
||
- [ ] Pretty-print results: collapsible JSON (reuse State tab renderer), errors in red with stack
|
||
- [ ] Command history: ↑/↓ navigation, `sessionStorage` (not `localStorage` — no stale credentials across sessions)
|
||
- [ ] Tab-completion on live object graphs: walk `Object.getOwnPropertyNames` + prototype chain, own-first sort
|
||
- [ ] Event label hints: secondary completion when typing `Events.publish('` or `Events.on('` — sourced from routeTable constants
|
||
- [ ] Every executed command echoed as `REPL:EXEC` entry in Console tab (trace of what ran)
|
||
- [ ] Toolbar: Clear (output only), Copy session (full transcript), Help (available globals guide)
|
||
- [ ] Multi-line input: Shift+Enter for newline, Enter to run
|
||
- [ ] Access gate: admin-role only (same `isAdmin` check as admin panel) OR `?debug=1` URL param
|
||
- [ ] _Nice-to-have_: snippets library dropdown ("List channels", "Show current user", "Ping WebSocket", "List loaded extensions")
|
||
- [ ] _Nice-to-have_: method signature tooltip from `fn.toString()` parsing on autocomplete selection
|
||
- [ ] Files: `index.html` (tab markup), `debug.js` (ReplRunner object), `debug.css` (output, input, suggestion dropdown)
|
||
|
||
---
|
||
|
||
## v0.22.0 — Smart Routing + Provider Extensions
|
||
|
||
Depends on: model roles (v0.10.0), usage tracking (v0.10.0).
|
||
Rules-based routing engine — policy, not ML. Plus declarative provider
|
||
configuration to replace hardcoded provider-specific behavior.
|
||
|
||
_(Shifted from v0.19.0 — routing content unchanged, provider extensions added)_
|
||
|
||
**Routing**
|
||
- [ ] Admin routing policies: "cheapest model with required capabilities",
|
||
"prefer private providers, fallback to cloud", "for team X, use Y"
|
||
- [ ] Fallback chains: primary provider down → next with same model
|
||
- [ ] Cost-aware: factor pricing into routing decisions
|
||
- [ ] Latency-aware: track response times per provider, prefer faster
|
||
|
||
**Provider Extensions (declarative provider config)**
|
||
- [ ] `provider_profiles` table (or JSONB on `api_configs`): per-provider configuration schema
|
||
- [ ] System prompt injection: provider-specific preambles (e.g. Venice character system prompt)
|
||
- [ ] Thinking mode toggle: per-provider `think` parameter support (Venice `venice_parameters.include_venice_system_prompt`, Anthropic `thinking`, etc.)
|
||
- [ ] Request transform hooks: provider-specific parameter mapping before API call
|
||
- [ ] Response transform hooks: normalize provider-specific response fields
|
||
- [ ] Admin UI: provider profile editor (key-value config per provider type)
|
||
- [ ] Preset-level overrides: Persona can override provider-specific settings (e.g. "always enable thinking for this Persona")
|
||
- [ ] Provider health: track error rates, latency percentiles, auto-disable unhealthy providers
|
||
- [ ] Search/URL fetch rate limiting per provider
|
||
- [ ] Capability admin/user override: manual correction for model capabilities (`intrinsic.go` admin override layer)
|
||
|
||
---
|
||
|
||
## v0.23.0 — Multi-Participant Channels + Presence
|
||
|
||
The channel foundation for workflows and real-time collaboration. Today
|
||
channels are single-user direct chats. This release makes channels a
|
||
shared space that multiple actors can inhabit.
|
||
|
||
Depends on: extension surfaces (v0.21.0), WebSocket infrastructure (already exists).
|
||
|
||
_(Shifted from v0.20.0 — no content changes)_
|
||
|
||
**Channel Participants**
|
||
- [ ] `channel_participants` table: `channel_id`, `participant_type` (user, session, persona), `participant_id`, `role` (owner, member, observer), `joined_at`
|
||
- [ ] Channel access queries rewritten: `WHERE user_id = $1` → participant-based lookup
|
||
- [ ] Backward compatible: existing single-user channels auto-have one participant (owner)
|
||
- [ ] Channel `type` column: `direct` (current), `group` (multi-user), `workflow` (staged)
|
||
|
||
**Presence + Real-time**
|
||
- [ ] Typing indicators and presence (who's online, who's in this channel)
|
||
- [ ] Participant join/leave events via WebSocket
|
||
- [ ] Co-editing for extension surfaces (editor mode, article mode)
|
||
- [ ] Cursor sharing, selection highlighting
|
||
|
||
**Channel-Scoped Notes**
|
||
- [ ] Optional `channel_id` FK on notes (NULL = personal notebook, set = channel-attached)
|
||
- [ ] Notes created by tool calls within a channel auto-attach to that channel
|
||
- [ ] Channel notes visible to all participants (not just creator)
|
||
|
||
---
|
||
|
||
## v0.24.0 — Auth Strategy (mTLS/OIDC) + Full RBAC
|
||
|
||
Enterprise auth modes on top of the teams + groups foundation.
|
||
Depends on: vault passphrase support from v0.9.3 (conditional unlock for
|
||
personal providers under external auth), user groups (v0.16.0).
|
||
|
||
_(Shifted from v0.21.0 — enhanced with group-based permissions)_
|
||
|
||
- [ ] `AUTH_MODE` env var: `builtin` | `mtls` | `oidc`
|
||
- [ ] All three resolve to the same internal user model
|
||
- [ ] `auth_source` + `external_id` columns on users table
|
||
- [ ] mTLS: header trust, auto-provision from cert DN
|
||
- [ ] OIDC: Keycloak/Okta token validation, claim extraction, role mapping
|
||
- [ ] Per-source auto-activate policy: auto_activate, default_team, default_role
|
||
- [ ] Vault passphrase prompt for mTLS/OIDC users (v0.9.3 conditional unlock)
|
||
- [ ] Fine-grained permissions: model access, KB write, task create, token budgets
|
||
- [ ] Group-based permission sets: assign permissions to groups, users inherit from membership
|
||
- [ ] OIDC claim → group mapping: external IdP groups auto-sync to internal groups
|
||
|
||
**Anonymous / Session Participants**
|
||
- [ ] Session-based identity for unauthenticated visitors (workflow intake)
|
||
- [ ] mTLS: cert CN/fingerprint as stable session identity (no `users` row required)
|
||
- [ ] Non-mTLS: ephemeral session token (cookie or URL token)
|
||
- [ ] Session participants can send messages and trigger tool calls within workflow channels
|
||
- [ ] Session identity visible to assigned team members (cert DN, display name, or "Anonymous #N")
|
||
|
||
---
|
||
|
||
## v0.25.0 — Workflow Engine
|
||
|
||
Team-owned, stage-based process execution. The channel is the runtime,
|
||
personas drive each stage, and the existing tool/notes infrastructure
|
||
handles structured data collection. See [ARCHITECTURE.md — Workflow
|
||
Architecture](ARCHITECTURE.md#workflow-architecture-future--v0210) for
|
||
the conceptual model.
|
||
|
||
Depends on: multi-participant channels (v0.23.0), anonymous identity (v0.24.0).
|
||
|
||
_(Shifted from v0.22.0 — no content changes, dependency refs updated)_
|
||
|
||
**Workflow Definitions**
|
||
- [ ] `workflows` table: `team_id` (owner), `name`, `description`, `is_active`, `entry_mode` (public_link, team_internal, api)
|
||
- [ ] `workflow_stages` table: `workflow_id`, `ordinal`, `persona_id`, `assignment_team_id`, `form_template` (JSONB, structured note schema), `transition_rules` (JSONB)
|
||
- [ ] Team-admin CRUD: create/edit/delete workflows and stages
|
||
- [ ] Workflow versioning: edits create new version, active instances continue on their version
|
||
|
||
**Workflow Instances (Channels)**
|
||
- [ ] Workflow-typed channels: `type='workflow'`, `workflow_id`, `current_stage`, `stage_version`
|
||
- [ ] Entry point: public link generates workflow channel, adds anonymous participant, binds stage 1 persona
|
||
- [ ] Stage transitions: triggered by AI (tool call), team member (button), or rule (form complete)
|
||
- [ ] On transition: swap active persona, notify assignment team, update channel metadata
|
||
|
||
**AI Intake**
|
||
- [ ] Stage persona drives structured collection via system prompt
|
||
- [ ] Form template → persona system prompt injection ("collect these fields: ...")
|
||
- [ ] Tool calls create channel-scoped notes as form responses
|
||
- [ ] AI determines readiness: "I have everything needed" → trigger transition
|
||
|
||
**Assignment + Queue**
|
||
- [ ] Assignment queue: unassigned workflow channels visible to team members
|
||
- [ ] Claim model: team member claims channel (becomes participant with `member` role)
|
||
- [ ] Round-robin / rule-based auto-assignment (optional, per-stage config)
|
||
- [ ] Assignment notifications via WebSocket + optional webhook
|
||
|
||
**Team Member Collaboration**
|
||
- [ ] Assigned member sees full history (AI intake + artifacts + notes)
|
||
- [ ] Persona remains active — assists both visitor and team member
|
||
- [ ] Member can trigger stage transitions, add notes, invoke tools
|
||
- [ ] Member can reassign to different team member or escalate to different team
|
||
|
||
**Frontend**
|
||
- [ ] Workflow builder UI in team admin panel (stage list, persona picker, form template editor)
|
||
- [ ] Queue view: sidebar section showing unassigned workflow channels for user's teams
|
||
- [ ] Channel header: workflow stage indicator, transition controls
|
||
- [ ] Anonymous visitor view: minimal UI, persona-driven conversation (public link entry)
|
||
|
||
---
|
||
|
||
## v0.26.0 — Tasks / Autonomous Agents
|
||
|
||
Unattended execution — workflows without a human in the loop.
|
||
Depends on: workflow engine (v0.25.0).
|
||
|
||
_(Shifted from v0.23.0 — no content changes, dependency refs updated)_
|
||
|
||
- [ ] Scheduler + task runner (cron-like triggers for workflow instantiation)
|
||
- [ ] `task_create` tool (AI can spawn sub-workflows)
|
||
- [ ] `type: 'service'` channels: workflow instances with no human participants
|
||
- [ ] Execution budgets: max tokens, max tool calls, max wall-clock per stage
|
||
- [ ] Admin controls for resource limits and kill switches
|
||
- [ ] Completion webhooks (notify external systems when workflow completes)
|
||
|
||
---
|
||
|
||
## TBD (unscheduled — real features, no immediate need)
|
||
|
||
Items that are real but don't yet have a version assignment. Pull left
|
||
based on need.
|
||
|
||
**Extension System — Additional Extensions**
|
||
- Image generation tool (browser or sidecar, provider-agnostic)
|
||
- STT/TTS (browser extension, Web Speech API — personal use case)
|
||
- Code execution sandbox (server-side, container isolation)
|
||
|
||
**Extension System — Server Tiers**
|
||
- Starlark runtime integration (Tier 1 — server sandbox)
|
||
- Sidecar HTTP tool protocol (Tier 2 — container isolation)
|
||
- Server-side tool execution in completion handler
|
||
|
||
**Desktop + Mobile**
|
||
- Desktop app (Tauri)
|
||
- Full PWA with offline capability
|
||
- Mobile-optimized layouts (beyond current responsive)
|
||
|
||
**Data + Portability**
|
||
- Bulk export/import (account data, conversations, settings)
|
||
- ChatGPT/other tool import
|
||
- GDPR-style "download my data"
|
||
- Backup/restore CronJob manifests
|
||
|
||
**UX / Multi-Seat**
|
||
- "Group" scope badge on model selector / KB list: show access-source annotation so users see _why_ they have access (global, team, group grant). Requires backend to include `access_source` in list responses.
|
||
- Per-provider model preferences: `user_model_settings` unique key is `(user_id, model_id)` — same model from different providers shares one visibility toggle. Needs `provider_config_id` dimension in DB constraint, store, API, and frontend `hiddenModels` keying. Frontend composite key (`configId:modelId`) already exists in `App.models[].id`.
|
||
|
||
**Knowledge Bases — Future**
|
||
- KB auto-injection: top-K chunk prepend to system prompt, context budget aware, per-channel toggle (latency budgeting required)
|
||
- Hybrid search: combine vector similarity with full-text `tsvector`, re-rank
|
||
- Semantic chunking: embedding-based boundary detection for smarter splits
|
||
- HNSW index: better query performance than IVFFlat for large datasets
|
||
- Web scraping source: ingest URLs as KB documents (extends url_fetch)
|
||
- Scheduled re-indexing: periodic rebuild when source documents update
|
||
- ~~Store cleanup: add `UpdateDocumentStorageKey()` to `KnowledgeBaseStore` interface~~ _(done in v0.17.0)_
|
||
(currently uses direct `database.DB.ExecContext` in handler — works but bypasses store layer)
|
||
|
||
**Memory — Future**
|
||
- Memory compaction: summarize old memories to save context tokens
|
||
- Memory confidence decay: reduce confidence over time, prune low-confidence entries
|
||
- Memory export/import: portable memory format across instances
|
||
- Cross-persona memory sharing (opt-in): e.g. "coding assistant" can read facts from "project manager"
|
||
- Memory analytics: dashboard showing what Personas are learning, memory growth trends
|
||
|
||
**Platform**
|
||
- Rate limiting per user/team/tier (token budgets)
|
||
- ~~Provider health monitoring~~ → v0.22.0 + key rotation
|
||
- Multi-tenant SaaS mode
|
||
- Plugin/extension marketplace
|
||
- Virtual scroll for long conversations
|
||
- ~~SQLite backend option (single-user / dev)~~ → v0.17.1 |