feat: add LDValueConverter and LDContextEncoder to common#187
Open
mattrmc1 wants to merge 2 commits into
Open
Conversation
Contributor
|
@mattrmc1 can you add a description for what this will be used for. I see it being added but not used anywhere. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 71f3f8e. Configure here.
4 tasks
Contributor
Author
|
PR for the actual implementation once this is published to common: #188 |
tanderson-ld
reviewed
Jul 9, 2026
| /** | ||
| * Maximum nesting depth converted before deeper values are dropped. | ||
| */ | ||
| public static final int MAX_DEPTH = 100; |
Contributor
There was a problem hiding this comment.
Where does this come from?
tanderson-ld
approved these changes
Jul 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Adds two general-purpose, public utilities to the shared
commonmodule (com.launchdarkly.sdk) for converting LaunchDarkly data-model types into plain Java structures:LDValueConverter— converts anLDValuetree into plain Java values (String,Long,Double,Boolean,List,Map, ornull).LDContextEncoder— encodes anLDContextinto a plain nestedMap<String, Object>, usingLDValueConverterfor leaf attribute values.Both are self-contained (no new dependencies) and live next to
LDValue/LDContextso they can be shared across artifacts. This change is additive only — no existing types are modified.Where this will be used
These utilities are being promoted into
commonso they can be shared rather than reimplemented per artifact. They aren't referenced withincommonitself yet — a follow-up change will wire them into the AI SDK (server-ai):LDValueConverterwill replace the AI SDK's internal copy used by its config parser to exposemodel.parameters,model.custom, and toolparameters/customParametersas plain Java maps on the public config surface (without leakingLDValue).LDContextEncoderwill replace the AI SDK'sInterpolatorcontext-encoding logic that builds theldctxvariable exposed to Mustache prompt templates (e.g.{{ldctx.key}},{{ldctx.name}}).Because
commonis a separately published artifact, it must be released with these utilities before the AI SDK can depend on them; the follow-up then removes the AI SDK's local copies. Landing this on its own keeps the shared utilities and their tests decoupled from the AI SDK release. The encoder is intentionally general-purpose (not Mustache-specific), so it's reusable anywhere a context needs to be rendered into a generic nested structure.LDValueConverterLongwhen they are mathematically integral and within the IEEE-754 exact-integer range (|value| <= 2^53); otherwise toDouble. Whole numbers outside±2^53return the nearestDouble.MAX_DEPTH; values deeper than the cap are dropped (null) to bound stack usage on adversarial input.LinkedHashMapto preserve insertion order; returned collections are unmodifiable.LDContextEncoderEncodes an
LDContextinto a nested map without round-tripping through JSON serialization:nullor invalid context produces an empty map.kind,key,name(only when non-null),anonymous(always present), and one entry per custom attribute.{"kind":"multi", "key":<fullyQualifiedKey>, <kindName>:{...}, ...}, where each per-kind nested map omitskind(it is implied by the property key), mirroring LaunchDarkly's standard context JSON shape.Test plan
commonmodule build and tests passLDValueConverterTest— null/JSON-null handling, integral vs. fractional numbers, the±2^53boundary (inside and just outside),NaN/Infinity, strings/booleans, nested objects and arrays, field-order preservation,toMapreturns null for non-objects, unmodifiable results, and depth-cap behavior on deeply nested inputLDContextEncoderTest— null/invalid context, single-kind (kind/key/anonymous, name present/omitted,anonymoustrue/false), custom attribute objects/arrays and deeply nested attributes, multi-kind (kind:multi+ fully-qualified key, per-kind objects,kindomission on nested objects, nestedanonymous/name), and custom context kindsNote
Low Risk
Additive-only new public APIs in common with no changes to existing behavior; edge cases (depth cap, multi-kind
"key"collision) are documented and tested.Overview
Adds two public utilities in
com.launchdarkly.sdkfor turning LaunchDarkly model types into plain Java structures without JSON round-trips.LDValueConverterwalks anLDValuetree intoString,Long,Double,Boolean, unmodifiableList/Map, ornull, with integral numbers in ±2^53 asLong, a depth cap of 100, and defensive handling so conversion does not throw.LDContextEncodermaps anLDContextto nestedMap<String, Object>matching standard context JSON (single-kind vs multi-kind, optionalname, alwaysanonymous, custom attrs via the converter). Null or invalid contexts yield an empty map; multi-kind output sets top-levelkeyto the fully qualified key after per-kind entries so it wins over a member kind named"key"(documented trade-off in tests).Comprehensive unit tests cover both classes; no existing types are modified.
Reviewed by Cursor Bugbot for commit 76872ec. Bugbot is set up for automated code reviews on this repo. Configure here.