Skip to content

Commit 9f7ec17

Browse files
authored
fix: Improve usage reporting (#18)
1 parent 73f2ad1 commit 9f7ec17

7 files changed

Lines changed: 77 additions & 19 deletions

File tree

examples/chatbot/aws-bedrock/hello_bedrock.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def map_converse_arguments(model_id, messages)
102102
# enabled: false
103103
# )
104104

105-
ai_config = ai_client.config(
105+
ai_config = ai_client.completion_config(
106106
ai_config_key,
107107
context,
108108
DEFAULT_VALUE

examples/chatbot/openai/hello_openai.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def agent_was_helpful(helpful)
8989
name: 'Lucy',
9090
})
9191

92-
ai_config = ai_client.config(
92+
ai_config = ai_client.completion_config(
9393
ai_config_key,
9494
context,
9595
DEFAULT_VALUE

lib/launchdarkly-server-sdk-ai.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
require 'mustache'
55

66
require 'server/ai/version'
7+
require 'server/ai/sdk_info'
78
require 'server/ai/client'
89
require 'server/ai/ai_config_tracker'
910

lib/server/ai/client.rb

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'ldclient-rb'
44
require 'mustache'
55
require_relative 'ai_config_tracker'
6+
require_relative 'sdk_info'
67

78
module LaunchDarkly
89
#
@@ -127,6 +128,15 @@ def to_h
127128
#
128129
# The Client class is the main entry point for the LaunchDarkly AI SDK.
129130
#
131+
TRACK_SDK_INFO = '$ld:ai:sdk:info'
132+
TRACK_USAGE_COMPLETION_CONFIG = '$ld:ai:usage:completion-config'
133+
134+
INIT_TRACK_CONTEXT = LaunchDarkly::LDContext.create({
135+
kind: 'ld_ai',
136+
key: 'ld-internal-tracking',
137+
anonymous: true,
138+
})
139+
130140
class Client
131141
attr_reader :logger, :ld_client
132142

@@ -135,6 +145,17 @@ def initialize(ld_client)
135145

136146
@ld_client = ld_client
137147
@logger = LaunchDarkly::Server::AI.default_logger
148+
149+
@ld_client.track(
150+
TRACK_SDK_INFO,
151+
INIT_TRACK_CONTEXT,
152+
{
153+
aiSdkName: LaunchDarkly::Server::AI::SDK_NAME,
154+
aiSdkVersion: LaunchDarkly::Server::AI::VERSION,
155+
aiSdkLanguage: LaunchDarkly::Server::AI::SDK_LANGUAGE,
156+
},
157+
1
158+
)
138159
end
139160

140161
#
@@ -146,9 +167,21 @@ def initialize(ld_client)
146167
# @param variables [Hash] Optional variables for rendering messages
147168
# @return [AIConfig] An AIConfig instance containing the configuration data
148169
#
170+
def completion_config(config_key, context, default_value = nil, variables = nil)
171+
@ld_client.track(TRACK_USAGE_COMPLETION_CONFIG, context, config_key, 1)
172+
173+
_completion_config(config_key, context, default_value, variables)
174+
end
175+
176+
# @deprecated Use {#completion_config} instead.
149177
def config(config_key, context, default_value = nil, variables = nil)
150-
@ld_client.track('$ld:ai:config:function:single', context, config_key, 1)
178+
warn '[DEPRECATION] `config` is deprecated. Use `completion_config` instead.'
179+
completion_config(config_key, context, default_value, variables)
180+
end
181+
182+
private
151183

184+
def _completion_config(config_key, context, default_value = nil, variables = nil)
152185
variation = @ld_client.variation(
153186
config_key,
154187
context,
@@ -158,7 +191,6 @@ def config(config_key, context, default_value = nil, variables = nil)
158191
all_variables = variables ? variables.dup : {}
159192
all_variables[:ldctx] = context.to_h
160193

161-
# Process messages and provider configuration
162194
messages = nil
163195
if variation[:messages].is_a?(Array) && variation[:messages].all? { |msg| msg.is_a?(Hash) }
164196
messages = variation[:messages].map do |message|

lib/server/ai/sdk_info.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# frozen_string_literal: true
2+
3+
module LaunchDarkly
4+
module Server
5+
module AI
6+
SDK_NAME = 'launchdarkly-server-sdk-ai'
7+
SDK_LANGUAGE = 'ruby'
8+
end
9+
end
10+
end

spec/server/ai/client_spec.rb

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,23 @@
129129
it 'raises an error if LDClient is not an instance of LaunchDarkly::LDClient' do
130130
expect { described_class.new('not a client') }.to raise_error(ArgumentError, 'LDClient instance is required')
131131
end
132+
133+
it 'tracks sdk-info on construction' do
134+
expect(ld_client).to receive(:track).with(
135+
'$ld:ai:sdk:info',
136+
an_object_satisfying { |ctx| ctx.kind == 'ld_ai' && ctx.key == 'ld-internal-tracking' && ctx.get_value(:anonymous) == true },
137+
{
138+
aiSdkName: LaunchDarkly::Server::AI::SDK_NAME,
139+
aiSdkVersion: LaunchDarkly::Server::AI::VERSION,
140+
aiSdkLanguage: LaunchDarkly::Server::AI::SDK_LANGUAGE,
141+
},
142+
1
143+
)
144+
described_class.new(ld_client)
145+
end
132146
end
133147

134-
describe '#config' do
148+
describe '#completion_config' do
135149
it 'uses default config on invalid flag' do
136150
context = LaunchDarkly::LDContext.create({ key: 'user-key', kind: 'user' })
137151
model = LaunchDarkly::Server::AI::ModelConfig.new(name: 'fakeModel',
@@ -146,7 +160,7 @@
146160
)
147161
variables = { 'name' => 'World' }
148162

149-
config = ai_client.config('missing-flag', context, default_config, variables)
163+
config = ai_client.completion_config('missing-flag', context, default_config, variables)
150164
expect(config.messages).not_to be_nil
151165
expect(config.messages.length).to be > 0
152166
expect(config.messages[0].content).to eq('Hello, World!')
@@ -167,7 +181,7 @@
167181
)
168182
variables = { 'name' => 'World' }
169183

170-
config = ai_client.config('model-config', context, default_value, variables)
184+
config = ai_client.completion_config('model-config', context, default_value, variables)
171185
expect(config.messages).not_to be_nil
172186
expect(config.messages.length).to be > 0
173187
expect(config.messages[0].content).to eq('Hello, World!')
@@ -187,7 +201,7 @@
187201
messages: []
188202
)
189203

190-
config = ai_client.config('model-config', context, default_value, {})
204+
config = ai_client.completion_config('model-config', context, default_value, {})
191205

192206
expect(config.messages).not_to be_nil
193207
expect(config.messages.length).to be > 0
@@ -209,7 +223,7 @@
209223
)
210224
variables = { 'name' => 'World' }
211225

212-
config = ai_client.config('model-config', context, default_value, variables)
226+
config = ai_client.completion_config('model-config', context, default_value, variables)
213227

214228
expect(config.provider).not_to be_nil
215229
expect(config.provider.name).to eq('fakeProvider')
@@ -229,7 +243,7 @@
229243
)
230244
variables = { 'name' => 'World' }
231245

232-
config = ai_client.config('ctx-interpolation', context, default_value, variables)
246+
config = ai_client.completion_config('ctx-interpolation', context, default_value, variables)
233247

234248
expect(config.messages).not_to be_nil
235249
expect(config.messages.length).to be > 0
@@ -255,7 +269,7 @@
255269
)
256270
variables = { 'name' => 'World' }
257271

258-
config = ai_client.config('multi-ctx-interpolation', context, default_value, variables)
272+
config = ai_client.completion_config('multi-ctx-interpolation', context, default_value, variables)
259273

260274
expect(config.messages).not_to be_nil
261275
expect(config.messages.length).to be > 0
@@ -278,7 +292,7 @@
278292
)
279293
variables = { 'name' => 'World', 'day' => 'Monday' }
280294

281-
config = ai_client.config('multiple-messages', context, default_value, variables)
295+
config = ai_client.completion_config('multiple-messages', context, default_value, variables)
282296

283297
expect(config.messages).not_to be_nil
284298
expect(config.messages.length).to be > 0
@@ -300,7 +314,7 @@
300314
messages: []
301315
)
302316

303-
config = ai_client.config('off-config', context, default_value, {})
317+
config = ai_client.completion_config('off-config', context, default_value, {})
304318

305319
expect(config.model).not_to be_nil
306320
expect(config.enabled).to be false
@@ -317,7 +331,7 @@
317331
messages: []
318332
)
319333

320-
config = ai_client.config('initial-config-disabled', context, default_value, {})
334+
config = ai_client.completion_config('initial-config-disabled', context, default_value, {})
321335

322336
expect(config.enabled).to be false
323337
expect(config.model).to be_nil
@@ -333,7 +347,7 @@
333347
messages: []
334348
)
335349

336-
config = ai_client.config('initial-config-enabled', context, default_value, {})
350+
config = ai_client.completion_config('initial-config-enabled', context, default_value, {})
337351

338352
expect(config.enabled).to be true
339353
expect(config.model).to be_nil

spec/server/ai/config_tracker_spec.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -378,10 +378,11 @@
378378
end
379379
end
380380

381-
describe 'config method tracking' do
382-
it 'calls track with correct parameters when config is called' do
381+
describe 'completion_config method tracking' do
382+
it 'calls track with correct parameters when completion_config is called' do
383+
allow(ld_client).to receive(:track)
383384
expect(ld_client).to receive(:track).with(
384-
'$ld:ai:config:function:single',
385+
'$ld:ai:usage:completion-config',
385386
context,
386387
'test-config-key',
387388
1
@@ -396,7 +397,7 @@
396397
client = LaunchDarkly::Server::AI::Client.new(ld_client)
397398
default_value = LaunchDarkly::Server::AI::AIConfig.new(enabled: false)
398399

399-
client.config('test-config-key', context, default_value)
400+
client.completion_config('test-config-key', context, default_value)
400401
end
401402
end
402403
end

0 commit comments

Comments
 (0)