惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
博客园_首页
Vercel News
Vercel News
WordPress大学
WordPress大学
美团技术团队
G
Google Developers Blog
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
Y
Y Combinator Blog
博客园 - 【当耐特】
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
The Cloudflare Blog
T
The Blog of Author Tim Ferriss
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google DeepMind News
Google DeepMind News
云风的 BLOG
云风的 BLOG
腾讯CDC
M
MIT News - Artificial intelligence
爱范儿
爱范儿
Recent Announcements
Recent Announcements
雷峰网
雷峰网
Last Week in AI
Last Week in AI
宝玉的分享
宝玉的分享
The Register - Security
The Register - Security
Jina AI
Jina AI
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Hugging Face - Blog
Hugging Face - Blog
P
Privacy & Cybersecurity Law Blog
Recorded Future
Recorded Future
Help Net Security
Help Net Security
N
News and Events Feed by Topic
博客园 - Franky
P
Proofpoint News Feed
L
LINUX DO - 热门话题
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
D
Docker
Google DeepMind News
Google DeepMind News
有赞技术团队
有赞技术团队
IT之家
IT之家
Security Latest
Security Latest
L
LangChain Blog
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
J
Java Code Geeks

OpenRouter Blog

Choosing the Optimal Image Input Detail Level in LLMs — OpenRouter Blog DeepSeek V4 Is Earning Agentic Token Share — OpenRouter Blog The Open Weight Models that Matter: June 2026 — OpenRouter Blog The OpenRouter MCP Server — OpenRouter Blog Introducing the Unified Image API — OpenRouter Blog The AI Governance Checklist That Maps to Your Stack — OpenRouter Blog Enforce AI Data Residency at the Routing Layer — OpenRouter Blog OpenRouter vs Portkey: Routing Network vs Control Plane — OpenRouter Blog OpenRouter vs LiteLLM: Managed vs Self-Hosted Gateway — OpenRouter Blog Connect OpenClaw to OpenRouter: One Key, Failover, Free Models — OpenRouter Blog Connect SillyTavern to OpenRouter: Setup, Models, Fixes — OpenRouter Blog A Robot is Sprinting Towards You: Do You Want it Running on Claude or Grok? Kilo Code + OpenRouter: Setup, Routing, and Free Models — OpenRouter Blog Codex CLI with OpenRouter: config.toml Setup and Models — OpenRouter Blog Claude Code with OpenRouter: Setup, Models, and Costs — OpenRouter Blog How to Use OpenRouter With Any Coding Agent or AI Tool — OpenRouter Blog Subagent: Let Your Model Delegate the Busywork — OpenRouter Blog Free LLM API in 2026: 13 Options Ranked and Compared — OpenRouter Blog How to Enforce Agentic AI Governance at the API Layer — OpenRouter Blog Keep Your Agent Running When Models Disappear — OpenRouter Blog Hermes Agent + OpenRouter: Setup, Model Choice & Routing Config — OpenRouter Blog Lowest-Cost LLM Inference: The Complete OpenRouter Guide — OpenRouter Blog How OpenRouter Model Routing Works: Providers, Fallbacks & Auto Router — OpenRouter Blog OpenRouter Failover: Provider Failover vs Model Fallbacks Explained — OpenRouter Blog Surpassing Frontier Performance with Fusion — OpenRouter Blog Dinner is Served — OpenRouter Blog LLM Gateway: What It Is and How to Choose One — OpenRouter Blog Advisor: Give Any Model a Lifeline to a Smarter One — OpenRouter Blog Gemini 2.5 Flash API - Pricing, Quickstart & Provider Comparison — OpenRouter Blog EU AI Act & Colorado ADMT Compliance: Human Oversight for AI Agents — OpenRouter Blog May Release Spotlight — OpenRouter Blog Guardrails: Protect your Agents, Data, and Costs — OpenRouter Blog OpenRouter Raises $113M Series B — OpenRouter Blog Consistent Web Search and Fetch Across Every Model — OpenRouter Blog GPT-5.5 Price Increase: What It Actually Costs — OpenRouter Blog New Audio APIs for Speech and Transcription — OpenRouter Blog Response Caching: Zero Cost for Identical Requests — OpenRouter Blog April Release Spotlight — OpenRouter Blog Create OpenRouter Accounts via CLI with Stripe Projects — OpenRouter Blog Opus 4.7 Agent SDK: Building Multi-turn Agent Workflows on OpenRouter — OpenRouter Blog Build Your Own Harness with the Agent SDK — OpenRouter Blog Introducing Workspaces — OpenRouter Blog Announcing Video Generation — OpenRouter Blog Auto Exacto: Adaptive Quality Routing, On by Default — OpenRouter Blog February Release Spotlight — OpenRouter Blog OpenRouter Outages on February 17 and 19, 2026 — OpenRouter Blog January Release Spotlight — OpenRouter Blog Distillable Models and Synthetic Data Pipelines with NeMo Data Designer — OpenRouter Blog December Release Spotlight — OpenRouter Blog Response Healing: Reduce JSON Defects by 80%+ — OpenRouter Blog The 2025 State of AI Report — OpenRouter Blog Is Implicit Caching Prompt Retention? — OpenRouter Blog Provider Variance: Introducing Exacto — OpenRouter Blog 1 million free BYOK requests per month — OpenRouter Blog The First-Ever Image Model Is Up on OpenRouter — OpenRouter Blog GPT-5 is now live — OpenRouter Blog Audio Inputs and PDF URLs for Apps — OpenRouter Blog Presets: How To Seamlessly Transfer Model Configurations Across Apps — OpenRouter Blog New Privacy-Focused Provider Drop: Venice — OpenRouter Blog Use OpenRouter Models in Cursor: Try it with Moonshot AI Updates to Our Free Tier: Sustaining Accessible AI for Everyone — OpenRouter Blog New Stealth Model: "Cypher Alpha" — OpenRouter Blog Introducing Presets: Manage LLM Configs from Your Dashboard! — OpenRouter Blog Dev & BYOK Updates: Uptime API + Smarter Key Management — OpenRouter Blog Simplifying Our Platform Fee — OpenRouter Blog GIF Prompts, Omni Search, Tool Caching, and BYOK Flags — OpenRouter Blog New Features: Reasoning Streams, Crypto Invoices, End-User IDs & More — OpenRouter Blog Passkeys, DevEx Upgrades, and a New Guide for TypeScript Agents — OpenRouter Blog New Provider Drop: Cerebras Is Here — OpenRouter Blog Better Insights, Faster Metrics, and New Developer Power Tools — OpenRouter Blog Privacy Clarity, New Providers, OAuth Upgrade, and Gemini Gets Parallel Tools — OpenRouter Blog Universal PDF Support — OpenRouter Blog Smarter Charts, Inline SVGs, and Live Usage Accounting — OpenRouter Blog Quasar Alpha and Optimus Alpha Reveal — OpenRouter Blog "Stealth" model: Optimus Alpha — OpenRouter Blog “Stealth” model: Quasar Alpha — OpenRouter Blog Never Pay for Empty AI Responses Again — OpenRouter Blog Deep Research & Many New Models — OpenRouter Blog Introducing Nitro and Floor Price Shortcuts — OpenRouter Blog Introducing Cloudflare as a new provider — OpenRouter Blog Reasoning Tokens for Thinking Models — OpenRouter Blog Introducing Web Search via the API — OpenRouter Blog Standardized finish reasons — OpenRouter Blog Happy New Year! Introducing a new Auto Router — OpenRouter Blog Holiday launches: Web Search & Price Cuts — OpenRouter Blog Bring Your Own API Keys — OpenRouter Blog Crypto Payments API — OpenRouter Blog Structured Outputs & Free Gemini Flash 2.0 — OpenRouter Blog Price Drops and Llama 3.3 70b — OpenRouter Blog Author Pages & Amazon Nova — OpenRouter Blog
Human-in-the-Loop Tools for the Agent SDK — OpenRouter Blog
Kenny Rogers · 2026-05-08 · via OpenRouter Blog

The Agent SDK now supports a fourth tool type: human-in-the-loop (HITL) tools. They let your agent handle routine calls automatically and pause for a human when stakes are high, all controlled by a single hook.

Install the SDK, define your HITL tool, and follow the cookbook recipe for a working implementation.

npm install @openrouter/agent

Auto-resolve or escalate, per call

Regular tools always execute. Manual tools always pause. HITL tools do both: your onToolCalled hook inspects the input and decides.

import { tool } from '@openrouter/agent/tool';
import { z } from 'zod';

const approvePayment = tool({
  name: 'approve_payment',
  description: 'Approve a payment, escalating large amounts to a human',
  inputSchema: z.object({
    amount: z.number(),
    recipient: z.string(),
  }),
  outputSchema: z.object({
    approved: z.boolean(),
    reviewedAt: z.number().optional(),
  }),
  onToolCalled: async (input) => {
    if (input.amount < 100) {
      return { approved: true };
    }
    // Pause for human review
    return null;
  },
});

Return a value and the agent keeps going (like a regular tool). Return null and the loop pauses with status: 'awaiting_hitl', surfacing the pending call to your application. You resume by calling callModel again with a function_call_output item containing the human’s decision.

This pattern fits anywhere the decision depends on data: dollar thresholds, risk scores, content policy flags, compliance checks. The branching logic lives in one function, not scattered across your application code.

Post-process human responses before the model sees them

An optional second hook, onResponseReceived, fires when a human supplies a result for a paused call. It transforms the raw input before passing it to the model.

onResponseReceived: async (raw) => {
  return { ...(raw as Record<string, unknown>), reviewedAt: Date.now() };
},

Use it to stamp metadata, normalize formats, validate against business rules, or enrich the response with context the human didn’t need to provide manually. If it throws, the error surfaces to the model as { error: ..., originalOutput: ... } so nothing gets silently swallowed.

How the pause and resume cycle works

Here’s the full lifecycle:

  1. The model calls your HITL tool during an agent loop.
  2. onToolCalled runs. If it returns a value, the agent continues. If it returns null, the loop pauses.
  3. Your application reads the pending calls via getToolCalls() and presents them to the user.
  4. The user makes a decision.
  5. You call callModel again with the decision as a function_call_output item.
  6. onResponseReceived (if defined) transforms the response.
  7. The model receives the result and the agent loop resumes.
const result = openrouter.callModel({
  model: 'openai/gpt-4o',
  input: 'Pay $500 to Acme Corp for the May invoice',
  tools: [approvePayment] as const,
  state,
});

const response = await result.getResponse();

if (response.state?.status === 'awaiting_hitl') {
  const pending = response.state.pendingToolCalls ?? [];
  // Present pending[0] to your user, collect their decision, then resume:
  const resumed = openrouter.callModel({
    model: 'openai/gpt-4o',
    input: [{
      type: 'function_call_output' as const,
      callId: pending[0].id,
      output: JSON.stringify({ approved: true }),
    }],
    tools: [approvePayment] as const,
    state,
  });
}

The SDK handles all the state tracking, hook dispatch, and schema validation. You wrote zero loop code.

When to use HITL vs requireApproval

Both pause for human input. The difference is in the decision logic.

HITL (onToolCalled)requireApproval
When it pausesOnly when your hook returns nullAlways, before any execution
Decision typeData-driven (thresholds, scoring, policy)Binary yes/no consent
Auto-resolveReturn a value to skip human reviewNot available
Post-processingonResponseReceived transforms the responseNot available

Use requireApproval when every invocation needs explicit human consent regardless of input (think: “delete this database,” “send this email”). Use HITL when some calls can proceed automatically and others need a human (think: “approve this payment if it’s under $100”).

Start building

The HITL tools cookbook recipe walks through a complete implementation: defining the tool, detecting pauses, collecting human input, and resuming the loop.

For the full type signatures and API surface, see the tools documentation and the API reference.

Get your API key and tell us what you’re building on Discord.