Events are the SDK contract

The Autohand CLI runs the reasoning loop. The SDK opens a JSON-RPC or stdio connection to the CLI and receives a stream of events. Your application never needs to host the model or implement tool calling itself; it only needs to understand the events.

This design keeps SDKs thin, consistent across languages, and safe. The CLI enforces permissions and file access; the SDK observes and responds.

Common event types

Event names are stable across all SDK languages. The payload shape is normalized so the same handler logic works in TypeScript, Python, Go, Java, and Swift.

EventWhen it firesKey fields
turn_startA new reasoning turn beginsturn, iteration
message_updateThe model streams a token or fragmentdelta, message
tool_startA tool is about to runtoolName, args
tool_endA tool has finishedtoolName, result, duration
permission_requestThe CLI needs user approvalrequestId, tool, action, resource
hook_invokedA configured shell hook ranevent, command, exitCode
session_startA session was createdsessionId, project
session_endThe session closedsessionId, duration
errorAn unrecoverable error occurredmessage, context

Stream events

Every SDK provides a streaming prompt method that yields events. The following examples show the same logic in TypeScript and Python.

TypeScript

Python

Intercept behavior with hooks

In addition to observing events, you can register SDK hooks that run before or after specific events and optionally veto the action. This is useful for guardrails, audit logging, and custom integrations.

A hook handler returns an object. Return { allow: true } or undefined to proceed. Return { allow: false, reason: '...' } to block the action and surface a message to the model.

Event ordering guarantees

  • Events for a single turn are delivered in order.
  • tool_start always precedes tool_end for the same invocation.
  • permission_request is emitted before the action is taken. The loop waits until the SDK responds or a timeout occurs.
  • Hook events are emitted after the shell command completes.

Best practices

  • Handle events asynchronously. Do not block the event stream with network calls unless the event requires a decision, such as permission_request.
  • Persist important events outside the process. The stream ends when the session closes.
  • Use typed SDK clients when available so event fields are validated at compile time or runtime.
  • Keep hook handlers stateless. The SDK may retry a call if the CLI restarts.