Skip to content

Commit ac7fd06

Browse files
authored
feat!: Nest AI config payload types under LdAiConfigTypes (#284)
1 parent 7e436fb commit ac7fd06

18 files changed

Lines changed: 204 additions & 198 deletions

pkgs/sdk/server-ai/docs-src/namespaces/LaunchDarkly.Sdk.Server.Ai.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ To get started, follow this pattern:
88
```csharp
99
using LaunchDarkly.Sdk.Server.Ai;
1010
using LaunchDarkly.Sdk.Server.Ai.Adapters;
11+
using LaunchDarkly.Sdk.Server.Ai.Config;
1112

1213
// This is a standard LaunchDarkly server-side .NET client instance.
1314
var baseClient = new LdClient(Configuration.Builder("sdk-key").Build());
@@ -17,5 +18,5 @@ var aiClient = new LdAiClient(new LdClientAdapter(baseClient));
1718

1819
// Pass in the key of the AI Config, a context, and a default value in case the config can't be
1920
// retrieved from LaunchDarkly.
20-
var myModelConfig = aiClient.Config("my-model-config", Context.New("user-key"), LdAiConfig.Disabled);
21+
var myModelConfig = aiClient.CompletionConfig("my-model-config", Context.New("user-key"), LdAiCompletionConfigDefault.Disabled);
2122
```

pkgs/sdk/server-ai/src/Config/ConfigFactory.cs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ private LdAiCompletionConfig BuildCompletionFromDefault(
7777
string key,
7878
LdAiCompletionConfigDefault defaultValue,
7979
IReadOnlyDictionary<string, object> mergedVars,
80-
Func<LdAiConfigBase, ILdAiConfigTracker> trackerFactory)
80+
Func<LdAiConfig, ILdAiConfigTracker> trackerFactory)
8181
{
8282
// Caller-supplied default messages can contain Mustache templates too; interpolate
8383
// with the same per-message fallback as server-returned configs.
@@ -93,16 +93,16 @@ private LdAiCompletionConfig BuildCompletionFromDefault(
9393
trackerFactory);
9494
}
9595

96-
private IReadOnlyList<Message> InterpolateMessages(
97-
IReadOnlyList<Message> messages,
96+
private IReadOnlyList<LdAiConfigTypes.Message> InterpolateMessages(
97+
IReadOnlyList<LdAiConfigTypes.Message> messages,
9898
IReadOnlyDictionary<string, object> mergedVars,
9999
string key)
100100
{
101101
if (messages == null)
102102
{
103-
return new List<Message>();
103+
return new List<LdAiConfigTypes.Message>();
104104
}
105-
var result = new List<Message>(messages.Count);
105+
var result = new List<LdAiConfigTypes.Message>(messages.Count);
106106
for (var i = 0; i < messages.Count; i++)
107107
{
108108
var msg = messages[i];
@@ -117,12 +117,12 @@ private IReadOnlyList<Message> InterpolateMessages(
117117
$"AI Config '{key}': skipping interpolation of malformed template in message {i}: {ex.Message}");
118118
interpolated = msg.Content;
119119
}
120-
result.Add(new Message(interpolated, msg.Role));
120+
result.Add(new LdAiConfigTypes.Message(interpolated, msg.Role));
121121
}
122122
return result;
123123
}
124124

125-
private Func<LdAiConfigBase, ILdAiConfigTracker> TrackerFactoryFor(Context context)
125+
private Func<LdAiConfig, ILdAiConfigTracker> TrackerFactoryFor(Context context)
126126
{
127127
return cfg => new LdAiConfigTracker(
128128
_client,
@@ -148,18 +148,18 @@ private static (bool Enabled, string VariationKey, int Version, string Mode) Par
148148
return (enabled, variationKey, version, mode);
149149
}
150150

151-
private static ModelConfig ParseModel(LdValue modelValue)
151+
private static LdAiConfigTypes.ModelConfig ParseModel(LdValue modelValue)
152152
{
153153
var name = modelValue.Get("name").AsString ?? "";
154154
var parameters = LdValueObjectToDictionary(modelValue.Get("parameters"));
155155
var custom = LdValueObjectToDictionary(modelValue.Get("custom"));
156-
return new ModelConfig(name, parameters, custom);
156+
return new LdAiConfigTypes.ModelConfig(name, parameters, custom);
157157
}
158158

159-
private static ProviderConfig ParseProvider(LdValue providerValue)
159+
private static LdAiConfigTypes.ProviderConfig ParseProvider(LdValue providerValue)
160160
{
161161
var name = providerValue.Get("name").AsString ?? "";
162-
return new ProviderConfig(name);
162+
return new LdAiConfigTypes.ProviderConfig(name);
163163
}
164164

165165
private static IReadOnlyDictionary<string, LdValue> LdValueObjectToDictionary(LdValue value)
@@ -173,14 +173,14 @@ private static IReadOnlyDictionary<string, LdValue> LdValueObjectToDictionary(Ld
173173
return value.Dictionary.ToDictionary(kv => kv.Key, kv => kv.Value);
174174
}
175175

176-
private static IReadOnlyList<Message> ParseMessages(LdValue messagesValue)
176+
private static IReadOnlyList<LdAiConfigTypes.Message> ParseMessages(LdValue messagesValue)
177177
{
178178
if (messagesValue.Type != LdValueType.Array)
179179
{
180-
return new List<Message>();
180+
return new List<LdAiConfigTypes.Message>();
181181
}
182182

183-
var result = new List<Message>(messagesValue.Count);
183+
var result = new List<LdAiConfigTypes.Message>(messagesValue.Count);
184184
for (var i = 0; i < messagesValue.Count; i++)
185185
{
186186
var msg = messagesValue.Get(i);
@@ -190,20 +190,20 @@ private static IReadOnlyList<Message> ParseMessages(LdValue messagesValue)
190190
}
191191
var content = msg.Get("content").AsString ?? "";
192192
var role = ParseRole(msg.Get("role").AsString);
193-
result.Add(new Message(content, role));
193+
result.Add(new LdAiConfigTypes.Message(content, role));
194194
}
195195
return result;
196196
}
197197

198-
private static Role ParseRole(string roleString)
198+
private static LdAiConfigTypes.Role ParseRole(string roleString)
199199
{
200200
// The wire format uses capitalized "User" / "System" / "Assistant"; Enum.TryParse with
201201
// ignoreCase = true is tolerant of casing variants. Unknown / null roles fall back to User.
202-
if (!string.IsNullOrEmpty(roleString) && Enum.TryParse<Role>(roleString, ignoreCase: true, out var parsed))
202+
if (!string.IsNullOrEmpty(roleString) && Enum.TryParse<LdAiConfigTypes.Role>(roleString, ignoreCase: true, out var parsed))
203203
{
204204
return parsed;
205205
}
206-
return Role.User;
206+
return LdAiConfigTypes.Role.User;
207207
}
208208

209209
private IReadOnlyDictionary<string, object> MergeVariables(

pkgs/sdk/server-ai/src/Config/LdAiCompletionConfig.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace LaunchDarkly.Sdk.Server.Ai.Config;
1414
/// they are not constructed directly by users. To supply a fallback default to the
1515
/// client, use <see cref="LdAiCompletionConfigDefault"/>.
1616
/// </summary>
17-
public sealed class LdAiCompletionConfig : LdAiConfigBase
17+
public sealed class LdAiCompletionConfig : LdAiConfig
1818
{
1919
/// <summary>
2020
/// The mode tag emitted in <c>_ldMeta.mode</c> for this config type. Future agent and
@@ -25,13 +25,13 @@ public sealed class LdAiCompletionConfig : LdAiConfigBase
2525
/// <summary>
2626
/// The prompts associated with the config.
2727
/// </summary>
28-
public IReadOnlyList<Message> Messages { get; }
28+
public IReadOnlyList<LdAiConfigTypes.Message> Messages { get; }
2929

3030
internal LdAiCompletionConfig(string key, bool enabled, string variationKey, int version,
31-
IEnumerable<Message> messages, ModelConfig model, ProviderConfig provider,
32-
Func<LdAiConfigBase, ILdAiConfigTracker> trackerFactory)
31+
IEnumerable<LdAiConfigTypes.Message> messages, LdAiConfigTypes.ModelConfig model, LdAiConfigTypes.ProviderConfig provider,
32+
Func<LdAiConfig, ILdAiConfigTracker> trackerFactory)
3333
: base(key, enabled, variationKey, version, model, provider, trackerFactory)
3434
{
35-
Messages = messages?.ToList() ?? new List<Message>();
35+
Messages = messages?.ToList() ?? new List<LdAiConfigTypes.Message>();
3636
}
3737
}

pkgs/sdk/server-ai/src/Config/LdAiCompletionConfigDefault.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace LaunchDarkly.Sdk.Server.Ai.Config;
1212
/// Construct an instance via <see cref="New"/> and the nested <see cref="Builder"/>,
1313
/// or use <see cref="Disabled"/> for a disabled default.
1414
/// </summary>
15-
public sealed class LdAiCompletionConfigDefault : LdAiConfigDefaultBase
15+
public sealed class LdAiCompletionConfigDefault : LdAiConfigDefault
1616
{
1717
/// <summary>
1818
/// Builder for constructing an LdAiCompletionConfigDefault instance, which can be passed
@@ -21,7 +21,7 @@ public sealed class LdAiCompletionConfigDefault : LdAiConfigDefaultBase
2121
public class Builder
2222
{
2323
private bool _enabled;
24-
private readonly List<Message> _messages;
24+
private readonly List<LdAiConfigTypes.Message> _messages;
2525
private readonly Dictionary<string, LdValue> _modelParams;
2626
private readonly Dictionary<string, LdValue> _customModelParams;
2727
private string _providerName;
@@ -30,22 +30,22 @@ public class Builder
3030
internal Builder()
3131
{
3232
_enabled = true;
33-
_messages = new List<Message>();
33+
_messages = new List<LdAiConfigTypes.Message>();
3434
_modelParams = new Dictionary<string, LdValue>();
3535
_customModelParams = new Dictionary<string, LdValue>();
3636
_providerName = "";
3737
_modelName = "";
3838
}
3939

4040
/// <summary>
41-
/// Adds a message with the given content and role. The default role is <see cref="Role.User"/>.
41+
/// Adds a message with the given content and role. The default role is <see cref="LdAiConfigTypes.Role.User"/>.
4242
/// </summary>
4343
/// <param name="content">the content, which may contain Mustache templates</param>
4444
/// <param name="role">the role</param>
4545
/// <returns>a new builder</returns>
46-
public Builder AddMessage(string content, Role role = Role.User)
46+
public Builder AddMessage(string content, LdAiConfigTypes.Role role = LdAiConfigTypes.Role.User)
4747
{
48-
_messages.Add(new Message(content, role));
48+
_messages.Add(new LdAiConfigTypes.Message(content, role));
4949
return this;
5050
}
5151

@@ -124,25 +124,25 @@ public Builder SetModelProviderName(string name)
124124
/// <returns>a new LdAiCompletionConfigDefault</returns>
125125
public LdAiCompletionConfigDefault Build()
126126
{
127-
var model = new ModelConfig(
127+
var model = new LdAiConfigTypes.ModelConfig(
128128
_modelName,
129129
new Dictionary<string, LdValue>(_modelParams),
130130
new Dictionary<string, LdValue>(_customModelParams));
131-
var provider = new ProviderConfig(_providerName);
131+
var provider = new LdAiConfigTypes.ProviderConfig(_providerName);
132132
return new LdAiCompletionConfigDefault(_enabled, _messages, model, provider);
133133
}
134134
}
135135

136136
/// <summary>
137137
/// The prompts associated with the config.
138138
/// </summary>
139-
public IReadOnlyList<Message> Messages { get; }
139+
public IReadOnlyList<LdAiConfigTypes.Message> Messages { get; }
140140

141-
internal LdAiCompletionConfigDefault(bool? enabled, IEnumerable<Message> messages,
142-
ModelConfig model, ProviderConfig provider)
141+
internal LdAiCompletionConfigDefault(bool? enabled, IEnumerable<LdAiConfigTypes.Message> messages,
142+
LdAiConfigTypes.ModelConfig model, LdAiConfigTypes.ProviderConfig provider)
143143
: base(enabled, model, provider)
144144
{
145-
Messages = messages?.ToList() ?? new List<Message>();
145+
Messages = messages?.ToList() ?? new List<LdAiConfigTypes.Message>();
146146
}
147147

148148
internal LdValue ToLdValue()

pkgs/sdk/server-ai/src/Config/LdAiConfigBase.cs renamed to pkgs/sdk/server-ai/src/Config/LdAiConfig.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
namespace LaunchDarkly.Sdk.Server.Ai.Config;
66

77
/// <summary>
8-
/// Base type for AI Configs returned by the SDK. Carries common fields and the
8+
/// Shared type for AI Configs returned by the SDK. Carries common fields and the
99
/// <see cref="CreateTracker"/> factory. Cannot be constructed or subclassed outside the SDK.
1010
/// </summary>
11-
public abstract class LdAiConfigBase
11+
public abstract class LdAiConfig
1212
{
1313
/// <summary>
1414
/// The key of the AI Config that was evaluated.
@@ -18,12 +18,12 @@ public abstract class LdAiConfigBase
1818
/// <summary>
1919
/// Information about the model.
2020
/// </summary>
21-
public ModelConfig Model { get; }
21+
public LdAiConfigTypes.ModelConfig Model { get; }
2222

2323
/// <summary>
2424
/// Information about the model provider.
2525
/// </summary>
26-
public ProviderConfig Provider { get; }
26+
public LdAiConfigTypes.ProviderConfig Provider { get; }
2727

2828
/// <summary>
2929
/// Whether the config is enabled.
@@ -42,11 +42,11 @@ public abstract class LdAiConfigBase
4242

4343
/// <summary>
4444
/// Factory that produces a tracker for the config. The factory is mode-agnostic — it
45-
/// operates only on the shared base fields (<see cref="Key"/>, <see cref="Model"/>,
45+
/// operates only on the shared fields (<see cref="Key"/>, <see cref="Model"/>,
4646
/// <see cref="Provider"/>, <see cref="VariationKey"/>, <see cref="Version"/>), so the
4747
/// same tracker class serves all config modes.
4848
/// </summary>
49-
private readonly Func<LdAiConfigBase, ILdAiConfigTracker> _trackerFactory;
49+
private readonly Func<LdAiConfig, ILdAiConfigTracker> _trackerFactory;
5050

5151
/// <summary>
5252
/// Creates a tracker that emits events related to this config. The returned tracker
@@ -56,24 +56,24 @@ public abstract class LdAiConfigBase
5656
public ILdAiConfigTracker CreateTracker() => _trackerFactory(this);
5757

5858
/// <summary>
59-
/// Constructs the base. Only public derived types in this assembly are intended
59+
/// Constructs the config. Only public derived types in this assembly are intended
6060
/// to extend this class.
6161
/// </summary>
62-
private protected LdAiConfigBase(
62+
private protected LdAiConfig(
6363
string key,
6464
bool enabled,
6565
string variationKey,
6666
int version,
67-
ModelConfig model,
68-
ProviderConfig provider,
69-
Func<LdAiConfigBase, ILdAiConfigTracker> trackerFactory)
67+
LdAiConfigTypes.ModelConfig model,
68+
LdAiConfigTypes.ProviderConfig provider,
69+
Func<LdAiConfig, ILdAiConfigTracker> trackerFactory)
7070
{
7171
Key = key;
7272
Enabled = enabled;
7373
VariationKey = variationKey ?? "";
7474
Version = version;
75-
Model = model ?? new ModelConfig("", new Dictionary<string, LdValue>(), new Dictionary<string, LdValue>());
76-
Provider = provider ?? new ProviderConfig("");
75+
Model = model ?? new LdAiConfigTypes.ModelConfig("", new Dictionary<string, LdValue>(), new Dictionary<string, LdValue>());
76+
Provider = provider ?? new LdAiConfigTypes.ProviderConfig("");
7777
_trackerFactory = trackerFactory ?? throw new ArgumentNullException(nameof(trackerFactory));
7878
}
7979
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Collections.Generic;
2+
3+
namespace LaunchDarkly.Sdk.Server.Ai.Config;
4+
5+
/// <summary>
6+
/// Shared type for user-supplied default AI Configs. Carries the data fields common to
7+
/// the mode-specific default config types. Cannot be constructed or subclassed outside the SDK.
8+
/// </summary>
9+
public abstract class LdAiConfigDefault
10+
{
11+
/// <summary>
12+
/// Information about the model.
13+
/// </summary>
14+
public LdAiConfigTypes.ModelConfig Model { get; }
15+
16+
/// <summary>
17+
/// Information about the model provider.
18+
/// </summary>
19+
public LdAiConfigTypes.ProviderConfig Provider { get; }
20+
21+
/// <summary>
22+
/// Whether the config is enabled. Null indicates the user did not specify a value.
23+
/// </summary>
24+
public bool? Enabled { get; }
25+
26+
/// <summary>
27+
/// Constructs the default config. Only public derived types in this assembly are intended
28+
/// to extend this class.
29+
/// </summary>
30+
private protected LdAiConfigDefault(bool? enabled, LdAiConfigTypes.ModelConfig model, LdAiConfigTypes.ProviderConfig provider)
31+
{
32+
Enabled = enabled;
33+
Model = model ?? new LdAiConfigTypes.ModelConfig("", new Dictionary<string, LdValue>(), new Dictionary<string, LdValue>());
34+
Provider = provider ?? new LdAiConfigTypes.ProviderConfig("");
35+
}
36+
}

pkgs/sdk/server-ai/src/Config/LdAiConfigDefaultBase.cs

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

0 commit comments

Comments
 (0)