Skip to content

Conversation

@strands-agent
Copy link
Contributor

@strands-agent strands-agent commented Jan 13, 2026

Description

This implements Option 1 from the #1461 discussion as requested by @afarntrog.

The Problem

When AgentResult.__str__ is called (e.g., in graph node transitions), it only returns structured_output when there is NO text content. This causes structured data to be lost when both text and structured output exist.

The Solution (Option 1 - JSON Format)

Modify __str__ to include both text and serialized structured_output when both exist, in JSON format for parseability:

def __str__(self) -> str:
    # ... extract text content ...
    
    # Always include structured output when present (Option 1 from #1461)
    if self.structured_output:
        structured_data = self.structured_output.model_dump()
        if result:
            # Both text and structured output exist - return JSON-parseable format
            combined = {"text": result.rstrip("\n"), "structured_output": structured_data}
            return json.dumps(combined)
        else:
            # Only structured output exists - return just the structured output JSON
            return self.structured_output.model_dump_json()
    return result

Output Format

When both text and structured output exist:

{"text": "Your text content here", "structured_output": {"field": "value"}}

This allows users to parse the output programmatically:

import json
result = agent("prompt", structured_output_model=MyModel)
output = str(result)
parsed = json.loads(output)
print(parsed["text"])  # The text response
print(parsed["structured_output"])  # The structured data as dict

Related Issues

Fixes #1461

Documentation PR

No documentation changes required - this is a behavioral fix.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Testing

  • Added 8 comprehensive unit tests covering all __str__ scenarios
  • Updated existing test to reflect new expected behavior
  • All 21 agent_result tests pass
hatch test tests/strands/agent/test_agent_result.py tests/strands/agent/test_agent_result_str.py
# 21 passed

Checklist

  • I have read the CONTRIBUTING document
  • I have added tests that prove my fix is effective
  • I have updated documentation (N/A - internal behavior change)
  • My changes generate no new warnings
  • I ran hatch run prepare (tests pass locally)

Requested by @afarntrog in comment and feedback on JSON format 🦆

@codecov
Copy link

codecov bot commented Jan 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@strands-agent
Copy link
Contributor Author

All three review comments have been addressed in commit 7ae3a2a:

  • ✅ Removed "Option 1" references from agent_result.py
  • ✅ Removed "Option 1" references from test_agent_result.py
  • ✅ Removed "Option 1" references from test_agent_result_str.py

The PR is now awaiting workflow approval (check-access-and-checkout is WAITING status).

🦆


🤖 This is an experimental AI agent response from the Strands team, powered by Strands Agents. We're exploring how AI agents can help with community support and development. Your feedback helps us improve! If you'd prefer human assistance, please let us know.

@cagataycali cagataycali changed the title fix: include both text and structured_output in AgentResult.__str__ (Option 1) fix: include both text and structured_output in AgentResult.__str__ Jan 14, 2026
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need a separate file for this single __str__ method. I want you to add the tests to the existing tests/strands/agent/test_agent_result.py file

structured_data = self.structured_output.model_dump()
if result:
# Both text and structured output exist - return JSON-parseable format
combined = {"text": result.rstrip("\n"), "structured_output": structured_data}
Copy link
Member

Choose a reason for hiding this comment

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

I am curious that this .rstrip modifies the result. In normal flow of the code result were not processed at all. This implementation now modifies the result which might not be intended. LLM might produce \n end token and we would want to keep as-is.

@github-actions github-actions bot added size/m and removed size/m labels Jan 15, 2026
@strands-agent strands-agent force-pushed the fix/agent-result-str-structured-output branch from 04d3b1f to f23a5da Compare January 15, 2026 06:23
@github-actions github-actions bot removed the size/m label Jan 15, 2026
@afarntrog afarntrog self-assigned this Jan 15, 2026
@strands-agent strands-agent force-pushed the fix/agent-result-str-structured-output branch from f23a5da to 47880b4 Compare January 15, 2026 20:34
@github-actions github-actions bot added size/m and removed size/m labels Jan 15, 2026
@strands-agent strands-agent force-pushed the fix/agent-result-str-structured-output branch from 47880b4 to aaef766 Compare January 15, 2026 20:45
@github-actions github-actions bot added size/m and removed size/m labels Jan 15, 2026
@strands-agent strands-agent force-pushed the fix/agent-result-str-structured-output branch from aaef766 to 6cd4949 Compare January 17, 2026 00:22
@github-actions github-actions bot added size/m and removed size/m labels Jan 17, 2026
strands-agent and others added 6 commits January 17, 2026 00:23
…Option 1)

Fixes strands-agents#1461: Structured output is not properly propagated in the graph

This implements Option 1 from strands-agents#1461 discussion - modifying __str__ to
include both text and serialized structured_output when both exist.

Changes:
- Updated AgentResult.__str__ to append structured output when present
- Format: text content followed by [Structured Output] section with JSON
- Updated existing test to reflect new expected behavior
- Added 8 comprehensive tests for all __str__ scenarios

The fix ensures that when AgentResult is stringified (e.g., in graph
node transitions), the structured output data is preserved alongside
any text content.

Requested-by: @afarntrog
Addresses feedback from @afarntrog to make the output JSON-parseable.

When both text and structured output exist, output is now:
{"text": "...", "structured_output": {...}}

This allows users to parse the combined output with json.loads() and
extract both the text and structured data programmatically.

- Text-only: returns raw text (unchanged)
- Structured-only: returns JSON of structured output (unchanged)
- Both: returns JSON with 'text' and 'structured_output' keys (NEW)
Address review feedback from @cagataycali to clean up code comments.
Per review feedback from @afarntrog, moved all __str__ method tests from
the separate test_agent_result_str.py file into the existing
test_agent_result.py file to keep related tests together.
Addresses review feedback from @cagataycali:
- Removed .rstrip() that was modifying LLM output
- Text content is now preserved exactly as produced

The previous implementation used .rstrip('\n') which could strip
intentional trailing newlines from the LLM output. This fix ensures
the original text is preserved without modification.
@strands-agent strands-agent force-pushed the fix/agent-result-str-structured-output branch from 6cd4949 to 8e82e27 Compare January 17, 2026 00:26
@github-actions github-actions bot added size/m and removed size/m labels Jan 17, 2026
@afarntrog
Copy link
Contributor

@strands-agent fix the failing lint. Be sure to run all checks before pushing any new commits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Structured output is not properly propagated in the graph

3 participants