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