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
ref(pr-metrics): Type signal_details for delegated-agent attributions; add run_id (#117519)
## What this does
Introduces `DelegatedAgentSignalDetails`, a Pydantic model that replaces
the ad-hoc `dict` used for `signal_details` on `SEER_DELEGATED_*`
attribution signals:
```python
class DelegatedAgentSignalDetails(BaseModel):
agent_id: str | None = None
pr_url: str
run_id: int | None = None
```
`run_id` is threaded through both paths that write these signals:
- **Polling path** (`poll_github_copilot_agents`,
`poll_claude_code_agents` → `poll_claude_agent`): reads
`autofix_state.run_id` and passes it to
`attribute_delegated_agent_pull_request`.
- **Seer RPC callback** (`record_pr_attribution`): validates the
incoming `signal_details` dict through `DelegatedAgentSignalDetails`
when the signal type is any `SEER_DELEGATED_*` value. Missing `pr_url`
raises a `ParseError`; nullable fields default to `None`.
The Cursor webhook has no autofix state at webhook time, so `run_id`
remains `None` there.
## Why
`run_id` is the natural join key back to Seer's run state and to
`SeerRun` in Sentry's DB — having it in `signal_details` makes post-hoc
attribution debugging much easier. The typed model enforces the contract
explicitly so future callers can't silently omit fields.
Refs CW-1493
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
0 commit comments