[sdk/python] Preserve events when optional promoted fields are unset - #791
[sdk/python] Preserve events when optional promoted fields are unset#791SiddarthAA wants to merge 1 commit into
Conversation
…he event A promoted key left at None in **fields reached the wire as an explicit JSON null, so _validate_promoted_string refused it. But None is how a caller says "I have no value", and the refusal landed inside their emit helper — which swallows telemetry errors, because telemetry must not break a run. The event vanished with nothing logged. agent_end(error_type=None) is the shape every SUCCESSFUL run produces: error_type is populated only on a failing outcome. Found against a real multi-agent app, where it dropped agent_end for every session that succeeded, leaving a dangling agent_start, no outcome, and no evaluation — the server triggers evaluation on agent_end. The same fix closes the mirror bug on promoted numerics. _build omits None only from a dataclass's named `specifics`; `extra` is merged verbatim. So duration_ms=None was dropped as a named parameter and written as an explicit null through **fields — same value, two outcomes, decided by which door it came through. Both paths now agree: for a promoted column, no value means no key. Dropped with a warning rather than silently: passing None is still a mistake worth hearing about, it just must not cost the event. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Thanks @SiddarthAA for your contribution to Failproof AI! 🙌 We'd love to discuss your PR and welcome you to our community. Discord: https://discord.befailproof.ai/ |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe Python SDK now removes ChangesPromoted None handling
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to The SDK now omits optional promoted fields passed as None while preserving event delivery and warning callers. Regression coverage confirms the intended event contract, with no actionable merge risk remaining. Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. A rabbit checks the fields with care Comment |
Hermes
No summary yet. What this changesNo component map for this revision. RoundsNo review has finished on this pull request yet. FindingsNothing raised yet.
|
Hermes
The promoted-field omission behavior works for ordinary custom fields, but What this changesflowchart LR
n0PythontelemetryeventAPI["~ Python telemetry event API"]
n1Eventpayloadserializer["Event payload serializer"]
n2Servercontracttests["~ Server-contract tests"]
n0PythontelemetryeventAPI -- "validated fields become payloads" --> n1Eventpayloadserializer
n2Servercontracttests -- "exercises promoted fields" --> n0PythontelemetryeventAPI
Rounds
FindingsOpen
|
hermes-exosphere
left a comment
There was a problem hiding this comment.
Hermes found no blocking issues in this revision.
1 advisory finding
- Medium/High
duration_ms=Noneis still rejected on closing events —tool_result,hook_completed,human_input, andagent_resumereject anyduration_mskey before calling_validate_fields, so theirduration_ms=Noneextras never reach the new omission-and-warning loop. An isolated container reproduced the rejection for all four methods. The added numeric test only invokesagent_start, where duration is not auto-computed. (sdk/python/failproofai_sdk/_events.py:393)
Summary
error_typeandduration_mswhen passed asNonethrough**fields.agent_endevents.Why
Successful agent runs commonly have no
error_type. The SDK previously serialized that value asnull, rejected it during promoted-field validation, and silently lost the completeagent_endevent in best-effort integrations.Validation
998 passed, 6 skippedinsdk/pythonSummary by CodeRabbit
None.agent_endcalls are now recorded correctly without an unnecessary error field.Hermes review
7503d88b4f190e64aa20f56cd8f4b371b75a5a261d8f31d926828f3bae215c58f5b35baa44acbff0gpt-5.6-terraSummary
The promoted-field omission behavior works for ordinary custom fields, but
duration_ms=Noneremains rejected on all auto-computed closing-event APIs, contrary to the stated behavior.Changes
Nonepromoted custom fields with a warning before validation.Validation
Passeddocker run --rm --pull=always --network none --read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m -e PYTHONDONTWRITEBYTECODE=1 -v "$PWD/sdk/python:/src:ro" -w /src python:3.11-slim python -c '<targeted promoted-field assertions>'— Confirmed promotedNonecustom fields are omitted, invalid non-null string/numeric values still raise, andagent_end(error_type=None)is emitted with a warning. (8s)Passeddocker run --rm --network none --read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m -e PYTHONDONTWRITEBYTECODE=1 -v "$PWD/sdk/python:/src:ro" -w /src python:3.11-slim python -c '<auto-computed duration assertions>'— Confirmed the auto-computed-duration guards rejectduration_ms=Noneon all four closing-event APIs, reproducing the finding. (0s)Findings
No blocking findings.
1 advisory finding
duration_ms=Noneis still rejected on closing events —tool_result,hook_completed,human_input, andagent_resumereject anyduration_mskey before calling_validate_fields, so theirduration_ms=Noneextras never reach the new omission-and-warning loop. An isolated container reproduced the rejection for all four methods. The added numeric test only invokesagent_start, where duration is not auto-computed. (sdk/python/failproofai_sdk/_events.py:393)Open questions
None.
Policy overrides
None.