- PHP 75.4%
- JavaScript 16.3%
- CSS 3.8%
- HTML 2.7%
- Shell 1.8%
|
|
||
|---|---|---|
| .agents/skills/ai-brief-development | ||
| .forgejo/workflows | ||
| assets | ||
| Controllers | ||
| i18n | ||
| scripts | ||
| Services | ||
| static | ||
| tests | ||
| .gitignore | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| composer-setup.php | ||
| composer.json | ||
| configure.phtml | ||
| DECISIONS.md | ||
| extension.php | ||
| LICENSE | ||
| metadata.json | ||
| phpstan.neon | ||
| phpunit.xml | ||
| README.md | ||
| ROADMAP.md | ||
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:
- Summarize one article with streamed output.
- 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.