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