Benchmark results
Three runs per hrns on a benchmark task using GPT-6-Luna with medium reasoning.
| hrns | Tests pass | All quality gates pass | Model responses | Tool calls | Total cost | Average/run |
|---|---|---|---|---|---|---|
| Codex | 3/3 | 3/3 | 44 | 56 | $0.03658 | $0.01219 |
| OpenCode | 3/3 | 2/3 | 43 | 47 | $0.03578 | $0.01193 |
| hrns | 3/3 | 3/3 | 44 | 59 | $0.03300 | $0.01100 |
All runs pass 130/130 tests. Quality gates cover Ruff lint, Ruff formatting, and Pyrefly type checking.
Counts and costs are totals across three runs. Model responses include tool-only responses and final answers. Tool calls count underlying attempts, including failures; Codex's 41 orchestration calls contain 56 underlying attempts. Costs are cache-aware API equivalents in USD using common Standard model pricing.
Skill loads: Codex 0/3, OpenCode 1/3, hrns 3/3. The loaded skill is
incremental-implementation, with relevant selection and partial adherence.
hrns
Define an agent once. Run it in Python, open it in a terminal, or host it remotely.
hrns combines native Pydantic AI capabilities with policy-controlled sessions, an independent ACP terminal, and authenticated remote hosting. Agent behavior stays in ordinary Python; the terminal can also connect to standard ACP agents that do not use this runtime.
Start developing
Requires Python 3.11+, macOS or Linux, uv, and just.
just install
just check
The checked-in lockfile pins the tested upstream versions. just install also
installs the prek Git hook, which runs just check before
each commit without applying automatic fixes. To install the hook after a manual
dependency sync, run uv run prek install.
Use a local agent with your model
The local developer agent is the default connection mode. The base install ships the
terminal, the runtime, and the OpenAI-compatible providers (DeepSeek, OpenAI, and local
servers); add the anthropic extra for Anthropic models. Set the API key for the provider
you use:
export DEEPSEEK_API_KEY='your-key'
uvx hrns
From a checkout, run uv sync --locked and then uv run hrns instead.
Press l to configure providers, type /providers or /models in a session, or create
hrns.local.toml in the project:
provider = "deepseek"
model = "deepseek-chat"
[providers.deepseek]
api_key_env = "DEEPSEEK_API_KEY"
The top level picks the active provider entry and model; each [providers.<name>] entry
owns its endpoint and key, so several providers (even two endpoints of one provider type)
stay configured side by side.
uv run hrns starts a session in the current directory using that model. Run the same
command from an installed copy (uvx hrns or hrns). The bundled
hrns.coder capability gives it file tools, content search, and a shell in that
directory: reads are automatic, while writes, edits, and commands ask for approval first.
hrns.ask_user lets the model ask structured multiple-choice questions in the terminal;
disable it with [capabilities] ask_user = false for headless runs. hrns.todo gives
the model a session-scoped plan and shows it in the Todos tab of the right drawer.
A second family of tools can run in the terminal instead of on the host: /settings →
Client-side tools (or --client-io all) lets the agent use this client's files and
terminal, and the client.terminal binding routes its commands there.
Configuration uses pydantic-settings. Providers that authenticate with an account
rather than a key work too: hrns login github-copilot runs GitHub's device flow, or
press Ctrl+G in the provider form. See
local setup for OpenAI-compatible endpoints, local inference, other
Pydantic AI providers, and headless execution.
Useful slash commands include /connect (switch or add a target), /providers (add, edit
or delete local providers), /models (select a model across providers, or add a custom
model id), /effort (change reasoning effort live),
/plugins (toggle, configure, or add plugins), /mcp (list MCP servers and their
tools), /skills (browse Agent Skills), and /todo (open the session's plan).
Typing / shows an inline filtered list. Type $ in the composer to find a skill and
insert a $skill-name reference, which runs that skill for the message. The older
/model and /capabilities names remain aliases.
Any independent ACP agent can still be launched explicitly:
uv run hrns connect --stdio -- /path/to/agent --acp
See client usage for headless execution, profiles, approvals and the bridge.
Serve agents in your FastAPI app
from fastapi import FastAPI
from hrns.runtime import SQLiteSessionStore
from hrns.server import AgentServer
app = FastAPI()
agents = AgentServer(store=SQLiteSessionStore("./sessions.sqlite3"))
agents.add_agent(definition)
agents.mount(app)
Optional aggregate runtime telemetry
An embedding can receive safe, aggregate runtime events without adding a Logfire or
OpenTelemetry dependency. Implement RuntimeTelemetry.emit(event) and pass it to
AgentServer(..., telemetry=observer) (or directly to HrnsACPAgent(..., telemetry=observer)). Events contain only lifecycle/transition enums plus connection
counts, queue depth, and oldest queued age; they never contain prompts, errors, URLs,
credentials, or principal/session/key identifiers. Observer failures are logged and
ignored by the runtime.
add_agent binds and validates the definition's resource requirements at registration; pass
resources=, or a definition.bind(...) result, when a capability needs host values.
Install the server extra, register your AgentDefinition objects, and run the app
with Uvicorn. Connect using hrns connect --url http://127.0.0.1:8080 --agent AGENT_ID.
PostgreSQL and optional FastAPI authentication dependencies use the same API.
See server embedding and the runnable example.
Layout
hrns is one distribution. The terminal, the runtime and the OpenAI-compatible providers ship by default; FastAPI hosting, Anthropic models and PostgreSQL are extras.
| Module | Extra | Purpose |
|---|---|---|
hrns.protocol |
base | Versioned extension schemas and transport contracts |
hrns.config |
base | Shared local settings using pydantic-settings |
hrns.runtime |
base | Native agent definitions, plugin management, sessions, hrns-host and hrns-local |
hrns.client |
base | Cyclopts CLI, Textual terminal, scripted ACP runner and stdio bridge |
hrns.server |
server |
FastAPI agent registration and in-process WebSocket ACP |
Install only what you need, for example pip install 'hrns[server]',
pip install 'hrns[anthropic]', or pip install 'hrns[all]'.
The hrns.client module does not import Pydantic AI or installed agent
plugins. Local stdio agents run in a separate process. Network agents run inside an existing
FastAPI application through AgentServer, sharing an explicit SQLite or PostgreSQL store.
Design essentials
- Upstream ACP execution:
PydanticAIACPAgentowns prompts, streaming, approvals, cancellation, history, and transcript replay. - Native composition: managed bindings contribute their complete Pydantic AI behavior—tools, instructions, hooks and settings—and are selected when a session is composed.
- Live model and effort: both use standard ACP configuration options and apply from the next request.
- Host-owned state: sessions pin their principal/deployment scope, retain history and metadata, and never silently retry an uncertain prompt.
- Explicit resources: workspace and provider bindings belong to the host. A local workspace is a path, not a sandbox.
- Standard ACP first: generic streaming content, tools and approvals work without project-specific extensions.
Checks and distribution builds
just check
just lint
just build
just fix
just check runs the checks and builds the package. just lint runs formatting,
lint, and type checks; just build builds the package. just fix applies automatic
formatting and lint fixes. CI exercises the same non-mutating checks on
macOS/Linux and Python 3.11–3.15. A wheel and source distribution are written to dist/; optional dependencies are declared as extras.
External provider, sandbox and durability integrations need their upstream extras and credentials. See the coverage matrix for managed, locally verified and deployment-only distinctions.
Releasing
The version comes from the git tag via hatch-vcs, so there is no version string to
edit. Publishing runs on release: create a GitHub release and
.github/workflows/publish.yml builds the distribution, runs just check, verifies
the tag, and uploads to PyPI.
git tag 0.1.0
git push origin 0.1.0
gh release create 0.1.0 --generate-notes
The tag must match the version hatch-vcs derives, so 0.1.0 publishes 0.1.0. A
mismatched tag fails the build instead of uploading an unintended version, and a
version that already exists on PyPI is rejected.
Uploads use PyPI Trusted Publishing, so no API token is stored in the repository.
Before the first release, configure a publisher on PyPI for the hrns project with
this repository's owner and name, workflow publish.yml, and environment pypi.
Because hrns does not exist on PyPI yet, use the pending publisher form.
License
MIT. See LICENSE.
Metadata
Release files for hrns 0.0.17
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| hrns-0.0.17.tar.gz | 406.7 kB | With provenance | Details for hrns-0.0.17.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| hrns-0.0.17-py3-none-any.whl | Python 3 | none | any | Details for hrns-0.0.17-py3-none-any.whl |
Total release size: 904.5 kB
Release files / hrns-0.0.17.tar.gz
| Download URL | hrns-0.0.17.tar.gz |
|---|---|
| Size | 406.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d98e431c4f00f988f947f0a1368512185e7c1726400f10193777a1fc85c3db32
|
|
BLAKE2b-256 checksum How to use checksums |
054fd2b53e3d142edfd1af9c8dc9916c5665767bc858f6c502f3b2dba57f01b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.
Transparency logRelease files / hrns-0.0.17-py3-none-any.whl
| Download URL | hrns-0.0.17-py3-none-any.whl |
|---|---|
| Size | 497.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
def926c0db48e0b5d3436fda943ba94526ba32008817cf1e8f8eba08d067f6cb
|
|
BLAKE2b-256 checksum How to use checksums |
0178bd396349ffc290bee1aab3e2e6974585ed2bd387d3602afebb632d11f0b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.
Transparency logSecurity for hrns 0.0.17
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for hrns-0.0.17.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.