agentx-python 0.6.15__tar.gz → 0.6.17__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.
Files changed (68) hide show
  1. {agentx_python-0.6.15 → agentx_python-0.6.17}/PKG-INFO +75 -38
  2. {agentx_python-0.6.15 → agentx_python-0.6.17}/README.md +74 -37
  3. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/agentx.py +12 -0
  4. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/cli.py +1 -1
  5. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/_term.py +1 -1
  6. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/adapters/http_endpoint.py +1 -1
  7. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/adapters/precomputed.py +1 -1
  8. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/client.py +32 -4
  9. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/datasets.py +1 -1
  10. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/evaluation_settings.py +1 -1
  11. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/models.py +10 -10
  12. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/prompts.py +1 -1
  13. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/results.py +1 -1
  14. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/runner.py +91 -12
  15. agentx_python-0.6.17/agentx/feedback.py +76 -0
  16. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/_traced_call.py +4 -4
  17. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/anthropic.py +4 -4
  18. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/autogen.py +5 -5
  19. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/crewai.py +6 -6
  20. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/google_adk.py +9 -9
  21. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/google_genai.py +6 -6
  22. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/langchain.py +10 -10
  23. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/litellm.py +4 -4
  24. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/llamaindex.py +6 -6
  25. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/openai.py +6 -6
  26. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/openai_agents.py +10 -10
  27. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/monitor/client.py +1 -1
  28. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/monitor/models.py +5 -1
  29. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/monitor/online_evaluators.py +15 -2
  30. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/monitor/patterns.py +3 -3
  31. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/monitor/profile.py +1 -1
  32. agentx_python-0.6.17/agentx/outcomes.py +84 -0
  33. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/tracing/ingest_client.py +3 -3
  34. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/tracing/tracer.py +99 -54
  35. agentx_python-0.6.17/agentx/version.py +1 -0
  36. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx_python.egg-info/PKG-INFO +75 -38
  37. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx_python.egg-info/SOURCES.txt +2 -0
  38. agentx_python-0.6.15/agentx/version.py +0 -1
  39. {agentx_python-0.6.15 → agentx_python-0.6.17}/LICENSE +0 -0
  40. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/__init__.py +0 -0
  41. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/__init__.py +0 -0
  42. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/adapters/__init__.py +0 -0
  43. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/adapters/raw.py +0 -0
  44. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/redaction.py +0 -0
  45. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/reporting.py +0 -0
  46. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/evaluations/tracing.py +0 -0
  47. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/exceptions.py +0 -0
  48. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/integrations/__init__.py +0 -0
  49. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/monitor/__init__.py +0 -0
  50. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/monitor/signals.py +0 -0
  51. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/py.typed +0 -0
  52. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/resources/__init__.py +0 -0
  53. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/resources/agent.py +0 -0
  54. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/resources/conversation.py +0 -0
  55. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/resources/workforce.py +0 -0
  56. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/tracing/__init__.py +0 -0
  57. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/tracing/ci_types.py +0 -0
  58. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx/util.py +0 -0
  59. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx_python.egg-info/dependency_links.txt +0 -0
  60. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx_python.egg-info/entry_points.txt +0 -0
  61. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx_python.egg-info/not-zip-safe +0 -0
  62. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx_python.egg-info/requires.txt +0 -0
  63. {agentx_python-0.6.15 → agentx_python-0.6.17}/agentx_python.egg-info/top_level.txt +0 -0
  64. {agentx_python-0.6.15 → agentx_python-0.6.17}/setup.cfg +0 -0
  65. {agentx_python-0.6.15 → agentx_python-0.6.17}/setup.py +0 -0
  66. {agentx_python-0.6.15 → agentx_python-0.6.17}/tests/test_integration.py +0 -0
  67. {agentx_python-0.6.15 → agentx_python-0.6.17}/tests/test_integrations.py +0 -0
  68. {agentx_python-0.6.15 → agentx_python-0.6.17}/tests/test_span_tree.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentx-python
3
- Version: 0.6.15
3
+ Version: 0.6.17
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
@@ -66,7 +66,7 @@ Dynamic: summary
66
66
  [![Python versions](https://img.shields.io/pypi/pyversions/agentx-python)](https://pypi.org/project/agentx-python/)
67
67
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
68
68
 
69
- The official Python SDK for **[AgentX](https://app.agentx.so/)** an evaluation, tracing, and monitoring framework for AI agents, plus a client for AgentX's own hosted agents.
69
+ The official Python SDK for **[AgentX](https://app.agentx.so/)** - an evaluation, tracing, and monitoring framework for AI agents, plus a client for AgentX's own hosted agents.
70
70
 
71
71
  Also see [SDK Developer Docs](https://developers.agentx.so), [API Reference Docs](https://docs.agentx.so/reference)
72
72
 
@@ -78,24 +78,24 @@ Also see [SDK Developer Docs](https://developers.agentx.so), [API Reference Docs
78
78
  - [Installation](#installation)
79
79
  - [Authentication](#authentication)
80
80
  - [Quick start](#quick-start)
81
- - [Custom agent evaluations](#custom-agent-evaluations) LLM-as-a-judge, cosine / Jaccard similarity, any framework
82
- - [Production tracing](#production-tracing) record live agent runs from any framework
83
- - [Monitor](#monitor) automatic production monitoring, patterns and signals
84
- - [Self-host](#self-host) run Trace/Evaluate/Monitor on your own machine instead of the hosted dashboard
85
- - [Agents & conversations](#agents--conversations) chat with and orchestrate AgentX's own hosted agents
81
+ - [Custom agent evaluations](#custom-agent-evaluations) - LLM-as-a-judge, cosine / Jaccard similarity, any framework
82
+ - [Production tracing](#production-tracing) - record live agent runs from any framework
83
+ - [Monitor](#monitor) - automatic production monitoring, patterns and signals
84
+ - [Self-host](#self-host) - run Trace/Evaluate/Monitor on your own machine instead of the hosted dashboard
85
+ - [Agents & conversations](#agents--conversations) - chat with and orchestrate AgentX's own hosted agents
86
86
  - [Links](#links)
87
87
 
88
88
  ---
89
89
 
90
90
  ## Why AgentX
91
91
 
92
- - **Agent Evaluations** score **any** agent (LangChain, CrewAI, AutoGen, LlamaIndex, OpenAI, Anthropic, HTTP, or plain Python) against a dataset with LLM-as-a-judge ratings plus optional cosine, Jaccard, and BLEU/ROUGE similarity metrics. Configurable judge prompt/model, per-question judge guidelines, smoke testing for phrasing robustness, and a durable multi-judge analysis pass for a qualitative report.
93
- - **Production tracing** one decorator or context manager records every agent run (input, output, latency, tool calls, token usage, and a real span tree) into your workspace, for any framework.
94
- - **Monitor** check live traces against detection patterns or a sampled LLM judge, and read back triage-ready signals, no dashboard setup required.
95
- - **Prompt registry** make AgentX the source of truth for your own agent's prompts: pull a version at runtime, tag eval runs and live traces with it, let a judge propose a rewrite from your worst-rated results.
96
- - **Self-host** run the whole Trace/Evaluate/Monitor stack locally, bring your own LLM keys, no account required.
97
- - **Bring any LLM** works across major open and closed-source vendors, for evaluation, tracing, and AgentX's own hosted agents alike.
98
- - **AgentX's own hosted agents** a simple `Agent → Conversation → Message` mental model, chain-of-thought built in, multi-agent workforces, MCP support, and A2A publishing, for when you want AgentX to run the agent too, not just evaluate/trace/monitor it.
92
+ - **Agent Evaluations** - score **any** agent (LangChain, CrewAI, AutoGen, LlamaIndex, OpenAI, Anthropic, HTTP, or plain Python) against a dataset with LLM-as-a-judge ratings plus optional cosine, Jaccard, and BLEU/ROUGE similarity metrics. Configurable judge prompt/model, per-question judge guidelines, smoke testing for phrasing robustness, and a durable multi-judge analysis pass for a qualitative report.
93
+ - **Production tracing** - one decorator or context manager records every agent run (input, output, latency, tool calls, token usage, and a real span tree) into your workspace, for any framework.
94
+ - **Monitor** - check live traces against detection patterns or a sampled LLM judge, and read back triage-ready signals, no dashboard setup required.
95
+ - **Prompt registry** - make AgentX the source of truth for your own agent's prompts: pull a version at runtime, tag eval runs and live traces with it, let a judge propose a rewrite from your worst-rated results.
96
+ - **Self-host** - run the whole Trace/Evaluate/Monitor stack locally, bring your own LLM keys, no account required.
97
+ - **Bring any LLM** - works across major open and closed-source vendors, for evaluation, tracing, and AgentX's own hosted agents alike.
98
+ - **AgentX's own hosted agents** - a simple `Agent → Conversation → Message` mental model, chain-of-thought built in, multi-agent workforces, MCP support, and A2A publishing, for when you want AgentX to run the agent too, not just evaluate/trace/monitor it.
99
99
 
100
100
  ---
101
101
 
@@ -114,11 +114,11 @@ Requires Python 3.9 or newer.
114
114
  Get your API key at [app.agentx.so](https://app.agentx.so), then either pass it inline or expose it as an environment variable.
115
115
 
116
116
  ```python
117
- # Option A pass the key inline
117
+ # Option A - pass the key inline
118
118
  from agentx import AgentX
119
119
  client = AgentX(api_key="your-api-key-here")
120
120
 
121
- # Option B set AGENTX_API_KEY in your environment, then:
121
+ # Option B - set AGENTX_API_KEY in your environment, then:
122
122
  client = AgentX.from_env()
123
123
  ```
124
124
 
@@ -126,7 +126,7 @@ client = AgentX.from_env()
126
126
 
127
127
  ## Quick start
128
128
 
129
- Evaluate your own agent any framework, or plain Python against a dataset:
129
+ Evaluate your own agent - any framework, or plain Python - against a dataset:
130
130
 
131
131
  ```python
132
132
  from agentx import AgentX
@@ -154,7 +154,7 @@ That's it. The rest of this section covers building the dataset, framework adapt
154
154
 
155
155
  ## Custom agent evaluations
156
156
 
157
- Evaluate **any** AI agent LangChain, CrewAI, AutoGen, LlamaIndex, OpenAI, Anthropic, HTTP endpoints, or plain Python using AgentX as the scoring and reporting backend. Includes optional **cosine**, **Jaccard**, and **BLEU/ROUGE** similarity metrics alongside LLM-graded ratings.
157
+ Evaluate **any** AI agent - LangChain, CrewAI, AutoGen, LlamaIndex, OpenAI, Anthropic, HTTP endpoints, or plain Python - using AgentX as the scoring and reporting backend. Includes optional **cosine**, **Jaccard**, and **BLEU/ROUGE** similarity metrics alongside LLM-graded ratings.
158
158
 
159
159
  ```python
160
160
  report = (
@@ -177,7 +177,7 @@ print(report.recommendations) # list of prioritized, actionable fixes
177
177
 
178
178
  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.
179
179
 
180
- 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:
180
+ 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:
181
181
 
182
182
  ```python
183
183
  prompt = client.evaluations.prompts.get("support-agent-system-prompt") # or prompt.id
@@ -189,15 +189,17 @@ client.evaluations.run(
189
189
  ).execute(my_agent_fn)
190
190
  ```
191
191
 
192
- 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).
192
+ See [Prompt registry](EVALUATIONS.md#prompt-registry) in the full guide, or [self-host's docs](https://docs.agentx.so/improve/prompt-management) for the "Suggest improvement" dashboard flow (self-host only - no hosted-SaaS equivalent yet).
193
193
 
194
- 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.
194
+ On self-host, a finalized run can also **gate a CI job**: `report.gate(fail_under=7, no_regression=True)` checks the run's average rating against an absolute floor and/or the dataset's previous run, prints per-check verdicts into the CI log, and returns an exit code - `sys.exit(gate.exit_code)` blocks the merge on regression. Recorded gates appear in the dashboard's CI Gates tab. See [self-host's CI docs](https://docs.agentx.so/integrations/self-host-ci) for the GitHub Actions recipe.
195
+
196
+ 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.
195
197
 
196
198
  ---
197
199
 
198
200
  ## Production tracing
199
201
 
200
- Record live agent runs into your workspace with a single decorator or context manager no changes to your agent's logic. Traces appear in the **Live Traces** tab and can be evaluated against your test datasets with [`tracer.evaluate_trace()`](TRACING.md#tracerevaluate_trace).
202
+ Record live agent runs into your workspace with a single decorator or context manager - no changes to your agent's logic. Traces appear in the **Live Traces** tab and can be evaluated against your test datasets with [`tracer.evaluate_trace()`](TRACING.md#tracerevaluate_trace).
201
203
 
202
204
  ```python
203
205
  from agentx import AgentX
@@ -226,9 +228,18 @@ with tracer.trace("rag-agent", framework="langchain") as span:
226
228
  span.output = llm.invoke(f"Context: {kb_result}\n\nQuery: {query}")
227
229
  ```
228
230
 
231
+ To time a tool call and capture its failures automatically, wrap the execution itself instead of reporting it after the fact:
232
+
233
+ ```python
234
+ with tracer.trace_tool_call("search_knowledge_base", input=query) as t:
235
+ t.output = search_knowledge_base(query)
236
+ ```
237
+
238
+ An exception escaping the block records the call as failed (`success=False` plus the error text, which is what Monitor's built-in "Tool failure" check and the dashboard's Tool quality column read) and then propagates unchanged.
239
+
229
240
  ### Framework integrations
230
241
 
231
- Each integration auto-captures LLM calls, tool calls, and token usage including prompt-caching
242
+ Each integration auto-captures LLM calls, tool calls, and token usage - including prompt-caching
232
243
  token counts (Anthropic's cache write/read, OpenAI/LiteLLM's cached tokens, Google GenAI's cached
233
244
  content), reported as their own `cache_read_tokens`/`cache_write_tokens` fields alongside the
234
245
  regular totals, no extra config needed. Self-host's cost estimate prices these separately from a
@@ -248,11 +259,11 @@ extra:
248
259
  | LlamaIndex | `pip install "agentx-python[llamaindex]"` | `AgentXLlamaIndexHandler`|
249
260
  | AutoGen | `pip install "agentx-python[autogen]"` | `AgentXAutoGenObserver` |
250
261
 
251
- Or plain Python wrap any function with `@tracer.trace(...)` and it just works, no framework required.
262
+ Or plain Python - wrap any function with `@tracer.trace(...)` and it just works, no framework required.
252
263
 
253
- Running specialist agents in parallel with a `ThreadPoolExecutor`? Wrap each worker body in `tracer.use_span(span)` so their steps land on the parent trace instead of becoming independent traces see [TRACING.md](TRACING.md) for the full pattern.
264
+ Running specialist agents in parallel with a `ThreadPoolExecutor`? Wrap each worker body in `tracer.use_span(span)` so their steps land on the parent trace instead of becoming independent traces - see [TRACING.md](TRACING.md) for the full pattern.
254
265
 
255
- See **[TRACING.md](TRACING.md)** for the complete guide session grouping, error handling, async support, and the full API reference.
266
+ See **[TRACING.md](TRACING.md)** for the complete guide - session grouping, error handling, async support, and the full API reference.
256
267
 
257
268
  ---
258
269
 
@@ -302,13 +313,39 @@ evaluator = client.monitor.online_evaluators.builder(
302
313
  client.monitor.online_evaluators.ratings(evaluator.id, window="7d")
303
314
  ```
304
315
 
316
+ An online evaluator can also judge **whole conversations** instead of single traces: pass `scope="session"` and the engine scores each multi-turn session once it's been idle for `idle_seconds`, re-scoring if the conversation resumes. And to close the loop with reality, two ground-truth streams feed the dashboard's Judge Calibration view (which measures how often AgentX's automated verdicts agree with what actually happened): `client.outcomes.report(...)` for after-the-fact system results (a reopened ticket, a human confirmation), and `client.feedback.report(...)` for end-user votes forwarded from your own app's UI - a "down" raises a "Negative user feedback" signal directly, no sampling or judge call involved. All self-host features.
317
+
318
+ ```python
319
+ client.monitor.online_evaluators.builder(
320
+ name="Conversation resolution",
321
+ evaluation_settings_id=settings.id,
322
+ scope="session", # judge the whole session, not each trace
323
+ idle_seconds=120, # score once the conversation has been quiet this long
324
+ alert_threshold=5,
325
+ ).publish()
326
+
327
+ client.outcomes.report(
328
+ trace_id=trace_id,
329
+ outcome="reopened",
330
+ is_negative=True,
331
+ reason="Customer reopened the ticket within 3 days",
332
+ )
333
+
334
+ client.feedback.report(
335
+ trace_id=trace_id,
336
+ rating="down", # "up" or "down"
337
+ comment="It never answered my question", # optional, the user's own words
338
+ end_user_id=current_user.id, # optional, opaque to AgentX
339
+ )
340
+ ```
341
+
305
342
  See **[TRACING.md](TRACING.md)** for the complete Monitor guide.
306
343
 
307
344
  ---
308
345
 
309
346
  ## Self-host
310
347
 
311
- 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:
348
+ 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:
312
349
 
313
350
  ```bash
314
351
  agentx-trace-eval --dev
@@ -321,22 +358,22 @@ export AGENTX_API_BASE_URL=http://localhost:4700/api/v1
321
358
  export AGENTX_API_KEY=<printed by agentx-trace-eval on first run>
322
359
  ```
323
360
 
324
- `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.
361
+ `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.
325
362
 
326
363
  ---
327
364
 
328
365
  ## Agents & conversations
329
366
 
330
- Beyond evaluation, tracing, and monitoring, this SDK is also a client for AgentX's own hosted agents build, chat with, and orchestrate them directly.
367
+ Beyond evaluation, tracing, and monitoring, this SDK is also a client for AgentX's own hosted agents - build, chat with, and orchestrate them directly.
331
368
 
332
369
  ```python
333
370
  agent = client.list_agents()[0]
334
371
  conversation = agent.new_conversation()
335
372
 
336
- # Blocking returns the full response once it's ready
373
+ # Blocking - returns the full response once it's ready
337
374
  print(conversation.chat("What can you help me with?"))
338
375
 
339
- # Streaming yields ChatResponse objects as the model produces them
376
+ # Streaming - yields ChatResponse objects as the model produces them
340
377
  for chunk in conversation.chat_stream("Hello!"):
341
378
  if chunk.text:
342
379
  print(chunk.text, end="")
@@ -359,10 +396,10 @@ for chunk in workforce.chat_stream(conversation.id, "How can you help me with th
359
396
 
360
397
  ## Links
361
398
 
362
- - **Dashboard** [app.agentx.so](https://app.agentx.so)
363
- - **Website** [agentx.so](https://www.agentx.so/)
364
- - **PyPI** [agentx-python](https://pypi.org/project/agentx-python/)
365
- - **Tracing docs** [TRACING.md](TRACING.md)
366
- - **Evaluations docs** [EVALUATIONS.md](EVALUATIONS.md)
367
- - **Monitor docs** [docs.agentx.so/sdk/monitor](https://docs.agentx.so/sdk/monitor)
368
- - **Self-host** [AgentX-trace-eval](https://github.com/AgentX-ai/AgentX-trace-eval)
399
+ - **Dashboard** - [app.agentx.so](https://app.agentx.so)
400
+ - **Website** - [agentx.so](https://www.agentx.so/)
401
+ - **PyPI** - [agentx-python](https://pypi.org/project/agentx-python/)
402
+ - **Tracing docs** - [TRACING.md](TRACING.md)
403
+ - **Evaluations docs** - [EVALUATIONS.md](EVALUATIONS.md)
404
+ - **Monitor docs** - [docs.agentx.so/sdk/monitor](https://docs.agentx.so/sdk/monitor)
405
+ - **Self-host** - [AgentX-trace-eval](https://github.com/AgentX-ai/AgentX-trace-eval)
@@ -4,7 +4,7 @@
4
4
  [![Python versions](https://img.shields.io/pypi/pyversions/agentx-python)](https://pypi.org/project/agentx-python/)
5
5
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
6
 
7
- The official Python SDK for **[AgentX](https://app.agentx.so/)** an evaluation, tracing, and monitoring framework for AI agents, plus a client for AgentX's own hosted agents.
7
+ The official Python SDK for **[AgentX](https://app.agentx.so/)** - an evaluation, tracing, and monitoring framework for AI agents, plus a client for AgentX's own hosted agents.
8
8
 
9
9
  Also see [SDK Developer Docs](https://developers.agentx.so), [API Reference Docs](https://docs.agentx.so/reference)
10
10
 
@@ -16,24 +16,24 @@ Also see [SDK Developer Docs](https://developers.agentx.so), [API Reference Docs
16
16
  - [Installation](#installation)
17
17
  - [Authentication](#authentication)
18
18
  - [Quick start](#quick-start)
19
- - [Custom agent evaluations](#custom-agent-evaluations) LLM-as-a-judge, cosine / Jaccard similarity, any framework
20
- - [Production tracing](#production-tracing) record live agent runs from any framework
21
- - [Monitor](#monitor) automatic production monitoring, patterns and signals
22
- - [Self-host](#self-host) run Trace/Evaluate/Monitor on your own machine instead of the hosted dashboard
23
- - [Agents & conversations](#agents--conversations) chat with and orchestrate AgentX's own hosted agents
19
+ - [Custom agent evaluations](#custom-agent-evaluations) - LLM-as-a-judge, cosine / Jaccard similarity, any framework
20
+ - [Production tracing](#production-tracing) - record live agent runs from any framework
21
+ - [Monitor](#monitor) - automatic production monitoring, patterns and signals
22
+ - [Self-host](#self-host) - run Trace/Evaluate/Monitor on your own machine instead of the hosted dashboard
23
+ - [Agents & conversations](#agents--conversations) - chat with and orchestrate AgentX's own hosted agents
24
24
  - [Links](#links)
25
25
 
26
26
  ---
27
27
 
28
28
  ## Why AgentX
29
29
 
30
- - **Agent Evaluations** score **any** agent (LangChain, CrewAI, AutoGen, LlamaIndex, OpenAI, Anthropic, HTTP, or plain Python) against a dataset with LLM-as-a-judge ratings plus optional cosine, Jaccard, and BLEU/ROUGE similarity metrics. Configurable judge prompt/model, per-question judge guidelines, smoke testing for phrasing robustness, and a durable multi-judge analysis pass for a qualitative report.
31
- - **Production tracing** one decorator or context manager records every agent run (input, output, latency, tool calls, token usage, and a real span tree) into your workspace, for any framework.
32
- - **Monitor** check live traces against detection patterns or a sampled LLM judge, and read back triage-ready signals, no dashboard setup required.
33
- - **Prompt registry** make AgentX the source of truth for your own agent's prompts: pull a version at runtime, tag eval runs and live traces with it, let a judge propose a rewrite from your worst-rated results.
34
- - **Self-host** run the whole Trace/Evaluate/Monitor stack locally, bring your own LLM keys, no account required.
35
- - **Bring any LLM** works across major open and closed-source vendors, for evaluation, tracing, and AgentX's own hosted agents alike.
36
- - **AgentX's own hosted agents** a simple `Agent → Conversation → Message` mental model, chain-of-thought built in, multi-agent workforces, MCP support, and A2A publishing, for when you want AgentX to run the agent too, not just evaluate/trace/monitor it.
30
+ - **Agent Evaluations** - score **any** agent (LangChain, CrewAI, AutoGen, LlamaIndex, OpenAI, Anthropic, HTTP, or plain Python) against a dataset with LLM-as-a-judge ratings plus optional cosine, Jaccard, and BLEU/ROUGE similarity metrics. Configurable judge prompt/model, per-question judge guidelines, smoke testing for phrasing robustness, and a durable multi-judge analysis pass for a qualitative report.
31
+ - **Production tracing** - one decorator or context manager records every agent run (input, output, latency, tool calls, token usage, and a real span tree) into your workspace, for any framework.
32
+ - **Monitor** - check live traces against detection patterns or a sampled LLM judge, and read back triage-ready signals, no dashboard setup required.
33
+ - **Prompt registry** - make AgentX the source of truth for your own agent's prompts: pull a version at runtime, tag eval runs and live traces with it, let a judge propose a rewrite from your worst-rated results.
34
+ - **Self-host** - run the whole Trace/Evaluate/Monitor stack locally, bring your own LLM keys, no account required.
35
+ - **Bring any LLM** - works across major open and closed-source vendors, for evaluation, tracing, and AgentX's own hosted agents alike.
36
+ - **AgentX's own hosted agents** - a simple `Agent → Conversation → Message` mental model, chain-of-thought built in, multi-agent workforces, MCP support, and A2A publishing, for when you want AgentX to run the agent too, not just evaluate/trace/monitor it.
37
37
 
38
38
  ---
39
39
 
@@ -52,11 +52,11 @@ Requires Python 3.9 or newer.
52
52
  Get your API key at [app.agentx.so](https://app.agentx.so), then either pass it inline or expose it as an environment variable.
53
53
 
54
54
  ```python
55
- # Option A pass the key inline
55
+ # Option A - pass the key inline
56
56
  from agentx import AgentX
57
57
  client = AgentX(api_key="your-api-key-here")
58
58
 
59
- # Option B set AGENTX_API_KEY in your environment, then:
59
+ # Option B - set AGENTX_API_KEY in your environment, then:
60
60
  client = AgentX.from_env()
61
61
  ```
62
62
 
@@ -64,7 +64,7 @@ client = AgentX.from_env()
64
64
 
65
65
  ## Quick start
66
66
 
67
- Evaluate your own agent any framework, or plain Python against a dataset:
67
+ Evaluate your own agent - any framework, or plain Python - against a dataset:
68
68
 
69
69
  ```python
70
70
  from agentx import AgentX
@@ -92,7 +92,7 @@ That's it. The rest of this section covers building the dataset, framework adapt
92
92
 
93
93
  ## Custom agent evaluations
94
94
 
95
- Evaluate **any** AI agent LangChain, CrewAI, AutoGen, LlamaIndex, OpenAI, Anthropic, HTTP endpoints, or plain Python using AgentX as the scoring and reporting backend. Includes optional **cosine**, **Jaccard**, and **BLEU/ROUGE** similarity metrics alongside LLM-graded ratings.
95
+ Evaluate **any** AI agent - LangChain, CrewAI, AutoGen, LlamaIndex, OpenAI, Anthropic, HTTP endpoints, or plain Python - using AgentX as the scoring and reporting backend. Includes optional **cosine**, **Jaccard**, and **BLEU/ROUGE** similarity metrics alongside LLM-graded ratings.
96
96
 
97
97
  ```python
98
98
  report = (
@@ -115,7 +115,7 @@ print(report.recommendations) # list of prioritized, actionable fixes
115
115
 
116
116
  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.
117
117
 
118
- 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:
118
+ 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:
119
119
 
120
120
  ```python
121
121
  prompt = client.evaluations.prompts.get("support-agent-system-prompt") # or prompt.id
@@ -127,15 +127,17 @@ client.evaluations.run(
127
127
  ).execute(my_agent_fn)
128
128
  ```
129
129
 
130
- 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).
130
+ See [Prompt registry](EVALUATIONS.md#prompt-registry) in the full guide, or [self-host's docs](https://docs.agentx.so/improve/prompt-management) for the "Suggest improvement" dashboard flow (self-host only - no hosted-SaaS equivalent yet).
131
131
 
132
- 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.
132
+ On self-host, a finalized run can also **gate a CI job**: `report.gate(fail_under=7, no_regression=True)` checks the run's average rating against an absolute floor and/or the dataset's previous run, prints per-check verdicts into the CI log, and returns an exit code - `sys.exit(gate.exit_code)` blocks the merge on regression. Recorded gates appear in the dashboard's CI Gates tab. See [self-host's CI docs](https://docs.agentx.so/integrations/self-host-ci) for the GitHub Actions recipe.
133
+
134
+ 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.
133
135
 
134
136
  ---
135
137
 
136
138
  ## Production tracing
137
139
 
138
- Record live agent runs into your workspace with a single decorator or context manager no changes to your agent's logic. Traces appear in the **Live Traces** tab and can be evaluated against your test datasets with [`tracer.evaluate_trace()`](TRACING.md#tracerevaluate_trace).
140
+ Record live agent runs into your workspace with a single decorator or context manager - no changes to your agent's logic. Traces appear in the **Live Traces** tab and can be evaluated against your test datasets with [`tracer.evaluate_trace()`](TRACING.md#tracerevaluate_trace).
139
141
 
140
142
  ```python
141
143
  from agentx import AgentX
@@ -164,9 +166,18 @@ with tracer.trace("rag-agent", framework="langchain") as span:
164
166
  span.output = llm.invoke(f"Context: {kb_result}\n\nQuery: {query}")
165
167
  ```
166
168
 
169
+ To time a tool call and capture its failures automatically, wrap the execution itself instead of reporting it after the fact:
170
+
171
+ ```python
172
+ with tracer.trace_tool_call("search_knowledge_base", input=query) as t:
173
+ t.output = search_knowledge_base(query)
174
+ ```
175
+
176
+ An exception escaping the block records the call as failed (`success=False` plus the error text, which is what Monitor's built-in "Tool failure" check and the dashboard's Tool quality column read) and then propagates unchanged.
177
+
167
178
  ### Framework integrations
168
179
 
169
- Each integration auto-captures LLM calls, tool calls, and token usage including prompt-caching
180
+ Each integration auto-captures LLM calls, tool calls, and token usage - including prompt-caching
170
181
  token counts (Anthropic's cache write/read, OpenAI/LiteLLM's cached tokens, Google GenAI's cached
171
182
  content), reported as their own `cache_read_tokens`/`cache_write_tokens` fields alongside the
172
183
  regular totals, no extra config needed. Self-host's cost estimate prices these separately from a
@@ -186,11 +197,11 @@ extra:
186
197
  | LlamaIndex | `pip install "agentx-python[llamaindex]"` | `AgentXLlamaIndexHandler`|
187
198
  | AutoGen | `pip install "agentx-python[autogen]"` | `AgentXAutoGenObserver` |
188
199
 
189
- Or plain Python wrap any function with `@tracer.trace(...)` and it just works, no framework required.
200
+ Or plain Python - wrap any function with `@tracer.trace(...)` and it just works, no framework required.
190
201
 
191
- Running specialist agents in parallel with a `ThreadPoolExecutor`? Wrap each worker body in `tracer.use_span(span)` so their steps land on the parent trace instead of becoming independent traces see [TRACING.md](TRACING.md) for the full pattern.
202
+ Running specialist agents in parallel with a `ThreadPoolExecutor`? Wrap each worker body in `tracer.use_span(span)` so their steps land on the parent trace instead of becoming independent traces - see [TRACING.md](TRACING.md) for the full pattern.
192
203
 
193
- See **[TRACING.md](TRACING.md)** for the complete guide session grouping, error handling, async support, and the full API reference.
204
+ See **[TRACING.md](TRACING.md)** for the complete guide - session grouping, error handling, async support, and the full API reference.
194
205
 
195
206
  ---
196
207
 
@@ -240,13 +251,39 @@ evaluator = client.monitor.online_evaluators.builder(
240
251
  client.monitor.online_evaluators.ratings(evaluator.id, window="7d")
241
252
  ```
242
253
 
254
+ An online evaluator can also judge **whole conversations** instead of single traces: pass `scope="session"` and the engine scores each multi-turn session once it's been idle for `idle_seconds`, re-scoring if the conversation resumes. And to close the loop with reality, two ground-truth streams feed the dashboard's Judge Calibration view (which measures how often AgentX's automated verdicts agree with what actually happened): `client.outcomes.report(...)` for after-the-fact system results (a reopened ticket, a human confirmation), and `client.feedback.report(...)` for end-user votes forwarded from your own app's UI - a "down" raises a "Negative user feedback" signal directly, no sampling or judge call involved. All self-host features.
255
+
256
+ ```python
257
+ client.monitor.online_evaluators.builder(
258
+ name="Conversation resolution",
259
+ evaluation_settings_id=settings.id,
260
+ scope="session", # judge the whole session, not each trace
261
+ idle_seconds=120, # score once the conversation has been quiet this long
262
+ alert_threshold=5,
263
+ ).publish()
264
+
265
+ client.outcomes.report(
266
+ trace_id=trace_id,
267
+ outcome="reopened",
268
+ is_negative=True,
269
+ reason="Customer reopened the ticket within 3 days",
270
+ )
271
+
272
+ client.feedback.report(
273
+ trace_id=trace_id,
274
+ rating="down", # "up" or "down"
275
+ comment="It never answered my question", # optional, the user's own words
276
+ end_user_id=current_user.id, # optional, opaque to AgentX
277
+ )
278
+ ```
279
+
243
280
  See **[TRACING.md](TRACING.md)** for the complete Monitor guide.
244
281
 
245
282
  ---
246
283
 
247
284
  ## Self-host
248
285
 
249
- 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:
286
+ 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:
250
287
 
251
288
  ```bash
252
289
  agentx-trace-eval --dev
@@ -259,22 +296,22 @@ export AGENTX_API_BASE_URL=http://localhost:4700/api/v1
259
296
  export AGENTX_API_KEY=<printed by agentx-trace-eval on first run>
260
297
  ```
261
298
 
262
- `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.
299
+ `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.
263
300
 
264
301
  ---
265
302
 
266
303
  ## Agents & conversations
267
304
 
268
- Beyond evaluation, tracing, and monitoring, this SDK is also a client for AgentX's own hosted agents build, chat with, and orchestrate them directly.
305
+ Beyond evaluation, tracing, and monitoring, this SDK is also a client for AgentX's own hosted agents - build, chat with, and orchestrate them directly.
269
306
 
270
307
  ```python
271
308
  agent = client.list_agents()[0]
272
309
  conversation = agent.new_conversation()
273
310
 
274
- # Blocking returns the full response once it's ready
311
+ # Blocking - returns the full response once it's ready
275
312
  print(conversation.chat("What can you help me with?"))
276
313
 
277
- # Streaming yields ChatResponse objects as the model produces them
314
+ # Streaming - yields ChatResponse objects as the model produces them
278
315
  for chunk in conversation.chat_stream("Hello!"):
279
316
  if chunk.text:
280
317
  print(chunk.text, end="")
@@ -297,10 +334,10 @@ for chunk in workforce.chat_stream(conversation.id, "How can you help me with th
297
334
 
298
335
  ## Links
299
336
 
300
- - **Dashboard** [app.agentx.so](https://app.agentx.so)
301
- - **Website** [agentx.so](https://www.agentx.so/)
302
- - **PyPI** [agentx-python](https://pypi.org/project/agentx-python/)
303
- - **Tracing docs** [TRACING.md](TRACING.md)
304
- - **Evaluations docs** [EVALUATIONS.md](EVALUATIONS.md)
305
- - **Monitor docs** [docs.agentx.so/sdk/monitor](https://docs.agentx.so/sdk/monitor)
306
- - **Self-host** [AgentX-trace-eval](https://github.com/AgentX-ai/AgentX-trace-eval)
337
+ - **Dashboard** - [app.agentx.so](https://app.agentx.so)
338
+ - **Website** - [agentx.so](https://www.agentx.so/)
339
+ - **PyPI** - [agentx-python](https://pypi.org/project/agentx-python/)
340
+ - **Tracing docs** - [TRACING.md](TRACING.md)
341
+ - **Evaluations docs** - [EVALUATIONS.md](EVALUATIONS.md)
342
+ - **Monitor docs** - [docs.agentx.so/sdk/monitor](https://docs.agentx.so/sdk/monitor)
343
+ - **Self-host** - [AgentX-trace-eval](https://github.com/AgentX-ai/AgentX-trace-eval)
@@ -54,6 +54,18 @@ class AgentX:
54
54
  workspace_id=self.workspace_id,
55
55
  )
56
56
 
57
+ from agentx.outcomes import OutcomesClient
58
+
59
+ # Report real, after-the-fact outcomes ("the ticket got reopened") against traces - the
60
+ # ground truth behind the dashboard's Judge Calibration card. Self-host only.
61
+ self.outcomes = OutcomesClient(api_key=self.api_key)
62
+
63
+ from agentx.feedback import FeedbackClient
64
+
65
+ # Forward end-user votes ("up"/"down") on traced responses - a "down" raises a signal
66
+ # directly, and every vote feeds Judge Calibration alongside outcomes. Self-host only.
67
+ self.feedback = FeedbackClient(api_key=self.api_key)
68
+
57
69
  _ingest_client = IngestClient(
58
70
  api_key=self.api_key,
59
71
  sdk_version=VERSION,
@@ -1,5 +1,5 @@
1
1
  """
2
- `agentx-trace-eval` thin launcher for AgentX's self-hostable governance engine (Trace,
2
+ `agentx-trace-eval` - thin launcher for AgentX's self-hostable governance engine (Trace,
3
3
  Evaluate, Monitor), published separately at github.com/AgentX-ai/AgentX-trace-eval (a Go CLI
4
4
  wrapping a Bun-compiled TypeScript engine, not Python). That compiled engine binary is tens of
5
5
  megabytes; most `pip install agentx-python` installs are just this SDK talking to the hosted
@@ -1,4 +1,4 @@
1
- """Minimal ANSI terminal helpers no external dependencies."""
1
+ """Minimal ANSI terminal helpers - no external dependencies."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
@@ -12,7 +12,7 @@ from agentx.evaluations.results import normalize_error, normalize_result
12
12
  class HttpEndpointAdapter:
13
13
  """
14
14
  Calls a user-hosted HTTP endpoint for each evaluation case.
15
- The SDK (running locally) makes the request the AgentX API never
15
+ The SDK (running locally) makes the request - the AgentX API never
16
16
  touches the customer's endpoint.
17
17
 
18
18
  The endpoint receives a POST with::
@@ -8,7 +8,7 @@ from agentx.evaluations.results import normalize_result
8
8
 
9
9
  class PrecomputedAdapter:
10
10
  """
11
- Adapter for pre-computed outputs useful when you already have agent
11
+ Adapter for pre-computed outputs - useful when you already have agent
12
12
  responses and just want AgentX to score them.
13
13
 
14
14
  Accepts a list or dict keyed by case_id::
@@ -57,7 +57,7 @@ class EvaluationsClient:
57
57
  raise AgentXAuthError("AGENTX_API_KEY is required")
58
58
  self._api_key = api_key
59
59
  self._sdk_version = sdk_version
60
- # Falls back to the caller's default workspace server-side when unset see
60
+ # Falls back to the caller's default workspace server-side when unset - see
61
61
  # _with_workspace(). Without this, dataset/settings/run creation silently land in
62
62
  # whatever workspace the API key's user defaults to, not the one the caller intended.
63
63
  self._workspace_id = workspace_id
@@ -139,7 +139,7 @@ class EvaluationsClient:
139
139
  # ------------------------------------------------------------------
140
140
 
141
141
  def list_models(self, provider: Optional[str] = None) -> List[ModelInfo]:
142
- """List the LLM models AgentX supports the same set selectable for
142
+ """List the LLM models AgentX supports - the same set selectable for
143
143
  the Sovereignty & Portability Index. Pass ``provider`` (e.g. "Google")
144
144
  to filter."""
145
145
  params = {"provider": provider} if provider else None
@@ -169,7 +169,7 @@ class EvaluationsClient:
169
169
  return Dataset(**data)
170
170
 
171
171
  # ------------------------------------------------------------------
172
- # Evaluation Settings endpoints standalone grading config, reusable
172
+ # Evaluation Settings endpoints - standalone grading config, reusable
173
173
  # across datasets.
174
174
  # ------------------------------------------------------------------
175
175
 
@@ -199,7 +199,7 @@ class EvaluationsClient:
199
199
  return EvaluationSettings(**data)
200
200
 
201
201
  # ------------------------------------------------------------------
202
- # Prompt registry endpoints see agentx.evaluations.prompts.PromptClient for the concept
202
+ # Prompt registry endpoints - see agentx.evaluations.prompts.PromptClient for the concept
203
203
  # (the external-agent analog to native autotune). Deliberately read-mostly: no publish here,
204
204
  # a new version only ever comes from the dashboard's human-approved propose/publish flow.
205
205
  # ------------------------------------------------------------------
@@ -265,6 +265,34 @@ class EvaluationsClient:
265
265
  "POST", f"/runs/{run_id}/finalize", json={"status": "completed"}
266
266
  )
267
267
 
268
+ def gate_run(
269
+ self,
270
+ run_id: str,
271
+ *,
272
+ fail_under: Optional[float] = None,
273
+ no_regression: bool = False,
274
+ tolerance: Optional[float] = None,
275
+ record: bool = True,
276
+ caller: Optional[str] = "sdk",
277
+ ) -> Dict[str, Any]:
278
+ # CI gate (self-host): pass/fail a finalized run against an absolute rating floor and/or
279
+ # the dataset's previous completed run. Recorded into gate history by default (the
280
+ # dashboard's CI page lists these); pass record=False for a preview that leaves no trace.
281
+ # `caller` is a free label shown in that history ("sdk", "github-actions", ...). See
282
+ # EvaluationRunContext.gate() for the CI-facing wrapper with printed verdicts.
283
+ params: Dict[str, Any] = {}
284
+ if fail_under is not None:
285
+ params["failUnder"] = fail_under
286
+ if no_regression:
287
+ params["noRegression"] = "true"
288
+ if tolerance is not None:
289
+ params["tolerance"] = tolerance
290
+ if record:
291
+ params["record"] = "true"
292
+ if caller:
293
+ params["caller"] = caller
294
+ return self._request("GET", f"/runs/{run_id}/gate", params=params)
295
+
268
296
  def analyze_run(
269
297
  self,
270
298
  run_id: str,
@@ -67,7 +67,7 @@ class DatasetBuilder:
67
67
  self._payload["bleuScore"] = {"enabled": True}
68
68
  if rouge_score:
69
69
  self._payload["rougeScore"] = {"enabled": True}
70
- # Sovereignty & Portability the models to compare on this dataset (use
70
+ # Sovereignty & Portability - the models to compare on this dataset (use
71
71
  # client.evaluations.list_models() to discover valid ids).
72
72
  if sovereignty_models:
73
73
  self._payload["sovereigntyIndex"] = {
@@ -61,7 +61,7 @@ class EvaluationSettingsBuilder:
61
61
  self._payload["bleuScore"] = {"enabled": True}
62
62
  if rouge_score:
63
63
  self._payload["rougeScore"] = {"enabled": True}
64
- # Sovereignty & Portability the models to compare when this config runs
64
+ # Sovereignty & Portability - the models to compare when this config runs
65
65
  # (use client.evaluations.list_models() to discover valid ids).
66
66
  if sovereignty_models:
67
67
  self._payload["sovereigntyIndex"] = {