agentx-python 0.8.16__tar.gz → 0.8.18__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.16/agentx_python.egg-info → agentx_python-0.8.18}/PKG-INFO +1 -1
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/datasets.py +1 -1
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/evaluation_settings.py +1 -1
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/models.py +2 -2
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/runner.py +5 -8
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/client.py +30 -5
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/patterns.py +4 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/scorer_groups.py +4 -2
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/sessions.py +13 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/version.py +2 -2
- {agentx_python-0.8.16 → agentx_python-0.8.18/agentx_python.egg-info}/PKG-INFO +1 -1
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_integrations.py +3 -1
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_selfhost_analysis_fallback.py +8 -2
- {agentx_python-0.8.16 → agentx_python-0.8.18}/LICENSE +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/README.md +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/__init__.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/agentx.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/cli.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/__init__.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/_term.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/adapters/__init__.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/adapters/http_endpoint.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/adapters/precomputed.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/adapters/raw.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/client.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/prompts.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/reporting.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/results.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/tool_schemas.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/evaluations/tracing.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/exceptions.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/export.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/feedback.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/__init__.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/_traced_call.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/anthropic.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/autogen.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/crewai.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/databricks.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/google_adk.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/google_genai.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/langchain.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/litellm.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/llamaindex.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/moveworks.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/openai.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/integrations/openai_agents.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/__init__.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/agents.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/improvement_groups.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/judge_scorers.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/models.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/online_evaluators.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/profile.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/review_queue.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/rules.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/scorers.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/monitor/signals.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/outcomes.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/projects.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/py.typed +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/resources/__init__.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/resources/agent.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/resources/conversation.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/resources/workforce.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/testing.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/traces.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/tracing/__init__.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/tracing/ci_types.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/tracing/eval_scope.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/tracing/framework_detect.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/tracing/ingest_client.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/tracing/tracer.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx/util.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx_python.egg-info/SOURCES.txt +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx_python.egg-info/dependency_links.txt +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx_python.egg-info/entry_points.txt +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx_python.egg-info/not-zip-safe +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx_python.egg-info/requires.txt +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/agentx_python.egg-info/top_level.txt +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/setup.cfg +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/setup.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_cli_launcher.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_deep_dive_fixes.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_docs_match_sdk.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_eval_scope.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_framework_detect.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_integration.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_judge_scorers.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_multi_judge.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_pairwise.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_review_queue.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_runner_features.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_selfhost_compat.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_span_tree.py +0 -0
- {agentx_python-0.8.16 → agentx_python-0.8.18}/tests/test_testing.py +0 -0
|
@@ -48,7 +48,7 @@ class DatasetBuilder:
|
|
|
48
48
|
"questions": [],
|
|
49
49
|
}
|
|
50
50
|
# LLM-as-judge overrides for this dataset's own grading config. Omit either to keep the
|
|
51
|
-
# server default (raw prompt template /
|
|
51
|
+
# server default (raw prompt template / gpt-5.6-luna, see EVALUATIONS.md). judge_model
|
|
52
52
|
# must be one of client.evaluations.list_models() (OpenAI or Anthropic).
|
|
53
53
|
if judge_prompt is not None:
|
|
54
54
|
self._payload["judgePrompt"] = judge_prompt
|
|
@@ -45,7 +45,7 @@ class EvaluationSettingsBuilder:
|
|
|
45
45
|
"evaluationCriteria": evaluation_criteria,
|
|
46
46
|
}
|
|
47
47
|
# LLM-as-judge overrides. Omit either to keep the server default (raw prompt template /
|
|
48
|
-
#
|
|
48
|
+
# gpt-5.6-luna, see EVALUATIONS.md). judge_model must be one of
|
|
49
49
|
# client.evaluations.list_models() (OpenAI or Anthropic).
|
|
50
50
|
if judge_prompt is not None:
|
|
51
51
|
self._payload["judgePrompt"] = judge_prompt
|
|
@@ -113,8 +113,8 @@ class EvaluationSettings(BaseModel):
|
|
|
113
113
|
evaluation_criteria: Optional[str] = Field(default=None, alias="evaluationCriteria")
|
|
114
114
|
# Custom code scorers on this scorer's offline profile - [{ id, name, code, enabled }].
|
|
115
115
|
code_scorers: Optional[List[Dict[str, Any]]] = Field(default=None, alias="codeScorers")
|
|
116
|
-
# LLM-as-judge overrides. None means "use the server default" (raw prompt template /
|
|
117
|
-
# gpt-5.
|
|
116
|
+
# LLM-as-judge overrides. None means "use the server default" (raw prompt template /
|
|
117
|
+
# gpt-5.6-luna). See client.evaluations.settings.builder(judge_prompt=..., judge_model=...).
|
|
118
118
|
judge_prompt: Optional[str] = Field(default=None, alias="judgePrompt")
|
|
119
119
|
judge_model: Optional[str] = Field(default=None, alias="judgeModel")
|
|
120
120
|
status: str = "published"
|
|
@@ -63,9 +63,6 @@ _ANALYSIS_LEVEL_LABELS = {
|
|
|
63
63
|
"l4_final_reduce": "writing final report",
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
_DEFAULT_JUDGE_MODEL = "gpt-5.5"
|
|
67
|
-
|
|
68
|
-
|
|
69
66
|
class GateResult:
|
|
70
67
|
"""Wire result of the CI gate (GET /runs/:id/gate) with attribute access for the fields a
|
|
71
68
|
CI script actually branches on."""
|
|
@@ -456,16 +453,16 @@ class EvaluationRunContext:
|
|
|
456
453
|
Args:
|
|
457
454
|
mode: "auto" (default), "sync", or "batch" - how item scoring executes server-side.
|
|
458
455
|
quality_mode: "quality_first" or "balanced" - how many items get a second/third judge.
|
|
459
|
-
judges: 1-3 model ids
|
|
460
|
-
|
|
461
|
-
|
|
456
|
+
judges: 1-3 model ids from ``client.evaluations.list_models()``, e.g.
|
|
457
|
+
``["gpt-5.6-luna", "claude-opus-4-8"]``. Omit to let the engine score with its
|
|
458
|
+
platform default model (a single judge, rather than the dashboard's 3-judge
|
|
459
|
+
default - SDK runs are typically lighter-weight, quick-start evaluations).
|
|
462
460
|
poll_interval: seconds between status checks while waiting.
|
|
463
461
|
timeout: give up waiting after this many seconds (the job keeps running server-side;
|
|
464
462
|
call ``get_report()`` later to check on it).
|
|
465
463
|
"""
|
|
466
464
|
if judges is not None and not (1 <= len(judges) <= 3):
|
|
467
465
|
raise ValueError("judges must contain 1-3 model ids")
|
|
468
|
-
resolved_judges = judges if judges is not None else [_DEFAULT_JUDGE_MODEL]
|
|
469
466
|
|
|
470
467
|
_say()
|
|
471
468
|
with Spinner("Analyzing - AI is reviewing your results") as spinner:
|
|
@@ -474,7 +471,7 @@ class EvaluationRunContext:
|
|
|
474
471
|
self._run.run_id,
|
|
475
472
|
mode=mode,
|
|
476
473
|
quality_mode=quality_mode,
|
|
477
|
-
judges=
|
|
474
|
+
judges=judges,
|
|
478
475
|
)
|
|
479
476
|
deadline = time.monotonic() + timeout
|
|
480
477
|
status = self._client.get_analysis_status(self._run.run_id)
|
|
@@ -187,10 +187,17 @@ class MonitorClient:
|
|
|
187
187
|
return self._base_url[: -len(suffix)]
|
|
188
188
|
return self._base_url
|
|
189
189
|
|
|
190
|
-
def _request(
|
|
190
|
+
def _request(
|
|
191
|
+
self, method: str, path: str, timeout: int = 30, base: Optional[str] = None, retry: bool = True, **kwargs
|
|
192
|
+
) -> Any:
|
|
193
|
+
# retry=False for non-idempotent judge-spending POSTs (sweep, coherence, portability,
|
|
194
|
+
# tuning): a client-side timeout must not fire the same LLM-billing work a second time
|
|
195
|
+
# while the first invocation is still running server-side. Same precedent as
|
|
196
|
+
# EvaluationsClient._request / analyze_run.
|
|
191
197
|
url = f"{base or self._base_url}{path}"
|
|
192
198
|
last_exc: Optional[Exception] = None
|
|
193
|
-
|
|
199
|
+
schedule = [0.0] + _RETRY_BACKOFF if retry else [0.0]
|
|
200
|
+
for attempt, wait in enumerate(schedule):
|
|
194
201
|
if wait:
|
|
195
202
|
time.sleep(wait)
|
|
196
203
|
try:
|
|
@@ -204,7 +211,7 @@ class MonitorClient:
|
|
|
204
211
|
raise AgentXAuthError("Invalid or missing API key")
|
|
205
212
|
if resp.status_code == 422:
|
|
206
213
|
raise AgentXValidationError(resp.text)
|
|
207
|
-
if resp.status_code in _RETRYABLE_STATUS and attempt < _MAX_RETRIES - 1:
|
|
214
|
+
if retry and resp.status_code in _RETRYABLE_STATUS and attempt < _MAX_RETRIES - 1:
|
|
208
215
|
logger.debug(
|
|
209
216
|
"Retryable status %d (attempt %d)", resp.status_code, attempt + 1
|
|
210
217
|
)
|
|
@@ -421,7 +428,7 @@ class MonitorClient:
|
|
|
421
428
|
button. Raises AgentXMonitorError if the engine has no judge key configured."""
|
|
422
429
|
data = self._request(
|
|
423
430
|
"POST", f"/agent-monitoring/sessions/{session_id}/coherence-check",
|
|
424
|
-
base=self._api_root(), timeout=180,
|
|
431
|
+
base=self._api_root(), timeout=180, retry=False,
|
|
425
432
|
)
|
|
426
433
|
return data.get("score", data) if isinstance(data, dict) else data
|
|
427
434
|
|
|
@@ -429,6 +436,24 @@ class MonitorClient:
|
|
|
429
436
|
data = self._request("GET", f"/ingest/sessions/{session_id}/spans", base=self._api_root())
|
|
430
437
|
return data.get("spans", []) if isinstance(data, dict) else data
|
|
431
438
|
|
|
439
|
+
def list_session_scores(self, session_id: str) -> List[dict]:
|
|
440
|
+
"""Every session-level verdict on the session, newest first: session-scoped online
|
|
441
|
+
evaluators (kind ``online-eval:<id>``), session-scoped scorer groups
|
|
442
|
+
(``scorer-group:<id>``), and legacy coherence rows."""
|
|
443
|
+
data = self._request(
|
|
444
|
+
"GET", f"/agent-monitoring/sessions/{session_id}/scores", base=self._api_root()
|
|
445
|
+
)
|
|
446
|
+
return data.get("scores", []) if isinstance(data, dict) else data
|
|
447
|
+
|
|
448
|
+
def run_session_sweep(self) -> dict:
|
|
449
|
+
"""Run the idle-session sweep once, now - the tick that scores quiet multi-turn
|
|
450
|
+
sessions with every enabled session-scoped evaluator and scorer group. Production
|
|
451
|
+
engines run this automatically every minute; the manual trigger exists for demos,
|
|
452
|
+
tests, and backfills. Returns ``{"judged": n}``."""
|
|
453
|
+
return self._request(
|
|
454
|
+
"POST", "/agent-monitoring/session-sweep/run", base=self._api_root(), timeout=300, retry=False
|
|
455
|
+
)
|
|
456
|
+
|
|
432
457
|
# ------------------------------------------------------------------
|
|
433
458
|
# Model portability (self-host): replay a trace's input against other models
|
|
434
459
|
# ------------------------------------------------------------------
|
|
@@ -439,7 +464,7 @@ class MonitorClient:
|
|
|
439
464
|
plus judging, so expect tens of seconds."""
|
|
440
465
|
return self._request(
|
|
441
466
|
"POST", f"/agent-monitoring/traces/{trace_id}/portability",
|
|
442
|
-
base=self._api_root(), json={"modelIds": model_ids}, timeout=300,
|
|
467
|
+
base=self._api_root(), json={"modelIds": model_ids}, timeout=300, retry=False,
|
|
443
468
|
)
|
|
444
469
|
|
|
445
470
|
# ------------------------------------------------------------------
|
|
@@ -114,6 +114,10 @@ class MonitorPatternClient:
|
|
|
114
114
|
agent_ids=agent_ids,
|
|
115
115
|
)
|
|
116
116
|
|
|
117
|
+
def delete(self, pattern_id: str) -> None:
|
|
118
|
+
"""Delete a pattern. Its historical signals remain as history."""
|
|
119
|
+
self._client._request("DELETE", f"/agent-monitoring/patterns/{pattern_id}", base=self._client._api_root())
|
|
120
|
+
|
|
117
121
|
def get(self, pattern_id: str) -> MonitorPattern:
|
|
118
122
|
return self._client.get_pattern(pattern_id)
|
|
119
123
|
|
|
@@ -65,8 +65,10 @@ class ScorerGroupsClient:
|
|
|
65
65
|
online: Optional[Dict[str, Any]] = None,
|
|
66
66
|
) -> ScorerGroup:
|
|
67
67
|
"""``members``: [{"kind": "judge"|"pattern"|"custom", "refId": ..., "weight": 1, "gate": False}].
|
|
68
|
-
``online``: {"enabled": True, "sampleRate": 0.1, "alertThreshold": 5, "severity": "medium"}
|
|
69
|
-
|
|
68
|
+
``online``: {"enabled": True, "sampleRate": 0.1, "alertThreshold": 5, "severity": "medium"}.
|
|
69
|
+
Add ``"scope": "session", "idleSeconds": 120`` to score whole multi-turn sessions once
|
|
70
|
+
idle, instead of each sampled trace. Pass ``online=None`` (the default) for a group
|
|
71
|
+
that only grades offline dataset runs."""
|
|
70
72
|
payload: Dict[str, Any] = {"name": name, "members": members}
|
|
71
73
|
if description is not None:
|
|
72
74
|
payload["description"] = description
|
|
@@ -19,3 +19,16 @@ class MonitorSessionClient:
|
|
|
19
19
|
def spans(self, session_id: str) -> List[dict]:
|
|
20
20
|
"""Every span in the session (roots and children), oldest first."""
|
|
21
21
|
return self._client.list_session_spans(session_id)
|
|
22
|
+
|
|
23
|
+
def scores(self, session_id: str) -> List[dict]:
|
|
24
|
+
"""Session-level verdicts, newest first. ``kind`` says who scored: a session-scoped
|
|
25
|
+
online evaluator (``online-eval:<id>``), a session-scoped scorer group
|
|
26
|
+
(``scorer-group:<id>``), or legacy ``"coherence"`` rows written before the Session
|
|
27
|
+
Baseline Judge existed - branch defensively on unknown kinds."""
|
|
28
|
+
return self._client.list_session_scores(session_id)
|
|
29
|
+
|
|
30
|
+
def run_sweep(self) -> dict:
|
|
31
|
+
"""Trigger the idle-session sweep once (normally automatic, every minute) - scores
|
|
32
|
+
idle multi-turn sessions with every enabled session-scoped evaluator and scorer
|
|
33
|
+
group. Returns ``{"judged": n}``."""
|
|
34
|
+
return self._client.run_session_sweep()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
VERSION = "0.8.
|
|
1
|
+
VERSION = "0.8.18"
|
|
2
2
|
|
|
3
3
|
# The AgentX-trace-eval release this SDK version is tested against - what `agentx-trace-eval`
|
|
4
4
|
# installs and converges to (see agentx/cli.py). Bump together with VERSION when releasing, so
|
|
5
5
|
# every published SDK names a known-good engine+dashboard pair. Users can override with
|
|
6
6
|
# AGENTX_TRACE_EVAL_VERSION=<tag|latest>.
|
|
7
|
-
ENGINE_VERSION = "v0.3.
|
|
7
|
+
ENGINE_VERSION = "v0.3.18"
|
|
@@ -599,7 +599,9 @@ def test_crewai_captures_real_per_task_timing_via_event_bus():
|
|
|
599
599
|
durations are provably unequal — the old "divide latency evenly across
|
|
600
600
|
tasks" approximation would have reported them as identical.
|
|
601
601
|
"""
|
|
602
|
-
|
|
602
|
+
# exc_type=Exception: on older Pythons crewai can raise TypeError (PEP 604 syntax) at
|
|
603
|
+
# import time, and a broken optional integration should skip this test, not fail it.
|
|
604
|
+
crewai = pytest.importorskip("crewai", exc_type=Exception)
|
|
603
605
|
from crewai.events.event_bus import crewai_event_bus
|
|
604
606
|
from crewai.events.types.task_events import TaskCompletedEvent, TaskStartedEvent
|
|
605
607
|
from crewai.tasks.task_output import TaskOutput
|
|
@@ -210,12 +210,18 @@ def test_the_fallback_request_gets_the_long_analysis_timeout():
|
|
|
210
210
|
{("POST", f"{API_ROOT}/evaluate/analyze/{RUN}"): FakeResponse(200, {"status": "completed"})}
|
|
211
211
|
)
|
|
212
212
|
|
|
213
|
-
client.analyze_run(RUN, judges=["gpt-5.
|
|
213
|
+
client.analyze_run(RUN, judges=["gpt-5.6-luna"])
|
|
214
214
|
|
|
215
215
|
method, url, kwargs = session.calls[-1]
|
|
216
216
|
assert url == f"{API_ROOT}/evaluate/analyze/{RUN}"
|
|
217
217
|
assert kwargs["timeout"] > 60, "a synchronous judge pass needs more than the 30s default"
|
|
218
|
-
assert kwargs["json"]["judges"] == [{"model": "gpt-5.
|
|
218
|
+
assert kwargs["json"]["judges"] == [{"model": "gpt-5.6-luna"}]
|
|
219
|
+
|
|
220
|
+
# judges=None must OMIT the key - the engine then scores with its platform default model;
|
|
221
|
+
# injecting a hosted-only default (the old "gpt-5.5") produced uncallable judges.
|
|
222
|
+
client.analyze_run(RUN)
|
|
223
|
+
_, _, kwargs = session.calls[-1]
|
|
224
|
+
assert "judges" not in kwargs["json"]
|
|
219
225
|
|
|
220
226
|
|
|
221
227
|
# ---------------------------------------------------------------------------
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|