Changeset 0.23.0 (#153)

This commit is contained in:
2026-03-05 22:40:26 +00:00
parent 40d9834f64
commit 2fc620e1ac
62 changed files with 6214 additions and 362 deletions

View File

@@ -263,6 +263,30 @@ scope='personal' → owner_id=user.id → User-managed, visible to owner
Used by: `provider_configs`, `personas`, `model_catalog` (visibility column adds `enabled`/`disabled`/`team` states on top), `projects`.
## Personas
Personas are named AI configurations: a system prompt, base model, provider
config, and behavioral parameters (temperature, max tokens, thinking budget).
Each persona has a unique `handle` field (e.g. `veronica-sharpe`) used for
@mention routing.
**Handle Generation:** Auto-generated from name on create (`HandleFromName()`):
lowercase, spaces→hyphens, alphanumeric only, max 50 chars. Editable via the
persona form. Unique index prevents collisions.
**Scope Model:** Same as other resources — global, team, personal. Personal
personas are only visible to the creator. Team and global personas are visible
to all users with the appropriate access.
**Resolution Chain (completion):**
```
Explicit persona (req.PersonaID) → Project persona → @mention persona → dropdown selection
```
**Memory:** Personas have `memory_enabled` and `memory_extraction_prompt` fields.
When memory is enabled, the persona's memory scope is independent — facts
extracted in conversations with Persona A are not visible to Persona B.
## Projects (v0.19.0)
Projects are organizational containers that group channels, knowledge bases,
@@ -324,19 +348,42 @@ in Settings → Notifications.
**Cleanup:** Background goroutine deletes notifications older than retention
period (default 90 days, configurable via admin settings).
## @mention Routing + Multi-model (v0.20.0)
## @mention Routing (v0.23.0)
Channels support multiple AI models. The `channel_models` table (schema 001)
holds the roster; `mentions.Parse()` extracts @mentions from message content
and resolves against display names (case-insensitive, longest-match-first).
Type `@handle` or `@model-id` in any chat to route the completion to a
different persona or model. No roster, group, or channel setup required.
**Completion Fan-out:** When mentions resolve to channel models, the completion
handler fires sequentially for each target, producing one assistant message
per model. Without @mention, the default channel model responds (backward
compatible). Frontend renders model attribution labels on multi-model responses.
**Resolution (`resolveMention`):** Extracts the first `@token` from message
content and queries the DB directly:
**Autocomplete:** CM6 `mentionCompletion` extension triggers on `@` in the
chat input, showing a dropdown of channel model display names.
1. Persona handle — exact match against `personas.handle` (case-insensitive)
2. Persona handle — prefix match (unambiguous only)
3. Model ID — exact match against `model_catalog.model_id` (enabled + active provider)
4. Model ID — prefix match (unambiguous only)
Persona resolution returns the persona's model, provider config, and system
prompt. Model resolution returns the raw model ID and config — no persona
character, no system prompt override.
**Context Boundaries:** When @mentioning a persona, a system message is
injected before the user's message telling the target to ignore previous
personas' styles. When no @mention is used but persona responses exist in
history, a boundary tells the default model to respond in its own style.
**Participant Hint:** `buildParticipantHint()` injects a system message
listing all @mentionable personas (handle + name + description). This tells
the LLM who it can invoke, enabling AI-to-AI chaining.
**AI-to-AI Chaining:** After each completion, `chainIfMentioned()` runs
`resolveMention()` on the assistant's response. If it @mentions another
persona, a follow-up completion fires asynchronously. Result delivered via
WebSocket (`message.created`). Self-mention blocked. Depth capped at 5.
Same resolution function for user→LLM and LLM→LLM routing.
**Autocomplete (Frontend):** `ChannelModels.onInput()` triggers on `@` in
the chat input, matching against all `App.models` (enabled, non-hidden) by
persona handle, model ID, and display name. Popup shows avatar, name,
`@handle` hint, and provider. Selection inserts `@handle` into the input.
## Frontend Architecture
@@ -356,9 +403,11 @@ src/
│ ├── api.js # HTTP client with token refresh
│ ├── app.js # Application state machine, startup, routing
│ ├── chat.js # Chat input abstraction, message send/receive
│ ├── channel-models.js # @mention autocomplete, channel model roster
│ ├── events.js # Labeled event bus + WebSocket bridge
│ ├── debug.js # Debug panel, diagnostics, state export
│ ├── ui-core.js # DOM rendering, sidebar, modals, panels
│ ├── ui-format.js # Markdown rendering, @mention pills, code blocks
│ ├── ui-settings.js # Settings tabs, theme, appearance, teams
│ ├── ui-admin.js # Admin panel rendering
│ ├── admin-handlers.js # Admin CRUD operations + extension editors