Skip to main content

Crate localharness

Crate localharness 

Source
Expand description

§localharness — agents that own themselves

One Rust crate that’s both an agent SDK — streaming text, custom tools, safety policies, background triggers, MCP, context compaction, all from a single cargo add with zero external binaries — and (on wasm32 with browser-app) the same loop compiled into a wallet-owning, self-sovereign agent that runs in the browser.

§Quick start

use localharness::{Agent, GeminiAgentConfig};

let cfg = GeminiAgentConfig::new(std::env::var("GEMINI_API_KEY").unwrap())
    .with_system_instructions("You are a concise code reviewer.");

let agent = Agent::start_gemini(cfg).await?;
let response = agent.chat("What is 2+2?").await?;
println!("{}", response.text().await?);
agent.shutdown().await?;

§Layers

LayerTypePurpose
1AgentHigh-level facade: connect, chat, shutdown.
2Conversation / ChatResponseStateful session, multi-cursor streams.
3connections::ConnectionTransport abstraction.
auxFilesystemWhat the 8 fs-shaped built-in tools call into; swap the impl to target OPFS, an in-memory FS, etc.

§Stability & MSRV

MSRV is Rust 1.85 (edition 2024); raising it is a minor-version bump. The 1.0 semver promise COVERS the agent-SDK surface: the layer seams (Agent + the *AgentConfigs, Conversation/ChatResponse/ChatCursor, connections::Connection/ConnectionStrategy); the extension traits (tools::Tool/ToolRunner, hooks, policy, triggers); the wire-neutral types (content, types, error::Error/Result, filesystem::Filesystem + the 8 fs builtins, the named builtins); and the root-re-exported backend constructors + *BackendConfig/*Connection/*ConnectionStrategy.

NOT covered (may change in any release, semver-exempt): the wallet feature — the entire registry surface is coupled to live on-chain diamond addresses + facets that churn via diamondCut, plus wallet/tempo_tx; the per-backend backends::*::{wire,api,compaction} modules; opaque history byte formats (history_bytes/set_history_bytes); the browser-app app (wasm-only, private); the local feature; and the platform compiler/runtime helpers (rustlite, soliditylite, bashlite, raster, compose). Growable public structs/enums carry #[non_exhaustive] (or grow only via ..Default::default()-friendly fields) so additive changes stay non-breaking.

Re-exports§

pub use agent::Agent;
pub use agent::AgentConfig;
pub use agent::GeminiAgentConfig;
pub use agent::MockAgentConfig;
pub use agent::AnthropicAgentConfig;
pub use agent::OpenAiAgentConfig;
pub use backends::gemini::decode_transcript_bytes;
pub use backends::gemini::GeminiBackendConfig;
pub use backends::gemini::GeminiConnection;
pub use backends::gemini::GeminiConnectionStrategy;
pub use backends::mock::MockConnection;
pub use backends::mock::MockConnectionBuilder;
pub use backends::mock::MockConnectionStrategy;
pub use backends::mock::MockRunners;
pub use backends::mock::ScriptedTurn;
pub use backends::anthropic::AnthropicBackendConfig;
pub use backends::anthropic::AnthropicConnection;
pub use backends::anthropic::AnthropicConnectionStrategy;
pub use backends::anthropic::AnthropicRunners;
pub use backends::openai::OpenAiBackendConfig;
pub use backends::openai::OpenAiConnection;
pub use backends::openai::OpenAiConnectionStrategy;
pub use backends::openai::OpenAiRunners;
pub use backends::mcp::McpBridge;
pub use backends::mcp::McpClient;
pub use backends::mcp::McpToolDecl;
pub use connections::Connection;
pub use connections::ConnectionStrategy;
pub use content::Content;
pub use content::Media;
pub use content::MediaKind;
pub use content::Part;
pub use conversation::ChatCursor;
pub use conversation::ChatResponse;
pub use conversation::Conversation;
pub use error::Error;
pub use error::Result;
pub use filesystem::DirEntry;
pub use filesystem::EntryKind;
pub use filesystem::Filesystem;
pub use filesystem::Metadata;
pub use filesystem::SharedFilesystem;
pub use filesystem::WalkEntry;
pub use filesystem::NativeFilesystem;
pub use hooks::HookContext;
pub use hooks::HookRunner;
pub use hooks::OnSessionEndHook;
pub use hooks::OnSessionStartHook;
pub use hooks::OperationContext;
pub use hooks::PostToolCallHook;
pub use hooks::PostTurnHook;
pub use hooks::PreToolCallDecideHook;
pub use hooks::PreTurnHook;
pub use hooks::SessionContext;
pub use hooks::TurnContext;
pub use policy::allow_all;
pub use policy::deny_all;
pub use policy::enforce;
pub use policy::evaluate;
pub use policy::is_path_in_workspace;
pub use policy::secure_normalize_path;
pub use policy::workspace_only;
pub use policy::AskUserHandler;
pub use policy::Decision;
pub use policy::Policy;
pub use policy::Predicate;
pub use tools::ClosureTool;
pub use tools::Tool;
pub use tools::ToolContext;
pub use tools::ToolRunner;
pub use triggers::every;
pub use triggers::Trigger;
pub use triggers::TriggerContext;
pub use triggers::TriggerRunner;
pub use types::BuiltinTool;
pub use types::CapabilitiesConfig;
pub use types::HookResult;
pub use types::Step;
pub use types::StepSource;
pub use types::StepStatus;
pub use types::StepTarget;
pub use types::StepType;
pub use types::StreamChunk;
pub use types::SystemInstructions;
pub use types::ThinkingLevel;
pub use types::ToolCall;
pub use types::ToolResult;
pub use types::TranscriptEntry;
pub use types::TranscriptRole;
pub use types::TriggerDelivery;
pub use types::UsageMetadata;

Modules§

accounting
Pure economics decision core for the Accounting (CFO / Treasurer) role of an autonomous company (design/autonomous-business/roles/accounting.md): a period accounting::Ledger (treasury + costs + earned revenue + SEED, held apart) plus pure judgements — accounting::net_position (signed, seed EXCLUDED), accounting::runway_cycles, accounting::breakeven_price, accounting::is_solvent / accounting::is_self_funding. Honest about the inherited “seed-capitalized, not self-funding” constraint. Native-testable, zero chain deps. See src/accounting.rs. Pure economics decision core for the Accounting (CFO / Treasurer) role of an autonomous localharness company (design/autonomous-business/roles/accounting.md). It models the company’s books as DATA so the solvency / runway / break-even invariants run under cargo test: a [Ledger] is a period snapshot, every judgement is a pure function over it, and NOTHING here reads the chain, the meter, or a TBA balance — the wiring (registry::query_balance / check_balances / the CreditMeterFacet read) lives in the deferred, greenlight-gated executor, exactly like work_cycle / keeper / lessons.
agent
Layer-1 agent facade: connect, chat, shutdown. Layer-1 Agent facade.
backends
Backend implementations (Gemini, MCP). Backend implementations of the Connection trait.
bashlite
bashlite — a tiny, total, sandboxed shell that scripts the platform’s filesystem in one pass (the cost unlock: a multi-step fs chore collapses from N LLM rounds to ONE execute_script tool call). Native-testable core over a bashlite::BashHost trait. See src/bashlite/ + design/bashlite.md. bashlite — a tiny, deterministic, TOTAL shell that scripts the platform’s filesystem in ONE pass (see design/bashlite.md).
builtins
The crate-wide built-in tool registry (fs tools, ask_question, finish, call_agent, …) — backend-neutral; every backend registers from here. Formerly backends::gemini::tools (the re-export shim is gone). The crate-wide built-in tool registry — backend-NEUTRAL.
compose
Compositor scheduling for host::compose — the deferred-mutation module table (native-testable control flow). See src/compose.rs. Compositor scheduling for host::compose (roadmap Track A / Phase 1a) — the part that is pure control flow, so it lives here and is native-tested, independent of the wasm Instance/Memory it will hold in app::display.
confirm
Pure typed-confirmation challenge gate for destructive tools (native-testable, turn_flow hoisting pattern): single-use random nonce bound to exact tool+args, valid only when typed by the USER. Enforced by app::chat::confirm_guard at the dispatch layer. See src/confirm.rs. Typed-confirmation challenge gate — the pure core of the destructive-action convention, enforced at the DISPATCH layer.
connections
Transport abstraction traits. Transport abstraction.
content
Multimodal input primitives (text, images, documents, audio, video). Multimodal input primitives (text, images, documents, audio, video).
conversation
Stateful conversation session with multi-cursor streaming. Stateful conversation session.
cut_guard
Static safety lint for agent-authored facet cuts (SolidityLite §7 Layer 1): reserved-selector denylist + clash + _init==0. Pure + native-testable; wired into localharness facet cut as a pre-flight. See src/cut_guard.rs. Static safety lint for agent-authored facet cuts — design soliditylite.md §7 Layer 1, the “immune system” first line.
difficulty
Pure DIFFICULTY ROUTER core (native-testable): classifies each chat turn into a difficulty::TurnTier (Light / Standard / Heavy) and maps it to a model preference + types::ThinkingLevel, so the in-tab agent can route cheap/minimal-thinking turns away from the premium tier reserved for build/debug. Wired into app::chat per-turn. See src/difficulty.rs. Pure turn-DIFFICULTY classification — the in-tab “difficulty router” core.
docs_manifest
THE single source of truth for the drift-prone FACTS mirrored across the three managed docs (web/skill.md, web/llms.txt, README.md): chain addresses (from registry::chain), the crate version, $LH pricing, the agent tool list, and the CLI command list. cargo run --bin gen-docs fills each doc’s <!-- GEN:key --> block from here; a cargo test drift gate + the release pre-flight enforce sync. Gated on wallet (it reads registry::chain) AND not(wasm32): it only feeds the native gen-docs bin + the native drift test, so excluding it from the wasm build keeps the testnet MODERATO strings (which render_chains documents) out of the prod bundle — the last non-test wasm referencer of MODERATO. See docs/SOP-doc-integrity.md. Single source of truth for the drift-prone FACTS that are mirrored across the managed docs (web/skill.md, web/llms.txt). The top-level README.md is hand-written and minimal — deliberately not generated.
encoding
Pure hex / address / amount encoding helpers (native-testable). Hoisted out of app::events so they run under cargo test. See src/encoding.rs. Pure hex / address / amount encoding helpers — native-testable, no DOM, no state, no async.
error
Typed error hierarchy. Typed error hierarchy for the SDK.
error_codes
The one LHxxxx error-code registry (compile / runtime / tx-revert). The one LHxxxx error-code registry — a single source of truth spanning the three failure families an agent (or a user) hits on this platform:
evm_tools
READ-ONLY multi-chain EVM tools (balances / eth_call / ENS) over registry::multichain — registered by the browser chat session AND the headless CLI call, so identifier resolution is real on both surfaces. Multi-chain EVM READ tools (Ethereum, Base, Optimism, Arbitrum, Polygon, Tempo): native/ERC-20 balances, ENS resolution, and a generic eth_call, so an agent reads OTHER chains directly instead of web_fetch-ing third-party explorer APIs. ALL READ-ONLY — no writes, no signing. Backed by registry::multichain (curated CORS-enabled public RPCs). Returned chain data is UNTRUSTED.
filesystem
Filesystem abstraction for built-in fs tools. Filesystem abstraction for the built-in fs tools.
hiring
Pure role-fit scoring core for the HR (People Ops / Recruiting) role of an autonomous company (design/autonomous-business/roles/hr.md): score + rank candidate agents against an open seat (hiring::RoleNeed) by exact role + proven reputation (hiring::score_candidate / hiring::rank_candidates). A hiring::Candidate mirrors a work_cycle::WorkerState (with a From impl) and ranks the same way work_cycle::assign_next_task allocates, so HR ranking and work-cycle allocation agree. Native-testable. See src/hiring.rs. Pure role-fit scoring core for the HR (People Ops / Recruiting) role of an autonomous localharness company (design/autonomous-business/roles/hr.md). Given a [RoleNeed] (the open seat: required work_cycle::Role + a minimum on-chain reputation bar) and a pool of [Candidate] agents, it decides who is ELIGIBLE and RANKS the eligible ones best-first. Pure functions over data, no chain / I/O — the wiring (reputation_of reads, invite_to_guild / set_role writes) lives in the deferred executor, same keeper / lessons / work_cycle pattern, so the eligibility + ordering invariants run under cargo test.
hooks
Hook traits for observing and gating agent events. Hook traits and the runner that dispatches them.
html_fb
Pure HTML → framebuffer rasterizer (block-level text subset over the raster bitmap font; native-testable, zero web-sys). Hoisted out of app::display (roadmap R5). See src/html_fb.rs. HTML → framebuffer rasterization (pure, native-testable).
keeper
Pure decision core for a decentralized scheduler keeper (krafto feedback #1.5, the P2P answer to the centralized Vercel cron): which due ScheduleFacet jobs THIS keeper should fire this tick — deterministic fair assignment (no thundering herd) + rank-staggered backoff (liveness if a peer is offline). Native-testable, zero chain/P2P deps. See src/keeper.rs. Pure decision core for a decentralized scheduler keeper (krafto #1.5): given the on-chain ScheduleFacet jobs + this peer’s roster position, decide which due jobs to fire this tick — herd-free (one primary per job) with backup liveness. No chain/P2P deps; the wiring is a thin shell (localharness keeper + the proxy ?poke).
kv_reduce
Pure Last-Writer-Wins key/value CRDT for SessionRoom shared state (#22): folds a set of decrypted ops into a converged map (order-independent, idempotent, optional TTL). Native-testable. See src/kv_reduce.rs. Last-Writer-Wins key/value CRDT for SessionRoom shared state (GitHub #22).
kv_room
SessionRoom op sealing/opening + deterministic per-room key derivation (#22): AES-256-GCM confidentiality under K_room inside a writer-signed, room-bound signaling_seal envelope. Needs wallet for k256/keccak. Native-testable. See src/kv_room.rs. SessionRoom op sealing + per-room key derivation (GitHub #22).
lessons
Pure lessons-blob merging + prompt-section composition for the agent LESSONS LOOP (native-testable). The browser record_lesson tool, the headless CLI call, and the proxy scheduler worker all fold its output into the system prompt. See src/lessons.rs. Self-recorded agent lessons — the native-testable core of the LESSONS LOOP.
policy
Declarative tool-execution policy engine. Declarative tool-execution policy engine.
push_enroll
Pure Web Push enrollment-verification core (native-testable; telemetry #40): confirm a POSTed push subscription actually LANDED in the proxy store + compose the bell panel’s enrolled/not-enrolled status line. Consumed by app::notifications. See src/push_enroll.rs. Pure Web Push enrollment-verification core (native-testable; telemetry #40).
raster
Pure framebuffer rasterization + Viewport (the host::compose geometry foundation; native-testable, used by app::display). See src/raster.rs. Pure, native-testable framebuffer rasterization with a viewport — the geometry foundation for host::compose (roadmap Phase 0a, design/host- compose.md).
registry
JSON-RPC client for the on-chain registry diamond. JSON-RPC client for LocalharnessRegistry — read AND write.
router
Pure INTENT-ROUTER core (native-testable): classifies a chat message as router::Route::Free (balance/UI-command/docs-FAQ — answered locally, zero $LH) or Metered (the normal ~1 $LH model turn). Exact-allowlist conservative by contract; '!' always forces Metered. The router::IntentClassifier trait is the seam a local-model classifier (in-browser Gemma) can slot into later. Wired in app::chat::router_wire. See src/router.rs. Pure INTENT-ROUTER core — the free/metered cost gate in front of the browser chat’s metered model call (native-testable, the crate::turn_flow hoisting pattern: no DOM, no state, no async).
rustlite
Rust-subset to wasm compiler.
seed_flow
Pure decision core for the seed-pull apex round-trip (native-testable): only a return leg carrying an actual sealed seed repaints; an empty ?seed_import=none bounce scrubs the URL without touching the painted face, and the apex bounces BACK in history (bfcache) when it has nothing to hand over. Wired in app::seed_pull + app::mount. See src/seed_flow.rs. Pure decision core for the seed-pull apex round-trip legs (native-tested; the turn_flow hoisting pattern). The wasm plumbing lives in src/app/seed_pull.rs + the mount routing in src/app/mod.rs; THIS module owns the two decisions that used to cause a visible face repaint for every pure visitor:
sharedfs_reconcile
Pure, deterministic CONVERGENT reconcile for cross-device shared-folder sync (native-testable). Hoisted out of app::sharedfs_sync so the convergence / symmetry property runs under cargo test. See src/sharedfs_reconcile.rs. Pure, deterministic CONVERGENT reconcile for the cross-device shared-folder sync (crate::app::sharedfs_sync — cfg-gated out of non-browser doc builds, so plain code formatting here, not links).
signaling_seal
Pure signed-envelope layer for on-chain WebRTC signaling blobs — the SDP sealing/sender-authentication core (native-testable; needs wallet for k256). Hoisted out of app::teams_sync so the seal/unseal round-trip and tamper/forgery rejection run under cargo test. See src/signaling_seal.rs. Pure, native-testable envelope layer for on-chain WebRTC signaling blobs (the P2P teams layer’s SDP exchange over SignalingFacet.postSignal).
simulation
PURE MULTI-CYCLE FORECAST core: runs work_cycle::step forward over N cycles from a simulation::SimConfig and projects the company’s trajectory — per-cycle simulation::CycleSnapshots (treasury, throughput, net position) plus the run simulation::Forecast (total accepted, runway simulation::Forecast::ran_out_at, final accounting::Ledger). Each cycle injects the off-core delivery at a fixed assumed quality, advances one transition, and books revenue/costs. Preview ONLY — executes/broadcasts NOTHING. Native-testable, zero chain deps. See src/simulation.rs. PURE MULTI-CYCLE FORECAST core for an autonomous localharness company — runs the crate::work_cycle driver forward over N cycles and projects the company’s TRAJECTORY (treasury, throughput, runway, the honest books) so an operator can SEE where the business is heading before committing real $LH.
skills
Pure agent-skills blob (JSON array) upsert/remove + prompt-section composition for the agent SKILLS LOOP (native-testable). The browser create_skill tool, the headless CLI call, and the proxy scheduler worker all fold its output into the system prompt. See src/skills.rs. Agent-defined named skills — the native-testable core of the SKILLS LOOP.
soliditylite
Solidity/EVM-subset to EVM-bytecode compiler foundation (the EVM analog of rustlite): a bytecode assembler + worked dispatch/init scaffolding. See design/soliditylite.md. SolidityLite — a hand-rolled, in-browser Solidity/EVM-subset → EVM-bytecode compiler (the EVM analog of crate::rustlite). This module is the FOUNDATION: a bytecode assembler ([asm]) plus a worked emitter that proves the dispatch/init scaffolding end-to-end against a deployable artifact.
subdomain
Pure subdomain-name validation (native-testable) — the single source of truth shared by the browser create tools and kept in sync with the on-chain LocalharnessRegistryFacet._isValidName rule. See src/subdomain.rs. Pure subdomain-name validation — the single source of truth for the browser create tools, kept in sync with the on-chain LocalharnessRegistryFacet._isValidName rule. Native-tested (this is why it lives at the crate root, not inside the wasm-only app module).
tempo_tx
Tempo Transaction (tx type 0x76) encoder for native account abstraction. Tempo Transaction encoder (tx type 0x76).
tool_params
Single-table tool parameters: the tool_params! macro generates BOTH the typed args struct AND the Gemini-safe wire input_schema from ONE table (schema↔parse drift impossible by construction; zero deps, wasm-clean). Migrated wasm-gated chat tools hoist their tables here (the turn_flow pattern) so plain cargo test byte-checks their schemas. Opt-in per tool. See src/tool_params.rs. Single-table tool parameters: ONE tool_params! declaration generates BOTH the typed args struct AND the wire input_schema JSON, so schema↔parse drift is impossible by construction — a field cannot exist in the schema without existing in the struct, and vice versa.
tools
Custom tool registration and dispatch. Host-side custom tools.
triggers
Background triggers that push messages into the agent. Background triggers — fire-and-forget tasks that push messages into the agent. Each trigger runs in its own tokio task; the runner owns the task handles and aborts them on shutdown.
turn_flow
Pure turn-outcome classification for the continuous-execution chat loop (native-testable). Hoisted out of app::chat so its guard tests run under cargo test. See src/turn_flow.rs. Pure turn-outcome classification for the in-tab agent’s continuous-execution loop — native-testable, no DOM, no state, no async.
turn_stage
Pure state machine for the turn-stage micro-pipeline (“paying → thinking → streaming”) shown inside a pending assistant turn (native-testable, same hoisting pattern as turn_flow). See src/turn_stage.rs. Pure state machine for the turn-stage micro-pipeline — the terse “paying → thinking → streaming” line shown inside a PENDING assistant turn (GitHub #19: the $LH-payment → execution transition was opaque; a visitor paid and then stared at an unexplained pause).
types
Public boundary types (steps, tool calls, usage, config, etc.). Public boundary types for the SDK.
wallet
Secp256k1 keypair, BIP-39 mnemonics, and RLP encoding. In-browser secp256k1 keypair — k256 + sha3 directly.
work_cycle
Pure work-cycle decision core for an autonomous company of role-agents (design/autonomous-business/): allocate a funded task to the best-fit role-agent, judge the delivered result, pay the worker, and attest the outcome — modeling one claim→work→judge→pay→attest cycle as DATA (every side effect is an work_cycle::Action descriptor the caller maps onto a real registry bounty/x402/attest call). Native-testable, zero chain deps. See src/work_cycle.rs. Pure work-cycle decision core for an autonomous localharness company — the logic by which a founded org actually DOES work: allocate a funded task to the best-fit role-agent, judge the delivered result, pay the worker, and attest the outcome to reputation. It models ONE claim → work → judge → pay → attest cycle (the oggoel / agent-coordination flywheel) as DATA: every decision is a pure function and every side effect is an [Action] descriptor the caller later maps onto a real edge call (registry::post_bounty_sponsored / claim_bounty_sponsored / accept_result_sponsored / attest_sponsored / a TBA $LH transfer).
work_cycle_runtime
PURE PLANNING SHELL over work_cycle: a work_cycle_runtime::Reader (no registry/wallet dep) feeds the read-only company view into work_cycle_runtime::plan_cycle, which runs work_cycle::step to quiescence and returns a work_cycle_runtime::CyclePlan of WHAT WOULD HAPPEN — preview ONLY, executes/broadcasts NOTHING. The greenlight-gated executor that maps each planned work_cycle::Action onto its sponsored registry call is deferred. Native-testable. See src/work_cycle_runtime.rs. PURE PLANNING SHELL around the crate::work_cycle decision core — turns a read-only view of the company (its backlog, its role-agents, its treasury) into a [CyclePlan] describing WHAT THE NEXT CYCLE WOULD DO, without ever executing or broadcasting anything.
x402_hook
App-injected x402 payment-signing hook (lets the backend call_agent tool sign payments using the app-layer wallet). App-injected x402 hooks.

Macros§

tool_params
Generate a typed tool-args struct + its wire input_schema from ONE table.