Overview
Simple agents provide:- System instructions: Define the agent’s behavior and personality
- LLM integration: Use any supported LLM provider (OpenAI, Anthropic, Gemini, etc.)
- Tool support: Optional tools for function calling
- Conversation history: Optional memory across interactions
- Streaming responses: A live channel of response chunks delivered through the run handle
- Stop signal: Cancel an in-flight run cleanly via
handle.Stop, including mid-stream and mid-tool-call - Hooks: Intercept tool calls and model calls for auth, budgets, and audit
Creating a Simple Agent
To create a simple agent, usehastekit.NewAgent() with AgentConfig:
AgentConfig Fields
Executing an Agent
Execute() is non-blocking — it generates a stream id, subscribes to the broker, and returns an *AgentHandle. There are two valid ways to consume the handle:
handle.Result()— drains the chunk channel internally and returns the aggregatedAgentOutput. Use this when you only care about the final output.for chunk := range handle.Chunks+handle.Wait()— observe chunks as they arrive (e.g. to forward to a UI or SSE stream), then collect the aggregated output.
handle.Stop(ctx) at any point to stop the run — including in the middle of a streaming model call or a running tool.
AgentInput Fields
AgentHandle
Execute() returns a handle:
Stoprecords a stop request on the broker and unwinds the run — see Stopping an In-Flight Run.EnqueueMessagepushes a message onto the run’s queue. The agent drains it at iteration boundaries, so a follow-up or an approval decision reaches a run that is still in flight. For a run that has already paused and exited, the nextagent.Executeon the same thread is the right entry instead.Waitblocks until the run finishes and returns the aggregated output. Safe to call only afterChunkshas been drained.ResultdrainsChunksinternally and returns the aggregated output — equivalent tofor range Chunks {}; Wait().
AgentOutput Structure
handle.Wait() returns the aggregated AgentOutput:
Complete Example
Here’s a complete working example:Streaming Responses
Streaming is built into the handle — every run delivers chunks onhandle.Chunks as they arrive:
Stopping an In-Flight Run
handle.Stop(ctx) records a stop request on the broker. The run records a "Cancelled by user" assistant turn in history and emits run.completed cleanly — the chunk stream stays open while the agent winds down, so you’ll still see that final chunk before the channel closes.
Stop does not wait for an iteration boundary. It reaches work already in flight:
- Mid-stream — the model call is cut off where it is, rather than waited out. Text that had already streamed still reached the client, but the turn is recorded as cancelled rather than as a half-answer the model never finished. Cancelling also reaches the provider’s own request, which is what actually stops the tokens being generated and billed.
- Mid-tool-call — a running tool has its context cancelled. A tool that ignores cancellation is abandoned after a grace period (
agents.DefaultCancelGrace, 2s) so the run still ends; it keeps running in the background, unobserved.
function_call in history is answered — a cancelled call gets a synthetic result saying so — so a stopped thread is still a valid thread to resume from.
Reaching a running tool or an in-flight stream needs a broker implementing
agents.StopWatcher; the built-in memory and Redis brokers both do. With a plain broker the stop still lands, at the loop’s next iteration boundary.Single-Turn Execution
SingleTurn ends the run as soon as the model has responded, before any tool is executed. The AgentOutput carries exactly what the model emitted — assistant text and/or tool calls — with status completed.
This is for evaluating a single decision rather than an outcome: offline single-turn evals score “given this conversation, what does the model do next?”, where executing the tool (or faking its result) would replace the thing under test with an improvised continuation.
It lives on agents.AgentOptions rather than AgentConfig, so set it with an AgentOption:
Helper Functions
The SDK provides convenient helper functions for creating messages:responses.UserMessage(msg string): Creates a user message from a string
Next Steps
- Learn about system instructions for customizing agent behavior
- Add conversation history for context-aware interactions
- Integrate tools to extend agent capabilities
- Give the agent skills it reads only when it needs them
- Add hooks for auth, budgets, and audit
- Explore durable agents for production workloads