Skip to content

feat(notebooks): size sql/python cells to the output they return - #73358

Merged
sinan-ku merged 3 commits into
masterfrom
feat/revamped-py-notebooks-gradual-node-growth
Jul 24, 2026
Merged

feat(notebooks): size sql/python cells to the output they return#73358
sinan-ku merged 3 commits into
masterfrom
feat/revamped-py-notebooks-gradual-node-growth

Conversation

@sinan-ku

Copy link
Copy Markdown
Contributor

Problem

Follow-up to #72512. That PR made V2 cells grow once results land, which fixed the clipping, but it grew every cell to the same 300px. A query that returns a single number now gets as much vertical room as a hundred-row table, and the notebook turns into a lot of empty boxes.

Changes

Size the cell to the output it actually got back instead of one fixed default. A new pure helper, outputHeightForShape, adds up what's there - rows in the returned page, printed stdout/stderr lines, and whether there's a figure - and clamps the total between a compact floor (160px) and a cap (460px). So a scalar lands around 176px, five rows around 290px, and anything past ~13 rows stops at the cap and scrolls.

Two smaller behavior changes come with it:

  • Sizing now keys off the run id rather than "first time output appeared", so re-running a cell that returns far more rows grows it again. Before, only the very first result ever resized the cell.
  • The visualization tab still snaps to VIZ_MIN_HEIGHT (350), since charts need room regardless of row count.

Still grow-only: a cell never shrinks, so a deliberate manual resize and a reload of an already-sized cell are both left alone.

Note

Existing notebooks keep whatever height they were saved with. The new sizing only applies from the next run onward.

How did you test this code?

Added notebookNodeOutputHeight.test.ts (6 cases) against the pure helper. The regression it catches is the one this PR exists for: a one-row result must come out shorter than a five-row result, and shorter than the old flat default - plus the clamps hold, so a 1000-line traceback or a 10k-row page can't produce an absurd height. No existing test covered sizing at all. I kept it at the pure-function rung rather than rendering the node, since all the arithmetic lives in the helper.

Ran locally: the new file plus the full src/scenes/notebooks Jest suite (all green), hogli ci:preflight (clean), oxlint + oxfmt on the touched files. Typecheck ran but the worktree only had a partial install, so unrelated workspace packages reported missing modules; nothing was reported in scenes/notebooks.

I (Claude) did not run this in a browser. The pixel constants are reasoned from the rendered chrome (table header, pagination bar, dataframe-name footer) rather than measured, so they're worth an eyeball in dev before this goes out.

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Docs update

No user-facing docs cover cell sizing.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

I directed this; Claude Code (Opus 4.8) wrote it in a separate worktree. Skills invoked: /writing-tests.

The first idea was to keep the single threshold and just add a second, larger one past 5 rows. We went with a continuous function instead - a step still gets the scalar case wrong unless you special-case it, and once you're special-casing you may as well compute from the shape. Rejected shrinking the cell when a re-run returns less: it would fight manual resizes, and grow-only matches what the previous PR established.

The switch from "first output" to "per run id" wasn't in the original ask, but row-count sizing is useless without it - a cell that already had a result would never re-size no matter how much data the next run returned.

Growing every result to one tall default meant a cell returning a single
number got as much room as a hundred-row table. Size the cell to what came
back instead: rows, printed lines, and figures each contribute, clamped
between a compact floor and a cap so a large result stays readable without
swallowing the notebook. Still grows only, and now re-sizes on each new run
rather than only the first one.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sinan-ku sinan-ku self-assigned this Jul 23, 2026
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Bundle size — 🔺 +522 B (+0.0%)

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

Total: 64.38 MiB · 🔺 +522 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.24 MiB · 22 files no change ███░░░░░░░ 27.5% of 4.51 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
8.07 MiB · 3,010 files no change ████████░░ 83.1% of 9.71 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/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers 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
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
789 B src/scenes/ChunkLoadErrorBoundary.tsx
762 B src/index.tsx
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
281.5 KiB ../node_modules/.pnpm/posthog-js@1.407.2/node_modules/posthog-js/dist/rrweb.js
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
236.0 KiB src/taxonomy/core-filter-definitions-by-group.json
226.1 KiB ../node_modules/.pnpm/posthog-js@1.407.2/node_modules/posthog-js/dist/module.js
154.3 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
105.8 KiB src/lib/api.ts
94.0 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

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.18 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.18 MiB · 17 files no change ████░░░░░░ 38.1% of 5.72 MiB
Deferred (lazy) 2.07 MiB · 33 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
713.8 KiB dist/toolbar/toolbar-app-HLTHZTTF.css
545.0 KiB dist/toolbar/chunk-chunk-JGF7ZYC3.js
484.2 KiB dist/toolbar/chunk-chunk-YMFODIKP.js
133.6 KiB dist/toolbar/chunk-chunk-YSVTUFEA.js
131.8 KiB dist/toolbar/chunk-chunk-T5KY5WYR.js
71.0 KiB dist/toolbar/toolbar-app-Y3ZKEAFE.js
69.0 KiB dist/toolbar/chunk-chunk-27JL52RE.js
35.6 KiB dist/toolbar/chunk-chunk-ALQOU6WO.js
20.9 KiB dist/toolbar/chunk-chunk-VMBXRLPQ.js
12.2 KiB dist/toolbar/chunk-chunk-PIK3PADE.js

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

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

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

Total: 1352.23 MiB · 🔺 +8.1 KiB (+0.0%)

Playwright — all passed

All tests passed.

View test results →

@posthog

posthog Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

👋 Visual changes detected for this PR.

Review and approve in PostHog Visual Review

If these changes are unexpected, they may be caused by a flaky test or a broken snapshot on master. Don't approve — rerun the job or wait for a fix.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

🦔 Hogbox preview · ✅ ready

▶ Open the preview

🔑 Login test@posthog.com / 12345678 (demo data)
🧩 Running this PR's backend and frontend, on the PostHog :master base
🔗 Link stable across rebuilds — a re-push swaps the box underneath, the URL stays
🔒 Access tailnet only (PostHog VPN)
🛠️ Admin inspect & debug state in hogland
💤 Idle sleeps after ~30 min idle (snapshot to S3, zero node cost) and wakes on your next visit in ~30s, behind a brief "waking up" screen

commit 28a17ae · box box-f11a46fe6bc9 · ready in 796s (push → usable) · build log · rebuilds on every push, torn down on close

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team July 23, 2026 21:17
@greptile-apps

greptile-apps Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
frontend/src/scenes/notebooks/Nodes/notebookNodeOutputHeight.ts:47-49
**Empty dataframes bypass sizing**

When an execution returns columns but no rows, the dataframe table still renders its header, controls, and surrounding chrome, but this branch returns `null`. The node therefore retains its short existing height and the empty-result table remains clipped.

### Issue 2 of 2
frontend/src/scenes/notebooks/Nodes/NotebookNodeSQLV2.tsx:180-182
**Reruns override manual heights**

When a user manually sizes a V2 cell below the calculated target and reruns it, the new run ID makes this effect grow the cell again. Because V2 resize handlers persist no marker distinguishing manual and automatic heights, the completed run overwrites the user's selected size.

Reviews (1): Last reviewed commit: "Merge branch 'master' into feat/revamped..." | Re-trigger Greptile

Comment thread frontend/src/scenes/notebooks/Nodes/notebookNodeOutputHeight.ts
Comment thread frontend/src/scenes/notebooks/Nodes/NotebookNodeSQLV2.tsx
@sinan-ku
sinan-ku requested a review from georgemunyoro July 24, 2026 08:28
@sinan-ku sinan-ku added the stamphog Request AI approval (no full review) label Jul 24, 2026
@sinan-ku
sinan-ku removed the request for review from georgemunyoro July 24, 2026 08:28

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pure frontend UI sizing logic for notebook cells, well outside risky territory, with a dedicated pure-function test suite; the two bot-raised P1 concerns were discussed and explicitly accepted as reasonable trade-offs by author and reviewer, not ignored.

  • Author wrote 100% of the modified lines and has 12 merged PRs in these paths (familiarity STRONG).
  • 👍 on the PR from greptile-apps[bot], hex-security-app[bot].
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 119L, 3F substantive, 153L/4F incl. docs/generated/snapshots — within ceiling
tier T1-agent / T1c-medium (153L, 4F, single-area, feat)
stamphog 2.0.0b3 .stamphog/policy.yml @ ec2002f · reviewed head 28a17ae

@sinan-ku
sinan-ku merged commit 967e56b into master Jul 24, 2026
322 of 325 checks passed
@sinan-ku
sinan-ku deleted the feat/revamped-py-notebooks-gradual-node-growth branch July 24, 2026 17:39
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 24, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-24 18:10 UTC Run
prod-us ✅ Deployed 2026-07-24 18:33 UTC Run
prod-eu ✅ Deployed 2026-07-24 18:32 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stamphog Request AI approval (no full review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant