tuieval 0.2.0.dev99__tar.gz → 0.2.0.dev100__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.
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/CHANGELOG.md +1 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/PKG-INFO +1 -1
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/models.md +1 -1
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/_version.py +2 -2
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/compare.py +29 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/engine.py +34 -19
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/tests/test_tuieval.py +31 -4
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/.gitignore +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/LICENSE +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/README.md +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/RELEASING.md +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/README.md +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/favicon.ico +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/readme-header.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/social-preview.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/tuieval-icon-1024.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/tuieval-icon-128.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/tuieval-icon-16.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/tuieval-icon-16.svg +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/tuieval-icon-256.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/tuieval-icon-32.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/tuieval-icon-48.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/tuieval-icon-512.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/tuieval-icon-64.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/tuieval-icon-animated.svg +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/brand/tuieval-icon.svg +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/tui-answer-reasoning.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/tui-run-reasoning.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/images/tui-setup.png +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/docs/writing-packs.md +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/pyproject.toml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/__init__.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/__main__.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/builtin.toml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/cli.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/client.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/doctor.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/export.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/graders/__init__.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/graders/answer.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/graders/code.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/graders/rag.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/graders/reply.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/graders/tool_call.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/insights.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/logs.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/machines.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/onboard.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/packs.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/profiles.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/pta.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/remove.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/run_evals.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/scaffold.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/selftest.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/models.toml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/answer/pack.toml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/answer/system.txt +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/answer/tests.yaml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/code/pack.toml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/code/system.txt +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/code/tests.yaml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/rag/pack.toml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/rag/system.txt +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/rag/tests.yaml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/reply/pack.toml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/reply/system.txt +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/reply/tests.yaml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/tool_call/pack.toml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/tool_call/system.txt +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/tool_call/tests.yaml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/tool_call/tools.yaml +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/tui.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/tune.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/verdict.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/watch_proxy.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/workspace.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/yamlout.py +0 -0
- {tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/tests/mock_server.py +0 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Fix: hosted models no longer count as running alongside local ones (they don't share the machine), so a one-model-at-a-time setup no longer gets the "ran alongside other models" note. Older results are read the same way.
|
|
5
6
|
- Results, Per question: the model summary shows every picked model without scrolling, and fits the window: shorter column names, and long model names cut in the middle (both ends kept). The PTA index table fits the same way.
|
|
6
7
|
- PTA index: the accuracy bar shows answers cut off at max_tokens in orange, with `(n% truncated)` beside it and a **truncated** column in the table, so overthinking stands apart from wrong answers.
|
|
7
8
|
- Results → Insights (also `tuieval insights`): charts with what to do next: every model against a reference (95% CI), the best model per use case, fine-tunes against their base (`base` in models.toml), why models fail, accuracy against tokens or time, question health, and the Certify runs that would settle the strongest models' verdicts. `[defaults] reference` sets the default reference.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tuieval
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev100
|
|
4
4
|
Summary: Evaluate local and frontier LLMs on your own questions: accuracy, speed, tokens and PASS/FAIL verdicts, in the terminal.
|
|
5
5
|
Project-URL: Homepage, https://github.com/ashe-wb/tuieval
|
|
6
6
|
Project-URL: Issues, https://github.com/ashe-wb/tuieval/issues
|
|
@@ -94,7 +94,7 @@ By default a run serves one model at a time. On a machine with room for more, se
|
|
|
94
94
|
- Models start in queue order, each in its own lane. The next one waits while its fit-check memory estimate wouldn't fit next to the ones running (without one, e.g. a server that sizes its own memory, the setting decides). Contexts are never shrunk to make room.
|
|
95
95
|
- A second model on the same server gets a free port, so a server's `cmd` must take `{port}`.
|
|
96
96
|
- A server with `before_start` (which may stop other servers) always runs on its own. Tuning is always one model at a time.
|
|
97
|
-
- Answers are judged exactly as in a run of one model. Each answer records the models served while it ran (`ran_alongside`), and a load time measured next to others is marked (`loaded_alongside`), since models side by side share the machine's GPU and memory bandwidth. The speed table and the answer view show it.
|
|
97
|
+
- Answers are judged exactly as in a run of one model. Each answer records the models served while it ran (`ran_alongside`), and a load time measured next to others is marked (`loaded_alongside`), since models side by side share the machine's GPU and memory bandwidth. Only local models count: hosted ones share nothing of the machine. The speed table and the answer view show it.
|
|
98
98
|
- In the TUI, one model's answers stream at a time: `v` switches to the next, `k` skips the one streaming. `tuieval run` prints one line per answer instead of streaming.
|
|
99
99
|
- Only one run uses the machine at a time across tuieval windows; models at a time applies within a run.
|
|
100
100
|
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.2.0.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 2, 0, '
|
|
21
|
+
__version__ = version = '0.2.0.dev100'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 0, 'dev100')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -41,6 +41,7 @@ def _load_native(data):
|
|
|
41
41
|
"pack": pack["name"], "pack_fp": pack["fingerprint"],
|
|
42
42
|
# hosted (OpenRouter) models: the provider endpoint and its declared quantization
|
|
43
43
|
"endpoint": run.get("endpoint"), "quantization": run.get("quantization"),
|
|
44
|
+
"hosted": bool(run.get("hosted") or run.get("endpoint")),
|
|
44
45
|
"loaded_alongside": run.get("loaded_alongside") or []}
|
|
45
46
|
rows = []
|
|
46
47
|
for r in data["results"]:
|
|
@@ -78,9 +79,37 @@ def load(paths):
|
|
|
78
79
|
row.update(raw=rec, path=path, pack_fp=data["pack"]["fingerprint"])
|
|
79
80
|
rows += r
|
|
80
81
|
infos.append(i)
|
|
82
|
+
# older results also noted hosted models alongside, which share nothing of this machine: a hosted
|
|
83
|
+
# model's rows note no one, and no one notes it
|
|
84
|
+
labels, prefixes = configured_hosted(paths)
|
|
85
|
+
labels |= {i["label"] for i in infos if i["hosted"]}
|
|
86
|
+
|
|
87
|
+
def local(along):
|
|
88
|
+
return [l for l in along if l not in labels and not l.startswith(tuple(prefixes))]
|
|
89
|
+
for row in rows:
|
|
90
|
+
row["alongside"] = [] if row["model"] in labels else local(row["alongside"])
|
|
91
|
+
for i in infos:
|
|
92
|
+
i["loaded_alongside"] = [] if i["label"] in labels else local(i["loaded_alongside"])
|
|
81
93
|
return rows, infos
|
|
82
94
|
|
|
83
95
|
|
|
96
|
+
def configured_hosted(paths):
|
|
97
|
+
"""(labels, label prefixes) models.toml says are hosted, in the workspaces these results/<label>/
|
|
98
|
+
<pack>.json are from: its hosted models, and the prefix of models named at run time on a hosted
|
|
99
|
+
server (e.g. "or-"). Covers hosted models whose results aren't loaded."""
|
|
100
|
+
from . import engine
|
|
101
|
+
labels, prefixes = set(), set()
|
|
102
|
+
for root in {os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(p)))) for p in paths}:
|
|
103
|
+
try:
|
|
104
|
+
cfg = engine.load_config(os.path.join(root, "models.toml"))
|
|
105
|
+
except Exception:
|
|
106
|
+
continue # no readable models.toml there: the results' own marks still apply
|
|
107
|
+
labels |= {m["label"] for m in cfg["models"] if engine.hosted(cfg, m)}
|
|
108
|
+
prefixes |= {engine.remote_label(n, s, "") for n, s in cfg["servers"].items()
|
|
109
|
+
if s.get("any_model") and engine.hosted(cfg, {"server": n})}
|
|
110
|
+
return labels, prefixes
|
|
111
|
+
|
|
112
|
+
|
|
84
113
|
def default_paths(results_dir=None):
|
|
85
114
|
"""results/<label>/<pack>.json, excluding smoke runs and the archive."""
|
|
86
115
|
results_dir = results_dir or workspace.path("results")
|
|
@@ -83,6 +83,21 @@ def builtin_config():
|
|
|
83
83
|
return tomllib.load(f)
|
|
84
84
|
|
|
85
85
|
|
|
86
|
+
def hosted(cfg, m):
|
|
87
|
+
"""A model served by an API elsewhere: tuieval doesn't start its server and its url isn't this
|
|
88
|
+
machine (or its server sets hosted = true). A server you started yourself on localhost still
|
|
89
|
+
counts as local (it uses the GPU)."""
|
|
90
|
+
if m.get("remote"):
|
|
91
|
+
return True
|
|
92
|
+
server = cfg["servers"][m["server"]]
|
|
93
|
+
if "hosted" in server: # say so for a server the url doesn't give away (e.g. a local proxy to an API)
|
|
94
|
+
return bool(server["hosted"])
|
|
95
|
+
if server.get("cmd"):
|
|
96
|
+
return False
|
|
97
|
+
host = urllib.parse.urlparse(server.get("url") or "").hostname or ""
|
|
98
|
+
return bool(host) and host not in ("localhost", "127.0.0.1", "::1", "0.0.0.0")
|
|
99
|
+
|
|
100
|
+
|
|
86
101
|
def load_config(path):
|
|
87
102
|
"""Read models.toml, fill in the built-ins it leaves out (builtin.toml) and each model's defaults.
|
|
88
103
|
[defaults] are filled key by key; [sampling] only when models.toml has none (sampling is part of
|
|
@@ -675,8 +690,9 @@ class Lane:
|
|
|
675
690
|
"""One model being run: its own request stream, stall reason and skip switch, so models run
|
|
676
691
|
side by side (parallel_models) stop independently. Runs and tunes in one lane use the engine's
|
|
677
692
|
main lane."""
|
|
678
|
-
def __init__(self, label=None):
|
|
693
|
+
def __init__(self, label=None, hosted=False):
|
|
679
694
|
self.label = label
|
|
695
|
+
self.hosted = hosted # a hosted model shares nothing of this machine, so it's never noted alongside
|
|
680
696
|
self.stream = None
|
|
681
697
|
self.stall = None # set by the stall watcher: why this model's server stalled
|
|
682
698
|
self.skip = threading.Event()
|
|
@@ -1282,18 +1298,7 @@ class Engine:
|
|
|
1282
1298
|
+ min(parallel_hosted or self.parallel_hosted(), hosted))
|
|
1283
1299
|
|
|
1284
1300
|
def hosted(self, m):
|
|
1285
|
-
|
|
1286
|
-
machine (or its server sets hosted = true). A server you started yourself on localhost still
|
|
1287
|
-
counts as local (it uses the GPU)."""
|
|
1288
|
-
if m.get("remote"):
|
|
1289
|
-
return True
|
|
1290
|
-
server = self.cfg["servers"][m["server"]]
|
|
1291
|
-
if "hosted" in server: # say so for a server the url doesn't give away (e.g. a local proxy to an API)
|
|
1292
|
-
return bool(server["hosted"])
|
|
1293
|
-
if server.get("cmd"):
|
|
1294
|
-
return False
|
|
1295
|
-
host = urllib.parse.urlparse(server.get("url") or "").hostname or ""
|
|
1296
|
-
return bool(host) and host not in ("localhost", "127.0.0.1", "::1", "0.0.0.0")
|
|
1301
|
+
return hosted(self.cfg, m)
|
|
1297
1302
|
|
|
1298
1303
|
def memory_need_gb(self, m):
|
|
1299
1304
|
"""GPU memory a model takes while served here: 0 for one we don't start (a hosted API or a
|
|
@@ -1817,15 +1822,23 @@ class Engine:
|
|
|
1817
1822
|
for t in threads:
|
|
1818
1823
|
t.join()
|
|
1819
1824
|
|
|
1825
|
+
def _local_lanes(self, lane, exclude=None):
|
|
1826
|
+
"""Labels of the local models served now (call with _lanes_lock held); none for a hosted lane."""
|
|
1827
|
+
if lane.hosted:
|
|
1828
|
+
return set()
|
|
1829
|
+
return {l for l, o in self._lanes.items() if not o.hosted} - {exclude}
|
|
1830
|
+
|
|
1820
1831
|
def _run_lane(self, label, mine):
|
|
1821
1832
|
"""One model's jobs, in this thread's own lane. Other models served meanwhile are noted on
|
|
1822
|
-
each answer (ran_alongside), since they share the machine's GPU and memory bandwidth.
|
|
1823
|
-
|
|
1833
|
+
each answer (ran_alongside), since they share the machine's GPU and memory bandwidth. Hosted
|
|
1834
|
+
models share neither, so they note nothing and nobody notes them."""
|
|
1824
1835
|
m = mine[0].model
|
|
1836
|
+
lane = Lane(label, self.hosted(m))
|
|
1825
1837
|
with self._lanes_lock:
|
|
1826
|
-
|
|
1827
|
-
other.
|
|
1828
|
-
|
|
1838
|
+
if not lane.hosted:
|
|
1839
|
+
for other in self._lanes.values():
|
|
1840
|
+
other.seen.add(label)
|
|
1841
|
+
lane.seen = self._local_lanes(lane)
|
|
1829
1842
|
if self.cfg["servers"][m["server"]].get("cmd"):
|
|
1830
1843
|
lane.port = self._lane_port(m)
|
|
1831
1844
|
self._lanes[label] = lane
|
|
@@ -1987,6 +2000,8 @@ class Engine:
|
|
|
1987
2000
|
"kv_type": sv.kv_type, "perf_args": sv.perf_args if local else None,
|
|
1988
2001
|
"perf_source": sv.perf_source, "server_version": self.server_version(m) if local else None}
|
|
1989
2002
|
ep = self.endpoint(m)
|
|
2003
|
+
if self.hosted(m):
|
|
2004
|
+
serving_info["hosted"] = True
|
|
1990
2005
|
if ep:
|
|
1991
2006
|
serving_info.update(endpoint=ep["tag"], provider=ep.get("provider"), quantization=ep.get("quantization"))
|
|
1992
2007
|
for j in jobs:
|
|
@@ -2244,7 +2259,7 @@ class Engine:
|
|
|
2244
2259
|
self._check()
|
|
2245
2260
|
lane = self._lane()
|
|
2246
2261
|
with self._lanes_lock:
|
|
2247
|
-
lane.seen =
|
|
2262
|
+
lane.seen = self._local_lanes(lane, job.label)
|
|
2248
2263
|
self.emit("request_started", job=job, test=test["description"], test_id=test["id"],
|
|
2249
2264
|
has_image=bool(test.get("image")), repeat=rep, difficulty=test.get("difficulty", "unrated"))
|
|
2250
2265
|
waits = list(self.SERVER_RETRY_WAITS_S)
|
|
@@ -893,15 +893,42 @@ class HostedBeside(unittest.TestCase):
|
|
|
893
893
|
|
|
894
894
|
def test_hosted_run_beside_local_with_one_slot(self):
|
|
895
895
|
from tuieval import engine
|
|
896
|
-
|
|
896
|
+
together = set()
|
|
897
|
+
|
|
898
|
+
def on_event(kind, **d):
|
|
899
|
+
if kind == "request_started":
|
|
900
|
+
together.add(frozenset(e._lanes))
|
|
901
|
+
e = engine.Engine(on_event, root=self.ws)
|
|
897
902
|
self.assertEqual([e.hosted(e.model(l)) for l in ("loc", "h1", "h2")], [False, True, True])
|
|
898
903
|
self.assertEqual(e.models_at_once({"loc", "h1", "h2"}, 1, 4), 3)
|
|
899
904
|
jobs = e.plan(["loc", "h1", "h2"], ["apps"], None, "certify", False, {})
|
|
900
905
|
e.run(jobs, parallel=1)
|
|
901
906
|
self.assertEqual([j.status for j in jobs], ["done"] * 3, [(j.key, j.note) for j in jobs])
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
907
|
+
self.assertIn(frozenset({"loc", "h1", "h2"}), together) # neither hosted model waited for the local one
|
|
908
|
+
# hosted models share nothing of this machine: no one notes them alongside, and they note no one
|
|
909
|
+
for label in ("loc", "h1", "h2"):
|
|
910
|
+
self.assertFalse(any("ran_alongside" in r for r in self.results(label)), label)
|
|
911
|
+
data = json.loads(read(os.path.join(self.ws, "results", "h1", "apps.json")))
|
|
912
|
+
self.assertTrue(data["run"]["hosted"])
|
|
913
|
+
self.assertNotIn("loaded_alongside", json.loads(read(os.path.join(self.ws, "results", "loc", "apps.json")))["run"])
|
|
914
|
+
|
|
915
|
+
def test_older_results_drop_hosted_models_alongside(self):
|
|
916
|
+
from tuieval import compare
|
|
917
|
+
paths = []
|
|
918
|
+
# h1's results say it's hosted; or-gone (named at run time, results deleted) by its server's prefix
|
|
919
|
+
for label, run, along in (("loc", {}, ["h1", "loc2", "or-gone"]), ("h1", {"endpoint": "x/fp8"}, ["loc"])):
|
|
920
|
+
data = {"format": "evals/1", "model": {"label": label}, "pack": {"name": "p", "fingerprint": "f"},
|
|
921
|
+
"run": {**run, "loaded_alongside": along}, "settings": {},
|
|
922
|
+
"results": [{"test": "t", "description": "d", "pass": True, "score": 1.0, "reason": "",
|
|
923
|
+
"ran_alongside": along}]}
|
|
924
|
+
path = os.path.join(self.ws, "results", label, "p.json")
|
|
925
|
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
926
|
+
with open(path, "w") as f:
|
|
927
|
+
json.dump(data, f)
|
|
928
|
+
paths.append(path)
|
|
929
|
+
rows, infos = compare.load(paths)
|
|
930
|
+
self.assertEqual({r["model"]: r["alongside"] for r in rows}, {"loc": ["loc2"], "h1": []})
|
|
931
|
+
self.assertEqual({i["label"]: i["loaded_alongside"] for i in infos}, {"loc": ["loc2"], "h1": []})
|
|
905
932
|
|
|
906
933
|
def test_local_model_joins_a_hosted_only_run(self):
|
|
907
934
|
from tuieval import engine
|
|
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
|
{tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/tool_call/pack.toml
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/tool_call/system.txt
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/tool_call/tests.yaml
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev99 → tuieval-0.2.0.dev100}/src/tuieval/templates/packs/tool_call/tools.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|