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