Skip to content

Runnable Jupyter notebooks in T3: run cells from the side-pane notebook viewer, and agent tools to build and run them #208

Closed
4 of 4 issues completed

Description

@tannerpolley

Owner request, 2026-10-28: full Jupyter notebook support in the side pane. That means running cells, plus agents creating notebooks to show results and analysis. The owner wants to try both ways, built by Codex agents.

Done now, no T3 code

Each research project has a JupyterLab project script:

Project Port
Lithium_Extraction 8891
ePC-SAFT 8892
Amine-Thermodynamics 8893
MEA-Absorption-Column 8894

The script runs uv run --no-sync --with jupyterlab jupyter lab --no-browser --ServerApp.ip=127.0.0.1 --ServerApp.port=<port> --IdentityProvider.token=<per-project token>. It layers JupyterLab over the project's own .venv, so the kernel imports the project's packages, and it opens in T3's in-app browser pane (previewUrl, autoOpenPreview). It was checked on Lithium_Extraction: the server started, the python3 kernel is available, and it stopped cleanly. The browser pane shows real browser tabs, so JupyterLab's frame-ancestors 'self' doesn't matter.

Wanted: native cell running (option 3)

Today: upstream's apps/web/src/components/files/NotebookPreview.tsx renders .ipynb read-only with saved outputs.

Proposed shape, as an optional extension:

  • A server service talks to a Jupyter kernel through the Jupyter Server REST and WebSocket API, or jupyter_client through a small sidecar. It runs one kernel per open notebook in the project's environment, with execute, interrupt and restart, and streams outputs back over T3's WebSocket as typed contracts.
  • The notebook viewer gets Run, Run all and Interrupt, shows live outputs, and saves them back to the .ipynb.
  • Agents get MCP tools to create a notebook, add or edit cells, run them and read the outputs. Scheduled tasks use the same service. Agents can then build analysis notebooks and leave them run for the owner to open.

Constraints:

  • Off unless a Jupyter server or kernel is available for the project.
  • Never binds beyond 127.0.0.1.
  • Kernels stop when their notebook closes or after idle time, and t3_preview_list-style tools show running kernels.
  • Performance: stream outputs without re-rendering the whole notebook.
  • Fork rules: Modular fork: move remaining fork code out of upstream files #24, as fork-owned files with small hooks.
  • Out of scope: mobile, and providers other than Codex and Claude.

Steps

  1. Read-only design: the kernel transport choice, contracts, UI, agent tools, lifecycle and security. Size it and split it into PRs.
  2. The owner approves the design.
  3. The build.

Also include agent guidance for the JupyterLab path in the meantime:

  • create .ipynb files with the analysis;
  • run them headless with uv run --no-sync --with jupyterlab jupyter nbconvert --to notebook --execute --inplace <file>;
  • open them in the file viewer, which shows the outputs, or in the JupyterLab tab.

Activity

  1. tannerpolley commented on Oct 28, 2026

    @tannerpolley
    OwnerAuthor

    Design pass (2026-10-28, read-only, GPT-6.1 Sol high). The full doc is ~/.local/share/t3-fork-notes/notebook-execution-design.md.

    Recommendation

    T3's server connects to a project-local Jupyter Server through REST (/api/kernels, kernelspecs, interrupt, restart, delete) and one kernel WebSocket per notebook. The JSON wire format is enough.

    • No sidecar: no Python process of T3's own, and no JupyterLab bundle in the web app.
    • One writer: T3 stays the only writer of the .ipynb. Jupyter's Contents API is not used.
    • Rejected: a jupyter_client sidecar, which adds another process to own; and "embed JupyterLab only", which is the interim path, not native.

    Shape

    Fork-owned modules: apps/server/src/notebook/NotebookService.ts, JupyterTransport.ts, notebookDocument.ts and packages/contracts/src/notebook.ts, with small hooks in ForkWsRpc, layer assembly, authorization and MCP.

    Methods: open, edit/create, execute (returns a run id, one active run per notebook), interrupt, restart (with a kernel generation), subscribe (snapshot plus typed deltas), readOutputs, save and listKernels.

    Rules:

    • Saving: a save checks the file's hash under the notebook write lock and writes through a temporary file and rename, so a conflict keeps your draft instead of overwriting.
    • Output limits: 8 MiB and 500 cells. Output beyond that shows a truncation marker, interrupt keeps working, and slow viewers get a fresh snapshot instead of an unbounded queue.
    • Security: localhost only, with no tokens in any result. allow_stdin=false, and widget/comm messages are not rendered.
    • Kernel lifecycle: viewing a notebook doesn't start a kernel. Kernels idle out and are listed for agents.

    Live probe (Jupyter Server on 127.0.0.1:8899, Lithium_Extraction)

    Verified:

    • token auth and kernel creation;
    • streamed stdout and results;
    • display updates and output clearing;
    • errors;
    • interrupt, restart and deletion;
    • project .venv imports through uv's overlay.

    execute_reply and idle arrived in both orders across runs, and the design accounts for that.

    Unverified: the UI, remote and multi-device use, output flooding, and running after a restart.

    PR split (about 9–15 engineering days)

    PR Content Effort
    1 Service, transport and contracts 3–5 days
    2 Persistence and lifecycle 2–3 days
    3 Web and desktop viewer integration 2–4 days
    4 Codex and Claude MCP tools, plus guidance and evals 2–3 days

    The doc also has paste-ready interim guidance for agents on the JupyterLab path. Waiting on the owner's approval before building.

  2. tannerpolley commented on Oct 28, 2026

    @tannerpolley
    OwnerAuthor

    T3 Code status: Unavailable

    Issue: #208 Runnable Jupyter notebooks in T3: run cells from the side-pane notebook viewer, and agent tools to build and run them

    Thread: thread:delegated-task:command%3Amcp%3A88ea76df-ad9e-4a1d-b66f-1a9ef47273be%3Adelegate-task%3A04d33e07-734d-4cea-8f73-375b363ffd79

    Model: gpt-6.1-sol

    Branch: issue-208-runnable-jupyter-notebooks-in-t3-run

    Updated: 2026-11-13T05:08:38.489Z

  3. tannerpolley commented on Oct 29, 2026

    @tannerpolley
    OwnerAuthor

    T3 Code closeout: done

    Issue: #208 Runnable Jupyter notebooks in T3: run cells from the side-pane notebook viewer, and agent tools to build and run them
    Thread: thread:delegated-task:command%3Amcp%3A88ea76df-ad9e-4a1d-b66f-1a9ef47273be%3Adelegate-task%3A04d33e07-734d-4cea-8f73-375b363ffd79
    Model: gpt-6.1-sol
    Branch: issue-208-runnable-jupyter-notebooks-in-t3-run
    Completed: 2026-10-29T22:06:15.083Z

    #208 and all four sub-issues are closed. Each phase passed independent Codex review, merged sequentially into main, and was pushed.

    Issue PR Merge commit Final integration checks
    #210 — service, transport, contracts #218 5cde48b9ff51a075ae2c27f1680723509c9a1a65 Server/contracts typechecks; 63 tests passed
    #211 — save safety and lifecycle #226 8c764e5ca36c4a88ce314d3c4d1e0341fa2dd95b Server/contracts typechecks; 76 tests passed
    #212 — runnable viewer #231 4c8582a2589f0f1a1868798fb318ccb1c607e23a Four affected packages typechecked; 79 tests passed; integrated Browser-panel pass completed
    #213 — MCP tools and guidance #249 615154bbffe3f2565d1cb3303cefa01298987cdd Five affected packages typechecked; 476 tests passed after merging current main

    The #213 pagination correction passed independent reconstruction probes, including Unicode and escaped text. Oversized output records now remain readable through bounded pages without losing data or changing saved notebook contents.

    The overall check:changed gate still reports the established unrelated baseline: three mobile type errors, three unused files, and 74 unused exports. Format, lint, GraphQL, and affected tests passed. Free eval context and dry-run checks passed; paid evaluation was skipped because no API key exists and is not an open gate.

    Cleanup is complete: the stale implementor run is interrupted, #213’s local/remote branches and both worktrees—including -2—are gone. Remote main matches the delivered commit. No migration, dev seeding, T3 installation/restart, or release build was performed.

    The external notebook skill update is applied and reviewed, but remains uncommitted in the shared skills repository, preserving unrelated work. Its focused diff is retained. Execution still requires trusted project configuration; disclosed save-race, crash-recovery, process-local draft, and binary-frame limits remain.

    PR #249, head 615154bbffe3f2565d1cb3303cefa01298987cdd, checks and reviews: independent checker passed; affected checks passed with the baseline exceptions above; merged.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions