Repository navigation
Conversation
Port the 9 PIA tracking events from the JS SDK so native Android apps can measure the Product Insights Agent. Each public method takes a single TrackingData request object with a builder, following SearchSubmitTrackingData. - section is sent as a query param on all 9 and defaults to defaultItemSection - analyticsTags are merged with defaultAnalyticsTags - items and followUpQuestions are capped at 100, the server limit - view timespans take epoch ms and are sent as ISO-8601 UTC date-times
The endpoints validate bodies strictly and the public methods are fire-and-forget, so a malformed body would fail as a silent 400. - MockWebServer tests check field presence and omission per event, plus edge cases: position 0, empty answerText, the 100 caps, UTC timespans - Builder tests cover each TrackingData class - One live test per event confirms the server returns 204
Add a Product Insights Agent Events subsection to README section 12 with
a build { } example for each of the 9 events.
Mudaafi
force-pushed
the
cdx-709-pia-tracking-events
branch
from
October 22, 2026 14:10
d971b2f to
81d5146
Compare
Address review feedback on the PIA tracking events. - Drop c/i/s/key/ui/us/_dt/beacon/section from the request bodies. RequestInterceptor already adds the client params to the query, and section is sent as a query param, which is where the spec expects them. - Add ProductInsightsAgentRequestBody holding item_id, item_name, variation_id, thread_id and analytics_tags for the 9 bodies. - Add ProductInsightsAgentTrackingData with a self-typed Builder for the shared itemId/itemName/variationId/threadId/sectionName/analyticsTags, so chained setters keep the concrete builder type. - Assert the client params on the query and their absence from the body.
The abstract base classes added a generic public builder and unchecked casts while saving little, so go back to flat classes. - Add a ProductInsightsAgentTrackingData interface for the fields every PIA event shares, implemented by the 9 TrackingData classes. Section and analytics tag resolution in ConstructorIo now goes through it. - Make the request bodies flat data classes again, still without the client params that RequestInterceptor adds to the query. - Share one body between focus and out_of_view, and one between question_click and question_submit, since each pair sends the same fields.
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
User question and answer text bypasses existing personal-information redaction when transmitted in JSON tracking bodies.
1 open issue
What changed in this PR
Adds nine Product Insights Agent tracking events to the Android SDK, following the single-request builder pattern introduced for search-submit tracking.
Changes:
- Adds public tracking methods, request builders, JSON models, and API wiring.
- Supports shared analytics tags, UTC view timestamps, and answer-view list limits.
- Adds usage examples, builder tests, request-payload tests, and live integration tests.
| File | Description |
|---|---|
| README.md | Documents all nine events with Kotlin examples. |
| library/src/test/java/io/constructor/data/builder/ProductInsightsAgentViewTrackingDataTest.kt | Tests view request construction. |
| library/src/test/java/io/constructor/data/builder/ProductInsightsAgentViewsTrackingDataTest.kt | Tests timespan request construction. |
| library/src/test/java/io/constructor/data/builder/ProductInsightsAgentTrackingDataTest.kt | Checks shared fields across all events. |
| library/src/test/java/io/constructor/data/builder/ProductInsightsAgentResultClickTrackingDataTest.kt | Tests result-click fields and zero position. |
| library/src/test/java/io/constructor/data/builder/ProductInsightsAgentQuestionSubmitTrackingDataTest.kt | Tests question-submit request construction. |
| library/src/test/java/io/constructor/data/builder/ProductInsightsAgentQuestionClickTrackingDataTest.kt | Tests question-click request construction. |
| library/src/test/java/io/constructor/data/builder/ProductInsightsAgentOutOfViewTrackingDataTest.kt | Tests out-of-view request construction. |
| library/src/test/java/io/constructor/data/builder/ProductInsightsAgentFocusTrackingDataTest.kt | Tests focus request construction. |
| library/src/test/java/io/constructor/data/builder/ProductInsightsAgentAnswerViewTrackingDataTest.kt | Tests answer-view fields and empty answers. |
| library/src/test/java/io/constructor/data/builder/ProductInsightsAgentAnswerFeedbackTrackingDataTest.kt | Tests feedback request construction. |
| library/src/test/java/io/constructor/core/ConstructorIoProductInsightsAgentTrackingTest.kt | Tests payloads, endpoints, errors, timestamps, and limits. |
| library/src/test/java/io/constructor/core/ConstructorIoIntegrationTest.kt | Adds live tests for all nine events. |
| library/src/main/java/io/constructor/data/remote/ConstructorApi.kt | Declares nine Retrofit tracking endpoints. |
| library/src/main/java/io/constructor/data/remote/ApiPaths.kt | Defines event URL constants. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentViewTimespanBody.kt | Models serialized timestamp pairs. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentViewTimespan.kt | Models epoch-millisecond view intervals. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentViewsRequestBody.kt | Defines the multiple-interval view payload. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentViewRequestBody.kt | Defines the view payload. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentResultClickRequestBody.kt | Defines the recommended-item click payload. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentQuestionRequestBody.kt | Shares payload fields for question events. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentQuestion.kt | Models displayed questions and optional topics. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentItemRequestBody.kt | Shares focus and out-of-view payload fields. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentFollowUpQuestion.kt | Defines follow-up question serialization. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentFeedbackLabel.kt | Defines thumbs-up and thumbs-down values. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentAnswerViewRequestBody.kt | Defines answer-view text and recommendation fields. |
| library/src/main/java/io/constructor/data/model/tracking/ProductInsightsAgentAnswerFeedbackRequestBody.kt | Defines the answer-feedback payload. |
| library/src/main/java/io/constructor/data/DataManager.kt | Forwards tracking requests to the API. |
| library/src/main/java/io/constructor/data/builder/ProductInsightsAgentViewTrackingData.kt | Adds the view request builder. |
| library/src/main/java/io/constructor/data/builder/ProductInsightsAgentViewsTrackingData.kt | Adds the view-timespan request builder. |
| library/src/main/java/io/constructor/data/builder/ProductInsightsAgentTrackingData.kt | Defines the shared tracking interface. |
| library/src/main/java/io/constructor/data/builder/ProductInsightsAgentResultClickTrackingData.kt | Adds the result-click request builder. |
| library/src/main/java/io/constructor/data/builder/ProductInsightsAgentQuestionSubmitTrackingData.kt | Adds the question-submit request builder. |
| library/src/main/java/io/constructor/data/builder/ProductInsightsAgentQuestionClickTrackingData.kt | Adds the question-click request builder. |
| library/src/main/java/io/constructor/data/builder/ProductInsightsAgentOutOfViewTrackingData.kt | Adds the out-of-view request builder. |
| library/src/main/java/io/constructor/data/builder/ProductInsightsAgentFocusTrackingData.kt | Adds the focus request builder. |
| library/src/main/java/io/constructor/data/builder/ProductInsightsAgentAnswerViewTrackingData.kt | Adds the answer-view request builder. |
| library/src/main/java/io/constructor/data/builder/ProductInsightsAgentAnswerFeedbackTrackingData.kt | Adds the answer-feedback request builder. |
| library/src/main/java/io/constructor/core/ConstructorIo.kt | Implements tracking methods and payload preparation. |
Review effort: Balanced
pedro-lb
previously approved these changes
Oct 26, 2026
The API rejects answer_text over 2000 Unicode code points with a 400, which drops the whole event silently. Truncate client-side, as items and followUpQuestions are already capped, cutting on a code point boundary so a surrogate pair is never split.
There was a problem hiding this comment.
Code Review
This PR adds 9 Product Insights Agent (PIA) tracking events following the same builder pattern established in #173, with comprehensive test coverage (43 mock + 9 integration tests). The implementation is well-structured and consistent.
Inline comments: 6 discussions added
Overall Assessment:
pedro-lb
approved these changes
Oct 26, 2026
This branch has not been deployed
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.

https://linear.app/constructor/issue/CDX-709/android-sdk-product-insights-agent-add-the-9-pia-tracking-events
Summary
Adds the 9 Product Insights Agent (PIA) tracking events, ported from the JS SDK. Each one takes a single request object with a builder, following the pattern from #173 (
SearchSubmitTrackingData).trackProductInsightsAgentFocusproduct_insights_agent_focustrackProductInsightsAgentOutOfViewproduct_insights_agent_out_of_viewtrackProductInsightsAgentViewproduct_insights_agent_viewtrackProductInsightsAgentViewsproduct_insights_agent_viewstrackProductInsightsAgentQuestionClickproduct_insights_agent_question_clicktrackProductInsightsAgentQuestionSubmitproduct_insights_agent_question_submittrackProductInsightsAgentAnswerFeedbackproduct_insights_agent_answer_feedbacktrackProductInsightsAgentResultClickproduct_insights_agent_result_clicktrackProductInsightsAgentAnswerViewproduct_insights_agent_answer_viewHow a request flows
flowchart TD A["App"] -->|"TrackingData.build { }"| B["ConstructorIo.trackProductInsightsAgentX(request)<br/><i>public, fire-and-forget</i>"] B --> C["...Internal(): Completable<br/>resolve section (default: defaultItemSection)<br/>merge analyticsTags with defaults<br/>build RequestBody: event fields + analytics_tags only"] C --> D["DataManager<br/><i>pass-through</i>"] D --> E["ConstructorApi (Retrofit)<br/>@POST · @Body JSON (Moshi) · section via @QueryMap"] E --> F["RequestInterceptor (OkHttp)<br/>runs on every SDK request"] F --> G["POST /v2/behavioral_action/product_insights_agent_x"] F -.- P["Adds query params:<br/>key · i · ui · s · us · ef-* · c · _dt<br/><br/>Redacts emails, phones and card numbers<br/>from behavioral paths and query"] classDef interceptor fill:#fff4d6,stroke:#c98a00,stroke-width:2px,color:#3d2a00 classDef note fill:#fffbea,stroke:#c98a00,stroke-dasharray:4 3,color:#3d2a00 class F interceptor class P noteThe PIA code only builds the event fields. The client params (
key,i,ui,s,us,ef-*,c,_dt) are added to the query of every SDK request byRequestInterceptor, which is where the spec expects them, so the request bodies don't repeat them.Noteworthy Details
itemsandfollowUpQuestionson answer view are capped at 100, matching the server limit.viewTimespanstake epoch milliseconds (System.currentTimeMillis()) and are sent as ISO-8601 UTC stringsTests
ConstructorIoProductInsightsAgentTrackingTest: 43 MockWebServer tests. Per event they check fields are present when set and absent when not.TrackingDataclass, plus a check that all 9 expose the shared fields through the interface.ConstructorIoIntegrationTest: one live test per event against the test key. All 9 return 204.The 3
ConstructorIoRecommendationsTestfailures and the randomSocketTimeoutExceptions in live*AgainstRealResponsetests happen onmastertoo. They're unrelated to this change.