Agent
The high-level entry point for most use cases. Agent and AsyncAgent compose
a Harness, SessionCache, and optional tools from a single configuration.
Agent
data_harness.Agent
Agent(
adapter: ProviderAdapter,
system: str,
*,
max_turns: int = 25,
cache: SessionCache | None = None,
run_dir: str | Path | None = None,
)
High-level synchronous agent.
Agent composes a Harness, a SessionCache, and optional tools from a
single configuration. Each call to run builds a fresh Harness with a
fresh message history. Use session when you need multi-turn conversation
state to persist across questions.
Example::
from data_harness import Agent
from data_harness.providers.anthropic import AnthropicAdapter
agent = Agent(
adapter=AnthropicAdapter(model="claude-sonnet-4-6"),
system="You are a data analyst.",
)
print(agent.run("Compute the mean of [1, 2, 3]."))
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adapter
|
ProviderAdapter
|
Synchronous provider adapter. |
required |
system
|
str
|
System prompt passed unchanged to every |
required |
max_turns
|
int
|
Hard cap on provider turns per |
25
|
cache
|
SessionCache | None
|
Shared |
None
|
run_dir
|
str | Path | None
|
Directory for JSONL logs. Defaults to |
None
|
Source code in data_harness/agent.py
connector
Register a named connector and return a builder for attaching tools.
Connector tools start hidden; the model must call load_connectors
before it can use them (progressive disclosure).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique connector name. Used as the tool-name prefix. |
required |
description
|
str
|
Shown to the model when it lists available connectors. |
required |
Returns:
| Type | Description |
|---|---|
ConnectorBuilder
|
A |
Source code in data_harness/agent.py
enable_planner
Enable the planning tool and suffix-based nag reminders.
The planner escalates reminders at turns 4, 8, and 12 when no progress
has been recorded. Call this before run or session.
Returns:
| Type | Description |
|---|---|
Agent
|
|
Source code in data_harness/agent.py
enable_subagents
Enable the subagent tool, using adapter_factory for spawned agents.
Each spawned subagent gets a fresh adapter, fresh message history, and
fresh cache. State crosses the boundary only through explicit
input_handles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adapter_factory
|
Callable[[], ProviderAdapter]
|
Zero-argument callable that returns a fresh
|
required |
Returns:
| Type | Description |
|---|---|
Agent
|
|
Source code in data_harness/agent.py
session
Create a stateful AgentSession for multi-turn conversations.
Returns:
| Type | Description |
|---|---|
AgentSession
|
A new |
run_result
Run the agent and return the full RunResult.
Builds a fresh Harness with a fresh message history for each call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_message
|
str
|
The user prompt to send. |
required |
Returns:
| Type | Description |
|---|---|
RunResult
|
A |
Source code in data_harness/agent.py
run
Run the agent and return the final text response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_message
|
str
|
The user prompt to send. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The model's final text response. |
Raises:
| Type | Description |
|---|---|
MaxTurnsExceeded
|
If the loop reaches |
RuntimeError
|
If the provider raises an exception. |
Source code in data_harness/agent.py
explain
Return a string showing the equivalent explicit Harness wiring.
Source code in data_harness/agent.py
AgentSession
data_harness.AgentSession
Stateful chat session built from an Agent definition.
Agent.run() intentionally stays one-shot for examples and tests. Use
Agent.session() when an application needs follow-up questions over the
same message history and cache handles.
Source code in data_harness/agent.py
put
Store a value in the session cache and return the handle used.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Desired handle name. Must be a valid Python identifier. |
required |
value
|
Any
|
Any Python object to store. |
required |
overwrite
|
bool
|
Replace the existing handle if |
False
|
Returns:
| Type | Description |
|---|---|
str
|
The handle name under which the value was stored. |
Source code in data_harness/agent.py
list_handles
ask_result
Send a follow-up message and return the full RunResult.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_message
|
str
|
The follow-up user prompt. |
required |
Returns:
| Type | Description |
|---|---|
RunResult
|
A |
Source code in data_harness/agent.py
ask
Send a follow-up message and return the final text response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_message
|
str
|
The follow-up user prompt. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The model's final text response. |
Raises:
| Type | Description |
|---|---|
MaxTurnsExceeded
|
If the loop reaches |
RuntimeError
|
If the provider raises an exception. |
Source code in data_harness/agent.py
AsyncAgent
data_harness.AsyncAgent
AsyncAgent(
adapter: AsyncProviderAdapter,
system: str,
*,
max_turns: int = 25,
cache: SessionCache | None = None,
run_dir: str | Path | None = None,
)
Async agent for use with AsyncProviderAdapter.
run() and run_result() are coroutines. run_stream() is an async
generator that yields text tokens as they arrive from the provider.
Use async_session() for multi-turn streaming conversations.
Source code in data_harness/agent.py
run_stream
async
Stream events for a one-shot run.
Yields StreamEvent objects (message_start, content_block_*, message_delta, message_stop, tool_result) following the Claude Agent SDK protocol.
Usage::
async for event in agent.run_stream("hello"):
if event.type == "content_block_delta":
from data_harness.streaming import TextDelta
if isinstance(event.delta, TextDelta):
print(event.delta.text, end="", flush=True)
Source code in data_harness/agent.py
AsyncAgentSession
data_harness.AsyncAgentSession
Stateful async chat session built from an AsyncAgent definition.
Source code in data_harness/agent.py
ask_stream
async
Stream events for a follow-up turn.
Source code in data_harness/agent.py
RunResult
data_harness.RunResult
dataclass
RunResult(
text: str,
status: Literal[
"success", "max_turns_exceeded", "error"
],
turns: int,
run_file: str | None,
stop_reason: StopReason | None,
usage: Usage,
cache_snapshots: dict[str, str] = dict(),
cache_storage: dict[str, CacheStorageInfo] = dict(),
error: str | None = None,
run_id: str | None = None,
session_id: str | None = None,
)
The complete outcome of a single Harness.run() or Agent.run() call.
Attributes:
| Name | Type | Description |
|---|---|---|
text |
str
|
The final text response from the model. |
status |
Literal['success', 'max_turns_exceeded', 'error']
|
|
turns |
int
|
Number of provider turns executed. |
run_file |
str | None
|
Path to the JSONL log for this run, or |
stop_reason |
StopReason | None
|
Provider stop reason from the final turn, or |
usage |
Usage
|
Cumulative token counts across all turns. |
cache_snapshots |
dict[str, str]
|
Mapping of handle name → compact snapshot string for every value in the session cache at the end of the run. |
cache_storage |
dict[str, CacheStorageInfo]
|
Mapping of handle name → |
error |
str | None
|
Exception repr when |
run_id |
str | None
|
Optional UUID assigned by |
session_id |
str | None
|
Optional session UUID when the run is part of an
|
Usage
data_harness.Usage
dataclass
Usage(
input_tokens: int = 0,
output_tokens: int = 0,
cache_read_tokens: int = 0,
cache_write_tokens: int = 0,
)
Accumulated token counts for a run or session turn.
Attributes:
| Name | Type | Description |
|---|---|---|
input_tokens |
int
|
Tokens in the prompt sent to the provider. |
output_tokens |
int
|
Tokens in the provider's response. |
cache_read_tokens |
int
|
Prompt tokens served from the provider's KV cache. |
cache_write_tokens |
int
|
Prompt tokens written to the provider's KV cache. |
CacheStorageInfo
data_harness.CacheStorageInfo
dataclass
Where a named handle is physically stored in the SessionCache.
Attributes:
| Name | Type | Description |
|---|---|---|
location |
Literal['memory', 'disk']
|
Either |
storage_type |
str
|
Format used on disk, e.g. |