Skip to content

Commit 89ce6db

Browse files
authored
fix: Do not include _ldMeta in returned config. (#668)
The primary purpose of this was to add unit tests, but it ended up with a bug fix, so that is the PR title.
1 parent 796b8a3 commit 89ce6db

File tree

6 files changed

+496
-2
lines changed

6 files changed

+496
-2
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { LDContext } from '@launchdarkly/js-server-sdk-common';
2+
3+
import { LDGenerationConfig } from '../src/api/config';
4+
import { LDAIClientImpl } from '../src/LDAIClientImpl';
5+
import { LDClientMin } from '../src/LDClientMin';
6+
7+
const mockLdClient: jest.Mocked<LDClientMin> = {
8+
variation: jest.fn(),
9+
track: jest.fn(),
10+
};
11+
12+
const testContext: LDContext = { kind: 'user', key: 'test-user' };
13+
14+
it('interpolates template variables', () => {
15+
const client = new LDAIClientImpl(mockLdClient);
16+
const template = 'Hello {{name}}, your score is {{score}}';
17+
const variables = { name: 'John', score: 42 };
18+
19+
const result = client.interpolateTemplate(template, variables);
20+
expect(result).toBe('Hello John, your score is 42');
21+
});
22+
23+
it('handles empty variables in template interpolation', () => {
24+
const client = new LDAIClientImpl(mockLdClient);
25+
const template = 'Hello {{name}}';
26+
const variables = {};
27+
28+
const result = client.interpolateTemplate(template, variables);
29+
expect(result).toBe('Hello ');
30+
});
31+
32+
it('returns model config with interpolated prompts', async () => {
33+
const client = new LDAIClientImpl(mockLdClient);
34+
const key = 'test-flag';
35+
const defaultValue: LDGenerationConfig = {
36+
model: { modelId: 'test', name: 'test-model' },
37+
prompt: [],
38+
};
39+
40+
const mockVariation = {
41+
model: { modelId: 'example-provider', name: 'imagination' },
42+
prompt: [
43+
{ role: 'system', content: 'Hello {{name}}' },
44+
{ role: 'user', content: 'Score: {{score}}' },
45+
],
46+
_ldMeta: {
47+
versionKey: 'v1',
48+
enabled: true,
49+
},
50+
};
51+
52+
mockLdClient.variation.mockResolvedValue(mockVariation);
53+
54+
const variables = { name: 'John', score: 42 };
55+
const result = await client.modelConfig(key, testContext, defaultValue, variables);
56+
57+
expect(result).toEqual({
58+
config: {
59+
model: { modelId: 'example-provider', name: 'imagination' },
60+
prompt: [
61+
{ role: 'system', content: 'Hello John' },
62+
{ role: 'user', content: 'Score: 42' },
63+
],
64+
},
65+
tracker: expect.any(Object),
66+
enabled: true,
67+
});
68+
});
69+
70+
it('includes context in variables for prompt interpolation', async () => {
71+
const client = new LDAIClientImpl(mockLdClient);
72+
const key = 'test-flag';
73+
const defaultValue: LDGenerationConfig = {
74+
model: { modelId: 'test', name: 'test-model' },
75+
prompt: [],
76+
};
77+
78+
const mockVariation = {
79+
prompt: [{ role: 'system', content: 'User key: {{ldctx.key}}' }],
80+
_ldMeta: { versionKey: 'v1', enabled: true },
81+
};
82+
83+
mockLdClient.variation.mockResolvedValue(mockVariation);
84+
85+
const result = await client.modelConfig(key, testContext, defaultValue);
86+
87+
expect(result.config.prompt?.[0].content).toBe('User key: test-user');
88+
});
89+
90+
it('handles missing metadata in variation', async () => {
91+
const client = new LDAIClientImpl(mockLdClient);
92+
const key = 'test-flag';
93+
const defaultValue: LDGenerationConfig = {
94+
model: { modelId: 'test', name: 'test-model' },
95+
prompt: [],
96+
};
97+
98+
const mockVariation = {
99+
model: { modelId: 'example-provider', name: 'imagination' },
100+
prompt: [{ role: 'system', content: 'Hello' }],
101+
};
102+
103+
mockLdClient.variation.mockResolvedValue(mockVariation);
104+
105+
const result = await client.modelConfig(key, testContext, defaultValue);
106+
107+
expect(result).toEqual({
108+
config: {
109+
model: { modelId: 'example-provider', name: 'imagination' },
110+
prompt: [{ role: 'system', content: 'Hello' }],
111+
},
112+
tracker: expect.any(Object),
113+
enabled: false,
114+
});
115+
});
116+
117+
it('passes the default value to the underlying client', async () => {
118+
const client = new LDAIClientImpl(mockLdClient);
119+
const key = 'non-existent-flag';
120+
const defaultValue: LDGenerationConfig = {
121+
model: { modelId: 'default-model', name: 'default' },
122+
prompt: [{ role: 'system', content: 'Default prompt' }],
123+
};
124+
125+
mockLdClient.variation.mockResolvedValue(defaultValue);
126+
127+
const result = await client.modelConfig(key, testContext, defaultValue);
128+
129+
expect(result).toEqual({
130+
config: defaultValue,
131+
tracker: expect.any(Object),
132+
enabled: false,
133+
});
134+
135+
expect(mockLdClient.variation).toHaveBeenCalledWith(key, testContext, defaultValue);
136+
});

0 commit comments

Comments
 (0)