tuieval 0.2.0.dev86__tar.gz → 0.2.0.dev87__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.dev86 → tuieval-0.2.0.dev87}/CHANGELOG.md +1 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/PKG-INFO +1 -1
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/_version.py +2 -2
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/tui.py +20 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/tests/test_tuieval.py +65 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/.gitignore +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/LICENSE +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/README.md +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/RELEASING.md +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/README.md +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/favicon.ico +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/readme-header.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/social-preview.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/tuieval-icon-1024.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/tuieval-icon-128.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/tuieval-icon-16.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/tuieval-icon-16.svg +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/tuieval-icon-256.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/tuieval-icon-32.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/tuieval-icon-48.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/tuieval-icon-512.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/tuieval-icon-64.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/tuieval-icon-animated.svg +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/brand/tuieval-icon.svg +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/tui-answer-reasoning.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/tui-run-reasoning.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/images/tui-setup.png +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/models.md +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/docs/writing-packs.md +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/pyproject.toml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/__init__.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/__main__.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/builtin.toml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/cli.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/client.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/compare.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/doctor.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/engine.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/export.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/graders/__init__.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/graders/answer.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/graders/code.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/graders/rag.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/graders/reply.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/graders/tool_call.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/logs.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/machines.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/onboard.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/packs.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/profiles.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/pta.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/remove.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/run_evals.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/scaffold.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/selftest.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/models.toml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/answer/pack.toml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/answer/system.txt +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/answer/tests.yaml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/code/pack.toml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/code/system.txt +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/code/tests.yaml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/rag/pack.toml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/rag/system.txt +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/rag/tests.yaml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/reply/pack.toml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/reply/system.txt +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/reply/tests.yaml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/tool_call/pack.toml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/tool_call/system.txt +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/tool_call/tests.yaml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/tool_call/tools.yaml +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/tune.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/verdict.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/watch_proxy.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/workspace.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/yamlout.py +0 -0
- {tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/tests/mock_server.py +0 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- The run screen's queue keeps the running model in view, unless you scroll it yourself (scrolling back to it follows again).
|
|
5
6
|
- Start while a run is going skips models and packs already running or queued (it says which); picking only those adds nothing. Retest and picked questions still go through.
|
|
6
7
|
- Fix: something queued just as a run ended (while its server was stopping) now starts instead of waiting forever.
|
|
7
8
|
- Hosted models (OpenRouter and other APIs) run beside local ones instead of waiting for a slot: up to `parallel_hosted` at a time (default 4, `--parallel-hosted N`). Local models can be added to a hosted-only run.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tuieval
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev87
|
|
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
|
|
@@ -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.dev87'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 0, 'dev87')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -2206,6 +2206,7 @@ class RunScreen(Screen):
|
|
|
2206
2206
|
yield Footer()
|
|
2207
2207
|
|
|
2208
2208
|
def on_mount(self):
|
|
2209
|
+
self._queue_follow, self._queue_y = True, None # follow_queue
|
|
2209
2210
|
q = self.query_one("#queue", DataTable)
|
|
2210
2211
|
for label, key in (("Model", "model"), ("Eval", "suite"), ("Status", "status"), ("Progress", "progress"),
|
|
2211
2212
|
("✓", "pass"), ("✗", "fail"), ("Time", "time"), ("Note", "note")):
|
|
@@ -2523,6 +2524,25 @@ class RunScreen(Screen):
|
|
|
2523
2524
|
self.update_job(j)
|
|
2524
2525
|
self.update_overall()
|
|
2525
2526
|
self.refresh_current()
|
|
2527
|
+
self.follow_queue()
|
|
2528
|
+
|
|
2529
|
+
def follow_queue(self):
|
|
2530
|
+
"""Keep the running model's row in view in the queue, unless you scrolled the queue yourself;
|
|
2531
|
+
scrolling back to where the running row shows picks the following up again."""
|
|
2532
|
+
q = self.query_one("#queue", DataTable)
|
|
2533
|
+
keys = [r.key.value for r in q.ordered_rows]
|
|
2534
|
+
now = next((i for i, k in enumerate(keys)
|
|
2535
|
+
if any(j.key == k and j.status in ("loading", "running") for j in self.jobs)), None)
|
|
2536
|
+
if now is None:
|
|
2537
|
+
return
|
|
2538
|
+
if self._queue_y is not None and q.scroll_y != self._queue_y: # you scrolled since we last did
|
|
2539
|
+
seen = q.scroll_y <= now < q.scroll_y + max(1, q.scrollable_content_region.height - 1)
|
|
2540
|
+
self._queue_follow = seen
|
|
2541
|
+
if self._queue_follow:
|
|
2542
|
+
q.scroll_to(y=max(0, now - 1), animate=False)
|
|
2543
|
+
self._queue_y = max(0, min(now - 1, q.max_scroll_y))
|
|
2544
|
+
else:
|
|
2545
|
+
self._queue_y = q.scroll_y
|
|
2526
2546
|
|
|
2527
2547
|
# -- actions
|
|
2528
2548
|
def action_skip_model(self):
|
|
@@ -1148,6 +1148,71 @@ class AddToRun(unittest.TestCase):
|
|
|
1148
1148
|
self.assertEqual(out["sessions"], [["a/apps", "done"], ["a/other", "done"], ["b/apps", "done"]])
|
|
1149
1149
|
|
|
1150
1150
|
|
|
1151
|
+
class QueueFollows(unittest.TestCase):
|
|
1152
|
+
"""The run screen's queue keeps the running model in view unless you scroll it yourself."""
|
|
1153
|
+
|
|
1154
|
+
def test_queue_follows_the_running_row(self):
|
|
1155
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
1156
|
+
ws = os.path.join(tmp, "ws")
|
|
1157
|
+
tuieval(tmp, "init", ws)
|
|
1158
|
+
for i in range(15):
|
|
1159
|
+
d = os.path.join(ws, "packs", f"p{i:02}")
|
|
1160
|
+
os.makedirs(d)
|
|
1161
|
+
write(os.path.join(d, "pack.toml"), f'label = "p{i:02}"\norder = {i}\n[certify]\nrepeat = 1\n[gate]\nmin_accuracy = 0.1\n')
|
|
1162
|
+
write(os.path.join(d, "tests.yaml"), f"- {{id: a, input: q{i} a, expected: 1, reference: 'ANSWER: 1', difficulty: easy}}\n"
|
|
1163
|
+
f"- {{id: b, input: q{i} b, expected: 1, reference: 'ANSWER: 1', difficulty: easy}}\n")
|
|
1164
|
+
mock = [sys.executable, os.path.join(HERE, "mock_server.py"), "--port", "{port}", "--packs",
|
|
1165
|
+
os.path.join(ws, "packs"), "--model", "{served_name}", "--delay", "0.4"]
|
|
1166
|
+
with open(os.path.join(ws, "models.toml"), "a") as f:
|
|
1167
|
+
f.write(f'\n[servers.mk]\ncmd = {json.dumps(mock)}\nport = {free_port()}\n'
|
|
1168
|
+
'\n[[models]]\nlabel = "m"\nserver = "mk"\nmodel = "m"\n')
|
|
1169
|
+
code = textwrap.dedent("""
|
|
1170
|
+
import asyncio, json, time
|
|
1171
|
+
from tuieval.tui import EvalsApp, RunScreen
|
|
1172
|
+
from textual.widgets import SelectionList, DataTable
|
|
1173
|
+
async def go():
|
|
1174
|
+
app = EvalsApp({})
|
|
1175
|
+
async with app.run_test(size=(160, 50)) as pilot:
|
|
1176
|
+
await pilot.pause()
|
|
1177
|
+
s = app.screen
|
|
1178
|
+
for i in range(15):
|
|
1179
|
+
s.query_one("#suites", SelectionList).select(f"p{i:02}")
|
|
1180
|
+
s.selected_models = {"m"}
|
|
1181
|
+
s.refresh_models()
|
|
1182
|
+
s.query_one("#tier-certify").value = True
|
|
1183
|
+
await pilot.pause()
|
|
1184
|
+
s.action_start()
|
|
1185
|
+
def at(run, n):
|
|
1186
|
+
return sum(j.status == "done" for j in run.jobs) >= n
|
|
1187
|
+
deadline = time.time() + 240
|
|
1188
|
+
while time.time() < deadline:
|
|
1189
|
+
await pilot.pause(0.2)
|
|
1190
|
+
if isinstance(app.screen, RunScreen) and at(app.screen, 12):
|
|
1191
|
+
break
|
|
1192
|
+
run = app.screen
|
|
1193
|
+
q = run.query_one("#queue", DataTable)
|
|
1194
|
+
await pilot.pause(1.5)
|
|
1195
|
+
followed = q.scroll_y
|
|
1196
|
+
q.scroll_to(y=0, animate=False) # you scroll up
|
|
1197
|
+
await pilot.pause(2.5)
|
|
1198
|
+
stayed = q.scroll_y
|
|
1199
|
+
q.scroll_to(y=q.max_scroll_y, animate=False) # back to where it runs
|
|
1200
|
+
await pilot.pause(2.5)
|
|
1201
|
+
again = q.scroll_y
|
|
1202
|
+
while run.running and time.time() < deadline:
|
|
1203
|
+
await pilot.pause(0.2)
|
|
1204
|
+
print(json.dumps({"followed": followed, "stayed": stayed, "again": again}))
|
|
1205
|
+
asyncio.run(go())
|
|
1206
|
+
""")
|
|
1207
|
+
p = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True, timeout=480,
|
|
1208
|
+
env=dict(os.environ, TUIEVAL_HOME=ws, TUIEVAL_DETECT_PORTS=""))
|
|
1209
|
+
out = json.loads(p.stdout.strip().splitlines()[-1]) if p.stdout.strip() else p.stderr
|
|
1210
|
+
self.assertIsInstance(out, dict, out)
|
|
1211
|
+
self.assertGreater(out["followed"], 0, out) # scrolled down to the running row by itself
|
|
1212
|
+
self.assertEqual(out["stayed"], 0, out) # your scroll wins
|
|
1213
|
+
self.assertGreater(out["again"], 0, out) # and following resumes once you're back
|
|
1214
|
+
|
|
1215
|
+
|
|
1151
1216
|
class PTAIndex(unittest.TestCase):
|
|
1152
1217
|
"""The PTA index: parsimony from tokens and speed from time, each relative to the best on a log
|
|
1153
1218
|
scale, and accuracy, all over the questions every compared model answered."""
|
|
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
|
{tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/tool_call/system.txt
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/src/tuieval/templates/packs/tool_call/tests.yaml
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev86 → tuieval-0.2.0.dev87}/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
|