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