Skip to content

Add a new method to track custom events for AI operations #858

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions packages/sdk/server-ai/__tests__/LDAIConfigTrackerImpl.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,80 @@ it('tracks negative feedback', () => {
);
});

it('tracks custom event with data', () => {
const tracker = new LDAIConfigTrackerImpl(
mockLdClient,
configKey,
variationKey,
version,
testContext,
);
const customData = { property: 'value', count: 42 };
tracker.trackCustomEvent('test-event', customData);

expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:custom:test-event',
testContext,
{ configKey, variationKey, version, custom: customData },
undefined,
);
});

it('tracks custom event with metric value', () => {
const tracker = new LDAIConfigTrackerImpl(
mockLdClient,
configKey,
variationKey,
version,
testContext,
);
tracker.trackCustomEvent('test-event', undefined, 123.45);

expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:custom:test-event',
testContext,
{ configKey, variationKey, version, custom: undefined },
123.45,
);
});

it('tracks custom event with both data and metric value', () => {
const tracker = new LDAIConfigTrackerImpl(
mockLdClient,
configKey,
variationKey,
version,
testContext,
);
const customData = { property: 'value' };
tracker.trackCustomEvent('test-event', customData, 123.45);

expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:custom:test-event',
testContext,
{ configKey, variationKey, version, custom: customData },
123.45,
);
});

it('tracks custom event with no data or metric value', () => {
const tracker = new LDAIConfigTrackerImpl(
mockLdClient,
configKey,
variationKey,
version,
testContext,
);
tracker.trackCustomEvent('test-event');

expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:custom:test-event',
testContext,
{ configKey, variationKey, version, custom: undefined },
undefined,
);
});

it('tracks success', () => {
const tracker = new LDAIConfigTrackerImpl(
mockLdClient,
Expand Down Expand Up @@ -429,6 +503,8 @@ it('summarizes tracked metrics', () => {
});
tracker.trackFeedback({ kind: LDFeedbackKind.Positive });
tracker.trackSuccess();
tracker.trackCustomEvent('event1', { test: 'data' });
tracker.trackCustomEvent('event2', undefined, 42);

const summary = tracker.getSummary();

Expand All @@ -443,6 +519,18 @@ it('summarizes tracked metrics', () => {
kind: 'positive',
},
success: true,
customEvents: [
{
name: 'event1',
data: { test: 'data' },
metricValue: undefined,
},
{
name: 'event2',
data: undefined,
metricValue: 42,
},
],
});
});

Expand Down
14 changes: 14 additions & 0 deletions packages/sdk/server-ai/src/LDAIConfigTrackerImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@ export class LDAIConfigTrackerImpl implements LDAIConfigTracker {
}
}

trackCustomEvent(eventName: string, data?: any, metricValue?: number): void {
if (!this._trackedMetrics.customEvents) {
this._trackedMetrics.customEvents = [];
}
this._trackedMetrics.customEvents.push({
name: eventName,
data,
metricValue,
});

const trackData = { ...this._getTrackData(), custom: data };
this._ldClient.track(`$ld:ai:custom:${eventName}`, this._context, trackData, metricValue);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any sanitization you want to consider on the event name or is it ok to append it no matter what the supplied value is?

}

trackSuccess(): void {
this._trackedMetrics.success = true;
this._ldClient.track('$ld:ai:generation', this._context, this._getTrackData(), 1);
Expand Down
31 changes: 31 additions & 0 deletions packages/sdk/server-ai/src/api/config/LDAIConfigTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,26 @@ export interface LDAIMetricSummary {
* Time to first token for this generation.
*/
timeToFirstTokenMs?: number;

/**
* Custom events tracked for this operation.
*/
customEvents?: Array<{
/**
* The name of the custom event.
*/
name: string;

/**
* Optional additional information associated with the event.
*/
data?: any;

/**
* Optional numeric value for analytics.
*/
metricValue?: number;
}>;
}

/**
Expand Down Expand Up @@ -67,6 +87,17 @@ export interface LDAIConfigTracker {
*/
trackFeedback(feedback: { kind: LDFeedbackKind }): void;

/**
* Track a custom event related to AI operations.
*
* This method allows for tracking arbitrary custom events specific to AI operations.
*
* @param eventName The name of the custom event.
* @param data Optional additional information to associate with the event.
* @param metricValue A numeric value that can be used for analytics. Can be omitted if not needed.
*/
trackCustomEvent(eventName: string, data?: any, metricValue?: number): void;

/**
* Track the time to first token for this generation.
*
Expand Down
Loading