tuieval 0.2.0.dev105__tar.gz → 0.2.0.dev107__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.dev105 → tuieval-0.2.0.dev107}/CHANGELOG.md +1 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/PKG-INFO +1 -1
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/_version.py +2 -2
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/tui.py +29 -7
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/tests/test_tuieval.py +16 -1
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/.gitignore +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/LICENSE +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/README.md +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/RELEASING.md +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/README.md +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/favicon.ico +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/readme-header.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/social-preview.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/tuieval-icon-1024.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/tuieval-icon-128.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/tuieval-icon-16.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/tuieval-icon-16.svg +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/tuieval-icon-256.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/tuieval-icon-32.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/tuieval-icon-48.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/tuieval-icon-512.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/tuieval-icon-64.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/tuieval-icon-animated.svg +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/brand/tuieval-icon.svg +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/tui-answer-reasoning.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/tui-run-reasoning.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/images/tui-setup.png +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/models.md +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/docs/writing-packs.md +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/pyproject.toml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/__init__.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/__main__.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/builtin.toml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/cli.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/client.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/compare.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/doctor.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/engine.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/export.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/graders/__init__.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/graders/answer.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/graders/code.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/graders/rag.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/graders/reply.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/graders/tool_call.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/insights.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/logs.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/machines.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/onboard.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/packs.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/profiles.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/pta.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/remove.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/run_evals.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/scaffold.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/selftest.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/models.toml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/answer/pack.toml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/answer/system.txt +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/answer/tests.yaml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/code/pack.toml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/code/system.txt +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/code/tests.yaml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/rag/pack.toml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/rag/system.txt +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/rag/tests.yaml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/reply/pack.toml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/reply/system.txt +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/reply/tests.yaml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/tool_call/pack.toml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/tool_call/system.txt +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/tool_call/tests.yaml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/tool_call/tools.yaml +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/tune.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/verdict.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/watch_proxy.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/workspace.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/yamlout.py +0 -0
- {tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/tests/mock_server.py +0 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Results → Failures: a Models button filters the list (the same pick as the other tabs), with the number of failures shown.
|
|
5
6
|
- Fix: an answer followed by a stray `</think>` (or a stray code fence after it) was graded as empty; the answer before the tag is graded now. The code grader also reads a doubled ```` ```python ```` fence as one.
|
|
6
7
|
- Run screen: `x` removes the highlighted pack from the run going if it hasn't started (the reverse of adding it); a model left with nothing isn't started.
|
|
7
8
|
- `k` (skip model) asks first, naming the model. Yes/no dialogs start on No; `y` answers yes, `n` or Esc no.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tuieval
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev107
|
|
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.dev107'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 0, 'dev107')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -454,7 +454,8 @@ with the model's reasoning and answer as they stream, then recent results with t
|
|
|
454
454
|
Results open here.
|
|
455
455
|
Production readiness one verdict per model and use case; the table says why and what to run next
|
|
456
456
|
Per question every question, model by model (filters: pack, level, Models disagree)
|
|
457
|
-
Failures every wrong answer with the grader's reason; enter opens it
|
|
457
|
+
Failures every wrong answer with the grader's reason (filter: Models); enter opens it
|
|
458
|
+
in full
|
|
458
459
|
|
|
459
460
|
Click a column name to sort a table by it; click it again to reverse. Empty cells stay last.
|
|
460
461
|
|
|
@@ -2825,6 +2826,9 @@ class ResultsScreen(Screen):
|
|
|
2825
2826
|
yield Static(id="pq-legend")
|
|
2826
2827
|
yield DataTable(id="per-question", zebra_stripes=True, cursor_type="cell")
|
|
2827
2828
|
with TabPane("Failures", id="tab-failures"):
|
|
2829
|
+
with Horizontal(id="fail-controls"):
|
|
2830
|
+
yield Button("Models: all", id="fail-models")
|
|
2831
|
+
yield Static(id="fail-count")
|
|
2828
2832
|
yield Static("[dim]Enter on a row shows the whole answer, its reasoning and what was checked.[/dim]")
|
|
2829
2833
|
yield DataTable(id="failures", zebra_stripes=True, cursor_type="row")
|
|
2830
2834
|
yield Footer()
|
|
@@ -2902,12 +2906,7 @@ class ResultsScreen(Screen):
|
|
|
2902
2906
|
info.update(f"{len(paths)} {'Smoke ' if smoke else ''}result files in {os.path.relpath(results_dir)}/" + banner
|
|
2903
2907
|
+ "".join(f"\n[yellow]⚠ {n}[/yellow]" for n in notes))
|
|
2904
2908
|
self.rows, self.infos = rows, infos
|
|
2905
|
-
|
|
2906
|
-
f.add_columns("Model", "Level", "Test", "Reason")
|
|
2907
|
-
# compare.failures lists the failed rows in order, so they line up with fail_rows
|
|
2908
|
-
self.fail_rows = [r for r in rows if not r["ok"]]
|
|
2909
|
-
for i, (model, test, reason, level) in enumerate(compare.failures(rows)):
|
|
2910
|
-
f.add_row(model, diff_badge(level), rich_escape(test), rich_escape(reason[:130]), key=str(i))
|
|
2909
|
+
self.fill_failures()
|
|
2911
2910
|
self.fill_per_question()
|
|
2912
2911
|
self.fill_pta()
|
|
2913
2912
|
self.fill_readiness(results_dir)
|
|
@@ -2916,6 +2915,24 @@ class ResultsScreen(Screen):
|
|
|
2916
2915
|
self.fill_insights()
|
|
2917
2916
|
self.sort_tables()
|
|
2918
2917
|
|
|
2918
|
+
def fill_failures(self):
|
|
2919
|
+
"""Every wrong answer, of the models picked (Models: shared with the other tabs)."""
|
|
2920
|
+
f = self.query_one("#failures", DataTable)
|
|
2921
|
+
f.clear(columns=True)
|
|
2922
|
+
f.add_columns("Model", "Level", "Test", "Reason")
|
|
2923
|
+
every = {r["model"] for r in self.rows}
|
|
2924
|
+
chosen = {m for m in self.app.pq_models if m in every}
|
|
2925
|
+
rows = [r for r in self.rows if not chosen or r["model"] in chosen]
|
|
2926
|
+
# compare.failures lists the failed rows in order, so they line up with fail_rows
|
|
2927
|
+
self.fail_rows = [r for r in rows if not r["ok"]]
|
|
2928
|
+
for i, (model, test, reason, level) in enumerate(compare.failures(rows)):
|
|
2929
|
+
f.add_row(model, diff_badge(level), rich_escape(test), rich_escape(reason[:130]), key=str(i))
|
|
2930
|
+
self.query_one("#fail-models", Button).label = f"Models: {len(chosen)} picked" if chosen else "Models: all"
|
|
2931
|
+
n = len(self.fail_rows)
|
|
2932
|
+
self.query_one("#fail-count", Static).update(
|
|
2933
|
+
f"{n} failure{'s' * (n != 1)}" + (f" of {len(chosen)} model{'s' * (len(chosen) != 1)}" if chosen else ""))
|
|
2934
|
+
self.sort_table(f)
|
|
2935
|
+
|
|
2919
2936
|
@on(DataTable.RowSelected, "#failures")
|
|
2920
2937
|
def failure_selected(self, event):
|
|
2921
2938
|
# in the order shown, so [ and ] step through them as sorted
|
|
@@ -2979,6 +2996,7 @@ class ResultsScreen(Screen):
|
|
|
2979
2996
|
@on(Button.Pressed, "#pq-models")
|
|
2980
2997
|
@on(Button.Pressed, "#pta-models")
|
|
2981
2998
|
@on(Button.Pressed, "#ins-models")
|
|
2999
|
+
@on(Button.Pressed, "#fail-models")
|
|
2982
3000
|
def pick_models(self):
|
|
2983
3001
|
counts = {}
|
|
2984
3002
|
for t in getattr(self, "pq_all_tests", []):
|
|
@@ -2997,6 +3015,7 @@ class ResultsScreen(Screen):
|
|
|
2997
3015
|
# after the picker has closed: a table rebuilt under a modal keeps its header-only widths
|
|
2998
3016
|
self.call_after_refresh(self.fill_per_question)
|
|
2999
3017
|
self.call_after_refresh(self.fill_pta)
|
|
3018
|
+
self.call_after_refresh(self.fill_failures)
|
|
3000
3019
|
self.insights_stale = True
|
|
3001
3020
|
if self.query_one(TabbedContent).active == "tab-insights":
|
|
3002
3021
|
self.call_after_refresh(self.fill_insights)
|
|
@@ -3397,6 +3416,9 @@ class EvalsApp(App):
|
|
|
3397
3416
|
#pq-controls Checkbox { width: auto; }
|
|
3398
3417
|
#pq-controls Select { width: 22; margin-right: 1; }
|
|
3399
3418
|
#pq-models { margin-right: 1; min-width: 20; }
|
|
3419
|
+
#fail-controls { height: 3; }
|
|
3420
|
+
#fail-models { margin-right: 1; min-width: 20; }
|
|
3421
|
+
#fail-count { width: auto; padding: 1 1; }
|
|
3400
3422
|
#pq-compare-title { padding: 0 1; height: auto; }
|
|
3401
3423
|
#pq-summary { height: auto; } /* every picked model, no scrolling: the tab scrolls instead */
|
|
3402
3424
|
#pq-legend { padding: 0 1; height: auto; }
|
|
@@ -1571,6 +1571,17 @@ class PTAIndex(unittest.TestCase):
|
|
|
1571
1571
|
app.screen.query_one(TabbedContent).active = "tab-failures"
|
|
1572
1572
|
await pilot.pause(0.3)
|
|
1573
1573
|
f = app.screen.query_one("#failures", DataTable)
|
|
1574
|
+
count = lambda: str(app.screen.query_one("#fail-count", Static).render())
|
|
1575
|
+
fails = {"all": [f.row_count, count()]}
|
|
1576
|
+
for m in ("good", "hosted"): # Models: only that model's failures
|
|
1577
|
+
app.pq_models = {m}
|
|
1578
|
+
app.screen.fill_failures()
|
|
1579
|
+
await pilot.pause(0.2)
|
|
1580
|
+
fails[m] = [f.row_count, count(), str(app.screen.query_one("#fail-models").label),
|
|
1581
|
+
sorted({str(f.get_row_at(r)[0]) for r in range(f.row_count)})]
|
|
1582
|
+
app.pq_models = set()
|
|
1583
|
+
app.screen.fill_failures()
|
|
1584
|
+
await pilot.pause(0.2)
|
|
1574
1585
|
await click_header(f, "Test")
|
|
1575
1586
|
sorts["tests"], _ = await click_header(f, "Test")
|
|
1576
1587
|
sorts["tests"] = [str(f.get_row_at(r)[2]) for r in range(f.row_count)]
|
|
@@ -1581,7 +1592,7 @@ class PTAIndex(unittest.TestCase):
|
|
|
1581
1592
|
s = app.screen
|
|
1582
1593
|
sorts["opened"] = s.entries[s.index]["record"]["test"]
|
|
1583
1594
|
print(json.dumps({"rows": rows, "bars": "P parsimony" in tri, "disagree": [both, alone],
|
|
1584
|
-
"tab": tab, "sorts": sorts}))
|
|
1595
|
+
"tab": tab, "sorts": sorts, "fails": fails}))
|
|
1585
1596
|
asyncio.run(go())
|
|
1586
1597
|
""")
|
|
1587
1598
|
p = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True, timeout=300,
|
|
@@ -1596,6 +1607,10 @@ class PTAIndex(unittest.TestCase):
|
|
|
1596
1607
|
self.assertEqual((s["up"], s["down"], s["kept"]), (["hosted", "good"], ["good", "hosted"], ["good", "hosted"]))
|
|
1597
1608
|
self.assertIn("answers right ▼", s["labels"])
|
|
1598
1609
|
self.assertEqual((s["tests"][0], s["opened"]), ("apps: d", "d"))
|
|
1610
|
+
fails = got["fails"]
|
|
1611
|
+
self.assertEqual(fails["all"], [4, "4 failures"])
|
|
1612
|
+
self.assertEqual(fails["good"], [0, "0 failures of 1 model", "Models: 1 picked", []])
|
|
1613
|
+
self.assertEqual(fails["hosted"], [4, "4 failures of 1 model", "Models: 1 picked", ["hosted"]])
|
|
1599
1614
|
|
|
1600
1615
|
|
|
1601
1616
|
class Unavailable(unittest.TestCase):
|
|
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.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/tool_call/pack.toml
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/tool_call/system.txt
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/src/tuieval/templates/packs/tool_call/tests.yaml
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev105 → tuieval-0.2.0.dev107}/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
|