FreshRSS extension for AI-powered article summaries and collection briefs
  • PHP 75.4%
  • JavaScript 16.3%
  • CSS 3.8%
  • HTML 2.7%
  • Shell 1.8%
Find a file
Mike T 5bb12e2eb7
All checks were successful
ci / PHP validation (push) Successful in 52s
chore: add focused validation helper
2026-07-12 15:11:31 -07:00
.agents/skills/ai-brief-development chore: add focused validation helper 2026-07-12 15:11:31 -07:00
.forgejo/workflows ci: scope live DeepSeek tests 2026-07-12 14:01:41 -07:00
assets refactor: update readme 2026-03-23 14:07:22 +01:00
Controllers fix: integrate collection UI with reader theme 2026-07-12 14:09:16 -07:00
i18n fix: integrate collection UI with reader theme 2026-07-12 14:09:16 -07:00
scripts chore: add focused validation helper 2026-07-12 15:11:31 -07:00
Services fix: integrate collection UI with reader theme 2026-07-12 14:09:16 -07:00
static fix: dismiss brief after marking read 2026-07-12 14:58:17 -07:00
tests feat: persist and refine collection dialog 2026-07-12 14:36:03 -07:00
.gitignore feat: add screenshots 2026-03-18 15:09:27 +01:00
AGENTS.md chore: add focused validation helper 2026-07-12 15:11:31 -07:00
CLAUDE.md chore: add focused validation helper 2026-07-12 15:11:31 -07:00
composer-setup.php feat: first release 2026-03-18 13:53:47 +01:00
composer.json feat: add collection brief preview 2026-07-12 13:04:04 -07:00
configure.phtml fix: integrate collection UI with reader theme 2026-07-12 14:09:16 -07:00
DECISIONS.md fix: integrate collection UI with reader theme 2026-07-12 14:09:16 -07:00
extension.php feat: persist and refine collection dialog 2026-07-12 14:36:03 -07:00
LICENSE Initial commit 2026-03-17 18:35:08 +01:00
metadata.json feat: establish independent AI Brief extension 2026-07-12 11:14:05 -07:00
phpstan.neon feat: add collection brief preview 2026-07-12 13:04:04 -07:00
phpunit.xml feat: first release 2026-03-18 13:53:47 +01:00
README.md fix: integrate collection UI with reader theme 2026-07-12 14:09:16 -07:00
ROADMAP.md docs: capture focused validation workflow 2026-07-12 15:03:27 -07:00

AI Brief for FreshRSS

AI Brief is a FreshRSS extension for streaming individual article summaries and combined briefs from the reader's current collection context.

The project now includes a collection preview and combined newsletter-style brief. It is not yet ready for production use; staging authorization, provider egress, and browser validation remain required.

Direction

AI Brief is being built around two workflows:

  1. Summarize one article with streamed output.
  2. Combine articles from the current FreshRSS folder, category, feed, search, or label into one newsletter-style report.

The feed-column collection action covers entries matching the current category, feed, label, search, state, and ordering. Source articles are not marked read automatically; the completed report offers an explicit action for marking exactly its included articles read. Full-article fetching, explicit saved-query identity, and generated digest entries remain deferred.

Provider Foundation

The current branch focuses on predictable, provider-agnostic behavior:

  • OpenAI-compatible base URLs and arbitrary model names.
  • Dedicated DeepSeek setup using the built-in API URL and model, requiring only an API key.
  • Server-side connection testing from the settings form before saving provider credentials.
  • Provider-specific URL storage so credentials cannot be sent to a stale endpoint after switching providers.
  • Trailing-slash, versioned-base, reverse-proxy, and endpoint-path normalization.
  • Explicit provider dispatch and early unknown-provider rejection.
  • Server-side credentials and provider requests.
  • Stream parsing and provider error detection for OpenAI, Anthropic, Gemini, and Ollama.
  • Fragment-safe SSE/NDJSON callbacks with disconnect, line-size, and response-size limits.
  • No model-name heuristics or globally forced reasoning parameters.
Provider mode Default endpoint family
OpenAI-compatible /v1/chat/completions
DeepSeek /v1/chat/completions
Anthropic /v1/messages
Gemini /v1beta/models/{model}:streamGenerateContent
Ollama /api/chat

Collection Brief Requirements

  • Configurable maximum article count, input-token budget, and maximum article length.
  • One cohesive overview with grouped topics, key insights, details, analysis, and source citations.
  • Structured report output with server-owned stable article IDs and source links.
  • Preserved source links and skipped-article reporting.
  • Cancellation, connection-abort handling, and hard timeouts.
  • Optional full-article fetching.
  • Optional generated FreshRSS digest entry.
  • Articles matching the current feed-column context.
  • Current folder, category, feed, search, label, saved query, and unread-only contexts.
  • Provider-agnostic OpenAI-compatible requests.
  • Explicit capabilities for reasoning and non-reasoning models without model-name assumptions.
  • No automatic marking as read; an explicit post-report action is available.

The first implementation considers at most 50 ordered articles, caps each article at 6,000 content characters, and fits the largest ordered prefix within an approximately 24,000-token request budget. The server previews the exact authorized count, reloads entries through the authenticated user's FreshRSS DAO, and re-applies the normalized collection query before provider work begins. The provider's Markdown report streams into a bounded scrolling dialog; the raw provider envelope is capped at 2 MiB and the final report at 131,072 characters. Source IDs and links are attached from authorized server-side records.

Safety Boundaries

  • Provider credentials remain on the FreshRSS server.
  • AI output is treated as untrusted content.
  • Collection requests must be authenticated, CSRF-protected, capped, and re-authorized against the user's FreshRSS data.
  • Explicit provider URLs may use private networks because local providers require them, so enabled users must be trusted with that egress until an administrator-owned origin/IP allowlist ships.
  • Automatic full-article fetching is disabled. Future fetching must be public-network-only and revalidate every redirect hop.
  • Creating a digest entry is optional and must be idempotent.
  • Source entries remain unread unless the user explicitly chooses otherwise.

Development Status

Current work:

  • Validate the collection preview against a staging FreshRSS user in Normal and Reader views.
  • Add two-user authorization and injectable provider transport integration fixtures.
  • Add administrator-owned private-provider allowlists, persistent cancellation, concurrency, retry, and deadline contracts.

See ROADMAP.md for staging and DECISIONS.md for accepted architectural constraints.

Development

Requirements: PHP 8.1 or newer, cURL, mbstring, and Composer.

Forgejo runs lint, PHPStan, and non-integration PHPUnit tests on every commit. Live DeepSeek contract tests run only when provider/controller/service paths change on main, or through manual workflow dispatch.

composer install
vendor/bin/phpunit --testdox
vendor/bin/phpstan analyse --memory-limit=512M
php -l extension.php
php -l Controllers/AiBriefController.php
php -l Services/AiBriefCollection.php

Forgejo runs the same checks from .forgejo/workflows/ci.yml on the VPS docker runner. CI does not deploy the extension to a live FreshRSS installation.

Development Installation

cd /path/to/FreshRSS/extensions
git clone ssh://git@git.questverse.club:222/miket/xExtension-AiBrief.git

Enable AI Brief from FreshRSS's extension settings and use a staging FreshRSS instance while provider and collection behavior remain under development.

Project Guidance

Agent-facing architecture, invariants, repository maps, and validation procedures live in:

Origin And License

AI Brief is a GPL-3.0-or-later fork of xExtension-AiSummary. It is maintained as an independent extension with its own AiBrief entrypoint and configuration namespace.