soup-cli 0.71.0__tar.gz → 0.71.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 (774) hide show
  1. soup_cli-0.71.2/CHANGELOG.md +120 -0
  2. {soup_cli-0.71.0 → soup_cli-0.71.2}/CONTRIBUTING.md +3 -1
  3. {soup_cli-0.71.0 → soup_cli-0.71.2}/PKG-INFO +17 -5
  4. {soup_cli-0.71.0 → soup_cli-0.71.2}/README.md +13 -4
  5. {soup_cli-0.71.0 → soup_cli-0.71.2}/docs/adapters-and-governance.md +54 -14
  6. {soup_cli-0.71.0 → soup_cli-0.71.2}/docs/commands.md +8 -3
  7. {soup_cli-0.71.0 → soup_cli-0.71.2}/docs/evaluation.md +2 -0
  8. {soup_cli-0.71.0 → soup_cli-0.71.2}/docs/training.md +1 -1
  9. {soup_cli-0.71.0 → soup_cli-0.71.2}/pyproject.toml +6 -2
  10. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/__init__.py +1 -1
  11. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/adapters.py +110 -21
  12. soup_cli-0.71.2/src/soup_cli/commands/attest.py +226 -0
  13. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/env.py +70 -0
  14. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/lock.py +41 -2
  15. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/serve.py +64 -0
  16. soup_cli-0.71.2/src/soup_cli/data/_fixtures/unlearning/muse_demo.jsonl +8 -0
  17. soup_cli-0.71.2/src/soup_cli/data/_fixtures/unlearning/wmdp_demo.jsonl +8 -0
  18. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/calibrate.py +59 -0
  19. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/registry/store.py +2 -0
  20. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_sign.py +154 -11
  21. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/attest.py +47 -11
  22. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/build_dag.py +26 -0
  23. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/completions.py +87 -10
  24. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/env_lock.py +96 -0
  25. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/hubs.py +101 -2
  26. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/license_matrix.py +185 -0
  27. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/namespace_pin.py +79 -9
  28. soup_cli-0.71.2/src/soup_cli/utils/signing.py +247 -0
  29. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/unlearning_eval.py +8 -4
  30. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_registry.py +15 -0
  31. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_serve.py +140 -0
  32. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0538.py +8 -1
  33. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0570_part_b.py +4 -0
  34. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0600_part_b.py +8 -3
  35. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0600_part_e.py +7 -4
  36. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0610_part_b.py +145 -0
  37. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0640_part_c.py +296 -0
  38. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0640_part_e.py +115 -0
  39. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0650_part_a.py +81 -0
  40. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0670_part_e.py +205 -0
  41. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0690_part_a.py +68 -0
  42. soup_cli-0.71.2/tests/test_v0712.py +1554 -0
  43. soup_cli-0.71.0/CHANGELOG.md +0 -50
  44. soup_cli-0.71.0/src/soup_cli/commands/attest.py +0 -90
  45. {soup_cli-0.71.0 → soup_cli-0.71.2}/.dockerignore +0 -0
  46. {soup_cli-0.71.0 → soup_cli-0.71.2}/.github/FUNDING.yml +0 -0
  47. {soup_cli-0.71.0 → soup_cli-0.71.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  48. {soup_cli-0.71.0 → soup_cli-0.71.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  49. {soup_cli-0.71.0 → soup_cli-0.71.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  50. {soup_cli-0.71.0 → soup_cli-0.71.2}/.github/pull_request_template.md +0 -0
  51. {soup_cli-0.71.0 → soup_cli-0.71.2}/.github/workflows/ci.yml +0 -0
  52. {soup_cli-0.71.0 → soup_cli-0.71.2}/.github/workflows/docker.yml +0 -0
  53. {soup_cli-0.71.0 → soup_cli-0.71.2}/.github/workflows/publish.yml +0 -0
  54. {soup_cli-0.71.0 → soup_cli-0.71.2}/.github/workflows/recipe-validation.yml +0 -0
  55. {soup_cli-0.71.0 → soup_cli-0.71.2}/.gitignore +0 -0
  56. {soup_cli-0.71.0 → soup_cli-0.71.2}/.pre-commit-config.yaml +0 -0
  57. {soup_cli-0.71.0 → soup_cli-0.71.2}/AGENTS.md +0 -0
  58. {soup_cli-0.71.0 → soup_cli-0.71.2}/CODEOWNERS +0 -0
  59. {soup_cli-0.71.0 → soup_cli-0.71.2}/CODE_OF_CONDUCT.md +0 -0
  60. {soup_cli-0.71.0 → soup_cli-0.71.2}/Dockerfile +0 -0
  61. {soup_cli-0.71.0 → soup_cli-0.71.2}/LICENSE +0 -0
  62. {soup_cli-0.71.0 → soup_cli-0.71.2}/NOTICE +0 -0
  63. {soup_cli-0.71.0 → soup_cli-0.71.2}/SECURITY.md +0 -0
  64. {soup_cli-0.71.0 → soup_cli-0.71.2}/docker-compose.yml +0 -0
  65. {soup_cli-0.71.0 → soup_cli-0.71.2}/docs/README.md +0 -0
  66. {soup_cli-0.71.0 → soup_cli-0.71.2}/docs/backends-and-ops.md +0 -0
  67. {soup_cli-0.71.0 → soup_cli-0.71.2}/docs/data.md +0 -0
  68. {soup_cli-0.71.0 → soup_cli-0.71.2}/docs/models.md +0 -0
  69. {soup_cli-0.71.0 → soup_cli-0.71.2}/docs/peft-and-efficiency.md +0 -0
  70. {soup_cli-0.71.0 → soup_cli-0.71.2}/docs/performance-and-quantization.md +0 -0
  71. {soup_cli-0.71.0 → soup_cli-0.71.2}/docs/serving-and-export.md +0 -0
  72. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/README.md +0 -0
  73. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/configs/dpo_chat.yaml +0 -0
  74. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/configs/dpo_example.yaml +0 -0
  75. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/configs/grpo_reasoning.yaml +0 -0
  76. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/configs/rlhf_step1_sft.yaml +0 -0
  77. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/configs/rlhf_step2_reward.yaml +0 -0
  78. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/configs/rlhf_step3_ppo.yaml +0 -0
  79. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/configs/sft_basic.yaml +0 -0
  80. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/configs/vision_llama.yaml +0 -0
  81. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/data/alpaca_tiny.jsonl +0 -0
  82. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/data/chat_preferences.jsonl +0 -0
  83. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/data/dpo_sample.jsonl +0 -0
  84. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/data/reasoning_math.jsonl +0 -0
  85. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/synthetic_workflow.md +0 -0
  86. {soup_cli-0.71.0 → soup_cli-0.71.2}/examples/synthetic_workflow.yaml +0 -0
  87. {soup_cli-0.71.0 → soup_cli-0.71.2}/soup.png +0 -0
  88. {soup_cli-0.71.0 → soup_cli-0.71.2}/soup_logo_svg.svg +0 -0
  89. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/__main__.py +0 -0
  90. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/autopilot/__init__.py +0 -0
  91. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/autopilot/analyzer.py +0 -0
  92. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/autopilot/decisions.py +0 -0
  93. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/autopilot/generate_config.py +0 -0
  94. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/cans/__init__.py +0 -0
  95. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/cans/pack.py +0 -0
  96. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/cans/publish.py +0 -0
  97. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/cans/run.py +0 -0
  98. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/cans/schema.py +0 -0
  99. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/cans/unpack.py +0 -0
  100. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/cans/verify.py +0 -0
  101. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/cli.py +0 -0
  102. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/__init__.py +0 -0
  103. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/_eval_v0550.py +0 -0
  104. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/_eval_v0610.py +0 -0
  105. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/_eval_v0650.py +0 -0
  106. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/ab.py +0 -0
  107. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/active_sample.py +0 -0
  108. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/advise.py +0 -0
  109. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/agent.py +0 -0
  110. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/airgap.py +0 -0
  111. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/apple_adapter.py +0 -0
  112. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/audit_log.py +0 -0
  113. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/autopilot.py +0 -0
  114. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/bench.py +0 -0
  115. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/bom.py +0 -0
  116. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/build.py +0 -0
  117. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/can.py +0 -0
  118. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/chat.py +0 -0
  119. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/compile_cmd.py +0 -0
  120. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/compile_tools.py +0 -0
  121. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/completions.py +0 -0
  122. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/cost.py +0 -0
  123. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/data.py +0 -0
  124. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/data_forge.py +0 -0
  125. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/data_mix.py +0 -0
  126. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/data_score.py +0 -0
  127. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/delinearize_llama4.py +0 -0
  128. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/deploy.py +0 -0
  129. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/diagnose.py +0 -0
  130. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/diff.py +0 -0
  131. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/distill_prompt.py +0 -0
  132. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/doctor.py +0 -0
  133. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/drift_alarm.py +0 -0
  134. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/edit.py +0 -0
  135. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/eval.py +0 -0
  136. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/expect.py +0 -0
  137. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/export.py +0 -0
  138. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/fetch.py +0 -0
  139. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/generate.py +0 -0
  140. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/history.py +0 -0
  141. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/infer.py +0 -0
  142. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/ingest.py +0 -0
  143. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/init.py +0 -0
  144. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/iterative_dpo.py +0 -0
  145. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/license_advisor.py +0 -0
  146. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/llama.py +0 -0
  147. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/local_rl.py +0 -0
  148. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/loop.py +0 -0
  149. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/merge.py +0 -0
  150. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/merge_sharded_fsdp_weights.py +0 -0
  151. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/migrate.py +0 -0
  152. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/monitor.py +0 -0
  153. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/plan.py +0 -0
  154. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/plugins.py +0 -0
  155. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/probe.py +0 -0
  156. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/profile.py +0 -0
  157. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/prune_prompt.py +0 -0
  158. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/push.py +0 -0
  159. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/quantize.py +0 -0
  160. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/quickstart.py +0 -0
  161. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/recipes.py +0 -0
  162. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/registry.py +0 -0
  163. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/runs.py +0 -0
  164. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/steer.py +0 -0
  165. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/sweep.py +0 -0
  166. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/tokenizer.py +0 -0
  167. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/train.py +0 -0
  168. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/tui.py +0 -0
  169. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/tunability.py +0 -0
  170. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/ui.py +0 -0
  171. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/commands/why.py +0 -0
  172. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/config/__init__.py +0 -0
  173. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/config/loader.py +0 -0
  174. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/config/schema.py +0 -0
  175. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/__init__.py +0 -0
  176. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/alpaca_tiny.jsonl +0 -0
  177. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/behavior/elephant.jsonl +0 -0
  178. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/behavior/harmbench.jsonl +0 -0
  179. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/behavior/jailbreakbench.jsonl +0 -0
  180. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/behavior/syceval.jsonl +0 -0
  181. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/behavior/xstest.jsonl +0 -0
  182. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/chat_preferences.jsonl +0 -0
  183. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/dpo_sample.jsonl +0 -0
  184. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/reasoning_math.jsonl +0 -0
  185. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/unlearning/tofu_demo.jsonl +0 -0
  186. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/augment.py +0 -0
  187. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/chat_templates.py +0 -0
  188. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/collators.py +0 -0
  189. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/formats.py +0 -0
  190. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/loader.py +0 -0
  191. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/loss_mask.py +0 -0
  192. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/providers/__init__.py +0 -0
  193. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/providers/_utils.py +0 -0
  194. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/providers/anthropic.py +0 -0
  195. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/providers/ollama.py +0 -0
  196. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/providers/vllm.py +0 -0
  197. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/sft_format.py +0 -0
  198. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/templates/__init__.py +0 -0
  199. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/templates/code.py +0 -0
  200. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/templates/conversation.py +0 -0
  201. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/templates/preference.py +0 -0
  202. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/templates/qa.py +0 -0
  203. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/templates/reasoning.py +0 -0
  204. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/templates/tool_calling.py +0 -0
  205. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/templates/verifiable.py +0 -0
  206. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/traces/__init__.py +0 -0
  207. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/traces/pair_builder.py +0 -0
  208. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/traces/parsers.py +0 -0
  209. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/traces/quality.py +0 -0
  210. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/data/validator.py +0 -0
  211. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/__init__.py +0 -0
  212. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/arena.py +0 -0
  213. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/benchmarks_v0_43.py +0 -0
  214. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/checkpoint_intelligence.py +0 -0
  215. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/custom.py +0 -0
  216. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/forgetting.py +0 -0
  217. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/gate.py +0 -0
  218. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/human.py +0 -0
  219. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/judge.py +0 -0
  220. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/leaderboard.py +0 -0
  221. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/eval/quant_check.py +0 -0
  222. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/experiment/__init__.py +0 -0
  223. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/experiment/tracker.py +0 -0
  224. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/migrate/__init__.py +0 -0
  225. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/migrate/axolotl.py +0 -0
  226. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/migrate/common.py +0 -0
  227. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/migrate/llamafactory.py +0 -0
  228. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/migrate/unsloth.py +0 -0
  229. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/monitoring/__init__.py +0 -0
  230. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/monitoring/callback.py +0 -0
  231. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/monitoring/curriculum_callback.py +0 -0
  232. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/monitoring/display.py +0 -0
  233. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/monitoring/grpo_stability_callback.py +0 -0
  234. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/monitoring/hf_push.py +0 -0
  235. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/monitoring/plugin_callback.py +0 -0
  236. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/monitoring/trace_logger.py +0 -0
  237. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/plugins/__init__.py +0 -0
  238. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/py.typed +0 -0
  239. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/recipes/__init__.py +0 -0
  240. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/recipes/catalog.py +0 -0
  241. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/registry/__init__.py +0 -0
  242. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/registry/attach.py +0 -0
  243. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/registry/diff.py +0 -0
  244. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/registry/hashing.py +0 -0
  245. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/__init__.py +0 -0
  246. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/audio.yaml +0 -0
  247. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/bco.yaml +0 -0
  248. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/chat.yaml +0 -0
  249. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/code.yaml +0 -0
  250. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/embedding.yaml +0 -0
  251. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/fetch_examples/llama-3.1-8b-lora.yaml +0 -0
  252. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/fetch_examples/qwen2.5-7b-dpo.yaml +0 -0
  253. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/fetch_examples/zero3-cpu-offload.json +0 -0
  254. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/ipo.yaml +0 -0
  255. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/kto.yaml +0 -0
  256. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/longcontext.yaml +0 -0
  257. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/manifest.json +0 -0
  258. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/medical.yaml +0 -0
  259. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/moe.yaml +0 -0
  260. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/orpo.yaml +0 -0
  261. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/pretrain.yaml +0 -0
  262. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/reasoning.yaml +0 -0
  263. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/rlhf.yaml +0 -0
  264. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/simpo.yaml +0 -0
  265. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/tool-calling.yaml +0 -0
  266. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/templates/vision.yaml +0 -0
  267. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/__init__.py +0 -0
  268. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/bco.py +0 -0
  269. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/classifier.py +0 -0
  270. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/distill.py +0 -0
  271. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/dpo.py +0 -0
  272. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/embedding.py +0 -0
  273. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/grpo.py +0 -0
  274. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/ipo.py +0 -0
  275. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/kto.py +0 -0
  276. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/mlx_dpo.py +0 -0
  277. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/mlx_grpo.py +0 -0
  278. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/mlx_routing.py +0 -0
  279. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/mlx_sft.py +0 -0
  280. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/orpo.py +0 -0
  281. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/ppo.py +0 -0
  282. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/preference.py +0 -0
  283. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/pretrain.py +0 -0
  284. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/prm.py +0 -0
  285. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/reward_model.py +0 -0
  286. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/rewards.py +0 -0
  287. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/sft.py +0 -0
  288. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/simpo.py +0 -0
  289. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/trainer/unlearn.py +0 -0
  290. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/tui_app.py +0 -0
  291. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/ui/__init__.py +0 -0
  292. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/ui/app.py +0 -0
  293. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/ui/plugins/__init__.py +0 -0
  294. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/ui/static/app.js +0 -0
  295. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/ui/static/index.html +0 -0
  296. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/ui/static/logo.png +0 -0
  297. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/ui/static/logo.svg +0 -0
  298. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/ui/static/style.css +0 -0
  299. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/__init__.py +0 -0
  300. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/_eval_text.py +0 -0
  301. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/ab_test.py +0 -0
  302. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/activation_offload.py +0 -0
  303. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/active_sampler.py +0 -0
  304. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_bisect.py +0 -0
  305. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_branch.py +0 -0
  306. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_diff.py +0 -0
  307. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_merge.py +0 -0
  308. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_pr.py +0 -0
  309. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_scan.py +0 -0
  310. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/advanced_precision.py +0 -0
  311. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/advise.py +0 -0
  312. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/advise_history.py +0 -0
  313. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/agent_forge.py +0 -0
  314. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/agent_rollout.py +0 -0
  315. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/airgap_bundle.py +0 -0
  316. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/annex_xi.py +0 -0
  317. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/anthropic_messages.py +0 -0
  318. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/apple_adapter.py +0 -0
  319. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/audit_log.py +0 -0
  320. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/auto_quant.py +0 -0
  321. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/backend_detect.py +0 -0
  322. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/batch_probe.py +0 -0
  323. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/behavior_battery.py +0 -0
  324. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/bitnet.py +0 -0
  325. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/blame.py +0 -0
  326. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/block_expansion.py +0 -0
  327. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/bom.py +0 -0
  328. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/brain_rot.py +0 -0
  329. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/brain_rot_lang.py +0 -0
  330. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/canary_discovery.py +0 -0
  331. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/canary_router.py +0 -0
  332. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/capability_suite.py +0 -0
  333. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/checklist_dsl.py +0 -0
  334. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/checkpoint_trigger.py +0 -0
  335. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/citation_faithful.py +0 -0
  336. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/classifier.py +0 -0
  337. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/cmaes_merge.py +0 -0
  338. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/compile_tools.py +0 -0
  339. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/constants.py +0 -0
  340. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/convergence.py +0 -0
  341. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/crash.py +0 -0
  342. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/cross_doc_attn.py +0 -0
  343. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/curriculum.py +0 -0
  344. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/curriculum_dynamic.py +0 -0
  345. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/cut_ce.py +0 -0
  346. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/data_forge.py +0 -0
  347. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/data_mix.py +0 -0
  348. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/data_pipeline.py +0 -0
  349. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/data_score.py +0 -0
  350. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/deepspeed.py +0 -0
  351. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/delinearize_llama4.py +0 -0
  352. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/demo_bundles.py +0 -0
  353. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/deploy_autopilot.py +0 -0
  354. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/deploy_measure.py +0 -0
  355. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/__init__.py +0 -0
  356. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/_common.py +0 -0
  357. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/badge.py +0 -0
  358. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/contamination.py +0 -0
  359. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/forgetting.py +0 -0
  360. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/format.py +0 -0
  361. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/memorization.py +0 -0
  362. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/mode_collapse.py +0 -0
  363. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/refusal.py +0 -0
  364. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/report.py +0 -0
  365. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/runner.py +0 -0
  366. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/distill.py +0 -0
  367. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/dpo_variants.py +0 -0
  368. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/drift_alarm.py +0 -0
  369. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/ebft_gdpo.py +0 -0
  370. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/echo_trap.py +0 -0
  371. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/edit_diff.py +0 -0
  372. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/edit_governor.py +0 -0
  373. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/encoding.py +0 -0
  374. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/energy.py +0 -0
  375. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/errors.py +0 -0
  376. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/eval_design.py +0 -0
  377. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/eval_gate_hook.py +0 -0
  378. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/eval_lock_coverage.py +0 -0
  379. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/expectations.py +0 -0
  380. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/fetch_examples.py +0 -0
  381. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/flash_attn.py +0 -0
  382. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/fp8.py +0 -0
  383. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/freeze.py +0 -0
  384. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/fsdp.py +0 -0
  385. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/fsdp_consolidate.py +0 -0
  386. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/galore.py +0 -0
  387. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/gguf_quant.py +0 -0
  388. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/gpu.py +0 -0
  389. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/gpu_monitor.py +0 -0
  390. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/grace_codebook.py +0 -0
  391. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/graceful_save.py +0 -0
  392. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/grad_accum.py +0 -0
  393. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/gradient_ckpt.py +0 -0
  394. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/grpo_long_context.py +0 -0
  395. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/grpo_variants.py +0 -0
  396. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/hardware_fit.py +0 -0
  397. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/hf.py +0 -0
  398. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/hf_space.py +0 -0
  399. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/ingest_sources.py +0 -0
  400. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/integrations.py +0 -0
  401. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/interference.py +0 -0
  402. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/irt.py +0 -0
  403. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/iterative_dpo.py +0 -0
  404. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/jinja_analyzer.py +0 -0
  405. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/kernel_picker.py +0 -0
  406. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/knowledge_edit.py +0 -0
  407. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/kv_cache.py +0 -0
  408. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/launcher.py +0 -0
  409. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/license_advisor.py +0 -0
  410. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/liger.py +0 -0
  411. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/llama_proxy.py +0 -0
  412. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/llama_server_timings.py +0 -0
  413. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/local_rl.py +0 -0
  414. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/loftq_init.py +0 -0
  415. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/log_level.py +0 -0
  416. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/long_context.py +0 -0
  417. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/longlora.py +0 -0
  418. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/loop_budget.py +0 -0
  419. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/loop_daemon.py +0 -0
  420. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/loop_iteration.py +0 -0
  421. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/loop_state.py +0 -0
  422. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/lr_finder.py +0 -0
  423. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/lr_groups.py +0 -0
  424. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/magpie.py +0 -0
  425. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/metrics.py +0 -0
  426. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/mii.py +0 -0
  427. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/minillm.py +0 -0
  428. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/mix_proxy.py +0 -0
  429. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/mixed_precision.py +0 -0
  430. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/mlx.py +0 -0
  431. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/moe.py +0 -0
  432. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/moe_quant.py +0 -0
  433. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/mole_routing.py +0 -0
  434. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/multipack.py +0 -0
  435. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/multipack_sampler.py +0 -0
  436. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/multipack_trainer.py +0 -0
  437. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/neat_packing.py +0 -0
  438. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/ngram_spec.py +0 -0
  439. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/nlg_metrics.py +0 -0
  440. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/ollama.py +0 -0
  441. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/onboarding.py +0 -0
  442. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/optimizer_zoo.py +0 -0
  443. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/paths.py +0 -0
  444. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/peft_builder.py +0 -0
  445. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/peft_patches.py +0 -0
  446. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/peft_wiring.py +0 -0
  447. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/persona_hub.py +0 -0
  448. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/pipeline.py +0 -0
  449. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/preference_combine.py +0 -0
  450. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/prm.py +0 -0
  451. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/probe_pack.py +0 -0
  452. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/profiler.py +0 -0
  453. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/profiling.py +0 -0
  454. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/profiling_v0_43.py +0 -0
  455. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/prompt_compile.py +0 -0
  456. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/prompt_distill.py +0 -0
  457. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/prune_prompt.py +0 -0
  458. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/qat.py +0 -0
  459. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/qr_url.py +0 -0
  460. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/quality.py +0 -0
  461. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/quant_menu.py +0 -0
  462. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/ra_dit.py +0 -0
  463. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/reasoning_effort.py +0 -0
  464. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/reasoning_parser.py +0 -0
  465. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/recipe_dag.py +0 -0
  466. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/recipe_run.py +0 -0
  467. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/registry.py +0 -0
  468. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/relora.py +0 -0
  469. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/replay.py +0 -0
  470. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/repro_receipt.py +0 -0
  471. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/reward_hacking.py +0 -0
  472. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/ring_attention.py +0 -0
  473. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/rl_checkpoint.py +0 -0
  474. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/run_cost.py +0 -0
  475. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/sae_diff.py +0 -0
  476. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/save_formats.py +0 -0
  477. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/server_tools.py +0 -0
  478. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/sglang.py +0 -0
  479. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/shortcuts.py +0 -0
  480. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/sleeper_probe.py +0 -0
  481. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/soup_lock.py +0 -0
  482. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/spec_pairing.py +0 -0
  483. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/spike_recovery.py +0 -0
  484. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/sse_train_stream.py +0 -0
  485. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/steering.py +0 -0
  486. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/strict_safetensors.py +0 -0
  487. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/structured_output.py +0 -0
  488. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/sweep_config.py +0 -0
  489. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/tail_latency.py +0 -0
  490. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/terraform_plan.py +0 -0
  491. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/tool_outputs.py +0 -0
  492. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/topology.py +0 -0
  493. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/tracing.py +0 -0
  494. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/trackers.py +0 -0
  495. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/train_event_buffer.py +0 -0
  496. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/trainer_plugins.py +0 -0
  497. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/trust_remote.py +0 -0
  498. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/tts.py +0 -0
  499. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/tunability.py +0 -0
  500. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/ui_env.py +0 -0
  501. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/uld.py +0 -0
  502. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/unlearning.py +0 -0
  503. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/unsloth.py +0 -0
  504. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/v028_features.py +0 -0
  505. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/vector_bank.py +0 -0
  506. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/vllm.py +0 -0
  507. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/vscode_setup.py +0 -0
  508. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/warmup.py +0 -0
  509. {soup_cli-0.71.0 → soup_cli-0.71.2}/src/soup_cli/utils/why.py +0 -0
  510. {soup_cli-0.71.0 → soup_cli-0.71.2}/templates/chat.yaml +0 -0
  511. {soup_cli-0.71.0 → soup_cli-0.71.2}/templates/code.yaml +0 -0
  512. {soup_cli-0.71.0 → soup_cli-0.71.2}/templates/medical.yaml +0 -0
  513. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/__init__.py +0 -0
  514. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/conftest.py +0 -0
  515. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/qa/v053_qa.md +0 -0
  516. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_adapters.py +0 -0
  517. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_advanced_peft.py +0 -0
  518. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_assistant_mask.py +0 -0
  519. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_audio.py +0 -0
  520. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_auto_tuning.py +0 -0
  521. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_autopilot.py +0 -0
  522. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_awq_gptq_export.py +0 -0
  523. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_batch_probe.py +0 -0
  524. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_bco.py +0 -0
  525. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_bench.py +0 -0
  526. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_brain_rot_multilingual.py +0 -0
  527. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_bugfixes.py +0 -0
  528. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_callback.py +0 -0
  529. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_cans.py +0 -0
  530. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_chat.py +0 -0
  531. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_chat_template.py +0 -0
  532. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_cli.py +0 -0
  533. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_cli_subprocess.py +0 -0
  534. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_config.py +0 -0
  535. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_cost.py +0 -0
  536. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_crash_reporter.py +0 -0
  537. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_curriculum.py +0 -0
  538. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_data.py +0 -0
  539. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_data_augment.py +0 -0
  540. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_data_sample.py +0 -0
  541. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_data_split.py +0 -0
  542. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_data_tools.py +0 -0
  543. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_dataset_hub.py +0 -0
  544. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_dataset_registry.py +0 -0
  545. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_deepspeed.py +0 -0
  546. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_deploy_ollama.py +0 -0
  547. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_diff.py +0 -0
  548. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_display.py +0 -0
  549. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_doctor.py +0 -0
  550. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_dpo_example.py +0 -0
  551. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_dpo_variants.py +0 -0
  552. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_embedding.py +0 -0
  553. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_errors.py +0 -0
  554. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_eval.py +0 -0
  555. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_eval_gate.py +0 -0
  556. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_eval_platform.py +0 -0
  557. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_export.py +0 -0
  558. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_formats.py +0 -0
  559. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_fp8_recipe.py +0 -0
  560. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_freeze_training.py +0 -0
  561. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_generate.py +0 -0
  562. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_gpu.py +0 -0
  563. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_grpo.py +0 -0
  564. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_hf_integration.py +0 -0
  565. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_infer.py +0 -0
  566. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_inference_advanced.py +0 -0
  567. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_init.py +0 -0
  568. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_ipo.py +0 -0
  569. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_jinja_analyzer.py +0 -0
  570. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_kto.py +0 -0
  571. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_loader.py +0 -0
  572. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_log_level.py +0 -0
  573. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_loss_watchdog.py +0 -0
  574. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_merge.py +0 -0
  575. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_migrate.py +0 -0
  576. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_mlx_backend.py +0 -0
  577. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_moe.py +0 -0
  578. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_multi_adapter.py +0 -0
  579. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_multi_gpu.py +0 -0
  580. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_multipack_config.py +0 -0
  581. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_multipack_invariants.py +0 -0
  582. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_multipack_sampler.py +0 -0
  583. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_neat_packing.py +0 -0
  584. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_neftune_rslora.py +0 -0
  585. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_onnx_tensorrt_export.py +0 -0
  586. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_orpo.py +0 -0
  587. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_packing.py +0 -0
  588. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_part_a_wave1.py +0 -0
  589. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_part_a_wave2.py +0 -0
  590. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_part_b.py +0 -0
  591. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_part_c.py +0 -0
  592. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_part_d.py +0 -0
  593. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_part_e.py +0 -0
  594. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_part_f_hardening.py +0 -0
  595. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_peft_methods.py +0 -0
  596. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_peft_patches.py +0 -0
  597. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_performance.py +0 -0
  598. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_pissa_init.py +0 -0
  599. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_ppo.py +0 -0
  600. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_preference_dispatcher.py +0 -0
  601. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_preference_multi.py +0 -0
  602. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_preference_multi_runtime.py +0 -0
  603. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_pretrain.py +0 -0
  604. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_profile.py +0 -0
  605. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_profiling.py +0 -0
  606. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_progress.py +0 -0
  607. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_push.py +0 -0
  608. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_qat.py +0 -0
  609. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_quality_filter.py +0 -0
  610. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_quant_check.py +0 -0
  611. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_quant_menu.py +0 -0
  612. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_quickstart.py +0 -0
  613. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_rank_pattern.py +0 -0
  614. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_recipes.py +0 -0
  615. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_recipes_v031.py +0 -0
  616. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_refusal_multilingual.py +0 -0
  617. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_relora.py +0 -0
  618. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_replay.py +0 -0
  619. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_resume.py +0 -0
  620. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_rlvr.py +0 -0
  621. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_run_cost.py +0 -0
  622. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_runs.py +0 -0
  623. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_server_generate.py +0 -0
  624. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_sglang_serve.py +0 -0
  625. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_simpo.py +0 -0
  626. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_smoke_train.py +0 -0
  627. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_speculative_decoding.py +0 -0
  628. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_sweep.py +0 -0
  629. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_synth_data_pro.py +0 -0
  630. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_templates_yaml.py +0 -0
  631. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_tensorboard.py +0 -0
  632. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_tool_calling.py +0 -0
  633. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_trace_to_pref.py +0 -0
  634. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_tracker.py +0 -0
  635. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_trainer_coverage_v035.py +0 -0
  636. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_trainer_init.py +0 -0
  637. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_training_intelligence.py +0 -0
  638. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_training_speed.py +0 -0
  639. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_trust_remote_code.py +0 -0
  640. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_tui.py +0 -0
  641. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_ui.py +0 -0
  642. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_ui_chat.py +0 -0
  643. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_ui_config_builder.py +0 -0
  644. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_ui_live_monitor.py +0 -0
  645. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_ui_metrics.py +0 -0
  646. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_unsloth.py +0 -0
  647. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0401_part_c.py +0 -0
  648. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0401_part_d.py +0 -0
  649. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0401_part_e.py +0 -0
  650. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0402_part_a.py +0 -0
  651. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0402_part_b.py +0 -0
  652. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0403_part_a.py +0 -0
  653. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0403_part_b.py +0 -0
  654. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0403_part_c.py +0 -0
  655. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0404_part_a.py +0 -0
  656. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0404_part_b.py +0 -0
  657. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0405_part_a.py +0 -0
  658. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0406_part_a.py +0 -0
  659. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0410_part_a.py +0 -0
  660. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0410_part_b.py +0 -0
  661. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0410_part_c.py +0 -0
  662. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0420.py +0 -0
  663. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0430_part_a.py +0 -0
  664. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0430_part_b.py +0 -0
  665. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0430_part_c.py +0 -0
  666. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0430_part_d.py +0 -0
  667. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0440_part_a.py +0 -0
  668. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0440_part_b.py +0 -0
  669. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0440_part_c.py +0 -0
  670. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0440_part_d.py +0 -0
  671. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0440_review_followups.py +0 -0
  672. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0450.py +0 -0
  673. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0460_part_a.py +0 -0
  674. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0460_part_b.py +0 -0
  675. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0470_part_a.py +0 -0
  676. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0470_part_b.py +0 -0
  677. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0480_part_a.py +0 -0
  678. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0480_part_b.py +0 -0
  679. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0490.py +0 -0
  680. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0500_part_a.py +0 -0
  681. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0500_part_b.py +0 -0
  682. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0500_part_c.py +0 -0
  683. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0500_part_d.py +0 -0
  684. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0500_part_e.py +0 -0
  685. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0510.py +0 -0
  686. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0520.py +0 -0
  687. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0530.py +0 -0
  688. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v05310.py +0 -0
  689. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v05311.py +0 -0
  690. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0531_109.py +0 -0
  691. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0531_139.py +0 -0
  692. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0531_142.py +0 -0
  693. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0531_82.py +0 -0
  694. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0532.py +0 -0
  695. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0533.py +0 -0
  696. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0534.py +0 -0
  697. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0535.py +0 -0
  698. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0536.py +0 -0
  699. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0537.py +0 -0
  700. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0539.py +0 -0
  701. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0540.py +0 -0
  702. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0550.py +0 -0
  703. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0550_followups.py +0 -0
  704. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0560.py +0 -0
  705. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0570_part_a.py +0 -0
  706. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0570_part_c.py +0 -0
  707. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0570_part_d.py +0 -0
  708. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0580.py +0 -0
  709. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0590.py +0 -0
  710. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0600_part_a.py +0 -0
  711. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0600_part_c.py +0 -0
  712. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0600_part_d.py +0 -0
  713. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0600_part_f.py +0 -0
  714. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0610_part_a.py +0 -0
  715. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0610_part_c.py +0 -0
  716. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0610_part_d.py +0 -0
  717. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0610_part_e.py +0 -0
  718. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0620_followups.py +0 -0
  719. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0620_part_a.py +0 -0
  720. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0620_part_b.py +0 -0
  721. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0620_part_c.py +0 -0
  722. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0620_part_d.py +0 -0
  723. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0620_part_e.py +0 -0
  724. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0630_followups.py +0 -0
  725. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0630_part_a.py +0 -0
  726. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0630_part_b.py +0 -0
  727. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0630_part_c.py +0 -0
  728. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0630_part_d.py +0 -0
  729. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0630_part_e.py +0 -0
  730. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0631_206.py +0 -0
  731. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0640_followups.py +0 -0
  732. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0640_part_a.py +0 -0
  733. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0640_part_b.py +0 -0
  734. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0640_part_d.py +0 -0
  735. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0640_part_f.py +0 -0
  736. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0650_followups.py +0 -0
  737. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0650_part_b.py +0 -0
  738. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0650_part_c.py +0 -0
  739. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0650_part_d.py +0 -0
  740. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0650_part_e.py +0 -0
  741. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0660_cli.py +0 -0
  742. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0660_followups.py +0 -0
  743. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0660_part_a.py +0 -0
  744. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0660_part_b.py +0 -0
  745. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0660_part_c.py +0 -0
  746. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0660_part_d.py +0 -0
  747. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0660_part_e.py +0 -0
  748. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0670_followups.py +0 -0
  749. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0670_part_a.py +0 -0
  750. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0670_part_b.py +0 -0
  751. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0670_part_c.py +0 -0
  752. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0670_part_d.py +0 -0
  753. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0670_part_f.py +0 -0
  754. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0680_followups.py +0 -0
  755. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0680_part_a.py +0 -0
  756. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0680_part_b.py +0 -0
  757. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0680_part_c.py +0 -0
  758. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0680_part_d.py +0 -0
  759. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0680_part_e.py +0 -0
  760. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0690_part_b.py +0 -0
  761. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0690_part_c.py +0 -0
  762. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0690_part_d.py +0 -0
  763. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0690_part_e.py +0 -0
  764. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0700_part_a.py +0 -0
  765. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0700_part_b.py +0 -0
  766. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0700_part_c.py +0 -0
  767. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0700_part_d.py +0 -0
  768. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0700_part_e.py +0 -0
  769. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_v0700_part_f.py +0 -0
  770. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_validator.py +0 -0
  771. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_vision.py +0 -0
  772. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_vllm_serve.py +0 -0
  773. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_why.py +0 -0
  774. {soup_cli-0.71.0 → soup_cli-0.71.2}/tests/test_windows_encoding.py +0 -0
@@ -0,0 +1,120 @@
1
+ # Changelog
2
+
3
+ All notable changes to **Soup CLI** are documented here.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ Detailed, per-release notes for every published version live on the
9
+ [GitHub Releases page](https://github.com/MakazhanAlpamys/Soup/releases). This
10
+ file tracks unreleased changes and links out for historical detail rather than
11
+ reproducing 70+ versions of notes.
12
+
13
+ ## [Unreleased]
14
+
15
+ ## [0.71.2] - 2026-06-01
16
+
17
+ ### Added
18
+ - **ed25519 signing for `soup adapters sign` / `soup attest`** — real detached
19
+ signatures (over the adapter Merkle root / the in-toto statement) via a new
20
+ `[sign]` extra (`pip install soup-cli[sign]`, pulling `cryptography`).
21
+ `soup adapters sign --backend ed25519 --key <priv.pem>` (or `--generate-key
22
+ <out.pem>`, or `SOUP_SIGNING_KEY`); `soup adapters verify [--public-key
23
+ <trusted.pem>]` does a cryptographic verify and, with a trusted key, genuine
24
+ authentication. `soup attest emit --sign ed25519 --key <priv.pem>` writes a
25
+ `<output>.sig` sidecar; new `soup attest verify <statement> --signature <sig>`
26
+ verifies it (canonical-JSON, so it's platform/newline-independent). Sigstore
27
+ keyless signing stays infra-blocked (needs an OIDC provider + Fulcio/Rekor
28
+ network — can't be honestly validated offline).
29
+ - **Anti-AI-Jacking namespace pin on Hub downloads** — HF model fetches now
30
+ consult a trust-on-first-use pin store: a repo whose author changes (or whose
31
+ `created_at` jumps backward) is refused unless the namespace shift is explicitly
32
+ allowed. Fails open when repo metadata is unavailable.
33
+ - **License auto-detection at `soup adapters merge`** — when `--license` isn't
34
+ given, the license is read from each adapter's `adapter_config.json` /
35
+ `config.json` / model-card frontmatter (HF `llama3.1`-style ids mapped to
36
+ canonical) and the conflict gate runs automatically.
37
+ - **Backdoor-scan gate at `soup adapters merge`** — refuses to merge any input
38
+ whose `soup adapters scan` returns FAIL (or can't be scanned) unless
39
+ `--allow-unscanned` is passed; WARN is advisory.
40
+
41
+ ### Changed
42
+ - License-conflict overrides (`--license-override <reason>`) are now recorded to
43
+ the audit log for legal review.
44
+ - The namespace-pin store now uses SQLite WAL + busy-timeout and a cross-process
45
+ file lock around its get+insert, so concurrent writers don't lose the trust
46
+ anchor.
47
+
48
+ ### Security
49
+ - ed25519 verification fails closed (any tamper / wrong key / missing key ⇒
50
+ invalid). Signing keys + trusted public keys are symlink-rejected and
51
+ size-capped via a shared reader (no cwd-containment — keys live outside the
52
+ project). `--generate-key` refuses to overwrite any existing path.
53
+
54
+ ## [0.71.1] - 2026-06-01
55
+
56
+ ### Added
57
+ - `soup env fix` — render a reproducible install plan from `soup-env.lock`.
58
+ Emits copy/paste `uv pip install` commands (`--format uv-pip`, default) or a
59
+ `requirements.txt` body (`--format requirements`); `--output` optionally writes
60
+ a `requirements.txt` under cwd. Print-only by design — never shells out to a
61
+ package manager.
62
+ - `soup lock write --env-lock <path>` — auto-derive `--env-hash` from a
63
+ `soup-env.lock` so operators who ran `soup env lock` don't copy the hash by
64
+ hand. `--env-hash` still wins when passed explicitly.
65
+ - `soup serve --record-thumbs <db>` — capture thumbs-up/down feedback into a
66
+ local-RL SQLite at startup, plus a new `POST /v1/thumbs` endpoint (transformers
67
+ backend). Returns 404 when the flag isn't set.
68
+ - Judge-calibration persistence: `JudgeCalibrationReport.to_dict`,
69
+ `write_judge_calibration`, and `load_judge_calibration`, backed by a new
70
+ `judge_calibration` registry artifact kind. Loading re-validates the report so
71
+ a corrupt on-disk field is rejected.
72
+ - Bundled MUSE and WMDP unlearning eval fixtures so
73
+ `soup eval unlearning --benchmark muse|wmdp` runs out of the box. WMDP
74
+ forget-set probes ship **redacted** (placeholder prompts + `REFUSED` responses)
75
+ — Soup never ships verbatim hazardous content.
76
+
77
+ ### Changed
78
+ - `soup completions` now introspects a cached base model's actual LoRA target
79
+ modules (config-only `AutoConfig` load, `local_files_only=True`, never networks
80
+ or raises) and falls back to the canonical default shape when the base isn't
81
+ cached locally.
82
+ - `build_dag` exposes a `validate_build_source` helper (cwd-containment +
83
+ symlink rejection) for build-manifest source paths.
84
+
85
+ ## [0.71.0] - 2026-06-01
86
+
87
+ ### Changed
88
+ - **Breaking — install split.** The heavy training stack (`torch`,
89
+ `transformers`, `peft`, `trl`, `datasets`, `bitsandbytes`, `accelerate`) moved
90
+ out of the core install into a new `[train]` extra. `pip install soup-cli` is
91
+ now a light CLI + data-tools install with **no PyTorch**; run
92
+ `pip install 'soup-cli[train]'` (or `[all]`) to fine-tune. Existing users who
93
+ train must reinstall with `[train]`. Version pins are unchanged.
94
+ - Trimmed `README.md` to a ~238-line front door; the full feature reference now
95
+ lives under `docs/` (one topic page per area, indexed from the README).
96
+ - Raised the pytest coverage gate from 50% to 77% (`--cov-fail-under=77`).
97
+ - Migrated to a `src/` layout (`src/soup_cli/`) for cleaner packaging and to
98
+ stop tests accidentally importing the in-tree package.
99
+
100
+ ### Added
101
+ - `[train]` and `[all]` optional-dependency extras (`[all]` pulls
102
+ `train`, `serve`, `ui`, `data`). `[dev]` self-references `[train]` so CI and
103
+ contributors still get the full stack from `pip install -e ".[dev]"`.
104
+ - Friendly error mapping: a missing heavy dependency (`torch`, `transformers`,
105
+ `peft`, `trl`, `datasets`, `bitsandbytes`, `accelerate`) now surfaces
106
+ "Training needs the [train] extra. Run: pip install 'soup-cli[train]'".
107
+ - `py.typed` marker (PEP 561) so downstream type checkers pick up Soup's inline
108
+ type hints.
109
+ - `.pre-commit-config.yaml` with ruff (lint + format) and standard file-hygiene
110
+ hooks.
111
+ - Lenient `mypy` configuration and a non-blocking `type-check` CI job.
112
+ - This `CHANGELOG.md`.
113
+
114
+ ### Removed
115
+ - The historical, per-version security-fix log that had grown inside
116
+ `SECURITY.md` (~220 KB). `SECURITY.md` is now a concise security policy; the
117
+ detailed hardening notes remain in git history and the GitHub Releases notes.
118
+
119
+ [Unreleased]: https://github.com/MakazhanAlpamys/Soup/compare/v0.71.0...HEAD
120
+ [0.71.0]: https://github.com/MakazhanAlpamys/Soup/compare/v0.70.0...v0.71.0
@@ -31,6 +31,8 @@ This installs:
31
31
  - the full training stack — `[dev]` self-references `[train]`, so `torch`,
32
32
  `transformers`, `peft`, `trl`, `datasets`, `bitsandbytes`, `accelerate` are
33
33
  pulled in too (since v0.71.0 these are an opt-in extra, not core deps)
34
+ - `cryptography` — `[dev]` also pulls it in (it's the `[sign]` extra) so the
35
+ ed25519 signing tests (`soup adapters sign` / `soup attest`) run in CI
34
36
 
35
37
  ### 3. Verify Setup
36
38
 
@@ -116,7 +118,7 @@ src/soup_cli/
116
118
  templates/ - 17 built-in soup.yaml templates (YAML + manifest.json) with load_template loader (v0.39.0, +bco v0.40.0)
117
119
  ui/ - Web UI (FastAPI + HTML/JS SPA)
118
120
 
119
- tests/ - Test suite (268 files, 11824 tests)
121
+ tests/ - Test suite (272 files, 12259 tests)
120
122
  examples/ - Real-world config examples and datasets
121
123
  ```
122
124
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soup-cli
3
- Version: 0.71.0
3
+ Version: 0.71.2
4
4
  Summary: Fine-tune LLMs in one command. No SSH, no config hell.
5
5
  Project-URL: Homepage, https://github.com/MakazhanAlpamys/Soup
6
6
  Project-URL: Repository, https://github.com/MakazhanAlpamys/Soup
@@ -51,6 +51,7 @@ Requires-Dist: deepspeed>=0.12.0; extra == 'deepspeed'
51
51
  Provides-Extra: dev
52
52
  Requires-Dist: accelerate>=0.25.0; extra == 'dev'
53
53
  Requires-Dist: bitsandbytes>=0.41.0; extra == 'dev'
54
+ Requires-Dist: cryptography>=41.0.0; extra == 'dev'
54
55
  Requires-Dist: datasets>=2.14.0; extra == 'dev'
55
56
  Requires-Dist: httpx>=0.24.0; extra == 'dev'
56
57
  Requires-Dist: mypy>=1.8.0; extra == 'dev'
@@ -99,6 +100,8 @@ Provides-Extra: sglang
99
100
  Requires-Dist: fastapi>=0.104.0; extra == 'sglang'
100
101
  Requires-Dist: sglang>=0.2.0; extra == 'sglang'
101
102
  Requires-Dist: uvicorn>=0.24.0; extra == 'sglang'
103
+ Provides-Extra: sign
104
+ Requires-Dist: cryptography>=41.0.0; extra == 'sign'
102
105
  Provides-Extra: tensorrt
103
106
  Requires-Dist: tensorrt-llm>=0.9.0; extra == 'tensorrt'
104
107
  Provides-Extra: trackers
@@ -175,10 +178,19 @@ infrastructure instead of improving models. Soup fixes that.
175
178
 
176
179
  ## What's New
177
180
 
178
- **v0.71.0Lighter install.** The heavy training stack (PyTorch, Transformers, PEFT, TRL,
179
- datasets, bitsandbytes, accelerate) moved into a `[train]` extra. `pip install soup-cli` is now a
180
- light CLI + data-tools install with no PyTorch; `pip install 'soup-cli[train]'` adds everything you
181
- need to fine-tune. **Breaking:** existing users who train must reinstall with `[train]`.
181
+ **v0.71.2Governance & supply-chain live.** Real signatures and supply-chain gates:
182
+
183
+ - **ed25519 signing** `soup adapters sign --backend ed25519 --key priv.pem` (or `--generate-key`)
184
+ produces a real detached signature over the adapter's Merkle root; `soup adapters verify
185
+ --public-key trusted.pem` does cryptographic authentication. Same for `soup attest emit
186
+ --sign ed25519` + the new `soup attest verify`. Install with `pip install soup-cli[sign]`.
187
+ - **Anti-AI-Jacking namespace pin** — Hub model downloads now refuse a repo whose author silently
188
+ changed (or whose creation date jumped backward), the classic namespace-re-creation attack.
189
+ - **License-conflict gate at merge** — `soup adapters merge` auto-detects each adapter's license
190
+ (from `adapter_config.json` / model card) and refuses incompatible combinations unless you pass
191
+ `--license-override <reason>` (logged to the audit trail).
192
+ - **Backdoor-scan gate at merge** — refuses to merge any adapter that `soup adapters scan` flags
193
+ FAIL unless you pass `--allow-unscanned`.
182
194
 
183
195
  Full history: [CHANGELOG.md](CHANGELOG.md) &middot; [GitHub Releases](https://github.com/MakazhanAlpamys/Soup/releases).
184
196
 
@@ -49,10 +49,19 @@ infrastructure instead of improving models. Soup fixes that.
49
49
 
50
50
  ## What's New
51
51
 
52
- **v0.71.0Lighter install.** The heavy training stack (PyTorch, Transformers, PEFT, TRL,
53
- datasets, bitsandbytes, accelerate) moved into a `[train]` extra. `pip install soup-cli` is now a
54
- light CLI + data-tools install with no PyTorch; `pip install 'soup-cli[train]'` adds everything you
55
- need to fine-tune. **Breaking:** existing users who train must reinstall with `[train]`.
52
+ **v0.71.2Governance & supply-chain live.** Real signatures and supply-chain gates:
53
+
54
+ - **ed25519 signing** `soup adapters sign --backend ed25519 --key priv.pem` (or `--generate-key`)
55
+ produces a real detached signature over the adapter's Merkle root; `soup adapters verify
56
+ --public-key trusted.pem` does cryptographic authentication. Same for `soup attest emit
57
+ --sign ed25519` + the new `soup attest verify`. Install with `pip install soup-cli[sign]`.
58
+ - **Anti-AI-Jacking namespace pin** — Hub model downloads now refuse a repo whose author silently
59
+ changed (or whose creation date jumped backward), the classic namespace-re-creation attack.
60
+ - **License-conflict gate at merge** — `soup adapters merge` auto-detects each adapter's license
61
+ (from `adapter_config.json` / model card) and refuses incompatible combinations unless you pass
62
+ `--license-override <reason>` (logged to the audit trail).
63
+ - **Backdoor-scan gate at merge** — refuses to merge any adapter that `soup adapters scan` flags
64
+ FAIL unless you pass `--allow-unscanned`.
56
65
 
57
66
  Full history: [CHANGELOG.md](CHANGELOG.md) &middot; [GitHub Releases](https://github.com/MakazhanAlpamys/Soup/releases).
58
67
 
@@ -336,7 +336,20 @@ soup attest emit \
336
336
 
337
337
  Stages are a closed allowlist: `extract` / `train` / `eval` / `export` / `publish`.
338
338
  Subject SHA must be 64-hex (sha256). The default `--sign unsigned` backend ships now;
339
- Sigstore (OIDC-via-GitHub) and ed25519 air-gap signing arrive in v0.59.1.
339
+ the **`ed25519` backend is live** (`pip install soup-cli[sign]`):
340
+
341
+ ```bash
342
+ soup attest emit --stage train --subject adapter-v1 --sha aaaa...64hex \
343
+ --sign ed25519 --key signing.pem --output att.json # writes att.json.sig
344
+ soup attest verify att.json --signature att.json.sig # exit 0 valid
345
+ soup attest verify att.json --signature att.json.sig --public-key trusted.pub
346
+ ```
347
+
348
+ `verify` re-canonicalises the statement JSON (so it's platform/newline-independent)
349
+ and checks the ed25519 signature — exit 3 on tamper, key mismatch, or a sidecar with
350
+ no public key. A valid signature proves the signer *asserted* the statement; it does
351
+ not re-verify the subject digest against an artifact. Sigstore keyless signing remains
352
+ infra-blocked (needs an OIDC identity provider + Fulcio/Rekor network).
340
353
 
341
354
 
342
355
  ## EU AI Act Annex XI/XII Auto-Doc (`soup train --annex-xi`)
@@ -397,12 +410,29 @@ v0.57.0 `adapter_diff` loader so the on-disk surface stays single-source.
397
410
 
398
411
  Deterministic Merkle-root manifest over every file in the adapter dir
399
412
  (including nested `tokenizer/` / `processor/` subdirs). Tamper any file
400
- and `verify` fails. The `unsigned` backend ships live for offline tamper
401
- detection (the Merkle-root hash is the trust anchor); `sigstore` and
402
- `ed25519` backends raise `NotImplementedError` with v0.60.1 marker so CI
403
- pipelines can integrate the schema today. Signature persists as
404
- `.soup-signature.json` written atomically via the shared
405
- `atomic_write_text` helper. `--strict` mode exits 3 on any verify
413
+ and `verify` fails. The `unsigned` backend gives offline tamper detection
414
+ (the Merkle-root hash is the trust anchor). The **`ed25519` backend is live**
415
+ (`pip install soup-cli[sign]`): it adds a real detached signature over the
416
+ Merkle root for *authentication* — proof the signer holds the private key.
417
+
418
+ ```bash
419
+ # generate a keypair + sign in one shot
420
+ soup adapters sign ./adapter --backend ed25519 --generate-key signing.pem
421
+ # or sign with an existing key (or set SOUP_SIGNING_KEY)
422
+ soup adapters sign ./adapter --backend ed25519 --key signing.pem
423
+ # self-consistency verify (embedded public key)
424
+ soup adapters verify ./adapter
425
+ # genuine authentication: require the signer's key match a trusted one
426
+ soup adapters verify ./adapter --public-key trusted.pub
427
+ ```
428
+
429
+ `verify` fails closed — any tamper, wrong/missing/unreadable key, or a
430
+ signature from an untrusted key marks the adapter invalid. Signing keys and
431
+ trusted public keys are symlink-rejected and size-capped but **not**
432
+ cwd-contained (keys are secrets that live outside the project). Signature
433
+ persists as `.soup-signature.json` (atomic write). `sigstore` keyless signing
434
+ stays infra-blocked (needs an OIDC identity provider + Fulcio/Rekor network —
435
+ it can't be honestly validated offline). `--strict` mode exits 3 on any verify
406
436
  failure (CI gate code distinct from generic errors).
407
437
 
408
438
 
@@ -428,9 +458,12 @@ bool rejected so callers can't smuggle a free-for-all bypass). Threat
428
458
  model: an attacker watches a popular repo, waits for the original owner
429
459
  to delete or expire it, then re-creates the same `owner/name` with
430
460
  malicious weights. Without this control, anyone with Soup pinned to that
431
- namespace silently pulls poison on the next run. Live wiring into
432
- `utils/hubs.download_repo` lands in v0.60.1; today the helpers are
433
- operator-callable via the Python API.
461
+ namespace silently pulls poison on the next run. **The gate is wired into
462
+ Hub model downloads** it consults the pin before fetching and refuses a
463
+ mismatch (raising before any weights land). It fails **open** when repo
464
+ metadata can't be fetched (offline / rate-limited) so a transient hiccup
465
+ never blocks a legitimate download. The pin store uses SQLite WAL + a
466
+ cross-process file lock so concurrent fetches don't lose the trust anchor.
434
467
 
435
468
 
436
469
  ## License-Conflict Matrix at Merge
@@ -440,10 +473,17 @@ MIT / BSD / LGPL / MPL / GPL / AGPL / CC-BY / CC-BY-NC / Llama-2/3.x /
440
473
  Gemma / Qwen-research / Mistral-research / OpenRAIL / OpenAI-ToS /
441
474
  Anthropic-AUP. `soup adapters merge --license apache-2.0 --license
442
475
  cc-by-nc-4.0 -o merged` refuses (non-commercial cannot combine with
443
- permissive). To proceed past a flagged conflict, pass
444
- `--license-override "legal-cleared 2026-05-19 by alice"` (8-char min,
445
- 4096-char max reason). The override reason surfaces in the merge panel;
446
- audit-log integration lands in v0.60.1.
476
+ permissive). When you don't pass `--license`, the license is
477
+ **auto-detected** from each adapter's `adapter_config.json` / `config.json`
478
+ / model-card frontmatter (HF `llama3.1`-style ids map to canonical) and the
479
+ gate runs automatically when every adapter resolves to a known license. To
480
+ proceed past a flagged conflict, pass `--license-override "legal-cleared
481
+ 2026-05-19 by alice"` (8-char min, 4096-char max reason) — the decision is
482
+ **recorded to the audit log** for later legal review.
483
+
484
+ Merge is additionally gated by the backdoor scanner: any input that
485
+ `soup adapters scan` flags FAIL (or that can't be scanned) refuses the
486
+ merge with exit 3 unless you pass `--allow-unscanned`.
447
487
 
448
488
 
449
489
  ## Airgap Bundle (`soup airgap-bundle`)
@@ -56,6 +56,7 @@ soup serve --model <m> --structured-output regex --regex-pattern '...' Regex-co
56
56
  soup serve --model <m> --dashboard Live dashboard + /metrics endpoint
57
57
  soup serve --model <m> --trace --trace-endpoint http://localhost:4317 OpenTelemetry tracing
58
58
  soup serve --model <m> --trace-log ./serve.jsonl Per-request JSONL log + rotation + secret redaction
59
+ soup serve --model <m> --record-thumbs ./rl.db Capture 👍/👎 feedback into local-RL SQLite + POST /v1/thumbs (transformers)
59
60
  POST /v1/adapters/activate/<name> Hot-swap active LoRA adapter
60
61
  soup sweep --config soup.yaml --param lr=... Hyperparameter search
61
62
  soup diff --model-a ./a --model-b ./b Compare two models
@@ -150,10 +151,12 @@ soup serve --reasoning-parser deepseek-r1 Strip <think> blocks from response
150
151
  soup doctor [--nccl] Check environment (optionally check NCCL bandwidth)
151
152
  soup quickstart [--dry-run] Full demo
152
153
  soup adapters scan <adapter> Spectral backdoor scan (rank-1 dominance + outlier detection)
153
- soup adapters sign <adapter> [--backend X] Compute Merkle-root manifest (.soup-signature.json)
154
- soup adapters verify <adapter> [--strict] Verify manifest against current files
154
+ soup adapters sign <adapter> [--backend unsigned|ed25519] [--key <pem>|--generate-key <pem>] Merkle manifest + ed25519 sign
155
+ soup adapters verify <adapter> [--strict] [--public-key <pem>] Verify manifest + ed25519 signature
155
156
  soup adapters check-safetensors <adapter> [--strict] Refuse pickle / PyTorch-classic weights
156
- soup adapters merge ... --license <id> --license-override <reason> License-conflict gate
157
+ soup adapters merge ... [--license <id>] [--license-override <reason>] [--allow-unscanned] License + backdoor-scan gates (auto-detect license; scan FAIL refused)
158
+ soup attest emit ... [--sign ed25519 --key <pem>] [-o att.json] in-toto/SLSA-3 attestation (+ .sig sidecar)
159
+ soup attest verify <statement> --signature <sig> [--public-key <pem>] Verify ed25519 attestation signature
157
160
  soup airgap-bundle --model <m> --output <out.tar> Signed tarball for data-diode transfer
158
161
  soup eval unlearning <run-id> --benchmark tofu|muse|wmdp Forget Quality + Model Utility + PrivLeak verdict
159
162
  soup edit set --base <m> --method rome|memit|alphaedit --subject "..." --target "..." Surgical knowledge edit (--plan-only available)
@@ -169,6 +172,7 @@ soup tunability --dataset <jsonl> [--candidates a,b,c] Probe 8 candidate bases
169
172
  soup plan --config soup.yaml Pre-flight summary + write soup.tfstate
170
173
  soup apply --config soup.yaml [--dry-run] Lock-and-execute; refuses on drift (exit 3)
171
174
  soup env lock | status | check Hermetic env lockfile + ABI drift detection (exit 3)
175
+ soup env fix [--format uv-pip|requirements] [--output req.txt] Render a reproducible install plan from soup-env.lock (print-only)
172
176
  soup completions bash | zsh | fish Shell completion script (sourceable via eval)
173
177
  soup license-advisor --target b2c|defense|embedded Recommend license-clean base for deploy target
174
178
  soup license-advisor ... --license <id> --mau N Per-license downstream-risk check (exit 3 on block)
@@ -182,6 +186,7 @@ soup adapters merge ... --strategy cmaes --eval <s> --budget 1h CMA-ES evolutio
182
186
  soup adapters pr <title> --base-sha <hex> --adapter <path> GitHub-shaped adapter PR Markdown / JSON (v0.67.0)
183
187
  soup adapters bisect <ckpt>... --eval-command "..." Binary search over training history (v0.67.0)
184
188
  soup lock write --base-sha <h> --dataset-sha <h> --env-hash <h> Write soup.lock (v0.67.0)
189
+ soup lock write --base-sha <h> --dataset-sha <h> --env-lock soup-env.lock Auto-derive --env-hash from soup-env.lock (v0.71.1)
185
190
  soup lock show / soup lock check Show + drift-check (exit 3 on drift)
186
191
  soup compile <program.py> --eval <suite> [--optimizer mipro|gepa|textgrad|copro|bootstrap_fewshot] DSPy / GEPA prompt-program compiler (v0.68.0)
187
192
  soup distill-prompt --traces <jsonl> --teacher <m> --student <m> --strategy sft|preference|kl Distill prompt-heavy traces to small FT (v0.68.0)
@@ -447,6 +447,8 @@ ensure_judge_calibrated(report) # raises RuntimeError if not calibrated
447
447
 
448
448
  The report carries `position_bias` ∈ [-1, 1] (0 = no slot preference), a conformal abstention threshold from the score quantile, agreement-rate vs the oracle, and a `calibrated` bool. `ensure_judge_calibrated` refuses on missing report, low agreement, or extreme bias — so production scoring code can fail loud, not silent.
449
449
 
450
+ Persist a calibration once and reuse it across runs (v0.71.1): `write_judge_calibration(report, "calib.json")` writes a cwd-contained JSON, and `load_judge_calibration("calib.json")` re-validates it on load (a corrupt or out-of-range field on disk is rejected, since it's the production-gate safety net). The artifact attaches to the registry under the new `judge_calibration` kind.
451
+
450
452
  **Behaviour battery** — pre/post diff on bundled safety / refusal / sycophancy probe sets:
451
453
 
452
454
  ```bash
@@ -117,7 +117,7 @@ training:
117
117
  soup eval unlearning <run-id> --benchmark tofu --evidence evidence.json --output report.json
118
118
  ```
119
119
 
120
- Three orthogonal axes: **Forget Quality** (pre/post forget-loss delta), **Model Utility** (retain-accuracy preserved), **PrivLeak** (membership-inference AUC distance from 0.5). Bundled TOFU mini-fixture; MUSE + WMDP loaders land in the next release.
120
+ Three orthogonal axes: **Forget Quality** (pre/post forget-loss delta), **Model Utility** (retain-accuracy preserved), **PrivLeak** (membership-inference AUC distance from 0.5). Bundled mini-fixtures for all three benchmarks ship in the box (v0.71.1 added MUSE + WMDP alongside the existing TOFU set), so `--benchmark muse|wmdp` runs without supplying evidence. The WMDP forget-set probes ship **redacted** (placeholder prompts + `REFUSED` responses) — Soup never bundles verbatim hazardous-knowledge content.
121
121
 
122
122
 
123
123
  ## Continued Pre-training
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "soup-cli"
7
- version = "0.71.0"
7
+ version = "0.71.2"
8
8
  description = "Fine-tune LLMs in one command. No SSH, no config hell."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -54,7 +54,7 @@ wandb = ["wandb>=0.15.0,<0.18.0"]
54
54
  # Self-references `[train]` so CI / contributors get the full training stack
55
55
  # (CI runs `pip install -e ".[dev]"`; without this every test would fail at
56
56
  # `import torch`).
57
- dev = ["soup-cli[train]", "pytest>=7.0", "ruff>=0.1.0", "pytest-cov>=4.0", "httpx>=0.24.0", "mypy>=1.8.0", "pre-commit>=3.5.0"]
57
+ dev = ["soup-cli[train]", "cryptography>=41.0.0", "pytest>=7.0", "ruff>=0.1.0", "pytest-cov>=4.0", "httpx>=0.24.0", "mypy>=1.8.0", "pre-commit>=3.5.0"]
58
58
  ui = ["fastapi>=0.104.0", "uvicorn>=0.24.0"]
59
59
  serve = ["fastapi>=0.104.0", "uvicorn>=0.24.0"]
60
60
  serve-fast = ["vllm>=0.4.0", "fastapi>=0.104.0", "uvicorn>=0.24.0"]
@@ -85,6 +85,10 @@ mix = ["scikit-optimize>=0.9.0"]
85
85
  # presidio-analyzer (PII). Llama-Guard-3-1B is documented as a manual recipe
86
86
  # (license + ~600 MB weight blob too large to bundle by default).
87
87
  data-pro = ["langdetect>=1.0.9", "presidio-analyzer>=2.2.0"]
88
+ # v0.71.2 #179/#185 — ed25519 detached signing for `soup attest` / `soup
89
+ # adapters sign`. Pure-offline; Sigstore keyless (OIDC + Fulcio/Rekor network)
90
+ # stays infra-blocked and is NOT bundled here.
91
+ sign = ["cryptography>=41.0.0"]
88
92
 
89
93
  [project.scripts]
90
94
  soup = "soup_cli.cli:run"
@@ -1,3 +1,3 @@
1
1
  """Soup CLI — Fine-tune LLMs in one command."""
2
2
 
3
- __version__ = "0.71.0"
3
+ __version__ = "0.71.2"
@@ -371,7 +371,15 @@ def merge(
371
371
  None, "--license-override",
372
372
  help=(
373
373
  "Free-text justification (>=8 chars) to merge across a license "
374
- "conflict. Logged for legal review."
374
+ "conflict. Logged to the audit log for legal review (v0.71.2)."
375
+ ),
376
+ ),
377
+ allow_unscanned: bool = typer.Option(
378
+ False, "--allow-unscanned",
379
+ help=(
380
+ "Skip the v0.71.2 backdoor-scan gate. By default `adapters merge` "
381
+ "refuses to merge an input whose `adapters scan` returns FAIL (or "
382
+ "that cannot be scanned)."
375
383
  ),
376
384
  ),
377
385
  ):
@@ -379,6 +387,8 @@ def merge(
379
387
  from soup_cli.utils.adapter_merge import SUPPORTED_STRATEGIES, merge_adapters
380
388
  from soup_cli.utils.license_matrix import (
381
389
  check_license_compat,
390
+ extract_license_from_adapter,
391
+ record_license_override,
382
392
  validate_license_override_reason,
383
393
  )
384
394
 
@@ -435,8 +445,44 @@ def merge(
435
445
  console.print(panel)
436
446
  return
437
447
 
438
- # v0.60.0 Part E: license-conflict gate. Operators MUST declare a
439
- # license per adapter (or pass --license-override <reason>).
448
+ # v0.71.2 #192 backdoor-scan gate. Refuse to merge any input whose
449
+ # spectral scan returns FAIL (or that cannot be scanned at all) unless the
450
+ # operator passes --allow-unscanned. WARN is advisory-only. Runs AFTER the
451
+ # cmaes plan-only branch (which doesn't merge weights) so it gates only the
452
+ # strategies that actually write a merged adapter.
453
+ if not allow_unscanned:
454
+ from soup_cli.utils.adapter_scan import scan_adapter
455
+
456
+ for adapter_path in adapters:
457
+ try:
458
+ scan_report = scan_adapter(adapter_path)
459
+ except (FileNotFoundError, ValueError, TypeError, RuntimeError) as exc:
460
+ console.print(
461
+ f"[red]Could not scan {escape(adapter_path)} "
462
+ f"({escape(str(exc))}).[/]\n"
463
+ "[dim]Pass --allow-unscanned to merge anyway.[/]"
464
+ )
465
+ raise typer.Exit(3) from exc
466
+ if scan_report.overall == "FAIL":
467
+ console.print(
468
+ f"[red]Backdoor scan FAILED for {escape(adapter_path)}: "
469
+ f"{escape(scan_report.summary)}[/]\n"
470
+ "[dim]Pass --allow-unscanned to merge anyway "
471
+ "(not recommended).[/]"
472
+ )
473
+ raise typer.Exit(3)
474
+ if scan_report.overall == "WARN":
475
+ console.print(
476
+ f"[yellow]Backdoor scan WARN for {escape(adapter_path)}: "
477
+ f"{escape(scan_report.summary)} — proceeding.[/]"
478
+ )
479
+
480
+ # v0.60.0 Part E: license-conflict gate. Operators may declare a license
481
+ # per adapter (--license, repeatable) OR rely on v0.71.2 #187
482
+ # auto-extraction from adapter_config.json / config.json / model-card
483
+ # frontmatter. On a conflict, --license-override <reason> proceeds and the
484
+ # decision is recorded to the audit log (#190).
485
+ gate_licenses: Optional[list[str]] = None
440
486
  if license_ids:
441
487
  if len(license_ids) != len(adapters):
442
488
  console.print(
@@ -444,8 +490,26 @@ def merge(
444
490
  f"adapter count {len(adapters)}[/]"
445
491
  )
446
492
  raise typer.Exit(2)
493
+ gate_licenses = list(license_ids)
494
+ else:
495
+ # #187 — auto-detect. Only run the gate if EVERY adapter resolves to a
496
+ # known license; partial info would make the conflict check misleading.
497
+ extracted = [extract_license_from_adapter(a) for a in adapters]
498
+ if all(e is not None for e in extracted):
499
+ gate_licenses = [str(e) for e in extracted]
500
+ console.print(
501
+ "[dim]Auto-detected licenses: "
502
+ f"{escape(', '.join(gate_licenses))}[/]"
503
+ )
504
+ elif license_override is not None:
505
+ console.print(
506
+ "[yellow]--license-override given but licenses could not be "
507
+ "auto-detected for every adapter; no conflict gate triggered.[/]"
508
+ )
509
+
510
+ if gate_licenses is not None:
447
511
  try:
448
- license_report = check_license_compat(license_ids)
512
+ license_report = check_license_compat(gate_licenses)
449
513
  except (TypeError, ValueError) as exc:
450
514
  console.print(f"[red]License check failed: {escape(str(exc))}[/]")
451
515
  raise typer.Exit(2) from exc
@@ -467,16 +531,13 @@ def merge(
467
531
  f"[red]Invalid --license-override: {escape(str(exc))}[/]"
468
532
  )
469
533
  raise typer.Exit(2) from exc
534
+ # #190 — persist the override decision for legal review.
535
+ record_license_override(gate_licenses, cleared)
470
536
  console.print(
471
537
  f"[yellow]License conflict overridden:[/] "
472
538
  f"{escape(license_report.reason)}\n"
473
- f"[dim]Reason: {escape(cleared)}[/]"
539
+ f"[dim]Reason: {escape(cleared)} (recorded to audit log)[/]"
474
540
  )
475
- elif license_override is not None:
476
- console.print(
477
- "[yellow]--license-override given without --license declarations; "
478
- "no conflict gate triggered.[/]"
479
- )
480
541
 
481
542
  parsed_weights = None
482
543
  if weights:
@@ -762,19 +823,32 @@ def sign(
762
823
  adapter: str = typer.Argument(..., help="Path to adapter directory"),
763
824
  backend: str = typer.Option(
764
825
  "unsigned", "--backend",
765
- help="Signing backend: unsigned | ed25519 | sigstore (v0.60.0 ships unsigned only)",
826
+ help="Signing backend: unsigned | ed25519 (sigstore is infra-blocked)",
827
+ ),
828
+ key: Optional[str] = typer.Option(
829
+ None, "--key",
830
+ help="ed25519 private-key PEM path (or set SOUP_SIGNING_KEY).",
831
+ ),
832
+ generate_key: Optional[str] = typer.Option(
833
+ None, "--generate-key",
834
+ help="Generate a fresh ed25519 keypair, persist the private key here "
835
+ "(PEM, 0600), and sign with it.",
766
836
  ),
767
837
  ):
768
- """Compute manifest + write ``.soup-signature.json`` (v0.60.0).
838
+ """Compute manifest + write ``.soup-signature.json`` (v0.60.0, ed25519 v0.71.2).
769
839
 
770
- Default backend is ``unsigned`` provides offline tamper detection
771
- via Merkle-root hash. Sigstore + ed25519 backends raise NotImplementedError
772
- until v0.60.1.
840
+ ``unsigned`` (default) gives offline tamper detection via a Merkle-root
841
+ hash. ``ed25519`` (v0.71.2 #185) adds a real detached signature over that
842
+ root — pass ``--key <priv.pem>``, set ``SOUP_SIGNING_KEY``, or use
843
+ ``--generate-key <out.pem>``. ``sigstore`` keyless signing is infra-blocked
844
+ (needs an OIDC identity provider + Fulcio/Rekor network).
773
845
  """
774
846
  from soup_cli.utils.adapter_sign import sign_adapter
775
847
 
776
848
  try:
777
- record = sign_adapter(adapter, backend=backend)
849
+ record = sign_adapter(
850
+ adapter, backend=backend, key_path=key, generate_key_path=generate_key
851
+ )
778
852
  except FileNotFoundError as exc:
779
853
  console.print(f"[red]{escape(str(exc))}[/]")
780
854
  raise typer.Exit(1) from exc
@@ -785,6 +859,12 @@ def sign(
785
859
  console.print(f"[red]{escape(str(exc))}[/]")
786
860
  raise typer.Exit(2) from exc
787
861
 
862
+ if generate_key and record.backend == "ed25519":
863
+ console.print(
864
+ f"[yellow]Generated ed25519 private key -> {escape(generate_key)} "
865
+ "(keep it secret; verify with the matching public key).[/]"
866
+ )
867
+
788
868
  console.print(
789
869
  Panel(
790
870
  f"Adapter: [bold]{escape(record.manifest.adapter)}[/]\n"
@@ -804,8 +884,18 @@ def verify(
804
884
  False, "--strict",
805
885
  help="Exit 3 on any verification failure (CI-friendly)",
806
886
  ),
887
+ public_key: Optional[str] = typer.Option(
888
+ None, "--public-key",
889
+ help="Trusted ed25519 public-key PEM. When set, the embedded signing "
890
+ "key must match it (genuine authentication, not just consistency).",
891
+ ),
807
892
  ):
808
- """Verify ``.soup-signature.json`` against current files (v0.60.0).
893
+ """Verify ``.soup-signature.json`` against current files (v0.60.0, ed25519 v0.71.2).
894
+
895
+ For ``ed25519``-signed adapters the detached signature is verified against
896
+ the embedded public key (self-consistency); pass ``--public-key
897
+ <trusted.pem>`` to additionally require the signer's key match a key you
898
+ trust out of band.
809
899
 
810
900
  Exit codes:
811
901
  0 signature present and matches
@@ -815,10 +905,9 @@ def verify(
815
905
  from soup_cli.utils.adapter_sign import verify_adapter
816
906
 
817
907
  try:
818
- if strict:
819
- report = verify_adapter(adapter, strict=True)
820
- else:
821
- report = verify_adapter(adapter, strict=False)
908
+ report = verify_adapter(
909
+ adapter, strict=strict, trusted_public_key=public_key
910
+ )
822
911
  except FileNotFoundError as exc:
823
912
  console.print(f"[red]{escape(str(exc))}[/]")
824
913
  raise typer.Exit(1) from exc