hermes-agent/tests
Teknium 031f9c9edc
fix(image_gen): cache xAI ephemeral URL responses to disk (#26942) (#31759)
xAI's grok-imagine-image API returns ephemeral imgen.x.ai/xai-tmp-* URLs
that 404 within minutes — long before downstream consumers (Telegram
send_photo, browser preview, multi-tier delivery fallback) get a chance
to fetch them.  The xAI image_gen provider was passing those URLs
through unchanged on the elif url: branch; b64 responses were already
cached locally via save_b64_image.  Result: every image_generate call
on a Telegram-routed xai-oauth profile delivered no image, falling
through to text-only.

Adds agent.image_gen_provider.save_url_image() — a sibling helper to
save_b64_image that downloads URL bytes to $HERMES_HOME/cache/images/.
Content-type-aware extension inference with URL-suffix fallback;
oversize cap (25MB default) with partial-write cleanup; empty-body
refusal.  Mirrors the audio_cache pattern used by text_to_speech.

Wires save_url_image into both the xAI and OpenAI providers' URL
branches.  When the download fails (network blip, 404 in-flight) we
log a warning and fall back to the bare URL rather than turning the
tool call into a hard error — the gateway's existing URL-send fallback
then gets a chance to surface the original error legibly.

Test plan:
- tests/agent/test_save_url_image.py — 8 direct tests against a real
  in-process HTTP server: bytes round-trip, content-type → extension,
  URL-suffix fallback, default-to-png, 404 propagation, empty-body
  refusal, oversize cap + cleanup, filename uniqueness.
- tests/plugins/image_gen/test_xai_provider.py — flip
  test_successful_url_response (was asserting the bug), add
  test_url_response_falls_back_to_bare_url_when_download_fails.
- tests/plugins/image_gen/test_openai_provider.py — symmetric pair.

160/160 in the broader image_gen test surface.
2026-05-24 18:10:47 -07:00
..
acp fix(acp): only deliver final_response after streaming when transformed 2026-05-24 04:31:13 -07:00
acp_adapter
…
agent fix(image_gen): cache xAI ephemeral URL responses to disk (#26942) (#31759) 2026-05-24 18:10:47 -07:00
cli test(cli): update resume usage-hint assertion for numbered selection 2026-05-24 16:22:48 -07:00
cron
…
e2e
…
fakes
…
gateway refactor(gateway): migrate Mattermost adapter to bundled plugin 2026-05-24 18:05:33 -07:00
hermes_cli feat(tts): add register_tts_provider() plugin hook (closes #30398) 2026-05-24 18:04:54 -07:00
hermes_state
…
honcho_plugin
…
integration
…
openviking_plugin
…
plugins fix(image_gen): cache xAI ephemeral URL responses to disk (#26942) (#31759) 2026-05-24 18:10:47 -07:00
providers
…
run_agent fix(security): redact credentials before persistence in session capture 2026-05-24 17:58:25 -07:00
scripts
…
skills
…
stress
…
tools refactor(gateway): migrate Mattermost adapter to bundled plugin 2026-05-24 18:05:33 -07:00
tui_gateway
…
website
…
__init__.py
…
conftest.py
…
run_interrupt_test.py
…
test_account_usage.py
…
test_atomic_replace_symlinks.py
…
test_base_url_hostname.py
…
test_batch_runner_checkpoint.py
…
test_bitwarden_secrets.py feat(secrets/bitwarden): EU Cloud + self-hosted server URL support (#31378) 2026-05-24 02:19:57 -07:00
test_cli_file_drop.py
…
test_cli_manual_compress.py
…
test_cli_skin_integration.py
…
test_ctx_halving_fix.py
…
test_empty_model_fallback.py
…
test_env_loader_secret_sources.py
…
test_evidence_store.py
…
test_gateway_streaming_nested_config.py
…
test_get_tool_definitions_cache_isolation.py
…
test_hermes_bootstrap.py
…
test_hermes_constants.py
…
test_hermes_home_profile_warning.py
…
test_hermes_logging.py
…
test_hermes_state.py
…
test_hermes_state_wal_fallback.py
…
test_honcho_client_config.py
…
test_install_sh_browser_install.py
…
test_install_sh_pythonpath_sanitization.py
…
test_install_sh_setup_wizard_tty_probe.py
…
test_install_sh_symlink_stomp.py
…
test_install_sh_termux_network_prereqs.py
…
test_ipv4_preference.py
…
test_lazy_session_regressions.py
…
test_lint_config.py
…
test_live_system_guard_self_test.py
…
test_mcp_serve.py
…
test_mini_swe_runner.py
…
test_minimax_model_validation.py
…
test_minimax_oauth.py
…
test_minisweagent_path.py
…
test_model_picker_scroll.py
…
test_model_tools.py
…
test_model_tools_async_bridge.py
…
test_ollama_num_ctx.py
…
test_package_json_lazy_deps.py
…
test_packaging_metadata.py
…
test_plugin_skills.py
…
test_process_loop_event_loop_warning.py
…
test_project_metadata.py
…
test_retry_utils.py
…
test_run_tests_parallel.py
…
test_sanitize_tool_error.py
…
test_sql_injection.py
…
test_subprocess_home_isolation.py
…
test_termux_all_extra_compat.py
…
test_timezone.py
…
test_toolset_distributions.py
…
test_toolsets.py
…
test_trajectory_compressor.py
…
test_trajectory_compressor_async.py
…
test_transform_llm_output_hook.py
…
test_transform_tool_result_hook.py
…
test_tui_gateway_server.py fix(tui): stop slash dropdown from chopping last char of /goal (#31311) 2026-05-23 22:12:55 -07:00
test_utils_truthy_values.py
…
test_yuanbao_integration.py
…
test_yuanbao_markdown.py
…
test_yuanbao_pipeline.py
…
test_yuanbao_proto.py
…