-
Notifications
You must be signed in to change notification settings - Fork 32
fix: Improve usage reporting #1108
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
base: main
Are you sure you want to change the base?
Changes from all commits
621be12
6b5da53
21f6e76
ef82f52
903f126
a765834
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,22 +23,40 @@ import { LDAIClient } from './api/LDAIClient'; | |
| import { AIProviderFactory, SupportedAIProvider } from './api/providers'; | ||
| import { LDAIConfigTrackerImpl } from './LDAIConfigTrackerImpl'; | ||
| import { LDClientMin } from './LDClientMin'; | ||
| import { aiSdkLanguage, aiSdkName, aiSdkVersion } from './sdkInfo'; | ||
|
|
||
| /** | ||
| * Tracking event keys for AI SDK usage metrics. | ||
| */ | ||
| const TRACK_CONFIG_SINGLE = '$ld:ai:config:function:single'; | ||
| const TRACK_CONFIG_CREATE_CHAT = '$ld:ai:config:function:createChat'; | ||
| const TRACK_JUDGE_SINGLE = '$ld:ai:judge:function:single'; | ||
| const TRACK_JUDGE_CREATE = '$ld:ai:judge:function:createJudge'; | ||
| const TRACK_AGENT_SINGLE = '$ld:ai:agent:function:single'; | ||
| const TRACK_AGENT_MULTIPLE = '$ld:ai:agent:function:multiple'; | ||
| const TRACK_SDK_INFO = '$ld:ai:sdk:info'; | ||
| const TRACK_USAGE_COMPLETION_CONFIG = '$ld:ai:usage:completion-config'; | ||
| const TRACK_USAGE_CREATE_CHAT = '$ld:ai:usage:create-chat'; | ||
| const TRACK_USAGE_JUDGE_CONFIG = '$ld:ai:usage:judge-config'; | ||
| const TRACK_USAGE_CREATE_JUDGE = '$ld:ai:usage:create-judge'; | ||
| const TRACK_USAGE_AGENT_CONFIG = '$ld:ai:usage:agent-config'; | ||
| const TRACK_USAGE_AGENT_CONFIGS = '$ld:ai:usage:agent-configs'; | ||
|
|
||
| const INIT_TRACK_CONTEXT: LDContext = { | ||
| kind: 'ld_ai', | ||
| key: 'ld-internal-tracking', | ||
| anonymous: true, | ||
| }; | ||
|
|
||
| export class LDAIClientImpl implements LDAIClient { | ||
| private _logger?: LDLogger; | ||
|
|
||
| constructor(private _ldClient: LDClientMin) { | ||
| this._logger = _ldClient.logger; | ||
| this._ldClient.track( | ||
| TRACK_SDK_INFO, | ||
| INIT_TRACK_CONTEXT, | ||
| { | ||
| aiSdkName, | ||
| aiSdkVersion, | ||
| aiSdkLanguage, | ||
| }, | ||
| 1, | ||
| ); | ||
| } | ||
|
|
||
| private _interpolateTemplate(template: string, variables: Record<string, unknown>): string { | ||
|
|
@@ -146,7 +164,7 @@ export class LDAIClientImpl implements LDAIClient { | |
| defaultValue: LDAICompletionConfigDefault, | ||
| variables?: Record<string, unknown>, | ||
| ): Promise<LDAICompletionConfig> { | ||
| this._ldClient.track(TRACK_CONFIG_SINGLE, context, key, 1); | ||
| this._ldClient.track(TRACK_USAGE_COMPLETION_CONFIG, context, key, 1); | ||
|
|
||
| const config = await this._evaluate(key, context, defaultValue, 'completion', variables); | ||
| return config as LDAICompletionConfig; | ||
|
|
@@ -170,7 +188,7 @@ export class LDAIClientImpl implements LDAIClient { | |
| defaultValue: LDAIJudgeConfigDefault, | ||
| variables?: Record<string, unknown>, | ||
| ): Promise<LDAIJudgeConfig> { | ||
| this._ldClient.track(TRACK_JUDGE_SINGLE, context, key, 1); | ||
| this._ldClient.track(TRACK_USAGE_JUDGE_CONFIG, context, key, 1); | ||
|
|
||
| const config = await this._evaluate(key, context, defaultValue, 'judge', variables); | ||
| return config as LDAIJudgeConfig; | ||
|
|
@@ -182,7 +200,7 @@ export class LDAIClientImpl implements LDAIClient { | |
| defaultValue: LDAIAgentConfigDefault, | ||
| variables?: Record<string, unknown>, | ||
| ): Promise<LDAIAgentConfig> { | ||
| this._ldClient.track(TRACK_AGENT_SINGLE, context, key, 1); | ||
| this._ldClient.track(TRACK_USAGE_AGENT_CONFIG, context, key, 1); | ||
|
|
||
| const config = await this._evaluate(key, context, defaultValue, 'agent', variables); | ||
| return config as LDAIAgentConfig; | ||
|
|
@@ -204,7 +222,12 @@ export class LDAIClientImpl implements LDAIClient { | |
| agentConfigs: T, | ||
| context: LDContext, | ||
| ): Promise<Record<T[number]['key'], LDAIAgentConfig>> { | ||
| this._ldClient.track(TRACK_AGENT_MULTIPLE, context, agentConfigs.length, agentConfigs.length); | ||
| this._ldClient.track( | ||
| TRACK_USAGE_AGENT_CONFIGS, | ||
| context, | ||
| agentConfigs.length, | ||
| agentConfigs.length, | ||
| ); | ||
|
|
||
| const agents = {} as Record<T[number]['key'], LDAIAgentConfig>; | ||
|
|
||
|
|
@@ -241,7 +264,7 @@ export class LDAIClientImpl implements LDAIClient { | |
| variables?: Record<string, unknown>, | ||
| defaultAiProvider?: SupportedAIProvider, | ||
| ): Promise<TrackedChat | undefined> { | ||
| this._ldClient.track(TRACK_CONFIG_CREATE_CHAT, context, key, 1); | ||
| this._ldClient.track(TRACK_USAGE_CREATE_CHAT, context, key, 1); | ||
|
|
||
| const config = await this.completionConfig(key, context, defaultValue, variables); | ||
|
|
||
|
|
@@ -272,7 +295,7 @@ export class LDAIClientImpl implements LDAIClient { | |
| variables?: Record<string, unknown>, | ||
| defaultAiProvider?: SupportedAIProvider, | ||
| ): Promise<Judge | undefined> { | ||
| this._ldClient.track(TRACK_JUDGE_CREATE, context, key, 1); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate usage events for chat creationMedium Severity
Additional Locations (1) |
||
| this._ldClient.track(TRACK_USAGE_CREATE_JUDGE, context, key, 1); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate usage events for judge creationMedium Severity
Additional Locations (1) |
||
|
|
||
| try { | ||
| if (variables?.message_history !== undefined) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,6 @@ import { | |
| LDTokenUsage, | ||
| } from './api/metrics'; | ||
| import { LDClientMin } from './LDClientMin'; | ||
| import { aiSdkName, aiSdkVersion } from './sdkInfo'; | ||
|
|
||
| export class LDAIConfigTrackerImpl implements LDAIConfigTracker { | ||
| private _trackedMetrics: LDAIMetricSummary = {}; | ||
|
|
@@ -33,17 +32,13 @@ export class LDAIConfigTrackerImpl implements LDAIConfigTracker { | |
| version: number; | ||
| modelName: string; | ||
| providerName: string; | ||
| aiSdkName: string; | ||
| aiSdkVersion: string; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SDK info removed from metrics payloadsMedium Severity
Additional Locations (1)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is intentional and we are making the change while still in pre-release. This is not something downstream consumers should be relying on which is part of the reason for this change. |
||
| } { | ||
| return { | ||
| variationKey: this._variationKey, | ||
| configKey: this._configKey, | ||
| version: this._version, | ||
| modelName: this._modelName, | ||
| providerName: this._providerName, | ||
| aiSdkName, | ||
| aiSdkVersion, | ||
| }; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| export const aiSdkName = '@launchdarkly/server-sdk-ai'; | ||
| export const aiSdkVersion = '0.16.2'; // x-release-please-version | ||
| export const aiSdkLanguage = 'javascript'; |


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Constructor tracking can spam events
Medium Severity
The
LDAIClientImplconstructor now unconditionally callstrackfor$ld:ai:sdk:info. If client instances are created per request/job (common in server code), this can generate high-volume duplicate events and unexpected side effects during object creation, increasing telemetry cost and potentially impacting latency.