Skip to content

fix: preserve ThinkingPart fields in OpenCode storage round-trip (#156) - #417

Closed
Million-mo wants to merge 1 commit into
develop/agenticfrom
fix/issue-156-thinkingpart-storage-fields
Closed

fix: preserve ThinkingPart fields in OpenCode storage round-trip (#156)#417
Million-mo wants to merge 1 commit into
develop/agenticfrom
fix/issue-156-thinkingpart-storage-fields

Conversation

@Million-mo

Copy link
Copy Markdown
Owner

Summary

Fixes #156

ThinkingPart.id, provider_name, signature, and provider_details were silently dropped during OpenCode storage serialization. The write path only saved content as ReasoningPart.text, and the read path only restored content — all other fields defaulted to None.

This caused send-back to degrade to tags mode: pydantic-ai checks id + provider_name to decide between field mode (reasoning_content) and tags mode. Without these fields, thinking content was wrapped in tags instead of sent via the proper reasoning_content field.

Fix

Store the extra fields in ReasoningPart.metadata during write, and restore them when constructing ThinkingPart during read. The metadata field already exists on ReasoningPart and is a dict[str, Any], making it a natural extensibility bucket without model changes.

Changes

  • provider.py:464-474: Write ThinkingPart.id/provider_name/signature/provider_details into ReasoningPart.metadata
  • helpers.py:328-330: Read back metadata fields when constructing ThinkingPart
  • test_opencode_thinking_roundtrip.py: 6 new tests covering all fields, partial metadata, empty metadata, coexistence with TextPart, and empty text skip

Backward Compatibility

Old data without metadata produces ThinkingPart with None defaults — same behavior as before this fix.

Test Plan

  • 6 new tests pass (all fields, no metadata, partial, empty, coexistence, empty text)
  • ruff check + format pass
  • mypy passes on both changed source files

Relationship to #155 and #174

Three independent fixes, no overlap.

备份迁移自 SRC-PR#222 · 作者 @Million-mo · 创建于 2026-07-20T01:29:53Z · head=fix/issue-156-thinkingpart-storage-fields base=develop/agentic
源状态: closed · merge_commit_sha=06a5746676bea619b3a2f96526c7d901e7e34568

ThinkingPart.id, provider_name, signature, and provider_details were
silently dropped during OpenCode storage serialization. The write path
(provider.py) only saved content as ReasoningPart.text, and the read
path (helpers.py) only restored content — all other fields defaulted
to None.

This caused send-back to degrade to tags mode: pydantic-ai's
_map_response_thinking_part() checks id + provider_name to decide
between field mode (reasoning_content) and tags mode. Without these
fields, thinking content was wrapped in <think> tags instead of sent
via the proper reasoning_content field.

Fix: store the extra fields in ReasoningPart.metadata during write,
and restore them when constructing ThinkingPart during read. The
metadata field already exists on ReasoningPart and is a dict[str, Any],
making it a natural extensibility bucket without model changes.

Backward compatible: old data without metadata produces ThinkingPart
with None defaults, same as before.
@Million-mo

Copy link
Copy Markdown
Owner Author

评论 by @Million-mo 于 2026-07-20T02:14:31Z(备份迁移)

Closing in favor of a new PR rebased on main. The original branch was based on develop/agentic which has diverged significantly from main, causing conflicts. A new PR will be created from a clean main-based branch.

@Million-mo Million-mo closed this Aug 23, 2026
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