@launchdarkly/server-sdk-ai 0.11.4 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +128 -6
  3. package/__tests__/LDAIConfigTrackerImpl.test.ts +155 -0
  4. package/__tests__/TrackedChat.test.ts +231 -0
  5. package/dist/LDAIClientImpl.d.ts +4 -0
  6. package/dist/LDAIClientImpl.d.ts.map +1 -1
  7. package/dist/LDAIClientImpl.js +21 -0
  8. package/dist/LDAIClientImpl.js.map +1 -1
  9. package/dist/LDAIConfigTrackerImpl.d.ts +2 -1
  10. package/dist/LDAIConfigTrackerImpl.d.ts.map +1 -1
  11. package/dist/LDAIConfigTrackerImpl.js +24 -0
  12. package/dist/LDAIConfigTrackerImpl.js.map +1 -1
  13. package/dist/LDClientMin.d.ts +2 -1
  14. package/dist/LDClientMin.d.ts.map +1 -1
  15. package/dist/api/LDAIClient.d.ts +39 -0
  16. package/dist/api/LDAIClient.d.ts.map +1 -1
  17. package/dist/api/chat/TrackedChat.d.ts +54 -0
  18. package/dist/api/chat/TrackedChat.d.ts.map +1 -0
  19. package/dist/api/chat/TrackedChat.js +84 -0
  20. package/dist/api/chat/TrackedChat.js.map +1 -0
  21. package/dist/api/chat/index.d.ts +3 -0
  22. package/dist/api/chat/index.d.ts.map +1 -0
  23. package/dist/api/chat/index.js +19 -0
  24. package/dist/api/chat/index.js.map +1 -0
  25. package/dist/api/chat/types.d.ts +16 -0
  26. package/dist/api/chat/types.d.ts.map +1 -0
  27. package/dist/api/chat/types.js +3 -0
  28. package/dist/api/chat/types.js.map +1 -0
  29. package/dist/api/config/LDAIConfigTracker.d.ts +16 -1
  30. package/dist/api/config/LDAIConfigTracker.d.ts.map +1 -1
  31. package/dist/api/index.d.ts +2 -0
  32. package/dist/api/index.d.ts.map +1 -1
  33. package/dist/api/index.js +2 -0
  34. package/dist/api/index.js.map +1 -1
  35. package/dist/api/metrics/LDAIMetrics.d.ts +17 -0
  36. package/dist/api/metrics/LDAIMetrics.d.ts.map +1 -0
  37. package/dist/api/metrics/LDAIMetrics.js +3 -0
  38. package/dist/api/metrics/LDAIMetrics.js.map +1 -0
  39. package/dist/api/metrics/index.d.ts +1 -0
  40. package/dist/api/metrics/index.d.ts.map +1 -1
  41. package/dist/api/metrics/index.js +1 -0
  42. package/dist/api/metrics/index.js.map +1 -1
  43. package/dist/api/providers/AIProvider.d.ts +35 -0
  44. package/dist/api/providers/AIProvider.d.ts.map +1 -0
  45. package/dist/api/providers/AIProvider.js +31 -0
  46. package/dist/api/providers/AIProvider.js.map +1 -0
  47. package/dist/api/providers/AIProviderFactory.d.ts +39 -0
  48. package/dist/api/providers/AIProviderFactory.d.ts.map +1 -0
  49. package/dist/api/providers/AIProviderFactory.js +102 -0
  50. package/dist/api/providers/AIProviderFactory.js.map +1 -0
  51. package/dist/api/providers/index.d.ts +3 -0
  52. package/dist/api/providers/index.d.ts.map +1 -0
  53. package/dist/api/providers/index.js +19 -0
  54. package/dist/api/providers/index.js.map +1 -0
  55. package/docs/assets/search.js +1 -1
  56. package/docs/classes/AIProvider.html +174 -0
  57. package/docs/classes/AIProviderFactory.html +197 -0
  58. package/docs/classes/TrackedChat.html +253 -0
  59. package/docs/enums/LDFeedbackKind.html +14 -7
  60. package/docs/functions/createBedrockTokenUsage.html +12 -5
  61. package/docs/functions/createOpenAiUsage.html +12 -5
  62. package/docs/functions/createVercelAISDKTokenUsage.html +12 -5
  63. package/docs/functions/initAi.html +12 -5
  64. package/docs/index.html +25 -5
  65. package/docs/interfaces/ChatResponse.html +108 -0
  66. package/docs/interfaces/LDAIAgent.html +17 -10
  67. package/docs/interfaces/LDAIAgentConfig.html +15 -8
  68. package/docs/interfaces/LDAIClient.html +55 -9
  69. package/docs/interfaces/LDAIConfig.html +18 -11
  70. package/docs/interfaces/LDAIConfigTracker.html +76 -17
  71. package/docs/interfaces/LDAIMetrics.html +110 -0
  72. package/docs/interfaces/LDMessage.html +14 -7
  73. package/docs/interfaces/LDModelConfig.html +15 -8
  74. package/docs/interfaces/LDProviderConfig.html +13 -6
  75. package/docs/interfaces/LDTokenUsage.html +15 -8
  76. package/docs/interfaces/VercelAISDKConfig.html +23 -16
  77. package/docs/interfaces/VercelAISDKMapOptions.html +13 -6
  78. package/docs/types/LDAIAgentDefaults.html +12 -5
  79. package/docs/types/LDAIDefaults.html +12 -5
  80. package/docs/types/SupportedAIProvider.html +70 -0
  81. package/docs/types/VercelAISDKProvider.html +12 -5
  82. package/docs/variables/SUPPORTED_AI_PROVIDERS.html +70 -0
  83. package/package.json +1 -1
  84. package/src/LDAIClientImpl.ts +36 -2
  85. package/src/LDAIConfigTrackerImpl.ts +32 -0
  86. package/src/LDClientMin.ts +3 -1
  87. package/src/api/LDAIClient.ts +46 -0
  88. package/src/api/chat/TrackedChat.ts +100 -0
  89. package/src/api/chat/index.ts +2 -0
  90. package/src/api/chat/types.ts +17 -0
  91. package/src/api/config/LDAIConfigTracker.ts +20 -1
  92. package/src/api/index.ts +2 -0
  93. package/src/api/metrics/LDAIMetrics.ts +18 -0
  94. package/src/api/metrics/index.ts +1 -0
  95. package/src/api/providers/AIProvider.ts +43 -0
  96. package/src/api/providers/AIProviderFactory.ts +152 -0
  97. package/src/api/providers/index.ts +2 -0
  98. package/tsconfig.eslint.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.12.1](https://github.com/launchdarkly/js-core/compare/server-sdk-ai-v0.12.0...server-sdk-ai-v0.12.1) (2025-10-14)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * Improve documentation for AI SDK and AIProvider ([#958](https://github.com/launchdarkly/js-core/issues/958)) ([17d595a](https://github.com/launchdarkly/js-core/commit/17d595aff301998030cfb62724b8eb37fea9adbf))
9
+
10
+ ## [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)
11
+
12
+
13
+ ### Features
14
+
15
+ * 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))
16
+ * 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))
17
+ * 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))
18
+ * 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))
19
+
3
20
  ## [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)
4
21
 
5
22
 
package/README.md CHANGED
@@ -27,6 +27,8 @@ This assumes that you have already installed the LaunchDarkly Node.js (server-si
27
27
 
28
28
  ```shell
29
29
  npm install @launchdarkly/server-sdk-ai --save
30
+ # or
31
+ yarn add @launchdarkly/server-sdk-ai
30
32
  ```
31
33
 
32
34
  2. Create an AI SDK instance:
@@ -36,18 +38,138 @@ npm install @launchdarkly/server-sdk-ai --save
36
38
  const aiClient = initAi(ldClient);
37
39
  ```
38
40
 
39
- 3. Evaluate a model configuration:
41
+ ## Setting Default AI Configurations
42
+
43
+ When retrieving AI configurations, you need to provide default values that will be used if the configuration is not available from LaunchDarkly:
44
+
45
+ ### Fully Configured Default
46
+
47
+ ```typescript
48
+ const defaultConfig = {
49
+ enabled: true,
50
+ model: {
51
+ name: 'gpt-4',
52
+ parameters: { temperature: 0.7, maxTokens: 1000 }
53
+ },
54
+ messages: [
55
+ { role: 'system', content: 'You are a helpful assistant.' }
56
+ ]
57
+ };
58
+ ```
59
+
60
+ ### Disabled Default
61
+
62
+ ```typescript
63
+ const defaultConfig = {
64
+ enabled: false
65
+ };
66
+ ```
67
+
68
+ ## Retrieving AI Configurations
69
+
70
+ The `config` method retrieves AI configurations from LaunchDarkly with support for dynamic variables and fallback values:
71
+
72
+ ```typescript
73
+ const aiConfig = await aiClient.config(
74
+ aiConfigKey,
75
+ context,
76
+ defaultConfig,
77
+ { myVariable: 'My User Defined Variable' } // Variables for template interpolation
78
+ );
79
+
80
+ // Ensure configuration is enabled
81
+ if (aiConfig.enabled) {
82
+ const { messages, model, tracker } = aiConfig;
83
+ // Use with your AI provider
84
+ }
85
+ ```
86
+
87
+ ## TrackedChat for Conversational AI
88
+
89
+ `TrackedChat` provides a high-level interface for conversational AI with automatic conversation management and metrics tracking:
90
+
91
+ - Automatically configures models based on AI configuration
92
+ - Maintains conversation history across multiple interactions
93
+ - Automatically tracks token usage, latency, and success rates
94
+ - Works with any supported AI provider (see [AI Providers](https://github.com/launchdarkly/js-core#ai-providers) for available packages)
95
+
96
+ ### Using TrackedChat
40
97
 
41
98
  ```typescript
42
- const config = await aiClient.config(
43
- aiConfigKey!,
99
+ // Use the same defaultConfig from the retrieval section above
100
+ const chat = await aiClient.initChat(
101
+ 'customer-support-chat',
44
102
  context,
45
- { enabled: false },
46
- { myVariable: 'My User Defined Variable' },
103
+ defaultConfig,
104
+ { customerName: 'John' }
47
105
  );
106
+
107
+ if (chat) {
108
+ // Simple conversation flow - metrics are automatically tracked by invoke()
109
+ const response1 = await chat.invoke('I need help with my order');
110
+ console.log(response1.message.content);
111
+
112
+ const response2 = await chat.invoke("What's the status?");
113
+ console.log(response2.message.content);
114
+
115
+ // Access conversation history
116
+ const messages = chat.getMessages();
117
+ console.log(`Conversation has ${messages.length} messages`);
118
+ }
48
119
  ```
49
120
 
50
- For an example of how to use the config please refer to the examples folder.
121
+ ## Advanced Usage with Providers
122
+
123
+ For more control, you can use the configuration directly with AI providers. We recommend using [LaunchDarkly AI Provider packages](https://github.com/launchdarkly/js-core#ai-providers) when available:
124
+
125
+ ### Using AI Provider Packages
126
+
127
+ ```typescript
128
+ import { LangChainProvider } from '@launchdarkly/server-sdk-ai-langchain';
129
+
130
+ const aiConfig = await aiClient.config(aiConfigKey, context, defaultValue);
131
+
132
+ // Create LangChain model from configuration
133
+ const llm = await LangChainProvider.createLangChainModel(aiConfig);
134
+
135
+ // Use with tracking
136
+ const response = await aiConfig.tracker.trackMetricsOf(
137
+ (result) => LangChainProvider.createAIMetrics(result),
138
+ () => llm.invoke(messages)
139
+ );
140
+
141
+ console.log('AI Response:', response.content);
142
+ ```
143
+
144
+ ### Using Custom Providers
145
+
146
+ ```typescript
147
+ import { LDAIMetrics } from '@launchdarkly/server-sdk-ai';
148
+
149
+ const aiConfig = await aiClient.config(aiConfigKey, context, defaultValue);
150
+
151
+ // Define custom metrics mapping for your provider
152
+ const mapCustomProviderMetrics = (response: any): LDAIMetrics => ({
153
+ success: true,
154
+ usage: {
155
+ total: response.usage?.total_tokens || 0,
156
+ input: response.usage?.prompt_tokens || 0,
157
+ output: response.usage?.completion_tokens || 0,
158
+ }
159
+ });
160
+
161
+ // Use with custom provider and tracking
162
+ const result = await aiConfig.tracker.trackMetricsOf(
163
+ mapCustomProviderMetrics,
164
+ () => customProvider.generate({
165
+ messages: aiConfig.messages || [],
166
+ model: aiConfig.model?.name || 'custom-model',
167
+ temperature: aiConfig.model?.parameters?.temperature ?? 0.5,
168
+ })
169
+ );
170
+
171
+ console.log('AI Response:', result.content);
172
+ ```
51
173
 
52
174
  ## Contributing
53
175
 
@@ -898,3 +898,158 @@ it('tracks error', () => {
898
898
  1,
899
899
  );
900
900
  });
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,0 +1,231 @@
1
+ import { TrackedChat } from '../src/api/chat/TrackedChat';
2
+ import { ChatResponse } from '../src/api/chat/types';
3
+ import { LDAIConfig, LDMessage } from '../src/api/config/LDAIConfig';
4
+ import { LDAIConfigTracker } from '../src/api/config/LDAIConfigTracker';
5
+ import { AIProvider } from '../src/api/providers/AIProvider';
6
+
7
+ describe('TrackedChat', () => {
8
+ let mockProvider: jest.Mocked<AIProvider>;
9
+ let mockTracker: jest.Mocked<LDAIConfigTracker>;
10
+ let aiConfig: LDAIConfig;
11
+
12
+ beforeEach(() => {
13
+ // Mock the AIProvider
14
+ mockProvider = {
15
+ invokeModel: jest.fn(),
16
+ } as any;
17
+
18
+ // Mock the LDAIConfigTracker
19
+ mockTracker = {
20
+ trackMetricsOf: jest.fn(),
21
+ trackDuration: jest.fn(),
22
+ trackTokens: jest.fn(),
23
+ trackSuccess: jest.fn(),
24
+ trackError: jest.fn(),
25
+ trackFeedback: jest.fn(),
26
+ trackTimeToFirstToken: jest.fn(),
27
+ trackDurationOf: jest.fn(),
28
+ trackOpenAIMetrics: jest.fn(),
29
+ trackBedrockConverseMetrics: jest.fn(),
30
+ trackVercelAIMetrics: jest.fn(),
31
+ getSummary: jest.fn(),
32
+ } as any;
33
+
34
+ // Create a basic AI config
35
+ aiConfig = {
36
+ enabled: true,
37
+ messages: [{ role: 'system', content: 'You are a helpful assistant.' }],
38
+ model: { name: 'gpt-4' },
39
+ provider: { name: 'openai' },
40
+ tracker: mockTracker,
41
+ toVercelAISDK: jest.fn(),
42
+ };
43
+ });
44
+
45
+ describe('appendMessages', () => {
46
+ it('appends messages to the conversation history', () => {
47
+ const chat = new TrackedChat(aiConfig, mockTracker, mockProvider);
48
+
49
+ const messagesToAppend: LDMessage[] = [
50
+ { role: 'user', content: 'Hello' },
51
+ { role: 'assistant', content: 'Hi there!' },
52
+ ];
53
+
54
+ chat.appendMessages(messagesToAppend);
55
+
56
+ const messages = chat.getMessages(false);
57
+ expect(messages).toHaveLength(2);
58
+ expect(messages[0]).toEqual({ role: 'user', content: 'Hello' });
59
+ expect(messages[1]).toEqual({ role: 'assistant', content: 'Hi there!' });
60
+ });
61
+
62
+ it('appends multiple message batches sequentially', () => {
63
+ const chat = new TrackedChat(aiConfig, mockTracker, mockProvider);
64
+
65
+ chat.appendMessages([{ role: 'user', content: 'First message' }]);
66
+ chat.appendMessages([{ role: 'assistant', content: 'Second message' }]);
67
+ chat.appendMessages([{ role: 'user', content: 'Third message' }]);
68
+
69
+ const messages = chat.getMessages(false);
70
+ expect(messages).toHaveLength(3);
71
+ expect(messages[0].content).toBe('First message');
72
+ expect(messages[1].content).toBe('Second message');
73
+ expect(messages[2].content).toBe('Third message');
74
+ });
75
+
76
+ it('handles empty message array', () => {
77
+ const chat = new TrackedChat(aiConfig, mockTracker, mockProvider);
78
+
79
+ chat.appendMessages([]);
80
+
81
+ const messages = chat.getMessages(false);
82
+ expect(messages).toHaveLength(0);
83
+ });
84
+ });
85
+
86
+ describe('getMessages', () => {
87
+ it('returns only conversation history when includeConfigMessages is false', () => {
88
+ const chat = new TrackedChat(aiConfig, mockTracker, mockProvider);
89
+
90
+ chat.appendMessages([
91
+ { role: 'user', content: 'User message' },
92
+ { role: 'assistant', content: 'Assistant message' },
93
+ ]);
94
+
95
+ const messages = chat.getMessages(false);
96
+
97
+ expect(messages).toHaveLength(2);
98
+ expect(messages[0]).toEqual({ role: 'user', content: 'User message' });
99
+ expect(messages[1]).toEqual({ role: 'assistant', content: 'Assistant message' });
100
+ });
101
+
102
+ it('returns only conversation history when includeConfigMessages is omitted (defaults to false)', () => {
103
+ const chat = new TrackedChat(aiConfig, mockTracker, mockProvider);
104
+
105
+ chat.appendMessages([{ role: 'user', content: 'User message' }]);
106
+
107
+ const messages = chat.getMessages();
108
+
109
+ expect(messages).toHaveLength(1);
110
+ expect(messages[0]).toEqual({ role: 'user', content: 'User message' });
111
+ });
112
+
113
+ it('returns config messages prepended when includeConfigMessages is true', () => {
114
+ const chat = new TrackedChat(aiConfig, mockTracker, mockProvider);
115
+
116
+ chat.appendMessages([
117
+ { role: 'user', content: 'User message' },
118
+ { role: 'assistant', content: 'Assistant message' },
119
+ ]);
120
+
121
+ const messages = chat.getMessages(true);
122
+
123
+ expect(messages).toHaveLength(3);
124
+ expect(messages[0]).toEqual({ role: 'system', content: 'You are a helpful assistant.' });
125
+ expect(messages[1]).toEqual({ role: 'user', content: 'User message' });
126
+ expect(messages[2]).toEqual({ role: 'assistant', content: 'Assistant message' });
127
+ });
128
+
129
+ it('returns only config messages when no conversation history exists and includeConfigMessages is true', () => {
130
+ const chat = new TrackedChat(aiConfig, mockTracker, mockProvider);
131
+
132
+ const messages = chat.getMessages(true);
133
+
134
+ expect(messages).toHaveLength(1);
135
+ expect(messages[0]).toEqual({ role: 'system', content: 'You are a helpful assistant.' });
136
+ });
137
+
138
+ it('returns empty array when no messages exist and includeConfigMessages is false', () => {
139
+ const configWithoutMessages: LDAIConfig = {
140
+ ...aiConfig,
141
+ messages: [],
142
+ };
143
+ const chat = new TrackedChat(configWithoutMessages, mockTracker, mockProvider);
144
+
145
+ const messages = chat.getMessages(false);
146
+
147
+ expect(messages).toHaveLength(0);
148
+ });
149
+
150
+ it('returns a copy of the messages array (not a reference)', () => {
151
+ const chat = new TrackedChat(aiConfig, mockTracker, mockProvider);
152
+
153
+ chat.appendMessages([{ role: 'user', content: 'Original message' }]);
154
+
155
+ const messages1 = chat.getMessages();
156
+ const messages2 = chat.getMessages();
157
+
158
+ expect(messages1).not.toBe(messages2);
159
+ expect(messages1).toEqual(messages2);
160
+
161
+ // Modifying returned array should not affect internal state
162
+ messages1.push({ role: 'assistant', content: 'Modified' });
163
+
164
+ const messages3 = chat.getMessages();
165
+ expect(messages3).toHaveLength(1);
166
+ expect(messages3[0].content).toBe('Original message');
167
+ });
168
+
169
+ it('handles undefined config messages gracefully', () => {
170
+ const configWithoutMessages: LDAIConfig = {
171
+ ...aiConfig,
172
+ messages: undefined,
173
+ };
174
+ const chat = new TrackedChat(configWithoutMessages, mockTracker, mockProvider);
175
+
176
+ chat.appendMessages([{ role: 'user', content: 'User message' }]);
177
+
178
+ const messagesWithConfig = chat.getMessages(true);
179
+ expect(messagesWithConfig).toHaveLength(1);
180
+ expect(messagesWithConfig[0].content).toBe('User message');
181
+
182
+ const messagesWithoutConfig = chat.getMessages(false);
183
+ expect(messagesWithoutConfig).toHaveLength(1);
184
+ expect(messagesWithoutConfig[0].content).toBe('User message');
185
+ });
186
+ });
187
+
188
+ describe('integration with invoke', () => {
189
+ it('adds messages from invoke to history accessible via getMessages', async () => {
190
+ const mockResponse: ChatResponse = {
191
+ message: { role: 'assistant', content: 'Response from model' },
192
+ metrics: { success: true },
193
+ };
194
+
195
+ mockTracker.trackMetricsOf.mockImplementation(async (extractor, func) => func());
196
+
197
+ mockProvider.invokeModel.mockResolvedValue(mockResponse);
198
+
199
+ const chat = new TrackedChat(aiConfig, mockTracker, mockProvider);
200
+
201
+ await chat.invoke('Hello');
202
+
203
+ const messages = chat.getMessages(false);
204
+ expect(messages).toHaveLength(2);
205
+ expect(messages[0]).toEqual({ role: 'user', content: 'Hello' });
206
+ expect(messages[1]).toEqual({ role: 'assistant', content: 'Response from model' });
207
+ });
208
+
209
+ it('preserves appended messages when invoking', async () => {
210
+ const mockResponse: ChatResponse = {
211
+ message: { role: 'assistant', content: 'Response' },
212
+ metrics: { success: true },
213
+ };
214
+
215
+ mockTracker.trackMetricsOf.mockImplementation(async (extractor, func) => func());
216
+
217
+ mockProvider.invokeModel.mockResolvedValue(mockResponse);
218
+
219
+ const chat = new TrackedChat(aiConfig, mockTracker, mockProvider);
220
+
221
+ chat.appendMessages([{ role: 'user', content: 'Pre-appended message' }]);
222
+ await chat.invoke('New user input');
223
+
224
+ const messages = chat.getMessages(false);
225
+ expect(messages).toHaveLength(3);
226
+ expect(messages[0].content).toBe('Pre-appended message');
227
+ expect(messages[1].content).toBe('New user input');
228
+ expect(messages[2].content).toBe('Response');
229
+ });
230
+ });
231
+ });
@@ -1,10 +1,13 @@
1
1
  import { LDContext } from '@launchdarkly/js-server-sdk-common';
2
2
  import { LDAIAgent, LDAIAgentConfig, LDAIAgentDefaults } from './api/agents';
3
+ import { TrackedChat } from './api/chat';
3
4
  import { LDAIConfig, LDAIDefaults } from './api/config';
4
5
  import { LDAIClient } from './api/LDAIClient';
6
+ import { SupportedAIProvider } from './api/providers';
5
7
  import { LDClientMin } from './LDClientMin';
6
8
  export declare class LDAIClientImpl implements LDAIClient {
7
9
  private _ldClient;
10
+ private _logger?;
8
11
  constructor(_ldClient: LDClientMin);
9
12
  private _interpolateTemplate;
10
13
  private _evaluate;
@@ -14,5 +17,6 @@ export declare class LDAIClientImpl implements LDAIClient {
14
17
  agents<const T extends readonly (LDAIAgentConfig & {
15
18
  defaultValue: LDAIAgentDefaults;
16
19
  })[]>(agentConfigs: T, context: LDContext): Promise<Record<T[number]['key'], LDAIAgent>>;
20
+ initChat(key: string, context: LDContext, defaultValue: LDAIDefaults, variables?: Record<string, unknown>, defaultAiProvider?: SupportedAIProvider): Promise<TrackedChat | undefined>;
17
21
  }
18
22
  //# sourceMappingURL=LDAIClientImpl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LDAIClientImpl.d.ts","sourceRoot":"","sources":["../src/LDAIClientImpl.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAE/D,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EACL,UAAU,EAEV,YAAY,EAOb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAuC5C,qBAAa,cAAe,YAAW,UAAU;IACnC,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,WAAW;IAE1C,OAAO,CAAC,oBAAoB;YAId,SAAS;YAkCT,cAAc;IAoCtB,MAAM,CACV,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,SAAS,EAClB,YAAY,EAAE,YAAY,EAC1B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,UAAU,CAAC;IA4ChB,KAAK,CACT,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,SAAS,EAClB,YAAY,EAAE,iBAAiB,EAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,SAAS,CAAC;IAOf,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,CAAC,eAAe,GAAG;QAAE,YAAY,EAAE,iBAAiB,CAAA;KAAE,CAAC,EAAE,EAC7F,YAAY,EAAE,CAAC,EACf,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;CAyBhD"}
1
+ {"version":3,"file":"LDAIClientImpl.d.ts","sourceRoot":"","sources":["../src/LDAIClientImpl.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAY,MAAM,oCAAoC,CAAC;AAEzE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EACL,UAAU,EAEV,YAAY,EAOb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAqB,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGzE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAuC5C,qBAAa,cAAe,YAAW,UAAU;IAGnC,OAAO,CAAC,SAAS;IAF7B,OAAO,CAAC,OAAO,CAAC,CAAW;gBAEP,SAAS,EAAE,WAAW;IAI1C,OAAO,CAAC,oBAAoB;YAId,SAAS;YAkCT,cAAc;IAoCtB,MAAM,CACV,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,SAAS,EAClB,YAAY,EAAE,YAAY,EAC1B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,UAAU,CAAC;IA4ChB,KAAK,CACT,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,SAAS,EAClB,YAAY,EAAE,iBAAiB,EAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,SAAS,CAAC;IAOf,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,CAAC,eAAe,GAAG;QAAE,YAAY,EAAE,iBAAiB,CAAA;KAAE,CAAC,EAAE,EAC7F,YAAY,EAAE,CAAC,EACf,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IA0BzC,QAAQ,CACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,SAAS,EAClB,YAAY,EAAE,YAAY,EAC1B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,iBAAiB,CAAC,EAAE,mBAAmB,GACtC,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;CAqBpC"}
@@ -2,11 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LDAIClientImpl = void 0;
4
4
  const Mustache = require("mustache");
5
+ const chat_1 = require("./api/chat");
6
+ const providers_1 = require("./api/providers");
5
7
  const LDAIConfigMapper_1 = require("./LDAIConfigMapper");
6
8
  const LDAIConfigTrackerImpl_1 = require("./LDAIConfigTrackerImpl");
7
9
  class LDAIClientImpl {
8
10
  constructor(_ldClient) {
9
11
  this._ldClient = _ldClient;
12
+ this._logger = _ldClient.logger;
10
13
  }
11
14
  _interpolateTemplate(template, variables) {
12
15
  return Mustache.render(template, variables, undefined, { escape: (item) => item });
@@ -89,6 +92,24 @@ class LDAIClientImpl {
89
92
  }));
90
93
  return agents;
91
94
  }
95
+ async initChat(key, context, defaultValue, variables, defaultAiProvider) {
96
+ var _a;
97
+ // Track chat initialization
98
+ this._ldClient.track('$ld:ai:config:function:initChat', context, key, 1);
99
+ const aiConfig = await this.config(key, context, defaultValue, variables);
100
+ // Return undefined if the configuration is disabled
101
+ if (!aiConfig.enabled) {
102
+ (_a = this._logger) === null || _a === void 0 ? void 0 : _a.info(`Chat configuration is disabled: ${key}`);
103
+ return undefined;
104
+ }
105
+ // Create the AIProvider instance
106
+ const provider = await providers_1.AIProviderFactory.create(aiConfig, this._logger, defaultAiProvider);
107
+ if (!provider) {
108
+ return undefined;
109
+ }
110
+ // Create the TrackedChat instance with the provider
111
+ return new chat_1.TrackedChat(aiConfig, aiConfig.tracker, provider);
112
+ }
92
113
  }
93
114
  exports.LDAIClientImpl = LDAIClientImpl;
94
115
  //# sourceMappingURL=LDAIClientImpl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LDAIClientImpl.js","sourceRoot":"","sources":["../src/LDAIClientImpl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LDAIClientImpl.js","sourceRoot":"","sources":["../src/LDAIClientImpl.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { LDContext } from '@launchdarkly/js-server-sdk-common';
2
2
  import { LDAIConfigTracker } from './api/config';
3
3
  import { LDAIMetricSummary } from './api/config/LDAIConfigTracker';
4
- import { LDFeedbackKind, LDTokenUsage } from './api/metrics';
4
+ import { LDAIMetrics, LDFeedbackKind, LDTokenUsage } from './api/metrics';
5
5
  import { LDClientMin } from './LDClientMin';
6
6
  export declare class LDAIConfigTrackerImpl implements LDAIConfigTracker {
7
7
  private _ldClient;
@@ -22,6 +22,7 @@ export declare class LDAIConfigTrackerImpl implements LDAIConfigTracker {
22
22
  }): void;
23
23
  trackSuccess(): void;
24
24
  trackError(): void;
25
+ trackMetricsOf<TRes>(metricsExtractor: (result: TRes) => LDAIMetrics, func: () => Promise<TRes>): Promise<TRes>;
25
26
  trackOpenAIMetrics<TRes extends {
26
27
  usage?: {
27
28
  total_tokens?: number;