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 llm::{
80    current_agent_session_id, drain_global_pending_feedback, push_pending_feedback_global,
81    register_session_end_hook,
82};
83pub use mcp::{
84    connect_mcp_server, connect_mcp_server_from_json, connect_mcp_server_from_spec,
85    register_mcp_builtins,
86};
87pub use mcp_card::{fetch_server_card, load_server_card_from_path, CardError};
88pub use mcp_registry::{
89    active_handle as mcp_active_handle, ensure_active as mcp_ensure_active,
90    get_registration as mcp_get_registration, install_active as mcp_install_active,
91    is_registered as mcp_is_registered, register_servers as mcp_register_servers,
92    release as mcp_release, reset as mcp_reset_registry, snapshot_status as mcp_snapshot_status,
93    sweep_expired as mcp_sweep_expired, RegisteredMcpServer, RegistryStatus,
94};
95pub use mcp_server::{
96    take_mcp_serve_prompts, take_mcp_serve_registry, take_mcp_serve_resource_templates,
97    take_mcp_serve_resources, tool_registry_to_mcp_tools, McpServer,
98};
99pub use metadata::{register_metadata_builtins, register_scan_builtins};
100pub use personas::{
101    disable_persona, fire_schedule as fire_persona_schedule, fire_trigger as fire_persona_trigger,
102    format_ms as format_persona_ms, now_ms as persona_now_ms, parse_rfc3339_ms as parse_persona_ms,
103    pause_persona, persona_status, record_persona_spend, register_persona_value_sink,
104    resume_persona, PersonaBudgetPolicy, PersonaBudgetStatus, PersonaLease, PersonaLifecycleState,
105    PersonaRunCost, PersonaRunReceipt, PersonaRuntimeBinding, PersonaStatus,
106    PersonaTriggerEnvelope, PersonaValueEvent, PersonaValueEventKind, PersonaValueSink,
107    PersonaValueSinkRegistration, PERSONA_RUNTIME_TOPIC,
108};
109pub use record_filter::{normalize_record_filter_expression, CompiledRecordFilter};
110pub use schema::json_to_vm_value;
111pub use stdlib::hitl::{
112    append_hitl_response, HitlHostResponse, HITL_APPROVALS_TOPIC, HITL_DUAL_CONTROL_TOPIC,
113    HITL_ESCALATIONS_TOPIC, HITL_QUESTIONS_TOPIC,
114};
115pub use stdlib::host::{clear_host_call_bridge, set_host_call_bridge, HostCallBridge};
116pub use stdlib::io::take_stderr_buffer;
117pub use stdlib::secret_scan::{
118    append_secret_scan_audit, audit_secret_scan_active, scan_content as secret_scan_content,
119    SecretFinding, SECRET_SCAN_AUDIT_TOPIC,
120};
121pub use stdlib::template::{
122    lookup_prompt_consumers, lookup_prompt_span, prompt_render_indices, record_prompt_render_index,
123    PromptSourceSpan, PromptSpanKind,
124};
125pub use stdlib::waitpoint::{
126    process_waitpoint_resume_event, service_waitpoints_once, WAITPOINT_RESUME_TOPIC,
127};
128pub use stdlib::workflow_messages::{
129    workflow_pause_for_base, workflow_publish_query_for_base, workflow_query_for_base,
130    workflow_respond_update_for_base, workflow_resume_for_base, workflow_signal_for_base,
131    workflow_update_for_base, WorkflowMailboxState,
132};
133pub use stdlib::{
134    register_agent_stdlib, register_core_stdlib, register_io_stdlib, register_vm_stdlib,
135};
136pub use store::register_store_builtins;
137pub use tenant::{
138    tenant_event_topic_prefix, tenant_secret_namespace, tenant_topic, validate_tenant_id, ApiKeyId,
139    TenantApiKeyRecord, TenantBudget, TenantEventLog, TenantRecord, TenantRegistrySnapshot,
140    TenantResolutionError, TenantScope, TenantSecretProvider, TenantStatus, TenantStore,
141    TENANT_EVENT_TOPIC_PREFIX, TENANT_REGISTRY_DIR, TENANT_REGISTRY_FILE,
142    TENANT_SECRET_NAMESPACE_PREFIX,
143};
144pub use triggers::{
145    append_dispatch_cancel_request, begin_in_flight, binding_autonomy_budget_would_exceed,
146    binding_budget_would_exceed, binding_version_as_of, classify_trigger_dlq_error,
147    clear_dispatcher_state, clear_orchestrator_budget, clear_trigger_registry, drain,
148    dynamic_deregister, dynamic_register, expected_predicate_cost_usd_micros, finish_in_flight,
149    install_manifest_triggers, install_orchestrator_budget, micros_to_usd,
150    note_autonomous_decision, note_orchestrator_budget_cost, orchestrator_budget_would_exceed,
151    parse_flow_control_duration, pin_trigger_binding, provider_metadata,
152    record_predicate_cost_sample, redact_headers, register_provider_schema,
153    registered_provider_metadata, registered_provider_schema_names, reset_binding_budget_windows,
154    reset_provider_catalog, reset_provider_catalog_with, resolve_live_or_as_of,
155    resolve_live_trigger_binding, resolve_trigger_binding_as_of, run_trigger_harness_fixture,
156    scheduler_in_flight_by_key, scheduler_ready_stats_by_key, snapshot_dispatcher_stats,
157    snapshot_orchestrator_budget, snapshot_trigger_bindings, unpin_trigger_binding, usd_to_micros,
158    worker_claims_topic_name, worker_job_topic_name, worker_response_topic_name, ClaimedWorkerJob,
159    DispatchCancelRequest, DispatchError, DispatchOutcome, DispatchStatus, Dispatcher,
160    DispatcherDrainReport, DispatcherStatsSnapshot, FairnessKey, HeaderRedactionPolicy, InboxIndex,
161    NotionPolledChangeEvent, OrchestratorBudgetConfig, OrchestratorBudgetSnapshot, ProviderCatalog,
162    ProviderCatalogError, ProviderId, ProviderMetadata, ProviderOutboundMethod, ProviderPayload,
163    ProviderRuntimeMetadata, ProviderSchema, ProviderSecretRequirement, ReadyKeyStats,
164    RecordedTriggerBinding, RetryPolicy, SchedulableJob, SchedulerKeyStat, SchedulerPolicy,
165    SchedulerSnapshot, SchedulerState, SchedulerStrategy, SignatureStatus,
166    SignatureVerificationMetadata, StreamEventPayload, TenantId, TraceId, TriggerBatchConfig,
167    TriggerBindingSnapshot, TriggerBindingSource, TriggerBindingSpec,
168    TriggerBudgetExhaustionStrategy, TriggerConcurrencyConfig, TriggerDebounceConfig,
169    TriggerDispatchOutcome, TriggerEvent, TriggerEventId, TriggerExpressionSpec,
170    TriggerFlowControlConfig, TriggerHandlerSpec, TriggerHarnessResult, TriggerId,
171    TriggerMetricsSnapshot, TriggerPredicateSpec, TriggerPriorityOrderConfig,
172    TriggerRateLimitConfig, TriggerRegistryError, TriggerRetryConfig, TriggerSingletonConfig,
173    TriggerState, TriggerThrottleConfig, WorkerQueue, WorkerQueueClaimHandle,
174    WorkerQueueEnqueueReceipt, WorkerQueueInspectSnapshot, WorkerQueueJob, WorkerQueueJobState,
175    WorkerQueuePriority, WorkerQueueResponseRecord, WorkerQueueState, WorkerQueueSummary,
176    DEFAULT_INBOX_RETENTION_DAYS, DEFAULT_STARVATION_AGE_MS, TRIGGERS_LIFECYCLE_TOPIC,
177    TRIGGER_ATTEMPTS_TOPIC, TRIGGER_CANCEL_REQUESTS_TOPIC, TRIGGER_DLQ_TOPIC,
178    TRIGGER_INBOX_CLAIMS_TOPIC, TRIGGER_INBOX_ENVELOPES_TOPIC, TRIGGER_INBOX_LEGACY_TOPIC,
179    TRIGGER_OPERATION_AUDIT_TOPIC, TRIGGER_OUTBOX_TOPIC, TRIGGER_TEST_FIXTURES,
180    WORKER_QUEUE_CATALOG_TOPIC,
181};
182pub use trust_graph::{
183    append_active_trust_record, append_trust_record, group_trust_records_by_trace,
184    policy_for_agent, policy_for_autonomy_tier, query_trust_records, resolve_agent_autonomy_tier,
185    summarize_trust_records, topic_for_agent, trust_score_for, verify_trust_chain, AutonomyTier,
186    TrustAgentSummary, TrustChainReport, TrustOutcome, TrustQueryFilters, TrustRecord, TrustScore,
187    TrustTraceGroup, OPENTRUSTGRAPH_SCHEMA_V0, TRUST_GRAPH_GLOBAL_TOPIC,
188    TRUST_GRAPH_LEGACY_GLOBAL_TOPIC, TRUST_GRAPH_LEGACY_TOPIC_PREFIX, TRUST_GRAPH_TOPIC_PREFIX,
189};
190pub use value::*;
191pub use vm::*;
192
193/// Lex, parse, type-check, and compile source to bytecode in one call.
194/// Bails on the first type error. For callers that need diagnostics
195/// rather than early exit, use `harn_parser::check_source` directly
196/// and then call `Compiler::new().compile(&program)`.
197pub fn compile_source(source: &str) -> Result<Chunk, String> {
198    let program = harn_parser::check_source_strict(source).map_err(|e| e.to_string())?;
199    Compiler::new().compile(&program).map_err(|e| e.to_string())
200}
201
202pub fn json_schema_for_type_expr(type_expr: &harn_parser::TypeExpr) -> Option<serde_json::Value> {
203    let schema = compiler::Compiler::type_expr_to_schema_value(type_expr)?;
204    let json_schema = schema::schema_to_json_schema_value(&schema).ok()?;
205    Some(llm::vm_value_to_json(&json_schema))
206}
207
208pub fn json_schema_for_typed_params(params: &[harn_parser::TypedParam]) -> serde_json::Value {
209    let mut properties = serde_json::Map::new();
210    let mut required = Vec::new();
211
212    for param in params {
213        let param_schema = param
214            .type_expr
215            .as_ref()
216            .and_then(json_schema_for_type_expr)
217            .unwrap_or_else(|| serde_json::json!({}));
218        if param.default_value.is_none() {
219            required.push(serde_json::Value::String(param.name.clone()));
220        }
221        properties.insert(param.name.clone(), param_schema);
222    }
223
224    let mut schema = serde_json::Map::new();
225    schema.insert(
226        "type".to_string(),
227        serde_json::Value::String("object".to_string()),
228    );
229    schema.insert(
230        "properties".to_string(),
231        serde_json::Value::Object(properties),
232    );
233    if !required.is_empty() {
234        schema.insert("required".to_string(), serde_json::Value::Array(required));
235    }
236    serde_json::Value::Object(schema)
237}
238
239/// Reset all thread-local state that can leak between test runs.
240pub fn reset_thread_local_state() {
241    llm::reset_llm_state();
242    llm_config::clear_user_overrides();
243    http::reset_http_state();
244    event_log::reset_active_event_log();
245    stdlib::reset_stdlib_state();
246    connectors::clear_active_connector_clients();
247    orchestration::clear_runtime_hooks();
248    triggers::clear_dispatcher_state();
249    triggers::clear_trigger_registry();
250    events::reset_event_sinks();
251    agent_events::reset_all_sinks();
252    agent_sessions::reset_session_store();
253    mcp_registry::reset();
254}