agentx-python 0.6.9__tar.gz → 0.6.11__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.
- {agentx_python-0.6.9 → agentx_python-0.6.11}/PKG-INFO +61 -2
- agentx_python-0.6.9/agentx_python.egg-info/PKG-INFO → agentx_python-0.6.11/README.md +46 -49
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/agentx.py +3 -1
- agentx_python-0.6.11/agentx/cli.py +158 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/client.py +25 -1
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/models.py +24 -0
- agentx_python-0.6.11/agentx/evaluations/prompts.py +49 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/runner.py +1 -0
- agentx_python-0.6.11/agentx/integrations/_traced_call.py +141 -0
- agentx_python-0.6.11/agentx/integrations/anthropic.py +266 -0
- agentx_python-0.6.11/agentx/integrations/autogen.py +199 -0
- agentx_python-0.6.11/agentx/integrations/crewai.py +257 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/integrations/google_adk.py +31 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/integrations/google_genai.py +127 -64
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/integrations/langchain.py +69 -7
- agentx_python-0.6.11/agentx/integrations/litellm.py +142 -0
- agentx_python-0.6.11/agentx/integrations/llamaindex.py +302 -0
- agentx_python-0.6.11/agentx/integrations/openai.py +158 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/integrations/openai_agents.py +11 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/monitor/__init__.py +4 -1
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/monitor/client.py +20 -1
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/monitor/models.py +30 -0
- agentx_python-0.6.11/agentx/monitor/profile.py +68 -0
- agentx_python-0.6.11/agentx/version.py +1 -0
- agentx_python-0.6.9/README.md → agentx_python-0.6.11/agentx_python.egg-info/PKG-INFO +108 -1
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx_python.egg-info/SOURCES.txt +11 -1
- agentx_python-0.6.11/agentx_python.egg-info/entry_points.txt +2 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx_python.egg-info/requires.txt +18 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/setup.py +15 -0
- agentx_python-0.6.11/tests/test_integrations.py +1011 -0
- agentx_python-0.6.9/agentx/integrations/anthropic.py +0 -250
- agentx_python-0.6.9/agentx/integrations/crewai.py +0 -141
- agentx_python-0.6.9/agentx/version.py +0 -1
- {agentx_python-0.6.9 → agentx_python-0.6.11}/LICENSE +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/__init__.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/__init__.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/_term.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/adapters/__init__.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/adapters/http_endpoint.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/adapters/precomputed.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/adapters/raw.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/datasets.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/evaluation_settings.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/redaction.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/reporting.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/results.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/evaluations/tracing.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/exceptions.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/integrations/__init__.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/integrations/_perf.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/monitor/patterns.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/monitor/signals.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/py.typed +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/resources/__init__.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/resources/agent.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/resources/conversation.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/resources/workforce.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/tracing/__init__.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/tracing/ci_types.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/tracing/ingest_client.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/tracing/tracer.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx/util.py +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx_python.egg-info/dependency_links.txt +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx_python.egg-info/not-zip-safe +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/agentx_python.egg-info/top_level.txt +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/setup.cfg +0 -0
- {agentx_python-0.6.9 → agentx_python-0.6.11}/tests/test_integration.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentx-python
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.11
|
|
4
4
|
Summary: Official Python SDK for AgentX (https://www.agentx.so/)
|
|
5
5
|
Home-page: https://github.com/AgentX-ai/AgentX-python
|
|
6
6
|
Author: Robin Wang and AgentX Team
|
|
@@ -21,19 +21,33 @@ Provides-Extra: crewai
|
|
|
21
21
|
Requires-Dist: crewai>=0.80.0; extra == "crewai"
|
|
22
22
|
Provides-Extra: openai-agents
|
|
23
23
|
Requires-Dist: openai-agents>=0.0.3; extra == "openai-agents"
|
|
24
|
+
Provides-Extra: openai
|
|
25
|
+
Requires-Dist: openai>=1.0.0; extra == "openai"
|
|
24
26
|
Provides-Extra: anthropic
|
|
25
27
|
Requires-Dist: anthropic>=0.25.0; extra == "anthropic"
|
|
26
28
|
Provides-Extra: google-adk
|
|
27
29
|
Requires-Dist: google-adk>=1.0.0; extra == "google-adk"
|
|
28
30
|
Provides-Extra: google-genai
|
|
29
31
|
Requires-Dist: google-genai>=1.0.0; extra == "google-genai"
|
|
32
|
+
Provides-Extra: litellm
|
|
33
|
+
Requires-Dist: litellm>=1.0.0; extra == "litellm"
|
|
34
|
+
Provides-Extra: llamaindex
|
|
35
|
+
Requires-Dist: llama-index-core>=0.10.0; extra == "llamaindex"
|
|
36
|
+
Provides-Extra: autogen
|
|
37
|
+
Requires-Dist: autogen-agentchat>=0.4.0; extra == "autogen"
|
|
38
|
+
Requires-Dist: autogen-core>=0.4.0; extra == "autogen"
|
|
30
39
|
Provides-Extra: all
|
|
31
40
|
Requires-Dist: langchain-core>=0.1.0; extra == "all"
|
|
32
41
|
Requires-Dist: crewai>=0.80.0; extra == "all"
|
|
33
42
|
Requires-Dist: openai-agents>=0.0.3; extra == "all"
|
|
43
|
+
Requires-Dist: openai>=1.0.0; extra == "all"
|
|
34
44
|
Requires-Dist: anthropic>=0.25.0; extra == "all"
|
|
35
45
|
Requires-Dist: google-adk>=1.0.0; extra == "all"
|
|
36
46
|
Requires-Dist: google-genai>=1.0.0; extra == "all"
|
|
47
|
+
Requires-Dist: litellm>=1.0.0; extra == "all"
|
|
48
|
+
Requires-Dist: llama-index-core>=0.10.0; extra == "all"
|
|
49
|
+
Requires-Dist: autogen-agentchat>=0.4.0; extra == "all"
|
|
50
|
+
Requires-Dist: autogen-core>=0.4.0; extra == "all"
|
|
37
51
|
Dynamic: author
|
|
38
52
|
Dynamic: author-email
|
|
39
53
|
Dynamic: classifier
|
|
@@ -72,6 +86,7 @@ Also see [SDK Developer Docs](https://developers.agentx.so), [API Reference Docs
|
|
|
72
86
|
- [Production tracing](#production-tracing) — record live agent runs from any framework
|
|
73
87
|
- [Monitor](#monitor) — automatic production monitoring, patterns and signals
|
|
74
88
|
- [Custom agent evaluations](#custom-agent-evaluations) — LLM-as-a-judge, cosine / Jaccard similarity
|
|
89
|
+
- [Self-host](#self-host) — run Trace/Evaluate/Monitor on your own machine instead of the hosted dashboard
|
|
75
90
|
- [Links](#links)
|
|
76
91
|
|
|
77
92
|
---
|
|
@@ -234,9 +249,13 @@ Each integration auto-captures LLM calls, tool calls, and token usage — instal
|
|
|
234
249
|
| LangChain | `pip install "agentx-python[langchain]"` | `AgentXCallbackHandler` |
|
|
235
250
|
| CrewAI | `pip install "agentx-python[crewai]"` | `AgentXCrewObserver` |
|
|
236
251
|
| OpenAI Agents SDK | `pip install "agentx-python[openai-agents]"` | `AgentXTracingProcessor` |
|
|
252
|
+
| OpenAI (raw client) | `pip install "agentx-python[openai]"` | `patch_openai_client` |
|
|
237
253
|
| Anthropic | `pip install "agentx-python[anthropic]"` | `patch_anthropic_client` |
|
|
238
254
|
| Google ADK | `pip install "agentx-python[google-adk]"` | `AgentXADKPlugin` |
|
|
239
255
|
| Google GenAI (Gemini) | `pip install "agentx-python[google-genai]"` | `patch_genai_client` |
|
|
256
|
+
| LiteLLM | `pip install "agentx-python[litellm]"` | `AgentXLiteLLMLogger` |
|
|
257
|
+
| LlamaIndex | `pip install "agentx-python[llamaindex]"` | `AgentXLlamaIndexHandler`|
|
|
258
|
+
| AutoGen | `pip install "agentx-python[autogen]"` | `AgentXAutoGenObserver` |
|
|
240
259
|
|
|
241
260
|
Or plain Python — wrap any function with `@tracer.trace(...)` and it just works, no framework required.
|
|
242
261
|
|
|
@@ -273,6 +292,12 @@ for signal in client.monitor.signals.list(severity="high"):
|
|
|
273
292
|
print(signal.summary, signal.occurrence_count)
|
|
274
293
|
```
|
|
275
294
|
|
|
295
|
+
Per-agent coverage/threshold settings (sample rate, retention, and threshold overrides like the built-in "Latency regression" pattern's threshold) are `client.monitor.profile.get()`/`.update()`:
|
|
296
|
+
|
|
297
|
+
```python
|
|
298
|
+
client.monitor.profile.update("agent_123", threshold_overrides={"latencyMs": 15000})
|
|
299
|
+
```
|
|
300
|
+
|
|
276
301
|
See **[TRACING.md](TRACING.md)** for the complete Monitor guide.
|
|
277
302
|
|
|
278
303
|
---
|
|
@@ -302,7 +327,40 @@ print(report.recommendations) # list of prioritized, actionable fixes
|
|
|
302
327
|
|
|
303
328
|
Ask a case's question several extra ways each run, LLM-paraphrased server-side, to catch agents that break on phrasing rather than substance, and override the judge's prompt/model per config, see [Smoke testing](EVALUATIONS.md#smoke-testing-phrasing-robustness) and [Configuring the judge](EVALUATIONS.md#configuring-the-judge) in the full guide.
|
|
304
329
|
|
|
305
|
-
|
|
330
|
+
Since AgentX doesn't own your agent's code, `client.evaluations.prompts` lets AgentX become your prompt's *source of truth* instead — the same problem LangSmith's Prompt Hub and Langfuse's Prompt Management solve. Pull a version at runtime, tag your eval runs (or live traces) with it, and let a judge propose a rewrite from your real worst-rated results — a human always has to approve before it publishes:
|
|
331
|
+
|
|
332
|
+
```python
|
|
333
|
+
prompt = client.evaluations.prompts.get("support-agent-system-prompt")
|
|
334
|
+
# use prompt.text as your own agent's system prompt
|
|
335
|
+
|
|
336
|
+
client.evaluations.run(
|
|
337
|
+
dataset_id="evds_…",
|
|
338
|
+
subject={"kind": "custom_agent", "metadata": {"promptName": prompt.name}},
|
|
339
|
+
).execute(my_agent_fn)
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
See [Prompt registry](EVALUATIONS.md#prompt-registry) in the full guide, or [self-host's docs](https://docs.agentx.so/self-host#prompt-registry) for the "Suggest improvement" dashboard flow (self-host only — no hosted-SaaS equivalent yet).
|
|
343
|
+
|
|
344
|
+
See **[EVALUATIONS.md](EVALUATIONS.md)** for the full guide — dataset builder, framework adapters, similarity metrics, smoke testing, judge configuration, prompt registry, and the complete API reference.
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Self-host
|
|
349
|
+
|
|
350
|
+
Prefer to run Trace/Evaluate/Monitor locally instead of the hosted dashboard — no account, bring your own LLM keys? This SDK ships a launcher for [AgentX-trace-eval](https://github.com/AgentX-ai/AgentX-trace-eval), a separate, portable governance engine:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
agentx-trace-eval --dev
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
The first run downloads the engine (and dashboard) into `~/.agentx/bin` and prints a local API key; every run after that just starts it. Point this SDK at it instead of the hosted API:
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
export AGENTX_API_BASE_URL=http://localhost:4700/api/v1
|
|
360
|
+
export AGENTX_API_KEY=<printed by agentx-trace-eval on first run>
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
`agentx-trace-eval` isn't this SDK's own code — the engine itself is a separate, compiled binary, downloaded on demand rather than bundled into this package, so installing `agentx-python` doesn't get any heavier for the (much more common) case of just talking to the hosted AgentX API. See that repo's README for what's included, and `AGENTX_INSTALL_DIR`/`AGENTX_TRACE_EVAL_VERSION`/`AGENTX_TRACE_EVAL_SKIP_WEB` env vars to control where/what it installs.
|
|
306
364
|
|
|
307
365
|
---
|
|
308
366
|
|
|
@@ -314,3 +372,4 @@ See **[EVALUATIONS.md](EVALUATIONS.md)** for the full guide — dataset builder,
|
|
|
314
372
|
- **Tracing docs** — [TRACING.md](TRACING.md)
|
|
315
373
|
- **Evaluations docs** — [EVALUATIONS.md](EVALUATIONS.md)
|
|
316
374
|
- **Monitor docs** — [docs.agentx.so/sdk/monitor](https://docs.agentx.so/sdk/monitor)
|
|
375
|
+
- **Self-host** — [AgentX-trace-eval](https://github.com/AgentX-ai/AgentX-trace-eval)
|
|
@@ -1,51 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: agentx-python
|
|
3
|
-
Version: 0.6.9
|
|
4
|
-
Summary: Official Python SDK for AgentX (https://www.agentx.so/)
|
|
5
|
-
Home-page: https://github.com/AgentX-ai/AgentX-python
|
|
6
|
-
Author: Robin Wang and AgentX Team
|
|
7
|
-
Author-email: contact@agentx.so
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
-
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.6
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
License-File: LICENSE
|
|
14
|
-
Requires-Dist: urllib3>=1.26.11
|
|
15
|
-
Requires-Dist: certifi
|
|
16
|
-
Requires-Dist: requests
|
|
17
|
-
Requires-Dist: pydantic>=2.0.0
|
|
18
|
-
Provides-Extra: langchain
|
|
19
|
-
Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
|
|
20
|
-
Provides-Extra: crewai
|
|
21
|
-
Requires-Dist: crewai>=0.80.0; extra == "crewai"
|
|
22
|
-
Provides-Extra: openai-agents
|
|
23
|
-
Requires-Dist: openai-agents>=0.0.3; extra == "openai-agents"
|
|
24
|
-
Provides-Extra: anthropic
|
|
25
|
-
Requires-Dist: anthropic>=0.25.0; extra == "anthropic"
|
|
26
|
-
Provides-Extra: google-adk
|
|
27
|
-
Requires-Dist: google-adk>=1.0.0; extra == "google-adk"
|
|
28
|
-
Provides-Extra: google-genai
|
|
29
|
-
Requires-Dist: google-genai>=1.0.0; extra == "google-genai"
|
|
30
|
-
Provides-Extra: all
|
|
31
|
-
Requires-Dist: langchain-core>=0.1.0; extra == "all"
|
|
32
|
-
Requires-Dist: crewai>=0.80.0; extra == "all"
|
|
33
|
-
Requires-Dist: openai-agents>=0.0.3; extra == "all"
|
|
34
|
-
Requires-Dist: anthropic>=0.25.0; extra == "all"
|
|
35
|
-
Requires-Dist: google-adk>=1.0.0; extra == "all"
|
|
36
|
-
Requires-Dist: google-genai>=1.0.0; extra == "all"
|
|
37
|
-
Dynamic: author
|
|
38
|
-
Dynamic: author-email
|
|
39
|
-
Dynamic: classifier
|
|
40
|
-
Dynamic: description
|
|
41
|
-
Dynamic: description-content-type
|
|
42
|
-
Dynamic: home-page
|
|
43
|
-
Dynamic: license-file
|
|
44
|
-
Dynamic: provides-extra
|
|
45
|
-
Dynamic: requires-dist
|
|
46
|
-
Dynamic: requires-python
|
|
47
|
-
Dynamic: summary
|
|
48
|
-
|
|
49
1
|

|
|
50
2
|
|
|
51
3
|
[](https://pypi.org/project/agentx-python/)
|
|
@@ -72,6 +24,7 @@ Also see [SDK Developer Docs](https://developers.agentx.so), [API Reference Docs
|
|
|
72
24
|
- [Production tracing](#production-tracing) — record live agent runs from any framework
|
|
73
25
|
- [Monitor](#monitor) — automatic production monitoring, patterns and signals
|
|
74
26
|
- [Custom agent evaluations](#custom-agent-evaluations) — LLM-as-a-judge, cosine / Jaccard similarity
|
|
27
|
+
- [Self-host](#self-host) — run Trace/Evaluate/Monitor on your own machine instead of the hosted dashboard
|
|
75
28
|
- [Links](#links)
|
|
76
29
|
|
|
77
30
|
---
|
|
@@ -234,9 +187,13 @@ Each integration auto-captures LLM calls, tool calls, and token usage — instal
|
|
|
234
187
|
| LangChain | `pip install "agentx-python[langchain]"` | `AgentXCallbackHandler` |
|
|
235
188
|
| CrewAI | `pip install "agentx-python[crewai]"` | `AgentXCrewObserver` |
|
|
236
189
|
| OpenAI Agents SDK | `pip install "agentx-python[openai-agents]"` | `AgentXTracingProcessor` |
|
|
190
|
+
| OpenAI (raw client) | `pip install "agentx-python[openai]"` | `patch_openai_client` |
|
|
237
191
|
| Anthropic | `pip install "agentx-python[anthropic]"` | `patch_anthropic_client` |
|
|
238
192
|
| Google ADK | `pip install "agentx-python[google-adk]"` | `AgentXADKPlugin` |
|
|
239
193
|
| Google GenAI (Gemini) | `pip install "agentx-python[google-genai]"` | `patch_genai_client` |
|
|
194
|
+
| LiteLLM | `pip install "agentx-python[litellm]"` | `AgentXLiteLLMLogger` |
|
|
195
|
+
| LlamaIndex | `pip install "agentx-python[llamaindex]"` | `AgentXLlamaIndexHandler`|
|
|
196
|
+
| AutoGen | `pip install "agentx-python[autogen]"` | `AgentXAutoGenObserver` |
|
|
240
197
|
|
|
241
198
|
Or plain Python — wrap any function with `@tracer.trace(...)` and it just works, no framework required.
|
|
242
199
|
|
|
@@ -273,6 +230,12 @@ for signal in client.monitor.signals.list(severity="high"):
|
|
|
273
230
|
print(signal.summary, signal.occurrence_count)
|
|
274
231
|
```
|
|
275
232
|
|
|
233
|
+
Per-agent coverage/threshold settings (sample rate, retention, and threshold overrides like the built-in "Latency regression" pattern's threshold) are `client.monitor.profile.get()`/`.update()`:
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
client.monitor.profile.update("agent_123", threshold_overrides={"latencyMs": 15000})
|
|
237
|
+
```
|
|
238
|
+
|
|
276
239
|
See **[TRACING.md](TRACING.md)** for the complete Monitor guide.
|
|
277
240
|
|
|
278
241
|
---
|
|
@@ -302,7 +265,40 @@ print(report.recommendations) # list of prioritized, actionable fixes
|
|
|
302
265
|
|
|
303
266
|
Ask a case's question several extra ways each run, LLM-paraphrased server-side, to catch agents that break on phrasing rather than substance, and override the judge's prompt/model per config, see [Smoke testing](EVALUATIONS.md#smoke-testing-phrasing-robustness) and [Configuring the judge](EVALUATIONS.md#configuring-the-judge) in the full guide.
|
|
304
267
|
|
|
305
|
-
|
|
268
|
+
Since AgentX doesn't own your agent's code, `client.evaluations.prompts` lets AgentX become your prompt's *source of truth* instead — the same problem LangSmith's Prompt Hub and Langfuse's Prompt Management solve. Pull a version at runtime, tag your eval runs (or live traces) with it, and let a judge propose a rewrite from your real worst-rated results — a human always has to approve before it publishes:
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
prompt = client.evaluations.prompts.get("support-agent-system-prompt")
|
|
272
|
+
# use prompt.text as your own agent's system prompt
|
|
273
|
+
|
|
274
|
+
client.evaluations.run(
|
|
275
|
+
dataset_id="evds_…",
|
|
276
|
+
subject={"kind": "custom_agent", "metadata": {"promptName": prompt.name}},
|
|
277
|
+
).execute(my_agent_fn)
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
See [Prompt registry](EVALUATIONS.md#prompt-registry) in the full guide, or [self-host's docs](https://docs.agentx.so/self-host#prompt-registry) for the "Suggest improvement" dashboard flow (self-host only — no hosted-SaaS equivalent yet).
|
|
281
|
+
|
|
282
|
+
See **[EVALUATIONS.md](EVALUATIONS.md)** for the full guide — dataset builder, framework adapters, similarity metrics, smoke testing, judge configuration, prompt registry, and the complete API reference.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Self-host
|
|
287
|
+
|
|
288
|
+
Prefer to run Trace/Evaluate/Monitor locally instead of the hosted dashboard — no account, bring your own LLM keys? This SDK ships a launcher for [AgentX-trace-eval](https://github.com/AgentX-ai/AgentX-trace-eval), a separate, portable governance engine:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
agentx-trace-eval --dev
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
The first run downloads the engine (and dashboard) into `~/.agentx/bin` and prints a local API key; every run after that just starts it. Point this SDK at it instead of the hosted API:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
export AGENTX_API_BASE_URL=http://localhost:4700/api/v1
|
|
298
|
+
export AGENTX_API_KEY=<printed by agentx-trace-eval on first run>
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
`agentx-trace-eval` isn't this SDK's own code — the engine itself is a separate, compiled binary, downloaded on demand rather than bundled into this package, so installing `agentx-python` doesn't get any heavier for the (much more common) case of just talking to the hosted AgentX API. See that repo's README for what's included, and `AGENTX_INSTALL_DIR`/`AGENTX_TRACE_EVAL_VERSION`/`AGENTX_TRACE_EVAL_SKIP_WEB` env vars to control where/what it installs.
|
|
306
302
|
|
|
307
303
|
---
|
|
308
304
|
|
|
@@ -314,3 +310,4 @@ See **[EVALUATIONS.md](EVALUATIONS.md)** for the full guide — dataset builder,
|
|
|
314
310
|
- **Tracing docs** — [TRACING.md](TRACING.md)
|
|
315
311
|
- **Evaluations docs** — [EVALUATIONS.md](EVALUATIONS.md)
|
|
316
312
|
- **Monitor docs** — [docs.agentx.so/sdk/monitor](https://docs.agentx.so/sdk/monitor)
|
|
313
|
+
- **Self-host** — [AgentX-trace-eval](https://github.com/AgentX-ai/AgentX-trace-eval)
|
|
@@ -44,7 +44,9 @@ class AgentX:
|
|
|
44
44
|
|
|
45
45
|
# Monitor: create/reuse patterns (client.monitor.patterns) that a trace can be checked
|
|
46
46
|
# against at send time via tracer.trace(..., monitor=True, pattern_ids=[...]), then read
|
|
47
|
-
# back the resulting alerts/findings with client.monitor.signals.
|
|
47
|
+
# back the resulting alerts/findings with client.monitor.signals. Per-agent coverage and
|
|
48
|
+
# detection settings (sample rate, retention, threshold overrides like the built-in
|
|
49
|
+
# "Latency regression" pattern's threshold) are client.monitor.profile.
|
|
48
50
|
self.monitor = MonitorClient(
|
|
49
51
|
api_key=self.api_key,
|
|
50
52
|
sdk_version=VERSION,
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""
|
|
2
|
+
`agentx-trace-eval` — thin launcher for AgentX's self-hostable governance engine (Trace,
|
|
3
|
+
Evaluate, Monitor), published separately at github.com/AgentX-ai/AgentX-trace-eval (a Go CLI
|
|
4
|
+
wrapping a Bun-compiled TypeScript engine, not Python). That compiled engine binary is tens of
|
|
5
|
+
megabytes; most `pip install agentx-python` installs are just this SDK talking to the hosted
|
|
6
|
+
AgentX SaaS and would never touch it, so it isn't bundled in this package. Instead, this command
|
|
7
|
+
downloads the matching release into ~/.agentx/bin the first time it's needed (mirroring
|
|
8
|
+
AgentX-trace-eval's own install.sh) and then hands off to the real `agentx-server` binary.
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
agentx-trace-eval --dev
|
|
12
|
+
agentx-trace-eval --port 5000 --db-url postgres://...
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import os
|
|
16
|
+
import platform
|
|
17
|
+
import shutil
|
|
18
|
+
import stat
|
|
19
|
+
import sys
|
|
20
|
+
import tarfile
|
|
21
|
+
import tempfile
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import Tuple
|
|
24
|
+
|
|
25
|
+
import requests
|
|
26
|
+
|
|
27
|
+
REPO = "AgentX-ai/AgentX-trace-eval"
|
|
28
|
+
INSTALL_DIR = Path(os.environ.get("AGENTX_INSTALL_DIR", str(Path.home() / ".agentx" / "bin")))
|
|
29
|
+
_BIN_NAMES = ("agentx", "agentx-server", "agentx-engine")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _platform_tag() -> Tuple[str, str]:
|
|
33
|
+
system = platform.system()
|
|
34
|
+
if system == "Darwin":
|
|
35
|
+
os_name = "darwin"
|
|
36
|
+
elif system == "Linux":
|
|
37
|
+
os_name = "linux"
|
|
38
|
+
else:
|
|
39
|
+
raise SystemExit(
|
|
40
|
+
f"agentx-trace-eval: unsupported OS {system!r} (self-host currently supports macOS and Linux)"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
machine = platform.machine().lower()
|
|
44
|
+
if machine in ("arm64", "aarch64"):
|
|
45
|
+
arch = "arm64"
|
|
46
|
+
elif machine in ("x86_64", "amd64"):
|
|
47
|
+
arch = "amd64"
|
|
48
|
+
else:
|
|
49
|
+
raise SystemExit(f"agentx-trace-eval: unsupported architecture {machine!r}")
|
|
50
|
+
|
|
51
|
+
return os_name, arch
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _release_url(asset: str, version: str) -> str:
|
|
55
|
+
if version == "latest":
|
|
56
|
+
return f"https://github.com/{REPO}/releases/latest/download/{asset}"
|
|
57
|
+
return f"https://github.com/{REPO}/releases/download/{version}/{asset}"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _download(url: str, dest: Path) -> None:
|
|
61
|
+
response = requests.get(url, stream=True, timeout=60)
|
|
62
|
+
response.raise_for_status()
|
|
63
|
+
with open(dest, "wb") as f:
|
|
64
|
+
for chunk in response.iter_content(chunk_size=1 << 16):
|
|
65
|
+
f.write(chunk)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _extract_tar(archive: Path, dest_dir: Path) -> None:
|
|
69
|
+
with tarfile.open(archive) as tar:
|
|
70
|
+
try:
|
|
71
|
+
# filter="data" (PEP 706, Python 3.12+) rejects absolute paths/symlink escapes.
|
|
72
|
+
# Belt-and-suspenders here since these are trusted release assets built by our own CI
|
|
73
|
+
# (see REPO above), not arbitrary user-supplied archives.
|
|
74
|
+
tar.extractall(dest_dir, filter="data")
|
|
75
|
+
except TypeError:
|
|
76
|
+
tar.extractall(dest_dir) # Python < 3.12: filter kwarg doesn't exist yet
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _install(version: str = "latest") -> None:
|
|
80
|
+
os_name, arch = _platform_tag()
|
|
81
|
+
INSTALL_DIR.mkdir(parents=True, exist_ok=True)
|
|
82
|
+
|
|
83
|
+
print(f"agentx-trace-eval: downloading agentx ({os_name}/{arch})...", file=sys.stderr)
|
|
84
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
85
|
+
tmp_dir = Path(tmp)
|
|
86
|
+
archive = tmp_dir / "agentx.tar.gz"
|
|
87
|
+
url = _release_url(f"agentx_{os_name}_{arch}.tar.gz", version)
|
|
88
|
+
try:
|
|
89
|
+
_download(url, archive)
|
|
90
|
+
except requests.HTTPError as exc:
|
|
91
|
+
raise SystemExit(
|
|
92
|
+
f"agentx-trace-eval: failed to download {url} ({exc}).\n"
|
|
93
|
+
"No published release found; see AgentX-trace-eval's README for building from source."
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
_extract_tar(archive, tmp_dir)
|
|
97
|
+
|
|
98
|
+
found_any = False
|
|
99
|
+
for name in _BIN_NAMES:
|
|
100
|
+
src = tmp_dir / name
|
|
101
|
+
if not src.exists():
|
|
102
|
+
continue
|
|
103
|
+
found_any = True
|
|
104
|
+
dest = INSTALL_DIR / name
|
|
105
|
+
shutil.move(str(src), str(dest))
|
|
106
|
+
dest.chmod(dest.stat().st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)
|
|
107
|
+
|
|
108
|
+
if not found_any:
|
|
109
|
+
raise SystemExit(f"agentx-trace-eval: downloaded archive from {url} didn't contain any of {_BIN_NAMES}")
|
|
110
|
+
|
|
111
|
+
if os.environ.get("AGENTX_TRACE_EVAL_SKIP_WEB"):
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
# Best-effort: the dashboard is a separate, platform-independent asset (see
|
|
115
|
+
# AgentX-trace-eval's README's "Dashboard release"). Missing it shouldn't block getting the
|
|
116
|
+
# engine running headless, so a failure here warns and continues rather than raising.
|
|
117
|
+
print("agentx-trace-eval: downloading dashboard...", file=sys.stderr)
|
|
118
|
+
web_dir = INSTALL_DIR / "web"
|
|
119
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
120
|
+
web_archive = Path(tmp) / "agentx-web.tar.gz"
|
|
121
|
+
web_url = _release_url("agentx-web.tar.gz", version)
|
|
122
|
+
try:
|
|
123
|
+
_download(web_url, web_archive)
|
|
124
|
+
except requests.HTTPError:
|
|
125
|
+
print(
|
|
126
|
+
f"agentx-trace-eval: no dashboard bundle found at {web_url}, continuing without one",
|
|
127
|
+
file=sys.stderr,
|
|
128
|
+
)
|
|
129
|
+
return
|
|
130
|
+
if web_dir.exists():
|
|
131
|
+
shutil.rmtree(web_dir)
|
|
132
|
+
web_dir.mkdir(parents=True)
|
|
133
|
+
_extract_tar(web_archive, web_dir)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def ensure_installed(version: str = "latest") -> Path:
|
|
137
|
+
"""Downloads agentx-server (+ its engine) into ~/.agentx/bin if not already present there.
|
|
138
|
+
Returns the path to the agentx-server executable. Set AGENTX_INSTALL_DIR to change where
|
|
139
|
+
this looks/installs; set AGENTX_TRACE_EVAL_VERSION to pin a release tag instead of latest."""
|
|
140
|
+
server_path = INSTALL_DIR / "agentx-server"
|
|
141
|
+
if not server_path.exists():
|
|
142
|
+
_install(version=version)
|
|
143
|
+
return server_path
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def main() -> None:
|
|
147
|
+
version = os.environ.get("AGENTX_TRACE_EVAL_VERSION", "latest")
|
|
148
|
+
server_path = ensure_installed(version=version)
|
|
149
|
+
if not server_path.exists():
|
|
150
|
+
raise SystemExit(f"agentx-trace-eval: {server_path} still missing after install, giving up")
|
|
151
|
+
|
|
152
|
+
# os.execv replaces this process rather than spawning a subprocess: signals, stdio, and the
|
|
153
|
+
# exit code all pass straight through to agentx-server, same as invoking it directly.
|
|
154
|
+
os.execv(str(server_path), [str(server_path)] + sys.argv[1:])
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
if __name__ == "__main__":
|
|
158
|
+
main()
|
|
@@ -17,6 +17,7 @@ from agentx.evaluations.models import (
|
|
|
17
17
|
EvaluationSettings,
|
|
18
18
|
EvaluationSubject,
|
|
19
19
|
ModelInfo,
|
|
20
|
+
Prompt,
|
|
20
21
|
Report,
|
|
21
22
|
)
|
|
22
23
|
|
|
@@ -77,12 +78,14 @@ class EvaluationsClient:
|
|
|
77
78
|
"accept": "*/*",
|
|
78
79
|
}
|
|
79
80
|
)
|
|
80
|
-
# Expose dataset / evaluation-settings builder factories
|
|
81
|
+
# Expose dataset / evaluation-settings / prompt builder factories
|
|
81
82
|
from agentx.evaluations.datasets import DatasetClient
|
|
82
83
|
from agentx.evaluations.evaluation_settings import EvaluationSettingsClient
|
|
84
|
+
from agentx.evaluations.prompts import PromptClient
|
|
83
85
|
|
|
84
86
|
self.datasets = DatasetClient(self)
|
|
85
87
|
self.settings = EvaluationSettingsClient(self)
|
|
88
|
+
self.prompts = PromptClient(self)
|
|
86
89
|
|
|
87
90
|
# ------------------------------------------------------------------
|
|
88
91
|
# Low-level HTTP
|
|
@@ -195,6 +198,27 @@ class EvaluationsClient:
|
|
|
195
198
|
)
|
|
196
199
|
return EvaluationSettings(**data)
|
|
197
200
|
|
|
201
|
+
# ------------------------------------------------------------------
|
|
202
|
+
# Prompt registry endpoints — see agentx.evaluations.prompts.PromptClient for the concept
|
|
203
|
+
# (the external-agent analog to native autotune). Deliberately read-mostly: no publish here,
|
|
204
|
+
# a new version only ever comes from the dashboard's human-approved propose/publish flow.
|
|
205
|
+
# ------------------------------------------------------------------
|
|
206
|
+
|
|
207
|
+
def create_prompt(self, payload: dict) -> Prompt:
|
|
208
|
+
data = self._request("POST", "/prompts", json=self._with_workspace(payload))
|
|
209
|
+
return Prompt(**data)
|
|
210
|
+
|
|
211
|
+
def list_prompts(self) -> List[Prompt]:
|
|
212
|
+
data = self._request("GET", "/prompts", params=self._workspace_params())
|
|
213
|
+
return [Prompt(**p) for p in (data if isinstance(data, list) else data.get("prompts", []))]
|
|
214
|
+
|
|
215
|
+
def get_prompt(self, name: str, version: Optional[int] = None) -> Prompt:
|
|
216
|
+
params = self._workspace_params() or {}
|
|
217
|
+
if version is not None:
|
|
218
|
+
params = {**params, "version": version}
|
|
219
|
+
data = self._request("GET", f"/prompts/{name}", params=params or None)
|
|
220
|
+
return Prompt(**data)
|
|
221
|
+
|
|
198
222
|
# ------------------------------------------------------------------
|
|
199
223
|
# Run endpoints
|
|
200
224
|
# ------------------------------------------------------------------
|
|
@@ -128,6 +128,30 @@ class EvaluationSettings(BaseModel):
|
|
|
128
128
|
extra = "ignore"
|
|
129
129
|
|
|
130
130
|
|
|
131
|
+
# ---------------------------------------------------------------------------
|
|
132
|
+
# Prompt registry — the external-agent analog to AgentX's native autotune. AgentX doesn't own
|
|
133
|
+
# your agent's code, so instead of branching/applying a config it becomes the prompt's source of
|
|
134
|
+
# truth (same shape as LangSmith's Prompt Hub / Langfuse's Prompt Management): pull a version at
|
|
135
|
+
# runtime with ``client.evaluations.prompts.get(name)``, use ``prompt.text`` as your agent's
|
|
136
|
+
# system prompt, and tag your eval runs so the existing version-comparison view can tell you
|
|
137
|
+
# which published version scored higher — see ``client.evaluations.prompts`` docs.
|
|
138
|
+
# ---------------------------------------------------------------------------
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class Prompt(BaseModel):
|
|
142
|
+
id: str = Field(alias="_id")
|
|
143
|
+
name: str
|
|
144
|
+
description: Optional[str] = None
|
|
145
|
+
version: int
|
|
146
|
+
text: str
|
|
147
|
+
created_at: Optional[str] = Field(default=None, alias="createdAt")
|
|
148
|
+
updated_at: Optional[str] = Field(default=None, alias="updatedAt")
|
|
149
|
+
|
|
150
|
+
class Config:
|
|
151
|
+
populate_by_name = True
|
|
152
|
+
extra = "ignore"
|
|
153
|
+
|
|
154
|
+
|
|
131
155
|
# ---------------------------------------------------------------------------
|
|
132
156
|
# Evaluation subject
|
|
133
157
|
# ---------------------------------------------------------------------------
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, List, Optional
|
|
4
|
+
|
|
5
|
+
from agentx.evaluations.models import Prompt
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from agentx.evaluations.client import EvaluationsClient
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PromptClient:
|
|
12
|
+
"""Thin wrapper surfaced as ``client.evaluations.prompts`` — the external-agent analog to
|
|
13
|
+
AgentX's native autotune. AgentX doesn't own your agent's code, so instead of branching and
|
|
14
|
+
applying a config, it becomes the prompt's source of truth (the same shape as LangSmith's
|
|
15
|
+
Prompt Hub / Langfuse's Prompt Management): create/pull versions here, use ``prompt.text`` as
|
|
16
|
+
your agent's own system prompt, and tag your eval runs with the pulled version so the
|
|
17
|
+
existing version-comparison view (``client.evaluations`` run comparisons on a dataset) can
|
|
18
|
+
tell you which published version actually scored higher.
|
|
19
|
+
|
|
20
|
+
Deliberately read-mostly from here: there is no ``publish`` on this client. A prompt only
|
|
21
|
+
gets a new version through the dashboard's human-approved propose/publish flow, so a
|
|
22
|
+
rewritten prompt never reaches your running agent without someone explicitly approving it.
|
|
23
|
+
|
|
24
|
+
Example::
|
|
25
|
+
|
|
26
|
+
prompt = client.evaluations.prompts.get("support-agent-system-prompt")
|
|
27
|
+
# ... call your own LLM using prompt.text as the system prompt ...
|
|
28
|
+
client.evaluations.init_run(
|
|
29
|
+
dataset_id=dataset_id,
|
|
30
|
+
subject=EvaluationSubject(
|
|
31
|
+
metadata={
|
|
32
|
+
"promptName": prompt.name,
|
|
33
|
+
"version": f"{prompt.name}@v{prompt.version}",
|
|
34
|
+
}
|
|
35
|
+
),
|
|
36
|
+
)
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, client: "EvaluationsClient"):
|
|
40
|
+
self._client = client
|
|
41
|
+
|
|
42
|
+
def create(self, name: str, text: str, description: Optional[str] = None) -> Prompt:
|
|
43
|
+
return self._client.create_prompt({"name": name, "text": text, "description": description})
|
|
44
|
+
|
|
45
|
+
def get(self, name: str, version: Optional[int] = None) -> Prompt:
|
|
46
|
+
return self._client.get_prompt(name, version=version)
|
|
47
|
+
|
|
48
|
+
def list(self) -> List[Prompt]:
|
|
49
|
+
return self._client.list_prompts()
|
|
@@ -335,6 +335,7 @@ class EvaluationsRunner:
|
|
|
335
335
|
self._client = client
|
|
336
336
|
self.datasets = client.datasets
|
|
337
337
|
self.settings = client.settings
|
|
338
|
+
self.prompts = client.prompts
|
|
338
339
|
|
|
339
340
|
def list_models(self, provider: Optional[str] = None) -> List[ModelInfo]:
|
|
340
341
|
"""List the LLM models AgentX supports — the same set selectable for
|