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