Focus Modes Implementation
Focus Modes Implementation Focus modes are temporary system prompt modifications that specialize the AI for specific tasks, treated as tool calls with activa...
Focus Modes Implementation
Focus modes are temporary system prompt modifications that specialize the AI for specific tasks, treated as tool calls with activation/deactivation/restart semantics.
Why This Exists
Allows the LLM to dynamically switch into specialized modes (e.g., “web research”, “code planning”) by modifying the system prompt mid-conversation. Users can reject activation during a countdown or deactivate via context menu.
How It Works
Data Flow
- User sends message -> WebSocket handler extracts
active_focus_idfrom chat metadata - Preprocessor identifies relevant focus modes from available list
- Main Processor generates
activate_focus_mode/deactivate_focus_modetools - LLM decides to call activation/deactivation
- Tool execution -> updates cache + Directus, creates
focus_mode_activationembed - Embed streamed as JSON reference inline in message stream
- Processing restarts with focus mode prompt in system prompt
Backend: Tool Generation (main_processor.py)
activate_focus_mode: generated when preprocessor finds relevant focus modes AND no mode is currently active. Parameters include enum of relevant focus mode IDs with descriptions.deactivate_focus_mode: generated whenactive_focus_idis set. No parameters.- Tool names use
system-prefix to distinguish from regular skills.
Backend: Activation Flow
When activate_focus_mode is called:
- Update
active_focus_idin cache viaCacheService - Persist to Directus via Celery task (
persist_chat_active_focus_id) - Create
focus_mode_activationembed viaembed_service.create_focus_mode_activation_embed()(TOON-encoded, encrypted, cached, streamed to client) - Set
restart_required = True, break tool loop - Re-construct system prompt with focus mode prompt, re-run LLM call from iteration 0
Backend: Deactivation
AI-initiated: Clear cache, persist to Directus, create system message, restart without focus mode prompt.
Client-initiated (focus_mode_deactivate_handler.py): WebSocket message chat_focus_mode_deactivate with chat_id + focus_id. Handler clears cache, dispatches Celery task to clear Directus, sends ACK.
Frontend: Activation UI (FocusModeActivationEmbed.svelte)
Renders inline in chat as a compact card:
- Countdown phase (4 seconds): App icon, focus mode name, “Activate in N sec…” with progress bar. User can click card or press ESC to reject.
- Activated phase: Card shows “Focus activated” with green accent.
- Rejected phase: Card hidden.
focusModeRejectedevent dispatched.ActiveChat.sveltesends WebSocket deactivation + local system message.
Context menu (via ChatMessage.svelte): “Deactivate” -> WebSocket deactivation. “Details” -> deep-link to settings.
ESC handling: Global document.addEventListener('keydown') registered on mount, cleaned up on destroy.
Frontend: Renderer and Registry
FocusModeActivationRenderer.tsmounts the Svelte component, dispatches custom events- Registered as
focus-mode-activationinembed_renderers/index.ts - Embed type and attributes defined in
message_parsing/types.tsandembedParsing.ts
Cache & Persistence
encrypted_active_focus_idstored in chat’slist_item_datacache key viaCacheService- Persisted to
chatscollection in Directus (field already exists in schema) - Frontend syncs via phased sync handler
Edge Cases
- Focus mode IDs are encrypted with chat-specific key (zero-knowledge)
- Server validates focus mode ID against available modes before activation
- Focus mode prompt loaded at system prompt beginning with markers (lines ~682-696 in
main_processor.py)
Related Docs
- Function Calling – tool preselection and execution
- Message Processing – overall pipeline
- Focus Modes Overview – user-facing documentation