tuieval 0.2.0.dev107__tar.gz → 0.2.0.dev108__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.dev107 → tuieval-0.2.0.dev108}/CHANGELOG.md +1 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/PKG-INFO +1 -1
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/_version.py +2 -2
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/tui.py +34 -7
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/tests/test_tuieval.py +41 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/.gitignore +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/LICENSE +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/README.md +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/RELEASING.md +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/README.md +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/favicon.ico +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/readme-header.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/social-preview.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/tuieval-icon-1024.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/tuieval-icon-128.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/tuieval-icon-16.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/tuieval-icon-16.svg +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/tuieval-icon-256.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/tuieval-icon-32.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/tuieval-icon-48.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/tuieval-icon-512.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/tuieval-icon-64.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/tuieval-icon-animated.svg +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/brand/tuieval-icon.svg +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/tui-answer-reasoning.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/tui-run-reasoning.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/images/tui-setup.png +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/models.md +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/docs/writing-packs.md +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/pyproject.toml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/__init__.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/__main__.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/builtin.toml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/cli.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/client.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/compare.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/doctor.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/engine.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/export.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/graders/__init__.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/graders/answer.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/graders/code.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/graders/rag.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/graders/reply.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/graders/tool_call.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/insights.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/logs.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/machines.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/onboard.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/packs.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/profiles.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/pta.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/remove.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/run_evals.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/scaffold.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/selftest.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/models.toml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/answer/pack.toml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/answer/system.txt +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/answer/tests.yaml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/code/pack.toml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/code/system.txt +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/code/tests.yaml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/rag/pack.toml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/rag/system.txt +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/rag/tests.yaml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/reply/pack.toml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/reply/system.txt +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/reply/tests.yaml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/tool_call/pack.toml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/tool_call/system.txt +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/tool_call/tests.yaml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/tool_call/tools.yaml +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/tune.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/verdict.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/watch_proxy.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/workspace.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/yamlout.py +0 -0
- {tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/tests/mock_server.py +0 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- The Models heading shows how many are selected, naming any the filter hides; Start asks first when some are hidden.
|
|
5
6
|
- Results → Failures: a Models button filters the list (the same pick as the other tabs), with the number of failures shown.
|
|
6
7
|
- 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.
|
|
7
8
|
- 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.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tuieval
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev108
|
|
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.dev108'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 0, 'dev108')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -776,10 +776,7 @@ class SetupScreen(Screen):
|
|
|
776
776
|
self.verdicts = {}
|
|
777
777
|
self.app.log(f"verdicts failed: {err!r}")
|
|
778
778
|
codes = group_codes(e)
|
|
779
|
-
self.
|
|
780
|
-
"[b]Models[/b] [dim][green]✓[/green] pass [red]✗[/red] fail [yellow]?[/yellow] inconclusive "
|
|
781
|
-
"grey = earlier · x hides[/dim]\n[dim]"
|
|
782
|
-
+ " ".join(f"{c} {g}" for g, c in codes.items()) + "[/dim]")
|
|
779
|
+
self.legend_codes = codes
|
|
783
780
|
n_hidden = sum(m["label"] in hidden for m in e.cfg["models"])
|
|
784
781
|
self.query_one("#show-hidden", Checkbox).label = f"Show hidden ({n_hidden})"
|
|
785
782
|
sections = {}
|
|
@@ -819,8 +816,27 @@ class SetupScreen(Screen):
|
|
|
819
816
|
at = values.index(keep) if keep in values else min(keep_at or 0, models.option_count - 1)
|
|
820
817
|
models.highlighted = min((i for i in enabled if i >= at), default=enabled[-1])
|
|
821
818
|
self.show_detail()
|
|
819
|
+
self.update_legend()
|
|
822
820
|
self.update_estimate()
|
|
823
821
|
|
|
822
|
+
def unseen_models(self):
|
|
823
|
+
"""Ticked models the list doesn't show right now (the filter leaves them out)."""
|
|
824
|
+
models = self.query_one("#models", SelectionList)
|
|
825
|
+
visible = {models.get_option_at_index(i).value for i in range(models.option_count)}
|
|
826
|
+
return [m["label"] for m in self.app.engine.cfg["models"]
|
|
827
|
+
if m["label"] in self.selected_models and m["label"] not in visible]
|
|
828
|
+
|
|
829
|
+
def update_legend(self):
|
|
830
|
+
"""The Models heading: how many are ticked (and which ones the filter hides), then the key."""
|
|
831
|
+
n, unseen = len(self.selected_models), self.unseen_models()
|
|
832
|
+
count = f"[b]{n}[/b] selected" if n else "[dim]none selected[/dim]"
|
|
833
|
+
if unseen:
|
|
834
|
+
count += f" [yellow]({len(unseen)} not shown: {rich_escape(', '.join(unseen))})[/yellow]"
|
|
835
|
+
self.query_one("#models-legend", Label).update(
|
|
836
|
+
f"[b]Models[/b] {count} [dim][green]✓[/green] pass [red]✗[/red] fail [yellow]?[/yellow] "
|
|
837
|
+
"inconclusive grey = earlier · x hides[/dim]\n[dim]"
|
|
838
|
+
+ " ".join(f"{c} {g}" for g, c in getattr(self, "legend_codes", {}).items()) + "[/dim]")
|
|
839
|
+
|
|
824
840
|
@on(SelectionList.SelectionHighlighted, "#models")
|
|
825
841
|
def show_detail(self, *_):
|
|
826
842
|
"""Everything about the highlighted model: verdicts in full, serving, per-pack results."""
|
|
@@ -894,6 +910,7 @@ class SetupScreen(Screen):
|
|
|
894
910
|
return
|
|
895
911
|
visible = {models.get_option_at_index(i).value for i in range(models.option_count)}
|
|
896
912
|
self.selected_models = (self.selected_models - visible) | set(models.selected)
|
|
913
|
+
self.update_legend()
|
|
897
914
|
self.update_estimate()
|
|
898
915
|
|
|
899
916
|
def tier(self):
|
|
@@ -1110,10 +1127,20 @@ class SetupScreen(Screen):
|
|
|
1110
1127
|
self.notify(f"Nothing to run: {item.problem}.", severity="warning")
|
|
1111
1128
|
return
|
|
1112
1129
|
self.app.start_or_queue(item)
|
|
1113
|
-
|
|
1114
|
-
|
|
1130
|
+
def asked(yes=True):
|
|
1131
|
+
if not yes:
|
|
1132
|
+
return
|
|
1133
|
+
if rows:
|
|
1134
|
+
self.app.push_screen(RetestScreen(rows, force, rerun), go)
|
|
1135
|
+
else:
|
|
1136
|
+
go({})
|
|
1137
|
+
unseen = self.unseen_models()
|
|
1138
|
+
if unseen: # ticks the filter hides are easy to forget: name them before anything starts
|
|
1139
|
+
self.app.push_screen(ConfirmScreen(
|
|
1140
|
+
f"Start {len(labels)} model(s)? {len(unseen)} of them the filter hides:\n "
|
|
1141
|
+
+ rich_escape("\n ".join(unseen) + f"\n\nAll selected: {', '.join(labels)}")), asked)
|
|
1115
1142
|
else:
|
|
1116
|
-
|
|
1143
|
+
asked()
|
|
1117
1144
|
|
|
1118
1145
|
def action_tune(self):
|
|
1119
1146
|
e = self.app.engine
|
|
@@ -1130,6 +1130,47 @@ class AddToRun(unittest.TestCase):
|
|
|
1130
1130
|
self.assertEqual(fewer, 4) # its 4 questions are no longer counted
|
|
1131
1131
|
self.assertEqual(out["running"], [False, True])
|
|
1132
1132
|
|
|
1133
|
+
def test_tui_counts_ticked_models_and_names_filtered_ones_before_start(self):
|
|
1134
|
+
code = textwrap.dedent("""
|
|
1135
|
+
import asyncio, json
|
|
1136
|
+
from tuieval.tui import EvalsApp, ConfirmScreen
|
|
1137
|
+
from textual.widgets import SelectionList, Input, Label
|
|
1138
|
+
async def go():
|
|
1139
|
+
app = EvalsApp({})
|
|
1140
|
+
async with app.run_test(size=(160, 50)) as pilot:
|
|
1141
|
+
await pilot.pause()
|
|
1142
|
+
s, out = app.screen, {}
|
|
1143
|
+
legend = lambda: str(s.query_one("#models-legend", Label).render())
|
|
1144
|
+
out["none"] = legend()
|
|
1145
|
+
s.query_one("#suites", SelectionList).select("apps")
|
|
1146
|
+
models = s.query_one("#models", SelectionList)
|
|
1147
|
+
models.select("a")
|
|
1148
|
+
models.select("b")
|
|
1149
|
+
await pilot.pause()
|
|
1150
|
+
out["two"] = legend()
|
|
1151
|
+
s.query_one("#filter", Input).value = "zzz-nothing"
|
|
1152
|
+
await pilot.pause()
|
|
1153
|
+
out["filtered"] = legend()
|
|
1154
|
+
s.action_start()
|
|
1155
|
+
await pilot.pause()
|
|
1156
|
+
out["asked"] = isinstance(app.screen, ConfirmScreen) and str(app.screen.question)
|
|
1157
|
+
await pilot.press("n")
|
|
1158
|
+
await pilot.pause()
|
|
1159
|
+
out["cancelled"] = app.screen is s and not app.is_busy()
|
|
1160
|
+
print(json.dumps(out))
|
|
1161
|
+
asyncio.run(go())
|
|
1162
|
+
""")
|
|
1163
|
+
p = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True, timeout=600,
|
|
1164
|
+
env=dict(os.environ, TUIEVAL_HOME=self.ws, TUIEVAL_DETECT_PORTS=""))
|
|
1165
|
+
out = json.loads(p.stdout.strip().splitlines()[-1]) if p.stdout.strip() else p.stderr
|
|
1166
|
+
self.assertIsInstance(out, dict, out)
|
|
1167
|
+
self.assertIn("none selected", out["none"])
|
|
1168
|
+
self.assertIn("2 selected", out["two"])
|
|
1169
|
+
self.assertNotIn("not shown", out["two"])
|
|
1170
|
+
self.assertIn("2 not shown: a, b", out["filtered"])
|
|
1171
|
+
self.assertIn("All selected: a, b", out["asked"])
|
|
1172
|
+
self.assertTrue(out["cancelled"])
|
|
1173
|
+
|
|
1133
1174
|
def test_tui_asks_before_skipping_a_model(self):
|
|
1134
1175
|
path = os.path.join(self.ws, "models.toml")
|
|
1135
1176
|
write(path, read(path).replace('"--delay", "0.2"', '"--delay", "3"')) # still running while it's asked
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/tool_call/pack.toml
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/tool_call/system.txt
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/src/tuieval/templates/packs/tool_call/tests.yaml
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev107 → tuieval-0.2.0.dev108}/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
|