Skip to content

Human-in-the-Loop

When your agent needs human input (approvals, reviews, clarifications), agent-os shows this live in the dashboard with a “Waiting for Human Input” status.

  1. Your agent calls aos.hitl_request() → dashboard shows waiting status
  2. You collect the human’s answer (your own logic)
  3. Your agent calls aos.hitl_received() → dashboard shows running again
from agent_os_sdk import AgentOS
aos = AgentOS(api_key="your-api-key")
def human_review_node(state):
run_id = state["run_id"]
# Signal: agent is waiting for human input
aos.hitl_request(
sdk_run_id=run_id,
question="Should we deploy to production?",
context={"target": "prod", "changes": 5},
channel="slack",
)
# Your own logic to get human input
answer = get_human_approval()
# Signal: human has responded
aos.hitl_received(
sdk_run_id=run_id,
response=answer,
responded_by="tobias",
)
return {**state, "approved": answer == "yes"}
import { AgentOS } from "agent-os-sdk";
const aos = new AgentOS({ apiKey: "your-api-key" });
// Signal: waiting for human input
await aos.hitlRequest(
runId,
"Should we deploy to production?",
{ target: "prod", changes: 5 },
"slack"
);
// Your own logic to get human input
const answer = await getHumanApproval();
// Signal: human has responded
await aos.hitlReceived(runId, answer, "tobias");

Python: aos.hitl_request(sdk_run_id, question, context=None, channel="dashboard")

Section titled “Python: aos.hitl_request(sdk_run_id, question, context=None, channel="dashboard")”

Signal that the agent is waiting for human input.

ParameterTypeDescription
sdk_run_idstrThe current run ID
questionstrWhat the agent is asking
contextdictOptional extra context (shown in dashboard)
channelstrWhere the human responds: "dashboard", "slack", "email"

Python: aos.hitl_received(sdk_run_id, response, responded_by=None)

Section titled “Python: aos.hitl_received(sdk_run_id, response, responded_by=None)”

Signal that human input has been received.

ParameterTypeDescription
sdk_run_idstrThe current run ID
responseanyThe human’s response
responded_bystrOptional: who responded

JavaScript: aos.hitlRequest(sdkRunId, question, context?, channel?)

Section titled “JavaScript: aos.hitlRequest(sdkRunId, question, context?, channel?)”

Same as Python, but with camelCase naming.

JavaScript: aos.hitlReceived(sdkRunId, response, respondedBy?)

Section titled “JavaScript: aos.hitlReceived(sdkRunId, response, respondedBy?)”

Same as Python, but with camelCase naming.

When hitl_request is sent:

  • The run’s status badge changes to “Waiting for Human Input”
  • The event timeline shows the question and context
  • A waiting timer starts

When hitl_received is sent:

  • Status returns to “Running”
  • The timeline shows who responded and what they said
  • The waiting duration is recorded