Files
zeekay 8a4a6bfe6d make build lands every target in dist/
make build builds the workspace, or one target with target=chrome
(firefox, safari, or any packages/<name>). browser writes dist/chrome,
firefox and safari itself; every other package builds in place, where
its package.json points, and dist/<name> links to it. make test runs
every suite, and all of them pass.

The Makefile, README and root src/, scripts/, test/, docs/, examples/,
benchmark/ and tsconfigs belonged to the hanzo-dev CLI this repo used
to be; none of it built or described anything here. CLAUDE.md, AGENTS.md
and GEMINI.md are symlinks to LLM.md and stay out of git.

jupyter ran a jupyter binary nobody installs; it runs under uvx pinned
to jupyterlab 4.5, since 4.6 fetches core metadata from GitHub at build
time. pdf's tests load pdf.js's legacy build, the one made for Node.
vscode's test is its vitest suite; the Electron harness is test:electron.

Claude-Session: https://claude.ai/code/session_01Dc8DXc3fEQCRHUa6XWK4Ku
2026-09-29 11:45:42 -07:00
..

Hanzo AI for JupyterLab

@hanzo/jupyter — an in-notebook AI assistant for JupyterLab 4. AI where data scientists live.

  • Assistant side panel — a model picker, a prompt, and streaming output. It can attach the active cell, the selected cells, or the whole notebook as context.
  • Cell actions (command palette, cell context menu, and cell toolbar):
    • Explain this cell — plain-language walkthrough of a code cell.
    • Fix / debug — reads the cell and its error traceback, inserts a corrected cell below.
    • Add docstring / comments — documents the code in place.
    • Optimize — vectorizes / cleans up without changing behavior.
    • Generate a cell from a prompt — describe what you want, get a new cell.
  • Reads cell outputs (especially tracebacks) for the fix action, and inserts AI-generated code as a new cell below the active one.

Model calls route through the Hanzo AI gateway (api.hanzo.ai, /v1/...) via the published headless client @hanzo/ai — no bespoke HTTP. Your Hanzo sk- key is set in JupyterLab settings, never in source.

Architecture

The JupyterLab widget layer is kept thin; the model-facing logic is pure and unit-tested.

File Responsibility
src/index.ts The JupyterLab plugin — the imperative shell. Registers the panel, the five commands, the cell toolbar button + context menu, tracks the active notebook, and adapts live cells into the pure data shapes.
src/panel.tsx The side-panel ReactWidget (model picker + prompt + streaming output over @hanzo/ai).
src/notebook.ts Pure. Cell / notebook → context text, error-output & traceback extraction, ANSI stripping, truncation, fence stripping.
src/hanzo.ts Thin over @hanzo/ai + the pure action catalog: system frame, per-action prompt builders, request shaping, and the two async model edges (runAction, streamChat).
src/config.ts Settings resolution + command/plugin ids.
schema/plugin.json The settings-registry schema (API key, default model, gateway base URL).

Requirements

  • JupyterLab >= 4.0
  • Node >= 18 and pnpm, the workspace's package manager. The labextension step runs jupyter labextension build, so JupyterLab has to be on PATH.
  • A Hanzo sk- API key (from https://hanzo.ai) for authenticated models; the gateway also serves public/limited models anonymously.

Build

# from the repo root, install workspace deps
pnpm install

cd packages/jupyter

# compile TypeScript → lib/ and build the federated labextension bundle
pnpm build          # dev build
pnpm build:prod     # minified production build

pnpm build runs build:lib (tsc) then build:labextension (jupyter labextension build .), emitting the federated bundle under hanzo_jupyter/labextension.

Install (development)

# from packages/jupyter — installs the Python package and links the source
# extension so a rebuild is picked up on JupyterLab reload
pip install -e .
jupyter labextension develop . --overwrite
pnpm build

jupyter labextension list   # should show @hanzo/jupyter … enabled OK
jupyter lab

For a normal install from a built wheel:

pip install .
jupyter lab

Settings — your Hanzo key

Open Settings → Settings Editor → Hanzo AI (or edit Advanced Settings JSON):

{
  "apiKey": "sk-…",
  "model": "zen5",
  "baseUrl": "https://api.hanzo.ai"
}
  • apiKey — your Hanzo sk- key. Sent as a Bearer token to api.hanzo.ai. Leave blank to use the gateway's public models. Stored by the JupyterLab settings registry, never committed to source.
  • model — the default model id for cell actions and the panel. Any id from /v1/models (the panel's picker lists them live). Defaults to a Zen model.
  • baseUrl — override only for a self-hosted gateway.

Usage

  • Panel — click the Hanzo tab in the right sidebar. Pick a model and a context mode, type a prompt, Send (or ⌘/Ctrl+Enter). Output streams in.
  • Cell actions — right-click a code cell, use the cell toolbar, or the command palette ("Hanzo AI"). Fix/document/optimize/generate insert a new cell below; explain inserts a markdown note.

Test / typecheck

pnpm test        # vitest — pure logic (notebook.ts, hanzo.ts, config.ts)
pnpm typecheck   # tsc --noEmit

The JupyterLab widget APIs are integration-tested by running JupyterLab; the unit tests cover the pure core: context assembly & truncation, traceback extraction, the action-catalog prompt builders, and @hanzo/ai request shaping (with a mocked client).

Publish

  • npm (the source package): npm publish (publishConfig.access is public).

  • PyPI (the prebuilt extension end users pip install):

    pnpm build:prod
    pip install build twine
    python -m build              # sdist + wheel with the bundled labextension
    twine upload dist/*
    

License

MIT