Skip to main content

harn_vm/
lib.rs

1#![allow(clippy::result_large_err, clippy::cloned_ref_to_slice_refs)]
2
3pub mod a2a;
4pub mod agent_events;
5pub mod agent_sessions;
6pub mod bridge;
7pub mod checkpoint;
8mod chunk;
9mod compiler;
10pub mod connectors;
11pub mod event_log;
12pub mod events;
13mod http;
14pub mod jsonrpc;
15pub mod llm;
16pub mod llm_config;
17pub mod mcp;
18pub mod mcp_card;
19pub mod mcp_registry;
20pub mod mcp_server;
21pub mod metadata;
22pub mod observability;
23pub mod orchestration;
24pub mod record_filter;
25pub mod runtime_paths;
26pub mod schema;
27pub mod secrets;
28pub mod skills;
29pub mod stdlib;
30pub mod stdlib_modules;
31pub mod store;
32pub mod tool_annotations;
33pub mod tracing;
34pub mod triggers;
35pub mod trust_graph;
36pub mod value;
37pub mod visible_text;
38mod vm;
39pub mod workspace_path;
40
41pub use checkpoint::register_checkpoint_builtins;
42pub use chunk::*;
43pub use compiler::*;
44pub use connectors::{
45    active_connector_client, clear_active_connector_clients,
46    cron::{CatchupMode, CronConnector},
47    harn_module::{
48        load_contract as load_harn_connector_contract, HarnConnector, HarnConnectorContract,
49    },
50    hmac::verify_hmac_signed,
51    install_active_connector_clients, load_pending_webhook_handshakes,
52    postprocess_normalized_event, ActivationHandle, ClientError, Connector, ConnectorClient,
53    ConnectorCtx, ConnectorError, ConnectorMetricsSnapshot, ConnectorRegistry,
54    GenericWebhookConnector, GitHubConnector, LinearConnector, MetricsRegistry, NotionConnector,
55    PersistedNotionWebhookHandshake, PostNormalizeOutcome, ProviderPayloadSchema, RateLimitConfig,
56    RateLimiterFactory, RawInbound, SlackConnector, TriggerBinding, TriggerKind, TriggerRegistry,
57    WebhookSignatureVariant,
58};
59pub use http::{register_http_builtins, reset_http_state};
60pub use llm::register_llm_builtins;
61pub use llm::trigger_predicate::TriggerPredicateBudget;
62pub use mcp::{
63    connect_mcp_server, connect_mcp_server_from_json, connect_mcp_server_from_spec,
64    register_mcp_builtins,
65};
66pub use mcp_card::{fetch_server_card, load_server_card_from_path, CardError};
67pub use mcp_registry::{
68    active_handle as mcp_active_handle, ensure_active as mcp_ensure_active,
69    get_registration as mcp_get_registration, install_active as mcp_install_active,
70    is_registered as mcp_is_registered, register_servers as mcp_register_servers,
71    release as mcp_release, reset as mcp_reset_registry, snapshot_status as mcp_snapshot_status,
72    sweep_expired as mcp_sweep_expired, RegisteredMcpServer, RegistryStatus,
73};
74pub use mcp_server::{
75    take_mcp_serve_prompts, take_mcp_serve_registry, take_mcp_serve_resource_templates,
76    take_mcp_serve_resources, tool_registry_to_mcp_tools, McpServer,
77};
78pub use metadata::{register_metadata_builtins, register_scan_builtins};
79pub use record_filter::{normalize_record_filter_expression, CompiledRecordFilter};
80pub use stdlib::hitl::{
81    append_hitl_response, HitlHostResponse, HITL_APPROVALS_TOPIC, HITL_DUAL_CONTROL_TOPIC,
82    HITL_ESCALATIONS_TOPIC, HITL_QUESTIONS_TOPIC,
83};
84pub use stdlib::host::{clear_host_call_bridge, set_host_call_bridge, HostCallBridge};
85pub use stdlib::secret_scan::{
86    append_secret_scan_audit, audit_secret_scan_active, scan_content as secret_scan_content,
87    SecretFinding, SECRET_SCAN_AUDIT_TOPIC,
88};
89pub use stdlib::template::{
90    lookup_prompt_consumers, lookup_prompt_span, prompt_render_indices, record_prompt_render_index,
91    PromptSourceSpan, PromptSpanKind,
92};
93pub use stdlib::{
94    register_agent_stdlib, register_core_stdlib, register_io_stdlib, register_vm_stdlib,
95};
96pub use store::register_store_builtins;
97pub use triggers::{
98    append_dispatch_cancel_request, begin_in_flight, binding_version_as_of, clear_dispatcher_state,
99    clear_trigger_registry, drain, dynamic_deregister, dynamic_register, finish_in_flight,
100    install_manifest_triggers, parse_flow_control_duration, pin_trigger_binding, provider_metadata,
101    redact_headers, register_provider_schema, registered_provider_metadata,
102    registered_provider_schema_names, reset_provider_catalog, resolve_live_or_as_of,
103    resolve_live_trigger_binding, resolve_trigger_binding_as_of, run_trigger_harness_fixture,
104    snapshot_dispatcher_stats, snapshot_trigger_bindings, unpin_trigger_binding,
105    worker_claims_topic_name, worker_job_topic_name, worker_response_topic_name, ClaimedWorkerJob,
106    DispatchCancelRequest, DispatchError, DispatchOutcome, DispatchStatus, Dispatcher,
107    DispatcherDrainReport, DispatcherStatsSnapshot, HeaderRedactionPolicy, InboxIndex,
108    NotionPolledChangeEvent, ProviderCatalog, ProviderCatalogError, ProviderId, ProviderMetadata,
109    ProviderOutboundMethod, ProviderPayload, ProviderRuntimeMetadata, ProviderSchema,
110    ProviderSecretRequirement, RecordedTriggerBinding, RetryPolicy, SignatureStatus,
111    SignatureVerificationMetadata, TenantId, TraceId, TriggerBatchConfig, TriggerBindingSnapshot,
112    TriggerBindingSource, TriggerBindingSpec, TriggerConcurrencyConfig, TriggerDebounceConfig,
113    TriggerDispatchOutcome, TriggerEvent, TriggerEventId, TriggerExpressionSpec,
114    TriggerFlowControlConfig, TriggerHandlerSpec, TriggerHarnessResult, TriggerId,
115    TriggerMetricsSnapshot, TriggerPredicateSpec, TriggerPriorityOrderConfig,
116    TriggerRateLimitConfig, TriggerRegistryError, TriggerRetryConfig, TriggerSingletonConfig,
117    TriggerState, TriggerThrottleConfig, WorkerQueue, WorkerQueueClaimHandle,
118    WorkerQueueEnqueueReceipt, WorkerQueueJob, WorkerQueueJobState, WorkerQueuePriority,
119    WorkerQueueResponseRecord, WorkerQueueState, WorkerQueueSummary, DEFAULT_INBOX_RETENTION_DAYS,
120    TRIGGERS_LIFECYCLE_TOPIC, TRIGGER_ATTEMPTS_TOPIC, TRIGGER_CANCEL_REQUESTS_TOPIC,
121    TRIGGER_DLQ_TOPIC, TRIGGER_INBOX_CLAIMS_TOPIC, TRIGGER_INBOX_ENVELOPES_TOPIC,
122    TRIGGER_INBOX_LEGACY_TOPIC, TRIGGER_OPERATION_AUDIT_TOPIC, TRIGGER_OUTBOX_TOPIC,
123    TRIGGER_TEST_FIXTURES, WORKER_QUEUE_CATALOG_TOPIC,
124};
125pub use trust_graph::{
126    append_active_trust_record, append_trust_record, query_trust_records,
127    resolve_agent_autonomy_tier, summarize_trust_records, topic_for_agent, AutonomyTier,
128    TrustAgentSummary, TrustOutcome, TrustQueryFilters, TrustRecord, OPENTRUSTGRAPH_SCHEMA_V0,
129    TRUST_GRAPH_GLOBAL_TOPIC, TRUST_GRAPH_TOPIC_PREFIX,
130};
131pub use value::*;
132pub use vm::*;
133
134/// Lex, parse, type-check, and compile source to bytecode in one call.
135/// Bails on the first type error. For callers that need diagnostics
136/// rather than early exit, use `harn_parser::check_source` directly
137/// and then call `Compiler::new().compile(&program)`.
138pub fn compile_source(source: &str) -> Result<Chunk, String> {
139    let program = harn_parser::check_source_strict(source).map_err(|e| e.to_string())?;
140    Compiler::new().compile(&program).map_err(|e| e.to_string())
141}
142
143pub fn json_schema_for_type_expr(type_expr: &harn_parser::TypeExpr) -> Option<serde_json::Value> {
144    let schema = compiler::Compiler::type_expr_to_schema_value(type_expr)?;
145    let json_schema = schema::schema_to_json_schema_value(&schema).ok()?;
146    Some(llm::vm_value_to_json(&json_schema))
147}
148
149pub fn json_schema_for_typed_params(params: &[harn_parser::TypedParam]) -> serde_json::Value {
150    let mut properties = serde_json::Map::new();
151    let mut required = Vec::new();
152
153    for param in params {
154        let param_schema = param
155            .type_expr
156            .as_ref()
157            .and_then(json_schema_for_type_expr)
158            .unwrap_or_else(|| serde_json::json!({}));
159        if param.default_value.is_none() {
160            required.push(serde_json::Value::String(param.name.clone()));
161        }
162        properties.insert(param.name.clone(), param_schema);
163    }
164
165    let mut schema = serde_json::Map::new();
166    schema.insert(
167        "type".to_string(),
168        serde_json::Value::String("object".to_string()),
169    );
170    schema.insert(
171        "properties".to_string(),
172        serde_json::Value::Object(properties),
173    );
174    if !required.is_empty() {
175        schema.insert("required".to_string(), serde_json::Value::Array(required));
176    }
177    serde_json::Value::Object(schema)
178}
179
180/// Reset all thread-local state that can leak between test runs.
181pub fn reset_thread_local_state() {
182    llm::reset_llm_state();
183    llm_config::clear_user_overrides();
184    http::reset_http_state();
185    event_log::reset_active_event_log();
186    stdlib::reset_stdlib_state();
187    connectors::clear_active_connector_clients();
188    orchestration::clear_runtime_hooks();
189    triggers::clear_dispatcher_state();
190    triggers::clear_trigger_registry();
191    events::reset_event_sinks();
192    agent_events::reset_all_sinks();
193    agent_sessions::reset_session_store();
194    mcp_registry::reset();
195}