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