Skip to main content

heartbit_core/
lib.rs

1//! # heartbit-core
2//!
3//! The Rust agentic framework — agents, tools, LLM providers, memory, evaluation.
4//!
5//! Documentation lands here as the crate's docs.rs preamble. The README
6//! is rendered above this on docs.rs.
7
8#![deny(missing_docs)]
9
10// Modules are added one at a time as subsequent tasks move them in.
11pub mod agent;
12pub mod auth;
13pub mod channel;
14pub mod config;
15pub mod error;
16pub mod eval;
17pub mod execution_context;
18pub mod http;
19pub mod knowledge;
20pub mod llm;
21pub mod lsp;
22pub mod memory;
23pub mod persona;
24pub mod sandbox;
25#[cfg(unix)]
26pub mod signal;
27pub mod store;
28pub mod template;
29pub mod tool;
30pub(crate) mod types;
31pub(crate) mod util;
32pub mod workspace;
33
34// --- Agent re-exports ---
35pub use agent::audit::{AuditMode, AuditRecord, AuditTrail, InMemoryAuditTrail};
36pub use agent::batch::{BatchConfig, BatchExecutor, BatchExecutorBuilder, BatchResult};
37pub use agent::blackboard::{Blackboard, InMemoryBlackboard};
38pub use agent::cache::ResponseCache;
39pub use agent::context::ContextStrategy;
40pub use agent::dag::{DagAgent, DagAgentBuilder};
41pub use agent::debate::{DebateAgent, DebateAgentBuilder};
42pub use agent::evaluator::{EvaluatorOptimizerAgent, EvaluatorOptimizerAgentBuilder};
43pub use agent::events::{AgentEvent, OnEvent};
44pub use agent::guardrail::{GuardAction, Guardrail};
45#[allow(deprecated)]
46pub use agent::guardrails::ContentFenceGuardrail;
47pub use agent::guardrails::tool_policy::{InputConstraint, ToolRule};
48pub use agent::guardrails::{
49    ActionBudgetGuardrail, ActionBudgetGuardrailBuilder, BehaviorRule, BehavioralMonitorGuardrail,
50    BehavioralMonitorGuardrailBuilder, BudgetRule, ConditionalGuardrail, GuardrailChain,
51    GuardrailMode, InjectionClassifierGuardrail, LlmJudgeGuardrail, LlmJudgeGuardrailBuilder,
52    PiiAction, PiiDetector, PiiGuardrail, SecretAction, SecretScannerGuardrail,
53    SecretScannerGuardrailBuilder, SensorSecurityGuardrail, ToolPolicyGuardrail, WarnToDeny,
54};
55pub use agent::handoff::{HandoffRunner, HandoffRunnerBuilder, make_handoff_tool};
56pub use agent::instructions::{
57    discover_instruction_files, load_instructions, prepend_instructions,
58};
59pub use agent::mixture::{MixtureOfAgentsAgent, MixtureOfAgentsAgentBuilder};
60pub use agent::observability::ObservabilityMode;
61pub use agent::orchestrator::{Orchestrator, OrchestratorBuilder, SubAgentConfig};
62pub use agent::permission::{
63    LearnedPermissions, PermissionAction, PermissionRule, PermissionRuleset,
64};
65pub use agent::prompts::MULTI_AGENT_COLLAB_PROMPT;
66pub use agent::pruner::SessionPruneConfig;
67pub use agent::routing::{
68    AgentCapability, ComplexitySignals, KeywordRoutingStrategy, RoutingDecision, RoutingMode,
69    RoutingStrategy, TaskComplexityAnalyzer, resolve_routing_mode, should_escalate,
70};
71pub use agent::tenant_tracker::{TenantTokenState, TenantTokenTracker, TokenReservation};
72pub use agent::tool_filter::ToolProfile;
73pub use agent::voting::{VoteResult, VotingAgent, VotingAgentBuilder};
74pub use agent::workflow::{
75    LoopAgent, LoopAgentBuilder, ParallelAgent, ParallelAgentBuilder, SequentialAgent,
76    SequentialAgentBuilder, WorkflowRouter, WorkflowType,
77};
78pub use agent::{AgentOutput, AgentRunner, AgentRunnerBuilder, OnInput};
79
80// --- Error re-exports ---
81pub use error::Error;
82
83// --- Execution context re-exports ---
84pub use execution_context::{AuditSink, CredentialResolver, ExecutionContext, Secret};
85
86// --- Eval re-exports ---
87pub use eval::{
88    CaseComparison, CostScorer, EvalCase, EvalComparison, EvalResult, EvalRunner, EvalScorer,
89    EvalSummary, EventCollector, KeywordScorer, LatencyScorer, SafetyScorer, ScorerResult,
90    SimilarityScorer, ToolCallCountScorer, TrajectoryScorer, build_eval_agent, clear_events,
91};
92
93// --- Sandbox re-exports ---
94pub use sandbox::{CorePathPolicy, CorePathPolicyBuilder};
95
96// --- Knowledge re-exports ---
97pub use knowledge::in_memory::InMemoryKnowledgeBase;
98pub use knowledge::{Chunk, DocumentSource, KnowledgeBase, KnowledgeQuery, SearchResult};
99
100// --- LLM re-exports ---
101pub use llm::ApprovalDecision;
102pub use llm::LlmProvider;
103pub use llm::OnApproval;
104pub use llm::OnText;
105pub use llm::anthropic::AnthropicProvider;
106pub use llm::cascade::{CascadingProvider, ConfidenceGate, HeuristicGate};
107pub use llm::circuit::{
108    CircuitBreakerProvider, CircuitConfig, CircuitKey, CircuitPermit, CircuitTracker,
109    ProviderCircuit, is_circuit_failure,
110};
111pub use llm::error_class::{ErrorClass, classify as classify_error};
112pub use llm::gemini::GeminiProvider;
113pub use llm::openai_compat::{AuthStyle, OpenAiCompatProvider};
114pub use llm::openrouter::OpenRouterProvider;
115pub use llm::pricing::estimate_cost;
116pub use llm::registry::{
117    ProviderInfo, detect_available_provider, get_provider, known_providers as known_llm_providers,
118    resolve_api_key,
119};
120pub use llm::retry::{OnRetry, RetryConfig, RetryingProvider};
121pub use llm::types::{
122    CompletionRequest, CompletionResponse, ContentBlock, Message, ReasoningEffort, Role,
123    StopReason, TokenUsage, ToolCall, ToolChoice, ToolDefinition, ToolResult,
124};
125pub use llm::{BoxedProvider, DynLlmProvider};
126
127// --- LSP re-exports ---
128pub use lsp::{Diagnostic as LspDiagnostic, LspManager};
129
130// --- Memory re-exports ---
131pub use memory::Confidentiality;
132pub use memory::consolidation::{
133    ConsolidationPipeline, ConsolidationResult, DEFAULT_SUMMARY_MAX_TOKENS, cluster_by_keywords,
134};
135pub use memory::embedding::{EmbeddingMemory, EmbeddingProvider, NoopEmbedding, OpenAiEmbedding};
136pub use memory::hybrid::{cosine_similarity, rrf_fuse};
137pub use memory::in_memory::InMemoryStore;
138pub use memory::namespaced::NamespacedMemory;
139pub use memory::pruning::{DEFAULT_MIN_STRENGTH, default_min_age, prune_weak_entries};
140pub use memory::reflection::ReflectionTracker;
141pub use memory::scoring::ScoringWeights;
142pub use memory::{Memory, MemoryEntry, MemoryQuery, MemoryType};
143
144// --- Persona re-exports ---
145pub use persona::{
146    AuthorshipMode, Persona, PersonaExpansion, PersonaParams, PersonaRegistry, ReviewSpec,
147    TriggerSpec,
148};
149
150// --- Tool re-exports ---
151#[cfg(feature = "a2a")]
152pub use tool::a2a::A2aClient;
153pub use tool::builtins::{
154    BuiltinToolsConfig, FileTracker, OnQuestion, Question, QuestionOption, QuestionRequest,
155    QuestionResponse, TodoPriority, TodoStatus, TodoStore, ToolRisk, TwitterCredentials,
156    builtin_tools,
157};
158pub use tool::handoff::{HandoffContextMode, HandoffTarget, HandoffTool};
159pub use tool::mcp::{
160    AuthProvider, AuthResolver, DirectAuthProvider, DynamicAuthResolver, McpClient,
161    McpPromptArgument, McpPromptDef, McpPromptMessage, McpPromptMessageContent, McpResourceContent,
162    McpResourceDef, McpRoot, McpTransportPool, SamplingContent, SamplingHandler, SamplingMessage,
163    SamplingModelHint, SamplingModelPreferences, SamplingRequest, StaticAuthProvider,
164    StaticAuthResolver, TokenExchangeAuthProvider,
165};
166pub use tool::mcp_presets::{McpPreset, check_preset_env, known_presets, resolve_preset};
167pub use tool::mcp_server::{McpServer, McpServerConfig, ServerResource};
168pub use tool::{Tool, ToolOutput, validate_tool_input};
169
170// --- Workspace re-exports ---
171pub use workspace::Workspace;
172
173// --- Benchmark-only helpers ---
174//
175// Thin wrappers over crate-internal hot paths exposed exclusively for
176// criterion benchmarks under `crates/heartbit-core/benches/`. Gated
177// behind the `bench-internals` feature so downstream consumers cannot
178// accidentally rely on this surface; the wrappers allocate their own
179// internal state and never leak crate-private types across the boundary.
180#[cfg(feature = "bench-internals")]
181#[doc(hidden)]
182pub mod __bench {
183    #![allow(missing_docs)]
184
185    /// Feed `chunk` to a fresh `SseParser` and return the number of
186    /// emitted events. Used to benchmark per-chunk allocation overhead
187    /// in the Anthropic SSE hot path (P-LLM-2, P-LLM-14).
188    pub fn sse_parse_chunk(chunk: &str) -> usize {
189        let mut parser = crate::llm::anthropic::SseParser::new();
190        parser.feed(chunk).len()
191    }
192
193    /// Mock LLM provider that returns the same canned response on every
194    /// call (no draining). Designed for the agent-ReAct-turn bench
195    /// (Bench-NEW-1 in `tasks/perf-audit-v2-bench-gaps.md`) where each
196    /// criterion sample needs a fresh `execute()` against an identical
197    /// provider response — different from the test-only `MockProvider`
198    /// which drains a queue.
199    pub struct BenchMockProvider {
200        response: crate::llm::types::CompletionResponse,
201    }
202
203    impl BenchMockProvider {
204        /// Build a provider that always returns a single text response.
205        pub fn new_text(text: impl Into<String>) -> Self {
206            use crate::llm::types::{CompletionResponse, ContentBlock, StopReason, TokenUsage};
207            Self {
208                response: CompletionResponse {
209                    content: vec![ContentBlock::Text { text: text.into() }],
210                    stop_reason: StopReason::EndTurn,
211                    usage: TokenUsage {
212                        input_tokens: 64,
213                        output_tokens: 16,
214                        ..Default::default()
215                    },
216                    model: None,
217                },
218            }
219        }
220    }
221
222    impl crate::llm::LlmProvider for BenchMockProvider {
223        async fn complete(
224            &self,
225            _request: crate::llm::types::CompletionRequest,
226        ) -> Result<crate::llm::types::CompletionResponse, crate::error::Error> {
227            Ok(self.response.clone())
228        }
229
230        fn model_name(&self) -> Option<&str> {
231            Some("bench-mock")
232        }
233    }
234}