loadn
English | 简体中文
As heaven moves with vigor — OldMan; as earth lies receptive — LoadN.
Naming. loadn (read load-n) is the engine package of the loadn-ai platform. Product forms:
loadnengine /loadn-webplatform /loadn desktop.
Introduction
loadn is a self-contained coding-agent engine written in pure Python, grown
into a self-hostable agent platform. One pip install plus any
Anthropic-form or OpenAI-compatible endpoint yields a headless agent with
built-in tools, MCP support, subagents, session persistence, and context
compaction. The CLI speaks the Claude Code stream-json dialect, so
harnesses built for the Claude CLI can drive loadn as a drop-in subprocess
engine.
The same repository also hosts the platform around the engine: loadn-web,
a multi-session web application providing digital-employee organization, a
resource hub, a seven-layer execution-security stack, scheduling, cost
accounting, and a tamper-evident audit ledger.
Status. v0.7.x (beta), actively maintained. The CLI argv contract, the
stream-json dialect, and configuration keys follow Semantic Versioning;
breaking changes are announced in CHANGELOG.md with every
minor release.
Repository layout
| Path | Contents | How to start |
|---|---|---|
loadn/ |
The agent engine (main subject of this document) | pip install loadn |
loadn_webui/ |
Web platform: sessions, organization, resource hub, security, scheduling, cost accounting | pip install -e ".[webui]" → loadn-web init → loadn-web serve |
desktop/ |
Desktop distribution: Tauri shell with a Debian rootfs; the whole execution domain runs inside a Linux VM on macOS and Windows | desktop/image/ build pipeline |
ui/ |
React frontend for the administration center (security, resource, and organization panels) | cd ui && npm run build |
Architecture
flowchart TB
subgraph HOSTS["CLI · library · daemon"]
HEAD["headless -p<br/>(stream-json NDJSON)"]
REPL["REPL"]
DAEMON["daemon (UDS attach)"]
LIB["python library<br/>build_agent()"]
end
subgraph CORE["AgentCore"]
ASM["ContextAssembler"] --> LOOP["agent loop"]
LOOP --> PERM["PermissionEngine"]
LOOP --> HOOKS["Hooks"]
LOOP --> GUARD["LoopGuard"]
LOOP --> COMP["Compactor (92% window)"]
LOOP --> SUB["SubagentManager"]
LOOP --> EVT["stream-event synth<br/>(--verbose deltas)"]
end
subgraph TOOLS["Tools — built-in set + MCP dynamic"]
BASH["Bash / Read / Write<br/>Edit / MultiEdit / Grep / Glob"]
SHELL["InteractiveShell (pty) · Task · Skill<br/>WebFetch · WebSearch · TodoWrite"]
MCP["mcp__server__tool"]
end
subgraph PROV["Providers"]
ANT["Anthropic-form SSE"]
OAI["OpenAI-compatible"]
end
PERSIST[("transcript JSONL (append-only)<br/>+ SQLite index")]
HOSTS --> CORE
CORE <-- "tool calls" --> TOOLS
CORE <-- "chat chunks" --> PROV
CORE --> PERSIST
Features
Agent runtime
- Agent loop with a permission engine, hooks, and a two-tier loop guard that interrupts repeated identical tool calls (soft reminder, then hard break).
- Context compaction at a 92% window that preserves tool-call pairing; stream interruptions and retriable provider errors are retried inside the loop, so a turn never ends with a bogus success.
- Session persistence: append-only JSONL transcripts with a SQLite index; replay resumes from the last compaction point.
loadn daemonkeeps AgentCore alive across disconnects (UDS attach), so cache warmth and context survive UI reconnects.- Long-running work: foreground commands exceeding 60 s are adopted into a
background task table automatically (the agent keeps working and reads
the log later); interactive programs (REPLs, install wizards) get a
pty-backed
InteractiveShelltool that scripts multi-round send/expect exchanges in a single call.
Tools and extensibility
- Built-in toolset: file editing (Read / Write / Edit / MultiEdit), search (Grep / Glob), shell (Bash, InteractiveShell), delegation (Task), on-demand knowledge (Skill), web (WebFetch / WebSearch), and task tracking (TodoWrite).
- MCP servers declared in
.mcp.json(stdio and streamable HTTP with OAuth); their tools appear asmcp__<server>__<tool>. - Skills follow the agentskills.io
SKILL.mdstandard; third-party installs pass a supply-chain lock, and any skill exports as a compatible zip. - Custom subagents defined as markdown files with
name/description/tools/modelfrontmatter, usable throughTask(subagent_type=...).
Provider-agnostic model layer
Any Anthropic-form SSE endpoint (Z.AI GLM, Anthropic proper) and any OpenAI-compatible endpoint (DeepSeek, vLLM, LiteLLM, and others). Thinking/reasoning content and tool-call syntax are translated in a single adapter layer.
Claude Code stream-json compatibility
- The argv contract and event stream are deliberately isomorphic to Claude
Code's headless mode (
-p --verbose --output-format stream-json, prompt asargv[-1],--session-id/--resume, andsystem/assistant/user/resultevents). - The final
resultevent carries snake_caseusageplus camelCase per-modelmodelUsage, ready for cost dashboards. - During long tool runs the CLI emits a
system/heartbeatline every 30 s, so parent-process stall detectors do not kill healthy work. - The live session lock reproduces the
Session ID already in useerror (stderr, exit 1) that supervisors match on.
Context engineering
The system prompt assembles from a CLAUDE.md / AGENTS.md ancestor chain
(git-root bounded, nearest last, @import support), a skills index,
long-term memory with boundary-driven background extraction, and a
repository map — mirroring Claude Code's layered memory.
Cost discipline
Three prompt-cache breakpoints (tools tail / system / last message) with a no-cache lane for auxiliary calls; a handoff-style compactor that prunes before summarizing (file ledger and UPDATE mode); a completion gate for grind mode (verbal-delivery interception plus artifact existence checks); last-call usage accounting; and context-overflow self-rescue via forced compaction.
Platform (loadn-web)
- Multi-session workbench: live agent process with thinking cards, tool cards, subagent dispatch, steering notes, and queued messages. Reloaded sessions replay byte-identically with the live stream.
- Digital employees: department trees and named employees, each an agent
definition (persona, skills, duty) hot-injected into the subagent
registry. Dispatch is by name —
Task(subagent_type="xiaoming")routes work with that employee's persona and skill set; a temporary-worker pool absorbs burst work. - Skills library: local and marketplace skills with source badges and lifecycle states; a suggestion loop turns your corrections into persistent, reviewable skills.
- Resource Hub: every resource is a
Resource.mdwith two-way editing between a structured form and markdown source; credentials bind from the encrypted vault by reference and inject into the task environment asLOADN_SVC_*variables, with a preview of exactly what the agent will see. - Scheduling, cost accounting, and a hash-chained audit ledger with daily external anchors.
Screenshots: organization console (docs/assets/org-page.png), skills
library (docs/assets/skills-page.png), resource hub
(docs/assets/resource-hub.png), resource drawer with injection preview
(docs/assets/resource-drawer.png).
Execution security
Security is treated as four multiplied terms: sandbox, control points, vault, and audit. No LLM sits on the enforcement path; every layer is deterministic and fail-closed.
flowchart LR
CALL["agent tool call"] --> L1["L1<br/>credential<br/>vault"] --> L2["L2<br/>bash-AST<br/>policy"] --> L3["L3<br/>egress allowlist<br/>proxy"] --> L4["L4<br/>filesystem<br/>sandbox"] --> L5["L5<br/>irreversible-action<br/>approval gate"] --> L6["L6<br/>canary +<br/>audit chain"] --> L7["L7<br/>supply-chain<br/>trust gate"] --> EXEC["exec"]
style CALL fill:#F8FAFC,stroke:#94A3B8
style EXEC fill:#FEF3C7,stroke:#F59E0B
| Layer | Term | Mechanism | Source |
|---|---|---|---|
| L1 | Vault | AES-GCM encryption; plaintext never enters the agent environment | loadn_webui/security/vault.py |
| L2 | Control point | Bash AST policy: red lines plus token-coverage rules, out-of-process PreToolUse | loadn_webui/security/policy.py |
| L3 | Control point | Egress allowlist proxy; CONNECT allowlist, DNS-rebinding and private-net rejection | loadn_webui/security/egress_proxy.py |
| L4 | Sandbox | bwrap same-path binds; network namespace with the proxy socket as sole egress | loadn_webui/security/sandbox.py |
| L5 | Control point | Irreversible-action approval gate: one-time codes bound to parameter hashes | loadn_webui/security/approve.py |
| L6 | Audit | Canary trips plus hash-chained ledger with daily anchors | loadn_webui/security/canary.py · audit.py |
| L7 | Control point | Supply-chain trust gate: skill sha256 locks, eight-class static scans | loadn_webui/security/skill_scan.py |
Quality
- 1600+ tests with zero API calls (fake-provider driven) at 83% line coverage.
- Mutation testing: 4055 injected bugs across 47 core files with a 78% kill rate, plus a weekly mutation gate in CI. See tests/TEST-PLAN.md §7.
Installation and quick start
Requirements
Python 3.10 or later. The engine has a single runtime dependency
(httpx); optional extras add capabilities:
| Extra | Provides |
|---|---|
ast |
Bash AST parsing for permission policies (bashlex) |
repomap |
Symbol extraction for repository maps (tree-sitter) |
tui |
Full-screen terminal UI (textual); the basic REPL is used without it |
dev |
Test and lint toolchain (pytest, ruff, playwright) |
webui |
loadn-web platform dependencies (FastAPI, cryptography, and others) |
TUI note: verified on Python 3.10/3.11. On Python 3.12 under a pseudo-terminal (pexpect,
script(1), some CI runners), textual 8.x may not deliver key events to input fields — the plain REPL (LOADN_NO_TUI=1, or simply notuiextra installed) is unaffected.
Install the engine
Requires Python ≥ 3.10. Three common pitfalls: bare Ubuntu servers and
containers (24.04+) ship without Python — run sudo apt-get update && sudo apt-get install -y python3 python3-venv first; on Debian 12+/
Ubuntu 23.04+ system Python, pip refuses system-wide installs
(externally-managed-environment); and an interpreter older than 3.10
resolves no versions at all (No matching distribution found). For the
latter two, install into a virtual environment:
python3 -m venv ~/.venvs/loadn
source ~/.venvs/loadn/bin/activate
pip install loadn
# or from source:
pip install git+https://github.com/loadn-ai/loadn
Configure an endpoint
No configuration file is required; endpoints resolve in the following order:
$LOADN_HOME/config.json— user overrides (LOADN_HOMEdefaults to~/.loadn)- Environment variables:
ANTHROPIC_BASE_URL,ANTHROPIC_AUTH_TOKEN,LOADN_MODEL, andLOADN_PROVIDER(anthropic|openai|fake) - The
envblock of~/.claude/settings.json, if present — installations that already run the Claude CLI against a gateway are reused as-is
On first run without a configured endpoint, the CLI enters an onboarding
wizard on an interactive terminal (bare loadn REPL or loadn setup;
preset endpoint menu, masked API-key entry) and writes the result to
$LOADN_HOME/config.json. Headless (-p) and non-tty stdin never enter
the wizard — the CLI fails fast (exit 2) with environment-variable and
config-file hints (loadn setup < /dev/null likewise aborts cleanly
instead of looping). The fake provider used by tests and playback never
triggers it.
First run
# one-shot, human-readable output
loadn -p --dangerously-skip-permissions "read ./note.txt and summarize it"
# headless event stream (Claude Code stream-json dialect)
loadn -p --verbose --output-format stream-json \
--session-id 11111111-2222-3333-4444-555555555555 "fix the failing test"
# continue a session / structured result only / interactive REPL
loadn -p --resume 11111111-2222-3333-4444-555555555555 "continue"
loadn -p --output-format json "list the todos"
loadn # REPL: /help /resume /fork /compact /todos
Development setup
pip install -e ".[dev]"
pytest # 1600+ tests, zero API calls
ruff check .
The fake provider (LOADN_PROVIDER=fake) replays control files from
$LOADN_FAKE_DIR — the same protocol used by the end-to-end CLI tests.
Beyond pytest, ten eval scenarios gate releases nightly, and
scripts/mutate.py measures whether tests actually kill injected bugs.
Contribution rules for new guard logic and the mutation TARGET_TESTS map
are described in CONTRIBUTING.md.
Usage examples
Event stream shape
NDJSON on stdout, one JSON object per line:
{"type":"system","subtype":"init","session_id":"…","model":"…","tools":[…]}
{"type":"stream_event","event":{"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Let me "}},"parent_tool_use_id":null}
{"type":"assistant","message":{"id":"msg_…","role":"assistant","content":[{"type":"tool_use","id":"tu_1","name":"Bash","input":{"command":"ls"}}]}}
{"type":"user","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"tu_1","content":"…","is_error":false}]}}
{"type":"result","subtype":"success","usage":{"input_tokens":…,"output_tokens":…,"cache_read_input_tokens":…,"cache_creation_input_tokens":…},"modelUsage":{…},"num_turns":2,"duration_ms":…}
stream_event lines (Anthropic SSE-shaped deltas, only with --verbose)
are best-effort transport for live rendering; the assembled assistant
event is always the source of truth. Exit codes: 0 for success, 1 for
any error_* outcome.
As a Python library
import asyncio
from pathlib import Path
from loadn.core.build import build_agent
async def main():
bundle = await build_agent(Path.cwd()) # provider/tools/session wired
summary = await bundle.core.run_turn("find TODOs and write them to notes/")
print(summary.text, summary.usage, summary.model_usage)
asyncio.run(main())
AgentCore is also constructible piecewise (custom tool registry,
permission mode, hooks, compactor off, and so on) — see
loadn/core/build.py.
Embedding into an existing harness
Because the CLI mirrors Claude Code's headless contract, any supervisor
that spawns claude -p --output-format stream-json can spawn loadn
instead:
- fresh sessions:
--session-id <uuid>; continuations:--resume <uuid>;--forkcopies a resumed session to a new id - concurrent reuse of a live session is rejected with the same wording
(
Session ID already in use, stderr, exit 1) - accounting: the final
resultevent carriesusageand per-modelmodelUsagefor cost dashboards - per-session transcripts live under
$LOADN_HOME/sessions/<sid>/(append-only JSONL; replay resumes from the last compaction point) - long-lived hosting:
loadn daemonkeeps AgentCore alive across disconnects (UDS attach)
Deploying the platform
# PyPI package (API-first — the wheel ships no frontend assets)
pip install "loadn[webui]"
loadn-web init # data root + config.yaml template + access token
loadn-web token show # read the token (auto-generated, 14-day grace)
loadn-web serve # http://127.0.0.1:8792 — api-only build;
# interactive API docs at /docs
# From source (full web UI)
git clone https://github.com/loadn-ai/loadn && cd loadn
pip install -e ".[webui]"
(cd ui && npm ci && npm run build) # builds ui/dist (served at /)
loadn-web init --model <model> --base-url <url> --api-key <key>
loadn-web serve # loadn-web doctor runs a self-check
The administration center (security, resource, and organization panels) is
the React frontend under ui/. Desktop distribution builds are produced
by the desktop/image/ pipeline.
Configuration
| Item | Location |
|---|---|
| Engine thresholds, budgets, and limits | loadn/constants.py |
| Permission rules | .loadn/settings.json in the project (deny/allow, Bash:git push* patterns; the legacy .agent/ path is still honored); modes: default / acceptEdits / plan / bypassPermissions |
| Hooks (Pre/PostToolUse, Stop, Session*) | hooks key of .loadn/settings.json — external commands, stdin JSON, exit code 2 blocks |
| MCP servers | .mcp.json in the project (stdio and streamable HTTP with OAuth) |
| Skills | .agents/skills/ (agentskills.io standard, highest priority) / .claude/skills/ / .loadn/skills/ / $LOADN_HOME/skills — indexed in the system prompt, body loaded on demand via the Skill tool |
| Custom subagents | .claude/agents/*.md / $LOADN_HOME/agents — frontmatter name/description/tools/model; platform employees are hot-injected here |
| Constitution chain | CLAUDE.md / AGENTS.md from the git root down to cwd, nearest last; @./file.md line imports; user-level $LOADN_HOME/AGENT.md on top |
| Platform configuration (50+ keys) | config.yaml at the data root, generated by loadn-web init (template: config.yaml.example); every key documented in docs/CONFIG.md |
| Thinking budget | LOADN_THINKING_BUDGET env or extra.thinking_budget (Anthropic-form thinking.budget_tokens; off by default) |
| Prompt caching | On by default (three breakpoints); extra.disable_prompt_cache disables it |
Documentation
| Document | Contents |
|---|---|
| docs/ARCHITECTURE.md | Planes, data layout, test system |
| docs/CONFIG.md | Every configuration key |
| docs/EXTENDING.md | Customization seams: engines, providers, skills, MCP, hooks |
| docs/PROTOCOL.md | Engine event-dialect contract |
| docs/RELEASE.md | Deployment, upgrade, rollback |
| docs/ATTACK_SURFACE.md | Attack surface and AI-BOM |
| docs/compat.md | Compatibility notes |
| docs/adr/ | Architecture decision records |
| CHANGELOG.md | Release history |
| ROADMAP.md | Roadmap and pending milestones |
| CONTRIBUTING.md | Repository layout, one-file tool/provider recipes, assertion-strength rules |
| SECURITY.md | Security policy |
| CODE_OF_CONDUCT.md | Code of conduct |
| tests/TEST-PLAN.md | Test plan, including the mutation-testing methodology |
| CITATION.cff | Citation metadata |
FAQ
Which models and providers are supported?
The model layer is provider-agnostic: any Anthropic-form SSE endpoint (for
example Z.AI GLM or Anthropic) and any OpenAI-compatible endpoint
(DeepSeek, vLLM, LiteLLM, and others). Select with LOADN_PROVIDER and
point ANTHROPIC_BASE_URL at the gateway.
Does the CLI require configuration before first use?
No. Endpoint resolution follows the order listed under
Installation; an unconfigured first run
enters the interactive onboarding wizard and writes
$LOADN_HOME/config.json. The fake provider never triggers it.
Where are sessions stored?
Under $LOADN_HOME/sessions/<session-id>/ (default ~/.loadn):
append-only JSONL transcripts plus a SQLite index. Replay resumes from the
last compaction point.
Can loadn replace claude -p in an existing supervisor?
Yes. The argv contract and event stream are deliberately isomorphic, and
the live session lock reproduces the Session ID already in use error
(stderr, exit 1) that supervisors match on.
How do I disable permission prompts in CI?
Use --dangerously-skip-permissions (alias --yolo) or
--permission-mode bypassPermissions. For interactive use, prefer scoped
deny/allow rules in .loadn/settings.json.
What do the exit codes mean?
0 for success; 1 for any error_* result.
Do the tests call paid APIs? No. All 1600+ tests run against the fake provider with zero API calls.
How are the engine, platform, and desktop related?
One monorepo, three product forms: the loadn engine, the loadn-web
platform (CLI entry point loadn-web; wd is a deprecated alias), and
the desktop distribution built from desktop/.
How do I add a tool, a provider, or a skill? See docs/EXTENDING.md and CONTRIBUTING.md; most extensions are a single file.
Is there a desktop application?
Yes, desktop/ contains the Tauri-based distribution (the execution
domain runs inside a Linux VM on macOS and Windows); real-device
validation is in progress.
License
Apache-2.0 — see LICENSE.
Metadata
Release files for loadn 0.7.40
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 | |
|---|---|---|---|---|
| loadn-0.7.40.tar.gz | 1.4 MB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| loadn-0.7.40-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.4 MB
Release files / loadn-0.7.40.tar.gz
| Download URL | loadn-0.7.40.tar.gz |
|---|---|
| Size | 1.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8da3b1aa4506b6a90a89d50aa3544d9753230f87a584fa3ce3246f1ed9741549
|
|
BLAKE2b-256 checksum How to use checksums |
b3a65d53a20925d86cd9c37518fac9b45d1e01cb3b586b6a5bd7a3222b3c3499
|
| 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 Oct 21, 2026.
Transparency logRelease files / loadn-0.7.40-py3-none-any.whl
| Download URL | loadn-0.7.40-py3-none-any.whl |
|---|---|
| Size | 1.1 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f08f0fa6e1af5cab980181d77c7ac9a9df1dcb7e782776fa054c6bbfc6ac747d
|
|
BLAKE2b-256 checksum How to use checksums |
0ee857be7617762c2d6f8a2eb98457f5ea39838635c1a246ac8727cb06f530cb
|
| 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 Oct 21, 2026.
Transparency logSecurity for loadn 0.7.40
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 loadn-0.7.40.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 Oct 21, 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.