126 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
// Database constants
 | 
						|
const (
 | 
						|
	dbPath = "articles.db"
 | 
						|
)
 | 
						|
 | 
						|
// LLM constants
 | 
						|
const (
 | 
						|
	// LLM system prompt
 | 
						|
	SYSTEM_PROMPT = "You are a news analyst."
 | 
						|
 | 
						|
	// Main LLM prompt for article summarization
 | 
						|
	ARTICLES_PROMPT = `Summarize each of these news items in under 165
 | 
						|
	characters, optimizing for information density (common news headline
 | 
						|
	abbreviations OK) and rate their importance from 1 to 100.
 | 
						|
 | 
						|
100 means most important; 1 means least important.
 | 
						|
 | 
						|
Never rate over 90 unless it is a massive event such as: war outbreak,
 | 
						|
revolution, death of a head of state, large-scale natural disaster, mass
 | 
						|
casualty terrorism, etc.
 | 
						|
 | 
						|
Rank any headlines primarily promoting commercial products or
 | 
						|
services as 1 (lowest importance).
 | 
						|
 | 
						|
Rank any article with a headline that poses a question without providing an
 | 
						|
answer (as an attempt to lure a reader into clicking a link) as 1 (lowest
 | 
						|
importance).
 | 
						|
 | 
						|
Boost the importance score by 10 points for breaking news that is less than 60
 | 
						|
minutes old based on its original publication date (which is provided for each
 | 
						|
article), but only for time-critical events that need to be reported in minutes,
 | 
						|
such as currently unfolding events.  Don't boost the importance score simply because
 | 
						|
it was recently published, unless it is a time-critical event.
 | 
						|
 | 
						|
Do not editorialize or otherwise label the summary.
 | 
						|
 | 
						|
For each article, return a JSON object with "id", "summary", and "importance"
 | 
						|
fields.  Return your response as a JSON array of objects like: [{"id":
 | 
						|
"article_id", "summary": "...", "importance": 42}, ...] 
 | 
						|
 | 
						|
Here are the articles:
 | 
						|
`
 | 
						|
 | 
						|
	// LLM batch processing settings
 | 
						|
	BATCH_SIZE                = 5
 | 
						|
	MAX_INDIVIDUAL_PROCESSING = 50
 | 
						|
)
 | 
						|
 | 
						|
// Timing constants
 | 
						|
const (
 | 
						|
	RSS_CHECK_INTERVAL          = 15 * time.Minute
 | 
						|
	SUMMARIZE_INTERVAL          = 10 * time.Second
 | 
						|
	BROADCAST_INTERVAL          = 1 * time.Hour
 | 
						|
	BROADCAST_CHECK_INTERVAL    = 10 * time.Second // Interval to check if broadcasting is needed
 | 
						|
	DEVICE_REBOOT_INTERVAL      = 6 * time.Hour    // Interval to reboot Meshtastic device
 | 
						|
	STARTUP_DELAY               = 60 * time.Second // Delay before first broadcast
 | 
						|
	BROADCAST_PREPARATION_DELAY = 30 * time.Second // Delay before executing broadcast command
 | 
						|
	ARTICLE_FRESHNESS_WINDOW    = 24 * time.Hour   // Time window for considering articles fresh
 | 
						|
)
 | 
						|
 | 
						|
// Message constants
 | 
						|
const (
 | 
						|
	MAX_MESSAGE_LENGTH = 200  // Maximum length of broadcast messages in characters
 | 
						|
	MAX_LOG_ENTRIES    = 1000 // Maximum number of log entries to keep in memory
 | 
						|
)
 | 
						|
 | 
						|
// ANSI color codes for colorized logging
 | 
						|
const (
 | 
						|
	colorReset  = "\033[0m"
 | 
						|
	colorRed    = "\033[31m"
 | 
						|
	colorGreen  = "\033[32m"
 | 
						|
	colorYellow = "\033[33m"
 | 
						|
	colorBlue   = "\033[34m"
 | 
						|
	colorPurple = "\033[35m"
 | 
						|
	colorCyan   = "\033[36m"
 | 
						|
	colorGray   = "\033[37m"
 | 
						|
	colorWhite  = "\033[97m"
 | 
						|
	bold        = "\033[1m"
 | 
						|
)
 | 
						|
 | 
						|
// Map of source names to their abbreviations
 | 
						|
var sourceAbbreviations = map[string]string{
 | 
						|
	"BBC":             "BBC",
 | 
						|
	"CNN":             "CNN",
 | 
						|
	"NYTimes":         "NYT",
 | 
						|
	"Guardian":        "Grd",
 | 
						|
	"Al Jazeera":      "AlJ",
 | 
						|
	"NBC":             "NBC",
 | 
						|
	"ABC":             "ABC",
 | 
						|
	"CBS":             "CBS",
 | 
						|
	"Sky News":        "Sky",
 | 
						|
	"Time":            "Time",
 | 
						|
	"NPR":             "NPR",
 | 
						|
	"Deutsche Welle":  "DW",
 | 
						|
	"France 24":       "F24",
 | 
						|
	"The Independent": "Ind",
 | 
						|
	"Washington Post": "WaPo",
 | 
						|
	"WSJ":             "WSJ",
 | 
						|
}
 | 
						|
 | 
						|
// RSS feed URLs
 | 
						|
var feeds = map[string]string{
 | 
						|
	"BBC":             "https://feeds.bbci.co.uk/news/world/rss.xml",
 | 
						|
	"CNN":             "http://rss.cnn.com/rss/edition.rss",
 | 
						|
	"NYTimes":         "https://rss.nytimes.com/services/xml/rss/nyt/World.xml",
 | 
						|
	"Guardian":        "https://www.theguardian.com/world/rss",
 | 
						|
	"Al Jazeera":      "https://www.aljazeera.com/xml/rss/all.xml",
 | 
						|
	"NBC":             "http://feeds.nbcnews.com/nbcnews/public/news",
 | 
						|
	"ABC":             "https://abcnews.go.com/abcnews/topstories",
 | 
						|
	"CBS":             "https://www.cbsnews.com/latest/rss/world",
 | 
						|
	"Sky News":        "https://feeds.skynews.com/feeds/rss/world.xml",
 | 
						|
	"Time":            "https://time.com/feed/",
 | 
						|
	"NPR":             "https://feeds.npr.org/1001/rss.xml",
 | 
						|
	"Deutsche Welle":  "https://rss.dw.com/rdf/rss-en-world",
 | 
						|
	"France 24":       "https://www.france24.com/en/rss",
 | 
						|
	"The Independent": "https://www.independent.co.uk/news/world/rss",
 | 
						|
	"Washington Post": "https://feeds.washingtonpost.com/rss/world",
 | 
						|
	"WSJ":             "https://feeds.a.dj.com/rss/RSSWorldNews.xml",
 | 
						|
}
 |