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