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
//! `harness-rs` — facade re-exporting the public surface of the harness-rs
//! agent framework.
//!
//! Most users depend only on this crate. It re-exports `harness-core` (traits +
//! types), the procedural macros from `harness-macros`, and exposes
//! `harness-skills` under the `skills` module. The lower-level crates remain
//! available individually for anyone who wants a minimal dependency footprint.
//!
//! # What is a harness?
//!
//! An *agent* in this framework is a `Model` + a *harness* — the surrounding
//! scaffold that decides what the model can see (`Guide`), what tools it can
//! call (`Tool`), what feedback signals come back to it (`Sensor`), what
//! policies wrap each step (`Hook`), and how its context is kept small
//! (`Compactor`). The `AgentLoop` in `harness-rs-loop` ties these together
//! in a ReAct loop with self-correction.
//!
//! See `DESIGN.md` at the workspace root for the architectural intent.
//!
//! # Quick start
//!
//! Define a tool with `#[tool]`, point the model adapter at any
//! OpenAI-compatible endpoint, and run the loop:
//!
//! ```ignore
//! use harness::{tool, ToolError};
//! use harness_loop::AgentLoop;
//! use harness_models::OpenAiCompat;
//! use harness_context::default_world;
//! use harness_core::{Policy, Task};
//! use std::sync::Arc;
//!
//! /// Add two integers.
//! #[tool(name = "add", risk = "Safe")]
//! async fn add(a: i64, b: i64) -> Result<i64, ToolError> {
//! Ok(a + b)
//! }
//!
//! # async fn run() -> anyhow::Result<()> {
//! let model = OpenAiCompat::with_key(
//! "https://api.deepseek.com",
//! "deepseek-chat",
//! std::env::var("DEEPSEEK_API_KEY")?,
//! );
//! let loop_ = AgentLoop::new(model).with_tool(Arc::new(add()));
//! let mut world = default_world(std::env::current_dir()?);
//! let outcome = loop_
//! .run(
//! Task { description: "What is 2 + 3?".into(),
//! source: None, deadline: None },
//! &mut world,
//! )
//! .await?;
//! println!("{outcome:?}");
//! # Ok(()) }
//! ```
//!
//! # Examples
//!
//! Worked examples live at <https://github.com/liliang-cn/harness-rs/tree/main/examples>:
//!
//! - `deepseek-hello` — smallest possible Hello-world.
//! - `crate-keeper` — `MockModel` smoke test (no network).
//! - `personal-assistant` — scheduling agent with `UserProfile`, REPL, brief mode.
//! - `investor-bot` — autonomous web research with multi-engine search + retry.
//!
//! # Crate map
//!
//! - [`harness_core`] — `Model` / `Tool` / `Guide` / `Sensor` / `Hook` /
//! `Compactor` / `Skill` traits, `World`, `Context`, `Event`, error types.
//! - [`harness_macros`] — `#[skill]` / `#[tool]` / `#[guide]` / `#[sensor]` /
//! `#[hook]` proc-macros.
//! - `harness_loop` — `AgentLoop` ReAct executor with auto-fix sensors.
//! - `harness_hooks` — `HookBus` over 27 lifecycle events.
//! - `harness_blueprint` — hybrid deterministic + agent state machine.
//! - `harness_compactor` — five-stage progressive context compaction.
//! - `harness_sandbox` — `WorktreeSandbox` (default) + container/VM stubs.
//! - `harness_models` — `OpenAiCompat` / `AnthropicNative` / `MockModel`.
//! - `harness_mcp` — MCP stdio JSON-RPC server.
//! - [`skills`] — agentskills.io-compliant skill loader + validator.
//! - `harness_tools_fs` / `harness_tools_shell` — built-in toolsets.
//! - `harness_sensors_rust` / `harness_sensors_common` — built-in sensors.
pub use *;
pub use *;
/// Crate version for diagnostic logging.
pub const VERSION: &str = env!;