Agent class is the core primitive of OpenHarness. An agent wraps a language model, a set of tools, and a multi-step execution loop into a stateless executor that you can run() with a message history and new input.
Creating an Agent
Running an Agent
agent.run() is an async generator that takes a message history and new input, and yields a stream of typed events as the agent works. The agent is stateless — it doesn’t accumulate messages internally. You pass the conversation history in and get the updated history back in the done event.
done event into the next run() call. It also means you have full control over the conversation history: you can inspect it, modify it, or share it between agents.
Events
The full set of events emitted byrun():
| Event | Description |
|---|---|
text.delta | Streamed text chunk from the model |
text.done | Full text for the current step is complete |
reasoning.delta | Streamed reasoning/thinking chunk (if the model supports it) |
reasoning.done | Full reasoning text for the step is complete |
tool.start | A tool call has been initiated |
tool.done | A tool call completed successfully |
tool.error | A tool call failed |
step.start | A new agentic step is starting |
step.done | A step completed (includes token usage and finish reason) |
error | An error occurred during execution |
done | The agent has finished — result is one of "complete", "stopped", "max_steps", or "error" |
Configuration
| Option | Default | Description |
|---|---|---|
name | (required) | Agent name, used in logging and subagent selection |
model | (required) | Any Vercel AI SDK LanguageModel |
systemPrompt | — | System prompt prepended to every request |
tools | — | AI SDK ToolSet — the tools the agent can call |
maxSteps | 100 | Maximum agentic steps before stopping |
temperature | — | Sampling temperature |
maxTokens | — | Max output tokens per step |
instructions | true | Whether to load AGENTS.md / CLAUDE.md from the project directory |
approve | — | Callback for tool call approval |
subagents | — | Child agents available via the task tool (see Subagents) |
maxSubagentDepth | 1 | Maximum nesting depth for subagents |
subagentBackground | — | Enable background subagent execution |
mcpServers | — | MCP servers to connect to |
skills | — | Skills configuration |
Multi-Turn Conversations
Since the agent is stateless, multi-turn is achieved by passing the updated messages back in:Cleanup
If the agent uses MCP servers or background subagents, callclose() when done: