-
Notifications
You must be signed in to change notification settings - Fork 9
feat!: Add per-execution runId, at-most-once tracking, and cross-process tracker resumption #249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
16102a9
4dee48f
c60b42e
4b43399
bd2aa39
2547784
23f93d8
6a17dd5
465b3b1
f477ee4
2991347
279a38e
2e0e593
958464a
6ad7497
31c1293
8643334
6b09826
64e0a90
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,15 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using LaunchDarkly.Sdk.Server.Ai.DataModel; | ||
| using LaunchDarkly.Sdk.Server.Ai.Interfaces; | ||
|
|
||
| namespace LaunchDarkly.Sdk.Server.Ai.Config; | ||
|
|
||
| /// <summary> | ||
| /// Represents an AI Config, which contains model parameters and prompt messages. | ||
| /// </summary> | ||
| public record LdAiConfig | ||
| public class LdAiConfig | ||
| { | ||
|
|
||
| /// <summary> | ||
|
|
@@ -217,7 +219,10 @@ public LdAiConfig Build() | |
| /// </summary> | ||
| public readonly ModelProvider Provider; | ||
|
|
||
| internal LdAiConfig(bool enabled, IEnumerable<Message> messages, Meta meta, Model model, Provider provider) | ||
| private readonly Func<ILdAiConfigTracker> _trackerFactory; | ||
|
|
||
| internal LdAiConfig(bool enabled, IEnumerable<Message> messages, Meta meta, Model model, Provider provider, | ||
| Func<ILdAiConfigTracker> createTracker = null) | ||
| { | ||
| Model = new ModelConfiguration(model?.Name ?? "", model?.Parameters ?? new Dictionary<string, LdValue>(), | ||
| model?.Custom ?? new Dictionary<string, LdValue>()); | ||
|
|
@@ -226,7 +231,20 @@ internal LdAiConfig(bool enabled, IEnumerable<Message> messages, Meta meta, Mode | |
| Version = meta?.Version ?? 1; | ||
| Enabled = enabled; | ||
| Provider = new ModelProvider(provider?.Name ?? ""); | ||
| _trackerFactory = createTracker; | ||
| } | ||
|
|
||
| internal LdAiConfig(LdAiConfig source, Func<ILdAiConfigTracker> createTracker) | ||
| { | ||
| Model = source.Model; | ||
| Messages = source.Messages; | ||
| VariationKey = source.VariationKey; | ||
| Version = source.Version; | ||
| Enabled = source.Enabled; | ||
| Provider = source.Provider; | ||
| _trackerFactory = createTracker; | ||
| } | ||
|
|
||
| internal LdValue ToLdValue() | ||
| { | ||
| return LdValue.ObjectFrom(new Dictionary<string, LdValue> | ||
|
|
@@ -278,6 +296,17 @@ internal LdValue ToLdValue() | |
| /// </summary> | ||
| public int Version { get; } | ||
|
|
||
| /// <summary> | ||
| /// Returns a new tracker for a fresh AI run. Each call mints a new runId (a UUIDv4) | ||
| /// that LaunchDarkly uses to correlate the run's events in metrics views. Call this | ||
| /// once per AI run; metrics from different runIds cannot be combined. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Returns null for configs created directly via the builder; only configs returned by | ||
| /// <see cref="LdAiClient.CompletionConfig"/> have a factory wired in. | ||
| /// </remarks> | ||
| public ILdAiConfigTracker CreateTracker() => _trackerFactory?.Invoke(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because we don't compile on a version of .Net with nullable reference types I don't really like having the option to return null. |
||
|
|
||
| /// <summary> | ||
| /// Convenient helper that returns a disabled LdAiConfig. | ||
| /// </summary> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,8 +12,9 @@ public interface ILdAiClient | |
|
|
||
| /// <summary> | ||
| /// Retrieves a LaunchDarkly AI Completion Config identified by the given key. The return value | ||
| /// is an <see cref="ILdAiConfigTracker"/>, which makes the configuration available and | ||
| /// provides convenience methods for generating events related to model usage. | ||
| /// is an <see cref="LdAiConfig"/>, which makes the configuration available and provides | ||
| /// a <see cref="LdAiConfig.CreateTracker"/> factory for generating trackers capable of | ||
| /// emitting events related to model usage. | ||
| /// | ||
| /// Any variables provided will be interpolated into the prompt's messages. | ||
| /// Additionally, the current LaunchDarkly context will be available as 'ldctx' within | ||
|
|
@@ -25,8 +26,8 @@ public interface ILdAiClient | |
| /// <param name="defaultValue">the default config, if unable to retrieve from LaunchDarkly. When not provided, | ||
| /// a disabled config is used as the fallback.</param> | ||
| /// <param name="variables">the list of variables used when interpolating the prompt</param> | ||
| /// <returns>an AI Completion Config tracker</returns> | ||
| public ILdAiConfigTracker CompletionConfig(string key, Context context, LdAiConfig defaultValue = null, | ||
| /// <returns>an AI Completion Config</returns> | ||
| public LdAiConfig CompletionConfig(string key, Context context, LdAiConfig defaultValue = null, | ||
| IReadOnlyDictionary<string, object> variables = null); | ||
|
|
||
| /// <summary> | ||
|
|
@@ -36,8 +37,21 @@ public ILdAiConfigTracker CompletionConfig(string key, Context context, LdAiConf | |
| /// <param name="context">the context</param> | ||
| /// <param name="defaultValue">the default config, if unable to retrieve from LaunchDarkly</param> | ||
| /// <param name="variables">the list of variables used when interpolating the prompt</param> | ||
| /// <returns>an AI Completion Config tracker</returns> | ||
| /// <returns>an AI Completion Config</returns> | ||
| [Obsolete("Use CompletionConfig instead.")] | ||
| public ILdAiConfigTracker Config(string key, Context context, LdAiConfig defaultValue = null, | ||
| public LdAiConfig Config(string key, Context context, LdAiConfig defaultValue = null, | ||
| IReadOnlyDictionary<string, object> variables = null); | ||
|
|
||
| /// <summary> | ||
| /// Reconstructs a tracker from a resumption token. This enables cross-process scenarios | ||
| /// such as deferred feedback, where a tracker's runId needs to be reused in a different | ||
| /// process or at a later time. | ||
| /// | ||
| /// The reconstructed tracker will have empty model and provider names, as these are not | ||
| /// included in the resumption token. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a durable decision? Probably?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We tried to cut down as much data as possible in the resumption token to be just the necessary for proper reporting since theses tokens could be sent client side. |
||
| /// </summary> | ||
| /// <param name="resumptionToken">the resumption token obtained from <see cref="ILdAiConfigTracker.ResumptionToken"/></param> | ||
| /// <param name="context">the context to use for track events</param> | ||
| /// <returns>a tracker associated with the original runId</returns> | ||
| public ILdAiConfigTracker CreateTracker(string resumptionToken, Context context); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would have had auto-generated equals, hashcode, tostring before. So we should consider if we need any of them. (It would have also worked with
withexpressions, but nothing we can do about that.)