Skip to content

atto-corp/attonews

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

342 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

attonews

CI

An AI-powered newsroom application where AI agents act as reporters and an editor, automatically generating articles and newspaper editions. The system uses scheduled jobs to create content based on predefined beats and editorial guidelines.

Overview

attonews is an AI-powered news platform that revolutionizes journalism through automated content creation. Our system employs specialized AI reporters covering various beats (Politics, Technology, Business, etc.) who continuously generate articles based on real-time events and editorial guidelines. An AI editor then curates the most newsworthy stories into comprehensive newspaper editions and daily compilations.

attonews operates 24/7, producing fresh content hourly with editions compiled every 6 hours and daily newspapers every 24 hours. The platform combines human-like journalistic standards with the efficiency of AI to deliver timely, relevant news coverage.

For Readers

Access attonews's AI-generated news content through our intuitive web interface:

Reading Features

  • Articles: Browse individual news stories generated by our AI reporters, each covering specific topics and beats
  • Newspaper Editions: Read curated hourly editions that compile the most important stories of the period
  • Daily Editions: Access comprehensive daily newspapers with front-page headlines, in-depth coverage, and editorial selections
  • Archive Access: Depending on your subscription tier, explore historical content dating back to the platform's inception

Public Access

All users can freely access recent content without registration. Visit the following pages to start reading:

  • / - Main page with latest stories and opinion articles
  • /about - About the project
  • /editions - View recent newspaper editions
  • /events - Browse event-level news developments

Features

  • AI Reporters: Specialized AI agents covering different beats (Politics, Technology, Business, etc.)
  • AI Editor: Curates and selects the most newsworthy stories for publication
  • External Scheduling: System crontab triggers API endpoints for content generation
  • Daily Editions: Comprehensive newspaper editions compiled from recent articles
  • Web Interface: Next.js frontend for managing reporters, editor, articles
  • Admin Authentication: Secure login system for editorial control (can be disabled for development with npm run dev:noauth)
  • Configurable Storage: Redis/Sqlite data persistence for articles, reporters, and editions

Prerequisites

  • Node.js 18+
  • Redis server running on redis://localhost:6379 (default database)
  • PostgreSQL server (optional, for PostgreSQL backend)
  • Docker (optional, for Docker Compose testing)

Getting Started

  1. Install dependencies:

    npm install
  2. Set up environment variables: Create a .env.local file with:

    OPENAI_API_KEY=your_openai_api_key
    DATA_STORAGE_BACKEND=redis
    
  3. Start the development server:

    npm run dev
  4. Open http://localhost:3000 to access the application.

Development Mode (Auth Disabled)

For development or testing without setting up user accounts, start with:

npm run dev:noauth

This runs the app with AUTH_DISABLED=true, which bypasses all authentication checks and grants admin-level access to every visitor. All API routes respond as if an admin user is logged in, without requiring tokens or login. The editor page, admin panels, and permission-gated features are all fully accessible.

Docker Compose (alternative)

For isolated testing without local dependencies:

docker compose run --rm test

Or start the dev server:

docker compose up app

Project Structure

  • src/app/ - Next.js app router pages and API routes
  • src/services/ - Business logic services (AI, Redis, Editor, Reporter)
  • src/models/ - TypeScript types and schemas
  • crontab.txt - System crontab for scheduling jobs

Content Pipelines

The system operates through 4 interconnected pipelines triggered by system crontab:

Pipeline Overview

Pipeline Cron Schedule Default Throttle Endpoint Description
Event Generation Hourly (:00) 30 min /api/cron/events Fetches real-time social media from Bluesky, generates events per reporter
Article Generation Hourly (:00) 15 min /api/cron/articles Generates articles for each enabled reporter using Bluesky data
Newspaper Edition Every 6 hours 180 min /api/cron/edition Curates articles from last 3 hours into newspaper edition
Daily Edition Daily at 8am /api/cron/daily Aggregates 24h of editions into comprehensive daily newspaper
News Ticker Daily at 8:10am /api/cron/ticker Condenses daily edition into scrolling ticker text

Pipeline Details

1. Event Generation (/api/cron/events)

  • Fetches real-time messages from Bluesky/Jetstream
  • For each enabled reporter, AI generates new events based on their beat + history
  • Updates existing events or creates new ones
  • Location: src/app/services/reporter.service.ts:260

2. Article Generation (/api/cron/articles)

  • For each enabled reporter:
    • Fetches latest Bluesky messages
    • Calls AI to generate structured article
    • Saves article to storage
  • Location: src/app/services/reporter.service.ts:11

3. Newspaper Edition (/api/cron/edition)

  • Collects all articles from the last 3 hours
  • AI selects most newsworthy stories
  • Creates newspaper edition with selected story IDs
  • Location: src/app/services/editor.service.ts:11

4. Daily Edition (/api/cron/daily)

  • Aggregates all newspaper editions from the last 24 hours
  • AI creates comprehensive front page headline/article
  • AI generates topic-by-topic breakdown with summaries
  • Location: src/app/services/editor.service.ts:85

Generation Period Throttling

Each pipeline has a configurable "generation period" stored in editor settings. This acts as a throttle to prevent excessive runs:

  • Article Generation: Default 15 minutes (cron runs hourly, but skips if <15min since last run)
  • Event Generation: Default 30 minutes (cron runs hourly, but skips if <30min since last run)
  • Edition Generation: Default 180 minutes (cron runs every 6h, but skips if <3h since last run)

The cron job will return { "skipped": true } if the generation period hasn't elapsed. Configure these values on the Editor page (/editor).

Scheduling

The production system uses a system crontab (crontab.txt) to trigger API endpoints. These define the maximum frequency — actual runs may be skipped based on the generation period throttle settings:

0 * * * * wget http://localhost:8080/api/cron/articles
0 * * * * wget http://localhost:8080/api/cron/events
0 */6 * * * wget http://localhost:8080/api/cron/edition
0 8 * * * wget http://localhost:8080/api/cron/daily
0 0 * * * redis-cli -n 0 save

Manual triggers: Jobs can also be triggered manually via the Editor page (/editor).

Data Flow

Bluesky/Jetstream → Events → Articles → Newspaper Editions → Daily Edition → Home Page

Key Services

  • ReporterService: Handles event and article generation per reporter
  • EditorService: Handles edition curation and compilation
  • AIService: All LLM calls (article, event, edition generation)
  • BlueskyService: Real-time social media ingestion

Key Frontend Pages

  • Reporters Page: View and edit reporter profiles and their articles
  • Editor Page: Configure editor settings and manually trigger jobs
  • Articles Page: Browse generated articles
  • Editions Page: View compiled newspaper editions

Testing

Tests use Node's built-in node:test framework with tsx for TypeScript support. Test files are named *.test.ts and are auto-discovered.

Running Tests

Locally (requires a local Node.js install):

DATA_STORAGE_BACKEND=sqlite npm test

With Docker Compose (isolated, no local dependencies needed):

docker compose run --rm test

Run a single test file:

docker compose run --rm test node --import tsx --test src/app/services/sqlite-data-storage.test.ts

Writing Tests

Tests use node:test and node:assert/strict:

import { describe, it, before, after } from "node:test";
import assert from "node:assert/strict";

Existing Test Suite

The primary test file at src/app/services/sqlite-data-storage.test.ts contains 47 tests covering:

Group Tests Areas
Editor 3 save/get, null when missing
Reporter 5 CRUD, empty beats, disabled state
Article 7 CRUD, 4 query patterns (latest, by reporter, time range, global)
Event 4 CRUD, by reporter, latest updated
NewspaperEdition / DailyEdition 6 CRUD, ordering, empty topics
User 8 create, lookup by ID/email, login tracking, delete, unique constraint
Job status, KPI, Log 8 running/lastRun/lastSuccess, set/get/increment, add/get
clearAllData 1 wipes all tables for isolation

About

attonews: AI news[gathering+writing] from bluesky

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Contributors