evalshift 1.2.0__tar.gz → 1.2.2__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 (259) hide show
  1. {evalshift-1.2.0 → evalshift-1.2.2}/CHANGELOG.md +39 -1
  2. {evalshift-1.2.0 → evalshift-1.2.2}/PKG-INFO +13 -13
  3. {evalshift-1.2.0 → evalshift-1.2.2}/README.md +7 -7
  4. {evalshift-1.2.0 → evalshift-1.2.2}/docs/agents.md +2 -2
  5. evalshift-1.2.2/docs/changelog.md +6 -0
  6. {evalshift-1.2.0 → evalshift-1.2.2}/docs/configuration.md +1 -1
  7. {evalshift-1.2.0 → evalshift-1.2.2}/docs/getting-started.md +1 -1
  8. {evalshift-1.2.0 → evalshift-1.2.2}/docs/github-action.md +4 -4
  9. {evalshift-1.2.0 → evalshift-1.2.2}/docs/hosted.md +12 -6
  10. {evalshift-1.2.0 → evalshift-1.2.2}/docs/sdk.md +5 -5
  11. {evalshift-1.2.0 → evalshift-1.2.2}/examples/capture-first/README.md +1 -1
  12. {evalshift-1.2.0 → evalshift-1.2.2}/examples/capture-first/evalshift.yaml +1 -1
  13. {evalshift-1.2.0 → evalshift-1.2.2}/pyproject.toml +7 -7
  14. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/_scaffold.py +3 -3
  15. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/init.py +1 -1
  16. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/hosted/bundle_manifest.schema.json +2 -2
  17. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/hosted/push.py +42 -1
  18. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/hosted/trace_events.py +13 -1
  19. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/reports/templates/report.css +33 -0
  20. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/reports/templates/report.html.j2 +5 -2
  21. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/traces/models.py +7 -4
  22. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/utils/ci_pin.py +20 -4
  23. {evalshift-1.2.0 → evalshift-1.2.2}/tests/conftest.py +3 -3
  24. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/test_validate_command.py +1 -1
  25. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_ci_pin.py +32 -3
  26. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_cli_capture.py +1 -1
  27. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_docs_currency.py +28 -0
  28. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_doctor.py +1 -1
  29. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_hosted_cli.py +135 -0
  30. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_init.py +3 -3
  31. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_reports.py +15 -0
  32. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_suite_models.py +2 -2
  33. evalshift-1.2.0/docs/changelog.md +0 -6
  34. {evalshift-1.2.0 → evalshift-1.2.2}/.gitignore +0 -0
  35. {evalshift-1.2.0 → evalshift-1.2.2}/CLAUDE.md +0 -0
  36. {evalshift-1.2.0 → evalshift-1.2.2}/LICENSE +0 -0
  37. {evalshift-1.2.0 → evalshift-1.2.2}/docs/conversations.md +0 -0
  38. {evalshift-1.2.0 → evalshift-1.2.2}/docs/evaluators.md +0 -0
  39. {evalshift-1.2.0 → evalshift-1.2.2}/docs/faq.md +0 -0
  40. {evalshift-1.2.0 → evalshift-1.2.2}/docs/index.md +0 -0
  41. {evalshift-1.2.0 → evalshift-1.2.2}/docs/methodology.md +0 -0
  42. {evalshift-1.2.0 → evalshift-1.2.2}/docs/traces.md +0 -0
  43. {evalshift-1.2.0 → evalshift-1.2.2}/examples/agent/README.md +0 -0
  44. {evalshift-1.2.0 → evalshift-1.2.2}/examples/agent/evalshift.yaml +0 -0
  45. {evalshift-1.2.0 → evalshift-1.2.2}/examples/agent/golden.jsonl +0 -0
  46. {evalshift-1.2.0 → evalshift-1.2.2}/examples/agent/prompts.py +0 -0
  47. {evalshift-1.2.0 → evalshift-1.2.2}/examples/agent/tools.yaml +0 -0
  48. {evalshift-1.2.0 → evalshift-1.2.2}/examples/agent/toolsets/ad3f07832877239336d594c7c1626197b39b9eb4c178842304c8754e94323d67.json +0 -0
  49. {evalshift-1.2.0 → evalshift-1.2.2}/examples/agent-traces/evalshift.yaml +0 -0
  50. {evalshift-1.2.0 → evalshift-1.2.2}/examples/agent-traces/golden.jsonl +0 -0
  51. {evalshift-1.2.0 → evalshift-1.2.2}/examples/agent-traces/source-traces.jsonl +0 -0
  52. {evalshift-1.2.0 → evalshift-1.2.2}/examples/agent-traces/target-traces.jsonl +0 -0
  53. {evalshift-1.2.0 → evalshift-1.2.2}/examples/capture-first/.gitignore +0 -0
  54. {evalshift-1.2.0 → evalshift-1.2.2}/examples/capture-first/agent.py +0 -0
  55. {evalshift-1.2.0 → evalshift-1.2.2}/examples/simple/README.md +0 -0
  56. {evalshift-1.2.0 → evalshift-1.2.2}/examples/simple/evalshift.yaml +0 -0
  57. {evalshift-1.2.0 → evalshift-1.2.2}/examples/simple/golden.jsonl +0 -0
  58. {evalshift-1.2.0 → evalshift-1.2.2}/examples/simple/prompts.py +0 -0
  59. {evalshift-1.2.0 → evalshift-1.2.2}/scripts/smoke_live_tools.py +0 -0
  60. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/__init__.py +0 -0
  61. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/__main__.py +0 -0
  62. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/analysis/__init__.py +0 -0
  63. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/analysis/policy.py +0 -0
  64. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/analysis/slicing.py +0 -0
  65. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/analysis/statistics.py +0 -0
  66. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cache/__init__.py +0 -0
  67. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cache/schema.py +0 -0
  68. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cache/store.py +0 -0
  69. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/captures/__init__.py +0 -0
  70. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/captures/models.py +0 -0
  71. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/captures/promote.py +0 -0
  72. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/captures/reader.py +0 -0
  73. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/captures/toolset.py +0 -0
  74. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/__init__.py +0 -0
  75. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/__init__.py +0 -0
  76. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/_agents.py +0 -0
  77. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/_suites.py +0 -0
  78. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/analyze.py +0 -0
  79. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/bundle.py +0 -0
  80. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/cache.py +0 -0
  81. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/capture.py +0 -0
  82. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/compare.py +0 -0
  83. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/debug_artifacts.py +0 -0
  84. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/diff.py +0 -0
  85. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/doctor.py +0 -0
  86. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/evaluate.py +0 -0
  87. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/inspect.py +0 -0
  88. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/login.py +0 -0
  89. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/logout.py +0 -0
  90. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/push.py +0 -0
  91. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/replay.py +0 -0
  92. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/report.py +0 -0
  93. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/run.py +0 -0
  94. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/runs.py +0 -0
  95. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/test_call.py +0 -0
  96. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/traces.py +0 -0
  97. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/validate.py +0 -0
  98. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/commands/whoami.py +0 -0
  99. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/cli/main.py +0 -0
  100. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/config/__init__.py +0 -0
  101. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/config/loader.py +0 -0
  102. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/config/models.py +0 -0
  103. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/__init__.py +0 -0
  104. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/agent_trace.py +0 -0
  105. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/base.py +0 -0
  106. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/failures.py +0 -0
  107. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/llm_judge.py +0 -0
  108. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/semantic.py +0 -0
  109. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/structural.py +0 -0
  110. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/tool_arguments.py +0 -0
  111. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/tool_loader.py +0 -0
  112. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/tool_models.py +0 -0
  113. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/tool_parser.py +0 -0
  114. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/tool_rounds.py +0 -0
  115. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/tool_selection.py +0 -0
  116. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/evaluators/tool_trace_structure.py +0 -0
  117. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/hosted/__init__.py +0 -0
  118. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/hosted/bundle.py +0 -0
  119. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/hosted/client.py +0 -0
  120. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/hosted/credentials.py +0 -0
  121. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/insights/__init__.py +0 -0
  122. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/insights/facts.py +0 -0
  123. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/insights/generator.py +0 -0
  124. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/insights/models.py +0 -0
  125. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/insights/stage.py +0 -0
  126. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/insights/templates.py +0 -0
  127. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/models/__init__.py +0 -0
  128. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/models/capabilities.py +0 -0
  129. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/models/client.py +0 -0
  130. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/models/deepseek.py +0 -0
  131. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/models/family.py +0 -0
  132. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/models/registry.py +0 -0
  133. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/parsers/__init__.py +0 -0
  134. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/parsers/base.py +0 -0
  135. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/parsers/manual.py +0 -0
  136. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/parsers/python_string.py +0 -0
  137. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/py.typed +0 -0
  138. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/reports/__init__.py +0 -0
  139. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/reports/economics.py +0 -0
  140. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/reports/html.py +0 -0
  141. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/reports/json.py +0 -0
  142. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/runner/__init__.py +0 -0
  143. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/runner/checkpoint.py +0 -0
  144. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/runner/generation.py +0 -0
  145. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/runner/models.py +0 -0
  146. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/runner/orchestrator.py +0 -0
  147. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/suite/__init__.py +0 -0
  148. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/suite/loader.py +0 -0
  149. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/suite/models.py +0 -0
  150. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/suite/tags.py +0 -0
  151. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/traces/__init__.py +0 -0
  152. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/traces/diff.py +0 -0
  153. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/traces/loader.py +0 -0
  154. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/utils/__init__.py +0 -0
  155. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/utils/cost.py +0 -0
  156. {evalshift-1.2.0 → evalshift-1.2.2}/src/evalshift_cli/utils/templating.py +0 -0
  157. {evalshift-1.2.0 → evalshift-1.2.2}/tests/__init__.py +0 -0
  158. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/__init__.py +0 -0
  159. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/fixtures/validate_missing_var/evalshift.yaml +0 -0
  160. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/fixtures/validate_missing_var/golden.jsonl +0 -0
  161. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/fixtures/validate_non_literal/evalshift.yaml +0 -0
  162. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/fixtures/validate_non_literal/golden.jsonl +0 -0
  163. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/fixtures/validate_non_literal/prompts.py +0 -0
  164. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/fixtures/validate_ok/evalshift.yaml +0 -0
  165. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/fixtures/validate_ok/golden.jsonl +0 -0
  166. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/fixtures/validate_ok/prompts.py +0 -0
  167. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/replay_client.py +0 -0
  168. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/test_agent_trace_pipeline.py +0 -0
  169. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/test_capture_to_verdict.py +0 -0
  170. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/test_conversation_pipeline.py +0 -0
  171. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/test_multi_round_replay.py +0 -0
  172. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/test_scoring_semantics.py +0 -0
  173. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/test_simple_example.py +0 -0
  174. {evalshift-1.2.0 → evalshift-1.2.2}/tests/integration/test_tool_pipeline.py +0 -0
  175. {evalshift-1.2.0 → evalshift-1.2.2}/tests/scoring_fixtures.py +0 -0
  176. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/__init__.py +0 -0
  177. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/conftest.py +0 -0
  178. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/captures/multi_round_tools.json +0 -0
  179. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/scoring/project_insights_pairs.jsonl +0 -0
  180. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/anthropic/parallel_tool_calls.json +0 -0
  181. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/anthropic/refusal.json +0 -0
  182. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/anthropic/single_tool_call.json +0 -0
  183. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/anthropic/text_only.json +0 -0
  184. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/anthropic/tool_call_with_text.json +0 -0
  185. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/deepseek/single_tool_call.json +0 -0
  186. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/gemini/single_tool_call.json +0 -0
  187. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/gemini/text_only.json +0 -0
  188. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/openai/parallel_tool_calls.json +0 -0
  189. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/openai/refusal.json +0 -0
  190. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/openai/single_tool_call.json +0 -0
  191. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/fixtures/tool_responses/openai/text_only.json +0 -0
  192. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/insights_factories.py +0 -0
  193. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/suite_examples.py +0 -0
  194. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_agent_trace_evaluator.py +0 -0
  195. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_agents.py +0 -0
  196. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_analysis.py +0 -0
  197. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_analyze_command.py +0 -0
  198. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_bundle_shape.py +0 -0
  199. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_cache.py +0 -0
  200. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_captures_models.py +0 -0
  201. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_captures_promote.py +0 -0
  202. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_captures_reader.py +0 -0
  203. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_captures_toolset.py +0 -0
  204. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_checkpoint.py +0 -0
  205. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_cli_runs_clean.py +0 -0
  206. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_cli_smoke.py +0 -0
  207. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_compare_alias.py +0 -0
  208. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_compare_command.py +0 -0
  209. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_compare_suite_name.py +0 -0
  210. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_config_loader.py +0 -0
  211. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_config_models.py +0 -0
  212. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_config_suites.py +0 -0
  213. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_cost.py +0 -0
  214. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_debug_commands.py +0 -0
  215. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_deepseek.py +0 -0
  216. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_deferred_warnings.py +0 -0
  217. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_dropped_params.py +0 -0
  218. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_economics.py +0 -0
  219. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_evaluate_command.py +0 -0
  220. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_evaluators.py +0 -0
  221. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_failures.py +0 -0
  222. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_hosted_client.py +0 -0
  223. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_insight_facts.py +0 -0
  224. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_insight_generator.py +0 -0
  225. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_insights_stage.py +0 -0
  226. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_litellm_log_dedupe.py +0 -0
  227. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_litellm_log_stream.py +0 -0
  228. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_model_capabilities.py +0 -0
  229. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_model_client.py +0 -0
  230. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_model_family.py +0 -0
  231. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_model_registry.py +0 -0
  232. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_orchestrator.py +0 -0
  233. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_parsers.py +0 -0
  234. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_policy.py +0 -0
  235. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_push_server_id.py +0 -0
  236. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_push_validation.py +0 -0
  237. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_reserved_slice_name.py +0 -0
  238. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_run_command.py +0 -0
  239. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_run_determinism.py +0 -0
  240. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_run_retention.py +0 -0
  241. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_run_suite_name.py +0 -0
  242. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_runner_generation.py +0 -0
  243. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_runner_models.py +0 -0
  244. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_suite_loader.py +0 -0
  245. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_suites_helpers.py +0 -0
  246. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_templating.py +0 -0
  247. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_test_call_command.py +0 -0
  248. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_tool_arguments.py +0 -0
  249. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_tool_loader.py +0 -0
  250. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_tool_models.py +0 -0
  251. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_tool_parser.py +0 -0
  252. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_tool_rounds.py +0 -0
  253. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_tool_selection.py +0 -0
  254. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_tool_trace_structure.py +0 -0
  255. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_trace_diff.py +0 -0
  256. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_trace_events.py +0 -0
  257. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_trace_import_command.py +0 -0
  258. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_trace_models.py +0 -0
  259. {evalshift-1.2.0 → evalshift-1.2.2}/tests/unit/test_version.py +0 -0
@@ -7,6 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.2.2] - 2026-10-05
11
+
12
+ ### Fixed
13
+
14
+ - `evalshift push` printed a traceback instead of the upgrade prompt when hosted EvalShift
15
+ refused the run with HTTP 402 right after auto-creating the project (over the monthly run
16
+ or concurrent-run limit, or a subscription that stopped paying). It now prints the
17
+ server's message and the billing link and exits 1. A 402 while auto-creating the
18
+ project — what an organization whose trial has ended gets — now shows the same prompt
19
+ instead of an access-permission hint.
20
+ - `evalshift push` printed a traceback when the connection failed while auto-creating the
21
+ project; it now prints the error and exits 1.
22
+
23
+ ### Changed
24
+
25
+ - The EvalShift repositories moved from the `babaliauskas` GitHub account to
26
+ the `evalshift` organization: <https://github.com/evalshift/evalshift-cli>,
27
+ `evalshift-sdk` and `evalshift-action`. Links, package metadata and the
28
+ workflow `evalshift init --ci` scaffolds now use
29
+ `evalshift/evalshift-action@v0`. GitHub redirects the old names, so existing
30
+ workflows keep working.
31
+ - The CI pin check (`init`, `validate`, `doctor`, `capture sync`) recognizes
32
+ `evalshift/evalshift-action` steps as well as the old
33
+ `babaliauskas/evalshift-action` name, matching owner and repository names
34
+ case-insensitively as GitHub does.
35
+ - Docs and the `init --ci` workflow comment describe hosted EvalShift's current plans: a
36
+ 30-day Pro trial for every new account, then Pro per organization (the hosted Free and
37
+ Team plans are gone). Local runs stay free and unlimited.
38
+
39
+ ## [1.2.1] - 2026-10-01
40
+
41
+ ### Changed
42
+
43
+ - Top regressions in the HTML report now read as expandable: the worst one
44
+ in each section starts open, each row has a boxed caret and a
45
+ "Show details" / "Hide details" hint, and the header reacts on hover and
46
+ shows a keyboard focus ring. Printing expands every regression in
47
+ Chromium-based browsers.
48
+
10
49
  ## [1.2.0] - 2026-10-01
11
50
 
12
51
  Shipped as a minor again. The `slices` removal below is breaking by the
@@ -606,7 +645,6 @@ the key and the fix, which is the whole migration.
606
645
  that imported CLI internals (`from evalshift.models.client import …`) must
607
646
  import from `evalshift_cli`. No shim is possible — shipping any `evalshift/`
608
647
  file would recreate the collision — so this ships as a minor bump (0.14.0).
609
- Design: `docs/superpowers/specs/2026-09-09-namespace-collision-design.md`.
610
648
  - Docs: the capture guides (`README.md`, `DOCS.md`, `docs/sdk.md`,
611
649
  `docs/getting-started.md`, `llms-full.txt`) now cover the SDK 0.4.0 provider
612
650
  client wrappers (`wrap_openai` / `wrap_anthropic` / `wrap_genai`), the
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: evalshift
3
- Version: 1.2.0
3
+ Version: 1.2.2
4
4
  Summary: Run your prompts on two LLMs and find out, with statistical confidence, what regressed.
5
- Project-URL: Homepage, https://github.com/babaliauskas/evalshift-cli
6
- Project-URL: Documentation, https://github.com/babaliauskas/evalshift-cli#readme
7
- Project-URL: Repository, https://github.com/babaliauskas/evalshift-cli
8
- Project-URL: Issues, https://github.com/babaliauskas/evalshift-cli/issues
9
- Project-URL: Changelog, https://github.com/babaliauskas/evalshift-cli/blob/main/CHANGELOG.md
5
+ Project-URL: Homepage, https://github.com/evalshift/evalshift-cli
6
+ Project-URL: Documentation, https://github.com/evalshift/evalshift-cli#readme
7
+ Project-URL: Repository, https://github.com/evalshift/evalshift-cli
8
+ Project-URL: Issues, https://github.com/evalshift/evalshift-cli/issues
9
+ Project-URL: Changelog, https://github.com/evalshift/evalshift-cli/blob/main/CHANGELOG.md
10
10
  Author: Lukas Babaliauskas
11
11
  License-Expression: Apache-2.0
12
12
  License-File: LICENSE
@@ -57,7 +57,7 @@ Description-Content-Type: text/markdown
57
57
 
58
58
  Open-source LLM migration and regression testing for AI agents.
59
59
 
60
- [![CI](https://github.com/babaliauskas/evalshift-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/babaliauskas/evalshift-cli/actions/workflows/ci.yml)
60
+ [![CI](https://github.com/evalshift/evalshift-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/evalshift/evalshift-cli/actions/workflows/ci.yml)
61
61
  [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
62
62
  [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)
63
63
  [![PyPI](https://img.shields.io/pypi/v/evalshift.svg)](https://pypi.org/project/evalshift/)
@@ -82,7 +82,7 @@ statistics**: paired tests, Cohen's d, 95% CIs, and Benjamini-Hochberg
82
82
  correction across every (prompt x evaluator x slice) comparison.
83
83
 
84
84
  An eval is only worth the examples in it. That is why the
85
- [capture SDK](https://github.com/babaliauskas/evalshift-sdk) is part of the
85
+ [capture SDK](https://github.com/evalshift/evalshift-sdk) is part of the
86
86
  product rather than an add-on: it records real production runs — model calls,
87
87
  tool calls, final outputs — to disk, and `evalshift capture sync` promotes them
88
88
  into golden suites. Hand-written suites are fully supported too, but captured
@@ -99,7 +99,7 @@ Four pieces, released and documented independently:
99
99
  | --- | --- | --- |
100
100
  | **SDK** — PyPI `evalshift-sdk` | Records what your agent actually did in production — model calls, tool calls, final output — as capture files on disk. Those captures become your golden suite. | [docs/sdk.md](docs/sdk.md) |
101
101
  | **CLI** — this repo, PyPI `evalshift` | Replays the suite on two models, scores, analyses, reports, bundles, pushes. | [DOCS.md](DOCS.md) |
102
- | **GitHub Action** — `babaliauskas/evalshift-action@v0` | Runs the pipeline on pull requests, pushes the run, posts one PR comment, sets the `evalshift/regression` status. | [docs/github-action.md](docs/github-action.md) |
102
+ | **GitHub Action** — `evalshift/evalshift-action@v0` | Runs the pipeline on pull requests, pushes the run, posts one PR comment, sets the `evalshift/regression` status. | [docs/github-action.md](docs/github-action.md) |
103
103
  | **Hosted server** — `api.evalshift.dev`, web app at `evalshift.dev` | Optional. Stores pushed run bundles, diffs them across branches, drives PR comments and gating. | [docs/hosted.md](docs/hosted.md) |
104
104
 
105
105
  The SDK and the CLI never call each other — the interface is files under
@@ -150,7 +150,7 @@ uv pip install evalshift-sdk # or: pip install evalshift-sdk
150
150
  From source (for contributors):
151
151
 
152
152
  ```bash
153
- git clone https://github.com/babaliauskas/evalshift-cli.git
153
+ git clone https://github.com/evalshift/evalshift-cli.git
154
154
  cd evalshift-cli
155
155
  uv venv --python 3.11
156
156
  source .venv/bin/activate
@@ -168,7 +168,7 @@ candidate model to it.
168
168
  evalshift init # minimal capture-first evalshift.yaml
169
169
  ```
170
170
 
171
- Instrument the agent with [evalshift-sdk](https://github.com/babaliauskas/evalshift-sdk)
171
+ Instrument the agent with [evalshift-sdk](https://github.com/evalshift/evalshift-sdk)
172
172
  — stdlib-only, Python 3.10+, installed with the CLI or on its own:
173
173
 
174
174
  ```python
@@ -297,7 +297,7 @@ The short version:
297
297
 
298
298
  `evalshift init --ci` scaffolds a production-shaped workflow: it discovers
299
299
  every committed suite under `.evalshift/suites/`, evaluates each on every
300
- pull request via [`babaliauskas/evalshift-action@v0`](https://github.com/babaliauskas/evalshift-action)
300
+ pull request via [`evalshift/evalshift-action@v0`](https://github.com/evalshift/evalshift-action)
301
301
  (one matrix job per suite), pushes the runs to hosted EvalShift, compares
302
302
  against the latest compatible base-branch run, posts one PR comment, and
303
303
  gates merges on your `migration_policy` through a single required
@@ -423,7 +423,7 @@ Runnable projects under [`examples/`](examples/):
423
423
 
424
424
  [Apache-2.0](LICENSE). Free for any use, commercial included — no share-back
425
425
  requirement, and an explicit patent grant. The capture SDK
426
- ([`evalshift-sdk`](https://github.com/babaliauskas/evalshift-sdk)), the piece
426
+ ([`evalshift-sdk`](https://github.com/evalshift/evalshift-sdk)), the piece
427
427
  you import into your own application, is MIT.
428
428
 
429
429
  Earlier releases stay under the license they shipped with: `0.3.0` and earlier
@@ -2,7 +2,7 @@
2
2
 
3
3
  Open-source LLM migration and regression testing for AI agents.
4
4
 
5
- [![CI](https://github.com/babaliauskas/evalshift-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/babaliauskas/evalshift-cli/actions/workflows/ci.yml)
5
+ [![CI](https://github.com/evalshift/evalshift-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/evalshift/evalshift-cli/actions/workflows/ci.yml)
6
6
  [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
7
7
  [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)
8
8
  [![PyPI](https://img.shields.io/pypi/v/evalshift.svg)](https://pypi.org/project/evalshift/)
@@ -27,7 +27,7 @@ statistics**: paired tests, Cohen's d, 95% CIs, and Benjamini-Hochberg
27
27
  correction across every (prompt x evaluator x slice) comparison.
28
28
 
29
29
  An eval is only worth the examples in it. That is why the
30
- [capture SDK](https://github.com/babaliauskas/evalshift-sdk) is part of the
30
+ [capture SDK](https://github.com/evalshift/evalshift-sdk) is part of the
31
31
  product rather than an add-on: it records real production runs — model calls,
32
32
  tool calls, final outputs — to disk, and `evalshift capture sync` promotes them
33
33
  into golden suites. Hand-written suites are fully supported too, but captured
@@ -44,7 +44,7 @@ Four pieces, released and documented independently:
44
44
  | --- | --- | --- |
45
45
  | **SDK** — PyPI `evalshift-sdk` | Records what your agent actually did in production — model calls, tool calls, final output — as capture files on disk. Those captures become your golden suite. | [docs/sdk.md](docs/sdk.md) |
46
46
  | **CLI** — this repo, PyPI `evalshift` | Replays the suite on two models, scores, analyses, reports, bundles, pushes. | [DOCS.md](DOCS.md) |
47
- | **GitHub Action** — `babaliauskas/evalshift-action@v0` | Runs the pipeline on pull requests, pushes the run, posts one PR comment, sets the `evalshift/regression` status. | [docs/github-action.md](docs/github-action.md) |
47
+ | **GitHub Action** — `evalshift/evalshift-action@v0` | Runs the pipeline on pull requests, pushes the run, posts one PR comment, sets the `evalshift/regression` status. | [docs/github-action.md](docs/github-action.md) |
48
48
  | **Hosted server** — `api.evalshift.dev`, web app at `evalshift.dev` | Optional. Stores pushed run bundles, diffs them across branches, drives PR comments and gating. | [docs/hosted.md](docs/hosted.md) |
49
49
 
50
50
  The SDK and the CLI never call each other — the interface is files under
@@ -95,7 +95,7 @@ uv pip install evalshift-sdk # or: pip install evalshift-sdk
95
95
  From source (for contributors):
96
96
 
97
97
  ```bash
98
- git clone https://github.com/babaliauskas/evalshift-cli.git
98
+ git clone https://github.com/evalshift/evalshift-cli.git
99
99
  cd evalshift-cli
100
100
  uv venv --python 3.11
101
101
  source .venv/bin/activate
@@ -113,7 +113,7 @@ candidate model to it.
113
113
  evalshift init # minimal capture-first evalshift.yaml
114
114
  ```
115
115
 
116
- Instrument the agent with [evalshift-sdk](https://github.com/babaliauskas/evalshift-sdk)
116
+ Instrument the agent with [evalshift-sdk](https://github.com/evalshift/evalshift-sdk)
117
117
  — stdlib-only, Python 3.10+, installed with the CLI or on its own:
118
118
 
119
119
  ```python
@@ -242,7 +242,7 @@ The short version:
242
242
 
243
243
  `evalshift init --ci` scaffolds a production-shaped workflow: it discovers
244
244
  every committed suite under `.evalshift/suites/`, evaluates each on every
245
- pull request via [`babaliauskas/evalshift-action@v0`](https://github.com/babaliauskas/evalshift-action)
245
+ pull request via [`evalshift/evalshift-action@v0`](https://github.com/evalshift/evalshift-action)
246
246
  (one matrix job per suite), pushes the runs to hosted EvalShift, compares
247
247
  against the latest compatible base-branch run, posts one PR comment, and
248
248
  gates merges on your `migration_policy` through a single required
@@ -368,7 +368,7 @@ Runnable projects under [`examples/`](examples/):
368
368
 
369
369
  [Apache-2.0](LICENSE). Free for any use, commercial included — no share-back
370
370
  requirement, and an explicit patent grant. The capture SDK
371
- ([`evalshift-sdk`](https://github.com/babaliauskas/evalshift-sdk)), the piece
371
+ ([`evalshift-sdk`](https://github.com/evalshift/evalshift-sdk)), the piece
372
372
  you import into your own application, is MIT.
373
373
 
374
374
  Earlier releases stay under the license they shipped with: `0.3.0` and earlier
@@ -60,7 +60,7 @@ parsed `ToolTrace`, and the configured `tool_*` evaluators score against the
60
60
  per-example `expected_tools` ground truth.
61
61
 
62
62
  For your own agent, the recommended path is capture-first: instrument it
63
- with the [evalshift-sdk](https://github.com/babaliauskas/evalshift-sdk),
63
+ with the [evalshift-sdk](https://github.com/evalshift/evalshift-sdk),
64
64
  exercise it to record captures, then `evalshift capture sync` promotes them
65
65
  into a golden suite carrying the toolset your production agent actually
66
66
  offered — see [Getting started](getting-started.md).
@@ -135,7 +135,7 @@ Nothing in `evalshift.yaml` wires a toolset to a prompt — dispatch reads it
135
135
  off each golden-suite *example* instead (`toolset_ref` or inline `tools`, see
136
136
  [Suite ground truth](#suite-ground-truth) below), so the same prompt can
137
137
  legitimately dispatch some examples with tools and others without, in one
138
- run. [`examples/agent/tools.yaml`](https://github.com/babaliauskas/evalshift-cli/blob/main/examples/agent/tools.yaml) is just this project's human-readable record of what
138
+ run. [`examples/agent/tools.yaml`](https://github.com/evalshift/evalshift-cli/blob/main/examples/agent/tools.yaml) is just this project's human-readable record of what
139
139
  those tools are; it accepts either Anthropic-shape (`name` / `description` /
140
140
  `input_schema`) or OpenAI-shape (`{ "type": "function", "function": {...}
141
141
  }`) entries — `evalshift run` serialises whatever a toolset resolves to in
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ This page mirrors [`CHANGELOG.md`](https://github.com/evalshift/evalshift-cli/blob/main/CHANGELOG.md)
4
+ in the repository.
5
+
6
+ For the canonical, always-current version, see the file in the repo.
@@ -366,7 +366,7 @@ A list of prompt definitions. Each entry has:
366
366
  | `judge_model` | string | `gemini-3.1-flash-lite-preview` | Default LLM-as-judge model. |
367
367
  | `insights_model`| string | (none) | Model that writes the run-insights narrative rendered in `report.html` and uploaded with the bundle. Falls back to `judge_model` when unset — writing analytical prose is a harder task than a pairwise A/B verdict, so it is worth tuning separately. See [Run insights](#run-insights). |
368
368
  | `concurrency` | int | 10 (1 ≤ x ≤ 64) | Max in-flight LLM calls during `evalshift run` **and** `evalshift evaluate` (the embedding and judge calls made while scoring). |
369
- | `cache` | bool | `true` | Read/write the local SQLite cache at `~/.evalshift/cache.db`. Covers run-stage completions — for examples that offer tools, one entry per replayed round — plus `semantic` embeddings and `llm_judge` verdicts. See [Response cache](https://github.com/babaliauskas/evalshift-cli/blob/main/DOCS.md#response-cache) for the key. |
369
+ | `cache` | bool | `true` | Read/write the local SQLite cache at `~/.evalshift/cache.db`. Covers run-stage completions — for examples that offer tools, one entry per replayed round — plus `semantic` embeddings and `llm_judge` verdicts. See [Response cache](https://github.com/evalshift/evalshift-cli/blob/main/DOCS.md#response-cache) for the key. |
370
370
  | `max_cost_usd` | float | 50.0 | Soft ceiling reserved for future enforcement. The pre-flight cost prompt currently triggers above $10 (skip with `--yes`). |
371
371
  | `max_tokens` | int | 4096 (`> 0`) | Completion length cap sent to every model call. Raise it if outputs are being truncated (the provider returns `finish_reason == "length"`); a `prompts[].max_tokens` entry overrides it per prompt. Truncated calls are detected, surfaced in the report, and **excluded from the regression statistics** so a cut-off output can't manufacture a false regression. |
372
372
  | `samples_per_example` | int | 1 (1 ≤ x ≤ 20) | How many times each `(prompt, example)` is sent to **each** model. Above 1, every sample is its own live call (the cache keys on the sample index), sample *i* of the source is scored against sample *i* of the target, and the example's row in `scores.jsonl` becomes the **mean over samples** with the per-sample scores and the within-example `delta_variance` under `metadata.samples`. The paired tests still run over examples, not samples, so this reduces noise without inflating `n`. Cost and the call count multiply by it; only worth turning on for a model that samples non-deterministically (see the report banner). See [Methodology](methodology.md#limitations-to-be-aware-of). |
@@ -240,4 +240,4 @@ See [Hosted EvalShift](hosted.md) and [GitHub Action](github-action.md) for CI
240
240
  setup and privacy details.
241
241
 
242
242
  [uv]: https://docs.astral.sh/uv/
243
- [sdk]: https://github.com/babaliauskas/evalshift-sdk
243
+ [sdk]: https://github.com/evalshift/evalshift-sdk
@@ -30,8 +30,8 @@ checklist) with three jobs:
30
30
  to the CLI that scaffolded the project: the CLI that *reads* the config in CI must be at least as new
31
31
  as the CLI that *wrote* it locally (`extra: forbid` rejects newer keys), and
32
32
  the CLI warns when the pin falls behind (or runs ahead of the local CLI) — see [Pin drift](#pin-drift). `max-parallel` defaults to 1 —
33
- raise it toward your hosted plan's in-flight-run ceiling (Free 1, Pro 5,
34
- Team 10). The PR comment is posted by the first matrix job only: the
33
+ raise it toward your hosted plan's concurrent-run limit (Pro: 5;
34
+ Enterprise: by contract). The PR comment is posted by the first matrix job only: the
35
35
  comment marker is a constant, so multiple suites would overwrite one
36
36
  another's summary.
37
37
  - **`evalshift gate`** — the join job to require in branch protection. It
@@ -182,12 +182,12 @@ The CLI checks for it wherever it writes or validates config — `capture sync`,
182
182
  `init` (without `--ci`, next to a workflow it did not write; `init --ci` pins
183
183
  the scaffolding CLI itself and does not warn about the file it just wrote),
184
184
  `doctor` (a `ci pin` row), and `validate`. It parses every `.github/workflows/*.yml` for
185
- `babaliauskas/evalshift-action` steps and compares their `evalshift-version`
185
+ `evalshift/evalshift-action` steps and compares their `evalshift-version`
186
186
  with its own:
187
187
 
188
188
  ```text
189
189
  ⚠ CI installs evalshift 0.12.1 (.github/workflows/evalshift.yml, job evalshift) but the local CLI is 0.13.1 — an older CLI rejects config keys a newer one writes.
190
- Fix: set `evalshift-version: "0.13.1"` on the babaliauskas/evalshift-action step.
190
+ Fix: set `evalshift-version: "0.13.1"` on the evalshift/evalshift-action step.
191
191
  ```
192
192
 
193
193
  | Status | Trigger | Fix |
@@ -237,20 +237,26 @@ the wrong one fails exactly like a permissions problem.
237
237
 
238
238
  Running locally is always unlimited. Plan limits apply only to what you push.
239
239
 
240
- When a push exceeds your organization's plan — monthly runs, seats, retention —
241
- or the subscription has stopped paying, the server refuses the push with HTTP
242
- 402 and the CLI prints exactly what the server said:
240
+ Every new hosted account gets a 30-day Pro trial (no card) that covers every
241
+ org it creates; after that each org needs its own Pro subscription.
242
+
243
+ When a push exceeds your organization's plan — monthly runs, seats, concurrent
244
+ runs — the org's trial ended without a subscription, or the subscription has
245
+ stopped paying, the server refuses the push with HTTP 402 and the CLI prints
246
+ exactly what the server said:
243
247
 
244
248
  ```
245
249
  ✗ EvalShift: this run needs a paid plan.
246
- Monthly run limit reached on the Free plan (50 of 50 runs used).
250
+ The free trial for this organization ended on 2026-11-02. Subscribe to Pro to push runs and keep the CI gate — existing runs stay readable.
247
251
  Upgrade: https://app.evalshift.dev/app/acme/settings/billing
248
252
  ```
249
253
 
250
254
  `push` exits 1 and nothing is uploaded. The CLI does not evaluate entitlements
251
255
  itself and does not retry a payment error — retrying cannot change the answer.
252
256
  Your run and its `report.html` stay on disk under `.evalshift/runs/`, so you can
253
- push the same run id again after upgrading, or after the monthly counter resets.
257
+ push the same run id again once the org is subscribed (or, for the monthly
258
+ quota, after the counter resets). An expired org stays readable — its runs,
259
+ diffs and baselines still load.
254
260
 
255
261
  Transient upload failures (HTTP 429 and 5xx from object storage) are a separate
256
262
  case and *are* retried with exponential backoff.
@@ -355,5 +361,5 @@ credential file locally and repository secrets in CI.
355
361
  | `could not determine a valid 40-character git SHA` | `bundle` (or `push <run-id>` building a bundle) ran outside a git checkout, or in one with no commits, and `GITHUB_SHA` is unset. | Run inside a git repository with at least one commit, or set `GITHUB_SHA`. |
356
362
  | `project was not found` | The project does not exist and auto-create is disabled or not allowed. | Ask an owner to create it, use an org-scoped owner token, or enable auto-create. |
357
363
  | `cannot auto-create <slug> at <host>` | The message names the host it talked to and the server's status. Most often the host is not the one you meant: with no `--host` and no `EVALSHIFT_HOST`, an unset credentials file falls back to `https://api.evalshift.dev`, where your org does not exist. | Run `evalshift whoami` and check the host it prints. If it is wrong, `evalshift login --host <hosted-api-url>`. If the host is right and the status is 403, the token lacks org access — see [Project auto-create](#project-auto-create). |
358
- | `this run needs a paid plan` | The org's plan does not cover this push, or the subscription has stopped paying. | Open the upgrade URL printed with the message, or wait for the monthly reset and push the same run id again. See [Plan limits](#plan-limits). |
364
+ | `this run needs a paid plan` | The org's plan does not cover this push, its 30-day trial ended without a subscription, or the subscription has stopped paying. | Open the upgrade URL printed with the message; for the monthly quota you can also wait for the reset and push the same run id again. See [Plan limits](#plan-limits). |
359
365
  | `this run carries no migration policy` warning | No `migration_policy` is configured in `evalshift.yaml`, so the bundle has no `decision.policy`. | Add `migration_policy` to `evalshift.yaml` (see [Configuration](configuration.md#migration_policy)). Until then the gate has only whatever old web-app policy the project still has; with none, it reports `inconclusive` and never blocks the pull request unless the GitHub Action sets `require-policy: true`. |
@@ -1,13 +1,13 @@
1
1
  # Capture SDK
2
2
 
3
- The [evalshift-sdk](https://github.com/babaliauskas/evalshift-sdk) is a separate
3
+ The [evalshift-sdk](https://github.com/evalshift/evalshift-sdk) is a separate
4
4
  package (`pip install evalshift-sdk`, import name `evalshift`) that you install
5
5
  **inside your agent process**. It records what your agent actually did — model
6
6
  calls, tool calls, the final output — as JSON capture files on disk. The CLI
7
7
  promotes those captures into golden suites.
8
8
 
9
9
  This page covers the CLI side of that contract. The full SDK guide lives in the
10
- SDK repo: [DOCS.md](https://github.com/babaliauskas/evalshift-sdk/blob/main/DOCS.md),
10
+ SDK repo: [DOCS.md](https://github.com/evalshift/evalshift-sdk/blob/main/DOCS.md),
11
11
  dense LLM reference at <https://www.evalshift.dev/sdk-llms-full.txt>.
12
12
 
13
13
  ## The contract
@@ -61,7 +61,7 @@ to state its masking policy in the call itself. `True` applies the SDK's
61
61
  `default_redactor` (emails, `sk-…`, `AKIA…`, `Bearer …`), `False` records
62
62
  verbatim, and a `(value) -> value` callable does something custom; any other
63
63
  value — `None` included — raises `TypeError`. Details:
64
- [REDACTION.md](https://github.com/babaliauskas/evalshift-sdk/blob/main/docs/REDACTION.md).
64
+ [REDACTION.md](https://github.com/evalshift/evalshift-sdk/blob/main/docs/REDACTION.md).
65
65
 
66
66
  `tools` is required on the same entry points: the toolset the agent was offered,
67
67
  or `[]` if it never calls tools. Omitting it is a `TypeError` too.
@@ -131,7 +131,7 @@ carries the recorded tool results so `run` replays later rounds teacher-forced
131
131
  `--keep-duplicates` disables dedup.
132
132
 
133
133
  Full behaviour: [Configuration](configuration.md) and the
134
- [Capturing from production](https://github.com/babaliauskas/evalshift-cli/blob/main/DOCS.md#capturing-from-production)
134
+ [Capturing from production](https://github.com/evalshift/evalshift-cli/blob/main/DOCS.md#capturing-from-production)
135
135
  section of DOCS.md.
136
136
 
137
137
  ## 4. Evaluate a candidate against real behaviour
@@ -145,7 +145,7 @@ from production traffic rather than hand-written examples.
145
145
 
146
146
  ## Related
147
147
 
148
- - [`examples/capture-first/`](https://github.com/babaliauskas/evalshift-cli/tree/main/examples/capture-first)
148
+ - [`examples/capture-first/`](https://github.com/evalshift/evalshift-cli/tree/main/examples/capture-first)
149
149
  — every step above checked in: the instrumented agent, the captures and
150
150
  toolset sidecar it wrote, the promoted suite, and the `evalshift.yaml` whose
151
151
  managed `suites:` block `capture sync` filled in.
@@ -1,7 +1,7 @@
1
1
  # Capture-first example
2
2
 
3
3
  The flow the README and `evalshift init` recommend, checked in end to end:
4
- instrument an agent with the [evalshift-sdk](https://github.com/babaliauskas/evalshift-sdk),
4
+ instrument an agent with the [evalshift-sdk](https://github.com/evalshift/evalshift-sdk),
5
5
  exercise it, then let `evalshift capture sync` turn what it recorded into a
6
6
  golden suite and wire that suite into `evalshift.yaml`.
7
7
 
@@ -1,5 +1,5 @@
1
1
  # migration_profile: model-upgrade
2
- # EvalShift configuration. See https://github.com/babaliauskas/EvalShift for docs.
2
+ # EvalShift configuration. See https://github.com/evalshift/evalshift-cli for docs.
3
3
  #
4
4
  # `init` writes only this file, set up for the capture-first flow: instrument
5
5
  # your agent with the evalshift-sdk, exercise it to record captures, then run
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "evalshift"
7
- version = "1.2.0"
7
+ version = "1.2.2"
8
8
  description = "Run your prompts on two LLMs and find out, with statistical confidence, what regressed."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -30,7 +30,7 @@ dependencies = [
30
30
  # The capture SDK (import name `evalshift`). Stdlib-only, so it adds nothing to
31
31
  # the environment; declared so one `pip install evalshift` serves both
32
32
  # instrumenting an agent and running evaluations, and so `import evalshift` is
33
- # always the SDK. See docs/superpowers/specs/2026-09-09-namespace-collision-design.md.
33
+ # always the SDK. See the co-install note in DOCS.md.
34
34
  "evalshift-sdk>=0.4.0",
35
35
  "typer>=0.12",
36
36
  "pydantic>=2.5",
@@ -68,11 +68,11 @@ dev = [
68
68
  ]
69
69
 
70
70
  [project.urls]
71
- Homepage = "https://github.com/babaliauskas/evalshift-cli"
72
- Documentation = "https://github.com/babaliauskas/evalshift-cli#readme"
73
- Repository = "https://github.com/babaliauskas/evalshift-cli"
74
- Issues = "https://github.com/babaliauskas/evalshift-cli/issues"
75
- Changelog = "https://github.com/babaliauskas/evalshift-cli/blob/main/CHANGELOG.md"
71
+ Homepage = "https://github.com/evalshift/evalshift-cli"
72
+ Documentation = "https://github.com/evalshift/evalshift-cli#readme"
73
+ Repository = "https://github.com/evalshift/evalshift-cli"
74
+ Issues = "https://github.com/evalshift/evalshift-cli/issues"
75
+ Changelog = "https://github.com/evalshift/evalshift-cli/blob/main/CHANGELOG.md"
76
76
 
77
77
  [project.scripts]
78
78
  evalshift = "evalshift_cli.cli.main:app"
@@ -231,8 +231,8 @@ jobs:
231
231
  strategy:
232
232
  # One suite regressing must not cancel the others' results.
233
233
  fail-fast: false
234
- # Hosted EvalShift refuses uploads past your org plan's in-flight run
235
- # ceiling (Free 1, Pro 5, Team 10). Raise this toward your plan's limit
234
+ # Hosted EvalShift refuses uploads past your org's concurrent-run
235
+ # limit (Pro: 5; Enterprise: by contract). Raise this toward it
236
236
  # to evaluate suites in parallel.
237
237
  max-parallel: 1
238
238
  matrix:
@@ -251,7 +251,7 @@ jobs:
251
251
 
252
252
  - name: Run evalshift on ${{ matrix.suite }}
253
253
  if: ${{ env.HAS_EVALSHIFT_TOKEN == 'true' }}
254
- uses: babaliauskas/evalshift-action@v0
254
+ uses: evalshift/evalshift-action@v0
255
255
  with:
256
256
  token: ${{ secrets.EVALSHIFT_TOKEN }}
257
257
  config: evalshift.yaml
@@ -98,7 +98,7 @@ _SEMANTIC_BLOCK_DISABLED: Final = """\
98
98
  # Body of the minimal config, up to (but excluding) the suites region and the
99
99
  # migration_policy block. ``render_minimal_config`` appends those.
100
100
  _MINIMAL_YAML_BODY: Final = """\
101
- # EvalShift configuration. See https://github.com/babaliauskas/EvalShift for docs.
101
+ # EvalShift configuration. See https://github.com/evalshift/evalshift-cli for docs.
102
102
  #
103
103
  # `init` writes only this file, set up for the capture-first flow: instrument
104
104
  # your agent with the evalshift-sdk, exercise it to record captures, then run
@@ -1018,7 +1018,7 @@
1018
1018
  },
1019
1019
  "GuardrailEvent": {
1020
1020
  "additionalProperties": false,
1021
- "description": "A guardrail or policy check. Imported agent traces only.",
1021
+ "description": "A guardrail or policy check.\n\nReserved for a bring-your-own-agent trace; no current producer emits it \u2014\n``evalshift traces import`` writes such traces only to a local artifact,\nnot into a pushed bundle.",
1022
1022
  "properties": {
1023
1023
  "name": {
1024
1024
  "minLength": 1,
@@ -1405,7 +1405,7 @@
1405
1405
  },
1406
1406
  "RetrievalEvent": {
1407
1407
  "additionalProperties": false,
1408
- "description": "A retrieval step. Imported agent traces only.",
1408
+ "description": "A retrieval step.\n\nReserved for a bring-your-own-agent trace; no current producer emits it \u2014\n``evalshift traces import`` writes such traces only to a local artifact,\nnot into a pushed bundle.",
1409
1409
  "properties": {
1410
1410
  "documents": {
1411
1411
  "items": {
@@ -108,6 +108,39 @@ def _upgrade_prompt(exc: HostedHTTPError) -> PushError:
108
108
  return PushError("\n".join(lines))
109
109
 
110
110
 
111
+ def _initiate_after_create(
112
+ client: HostedClient, manifest: dict[str, Any], *, size_bytes: int
113
+ ) -> dict[str, Any]:
114
+ """The ``POST /runs`` retried after auto-creating the project, mapped like the first.
115
+
116
+ It runs inside the first attempt's ``except`` clause, so its own errors would skip the
117
+ sibling handlers and surface as a traceback. ``POST /runs`` answers 404 for a missing
118
+ project before any entitlement check, so a 402 for the monthly run or concurrent-run
119
+ limit, seat overage, or a subscription that stopped paying arrives on this retry, not
120
+ on the first call.
121
+
122
+ Args:
123
+ client: The hosted client the first attempt used.
124
+ manifest: The bundle manifest sent as the run's create payload.
125
+ size_bytes: Size of the bundle file that will be uploaded.
126
+
127
+ Returns:
128
+ The server's ``POST /runs`` response.
129
+
130
+ Raises:
131
+ PushError: On any hosted error — the upgrade prompt for a 402, the server's
132
+ message otherwise.
133
+ """
134
+ try:
135
+ return client.initiate_run(manifest, size_bytes=size_bytes)
136
+ except HostedHTTPError as exc:
137
+ if exc.status_code == _PAYMENT_REQUIRED:
138
+ raise _upgrade_prompt(exc) from exc
139
+ raise PushError(str(exc)) from exc
140
+ except (HostedNetworkError, HostedError) as exc:
141
+ raise PushError(str(exc)) from exc
142
+
143
+
111
144
  @dataclass(frozen=True, slots=True)
112
145
  class PushResult:
113
146
  """Outcome of a hosted push.
@@ -239,7 +272,7 @@ def push_bundle(
239
272
  raise PushError(str(exc)) from exc
240
273
  _auto_create_project(client, project_slug=str(manifest["project_slug"]))
241
274
  project_created = True
242
- response = client.initiate_run(manifest, size_bytes=upload_size_bytes)
275
+ response = _initiate_after_create(client, manifest, size_bytes=upload_size_bytes)
243
276
  except (HostedNetworkError, HostedError) as exc:
244
277
  raise PushError(str(exc)) from exc
245
278
 
@@ -489,17 +522,25 @@ def _auto_create_project(client: HostedClient, *, project_slug: str) -> None:
489
522
  f"permission — check `evalshift whoami` reports this host and an org "
490
523
  f"named {org_slug!r}",
491
524
  ) from exc
525
+ except (HostedNetworkError, HostedError) as exc:
526
+ raise PushError(str(exc)) from exc
492
527
  if any(item.get("slug") == project for item in projects):
493
528
  return
494
529
  try:
495
530
  client.create_project(org_slug, slug=project, name=_name_from_slug(project))
496
531
  except HostedHTTPError as exc:
532
+ if exc.status_code == _PAYMENT_REQUIRED:
533
+ # An expired org is read-only: creating a project is refused with the same 402 a
534
+ # push gets, and it deserves the same prompt rather than an access-permission hint.
535
+ raise _upgrade_prompt(exc) from exc
497
536
  raise PushError(
498
537
  f"cannot auto-create {project_slug!r} at {client.host}: "
499
538
  f"{_server_said(exc)}. Creating a project needs owner access to "
500
539
  f"{org_slug!r}; a scoped service-account key cannot do it — create the "
501
540
  f"project by hand, or push with an owner token",
502
541
  ) from exc
542
+ except (HostedNetworkError, HostedError) as exc:
543
+ raise PushError(str(exc)) from exc
503
544
 
504
545
 
505
546
  def _server_said(exc: HostedHTTPError) -> str:
@@ -12,6 +12,11 @@ Two internal representations describe that, and neither goes on the wire:
12
12
 
13
13
  Both map here onto one wire shape so the server, the database and the client
14
14
  speak a single language. Neither internal model changes.
15
+
16
+ Only :func:`from_tool_trace` has a production caller (``hosted/bundle.py``): a run
17
+ bundle's ``examples[].traces`` come from the replay's own tool-call traces.
18
+ :func:`from_agent_trace` converts imported agent traces to the same wire shape but is
19
+ not wired into bundling today — those traces stay local.
15
20
  """
16
21
 
17
22
  from __future__ import annotations
@@ -170,7 +175,14 @@ _PASSTHROUGH_FIELDS: dict[str, tuple[str, ...]] = {
170
175
 
171
176
 
172
177
  def from_agent_trace(trace: AgentTrace) -> dict[str, Any] | None:
173
- """Wire stream for one imported bring-your-own-agent trace.
178
+ """Convert an imported agent trace to bundle wire events.
179
+
180
+ Not called by ``bundle.py`` today: imported traces (``evalshift traces import``)
181
+ stay local in ``.evalshift/runs/<id>/traces.jsonl`` and are read only by
182
+ ``evaluate``, ``report.json`` and the ``diff``/``inspect``/``replay case``
183
+ commands. A run bundle's ``examples[].traces`` come solely from the replay's own
184
+ tool-call traces via :func:`from_tool_trace`. This function exists for a future
185
+ caller that would include imported traces in the bundle.
174
186
 
175
187
  A round begins at each ``model_call``. The counter increments on every
176
188
  ``model_call`` after the first, so events preceding any model call stay in
@@ -556,6 +556,33 @@ details[open] > summary .caret::after { content: "\25BE"; }
556
556
  background: var(--strip);
557
557
  flex-wrap: wrap;
558
558
  }
559
+ /* The row must read as a control, not a static line: a boxed caret, a worded
560
+ hint, and a hover state that reacts across the whole header. */
561
+ .reg-head .caret {
562
+ display: inline-flex;
563
+ align-items: center;
564
+ justify-content: center;
565
+ width: 22px;
566
+ height: 22px;
567
+ flex: none;
568
+ border: 1px solid var(--stroke);
569
+ background: var(--panel-2);
570
+ }
571
+ .reg-head .caret::after { font-size: 14px; width: auto; color: var(--body); }
572
+ .reg-toggle {
573
+ font-family: var(--font-mono);
574
+ font-size: 12px;
575
+ color: var(--dim);
576
+ min-width: 88px;
577
+ text-align: right;
578
+ }
579
+ .reg-toggle::after { content: "Show details"; }
580
+ .regression[open] > .reg-head .reg-toggle::after { content: "Hide details"; }
581
+ .reg-head:hover { background: var(--panel-2); }
582
+ .reg-head:hover .caret { border-color: var(--ok-edge); }
583
+ .reg-head:hover .caret::after,
584
+ .reg-head:hover .reg-toggle { color: var(--accent); }
585
+ .reg-head:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
559
586
  .reg-id { font-family: var(--font-mono); font-size: 14px; color: var(--fg); }
560
587
  .reg-what {
561
588
  font-size: 14px;
@@ -762,6 +789,8 @@ footer p { margin: 0; }
762
789
  id instead. */
763
790
  .reg-head { gap: 8px 12px; padding: 12px 14px; }
764
791
  .reg-what { flex: 1 1 60%; min-width: 0; white-space: normal; }
792
+ /* The boxed caret alone carries the affordance when space is tight. */
793
+ .reg-toggle { display: none; }
765
794
  .reg-body { padding: 14px; }
766
795
  .trace-list { padding: 12px 12px 12px 26px; }
767
796
  .transcript-body { padding: 0 12px 12px 28px; }
@@ -769,6 +798,10 @@ footer p { margin: 0; }
769
798
 
770
799
  @media print {
771
800
  body { background: #fff; color: #111; }
801
+ /* Paper can't be clicked: show every regression body. Best-effort: only
802
+ engines with ::details-content (Chromium 131+) honour it. */
803
+ .regression::details-content { content-visibility: visible; }
804
+ .reg-toggle { display: none; }
772
805
  }
773
806
 
774
807
  /* --- Tone utilities ------------------------------------------------------ */