feat: public feature_flags surface on track/patch (DEV-1214)#10
Open
devin-ai-integration[bot] wants to merge 1 commit into
Open
feat: public feature_flags surface on track/patch (DEV-1214)#10devin-ai-integration[bot] wants to merge 1 commit into
devin-ai-integration[bot] wants to merge 1 commit into
Conversation
Add an optional FeatureFlags map[string]string to the public event surfaces (Event, AIEvent, BeginOptions, PatchOptions, FinishOptions) and interaction.SetFeatureFlags. It serializes to a top-level feature_flags string->string object on the events/track_partial body — the ratified wire shape (dawn ingest TrackEventSchema; raindrop-js core event-shipper). Omitted flags leave the wire body byte-identical for existing callers (json omitempty; nil is never populated). Flip the conformance driver: declare the events.feature_flags capability and map the harness feature_flags step arg (string-valued object, refused loudly otherwise) through track/track_ai/begin/patch/finish. Bump HARNESS_REF to the main SHA where the feature_flags scenarios are stable and ratchet feature-flags-request-shape@fault as missing_feature (DEV-1149 route gap: the SDK ships events/track_partial single-object bodies, not the events/track array batch the scenario asserts). Bump Version to 0.1.6. Co-Authored-By: pavel <pavel.y.ivanov@gmail.com>
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
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 the public
feature_flagssurface to the Go core SDK (DEV-1214), matching the JS event-shipper wire contract. Additive-only: existing callers are unaffected.FeatureFlags map[string]stringonEvent,AIEvent,BeginOptions,PatchOptions,FinishOptions, plusinteraction.SetFeatureFlags(map[string]string). Maps are defensively cloned at the boundary.feature_flagsobject (sibling ofai_data/properties/attachments) on theevents/track_partialbody, exactly the ratified shape (dawn ingestTrackEventSchema:feature_flags: z.record(z.string()).optional(); raindrop-js core event-shipperbody[0].feature_flags). Taggedjson:"feature_flags,omitempty"and never populated when nil, so omitted → key absent.properties(later keys win, earlier keys retained), so flags set onBegin/Patchsurvive to the finalized flush.events.feature_flagscapability and maps the harnessfeature_flagsstep arg (a string→string object; non-string values are refused loudly) throughtrack/track_ai/begin/patch/finish.HARNESS_REFto6bd23884ce390dd56b29d4ba32277a2d9d9ec0a8(themainSHA where thefeature_flagsscenarios arestable); the existingfailures.txtis exactly green at this SHA (no unrelated ratchet churn).Versionbumped0.1.5→0.1.6.Wire-shape proof
Actual request bodies produced by the SDK's public API (captured from
TrackAI):With
FeatureFlagsset — top-levelfeature_flags, multibyte value round-trips unmangled:{"event_id":"…","user_id":"flags-u1","event":"chat","timestamp":"…", "ai_data":{"input":"How do I enable reasoning?","output":"Toggle it in Settings.","model":"mock-gpt"}, "properties":{"$context":{…}},"attachments":[], "feature_flags":{"locale-label":"café-日本語","prompt-version":"v2"},"is_pending":false}Without
FeatureFlags— nofeature_flagskey at all (byte-identical to pre-change bodies for existing callers):{"event_id":"…","user_id":"flags-u1","event":"chat","timestamp":"…", "ai_data":{"input":"hello","output":"world","model":"mock-gpt"}, "properties":{"$context":{…}},"attachments":[],"is_pending":false}Asserted by unit tests in
feature_flags_test.go:TestTrackAISerializesFeatureFlags— top-levelfeature_flagsstring→string object; multibyte round-trip.TestOmittedFeatureFlagsLeaveBodyUnchanged— omitted flags leave nofeature_flagskey on the wire.TestInteractionFeatureFlagsMergeAcrossPartials,TestFeatureFlagsClonedFromCaller.Verification
Unit tests + linters (repo CI checks):
Fault lane (harness
6bd23884…, driverconformance/driver,conformance/failures.txt) — from this PR'sfault-laneCI job:Lane exits 0 (reproduced identically locally).
feature-flags-request-shape@faultdoes not PASS for this SDK, and cannot: the scenario assertsendpoint: events/trackwith a JSON array body ($[0].feature_flags…), but the Go SDK ships every event viaevents/track_partialas a single object. This is the pre-existing DEV-1149 route gap shared by allevents/trackscenarios (all ratchetedmissing_feature), not specific tofeature_flags— so it is ratcheted the same way. Thefeature_flagswire shape itself is correct (top-level string→string object, verified above); only the route/batching differ.Prod readback (
feature-flags-readback@prod) — PASSED in this PR'sprod-laneCI job (real production ingest + Query API round-trip):This is the meaningful end-to-end proof that
feature_flagsset via the public Go API lands in ingest and reads back through the Query API. (A local prod run from this session was blocked by an expired sessionRAINDROP_WRITE_KEY; CI uses a valid org credential, so the prod round-trip is verified there.)Safety
Additive-only, no behavior change for existing callers.
feature_flagsusesjson:",omitempty"and is never populated when nil, so callers that don't set it produce byte-identical request bodies — proven byTestOmittedFeatureFlagsLeaveBodyUnchanged(asserts nofeature_flagskey reaches the wire when omitted). No regressions observed in the full unit suite (incl.-race) or the fault lane (exit 0, zero unrelated ratchet churn); the ratchet file gained exactly one line for the newly-in-corpus feature-flags scenario.Link to Devin session: https://app.devin.ai/sessions/5298408969504710a5a2e2a9744b6320
Requested by: @pavel-y-ivanov