You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* fix(idempotency): @IdempotencyStore.wrap supports arg-projected methods (closes#559)
Wrap was hard-coded for the (self, params, ctx) calling convention,
so framework-dispatched arg-projected tools like update_media_buy —
called as method(self, media_buy_id=..., patch=..., ctx=ctx) by
dispatch.py's arg_projector path — raised TypeError before the wrap
body ran. Salesagent shipped a workaround dropping @Wrap from
update_media_buy entirely, losing idempotency on retries.
Wrap now resolves the calling convention via _resolve_call_args()
and supports three shapes:
1. Positional (self, params, ctx) — original.
2. Keyword (self, params=..., context=...).
3. Arg-projected (self, **arg_projector_kwargs, ctx=...) — searches
kwargs for a Pydantic model (the framework's contract for the
request model, e.g. patch on update_media_buy) to pull
idempotency_key from. Falls back to the kwargs dict (excluding
ctx/context) when no Pydantic model is present, so projections
exposing idempotency_key at the top level still work.
Tests: 6 new in TestWrapArgProjectionCalling, 154 across the broader
idempotency surface green. Lint clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(idempotency): expert-review fixes for #567 (None-context, multi-Pydantic, BaseModel strictness)
- _resolve_call_args: 'kwargs.get(context) or kwargs.get(ctx)' silently
fell through to ctx when context was explicitly None. Switched to
'in'-based check so explicit None wins.
- Multi-Pydantic-kwarg: prefer 'params' / 'request' / 'patch' by name
before falling back to first-by-iteration. Eliminates dict-order
fragility when a tool has two model kwargs.
- isinstance(BaseModel) instead of hasattr(model_dump). A duck-typed
object with model_dump no longer accidentally matches.
4 new tests cover: explicit None-context wins, multi-Pydantic
preference order, no-preferred-name first-by-iteration fallback,
duck-typed non-Pydantic exclusion. 59 tests green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments