feat(client): surface structured adcp_error on TaskResult#675
Merged
Conversation
TaskResult.error is for humans; TaskResult.adcp_error is for programs. Both MCP and A2A failure paths now populate the structured envelope (code, message, recovery, field, suggestion, retry_after, details) independent of debug mode, so adopters can branch on adcp_error.code without enabling debug capture. Previously the SDK paraphrased the seller's structured diagnostic into a flat error string and gated the structured form behind debug=True. That hid spec-shaped errors (INVALID_REQUEST.field_path, TERMS_REJECTED, etc.) from alerting, version-compat probes, and grader assertions. - TaskResult.adcp_error: dict[str, Any] | None added to the public model - MCP FAILED path passes the extracted envelope through - A2A FAILED path now extracts the adcp_error DataPart per transport-errors.mdx §A2A Binding; falls back to envelope.message / envelope.code when the seller omits the TextPart - Validation helper extracted to protocols/_adcp_errors.py so both transports share the spec-defined size/shape caps Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the SDK's last politeness move on the buyer error path:
TaskResult.adcp_erroris now a first-class field carrying the seller's full structured error envelope, independent ofdebugmode.Previously the SDK paraphrased a seller's structured
adcp_error(code,field,details,recovery, ...) into a flaterror: strand gated the structured form behinddebug=True. That made spec-shaped errors invisible to alerting, version-compat probes, and grader assertions in production.This is the Python analog of the JS-side issue 1679 ("flatten wire INVALID_REQUEST detail to
{}") — same disease, slightly different shape: Python doesn't flatten to{}, it flattens to a string and hides the structure behind a debug flag.What changes
TaskResult.adcp_error: dict[str, Any] | None— new public field, populated whenever the wire carried a spec-shaped envelope.TaskResultcarries the already-validatedadcp_errordict (was previously only indebug_info.response).adcp_errorDataPart pertransport-errors.mdx §A2A Binding. When the seller omits the TextPart, the structured envelope'smessage/codesynthesizes theerrorstring so adopters don't see the"Task failed"placeholder mask a real diagnostic.protocols/_adcp_errors.pyholds the spec-defined size/shape caps (codenon-empty string ≤ 64 chars, total ≤ 4 KB), used by both transports.Adopter ergonomics
The flat
error: strstays for back-compat (human messages, logging).Tests
structuredContent.adcp_errorand text-fallback both surface onTaskResult.adcp_errorwithdebug=False.adcp_errorDataPart surfaces structurally; envelope-only (no TextPart) synthesizes the human message.adcp_errorstaysNone.Test plan
pytest tests/test_protocols.py tests/test_mcp_structured_error.py tests/test_a2a_structured_error.py tests/test_mcp_extraction.py— 194 passedruff checkclean on changed filesmypyclean on changed files🤖 Generated with Claude Code