nodex-ai 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.
- nodex_ai-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +34 -0
- nodex_ai-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +29 -0
- nodex_ai-0.1.0/.github/workflows/pages.yml +37 -0
- nodex_ai-0.1.0/.github/workflows/publish.yml +33 -0
- nodex_ai-0.1.0/.github/workflows/test.yml +34 -0
- nodex_ai-0.1.0/.gitignore +60 -0
- nodex_ai-0.1.0/.pre-commit-config.yaml +7 -0
- nodex_ai-0.1.0/.python-version +2 -0
- nodex_ai-0.1.0/AGENTS.md +28 -0
- nodex_ai-0.1.0/CONTRIBUTING.md +46 -0
- nodex_ai-0.1.0/LICENSE +21 -0
- nodex_ai-0.1.0/Makefile +11 -0
- nodex_ai-0.1.0/PKG-INFO +287 -0
- nodex_ai-0.1.0/README.md +225 -0
- nodex_ai-0.1.0/SECURITY.md +36 -0
- nodex_ai-0.1.0/docs/api_reference.md +140 -0
- nodex_ai-0.1.0/docs/migration_from_langgraph.md +96 -0
- nodex_ai-0.1.0/docs/quickstart.md +85 -0
- nodex_ai-0.1.0/docs/why_nodex.md +65 -0
- nodex_ai-0.1.0/examples/basic_agent/README.md +43 -0
- nodex_ai-0.1.0/examples/basic_agent/agent.py +42 -0
- nodex_ai-0.1.0/examples/human_in_the_loop/README.md +26 -0
- nodex_ai-0.1.0/examples/human_in_the_loop/agent.py +23 -0
- nodex_ai-0.1.0/examples/multi_node_pipeline/README.md +42 -0
- nodex_ai-0.1.0/examples/multi_node_pipeline/agent.py +171 -0
- nodex_ai-0.1.0/package.json +9 -0
- nodex_ai-0.1.0/pyproject.toml +130 -0
- nodex_ai-0.1.0/site/docs/api.html +69 -0
- nodex_ai-0.1.0/site/docs/cli.html +33 -0
- nodex_ai-0.1.0/site/docs/getting-started.html +134 -0
- nodex_ai-0.1.0/site/docs/guide.html +90 -0
- nodex_ai-0.1.0/site/docs/middleware.html +54 -0
- nodex_ai-0.1.0/site/docs/migration.html +58 -0
- nodex_ai-0.1.0/site/index.html +97 -0
- nodex_ai-0.1.0/site/styles.css +766 -0
- nodex_ai-0.1.0/src/nodex/__init__.py +41 -0
- nodex_ai-0.1.0/src/nodex/app.py +99 -0
- nodex_ai-0.1.0/src/nodex/cli/__init__.py +1 -0
- nodex_ai-0.1.0/src/nodex/cli/commands/__init__.py +1 -0
- nodex_ai-0.1.0/src/nodex/cli/commands/dev.py +58 -0
- nodex_ai-0.1.0/src/nodex/cli/commands/new.py +62 -0
- nodex_ai-0.1.0/src/nodex/cli/commands/run.py +51 -0
- nodex_ai-0.1.0/src/nodex/cli/main.py +19 -0
- nodex_ai-0.1.0/src/nodex/cli/templates/.env.example +1 -0
- nodex_ai-0.1.0/src/nodex/cli/templates/agent.py.jinja +4 -0
- nodex_ai-0.1.0/src/nodex/cli/templates/pyproject.toml.jinja +4 -0
- nodex_ai-0.1.0/src/nodex/decorators.py +203 -0
- nodex_ai-0.1.0/src/nodex/display.py +99 -0
- nodex_ai-0.1.0/src/nodex/errors.py +98 -0
- nodex_ai-0.1.0/src/nodex/exceptions.py +67 -0
- nodex_ai-0.1.0/src/nodex/graph.py +48 -0
- nodex_ai-0.1.0/src/nodex/middleware.py +37 -0
- nodex_ai-0.1.0/src/nodex/state.py +78 -0
- nodex_ai-0.1.0/src/nodex/testing/__init__.py +15 -0
- nodex_ai-0.1.0/src/nodex/testing/utils.py +89 -0
- nodex_ai-0.1.0/src/nodex/tracer.py +93 -0
- nodex_ai-0.1.0/src/nodex/types.py +54 -0
- nodex_ai-0.1.0/tests/__init__.py +1 -0
- nodex_ai-0.1.0/tests/conftest.py +67 -0
- nodex_ai-0.1.0/tests/test_app.py +82 -0
- nodex_ai-0.1.0/tests/test_cli.py +66 -0
- nodex_ai-0.1.0/tests/test_decorators.py +116 -0
- nodex_ai-0.1.0/tests/test_errors.py +70 -0
- nodex_ai-0.1.0/tests/test_middleware.py +80 -0
- nodex_ai-0.1.0/tests/test_state.py +79 -0
- nodex_ai-0.1.0/tests/test_testing_utils.py +37 -0
- nodex_ai-0.1.0/tests/test_tracer.py +59 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report something broken or confusing
|
|
4
|
+
title: "bug: "
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What happened?
|
|
10
|
+
|
|
11
|
+
Describe the bug clearly.
|
|
12
|
+
|
|
13
|
+
## Reproduction
|
|
14
|
+
|
|
15
|
+
Steps or a minimal code sample:
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from nodex import Agent
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Expected behavior
|
|
22
|
+
|
|
23
|
+
What did you expect Nodex to do?
|
|
24
|
+
|
|
25
|
+
## Environment
|
|
26
|
+
|
|
27
|
+
- Python version:
|
|
28
|
+
- Nodex version or commit:
|
|
29
|
+
- Operating system:
|
|
30
|
+
- LangGraph version:
|
|
31
|
+
|
|
32
|
+
## Logs or output
|
|
33
|
+
|
|
34
|
+
Paste relevant terminal output here.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest a new capability or improvement
|
|
4
|
+
title: "feature: "
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
What pain point should this solve?
|
|
12
|
+
|
|
13
|
+
## Proposed solution
|
|
14
|
+
|
|
15
|
+
Describe the API or behavior you want.
|
|
16
|
+
|
|
17
|
+
## Example
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from nodex import Agent
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Alternatives considered
|
|
24
|
+
|
|
25
|
+
What other approaches did you think about?
|
|
26
|
+
|
|
27
|
+
## Extra context
|
|
28
|
+
|
|
29
|
+
Add screenshots, links, or related issues if useful.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pages: write
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: pages
|
|
15
|
+
cancel-in-progress: false
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
deploy:
|
|
19
|
+
environment:
|
|
20
|
+
name: github-pages
|
|
21
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- name: Check out repository
|
|
25
|
+
uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Set up Pages
|
|
28
|
+
uses: actions/configure-pages@v5
|
|
29
|
+
|
|
30
|
+
- name: Upload site
|
|
31
|
+
uses: actions/upload-pages-artifact@v3
|
|
32
|
+
with:
|
|
33
|
+
path: site
|
|
34
|
+
|
|
35
|
+
- name: Deploy to GitHub Pages
|
|
36
|
+
id: deployment
|
|
37
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
id-token: write
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Check out repository
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.11"
|
|
23
|
+
|
|
24
|
+
- name: Install build tools
|
|
25
|
+
run: |
|
|
26
|
+
python -m pip install --upgrade pip
|
|
27
|
+
pip install hatch
|
|
28
|
+
|
|
29
|
+
- name: Build package
|
|
30
|
+
run: hatch build
|
|
31
|
+
|
|
32
|
+
- name: Publish to PyPI
|
|
33
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.11", "3.12"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- name: Check out repository
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: ${{ matrix.python-version }}
|
|
24
|
+
|
|
25
|
+
- name: Install package
|
|
26
|
+
run: |
|
|
27
|
+
python -m pip install --upgrade pip
|
|
28
|
+
pip install -e ".[dev]"
|
|
29
|
+
|
|
30
|
+
- name: Lint
|
|
31
|
+
run: ruff check src tests
|
|
32
|
+
|
|
33
|
+
- name: Test
|
|
34
|
+
run: pytest
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
*.egg
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
eggs/
|
|
11
|
+
parts/
|
|
12
|
+
var/
|
|
13
|
+
sdist/
|
|
14
|
+
wheels/
|
|
15
|
+
pip-wheel-metadata/
|
|
16
|
+
share/python-wheels/
|
|
17
|
+
.installed.cfg
|
|
18
|
+
lib/
|
|
19
|
+
lib64/
|
|
20
|
+
MANIFEST
|
|
21
|
+
|
|
22
|
+
# Virtual environments
|
|
23
|
+
.venv/
|
|
24
|
+
venv/
|
|
25
|
+
ENV/
|
|
26
|
+
env/
|
|
27
|
+
|
|
28
|
+
# Environment variables
|
|
29
|
+
.env
|
|
30
|
+
.env.local
|
|
31
|
+
.env.*.local
|
|
32
|
+
|
|
33
|
+
# Testing
|
|
34
|
+
.pytest_cache/
|
|
35
|
+
.coverage
|
|
36
|
+
htmlcov/
|
|
37
|
+
.tox/
|
|
38
|
+
coverage.xml
|
|
39
|
+
*.cover
|
|
40
|
+
|
|
41
|
+
# Type checking
|
|
42
|
+
.mypy_cache/
|
|
43
|
+
.dmypy.json
|
|
44
|
+
dmypy.json
|
|
45
|
+
.pytype/
|
|
46
|
+
|
|
47
|
+
# IDE
|
|
48
|
+
.vscode/
|
|
49
|
+
.idea/
|
|
50
|
+
*.swp
|
|
51
|
+
*.swo
|
|
52
|
+
*~
|
|
53
|
+
|
|
54
|
+
# OS
|
|
55
|
+
.DS_Store
|
|
56
|
+
Thumbs.db
|
|
57
|
+
|
|
58
|
+
# nodex specific
|
|
59
|
+
*.trace
|
|
60
|
+
*.nodex_cache
|
nodex_ai-0.1.0/AGENTS.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Agent Contribution Guide
|
|
2
|
+
|
|
3
|
+
This file is for AI coding agents working on Nodex.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
- Read the relevant source files before editing.
|
|
8
|
+
- Keep `src/nodex` behavior aligned with `README.md`, `docs/`, and `site/`.
|
|
9
|
+
- Use ASCII-safe terminal output unless there is a tested reason not to.
|
|
10
|
+
- Do not introduce provider-specific dependencies into the core package.
|
|
11
|
+
- Add or update tests for behavior changes.
|
|
12
|
+
- Run `ruff check src tests` and `pytest` before handing off.
|
|
13
|
+
|
|
14
|
+
## Important behavior
|
|
15
|
+
|
|
16
|
+
- `Agent.run()` returns an `ExecutionTrace`.
|
|
17
|
+
- Node functions must return a non-empty dictionary.
|
|
18
|
+
- `next="end"` finishes the graph.
|
|
19
|
+
- Middleware wraps node execution in registration order.
|
|
20
|
+
- Route metadata should work in both decorator orders.
|
|
21
|
+
- Testing helpers are public through `nodex.testing`.
|
|
22
|
+
|
|
23
|
+
## Do not
|
|
24
|
+
|
|
25
|
+
- Revert user work without explicit instruction.
|
|
26
|
+
- Replace LangGraph internals with a custom graph engine.
|
|
27
|
+
- Document features that do not exist.
|
|
28
|
+
- Add large framework dependencies to the docs site without asking.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for helping improve Nodex.
|
|
4
|
+
|
|
5
|
+
## Local setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/VamsiKrishna0101/nodex
|
|
9
|
+
cd nodex
|
|
10
|
+
python -m venv .venv
|
|
11
|
+
.venv\Scripts\activate
|
|
12
|
+
pip install -e ".[dev]"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
On macOS or Linux:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
source .venv/bin/activate
|
|
19
|
+
pip install -e ".[dev]"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Checks
|
|
23
|
+
|
|
24
|
+
Run these before opening a pull request:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
ruff check src tests
|
|
28
|
+
pytest
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Development guidelines
|
|
32
|
+
|
|
33
|
+
- Keep the public API small and obvious.
|
|
34
|
+
- Prefer examples that run without extra infrastructure.
|
|
35
|
+
- Do not document behavior that is not covered by tests.
|
|
36
|
+
- Keep terminal output ASCII-safe so Windows users do not hit encoding issues.
|
|
37
|
+
- Add tests for user-facing behavior, especially CLI and graph execution paths.
|
|
38
|
+
|
|
39
|
+
## Pull requests
|
|
40
|
+
|
|
41
|
+
Include:
|
|
42
|
+
|
|
43
|
+
- what changed,
|
|
44
|
+
- why it changed,
|
|
45
|
+
- tests added or updated,
|
|
46
|
+
- and any behavior users should know about.
|
nodex_ai-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vamsi Krishna
|
|
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.
|
nodex_ai-0.1.0/Makefile
ADDED
nodex_ai-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nodex-ai
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The Express.js-style developer experience for LangGraph agents.
|
|
5
|
+
Project-URL: Homepage, https://github.com/VamsiKrishna0101/Nodex
|
|
6
|
+
Project-URL: Documentation, https://vamsikrishna0101.github.io/Nodex/
|
|
7
|
+
Project-URL: Repository, https://github.com/VamsiKrishna0101/Nodex
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/VamsiKrishna0101/Nodex/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/VamsiKrishna0101/Nodex/releases
|
|
10
|
+
Author-email: Vamsi Krishna <vklvl0101@gmail.com>
|
|
11
|
+
License: MIT License
|
|
12
|
+
|
|
13
|
+
Copyright (c) 2026 Vamsi Krishna
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Keywords: agentic-ai,agents,ai,framework,langchain,langgraph,llm,multi-agent,orchestration
|
|
34
|
+
Classifier: Development Status :: 3 - Alpha
|
|
35
|
+
Classifier: Intended Audience :: Developers
|
|
36
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
37
|
+
Classifier: Programming Language :: Python :: 3
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
40
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
41
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
42
|
+
Requires-Python: >=3.11
|
|
43
|
+
Requires-Dist: langchain-core>=0.2.0
|
|
44
|
+
Requires-Dist: langgraph>=0.2.0
|
|
45
|
+
Requires-Dist: pydantic>=2.0.0
|
|
46
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
47
|
+
Requires-Dist: rich>=13.0.0
|
|
48
|
+
Requires-Dist: typer>=0.12.0
|
|
49
|
+
Requires-Dist: watchfiles>=0.21.0
|
|
50
|
+
Provides-Extra: dev
|
|
51
|
+
Requires-Dist: hatch>=1.12.0; extra == 'dev'
|
|
52
|
+
Requires-Dist: mypy>=1.10.0; extra == 'dev'
|
|
53
|
+
Requires-Dist: pre-commit>=3.7.0; extra == 'dev'
|
|
54
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
55
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
|
|
56
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
57
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
58
|
+
Provides-Extra: test
|
|
59
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
|
|
60
|
+
Requires-Dist: pytest>=8.0.0; extra == 'test'
|
|
61
|
+
Description-Content-Type: text/markdown
|
|
62
|
+
|
|
63
|
+
# nodex
|
|
64
|
+
|
|
65
|
+
**The Express.js-style developer experience for LangGraph agents.**
|
|
66
|
+
|
|
67
|
+
[](https://www.python.org/downloads/)
|
|
68
|
+
[](LICENSE)
|
|
69
|
+
[](https://github.com/VamsiKrishna0101/Nodex/actions)
|
|
70
|
+
|
|
71
|
+
Nodex is a thin layer on top of LangGraph that lets you build agents with
|
|
72
|
+
decorators, middleware, retries, fallbacks, tracing, and a small CLI.
|
|
73
|
+
|
|
74
|
+
It does not replace LangGraph. It removes the boilerplate around it.
|
|
75
|
+
|
|
76
|
+
## Why
|
|
77
|
+
|
|
78
|
+
LangGraph is powerful, but even a small agent can require manual state types,
|
|
79
|
+
node registration, edge wiring, retry handling, and debugging through several
|
|
80
|
+
layers of framework internals.
|
|
81
|
+
|
|
82
|
+
Nodex gives that workflow a smaller surface:
|
|
83
|
+
|
|
84
|
+
- Define graph steps with `@app.node`.
|
|
85
|
+
- Add cross-cutting behavior with `@app.middleware`.
|
|
86
|
+
- Route conditionally with `@app.route`.
|
|
87
|
+
- Run the graph with `app.run(...)`.
|
|
88
|
+
- Get a terminal execution trace automatically.
|
|
89
|
+
|
|
90
|
+
## Install
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pip install nodex-ai
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Requires Python 3.11 or newer.
|
|
97
|
+
|
|
98
|
+
## Quickstart
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from nodex import Agent
|
|
102
|
+
|
|
103
|
+
app = Agent(name="hello-agent")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@app.node(next="writer")
|
|
107
|
+
def research(state):
|
|
108
|
+
query = state.get("query", "LangGraph")
|
|
109
|
+
return {"notes": f"Research notes about {query}"}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@app.node(next="end")
|
|
113
|
+
def writer(state):
|
|
114
|
+
return {"final": state.get("notes").upper()}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
app.run({"query": "agent frameworks"})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Output:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
> nodex running - hello-agent
|
|
125
|
+
--------------------------------------------------
|
|
126
|
+
OK research -> 0.002s | tokens: 0 | $0.0000
|
|
127
|
+
OK writer -> 0.001s | tokens: 0 | $0.0000
|
|
128
|
+
--------------------------------------------------
|
|
129
|
+
OK Completed | 0.023s | $0.0000 | 2 nodes | 0 failed | tokens: 0
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## LangGraph vs Nodex
|
|
133
|
+
|
|
134
|
+
LangGraph:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from langgraph.graph import END, START, StateGraph
|
|
138
|
+
|
|
139
|
+
graph = StateGraph(dict)
|
|
140
|
+
graph.add_node("research", research)
|
|
141
|
+
graph.add_node("writer", writer)
|
|
142
|
+
graph.add_edge(START, "research")
|
|
143
|
+
graph.add_edge("research", "writer")
|
|
144
|
+
graph.add_edge("writer", END)
|
|
145
|
+
app = graph.compile()
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Nodex:
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
from nodex import Agent
|
|
152
|
+
|
|
153
|
+
app = Agent()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@app.node(next="writer")
|
|
157
|
+
def research(state):
|
|
158
|
+
return {"notes": "research"}
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@app.node(next="end")
|
|
162
|
+
def writer(state):
|
|
163
|
+
return {"final": state.get("notes")}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
app.run()
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Core API
|
|
170
|
+
|
|
171
|
+
### Agent
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
from nodex import Agent
|
|
175
|
+
|
|
176
|
+
app = Agent(name="research-agent", debug=True)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
`Agent` owns node registration, middleware registration, graph compilation, and
|
|
180
|
+
execution tracing.
|
|
181
|
+
|
|
182
|
+
### Nodes
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
@app.node(next="writer", retry=2, on_fail="fallback_research")
|
|
186
|
+
def research(state):
|
|
187
|
+
return {"research_results": "data"}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Node functions receive a `NodexState` object and must return a non-empty
|
|
191
|
+
dictionary. Internal keys such as `_trace` and `_retry_count` are protected.
|
|
192
|
+
|
|
193
|
+
### Middleware
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
@app.middleware
|
|
197
|
+
def logger(state, next_node):
|
|
198
|
+
print(f"running {state._current_node}")
|
|
199
|
+
return next_node(state)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Middleware runs in registration order and wraps node execution.
|
|
203
|
+
|
|
204
|
+
### Conditional routing
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
@app.node()
|
|
208
|
+
@app.route(
|
|
209
|
+
condition=lambda state: state.get("confidence", 0) > 0.8,
|
|
210
|
+
if_true="publish",
|
|
211
|
+
if_false="review",
|
|
212
|
+
)
|
|
213
|
+
def writer(state):
|
|
214
|
+
return {"draft": "ready"}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Human review
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
@app.node(next="publish", human_review=True)
|
|
221
|
+
def review(state):
|
|
222
|
+
return {"approved_content": state.get("draft")}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
When `human_review=True`, Nodex asks for terminal approval before continuing.
|
|
226
|
+
|
|
227
|
+
## CLI
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
nodex new my-agent
|
|
231
|
+
cd my-agent
|
|
232
|
+
nodex dev agent:app
|
|
233
|
+
nodex run agent:app --input '{"query":"hello"}'
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Testing nodes
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
from nodex.testing import assert_node_output, test_node
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def test_research():
|
|
243
|
+
result = test_node(research, {"query": "AI trends"})
|
|
244
|
+
assert result.success
|
|
245
|
+
assert "research_results" in result.output
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def test_required_keys():
|
|
249
|
+
assert_node_output(research, {"query": "AI trends"}, ["research_results"])
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Local development
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
pip install -e ".[dev]"
|
|
256
|
+
ruff check src tests
|
|
257
|
+
pytest
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Current test suite: 58 tests, with app, graph, CLI, decorators, middleware,
|
|
261
|
+
state, tracer, errors, and testing helpers covered.
|
|
262
|
+
|
|
263
|
+
## Documentation
|
|
264
|
+
|
|
265
|
+
The local docs site lives in `site/` and can be served with:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
npm run dev
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Then open `http://127.0.0.1:4173/`.
|
|
272
|
+
|
|
273
|
+
## Roadmap
|
|
274
|
+
|
|
275
|
+
- Decorator-based node definition
|
|
276
|
+
- Middleware engine
|
|
277
|
+
- Retry and fallback handling
|
|
278
|
+
- Terminal execution tracing
|
|
279
|
+
- CLI scaffold/run/dev commands
|
|
280
|
+
- Testing helpers
|
|
281
|
+
- Multi-page docs site
|
|
282
|
+
- Provider-specific examples
|
|
283
|
+
- Dashboard or trace viewer
|
|
284
|
+
|
|
285
|
+
## License
|
|
286
|
+
|
|
287
|
+
MIT. See [LICENSE](LICENSE).
|