Skip to content

feat(webhooks): create_mcp_webhook_payload should return McpWebhookPayload #607

@bokelley

Description

@bokelley

Follow-up to the optional bonus in #601 that PR #602 (`to_wire_dict` seam) and #600 (annotation fixes) deliberately deferred.

Current behaviour

```python
def create_mcp_webhook_payload(...) -> dict[str, Any]:
...
```

Adopters who want a typed shape do the ceremony manually. From `salesagent/context_manager.py`:

```python

TODO: Fix in adcp python client - create_mcp_webhook_payload should return

McpWebhookPayload instead of dict[str, Any] for proper type safety

mcp_payload_dict = create_mcp_webhook_payload(step.step_id, status_enum, step.response_data)
payload = McpWebhookPayload.model_construct(**mcp_payload_dict)
```

Proposed change

```python
def create_mcp_webhook_payload(...) -> McpWebhookPayload:
...
```

Adopters drop `.model_construct(**dict)` and get a typed instance directly. Anyone who needs the wire dict calls `to_wire_dict(payload)` (#602) — the seam handles both shapes uniformly, so this is purely an ergonomics win.

Why this didn't ship in #602 / #600

Compatibility

Breaking for any adopter that mutates the dict, calls `.update()`, or reads keys without unwrapping. Migration:

Old (dict) New (McpWebhookPayload)
`payload["task_id"]` `payload.task_id`
`payload.update(extra)` n/a — use the builder kwargs
`json.dumps(payload)` `to_wire_dict(payload)` (or `payload.model_dump(mode="json", exclude_none=True)`)
HTTP transport (`json=payload`) `json=to_wire_dict(payload)`

Suggested rollout

One minor with widened return type `dict[str, Any] | McpWebhookPayload` and a deprecation note in the builder docstring, then drop `dict` in the next minor. Or skip the widening since runtime callers see no shape difference if they switch to `to_wire_dict` — strictly a typing-surface change for adopters who type-check.

Acceptance criteria

  • `create_mcp_webhook_payload` returns `McpWebhookPayload`.
  • Test asserts the returned instance is a `McpWebhookPayload` and that `to_wire_dict(payload)` produces the same wire bytes as before.
  • CHANGELOG / MIGRATION note covering the type narrowing.
  • Update the salesagent TODO referenced above (cross-link from the PR).

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions