feat(sdk): add external sink#175
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
lan17
left a comment
There was a problem hiding this comment.
I like the direction here, but I don't think this base PR is ready to merge yet. The main thing I'd fix first is the enabled= override becoming sticky process state. I also think we need an explicit lifecycle/ownership story for external sinks before we merge the base abstraction.
|
@lan17 Thanks, I agree those were the two biggest issues in the base abstraction. I fixed the sticky enabled= behavior first. init_observability(enabled=...) no longer writes back into the process-global SDK settings, so it now behaves as a per-call override for that initialization path instead of poisoning later init/re-init flows for the rest of the process. I also made the external-sink ownership model explicit. Caller-registered sinks are now documented as caller-owned: the SDK does not flush, close, or unregister them during shutdown, and shutdown_observability() only drains SDK-owned resources like the built-in batcher. I added regression coverage for both behaviors so the base API has a clear lifecycle boundary before we build on it further. |
lan17
left a comment
There was a problem hiding this comment.
Looks good to me. The main issues from the earlier round were addressed, and the overall shape here makes sense. I left a couple of follow-up comments around fanout semantics and sink registration bookkeeping, but I don't think either one should hold this up.
## [2.4.0](ts-sdk-v2.3.0...ts-sdk-v2.4.0) (2026-04-22) ### Features * **evaluators:** add built-in budget evaluator for per-agent cost tracking ([#144](#144)) ([d4ce113](d4ce113)), closes [#130](#130) * **sdk:** add external sink ([#175](#175)) ([45f3645](45f3645)) * **server:** Align condition and template depth limits ([#166](#166)) ([03f402e](03f402e)) * **server:** Phase 0: add control version history and soft-delete unusable legacy controls ([#172](#172)) ([e5b2b33](e5b2b33)) ### Bug Fixes * **examples:** fix crewai examples ([#179](#179)) ([9004ea3](9004ea3))
|
🎉 This PR is included in version 2.4.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Summary
Added a vendor-neutral external control-event sink registration API in the Python SDK so integrations can receive finalized
ControlExecutionEventpayloads without adding vendor-specific logic to OSS.Updated observability delivery so
observability_enabledis the master gate, and when enabled the SDK uses registered sinks if present, otherwise the existing default OSS batcher sink.Added docs and test coverage for sink registration, override behavior, fallback to default delivery, and local/server/merged event delivery parity.
Scope
User-facing/API changes:
register_control_event_sink(...),unregister_control_event_sink(...), andget_registered_control_event_sinks(...)to the Python SDK public APIInternal changes:
observability_enabledbefore any sink delivery occursOut of scope:
Risk and Rollout
Risk level: medium
Rollback plan: Revert the SDK observability sink-resolution changes and public sink registration API additions in the Python SDK. Since default OSS delivery remains the fallback when no external sink is registered, rollback is isolated to the SDK observability layer.
Testing
make check— focused validation was run instead. Full workspace checks were unnecessary for this scoped SDK change. There is also a pre-existing unrelated SDK typecheck issue aroundgoogle.adkuntyped imports.Checklist