|
227 | 227 |
|
228 | 228 | expect(config.provider).not_to be_nil |
229 | 229 | expect(config.provider.name).to eq('fakeProvider') |
230 | | - expect(config.tracker).not_to be_nil |
231 | | - expect(config.tracker.send(:flag_data)).to include( |
| 230 | + tracker = config.create_tracker |
| 231 | + expect(tracker).not_to be_nil |
| 232 | + expect(tracker.send(:flag_data)).to include( |
232 | 233 | modelName: 'fakeModel', |
233 | 234 | providerName: 'fakeProvider' |
234 | 235 | ) |
|
353 | 354 | expect(config.model).to be_nil |
354 | 355 | expect(config.messages).to be_nil |
355 | 356 | expect(config.provider).to be_nil |
356 | | - expect(config.tracker).not_to be_nil |
357 | | - expect(config.tracker.send(:flag_data)).to include( |
| 357 | + tracker = config.create_tracker |
| 358 | + expect(tracker).not_to be_nil |
| 359 | + expect(tracker.send(:flag_data)).to include( |
358 | 360 | modelName: '', |
359 | 361 | providerName: '' |
360 | 362 | ) |
|
375 | 377 |
|
376 | 378 | expect(config.enabled).to be false |
377 | 379 | end |
| 380 | + |
| 381 | + it 'create_tracker returns a new tracker with a fresh runId each time' do |
| 382 | + context = LaunchDarkly::LDContext.create({ key: 'user-key', kind: 'user' }) |
| 383 | + config = ai_client.completion_config(key: 'model-config', context:, variables: { 'name' => 'World' }) |
| 384 | + |
| 385 | + tracker1 = config.create_tracker |
| 386 | + tracker2 = config.create_tracker |
| 387 | + |
| 388 | + expect(tracker1).to be_a(LaunchDarkly::Server::AI::AIConfigTracker) |
| 389 | + expect(tracker2).to be_a(LaunchDarkly::Server::AI::AIConfigTracker) |
| 390 | + expect(tracker1).not_to equal(tracker2) |
| 391 | + |
| 392 | + run_id1 = tracker1.send(:flag_data)[:runId] |
| 393 | + run_id2 = tracker2.send(:flag_data)[:runId] |
| 394 | + expect(run_id1).not_to eq(run_id2) |
| 395 | + expect(run_id1).to match(/\A[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\z/i) |
| 396 | + expect(run_id2).to match(/\A[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\z/i) |
| 397 | + end |
| 398 | + |
| 399 | + it 'create_tracker preserves flag metadata across calls' do |
| 400 | + context = LaunchDarkly::LDContext.create({ key: 'user-key', kind: 'user' }) |
| 401 | + config = ai_client.completion_config(key: 'model-config', context:, variables: { 'name' => 'World' }) |
| 402 | + |
| 403 | + tracker = config.create_tracker |
| 404 | + flag_data = tracker.send(:flag_data) |
| 405 | + |
| 406 | + expect(flag_data[:configKey]).to eq('model-config') |
| 407 | + expect(flag_data[:variationKey]).to eq('abcd') |
| 408 | + expect(flag_data[:version]).to eq(1) |
| 409 | + expect(flag_data[:modelName]).to eq('fakeModel') |
| 410 | + expect(flag_data[:providerName]).to eq('fakeProvider') |
| 411 | + end |
| 412 | + |
| 413 | + it 'create_tracker returns nil for static disabled config' do |
| 414 | + config = LaunchDarkly::Server::AI::AIConfig.disabled |
| 415 | + expect(config.create_tracker).to be_nil |
| 416 | + end |
| 417 | + |
| 418 | + it 'round-trips a tracker through a resumption token via client create_tracker' do |
| 419 | + context = LaunchDarkly::LDContext.create({ key: 'user-key', kind: 'user' }) |
| 420 | + config = ai_client.completion_config(key: 'model-config', context:, variables: { 'name' => 'World' }) |
| 421 | + |
| 422 | + tracker = config.create_tracker |
| 423 | + token = tracker.resumption_token |
| 424 | + original_run_id = tracker.send(:flag_data)[:runId] |
| 425 | + |
| 426 | + restored = ai_client.create_tracker(token: token, context: context) |
| 427 | + |
| 428 | + expect(restored).to be_a(LaunchDarkly::Server::AI::AIConfigTracker) |
| 429 | + expect(restored.send(:flag_data)[:runId]).to eq(original_run_id) |
| 430 | + expect(restored.send(:flag_data)[:configKey]).to eq('model-config') |
| 431 | + expect(restored.send(:flag_data)[:modelName]).to eq('') |
| 432 | + expect(restored.send(:flag_data)[:providerName]).to eq('') |
| 433 | + end |
| 434 | + |
| 435 | + it 'each tracker has independent at-most-once tracking' do |
| 436 | + context = LaunchDarkly::LDContext.create({ key: 'user-key', kind: 'user' }) |
| 437 | + config = ai_client.completion_config(key: 'model-config', context:, variables: { 'name' => 'World' }) |
| 438 | + |
| 439 | + tracker1 = config.create_tracker |
| 440 | + tracker2 = config.create_tracker |
| 441 | + |
| 442 | + tracker1.track_duration(100) |
| 443 | + tracker2.track_duration(200) |
| 444 | + |
| 445 | + expect(tracker1.summary.duration).to eq(100) |
| 446 | + expect(tracker2.summary.duration).to eq(200) |
| 447 | + end |
378 | 448 | end |
379 | 449 |
|
380 | 450 | describe LaunchDarkly::Server::AI::AIConfig do |
|
0 commit comments