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