nb-lab-runtime 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. nb_lab_runtime-0.1.0/.github/workflows/openapi.yml +20 -0
  2. nb_lab_runtime-0.1.0/.gitignore +7 -0
  3. nb_lab_runtime-0.1.0/LICENSE +21 -0
  4. nb_lab_runtime-0.1.0/PKG-INFO +276 -0
  5. nb_lab_runtime-0.1.0/README.md +264 -0
  6. nb_lab_runtime-0.1.0/docs/agent-prompting.md +56 -0
  7. nb_lab_runtime-0.1.0/docs/agent-tools.md +99 -0
  8. nb_lab_runtime-0.1.0/docs/demo-transcript.md +35 -0
  9. nb_lab_runtime-0.1.0/docs/mcp-hosting.md +9 -0
  10. nb_lab_runtime-0.1.0/docs/mcp.json +88 -0
  11. nb_lab_runtime-0.1.0/docs/openapi.json +794 -0
  12. nb_lab_runtime-0.1.0/docs/tool-examples.md +35 -0
  13. nb_lab_runtime-0.1.0/examples/demo.py +24 -0
  14. nb_lab_runtime-0.1.0/pyproject.toml +30 -0
  15. nb_lab_runtime-0.1.0/scripts/gen_openapi.sh +15 -0
  16. nb_lab_runtime-0.1.0/scripts/install_tool.sh +8 -0
  17. nb_lab_runtime-0.1.0/scripts/release_check.sh +9 -0
  18. nb_lab_runtime-0.1.0/scripts/smoke_demo.sh +54 -0
  19. nb_lab_runtime-0.1.0/src/nb_lab/__init__.py +28 -0
  20. nb_lab_runtime-0.1.0/src/nb_lab/cell_model.py +299 -0
  21. nb_lab_runtime-0.1.0/src/nb_lab/cli.py +310 -0
  22. nb_lab_runtime-0.1.0/src/nb_lab/executor.py +397 -0
  23. nb_lab_runtime-0.1.0/src/nb_lab/models.py +25 -0
  24. nb_lab_runtime-0.1.0/src/nb_lab/notebook_edit.py +85 -0
  25. nb_lab_runtime-0.1.0/src/nb_lab/notebook_state.py +71 -0
  26. nb_lab_runtime-0.1.0/src/nb_lab/plot_meta.py +162 -0
  27. nb_lab_runtime-0.1.0/src/nb_lab/server.py +279 -0
  28. nb_lab_runtime-0.1.0/src/nb_lab/watcher.py +119 -0
  29. nb_lab_runtime-0.1.0/tests/conftest.py +7 -0
  30. nb_lab_runtime-0.1.0/tests/test_cache.py +17 -0
  31. nb_lab_runtime-0.1.0/tests/test_cell_model.py +70 -0
  32. nb_lab_runtime-0.1.0/tests/test_cli_helpers.py +148 -0
  33. nb_lab_runtime-0.1.0/tests/test_executor.py +29 -0
  34. nb_lab_runtime-0.1.0/tests/test_incremental_run.py +17 -0
  35. nb_lab_runtime-0.1.0/tests/test_notebook_edit.py +25 -0
  36. nb_lab_runtime-0.1.0/tests/test_notebook_state.py +23 -0
  37. nb_lab_runtime-0.1.0/tests/test_plot_meta.py +53 -0
  38. nb_lab_runtime-0.1.0/tests/test_watcher.py +20 -0
  39. nb_lab_runtime-0.1.0/uv.lock +741 -0
@@ -0,0 +1,20 @@
1
+ name: OpenAPI Check
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - main
8
+
9
+ jobs:
10
+ openapi:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: astral-sh/setup-uv@v4
15
+ - name: Install dependencies
16
+ run: uv sync
17
+ - name: Generate OpenAPI schema
18
+ run: bash scripts/gen_openapi.sh
19
+ - name: Check for diffs
20
+ run: git diff --exit-code docs/openapi.json
@@ -0,0 +1,7 @@
1
+ .venv/
2
+ .pytest_cache/
3
+ __pycache__/
4
+ internal/
5
+ .DS_Store
6
+ .python-version
7
+ .nblab/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,276 @@
1
+ Metadata-Version: 2.4
2
+ Name: nb-lab-runtime
3
+ Version: 0.1.0
4
+ Summary: AI-native notebooks from plain Python files.
5
+ License-File: LICENSE
6
+ Requires-Python: >=3.12
7
+ Requires-Dist: fastapi>=0.135.1
8
+ Requires-Dist: matplotlib>=3.10.8
9
+ Requires-Dist: uvicorn>=0.42.0
10
+ Requires-Dist: watchdog>=6.0.0
11
+ Description-Content-Type: text/markdown
12
+
13
+ # nb-lab
14
+
15
+ AI-native notebooks from plain Python files.
16
+
17
+ `nb-lab` turns `.py:percent` scripts (with `# %%` cells) into notebook-style sessions with a simple HTTP API so humans and AI agents can read, edit, and run cells, and understand plots without `.ipynb`.
18
+
19
+ ## Install
20
+ Package name on PyPI is `nb-lab-runtime`; the CLI remains `nb-lab`.
21
+
22
+ Use uv:
23
+ ```bash
24
+ uv add nb-lab-runtime
25
+ ```
26
+
27
+ For local development:
28
+ ```bash
29
+ uv sync
30
+ ```
31
+ This installs the `nb-lab` CLI entry point.
32
+ If you prefer, you can also use `uv run nb-lab ...` without installing globally.
33
+
34
+ ## Recommended (after release): uvx
35
+ Once `nb-lab-runtime` is published, you can run it without cloning:
36
+ ```bash
37
+ uvx --from nb-lab-runtime nb-lab serve /path/to/your-ds-repo/notebook.py
38
+ ```
39
+
40
+ ## Quick start
41
+ Create a `.py` file with `# %%` cells:
42
+ ```python
43
+ # %% [markdown]
44
+ # Simple example
45
+
46
+ # %%
47
+ import matplotlib.pyplot as plt
48
+ import numpy as np
49
+
50
+ x = np.linspace(0, 10, 200)
51
+ y = np.sin(x)
52
+
53
+ # %%
54
+ plt.plot(x, y)
55
+ plt.title("Sine wave")
56
+ plt.show()
57
+ ```
58
+
59
+ Start the server:
60
+ ```bash
61
+ nb-lab serve path/to/script.py
62
+ ```
63
+ If binding fails, use an ephemeral port:
64
+ ```bash
65
+ nb-lab serve path/to/script.py --port 0
66
+ ```
67
+
68
+ ## Troubleshooting (restricted environments)
69
+ If you see cache or permission errors, set writable cache directories:
70
+ ```bash
71
+ export NB_LAB_CACHE_DIR=/tmp/nb-lab-cache
72
+ export MPLCONFIGDIR=/tmp/mpl-cache
73
+ export UV_CACHE_DIR=/tmp/uv-cache
74
+ ```
75
+
76
+ ## Using nb-lab with another repo
77
+ Run nb-lab from this repo but point at a different project:
78
+ ```bash
79
+ cd /path/to/nb-lab
80
+ uv sync
81
+ nb-lab serve /path/to/your-ds-repo/notebook.py
82
+ ```
83
+
84
+ If `nb-lab` is not on your PATH, re-run `uv sync`.
85
+
86
+ ### Recommended for multi-repo use (uv tool install)
87
+ Install nb-lab once and use it across projects:
88
+ ```bash
89
+ uv tool install -e /path/to/nb-lab
90
+ nb-lab serve /path/to/your-ds-repo/notebook.py
91
+ ```
92
+
93
+ This keeps your data science repo’s dependencies separate from nb-lab’s runtime.
94
+
95
+ Helper script:
96
+ ```bash
97
+ bash scripts/install_tool.sh
98
+ ```
99
+
100
+ List cells:
101
+ ```bash
102
+ nb-lab list
103
+ ```
104
+
105
+ Run a cell:
106
+ ```bash
107
+ nb-lab run <CELL_ID> --mode incremental
108
+ ```
109
+
110
+ Show outputs:
111
+ ```bash
112
+ nb-lab show <CELL_ID>
113
+ ```
114
+
115
+ Suppress image payloads:
116
+ ```bash
117
+ nb-lab run <CELL_ID> --no-images
118
+ nb-lab show <CELL_ID> --compact
119
+ ```
120
+
121
+ Check server status:
122
+ ```bash
123
+ nb-lab status
124
+ ```
125
+
126
+ Tip: `--base-version` is optional. If omitted, nb-lab fetches the latest version automatically.
127
+ You can also use `--cell-index N` to refer to the Nth cell in `nb-lab list`.
128
+
129
+ ## Cache commands
130
+ ```bash
131
+ nb-lab cache info
132
+ nb-lab cache list
133
+ nb-lab cache clear --yes
134
+ nb-lab cache clear --all
135
+ nb-lab cache clear --path path/to/notebook.py
136
+ ```
137
+
138
+ ## Smoke demo
139
+ Run an end-to-end demo that starts the server, runs a cell, and fetches outputs:
140
+ ```bash
141
+ uv sync
142
+ bash scripts/smoke_demo.sh
143
+ ```
144
+
145
+ ## Live workflow demo (agent-in-the-loop)
146
+ Here is a concrete end-to-end workflow that shows why nb-lab exists. The agent never touches `.ipynb` and still iterates like a notebook.
147
+
148
+ 1. Start the server on a real `.py:percent` notebook:
149
+ ```bash
150
+ nb-lab serve examples/demo.py
151
+ ```
152
+
153
+ 2. List cells and grab the current version:
154
+ ```bash
155
+ nb-lab list
156
+ ```
157
+
158
+ 3. Pick a target cell and run it (incremental, no full replay):
159
+ ```bash
160
+ nb-lab run --cell-index 1 --mode incremental
161
+ ```
162
+
163
+ 4. Fetch outputs and inspect both text and plot metadata:
164
+ ```bash
165
+ nb-lab show <CELL_ID>
166
+ ```
167
+
168
+ 5. Let the agent edit a cell in the middle and rerun just what’s needed:
169
+ ```bash
170
+ cat <<'PY' | nb-lab edit --cell-index 1 --from-stdin
171
+ <NEW_CODE>
172
+ PY
173
+ ```
174
+
175
+ 6. Re-run the changed cell; nb-lab replays only the dirty prefix:
176
+ ```bash
177
+ nb-lab run --cell-index 1
178
+ ```
179
+
180
+ This is the critical workflow: the agent can read/edit/run cells and reason about plots via `plot_meta` without JSON notebooks or manual state management.
181
+
182
+ ### Mini transcript (agent loop)
183
+ ```
184
+ User: "Check if the sine plot has a mean offset, and annotate it."
185
+
186
+ Agent -> GET /cells
187
+ Agent: Finds plot cell id = c3, base_version = 7
188
+
189
+ Agent -> POST /cells/c3/run
190
+ Agent -> GET /outputs/c3
191
+ Agent: Sees plot_meta.summary_text = "Line plot with 1 series."
192
+
193
+ Agent -> POST /cells/c2/edit
194
+ Agent: Inserts mean calculation and axhline overlay
195
+
196
+ Agent -> POST /cells/c3/run
197
+ Agent: Receives updated plot_meta + image_png
198
+
199
+ User: "Looks good—ship it."
200
+ ```
201
+
202
+ ## Execution semantics
203
+ - The `.py` file is the source of truth. Any edit (API or manual) writes to disk and triggers a reparse.
204
+ - Runs are incremental: when you run a cell, nb-lab replays only the minimal dirty prefix (cells whose source changed) up to the target cell.
205
+ - If nothing is dirty, nb-lab returns the cached output for that cell.
206
+
207
+ This favors iteration speed over strict correctness and mirrors how users actually iterate in notebooks.
208
+
209
+ ## Cell ID storage
210
+ Stable cell IDs are stored in a user cache directory (default `~/.cache/nb-lab`). Set `NB_LAB_CACHE_DIR` to override.
211
+
212
+ ## HTTP API (MVP)
213
+ Base URL: `http://localhost:8787`
214
+
215
+ - `GET /cells`
216
+ Returns `{ "version": int, "cells": [CellSummary...] }`
217
+
218
+ - `GET /status`
219
+ Returns `{ "version": int, "running_cell_id": string | null, "running_since": float | null }`
220
+
221
+ - `GET /cells/{cell_id}`
222
+ Returns full `Cell`.
223
+
224
+ - `POST /cells/{cell_id}/run`
225
+ Body: `{ "mode": "incremental" | "run_above" | "single", "timeout_ms": 60000, "base_version": int }`
226
+ Returns `ExecutionResult`.
227
+
228
+ - `POST /run_up_to/{cell_id}`
229
+ Same body as above. Runs prefix up to `cell_id` based on mode.
230
+
231
+ - `GET /outputs/{cell_id}`
232
+ Returns `{ "cell_id": str, "result": ExecutionResult }`.
233
+
234
+ - `POST /cells/{cell_id}/edit`
235
+ Body: `{ "new_source": "...", "base_version": int }`
236
+ Returns updated `Cell`.
237
+
238
+ - `POST /cells/insert_after`
239
+ Body: `{ "after_id": "cell-id-or-null", "source": "...", "kind": "code" | "markdown", "base_version": int }`
240
+ Returns new `Cell`.
241
+
242
+ - `DELETE /cells/{cell_id}`
243
+ Body: `{ "base_version": int }`
244
+ Returns updated cell list.
245
+
246
+ Concurrency: If `base_version` does not match the current notebook version, the server returns `409`.
247
+
248
+ ## Output payloads
249
+ `ExecutionResult.outputs` is a list of `OutputItem`:
250
+ - `text`: captured stdout
251
+ - `stderr`: captured stderr
252
+ - `repr`: last expression repr
253
+ - `plot_meta`: JSON summary of plot structure and data
254
+ - `image_png`: PNG image encoded as hex
255
+
256
+ Note: `plot_meta.series[].sample` is downsampled (default max 200 points), while `n_points` reports the full series length.
257
+
258
+ ## Agent tooling
259
+ See `docs/agent-tools.md` for function-calling tool definitions and suggested usage patterns.
260
+
261
+ For a copy-pasteable, agent-ready prompt that drives a full analysis run, see `docs/agent-prompting.md`.
262
+ For a human-readable demo flow, see `docs/demo-transcript.md`.
263
+
264
+ ## OpenAPI + MCP
265
+ - OpenAPI schema: `docs/openapi.json`
266
+ - MCP manifest: `docs/mcp.json`
267
+ - Tool examples: `docs/tool-examples.md`
268
+ - MCP hosting note: `docs/mcp-hosting.md`
269
+
270
+ To regenerate the OpenAPI schema:
271
+ ```bash
272
+ bash scripts/gen_openapi.sh
273
+ ```
274
+
275
+ ## Status
276
+ nb-lab is early and experimental. Contributions, issues, and ideas are welcome.
@@ -0,0 +1,264 @@
1
+ # nb-lab
2
+
3
+ AI-native notebooks from plain Python files.
4
+
5
+ `nb-lab` turns `.py:percent` scripts (with `# %%` cells) into notebook-style sessions with a simple HTTP API so humans and AI agents can read, edit, and run cells, and understand plots without `.ipynb`.
6
+
7
+ ## Install
8
+ Package name on PyPI is `nb-lab-runtime`; the CLI remains `nb-lab`.
9
+
10
+ Use uv:
11
+ ```bash
12
+ uv add nb-lab-runtime
13
+ ```
14
+
15
+ For local development:
16
+ ```bash
17
+ uv sync
18
+ ```
19
+ This installs the `nb-lab` CLI entry point.
20
+ If you prefer, you can also use `uv run nb-lab ...` without installing globally.
21
+
22
+ ## Recommended (after release): uvx
23
+ Once `nb-lab-runtime` is published, you can run it without cloning:
24
+ ```bash
25
+ uvx --from nb-lab-runtime nb-lab serve /path/to/your-ds-repo/notebook.py
26
+ ```
27
+
28
+ ## Quick start
29
+ Create a `.py` file with `# %%` cells:
30
+ ```python
31
+ # %% [markdown]
32
+ # Simple example
33
+
34
+ # %%
35
+ import matplotlib.pyplot as plt
36
+ import numpy as np
37
+
38
+ x = np.linspace(0, 10, 200)
39
+ y = np.sin(x)
40
+
41
+ # %%
42
+ plt.plot(x, y)
43
+ plt.title("Sine wave")
44
+ plt.show()
45
+ ```
46
+
47
+ Start the server:
48
+ ```bash
49
+ nb-lab serve path/to/script.py
50
+ ```
51
+ If binding fails, use an ephemeral port:
52
+ ```bash
53
+ nb-lab serve path/to/script.py --port 0
54
+ ```
55
+
56
+ ## Troubleshooting (restricted environments)
57
+ If you see cache or permission errors, set writable cache directories:
58
+ ```bash
59
+ export NB_LAB_CACHE_DIR=/tmp/nb-lab-cache
60
+ export MPLCONFIGDIR=/tmp/mpl-cache
61
+ export UV_CACHE_DIR=/tmp/uv-cache
62
+ ```
63
+
64
+ ## Using nb-lab with another repo
65
+ Run nb-lab from this repo but point at a different project:
66
+ ```bash
67
+ cd /path/to/nb-lab
68
+ uv sync
69
+ nb-lab serve /path/to/your-ds-repo/notebook.py
70
+ ```
71
+
72
+ If `nb-lab` is not on your PATH, re-run `uv sync`.
73
+
74
+ ### Recommended for multi-repo use (uv tool install)
75
+ Install nb-lab once and use it across projects:
76
+ ```bash
77
+ uv tool install -e /path/to/nb-lab
78
+ nb-lab serve /path/to/your-ds-repo/notebook.py
79
+ ```
80
+
81
+ This keeps your data science repo’s dependencies separate from nb-lab’s runtime.
82
+
83
+ Helper script:
84
+ ```bash
85
+ bash scripts/install_tool.sh
86
+ ```
87
+
88
+ List cells:
89
+ ```bash
90
+ nb-lab list
91
+ ```
92
+
93
+ Run a cell:
94
+ ```bash
95
+ nb-lab run <CELL_ID> --mode incremental
96
+ ```
97
+
98
+ Show outputs:
99
+ ```bash
100
+ nb-lab show <CELL_ID>
101
+ ```
102
+
103
+ Suppress image payloads:
104
+ ```bash
105
+ nb-lab run <CELL_ID> --no-images
106
+ nb-lab show <CELL_ID> --compact
107
+ ```
108
+
109
+ Check server status:
110
+ ```bash
111
+ nb-lab status
112
+ ```
113
+
114
+ Tip: `--base-version` is optional. If omitted, nb-lab fetches the latest version automatically.
115
+ You can also use `--cell-index N` to refer to the Nth cell in `nb-lab list`.
116
+
117
+ ## Cache commands
118
+ ```bash
119
+ nb-lab cache info
120
+ nb-lab cache list
121
+ nb-lab cache clear --yes
122
+ nb-lab cache clear --all
123
+ nb-lab cache clear --path path/to/notebook.py
124
+ ```
125
+
126
+ ## Smoke demo
127
+ Run an end-to-end demo that starts the server, runs a cell, and fetches outputs:
128
+ ```bash
129
+ uv sync
130
+ bash scripts/smoke_demo.sh
131
+ ```
132
+
133
+ ## Live workflow demo (agent-in-the-loop)
134
+ Here is a concrete end-to-end workflow that shows why nb-lab exists. The agent never touches `.ipynb` and still iterates like a notebook.
135
+
136
+ 1. Start the server on a real `.py:percent` notebook:
137
+ ```bash
138
+ nb-lab serve examples/demo.py
139
+ ```
140
+
141
+ 2. List cells and grab the current version:
142
+ ```bash
143
+ nb-lab list
144
+ ```
145
+
146
+ 3. Pick a target cell and run it (incremental, no full replay):
147
+ ```bash
148
+ nb-lab run --cell-index 1 --mode incremental
149
+ ```
150
+
151
+ 4. Fetch outputs and inspect both text and plot metadata:
152
+ ```bash
153
+ nb-lab show <CELL_ID>
154
+ ```
155
+
156
+ 5. Let the agent edit a cell in the middle and rerun just what’s needed:
157
+ ```bash
158
+ cat <<'PY' | nb-lab edit --cell-index 1 --from-stdin
159
+ <NEW_CODE>
160
+ PY
161
+ ```
162
+
163
+ 6. Re-run the changed cell; nb-lab replays only the dirty prefix:
164
+ ```bash
165
+ nb-lab run --cell-index 1
166
+ ```
167
+
168
+ This is the critical workflow: the agent can read/edit/run cells and reason about plots via `plot_meta` without JSON notebooks or manual state management.
169
+
170
+ ### Mini transcript (agent loop)
171
+ ```
172
+ User: "Check if the sine plot has a mean offset, and annotate it."
173
+
174
+ Agent -> GET /cells
175
+ Agent: Finds plot cell id = c3, base_version = 7
176
+
177
+ Agent -> POST /cells/c3/run
178
+ Agent -> GET /outputs/c3
179
+ Agent: Sees plot_meta.summary_text = "Line plot with 1 series."
180
+
181
+ Agent -> POST /cells/c2/edit
182
+ Agent: Inserts mean calculation and axhline overlay
183
+
184
+ Agent -> POST /cells/c3/run
185
+ Agent: Receives updated plot_meta + image_png
186
+
187
+ User: "Looks good—ship it."
188
+ ```
189
+
190
+ ## Execution semantics
191
+ - The `.py` file is the source of truth. Any edit (API or manual) writes to disk and triggers a reparse.
192
+ - Runs are incremental: when you run a cell, nb-lab replays only the minimal dirty prefix (cells whose source changed) up to the target cell.
193
+ - If nothing is dirty, nb-lab returns the cached output for that cell.
194
+
195
+ This favors iteration speed over strict correctness and mirrors how users actually iterate in notebooks.
196
+
197
+ ## Cell ID storage
198
+ Stable cell IDs are stored in a user cache directory (default `~/.cache/nb-lab`). Set `NB_LAB_CACHE_DIR` to override.
199
+
200
+ ## HTTP API (MVP)
201
+ Base URL: `http://localhost:8787`
202
+
203
+ - `GET /cells`
204
+ Returns `{ "version": int, "cells": [CellSummary...] }`
205
+
206
+ - `GET /status`
207
+ Returns `{ "version": int, "running_cell_id": string | null, "running_since": float | null }`
208
+
209
+ - `GET /cells/{cell_id}`
210
+ Returns full `Cell`.
211
+
212
+ - `POST /cells/{cell_id}/run`
213
+ Body: `{ "mode": "incremental" | "run_above" | "single", "timeout_ms": 60000, "base_version": int }`
214
+ Returns `ExecutionResult`.
215
+
216
+ - `POST /run_up_to/{cell_id}`
217
+ Same body as above. Runs prefix up to `cell_id` based on mode.
218
+
219
+ - `GET /outputs/{cell_id}`
220
+ Returns `{ "cell_id": str, "result": ExecutionResult }`.
221
+
222
+ - `POST /cells/{cell_id}/edit`
223
+ Body: `{ "new_source": "...", "base_version": int }`
224
+ Returns updated `Cell`.
225
+
226
+ - `POST /cells/insert_after`
227
+ Body: `{ "after_id": "cell-id-or-null", "source": "...", "kind": "code" | "markdown", "base_version": int }`
228
+ Returns new `Cell`.
229
+
230
+ - `DELETE /cells/{cell_id}`
231
+ Body: `{ "base_version": int }`
232
+ Returns updated cell list.
233
+
234
+ Concurrency: If `base_version` does not match the current notebook version, the server returns `409`.
235
+
236
+ ## Output payloads
237
+ `ExecutionResult.outputs` is a list of `OutputItem`:
238
+ - `text`: captured stdout
239
+ - `stderr`: captured stderr
240
+ - `repr`: last expression repr
241
+ - `plot_meta`: JSON summary of plot structure and data
242
+ - `image_png`: PNG image encoded as hex
243
+
244
+ Note: `plot_meta.series[].sample` is downsampled (default max 200 points), while `n_points` reports the full series length.
245
+
246
+ ## Agent tooling
247
+ See `docs/agent-tools.md` for function-calling tool definitions and suggested usage patterns.
248
+
249
+ For a copy-pasteable, agent-ready prompt that drives a full analysis run, see `docs/agent-prompting.md`.
250
+ For a human-readable demo flow, see `docs/demo-transcript.md`.
251
+
252
+ ## OpenAPI + MCP
253
+ - OpenAPI schema: `docs/openapi.json`
254
+ - MCP manifest: `docs/mcp.json`
255
+ - Tool examples: `docs/tool-examples.md`
256
+ - MCP hosting note: `docs/mcp-hosting.md`
257
+
258
+ To regenerate the OpenAPI schema:
259
+ ```bash
260
+ bash scripts/gen_openapi.sh
261
+ ```
262
+
263
+ ## Status
264
+ nb-lab is early and experimental. Contributions, issues, and ideas are welcome.
@@ -0,0 +1,56 @@
1
+ # Prompting an AI Agent to Use nb-lab
2
+
3
+ This doc is the canonical, copy-pasteable instruction set for getting an AI agent to run a real analysis using nb-lab. It is designed to be used as a system or developer prompt in an agent thread.
4
+
5
+ ## 1) Minimal agent prompt (copy/paste)
6
+
7
+ ```
8
+ You are an AI research assistant. You have access to a local nb-lab server that exposes a notebook-style API over HTTP.
9
+
10
+ Rules:
11
+ - The .py file is the source of truth. If you edit code, use the nb-lab edit/insert/delete endpoints.
12
+ - Always start by listing cells and reading the target cell before editing.
13
+ - Prefer incremental runs: run only the cell you need, and rely on nb-lab to replay dirty prefixes.
14
+ - After each run, fetch outputs and summarize text + plot_meta in plain English.
15
+
16
+ Workflow:
17
+ 1. GET /cells to list cells and get base_version.
18
+ 2. For a target cell: GET /cells/{cell_id} to see its source.
19
+ 3. If needed, edit or insert a cell via POST /cells/{cell_id}/edit or /cells/insert_after.
20
+ 4. Run with POST /cells/{cell_id}/run using base_version and mode (incremental by default). Set include_images=false when you only need text/plot_meta.
21
+ 5. Fetch outputs with GET /outputs/{cell_id} and summarize.
22
+
23
+ You must show your work: include the exact API calls you make and the short summaries of outputs.
24
+ ```
25
+
26
+ ## 2) Expanded prompt with tool wrappers
27
+
28
+ If your agent supports tool definitions, you can provide these high-level tools (see `docs/agent-tools.md` for details):
29
+
30
+ ```
31
+ Tools:
32
+ - list_notebook_cells(notebook_path)
33
+ - get_notebook_context(notebook_path, focus_cell_ids)
34
+ - edit_notebook_cell(notebook_path, cell_id, new_source)
35
+ - insert_notebook_cell(notebook_path, after_cell_id, source, kind)
36
+ - run_notebook_cell(notebook_path, cell_id, mode="stateful_from_top")
37
+ - get_plot_meta(notebook_path, cell_id)
38
+ ```
39
+
40
+ ## 3) Example task prompt
41
+
42
+ ```
43
+ Task: Open the notebook, find the cell that makes the plot, compute the mean of the series, overlay it on the plot as a dashed red line, and re-run the plot cell. Summarize the change and the updated plot_meta summary.
44
+ ```
45
+
46
+ ## 4) Agent output expectations
47
+
48
+ A strong agent run should:
49
+ - Show the initial cell list with IDs and a chosen target.
50
+ - Edit/insert the mean computation safely.
51
+ - Re-run the plot cell and retrieve plot_meta.
52
+ - Explain what changed and what the plot_meta summary says.
53
+
54
+ ## 5) Notes for evaluators
55
+ - We value iteration speed over strict correctness in MVP; the agent can re-run a cell without replaying the full notebook if it’s already clean.
56
+ - If a base_version conflict occurs, the agent should re-list cells and retry.