Conversation
84ffab2 to
73e853a
Compare
73e853a to
37d2cda
Compare
…er subclass annotation Closes #596. _invoke_platform_method received an already-deserialized Pydantic instance typed as the library's base request (e.g. GetProductsRequest with extra="allow") and passed it directly to the platform method without consulting the platform method's own annotation. A DecisioningPlatform subclass that annotated its method with a stricter subclass (e.g. extra="forbid", custom @field_validator) had those rules silently bypassed at the dispatch boundary. The fix adds _coerce_params_to_platform_type, called from _invoke_platform_method when arg_projector is None. It inspects the platform method's first non-self/non-ctx/non-context typed parameter annotation; when that annotation is a strict Pydantic subclass of the current params type, it re-validates via model_dump(mode="python") → model_validate(). A ValidationError from re-validation surfaces as INVALID_REQUEST / correctable (not INTERNAL_ERROR). The on_failure hook is called before re-raising so proposal-flow callers can release any consumption reservation taken before _invoke_platform_method. Guard conditions that skip coercion: same type (no-op), unrelated annotation, VAR_POSITIONAL/VAR_KEYWORD parameters, get_type_hints() resolution failure (graceful degradation to dict pass-through). 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.
Closes #596
Summary
_invoke_platform_methodreceived an already-deserialized Pydantic instance typed as the library's base request (e.g.GetProductsRequestwithextra="allow") and passed it directly to the platform method without consulting the platform method's own annotation. ADecisioningPlatformsubclass that annotated its method with a stricter subclass (e.g.extra="forbid", custom@field_validator) had those rules silently bypassed at the dispatch boundary.The fix adds
_coerce_params_to_platform_type, called from_invoke_platform_methodwhenarg_projector is None. It inspects the platform method's first non-self/non-ctx/non-context typed parameter annotation; when that annotation is a strict Pydantic subclass of the current params type, it re-validates viamodel_dump(mode="python") → model_validate(). AValidationErrorfrom re-validation surfaces asINVALID_REQUEST / correctable(notINTERNAL_ERROR). Theon_failurehook is called before re-raising so proposal-flow callers can release any consumption reservation taken before_invoke_platform_method.Guard conditions that skip coercion: same type (no-op), unrelated annotation,
VAR_POSITIONAL/VAR_KEYWORDparameters,get_type_hints()resolution failure (graceful degradation to dict pass-through).What was tested
pytest tests/test_decisioning_dispatch.py— 51 passed (6 pre-existing + 8 new coerce tests including:extra="forbid"rejection, same-type no-op, valid subclass passthrough, unrelated annotation no-op, param-name agnosticism,get_type_hintsfailure graceful degradation,on_failurehook fires on coercion failure,VAR_POSITIONALguard)mypy src/adcp/decisioning/dispatch.py --ignore-missing-imports— cleanruff check src/adcp/decisioning/dispatch.py— cleanPre-PR review:
Known nit (not fixed): The handler-authoring.md "Custom models too" paragraph could benefit from a code example showing the full
DecisioningPlatformsubclass pattern withextra="forbid"and@field_validator. Noted for a follow-up docs PR.Session: https://claude.ai/code/session_01GUtwfX2NfFEVUuZZBCA5qP
Generated by Claude Code