agentpm 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.
- agentpm-0.1.0/.gitignore +15 -0
- agentpm-0.1.0/LICENSE +21 -0
- agentpm-0.1.0/PKG-INFO +336 -0
- agentpm-0.1.0/README.md +282 -0
- agentpm-0.1.0/pyproject.toml +92 -0
- agentpm-0.1.0/src/agentpm/__init__.py +30 -0
- agentpm-0.1.0/src/agentpm/adapters/__init__.py +0 -0
- agentpm-0.1.0/src/agentpm/adapters/langchain.py +157 -0
- agentpm-0.1.0/src/agentpm/core.py +600 -0
- agentpm-0.1.0/src/agentpm/py.typed +0 -0
- agentpm-0.1.0/src/agentpm/types.py +41 -0
agentpm-0.1.0/.gitignore
ADDED
agentpm-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Zack Hine
|
|
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
|
|
13
|
+
all 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
|
|
21
|
+
THE SOFTWARE.
|
agentpm-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentpm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AgentPM Python SDK
|
|
5
|
+
Project-URL: Homepage, https://github.com/agentpm-dev/sdk-python
|
|
6
|
+
Project-URL: Repository, https://github.com/agentpm-dev/sdk-python
|
|
7
|
+
Project-URL: Issues, https://github.com/agentpm-dev/sdk-python/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/agentpm-dev/sdk-python/releases
|
|
9
|
+
Author-email: AgentPM <dev@agentpm.dev>
|
|
10
|
+
License: MIT License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2025 Zack Hine
|
|
13
|
+
|
|
14
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
|
+
of this software and associated documentation files (the “Software”), to deal
|
|
16
|
+
in the Software without restriction, including without limitation the rights
|
|
17
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
19
|
+
furnished to do so, subject to the following conditions:
|
|
20
|
+
|
|
21
|
+
The above copyright notice and this permission notice shall be included in
|
|
22
|
+
all copies or substantial portions of the Software.
|
|
23
|
+
|
|
24
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
27
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
28
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
29
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
30
|
+
THE SOFTWARE.
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Keywords: agentpm,agents,ai,tools
|
|
33
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
34
|
+
Classifier: Programming Language :: Python :: 3
|
|
35
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
39
|
+
Classifier: Typing :: Typed
|
|
40
|
+
Requires-Python: >=3.10
|
|
41
|
+
Requires-Dist: semver>=3.0.0
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: black>=24.8.0; extra == 'dev'
|
|
44
|
+
Requires-Dist: build>=1.2.1; extra == 'dev'
|
|
45
|
+
Requires-Dist: mypy>=1.11.0; extra == 'dev'
|
|
46
|
+
Requires-Dist: pre-commit>=3.8.0; extra == 'dev'
|
|
47
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
|
|
48
|
+
Requires-Dist: pytest>=8.3.0; extra == 'dev'
|
|
49
|
+
Requires-Dist: ruff>=0.6.8; extra == 'dev'
|
|
50
|
+
Requires-Dist: twine>=5.1.1; extra == 'dev'
|
|
51
|
+
Provides-Extra: langchain
|
|
52
|
+
Requires-Dist: langchain-core>=0.2.0; extra == 'langchain'
|
|
53
|
+
Description-Content-Type: text/markdown
|
|
54
|
+
|
|
55
|
+
# AgentPM Python SDK
|
|
56
|
+
|
|
57
|
+
A lean, typed Python SDK for **AgentPM** tools. It discovers tools installed by `agentpm install`, executes their entrypoints in a subprocess, and returns JSON results you can pass to your agents.
|
|
58
|
+
|
|
59
|
+
- 🔎 **Discovers** tools in `.agentpm/tools` (project) and `~/.agentpm/tools` (user), with `AGENTPM_TOOL_DIR` override.
|
|
60
|
+
- 🚀 **Runs entrypoints** via `node` or `python` (whitelisted) and exchanges JSON over stdin/stdout.
|
|
61
|
+
- 🧩 **Metadata-aware**: `with_meta=True` returns `func + meta` (name, version, description, inputs, outputs).
|
|
62
|
+
- 🧪 **Framework adapters (optional)**: e.g., a LangChain adapter you can use if installed.
|
|
63
|
+
|
|
64
|
+
> Requires Python **3.10+**.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Installation
|
|
69
|
+
|
|
70
|
+
### From PyPI (recommended)
|
|
71
|
+
|
|
72
|
+
Using **uv**:
|
|
73
|
+
```bash
|
|
74
|
+
uv pip install agentpm
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Or with standard pip:
|
|
78
|
+
```bash
|
|
79
|
+
python -m pip install agentpm
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If you'll use the optional LangChain adapter:
|
|
83
|
+
```bash
|
|
84
|
+
uv pip install 'agentpm[langchain]'
|
|
85
|
+
# or
|
|
86
|
+
python -m pip install 'agentpm[langchain]'
|
|
87
|
+
```
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Quick Start (with `uv`)
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# create and activate a venv
|
|
94
|
+
uv venv
|
|
95
|
+
source .venv/bin/activate
|
|
96
|
+
|
|
97
|
+
# install SDK in editable dev mode (ruff/black/mypy/pytest, etc.)
|
|
98
|
+
uv pip install -e ".[dev]"
|
|
99
|
+
|
|
100
|
+
# sanity checks
|
|
101
|
+
uv run ruff check .
|
|
102
|
+
uv run black --check .
|
|
103
|
+
uv run mypy
|
|
104
|
+
uv run pytest -q
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
> If you're not using `uv`, standard `python -m venv` + `pip install -e ".[dev]"` works too.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Using the SDK
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from agentpm import load
|
|
115
|
+
|
|
116
|
+
# Spec format: "@scope/name@version"
|
|
117
|
+
summarize = load("@zack/summarize@0.1.0")
|
|
118
|
+
|
|
119
|
+
result = summarize({"text": "Long document content..."})
|
|
120
|
+
print(result["summary"])
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### With metadata (build richer tool descriptions)
|
|
124
|
+
```python
|
|
125
|
+
from agentpm import load
|
|
126
|
+
|
|
127
|
+
tool = load("@zack/summarize@0.1.0", with_meta=True)
|
|
128
|
+
summarize, meta = tool["func"], tool["meta"]
|
|
129
|
+
|
|
130
|
+
rich_description = (
|
|
131
|
+
f"{meta.get('description','')} "
|
|
132
|
+
f"Inputs: {meta.get('inputs')}. "
|
|
133
|
+
f"Outputs: {meta.get('outputs')}."
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
print(rich_description)
|
|
137
|
+
print(summarize({"text": "hello"})["summary"])
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Optional: LangChain adapter
|
|
141
|
+
The adapter is lazy-imported and only needed if you call it.
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from agentpm import load, to_langchain_tool # to_langchain_tool is loaded on first access
|
|
145
|
+
|
|
146
|
+
loaded = load("@zack/summarize@0.1.0", with_meta=True)
|
|
147
|
+
tool = to_langchain_tool(loaded) # requires `langchain-core` installed
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
If you use the adapter, install LangChain core:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
uv pip install langchain-core
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Where tools are discovered
|
|
159
|
+
|
|
160
|
+
Resolution order:
|
|
161
|
+
|
|
162
|
+
1. `AGENTPM_TOOL_DIR` (environment variable)
|
|
163
|
+
2. `./.agentpm/tools` (project-local)
|
|
164
|
+
3. `~/.agentpm/tools` (user-local)
|
|
165
|
+
|
|
166
|
+
Each tool lives in a directory like:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
.agentpm/
|
|
170
|
+
tools/
|
|
171
|
+
@zack/summarize/
|
|
172
|
+
0.1.0/
|
|
173
|
+
agent.json
|
|
174
|
+
(tool files…)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Manifest & Runtime Contract
|
|
180
|
+
|
|
181
|
+
**`agent.json` (minimal fields used by the SDK):**
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"name": "@zack/summarize",
|
|
185
|
+
"version": "0.1.0",
|
|
186
|
+
"description": "Summarize long text.",
|
|
187
|
+
"inputs": {
|
|
188
|
+
"type": "object",
|
|
189
|
+
"properties": { "text": { "type": "string", "description": "Text to summarize" } },
|
|
190
|
+
"required": ["text"]
|
|
191
|
+
},
|
|
192
|
+
"outputs": {
|
|
193
|
+
"type": "object",
|
|
194
|
+
"properties": { "summary": { "type": "string", "description": "Summarized text" } },
|
|
195
|
+
"required": ["summary"]
|
|
196
|
+
},
|
|
197
|
+
"entrypoint": {
|
|
198
|
+
"command": "python",
|
|
199
|
+
"args": ["main.py"],
|
|
200
|
+
"cwd": ".",
|
|
201
|
+
"timeout_ms": 60000,
|
|
202
|
+
"env": {}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**Execution contract:**
|
|
208
|
+
- SDK writes **inputs JSON** to the process **stdin**.
|
|
209
|
+
- Tool writes a single **outputs JSON** object to **stdout**.
|
|
210
|
+
- Non-JSON logs should go to **stderr**.
|
|
211
|
+
- Process must exit with **code 0** on success.
|
|
212
|
+
|
|
213
|
+
**Interpreter whitelist:** `node`, `nodejs`, `python`, `python3`.
|
|
214
|
+
The SDK validates the interpreter and checks it’s present on `PATH`.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Development
|
|
219
|
+
|
|
220
|
+
### Project layout
|
|
221
|
+
```
|
|
222
|
+
src/
|
|
223
|
+
agentpm/
|
|
224
|
+
__init__.py # re-exports: load, to_langchain_tool (lazy)
|
|
225
|
+
core.py # resolver/spawn/JSON plumbing
|
|
226
|
+
types.py # JsonValue, TypedDicts
|
|
227
|
+
adapters/
|
|
228
|
+
__init__.py
|
|
229
|
+
langchain.py # optional adapter
|
|
230
|
+
py.typed # marks package as typed
|
|
231
|
+
tests/
|
|
232
|
+
test_basic.py
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Common tasks (via `uv`)
|
|
236
|
+
```bash
|
|
237
|
+
uv run ruff check .
|
|
238
|
+
uv run black --check .
|
|
239
|
+
uv run mypy
|
|
240
|
+
uv run pytest -q
|
|
241
|
+
|
|
242
|
+
# run hooks locally on all files
|
|
243
|
+
uv run pre-commit run --all-files
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Building & Publishing
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
# build wheel & sdist
|
|
252
|
+
uv run python -m build
|
|
253
|
+
|
|
254
|
+
# verify metadata
|
|
255
|
+
uv run twine check dist/*
|
|
256
|
+
|
|
257
|
+
# upload (PyPI)
|
|
258
|
+
uv run twine upload dist/*
|
|
259
|
+
|
|
260
|
+
# or TestPyPI first
|
|
261
|
+
uv run twine upload -r testpypi dist/*
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Running mixed-runtime Agent apps with Docker
|
|
267
|
+
|
|
268
|
+
Some AgentPM tools run on Node, some on Python—and your agent may need to spawn both. Using Docker gives you a single, reproducible environment where both interpreters are installed and on PATH, which avoids the common “interpreter not found” issues that pop up on PaaS/CI or IDEs.
|
|
269
|
+
|
|
270
|
+
Why Docker?
|
|
271
|
+
|
|
272
|
+
✅ Hermetic: Python + Node versions are pinned inside the image.
|
|
273
|
+
|
|
274
|
+
✅ No PATH drama: node/python are present and discoverable.
|
|
275
|
+
|
|
276
|
+
✅ Prod/CI parity: the same image runs on your laptop, CI, and servers.
|
|
277
|
+
|
|
278
|
+
✅ Easy secrets: pass API keys via env at docker run/Compose time.
|
|
279
|
+
|
|
280
|
+
✅ Fewer surprises: consistent OS libs for LLM clients, SSL, etc.
|
|
281
|
+
|
|
282
|
+
### When to use it
|
|
283
|
+
|
|
284
|
+
- You deploy to platforms that don’t let you apt-get both runtimes.
|
|
285
|
+
- Your agent uses tools with different interpreters (Node + Python).
|
|
286
|
+
- Your local dev/IDE PATH differs from production and causes failures.
|
|
287
|
+
- You want reproducible builds and easy rollback.
|
|
288
|
+
|
|
289
|
+
### How to use it
|
|
290
|
+
|
|
291
|
+
1. Copy the provided [Dockerfile](https://github.com/agentpm-dev/sdk-python/tree/main/examples/python-agent) into your repo.
|
|
292
|
+
2. (Optional) Pre-install tools locally with agentpm install ... and commit or copy .agentpm/tools/ into the image, or run agentpm install at build time if your CLI is available in the image.
|
|
293
|
+
3. Build & run:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
docker build -t agent-app .
|
|
297
|
+
docker run --rm -e OPENAI_API_KEY=$OPENAI_API_KEY agent-app
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
4. For development, use the docker-compose.yml snippet to mount your source and pass env vars conveniently.
|
|
301
|
+
|
|
302
|
+
### Troubleshooting
|
|
303
|
+
|
|
304
|
+
- Set `AGENTPM_DEBUG=1` to print the SDK’s project root, search paths, merged PATH, and resolved interpreters.
|
|
305
|
+
- You can force interpreters via:
|
|
306
|
+
```ini
|
|
307
|
+
AGENTPM_NODE=/usr/bin/node
|
|
308
|
+
AGENTPM_PYTHON=/usr/local/bin/python3.11
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
- Prefer absolute interpreters in agent.json.entrypoint.command for production (e.g., /usr/bin/node). The SDKs still enforce the Node/Python family.
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Troubleshooting
|
|
316
|
+
|
|
317
|
+
- **`No JSON object found on stdout.`**
|
|
318
|
+
Ensure your tool prints a single JSON object as the last thing on stdout, and writes logs to stderr.
|
|
319
|
+
|
|
320
|
+
- **`Unsupported agent.json.entrypoint.command`**
|
|
321
|
+
Only `node` / `python` are allowed (including `nodejs` / `python3`). Update `entrypoint.command`.
|
|
322
|
+
|
|
323
|
+
- **`Interpreter "... " not found on PATH`**
|
|
324
|
+
Install the interpreter or adjust `entrypoint.command`. The SDK runs `<command> --version` to verify availability.
|
|
325
|
+
|
|
326
|
+
- **PEP 668 / “externally managed”**
|
|
327
|
+
Use a venv (we recommend `uv venv`) and install with `uv pip install -e ".[dev]"`.
|
|
328
|
+
|
|
329
|
+
- **IDE can’t import `agentpm`**
|
|
330
|
+
Ensure your interpreter is the project’s `.venv/bin/python`, and that you ran the editable install.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## License
|
|
335
|
+
|
|
336
|
+
MIT — see `LICENSE`.
|
agentpm-0.1.0/README.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# AgentPM Python SDK
|
|
2
|
+
|
|
3
|
+
A lean, typed Python SDK for **AgentPM** tools. It discovers tools installed by `agentpm install`, executes their entrypoints in a subprocess, and returns JSON results you can pass to your agents.
|
|
4
|
+
|
|
5
|
+
- 🔎 **Discovers** tools in `.agentpm/tools` (project) and `~/.agentpm/tools` (user), with `AGENTPM_TOOL_DIR` override.
|
|
6
|
+
- 🚀 **Runs entrypoints** via `node` or `python` (whitelisted) and exchanges JSON over stdin/stdout.
|
|
7
|
+
- 🧩 **Metadata-aware**: `with_meta=True` returns `func + meta` (name, version, description, inputs, outputs).
|
|
8
|
+
- 🧪 **Framework adapters (optional)**: e.g., a LangChain adapter you can use if installed.
|
|
9
|
+
|
|
10
|
+
> Requires Python **3.10+**.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### From PyPI (recommended)
|
|
17
|
+
|
|
18
|
+
Using **uv**:
|
|
19
|
+
```bash
|
|
20
|
+
uv pip install agentpm
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or with standard pip:
|
|
24
|
+
```bash
|
|
25
|
+
python -m pip install agentpm
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
If you'll use the optional LangChain adapter:
|
|
29
|
+
```bash
|
|
30
|
+
uv pip install 'agentpm[langchain]'
|
|
31
|
+
# or
|
|
32
|
+
python -m pip install 'agentpm[langchain]'
|
|
33
|
+
```
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Quick Start (with `uv`)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# create and activate a venv
|
|
40
|
+
uv venv
|
|
41
|
+
source .venv/bin/activate
|
|
42
|
+
|
|
43
|
+
# install SDK in editable dev mode (ruff/black/mypy/pytest, etc.)
|
|
44
|
+
uv pip install -e ".[dev]"
|
|
45
|
+
|
|
46
|
+
# sanity checks
|
|
47
|
+
uv run ruff check .
|
|
48
|
+
uv run black --check .
|
|
49
|
+
uv run mypy
|
|
50
|
+
uv run pytest -q
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
> If you're not using `uv`, standard `python -m venv` + `pip install -e ".[dev]"` works too.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Using the SDK
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from agentpm import load
|
|
61
|
+
|
|
62
|
+
# Spec format: "@scope/name@version"
|
|
63
|
+
summarize = load("@zack/summarize@0.1.0")
|
|
64
|
+
|
|
65
|
+
result = summarize({"text": "Long document content..."})
|
|
66
|
+
print(result["summary"])
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### With metadata (build richer tool descriptions)
|
|
70
|
+
```python
|
|
71
|
+
from agentpm import load
|
|
72
|
+
|
|
73
|
+
tool = load("@zack/summarize@0.1.0", with_meta=True)
|
|
74
|
+
summarize, meta = tool["func"], tool["meta"]
|
|
75
|
+
|
|
76
|
+
rich_description = (
|
|
77
|
+
f"{meta.get('description','')} "
|
|
78
|
+
f"Inputs: {meta.get('inputs')}. "
|
|
79
|
+
f"Outputs: {meta.get('outputs')}."
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
print(rich_description)
|
|
83
|
+
print(summarize({"text": "hello"})["summary"])
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Optional: LangChain adapter
|
|
87
|
+
The adapter is lazy-imported and only needed if you call it.
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from agentpm import load, to_langchain_tool # to_langchain_tool is loaded on first access
|
|
91
|
+
|
|
92
|
+
loaded = load("@zack/summarize@0.1.0", with_meta=True)
|
|
93
|
+
tool = to_langchain_tool(loaded) # requires `langchain-core` installed
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
If you use the adapter, install LangChain core:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uv pip install langchain-core
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Where tools are discovered
|
|
105
|
+
|
|
106
|
+
Resolution order:
|
|
107
|
+
|
|
108
|
+
1. `AGENTPM_TOOL_DIR` (environment variable)
|
|
109
|
+
2. `./.agentpm/tools` (project-local)
|
|
110
|
+
3. `~/.agentpm/tools` (user-local)
|
|
111
|
+
|
|
112
|
+
Each tool lives in a directory like:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
.agentpm/
|
|
116
|
+
tools/
|
|
117
|
+
@zack/summarize/
|
|
118
|
+
0.1.0/
|
|
119
|
+
agent.json
|
|
120
|
+
(tool files…)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Manifest & Runtime Contract
|
|
126
|
+
|
|
127
|
+
**`agent.json` (minimal fields used by the SDK):**
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"name": "@zack/summarize",
|
|
131
|
+
"version": "0.1.0",
|
|
132
|
+
"description": "Summarize long text.",
|
|
133
|
+
"inputs": {
|
|
134
|
+
"type": "object",
|
|
135
|
+
"properties": { "text": { "type": "string", "description": "Text to summarize" } },
|
|
136
|
+
"required": ["text"]
|
|
137
|
+
},
|
|
138
|
+
"outputs": {
|
|
139
|
+
"type": "object",
|
|
140
|
+
"properties": { "summary": { "type": "string", "description": "Summarized text" } },
|
|
141
|
+
"required": ["summary"]
|
|
142
|
+
},
|
|
143
|
+
"entrypoint": {
|
|
144
|
+
"command": "python",
|
|
145
|
+
"args": ["main.py"],
|
|
146
|
+
"cwd": ".",
|
|
147
|
+
"timeout_ms": 60000,
|
|
148
|
+
"env": {}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Execution contract:**
|
|
154
|
+
- SDK writes **inputs JSON** to the process **stdin**.
|
|
155
|
+
- Tool writes a single **outputs JSON** object to **stdout**.
|
|
156
|
+
- Non-JSON logs should go to **stderr**.
|
|
157
|
+
- Process must exit with **code 0** on success.
|
|
158
|
+
|
|
159
|
+
**Interpreter whitelist:** `node`, `nodejs`, `python`, `python3`.
|
|
160
|
+
The SDK validates the interpreter and checks it’s present on `PATH`.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Development
|
|
165
|
+
|
|
166
|
+
### Project layout
|
|
167
|
+
```
|
|
168
|
+
src/
|
|
169
|
+
agentpm/
|
|
170
|
+
__init__.py # re-exports: load, to_langchain_tool (lazy)
|
|
171
|
+
core.py # resolver/spawn/JSON plumbing
|
|
172
|
+
types.py # JsonValue, TypedDicts
|
|
173
|
+
adapters/
|
|
174
|
+
__init__.py
|
|
175
|
+
langchain.py # optional adapter
|
|
176
|
+
py.typed # marks package as typed
|
|
177
|
+
tests/
|
|
178
|
+
test_basic.py
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Common tasks (via `uv`)
|
|
182
|
+
```bash
|
|
183
|
+
uv run ruff check .
|
|
184
|
+
uv run black --check .
|
|
185
|
+
uv run mypy
|
|
186
|
+
uv run pytest -q
|
|
187
|
+
|
|
188
|
+
# run hooks locally on all files
|
|
189
|
+
uv run pre-commit run --all-files
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Building & Publishing
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# build wheel & sdist
|
|
198
|
+
uv run python -m build
|
|
199
|
+
|
|
200
|
+
# verify metadata
|
|
201
|
+
uv run twine check dist/*
|
|
202
|
+
|
|
203
|
+
# upload (PyPI)
|
|
204
|
+
uv run twine upload dist/*
|
|
205
|
+
|
|
206
|
+
# or TestPyPI first
|
|
207
|
+
uv run twine upload -r testpypi dist/*
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Running mixed-runtime Agent apps with Docker
|
|
213
|
+
|
|
214
|
+
Some AgentPM tools run on Node, some on Python—and your agent may need to spawn both. Using Docker gives you a single, reproducible environment where both interpreters are installed and on PATH, which avoids the common “interpreter not found” issues that pop up on PaaS/CI or IDEs.
|
|
215
|
+
|
|
216
|
+
Why Docker?
|
|
217
|
+
|
|
218
|
+
✅ Hermetic: Python + Node versions are pinned inside the image.
|
|
219
|
+
|
|
220
|
+
✅ No PATH drama: node/python are present and discoverable.
|
|
221
|
+
|
|
222
|
+
✅ Prod/CI parity: the same image runs on your laptop, CI, and servers.
|
|
223
|
+
|
|
224
|
+
✅ Easy secrets: pass API keys via env at docker run/Compose time.
|
|
225
|
+
|
|
226
|
+
✅ Fewer surprises: consistent OS libs for LLM clients, SSL, etc.
|
|
227
|
+
|
|
228
|
+
### When to use it
|
|
229
|
+
|
|
230
|
+
- You deploy to platforms that don’t let you apt-get both runtimes.
|
|
231
|
+
- Your agent uses tools with different interpreters (Node + Python).
|
|
232
|
+
- Your local dev/IDE PATH differs from production and causes failures.
|
|
233
|
+
- You want reproducible builds and easy rollback.
|
|
234
|
+
|
|
235
|
+
### How to use it
|
|
236
|
+
|
|
237
|
+
1. Copy the provided [Dockerfile](https://github.com/agentpm-dev/sdk-python/tree/main/examples/python-agent) into your repo.
|
|
238
|
+
2. (Optional) Pre-install tools locally with agentpm install ... and commit or copy .agentpm/tools/ into the image, or run agentpm install at build time if your CLI is available in the image.
|
|
239
|
+
3. Build & run:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
docker build -t agent-app .
|
|
243
|
+
docker run --rm -e OPENAI_API_KEY=$OPENAI_API_KEY agent-app
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
4. For development, use the docker-compose.yml snippet to mount your source and pass env vars conveniently.
|
|
247
|
+
|
|
248
|
+
### Troubleshooting
|
|
249
|
+
|
|
250
|
+
- Set `AGENTPM_DEBUG=1` to print the SDK’s project root, search paths, merged PATH, and resolved interpreters.
|
|
251
|
+
- You can force interpreters via:
|
|
252
|
+
```ini
|
|
253
|
+
AGENTPM_NODE=/usr/bin/node
|
|
254
|
+
AGENTPM_PYTHON=/usr/local/bin/python3.11
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
- Prefer absolute interpreters in agent.json.entrypoint.command for production (e.g., /usr/bin/node). The SDKs still enforce the Node/Python family.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Troubleshooting
|
|
262
|
+
|
|
263
|
+
- **`No JSON object found on stdout.`**
|
|
264
|
+
Ensure your tool prints a single JSON object as the last thing on stdout, and writes logs to stderr.
|
|
265
|
+
|
|
266
|
+
- **`Unsupported agent.json.entrypoint.command`**
|
|
267
|
+
Only `node` / `python` are allowed (including `nodejs` / `python3`). Update `entrypoint.command`.
|
|
268
|
+
|
|
269
|
+
- **`Interpreter "... " not found on PATH`**
|
|
270
|
+
Install the interpreter or adjust `entrypoint.command`. The SDK runs `<command> --version` to verify availability.
|
|
271
|
+
|
|
272
|
+
- **PEP 668 / “externally managed”**
|
|
273
|
+
Use a venv (we recommend `uv venv`) and install with `uv pip install -e ".[dev]"`.
|
|
274
|
+
|
|
275
|
+
- **IDE can’t import `agentpm`**
|
|
276
|
+
Ensure your interpreter is the project’s `.venv/bin/python`, and that you ran the editable install.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## License
|
|
281
|
+
|
|
282
|
+
MIT — see `LICENSE`.
|