agentleFS
jupyterlabjupyterlab/jupyter-ai/AGENTS.md

jupyter-ai

AGENTS.md4.4k starsChanged 9 days agoBSD-3-ClauseView on GitHub

Guidance for AI agents working in jupyter-ai and its subpackages. As of v3, Jupyter AI is a set of subpackages, each living in its own repo under the jupyter-ai-contrib org. This repo holds the two metapackages that distribute a working set of them, under python/: - jupyter-ai-core (python/jupyter-ai-core/): JupyterLab with the extensions that terminal coding agents need (jupyter-server-mcp, jupyterlab-commands-toolkit, jupyter-live-content), and default settings. - jupyter-ai (python/jupyter-ai/): the agent chat. It depends on jupyter-ai-core and adds the chat subpackages. Both are…

  • Installs packages

Trending

Less talk lately.about the whole repository

Dec 2025: 1 mentionJan 2026: 0 mentionsFeb 2026: 3 mentionsMar 2026: 3 mentionsApr 2026: 2 mentionsMay 2026: 0 mentionsJun 2026: 4 mentionsJul 2026: 5 mentionsAug 2026: 4 mentionsSep 2026: 5 mentionsOct 2026: 4 mentionsNov 2026: 0 mentions
Dec 2025Jun 2026Nov 2026
Mentions a month of the jupyterlab/jupyter-ai repository that our weekly crawl found. There is no adoption data for this file yet.

Who's talking about jupyterlab/jupyter-ai

The biggest 5 of 56 mentions linking to the repository that our crawl found. Each line is their own headline.

See all 56

Talked about on GitHub, Bluesky, Hacker News and Stack Overflow (56 times).

On GitHub · 47

42 more on GitHub

On Bluesky · 6

1 more on Bluesky

On Hacker News · 2

On Stack Overflow · 1

  • Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.

    Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

The file

We split this AGENTS.md into the rules it gives an agent

6 rules. About 0 are common, 1 is distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Add a dependency to the package that needs it: jupyter-ai-core for what a terminal agent uses, jupyter-ai for the chat.

    line 24
  2. Very specific:

    Do not edit the versions by hand.

    line 30
  3. Very specific:

    When you add or change functionality in a subpackage under jupyter-ai-contrib/, put its contributor/developer documentation in that …

    line 46
  4. Very specific:

    When you add a new subpackage dependency that should contribute docs, add it to submodules/manifest.json and run …

    line 87
  5. Distinctive:

    Write the summary for users first, developers second.

    line 137
  6. Very specific:

    Be precise about what's actually new vs. moved: Don't call something "upstreamed" if it never existed before.

    line 161

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

AGENTS.md

Guidance for AI agents working in jupyter-ai and its subpackages.

What Jupyter AI is

As of v3, Jupyter AI is a set of subpackages, each living in its own repo under the jupyter-ai-contrib org. This repo holds the two metapackages that distribute a working set of them, under python/:

  • jupyter-ai-core (python/jupyter-ai-core/): JupyterLab with the extensions that terminal coding agents need (jupyter-server-mcp, jupyterlab-commands-toolkit, jupyter-live-content), and default settings.
  • jupyter-ai (python/jupyter-ai/): the agent chat. It depends on jupyter-ai-core and adds the chat subpackages.

Both are mostly empty; the composition is recorded in their pyproject.toml files, in submodules/manifest.json (a "pypi_name": "org/repo" map), and in the Contributor Guide.

Packages and versions

  • Add a dependency to the package that needs it: jupyter-ai-core for what a terminal agent uses, jupyter-ai for the chat. A dependency of jupyter-ai-core reaches jupyter-ai users too.
  • Both packages share one version and are released together: Jupyter Releaser builds every package listed in python_packages in the root pyproject.toml. jupyter-ai pins jupyter-ai-core to that exact version.
  • Do not edit the versions by hand. scripts/bump_version.py <spec> sets the version of both packages and the pin; Jupyter Releaser runs it during a release. python scripts/bump_version.py --check verifies that they agree, and runs in CI.

Documentation lives with the code

Documentation is split by audience:

  • User docs live solely in this repo, under docs/source/users/.
  • Contributor and developer docs live in each subpackage's own repo. The main Jupyter AI docs site aggregates them into versioned subpages, so everything is readable in one place.

If you are working in a subpackage repo

When you add or change functionality in a subpackage under jupyter-ai-contrib/, put its contributor/developer documentation in that subpackage's own repo, not here. Create either or both of:

docs/source/contributors/index.md   # → surfaces under Contributors on the main site
docs/source/developers/index.md     # → surfaces under Developers on the main site
  • The index.md H1 becomes the subpage title — use the repo name by convention (e.g. # jupyter-ai-tools).
  • The two sections are independent; define one, both, or neither.
  • You may ship a full subtree (nested pages + images); your index.md's {toctree} structures it.
  • These pages flow up to https://jupyter-ai.readthedocs.io automatically once a maintainer bumps the doc submodule pins (see below). You do not edit the jupyter-ai repo to publish subpackage docs.

This is a gradual rollout — most subpackages do not have these docs yet, so adding them is a genuine improvement, not a requirement to match existing repos.

If you are working in this (jupyter-ai) repo

The submodule-docs aggregation infrastructure lives here:

  • submodules/manifest.json — registry of doc submodules.
  • submodules/<repo>/ — git submodules, sparse-checked-out to docs/ only.
  • scripts/update-doc-submodules.sh — re-pins each submodule to the latest tag matching its version range in python/*/pyproject.toml (PEP 440 via packaging). Run by the Update submodule documentation workflow (workflow_dispatch), which opens a PR with the new pins.
  • scripts/rtd-post-checkout.sh — Read the Docs post_checkout hook that sparse-initialises the submodules.
  • docs/source/_ext/subpackage_docs.py — Sphinx extension that copies each submodule's docs/source/{contributors,developers}/ into git-ignored staging dirs and injects them into the aggregation toctrees. Missing docs are silently skipped; the build stays green.
  • docs/tests/ — integration tests (real sphinx-build against synthesized fixtures). The Docs build system CI workflow runs them on any change to the docs build system. Run them locally with pytest docs/tests.

When you add a new subpackage dependency that should contribute docs, add it to submodules/manifest.json and run scripts/update-doc-submodules.sh.

Writing release notes

Each release has a page under docs/source/releases/<version>.md. The title, date, and per-subpackage changelog are auto-generated (wrapped in AUTO-GENERATED markers — don't edit those). Your job as a contributor is the summary in the SUMMARY markers: a human-readable overview that a reader sees before the raw changelog. Edit only between the SUMMARY markers; a re-run of the release-notes workflow regenerates everything else and preserves your summary.

The changelog covers every repo in submodules/manifest.json plus EXTRA_CHANGELOG_REPOS in scripts/generate_release_notes.py. The manifest is the doc-submodule registry, so a dependency whose docs we don't aggregate (jupyterlab_chat, whose developer docs live on its own site) goes in EXTRA_CHANGELOG_REPOS instead — its PRs then reach the release notes without pulling its docs into this site. A dependency whose changelog is missing from a generated page is registered in neither.

Generating the page (Step 0 workflow)

The page is produced by the "Step 0: Prep release documentation" workflow (.github/workflows/prep-release-docs.yml), a manual workflow_dispatch. Run it with the GitHub CLI:

gh workflow run "Step 0: Prep release documentation" \
  --ref main \
  -f version=v3.1.0 \
  -f target-branch=main
  • version — the release being prepped (e.g. v3.1.0).
  • target-branch — the branch the release is cut from; patch releases of an older minor use that minor's maintenance branch (e.g. 3.0.x) instead of main.

The workflow generates the page from the version floors in python/*/pyproject.toml, commits it to a release-docs/<version> branch, and opens a draft PR against the target branch. It is safe to re-run: it reuses the same branch and open PR, merges the target branch in to pick up the latest floors and docs, regenerates the auto sections, and preserves your hand-edited summary. Watch a run with:

gh run watch "$(gh run list --workflow 'Step 0: Prep release documentation' \
  -L1 --json databaseId --jq '.[0].databaseId')" --exit-status

Write the summary for users first, developers second. Use these sections, in order (drop any that don't apply):

  • ## Highlights — the handful of changes users will care about most.
  • ## Major bugs fixed — notable fixes, in plain "what was broken, now works" terms.
  • ## API changes — for extension developers: what they can now build, and the methods they'd implement.
  • Optional :::{note} admonitions for caveats or forward-looking context.
  • The auto-generated per-subpackage changelog follows as the full changelog.

Style, learned from real edits

Lead with what a change does, not how it's built. Implementation details (transport, internal wiring) are noise in a summary.

Before: "Persona session state now flows over a Yjs awareness channel instead of REST, and message routing is driven by per-message metadata rather than @-mentions. The old active-persona REST endpoints are removed."

After: "The APIs powering the new in-chat controls are all built into the Persona API, so any persona can advertise its models, settings, and session usage and reuse the built-in chat UI — no custom REST API required."

Be precise about what's actually new vs. moved. Don't call something "upstreamed" if it never existed before; reserve that for APIs genuinely moved out of a specific package. (E.g. the report_*/update_* methods are new this release; only cancel_response() was moved out of the ACP client into the base Persona API.)

In ## API changes, list the methods a developer implements — real method name, empty-argument-shape signature, one sentence each. Skip methods that are only called for you (plumbing/implementation details).

Before: "BasePersona gains get_* accessors, report_* publishers, and apply_model_spec / apply_settings_spec appliers."

After:

  • report_model_configuration(model) — advertise the current model and its options, populating the model picker.
  • report_usage(usage) — publish context-window, token, and cost usage for the live gauge.
  • update_model(model_id) — switch the persona to the selected model.

(Dropped get_* readers and apply_*_spec — those are read by/called for the persona, not implemented by it.)

Drop parentheticals in Highlights. They read as hedging; fold the detail into the sentence or cut it.

Before: "works with JupyterLab 4.6+ (Jupyter YDoc v4)" · "switch its model, mode, and options (reasoning effort, permissions, and more)"

After: "works with JupyterLab 4.6+" · "switch the active agent's model, permission mode, effort, and other settings"

Use user-facing product language. Name things as a user sees them, not as the code does.

Before: "A new control row lets you pick which persona replies"

After: "A new input toolbar lets you pick which persona replies"

Admonitions use colon-fences, not backtick-fences, so Sphinx renders a note while plain-Markdown previews (GitHub, etc.) show prose instead of a code block:

:::{note}
The permission-requests API remains the only API specific to ACP agents.
:::

Building and testing docs locally

pip install ./python/jupyter-ai-core "./python/jupyter-ai[docs]"
sphinx-build -b html docs/source docs/_build/html
pytest docs/tests          # aggregation integration tests

See the Contributor Guide for the full development setup, the devrepo workflow, and design principles.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.