Files
FabledScribe/docs/features.md
T
bvandeusen e2133529a0 docs: add missing content from summary.md (API reference, Android app, file structure, LLM internals)
- docs/api-reference.md: complete REST API endpoint reference (~60+ routes)
- docs/android-app.md: Flutter companion app stack, architecture, feature status
- docs/architecture.md: detailed file-by-file reference for all backend services and frontend components
- docs/features.md: LLM pipeline internals (intent routing, tool loop, duplicate guards, image search, research pipeline), roadmap
- docs/development.md: full migration chain (0001–0026) with naming and caveats
- README.md: link to new api-reference and android-app docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:25:12 -04:00

12 KiB
Raw Blame History

Features

Notes

Write in Markdown with a live-preview editor (Tiptap/ProseMirror). Headings, bold, italic, lists, code blocks, and task checklists render inline. A slash-command menu (/) inserts common blocks.

Wikilinks — Link notes with [[Title]] or [[Title|Display Text]] syntax. Clicking a wikilink navigates to (or auto-creates) the referenced note. The editor suggests existing note titles as candidate links while typing [[. Backlinks appear in the note viewer sidebar.

Tags — First-class ARRAY[text] column. Tag autocomplete in the editor sidebar suggests existing tags. Hierarchical tags (project/webapp) supported — filtering by project matches all project/* children. Tags are browsable via the knowledge graph.

Version history — Every body edit snapshots a version (up to 20 per note). Browse and restore from the editor's History panel. Diff view shows changes against the current body.

AI writing assist — Select a passage or work on the full document. Give an instruction ("make this more concise", "add examples"). The assistant streams a proposal; a diff view shows changes to accept or reject. Drafts persist across page loads.

Link suggestions — The editor detects note titles appearing as plain text in the body and suggests converting them to wikilinks.

Tasks

Tasks are notes with status IS NOT NULL. They carry status (todoin_progressdone), priority (none/low/medium/high), due date, milestone assignment, and a parent task (sub-tasks).

Task work logs — Append progress log entries to a task with optional duration. Time tracking is visible in the task editor sidebar.

Sub-tasks — Any task can have child tasks via parent_id. The task viewer shows sub-tasks inline.

Convert freely — Convert a note to a task (sets status=todo) or a task back to a note from the viewer toolbar.

Projects and Milestones

Projects — Group related notes and tasks. Each project has a title, description, goal, status (active/completed/archived), and a colour.

Milestones — Ordered stages within a project. Tasks are assigned to milestones. Milestone completion percentage shown on the project page.

Kanban view/projects/:id groups tasks by milestone in a kanban-style column layout with status-advance buttons directly on cards (→ advance, ✓ complete).

Project Workspace/workspace/:projectId opens a three-panel environment (tasks / chat / notes) locked to a project. The AI assistant creates and updates content directly in the workspace; new notes auto-load in the editor and the task list refreshes automatically after tool calls.

Knowledge Graph

/graph renders all notes, tasks, and tags as a D3 force-directed graph. Tag nodes cluster notes that share tags; invisible project hub nodes attract project members. Physics controls: repulsion, link distance, link strength, hub pull, gravity. Click any node to open a slide-in peek panel. Click a tag node to filter the notes list.

AI Chat

Full conversation history with SSE streaming. Features:

  • RAG — Semantically relevant notes (≥ 0.60 cosine similarity) auto-injected as context. Notes 0.450.60 shown in sidebar as "Suggested."
  • Attach notes — Paperclip icon to include specific notes in context.
  • Project scope — Restrict RAG to a single project's notes via the sidebar selector.
  • Tool calls — The assistant can create/update notes, tasks, projects, milestones, search the web, check weather, read RSS, query calendar events, and more. Tool calls display inline with confirm/deny for creates.
  • Thinking mode — Toggle extended reasoning for complex questions.
  • Abort — Stop button cancels in-flight generation.
  • Message queue — Messages sent while generation is in progress are queued and drained sequentially.
  • Save to note — Save any assistant reply directly as a note.
  • Bulk delete — Select and delete multiple conversations.
  • Retention — Conversations auto-pruned after configurable days (default 90).

Daily Briefing

/briefing is a scheduled, dialogue-based morning briefing. The assistant compiles tasks, calendar events, projects, weather forecast, and RSS digest at configurable times, then checks in throughout the day. You can reply interactively.

Schedule — Configurable slots: morning (default 4am compile), midday (8am check-in), evening (12pm check-in), night (4pm). Scheduler catches up missed slots on startup.

Configuration — Settings → Briefing: enable toggle, location geocoding, office days, time slot toggles, RSS feed management, push notification toggle.

RSS feeds — Add feed URLs with optional name and category. Feeds are fetched and cached; the briefing digest includes recent items. Category badges shown in the UI. Feeds can be manually refreshed.

Weather — Location-based forecast via Open-Meteo. Multiple locations supported (home, work, or any city name). Geocoding via Nominatim.

Profile note — The assistant maintains a profile note for each user that it updates based on briefing conversations, improving personalisation over time.

Web Research

The assistant can search the web (SearXNG) and fetch pages, synthesising findings into notes. A lightweight search_web tool answers quick questions inline without saving. Requires SEARXNG_URL to be configured.

CalDAV Calendar

Connect an external CalDAV server (Nextcloud, Radicale, etc.) and manage calendar events via natural language. Tools: create_event, list_events, search_events, update_event, delete_event. Activated when user configures CalDAV credentials in Settings → Integrations.

Sharing and Collaboration

Share — Share any project or note/task with users or groups at viewer/editor/admin permission levels. Share button in the viewer/project toolbar opens a dialog.

Groups — Admins create platform-wide groups and assign users member/owner roles. Share a resource with a group in one action.

Shared with me/shared lists all incoming shared projects and notes with permission badges.

Notifications — Bell icon in nav shows unread count (60s polling). Notifications generated for: project shared, note shared, added to group. Click navigates to the resource.

Push notifications — Web Push (VAPID) notifies when AI generation completes, even in another tab. Works over HTTPS only. Configurable per-user.

Quick Capture

Quick capture from the Android app routes to the intent classifier. It creates notes, tasks, or projects based on content — using the user's configured model, not the hardcoded default.

Data Export and Backup

  • Personal export — Settings → Data: download all notes/tasks as a Markdown ZIP (with YAML frontmatter) or JSON array.
  • Admin backup — Full application backup (version 2): includes projects, milestones, task logs, AI drafts, note versions, push subscriptions. ID remapping on restore for cross-instance migration.

PWA

Installable as a desktop or mobile app. Service worker caches the shell. Push notifications handled by public/sw.js (suppresses duplicate notifications when the relevant tab is already focused). Works over HTTPS only in Firefox.

Settings

Settings are tabbed:

Tab Contents
General Assistant name, default model, model management (pull/delete)
Account Email change, password change, session invalidation
Notifications Push notification subscription, briefing push toggle
Integrations CalDAV configuration, SearXNG status
Data Personal export, backup/restore (admin)
Briefing Enable, location, office days, slots, RSS feeds, weather
API Keys Create/revoke API keys, Fable MCP download and install
Config (admin) Base URL, SMTP, OIDC settings
Users (admin) User list, invite links, registration toggle
Logs (admin) Error, audit, and usage logs with search
Groups (admin) Create/manage groups and membership

LLM Chat — Internal Pipeline

Intent Routing

Before the main model runs, a lightweight intent classifier (services/intent.py) runs concurrently with build_context(). It makes a fast non-streaming call (~400ms) using a smaller dedicated model (OLLAMA_INTENT_MODEL, default qwen2.5:7b) to determine if the message requires a tool call.

Skip heuristic — Intent classification is skipped entirely for short messages (≤10 words) with no action/object keywords, saving 400800ms on conversational replies.

Prior-work fast-path — Phrases like "research you did", "note you made", "using your research" skip the LLM call entirely and route to null (chat), preventing search_web from firing when the user references existing notes.

If a tool is detected, the intent's one-sentence ack field is streamed as the first chunk (becoming time-to-first-token), then the tool executes, then the main model generates a follow-up response with the tool result.

Tool Loop

Multi-round tool loop (max 5 rounds). All tool implementations are in services/tools.py with execute_tool() as the dispatcher.

Duplicate protection on create_note / create_task:

  1. Exact title match (case-insensitive) → hard block, redirect to update_note
  2. Fuzzy title match (SequenceMatcher ≥ 82%; punctuation stripped before candidate search) → hard block
  3. Semantic content similarity (semantic_search_notes threshold 0.90, body ≥ 200 chars) → soft block with requires_confirmation: true

Project resolution (_resolve_project): 4-step lookup — (1) exact DB match, (2) query in title substring, (3) title in query reverse substring, (4) SequenceMatcher ≥ 0.55.

Model Status

Three states returned by GET /api/chat/status:

  • not_found — model not installed; orange indicator in header
  • cold — installed but not loaded in VRAM; yellow pulsing indicator (first request will be slow)
  • loaded — hot in VRAM; green indicator

After warmModel() is called, a 5s polling loop runs for up to 60s until the indicator turns green.

Context Window

OLLAMA_NUM_CTX (default 16384) controls the context window for all generation calls. Intent classification always uses num_ctx=4096 to reduce VRAM pressure. History summarisation kicks in at 30 messages, keeps 8 recent, summary max 400 tokens.

search_images tool (SearXNG categories=images) fetches images server-side, stores on disk (SHA-256 dedup, 5 MB cap), and serves from /api/images/<id> — the user's browser never contacts the original image host. Requires SEARXNG_URL.

Web Research Pipeline

Triggered by "research X and make a note" or the Research button in ChatView:

  1. Intent model generates 5 focused sub-queries as a JSON array
  2. All 5 SearXNG queries run in parallel (200ms stagger)
  3. Up to 15 unique URLs fetched in parallel
  4. Up to 12 sources passed to synthesis LLM (num_ctx=16384, num_predict=8192)
  5. Note created with tags=["research"]

SearXNG tip: add the app server IP to botdetection.ip_lists.pass_ip in SearXNG settings.yml to bypass the rate limiter for backend requests.

Roadmap

  • Calendar/timeline view for tasks with due dates
  • Email integration (read/send via IMAP/SMTP tools in chat)
  • Session invalidation on user deletion
  • Flutter push notifications (requires FCM/APNs — separate from web VAPID)
  • Flutter milestone support in project view

Keyboard Shortcuts

Key Action
g + h Go to Home
g + n Go to Notes
g + t Go to Tasks
g + p Go to Projects
g + c Go to Chat
g (bare) Go to Graph
n New note
t New task
c Focus chat input
e Edit current item
/ Search
? Show shortcuts panel
j / k Navigate list items
Enter Open selected item
Escape Close panel / blur / go home (progressive)
Ctrl+S Save in editor