Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,8 @@ private Supplier<LDAIConfigTracker> trackerFactory(
String graphKey) {
String modelName = model != null && model.getName() != null ? model.getName() : "";
String providerName = provider != null && provider.getName() != null ? provider.getName() : "";
String modelKey = model != null ? model.getModelKey() : null;
int modelVersion = model != null ? model.getModelVersion() : 1;
int ver = version != null ? version : 1;
return () -> new LDAIConfigTrackerImpl(
client,
Expand All @@ -409,6 +411,8 @@ private Supplier<LDAIConfigTracker> trackerFactory(
ver,
modelName,
providerName,
modelKey,
modelVersion,
context,
graphKey,
logger);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,20 @@ public String toString() {
*/
public static final class Model {
private final String name;
private final String modelKey;
private final int modelVersion;
private final Map<String, Object> parameters;
private final Map<String, Object> custom;

private Model(String name, Map<String, Object> parameters, Map<String, Object> custom) {
private Model(
String name,
String modelKey,
int modelVersion,
Map<String, Object> parameters,
Map<String, Object> custom) {
this.name = name;
this.modelKey = modelKey;
this.modelVersion = modelVersion;
this.parameters = parameters;
this.custom = custom;
}
Expand All @@ -232,6 +241,24 @@ public String getName() {
return name;
}

/**
* Returns the stable key of the model configuration.
*
* @return the model key, or {@code null} if none was specified
*/
public String getModelKey() {
return modelKey;
}

/**
* Returns the version of the model configuration.
*
* @return the model version; defaults to {@code 1}
*/
public int getModelVersion() {
return modelVersion;
}

/**
* Returns the model-specific parameters as an unmodifiable map.
*
Expand Down Expand Up @@ -290,32 +317,59 @@ public boolean equals(Object o) {
}
Model other = (Model) o;
return Objects.equals(name, other.name)
&& Objects.equals(modelKey, other.modelKey)
&& modelVersion == other.modelVersion
&& parameters.equals(other.parameters)
&& custom.equals(other.custom);
}

@Override
public int hashCode() {
return Objects.hash(name, parameters, custom);
return Objects.hash(name, modelKey, modelVersion, parameters, custom);
}

@Override
public String toString() {
return "Model{name=" + name + ", parameters=" + parameters + ", custom=" + custom + '}';
return "Model{name=" + name + ", modelKey=" + modelKey + ", modelVersion=" + modelVersion
+ ", parameters=" + parameters + ", custom=" + custom + '}';
}

/**
* Builder for {@link Model}.
*/
public static final class Builder {
private final String name;
private String modelKey;
private int modelVersion = 1;
private Map<String, Object> parameters;
private Map<String, Object> custom;

private Builder(String name) {
this.name = name;
}

/**
* Sets the stable key of the model configuration.
*
* @param modelKey the model key; may be {@code null}
* @return this builder
*/
public Builder modelKey(String modelKey) {
this.modelKey = modelKey;
return this;
}

/**
* Sets the version of the model configuration.
*
* @param modelVersion the model version
* @return this builder
*/
public Builder modelVersion(int modelVersion) {
this.modelVersion = modelVersion;
return this;
}

/**
* Sets the model-specific parameters. The map is copied defensively.
*
Expand Down Expand Up @@ -350,7 +404,7 @@ public Model build() {
Map<String, Object> cust = custom == null
? Collections.<String, Object>emptyMap()
: Collections.unmodifiableMap(new HashMap<>(custom));
return new Model(name, params, cust);
return new Model(name, modelKey, modelVersion, params, cust);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,8 @@ public static final class TrackData {
private final int version;
private final String modelName;
private final String providerName;
private final String modelKey;
private final int modelVersion;
private final String graphKey;

/**
Expand All @@ -610,6 +612,8 @@ public static final class TrackData {
* @param version the config version
* @param modelName the model name, or empty string when unknown
* @param providerName the provider name, or empty string when unknown
* @param modelKey the stable model key, or {@code null} when unknown
* @param modelVersion the model version
* @param graphKey the agent graph key, or {@code null} when not part of a graph
*/
public TrackData(
Expand All @@ -619,13 +623,17 @@ public TrackData(
int version,
String modelName,
String providerName,
String modelKey,
int modelVersion,
String graphKey) {
this.runId = Objects.requireNonNull(runId, "runId");
this.configKey = Objects.requireNonNull(configKey, "configKey");
this.variationKey = variationKey;
this.version = version;
this.modelName = modelName == null ? "" : modelName;
this.providerName = providerName == null ? "" : providerName;
this.modelKey = modelKey == null || modelKey.trim().isEmpty() ? null : modelKey;
this.modelVersion = modelVersion;
this.graphKey = graphKey;
}

Expand Down Expand Up @@ -683,6 +691,24 @@ public String getProviderName() {
return providerName;
}

/**
* Returns the stable model key.
*
* @return the model key, or {@code null} when unknown
*/
public String getModelKey() {
return modelKey;
}

/**
* Returns the model version.
*
* @return the model version
*/
public int getModelVersion() {
return modelVersion;
}

/**
* Returns the agent graph key.
*
Expand All @@ -695,7 +721,7 @@ public String getGraphKey() {
/**
* Builds an {@link LDValue} representation of this track data using camelCase keys.
* <p>
* {@code variationKey} and {@code graphKey} are omitted when {@code null}.
* {@code variationKey}, {@code modelKey}, and {@code graphKey} are omitted when {@code null}.
*
* @return an {@link LDValue} object containing all non-null fields
*/
Expand All @@ -705,10 +731,14 @@ public LDValue toLDValue() {
.put("configKey", configKey)
.put("version", version)
.put("modelName", modelName)
.put("providerName", providerName);
.put("providerName", providerName)
.put("modelVersion", modelVersion);
if (variationKey != null) {
b.put("variationKey", variationKey);
}
if (modelKey != null) {
b.put("modelKey", modelKey);
}
if (graphKey != null) {
b.put("graphKey", graphKey);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ static Model parseModel(LDValue model) {
if (model == null || model.getType() != LDValueType.OBJECT) {
return null;
}
LDValue modelVersion = model.get("modelVersion");
int version = modelVersion.getType() == LDValueType.NUMBER ? modelVersion.intValue() : 1;
return Model.builder(asStringOrNull(model.get("name")))
.modelKey(trimToNull(asStringOrNull(model.get("modelKey"))))
.modelVersion(version)
.parameters(LDValueConverter.toMap(model.get("parameters")))
.custom(LDValueConverter.toMap(model.get("custom")))
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ public final class LDAIConfigTrackerImpl implements LDAIConfigTracker {
private final int version;
private final String modelName; // empty string when unknown
private final String providerName; // empty string when unknown
private final String modelKey; // nullable
private final int modelVersion;
private final String graphKey; // nullable

// Computed once at construction
Expand Down Expand Up @@ -86,6 +88,8 @@ public final class LDAIConfigTrackerImpl implements LDAIConfigTracker {
* @param version the config version
* @param modelName the model name, or empty string when unknown
* @param providerName the provider name, or empty string when unknown
* @param modelKey the stable model key, or {@code null} when unknown
* @param modelVersion the model version
* @param context the evaluation context; must not be {@code null}
* @param graphKey the agent graph key, or {@code null} when not part of a graph
* @param logger the logger; must not be {@code null}
Expand All @@ -98,6 +102,8 @@ public LDAIConfigTrackerImpl(
int version,
String modelName,
String providerName,
String modelKey,
int modelVersion,
LDContext context,
String graphKey,
LDLogger logger) {
Expand All @@ -108,6 +114,8 @@ public LDAIConfigTrackerImpl(
this.version = version;
this.modelName = modelName == null ? "" : modelName;
this.providerName = providerName == null ? "" : providerName;
this.modelKey = modelKey == null || modelKey.trim().isEmpty() ? null : modelKey;
this.modelVersion = modelVersion;
this.context = Objects.requireNonNull(context, "context");
this.graphKey = graphKey;
this.logger = Objects.requireNonNull(logger, "logger");
Expand Down Expand Up @@ -137,14 +145,25 @@ public static LDAIConfigTrackerImpl fromResumptionToken(
d.getVersion(),
"", // modelName not carried in token
"", // providerName not carried in token
null, // modelKey not carried in token
1, // modelVersion not carried in token
context,
d.getGraphKey(),
logger);
}

@Override
public TrackData getTrackData() {
return new TrackData(runId, configKey, variationKey, version, modelName, providerName, graphKey);
return new TrackData(
runId,
configKey,
variationKey,
version,
modelName,
providerName,
modelKey,
modelVersion,
graphKey);
}

@Override
Expand Down Expand Up @@ -377,10 +396,14 @@ private ObjectBuilder baseData() {
.put("configKey", configKey)
.put("version", version)
.put("modelName", modelName)
.put("providerName", providerName);
.put("providerName", providerName)
.put("modelVersion", modelVersion);
if (variationKey != null) {
b.put("variationKey", variationKey);
}
if (modelKey != null) {
b.put("modelKey", modelKey);
}
if (graphKey != null) {
b.put("graphKey", graphKey);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,34 @@ public void completionConfigReturnsTypedConfigFromVariation() {
assertThat(config.getMessages().get(0).getRole(), is(Message.Role.SYSTEM));
}

@Test
public void completionConfigPropagatesModelMetadataToTracker() {
String json = "{\"_ldMeta\":{\"enabled\":true,\"mode\":\"completion\"},"
+ "\"model\":{\"name\":\"gpt-4\",\"modelKey\":\"custom-gpt\",\"modelVersion\":7}}";
when(client.jsonValueVariation(anyString(), any(), any())).thenReturn(LDValue.parse(json));

AICompletionConfig config = ai.completionConfig("key", context, null, null);

assertThat(config.getModel().getModelKey(), is("custom-gpt"));
assertThat(config.getModel().getModelVersion(), is(7));
assertThat(config.createTracker().getTrackData().getModelKey(), is("custom-gpt"));
assertThat(config.createTracker().getTrackData().getModelVersion(), is(7));
}

@Test
public void completionConfigDefaultsMissingModelMetadata() {
String json = "{\"_ldMeta\":{\"enabled\":true,\"mode\":\"completion\"},"
+ "\"model\":{\"name\":\"gpt-4\"}}";
when(client.jsonValueVariation(anyString(), any(), any())).thenReturn(LDValue.parse(json));

AICompletionConfig config = ai.completionConfig("key", context, null, null);

assertThat(config.getModel().getModelKey(), is(nullValue()));
assertThat(config.getModel().getModelVersion(), is(1));
assertThat(config.createTracker().getTrackData().getModelKey(), is(nullValue()));
assertThat(config.createTracker().getTrackData().getModelVersion(), is(1));
}

@Test
public void interpolationExposesContextAsLdctx() {
String json = "{\"_ldMeta\":{\"enabled\":true,\"mode\":\"completion\"},"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public class AIConfigParserTest {
public void parsesFullCompletionConfig() {
LDValue value = LDValue.parse("{"
+ "\"_ldMeta\":{\"variationKey\":\"v1\",\"enabled\":true,\"version\":3,\"mode\":\"completion\"},"
+ "\"model\":{\"name\":\"gpt-4\",\"parameters\":{\"temperature\":0.7,\"maxTokens\":100},"
+ "\"model\":{\"name\":\"gpt-4\",\"modelKey\":\"custom-gpt\",\"modelVersion\":7,"
+ "\"parameters\":{\"temperature\":0.7,\"maxTokens\":100},"
+ "\"custom\":{\"team\":\"core\"}},"
+ "\"provider\":{\"name\":\"openai\"},"
+ "\"messages\":[{\"role\":\"system\",\"content\":\"You are {{persona}}.\"},"
Expand All @@ -39,6 +40,8 @@ public void parsesFullCompletionConfig() {
assertThat(parsed.getVersion(), is(3));
assertThat(parsed.getMode(), is(Mode.COMPLETION));
assertThat(parsed.getModel().getName(), is("gpt-4"));
assertThat(parsed.getModel().getModelKey(), is("custom-gpt"));
assertThat(parsed.getModel().getModelVersion(), is(7));
assertThat(parsed.getModel().getParameter("temperature"), is((Object) 0.7));
assertThat(parsed.getModel().getParameter("maxTokens"), is((Object) 100L));
assertThat(parsed.getModel().getCustom("team"), is((Object) "core"));
Expand All @@ -53,6 +56,23 @@ public void parsesFullCompletionConfig() {
assertThat(parsed.getTools().get("search").getType(), is("function"));
}

@Test
public void modelMetadataDefaultsWhenMissingOrWrongType() {
AIConfigFlagValue missing = AIConfigParser.parse(
LDValue.parse("{\"model\":{\"name\":\"gpt-4\"}}"));
assertThat(missing.getModel().getModelKey(), is(nullValue()));
assertThat(missing.getModel().getModelVersion(), is(1));

AIConfigFlagValue wrongType = AIConfigParser.parse(
LDValue.parse("{\"model\":{\"modelKey\":3,\"modelVersion\":\"two\"}}"));
assertThat(wrongType.getModel().getModelKey(), is(nullValue()));
assertThat(wrongType.getModel().getModelVersion(), is(1));

AIConfigFlagValue blankKey = AIConfigParser.parse(
LDValue.parse("{\"model\":{\"modelKey\":\" \"}}"));
assertThat(blankKey.getModel().getModelKey(), is(nullValue()));
}

@Test
public void parsesAgentInstructions() {
LDValue value = LDValue.parse("{\"_ldMeta\":{\"enabled\":true,\"mode\":\"agent\"},"
Expand Down
Loading
Loading