agentx-python 0.6.6__tar.gz → 0.6.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.6.6 → agentx_python-0.6.7}/PKG-INFO +6 -1
- {agentx_python-0.6.6 → agentx_python-0.6.7}/README.md +5 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/_term.py +6 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/client.py +23 -2
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/models.py +63 -5
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/runner.py +70 -4
- agentx_python-0.6.7/agentx/version.py +1 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx_python.egg-info/PKG-INFO +6 -1
- agentx_python-0.6.6/agentx/version.py +0 -1
- {agentx_python-0.6.6 → agentx_python-0.6.7}/LICENSE +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/__init__.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/agentx.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/__init__.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/adapters/__init__.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/adapters/http_endpoint.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/adapters/precomputed.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/adapters/raw.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/datasets.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/evaluation_settings.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/redaction.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/reporting.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/results.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/evaluations/tracing.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/exceptions.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/integrations/__init__.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/integrations/_perf.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/integrations/anthropic.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/integrations/crewai.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/integrations/google_adk.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/integrations/google_genai.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/integrations/langchain.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/integrations/openai_agents.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/monitor/__init__.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/monitor/client.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/monitor/models.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/monitor/patterns.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/py.typed +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/resources/__init__.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/resources/agent.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/resources/conversation.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/resources/workforce.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/tracing/__init__.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/tracing/ci_types.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/tracing/ingest_client.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/tracing/tracer.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx/util.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx_python.egg-info/SOURCES.txt +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx_python.egg-info/dependency_links.txt +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx_python.egg-info/not-zip-safe +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx_python.egg-info/requires.txt +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/agentx_python.egg-info/top_level.txt +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/setup.cfg +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/setup.py +0 -0
- {agentx_python-0.6.6 → agentx_python-0.6.7}/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.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
|
|
@@ -286,8 +286,13 @@ report = (
|
|
|
286
286
|
print(report.average_rating) # LLM-graded score, 0–10
|
|
287
287
|
print(report.cosine_similarity) # embedding cosine, 0–1 (None if not enabled)
|
|
288
288
|
print(report.jaccard_similarity) # token-set overlap, 0–1 (None if not enabled)
|
|
289
|
+
|
|
290
|
+
print(report.summary) # AI-generated narrative from .analyze()
|
|
291
|
+
print(report.recommendations) # list of prioritized, actionable fixes
|
|
289
292
|
```
|
|
290
293
|
|
|
294
|
+
`.analyze()` also generates a full qualitative report (strengths, weaknesses, instruction adherence, reasoning quality, and recommendations), running the same durable, multi-judge pipeline as the dashboard's "Analyze" button. `analyze(mode=..., quality_mode=..., judges=[...])` controls how items are scored and by which models. See [AI analysis report](EVALUATIONS.md#ai-analysis-report) in the full guide for the complete field and parameter reference.
|
|
295
|
+
|
|
291
296
|
See **[EVALUATIONS.md](EVALUATIONS.md)** for the full guide — dataset builder, framework adapters, similarity metrics, and the complete API reference.
|
|
292
297
|
|
|
293
298
|
---
|
|
@@ -238,8 +238,13 @@ report = (
|
|
|
238
238
|
print(report.average_rating) # LLM-graded score, 0–10
|
|
239
239
|
print(report.cosine_similarity) # embedding cosine, 0–1 (None if not enabled)
|
|
240
240
|
print(report.jaccard_similarity) # token-set overlap, 0–1 (None if not enabled)
|
|
241
|
+
|
|
242
|
+
print(report.summary) # AI-generated narrative from .analyze()
|
|
243
|
+
print(report.recommendations) # list of prioritized, actionable fixes
|
|
241
244
|
```
|
|
242
245
|
|
|
246
|
+
`.analyze()` also generates a full qualitative report (strengths, weaknesses, instruction adherence, reasoning quality, and recommendations), running the same durable, multi-judge pipeline as the dashboard's "Analyze" button. `analyze(mode=..., quality_mode=..., judges=[...])` controls how items are scored and by which models. See [AI analysis report](EVALUATIONS.md#ai-analysis-report) in the full guide for the complete field and parameter reference.
|
|
247
|
+
|
|
243
248
|
See **[EVALUATIONS.md](EVALUATIONS.md)** for the full guide — dataset builder, framework adapters, similarity metrics, and the complete API reference.
|
|
244
249
|
|
|
245
250
|
---
|
|
@@ -71,6 +71,12 @@ class Spinner:
|
|
|
71
71
|
self._thread.start()
|
|
72
72
|
return self
|
|
73
73
|
|
|
74
|
+
def update(self, message: str) -> None:
|
|
75
|
+
"""Change the displayed message while the spinner keeps running."""
|
|
76
|
+
self._message = message
|
|
77
|
+
if not _IS_TTY:
|
|
78
|
+
print(f" {message}...", flush=True)
|
|
79
|
+
|
|
74
80
|
def __exit__(self, *_) -> None:
|
|
75
81
|
if not _IS_TTY:
|
|
76
82
|
return
|
|
@@ -9,6 +9,7 @@ from typing import Any, Dict, List, Optional
|
|
|
9
9
|
import requests
|
|
10
10
|
|
|
11
11
|
from agentx.evaluations.models import (
|
|
12
|
+
AnalysisStatus,
|
|
12
13
|
BatchAppendResponse,
|
|
13
14
|
Dataset,
|
|
14
15
|
EvaluationResult,
|
|
@@ -238,8 +239,28 @@ class EvaluationsClient:
|
|
|
238
239
|
"POST", f"/runs/{run_id}/finalize", json={"status": "completed"}
|
|
239
240
|
)
|
|
240
241
|
|
|
241
|
-
def analyze_run(
|
|
242
|
-
|
|
242
|
+
def analyze_run(
|
|
243
|
+
self,
|
|
244
|
+
run_id: str,
|
|
245
|
+
mode: Optional[str] = None,
|
|
246
|
+
quality_mode: Optional[str] = None,
|
|
247
|
+
judges: Optional[List[str]] = None,
|
|
248
|
+
) -> Dict[str, Any]:
|
|
249
|
+
# Starts the durable analysis job and returns immediately (e.g. {"jobId": ..., "status":
|
|
250
|
+
# "pending"}); poll get_analysis_status() until it reaches a terminal status, then call
|
|
251
|
+
# get_report(). mode/quality_mode/judges mirror the dashboard's AnalyzeEvaluationRequest.
|
|
252
|
+
payload: Dict[str, Any] = {}
|
|
253
|
+
if mode is not None:
|
|
254
|
+
payload["mode"] = mode
|
|
255
|
+
if quality_mode is not None:
|
|
256
|
+
payload["qualityMode"] = quality_mode
|
|
257
|
+
if judges is not None:
|
|
258
|
+
payload["judges"] = [{"model": m} for m in judges]
|
|
259
|
+
return self._request("POST", f"/runs/{run_id}/analyze", json=payload, timeout=30)
|
|
260
|
+
|
|
261
|
+
def get_analysis_status(self, run_id: str) -> AnalysisStatus:
|
|
262
|
+
data = self._request("GET", f"/runs/{run_id}/analyze-status")
|
|
263
|
+
return AnalysisStatus(**data)
|
|
243
264
|
|
|
244
265
|
def get_run(self, run_id: str) -> Dict[str, Any]:
|
|
245
266
|
return self._request("GET", f"/runs/{run_id}")
|
|
@@ -438,11 +438,9 @@ class SovereigntyIndex(BaseModel):
|
|
|
438
438
|
extra = "ignore"
|
|
439
439
|
|
|
440
440
|
|
|
441
|
-
class
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
status: str = "completed"
|
|
445
|
-
statistics: Optional[ReportStatistics] = None
|
|
441
|
+
class AnalysisResult(BaseModel):
|
|
442
|
+
"""Shared qualitative-report fields, produced by ``client.evaluations.run(...).analyze()``."""
|
|
443
|
+
|
|
446
444
|
summary: Optional[str] = None
|
|
447
445
|
consistency_score: Optional[float] = Field(default=None, alias="consistencyScore")
|
|
448
446
|
instruction_adherence: Optional[ReportInstructionAdherence] = Field(
|
|
@@ -461,6 +459,17 @@ class Report(BaseModel):
|
|
|
461
459
|
weaknesses: List[str] = Field(default_factory=list)
|
|
462
460
|
overall_rating: Optional[str] = Field(default=None, alias="overallRating")
|
|
463
461
|
recommendations: List[ReportRecommendation] = Field(default_factory=list)
|
|
462
|
+
|
|
463
|
+
class Config:
|
|
464
|
+
populate_by_name = True
|
|
465
|
+
extra = "ignore"
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
class Report(AnalysisResult):
|
|
469
|
+
run_id: str = Field(alias="runId")
|
|
470
|
+
dataset_id: str = Field(alias="datasetId")
|
|
471
|
+
status: str = "completed"
|
|
472
|
+
statistics: Optional[ReportStatistics] = None
|
|
464
473
|
low_scoring_cases: List[Dict[str, Any]] = Field(
|
|
465
474
|
default_factory=list, alias="lowScoringCases"
|
|
466
475
|
)
|
|
@@ -548,3 +557,52 @@ class Report(BaseModel):
|
|
|
548
557
|
def average_rating(self) -> Optional[float]:
|
|
549
558
|
"""Convenience accessor matching cosine_similarity / jaccard_similarity."""
|
|
550
559
|
return self.statistics.average_rating if self.statistics is not None else None
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
class AnalysisLevelProgress(BaseModel):
|
|
563
|
+
total: int = 0
|
|
564
|
+
completed: int = 0
|
|
565
|
+
failed: int = 0
|
|
566
|
+
percentage: int = 0
|
|
567
|
+
|
|
568
|
+
class Config:
|
|
569
|
+
extra = "ignore"
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
class AnalysisProgress(BaseModel):
|
|
573
|
+
overall_percentage: int = Field(default=0, alias="overallPercentage")
|
|
574
|
+
current_level: Optional[str] = Field(default=None, alias="currentLevel")
|
|
575
|
+
levels: Dict[str, AnalysisLevelProgress] = Field(default_factory=dict)
|
|
576
|
+
|
|
577
|
+
class Config:
|
|
578
|
+
populate_by_name = True
|
|
579
|
+
extra = "ignore"
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
class AnalysisFailureReason(BaseModel):
|
|
583
|
+
code: str
|
|
584
|
+
message: str
|
|
585
|
+
retryable: bool = False
|
|
586
|
+
|
|
587
|
+
class Config:
|
|
588
|
+
extra = "ignore"
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
class AnalysisStatus(BaseModel):
|
|
592
|
+
"""Returned by ``client.evaluations.run(...).analyze()``'s polling loop
|
|
593
|
+
(``EvaluationsClient.get_analysis_status``). ``status`` is terminal once it's one of
|
|
594
|
+
"completed", "partially_failed", or "failed"."""
|
|
595
|
+
|
|
596
|
+
job_id: Optional[str] = Field(default=None, alias="jobId")
|
|
597
|
+
status: str = "not_started"
|
|
598
|
+
progress: AnalysisProgress = Field(default_factory=AnalysisProgress)
|
|
599
|
+
failure_reason: Optional[AnalysisFailureReason] = Field(default=None, alias="failureReason")
|
|
600
|
+
warnings: List[Dict[str, Any]] = Field(default_factory=list)
|
|
601
|
+
|
|
602
|
+
class Config:
|
|
603
|
+
populate_by_name = True
|
|
604
|
+
extra = "ignore"
|
|
605
|
+
|
|
606
|
+
@property
|
|
607
|
+
def is_terminal(self) -> bool:
|
|
608
|
+
return self.status in ("completed", "partially_failed", "failed")
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
import time
|
|
4
5
|
import uuid
|
|
5
6
|
from typing import Any, Callable, Dict, List, Optional, Set, Union
|
|
6
7
|
|
|
@@ -9,6 +10,7 @@ from agentx.evaluations.adapters.precomputed import PrecomputedAdapter
|
|
|
9
10
|
from agentx.evaluations.adapters.http_endpoint import HttpEndpointAdapter
|
|
10
11
|
from agentx.evaluations.client import EvaluationsClient
|
|
11
12
|
from agentx.evaluations.models import (
|
|
13
|
+
AnalysisStatus,
|
|
12
14
|
Dataset,
|
|
13
15
|
EvaluationCase,
|
|
14
16
|
EvaluationResult,
|
|
@@ -43,6 +45,15 @@ AdapterLike = Union[
|
|
|
43
45
|
HttpEndpointAdapter,
|
|
44
46
|
]
|
|
45
47
|
|
|
48
|
+
_ANALYSIS_LEVEL_LABELS = {
|
|
49
|
+
"l1_score": "scoring responses",
|
|
50
|
+
"l2_question_reduce": "reducing questions",
|
|
51
|
+
"l3_cluster_reduce": "reducing clusters",
|
|
52
|
+
"l4_final_reduce": "writing final report",
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
_DEFAULT_JUDGE_MODEL = "gpt-5.5"
|
|
56
|
+
|
|
46
57
|
|
|
47
58
|
class EvaluationRunContext:
|
|
48
59
|
"""
|
|
@@ -228,12 +239,61 @@ class EvaluationRunContext:
|
|
|
228
239
|
# Step 3: analyze + report
|
|
229
240
|
# ------------------------------------------------------------------
|
|
230
241
|
|
|
231
|
-
def analyze(
|
|
242
|
+
def analyze(
|
|
243
|
+
self,
|
|
244
|
+
mode: Optional[str] = None,
|
|
245
|
+
quality_mode: Optional[str] = None,
|
|
246
|
+
judges: Optional[List[str]] = None,
|
|
247
|
+
poll_interval: float = 5.0,
|
|
248
|
+
timeout: float = 1800.0,
|
|
249
|
+
) -> Report:
|
|
250
|
+
"""Generate the qualitative AI analysis report.
|
|
251
|
+
|
|
252
|
+
Runs the same durable, multi-stage pipeline as the dashboard's "Analyze" button: each
|
|
253
|
+
response is scored by 1-3 LLM judges (``judges``), then reduced into the final report.
|
|
254
|
+
This starts the job and polls until it finishes, which can take noticeably longer than a
|
|
255
|
+
single LLM call for larger runs.
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
mode: "auto" (default), "sync", or "batch" - how item scoring executes server-side.
|
|
259
|
+
quality_mode: "quality_first" or "balanced" - how many items get a second/third judge.
|
|
260
|
+
judges: 1-3 model ids, e.g. ``["gpt-5.5", "claude-opus-4-8"]``. Defaults to a single
|
|
261
|
+
judge, ``["gpt-5.5"]``, rather than the dashboard's 3-judge default - SDK runs are
|
|
262
|
+
typically lighter-weight, quick-start evaluations.
|
|
263
|
+
poll_interval: seconds between status checks while waiting.
|
|
264
|
+
timeout: give up waiting after this many seconds (the job keeps running server-side;
|
|
265
|
+
call ``get_report()`` later to check on it).
|
|
266
|
+
"""
|
|
267
|
+
if judges is not None and not (1 <= len(judges) <= 3):
|
|
268
|
+
raise ValueError("judges must contain 1-3 model ids")
|
|
269
|
+
resolved_judges = judges if judges is not None else [_DEFAULT_JUDGE_MODEL]
|
|
270
|
+
|
|
232
271
|
print()
|
|
233
|
-
with Spinner("Analyzing — AI is reviewing your results"):
|
|
272
|
+
with Spinner("Analyzing — AI is reviewing your results") as spinner:
|
|
234
273
|
try:
|
|
235
|
-
self._client.analyze_run(
|
|
236
|
-
|
|
274
|
+
self._client.analyze_run(
|
|
275
|
+
self._run.run_id,
|
|
276
|
+
mode=mode,
|
|
277
|
+
quality_mode=quality_mode,
|
|
278
|
+
judges=resolved_judges,
|
|
279
|
+
)
|
|
280
|
+
deadline = time.monotonic() + timeout
|
|
281
|
+
status = self._client.get_analysis_status(self._run.run_id)
|
|
282
|
+
while not status.is_terminal and time.monotonic() < deadline:
|
|
283
|
+
level = _ANALYSIS_LEVEL_LABELS.get(status.progress.current_level, "")
|
|
284
|
+
spinner.update(
|
|
285
|
+
f"Analyzing, {level + ' ' if level else ''}{status.progress.overall_percentage}%"
|
|
286
|
+
)
|
|
287
|
+
time.sleep(poll_interval)
|
|
288
|
+
status = self._client.get_analysis_status(self._run.run_id)
|
|
289
|
+
|
|
290
|
+
if not status.is_terminal:
|
|
291
|
+
print(f" {yellow('!')} Still running after {int(timeout)}s, check the dashboard for status")
|
|
292
|
+
elif status.status == "failed":
|
|
293
|
+
reason = status.failure_reason.message if status.failure_reason else "unknown error"
|
|
294
|
+
print(f" {red('✗')} Analyze failed: {dim(reason)}")
|
|
295
|
+
else:
|
|
296
|
+
print(f" {green('✓')} Analysis complete")
|
|
237
297
|
except Exception as exc:
|
|
238
298
|
print(f" {red('✗')} Analyze failed: {dim(str(exc))}")
|
|
239
299
|
logger.warning("Analyze request failed: %s", exc)
|
|
@@ -280,6 +340,12 @@ class EvaluationsRunner:
|
|
|
280
340
|
against."""
|
|
281
341
|
return self._client.list_models(provider)
|
|
282
342
|
|
|
343
|
+
def get_analysis_status(self, run_id: str) -> AnalysisStatus:
|
|
344
|
+
"""Check on an in-progress ``.analyze()`` job by run id, without needing
|
|
345
|
+
the ``EvaluationRunContext`` that started it (e.g. from a separate
|
|
346
|
+
script execution)."""
|
|
347
|
+
return self._client.get_analysis_status(run_id)
|
|
348
|
+
|
|
283
349
|
def run(
|
|
284
350
|
self,
|
|
285
351
|
dataset_id: str,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = "0.6.7"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentx-python
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.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
|
|
@@ -286,8 +286,13 @@ report = (
|
|
|
286
286
|
print(report.average_rating) # LLM-graded score, 0–10
|
|
287
287
|
print(report.cosine_similarity) # embedding cosine, 0–1 (None if not enabled)
|
|
288
288
|
print(report.jaccard_similarity) # token-set overlap, 0–1 (None if not enabled)
|
|
289
|
+
|
|
290
|
+
print(report.summary) # AI-generated narrative from .analyze()
|
|
291
|
+
print(report.recommendations) # list of prioritized, actionable fixes
|
|
289
292
|
```
|
|
290
293
|
|
|
294
|
+
`.analyze()` also generates a full qualitative report (strengths, weaknesses, instruction adherence, reasoning quality, and recommendations), running the same durable, multi-judge pipeline as the dashboard's "Analyze" button. `analyze(mode=..., quality_mode=..., judges=[...])` controls how items are scored and by which models. See [AI analysis report](EVALUATIONS.md#ai-analysis-report) in the full guide for the complete field and parameter reference.
|
|
295
|
+
|
|
291
296
|
See **[EVALUATIONS.md](EVALUATIONS.md)** for the full guide — dataset builder, framework adapters, similarity metrics, and the complete API reference.
|
|
292
297
|
|
|
293
298
|
---
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VERSION = "0.6.6"
|
|
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
|