Skip to content

Preserve provider reasoning metadata and batch concurrent tool results - #155

Merged
JohnRichard4096 merged 4 commits into
mainfrom
fix-agent
Aug 15, 2026
Merged

Preserve provider reasoning metadata and batch concurrent tool results#155
JohnRichard4096 merged 4 commits into
mainfrom
fix-agent

Conversation

@JohnRichard4096

@JohnRichard4096 JohnRichard4096 commented Aug 15, 2026

Copy link
Copy Markdown
Member

Summary by Sourcery

Ensure agent tool-call handling preserves provider reasoning metadata and batches concurrent tool results into a single assistant message per response.

Bug Fixes:

  • Preserve reasoning_signature and any provider-specific extra fields on fabricated assistant messages so thinking-mode provider contracts are respected.
  • Keep original ToolCall arguments verbatim when tools raise errors, marking failures only via ERR-prefixed ToolResult content.
  • Batch multiple concurrent tool_calls from a single response into one assistant message followed by all corresponding ToolResults in call order to satisfy API pairing requirements.

Enhancements:

  • Refactor assistant message construction to derive fields generically from provider responses, avoiding hard-coded reasoning metadata handling.
  • Introduce optional injection points for tool failure guidance hints that can be customized by strategies.

Build:

  • Bump project version from 0.13.2 to 0.13.4.

Documentation:

  • Update English and Chinese troubleshooting guides to document the new reasoning metadata round-trip and batched tool-call/result pairing behavior.

@sourcery-ai

sourcery-ai Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Ensure assistant messages created during tool execution round-trip provider thinking fields verbatim (including reasoning_signature and extra fields) and batch concurrent tool calls into a single assistant message followed by ordered ToolResults, while tightening error handling behavior and updating docs and templates.

Sequence diagram for batched tool-call handling and thinking-field round-trip

sequenceDiagram
    participant Agent as ReactBaseAgent
    participant Provider as LLMProvider
    participant ToolRunner as ToolRunner
    participant Ctx as ContextMessageList

    Agent->>Provider: _execute_tool_loop(request)
    Provider-->>Agent: UniResponse(response_msg with tool_calls)

    Agent->>ToolRunner: _run_tool_calls_concurrently(tool_calls)
    ToolRunner-->>Agent: concurrent_results[ToolCall, func_response, exc]

    Agent->>Agent: _append_tool_results_batch(response_msg, results)

    Agent->>Ctx: append Message(role=assistant, content=response_msg.content, tool_calls=[all ToolCall])
    Agent->>Agent: _assistant_fields_from_response(response_msg)
    Agent->>Ctx: append ToolResult for each ToolCall
    Agent->>Agent: _maybe_inject_tool_failure_hint(tool_call, func_response)
Loading

File-Level Changes

Change Details Files
Assistant messages now mirror provider responses verbatim for thinking-related fields and extra metadata when appending tool results or handling stop/error paths.
  • Introduce _assistant_fields_from_response helper to extract allowed assistant fields from UniResponse while excluding role/content/tool_calls/usage/metadata.
  • Update _append_tool_result_to_context to use provider content and assistant field extraction instead of hard-coding reasoning_content.
  • Update stop-response append logic in _build_stop_response_and_append to reuse provider content and assistant field extraction.
  • Change error-append handling signatures to take ToolCall objects and reuse provider assistant fields instead of reconstructing function/arguments manually.
src/amrita_core/builtins/agent/react_base.py
src/amrita_core/builtins/agent/react_comm.py
Concurrent tool-call execution now produces exactly one assistant tool_calls message per response, followed by all ToolResults in input order, without splitting calls across messages.
  • Modify _execute_tool_loop to collect per-call results, append them in a single batch via _append_tool_results_batch, and maintain ordered ToolResult notifications.
  • Add _append_tool_results_batch to construct the single assistant message containing all ToolCalls plus provider fields, then append one ToolResult per call.
  • Ensure early loop-reasoning stops flush any collected results before cleanup and yielding intermediate responses.
src/amrita_core/builtins/agent/react_base.py
Error handling and failure hint injection are generalized so the base strategy can optionally inject guidance while ReAct-specific behavior overrides this hook.
  • Introduce _maybe_inject_tool_failure_hint no-op in react_base with documentation describing its intended override behavior.
  • Update react_comm to override _maybe_inject_tool_failure_hint and call it after every ToolResult append, including batched results.
  • Refactor _handle_error_append in react_comm to operate on full ToolCall objects and mirror provider thinking fields and content on fabricated assistant messages.
src/amrita_core/builtins/agent/react_base.py
src/amrita_core/builtins/agent/react_comm.py
Troubleshooting docs are updated to describe the new thinking-field round-trip behavior and single-assistant-message batching semantics in both English and Chinese guides.
  • Clarify that all thinking-related fields (reasoning_content, reasoning_signature, and provider extras) are passed back verbatim on assistant messages.
  • Update guidance on tool-call/result pairing to emphasize single assistant message per provider response containing all tool_calls and their ordered ToolResults.
  • Mirror these explanations in the Chinese troubleshooting documentation.
docs/docs/guide/agent-engineering/troubleshooting.md
docs/docs/zh/guide/agent-engineering/troubleshooting.md
Prompt templates and default instruction strings are adjusted to use backslash-prefixed triple-quoted literals for cleaner formatting, and project version is bumped.
  • Change ABSTRACT_INSTRUCTION, PROMPT_TEMPLATE, and DEFAULT_INSTRUCTIONS to use """-prefixed multi-line string literals.
  • Bump amrita_core version from 0.13.2 to 0.13.4 in pyproject.toml and regenerate uv.lock accordingly.
src/amrita_core/consts.py
pyproject.toml
uv.lock
New tests validate reasoning_signature and extra provider fields round-trip correctly and concurrent tool calls are batched into one assistant message with ordered ToolResults for both success and error cases.
  • Add tests to ensure _append_tool_result_to_context carries reasoning_content and reasoning_signature through to assistant messages.
  • Add tests verifying that error paths preserve original ToolCall arguments, round-trip reasoning fields, and produce ERR-prefixed ToolResults.
  • Add a concurrency test confirming a single assistant message with all tool_calls plus provider_extra, followed by ordered ToolResults including error markers.
tests/test_step_loop.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@JohnRichard4096

Copy link
Copy Markdown
Member Author

@sourcery-ai title

@sourcery-ai sourcery-ai Bot changed the title Fix agent Preserve provider reasoning metadata and batch concurrent tool results Aug 15, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/amrita_core/builtins/agent/react_base.py" line_range="1154-1159" />
<code_context>
                     # concurrent runner); surface the error, don't swallow.
                     self.reasoning_pc = 0
                     await self._handle_error_append(
-                        function_name,
+                        tc,
</code_context>
<issue_to_address>
**issue (bug_risk):** Error paths are now appended twice: once via `_handle_error_append` and again in the batch helper.

In the `exc is not None` branch, `_handle_error_append` appends an assistant+tool message pair, and the `(tc, func_response, exc)` tuple is still added to `collected` for `_append_tool_results_batch`. That causes error outputs to be emitted twice and may violate the "one tool_result per tool_call" assumption, breaking downstream logic expecting a single error record. To avoid this, either make `_handle_error_append` non-append-only for exceptions (e.g., diagnostics only), or skip adding to `collected`/`result_msg_list` when `exc is not None` so errors are surfaced only via the handler.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/amrita_core/builtins/agent/react_base.py
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying amritacore with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9b29a24
Status: ✅  Deploy successful!
Preview URL: https://9b4d5ec0.amritacore.pages.dev
Branch Preview URL: https://fix-agent.amritacore.pages.dev

View logs

@JohnRichard4096
JohnRichard4096 merged commit a4fedff into main Aug 15, 2026
9 checks passed
@JohnRichard4096
JohnRichard4096 deleted the fix-agent branch August 15, 2026 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant