evalgate-sdk 3.5.0__tar.gz → 3.5.1__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.
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/CHANGELOG.md +9 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/PKG-INFO +32 -2
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/README.md +29 -1
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/pyproject.toml +5 -1
- evalgate_sdk-3.5.1/src/evalgate_sdk/_version.py +3 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/__init__.py +29 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/commands.py +280 -35
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/config.py +31 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/new_commands.py +23 -1
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/regression_gate.py +20 -5
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/client.py +354 -24
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/runtime/executor.py +2 -2
- evalgate_sdk-3.5.1/tests/test_cli_hardening_351.py +321 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_client.py +195 -0
- evalgate_sdk-3.5.0/src/evalgate_sdk/_version.py +0 -3
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/.gitignore +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/__init__.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/assertions.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/auto.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/auto_experiment_runner.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/auto_failure_analyzer.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/auto_mutation_engine.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/batch.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cache.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/ci_context.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/api.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/api_command_config.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/cli_constants.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/env.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/formatters/types.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/golden_commands.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/judge_commands.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/manifest.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/policy_packs.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/profiles.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/render/__init__.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/render/snippet.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/render/sort.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/report/__init__.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/report/build_check_report.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/traces.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/workflow_commands.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cli/workspace.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/cluster.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/collector.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/constants.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/context.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/errors.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/export.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/formatters/__init__.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/formatters/github.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/formatters/human.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/formatters/json_fmt.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/formatters/pr_comment.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/golden.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/integrations/__init__.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/integrations/anthropic.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/integrations/autogen.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/integrations/crewai.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/integrations/langchain.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/integrations/openai.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/integrations/openai_eval.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/knowledge.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/local.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/logger.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/matchers.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/otel.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/pagination.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/py.typed +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/pytest_plugin.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/reason_codes.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/regression.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/replay_decision.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/runtime/__init__.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/runtime/adapters/__init__.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/runtime/adapters/config_to_dsl.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/runtime/adapters/testsuite_to_dsl.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/runtime/context.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/runtime/eval.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/runtime/execution_mode.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/runtime/registry.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/runtime/run_report.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/runtime/types.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/snapshot.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/streaming.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/synthesize.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/testing.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/types.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/utils/__init__.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/utils/input_hash.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/src/evalgate_sdk/workflows.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/__init__.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_assertions.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_assertions_async.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_auto_mutation_engine_parity.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_auto_session_methods.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_batch_collector.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_ci_context.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_cli_golden_commands.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_cli_new_commands.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_collector.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_contract_payloads.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_decorators_and_integrations.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_errors.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_execution_mode.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_formatters.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_knowledge_methods.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_local_storage.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_new_modules.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_openapi_contracts.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_otel.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_parity_gap_modules.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_parity_gaps.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_prod_hardening.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_pytest_plugin.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_run_report.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_runtime_dsl.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_sdk_contract_scaffold.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_testing.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_types.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_workflows.py +0 -0
- {evalgate_sdk-3.5.0 → evalgate_sdk-3.5.1}/tests/test_workflows_parity.py +0 -0
|
@@ -9,6 +9,15 @@ Version numbering is aligned with the TypeScript SDK (`@evalgate/sdk`) and the p
|
|
|
9
9
|
|
|
10
10
|
**Version history note:** The Python SDK jumped from 1.0.0 → 1.9.x → 2.0.0 to stay in sync with the TypeScript SDK. The TypeScript SDK had many releases (1.1–1.9) before the Python SDK existed. We now align both SDKs on the same major.minor version.
|
|
11
11
|
|
|
12
|
+
## [3.5.1] - 2026-06-26
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **CLI JSON contracts** — `check --format json` now emits one parseable JSON document.
|
|
16
|
+
- **Zero-config scaffolds** — `start --template` writes config that `run` and `doctor` discover consistently.
|
|
17
|
+
- **Runtime scoring defaults** — boolean/dict executor fallbacks now use the SDK's 0-100 score scale.
|
|
18
|
+
- **Sync safety** — missing labeled datasets surface an explicit error, and prompt pulls write UTF-8 content on Windows.
|
|
19
|
+
- **Default CLI install** — `pip install evalgate-sdk` now includes the runtime dependencies needed for the `evalgate` command.
|
|
20
|
+
|
|
12
21
|
## [3.5.0] - 2026-04-09
|
|
13
22
|
|
|
14
23
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: evalgate-sdk
|
|
3
|
-
Version: 3.5.
|
|
3
|
+
Version: 3.5.1
|
|
4
4
|
Summary: EvalGate Python SDK — CI for AI behavior. Traces, evaluations, assertions, and regression gates for LLM apps.
|
|
5
5
|
Project-URL: Homepage, https://evalgate.com
|
|
6
6
|
Project-URL: Documentation, https://github.com/evalgate/ai-evaluation-platform#readme
|
|
@@ -24,6 +24,8 @@ Classifier: Typing :: Typed
|
|
|
24
24
|
Requires-Python: >=3.10
|
|
25
25
|
Requires-Dist: httpx<1,>=0.27
|
|
26
26
|
Requires-Dist: pydantic<3,>=2.0
|
|
27
|
+
Requires-Dist: rich>=13
|
|
28
|
+
Requires-Dist: typer>=0.12
|
|
27
29
|
Provides-Extra: all
|
|
28
30
|
Requires-Dist: anthropic>=0.20; extra == 'all'
|
|
29
31
|
Requires-Dist: langchain-core>=0.2; extra == 'all'
|
|
@@ -65,7 +67,6 @@ Use it to run assertions, trace agent workflows, inspect platform runs, orchestr
|
|
|
65
67
|
|
|
66
68
|
```bash
|
|
67
69
|
pip install evalgate-sdk
|
|
68
|
-
pip install "evalgate-sdk[cli]"
|
|
69
70
|
```
|
|
70
71
|
|
|
71
72
|
Optional extras:
|
|
@@ -125,6 +126,35 @@ evalgate judge registry
|
|
|
125
126
|
evalgate judge presets
|
|
126
127
|
```
|
|
127
128
|
|
|
129
|
+
## Web App Sync
|
|
130
|
+
|
|
131
|
+
The Python CLI uses the same sync contracts as the TypeScript SDK. Local labeled
|
|
132
|
+
JSONL can be pushed into the web app, web-labeled cases can be merged back into
|
|
133
|
+
the same file, and prompt files can round-trip with stale active-version
|
|
134
|
+
protection.
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Push local labels into the web app and pull web labels back into JSONL
|
|
138
|
+
evalgate sync \
|
|
139
|
+
--project-key support-agent \
|
|
140
|
+
--labeled-dataset .evalgate/golden/labeled.jsonl \
|
|
141
|
+
--pull-labels
|
|
142
|
+
|
|
143
|
+
# Pull the active web prompt into a local file
|
|
144
|
+
evalgate sync \
|
|
145
|
+
--project-key support-agent \
|
|
146
|
+
--prompt-id prompt_support \
|
|
147
|
+
--target-path prompts/support.md \
|
|
148
|
+
--pull-prompt
|
|
149
|
+
|
|
150
|
+
# Push an edited local prompt as a new web prompt version
|
|
151
|
+
evalgate sync \
|
|
152
|
+
--project-key support-agent \
|
|
153
|
+
--prompt-id prompt_support \
|
|
154
|
+
--target-path prompts/support.md \
|
|
155
|
+
--push-prompt
|
|
156
|
+
```
|
|
157
|
+
|
|
128
158
|
## Judge Orchestration
|
|
129
159
|
|
|
130
160
|
The Python SDK supports the same core judge model as the platform:
|
|
@@ -13,7 +13,6 @@ Use it to run assertions, trace agent workflows, inspect platform runs, orchestr
|
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
15
|
pip install evalgate-sdk
|
|
16
|
-
pip install "evalgate-sdk[cli]"
|
|
17
16
|
```
|
|
18
17
|
|
|
19
18
|
Optional extras:
|
|
@@ -73,6 +72,35 @@ evalgate judge registry
|
|
|
73
72
|
evalgate judge presets
|
|
74
73
|
```
|
|
75
74
|
|
|
75
|
+
## Web App Sync
|
|
76
|
+
|
|
77
|
+
The Python CLI uses the same sync contracts as the TypeScript SDK. Local labeled
|
|
78
|
+
JSONL can be pushed into the web app, web-labeled cases can be merged back into
|
|
79
|
+
the same file, and prompt files can round-trip with stale active-version
|
|
80
|
+
protection.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Push local labels into the web app and pull web labels back into JSONL
|
|
84
|
+
evalgate sync \
|
|
85
|
+
--project-key support-agent \
|
|
86
|
+
--labeled-dataset .evalgate/golden/labeled.jsonl \
|
|
87
|
+
--pull-labels
|
|
88
|
+
|
|
89
|
+
# Pull the active web prompt into a local file
|
|
90
|
+
evalgate sync \
|
|
91
|
+
--project-key support-agent \
|
|
92
|
+
--prompt-id prompt_support \
|
|
93
|
+
--target-path prompts/support.md \
|
|
94
|
+
--pull-prompt
|
|
95
|
+
|
|
96
|
+
# Push an edited local prompt as a new web prompt version
|
|
97
|
+
evalgate sync \
|
|
98
|
+
--project-key support-agent \
|
|
99
|
+
--prompt-id prompt_support \
|
|
100
|
+
--target-path prompts/support.md \
|
|
101
|
+
--push-prompt
|
|
102
|
+
```
|
|
103
|
+
|
|
76
104
|
## Judge Orchestration
|
|
77
105
|
|
|
78
106
|
The Python SDK supports the same core judge model as the platform:
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "evalgate-sdk"
|
|
7
|
-
version = "3.5.
|
|
7
|
+
version = "3.5.1"
|
|
8
8
|
description = "EvalGate Python SDK — CI for AI behavior. Traces, evaluations, assertions, and regression gates for LLM apps."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -31,6 +31,8 @@ classifiers = [
|
|
|
31
31
|
dependencies = [
|
|
32
32
|
"httpx>=0.27,<1",
|
|
33
33
|
"pydantic>=2.0,<3",
|
|
34
|
+
"rich>=13",
|
|
35
|
+
"typer>=0.12",
|
|
34
36
|
]
|
|
35
37
|
|
|
36
38
|
[project.optional-dependencies]
|
|
@@ -66,6 +68,8 @@ packages = ["src/evalgate_sdk"]
|
|
|
66
68
|
[tool.pytest.ini_options]
|
|
67
69
|
testpaths = ["tests"]
|
|
68
70
|
asyncio_mode = "auto"
|
|
71
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
72
|
+
pythonpath = ["src"]
|
|
69
73
|
|
|
70
74
|
[tool.ruff]
|
|
71
75
|
target-version = "py310"
|
|
@@ -6,10 +6,34 @@ Submodules like config.py, api.py, etc. can be imported without typer.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
+
import sys
|
|
10
|
+
|
|
9
11
|
# Lazy initialization - only set up CLI when typer is available
|
|
10
12
|
app = None # Will be initialized on first access via get_app()
|
|
11
13
|
|
|
12
14
|
|
|
15
|
+
def _stream_needs_replacement_errors(stream: object) -> bool:
|
|
16
|
+
"""Return whether the stream encoding cannot represent common CLI glyphs."""
|
|
17
|
+
encoding = getattr(stream, "encoding", None)
|
|
18
|
+
if not encoding:
|
|
19
|
+
return False
|
|
20
|
+
try:
|
|
21
|
+
"✓ → ─".encode(encoding)
|
|
22
|
+
return False
|
|
23
|
+
except (LookupError, UnicodeEncodeError):
|
|
24
|
+
return True
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _make_output_streams_encoding_safe() -> None:
|
|
28
|
+
"""Prevent Windows legacy code pages from crashing Rich/Typer help output."""
|
|
29
|
+
for stream in (sys.stdout, sys.stderr):
|
|
30
|
+
if not _stream_needs_replacement_errors(stream):
|
|
31
|
+
continue
|
|
32
|
+
reconfigure = getattr(stream, "reconfigure", None)
|
|
33
|
+
if reconfigure is not None:
|
|
34
|
+
reconfigure(errors="replace")
|
|
35
|
+
|
|
36
|
+
|
|
13
37
|
def _ensure_typer() -> None:
|
|
14
38
|
"""Check that typer is installed, raise helpful error if not."""
|
|
15
39
|
try:
|
|
@@ -50,7 +74,9 @@ def get_app():
|
|
|
50
74
|
print_config,
|
|
51
75
|
run,
|
|
52
76
|
share,
|
|
77
|
+
sync,
|
|
53
78
|
upgrade,
|
|
79
|
+
version,
|
|
54
80
|
)
|
|
55
81
|
from evalgate_sdk.cli.judge_commands import judge
|
|
56
82
|
from evalgate_sdk.cli.workflow_commands import controls, integrity, knowledge, plan, trace, workflow
|
|
@@ -74,8 +100,10 @@ def get_app():
|
|
|
74
100
|
app.command("baseline")(baseline)
|
|
75
101
|
app.command("print-config")(print_config)
|
|
76
102
|
app.command("share")(share)
|
|
103
|
+
app.command("sync")(sync)
|
|
77
104
|
app.command("configure")(configure)
|
|
78
105
|
app.command("upgrade")(upgrade)
|
|
106
|
+
app.command("version")(version)
|
|
79
107
|
app.command("impact-analysis")(impact_analysis)
|
|
80
108
|
app.command("migrate")(migrate)
|
|
81
109
|
|
|
@@ -116,5 +144,6 @@ def __getattr__(name: str):
|
|
|
116
144
|
|
|
117
145
|
def main() -> None:
|
|
118
146
|
"""CLI entry point."""
|
|
147
|
+
_make_output_streams_encoding_safe()
|
|
119
148
|
cli_app = get_app()
|
|
120
149
|
cli_app()
|