greennode-agentbase 1.0.1__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.
- greennode_agentbase-1.0.1/.github/workflows/publish.yml +272 -0
- greennode_agentbase-1.0.1/.gitignore +3 -0
- greennode_agentbase-1.0.1/PKG-INFO +367 -0
- greennode_agentbase-1.0.1/README.md +333 -0
- greennode_agentbase-1.0.1/pyproject.toml +138 -0
- greennode_agentbase-1.0.1/setup.py +42 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/__init__.py +78 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/cli/__init__.py +6 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/cli/deploy.py +756 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/cli/main.py +84 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/cli/memory.py +681 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/cli/runtime.py +301 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/core/__init__.py +8 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/core/authenticated_client.py +215 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/core/base.py +104 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/core/engine.py +5 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/core/engine.pyx +7 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/core/http_client.py +299 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/core/loader.py +79 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/core/logging.py +237 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/core/method_generator.py +261 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/exceptions.py +155 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/identity/__init__.py +63 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/identity/auth.py +753 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/identity/client.py +198 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/identity/config.py +132 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/identity/credentials.py +130 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/identity/models.py +332 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/memory/__init__.py +44 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/memory/client.py +50 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/memory/models.py +166 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/py.typed +0 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/runtime/__init__.py +18 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/runtime/app.py +1051 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/runtime/client.py +57 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/runtime/config.py +215 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/runtime/context.py +215 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/runtime/models.py +238 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/runtime/utils.py +82 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/specs/__init__.py +2 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/specs/identity/__init__.py +2 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/specs/identity/api.json.gz +0 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/specs/memory/__init__.py +1 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/specs/memory/api.json.gz +0 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/specs/runtime/__init__.py +1 -0
- greennode_agentbase-1.0.1/src/greennode_agentbase/specs/runtime/api.json.gz +0 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
name: Publish Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- dev
|
|
7
|
+
tags:
|
|
8
|
+
- 'v*'
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish-dev:
|
|
13
|
+
name: Publish Dev Version to TestPyPI
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
id-token: write
|
|
17
|
+
contents: read
|
|
18
|
+
if: github.ref == 'refs/heads/dev' && github.event_name == 'push'
|
|
19
|
+
environment:
|
|
20
|
+
name: testpypi
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout code
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Set up Python
|
|
27
|
+
uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: '3.11'
|
|
30
|
+
|
|
31
|
+
- name: Install hatch
|
|
32
|
+
run: pip install hatch
|
|
33
|
+
|
|
34
|
+
- name: Inject Multiple Configs
|
|
35
|
+
env:
|
|
36
|
+
IDENTITY_CONFIG: ${{ secrets.IDENTITY_CONFIG }}
|
|
37
|
+
RUNTIME_CONFIG: ${{ secrets.RUNTIME_CONFIG }}
|
|
38
|
+
MEMORY_CONFIG: ${{ secrets.MEMORY_CONFIG }}
|
|
39
|
+
run: |
|
|
40
|
+
echo -n "$IDENTITY_CONFIG" | base64 --decode > src/greennode_agentbase/specs/identity/api.json.gz
|
|
41
|
+
echo -n "$RUNTIME_CONFIG" | base64 --decode > src/greennode_agentbase/specs/runtime/api.json.gz
|
|
42
|
+
echo -n "$MEMORY_CONFIG" | base64 --decode > src/greennode_agentbase/specs/memory/api.json.gz
|
|
43
|
+
|
|
44
|
+
- name: Verify Files Exist
|
|
45
|
+
run: |
|
|
46
|
+
ls -l src/greennode_agentbase/specs/identity/api.json.gz
|
|
47
|
+
ls -l src/greennode_agentbase/specs/runtime/api.json.gz
|
|
48
|
+
ls -l src/greennode_agentbase/specs/memory/api.json.gz
|
|
49
|
+
|
|
50
|
+
if [ ! -s src/greennode_agentbase/specs/identity/api.json.gz ]; then
|
|
51
|
+
echo "Error: Identity config is empty!"
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
- name: Extract base version from pyproject.toml
|
|
56
|
+
id: get_version
|
|
57
|
+
run: |
|
|
58
|
+
python << PYTHON_SCRIPT
|
|
59
|
+
import os
|
|
60
|
+
import sys
|
|
61
|
+
try:
|
|
62
|
+
import tomllib
|
|
63
|
+
with open('pyproject.toml', 'rb') as f:
|
|
64
|
+
data = tomllib.load(f)
|
|
65
|
+
version = data['project']['version']
|
|
66
|
+
except ImportError:
|
|
67
|
+
import tomli
|
|
68
|
+
with open('pyproject.toml', 'rb') as f:
|
|
69
|
+
data = tomli.load(f)
|
|
70
|
+
version = data['project']['version']
|
|
71
|
+
output_file = os.environ['GITHUB_OUTPUT']
|
|
72
|
+
with open(output_file, 'a') as f:
|
|
73
|
+
f.write(f'base_version={version}\n')
|
|
74
|
+
PYTHON_SCRIPT
|
|
75
|
+
|
|
76
|
+
- name: Generate dev version
|
|
77
|
+
id: dev_version
|
|
78
|
+
run: |
|
|
79
|
+
TIMESTAMP=$(date -u +%Y%m%d%H%M%S)
|
|
80
|
+
DEV_VERSION="${{ steps.get_version.outputs.base_version }}dev-$TIMESTAMP"
|
|
81
|
+
echo "version=$DEV_VERSION" >> $GITHUB_OUTPUT
|
|
82
|
+
echo "Generated dev version: $DEV_VERSION"
|
|
83
|
+
|
|
84
|
+
- name: Update pyproject.toml with dev version
|
|
85
|
+
run: |
|
|
86
|
+
python << EOF
|
|
87
|
+
import re
|
|
88
|
+
with open('pyproject.toml', 'r') as f:
|
|
89
|
+
content = f.read()
|
|
90
|
+
content = re.sub(
|
|
91
|
+
r'^version = ".*"',
|
|
92
|
+
f'version = "${{ steps.dev_version.outputs.version }}"',
|
|
93
|
+
content,
|
|
94
|
+
flags=re.MULTILINE
|
|
95
|
+
)
|
|
96
|
+
with open('pyproject.toml', 'w') as f:
|
|
97
|
+
f.write(content)
|
|
98
|
+
EOF
|
|
99
|
+
|
|
100
|
+
- name: Build package
|
|
101
|
+
run: hatch build
|
|
102
|
+
|
|
103
|
+
- name: Publish to TestPyPI
|
|
104
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
105
|
+
with:
|
|
106
|
+
packages-dir: dist/
|
|
107
|
+
repository-url: https://test.pypi.org/legacy/
|
|
108
|
+
|
|
109
|
+
test-publish:
|
|
110
|
+
name: Verify on TestPyPI
|
|
111
|
+
runs-on: ubuntu-latest
|
|
112
|
+
environment: testpypi
|
|
113
|
+
permissions:
|
|
114
|
+
id-token: write
|
|
115
|
+
contents: read
|
|
116
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
117
|
+
steps:
|
|
118
|
+
- name: Checkout code
|
|
119
|
+
uses: actions/checkout@v4
|
|
120
|
+
|
|
121
|
+
- name: Set up Python
|
|
122
|
+
uses: actions/setup-python@v5
|
|
123
|
+
with:
|
|
124
|
+
python-version: '3.11'
|
|
125
|
+
|
|
126
|
+
- name: Install hatch
|
|
127
|
+
run: pip install hatch
|
|
128
|
+
|
|
129
|
+
- name: Inject Multiple Configs
|
|
130
|
+
env:
|
|
131
|
+
IDENTITY_CONFIG: ${{ secrets.IDENTITY_CONFIG }}
|
|
132
|
+
RUNTIME_CONFIG: ${{ secrets.RUNTIME_CONFIG }}
|
|
133
|
+
MEMORY_CONFIG: ${{ secrets.MEMORY_CONFIG }}
|
|
134
|
+
run: |
|
|
135
|
+
echo -n "$IDENTITY_CONFIG" | base64 --decode > src/greennode_agentbase/specs/identity/api.json.gz
|
|
136
|
+
echo -n "$RUNTIME_CONFIG" | base64 --decode > src/greennode_agentbase/specs/runtime/api.json.gz
|
|
137
|
+
echo -n "$MEMORY_CONFIG" | base64 --decode > src/greennode_agentbase/specs/memory/api.json.gz
|
|
138
|
+
|
|
139
|
+
- name: Verify Files Exist
|
|
140
|
+
run: |
|
|
141
|
+
ls -l src/greennode_agentbase/specs/identity/api.json.gz
|
|
142
|
+
ls -l src/greennode_agentbase/specs/runtime/api.json.gz
|
|
143
|
+
ls -l src/greennode_agentbase/specs/memory/api.json.gz
|
|
144
|
+
|
|
145
|
+
if [ ! -s src/greennode_agentbase/specs/identity/api.json.gz ]; then
|
|
146
|
+
echo "Error: Identity config is empty!"
|
|
147
|
+
exit 1
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
- name: Extract version from tag
|
|
151
|
+
id: get_tag_version
|
|
152
|
+
run: |
|
|
153
|
+
if [[ "${{ github.ref }}" =~ ^refs/tags/v(.+)$ ]]; then
|
|
154
|
+
TAG_VERSION="${BASH_REMATCH[1]}"
|
|
155
|
+
else
|
|
156
|
+
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
|
|
157
|
+
fi
|
|
158
|
+
echo "version=$TAG_VERSION" >> $GITHUB_OUTPUT
|
|
159
|
+
echo "Extracted version from tag: $TAG_VERSION"
|
|
160
|
+
|
|
161
|
+
- name: Update pyproject.toml with tag version
|
|
162
|
+
run: |
|
|
163
|
+
python << EOF
|
|
164
|
+
import re
|
|
165
|
+
with open('pyproject.toml', 'r') as f:
|
|
166
|
+
content = f.read()
|
|
167
|
+
content = re.sub(
|
|
168
|
+
r'^version = ".*"',
|
|
169
|
+
f'version = "${{ steps.get_tag_version.outputs.version }}"',
|
|
170
|
+
content,
|
|
171
|
+
flags=re.MULTILINE
|
|
172
|
+
)
|
|
173
|
+
with open('pyproject.toml', 'w') as f:
|
|
174
|
+
f.write(content)
|
|
175
|
+
EOF
|
|
176
|
+
|
|
177
|
+
- name: Build package
|
|
178
|
+
run: hatch build
|
|
179
|
+
|
|
180
|
+
- name: Verify Package Contents (Crucial)
|
|
181
|
+
run: |
|
|
182
|
+
echo "Checking for json.gz in the built wheel..."
|
|
183
|
+
unzip -l dist/*.whl | grep "json.gz"
|
|
184
|
+
- name: Publish to TestPyPI
|
|
185
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
186
|
+
with:
|
|
187
|
+
repository-url: https://test.pypi.org/legacy/
|
|
188
|
+
|
|
189
|
+
publish-release:
|
|
190
|
+
name: Publish Release to PyPI
|
|
191
|
+
needs: test-publish
|
|
192
|
+
runs-on: ubuntu-latest
|
|
193
|
+
permissions:
|
|
194
|
+
id-token: write
|
|
195
|
+
contents: read
|
|
196
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
197
|
+
environment:
|
|
198
|
+
name: pypi
|
|
199
|
+
|
|
200
|
+
steps:
|
|
201
|
+
- name: Checkout code
|
|
202
|
+
uses: actions/checkout@v4
|
|
203
|
+
|
|
204
|
+
- name: Set up Python
|
|
205
|
+
uses: actions/setup-python@v5
|
|
206
|
+
with:
|
|
207
|
+
python-version: '3.11'
|
|
208
|
+
|
|
209
|
+
- name: Install hatch
|
|
210
|
+
run: pip install hatch
|
|
211
|
+
|
|
212
|
+
- name: Inject Multiple Configs
|
|
213
|
+
env:
|
|
214
|
+
IDENTITY_CONFIG: ${{ secrets.IDENTITY_CONFIG }}
|
|
215
|
+
RUNTIME_CONFIG: ${{ secrets.RUNTIME_CONFIG }}
|
|
216
|
+
MEMORY_CONFIG: ${{ secrets.MEMORY_CONFIG }}
|
|
217
|
+
run: |
|
|
218
|
+
echo -n "$IDENTITY_CONFIG" | base64 --decode > src/greennode_agentbase/specs/identity/api.json.gz
|
|
219
|
+
echo -n "$RUNTIME_CONFIG" | base64 --decode > src/greennode_agentbase/specs/runtime/api.json.gz
|
|
220
|
+
echo -n "$MEMORY_CONFIG" | base64 --decode > src/greennode_agentbase/specs/memory/api.json.gz
|
|
221
|
+
|
|
222
|
+
- name: Verify Files Exist
|
|
223
|
+
run: |
|
|
224
|
+
ls -l src/greennode_agentbase/specs/identity/api.json.gz
|
|
225
|
+
ls -l src/greennode_agentbase/specs/runtime/api.json.gz
|
|
226
|
+
ls -l src/greennode_agentbase/specs/memory/api.json.gz
|
|
227
|
+
|
|
228
|
+
if [ ! -s src/greennode_agentbase/specs/identity/api.json.gz ]; then
|
|
229
|
+
echo "Error: Identity config is empty!"
|
|
230
|
+
exit 1
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
- name: Extract version from tag
|
|
234
|
+
id: get_tag_version
|
|
235
|
+
run: |
|
|
236
|
+
if [[ "${{ github.ref }}" =~ ^refs/tags/v(.+)$ ]]; then
|
|
237
|
+
TAG_VERSION="${BASH_REMATCH[1]}"
|
|
238
|
+
else
|
|
239
|
+
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
|
|
240
|
+
fi
|
|
241
|
+
echo "version=$TAG_VERSION" >> $GITHUB_OUTPUT
|
|
242
|
+
echo "Extracted version from tag: $TAG_VERSION"
|
|
243
|
+
|
|
244
|
+
- name: Update pyproject.toml with tag version
|
|
245
|
+
run: |
|
|
246
|
+
python << EOF
|
|
247
|
+
import re
|
|
248
|
+
with open('pyproject.toml', 'r') as f:
|
|
249
|
+
content = f.read()
|
|
250
|
+
content = re.sub(
|
|
251
|
+
r'^version = ".*"',
|
|
252
|
+
f'version = "${{ steps.get_tag_version.outputs.version }}"',
|
|
253
|
+
content,
|
|
254
|
+
flags=re.MULTILINE
|
|
255
|
+
)
|
|
256
|
+
with open('pyproject.toml', 'w') as f:
|
|
257
|
+
f.write(content)
|
|
258
|
+
EOF
|
|
259
|
+
|
|
260
|
+
- name: Build package
|
|
261
|
+
run: hatch build
|
|
262
|
+
|
|
263
|
+
- name: Verify Package Contents (Crucial)
|
|
264
|
+
run: |
|
|
265
|
+
echo "Checking for json.gz in the built wheel..."
|
|
266
|
+
unzip -l dist/*.whl | grep "json.gz"
|
|
267
|
+
|
|
268
|
+
- name: Publish to PyPI
|
|
269
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
270
|
+
with:
|
|
271
|
+
packages-dir: dist/
|
|
272
|
+
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: greennode-agentbase
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: An SDK for building and deploying AI agents with GreenNode AgentBase
|
|
5
|
+
Project-URL: Homepage, https://git.vngcloud.tech/cloud-ai-platform/greennode-agent-base-sdk
|
|
6
|
+
Project-URL: Bug Tracker, https://git.vngcloud.tech/cloud-ai-platform/greennode-agent-base-sdk/issues
|
|
7
|
+
Project-URL: Documentation, https://git.vngcloud.tech/cloud-ai-platform/greennode-agent-base-sdk
|
|
8
|
+
Author-email: GreenNode <opensource@greennode.ai>
|
|
9
|
+
License: Apache-2.0
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Requires-Python: >=3.7
|
|
25
|
+
Requires-Dist: click>=8.0.0
|
|
26
|
+
Requires-Dist: docker>=6.0.0
|
|
27
|
+
Requires-Dist: httpx>=0.28.1
|
|
28
|
+
Requires-Dist: pydantic<2.41.3,>=2.0.0
|
|
29
|
+
Requires-Dist: rich>=13.0.0
|
|
30
|
+
Requires-Dist: starlette>=0.46.2
|
|
31
|
+
Requires-Dist: typing-extensions<5.0.0,>=4.13.2
|
|
32
|
+
Requires-Dist: uvicorn>=0.34.2
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# GreenNode AgentBase SDK
|
|
36
|
+
|
|
37
|
+
A Python SDK for building and deploying AI agents with GreenNode AgentBase runtime.
|
|
38
|
+
|
|
39
|
+
## Overview
|
|
40
|
+
|
|
41
|
+
GreenNode AgentBase SDK provides a runtime framework for deploying AI agents with support for:
|
|
42
|
+
- HTTP endpoint handling for agent invocations
|
|
43
|
+
- Health status monitoring and ping endpoints
|
|
44
|
+
- Async task tracking
|
|
45
|
+
- Request context management
|
|
46
|
+
- Streaming responses
|
|
47
|
+
- Unified error handling
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install greennode-agentbase
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from greennode_agentbase import GreenNodeAgentBaseApp
|
|
59
|
+
|
|
60
|
+
# Create the application
|
|
61
|
+
app = GreenNodeAgentBaseApp()
|
|
62
|
+
|
|
63
|
+
# Define your agent handler
|
|
64
|
+
@app.entrypoint
|
|
65
|
+
def my_agent(payload: dict):
|
|
66
|
+
"""Your agent logic here."""
|
|
67
|
+
query = payload.get("query", "")
|
|
68
|
+
# Process the query with your agent
|
|
69
|
+
return {"response": f"Processed: {query}"}
|
|
70
|
+
|
|
71
|
+
# Run the server
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
app.run(port=8080)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Usage
|
|
77
|
+
|
|
78
|
+
### Basic Agent Handler
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from greennode_agentbase import GreenNodeAgentBaseApp
|
|
82
|
+
|
|
83
|
+
app = GreenNodeAgentBaseApp()
|
|
84
|
+
|
|
85
|
+
@app.entrypoint
|
|
86
|
+
def simple_agent(payload: dict) -> dict:
|
|
87
|
+
"""Simple agent that echoes the input."""
|
|
88
|
+
return {"echo": payload}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Handler with Request Context
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from greennode_agentbase import GreenNodeAgentBaseApp, RequestContext
|
|
95
|
+
|
|
96
|
+
app = GreenNodeAgentBaseApp()
|
|
97
|
+
|
|
98
|
+
@app.entrypoint
|
|
99
|
+
def contextual_agent(payload: dict, context: RequestContext) -> dict:
|
|
100
|
+
"""Agent that uses request context."""
|
|
101
|
+
session_id = context.session_id
|
|
102
|
+
headers = context.request_headers or {}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
"result": payload,
|
|
106
|
+
"session_id": session_id,
|
|
107
|
+
"authorization": headers.get("Authorization"),
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Async Agent Handler
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
import asyncio
|
|
115
|
+
from greennode_agentbase import GreenNodeAgentBaseApp
|
|
116
|
+
|
|
117
|
+
app = GreenNodeAgentBaseApp()
|
|
118
|
+
|
|
119
|
+
@app.entrypoint
|
|
120
|
+
async def async_agent(payload: dict) -> dict:
|
|
121
|
+
"""Async agent handler."""
|
|
122
|
+
# Simulate async work
|
|
123
|
+
await asyncio.sleep(0.1)
|
|
124
|
+
return {"result": "async processing complete"}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Streaming Responses
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from greennode_agentbase import GreenNodeAgentBaseApp
|
|
131
|
+
|
|
132
|
+
app = GreenNodeAgentBaseApp()
|
|
133
|
+
|
|
134
|
+
@app.entrypoint
|
|
135
|
+
def streaming_agent(payload: dict):
|
|
136
|
+
"""Agent that streams responses."""
|
|
137
|
+
for i in range(5):
|
|
138
|
+
yield {"chunk": i, "data": f"chunk_{i}"}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Custom Ping Handler
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from greennode_agentbase import GreenNodeAgentBaseApp, PingStatus
|
|
145
|
+
|
|
146
|
+
app = GreenNodeAgentBaseApp()
|
|
147
|
+
|
|
148
|
+
@app.ping
|
|
149
|
+
def custom_health_check() -> PingStatus:
|
|
150
|
+
"""Custom health check logic."""
|
|
151
|
+
# Check your system health
|
|
152
|
+
if system_is_busy():
|
|
153
|
+
return PingStatus.HEALTHY_BUSY
|
|
154
|
+
return PingStatus.HEALTHY
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Async Task Tracking
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from greennode_agentbase import GreenNodeAgentBaseApp
|
|
161
|
+
|
|
162
|
+
app = GreenNodeAgentBaseApp()
|
|
163
|
+
|
|
164
|
+
@app.async_task
|
|
165
|
+
async def background_processing():
|
|
166
|
+
"""Long-running background task."""
|
|
167
|
+
# This task will be tracked for health monitoring
|
|
168
|
+
await process_large_dataset()
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Error Handling
|
|
172
|
+
|
|
173
|
+
All SDK errors inherit from `GreenNodeAgentBaseError`:
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from greennode_agentbase import (
|
|
177
|
+
GreenNodeAgentBaseError,
|
|
178
|
+
GreenNodeValidationError,
|
|
179
|
+
GreenNodeRuntimeError,
|
|
180
|
+
GreenNodeRequestError,
|
|
181
|
+
GreenNodeConfigurationError,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
# Your code here
|
|
186
|
+
pass
|
|
187
|
+
except GreenNodeValidationError as e:
|
|
188
|
+
print(f"Validation error: {e.message}")
|
|
189
|
+
print(f"Details: {e.details}")
|
|
190
|
+
except GreenNodeRuntimeError as e:
|
|
191
|
+
print(f"Runtime error: {e.message}")
|
|
192
|
+
except GreenNodeAgentBaseError as e:
|
|
193
|
+
print(f"SDK error: {e.message}")
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Command-line interface (CLI)
|
|
197
|
+
|
|
198
|
+
The `greennode` CLI provides deploy, memory, and runtime management. Use `greennode --help` and `greennode <group> --help` for details.
|
|
199
|
+
|
|
200
|
+
### CLI hierarchy
|
|
201
|
+
|
|
202
|
+
```text
|
|
203
|
+
greennode
|
|
204
|
+
├── deploy
|
|
205
|
+
│ └── run Deploy agent (build, push, create runtime). Use -o id to print only the runtime id.
|
|
206
|
+
├── memory
|
|
207
|
+
│ ├── create Create a memory
|
|
208
|
+
│ ├── list List memories
|
|
209
|
+
│ ├── get Get a memory by ID
|
|
210
|
+
│ └── ... (other memory subcommands)
|
|
211
|
+
└── runtime
|
|
212
|
+
├── list List runtimes
|
|
213
|
+
├── get <id> Get a runtime by ID
|
|
214
|
+
├── patch <id> Update a runtime (image, flavor, env, command, args)
|
|
215
|
+
└── endpoints
|
|
216
|
+
├── list <runtime-id> List endpoints for a runtime
|
|
217
|
+
├── create <runtime-id> Create an endpoint
|
|
218
|
+
├── update <runtime-id> <endpoint-id> Update endpoint (e.g. --version)
|
|
219
|
+
└── delete <runtime-id> <endpoint-id> Delete an endpoint
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Best practices
|
|
223
|
+
|
|
224
|
+
- **Config precedence:** Values are resolved in order: environment variables → `.greennode.json` (for `GREENNODE_CLIENT_ID`, `GREENNODE_CLIENT_SECRET`, `GREENNODE_ACCESS_CONTROL_NAME`, registry vars, etc.). Use `.greennode.json` for non-sensitive defaults and environment variables for secrets.
|
|
225
|
+
- **When to use which:** Use `greennode deploy run` for a full deploy (build, push, create runtime). Use `greennode runtime list`, `get`, `patch` and `greennode runtime endpoints ...` to manage runtimes and endpoints without redeploying.
|
|
226
|
+
- **Scripting:** After `greennode deploy run`, the runtime id is printed on its own line. Use `greennode deploy run -o id` to print only the runtime id for scripts.
|
|
227
|
+
|
|
228
|
+
## API Reference
|
|
229
|
+
|
|
230
|
+
### GreenNodeAgentBaseApp
|
|
231
|
+
|
|
232
|
+
Main application class for deploying agents.
|
|
233
|
+
|
|
234
|
+
#### Methods
|
|
235
|
+
|
|
236
|
+
- `entrypoint(func)` - Decorator to register the main agent handler
|
|
237
|
+
- `ping(func)` - Decorator to register a custom ping/health handler
|
|
238
|
+
- `async_task(func)` - Decorator to track async tasks
|
|
239
|
+
- `run(port=8080, host=None)` - Start the server
|
|
240
|
+
- `get_current_ping_status()` - Get current health status
|
|
241
|
+
- `force_ping_status(status)` - Force a specific ping status
|
|
242
|
+
- `add_async_task(name, metadata=None)` - Manually track an async task
|
|
243
|
+
- `complete_async_task(task_id)` - Mark an async task as complete
|
|
244
|
+
|
|
245
|
+
### RequestContext
|
|
246
|
+
|
|
247
|
+
Request context model containing request metadata.
|
|
248
|
+
|
|
249
|
+
#### Attributes
|
|
250
|
+
|
|
251
|
+
- `session_id` - Optional session identifier
|
|
252
|
+
- `request_headers` - Optional dictionary of request headers
|
|
253
|
+
- `request` - Underlying Starlette request object
|
|
254
|
+
|
|
255
|
+
### GreenNodeAgentBaseContext
|
|
256
|
+
|
|
257
|
+
Context manager for request-scoped data.
|
|
258
|
+
|
|
259
|
+
#### Methods
|
|
260
|
+
|
|
261
|
+
- `set_request_context(request_id, session_id=None)` - Set request context
|
|
262
|
+
- `get_request_id()` - Get current request ID
|
|
263
|
+
- `get_session_id()` - Get current session ID
|
|
264
|
+
- `set_workload_access_token(token)` - Set access token
|
|
265
|
+
- `get_workload_access_token()` - Get access token
|
|
266
|
+
- `set_request_headers(headers)` - Set request headers
|
|
267
|
+
- `get_request_headers()` - Get request headers
|
|
268
|
+
|
|
269
|
+
### PingStatus
|
|
270
|
+
|
|
271
|
+
Enum for health status values:
|
|
272
|
+
|
|
273
|
+
- `HEALTHY` - Agent is healthy and ready
|
|
274
|
+
- `HEALTHY_BUSY` - Agent is healthy but processing requests
|
|
275
|
+
|
|
276
|
+
## HTTP Endpoints
|
|
277
|
+
|
|
278
|
+
### POST /invocations
|
|
279
|
+
|
|
280
|
+
Main endpoint for agent invocations.
|
|
281
|
+
|
|
282
|
+
**Request:**
|
|
283
|
+
```json
|
|
284
|
+
{
|
|
285
|
+
"prompt": "your input here"
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Response:**
|
|
290
|
+
```json
|
|
291
|
+
{
|
|
292
|
+
"result": "agent output"
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### GET /health
|
|
297
|
+
|
|
298
|
+
Health check endpoint.
|
|
299
|
+
|
|
300
|
+
**Response:**
|
|
301
|
+
```json
|
|
302
|
+
{
|
|
303
|
+
"status": "Healthy",
|
|
304
|
+
"time_of_last_update": 1234567890
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Error Handling
|
|
309
|
+
|
|
310
|
+
All errors in the SDK inherit from `GreenNodeAgentBaseError`:
|
|
311
|
+
|
|
312
|
+
- `GreenNodeValidationError` - Input validation errors
|
|
313
|
+
- `GreenNodeRuntimeError` - Runtime execution errors
|
|
314
|
+
- `GreenNodeConfigurationError` - Configuration errors
|
|
315
|
+
- `GreenNodeRequestError` - HTTP request errors
|
|
316
|
+
|
|
317
|
+
All errors include:
|
|
318
|
+
- `message` - Error message
|
|
319
|
+
- `details` - Optional error details dictionary
|
|
320
|
+
- `cause` - Optional underlying exception
|
|
321
|
+
|
|
322
|
+
## Development
|
|
323
|
+
|
|
324
|
+
### Setup
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
# Install development dependencies
|
|
328
|
+
pip install -e ".[dev]"
|
|
329
|
+
|
|
330
|
+
# Run tests
|
|
331
|
+
pytest
|
|
332
|
+
|
|
333
|
+
# Run linting
|
|
334
|
+
ruff check src tests
|
|
335
|
+
|
|
336
|
+
# Run type checking
|
|
337
|
+
mypy src
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Testing
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
# Run all tests
|
|
344
|
+
pytest
|
|
345
|
+
|
|
346
|
+
# Run with coverage
|
|
347
|
+
pytest --cov=src --cov-report=html
|
|
348
|
+
|
|
349
|
+
# Run specific test file
|
|
350
|
+
pytest tests/greennode_agentbase/runtime/test_app.py
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## License
|
|
354
|
+
|
|
355
|
+
Apache License 2.0 - see [LICENSE.txt](LICENSE.txt) for details.
|
|
356
|
+
|
|
357
|
+
## Contributing
|
|
358
|
+
|
|
359
|
+
Contributions are welcome! Please ensure:
|
|
360
|
+
- All tests pass
|
|
361
|
+
- Code follows the style guidelines (ruff, mypy)
|
|
362
|
+
- New features include tests
|
|
363
|
+
- Documentation is updated
|
|
364
|
+
|
|
365
|
+
## Support
|
|
366
|
+
|
|
367
|
+
For issues and questions, please use the project's issue tracker.
|