Skip to main content

clark_agent/
lib.rs

1//! # clark-agent
2//!
3//! A small, typed, hookable agent loop. Provider-agnostic, sandbox-agnostic,
4//! tooling-agnostic.
5//!
6//! ## Shape
7//!
8//! ```text
9//! context → LLM (StreamFn) → tool batch → results appended → repeat
10//! ```
11//!
12//! Termination is a tool decision (`ToolResult::terminate = true`, unanimous
13//! across the batch). The runtime owns execution and event emission; tools
14//! own semantics; plugins own cross-cutting extension.
15//!
16//! ## Layers
17//!
18//! - [`types`] — `AgentMessage`, content blocks, `StopReason`. The conversation
19//!   transcript is `Vec<AgentMessage>`. Apps extend via `AgentMessage::Custom`
20//!   or by wrapping in their own enum.
21//! - [`event`] — `AgentEvent` enum + `EventSink` trait. Single sink, typed
22//!   events. Streamed and final delivery use the same enum.
23//! - [`tool`] — `AgentTool` trait + `ToolRegistry`. Tools own their own state
24//!   and validation; the loop only dispatches.
25//! - [`stream`] — `StreamFn` trait. Swappable LLM transport: real provider,
26//!   fixture replay, scripted scenario, remote proxy.
27//! - [`plugin`] — `Plugin` + capability traits (`BeforeToolCall`,
28//!   `AfterToolCall`, `ContextTransform`, `EventObserver`, `SteeringSource`).
29//!   Cross-cutting concerns register here, not inline in the loop.
30//! - [`protocol`] — `ProtocolPolicy`. The seam for product-specific tool
31//!   vocabulary (recovery prose, tool-call alias repair, hidden-tool errors).
32//!   The core ships a generic default that names no tools.
33//! - [`config`] — `LoopConfig` + `AgentBuilder` for assembling everything.
34//! - [`mod@run`] — [`run()`] / [`run_continue()`] — the canonical loop. Pure functions.
35//! - [`exec`] — tool execution: parallel + sequential dispatch, hook plumbing.
36//! - [`budget`] — default token-budget context transform.
37//! - [`error`] — typed error enums.
38
39pub mod budget;
40pub mod config;
41pub mod error;
42pub mod event;
43pub mod exec;
44pub mod history;
45pub mod plugin;
46pub mod plugins;
47pub mod protocol;
48pub mod reasoning;
49pub mod run;
50pub mod stream;
51pub mod thinking_filter;
52pub mod tokens;
53pub mod tool;
54pub mod tool_identity;
55pub mod tool_result_budget;
56pub mod trajectory;
57pub mod types;
58
59pub use budget::TokenBudget;
60pub use config::{
61    AgentBuilder, LoopConfig, MaxTokensRecovery, PluginNames, TokenScaling,
62    DEFAULT_GRACE_ITERATIONS,
63};
64pub use error::{LoopError, StreamError, ToolError, ToolValidationError};
65pub use event::ChannelSink;
66pub use event::{AgentEvent, EventSink, ProviderRequestSummary};
67pub use history::{normalize_tool_call_ids, ToolCallIdNormalization, UniqueToolCallIds};
68pub use plugin::PluginCapabilities;
69pub use plugin::{
70    AfterToolCall, AfterToolDecision, BeforeToolCall, BeforeToolDecision, ContextOverflowRecovery,
71    ContextTransform, EventObserver, FollowUpSource, Plugin, SteeringSource, TransformContext,
72};
73pub use plugins::GracefulTurnLimit;
74pub use protocol::{
75    DefaultProtocolPolicy, HiddenToolContext, HiddenToolError, PlainTextRecoveryContext,
76    ProtocolPolicy, DEFAULT_PLAIN_TEXT_RECOVERY_PROMPT,
77};
78pub use reasoning::{
79    audit_replay, OpenRouterReasoningCodec, ReasoningCodec, ReasoningFormat, ReasoningItem,
80    ReplayAudit, ReplayContract, ReplayViolation,
81};
82pub use run::{run, run_continue, LoopOutcome, RunResult};
83pub use stream::{
84    AssistantStreamChunk, ReasoningEffort, StreamEvent, StreamFn, StreamRequest, StreamResponse,
85};
86pub use thinking_filter::{strip_thinking_tags, ThinkingTagStreamFilter};
87pub use tokens::{CharHeuristicEstimator, TokenEstimator, CHAR_HEURISTIC};
88pub use tool::{
89    arg_parse_error_value, detect_arg_parse_error, AgentTool, ExecutionMode, ToolCall,
90    ToolHistoryPolicy, ToolRegistry, ToolResult, ToolUpdateSink, TypedAgentTool,
91    ARG_PARSE_ERROR_MARKER, ARG_PARSE_RAW_MARKER,
92};
93pub use tool_identity::{
94    extract_args_key, extract_operation_key, extract_target, ArgsKeyFn, TargetExtractor, TargetFn,
95    ToolIdentityPolicy,
96};
97pub use tool_result_budget::{ToolResultBudget, DEFAULT_PER_TOOL_CHARS};
98pub use trajectory::{
99    InMemoryTrajectorySink, TrajectoryError, TrajectoryPayload, TrajectoryRecord,
100    TrajectoryRecorder, TrajectorySink, TRAJECTORY_SCHEMA_VERSION,
101};
102pub use types::{
103    AgentContext, AgentMessage, AssistantBlock, AssistantContent, ImageContent,
104    ReasoningDetailsContent, RunIdentity, StopReason, TextContent, ToolResultBlock,
105    ToolResultContent, UserBlock, UserContent,
106};