Skip to content

Commit 817159e

Browse files
authored
Merge branch 'main' into jb/sdk-1454/ai-provider-langchain
2 parents 2334e66 + ea50d19 commit 817159e

23 files changed

+878
-14
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"packages/sdk/fastly": "0.2.1",
99
"packages/sdk/react-native": "10.11.0",
1010
"packages/sdk/react-universal": "0.0.1",
11-
"packages/sdk/server-ai": "0.11.4",
11+
"packages/sdk/server-ai": "0.12.0",
1212
"packages/sdk/server-node": "9.10.2",
1313
"packages/sdk/svelte": "0.1.0",
1414
"packages/sdk/vercel": "1.3.34",

packages/sdk/server-ai/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## [0.12.0](https://github.com/launchdarkly/js-core/compare/server-sdk-ai-v0.11.4...server-sdk-ai-v0.12.0) (2025-10-13)
4+
5+
6+
### Features
7+
8+
* Add support for TrackedChats in the AI SDK ([#939](https://github.com/launchdarkly/js-core/issues/939)) ([a7ad0ea](https://github.com/launchdarkly/js-core/commit/a7ad0ead1408fdd80b333baa085c462f47ea5ac1))
9+
* Add support for OpenAI AIProvider to the AI SDK ([#939](https://github.com/launchdarkly/js-core/issues/939)) ([a7ad0ea](https://github.com/launchdarkly/js-core/commit/a7ad0ead1408fdd80b333baa085c462f47ea5ac1))
10+
* Add support for LangChain AIProvider to the AI SDK ([#939](https://github.com/launchdarkly/js-core/issues/939)) ([a7ad0ea](https://github.com/launchdarkly/js-core/commit/a7ad0ead1408fdd80b333baa085c462f47ea5ac1))
11+
* Add support for Vercel AIProvider to the AI SDK ([#946](https://github.com/launchdarkly/js-core/issues/946)) ([8553f24](https://github.com/launchdarkly/js-core/commit/8553f2482a3437975b63992f622b4396cc4ac7e7))
12+
313
## [0.11.4](https://github.com/launchdarkly/js-core/compare/server-sdk-ai-v0.11.3...server-sdk-ai-v0.11.4) (2025-09-15)
414

515

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

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,3 +898,158 @@ it('tracks error', () => {
898898
1,
899899
);
900900
});
901+
902+
describe('trackMetricsOf', () => {
903+
it('tracks success and token usage from metrics', async () => {
904+
const tracker = new LDAIConfigTrackerImpl(
905+
mockLdClient,
906+
configKey,
907+
variationKey,
908+
version,
909+
modelName,
910+
providerName,
911+
testContext,
912+
);
913+
914+
const mockResult = { response: 'test' };
915+
const mockMetrics = {
916+
success: true,
917+
usage: { total: 100, input: 50, output: 50 },
918+
};
919+
920+
const metricsExtractor = jest.fn().mockReturnValue(mockMetrics);
921+
const operation = jest.fn().mockResolvedValue(mockResult);
922+
923+
const result = await tracker.trackMetricsOf(metricsExtractor, operation);
924+
925+
expect(result).toBe(mockResult);
926+
expect(metricsExtractor).toHaveBeenCalledWith(mockResult);
927+
expect(operation).toHaveBeenCalled();
928+
929+
// Should track success
930+
expect(mockTrack).toHaveBeenCalledWith(
931+
'$ld:ai:generation:success',
932+
testContext,
933+
{ configKey, variationKey, version, modelName, providerName },
934+
1,
935+
);
936+
937+
// Should track token usage
938+
expect(mockTrack).toHaveBeenCalledWith(
939+
'$ld:ai:tokens:total',
940+
testContext,
941+
{ configKey, variationKey, version, modelName, providerName },
942+
100,
943+
);
944+
expect(mockTrack).toHaveBeenCalledWith(
945+
'$ld:ai:tokens:input',
946+
testContext,
947+
{ configKey, variationKey, version, modelName, providerName },
948+
50,
949+
);
950+
expect(mockTrack).toHaveBeenCalledWith(
951+
'$ld:ai:tokens:output',
952+
testContext,
953+
{ configKey, variationKey, version, modelName, providerName },
954+
50,
955+
);
956+
});
957+
958+
it('tracks failure when metrics indicate failure', async () => {
959+
const tracker = new LDAIConfigTrackerImpl(
960+
mockLdClient,
961+
configKey,
962+
variationKey,
963+
version,
964+
modelName,
965+
providerName,
966+
testContext,
967+
);
968+
969+
const mockResult = { response: 'test' };
970+
const mockMetrics = {
971+
success: false,
972+
};
973+
974+
const metricsExtractor = jest.fn().mockReturnValue(mockMetrics);
975+
const operation = jest.fn().mockResolvedValue(mockResult);
976+
977+
await tracker.trackMetricsOf(metricsExtractor, operation);
978+
979+
// Should track error
980+
expect(mockTrack).toHaveBeenCalledWith(
981+
'$ld:ai:generation:error',
982+
testContext,
983+
{ configKey, variationKey, version, modelName, providerName },
984+
1,
985+
);
986+
});
987+
988+
it('tracks failure when operation throws', async () => {
989+
const tracker = new LDAIConfigTrackerImpl(
990+
mockLdClient,
991+
configKey,
992+
variationKey,
993+
version,
994+
modelName,
995+
providerName,
996+
testContext,
997+
);
998+
999+
const error = new Error('Operation failed');
1000+
const metricsExtractor = jest.fn();
1001+
const operation = jest.fn().mockRejectedValue(error);
1002+
1003+
await expect(tracker.trackMetricsOf(metricsExtractor, operation)).rejects.toThrow(error);
1004+
1005+
// Should track error
1006+
expect(mockTrack).toHaveBeenCalledWith(
1007+
'$ld:ai:generation:error',
1008+
testContext,
1009+
{ configKey, variationKey, version, modelName, providerName },
1010+
1,
1011+
);
1012+
1013+
// Should not call metrics extractor when operation fails
1014+
expect(metricsExtractor).not.toHaveBeenCalled();
1015+
});
1016+
1017+
it('tracks metrics without token usage', async () => {
1018+
const tracker = new LDAIConfigTrackerImpl(
1019+
mockLdClient,
1020+
configKey,
1021+
variationKey,
1022+
version,
1023+
modelName,
1024+
providerName,
1025+
testContext,
1026+
);
1027+
1028+
const mockResult = { response: 'test' };
1029+
const mockMetrics = {
1030+
success: true,
1031+
// No usage provided
1032+
};
1033+
1034+
const metricsExtractor = jest.fn().mockReturnValue(mockMetrics);
1035+
const operation = jest.fn().mockResolvedValue(mockResult);
1036+
1037+
await tracker.trackMetricsOf(metricsExtractor, operation);
1038+
1039+
// Should track success but not token usage
1040+
expect(mockTrack).toHaveBeenCalledWith(
1041+
'$ld:ai:generation:success',
1042+
testContext,
1043+
{ configKey, variationKey, version, modelName, providerName },
1044+
1,
1045+
);
1046+
1047+
// Should not track token usage
1048+
expect(mockTrack).not.toHaveBeenCalledWith(
1049+
'$ld:ai:tokens:total',
1050+
expect.any(Object),
1051+
expect.any(Object),
1052+
expect.any(Number),
1053+
);
1054+
});
1055+
});

0 commit comments

Comments
 (0)