Saga Reader Documentation

repository·main·Indexed 19 days ago

https://github.com/sopaco/saga-reader

An AI-driven, cross-platform internet reader built with Rust, Tauri, and Svelte. It features automated information retrieval, an AI-powered reading companion, and a monorepo architecture including crates for LLM provider abstractions, local Ollama management, web scraping, and feed management via the FeaturesAPI.

Tokens
92.2K
Snippets
221
Records
398
Agent score
66%

What's inside Saga Reader

  1. Overview of the Frontend Presentation Domain

    main

    The Frontend Presentation Domain serves as the user interaction entry point for Saga Reader. It is responsible for presenting core system features—such as content aggregation, AI enhancement, local search, and theme switching—through an intuitive and responsive interface.

    Technical Stack:

    • SvelteKit
    • TypeScript
    • Tailwind CSS

    Core Responsibilities:

    • Rendering: Visualizing data provided by the state management domain.
    • Interaction: Capturing user actions (clicks, inputs, toggles) to trigger backend services.
    • Feedback: Providing immediate UI feedback via loading states, error messages, and empty states.
    • Consistency: Ensuring visual and linguistic uniformity through internationalization (i18n) and theme systems.

    Architecture & Data Flow: The frontend follows a component-based, reactive, and state-driven architecture featuring a three-column reading workspace. It is deeply coupled with the state management domain. All data changes are driven by Svelte Stores, and all user operations are executed via a bridge layer that calls backend Rust services.

    The complete data loop is: UIStoreBridgeRustDBStoreUI

  2. What is Saga Reader (麒睿智库)

    main

    Saga Reader is an AI-driven, lightweight, and fast internet reader. It automatically retrieves information from the web based on user-specified topics and preference keywords.

    Key capabilities include:

    • AI-Powered Summarization: Uses cloud or local Large Language Models (LLMs) to summarize content and provide guidance.
    • Interactive Reading: An AI companion allows users to discuss and exchange ideas about the reading material in real-time.
    • Privacy-First: All data is stored locally on the user's computer, ensuring security and independence from third-party providers.
    • Smart Subscriptions: Users define interest keywords to trigger autonomous web searches without complex subscription management.
    • Multi-language Support: Automatically translates hundreds of foreign language articles into the user's preferred language.
    • High Performance: Built with Rust, Tauri, and Svelte, it is optimized for low resource usage (memory usage < 10MB), making it suitable for older hardware.
  3. Overview of Saga Reader

    main

    Saga Reader is a privacy-focused, AI-enhanced desktop reading application designed for knowledge workers, tech enthusiasts, and privacy-sensitive users. It uses a multi-layered heterogeneous architecture consisting of Svelte + Tauri + Rust to provide a fully localized experience.

    Core Value Proposition

    • Data Sovereignty: All content scraping, AI processing, and data storage are performed locally. No data is uploaded to the cloud.
    • AI-Enhanced Reading: Uses local Large Language Models (LLMs) via Ollama to perform:
      • Purge: Removing noise like ads and navigation.
      • Optimizer: Refining language and professionalism.
      • Melt: Merging multiple articles into a single comprehensive summary.
    • Interactive AI Assistant: Enables "reading as conversation" by allowing users to ask questions about the current article using a local LLM.
    • Automated Workflows: A background daemon handles periodic content refreshes automatically.
  4. Understand the Saga Reader technical stack

    main

    Saga Reader is built using a multi-layered architecture designed for high performance and local-first privacy. The stack consists of:

    • Frontend UI: SvelteKit, TypeScript, and Tailwind CSS for a responsive, componentized interface.
    • Desktop Container: Tauri 2.x, which wraps the web frontend into a native desktop application with system-level API access.
    • Backend Engine: Rust (1.78+) handles all core business logic, including web scraping, AI processing, database management, and background daemons.
    • AI Inference: Local open-source Large Language Models (LLMs) like Llama 3, Mistral, or GLM-4, invoked via Ollama through HTTP APIs.
    • Database: SQLite with SeaORM for lightweight, zero-configuration, ACID-compliant local storage.
    • Configuration: TOML files managed via serde for structured, human-readable settings.
    • Communication: Tauri IPC (JSON-RPC over WebSocket) provides type-safe communication between TypeScript (Frontend) and Rust (Backend).
    • Build Tools: Bun and Vite for fast frontend bundling and Svelte hot-reloading.
  5. Overview of the System Integration Domain

    main

    The System Integration Domain serves as the core infrastructure of Saga Reader, acting as the application's 'nervous system'. It is responsible for managing the desktop application's runtime environment and ensuring seamless integration between the frontend UI and the Rust backend engine.

    Key responsibilities include:

    • Application lifecycle management
    • System service integration
    • Cross-process communication
    • Automated task scheduling

    The domain is built on the Tauri framework, utilizing Rust-based plugins and daemon processes to create a secure and efficient local application ecosystem. It follows 'single responsibility' and 'low coupling' principles, decoupling system-level functions (startup, window management, system tray, scheduled tasks) from core business logic (data scraping, AI processing).

  6. What is Ollama and how to use it with Saga Reader

    main

    Ollama is a popular engine for running large language models (LLMs) locally. If you want to use the Local LLM mode in Saga Reader to run inference on your own device without connecting to commercial online services, you must first install Ollama.

    You can download it from ollama.com/download. Once installed, Saga Reader can connect to it to perform local AI tasks.

  7. Overview of the Saga Reader State Management Domain

    main

    The State Management Domain is the central hub of the Saga Reader frontend architecture. It is responsible for unified management of all key business data, enabling decoupled data flow and reactive synchronization between components.

    Built on Svelte's reactive system, the domain uses a modular Store design and TypeScript for type safety. It is composed of three main parts:

    1. Core Data Stores: Handle primary business logic such as feed management, article aggregation, search filtering, reading status, and AI session management.
    2. State Utility Stores: Provide supporting tools for state manipulation.
    3. Type Contracts: Ensure data consistency through TypeScript interfaces.

    All stores collaborate via an event-driven model to create a complete frontend state loop.

  8. Initialize LLM providers with init_llm

    main

    The LLM initialization logic (found in init_llm.rs) handles the detection and startup of Large Language Model providers during system boot.

    Currently, it specifically supports Ollama:

    • Detection: Checks if Ollama is installed and its current running status.
    • Auto-start: If Ollama is installed but not running, the system attempts to automatically start the service.
    • Error Handling: If Ollama is unavailable or fails to start, errors are logged via spdlog.
    • Other Providers: For non-Ollama providers, the system performs a no-op (empty initialization task).
  9. Manage LLM providers via the LLM Proxy Service

    main

    The system provides a unified CompletionService to manage calls to various Large Language Models. This abstraction allows the application to interact with different providers using a consistent interface. Supported providers include:

    • Ollama (includes automatic detection and startup of local services)
    • GLM
    • Mistral
    • OpenAI

    The service handles constructing structured prompt requests and executing asynchronous completions.

  10. Implement background daemon and scheduled tasks

    main

    The application uses a daemon mode to automate feed updates without a visible UI. This is implemented in app/src-tauri/src/daemon/feeds_update.rs.

    Key Mechanisms:

    • Process Mode Detection: The application checks for the --feeds-schedule-update command-line argument via env::is_daemon(). If present, the setup hook skips showing the main window and only runs background tasks.
    • Concurrency & Safety:
      • Uses fslock (via LockFile) to create a lock file (feeds_schedule_update.lock), preventing multiple daemon instances from running simultaneously.
      • Uses async_runtime::spawn to run the schedule_loop in the background.
    • Scheduled Loop:
      • Uses tokio::time::interval to trigger updates based on configuration (frequency_feeds_update).
      • Iterates through feeds_packages and calls features.update_feed_contents to trigger the scraping and AI processing pipeline.
    • State Sharing: The daemon receives an Arc<HybridRuntimeState>, allowing it to access FeaturesAPI to perform business logic tasks.
    // Check if running in daemon mode
    pub fn is_daemon() -> bool {
        let launch_mode = std::env::args().nth(1).unwrap_or_default();
        launch_mode.eq(DAEMON_FEEDS_SCHEDULE_UPDATE)
    }
    
    // Background loop logic
    async fn schedule_loop<R: Runtime>(app_handle: AppHandle, state: Arc<HybridRuntimeState>) -> anyhow::Result<()> {
        // ... interval setup
        loop {
            interval.tick().await;
            let feeds_packages = features.get_feeds_packages().await;
            for feed_package in feeds_packages {
                for feed in feed_package.feeds {
                    features.update_feed_contents(&feed_package.id, &feed.id, Some(app_handle.clone())).await?;
                }
            }
        }
    }
  11. How configuration changes are synchronized

    main

    Saga Reader uses a File-driven + Memory Cache + Transactional Write architecture to ensure consistency and performance:

    1. Initialization: On startup, the system reads the TOML files from the appdata directory, deserializes them, and populates an in-memory cache.
    2. Access: Other modules (AI, Scraping, Theme) read configuration from the in-memory cache.
    3. Modification: When a user changes a setting (e.g., via the Svelte frontend), the system updates the in-memory structure.
    4. Persistence: The sync_to() method is called, which serializes the configuration to TOML and performs an atomic write to the disk using File::create() to prevent file corruption during interruptions.
  12. Understand the interaction patterns between the Frontend and Backend

    main

    The Frontend Presentation Domain follows a strict layered architecture to ensure testability and clarity. The UI does not call backend services directly. Instead, all communication flows through a State Management Domain and a Bridge Layer.

    Core Principle

    • UI: Responsible only for rendering and event handling.
    • State: Responsible for data flow.
    • Bridge: Responsible for communication.

    Common Interaction Chains

    ScenarioCall Chain
    Refreshing FeedsFeedsListdispatch('refresh')Store.update_feeds()featuresApi.update_feed_contents()
    SearchingSearchBarfilterText.set()articles/search/store$derivedarticles/list/storefeaturesApi.search_articles()
    AI ChattingAISpritePanelsprite.addMessage()featuresApi.chat_with_article_assistant()
    Theme SwitchingSettingsPagefeaturesApi.set_app_config()config.storethemes/index.tsdocument.documentElement.classList
    App Startup+page.sveltecreateStore()articles/list/storefeaturesApi.get_feeds_packages()ArticleRecorderService.query()