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