AGENTIC COMMONSAI industry briefings

繁中EN

TopicAI Agents & WorkflowsPublished

All English articles

OpenRouter Agent SDK: Build an Always-On TypeScript Agent

On this page6 sections
  1. The four things an always-on agent needs
  2. Cost control as a first-class parameter
  3. Memory that survives a kill -9
  4. Approval gates that pause, not block
  5. Where to start
  6. Sources

Summary: OpenRouter published a TypeScript tutorial (October 31, 2026) for building an always-on agent with @openrouter/agent 0.11.0 — a Hacker News watcher that runs on a schedule, remembers what it has seen across restarts, and stops any run that hits five cents. The interesting part isn’t the demo; it’s which responsibilities the SDK takes and which stay in your code.

The four things an always-on agent needs

The tutorial frames the problem cleanly: a scheduled loop, tools to look at the world and act on it, memory that survives a crash, and limits — a step and cost cap per run, plus human approval for anything with consequences. The demo agent watches HN for chosen topics, writes a digest, and posts to a team channel only for major releases.

The division of labor is the part worth studying. The SDK runs the model and tool calls, applies the stop conditions, and persists the conversation so a paused run can resume. Your code owns the cron schedule and the file of seen story IDs. That split keeps the SDK small and your state boring — a JSON file on disk.

If you want to understand what the SDK is actually doing for you, our earlier post on OpenRouter’s tool-calling loop covers where stop conditions belong when you write the same loop by hand.

Cost control as a first-class parameter

Each check cost $0.0003 to $0.0012 in the tutorial’s runs on October 13, 2026, using Claude Haiku 5.5 — roughly $0.86 to $3.46 per month at one check every 15 minutes. The bounding is layered: stopWhen: [stepCountIs(6), maxCost(0.05)] caps every run, and a credit limit on the API key caps the total. That’s the pattern I’d copy regardless of framework — per-run limits in code, a hard total limit at the account level, so a runaway loop can’t surprise you twice.

A subtler cost trick: each check starts a fresh conversation. Long-term memory lives in a file of seen story IDs, not in an ever-growing context, so the cost of a check stays flat over weeks. The tool filters out already-seen stories before the model ever sees them, which means the model doesn’t burn tokens tracking its own history — or risk re-reporting the same story.

Memory that survives a kill -9

The tutorial’s restart test is the most instructive part. They killed the process right after a search returned 20 new stories. The next run resumed the saved conversation, wrote the digest from the stored search results, and marked all 20 IDs as seen; the following check found zero new stories.

The mechanics: new IDs go into a transient fetched.json during a run and only merge into seen.json when the run finishes. The documented tradeoff — a run failing after writing the digest can list a story twice — is the right call. A duplicate is easier to fix than a lost story.

Approval gates that pause, not block

The post_to_team_channel tool is declared with requireApproval: true. When the model calls it, the run pauses before execution, the pending call is logged with its ID, and scheduled runs are skipped while approval is pending. You drop an approve or reject decision into decisions.json, and the next run resumes the saved conversation with your decision applied. A resumed run can pause again, so the gate isn’t a one-time check.

This is a lightweight pattern for anything with external consequences — posting, emailing, spending. The SDK saves the conversation state; the approval queue is just a file you can review.

Where to start

The tutorial needs Node.js 22, an OpenRouter API key, and three packages (@openrouter/agent pinned at 0.11.0, Zod for tool schemas, tsx). Bun works too. The same structure transfers to any scheduled watcher — a repo, a status page, a competitor’s changelog — wherever something should be checked without you asking. One caveat to keep in mind: the SDK is still on 0.x releases, so pin the version and expect API changes.

Sources

AGENTIC COMMONSOperated by PHLEGON LABS
ShareXEmail
Support us

Related reading

  1. OpenRouter's Tool-Calling Loop: Where Your Stop Conditions Belong

    OpenRouter's TypeScript tutorial shows why the iteration cap, not the model, decides when an agent loop ends.

    OpenRouter

  2. Mastra Custom Adapters Get Official-Grade Checks

    Mastra shipped a conformance test suite so custom server adapters can be verified against the same tests as its official ones.

    AI Agents

  3. 600 Hours a Month: What One Sales Agent Says About Where Agents Actually Pay Off

    OpenRouter's Rasp agent cut a five-person sales team's admin work by 600 hours a month and its own costs from $800 to $30 a day.

    AI Agents