MiniCPM News Desk is a local-first news reader powered by MiniCPM5-2B and ordinary Python. It helps an operator review official announcements with source-linked passages and explicit access, pricing, and setup conditions.
The public reference workflow includes fixed-source RSS collection, local build/preview, explicit Telegram sending, and recovery commands. You supply your own local model and Telegram bot. Nothing installs a schedule, downloads weights, or sends automatically.
The original personal setup runs on an Intel Core i5-9400F Linux desktop with 16 GB RAM and CPU-only MiniCPM inference. A private collector checks official sources hourly and sends one Telegram recap of the previous 24 hours. This repository shares the reusable briefing logic, not the owner's collector, Telegram account, or machine-specific configuration; the public workflow uses separate state and a smaller two-feed registry rather than the private collector's 28 sources.

The screenshot is a fictional layout example, not a fresh model result.
One daily recap, not another hourly feed
The target is an approachable morning reading experience: a lead story, a few updates worth knowing, and smaller quick hits, all linked to original sources.
- Delivered around 8 AM America/New_York, covering exactly the preceding 24 hours.
- Collection runs independently throughout the day. No hourly MiniCPM messages or breaking-news alerts.
- Source publication dates are used when available; otherwise discovery time is labeled. Older articles are not recycled as fresh news; listing revisions count as updates.
- Up to nine items: one lead and at most three additional detailed stories; remaining selected items appear as source links when no verified brief exists.
- Canonical URLs and same-source identical headline/day events are deduplicated. This is deterministic editorial ranking, not comprehensive semantic clustering.
- Material conditions are preserved. Word counts are soft targets, not truncation rules; long editions split at paragraph boundaries into numbered messages.
- Overflow is kept in a local archive and included later only while it still meets the 24-hour window. The omitted count is displayed.
How it works
MiniCPM selects exact source passages rather than generating free-form newsletter prose. A deterministic editorial layer retains relevant qualifications in the brief and moves navigation, unrelated field definitions, and background detail into a private supporting report. Unknown conditions stay visible. Full extracted sources and placement reasons remain in the report.
- Import a discovery snapshot or explicitly retrieve a supported article.
- Preserve exact source text, identity, dates, hashes, and offsets.
- Retain condition-related passages using deterministic rules.
- Optionally ask a local MiniCPM server to select up to two highlight IDs.
- Resolve IDs to exact quotations and review the report against the source.
The model cannot rewrite claims, choose new destinations, call tools, or send messages. It can still choose irrelevant passages or omit useful ones, and the rules can miss conditions. Quoting a source is not independent verification of its claims.
If a valid model response selects nothing, the report displays the full source as SOURCE-ONLY FALLBACK — unranked original text, not an AI summary or a model-quality success. Incomplete/invalid responses and held sources still fail closed.
Article retrieval is an explicit network operation. Supported main-body adapters cover xAI /news/, OpenAI /index/, and GitHub /changelog/. OpenAI retrieval has returned HTTP 403/challenge on both tested hosts; no challenge bypass is implemented, and blocked or unsupported sources stay clearly labeled links.
Local model selection
Bring your own authenticated, already-running numeric-loopback server. The evaluated identity is MiniCPM5-2B-Q4_K_M, llama.cpp b10809/5266f24da, thinking mode, context 8192, and 4096 output tokens, with reasoning_budget_tokens=512 in requests. Generic OpenAI-compatible servers may not implement this control. Preflight checks model alias, context, and template, but does not cryptographically verify your external server's runtime or weights.
Each invocation performs one explicit generation with a 480-second outer deadline, no retry, and no hosted-model fallback. Provide MINICPM_API_KEY through your secret mechanism — never in the config or Git.
Current evidence
- 0.8.1: deterministic source-preservation repairs; 270 offline tests pass. A separate 40-call comparison on an earlier frozen 0.8.1 checkpoint found that 1024 reasoning tokens improved coverage over 512 on known cases, but matched an exploratory deterministic comparator and still missed the quality targets. One synthetic instruction passage was selected at 512. Human review remains required; the shipped setting stays 512.
- 0.8.0: adds the public reference workflow and repairs technical-character loss, tested licensing omissions, and a preparation-context false hold. 257 offline tests passed; two fresh local selections and one actual Telegram delivery exercised the candidate.
- Historical 0.7.5 private test: two local-model briefs and seven source-only quick hits reached Telegram in two confirmed messages.
- Earlier selector evidence: 110 offline tests; one repair produced 7/8 semantic passes, followed by 8/8 offline saved-response handling checks; a separate fresh Linux CLI smoke test passed 3/3. These are separate measurements, not one combined accuracy score.
API charges for local tests were zero, but hardware, electricity, and review time are not zero-cost or measured savings. No matched cloud-cost comparison or general reliability claim is made.
Quick start
Try the fictional daily layout without a model or network (Python 3.14 standard library only):
git clone https://github.com/fenner888/minicpm-news-desk.git
cd minicpm-news-desk
python3.14 -m newsdesk.digest demo --out outputs/daily-demo-1
Connect a local MiniCPM for real passage selection:
python3.14 -m newsdesk select --article outputs/article-1/article.json \
--config config.local.json --allow-local-inference --out outputs/selection-1
Deliberate limits
- Every output requires meaning review; extractive wording may repeat context or preserve awkward source transitions.
- Budgets: 7,000 source characters, 120 blocks, 2,000 per block; protected text 5,500 characters/30 blocks; pool 4,000/25; selected text 1,800 characters total. Exceeding a limit holds the item instead of silently clipping it.
- English heading/demo heuristics can miss context. Known instruction-like patterns hold the item but are not comprehensive injection detection.
- No matching price passage does not mean free, unrestricted, or unannounced.
- No accounts, public API, UI dashboard, or bundled messaging credentials; schedule installation and unattended use remain operator decisions.
Links
- GitHub: fenner888/minicpm-news-desk
