1#![recursion_limit = "256"]
2#![allow(clippy::result_large_err, clippy::cloned_ref_to_slice_refs)]
3
4pub use harn_clock as clock;
8
9pub mod a2a;
10pub mod agent_events;
11pub mod agent_sessions;
12pub mod atomic_io;
13pub mod autonomy;
14pub(crate) mod aws_sigv4;
15pub mod bridge;
16mod builtin_id;
17pub mod bytecode_cache;
18pub mod call_budget;
19pub mod channel_guardrails;
20pub mod channels;
21pub mod checkpoint;
22mod chunk;
23mod compiler;
24pub mod composition;
25pub mod config;
26pub mod connectors;
27pub mod corrections;
28pub(crate) mod durable_rate_limit;
29pub mod egress;
30pub mod event_log;
31pub mod events;
32pub mod external_agent;
33pub mod flow;
34pub mod harness;
35pub mod harness_auth;
36pub(crate) mod harness_crypto;
37pub mod harness_net;
38pub mod harness_system;
39pub mod harness_tenant;
40mod http;
41pub mod jsonrpc;
42pub(crate) mod limits;
43pub mod llm;
44pub mod llm_config;
45pub mod mcp;
46pub mod mcp_allowlist;
47pub mod mcp_auth;
48pub mod mcp_bulk_auth;
49pub mod mcp_card;
50pub mod mcp_elicit;
51pub mod mcp_file_upload;
52pub mod mcp_host;
53pub mod mcp_identity;
54pub mod mcp_oauth;
55pub mod mcp_presets;
56pub mod mcp_progress;
57pub mod mcp_protocol;
58pub mod mcp_registry;
59pub mod mcp_sampling;
60pub mod mcp_server;
61pub mod metadata;
62pub mod module_artifact;
63pub mod observability;
64pub mod orchestration;
65pub mod personas;
66pub mod process_sandbox;
67pub mod profile;
68pub mod provenance;
69pub mod provider_catalog;
70pub mod receipts;
71pub mod record_filter;
72pub mod redact;
73pub mod run_events;
74pub mod runtime_context;
75pub(crate) mod runtime_guards;
76pub mod runtime_limits;
77pub mod runtime_paths;
78pub mod schema;
79pub(crate) mod secret_patterns;
80pub mod secrets;
81pub mod security;
82pub mod session_bundle;
83pub mod session_timeline;
84pub mod sessions;
85pub(crate) mod shared_state;
86pub mod shells;
87pub mod skills;
88pub mod stdlib;
89pub mod stdlib_modules;
90pub mod step_runtime;
91pub mod store;
92pub(crate) mod synchronization;
93pub mod tenant;
94pub(crate) mod term;
95pub mod testbench;
96pub mod tool_annotations;
97pub mod tool_call_cancellations;
98pub mod tool_surface;
99pub mod tracing;
100pub mod triggers;
101pub mod trust_graph;
102pub(crate) mod url_encoding;
103pub mod user_dirs;
104
105pub mod clock_mock {
110 pub use crate::triggers::test_util::clock::{
111 active_mock_clock, advance, clear_overrides, install_override, instant_now, is_mocked,
112 now_ms, now_utc, sleep, ClockInstant, ClockOverrideGuard, MockClock,
113 };
114
115 pub mod leak_audit {
119 #[cfg(test)]
120 pub use crate::triggers::test_util::clock_leak::TEST_LOCK;
121 pub use crate::triggers::test_util::clock_leak::{
122 drain, instant_now, reset, snapshot, wall_now, ClockLeak,
123 };
124 }
125}
126
127pub mod typecheck;
128pub mod value;
129pub mod visible_text;
130mod vm;
131pub(crate) mod wait_for_graph;
132pub mod waitpoints;
133pub mod workspace_anchor;
134pub mod workspace_path;
135
136pub use builtin_id::BuiltinId;
137pub use call_budget::{
138 charge_mcp_call, charge_pg_query, install_mcp_call_budget, install_pg_query_budget,
139 McpCallBudgetGuard, PgQueryBudgetGuard,
140};
141pub use checkpoint::register_checkpoint_builtins;
142pub use chunk::*;
143pub use compiler::*;
144pub use connectors::{
145 active_connector_client, active_metrics_registry, clear_active_connector_clients,
146 clear_active_metrics_registry, connector_export_denied_builtin_reason,
147 connector_export_effect_class,
148 cron::{CatchupMode, CronConnector},
149 default_connector_export_policy,
150 harn_module::{
151 load_contract as load_harn_connector_contract, HarnConnector, HarnConnectorContract,
152 },
153 hmac::{verify_hmac_signed, SIGNATURE_VERIFY_AUDIT_TOPIC},
154 install_active_connector_clients, install_active_metrics_registry,
155 postprocess_normalized_event, ActivationHandle, ClientError, Connector, ConnectorClient,
156 ConnectorCtx, ConnectorError, ConnectorExportEffectClass, ConnectorHttpResponse,
157 ConnectorMetricsSnapshot, ConnectorNormalizeResult, ConnectorRegistry, GenericWebhookConnector,
158 HarnConnectorEffectPolicies, MetricsRegistry, PostNormalizeOutcome, ProviderPayloadSchema,
159 RateLimitConfig, RateLimiterFactory, RawInbound, StreamConnector, TriggerBinding, TriggerKind,
160 TriggerRegistry, WebhookSignatureVariant,
161};
162pub use corrections::{
163 append_correction_record, apply_corrections_to_policy, correction_query_filters_from_json,
164 correction_record_from_json, policy_with_corrections, query_correction_records,
165 CorrectionQueryFilters, CorrectionRecord, CorrectionScope, CORRECTIONS_TOPIC,
166 CORRECTION_EVENT_KIND, CORRECTION_SCHEMA_V0,
167};
168pub use harness::{
169 DenyEvent, Harness, HarnessCall, HarnessClock, HarnessCrypto, HarnessEnv, HarnessFs,
170 HarnessKind, HarnessLlm, HarnessNet, HarnessObs, HarnessProcess, HarnessRandom, HarnessStdio,
171 HarnessSystem, HarnessTenant, HarnessTerm, MockAwareClock, MockHarnessBuilder, VmHarness,
172};
173pub use harness_auth::{
174 current_auth_principal, enter_auth_principal, AuthPrincipal, AuthPrincipalScopeGuard,
175 MISSING_PRINCIPAL_MESSAGE,
176};
177pub use harness_net::{
178 bypass_enabled as net_policy_bypass_enabled, NetMatcher, NetPolicy, NetPolicyAudit,
179 NetPolicyDecision, NetPolicyDefault, NetPolicyRule, OnViolation, HARN_NET_POLICY_BYPASS_ENV,
180 NET_POLICY_AUDIT_TOPIC,
181};
182pub use harness_tenant::{
183 current_tenant_id, enter_tenant, TenantScopeGuard, MISSING_TENANT_MESSAGE,
184};
185pub use http::{register_http_builtins, reset_http_state};
186pub use llm::register_llm_builtins;
187pub use llm::trigger_predicate::TriggerPredicateBudget;
188pub use llm::{
189 current_agent_session_id, install_llm_cost_budget, install_llm_token_budget,
190 peek_llm_cost_budget, peek_llm_token_budget, register_session_end_hook, set_llm_cost_budget,
191 set_llm_token_budget, LlmBudgetGuard, LlmTokenBudgetGuard,
192};
193pub use mcp::{connect_mcp_server_from_json, connect_mcp_server_from_spec, register_mcp_builtins};
194pub use mcp_allowlist::{
195 build_catalog as build_mcp_catalog, catalog_for_request as mcp_catalog_for_request,
196 AdvertisedItem as McpAdvertisedItem, CatalogRequest as McpCatalogRequest, McpAllowlist,
197 McpAllowlistItem, McpCatalog, McpCatalogItem, McpCatalogServer, McpItemKind,
198 MCP_ALLOWLIST_SCHEMA_VERSION,
199};
200pub use mcp_card::{fetch_server_card, load_server_card_from_path, CardError};
201pub use mcp_host::{
202 cache_stats as mcp_host_cache_stats, set_allowlist as set_mcp_host_allowlist,
203 AllowlistDecision as McpHostAllowlistDecision, AllowlistGuard as McpHostAllowlistGuard,
204 BreakerState as McpHostBreakerState, CacheStats as McpHostCacheStats, McpHostStatus,
205 SpawnOptions as McpHostSpawnOptions, SupervisionPolicy as McpHostSupervisionPolicy,
206};
207pub use mcp_registry::{
208 active_handle as mcp_active_handle, ensure_active as mcp_ensure_active,
209 get_registration as mcp_get_registration, install_active as mcp_install_active,
210 is_registered as mcp_is_registered, register_servers as mcp_register_servers,
211 release as mcp_release, reset as mcp_reset_registry, snapshot_status as mcp_snapshot_status,
212 sweep_expired as mcp_sweep_expired, RegisteredMcpServer, RegistryStatus,
213};
214pub use mcp_server::{
215 take_mcp_serve_prompts, take_mcp_serve_registry, take_mcp_serve_resource_templates,
216 take_mcp_serve_resources, tool_registry_to_mcp_tools, McpServer,
217};
218pub use metadata::register_metadata_builtins;
219pub use observability::audit::{audit_events as audit_obs_events, AuditFinding, AuditFindingKind};
220pub use observability::request_id::{current_request_id, enter_request_id, RequestIdScopeGuard};
221pub use orchestration::{
222 benchmark_adapted_replay_pair, benchmark_replay_trace, build_replay_benchmark_report,
223 OpenCodeJsonlAdapter, ReplayBenchmarkCloudIngest, ReplayBenchmarkError,
224 ReplayBenchmarkFixtureReceipt, ReplayBenchmarkFixtureReport, ReplayBenchmarkMetrics,
225 ReplayBenchmarkReport, ReplayBenchmarkSuiteIdentity, ReplayBenchmarkSummary,
226 ReplayCategoryMetric, ReplayDebuggingProxyMetrics, ReplayRuntimeCostMetrics,
227 ReplayTraceAdapter, OPENCODE_JSONL_ADAPTER_ID, OPENCODE_JSONL_ADAPTER_SCHEMA_VERSION,
228 REPLAY_BENCHMARK_CLOUD_INGEST_KIND, REPLAY_BENCHMARK_REPORT_SCHEMA_VERSION,
229};
230pub use orchestration::{
231 canonicalize_run, first_divergence, run_replay_oracle_trace, ReplayAllowlistRule,
232 ReplayDivergence, ReplayExpectation, ReplayOracleError, ReplayOracleReport, ReplayOracleTrace,
233 ReplayTraceRun, ReplayTraceRunCounts, REPLAY_TRACE_SCHEMA_VERSION,
234};
235pub use orchestration::{
236 install_handoff_routes, snapshot_handoff_routes, HandoffRouteConfig,
237 HandoffRouteDecisionRecord, HandoffRouteTargetConfig,
238};
239pub use personas::{
240 disable_persona, fire_schedule as fire_persona_schedule, fire_trigger as fire_persona_trigger,
241 format_ms as format_persona_ms, now_ms as persona_now_ms, parse_rfc3339_ms as parse_persona_ms,
242 pause_persona, persona_status, record_persona_spend, register_persona_supervision_sink,
243 register_persona_value_sink, report_repair_worker_status, restore_persona_checkpoint,
244 resume_persona, PersonaAssignmentStatus, PersonaBudgetPolicy, PersonaBudgetStatus,
245 PersonaCheckpointAction, PersonaCheckpointRestoreOutcome, PersonaCheckpointRestoreRequest,
246 PersonaCheckpointResume, PersonaCheckpointUpdate, PersonaHandoffInboxItem, PersonaLease,
247 PersonaLifecycleState, PersonaQueuePositionUpdate, PersonaQueuedWork, PersonaReceiptUpdate,
248 PersonaRepairWorkerLifecycle, PersonaRepairWorkerStatusUpdate, PersonaRunCost,
249 PersonaRunReceipt, PersonaRuntimeBinding, PersonaStatus, PersonaSupervisionEvent,
250 PersonaSupervisionSink, PersonaSupervisionSinkRegistration, PersonaTriggerEnvelope,
251 PersonaValueEvent, PersonaValueEventKind, PersonaValueReceipt, PersonaValueSink,
252 PersonaValueSinkRegistration, StageDecl, StageExit, PERSONA_RUNTIME_TOPIC,
253};
254pub use provenance::{
255 build_signed_receipt, load_or_generate_agent_signing_key, verify_receipt, ProvenanceReceipt,
256 ReceiptBuildOptions, ReceiptVerificationReport,
257};
258pub use receipts::{
259 Receipt, ReceiptSink, ReceiptStatus, ReceiptValidationError, RedactingReceiptSink,
260 RedactionClass, RECEIPT_SCHEMA_ID, RECEIPT_SCHEMA_JSON, RECEIPT_SCHEMA_VERSION,
261};
262pub use record_filter::{normalize_record_filter_expression, CompiledRecordFilter};
263pub use runtime_limits::{
264 RuntimeLimitDescription, RuntimeLimitEntry, RuntimeLimits, RuntimeLimitsReport,
265 RUNTIME_LIMIT_DESCRIPTIONS,
266};
267pub use schema::json_to_vm_value;
268pub use sessions::{
269 CreateSession, ExpireSession, Session, SessionAttributes, SessionError, SessionStore,
270 TouchSession, SESSIONS_TOPIC,
271};
272pub use stdlib::hitl::{
273 append_hitl_response, ApprovalRequest, HitlHostResponse, HITL_APPROVALS_TOPIC,
274 HITL_DUAL_CONTROL_TOPIC, HITL_ESCALATIONS_TOPIC, HITL_QUESTIONS_TOPIC,
275};
276pub use stdlib::host::{clear_host_call_bridge, set_host_call_bridge, HostCallBridge};
277pub use stdlib::http_response::{
278 parse_envelope as parse_http_envelope, HttpEnvelope, HttpHeaderValue, WsUpgradeSpec,
279 HTTP_RESPONSE_TAG_KEY, HTTP_RESPONSE_TAG_VERSION,
280};
281#[cfg(feature = "postgres")]
282pub use stdlib::install_shared_pool_registry;
283pub use stdlib::io::{set_stdout_passthrough, take_stderr_buffer};
284pub use stdlib::long_running::cancel_handle as cancel_long_running_handle;
285pub use stdlib::observability::install_default_backend as install_obs_default_backend;
286pub use stdlib::secret_scan::{
287 append_secret_scan_audit, audit_secret_scan_active, scan_content as secret_scan_content,
288 SecretFinding, SECRET_SCAN_AUDIT_TOPIC,
289};
290pub use stdlib::template::{
291 lookup_prompt_consumers, lookup_prompt_span, prompt_render_indices, record_prompt_render_index,
292 PromptSourceSpan, PromptSpanKind,
293};
294pub use stdlib::waitpoint::{
295 process_waitpoint_resume_event, service_waitpoints_once, WAITPOINT_RESUME_TOPIC,
296};
297pub use stdlib::workflow_messages::{
298 workflow_pause_for_base, workflow_publish_query_for_base, workflow_query_for_base,
299 workflow_respond_update_for_base, workflow_resume_for_base, workflow_signal_for_base,
300 workflow_update_for_base, WorkflowMailboxState,
301};
302pub use stdlib::{
303 register_agent_stdlib, register_core_stdlib, register_io_stdlib, register_vm_stdlib,
304};
305pub use store::register_store_builtins;
306pub use tenant::{
307 tenant_event_topic_prefix, tenant_secret_namespace, tenant_topic, validate_tenant_id, ApiKeyId,
308 TenantApiKeyRecord, TenantBudget, TenantEventLog, TenantRecord, TenantRegistrySnapshot,
309 TenantResolutionError, TenantScope, TenantSecretProvider, TenantStatus, TenantStore,
310 TENANT_EVENT_TOPIC_PREFIX, TENANT_REGISTRY_DIR, TENANT_REGISTRY_FILE,
311 TENANT_SECRET_NAMESPACE_PREFIX,
312};
313pub use triggers::{
314 append_dispatch_cancel_request, begin_in_flight, binding_autonomy_budget_would_exceed,
315 binding_budget_would_exceed, binding_version_as_of, classify_trigger_dlq_error,
316 clear_dispatcher_state, clear_orchestrator_budget, clear_trigger_registry, drain,
317 dynamic_deregister, dynamic_register, expected_predicate_cost_usd_micros, finish_in_flight,
318 install_manifest_triggers, install_orchestrator_budget, install_provider_catalog,
319 micros_to_usd, note_autonomous_decision, note_orchestrator_budget_cost,
320 orchestrator_budget_would_exceed, parse_flow_control_duration, pause, pin_trigger_binding,
321 provider_metadata, record_predicate_cost_sample, redact_headers, register_provider_schema,
322 registered_provider_metadata, registered_provider_schema_names, reset_binding_budget_windows,
323 reset_provider_catalog, reset_provider_catalog_with, resolve_live_or_as_of,
324 resolve_live_trigger_binding, resolve_trigger_binding_as_of, resume,
325 run_trigger_harness_fixture, scheduler_in_flight_by_key, scheduler_ready_stats_by_key,
326 snapshot_dispatcher_stats, snapshot_orchestrator_budget, snapshot_trigger_bindings,
327 unpin_trigger_binding, usd_to_micros, worker_claims_topic_name, worker_job_topic_name,
328 worker_response_topic_name, ClaimedWorkerJob, DispatchCancelRequest, DispatchError,
329 DispatchOutcome, DispatchStatus, Dispatcher, DispatcherDrainReport, DispatcherStatsSnapshot,
330 FairnessKey, HeaderRedactionPolicy, InboxIndex, NotionPolledChangeEvent,
331 OrchestratorBudgetConfig, OrchestratorBudgetSnapshot, ProviderCatalog, ProviderCatalogError,
332 ProviderId, ProviderMetadata, ProviderOutboundMethod, ProviderPayload, ProviderRuntimeMetadata,
333 ProviderSchema, ProviderSecretRequirement, ReadyKeyStats, RecordedTriggerBinding, RetryPolicy,
334 SchedulableJob, SchedulerKeyStat, SchedulerPolicy, SchedulerSnapshot, SchedulerState,
335 SchedulerStrategy, SignatureStatus, SignatureVerificationMetadata, StreamEventPayload,
336 TenantId, TraceId, TriggerBatchConfig, TriggerBindingSnapshot, TriggerBindingSource,
337 TriggerBindingSpec, TriggerBudgetExhaustionStrategy, TriggerConcurrencyConfig,
338 TriggerDebounceConfig, TriggerDispatchOutcome, TriggerEvent, TriggerEventId,
339 TriggerExpressionSpec, TriggerFlowControlConfig, TriggerHandlerSpec, TriggerHarnessResult,
340 TriggerId, TriggerMetricsSnapshot, TriggerPredicateSpec, TriggerPriorityOrderConfig,
341 TriggerRateLimitConfig, TriggerRegistryError, TriggerRetryConfig, TriggerSingletonConfig,
342 TriggerState, TriggerThrottleConfig, WorkerQueue, WorkerQueueClaimHandle,
343 WorkerQueueEnqueueReceipt, WorkerQueueInspectSnapshot, WorkerQueueJob, WorkerQueueJobState,
344 WorkerQueuePriority, WorkerQueueResponseRecord, WorkerQueueState, WorkerQueueSummary,
345 DEFAULT_INBOX_RETENTION_DAYS, DEFAULT_STARVATION_AGE_MS, TRIGGERS_LIFECYCLE_TOPIC,
346 TRIGGER_ATTEMPTS_TOPIC, TRIGGER_CANCEL_REQUESTS_TOPIC, TRIGGER_DLQ_TOPIC,
347 TRIGGER_INBOX_CLAIMS_TOPIC, TRIGGER_INBOX_ENVELOPES_TOPIC, TRIGGER_INBOX_LEGACY_TOPIC,
348 TRIGGER_OPERATION_AUDIT_TOPIC, TRIGGER_OUTBOX_TOPIC, TRIGGER_TEST_FIXTURES,
349 WORKER_QUEUE_CATALOG_TOPIC,
350};
351pub use trust_graph::{
352 append_active_trust_record, append_trust_record, export_trust_chain,
353 group_trust_records_by_trace, policy_for_agent, policy_for_autonomy_tier,
354 query_trust_graph_records, query_trust_records, resolve_agent_autonomy_tier,
355 summarize_trust_records, topic_for_agent, trust_score_for, verify_trust_chain, AutonomyTier,
356 TrustAgentSummary, TrustChainExport, TrustChainExportMetadata, TrustChainExportProducer,
357 TrustChainReport, TrustGraphRecord, TrustOutcome, TrustQueryFilters, TrustRecord,
358 TrustRecordActionKind, TrustScore, TrustTraceGroup, METADATA_KEY_EFFECTS_GRANT,
359 METADATA_KEY_EFFECTS_USED, METADATA_KEY_PARENT_RECORD_ID, OPENTRUSTGRAPH_ACCEPTED_SCHEMAS,
360 OPENTRUSTGRAPH_CHAIN_SCHEMA_V0, OPENTRUSTGRAPH_SCHEMA_V0, OPENTRUSTGRAPH_SCHEMA_V0_1,
361 TRUST_ACTION_RELEASE, TRUST_GRAPH_GLOBAL_TOPIC, TRUST_GRAPH_LEGACY_GLOBAL_TOPIC,
362 TRUST_GRAPH_LEGACY_TOPIC_PREFIX, TRUST_GRAPH_RECORDS_TOPIC, TRUST_GRAPH_TOPIC_PREFIX,
363};
364pub use value::*;
365pub use vm::*;
366
367#[cfg(feature = "vm-bench-internals")]
368#[doc(hidden)]
369pub mod bench_internals;
370
371pub fn compile_source(source: &str) -> Result<Chunk, String> {
376 let program = harn_parser::check_source_strict(source).map_err(|e| e.to_string())?;
377 Compiler::new().compile(&program).map_err(|e| e.to_string())
378}
379
380pub fn compile_source_named(source: &str, pipeline_name: &str) -> Result<Chunk, String> {
385 let program = harn_parser::check_source_strict(source).map_err(|e| e.to_string())?;
386 let has_pipeline = program.iter().any(|sn| {
387 let (_, inner) = harn_parser::peel_attributes(sn);
388 matches!(&inner.node, harn_parser::Node::Pipeline { name, .. } if name == pipeline_name)
389 });
390 if !has_pipeline {
391 return Err(format!("no pipeline named `{pipeline_name}` in source"));
392 }
393 Compiler::new()
394 .compile_named(&program, pipeline_name)
395 .map_err(|e| e.to_string())
396}
397
398pub fn json_schema_for_type_expr(type_expr: &harn_parser::TypeExpr) -> Option<serde_json::Value> {
399 let schema = compiler::Compiler::type_expr_to_schema_value(type_expr)?;
400 let json_schema = schema::schema_to_json_schema_value(&schema).ok()?;
401 Some(llm::vm_value_to_json(&json_schema))
402}
403
404pub fn json_schema_for_typed_params(params: &[harn_parser::TypedParam]) -> serde_json::Value {
405 let mut properties = serde_json::Map::new();
406 let mut required = Vec::new();
407
408 for param in params {
409 let param_schema = param
410 .type_expr
411 .as_ref()
412 .and_then(json_schema_for_type_expr)
413 .unwrap_or_else(|| serde_json::json!({}));
414 if param.default_value.is_none() {
415 required.push(serde_json::Value::String(param.name.clone()));
416 }
417 properties.insert(param.name.clone(), param_schema);
418 }
419
420 let mut schema = serde_json::Map::new();
421 schema.insert(
422 "type".to_string(),
423 serde_json::Value::String("object".to_string()),
424 );
425 schema.insert(
426 "properties".to_string(),
427 serde_json::Value::Object(properties),
428 );
429 if !required.is_empty() {
430 schema.insert("required".to_string(), serde_json::Value::Array(required));
431 }
432 serde_json::Value::Object(schema)
433}
434
435pub fn reset_thread_local_state() {
437 llm::reset_llm_state();
438 llm::reset_rate_limit_registry();
446 llm_config::clear_user_overrides();
447 http::reset_http_state();
448 channels::reset_channel_state();
449 event_log::reset_active_event_log();
450 egress::clear_explicit_egress_policy_requirement_for_host();
451 egress::clear_ssrf_guard_requirement_for_host();
452 stdlib::reset_stdlib_state();
453 connectors::clear_active_connector_clients();
454 orchestration::clear_runtime_hooks();
455 orchestration::clear_execution_policy_stacks();
456 orchestration::clear_command_policies();
457 orchestration::clear_pipeline_on_finish();
458 orchestration::reset_lifecycle_receipt_registry();
459 orchestration::agent_inbox::reset();
460 tool_call_cancellations::reset_registry();
461 redact::clear_policy_stack();
462 security::reset_thread_state();
463 triggers::clear_dispatcher_state();
464 triggers::clear_trigger_registry();
465 events::reset_event_sinks();
466 tracing::set_tracing_enabled(false);
467 tracing::reset_tracing();
468 agent_events::reset_all_sinks();
469 agent_sessions::reset_session_store();
470 mcp_registry::reset();
471 mcp_host::reset_for_tests();
472 call_budget::reset_call_budget_state();
473 clock_mock::leak_audit::reset();
474}
475
476#[cfg(test)]
477mod reset_leak_tests {
478 use super::*;
484 use crate::value::VmValue;
485
486 #[test]
487 fn reset_drains_agent_inbox() {
488 orchestration::agent_inbox::reset();
489 orchestration::agent_inbox::push("sess-2660", "note", "leak", "test");
490 assert!(orchestration::agent_inbox::session_count() > 0);
491 reset_thread_local_state();
492 assert_eq!(
493 orchestration::agent_inbox::session_count(),
494 0,
495 "agent_inbox must be empty after reset"
496 );
497 }
498
499 #[test]
500 fn reset_drains_tool_call_cancellation_registry() {
501 tool_call_cancellations::reset_registry();
502 let registered = tool_call_cancellations::register("sess-2660", "call-1", "tool");
505 if let Some((_handle, guard)) = registered {
506 std::mem::forget(guard);
507 }
508 assert!(tool_call_cancellations::registry_len() > 0);
509 reset_thread_local_state();
510 assert_eq!(
511 tool_call_cancellations::registry_len(),
512 0,
513 "tool-call cancellation registry must be empty after reset"
514 );
515 }
516
517 #[test]
518 fn reset_drains_routing_policy_registry() {
519 llm::routing::clear_policy_registry();
520 let mut config: crate::value::DictMap = crate::value::DictMap::new();
521 config.insert(
522 "chain".to_string(),
523 VmValue::List(std::sync::Arc::new(vec![VmValue::String(
524 std::sync::Arc::from("mock:mock"),
525 )])),
526 );
527 llm::routing::build_routing_policy(&config).expect("intern a routing policy");
528 assert!(llm::routing::policy_registry_len() > 0);
529 reset_thread_local_state();
530 assert_eq!(
531 llm::routing::policy_registry_len(),
532 0,
533 "routing policy registry must be empty after reset"
534 );
535 }
536}