For agents built without a directly supported framework,Documentation Index
Fetch the complete documentation index at: https://handlebar.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
handlebar-core provides the
primitives to wire governance into any agent loop.
Prerequisites
- A Handlebar account
- Handlebar API key (created on the platform)
Install
How it fits into your agent
A typical agent loop looks like this:start_run/end_run— bracket the entire agent invocation. Handlebar uses these to group all events and enforce run-level budgets.before_llm/after_llm— record the messages sent to the model and the response (including token usage) for the audit log.before_tool— evaluate the proposed tool call against your configured policies. Returns aDecisionthat tells you whether to proceed, block, or stop the run.after_tool— record the tool’s result.
The client
HandlebarClient is the top-level object that connects your agent to the Handlebar
platform. It handles authentication, registers your agent, and manages the audit event
stream.
Initialise it once at application startup — not once per request or per run. The
client is designed to be shared: it maintains a single connection to the platform and
fans out events for all concurrent runs.
init_sync:
AgentDescriptor.slug is the stable identifier for your agent on the Handlebar platform.
It is how you match runs in the dashboard to a specific agent in your codebase. Use a
short, unique, URL-safe string — e.g. "travel-booking-agent".
Runs
A run represents one end-to-end invocation of your agent — from the first message in to the final response out. Everything that happens in between (LLM calls, tool calls, decisions) is attributed to that run in the audit log. Start a new run at the beginning of each invocation and end it when the agent finishes:run_id must be unique per invocation. A UUID works well:
run object is what you interact with throughout the agent loop. Hold a reference to
it for the lifetime of the invocation — typically as a local variable in the function that
runs your agent.
Agent lifecycle
Before LLM call
message.raw.created audit events for each message, enabling full conversation logging on the platform.
before_llm is optional - skipping it means conversation content won’t appear in audit logs, but tool governance still works fully.
After LLM call
llm.result event.
before_llm, this is optional but enables token-based budget enforcement and spend tracking on the platform.
Before tool call
before_tool is where governance actually happens. It evaluates the proposed call against your configured rules. and returns a Decision indicating whether to allow or block the call.
Decision shape:
BLOCK + CONTINUE means the tool should be skipped but the agent loop can continue - the blocked message is typically returned to the LLM so it can respond gracefully.
BLOCK + TERMINATE means the run should stop entirely. Throw an error that propagates up through your agent loop, catch it at the top level, and call run.end("interrupted").
After tool call
tool.after rules (e.g. inspecting output content or checking data exfiltration patterns).
Sync usage
Every async method has a_sync counterpart:
Additional config
Tool tags
Tags let you group tools by function so governance rules apply to the whole category rather than individual tool names. For example:- Rate-limit all
"search"tools regardless of which search API they call - Block data exfiltration by preventing a
"pii-read"result flowing into an"external"tool - Require human review before any
"write"action
before_tool is called:
End-user / actor configuration
Attach the identity of the end-user to the run so that Handlebar can:- Enforce per-user budgets — e.g. each user gets a fixed number of tool calls or tokens per day
- Attribute every audit event to a specific user
- Apply per-user rules — e.g. restrict which tools a given user role can invoke
external_id can be any stable identifier your application uses — a database ID, a UUID,
an email address, etc. Handlebar stores it opaquely and uses it to aggregate usage and
enforce per-user policies.
session_id is optional but recommended when an agent can be invoked multiple times
within a single user session — it lets the platform group related runs together.
Misc options
enforce_mode | Behaviour |
|---|---|
"enforce" | Governance decisions are applied — blocked tools are stopped |
"shadow" | Decisions are evaluated and logged but never enforced |
"off" | No API calls; pass-through only |