Skip to content

feat(subscriptions): add AI report context picker - #91788

Draft
vdekrijger wants to merge 13 commits into
codex/ai-subscription-context-execution-v1from
codex/ai-subscription-context-frontend-v1
Draft

feat(subscriptions): add AI report context picker#91788
vdekrijger wants to merge 13 commits into
codex/ai-subscription-context-execution-v1from
codex/ai-subscription-context-frontend-v1

Conversation

@vdekrijger

@vdekrijger vdekrijger commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Problem

People creating AI report subscriptions cannot choose saved dashboards or insights as report context.

This UI layer depends on #91787.

Changes

  • People can attach up to three dashboard or insight contexts to an AI report subscription.
  • New subscriptions prefill the current dashboard or insight when available.
  • The subscription-ai-contexts flag controls the picker rollout.
  • Synthetic Storybook stories cover empty, mixed, maximum, and narrow layouts.
  • Snapshot and fixture updates are mechanical.

Normal layout:

AI report context picker with mixed contexts

Narrow layout:

AI report context picker at its maximum

How did you test this code?

  • Picker tests cover selection, removal, limits, and disabled states.
  • Logic tests cover prefill, rollout gating, payload shape, validation, and duplicate submission guards.
  • TypeScript checks, scoped Jest tests, formatting, repository-wide mypy, and strict preflight completed locally.
  • Browser QA was not run in this task.

👉 Stay up-to-date with PostHog coding conventions for a smoother review.

Automatic notifications

  • Publish to changelog?

Docs update

No public docs update. The feature remains behind subscription-ai-contexts during validation.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

  • Codex separated the picker, feature flag, stories, and frontend tests from the backend layers.
  • Skills: /writing-kea-logics, /writing-ui-components, /setting-feature-flags-in-storybook, /writing-tests, /running-ci-preflight, /writing-pr-descriptions, and /stacking-prs.
  • Public-artifact review found no customer-derived or private material.

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Trunk lane — backend Python lane

This PR is assigned to the backend Python lane. It runs backend Python tests and may merge in parallel with PRs in other lanes.

⚠️ Complexity (TypeScript) — 11 functions above the limit (max 52)

Cyclomatic complexity above the limit in changed typescript files (10 for production files, 15 for test files). Warn only: worth simplifying when you next touch these functions.

Function Location Complexity Limit
EditSubscriptionForm products/subscriptions/frontend/components/Subscriptions/views/EditSubscription.tsx:243 52 10
SubscriptionWizard products/subscriptions/frontend/components/Subscriptions/SubscriptionWizard.tsx:96 35 10
submit products/subscriptions/frontend/components/Subscriptions/subscriptionLogic.ts:713 20 10
SubscriptionReviewStep products/subscriptions/frontend/components/Subscriptions/SubscriptionWizard.tsx:688 19 10
setSubscriptionValue products/subscriptions/frontend/components/Subscriptions/subscriptionLogic.ts:1012 17 10
generatePreview products/subscriptions/frontend/components/Subscriptions/subscriptionLogic.ts:1065 15 10
validateAiWindow products/subscriptions/frontend/components/Subscriptions/subscriptionLogic.ts:90 14 10
loadSubscriptionSuccess products/subscriptions/frontend/components/Subscriptions/subscriptionLogic.ts:802 14 10
<anonymous> products/subscriptions/frontend/components/Subscriptions/subscriptionLogic.ts:1163 14 10
SubscriptionsModal products/subscriptions/frontend/components/Subscriptions/SubscriptionsModal.tsx:36 12 10
getAiSubscriptionGate products/subscriptions/frontend/components/Subscriptions/utils.tsx:352 12 10
⚠️ Bundle size — 🔺 +63 B (+0.0%)

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 68.65 MiB · 🔺 +63 B (+0.0%)

No file changed by more than 1000 B.

Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report

Eager graph — within budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.50 MiB · 22 files no change ███░░░░░░░ 33.2% of 4.51 MiB
logged-out boot: index + App + bootApp (preloaded by every page, including /login)
src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
5.24 MiB · 668 files 🔺 +52 B (+0.0%) █████████░ 93.1% of 5.63 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
7.66 MiB · 2,677 files 🔺 +75 B (+0.0%) █████████░ 87.3% of 8.77 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.5 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
3.9 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.4 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.3 KiB src/RootErrorBoundary.tsx
1.0 KiB src/index.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
854 B src/scenes/ChunkLoadErrorBoundary.tsx
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
Size File
281.8 KiB ../node_modules/.pnpm/posthog-js@1.428.6_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
267.7 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
255.4 KiB src/taxonomy/core-filter-definitions-by-group.json
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
104.2 KiB src/lib/api.ts
79.0 KiB src/products.tsx
68.8 KiB src/lib/lemon-ui/icons/icons.tsx
62.5 KiB src/lib/utils/eventUsageLogic.ts
38.8 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
33.9 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
281.8 KiB ../node_modules/.pnpm/posthog-js@1.428.6_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
267.7 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
255.4 KiB src/taxonomy/core-filter-definitions-by-group.json
153.8 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
104.2 KiB src/lib/api.ts
95.8 KiB ../packages/quill/packages/quill/dist/index.js
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
79.0 KiB src/products.tsx

Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479

Toolbar bundle — eager 2.29 MiB within budget

What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.

Metric Size Δ vs base Budget
Eager (shipped)
entry + static imports
2.29 MiB · 18 files 🔺 +52 B (+0.0%) ████░░░░░░ 40.0% of 5.72 MiB
Deferred (lazy) 2.11 MiB · 45 files no change n/a — loads on demand
Loader dist/toolbar.js 1.1 KiB no change █░░░░░░░░░ 5.8% of 19.5 KiB
Largest eagerly-shipped chunks
Size File
756.4 KiB dist/toolbar/toolbar-app-LA4JX7FS.css
608.8 KiB dist/toolbar/chunk-chunk-Y4IQSBQ5.js
484.7 KiB dist/toolbar/chunk-chunk-RPV3NYRJ.js
136.6 KiB dist/toolbar/chunk-chunk-UB4UNSJ2.js
131.8 KiB dist/toolbar/chunk-chunk-FDH2IBXT.js
72.2 KiB dist/toolbar/toolbar-app-7I76D2UW.js
69.0 KiB dist/toolbar/chunk-chunk-TSAL54PB.js
35.6 KiB dist/toolbar/chunk-chunk-N77YTDD3.js
21.0 KiB dist/toolbar/chunk-chunk-UROSD4V5.js
6.8 KiB dist/toolbar/chunk-chunk-DV7IWQNF.js

Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile

Dist folder size — 🔺 +57.5 KiB (+0.0%)

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 1458.26 MiB · 🔺 +57.5 KiB (+0.0%)

@vdekrijger
vdekrijger force-pushed the codex/ai-subscription-context-execution-v1 branch from 78016f1 to 9a6188d Compare August 31, 2026 16:19
@vdekrijger
vdekrijger force-pushed the codex/ai-subscription-context-frontend-v1 branch from d2f6ee8 to 54c5ddb Compare August 31, 2026 16:19
@trunk-io

trunk-io Bot commented Aug 31, 2026

Copy link
Copy Markdown

Static BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

@vdekrijger
vdekrijger force-pushed the codex/ai-subscription-context-execution-v1 branch from 9a6188d to 97058bc Compare September 1, 2026 10:49
@vdekrijger
vdekrijger force-pushed the codex/ai-subscription-context-frontend-v1 branch from 54c5ddb to b7d409e Compare September 1, 2026 10:50
@vdekrijger
vdekrijger force-pushed the codex/ai-subscription-context-execution-v1 branch from 97058bc to 8a32ee0 Compare September 1, 2026 13:01
@vdekrijger
vdekrijger force-pushed the codex/ai-subscription-context-frontend-v1 branch from b7d409e to 716344c Compare September 1, 2026 13:01
@vdekrijger vdekrijger added the reviewhog ($$$) Reviews pull requests before humans do label Sep 8, 2026
@posthog

posthog Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

🦔 PostHog Review reviewed this pull request

Found 1 must fix, 1 should fix, 0 consider.

Published 2 findings (view the review).

Resolved comments: 1 fixed, 1 already settled

@posthog

posthog Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

PostHog Review alpha 🦔 If you find any issues helpful - please reply "valid", "invalid", etc., for evaluation purposes 🙏

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostHog Review

Found 4 should fix, 3 consider.

Comment thread products/subscriptions/frontend/components/Subscriptions/utils.tsx Outdated
Comment thread products/subscriptions/frontend/components/Subscriptions/AiPromptFields.tsx Outdated
@posthog posthog Bot removed the reviewhog ($$$) Reviews pull requests before humans do label Sep 8, 2026
@vdekrijger
vdekrijger force-pushed the codex/ai-subscription-context-execution-v1 branch from 8a32ee0 to 8730b54 Compare September 8, 2026 16:47
@vdekrijger
vdekrijger force-pushed the codex/ai-subscription-context-frontend-v1 branch from d8d2011 to 0d75459 Compare September 8, 2026 17:29
@vdekrijger vdekrijger added the reviewhog ($$$) Reviews pull requests before humans do label Sep 8, 2026
vdekrijger and others added 6 commits September 8, 2026 19:57
The review step is where someone confirms an AI report before creating it,
but it listed the prompt and analysis window without the attached dashboards
and insights. Context changes what the report is about, and the prefill can
attach the current dashboard or insight on its own, so the summary could
differ from what the person expected.

The row lists the selected names, or explains that the report picks project
data from the prompt when nothing is attached. It follows the rollout flag,
and sits above Prompt to match the order of the content step.

Generated-By: PostHog Desktop
Task-Id: 027a8ebc-4593-4419-a6e0-dd18ff544d49
Someone who opened an AI report from an insight and pressed create while the
insight was still being looked up saved a report with no context, so it ran on
general project data. The form then reloaded from the server and the context
chip they had seen disappeared, with nothing explaining why.

The wait for the prefill sat in the form's submit handler, which receives a
copy of the form taken before that handler runs. Waiting there delayed the
request without changing what it carried. The wait now runs in preSubmit,
which finishes before the form is read.

The new test holds the insight lookup open across a submit and fails without
this change.

Generated-By: PostHog Desktop
Task-Id: 027a8ebc-4593-4419-a6e0-dd18ff544d49
The server can reject a chosen dashboard or insight after it is deleted, moves
out of the team, or the person loses viewer access to it. It answers with an
error against the context field, and the form already stores that error, but
nothing displayed it. The person saw one toast and had no marker on the
selection that caused it.

The picker now sits in a form field, like the prompt below it, so the message
appears under the selection and stays there.

The wizard submits from the review step, where the picker is not visible, so
someone who saves from there still has to go back to the content step to read
it. Anchoring or reflecting the error on review is left as a separate call.

Generated-By: PostHog Desktop
Task-Id: 027a8ebc-4593-4419-a6e0-dd18ff544d49
@vdekrijger
vdekrijger force-pushed the codex/ai-subscription-context-frontend-v1 branch from 0d75459 to 7f07ab2 Compare September 8, 2026 17:59

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostHog Review

Found 1 must fix, 1 should fix.

@posthog posthog Bot removed the reviewhog ($$$) Reviews pull requests before humans do label Sep 8, 2026
posthog Bot and others added 2 commits September 8, 2026 18:12
The form waits for an in-flight insight lookup in preSubmit, which runs before
kea-forms marks the form as submitting. The submit button therefore stayed
clickable for the whole wait, so a second click let both submit listeners
dispatch a create request. That created two subscriptions and sent two test
reports.

preSubmit now takes the listener breakpoint and calls it after the wait, so a
superseded submit stops there and only the latest one reaches the API.

Generated-By: PostHog Desktop
Task-Id: bd7245d1-8918-4060-9637-2dfd4e38a613
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant