agentnb 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.
@@ -0,0 +1,25 @@
1
+ # Bytecode / caches
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+
7
+ # Build / packaging artifacts
8
+ build/
9
+ dist/
10
+ *.egg-info/
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+
16
+ # Test / tooling caches
17
+ .pytest_cache/
18
+ .ruff_cache/
19
+ .mypy_cache/
20
+ .coverage
21
+ coverage.xml
22
+
23
+ # AgentNB runtime state
24
+ .agentnb/
25
+ *.ipynb_checkpoints
agentnb-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Oege Dijk
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.
agentnb-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,178 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentnb
3
+ Version: 0.1.0
4
+ Summary: A persistent Python notebook for AI agents, driven from the CLI
5
+ Project-URL: Homepage, https://github.com/oegedijk/agentnb
6
+ Project-URL: Repository, https://github.com/oegedijk/agentnb
7
+ Project-URL: Issues, https://github.com/oegedijk/agentnb/issues
8
+ Author-email: Oege Dijk <oegedijk@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent,ai,cli,ipython,jupyter,notebook,repl
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Debuggers
21
+ Classifier: Topic :: Software Development :: Testing
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.11
24
+ Requires-Dist: click>=8.1
25
+ Requires-Dist: ipykernel>=6.0
26
+ Requires-Dist: jupyter-client>=8.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pre-commit>=4.0; extra == 'dev'
29
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
30
+ Requires-Dist: pytest-mock>=3.14; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.11; extra == 'dev'
33
+ Requires-Dist: ty>=0.0.1a6; extra == 'dev'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # agentnb
37
+
38
+ A persistent project-scoped Python REPL for coding agents, exposed through a simple CLI.
39
+
40
+ > Status: alpha. Expect rough edges and breaking changes. Use in local
41
+ > development workflows at your own risk.
42
+
43
+ ## Why
44
+
45
+ Agents can run shell commands, but they lose state when using one-off `python -c` and script invocations. `agentnb` gives agents a long-running IPython kernel they can drive with CLI commands, so they can explore incrementally, keep expensive setup in memory, inspect live variables, and recover without restarting from scratch on every step.
46
+
47
+ The right mental model is a persistent REPL for agents, or an append-only notebook without a notebook UI. `agentnb` keeps execution state and history, but it does not edit notebook cells or manage `.ipynb` files.
48
+
49
+ ## Install
50
+
51
+ ```bash
52
+ uv add agentnb
53
+ # or
54
+ pip install agentnb
55
+ ```
56
+
57
+ ## Quick Start
58
+
59
+ ```bash
60
+ agentnb start --project /path/to/project --json
61
+ agentnb exec "from myapp.models import User" --json
62
+ agentnb exec "u = User(name='test'); print(u)" --json
63
+ agentnb vars --json
64
+ agentnb stop --json
65
+ ```
66
+
67
+ ## Recommended Workflow
68
+
69
+ The normal agent loop is:
70
+
71
+ 1. `agentnb start --json`
72
+ 2. `agentnb exec "..." --json`
73
+ 3. `agentnb vars --json`
74
+ 4. `agentnb inspect NAME --json`
75
+ 5. `agentnb reload MODULE --json` after source edits
76
+ 6. `agentnb history --json`
77
+
78
+ Use `agentnb doctor --json` if startup fails, `agentnb interrupt --json` if execution hangs, and `agentnb reset --json` if the namespace needs a clean slate.
79
+
80
+ If startup reports that `ipykernel` is missing, rerun `agentnb start` with
81
+ `--auto-install` or use `agentnb doctor --fix --json`.
82
+
83
+ Running `agentnb` with no arguments, or `agentnb --help`, prints an agent-oriented command guide and workflow summary.
84
+
85
+ ## Positioning
86
+
87
+ `agentnb` is optimized for stateful agent iteration inside a project:
88
+ - a persistent REPL the agent can keep using across steps
89
+ - a lightweight append-only notebook model backed by execution history
90
+ - module reload and variable inspection without a notebook editor
91
+
92
+ It is not a notebook editing tool:
93
+ - it does not edit cells
94
+ - it does not write `.ipynb` files
95
+ - it does not synchronize with JupyterLab
96
+
97
+ ## Commands
98
+
99
+ - `agentnb start [--project PATH] [--python PATH] [--auto-install]`
100
+ - `agentnb status [--project PATH]`
101
+ - `agentnb exec [CODE] [-f FILE] [--timeout SECONDS] [--project PATH] [--json]`
102
+ - `agentnb vars [--project PATH] [--json] [--types]`
103
+ - `agentnb inspect NAME [--project PATH] [--json]`
104
+ - `agentnb reload MODULE [--project PATH] [--json]`
105
+ - `agentnb history [--project PATH] [--errors] [--json]`
106
+ - `agentnb interrupt [--project PATH] [--json]`
107
+ - `agentnb reset [--project PATH] [--json]`
108
+ - `agentnb stop [--project PATH] [--json]`
109
+ - `agentnb doctor [--project PATH] [--python PATH] [--fix] [--json]`
110
+
111
+ ## Out-of-the-box startup
112
+
113
+ On `agentnb start`, the runtime selects an interpreter in this order:
114
+
115
+ 1. `--python` interpreter
116
+ 2. `<project>/.venv` interpreter
117
+ 3. active `VIRTUAL_ENV` interpreter
118
+ 4. current Python executable
119
+
120
+ If `ipykernel` is missing for the selected interpreter, `agentnb start` fails
121
+ with the exact install command. Pass `--auto-install` to let `agentnb` install
122
+ it for you, or use `agentnb doctor --fix --json`.
123
+
124
+ ## JSON Mode
125
+
126
+ Pass `--json` to emit a stable machine-readable envelope. This is the preferred mode for agent integrations.
127
+
128
+ ```json
129
+ {
130
+ "schema_version": "1.0",
131
+ "status": "ok",
132
+ "command": "exec",
133
+ "project": "/path/to/project",
134
+ "session_id": "default",
135
+ "timestamp": "2026-03-08T21:00:00+00:00",
136
+ "data": {
137
+ "status": "ok",
138
+ "stdout": "",
139
+ "stderr": "",
140
+ "result": "42",
141
+ "execution_count": 1,
142
+ "duration_ms": 12
143
+ },
144
+ "suggestions": [
145
+ "Run `agentnb vars --json` to inspect the updated namespace.",
146
+ "Run `agentnb inspect NAME --json` to inspect a specific variable.",
147
+ "Run `agentnb history --json` to review prior executions."
148
+ ],
149
+ "error": null
150
+ }
151
+ ```
152
+
153
+ ## How It Works
154
+
155
+ `agentnb` starts an IPython kernel process and stores connection/session metadata under `.agentnb/` in the target project. CLI commands connect via Jupyter messaging protocol.
156
+
157
+ ## Architecture
158
+
159
+ - `SessionStore`: project/session metadata, stale cleanup, history
160
+ - `KernelRuntime`: lifecycle + execution API
161
+ - `RuntimeBackend`: backend interface, with local IPython backend for v0.1
162
+ - `NotebookOps`: vars/inspect/reload semantic operations
163
+ - `OutputContract`: human + JSON output from one response envelope
164
+ - `Hooks`: no-op extension points for future policy/plugins/telemetry
165
+
166
+ ## Development
167
+
168
+ ```bash
169
+ uv sync --extra dev
170
+ uv run ruff check src tests
171
+ uv run ruff format --check src tests
172
+ uv run ty check src
173
+ uv run pytest
174
+ ```
175
+
176
+ ## License
177
+
178
+ MIT
@@ -0,0 +1,143 @@
1
+ # agentnb
2
+
3
+ A persistent project-scoped Python REPL for coding agents, exposed through a simple CLI.
4
+
5
+ > Status: alpha. Expect rough edges and breaking changes. Use in local
6
+ > development workflows at your own risk.
7
+
8
+ ## Why
9
+
10
+ Agents can run shell commands, but they lose state when using one-off `python -c` and script invocations. `agentnb` gives agents a long-running IPython kernel they can drive with CLI commands, so they can explore incrementally, keep expensive setup in memory, inspect live variables, and recover without restarting from scratch on every step.
11
+
12
+ The right mental model is a persistent REPL for agents, or an append-only notebook without a notebook UI. `agentnb` keeps execution state and history, but it does not edit notebook cells or manage `.ipynb` files.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ uv add agentnb
18
+ # or
19
+ pip install agentnb
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```bash
25
+ agentnb start --project /path/to/project --json
26
+ agentnb exec "from myapp.models import User" --json
27
+ agentnb exec "u = User(name='test'); print(u)" --json
28
+ agentnb vars --json
29
+ agentnb stop --json
30
+ ```
31
+
32
+ ## Recommended Workflow
33
+
34
+ The normal agent loop is:
35
+
36
+ 1. `agentnb start --json`
37
+ 2. `agentnb exec "..." --json`
38
+ 3. `agentnb vars --json`
39
+ 4. `agentnb inspect NAME --json`
40
+ 5. `agentnb reload MODULE --json` after source edits
41
+ 6. `agentnb history --json`
42
+
43
+ Use `agentnb doctor --json` if startup fails, `agentnb interrupt --json` if execution hangs, and `agentnb reset --json` if the namespace needs a clean slate.
44
+
45
+ If startup reports that `ipykernel` is missing, rerun `agentnb start` with
46
+ `--auto-install` or use `agentnb doctor --fix --json`.
47
+
48
+ Running `agentnb` with no arguments, or `agentnb --help`, prints an agent-oriented command guide and workflow summary.
49
+
50
+ ## Positioning
51
+
52
+ `agentnb` is optimized for stateful agent iteration inside a project:
53
+ - a persistent REPL the agent can keep using across steps
54
+ - a lightweight append-only notebook model backed by execution history
55
+ - module reload and variable inspection without a notebook editor
56
+
57
+ It is not a notebook editing tool:
58
+ - it does not edit cells
59
+ - it does not write `.ipynb` files
60
+ - it does not synchronize with JupyterLab
61
+
62
+ ## Commands
63
+
64
+ - `agentnb start [--project PATH] [--python PATH] [--auto-install]`
65
+ - `agentnb status [--project PATH]`
66
+ - `agentnb exec [CODE] [-f FILE] [--timeout SECONDS] [--project PATH] [--json]`
67
+ - `agentnb vars [--project PATH] [--json] [--types]`
68
+ - `agentnb inspect NAME [--project PATH] [--json]`
69
+ - `agentnb reload MODULE [--project PATH] [--json]`
70
+ - `agentnb history [--project PATH] [--errors] [--json]`
71
+ - `agentnb interrupt [--project PATH] [--json]`
72
+ - `agentnb reset [--project PATH] [--json]`
73
+ - `agentnb stop [--project PATH] [--json]`
74
+ - `agentnb doctor [--project PATH] [--python PATH] [--fix] [--json]`
75
+
76
+ ## Out-of-the-box startup
77
+
78
+ On `agentnb start`, the runtime selects an interpreter in this order:
79
+
80
+ 1. `--python` interpreter
81
+ 2. `<project>/.venv` interpreter
82
+ 3. active `VIRTUAL_ENV` interpreter
83
+ 4. current Python executable
84
+
85
+ If `ipykernel` is missing for the selected interpreter, `agentnb start` fails
86
+ with the exact install command. Pass `--auto-install` to let `agentnb` install
87
+ it for you, or use `agentnb doctor --fix --json`.
88
+
89
+ ## JSON Mode
90
+
91
+ Pass `--json` to emit a stable machine-readable envelope. This is the preferred mode for agent integrations.
92
+
93
+ ```json
94
+ {
95
+ "schema_version": "1.0",
96
+ "status": "ok",
97
+ "command": "exec",
98
+ "project": "/path/to/project",
99
+ "session_id": "default",
100
+ "timestamp": "2026-03-08T21:00:00+00:00",
101
+ "data": {
102
+ "status": "ok",
103
+ "stdout": "",
104
+ "stderr": "",
105
+ "result": "42",
106
+ "execution_count": 1,
107
+ "duration_ms": 12
108
+ },
109
+ "suggestions": [
110
+ "Run `agentnb vars --json` to inspect the updated namespace.",
111
+ "Run `agentnb inspect NAME --json` to inspect a specific variable.",
112
+ "Run `agentnb history --json` to review prior executions."
113
+ ],
114
+ "error": null
115
+ }
116
+ ```
117
+
118
+ ## How It Works
119
+
120
+ `agentnb` starts an IPython kernel process and stores connection/session metadata under `.agentnb/` in the target project. CLI commands connect via Jupyter messaging protocol.
121
+
122
+ ## Architecture
123
+
124
+ - `SessionStore`: project/session metadata, stale cleanup, history
125
+ - `KernelRuntime`: lifecycle + execution API
126
+ - `RuntimeBackend`: backend interface, with local IPython backend for v0.1
127
+ - `NotebookOps`: vars/inspect/reload semantic operations
128
+ - `OutputContract`: human + JSON output from one response envelope
129
+ - `Hooks`: no-op extension points for future policy/plugins/telemetry
130
+
131
+ ## Development
132
+
133
+ ```bash
134
+ uv sync --extra dev
135
+ uv run ruff check src tests
136
+ uv run ruff format --check src tests
137
+ uv run ty check src
138
+ uv run pytest
139
+ ```
140
+
141
+ ## License
142
+
143
+ MIT
@@ -0,0 +1,110 @@
1
+ [project]
2
+ name = "agentnb"
3
+ version = "0.1.0"
4
+ description = "A persistent Python notebook for AI agents, driven from the CLI"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ requires-python = ">=3.11"
9
+ authors = [
10
+ { name = "Oege Dijk", email = "oegedijk@gmail.com" },
11
+ ]
12
+ keywords = ["agent", "repl", "notebook", "ipython", "jupyter", "cli", "ai"]
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Environment :: Console",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Topic :: Software Development :: Debuggers",
23
+ "Topic :: Software Development :: Testing",
24
+ "Typing :: Typed",
25
+ ]
26
+
27
+ dependencies = [
28
+ "click>=8.1",
29
+ "ipykernel>=6.0",
30
+ "jupyter-client>=8.0",
31
+ ]
32
+
33
+ [project.optional-dependencies]
34
+ dev = [
35
+ "pre-commit>=4.0",
36
+ "pytest>=8.0",
37
+ "pytest-asyncio>=0.23",
38
+ "pytest-mock>=3.14",
39
+ "ruff>=0.11",
40
+ "ty>=0.0.1a6",
41
+ ]
42
+
43
+ [project.scripts]
44
+ agentnb = "agentnb.cli:main"
45
+
46
+ [project.urls]
47
+ Homepage = "https://github.com/oegedijk/agentnb"
48
+ Repository = "https://github.com/oegedijk/agentnb"
49
+ Issues = "https://github.com/oegedijk/agentnb/issues"
50
+
51
+ [build-system]
52
+ requires = ["hatchling"]
53
+ build-backend = "hatchling.build"
54
+
55
+ [tool.hatch.build]
56
+ ignore-vcs = true
57
+ exclude = [
58
+ ".agentnb",
59
+ ".github",
60
+ ".pytest_cache",
61
+ ".ruff_cache",
62
+ ".venv",
63
+ "dist",
64
+ "tests",
65
+ "ROADMAP.md",
66
+ ".gitignore",
67
+ "**/.gitignore",
68
+ "uv.lock",
69
+ "**/__pycache__",
70
+ "*.py[cod]",
71
+ ]
72
+
73
+ [tool.hatch.build.targets.wheel]
74
+ packages = ["src/agentnb"]
75
+
76
+ [tool.hatch.build.targets.sdist]
77
+ only-include = [
78
+ "src/agentnb",
79
+ "README.md",
80
+ "LICENSE",
81
+ "pyproject.toml",
82
+ ]
83
+ exclude = [
84
+ ".gitignore",
85
+ "**/.gitignore",
86
+ ]
87
+
88
+ [tool.ruff]
89
+ target-version = "py311"
90
+ line-length = 100
91
+ src = ["src", "tests"]
92
+
93
+ [tool.ruff.lint]
94
+ select = [
95
+ "E",
96
+ "W",
97
+ "F",
98
+ "I",
99
+ "UP",
100
+ "B",
101
+ "SIM",
102
+ "RUF",
103
+ ]
104
+
105
+ [tool.ruff.lint.isort]
106
+ known-first-party = ["agentnb"]
107
+
108
+ [tool.pytest.ini_options]
109
+ testpaths = ["tests"]
110
+ asyncio_mode = "auto"
@@ -0,0 +1,84 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ from .contracts import CommandResponse, ExecutionResult, KernelStatus
6
+ from .provisioner import DoctorReport, KernelProvisioner, ProvisionResult
7
+ from .runtime import KernelRuntime
8
+ from .session import DEFAULT_SESSION_ID, resolve_project_root
9
+
10
+ __version__ = "0.1.0"
11
+
12
+ __all__ = [
13
+ "CommandResponse",
14
+ "DoctorReport",
15
+ "ExecutionResult",
16
+ "KernelProvisioner",
17
+ "KernelRuntime",
18
+ "KernelStatus",
19
+ "ProvisionResult",
20
+ "__version__",
21
+ "doctor_environment",
22
+ "execute_code",
23
+ "start_kernel",
24
+ "status_kernel",
25
+ "stop_kernel",
26
+ ]
27
+
28
+
29
+ def start_kernel(
30
+ project: str | Path = ".",
31
+ session_id: str = DEFAULT_SESSION_ID,
32
+ *,
33
+ auto_install: bool = False,
34
+ ) -> tuple[KernelStatus, bool]:
35
+ runtime = KernelRuntime()
36
+ project_root = resolve_project_root(override=Path(project))
37
+ return runtime.start(
38
+ project_root=project_root,
39
+ session_id=session_id,
40
+ auto_install=auto_install,
41
+ )
42
+
43
+
44
+ def status_kernel(project: str | Path = ".", session_id: str = DEFAULT_SESSION_ID) -> KernelStatus:
45
+ runtime = KernelRuntime()
46
+ project_root = resolve_project_root(override=Path(project))
47
+ return runtime.status(project_root=project_root, session_id=session_id)
48
+
49
+
50
+ def execute_code(
51
+ code: str,
52
+ project: str | Path = ".",
53
+ timeout_s: float = 30.0,
54
+ session_id: str = DEFAULT_SESSION_ID,
55
+ ) -> ExecutionResult:
56
+ runtime = KernelRuntime()
57
+ project_root = resolve_project_root(override=Path(project))
58
+ return runtime.execute(
59
+ project_root=project_root, session_id=session_id, code=code, timeout_s=timeout_s
60
+ )
61
+
62
+
63
+ def stop_kernel(project: str | Path = ".", session_id: str = DEFAULT_SESSION_ID) -> None:
64
+ runtime = KernelRuntime()
65
+ project_root = resolve_project_root(override=Path(project))
66
+ runtime.stop(project_root=project_root, session_id=session_id)
67
+
68
+
69
+ def doctor_environment(
70
+ project: str | Path = ".",
71
+ *,
72
+ python_executable: str | Path | None = None,
73
+ auto_fix: bool = False,
74
+ session_id: str = DEFAULT_SESSION_ID,
75
+ ) -> dict[str, object]:
76
+ runtime = KernelRuntime()
77
+ project_root = resolve_project_root(override=Path(project))
78
+ python_path = Path(python_executable) if python_executable is not None else None
79
+ return runtime.doctor(
80
+ project_root=project_root,
81
+ session_id=session_id,
82
+ python_executable=python_path,
83
+ auto_fix=auto_fix,
84
+ )
@@ -0,0 +1,4 @@
1
+ from .cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()