feat!: Add per-execution runId, at-most-once tracking, and cross-process tracker resumption#1270
Conversation
|
@launchdarkly/js-sdk-common size report |
|
@launchdarkly/js-client-sdk size report |
|
@launchdarkly/browser size report |
|
@launchdarkly/js-client-sdk-common size report |
andrewklatzke
left a comment
There was a problem hiding this comment.
Had one question but overall LGTM
…ess tracker resumption - Each tracker now carries a `runId` (UUIDv4) included in all emitted events, scoping every metric to a single execution - At-most-once semantics: duplicate calls to trackDuration, trackTokens, trackSuccess/trackError, trackFeedback, and trackTimeToFirstToken on the same tracker are dropped with a warning - `tracker` property on config objects replaced by `createTracker()` factory; each call returns a new tracker with a fresh runId so repeated invocations are independent - `TrackedChat` and `Judge` now call `createTracker()` internally per invocation rather than accepting a pre-created tracker - `resumptionToken` getter encodes runId, configKey, variationKey, and version as URL-safe Base64 JSON for cross-process correlation - `LDAIConfigTrackerImpl.fromResumptionToken()` and `LDAIClient.createTracker()` reconstruct a tracker from a token, preserving the original runId (useful for associating deferred feedback with the originating execution) BREAKING CHANGE: `tracker` property removed from config types in favour of `createTracker?: () => LDAIConfigTracker`. `TrackedChat` and `Judge` constructors no longer accept a tracker argument. `getTracker()` methods removed from both classes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the removed tracker property with the new createTracker() factory pattern in bedrock, openai, and vercel-ai examples. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
197c366 to
7fc3a54
Compare
Summary
runId(UUIDv4) included in all emitted events, scoping every metric to a single executiontrackDuration,trackTokens,trackSuccess/trackError,trackFeedback, andtrackTimeToFirstTokencan only fire once per tracker instance; subsequent calls are dropped with a warningtrackerproperty on config objects replaced by acreateTracker()factory — each call returns a new tracker with a freshrunId, making repeatedinvoke()/evaluate()calls fully independentTrackedChatandJudgecallcreateTracker()internally at the start of each invocation rather than holding a shared trackerresumptionTokengetter on the tracker encodesrunId,configKey,variationKey, andversionas URL-safe Base64 JSON, enabling cross-process event correlationLDAIConfigTrackerImpl.fromResumptionToken()andLDAIClient.createTracker()reconstruct a tracker from a token with the originalrunIdpreserved — useful for associating deferred user feedback with the originating executionBreaking changes
trackerproperty removed from all config types; replaced bycreateTracker?: () => LDAIConfigTrackerTrackedChatandJudgeconstructors no longer accept a tracker argumentgetTracker()removed from bothTrackedChatandJudgegetTrackData()return type now includesrunId: stringas the first fieldTest plan
yarn workspace @launchdarkly/server-sdk-ai test— all 110 tests passyarn workspace @launchdarkly/server-sdk-ai lint— no lint errorsresumptionTokenround-trips correctly throughfromResumptionToken🤖 Generated with Claude Code
Note
Medium Risk
Breaking API change replaces
trackerwithcreateTracker()and changes how metrics are emitted; incorrect adoption could drop or misattribute analytics events. Adds new runId/resumption-token parsing and at-most-once guards that may affect existing metric call patterns.Overview
Refactors AI config tracking to be per-execution. Config objects no longer expose a shared
tracker; they now providecreateTracker()which returns a fresh tracker (newrunId) each invocation, andTrackedChat/Judgeconstruct a tracker internally at the start ofinvoke()/evaluate().Adds run correlation and tracker resumption.
LDAIConfigTrackernow includesrunIdingetTrackData(),LDAIConfigTrackerImplcan emit/parse a URL-safe Base64resumptionToken, andLDAIClientImpladdscreateTracker(token, context)to reconstruct a tracker for deferred tracking across processes.Enforces at-most-once metric emission per tracker instance. Duplicate calls to
trackDuration,trackTokens,trackSuccess/trackError,trackFeedback, andtrackTimeToFirstTokenare dropped with warnings. Tests and examples are updated to the newcreateTracker()flow and constructor signatures (removinggetTracker()and tracker constructor args).Reviewed by Cursor Bugbot for commit e2b5362. Bugbot is set up for automated code reviews on this repo. Configure here.