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.
- {agentx_python-0.8.5 → agentx_python-0.8.7}/PKG-INFO +1 -1
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/client.py +6 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/datasets.py +31 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/models.py +5 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/client.py +27 -1
- agentx_python-0.8.7/agentx/monitor/rules.py +78 -0
- agentx_python-0.8.7/agentx/version.py +1 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/PKG-INFO +1 -1
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/SOURCES.txt +1 -0
- agentx_python-0.8.5/agentx/version.py +0 -1
- {agentx_python-0.8.5 → agentx_python-0.8.7}/LICENSE +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/README.md +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/__init__.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/agentx.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/cli.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/__init__.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/_term.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/adapters/__init__.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/adapters/http_endpoint.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/adapters/precomputed.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/adapters/raw.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/evaluation_settings.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/prompts.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/reporting.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/results.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/runner.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/tool_schemas.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/evaluations/tracing.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/exceptions.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/export.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/feedback.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/__init__.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/_traced_call.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/anthropic.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/autogen.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/crewai.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/databricks.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/google_adk.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/google_genai.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/langchain.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/litellm.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/llamaindex.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/moveworks.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/openai.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/integrations/openai_agents.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/__init__.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/agents.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/judge_scorers.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/models.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/online_evaluators.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/patterns.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/profile.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/review_queue.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/scorers.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/sessions.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/monitor/signals.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/outcomes.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/projects.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/py.typed +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/resources/__init__.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/resources/agent.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/resources/conversation.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/resources/workforce.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/testing.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/traces.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/tracing/__init__.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/tracing/ci_types.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/tracing/eval_scope.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/tracing/ingest_client.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/tracing/tracer.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx/util.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/dependency_links.txt +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/entry_points.txt +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/not-zip-safe +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/requires.txt +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/agentx_python.egg-info/top_level.txt +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/setup.cfg +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/setup.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_deep_dive_fixes.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_docs_match_sdk.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_eval_scope.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_integration.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_integrations.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_judge_scorers.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_pairwise.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_review_queue.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_runner_features.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_selfhost_analysis_fallback.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_span_tree.py +0 -0
- {agentx_python-0.8.5 → agentx_python-0.8.7}/tests/test_testing.py +0 -0
|
@@ -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 +0,0 @@
|
|
|
1
|
-
VERSION = "0.8.5"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|