tuieval 0.2.0.dev118__tar.gz → 0.2.0.dev119__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.
Files changed (80) hide show
  1. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/CHANGELOG.md +1 -0
  2. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/PKG-INFO +1 -1
  3. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/_version.py +2 -2
  4. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/tui.py +16 -7
  5. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/tests/test_tuieval.py +26 -0
  6. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/.gitignore +0 -0
  7. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/LICENSE +0 -0
  8. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/README.md +0 -0
  9. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/RELEASING.md +0 -0
  10. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/README.md +0 -0
  11. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/favicon.ico +0 -0
  12. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/readme-header.png +0 -0
  13. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/social-preview.png +0 -0
  14. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/tuieval-icon-1024.png +0 -0
  15. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/tuieval-icon-128.png +0 -0
  16. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/tuieval-icon-16.png +0 -0
  17. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/tuieval-icon-16.svg +0 -0
  18. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/tuieval-icon-256.png +0 -0
  19. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/tuieval-icon-32.png +0 -0
  20. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/tuieval-icon-48.png +0 -0
  21. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/tuieval-icon-512.png +0 -0
  22. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/tuieval-icon-64.png +0 -0
  23. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/tuieval-icon-animated.svg +0 -0
  24. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/brand/tuieval-icon.svg +0 -0
  25. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/tui-answer-reasoning.png +0 -0
  26. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/tui-run-reasoning.png +0 -0
  27. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/images/tui-setup.png +0 -0
  28. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/models.md +0 -0
  29. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/docs/writing-packs.md +0 -0
  30. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/pyproject.toml +0 -0
  31. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/__init__.py +0 -0
  32. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/__main__.py +0 -0
  33. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/builtin.toml +0 -0
  34. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/cli.py +0 -0
  35. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/client.py +0 -0
  36. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/compare.py +0 -0
  37. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/dates.py +0 -0
  38. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/doctor.py +0 -0
  39. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/engine.py +0 -0
  40. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/export.py +0 -0
  41. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/graders/__init__.py +0 -0
  42. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/graders/answer.py +0 -0
  43. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/graders/code.py +0 -0
  44. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/graders/rag.py +0 -0
  45. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/graders/reply.py +0 -0
  46. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/graders/tool_call.py +0 -0
  47. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/insights.py +0 -0
  48. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/logs.py +0 -0
  49. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/machines.py +0 -0
  50. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/onboard.py +0 -0
  51. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/packs.py +0 -0
  52. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/profiles.py +0 -0
  53. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/pta.py +0 -0
  54. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/remove.py +0 -0
  55. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/run_evals.py +0 -0
  56. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/scaffold.py +0 -0
  57. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/selftest.py +0 -0
  58. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/models.toml +0 -0
  59. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/answer/pack.toml +0 -0
  60. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/answer/system.txt +0 -0
  61. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/answer/tests.yaml +0 -0
  62. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/code/pack.toml +0 -0
  63. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/code/system.txt +0 -0
  64. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/code/tests.yaml +0 -0
  65. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/rag/pack.toml +0 -0
  66. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/rag/system.txt +0 -0
  67. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/rag/tests.yaml +0 -0
  68. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/reply/pack.toml +0 -0
  69. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/reply/system.txt +0 -0
  70. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/reply/tests.yaml +0 -0
  71. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/tool_call/pack.toml +0 -0
  72. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/tool_call/system.txt +0 -0
  73. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/tool_call/tests.yaml +0 -0
  74. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/templates/packs/tool_call/tools.yaml +0 -0
  75. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/tune.py +0 -0
  76. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/verdict.py +0 -0
  77. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/watch_proxy.py +0 -0
  78. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/workspace.py +0 -0
  79. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/src/tuieval/yamlout.py +0 -0
  80. {tuieval-0.2.0.dev118 → tuieval-0.2.0.dev119}/tests/mock_server.py +0 -0
@@ -2,6 +2,7 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - 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
6
  - 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
7
  - 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
8
  - 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.dev118
3
+ Version: 0.2.0.dev119
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.dev118'
22
- __version_tuple__ = version_tuple = (0, 2, 0, 'dev118')
21
+ __version__ = version = '0.2.0.dev119'
22
+ __version_tuple__ = version_tuple = (0, 2, 0, 'dev119')
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
- self.apply_selection(state, quiet=True)
755
- if not state:
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
@@ -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() # Setup still holds the last selection
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:
@@ -2016,6 +2016,32 @@ class FirstRun(unittest.TestCase):
2016
2016
  env=dict(os.environ, TUIEVAL_HOME=self.ws, TUIEVAL_DETECT_PORTS=""), timeout=60).stdout.strip()
2017
2017
  self.assertEqual(out, "['first'] ['my-model'] smoke False") # tuning shows once something has run
2018
2018
 
2019
+ def test_setup_never_starts_with_models_ticked(self):
2020
+ tuieval(self.ws, "add", "my-model", "--server", "local")
2021
+ os.makedirs(os.path.join(self.ws, "logs"), exist_ok=True)
2022
+ write(os.path.join(self.ws, "logs", "tui_state.json"),
2023
+ json.dumps({"models": ["my-model"], "packs": ["first"], "tier": "certify", "repeat": 2}))
2024
+ code = textwrap.dedent("""
2025
+ import asyncio
2026
+ from tuieval.tui import EvalsApp
2027
+ from textual.widgets import SelectionList
2028
+ async def go():
2029
+ app = EvalsApp({})
2030
+ async with app.run_test(size=(140, 40)) as pilot:
2031
+ await pilot.pause()
2032
+ s = app.screen
2033
+ print(s.query_one("#suites", SelectionList).selected, sorted(s.selected_models), s.tier())
2034
+ s.selected_models = {"my-model"}
2035
+ s.refresh_models()
2036
+ app.back_to_setup(clear_models=True) # what New run and Back do
2037
+ await pilot.pause()
2038
+ print(s.query_one("#suites", SelectionList).selected, sorted(s.selected_models))
2039
+ asyncio.run(go())
2040
+ """)
2041
+ out = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True,
2042
+ env=dict(os.environ, TUIEVAL_HOME=self.ws, TUIEVAL_DETECT_PORTS=""), timeout=60).stdout
2043
+ self.assertEqual(out.strip().splitlines(), ["['first'] [] certify", "['first'] []"])
2044
+
2019
2045
  def test_trimmed_names_keep_both_ends(self):
2020
2046
  from tuieval.tui import fit_first_column, mid_trim, trim_names
2021
2047
  name = "some-author--some-long-model-name-q4_k_m-vllm"
File without changes
File without changes