tuieval 0.2.0.dev74__tar.gz → 0.2.0.dev75__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.dev74 → tuieval-0.2.0.dev75}/CHANGELOG.md +1 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/PKG-INFO +1 -1
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/_version.py +2 -2
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/tui.py +7 -6
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/tests/test_tuieval.py +50 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/.gitignore +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/LICENSE +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/README.md +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/RELEASING.md +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/README.md +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/favicon.ico +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/readme-header.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/social-preview.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/tuieval-icon-1024.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/tuieval-icon-128.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/tuieval-icon-16.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/tuieval-icon-16.svg +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/tuieval-icon-256.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/tuieval-icon-32.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/tuieval-icon-48.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/tuieval-icon-512.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/tuieval-icon-64.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/tuieval-icon-animated.svg +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/brand/tuieval-icon.svg +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/tui-answer-reasoning.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/tui-run-reasoning.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/images/tui-setup.png +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/models.md +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/docs/writing-packs.md +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/pyproject.toml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/__init__.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/__main__.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/builtin.toml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/cli.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/client.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/compare.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/doctor.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/engine.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/export.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/graders/__init__.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/graders/answer.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/graders/code.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/graders/rag.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/graders/reply.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/graders/tool_call.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/logs.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/machines.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/onboard.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/packs.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/profiles.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/pta.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/remove.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/run_evals.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/scaffold.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/selftest.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/models.toml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/answer/pack.toml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/answer/system.txt +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/answer/tests.yaml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/code/pack.toml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/code/system.txt +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/code/tests.yaml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/rag/pack.toml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/rag/system.txt +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/rag/tests.yaml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/reply/pack.toml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/reply/system.txt +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/reply/tests.yaml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/tool_call/pack.toml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/tool_call/system.txt +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/tool_call/tests.yaml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/tool_call/tools.yaml +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/tune.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/verdict.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/watch_proxy.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/workspace.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/yamlout.py +0 -0
- {tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/tests/mock_server.py +0 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Fix: a question description or grader reason containing `[` no longer crashes the run screen.
|
|
5
6
|
- Retest asks per pack before it starts: from zero, continue or leave out. It now really starts from zero, and replaced smoke results go to history/.
|
|
6
7
|
- Retest: the setup checkbox "Rerun existing results" is now "Retest (ask again, even if already answered)", and `tuieval run --retest` is the same (`--force` still works).
|
|
7
8
|
- `tuieval logs` follows the server log of the model running now and moves on with the run; `logs live` shows each answer as it finishes, `--list` every log.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tuieval
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev75
|
|
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.dev75'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 0, 'dev75')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -2239,9 +2239,10 @@ class RunScreen(Screen):
|
|
|
2239
2239
|
self.req_started, self.req_tokens, self.req_first = time.time(), 0, None
|
|
2240
2240
|
job = d["job"]
|
|
2241
2241
|
rep_note = f" · repeat {d['repeat'] + 1}/{job.repeat}" if job.repeat > 1 else ""
|
|
2242
|
-
self.current = (f"[b]{job.label}[/b] · {job.pack.label} · test
|
|
2242
|
+
self.current = (f"[b]{rich_escape(job.label)}[/b] · {rich_escape(job.pack.label)} · test "
|
|
2243
|
+
f"{job.done + 1}/{job.total}{rep_note}"
|
|
2243
2244
|
f"{' [magenta]🖼 image[/magenta]' if d['has_image'] else ''}\n"
|
|
2244
|
-
f"{diff_badge(d.get('difficulty', 'unrated'))} {d['test']}")
|
|
2245
|
+
f"{diff_badge(d.get('difficulty', 'unrated'))} {rich_escape(d['test'])}")
|
|
2245
2246
|
elif kind == "request_done":
|
|
2246
2247
|
if self.watched(kind, d):
|
|
2247
2248
|
self.flush_streams()
|
|
@@ -2251,12 +2252,12 @@ class RunScreen(Screen):
|
|
|
2251
2252
|
# follow new rows unless you're browsing an older one
|
|
2252
2253
|
at_end = not recent.has_focus or recent.cursor_row >= recent.row_count - 1
|
|
2253
2254
|
calls = f" [cyan]→ {r['tool_calls'][0]['name']}()[/cyan]" if r.get("tool_calls") else ""
|
|
2254
|
-
row_key = recent.add_row(mark, diff_badge(r.get("difficulty", "unrated")), r["description"][:50], job.label,
|
|
2255
|
+
row_key = recent.add_row(mark, diff_badge(r.get("difficulty", "unrated")), rich_escape(r["description"][:50]), job.label,
|
|
2255
2256
|
str(r.get("completion_tokens") or ""),
|
|
2256
2257
|
(f"{r['ttft_s']:.1f}" + (" ⟲" if r.get("cached_tokens") else ""))
|
|
2257
2258
|
if r.get("ttft_s") is not None else "",
|
|
2258
2259
|
f"{r['gen_tps']:.0f}" if r.get("gen_tps") else "", f"{r['total_s']:.0f}",
|
|
2259
|
-
r["reason"][:90] + calls
|
|
2260
|
+
rich_escape(r["reason"][:90]) + calls
|
|
2260
2261
|
+ (f" [red]copy of repeat {r['identical_to_repeat'] + 1}[/red]"
|
|
2261
2262
|
if r.get("identical_to_repeat") is not None else ""))
|
|
2262
2263
|
self.stats.append(r)
|
|
@@ -2364,7 +2365,7 @@ class RunScreen(Screen):
|
|
|
2364
2365
|
self.event("[bold yellow]REUSE[/bold yellow] " + msg)
|
|
2365
2366
|
self.notify(msg, severity="warning", timeout=20)
|
|
2366
2367
|
elif kind == "identical_answer":
|
|
2367
|
-
msg = (f"{d['label']} · {d['pack']} · {d['test']}: repeat {d['repeat'] + 1} is an exact copy of repeat "
|
|
2368
|
+
msg = (f"{d['label']} · {d['pack']} · {rich_escape(d['test'])}: repeat {d['repeat'] + 1} is an exact copy of repeat "
|
|
2368
2369
|
f"{d['same'] + 1}, so the server may be returning cached answers rather than fresh ones.")
|
|
2369
2370
|
self.event("[bold red]COPY[/bold red] " + msg)
|
|
2370
2371
|
self.notify(msg, severity="error", timeout=20)
|
|
@@ -2711,7 +2712,7 @@ class ResultsScreen(Screen):
|
|
|
2711
2712
|
# compare.failures lists the failed rows in order, so they line up with fail_rows
|
|
2712
2713
|
self.fail_rows = [r for r in rows if not r["ok"]]
|
|
2713
2714
|
for i, (model, test, reason, level) in enumerate(compare.failures(rows)):
|
|
2714
|
-
f.add_row(model, diff_badge(level), test, rich_escape(reason[:130]), key=str(i))
|
|
2715
|
+
f.add_row(model, diff_badge(level), rich_escape(test), rich_escape(reason[:130]), key=str(i))
|
|
2715
2716
|
self.fill_per_question()
|
|
2716
2717
|
self.fill_pta()
|
|
2717
2718
|
self.fill_readiness(results_dir)
|
|
@@ -735,6 +735,56 @@ class Parallel(unittest.TestCase):
|
|
|
735
735
|
self.assertEqual(sum(r["pass"] for r in self.results("b")["results"]), 6)
|
|
736
736
|
|
|
737
737
|
|
|
738
|
+
class MarkupInText(unittest.TestCase):
|
|
739
|
+
"""Brackets in a description or a grader's reason are shown as text: an unmatched
|
|
740
|
+
"[" once crashed the run screen (it swallowed the "[dim]" of the line after it)."""
|
|
741
|
+
|
|
742
|
+
def test_run_screen_shows_brackets(self):
|
|
743
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
744
|
+
ws = os.path.join(tmp, "ws")
|
|
745
|
+
tuieval(tmp, "init", ws)
|
|
746
|
+
d = os.path.join(ws, "packs", "br")
|
|
747
|
+
os.makedirs(d)
|
|
748
|
+
write(os.path.join(d, "pack.toml"), 'label = "Brackets"\n[certify]\nrepeat = 1\n[gate]\nmin_accuracy = 0.1\n')
|
|
749
|
+
write(os.path.join(d, "tests.yaml"),
|
|
750
|
+
"- {id: a, description: 'notional in [t - 10 s, t), excluding ties', input: q a, expected: 1, "
|
|
751
|
+
"reference: 'ANSWER: 1', wrong: ['ANSWER: [2'], difficulty: hard}\n"
|
|
752
|
+
"- {id: b, description: 'window [a, b) then [/dim] text', input: q b, expected: 1, "
|
|
753
|
+
"reference: 'ANSWER: 1', wrong: ['ANSWER: [2'], difficulty: hard}\n")
|
|
754
|
+
mock = [sys.executable, os.path.join(HERE, "mock_server.py"), "--port", "{port}", "--packs",
|
|
755
|
+
os.path.join(ws, "packs"), "--model", "{served_name}", "--mode", "wrong", "--delay", "0.2"]
|
|
756
|
+
with open(os.path.join(ws, "models.toml"), "a") as f:
|
|
757
|
+
f.write(f'\n[servers.mk]\ncmd = {json.dumps(mock)}\nport = {free_port()}\n'
|
|
758
|
+
'\n[[models]]\nlabel = "m"\nserver = "mk"\nmodel = "m"\n')
|
|
759
|
+
code = textwrap.dedent("""
|
|
760
|
+
import asyncio, json, time
|
|
761
|
+
from tuieval.tui import EvalsApp, RunScreen
|
|
762
|
+
from textual.widgets import SelectionList
|
|
763
|
+
async def go():
|
|
764
|
+
app = EvalsApp({})
|
|
765
|
+
async with app.run_test(size=(160, 50)) as pilot:
|
|
766
|
+
await pilot.pause()
|
|
767
|
+
s = app.screen
|
|
768
|
+
s.query_one("#suites", SelectionList).select("br")
|
|
769
|
+
s.selected_models = {"m"}
|
|
770
|
+
s.refresh_models()
|
|
771
|
+
s.query_one("#tier-certify").value = True
|
|
772
|
+
await pilot.pause()
|
|
773
|
+
s.action_start()
|
|
774
|
+
deadline = time.time() + 240
|
|
775
|
+
while time.time() < deadline:
|
|
776
|
+
await pilot.pause(0.2)
|
|
777
|
+
if isinstance(app.screen, RunScreen) and not app.screen.running:
|
|
778
|
+
break
|
|
779
|
+
print(json.dumps([(j.key, j.status, j.done) for j in app.screen.jobs]))
|
|
780
|
+
asyncio.run(go())
|
|
781
|
+
""")
|
|
782
|
+
p = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True, timeout=480,
|
|
783
|
+
env=dict(os.environ, TUIEVAL_HOME=ws, TUIEVAL_DETECT_PORTS=""))
|
|
784
|
+
self.assertNotIn("MarkupError", p.stderr + p.stdout)
|
|
785
|
+
self.assertEqual(json.loads(p.stdout.strip().splitlines()[-1]), [["m/br", "done", 2]], p.stderr[-2000:])
|
|
786
|
+
|
|
787
|
+
|
|
738
788
|
class AddToRun(unittest.TestCase):
|
|
739
789
|
"""More evals while a run is going: added to it (they run after its other jobs) or queued after it."""
|
|
740
790
|
|
|
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.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/tool_call/system.txt
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/src/tuieval/templates/packs/tool_call/tests.yaml
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev74 → tuieval-0.2.0.dev75}/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
|