1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
//! # 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
//!
//! ```rust,no_run
//! use localharness::{Agent, GeminiAgentConfig};
//!
//! # async fn run() -> localharness::Result<()> {
//! 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?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Layers
//!
//! | Layer | Type | Purpose |
//! |-------|------|---------|
//! | 1 | [`Agent`] | High-level facade: connect, chat, shutdown. |
//! | 2 | [`Conversation`] / [`ChatResponse`] | Stateful session, multi-cursor streams. |
//! | 3 | [`connections::Connection`] | Transport abstraction. |
//! | aux | [`Filesystem`] | What the 6 fs-shaped built-in tools call into; swap the impl to target OPFS, an in-memory FS, etc. |
//!
//! [`Agent`]: agent::Agent
//! [`Conversation`]: conversation::Conversation
//! [`ChatResponse`]: conversation::ChatResponse
//! [`connections::Connection`]: connections::Connection
//! [`Filesystem`]: filesystem::Filesystem
// On wasm32 the crate is single-threaded (browser) and intentionally
// uses `Arc` over non-Send/Sync values via the `MaybeSendSync` marker
// (see `runtime.rs`). Clippy's `arc_with_non_send_sync` fires on every
// such use; it's by design on this target, so silence it crate-wide for
// wasm rather than peppering `#[allow]` across the modules.
// On wasm32 the upper architecture (Agent → Conversation → Connection)
// is temporarily gated behind `native` because its trait bounds require
// `Send` futures, which reqwest's browser fetch can't satisfy. The wasm
// surface exposes `error`, `content`, `types`, and the low-level
// `backends::gemini::api::GeminiClient` so a web demo can drive the
// Gemini REST API directly. Lifting the gate is M2.5: thread a
// `MaybeSend` shim through the Tool/Connection/Hook traits.
/// Layer-1 agent facade: connect, chat, shutdown.
/// Backend implementations (Gemini, MCP).
/// 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` (a re-export shim remains there).
/// Transport abstraction traits.
/// Multimodal input primitives (text, images, documents, audio, video).
/// Stateful conversation session with multi-cursor streaming.
/// Typed error hierarchy.
/// The one `LHxxxx` error-code registry (compile / runtime / tx-revert).
/// Filesystem abstraction for built-in fs tools.
pub
/// Hook traits for observing and gating agent events.
/// Declarative tool-execution policy engine.
/// Custom tool registration and dispatch.
/// Background triggers that push messages into the agent.
/// Public boundary types (steps, tool calls, usage, config, etc.).
/// Rust-subset to wasm compiler.
/// Solidity/EVM-subset to EVM-bytecode compiler foundation (the EVM analog of
/// [`rustlite`]): a bytecode assembler + worked dispatch/init scaffolding. See
/// `design/soliditylite.md`.
/// Pure framebuffer rasterization + `Viewport` (the host::compose geometry
/// foundation; native-testable, used by `app::display`). See `src/raster.rs`.
/// Compositor scheduling for `host::compose` — the deferred-mutation module
/// table (native-testable control flow). See `src/compose.rs`.
/// Pure hex / address / amount encoding helpers (native-testable). Hoisted out
/// of `app::events` so they run under `cargo test`. See `src/encoding.rs`.
/// 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 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 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`.
/// 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`.
/// 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`.
/// 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`.
/// 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`.
/// 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 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 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`.
/// 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`.
// Inline SVG QR-code generation for the app's share surfaces (device
// pairing, publish share, `?invite=` links). Feature-gated like `app`
// but NOT wasm-gated, so its unit test runs under a native
// `cargo test --features browser-app` (the `turn_flow` hoisting pattern).
// Apex fresh-visitor landing markup — hoisted out of the wasm-gated `app/`
// tree (the raster.rs/compose.rs pattern) so the SHIPPING markup also
// renders natively: `cargo test --features browser-app landing_preview`
// writes `target/landing-preview.html` for screenshot review. The `test`
// arm keeps non-test native builds free of dead-code (only the wasm app
// and the preview test consume it).
// The browser-resident IDE. Gated on the `browser-app` feature AND a
// wasm target, so a native `cargo add localharness` never compiles it.
// M6 spike: in-browser secp256k1 keypair via alloy's local signer.
// Pure-compute (no HTTP, no JS deps), so it builds on every target.
/// Secp256k1 keypair, BIP-39 mnemonics, and RLP encoding.
// JSON-RPC client for the `LocalharnessRegistry` diamond on Tempo
// Moderato. Read-only views (`check_name`, `owner_of_name`,
// `tba_of_name`, `list_owned_tokens`) work on every target; the
// sponsored writes sign with a `k256` key (needs the wallet feature)
// and use `tokio::time::sleep` on native / `setTimeout` on wasm to
// poll the receipt. The diamond's address is baked in as
// `registry::REGISTRY_ADDRESS`; the RPC URL is `registry::RPC_URL`.
/// JSON-RPC client for the on-chain registry diamond.
// Tempo Transaction encoder (tx type 0x76). Implements Tempo's native
// account-abstraction tx format so users can pay fees in $LH instead
// of native and so a project-controlled fee_payer can sponsor user
// txs without users holding any balance. Wire format per
// docs.tempo.xyz/protocol/transactions/spec-tempo-transaction.
/// Tempo Transaction (tx type 0x76) encoder for native account abstraction.
/// App-injected x402 payment-signing hook (lets the backend `call_agent`
/// tool sign payments using the app-layer wallet).
pub use ;
pub use AnthropicAgentConfig;
pub use OpenAiAgentConfig;
pub use LocalAgentConfig;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use NativeFilesystem;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;