Skip to content

Commit 04326f0

Browse files
ctawiahcursoragent
andcommitted
fix: omit kind on nested per-kind ldctx entries for multi-kind contexts (AIC-2695)
Match LaunchDarkly's standard context JSON, where per-kind objects under a multi-kind context omit "kind" (it is implied by the property key). Keeps {{ldctx.<kind>.kind}} consistent with the JS and Python SDKs. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 8969c72 commit 04326f0

2 files changed

Lines changed: 19 additions & 4 deletions

File tree

lib/sdk/server-ai/src/main/java/com/launchdarkly/sdk/server/ai/internal/Interpolator.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,21 @@ private static Map<String, Object> contextToMap(LDContext context) {
101101
for (int i = 0; i < count; i++) {
102102
LDContext individual = context.getIndividualContext(i);
103103
if (individual != null) {
104-
map.put(individual.getKind().toString(), singleContextToMap(individual));
104+
// Mirror LaunchDarkly's standard context JSON: the per-kind objects nested under a
105+
// multi-kind context omit "kind" because it is already implied by the property key.
106+
map.put(individual.getKind().toString(), singleContextToMap(individual, false));
105107
}
106108
}
107109
return map;
108110
}
109-
return singleContextToMap(context);
111+
return singleContextToMap(context, true);
110112
}
111113

112-
private static Map<String, Object> singleContextToMap(LDContext context) {
114+
private static Map<String, Object> singleContextToMap(LDContext context, boolean includeKind) {
113115
Map<String, Object> map = new HashMap<>();
114-
map.put("kind", context.getKind().toString());
116+
if (includeKind) {
117+
map.put("kind", context.getKind().toString());
118+
}
115119
map.put("key", context.getKey());
116120
if (context.getName() != null) {
117121
map.put("name", context.getName());

lib/sdk/server-ai/src/test/java/com/launchdarkly/sdk/server/ai/internal/InterpolatorTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,17 @@ public void exposesMultiKindContextByKind() {
8585
assertThat(result, is("multi/user-key/Bob/gold"));
8686
}
8787

88+
@Test
89+
public void multiKindNestedContextsOmitKind() {
90+
LDContext multi = LDContext.createMulti(
91+
LDContext.builder("user-key").build(),
92+
LDContext.builder(com.launchdarkly.sdk.ContextKind.of("org"), "org-key").build());
93+
// Standard LaunchDarkly context JSON omits "kind" on the per-kind objects of a multi-kind
94+
// context, so {{ldctx.user.kind}} renders empty rather than echoing the kind name.
95+
assertThat(
96+
interpolator.interpolate("[{{ldctx.user.kind}}]", null, multi), is("[]"));
97+
}
98+
8899
@Test
89100
public void ldctxOverridesUserSuppliedValue() {
90101
Map<String, Object> userLdctx = new HashMap<>();

0 commit comments

Comments
 (0)