Changeset 0.12.0 (#63)

This commit is contained in:
2026-02-25 21:38:49 +00:00
parent c9d8e9457e
commit 88216ec4cb
59 changed files with 13115 additions and 139 deletions

View File

@@ -43,19 +43,23 @@ v0.14.0 Knowledge Bases (embedding role + file storage + pgvector)
v0.15.0 Compaction (utility role + background job)
v0.16.0 @mention Routing + Multi-model
v0.15.1 Context Recall Tools (attachment_recall, conversation_search)
v0.17.0 Extension Surfaces + Modes
v0.16.0 Conversation Memory (cross-conversation user facts)
v0.18.0 Smart Routing (policy on model roles)
v0.17.0 @mention Routing + Multi-model
v0.19.0 Multi-Participant Channels + Presence
v0.18.0 Extension Surfaces + Modes
v0.20.0 Auth Strategy (mTLS/OIDC) + Full RBAC
v0.19.0 Smart Routing (policy on model roles)
v0.20.0 Multi-Participant Channels + Presence
v0.21.0 Auth Strategy (mTLS/OIDC) + Full RBAC
┌───────┴──────────────┐
│ │
v0.21.0 Workflow v0.22.0 Tasks /
v0.22.0 Workflow v0.23.0 Tasks /
Engine Autonomous Agents
(team-owned, (service channels,
staged processes, scheduler, unattended
@@ -254,7 +258,7 @@ after backfill. If `ENCRYPTION_KEY` is not set, migration refuses to run
derivation. No additional UX. On login, derive PDK → unwrap UEK → cache
in session. User never knows the vault exists.
**mTLS / OIDC** (v0.20.0) — authentication is external (cert/token).
**mTLS / OIDC** (v0.21.0) — authentication is external (cert/token).
Vault passphrase is conditionally required:
```
@@ -336,7 +340,7 @@ func (s *Store) DecryptAPIKey(config ApiConfig, uekCache *sync.Map) (string, err
- [x] UEK eviction on logout (memory zeroing)
- [ ] UEK re-wrap on password change _(deferred — Settings handler)_
- [ ] UEK destruction on admin password reset with confirmation _(deferred)_
- [ ] Vault passphrase prompt for mTLS/OIDC _(deferred — v0.20.0 dependency)_
- [ ] Vault passphrase prompt for mTLS/OIDC _(deferred — v0.21.0 dependency)_
**Provider key lifecycle**
- [x] Encrypt on provider create/update (all 6 write paths: admin global, personal, team)
@@ -344,8 +348,9 @@ func (s *Store) DecryptAPIKey(config ApiConfig, uekCache *sync.Map) (string, err
- [x] `ErrVaultLocked` handling (prompt user to unlock)
**Admin tooling**
- [ ] `switchboard vault rekey` CLI command _(deferred)_
- [ ] Admin UI: encryption status indicator _(deferred)_
- [x] `switchboard vault rekey` CLI command _(v0.12.0)_
- [x] `switchboard vault status` CLI command _(v0.12.0)_
- [x] Admin UI: encryption status indicator _(v0.12.0 — Settings tab)_
- [x] Admin UI: password reset warning (v0.10.0 — vault destruction dialog)
**CI/CD**
@@ -579,17 +584,21 @@ The platform play. See [EXTENSIONS.md](EXTENSIONS.md) for full spec.
File input into chat — table stakes for serious use.
**Storage Backend**
- [ ] S3-compatible API (MinIO, Ceph RGW, AWS — anything with S3 API)
- [ ] Local PVC fallback (single-node / dev)
- [ ] Admin config: backend selection, endpoint, credentials, size limits
- [ ] Reused by KBs (v0.14.0) and compaction snapshots (v0.15.0)
- [x] S3-compatible API (MinIO, Ceph RGW, AWS — anything with S3 API)
- [x] Local PVC backend (single-node / dev)
- [x] Admin config: backend health status, orphan cleanup panel
- [x] Reused by KBs (v0.14.0) and compaction snapshots (v0.15.0)
**Chat Integration**
- [ ] `attachments` table (metadata in PG, blobs in object store)
- [ ] Image/file upload in chat messages
- [ ] Multimodal message assembly for vision-capable models
- [ ] Text extraction on upload (PDF, DOCX, TXT → tsvector)
- [ ] Paste-to-upload (clipboard image support)
- [x] `attachments` table (metadata in PG, blobs in object store)
- [x] Image/file upload in chat messages (📎 button, drag-and-drop)
- [x] Multimodal message assembly for vision-capable models
- [x] Text extraction pipeline (PDF, DOCX, TXT — inline + sidecar modes)
- [x] Paste-to-upload (clipboard images + large text auto-attach)
- [x] Staged attachment strip with extraction status polling
- [x] Auth-aware rendering (blob URLs with Bearer token)
- [x] Image lightbox viewer
- [x] Vision capability hints on image attachments
- [ ] Document generation output storage (extension → attachment → download)
---
@@ -633,7 +642,56 @@ Depends on: utility model role (v0.10.0).
---
## v0.16.0 — @mention Routing + Multi-model
## v0.15.1 — Context Recall Tools
Depends on: file handling (v0.12.0), tool framework (v0.11.0).
Attachments are injected into context once (at send time) and are not
replayed on subsequent turns — the model's own response acts as a natural
summary. After compaction (v0.15.0) or in long conversations, the model
may need to re-read source material. These tools bridge that gap.
**`attachment_recall` tool**
- [ ] `attachment_recall(attachment_id)` — re-reads attachment content from storage
- [ ] Images: re-inject as base64 content part (vision gating still applies)
- [ ] Documents: return extracted text
- [ ] Security: scoped to current channel's attachments only
- [ ] Extend `ExecutionContext` with optional storage backend reference
- [ ] Tool definition includes attachment list hint so model knows what's available
**`conversation_search` tool**
- [ ] Keyword search over compacted/archived messages in current channel
- [ ] Returns matching message excerpts with timestamps
- [ ] Useful post-compaction when summary dropped details the user asks about
**Token estimator improvements**
- [ ] Include attachment token estimates in context counter
- [ ] Images: use provider-specific sizing rules (e.g. tile-based for OpenAI)
- [ ] Documents: count extracted text tokens
- [ ] Staged attachments reflected in input token counter before send
---
## v0.16.0 — Conversation Memory
Depends on: compaction (v0.15.0), knowledge bases (v0.14.0).
Long-term memory across conversations. Unlike KB (static documents) or
compaction (within-conversation), this captures user-level facts and
preferences that persist across channels.
- [ ] `user_memory` table: `user_id`, `key`, `value`, `source_channel_id`, `confidence`, `created_at`, `updated_at`
- [ ] `memory_save` tool: LLM can explicitly store a fact ("user prefers Python", "project deadline is March 15")
- [ ] `memory_recall` tool: LLM queries stored facts relevant to current context
- [ ] Auto-extraction: background job identifies memorable facts from conversations (opt-in)
- [ ] Memory injection: relevant facts injected into system prompt at completion time
- [ ] User controls: view, edit, delete memories in Settings
- [ ] Admin controls: enable/disable, retention policies, per-team scoping
- [ ] Privacy: memories never cross team boundaries
---
## v0.17.0 — @mention Routing + Multi-model
The channel schema already supports multiple models. This adds routing.
@@ -645,7 +703,7 @@ The channel schema already supports multiple models. This adds routing.
---
## v0.17.0 — Extension Surfaces + Modes
## v0.18.0 — Extension Surfaces + Modes
Depends on: extension foundation (v0.11.0).
See [EXTENSIONS.md §6](EXTENSIONS.md#6-surfaces-modes).
@@ -659,7 +717,7 @@ See [EXTENSIONS.md §6](EXTENSIONS.md#6-surfaces-modes).
---
## v0.18.0 — Smart Routing
## v0.19.0 — Smart Routing
Depends on: model roles (v0.10.0), usage tracking (v0.10.0).
Rules-based routing engine — policy, not ML.
@@ -672,13 +730,13 @@ Rules-based routing engine — policy, not ML.
---
## v0.19.0 — Multi-Participant Channels + Presence
## v0.20.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.17.0), WebSocket infrastructure (already exists).
Depends on: extension surfaces (v0.18.0), WebSocket infrastructure (already exists).
**Channel Participants**
- [ ] `channel_participants` table: `channel_id`, `participant_type` (user, session, persona), `participant_id`, `role` (owner, member, observer), `joined_at`
@@ -699,7 +757,7 @@ Depends on: extension surfaces (v0.17.0), WebSocket infrastructure (already exis
---
## v0.20.0 — Auth Strategy (mTLS/OIDC) + Full RBAC
## v0.21.0 — Auth Strategy (mTLS/OIDC) + Full RBAC
Enterprise auth modes on top of the teams foundation.
Depends on: vault passphrase support from v0.9.3 (conditional unlock for
@@ -723,7 +781,7 @@ personal providers under external auth).
---
## v0.21.0 — Workflow Engine
## v0.22.0 — Workflow Engine
Team-owned, stage-based process execution. The channel is the runtime,
personas drive each stage, and the existing tool/notes infrastructure
@@ -731,7 +789,7 @@ 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.19.0), anonymous identity (v0.20.0).
Depends on: multi-participant channels (v0.20.0), anonymous identity (v0.21.0).
**Workflow Definitions**
- [ ] `workflows` table: `team_id` (owner), `name`, `description`, `is_active`, `entry_mode` (public_link, team_internal, api)
@@ -771,10 +829,10 @@ Depends on: multi-participant channels (v0.19.0), anonymous identity (v0.20.0).
---
## v0.22.0 — Tasks / Autonomous Agents
## v0.23.0 — Tasks / Autonomous Agents
Unattended execution — workflows without a human in the loop.
Depends on: workflow engine (v0.21.0).
Depends on: workflow engine (v0.22.0).
- [ ] Scheduler + task runner (cron-like triggers for workflow instantiation)
- [ ] `task_create` tool (AI can spawn sub-workflows)
@@ -812,13 +870,7 @@ based on need.
- Backup/restore CronJob manifests
**UX / Multi-Seat**
- Per-chat model/preset persistence (server-side). Currently a localStorage
bandaid (v0.10.2) that doesn't roam across devices. Proper fix: store
`last_selector_id` in `channels.settings` JSONB on each send. On chat
selection, resolve from `channel.settings.last_selector_id` → match against
available models/presets → fall back to `channel.model` → global default.
Eliminates device-local state entirely. Needs `updateChannel` PATCH on
completion success (single extra column merge, no migration).
- ~~Per-chat model/preset persistence (server-side)~~ ✅ _(v0.12.0 — `channels.settings.last_selector_id` JSONB merge, localStorage write-through cache)_
**Platform**
- Rate limiting per user/team/tier (token budgets)