hermes-agent/tests/agent
dsad 3c4220cd9c fix(agent): keep system cache breakpoints across provider failover
`apply_anthropic_cache_control` runs once per call block, before the retry
loop, and splits the system prompt into `[static prefix, volatile tail]` text
blocks carrying the cache_control breakpoints.

A failover fires *inside* that retry loop, and `_sync_failover_system_message`
assigns a bare string over `api_messages[0]["content"]` to refresh the
`Model:`/`Provider:` identity lines. That drops the block list and both
breakpoints. `convert_messages_to_anthropic` only emits system cache blocks for
list content (`isinstance(content, list)`), so the retried request ships
`system` as one plain string: zero breakpoints, nothing written to cache, and
the whole system prompt re-billed at full write price. The next call misses
too, so a failover costs two full-price prompts instead of one write + one
read.

Measured with the real functions, same history, native Anthropic layout:

  normal turn       system=BLOCK LIST(2)  system breakpoints=2
  after failover    system=plain string   system breakpoints=0

`_sync_failover_system_message`'s own docstring notes this fires on "every
gateway turn, since fallback re-activates per message while the primary is
down" -- so a gateway running on a degraded primary pays it on every message.

Fix: rewrite the decorated blocks in place instead of flattening them.
`rewrite_prompt_model_identity` only touches the LAST `Model:`/`Provider:`
lines, and those live in the volatile tail, so the static prefix stays
byte-identical and its cache entry keeps matching -- the failover retry keeps
both breakpoints AND the warm prefix. Shapes we cannot safely patch fall back
to the existing plain-string assignment.

This is the same class the retry loop already guards against eight lines below
the gap, for reasoning fields:

    # api_messages is built once, before this retry loop, while the primary
    # provider is active. [...] so the fallback request isn't sent with stale,
    # primary-shaped reasoning fields.
    agent._reapply_reasoning_echo_for_provider(api_messages)

There was no equivalent for cache decoration.
2026-07-26 19:42:43 -07:00
..
lsp refactor(lsp): version-tagged _DocState replaces timestamp freshness tracking 2026-07-20 13:43:36 -04:00
transports fix(codex): scope 24h retention to Bedrock Mantle 2026-07-24 15:54:08 -07:00
__init__.py
test_account_usage.py
test_anthropic_adapter.py fix(anthropic): keep the assistant cache breakpoint on the ordered-replay path 2026-07-26 19:29:51 -07:00
test_anthropic_billing_guidance.py
test_anthropic_keychain.py
test_anthropic_kimi_signed_thinking_replay.py test: fix stale k3 fixture in deepseek signed-thinking replay test 2026-07-20 08:47:55 -07:00
test_anthropic_kwargs_sanitize.py
test_anthropic_mcp_prefix_strip.py
test_anthropic_oauth_pkce.py
test_anthropic_oauth_ua_prefix.py
test_anthropic_output_field_leak.py
test_anthropic_thinking_block_order.py
test_anthropic_whitespace_text_blocks.py fix(anthropic): keep replay content schema-valid when every block is blank 2026-07-24 15:54:38 -07:00
test_api_content_sidecar.py fix(agent): keep the compaction summary when the turn-end override rewrites the user row 2026-07-26 19:30:08 -07:00
test_arcee_trinity_overrides.py
test_async_utils.py
test_aux_progress_streaming.py feat(aux): force streaming for providers that reject non-stream requests 2026-07-25 14:58:04 -07:00
test_auxiliary_anthropic_pool_fallback_regression.py
test_auxiliary_client.py feat(compression): progress-aware timeouts — stop punishing slow summary models 2026-07-25 12:26:28 -07:00
test_auxiliary_client_anthropic_custom.py
test_auxiliary_client_azure_foundry.py
test_auxiliary_client_base_url_host_validation_52608.py
test_auxiliary_client_bootstrap_skew.py
test_auxiliary_client_proxy_env.py
test_auxiliary_client_resolve_dedup.py
test_auxiliary_client_ssl_verify.py
test_auxiliary_client_xai_oauth_recovery.py
test_auxiliary_compression_timeout_floor.py
test_auxiliary_config_bridge.py
test_auxiliary_main_first.py
test_auxiliary_named_custom_providers.py
test_auxiliary_runtime_cache_key.py
test_auxiliary_transient_retry.py
test_auxiliary_transport_autodetect.py
test_auxiliary_user_default_headers.py
test_azure_identity_adapter.py
test_battery.py feat(status-bar): add /battery toggle for a color-coded battery read-out 2026-07-21 13:54:11 -05:00
test_bedrock_1m_context.py
test_bedrock_adapter.py feat(bedrock): add Converse API prompt caching (cachePoint) 2026-07-23 11:45:07 -07:00
test_bedrock_empty_text_blocks.py fix(bedrock): use non-whitespace placeholder for empty text blocks 2026-07-20 03:27:38 -07:00
test_bedrock_integration.py
test_bedrock_interrupt_post_worker.py
test_billing_links.py feat(billing): shared cross-surface out-of-credits signal 2026-07-22 18:08:59 -05:00
test_billing_usage.py
test_billing_view.py feat(billing): carry the payment-method union through to clients (#71542) 2026-07-27 01:49:43 +05:30
test_bounded_response.py
test_cascading_interrupt_6600.py
test_chat_completion_helpers_provider_sort.py
test_cjk_token_estimation.py perf(compression): gate CJK-aware token estimation behind an ASCII fast path 2026-07-22 06:57:22 -07:00
test_close_interrupted_tool_sequence.py
test_codex_app_server_event_bridge.py
test_codex_app_server_persist.py feat(codex): honor redirect and hard stop in the app-server runtime 2026-07-22 12:02:40 -05:00
test_codex_cloudflare_headers.py
test_codex_gpt55_autoraise_notice.py
test_codex_responses_adapter.py
test_codex_runtime_live_events.py
test_codex_ttfb_watchdog.py
test_coding_context.py
test_compaction_anti_thrash.py
test_compaction_redaction_boundaries.py fix(compression): apply strict redaction at every compaction text boundary (#69294) 2026-07-22 08:11:40 -07:00
test_compress_focus.py
test_compress_signal_leak.py fix: prevent stale lock-skip signal leaking between compress_context calls 2026-07-23 08:19:14 -07:00
test_compressed_summary_metadata.py test(compression): pin classify_summary_content agreement with summary predicates on live emissions 2026-07-22 16:58:35 -07:00
test_compression_anti_thrash_persistence.py fix(compression): persist anti-thrash state across process restarts (#69872) 2026-07-23 08:08:48 -07:00
test_compression_anti_thrash_recovery.py fix(compression): add recovery path to anti-thrash auto-compaction block 2026-07-24 15:57:09 -07:00
test_compression_attempt_telemetry.py fix: adapt compression attempt logging to current main aux-call contract 2026-07-22 08:13:41 -07:00
test_compression_concurrent_fork.py fix(compression-lock): reclaim crashed holders instead of stranding the lease 2026-07-25 22:47:07 -07:00
test_compression_count_warning_36908.py
test_compression_fallback_budget.py
test_compression_interrupt_protection.py
test_compression_logging_session_context.py
test_compression_max_attempts_config.py fix(compression): unify the attempt cap across every compression site 2026-07-22 06:56:42 -07:00
test_compression_progress.py fix(compression): prevent stale-budget retry loops 2026-07-22 11:19:37 +05:30
test_compression_rotation_state.py fix(compression): recover rotated session lineage 2026-07-24 16:00:34 -07:00
test_compression_small_ctx_threshold_floor.py
test_compressor_actionable_tail_anchor.py test(compression): cover leading and input-text blanks 2026-07-22 08:10:47 -07:00
test_compressor_assistant_tail_anchor.py fix(compression): ignore assistant handoff summaries in tail anchor 2026-07-22 11:46:05 +05:30
test_compressor_historical_media.py
test_compressor_image_tokens.py
test_compressor_media_stripping.py
test_compressor_tail_cut_tool_pair_floor.py fix(compression): stop the progress floor from splitting a tool group 2026-07-20 11:58:50 +05:30
test_compressor_tool_call_budget.py perf(compression): gate CJK-aware token estimation behind an ASCII fast path 2026-07-22 06:57:22 -07:00
test_compressor_zero_user_guard.py
test_context_breakdown.py feat(cli,gateway): unify /context into a visual context-usage breakdown 2026-07-26 18:06:21 -07:00
test_context_compressor.py fix(compress): gate N-user tail guarantee to actionable turns, behavior-preserving default 2026-07-23 17:03:49 -07:00
test_context_compressor_cross_session_guard.py
test_context_compressor_session_end_clears_state.py fix(compression): preserve zero-user provenance 2026-07-22 06:56:53 -07:00
test_context_compressor_summary_continuity.py fix(compression): skip empty post-handoff summary windows 2026-07-23 16:27:06 -07:00
test_context_compressor_temporal_anchoring.py
test_context_compressor_zero_user_provenance.py fix(compression): preserve synthetic user provenance 2026-07-22 06:56:53 -07:00
test_context_engine.py feat(compression): proactive tool-result pruning for large-window models 2026-07-23 16:44:12 -07:00
test_context_engine_host_contract.py
test_context_engine_on_turn_complete_usage.py docs+test(context-engine): sync public guide coverage note; pin finalization-seam observation contract 2026-07-23 19:44:35 -07:00
test_context_engine_select_context.py fix(context-engine): short-circuit the inherited no-op select_context before any per-request work 2026-07-23 19:44:35 -07:00
test_context_references.py fix(desktop): quote persisted @image: paths so spaced paths render 2026-07-24 21:20:52 -05:00
test_context_refs_concurrent.py
test_copilot_acp_client.py fix: decode config and state files as UTF-8 on non-UTF-8 locales 2026-07-24 17:10:39 -07:00
test_copilot_acp_deprecation.py
test_credential_pool.py fix: resolve current entry unlocked in try_refresh_matching no-hint branch 2026-07-23 09:31:58 -07:00
test_credential_pool_no_entries_log_throttle.py
test_credential_pool_oat_authtype.py
test_credential_pool_oauth_writethrough.py
test_credential_pool_provider_boundary.py
test_credential_pool_routing.py fix(auth): stop stale-key credential recovery loops 2026-07-24 22:58:47 +05:30
test_credential_pool_unmatched_rotation_bound.py fix: break unbounded 401 retry loop in credential pool OAuth path 2026-07-24 15:50:36 -07:00
test_credits_cold_start.py
test_credits_fixture_snapshot.py
test_credits_policy.py feat(credits): report $used of $cap instead of % in the usage notice 2026-07-23 01:28:58 -05:00
test_credits_tracker.py
test_credits_view.py
test_cron_inline_api_call_62151.py
test_crossloop_client_cache.py
test_curator.py
test_curator_activity.py
test_curator_backup.py
test_curator_classification.py
test_curator_reports.py
test_custom_pool_mismatch_guard.py
test_custom_provider_extra_body.py
test_custom_provider_extra_body_matching.py
test_custom_providers_vision.py fix: preserve named custom provider vision overrides 2026-07-23 17:57:33 +05:30
test_deepseek_anthropic_thinking.py
test_direct_provider_url_detection.py
test_display.py
test_display_emoji.py
test_display_todo_progress.py
test_display_tool_failure.py
test_empty_tool_name_loop_dampening.py fix(agent): close tool-result tails on invalid-tool and truncated-tool early returns 2026-07-23 17:38:05 +05:30
test_engine_preflight_wire.py fix(agent): wire should_compress_preflight into the turn-start preflight flow 2026-07-23 07:25:08 -07:00
test_error_classifier.py
test_external_skills.py
test_external_skills_dirs_cache.py
test_failover_identity.py fix(agent): keep system cache breakpoints across provider failover 2026-07-26 19:42:43 -07:00
test_file_safety.py
test_file_safety_container_mirror.py
test_file_safety_credentials.py
test_file_safety_cross_profile.py
test_file_safety_sandbox_mirror.py
test_file_safety_session_state.py
test_gateway_turn_sidecar.py
test_gemini_fast_fallback.py
test_gemini_free_tier_gate.py
test_gemini_native_adapter.py fix(gemini): emit thoughtSignature sentinel for cross-provider tool_calls in native adapter 2026-07-23 17:26:24 -07:00
test_gemini_schema.py
test_ghost_skill_pruning.py fix(compression): mark raw skill_view bodies summarized away, not only pre-pruned rows 2026-07-23 16:58:06 -07:00
test_i18n.py rip out brew + pip/PyPI wheel support (#68217) 2026-07-22 16:51:01 -04:00
test_idle_compaction.py feat(compression): add opt-in idle-triggered context compaction 2026-07-22 09:14:11 -07:00
test_idle_compaction_lock_and_guards.py fix(compression): persist anti-thrash state across process restarts (#69872) 2026-07-23 08:08:48 -07:00
test_image_gen_registry.py
test_image_routing.py feat(image_routing): accept vision alias for custom provider models 2026-07-23 08:32:09 -07:00
test_insights.py
test_intent_ack_continuation.py
test_jiter_preload.py
test_kanban_stop.py
test_kimi_coding_anthropic_thinking.py
test_last_total_tokens.py
test_learn_prompt.py
test_learning_graph.py
test_learning_graph_render.py
test_learning_mutations.py
test_lmstudio_reasoning.py
test_local_stream_timeout.py
test_manual_compression_feedback.py fix(compress): classify unconfirmed lock-acquire failures and cover all manual-compress surfaces 2026-07-23 08:19:14 -07:00
test_markdown_tables.py
test_memory_async_sync.py
test_memory_boundary_commit.py
test_memory_provider.py fix(memory): honor disabled toolsets for provider tools 2026-07-24 13:00:53 +05:30
test_memory_session_switch.py
test_memory_skill_scaffolding.py
test_memory_user_id.py
test_memory_write_bridge.py
test_message_content.py
test_minimax_auxiliary_url.py
test_minimax_provider.py feat(models): add Claude Sonnet 5 support 2026-07-20 02:25:44 -07:00
test_moa_aggregator_cache_control.py
test_moa_aggregator_cost_slot.py
test_moa_context_max_tokens.py fix(moa): stop reference_max_tokens from also capping the aggregator 2026-07-23 16:17:27 -07:00
test_moa_progress.py feat(agent): add MOA progress indicator (#59546) 2026-07-23 18:11:57 -07:00
test_moa_quiet_reference_output.py fix(moa): scope quiet relay to machine-readable CLI 2026-07-23 18:40:09 -07:00
test_moa_reasoning_effort.py
test_moa_reference_system_prompt.py chore(moa): add trailing newline to reference-prompt test file 2026-07-23 18:40:09 -07:00
test_moa_slot_api_mode.py test(moa): cover the one-shot /moa aggregator path for slot extra_body 2026-07-23 11:20:54 -07:00
test_moa_slot_max_tokens.py feat(moa): per-reference-model max_tokens override 2026-07-23 16:17:27 -07:00
test_moa_switch_api_mode.py
test_moa_trace_streamed_capture.py
test_model_extra_type_guard.py
test_model_metadata.py fix(moa): preserve custom provider context metadata 2026-07-23 11:21:04 -07:00
test_model_metadata_local_ctx.py
test_model_metadata_ssl.py
test_models_dev.py
test_moonshot_schema.py fix(agent): inject empty required array on Moonshot object schemas 2026-07-20 11:05:52 -07:00
test_non_stream_stale_timeout.py
test_none_deref_guards.py
test_nous_credits_gauge.py
test_nous_credits_snapshot.py
test_nous_oauth_401_guidance.py
test_nous_rate_guard.py fix: decode config and state files as UTF-8 on non-UTF-8 locales 2026-07-24 17:10:39 -07:00
test_onboarding.py
test_oneshot.py
test_openrouter_response_cache.py
test_pet_engine.py
test_pet_generate.py
test_platform_hint_desktop.py
test_platform_hint_overrides.py
test_plugin_llm.py
test_portal_tags.py fix(nous-portal): give auxiliary calls the Portal sticky routing key 2026-07-25 22:15:00 -07:00
test_pre_compress_memory_context.py fix(redaction): normalize URL credential key aliases 2026-07-20 02:25:57 -07:00
test_preflight_compression_gate.py
test_preflight_lock_defer.py fix(gateway): retry-next-message semantics for compression_deferred + regression suite 2026-07-23 16:23:57 -07:00
test_proactive_prune_config.py feat(compression): prompt-cache reclaim gate + hardened wiring for proactive prune 2026-07-23 16:44:12 -07:00
test_proactive_tool_result_pruning.py feat(compression): prompt-cache reclaim gate + hardened wiring for proactive prune 2026-07-23 16:44:12 -07:00
test_probe_cache_followups.py
test_prompt_builder.py fix(prompt): scope api_server MEDIA: hint to actual interception behavior 2026-07-23 11:55:01 -07:00
test_prompt_caching.py fix(prompt-caching): inject cache breakpoints after message normalization 2026-07-24 16:01:38 -07:00
test_protected_tail_pressure_61932.py test(agent): pin the #61932 all-oversized-tail dead-end shape as compressible 2026-07-23 07:25:33 -07:00
test_proxy_and_url_validation.py
test_rate_limit_tracker.py
test_reactions.py
test_reasoning_stale_timeout_floor.py feat(x_search): default model grok-4.20-reasoning -> grok-4.5 (#67719) 2026-07-19 16:32:20 -07:00
test_redact.py fix(redaction): cover strict URL reference forms 2026-07-20 02:25:57 -07:00
test_replay_cleanup.py
test_restore_primary_pool_reselect.py
test_resume_stale_active_task.py
test_rotation_flush_persisted_boundary_68196.py fix(agent): pass persisted-prefix boundary when rotation flushes on cold resume (#68196) 2026-07-21 12:11:31 +05:30
test_runtime_cwd.py
test_save_url_image.py
test_secret_scope.py fix(secrets): scope BWS-injected provider keys 2026-07-22 04:39:17 -07:00
test_session_rotation_flush_cold_resume_68454.py test: drop source-grep change-detector from #68480 2026-07-22 10:00:39 +05:30
test_set_runtime_main_custom_provider.py
test_shell_hooks.py
test_shell_hooks_consent.py
test_skill_bundles.py
test_skill_commands.py
test_skill_commands_reload.py
test_skill_invocation_description.py feat(skills): describe a /skill turn the way the user typed it 2026-07-26 02:58:12 -05:00
test_skill_utils.py
test_skip_memory_store_65429.py test(memory): behavioral check — memory tool handler works with skip_memory=True, provider stays skipped 2026-07-22 07:00:16 -07:00
test_ssl_ca_guard.py
test_ssl_verify.py
test_stream_read_timeout_floor.py
test_stream_single_writer_guard.py
test_streaming_context_scrubber.py
test_subagent_progress.py
test_subagent_stop_hook.py
test_subdirectory_hints.py
test_subdirectory_hints_tilde.py
test_subscription_view.py feat(cli): plan catalog on Free + plan= deep link + top-up/auto-refill copy split (#68689) 2026-07-22 08:11:09 +05:30
test_summarize_tool_result_type_safety.py
test_summary_prefix_semantics.py test(compaction): byte-pin every frozen prefix generation 2026-07-24 15:48:23 -07:00
test_summary_prefix_tool_use.py fix(compaction): freeze pre-change SUMMARY_PREFIX generation, restore mutated entry 2026-07-24 15:48:23 -07:00
test_system_prompt.py fix(agent): cache static system prompt prefixes 2026-07-24 16:01:38 -07:00
test_system_prompt_restore.py fix(caching): reconstruct static system prefix on session restore and post-compression reuse 2026-07-24 16:01:38 -07:00
test_think_scrubber.py
test_thinking_timeout_guidance.py
test_thread_scoped_output.py
test_title_generator.py fix(sessions): stop titling a session after the skill it invoked 2026-07-26 02:58:16 -05:00
test_tool_call_arg_no_redaction.py
test_tool_dispatch_helpers.py
test_tool_executor_checkpoint_paths.py fix(checkpoints): honor gateway config and task cwd (#68195) 2026-07-20 13:04:12 -07:00
test_tool_guardrails.py
test_tool_result_classification.py
test_trace_upload.py
test_transcription_registry.py
test_tts_registry.py
test_turn_context.py fix(compression): recover rotated session lineage 2026-07-24 16:00:34 -07:00
test_turn_context_overflow_warning.py fix(compression): reset blocked-overflow dedup on every compression path + noise-filter survival pins 2026-07-23 08:43:21 -07:00
test_turn_finalizer_cleanup_guard.py
test_turn_finalizer_final_response_persistence.py
test_turn_finalizer_interrupt_alternation.py
test_turn_finalizer_iteration_limit_exit.py fix(desktop, ink): don't wipe messages before final message (#65919) 2026-07-20 11:42:29 -04:00
test_turn_overlap_tripwire.py
test_turn_retry_state.py feat(agent): add active-turn redirect core primitive 2026-07-22 12:02:40 -05:00
test_turn_summary.py fix(cli): report unknown line deltas for content-free diffs instead of +0 -0 2026-07-26 17:47:51 -07:00
test_unsupported_parameter_retry.py
test_unsupported_temperature_retry.py
test_usage_pricing.py feat(bedrock): add Converse API prompt caching (cachePoint) 2026-07-23 11:45:07 -07:00
test_verification_evidence.py fix(desktop, ink): don't wipe messages before final message (#65919) 2026-07-20 11:42:29 -04:00
test_verification_evidence_fd_leak.py fix(gateway,tools,agent): close leaked SQLite connections in delivery, delegation, and verification ledgers 2026-07-24 15:55:08 -07:00
test_verification_stop.py
test_verification_stop_caching.py fix(desktop, ink): don't wipe messages before final message (#65919) 2026-07-20 11:42:29 -04:00
test_verify_hooks.py
test_vertex_adapter.py
test_video_gen_registry.py
test_vision_resolved_args.py
test_vision_routing_31179.py