tuieval 0.2.0.dev118__tar.gz → 0.2.0.dev120__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.dev118 → tuieval-0.2.0.dev120}/CHANGELOG.md +2 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/PKG-INFO +1 -1
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/_version.py +2 -2
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/tui.py +18 -9
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/tests/test_tuieval.py +37 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/.gitignore +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/LICENSE +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/README.md +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/RELEASING.md +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/README.md +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/favicon.ico +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/readme-header.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/social-preview.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/tuieval-icon-1024.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/tuieval-icon-128.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/tuieval-icon-16.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/tuieval-icon-16.svg +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/tuieval-icon-256.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/tuieval-icon-32.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/tuieval-icon-48.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/tuieval-icon-512.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/tuieval-icon-64.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/tuieval-icon-animated.svg +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/brand/tuieval-icon.svg +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/tui-answer-reasoning.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/tui-run-reasoning.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/images/tui-setup.png +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/models.md +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/docs/writing-packs.md +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/pyproject.toml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/__init__.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/__main__.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/builtin.toml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/cli.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/client.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/compare.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/dates.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/doctor.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/engine.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/export.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/graders/__init__.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/graders/answer.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/graders/code.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/graders/rag.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/graders/reply.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/graders/tool_call.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/insights.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/logs.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/machines.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/onboard.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/packs.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/profiles.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/pta.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/remove.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/run_evals.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/scaffold.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/selftest.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/models.toml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/answer/pack.toml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/answer/system.txt +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/answer/tests.yaml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/code/pack.toml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/code/system.txt +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/code/tests.yaml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/rag/pack.toml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/rag/system.txt +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/rag/tests.yaml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/reply/pack.toml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/reply/system.txt +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/reply/tests.yaml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/tool_call/pack.toml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/tool_call/system.txt +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/tool_call/tests.yaml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/tool_call/tools.yaml +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/tune.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/verdict.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/watch_proxy.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/workspace.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/yamlout.py +0 -0
- {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/tests/mock_server.py +0 -0
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Fix: `v` on the run screen switches to the last model still running when the stream shows one that has finished.
|
|
6
|
+
- Setup opens with no models ticked: at launch, after New run, and after Back from a run or tune. Packs and options are still remembered.
|
|
5
7
|
- Tuning: a server that refuses the `ignore_eos` request field is asked again without it, so strict servers can be tuned; the profile notes that workload answers may end early.
|
|
6
8
|
- Fix: a server that crashes mid-request (the stream ends with no finish reason) was graded as an empty or cut-short answer; it's a server error now, never counted against the model.
|
|
7
9
|
- Dates: answers record `answered_at` (older ones read it from their log name); tests get an added date (an `added` field, or the day tuieval first saw them, in `test-dates.json`). Shown in the answer view, Pick tests, Per question, Failures and Production readiness.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tuieval
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev120
|
|
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.dev120'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 0, 'dev120')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -751,11 +751,17 @@ class SetupScreen(Screen):
|
|
|
751
751
|
self.refresh_packs()
|
|
752
752
|
self.refresh_models()
|
|
753
753
|
state = self.app.load_state()
|
|
754
|
-
|
|
755
|
-
|
|
754
|
+
if state: # packs and options carry over; models start unticked every time
|
|
755
|
+
self.apply_selection({k: v for k, v in state.items() if k != "models"}, quiet=True)
|
|
756
|
+
else:
|
|
756
757
|
self.first_time_defaults()
|
|
757
758
|
self.query_one("#suites", SelectionList).focus()
|
|
758
759
|
|
|
760
|
+
def clear_models(self):
|
|
761
|
+
"""Untick every model (Setup shown again after a run: each run picks its models afresh)."""
|
|
762
|
+
self.selected_models = set()
|
|
763
|
+
self.refresh_models()
|
|
764
|
+
|
|
759
765
|
def first_time_defaults(self):
|
|
760
766
|
"""With nothing chosen before: tick the only pack and the only local model, and start on
|
|
761
767
|
Smoke until something has run (a 3-question check of the setup)."""
|
|
@@ -1155,7 +1161,7 @@ class SetupScreen(Screen):
|
|
|
1155
1161
|
reasons = sorted({j.note for j in jobs if j.status == "skipped"})
|
|
1156
1162
|
self.notify(f"Nothing selected can run: {'; '.join(reasons)}", severity="warning")
|
|
1157
1163
|
return
|
|
1158
|
-
self.app.save_state(sel)
|
|
1164
|
+
self.app.save_state({k: v for k, v in sel.items() if k != "models"}) # models aren't remembered
|
|
1159
1165
|
# Packs whose earlier answers a start would set aside (Retest, everything already done, or
|
|
1160
1166
|
# other questions or settings): the user picks per pack before anything moves.
|
|
1161
1167
|
rows, rerun = retest_rows(e, labels, suites, repeat, tier, picks, force)
|
|
@@ -1349,7 +1355,7 @@ class TuneScreen(Screen):
|
|
|
1349
1355
|
def action_back(self):
|
|
1350
1356
|
if self.running:
|
|
1351
1357
|
self.notify("Tuning keeps going; the header shows its progress. Press w to come back.")
|
|
1352
|
-
self.app.back_to_setup()
|
|
1358
|
+
self.app.back_to_setup(clear_models=True)
|
|
1353
1359
|
|
|
1354
1360
|
|
|
1355
1361
|
# ------------------------------------------------------------------ add model
|
|
@@ -2773,8 +2779,8 @@ class RunScreen(Screen):
|
|
|
2773
2779
|
def action_watch_next(self):
|
|
2774
2780
|
"""Stream the next model running alongside (from its next answer)."""
|
|
2775
2781
|
active = self.active()
|
|
2776
|
-
if
|
|
2777
|
-
self.notify("Only one model is running right now.")
|
|
2782
|
+
if not active or active == [self.watch]:
|
|
2783
|
+
self.notify("Only one model is running right now." if active else "No model is running right now.")
|
|
2778
2784
|
return
|
|
2779
2785
|
self.watch = active[(active.index(self.watch) + 1) % len(active)] if self.watch in active else active[0]
|
|
2780
2786
|
with self.buf_lock:
|
|
@@ -2825,7 +2831,7 @@ class RunScreen(Screen):
|
|
|
2825
2831
|
if self.running:
|
|
2826
2832
|
self.notify("Pick models and packs, then Start: add them to this run or queue them after it.",
|
|
2827
2833
|
timeout=8)
|
|
2828
|
-
self.app.back_to_setup() #
|
|
2834
|
+
self.app.back_to_setup(clear_models=True) # packs and options stay; models are picked afresh
|
|
2829
2835
|
self.app.screen.query_one("#models").focus()
|
|
2830
2836
|
|
|
2831
2837
|
@on(Button.Pressed, "#done-runs")
|
|
@@ -2835,7 +2841,7 @@ class RunScreen(Screen):
|
|
|
2835
2841
|
def action_back(self):
|
|
2836
2842
|
if self.running:
|
|
2837
2843
|
self.notify("The run keeps going; the header shows its progress. Press w to come back.")
|
|
2838
|
-
self.app.back_to_setup()
|
|
2844
|
+
self.app.back_to_setup(clear_models=True)
|
|
2839
2845
|
|
|
2840
2846
|
|
|
2841
2847
|
# ------------------------------------------------------------------ results
|
|
@@ -3789,9 +3795,12 @@ class EvalsApp(App):
|
|
|
3789
3795
|
return (f"\n\nThe {len(self.queue)} queued item(s) are dropped (the queue isn't kept after quitting): "
|
|
3790
3796
|
+ "; ".join(i.title for i in self.queue) + ".")
|
|
3791
3797
|
|
|
3792
|
-
def back_to_setup(self):
|
|
3798
|
+
def back_to_setup(self, clear_models=False):
|
|
3799
|
+
"""clear_models: Setup is being shown for a new pick (New run, Back), so no model stays ticked."""
|
|
3793
3800
|
while len(self.screen_stack) > 2 and not isinstance(self.screen, SetupScreen):
|
|
3794
3801
|
self.pop_screen()
|
|
3802
|
+
if clear_models and isinstance(self.screen, SetupScreen):
|
|
3803
|
+
self.screen.clear_models()
|
|
3795
3804
|
|
|
3796
3805
|
def show_session(self, screen):
|
|
3797
3806
|
if screen is None or screen is self.screen:
|
|
@@ -847,6 +847,17 @@ class Parallel(unittest.TestCase):
|
|
|
847
847
|
self.assertEqual({out["first"], out["switched"]}, {"a", "b"}) # v streams the other model
|
|
848
848
|
self.assertTrue(any(r.get("ran_alongside") for r in self.results("a")["results"]))
|
|
849
849
|
|
|
850
|
+
def test_watch_next_moves_to_the_last_model_running(self):
|
|
851
|
+
from tuieval.tui import RunScreen
|
|
852
|
+
run = unittest.mock.MagicMock(watch="a", buf={"reasoning": [], "answer": []}, buf_lock=threading.Lock())
|
|
853
|
+
run.active.return_value = ["b"] # a finished; only b is still running
|
|
854
|
+
RunScreen.action_watch_next(run)
|
|
855
|
+
self.assertEqual(run.watch, "b")
|
|
856
|
+
run.active.return_value = ["b"]
|
|
857
|
+
RunScreen.action_watch_next(run) # already watching the only one
|
|
858
|
+
self.assertEqual(run.watch, "b")
|
|
859
|
+
run.notify.assert_called_with("Only one model is running right now.")
|
|
860
|
+
|
|
850
861
|
def test_skip_one_model_keeps_the_other(self):
|
|
851
862
|
e, events = self.engine()
|
|
852
863
|
jobs = e.plan(["a", "b"], ["apps"], None, "certify", False, {})
|
|
@@ -2016,6 +2027,32 @@ class FirstRun(unittest.TestCase):
|
|
|
2016
2027
|
env=dict(os.environ, TUIEVAL_HOME=self.ws, TUIEVAL_DETECT_PORTS=""), timeout=60).stdout.strip()
|
|
2017
2028
|
self.assertEqual(out, "['first'] ['my-model'] smoke False") # tuning shows once something has run
|
|
2018
2029
|
|
|
2030
|
+
def test_setup_never_starts_with_models_ticked(self):
|
|
2031
|
+
tuieval(self.ws, "add", "my-model", "--server", "local")
|
|
2032
|
+
os.makedirs(os.path.join(self.ws, "logs"), exist_ok=True)
|
|
2033
|
+
write(os.path.join(self.ws, "logs", "tui_state.json"),
|
|
2034
|
+
json.dumps({"models": ["my-model"], "packs": ["first"], "tier": "certify", "repeat": 2}))
|
|
2035
|
+
code = textwrap.dedent("""
|
|
2036
|
+
import asyncio
|
|
2037
|
+
from tuieval.tui import EvalsApp
|
|
2038
|
+
from textual.widgets import SelectionList
|
|
2039
|
+
async def go():
|
|
2040
|
+
app = EvalsApp({})
|
|
2041
|
+
async with app.run_test(size=(140, 40)) as pilot:
|
|
2042
|
+
await pilot.pause()
|
|
2043
|
+
s = app.screen
|
|
2044
|
+
print(s.query_one("#suites", SelectionList).selected, sorted(s.selected_models), s.tier())
|
|
2045
|
+
s.selected_models = {"my-model"}
|
|
2046
|
+
s.refresh_models()
|
|
2047
|
+
app.back_to_setup(clear_models=True) # what New run and Back do
|
|
2048
|
+
await pilot.pause()
|
|
2049
|
+
print(s.query_one("#suites", SelectionList).selected, sorted(s.selected_models))
|
|
2050
|
+
asyncio.run(go())
|
|
2051
|
+
""")
|
|
2052
|
+
out = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True,
|
|
2053
|
+
env=dict(os.environ, TUIEVAL_HOME=self.ws, TUIEVAL_DETECT_PORTS=""), timeout=60).stdout
|
|
2054
|
+
self.assertEqual(out.strip().splitlines(), ["['first'] [] certify", "['first'] []"])
|
|
2055
|
+
|
|
2019
2056
|
def test_trimmed_names_keep_both_ends(self):
|
|
2020
2057
|
from tuieval.tui import fit_first_column, mid_trim, trim_names
|
|
2021
2058
|
name = "some-author--some-long-model-name-q4_k_m-vllm"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/tool_call/pack.toml
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/tool_call/system.txt
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/src/tuieval/templates/packs/tool_call/tests.yaml
RENAMED
|
File without changes
|
{tuieval-0.2.0.dev118 → tuieval-0.2.0.dev120}/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
|