SDK

Overview

The mental model behind the SDK, the objects you'll use, and how Python and TypeScript map to each other.

The core objects

The SDK is small on purpose. Almost everything starts from one client:

  • Harnext — the agent client. Holds a provider, model, working directory, tools, and permission policy. Call run() or stream().
  • RunResult — the outcome of a run: final text, ordered tool steps, token usage, changed files, and the session id.
  • Session — a persisted, replayable transcript of a run. List, load, resume, export.
  • tool() — wrap any function as a typed tool the agent can call.
  • Harness and Runner — generate the GitHub Actions pipeline and manage a self-hosted runner from code.

The agent loop

When you call run(), the client starts a loop: the model receives your prompt and the available tool schemas, decides whether to respond or call a tool, the SDK executes the tool against cwd, feeds the result back, and repeats. The loop ends when the model returns a final answer with no tool call, or when max_turns is reached. stream() surfaces every step of that loop as it happens.

from harnext import Harnext

agent = Harnext(
    provider="anthropic",
    model="claude-opus-4-8",
    cwd=".",
    tools=["read", "write", "edit", "bash"],
    permission_mode="auto",
    max_turns=40,
)

result = agent.run("Fix the failing test in tests/test_users.py")
for step in result.steps:
    print(step.tool, step.status)

Python ↔ TypeScript

The two SDKs are intentionally symmetric. The only routine differences:

  • Naming: Python is snake_case, TypeScript is camelCase (e.g. max_turns maxTurns, files_changed filesChanged).
  • Async: every TypeScript method returns a Promise. Python methods are synchronous by default, with a-prefixed async variants (arun, astream) for asyncio.
  • Streaming: Python yields from a generator; TypeScript exposes an AsyncIterable you consume with for await … of.
Async in Python
Use await agent.arun(...) and async for event in agent.astream(...) inside an asyncio event loop. The synchronous methods are thin wrappers around these.

Where to go next