Skip to content

fix(hooks): skip offload for empty-string tool results - #12584

Draft
Alphaxiaoteng wants to merge 2 commits into
deepset-ai:mainfrom
Alphaxiaoteng:fix-12583
Draft

fix(hooks): skip offload for empty-string tool results#12584
Alphaxiaoteng wants to merge 2 commits into
deepset-ai:mainfrom
Alphaxiaoteng:fix-12583

Conversation

@Alphaxiaoteng

Copy link
Copy Markdown

Related Issues

Proposed Changes:

_maybe_offload wrapped string results into [TextContent(...)] before the emptiness check, so result="" became a one-element list and was offloaded as a zero-byte file with a dangling Preview: pointer. Empty lists already returned early. Check if not result.result before wrapping so "" and [] are both left in context.

How did you test it?

pytest test/hooks/tool_result_offloading/test_hooks.py -k empty_result_is_not_offloaded -q

2 passed (empty_string, empty_list).

Notes for the reviewer

This PR was fully generated with an AI assistant. I have reviewed the changes and run the relevant tests.

Checklist

  • I have read the contributors guidelines and the code of conduct.
  • I have updated the related issue with new insights and changes.
  • I have added unit tests and updated the docstrings.
  • I've used one of the conventional commit types for my PR title.
  • I have documented my code.
  • I have added a release note file.
  • I have run focused tests for this change.

Made with Cursor

Alphaxiaoteng and others added 2 commits September 3, 2026 18:58
Empty string results were wrapped into TextContent before the emptiness
check, so they were written as zero-byte files with a dangling Preview
pointer. Treat "" like [] and leave them in context.

Closes deepset-ai#12583

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@Alphaxiaoteng
Alphaxiaoteng requested a review from a team as a code owner September 3, 2026 11:00
@Alphaxiaoteng
Alphaxiaoteng requested review from julian-risch and removed request for a team September 3, 2026 11:00
@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

@Alphaxiaoteng is attempting to deploy a commit to the deepset Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@TheDeveloperDoctor

Copy link
Copy Markdown

I independently opened #12585 with what turns out to be the same patch (the test change is byte-identical — we both took the regression test from the issue verbatim). Closing mine in favour of this one since it came first. Two findings from my verification that might be worth having on the record here:

1. This is reachable from a normal Agent run, not just a hand-built message. Worth stating explicitly because the fix hinges on result.result still being a str by the time the hook sees it. It is: a tool returning "" goes through _result_to_string (tool_calling.py:93), which returns strings as-is, into ChatMessage.from_tool, which stores the value verbatim into ToolCallResult.result. No normalisation into [TextContent("")] happens anywhere in between, so the raw-value check catches the real path and not only the reproducer.

2. One adjacent shape still produces the reported symptom. A non-empty list whose blocks are all empty text — [TextContent(text="")] — still offloads, still writes a zero-byte entry, and still emits the dangling Preview: . It's reachable via raw_result: True or a custom outputs_to_string handler. Covering it would mean something like:

if not result.result or all(isinstance(b, TextContent) and not b.text for b in content_blocks):
    return message

The issue explicitly considered and set that aside as reading further from the docstring's "the result is empty" than the raw-value check does, so this PR matches the issue's chosen scope — just flagging it so the maintainers can decide deliberately rather than by omission.

Verification (same diff as here): against pre-fix hooks.py the new empty_string case fails with exactly the reported output —

E   assert "Tool result ...t'. Preview: " == ''
E     + Tool result offloaded to text (0 characters) at '.../1_a_1.txt'. Preview:

— so it's a real regression test, not just a passing assertion. With the change, test/hooks/tool_result_offloading/ is 37 passed, and ruff format --check, ruff check, and mypy are clean on the package.

@HaystackBot

Copy link
Copy Markdown
Contributor

Hi @Alphaxiaoteng, thanks a lot for your contribution! 🙏

We noticed that the Contributor License Agreement (CLA) check (license/cla) hasn't passed yet, so we've temporarily moved this PR to draft and paused the review assignment.

To get your PR reviewed, please sign the CLA via the link in the license/cla check below (or in the CLA bot comment). As soon as the check turns green, this PR will automatically be marked ready for review again and a reviewer will be re-assigned.

@HaystackBot
HaystackBot removed the request for review from julian-risch September 3, 2026 12:40
@HaystackBot HaystackBot added the cla-pending PR is in draft until the contributor signs the CLA label Sep 3, 2026
@HaystackBot
HaystackBot marked this pull request as draft September 3, 2026 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-pending PR is in draft until the contributor signs the CLA topic:tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ToolResultOffloadHook offloads empty-string results but leaves empty-list results in context

4 participants