harness/lib.rs
1//! `harness-rs` — facade re-exporting the public surface of the harness-rs
2//! agent framework.
3//!
4//! Most users depend only on this crate. It re-exports `harness-core` (traits +
5//! types), the procedural macros from `harness-macros`, and exposes
6//! `harness-skills` under the `skills` module. The lower-level crates remain
7//! available individually for anyone who wants a minimal dependency footprint.
8//!
9//! # What is a harness?
10//!
11//! An *agent* in this framework is a `Model` + a *harness* — the surrounding
12//! scaffold that decides what the model can see (`Guide`), what tools it can
13//! call (`Tool`), what feedback signals come back to it (`Sensor`), what
14//! policies wrap each step (`Hook`), and how its context is kept small
15//! (`Compactor`). The `AgentLoop` in `harness-rs-loop` ties these together
16//! in a ReAct loop with self-correction.
17//!
18//! See `DESIGN.md` at the workspace root for the architectural intent.
19//!
20//! # Quick start
21//!
22//! Define a tool with `#[tool]`, point the model adapter at any
23//! OpenAI-compatible endpoint, and run the loop:
24//!
25//! ```ignore
26//! use harness::{tool, ToolError};
27//! use harness_loop::AgentLoop;
28//! use harness_models::OpenAiCompat;
29//! use harness_context::default_world;
30//! use harness_core::{Policy, Task};
31//! use std::sync::Arc;
32//!
33//! /// Add two integers.
34//! #[tool(name = "add", risk = "Safe")]
35//! async fn add(a: i64, b: i64) -> Result<i64, ToolError> {
36//! Ok(a + b)
37//! }
38//!
39//! # async fn run() -> anyhow::Result<()> {
40//! let model = OpenAiCompat::with_key(
41//! "https://api.deepseek.com",
42//! "deepseek-chat",
43//! std::env::var("DEEPSEEK_API_KEY")?,
44//! );
45//! let loop_ = AgentLoop::new(model).with_tool(Arc::new(add()));
46//! let mut world = default_world(std::env::current_dir()?);
47//! let outcome = loop_
48//! .run(
49//! Task { description: "What is 2 + 3?".into(),
50//! source: None, deadline: None },
51//! &mut world,
52//! )
53//! .await?;
54//! println!("{outcome:?}");
55//! # Ok(()) }
56//! ```
57//!
58//! # Examples
59//!
60//! Worked examples live at <https://github.com/liliang-cn/harness-rs/tree/main/examples>:
61//!
62//! - `deepseek-hello` — smallest possible Hello-world.
63//! - `crate-keeper` — `MockModel` smoke test (no network).
64//! - `personal-assistant` — scheduling agent with `UserProfile`, REPL, brief mode.
65//! - `investor-bot` — autonomous web research with multi-engine search + retry.
66//!
67//! # Crate map
68//!
69//! - [`harness_core`] — `Model` / `Tool` / `Guide` / `Sensor` / `Hook` /
70//! `Compactor` / `Skill` traits, `World`, `Context`, `Event`, error types.
71//! - [`harness_macros`] — `#[skill]` / `#[tool]` / `#[guide]` / `#[sensor]` /
72//! `#[hook]` proc-macros.
73//! - `harness_loop` — `AgentLoop` ReAct executor with auto-fix sensors.
74//! - `harness_hooks` — `HookBus` over 27 lifecycle events.
75//! - `harness_blueprint` — hybrid deterministic + agent state machine.
76//! - `harness_compactor` — five-stage progressive context compaction.
77//! - `harness_sandbox` — `WorktreeSandbox` (default) + container/VM stubs.
78//! - `harness_models` — `OpenAiCompat` / `AnthropicNative` / `MockModel`.
79//! - `harness_mcp` — MCP stdio JSON-RPC server.
80//! - [`skills`] — agentskills.io-compliant skill loader + validator.
81//! - `harness_tools_fs` / `harness_tools_shell` — built-in toolsets.
82//! - `harness_sensors_rust` / `harness_sensors_common` — built-in sensors.
83
84pub use harness_core::*;
85pub use harness_macros::*;
86
87pub mod skills {
88 //! agentskills.io-compliant skill loading.
89 pub use harness_skills::*;
90}
91
92pub mod prelude {
93 pub use harness_core::{
94 Action, Block, Compactor, Context, Event, Execution, Guide, GuideScope, HarnessError, Hook,
95 Model, ModelOutput, Policy, Result, Sensor, Severity, Signal, Skill, SkillManifest, Stage,
96 Task, Tool, ToolResult, ToolRisk, ToolSchema, World,
97 };
98}
99
100/// Crate version for diagnostic logging.
101pub const VERSION: &str = env!("CARGO_PKG_VERSION");