Skip to content

Commit f7dbee8

Browse files
authored
feat!: Remove bedrock-specific tracker method (#1385)
1 parent 44350e8 commit f7dbee8

10 files changed

Lines changed: 27 additions & 222 deletions

File tree

packages/sdk/server-ai/__tests__/LDAIConfigTrackerImpl.test.ts

Lines changed: 0 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -167,112 +167,6 @@ it('tracks success', () => {
167167
);
168168
});
169169

170-
it('tracks Bedrock conversation with successful response', () => {
171-
const tracker = new LDAIConfigTrackerImpl(
172-
mockLdClient,
173-
testRunId,
174-
configKey,
175-
variationKey,
176-
version,
177-
modelName,
178-
providerName,
179-
testContext,
180-
);
181-
182-
const TOTAL_TOKENS = 100;
183-
const PROMPT_TOKENS = 49;
184-
const COMPLETION_TOKENS = 51;
185-
186-
const response = {
187-
$metadata: { httpStatusCode: 200 },
188-
metrics: { latencyMs: 500 },
189-
usage: {
190-
inputTokens: PROMPT_TOKENS,
191-
outputTokens: COMPLETION_TOKENS,
192-
totalTokens: TOTAL_TOKENS,
193-
},
194-
};
195-
196-
tracker.trackBedrockConverseMetrics(response);
197-
198-
expect(mockTrack).toHaveBeenCalledWith(
199-
'$ld:ai:generation:success',
200-
testContext,
201-
getExpectedTrackData(),
202-
1,
203-
);
204-
205-
expect(mockTrack).not.toHaveBeenCalledWith(
206-
'$ld:ai:generation:error',
207-
expect.anything(),
208-
expect.anything(),
209-
expect.anything(),
210-
);
211-
212-
expect(mockTrack).toHaveBeenCalledWith(
213-
'$ld:ai:duration:total',
214-
testContext,
215-
getExpectedTrackData(),
216-
500,
217-
);
218-
219-
expect(mockTrack).toHaveBeenCalledWith(
220-
'$ld:ai:tokens:total',
221-
testContext,
222-
getExpectedTrackData(),
223-
TOTAL_TOKENS,
224-
);
225-
226-
expect(mockTrack).toHaveBeenCalledWith(
227-
'$ld:ai:tokens:input',
228-
testContext,
229-
getExpectedTrackData(),
230-
PROMPT_TOKENS,
231-
);
232-
233-
expect(mockTrack).toHaveBeenCalledWith(
234-
'$ld:ai:tokens:output',
235-
testContext,
236-
getExpectedTrackData(),
237-
COMPLETION_TOKENS,
238-
);
239-
});
240-
241-
it('tracks Bedrock conversation with error response', () => {
242-
const tracker = new LDAIConfigTrackerImpl(
243-
mockLdClient,
244-
testRunId,
245-
configKey,
246-
variationKey,
247-
version,
248-
modelName,
249-
providerName,
250-
testContext,
251-
);
252-
253-
const response = {
254-
$metadata: { httpStatusCode: 400 },
255-
};
256-
257-
tracker.trackBedrockConverseMetrics(response);
258-
259-
expect(mockTrack).toHaveBeenCalledTimes(1);
260-
261-
expect(mockTrack).toHaveBeenCalledWith(
262-
'$ld:ai:generation:error',
263-
testContext,
264-
getExpectedTrackData(),
265-
1,
266-
);
267-
268-
expect(mockTrack).not.toHaveBeenCalledWith(
269-
expect.stringMatching(/^\$ld:ai:tokens:/),
270-
expect.anything(),
271-
expect.anything(),
272-
expect.anything(),
273-
);
274-
});
275-
276170
it('tracks tokens', () => {
277171
const tracker = new LDAIConfigTrackerImpl(
278172
mockLdClient,

packages/sdk/server-ai/__tests__/ManagedAgent.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ describe('ManagedAgent', () => {
3333
trackFeedback: jest.fn(),
3434
trackTimeToFirstToken: jest.fn(),
3535
trackDurationOf: jest.fn(),
36-
trackBedrockConverseMetrics: jest.fn(),
3736
getSummary: jest.fn().mockReturnValue({ success: true, resumptionToken: 'agent-resumption-token' }),
3837
} as any;
3938

packages/sdk/server-ai/__tests__/ManagedModel.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ describe('ManagedModel', () => {
2424
trackFeedback: jest.fn(),
2525
trackTimeToFirstToken: jest.fn(),
2626
trackDurationOf: jest.fn(),
27-
trackBedrockConverseMetrics: jest.fn(),
2827
getSummary: jest.fn().mockReturnValue({}),
2928
trackJudgeResult: jest.fn(),
3029
resumptionToken: 'resumption-token-123',

packages/sdk/server-ai/__tests__/ManagedModelRun.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ describe('ManagedModel.run() evaluations', () => {
3333
trackFeedback: jest.fn(),
3434
trackTimeToFirstToken: jest.fn(),
3535
trackDurationOf: jest.fn(),
36-
trackBedrockConverseMetrics: jest.fn(),
3736
getSummary: jest
3837
.fn()
3938
.mockReturnValue({ success: true, resumptionToken: 'test-resumption-token' }),

packages/sdk/server-ai/__tests__/TokenUsage.test.ts

Lines changed: 0 additions & 39 deletions
This file was deleted.

packages/sdk/server-ai/examples/getting-started/bedrock/converse/src/index.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
/* eslint-disable no-console */
22
import 'dotenv/config';
33

4-
import { BedrockRuntimeClient, ConverseCommand, Message } from '@aws-sdk/client-bedrock-runtime';
4+
import {
5+
BedrockRuntimeClient,
6+
ConverseCommand,
7+
type ConverseCommandOutput,
8+
Message,
9+
} from '@aws-sdk/client-bedrock-runtime';
510

611
import { init, type LDContext } from '@launchdarkly/node-server-sdk';
712
import { Observability } from '@launchdarkly/observability-node';
8-
import { initAi } from '@launchdarkly/server-sdk-ai';
13+
import { initAi, type LDAIMetrics } from '@launchdarkly/server-sdk-ai';
914

1015
const awsClient = new BedrockRuntimeClient({
1116
region: process.env.AWS_DEFAULT_REGION ?? 'us-east-1',
@@ -34,6 +39,23 @@ const context: LDContext = {
3439
name: 'Sandy',
3540
};
3641

42+
// Extract LD AI metrics from a Bedrock Converse response. Passed to
43+
// tracker.trackMetricsOf, which wraps the AI call to track duration and
44+
// success automatically. The dedicated @launchdarkly/server-sdk-ai-bedrock
45+
// provider package will supply an equivalent extractor out of the box.
46+
function extractBedrockConverseMetrics(res: ConverseCommandOutput): LDAIMetrics {
47+
return {
48+
success: (res.$metadata?.httpStatusCode ?? 0) === 200,
49+
tokens: res.usage
50+
? {
51+
total: res.usage.totalTokens ?? 0,
52+
input: res.usage.inputTokens ?? 0,
53+
output: res.usage.outputTokens ?? 0,
54+
}
55+
: undefined,
56+
};
57+
}
58+
3759
function mapPromptToConversation(
3860
prompt: { role: 'user' | 'assistant' | 'system'; content: string }[],
3961
): Message[] {
@@ -93,8 +115,8 @@ async function main() {
93115
console.log(`\nSending sample question to ${aiConfig.model?.name}: "${sampleQuestion}"`);
94116
console.log('Waiting for response...');
95117

96-
const completion = tracker.trackBedrockConverseMetrics(
97-
await awsClient.send(
118+
const completion = await tracker.trackMetricsOf(extractBedrockConverseMetrics, () =>
119+
awsClient.send(
98120
new ConverseCommand({
99121
modelId: aiConfig.model?.name ?? 'no-model',
100122
messages: chatMessages,

packages/sdk/server-ai/src/LDAIConfigTrackerImpl.ts

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,7 @@ import { LDContext } from '@launchdarkly/js-server-sdk-common';
33
import { LDAIConfigTracker } from './api/config';
44
import { LDAIMetricSummary } from './api/model/types';
55
import { LDJudgeResult } from './api/judge/types';
6-
import {
7-
createBedrockTokenUsage,
8-
LDAIMetrics,
9-
LDFeedbackKind,
10-
LDTokenUsage,
11-
} from './api/metrics';
6+
import { LDAIMetrics, LDFeedbackKind, LDTokenUsage } from './api/metrics';
127
import { LDClientMin } from './LDClientMin';
138

149
export class LDAIConfigTrackerImpl implements LDAIConfigTracker {
@@ -275,31 +270,6 @@ export class LDAIConfigTrackerImpl implements LDAIConfigTracker {
275270
}
276271
}
277272

278-
trackBedrockConverseMetrics<
279-
TRes extends {
280-
$metadata: { httpStatusCode?: number };
281-
metrics?: { latencyMs?: number };
282-
usage?: {
283-
inputTokens?: number;
284-
outputTokens?: number;
285-
totalTokens?: number;
286-
};
287-
},
288-
>(res: TRes): TRes {
289-
if (res.$metadata?.httpStatusCode === 200) {
290-
this.trackSuccess();
291-
} else if (res.$metadata?.httpStatusCode && res.$metadata.httpStatusCode >= 400) {
292-
this.trackError();
293-
}
294-
if (res.metrics && res.metrics.latencyMs) {
295-
this.trackDuration(res.metrics.latencyMs);
296-
}
297-
if (res.usage) {
298-
this.trackTokens(createBedrockTokenUsage(res.usage));
299-
}
300-
return res;
301-
}
302-
303273
trackTokens(tokens: LDTokenUsage): void {
304274
if (this._trackedMetrics.tokens !== undefined) {
305275
this._ldClient.logger?.warn(

packages/sdk/server-ai/src/api/config/LDAIConfigTracker.ts

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -191,31 +191,6 @@ export interface LDAIConfigTracker {
191191
metricsExtractor: (stream: TStream) => Promise<LDAIMetrics>,
192192
): TStream;
193193

194-
/**
195-
* Track an AI run which uses Bedrock.
196-
*
197-
* This function will track the duration of the AI run, the token usage, and the success or error status.
198-
*
199-
* @param res The result of the Bedrock operation.
200-
* @returns The input operation.
201-
*
202-
* @remarks Subsequent calls emit only metrics not already recorded on this
203-
* Tracker. Call createTracker on the AI Config to start a new run.
204-
*/
205-
trackBedrockConverseMetrics<
206-
TRes extends {
207-
$metadata: { httpStatusCode?: number };
208-
metrics?: { latencyMs?: number };
209-
usage?: {
210-
inputTokens?: number;
211-
outputTokens?: number;
212-
totalTokens?: number;
213-
};
214-
},
215-
>(
216-
res: TRes,
217-
): TRes;
218-
219194
/**
220195
* Get a summary of the tracked metrics.
221196
*/

packages/sdk/server-ai/src/api/metrics/BedrockTokenUsage.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
export * from './BedrockTokenUsage';
21
export * from './LDFeedbackKind';
32
export * from './LDAIMetrics';
43
export * from './LDTokenUsage';

0 commit comments

Comments
 (0)