Let a free model triage your reading: one-line summary + reply flag
Point any OpenAI-compatible tool at an OpenRouter free model so each email/article/report comes back as a one-sentence summary plus a needs-reply flag, and you only open what earns it.
Run this workflow
CI-verified, 2/2 fixtures passing.
Build this with your agent
One copy-paste hands Claude Code, Codex, or Cursor the full recipe, steps included, nothing to fetch.
Intended Use
Anyone drowning in a daily reading pile who wants to decide what to open. CI validates the triage config: base_url points at OpenRouter, the model is a free model (id ends with :free), and the response schema returns a summary plus a needs_reply boolean. No key, no model call. The summarization itself is fenced.
Not for
- Sensitive material on free models, free options are the most likely to retain or train on what you send; use a cheap paid model (still pennies) for anything private
- Replacing reading, a one-line summary is a squeeze that sometimes flattens the one detail that mattered; use it to decide what to read, not instead of reading what you flagged
- High volume, OpenRouter free models cap at 20 req/min and 50 req/day (1000/day once you have added $10 in credits once)
The Stack
Tested Against
openrouter.ai/docs (free tier, 2026-06)node@20Side effects & data flow
- Network
- none, local only
- Writes
- ./triage.json
- Credentials
- none required
Prerequisites
- A free OpenRouter account + API key (only to actually run triage)
Steps
- 1
Write the triage config and validate it
Point your client at https://openrouter.ai/api/v1 with a :free model, and give it one standing instruction: summarize in a sentence and flag whether it needs a reply. CI checks the config shape; running it on your pile needs a key and is fenced.
cat > triage.json <<'JSON' { "base_url": "https://openrouter.ai/api/v1", "model": "deepseek/deepseek-r1:free", "instruction": "Summarize this in one sentence and flag whether it needs a reply.", "response_schema": { "type": "object", "properties": { "summary": { "type": "string" }, "needs_reply": { "type": "boolean" } }, "required": ["summary", "needs_reply"] } } JSON node -e ' const fs = require("fs"); const c = JSON.parse(fs.readFileSync("triage.json", "utf8")); function bad(m) { console.error("BAD: " + m); process.exit(1); } if (!c.base_url || !String(c.base_url).includes("openrouter.ai")) bad("base_url does not point at OpenRouter"); const m = c.model || ""; if (!m.endsWith(":free")) bad("model is not an OpenRouter free model (id must end with :free)"); const props = (c.response_schema && c.response_schema.properties) || {}; if (!props.summary || props.summary.type !== "string") bad("schema missing a string summary"); if (!props.needs_reply || props.needs_reply.type !== "boolean") bad("schema missing a boolean needs_reply"); console.log("config OK: OpenRouter free model " + m + ", triage returns a one-line summary + needs_reply flag"); ' - 2
Wire it into your tools (the model step, not checked by CI)
Drop your OpenRouter key into any tool that takes one (notes app, email automation, a small script) and feed each item through the config. Read the summaries, open only the flagged few. Keep sensitive items on a cheap paid model. The summarization is fenced.
Eval, 2 fixtures
Last passed: verified todaytriage-okcontainstimeout 30s · max $0Expected:
config OK: OpenRouter free model deepseek/deepseek-r1:free, triage returns a one-line summary + needs_reply flagclean-exitexit_codetimeout 30s · max $0Expected:
0
Results
Skimming twenty long items by hand at ~3 min each is about an hour; reading twenty one-line summaries and opening only the few that matter is about fifteen minutes. Roughly 45 minutes back a day. On OpenRouter free models it costs nothing (twenty items/day sits under the free daily cap); the same volume on a top-tier paid model would run ~$15-20/month.
Did this work for you?
Our CI checks the setup runs. You tell us if the whole thing worked. Tell us straight.
Related workflows
- Teach OpenCode Go your weekly chore once, then run it in minutes
- Scrape politely: honor robots.txt and a crawl delay (the part most skip)
- Firecrawl: turn a page into the exact JSON you asked for
- Claude Code Cloud Schedule: Runs With Your Laptop Off
- Claude Code Headless: An Always-On Local Schedule
- Claude Code /loop: Poll a Deploy on a Fixed Interval
Liked this workflow?
Get new verified workflows in WebAfterAI, three issues a week (Tue, Thu, Sat).