sys1bench 0.3.0__tar.gz → 0.3.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.
- {sys1bench-0.3.0 → sys1bench-0.3.1}/PKG-INFO +6 -6
- {sys1bench-0.3.0 → sys1bench-0.3.1}/README.md +5 -5
- {sys1bench-0.3.0 → sys1bench-0.3.1}/pyproject.toml +2 -2
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/__init__.py +1 -1
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/jev_typesafe.py +9 -2
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/cli.py +50 -14
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/data/__init__.py +21 -4
- sys1bench-0.3.1/src/sys1bench/data/configs/example_future_vendor.yaml +18 -0
- sys1bench-0.3.1/src/sys1bench/data/configs/hybrid_mock.yaml +4 -0
- sys1bench-0.3.1/src/sys1bench/data/configs/jev_1.13.yaml +4 -0
- sys1bench-0.3.1/src/sys1bench/data/configs/jev_1.13_openrouter.yaml +3 -0
- sys1bench-0.3.1/src/sys1bench/data/configs/laya_en.yaml +6 -0
- sys1bench-0.3.1/src/sys1bench/data/configs/laya_typed_decisions.yaml +6 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench.egg-info/PKG-INFO +6 -6
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench.egg-info/SOURCES.txt +6 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/LICENSE +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/setup.cfg +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/__init__.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/base.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/embed_knn.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/encoder_finetuned.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/generic_http.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/hybrid_router.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/jev_openrouter.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/laya_local.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/llm_constrained.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/majority_prior.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/mock.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/nli_zeroshot.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/adapters/regex_keyword.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/analysis/__init__.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/analysis/arms.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/analysis/decision_value.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/analysis/decomposition.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/analysis/meta_eval.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/analysis/stats.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/data/canary/canary.jsonl +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/data/framings/guardrail_intent.yaml +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/data/framings/log_triage.yaml +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/data/framings/phishing_email.yaml +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/data/framings/policy_compliance.yaml +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/data/framings/support_tickets.yaml +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/framing/__init__.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/framing/expand.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/framing/perturb.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/generators/__init__.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/generators/base.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/generators/guardrail_intent.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/generators/log_triage.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/generators/multilingual_tickets.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/generators/phishing_email.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/generators/policy_compliance.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/generators/rag_relevance.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/generators/support_tickets.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/metrics/__init__.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/metrics/calibration.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/metrics/consistency.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/metrics/decision_value.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/metrics/efficiency.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/metrics/ordinal.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/metrics/robustness.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/metrics/selective.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/report/__init__.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/report/dashboard.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/report/latex.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/report/plots.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/report/results_doc.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/report/scorecard.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/runners/__init__.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/runners/benchmark_runner.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/runners/cache.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/runners/canary.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/runners/hybrid_sweep.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/runners/noul_consistency.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/runners/ordinal_probes.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/runners/robustness.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/runners/suite.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/runners/sweeps.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench/schemas.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench.egg-info/dependency_links.txt +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench.egg-info/entry_points.txt +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench.egg-info/requires.txt +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/src/sys1bench.egg-info/top_level.txt +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/tests/test_generators_framing.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/tests/test_metrics.py +0 -0
- {sys1bench-0.3.0 → sys1bench-0.3.1}/tests/test_runner_end_to_end.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sys1bench
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Benchmark harness for typed System One decision models (choice / score / noul): calibration vs noise floor, framing sensitivity, selective prediction, ordinal fidelity, interference, robustness.
|
|
5
5
|
Author-email: Rahul Sharma <rsharma@rptu.de>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -55,8 +55,8 @@ Dynamic: license-file
|
|
|
55
55
|
</p>
|
|
56
56
|
|
|
57
57
|
<p align="center">
|
|
58
|
-
<a href="https://pypi.org/project/sys1bench/"><img alt="PyPI" src="https://img.shields.io/pypi/v/sys1bench?color=4F46E5&label=PyPI"></a>
|
|
59
|
-
<a href="https://pypi.org/project/sys1bench/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/sys1bench?color=06B6D4"></a>
|
|
58
|
+
<a href="https://pypi.org/project/sys1bench/"><img alt="PyPI" src="https://img.shields.io/pypi/v/sys1bench?color=4F46E5&label=PyPI&logo=pypi&logoColor=white&cacheSeconds=3600"></a>
|
|
59
|
+
<a href="https://pypi.org/project/sys1bench/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/sys1bench?color=06B6D4&logo=python&logoColor=white&cacheSeconds=3600"></a>
|
|
60
60
|
<a href="https://github.com/rssr25/system-one-bench/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/rssr25/system-one-bench/actions/workflows/ci.yml/badge.svg"></a>
|
|
61
61
|
<a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-blue.svg"></a>
|
|
62
62
|
<img alt="Tests" src="https://img.shields.io/badge/tests-31%20passing-brightgreen">
|
|
@@ -114,10 +114,10 @@ sys1bench score preds.jsonl prior.jsonl --out summary.json
|
|
|
114
114
|
# Jev (hosted, first-party API)
|
|
115
115
|
echo 'TypeSafe_API_KEY=...' > .env
|
|
116
116
|
sys1bench canary jev_typesafe --model jev-1.13.0 # 200 fixed items; drift baseline
|
|
117
|
-
sys1bench suite all results/jev --config
|
|
117
|
+
sys1bench suite all results/jev --config jev_1.13 --n 500 --concurrency 4 # packaged config; `sys1bench configs` lists them
|
|
118
118
|
|
|
119
119
|
# Laya (local; same manifests as Jev so the comparison is item-for-item)
|
|
120
|
-
sys1bench suite all results/laya --config
|
|
120
|
+
sys1bench suite all results/laya --config laya_en --manifests-from results/jev --budget
|
|
121
121
|
|
|
122
122
|
# Report, LaTeX tables, HTML dashboard and plots for everything under results/
|
|
123
123
|
sys1bench report results --latex results/tables.tex --html results/dashboard.html
|
|
@@ -132,7 +132,7 @@ sys1bench plots results
|
|
|
132
132
|
|
|
133
133
|
| Your model | What to do |
|
|
134
134
|
|---|---|
|
|
135
|
-
| Hosted, conventional JSON decisions API |
|
|
135
|
+
| Hosted, conventional JSON decisions API | `sys1bench configs example_future_vendor > my_model.yaml`, fill in URL, auth env var and field names, run with `--config my_model.yaml`. No code. |
|
|
136
136
|
| Anything else | Subclass `BaseAdapter`: declare `capabilities` (primitives, max options, state tokens, native abstain, batching) and implement `decide` (state + typed questions in, one probability vector per question out). Register with `@register("my_model")` or the `sys1bench.adapters` entry-point group from your own package. |
|
|
137
137
|
|
|
138
138
|
Capability limits are declared, then measured: a request outside them is recorded as a `capability_issue` or `rejected_by_vendor` row, never a crash.
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<a href="https://pypi.org/project/sys1bench/"><img alt="PyPI" src="https://img.shields.io/pypi/v/sys1bench?color=4F46E5&label=PyPI"></a>
|
|
7
|
-
<a href="https://pypi.org/project/sys1bench/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/sys1bench?color=06B6D4"></a>
|
|
6
|
+
<a href="https://pypi.org/project/sys1bench/"><img alt="PyPI" src="https://img.shields.io/pypi/v/sys1bench?color=4F46E5&label=PyPI&logo=pypi&logoColor=white&cacheSeconds=3600"></a>
|
|
7
|
+
<a href="https://pypi.org/project/sys1bench/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/sys1bench?color=06B6D4&logo=python&logoColor=white&cacheSeconds=3600"></a>
|
|
8
8
|
<a href="https://github.com/rssr25/system-one-bench/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/rssr25/system-one-bench/actions/workflows/ci.yml/badge.svg"></a>
|
|
9
9
|
<a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-blue.svg"></a>
|
|
10
10
|
<img alt="Tests" src="https://img.shields.io/badge/tests-31%20passing-brightgreen">
|
|
@@ -62,10 +62,10 @@ sys1bench score preds.jsonl prior.jsonl --out summary.json
|
|
|
62
62
|
# Jev (hosted, first-party API)
|
|
63
63
|
echo 'TypeSafe_API_KEY=...' > .env
|
|
64
64
|
sys1bench canary jev_typesafe --model jev-1.13.0 # 200 fixed items; drift baseline
|
|
65
|
-
sys1bench suite all results/jev --config
|
|
65
|
+
sys1bench suite all results/jev --config jev_1.13 --n 500 --concurrency 4 # packaged config; `sys1bench configs` lists them
|
|
66
66
|
|
|
67
67
|
# Laya (local; same manifests as Jev so the comparison is item-for-item)
|
|
68
|
-
sys1bench suite all results/laya --config
|
|
68
|
+
sys1bench suite all results/laya --config laya_en --manifests-from results/jev --budget
|
|
69
69
|
|
|
70
70
|
# Report, LaTeX tables, HTML dashboard and plots for everything under results/
|
|
71
71
|
sys1bench report results --latex results/tables.tex --html results/dashboard.html
|
|
@@ -80,7 +80,7 @@ sys1bench plots results
|
|
|
80
80
|
|
|
81
81
|
| Your model | What to do |
|
|
82
82
|
|---|---|
|
|
83
|
-
| Hosted, conventional JSON decisions API |
|
|
83
|
+
| Hosted, conventional JSON decisions API | `sys1bench configs example_future_vendor > my_model.yaml`, fill in URL, auth env var and field names, run with `--config my_model.yaml`. No code. |
|
|
84
84
|
| Anything else | Subclass `BaseAdapter`: declare `capabilities` (primitives, max options, state tokens, native abstain, batching) and implement `decide` (state + typed questions in, one probability vector per question out). Register with `@register("my_model")` or the `sys1bench.adapters` entry-point group from your own package. |
|
|
85
85
|
|
|
86
86
|
Capability limits are declared, then measured: a request outside them is recorded as a `capability_issue` or `rejected_by_vendor` row, never a crash.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sys1bench"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.1"
|
|
4
4
|
description = "Benchmark harness for typed System One decision models (choice / score / noul): calibration vs noise floor, framing sensitivity, selective prediction, ordinal fidelity, interference, robustness."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -59,7 +59,7 @@ build-backend = "setuptools.build_meta"
|
|
|
59
59
|
where = ["src"]
|
|
60
60
|
|
|
61
61
|
[tool.setuptools.package-data]
|
|
62
|
-
"sys1bench.data" = ["framings/*.yaml", "canary/*.jsonl"]
|
|
62
|
+
"sys1bench.data" = ["framings/*.yaml", "canary/*.jsonl", "configs/*.yaml"]
|
|
63
63
|
|
|
64
64
|
[tool.pytest.ini_options]
|
|
65
65
|
testpaths = ["tests"]
|
|
@@ -27,7 +27,7 @@ from typing import Any
|
|
|
27
27
|
import httpx
|
|
28
28
|
|
|
29
29
|
from ..schemas import Answer, DecisionRequest, DecisionResponse, LatencyRecord, ModelCapabilities, ProviderRecord, Question
|
|
30
|
-
from .base import BaseAdapter, finalize_answer, register
|
|
30
|
+
from .base import BaseAdapter, FatalAdapterError, finalize_answer, register
|
|
31
31
|
|
|
32
32
|
DEFAULT_URL = "https://api.typesafe.ai/v1/systemone"
|
|
33
33
|
PRICE_PER_M_INPUT = 0.042
|
|
@@ -38,7 +38,7 @@ def _load_dotenv_key() -> str | None:
|
|
|
38
38
|
for k in ENV_KEYS:
|
|
39
39
|
if os.environ.get(k):
|
|
40
40
|
return os.environ[k]
|
|
41
|
-
for candidate in (Path.cwd() / ".env",
|
|
41
|
+
for candidate in (Path.cwd() / ".env",):
|
|
42
42
|
if candidate.exists():
|
|
43
43
|
for line in candidate.read_text().splitlines():
|
|
44
44
|
line = line.strip()
|
|
@@ -95,6 +95,9 @@ class JevTypeSafeAdapter(BaseAdapter):
|
|
|
95
95
|
raise ValueError("pin a versioned Jev id (e.g. jev-1.13.0); aliases move silently. Pass allow_alias=True to override.")
|
|
96
96
|
self.url, self.timeout_s, self.max_retries = url, timeout_s, max_retries
|
|
97
97
|
self.api_key = api_key or _load_dotenv_key()
|
|
98
|
+
if not self.api_key:
|
|
99
|
+
raise FatalAdapterError("No TypeSafe API key found. Set TypeSafe_API_KEY (or TYPESAFE_API_KEY) in the environment or in a .env file "
|
|
100
|
+
"in the working directory. Keys: https://typesafe.ai")
|
|
98
101
|
self._client = httpx.Client(timeout=timeout_s, http2=False)
|
|
99
102
|
|
|
100
103
|
@property
|
|
@@ -121,6 +124,8 @@ class JevTypeSafeAdapter(BaseAdapter):
|
|
|
121
124
|
except ValueError:
|
|
122
125
|
pass
|
|
123
126
|
raise httpx.HTTPStatusError(f"{r.status_code}: {r.text[:200]}", request=r.request, response=r)
|
|
127
|
+
if r.status_code in (401, 403):
|
|
128
|
+
raise FatalAdapterError(f"TypeSafe API rejected the key (HTTP {r.status_code}). Check TypeSafe_API_KEY.")
|
|
124
129
|
if 400 <= r.status_code < 500 and r.status_code != 429:
|
|
125
130
|
# request rejected (400 over the 32k state limit, 413, 422 malformed): never retry, classify as vendor rejection
|
|
126
131
|
raise ValueError(f"{r.status_code} rejected: {r.text[:300]}")
|
|
@@ -140,6 +145,8 @@ class JevTypeSafeAdapter(BaseAdapter):
|
|
|
140
145
|
"questions": {k: to_vendor_question(q) for k, q in request.questions.items()}}
|
|
141
146
|
try:
|
|
142
147
|
data, ms, headers = self._post(body)
|
|
148
|
+
except FatalAdapterError:
|
|
149
|
+
raise
|
|
143
150
|
except Exception as e:
|
|
144
151
|
kind = "rejected_by_vendor" if isinstance(e, ValueError) else "transport"
|
|
145
152
|
return DecisionResponse(
|
|
@@ -17,7 +17,7 @@ import yaml
|
|
|
17
17
|
|
|
18
18
|
from . import __version__
|
|
19
19
|
from .adapters import get_adapter, list_adapters
|
|
20
|
-
from .data import framings_path
|
|
20
|
+
from .data import canary_path, config_path, framings_path, list_configs
|
|
21
21
|
from .framing import apply_corruption, expand_framings, permute_options, strip_options, strip_state
|
|
22
22
|
from .framing.expand import load_framings
|
|
23
23
|
from .generators import GENERATORS, get_generator
|
|
@@ -38,14 +38,31 @@ def _main(ctx: typer.Context, version: bool = typer.Option(False, "--version", "
|
|
|
38
38
|
typer.echo(ctx.get_help())
|
|
39
39
|
|
|
40
40
|
|
|
41
|
+
def _fail(msg: str, code: int = 2) -> None:
|
|
42
|
+
typer.secho(f"error: {msg}", fg=typer.colors.RED, err=True)
|
|
43
|
+
raise typer.Exit(code)
|
|
44
|
+
|
|
45
|
+
|
|
41
46
|
def _adapter_from(adapter: str | None, model: str | None, config: str | None):
|
|
47
|
+
from .adapters.base import FatalAdapterError
|
|
48
|
+
|
|
42
49
|
cfg = {}
|
|
43
50
|
if config:
|
|
44
|
-
|
|
45
|
-
|
|
51
|
+
try:
|
|
52
|
+
cfg = yaml.safe_load(config_path(config).read_text()) or {}
|
|
53
|
+
except FileNotFoundError as e:
|
|
54
|
+
_fail(str(e))
|
|
55
|
+
adapter = adapter or cfg.pop("adapter", None)
|
|
56
|
+
if not adapter:
|
|
57
|
+
_fail("no adapter given: pass --adapter <id> or --config <yaml with an `adapter:` key>. Known: " + ", ".join(list_adapters()))
|
|
46
58
|
if model:
|
|
47
59
|
cfg["model_id"] = model
|
|
48
|
-
|
|
60
|
+
try:
|
|
61
|
+
return get_adapter(adapter, **cfg)
|
|
62
|
+
except KeyError as e:
|
|
63
|
+
_fail(str(e).strip('"'))
|
|
64
|
+
except (ValueError, FatalAdapterError) as e:
|
|
65
|
+
_fail(str(e))
|
|
49
66
|
|
|
50
67
|
|
|
51
68
|
@app.command()
|
|
@@ -55,8 +72,19 @@ def adapters():
|
|
|
55
72
|
typer.echo(a)
|
|
56
73
|
|
|
57
74
|
|
|
75
|
+
@app.command()
|
|
76
|
+
def configs(show: Optional[str] = typer.Argument(None, help="print a packaged config by name")):
|
|
77
|
+
"""List packaged example model configs (use with --config <name>), or print one to copy and edit."""
|
|
78
|
+
if show:
|
|
79
|
+
typer.echo(config_path(show).read_text())
|
|
80
|
+
return
|
|
81
|
+
for c in sorted(list_configs()):
|
|
82
|
+
typer.echo(c)
|
|
83
|
+
|
|
84
|
+
|
|
58
85
|
@app.command()
|
|
59
86
|
def generators():
|
|
87
|
+
"""List Tier G generators and their versions."""
|
|
60
88
|
for g in sorted(GENERATORS):
|
|
61
89
|
typer.echo(f"{g}@{GENERATORS[g].version}")
|
|
62
90
|
|
|
@@ -93,14 +121,22 @@ def run(manifest: Path, out: Path, adapter: str | None = None, model: str | None
|
|
|
93
121
|
if permutations:
|
|
94
122
|
items = permute_options(items, permutations)
|
|
95
123
|
c = ResponseCache(cache)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
rows_all += run_items(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
124
|
+
from .adapters.base import FatalAdapterError
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
rows_all += run_items(items, ad, c, suite=suite, arm="main", concurrency=concurrency, progress=True)
|
|
128
|
+
base = [i for i in items if i.permutation_id == "p0" and all(q.framing_id == "f0" for q in i.questions.values())]
|
|
129
|
+
if corruption:
|
|
130
|
+
rows_all += run_items(apply_corruption(base), ad, c, suite=suite, arm="corruption", concurrency=concurrency)
|
|
131
|
+
if short_circuit:
|
|
132
|
+
rows_all += run_items(strip_state(base), ad, c, suite=suite, arm="state_only", concurrency=concurrency)
|
|
133
|
+
rows_all += run_items(strip_options(base), ad, c, suite=suite, arm="options_only", concurrency=concurrency)
|
|
134
|
+
except FatalAdapterError as e:
|
|
135
|
+
_fail(str(e), code=3)
|
|
103
136
|
write_predictions(rows_all, out)
|
|
137
|
+
n_err = sum(1 for r in rows_all if r.error)
|
|
138
|
+
if n_err:
|
|
139
|
+
typer.secho(f"warning: {n_err}/{len(rows_all)} rows have errors (see the `error` field); first: {next(r.error for r in rows_all if r.error)}", fg=typer.colors.YELLOW, err=True)
|
|
104
140
|
typer.echo(f"wrote {len(rows_all)} prediction rows to {out}; cache size {len(c)}")
|
|
105
141
|
|
|
106
142
|
|
|
@@ -124,11 +160,11 @@ def score(predictions: list[Path], out: Path = Path("results/summary.json"), tab
|
|
|
124
160
|
|
|
125
161
|
|
|
126
162
|
@app.command()
|
|
127
|
-
def canary(adapter: str, model: str | None = None, manifest: Path =
|
|
163
|
+
def canary(adapter: str, model: str | None = None, manifest: Path | None = None,
|
|
128
164
|
store: Path = Path("results/canary"), config: Path | None = None):
|
|
129
|
-
"""Run the drift canary for a hosted model."""
|
|
165
|
+
"""Run the drift canary for a hosted model (default: the packaged 200-item set)."""
|
|
130
166
|
ad = _adapter_from(adapter, model, str(config) if config else None)
|
|
131
|
-
res = run_canary(load_manifest(manifest), ad, store)
|
|
167
|
+
res = run_canary(load_manifest(manifest or canary_path()), ad, store)
|
|
132
168
|
typer.echo(json.dumps(res, indent=1))
|
|
133
169
|
if res["drift_suspected"]:
|
|
134
170
|
raise typer.Exit(code=2)
|
|
@@ -22,10 +22,10 @@ def framings_path(name_or_path: str | Path) -> Path:
|
|
|
22
22
|
p = Path(name_or_path)
|
|
23
23
|
if p.exists():
|
|
24
24
|
return p
|
|
25
|
-
stem
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
for stem in (str(name_or_path), p.stem): # names may contain dots (jev_1.13), so try the full name first
|
|
26
|
+
cand = _pkg_file("framings", f"{stem}.yaml")
|
|
27
|
+
if cand.exists():
|
|
28
|
+
return cand
|
|
29
29
|
raise FileNotFoundError(f"no framing set {name_or_path!r}; packaged: {sorted(list_framings())}")
|
|
30
30
|
|
|
31
31
|
|
|
@@ -35,3 +35,20 @@ def list_framings() -> list[str]:
|
|
|
35
35
|
|
|
36
36
|
def canary_path() -> Path:
|
|
37
37
|
return _pkg_file("canary", "canary.jsonl")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def config_path(name_or_path: str | Path) -> Path:
|
|
41
|
+
"""Resolve a model config: an existing path, or a packaged example in `configs/<name>.yaml`
|
|
42
|
+
(jev_1.13, jev_1.13_openrouter, laya_en, laya_typed_decisions, example_future_vendor, hybrid_mock)."""
|
|
43
|
+
p = Path(name_or_path)
|
|
44
|
+
if p.exists():
|
|
45
|
+
return p
|
|
46
|
+
for stem in (str(name_or_path), p.stem):
|
|
47
|
+
cand = _pkg_file("configs", f"{stem}.yaml")
|
|
48
|
+
if cand.exists():
|
|
49
|
+
return cand
|
|
50
|
+
raise FileNotFoundError(f"no config {name_or_path!r}; packaged: {sorted(list_configs())}")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def list_configs() -> list[str]:
|
|
54
|
+
return [p.stem for p in Path(str(resources.files(_PKG).joinpath("configs"))).glob("*.yaml")]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Template for a new hosted System One model: no code needed if its JSON shape is conventional.
|
|
2
|
+
adapter: generic_http
|
|
3
|
+
model_id: vendor/decider-1.0
|
|
4
|
+
url: https://api.vendor.example/v1/decisions
|
|
5
|
+
auth_env: VENDOR_API_KEY
|
|
6
|
+
type_map: {choice: choice, score: score, noul: boolean}
|
|
7
|
+
body_template: {"model": "{model_id}", "state": "{state}", "questions": "{questions}"}
|
|
8
|
+
answers_path: [answers]
|
|
9
|
+
fields:
|
|
10
|
+
probs: [[probabilities], [distribution]]
|
|
11
|
+
p_true: [[probability]]
|
|
12
|
+
confidence: [[confidence]]
|
|
13
|
+
model_returned: [[model]]
|
|
14
|
+
generation_id: [[id]]
|
|
15
|
+
input_tokens: [[usage, input_tokens]]
|
|
16
|
+
price_per_m_input: 0.05
|
|
17
|
+
max_options: 255
|
|
18
|
+
max_state_tokens: 32000
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
adapter: laya_local
|
|
2
|
+
model_id: convaiinnovations/laya
|
|
3
|
+
checkpoint: english # english | multilingual | typed-decisions | router
|
|
4
|
+
device: cuda # falls back to CPU if CUDA is unavailable; the device used is recorded per row
|
|
5
|
+
head_max_len: 192 # Suite C sweeps [64,128,192,256,384,512]
|
|
6
|
+
max_len: 512
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sys1bench
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Benchmark harness for typed System One decision models (choice / score / noul): calibration vs noise floor, framing sensitivity, selective prediction, ordinal fidelity, interference, robustness.
|
|
5
5
|
Author-email: Rahul Sharma <rsharma@rptu.de>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -55,8 +55,8 @@ Dynamic: license-file
|
|
|
55
55
|
</p>
|
|
56
56
|
|
|
57
57
|
<p align="center">
|
|
58
|
-
<a href="https://pypi.org/project/sys1bench/"><img alt="PyPI" src="https://img.shields.io/pypi/v/sys1bench?color=4F46E5&label=PyPI"></a>
|
|
59
|
-
<a href="https://pypi.org/project/sys1bench/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/sys1bench?color=06B6D4"></a>
|
|
58
|
+
<a href="https://pypi.org/project/sys1bench/"><img alt="PyPI" src="https://img.shields.io/pypi/v/sys1bench?color=4F46E5&label=PyPI&logo=pypi&logoColor=white&cacheSeconds=3600"></a>
|
|
59
|
+
<a href="https://pypi.org/project/sys1bench/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/sys1bench?color=06B6D4&logo=python&logoColor=white&cacheSeconds=3600"></a>
|
|
60
60
|
<a href="https://github.com/rssr25/system-one-bench/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/rssr25/system-one-bench/actions/workflows/ci.yml/badge.svg"></a>
|
|
61
61
|
<a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-blue.svg"></a>
|
|
62
62
|
<img alt="Tests" src="https://img.shields.io/badge/tests-31%20passing-brightgreen">
|
|
@@ -114,10 +114,10 @@ sys1bench score preds.jsonl prior.jsonl --out summary.json
|
|
|
114
114
|
# Jev (hosted, first-party API)
|
|
115
115
|
echo 'TypeSafe_API_KEY=...' > .env
|
|
116
116
|
sys1bench canary jev_typesafe --model jev-1.13.0 # 200 fixed items; drift baseline
|
|
117
|
-
sys1bench suite all results/jev --config
|
|
117
|
+
sys1bench suite all results/jev --config jev_1.13 --n 500 --concurrency 4 # packaged config; `sys1bench configs` lists them
|
|
118
118
|
|
|
119
119
|
# Laya (local; same manifests as Jev so the comparison is item-for-item)
|
|
120
|
-
sys1bench suite all results/laya --config
|
|
120
|
+
sys1bench suite all results/laya --config laya_en --manifests-from results/jev --budget
|
|
121
121
|
|
|
122
122
|
# Report, LaTeX tables, HTML dashboard and plots for everything under results/
|
|
123
123
|
sys1bench report results --latex results/tables.tex --html results/dashboard.html
|
|
@@ -132,7 +132,7 @@ sys1bench plots results
|
|
|
132
132
|
|
|
133
133
|
| Your model | What to do |
|
|
134
134
|
|---|---|
|
|
135
|
-
| Hosted, conventional JSON decisions API |
|
|
135
|
+
| Hosted, conventional JSON decisions API | `sys1bench configs example_future_vendor > my_model.yaml`, fill in URL, auth env var and field names, run with `--config my_model.yaml`. No code. |
|
|
136
136
|
| Anything else | Subclass `BaseAdapter`: declare `capabilities` (primitives, max options, state tokens, native abstain, batching) and implement `decide` (state + typed questions in, one probability vector per question out). Register with `@register("my_model")` or the `sys1bench.adapters` entry-point group from your own package. |
|
|
137
137
|
|
|
138
138
|
Capability limits are declared, then measured: a request outside them is recorded as a `capability_issue` or `rejected_by_vendor` row, never a crash.
|
|
@@ -32,6 +32,12 @@ src/sys1bench/analysis/meta_eval.py
|
|
|
32
32
|
src/sys1bench/analysis/stats.py
|
|
33
33
|
src/sys1bench/data/__init__.py
|
|
34
34
|
src/sys1bench/data/canary/canary.jsonl
|
|
35
|
+
src/sys1bench/data/configs/example_future_vendor.yaml
|
|
36
|
+
src/sys1bench/data/configs/hybrid_mock.yaml
|
|
37
|
+
src/sys1bench/data/configs/jev_1.13.yaml
|
|
38
|
+
src/sys1bench/data/configs/jev_1.13_openrouter.yaml
|
|
39
|
+
src/sys1bench/data/configs/laya_en.yaml
|
|
40
|
+
src/sys1bench/data/configs/laya_typed_decisions.yaml
|
|
35
41
|
src/sys1bench/data/framings/guardrail_intent.yaml
|
|
36
42
|
src/sys1bench/data/framings/log_triage.yaml
|
|
37
43
|
src/sys1bench/data/framings/phishing_email.yaml
|
|
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
|