hermes-agent/agent
Ben Barclay f52feed1ef
fix(azure-foundry): scope Responses reasoning suppression to post-tool turns (#84320)
Azure Foundry's OpenAI-compatible Responses surface rejects the post-tool
follow-up payload with HTTP 400 `invalid_payload` when a replayed encrypted
`reasoning` item is sent alongside `function_call` / `function_call_output`.
The initial function-call request and ordinary multi-turn continuity are both
accepted, so the failure only appears after the first tool executes.

Detect the Foundry endpoint in `ResponsesApiTransport.build_kwargs` and drop
only the encrypted reasoning replay on that follow-up turn, leaving
function_call / function_call_output continuity intact.

Salvage of #59981, rebuilt on current main. Same root cause and fix direction
as the original, which was correct; this version resolves three defects:

- No `chat_completion_helpers.py` change. main already forwards `provider`
  and `base_url` to the Responses transport, so the original's re-added
  arguments produced `SyntaxError: keyword argument repeated: provider` on
  merge. Dropping the hunk removed the syntax error and the conflict.

- Host matching uses `utils.base_url_host_matches`, not a substring test.
  `".services.ai.azure.com" in base_url` also matches URLs carrying the
  domain in a path or query segment, which would silently disable reasoning
  replay on an unrelated provider.

- The post-tool predicate tests the trailing messages, not the whole history.
  Scanning for any tool call plus any tool result made it sticky: one tool
  call early in a conversation suppressed reasoning on every later turn.

- Tool calls pair on `call_id` as well as `id`. Responses histories carry the
  function call id in `call_id` while `id` holds the response item id
  (`fc_...`). Identity is resolved via the converter's own
  `_split_responses_tool_id`, covering composite `"call_x|fc_y"` ids and bare
  `fc_` ids on both sides of the pairing.

Tests: 27 cases across the transport and the live `build_api_kwargs` bridge,
including six parametrized tool-call id shapes, non-Foundry host lookalikes,
the sticky-history guard, parallel tool results, and an unpaired tool result.
Each guard was confirmed to catch its defect by reverting the fix.

Verified with `scripts/run_tests.sh tests/agent/ tests/run_agent/`:
532 files, 5602 tests passed, 0 failed.

Not verified against a live Azure Foundry endpoint — no credentials. The
original HTTP 400 reproduction and post-fix Foundry Project / Azure Container
Apps harness runs are @AshuJoshi's, from #59981. This change is verified at
the payload-construction layer only.

Closes #59981.

Co-authored-by: Ashu Joshi <AshuJoshi@users.noreply.github.com>
2026-08-14 12:41:26 +10:00
..
lsp fix(runtime): resolve Hermes-managed Node and uv before bare PATH 2026-08-01 21:17:51 -04:00
monitoring fix(otlp): span exporter now inherits configured resource_attributes 2026-08-08 18:11:02 -07:00
pet
proxy_sources
secret_sources fix(plugins): preserve force-path platform sweep + scoped plugin-source listing after rebase 2026-08-12 19:13:32 -07:00
transports fix(azure-foundry): scope Responses reasoning suppression to post-tool turns (#84320) 2026-08-14 12:41:26 +10:00
verify Integrate verify subsystem with the existing verification stack 2026-08-07 10:11:05 -07:00
__init__.py
account_usage.py
agent_init.py fix: security + efficiency review fixes for salvaged PR #74379 2026-08-13 23:15:25 +05:30
agent_runtime_helpers.py fix: address review feedback from #85512 2026-08-14 00:59:38 +05:30
anthropic_adapter.py fix: send Hermes Agent attribution headers to OpenCode Zen and Go 2026-08-13 02:03:40 -07:00
async_utils.py
aux_accounting.py
auxiliary_client.py fix(auxiliary): keep ZAI Coding Plan routing 2026-08-13 12:30:29 -07:00
azure_identity_adapter.py fix(secrets): scope-aware Azure credential presence reads in identity diagnostics 2026-08-02 10:02:33 -07:00
backend_identity.py
background_review.py simplify: match delegate_tool.py hasattr pattern, drop change-detector test 2026-08-09 16:13:52 +05:30
battery.py
bedrock_adapter.py
billing_links.py
billing_usage.py
billing_view.py
bounded_response.py
browser_provider.py feat(browser): integrate Browser Use CLI 3.0 2026-08-10 10:45:44 -07:00
browser_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
chat_completion_helpers.py fix: explicit fallback api_mode always wins; clean up dead-code guard 2026-08-13 12:31:02 -07:00
codex_responses_adapter.py fix(compression): prune pre-checkpoint history on native compaction replay 2026-08-13 01:51:24 -07:00
codex_runtime.py fix: widen APIConnectionError handling to finalization drain loop 2026-08-12 12:42:39 +05:30
coding_context.py
context_breakdown.py
context_compressor.py fix: double-paren bug in dropped-tools prefix + add empty-response nudge sibling 2026-08-09 16:20:48 +05:30
context_engine.py Revert "fix: rewire DCP context engine to current main architecture" 2026-08-08 23:09:45 +05:30
context_references.py feat(plugins): allow plugins to register custom @-prefix context references 2026-08-12 18:41:59 -07:00
conversation_compression.py feat(relay): session-span segmentation for continuous sessions 2026-08-13 10:45:15 -07:00
conversation_loop.py fix: restore stale-base revert hunks in conversation_loop.py and moa_loop.py 2026-08-13 23:10:16 +05:30
copilot_acp_client.py fix(file-safety): approval-gate ~/.ssh/config writes instead of hard-denying (#84663) 2026-08-12 11:04:45 -07:00
credential_persistence.py
credential_pool.py fix(agent): rebind pool entry id after env credential refresh 2026-08-08 19:17:02 -07:00
credential_sources.py fix(auth): read .env as utf-8-sig in the dotenv-vs-shell detector 2026-08-08 12:32:23 -07:00
credits_tracker.py
curator.py perf(curator): trim dead tool-schema from the LLM review fork 2026-08-03 18:21:17 +05:30
curator_backup.py refactor: fold simplify findings — 6th copy in update_cmd, drop dead wrapper + speculative kwarg, behavior-contract tests 2026-08-08 15:10:35 +05:30
delegation_context.py fix(cron): don't let a cron job inherit a kanban worker's dispatcher identity 2026-08-06 03:16:26 +05:30
display.py feat(delegation): live orchestration of running subagents via delegate_task action param 2026-08-13 09:34:36 -07:00
error_classifier.py feat(plugins): rename hook to transform_api_error_classification per #64231 verdict 2026-08-13 09:36:02 -07:00
errors.py
estop.py fix: post-merge audit follow-ups for #81138/#81139/#81141/#81148 2026-08-08 05:21:09 -07:00
file_safety.py fix(file-safety): approval-gate ~/.ssh/config writes instead of hard-denying (#84663) 2026-08-12 11:04:45 -07:00
gemini_native_adapter.py fix(gemini): interpose placeholder model turn between tool result and user text 2026-08-05 17:21:01 -07:00
gemini_schema.py
i18n.py
image_gen_provider.py feat(media): opt-in upscale pass for image_generate and video_generate across FAL and Krea 2026-08-08 14:49:28 -07:00
image_gen_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
image_routing.py fix(models): repair the two CI slices the default-flip broke 2026-08-14 03:31:22 +05:30
insights.py refactor(usage): simplify-pass follow-ups 2026-08-14 02:04:24 +05:30
interrupt_compat.py fix(compression): let explicit interrupts cancel safely 2026-08-02 22:15:20 +05:30
iteration_budget.py
jiter_preload.py
kanban_stop.py
learn_prompt.py fix(learn): process large sources incrementally 2026-08-08 05:09:43 -07:00
learning_graph.py
learning_graph_render.py
learning_mutations.py
lmstudio_reasoning.py
manual_compression_feedback.py
markdown_tables.py
memory_manager.py fix: replace double-lambda with functools.partial, close from_env config_path gap 2026-08-13 23:43:15 +05:30
memory_provider.py fix: security + efficiency review fixes for salvaged PR #74379 2026-08-13 23:15:25 +05:30
message_content.py
message_sanitization.py fix(agent): preserve destroyed tool-call argument bytes in the WARNING log 2026-08-07 16:57:11 +05:30
moa_loop.py fix: restore stale-base revert hunks in conversation_loop.py and moa_loop.py 2026-08-13 23:10:16 +05:30
moa_trace.py feat(langfuse): widen tracing to errors, sessions, subagents, and MoA fan-out 2026-08-13 23:10:16 +05:30
model_metadata.py fix(models): one canonical override schema, fill-gap _default semantics 2026-08-14 02:03:54 +05:30
models_dev.py refactor(models): simplify-pass follow-ups on the refresh path 2026-08-14 03:31:22 +05:30
moonshot_schema.py
native_compaction.py fix(agent): keep native compaction checkpoints out of the thinking-only drop 2026-08-13 03:04:45 -07:00
nous_rate_guard.py
onboarding.py
oneshot.py
outbound_webhooks.py fix(hooks): flush outbound queue at interpreter exit 2026-08-02 15:01:11 -07:00
plugin_llm.py fix(plugins): complete task-routed LLM integration 2026-08-12 16:25:20 -07:00
plugin_stream_hooks.py feat(plugins): add streaming output observer hooks 2026-08-12 18:38:25 -07:00
portal_tags.py
process_bootstrap.py
prompt_builder.py feat(desktop): setup_mcp tool — inline MCP consent card over the clarify-style blocking bridge 2026-08-13 01:06:51 -05:00
prompt_cache_boundary.py refactor(cache): share the boundary-declaration helper and simplify the registry 2026-08-09 15:25:12 +05:30
prompt_caching.py refactor: hoist preflight clear into restart handler, single-source qwen predicate 2026-08-13 15:24:47 +05:30
rate_limit_tracker.py
reactions.py
reasoning_summaries.py fix(reasoning): keep gpt-5.x summary parts as separate blocks on the chat wire 2026-08-06 22:02:37 -05:00
reasoning_timeouts.py add grok 4.6 (#84661) 2026-08-12 13:37:04 -04:00
redact.py fix: reuse redact_sensitive_text, fix leaky abstraction, fix test data 2026-08-13 23:10:16 +05:30
relay_llm.py fix(relay): bypass managed execution for nested calls inside managed callbacks 2026-08-08 23:46:17 -07:00
relay_runtime.py fix(relay): defer rotating-compaction session close while a turn is live 2026-08-13 10:45:15 -07:00
relay_tools.py fix(relay): bypass managed execution for nested calls inside managed callbacks 2026-08-08 23:46:17 -07:00
replay_cleanup.py
retry_utils.py
runtime_cwd.py
secret_scope.py fix(secrets): allowlist API_SERVER listener settings as global deployment env 2026-08-02 09:59:52 -07:00
session_activity.py refactor(agent): pin session activity heartbeat cadence + harden best-effort write 2026-08-02 16:16:36 -07:00
shell_hooks.py fix(plugins): synthetic hook fixture, shell-hook exclusion, docs per review 2026-08-13 09:36:02 -07:00
skill_bundles.py
skill_commands.py refactor(cache): share the boundary-declaration helper and simplify the registry 2026-08-09 15:25:12 +05:30
skill_preprocessing.py
skill_utils.py fix(cron): don't let a cron job inherit a kanban worker's dispatcher identity 2026-08-06 03:16:26 +05:30
ssl_guard.py fix(ssl_guard): tolerate truststore SSLContext.get_ca_certs() NotImplementedError on Windows 2026-08-08 15:10:24 +05:30
ssl_verify.py
stream_diag.py
stream_single_writer.py
subagent_lifecycle.py fix(compression): let explicit interrupts cancel safely 2026-08-02 22:15:20 +05:30
subdirectory_hints.py fix(context): dedupe subdirectory hints by content digest and skip backup/vendor dirs 2026-08-03 20:43:34 +05:30
subscription_view.py
system_prompt.py feat(plugins): add cache-safe system prompt sections 2026-08-12 16:34:58 -07:00
think_scrubber.py
thinking_timeout_guidance.py
thread_scoped_output.py fix: preserve session history when a turn crashes 2026-08-06 23:08:23 -05:00
title_generator.py refactor(title): decide on the stored title and the real turns behind it 2026-08-09 04:33:58 -05:00
tool_dispatch_helpers.py feat(image): parallelize image_generate batches 2026-08-03 22:53:32 +05:30
tool_executor.py feat(delegation): live orchestration of running subagents via delegate_task action param 2026-08-13 09:34:36 -07:00
tool_guardrails.py feat(delegation): live orchestration of running subagents via delegate_task action param 2026-08-13 09:34:36 -07:00
tool_result_classification.py
trace_upload.py
trajectory.py
transcription_provider.py feat(plugins): add pre_transcription hook and STT prompt threading 2026-08-12 19:01:30 -07:00
transcription_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
tts_provider.py
tts_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
turn_context.py feat(hindsight): memory provider improvements — recall_sync, retain_source, setup templates, memory indicators, error hints 2026-08-13 23:15:25 +05:30
turn_finalizer.py fix(agent,gateway): class-level lone-surrogate chokepoints (#80366 #55143 #55309 #50959 #19819) 2026-08-08 12:31:19 -07:00
turn_retry_state.py feat(compression): native OpenAI Responses server-side compaction for gpt-5.6 2026-08-08 11:24:45 -07:00
turn_summary.py
usage_pricing.py refactor(usage): simplify-pass follow-ups 2026-08-14 02:04:24 +05:30
verification_evidence.py Integrate verify subsystem with the existing verification stack 2026-08-07 10:11:05 -07:00
verification_stop.py fix: make verify_on_stop opt-in everywhere (default False, not auto) (#84383) 2026-08-12 01:15:25 -07:00
verify_hooks.py
vertex_adapter.py
video_gen_provider.py feat(media): opt-in upscale pass for image_generate and video_generate across FAL and Krea 2026-08-08 14:49:28 -07:00
video_gen_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
web_search_provider.py
web_search_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00