Skip to content
HaneDOCS日本語

Hane Platform

Agents and AgentRuns

How agent definitions, drivers, tools through the Tool Gateway, approvals inside runs, conversation context, and evaluations work.

This page explains how Hane agents are defined and run. It covers which drivers are available where, how agents call tools, how outbound actions are approved, and how to evaluate an agent.

An agent is a definition with a purpose, the tools it may use, limits, and input and output schemas. You write it as a manifest (Agent in agents/v1alpha1) and activate it in a ReleaseBundle, like any other definition.

An AgentRun is one run of an agent from the active release. It holds the input, the result, a summary of tool calls, the tokens used, and the status. A run starts as queued or running and ends as succeeded, failed, cancelled, or limit_exceeded.

Field Meaning
purpose, examples What the agent does. Reception also uses these to pick an agent from free text
input, output JSON Schema for the input, and for the result returned with submit_result. The result must have a status
driver How the agent runs (see the table below)
instructions, script Instructions for the model, or the steps for the scripted driver
tools Tools the agent may call. The Tool Gateway checks this list on every call
limits maxToolCalls, maxSeconds, maxModelTokens (tokens for one run; default 50,000)
approval, handover Assignment rules for approving outbound actions and for handing work to a person
workflows, connections, toolExposures Workflows the agent may start, and customer APIs it may call
apiVersion: agents/v1alpha1
kind: Agent
metadata:
name: vehicle-check
spec:
purpose: Look up a vehicle's model, inspection expiry, and mileage in the fleet ledger
input:
type: object
required: [vehicle]
properties:
vehicle: { type: string, title: Registration number }
driver: opencode
instructions: |-
Find the vehicle with data.find_record and answer with submit_result.
If it is not found, hand over to the fleet desk with request_human_help. Never invent values.
tools: [data.find_record, request_human_help]
handover:
assignment: fleet-desk
limits:
maxToolCalls: 4
maxSeconds: 120
output:
type: object
required: [status, vehicle]
properties:
status: { type: string }
vehicle: { type: string }

The driver decides what runs the agent. Every driver calls tools through the same Tool Gateway and returns its result with submit_result.

driver How it works Where it runs and availability
scripted Calls tools in the order given in script. Uses no model Runs in every environment
llm Lets a model choose the tools Preview Runs on recorded responses in local development. Not yet enabled in the cloud environment
opencode Starts the open-source harness opencode in a sandbox container. Model calls go through the Model Gateway Preview Runs in the cloud sandbox. Verified with Cloudflare Workers AI as the upstream model
codex, claude Starts Codex CLI or Claude Code on a developer’s machine and lets it use only Hane’s MCP tools Preview For local development and verification only. Not offered in the cloud environment

CLI drivers (opencode, codex, claude) choose a pair of CLI version and sandbox image with cliProfile. Without it, each driver uses its baseline pair. The ReleaseBundle fixes which pair runs, so upgrading or rolling back a CLI goes through the same evaluation and activation path as any definition change.

Agents always call tools through the Tool Gateway. The driver attaches a short-lived RunToken issued for that run. On every call, the Tool Gateway checks that the tool is in the definition’s tools, that the run has not been stopped, and that no limit is exceeded. When you cancel a run, the next call is rejected without waiting for the RunToken to expire.

The main tools are:

Group Examples
Reading the ledger data.find_record, data.get_record, ontology.query, ontology.knowledge
Reading documents documents.search, documents.read_pages, documents.read_summary
Moving work forward workflow.start, workflow.get_case, tasks.create, request_human_help
Customer APIs integration.describe, integration.read, integration.execute
Outbound actions communication.send_email, communication.send_sms, communication.place_call, browser.run_flow
Results submit_result (submit_review for review agents)

To turn an operation of an API you publish into an agent tool, define a ToolExposure. The resulting tool definitions (ToolDefinition: input and output schemas, impact, timeout, and so on) are listed by GET /v1/agents/tools. See Integrations.

Tool results, document text, and incoming email are treated as untrusted input. Instructions written in them never grant permissions.

Outbound actions such as email, SMS, phone calls, and updates through a customer API do not run when the agent calls them. Hane fixes the recipient and content into an ActionRequest with a digest and creates an approval task. Once approved, the action runs exactly once through the execution ledger.

  • Who may approve is decided when the action is proposed, by the DeciderPolicy named in the agent’s approval.decider. Without one, a person decides every action.
  • Depending on the rules, a review agent can approve, reject, or escalate to a person, or a policy approval can approve without creating a task. Decisions by AI or by policy never count as human approval.
  • A decider override (POST /v1/agents/decider-overrides) returns a tool’s approvals to people only, without waiting for a new ReleaseBundle.
  • An action whose outcome is unknown becomes unknown. Hane does not resend it; a person reconciles it (POST /v1/agents/action-requests/{id}/reconcile).

See Approvals for the full flow.

An AgentRun starts in one of these ways:

  • Pass the agent name and input to POST /v1/agents/runs
  • Pass free text to POST /v1/agents/requests (reception), which chooses the agent and the input
  • A Workflow agent step, a schedule, or a message in the built-in chat
import { createHaneClient, unwrap } from "@hane/sdk";
const client = createHaneClient({ baseUrl, token: async () => accessToken });
const run = await unwrap(
client.POST("/v1/agents/runs", {
body: { agent: "vehicle-check", input: { vehicle: "架空 300 あ 10-02" } },
}),
);

With shadow: true, the run skips outbound actions and handovers and only keeps a record.

The definition’s limits cap a single run. A Budget in platform/v1alpha1 sets daily (UTC) limits for a project and environment.

apiVersion: platform/v1alpha1
kind: Budget
metadata:
name: daily-budget
spec:
agentRunsPerDay: 200
externalActionsPerDay: 50
modelTokensPerDay: 200000
alertAtPercent: 80

When Hane creates a run that uses a model, it first reserves maxModelTokens from the daily budget. If not enough remains, the run does not start. Read today’s usage with GET /v1/agents/budget.

In built-in chat conversations, Hane stores the messages, run inputs and results, and action states, and builds the context passed to the model from them. It does not depend on CLI sessions.

With /v1/agents/conversations/{id}/memory, you can read and save the current context as versioned JSON, and start a new conversation from a saved history. The saved JSON never contains RunTokens, API keys, or credentials, and a restored history never overrides current permissions or the execution ledger.

An EvalSuite in agents/v1alpha1 lists up to 50 pairs of input and expected result. POST /v1/agents/evals runs the agent in shadow mode for each case and compares the result fields. GET /v1/agents/evals/compare compares two evaluations of the same suite case by case.

apiVersion: agents/v1alpha1
kind: EvalSuite
metadata:
name: lease-qa-eval
spec:
agent: lease-qa
passRate: 1
cases:
- name: Contract not in the ledger
input: { contract_no: C-9999 }
expect: { status: handed_over }