agentx-python 0.8.5__tar.gz → 0.8.7__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 (90) hide show
  1. {agentx_python-0.8.5 → agentx_python-0.8.7}/PKG-INFO +1 -1
  2. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/client.py +6 -0
  3. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/datasets.py +31 -0
  4. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/models.py +5 -0
  5. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/client.py +27 -1
  6. agentx_python-0.8.7/agentx/monitor/rules.py +78 -0
  7. agentx_python-0.8.7/agentx/version.py +1 -0
  8. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/PKG-INFO +1 -1
  9. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/SOURCES.txt +1 -0
  10. agentx_python-0.8.5/agentx/version.py +0 -1
  11. {agentx_python-0.8.5 → agentx_python-0.8.7}/LICENSE +0 -0
  12. {agentx_python-0.8.5 → agentx_python-0.8.7}/README.md +0 -0
  13. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/__init__.py +0 -0
  14. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/agentx.py +0 -0
  15. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/cli.py +0 -0
  16. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/__init__.py +0 -0
  17. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/_term.py +0 -0
  18. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/adapters/__init__.py +0 -0
  19. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/adapters/http_endpoint.py +0 -0
  20. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/adapters/precomputed.py +0 -0
  21. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/adapters/raw.py +0 -0
  22. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/evaluation_settings.py +0 -0
  23. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/prompts.py +0 -0
  24. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/reporting.py +0 -0
  25. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/results.py +0 -0
  26. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/runner.py +0 -0
  27. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/tool_schemas.py +0 -0
  28. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/tracing.py +0 -0
  29. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/exceptions.py +0 -0
  30. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/export.py +0 -0
  31. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/feedback.py +0 -0
  32. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/__init__.py +0 -0
  33. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/_traced_call.py +0 -0
  34. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/anthropic.py +0 -0
  35. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/autogen.py +0 -0
  36. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/crewai.py +0 -0
  37. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/databricks.py +0 -0
  38. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/google_adk.py +0 -0
  39. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/google_genai.py +0 -0
  40. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/langchain.py +0 -0
  41. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/litellm.py +0 -0
  42. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/llamaindex.py +0 -0
  43. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/moveworks.py +0 -0
  44. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/openai.py +0 -0
  45. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/openai_agents.py +0 -0
  46. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/__init__.py +0 -0
  47. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/agents.py +0 -0
  48. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/judge_scorers.py +0 -0
  49. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/models.py +0 -0
  50. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/online_evaluators.py +0 -0
  51. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/patterns.py +0 -0
  52. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/profile.py +0 -0
  53. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/review_queue.py +0 -0
  54. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/scorers.py +0 -0
  55. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/sessions.py +0 -0
  56. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/signals.py +0 -0
  57. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/outcomes.py +0 -0
  58. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/projects.py +0 -0
  59. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/py.typed +0 -0
  60. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/resources/__init__.py +0 -0
  61. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/resources/agent.py +0 -0
  62. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/resources/conversation.py +0 -0
  63. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/resources/workforce.py +0 -0
  64. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/testing.py +0 -0
  65. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/traces.py +0 -0
  66. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/tracing/__init__.py +0 -0
  67. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/tracing/ci_types.py +0 -0
  68. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/tracing/eval_scope.py +0 -0
  69. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/tracing/ingest_client.py +0 -0
  70. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/tracing/tracer.py +0 -0
  71. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/util.py +0 -0
  72. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/dependency_links.txt +0 -0
  73. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/entry_points.txt +0 -0
  74. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/not-zip-safe +0 -0
  75. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/requires.txt +0 -0
  76. {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/top_level.txt +0 -0
  77. {agentx_python-0.8.5 → agentx_python-0.8.7}/setup.cfg +0 -0
  78. {agentx_python-0.8.5 → agentx_python-0.8.7}/setup.py +0 -0
  79. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_deep_dive_fixes.py +0 -0
  80. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_docs_match_sdk.py +0 -0
  81. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_eval_scope.py +0 -0
  82. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_integration.py +0 -0
  83. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_integrations.py +0 -0
  84. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_judge_scorers.py +0 -0
  85. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_pairwise.py +0 -0
  86. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_review_queue.py +0 -0
  87. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_runner_features.py +0 -0
  88. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_selfhost_analysis_fallback.py +0 -0
  89. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_span_tree.py +0 -0
  90. {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_testing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentx-python
3
- Version: 0.8.5
3
+ Version: 0.8.7
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
@@ -227,6 +227,12 @@ class EvaluationsClient:
227
227
  data = self._request("POST", "/datasets", json=self._with_workspace(payload))
228
228
  return Dataset(**data)
229
229
 
230
+ def delete_dataset(self, dataset_id: str) -> None:
231
+ """Deletes the dataset, its grading config, and both version histories. Past runs are
232
+ kept (their dataset reference degrades to a bare id). The engine refuses (409) when the
233
+ dataset's config is attached to a live scorer."""
234
+ self._request("DELETE", f"/datasets/{dataset_id}")
235
+
230
236
  def list_datasets(self) -> List[Dataset]:
231
237
  data = self._request("GET", "/datasets", params=self._workspace_params())
232
238
  return [
@@ -333,6 +333,37 @@ class DatasetClient:
333
333
  def list(self) -> List[Dataset]:
334
334
  return self._client.list_datasets()
335
335
 
336
+ def delete(self, dataset_id: str) -> None:
337
+ """Delete a dataset (and its grading config + version histories; past runs are kept)."""
338
+ self._client.delete_dataset(dataset_id)
339
+
340
+ def import_dataset(self, source: Any, name: Optional[str] = None) -> Dataset:
341
+ """Create a NEW dataset from an exported/fetched one (a ``Dataset`` from ``get()``, or
342
+ the engine's wire/NDJSON-export dict). Always a copy with a fresh id - never a
343
+ restore-in-place. ``name`` optionally renames the copy."""
344
+ wire: Dict[str, Any] = (
345
+ source.model_dump(by_alias=True) if hasattr(source, "model_dump") else dict(source)
346
+ )
347
+ payload: Dict[str, Any] = {
348
+ "name": name or wire.get("name") or "Imported dataset",
349
+ "questions": wire.get("questions") or [],
350
+ }
351
+ for key in (
352
+ "description",
353
+ "numberOfRequests",
354
+ "acceptanceCriteria",
355
+ "rejectionCriteria",
356
+ "evaluationCriteria",
357
+ "vectorSimilarity",
358
+ "jaccardSimilarity",
359
+ "bleuScore",
360
+ "rougeScore",
361
+ "codeScorers",
362
+ ):
363
+ if wire.get(key) is not None:
364
+ payload[key] = wire[key]
365
+ return self._client.create_dataset(payload)
366
+
336
367
 
337
368
  # ---------------------------------------------------------------------------
338
369
  # Helpers
@@ -415,6 +415,11 @@ class RunResultRow(BaseModel):
415
415
 
416
416
  rating: Optional[float] = None
417
417
  justification: Optional[str] = None
418
+ # scored | skipped (the judge could not score this row) | failed (the submitted result
419
+ # carried an error). A skipped row has rating None - a fact about the judge, not a 0.
420
+ status: Optional[str] = None
421
+ question_index: Optional[int] = Field(default=None, alias="questionIndex")
422
+ run_number: Optional[int] = Field(default=None, alias="runNumber")
418
423
  question_text: Optional[str] = Field(default=None, alias="questionText")
419
424
  response: Optional[str] = None
420
425
  trace_id: Optional[str] = Field(default=None, alias="traceId")
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import logging
4
4
  import os
5
5
  import time
6
- from typing import Any, List, Optional
6
+ from typing import Any, Dict, List, Optional
7
7
 
8
8
  import requests
9
9
 
@@ -116,6 +116,10 @@ class MonitorClient:
116
116
  # The human-review queue (list / queue / label / dismiss) - what makes the
117
117
  # label-and-calibrate loop scriptable instead of dashboard-only.
118
118
  self.review_queue = ReviewQueueClient(self)
119
+ from agentx.monitor.rules import MonitorRulesClient
120
+
121
+ # Automation rules: route matching traffic into review / a dataset / a webhook.
122
+ self.rules = MonitorRulesClient(self)
119
123
  from agentx.monitor.scorers import ScorersClient
120
124
  # Scorers-catalog administration as code: template enable/disable, code/external scorer
121
125
  # CRUD and dry runs - full parity with the dashboard's Scorers page (P1.3).
@@ -264,6 +268,28 @@ class MonitorClient:
264
268
  plus deltas vs the prior window and the run-outcome breakdown."""
265
269
  return self._request("GET", "/kpis", params={"window": window})
266
270
 
271
+ def topics(self, window: str = "7d") -> dict:
272
+ """The Topics view's data over a window ("24h", "7d", "30d"): LLM-classified themes of
273
+ sampled production traffic with per-topic counts and sentiment. Empty until Topics is
274
+ enabled project-wide via ``set_topics(True)`` - classification spends one judge call
275
+ per sampled trace, so it is off by default."""
276
+ return self._request(
277
+ "GET", "/agent-monitoring/topics",
278
+ base=self._api_root(), params={"window": window},
279
+ )
280
+
281
+ def set_topics(self, enabled: bool, sample_rate: Optional[float] = None) -> dict:
282
+ """Turn Topics classification on/off for the whole project (Platform Settings >
283
+ Monitoring Defaults). ``sample_rate`` (0-1) optionally bounds what fraction of traffic
284
+ is classified - each classified trace costs one judge call."""
285
+ payload: Dict[str, Any] = {"topicsEnabled": enabled}
286
+ if sample_rate is not None:
287
+ payload["topicsSampleRate"] = sample_rate
288
+ return self._request(
289
+ "PUT", "/agent-monitoring/settings/monitoring-defaults",
290
+ base=self._api_root(), json=payload,
291
+ )
292
+
267
293
  def calibration(self, window: str = "7d") -> "CalibrationSummary":
268
294
  """Project-level judge calibration over a window ("24h", "7d", or "30d"): how often
269
295
  AgentX's own verdicts agreed with real-world ground truth reported later (ops outcomes
@@ -0,0 +1,78 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from typing import Any, Dict, List, Optional, TYPE_CHECKING
5
+
6
+ if TYPE_CHECKING:
7
+ from agentx.monitor.client import MonitorClient
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ class MonitorRule(dict):
13
+ """Wire object for one automation rule (dict subclass so unknown fields round-trip)."""
14
+
15
+ @property
16
+ def id(self) -> str:
17
+ return self["_id"]
18
+
19
+ @property
20
+ def enabled(self) -> bool:
21
+ return bool(self.get("enabled"))
22
+
23
+
24
+ class MonitorRulesClient:
25
+ """Surfaced as ``client.monitor.rules``: automation rules, evaluated on every ingested root
26
+ trace. A RULE routes traffic somewhere (it never scores): ``action`` is one of
27
+
28
+ - ``"review"`` - sample matching traces into the human-review queue (the stream that feeds
29
+ judge calibration and tuning),
30
+ - ``"dataset"`` - append matching traces as cases on a dataset (``action_config
31
+ {"datasetId": ...}``),
32
+ - ``"webhook"`` - POST the matching trace to your URL (``action_config {"url": ...}``).
33
+
34
+ ``filter`` narrows what matches: ``{"model": ..., "status": "error"|"any", "contains": ...,
35
+ "scopeMode": "all"|"selected", "agentIds": [...]}``; ``sample_rate`` (0-1, default 1)
36
+ down-samples the matches.
37
+ """
38
+
39
+ def __init__(self, client: "MonitorClient"):
40
+ self._client = client
41
+
42
+ def _request(self, method: str, path: str, **kwargs: Any) -> Any:
43
+ return self._client._request(method, path, base=self._client._api_root(), **kwargs)
44
+
45
+ def list(self) -> List[MonitorRule]:
46
+ data = self._request("GET", "/agent-monitoring/rules")
47
+ return [MonitorRule(r) for r in data.get("rules", [])]
48
+
49
+ def create(
50
+ self,
51
+ name: str,
52
+ action: str,
53
+ *,
54
+ filter: Optional[Dict[str, Any]] = None,
55
+ sample_rate: Optional[float] = None,
56
+ action_config: Optional[Dict[str, Any]] = None,
57
+ enabled: bool = True,
58
+ ) -> MonitorRule:
59
+ payload: Dict[str, Any] = {"name": name, "action": action, "enabled": enabled}
60
+ if filter is not None:
61
+ payload["filter"] = filter
62
+ if sample_rate is not None:
63
+ payload["sampleRate"] = sample_rate
64
+ if action_config is not None:
65
+ payload["actionConfig"] = action_config
66
+ data = self._request("POST", "/agent-monitoring/rules", json=payload)
67
+ return MonitorRule(data.get("rule", data))
68
+
69
+ def update(self, rule_id: str, **fields: Any) -> MonitorRule:
70
+ """Sparse update. snake_case keys are mapped to the wire (``sample_rate`` ->
71
+ ``sampleRate``, ``action_config`` -> ``actionConfig``)."""
72
+ aliases = {"sample_rate": "sampleRate", "action_config": "actionConfig"}
73
+ payload = {aliases.get(k, k): v for k, v in fields.items()}
74
+ data = self._request("PUT", f"/agent-monitoring/rules/{rule_id}", json=payload)
75
+ return MonitorRule(data.get("rule", data))
76
+
77
+ def delete(self, rule_id: str) -> None:
78
+ self._request("DELETE", f"/agent-monitoring/rules/{rule_id}")
@@ -0,0 +1 @@
1
+ VERSION = "0.8.7"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentx-python
3
- Version: 0.8.5
3
+ Version: 0.8.7
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
@@ -53,6 +53,7 @@ agentx/monitor/online_evaluators.py
53
53
  agentx/monitor/patterns.py
54
54
  agentx/monitor/profile.py
55
55
  agentx/monitor/review_queue.py
56
+ agentx/monitor/rules.py
56
57
  agentx/monitor/scorers.py
57
58
  agentx/monitor/sessions.py
58
59
  agentx/monitor/signals.py
@@ -1 +0,0 @@
1
- VERSION = "0.8.5"
File without changes
File without changes
File without changes
File without changes