self-evolve-framework 1.6.0 → 1.6.1

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 (301) hide show
  1. package/README.md +33 -23
  2. package/bin/cli.js +24 -67
  3. package/package.json +1 -1
  4. package/template/rules/knowledge/README.md +56 -0
  5. package/template/rules/knowledge/ant-design-vue.mdc +54 -0
  6. package/template/rules/knowledge/general.mdc +56 -0
  7. package/template/rules/knowledge/rust.mdc +55 -0
  8. package/template/rules/knowledge/shadcn-svelte.mdc +64 -0
  9. package/template/rules/knowledge/svelte.mdc +135 -0
  10. package/template/rules/knowledge/tailwind.mdc +66 -0
  11. package/template/rules/knowledge/tauri.mdc +65 -0
  12. package/template/rules/knowledge/typescript.mdc +41 -0
  13. package/template/rules/knowledge/vue.mdc +48 -0
  14. package/template/rules/ponytail.mdc +23 -98
  15. package/template/rules/self-evolve.mdc +24 -0
  16. package/template/skills/impeccable/SKILL.md +47 -174
  17. package/template/skills/skillopt-sleep/SKILL.md +32 -88
  18. package/template/skills/impeccable/agents/impeccable_asset_producer.toml +0 -92
  19. package/template/skills/impeccable/agents/impeccable_manual_edit_applier.toml +0 -95
  20. package/template/skills/impeccable/agents/openai.yaml +0 -4
  21. package/template/skills/impeccable/reference/adapt.md +0 -311
  22. package/template/skills/impeccable/reference/animate.md +0 -201
  23. package/template/skills/impeccable/reference/audit.md +0 -133
  24. package/template/skills/impeccable/reference/bolder.md +0 -113
  25. package/template/skills/impeccable/reference/brand.md +0 -108
  26. package/template/skills/impeccable/reference/clarify.md +0 -288
  27. package/template/skills/impeccable/reference/codex.md +0 -105
  28. package/template/skills/impeccable/reference/colorize.md +0 -257
  29. package/template/skills/impeccable/reference/craft.md +0 -123
  30. package/template/skills/impeccable/reference/critique.md +0 -790
  31. package/template/skills/impeccable/reference/delight.md +0 -302
  32. package/template/skills/impeccable/reference/distill.md +0 -111
  33. package/template/skills/impeccable/reference/document.md +0 -429
  34. package/template/skills/impeccable/reference/extract.md +0 -69
  35. package/template/skills/impeccable/reference/harden.md +0 -347
  36. package/template/skills/impeccable/reference/hooks.md +0 -90
  37. package/template/skills/impeccable/reference/init.md +0 -172
  38. package/template/skills/impeccable/reference/interaction-design.md +0 -189
  39. package/template/skills/impeccable/reference/layout.md +0 -161
  40. package/template/skills/impeccable/reference/live.md +0 -720
  41. package/template/skills/impeccable/reference/onboard.md +0 -234
  42. package/template/skills/impeccable/reference/optimize.md +0 -258
  43. package/template/skills/impeccable/reference/overdrive.md +0 -130
  44. package/template/skills/impeccable/reference/polish.md +0 -241
  45. package/template/skills/impeccable/reference/product.md +0 -60
  46. package/template/skills/impeccable/reference/quieter.md +0 -99
  47. package/template/skills/impeccable/reference/shape.md +0 -165
  48. package/template/skills/impeccable/reference/typeset.md +0 -279
  49. package/template/skills/impeccable/scripts/command-metadata.json +0 -94
  50. package/template/skills/impeccable/scripts/context-signals.mjs +0 -225
  51. package/template/skills/impeccable/scripts/context.mjs +0 -961
  52. package/template/skills/impeccable/scripts/critique-storage.mjs +0 -242
  53. package/template/skills/impeccable/scripts/detect-csp.mjs +0 -198
  54. package/template/skills/impeccable/scripts/detect.mjs +0 -21
  55. package/template/skills/impeccable/scripts/detector/browser/injected/index.mjs +0 -1937
  56. package/template/skills/impeccable/scripts/detector/cli/main.mjs +0 -290
  57. package/template/skills/impeccable/scripts/detector/design-system.mjs +0 -750
  58. package/template/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +0 -5138
  59. package/template/skills/impeccable/scripts/detector/detect-antipatterns.mjs +0 -50
  60. package/template/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +0 -277
  61. package/template/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +0 -568
  62. package/template/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +0 -1015
  63. package/template/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs +0 -234
  64. package/template/skills/impeccable/scripts/detector/engines/visual/screenshot-contrast.mjs +0 -189
  65. package/template/skills/impeccable/scripts/detector/findings.mjs +0 -12
  66. package/template/skills/impeccable/scripts/detector/node/file-system.mjs +0 -198
  67. package/template/skills/impeccable/scripts/detector/profile/profiler.mjs +0 -166
  68. package/template/skills/impeccable/scripts/detector/registry/antipatterns.mjs +0 -448
  69. package/template/skills/impeccable/scripts/detector/rules/checks.mjs +0 -2671
  70. package/template/skills/impeccable/scripts/detector/shared/color.mjs +0 -124
  71. package/template/skills/impeccable/scripts/detector/shared/constants.mjs +0 -101
  72. package/template/skills/impeccable/scripts/detector/shared/inline-ignores.mjs +0 -148
  73. package/template/skills/impeccable/scripts/detector/shared/page.mjs +0 -7
  74. package/template/skills/impeccable/scripts/hook-admin.mjs +0 -661
  75. package/template/skills/impeccable/scripts/hook-before-edit.mjs +0 -476
  76. package/template/skills/impeccable/scripts/hook-lib.mjs +0 -1632
  77. package/template/skills/impeccable/scripts/hook.mjs +0 -61
  78. package/template/skills/impeccable/scripts/lib/design-parser.mjs +0 -842
  79. package/template/skills/impeccable/scripts/lib/impeccable-config.mjs +0 -638
  80. package/template/skills/impeccable/scripts/lib/impeccable-paths.mjs +0 -128
  81. package/template/skills/impeccable/scripts/lib/is-generated.mjs +0 -69
  82. package/template/skills/impeccable/scripts/lib/target-args.mjs +0 -42
  83. package/template/skills/impeccable/scripts/live/browser-script-parts.mjs +0 -49
  84. package/template/skills/impeccable/scripts/live/completion.mjs +0 -19
  85. package/template/skills/impeccable/scripts/live/event-validation.mjs +0 -137
  86. package/template/skills/impeccable/scripts/live/insert-ui.mjs +0 -458
  87. package/template/skills/impeccable/scripts/live/manual-apply.mjs +0 -939
  88. package/template/skills/impeccable/scripts/live/manual-edit-routes.mjs +0 -357
  89. package/template/skills/impeccable/scripts/live/manual-edits-buffer.mjs +0 -152
  90. package/template/skills/impeccable/scripts/live/session-store.mjs +0 -289
  91. package/template/skills/impeccable/scripts/live/svelte-component.mjs +0 -826
  92. package/template/skills/impeccable/scripts/live/sveltekit-adapter.mjs +0 -274
  93. package/template/skills/impeccable/scripts/live/ui-core.mjs +0 -180
  94. package/template/skills/impeccable/scripts/live/vocabulary.mjs +0 -36
  95. package/template/skills/impeccable/scripts/live-accept.mjs +0 -812
  96. package/template/skills/impeccable/scripts/live-browser-dom.js +0 -146
  97. package/template/skills/impeccable/scripts/live-browser-session.js +0 -123
  98. package/template/skills/impeccable/scripts/live-browser.js +0 -11173
  99. package/template/skills/impeccable/scripts/live-commit-manual-edits.mjs +0 -1241
  100. package/template/skills/impeccable/scripts/live-complete.mjs +0 -75
  101. package/template/skills/impeccable/scripts/live-copy-edit-agent.mjs +0 -683
  102. package/template/skills/impeccable/scripts/live-discard-manual-edits.mjs +0 -51
  103. package/template/skills/impeccable/scripts/live-inject.mjs +0 -583
  104. package/template/skills/impeccable/scripts/live-insert.mjs +0 -272
  105. package/template/skills/impeccable/scripts/live-manual-edit-evidence.mjs +0 -363
  106. package/template/skills/impeccable/scripts/live-poll.mjs +0 -384
  107. package/template/skills/impeccable/scripts/live-resume.mjs +0 -94
  108. package/template/skills/impeccable/scripts/live-server.mjs +0 -1135
  109. package/template/skills/impeccable/scripts/live-status.mjs +0 -61
  110. package/template/skills/impeccable/scripts/live-target.mjs +0 -30
  111. package/template/skills/impeccable/scripts/live-wrap.mjs +0 -894
  112. package/template/skills/impeccable/scripts/live.mjs +0 -297
  113. package/template/skills/impeccable/scripts/modern-screenshot.umd.js +0 -14
  114. package/template/skills/impeccable/scripts/palette.mjs +0 -633
  115. package/template/skills/impeccable/scripts/pin.mjs +0 -214
  116. package/template/skills/skillopt-sleep/configs/_base_/default.yaml +0 -103
  117. package/template/skills/skillopt-sleep/configs/alfworld/default.yaml +0 -29
  118. package/template/skills/skillopt-sleep/configs/docvqa/default.yaml +0 -28
  119. package/template/skills/skillopt-sleep/configs/features/soft_gate.yaml +0 -47
  120. package/template/skills/skillopt-sleep/configs/livemathematicianbench/default.yaml +0 -22
  121. package/template/skills/skillopt-sleep/configs/officeqa/default.yaml +0 -34
  122. package/template/skills/skillopt-sleep/configs/searchqa/default.yaml +0 -32
  123. package/template/skills/skillopt-sleep/configs/spreadsheetbench/default.yaml +0 -34
  124. package/template/skills/skillopt-sleep/scripts/framework/skillopt/__init__.py +0 -28
  125. package/template/skills/skillopt-sleep/scripts/framework/skillopt/config.py +0 -282
  126. package/template/skills/skillopt-sleep/scripts/framework/skillopt/datasets/__init__.py +0 -7
  127. package/template/skills/skillopt-sleep/scripts/framework/skillopt/datasets/base.py +0 -512
  128. package/template/skills/skillopt-sleep/scripts/framework/skillopt/engine/__init__.py +0 -9
  129. package/template/skills/skillopt-sleep/scripts/framework/skillopt/engine/trainer.py +0 -2379
  130. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/__init__.py +0 -1
  131. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/README.md +0 -43
  132. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/config_template.yaml +0 -55
  133. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/env_template.py +0 -151
  134. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/_template/loader_template.py +0 -87
  135. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/__init__.py +0 -5
  136. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/adapter.py +0 -428
  137. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/dataloader.py +0 -123
  138. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/analyst_error.md +0 -55
  139. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/analyst_success.md +0 -33
  140. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/rollout_no_history.md +0 -8
  141. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/rollout_with_history.md +0 -9
  142. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/prompts/rollout_with_memory.md +0 -16
  143. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/reflect.py +0 -4
  144. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/rollout.py +0 -366
  145. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/skills/initial.md +0 -45
  146. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/__init__.py +0 -9
  147. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/alfworld_envs.py +0 -221
  148. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/alfworld_projection.py +0 -60
  149. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/alfworld_prompts.py +0 -8
  150. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/config_tw.yaml +0 -145
  151. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/env_base.py +0 -84
  152. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/env_manager.py +0 -139
  153. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/alfworld/vendor/memory.py +0 -87
  154. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/base.py +0 -329
  155. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/__init__.py +0 -1
  156. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/adapter.py +0 -90
  157. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/dataloader.py +0 -61
  158. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/evaluator.py +0 -113
  159. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/prompts/analyst_error.md +0 -35
  160. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/prompts/analyst_success.md +0 -24
  161. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/prompts/rollout_system.md +0 -12
  162. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/rollout.py +0 -391
  163. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/docvqa/skills/initial.md +0 -11
  164. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/__init__.py +0 -1
  165. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/adapter.py +0 -129
  166. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/dataloader.py +0 -308
  167. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/evaluator.py +0 -62
  168. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/prompts/analyst_error.md +0 -37
  169. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/prompts/analyst_success.md +0 -25
  170. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/prompts/rollout_system.md +0 -12
  171. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/reflect.py +0 -4
  172. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/rollout.py +0 -434
  173. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/livemathematicianbench/skills/initial.md +0 -16
  174. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/__init__.py +0 -1
  175. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/adapter.py +0 -112
  176. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/dataloader.py +0 -71
  177. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/evaluator.py +0 -46
  178. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/prompts/analyst_error.md +0 -37
  179. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/prompts/analyst_success.md +0 -25
  180. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/prompts/rollout_system.md +0 -15
  181. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/rollout.py +0 -799
  182. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/skills/initial.md +0 -15
  183. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/officeqa/tool_runtime.py +0 -552
  184. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/__init__.py +0 -1
  185. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/adapter.py +0 -96
  186. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/dataloader.py +0 -42
  187. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/evaluator.py +0 -100
  188. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/prompts/analyst_error.md +0 -46
  189. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/prompts/analyst_success.md +0 -32
  190. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/prompts/rollout_system.md +0 -13
  191. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/reflect.py +0 -4
  192. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/rollout.py +0 -494
  193. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/searchqa/skills/initial.md +0 -3
  194. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/__init__.py +0 -5
  195. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/adapter.py +0 -159
  196. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/codegen_agent.py +0 -731
  197. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/dataloader.py +0 -37
  198. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/evaluator.py +0 -158
  199. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/executor.py +0 -67
  200. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/analyst_error.md +0 -46
  201. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/analyst_success.md +0 -32
  202. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/codegen_system.md +0 -1
  203. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/critical_rules.md +0 -9
  204. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/prompts/react_system.md +0 -21
  205. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/react_agent.py +0 -395
  206. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/reflect.py +0 -4
  207. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/rollout.py +0 -979
  208. package/template/skills/skillopt-sleep/scripts/framework/skillopt/envs/spreadsheetbench/skills/initial.md +0 -56
  209. package/template/skills/skillopt-sleep/scripts/framework/skillopt/evaluation/__init__.py +0 -13
  210. package/template/skills/skillopt-sleep/scripts/framework/skillopt/evaluation/gate.py +0 -148
  211. package/template/skills/skillopt-sleep/scripts/framework/skillopt/gradient/__init__.py +0 -15
  212. package/template/skills/skillopt-sleep/scripts/framework/skillopt/gradient/aggregate.py +0 -253
  213. package/template/skills/skillopt-sleep/scripts/framework/skillopt/gradient/reflect.py +0 -635
  214. package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/__init__.py +0 -514
  215. package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/azure_openai.py +0 -915
  216. package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/backend_config.py +0 -185
  217. package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/claude_backend.py +0 -371
  218. package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/codex_backend.py +0 -666
  219. package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/codex_harness.py +0 -1057
  220. package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/common.py +0 -229
  221. package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/minimax_backend.py +0 -277
  222. package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/qwen_backend.py +0 -456
  223. package/template/skills/skillopt-sleep/scripts/framework/skillopt/model/router.py +0 -236
  224. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/__init__.py +0 -15
  225. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/appendix.py +0 -156
  226. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/clip.py +0 -109
  227. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/lr_autonomous.py +0 -108
  228. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/meta_skill.py +0 -79
  229. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/rewrite.py +0 -59
  230. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/scheduler.py +0 -127
  231. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/select.py +0 -4
  232. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/skill.py +0 -201
  233. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/skill_aware.py +0 -206
  234. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/slow_update.py +0 -396
  235. package/template/skills/skillopt-sleep/scripts/framework/skillopt/optimizer/update_modes.py +0 -135
  236. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/__init__.py +0 -63
  237. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_error.md +0 -41
  238. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_error_full_rewrite.md +0 -32
  239. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_error_rewrite.md +0 -44
  240. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_success.md +0 -36
  241. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_success_full_rewrite.md +0 -30
  242. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/analyst_success_rewrite.md +0 -33
  243. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/lr_autonomous.md +0 -20
  244. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_failure.md +0 -30
  245. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_failure_full_rewrite.md +0 -28
  246. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_failure_rewrite.md +0 -26
  247. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_final.md +0 -33
  248. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_final_full_rewrite.md +0 -28
  249. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_final_rewrite.md +0 -25
  250. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_success.md +0 -28
  251. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_success_full_rewrite.md +0 -28
  252. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/merge_success_rewrite.md +0 -25
  253. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/meta_skill.md +0 -40
  254. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/ranking.md +0 -20
  255. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/ranking_rewrite.md +0 -15
  256. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/rewrite_skill.md +0 -25
  257. package/template/skills/skillopt-sleep/scripts/framework/skillopt/prompts/slow_update.md +0 -60
  258. package/template/skills/skillopt-sleep/scripts/framework/skillopt/scheduler/__init__.py +0 -8
  259. package/template/skills/skillopt-sleep/scripts/framework/skillopt/types.py +0 -306
  260. package/template/skills/skillopt-sleep/scripts/framework/skillopt/utils/__init__.py +0 -4
  261. package/template/skills/skillopt-sleep/scripts/framework/skillopt/utils/json_utils.py +0 -172
  262. package/template/skills/skillopt-sleep/scripts/framework/skillopt/utils/scoring.py +0 -28
  263. package/template/skills/skillopt-sleep/scripts/python/__init__.py +0 -20
  264. package/template/skills/skillopt-sleep/scripts/python/__main__.py +0 -343
  265. package/template/skills/skillopt-sleep/scripts/python/backend.py +0 -1371
  266. package/template/skills/skillopt-sleep/scripts/python/budget.py +0 -75
  267. package/template/skills/skillopt-sleep/scripts/python/config.py +0 -162
  268. package/template/skills/skillopt-sleep/scripts/python/consolidate.py +0 -238
  269. package/template/skills/skillopt-sleep/scripts/python/cycle.py +0 -291
  270. package/template/skills/skillopt-sleep/scripts/python/dream.py +0 -138
  271. package/template/skills/skillopt-sleep/scripts/python/experiments/__init__.py +0 -1
  272. package/template/skills/skillopt-sleep/scripts/python/experiments/gbrain_bench.py +0 -119
  273. package/template/skills/skillopt-sleep/scripts/python/experiments/personas.py +0 -86
  274. package/template/skills/skillopt-sleep/scripts/python/experiments/report.py +0 -132
  275. package/template/skills/skillopt-sleep/scripts/python/experiments/run_experiment.py +0 -178
  276. package/template/skills/skillopt-sleep/scripts/python/experiments/run_gbrain.py +0 -209
  277. package/template/skills/skillopt-sleep/scripts/python/experiments/run_transfer.py +0 -155
  278. package/template/skills/skillopt-sleep/scripts/python/experiments/sweep.py +0 -164
  279. package/template/skills/skillopt-sleep/scripts/python/gate.py +0 -50
  280. package/template/skills/skillopt-sleep/scripts/python/harvest.py +0 -304
  281. package/template/skills/skillopt-sleep/scripts/python/harvest_codex.py +0 -253
  282. package/template/skills/skillopt-sleep/scripts/python/harvest_sources.py +0 -41
  283. package/template/skills/skillopt-sleep/scripts/python/judges.py +0 -84
  284. package/template/skills/skillopt-sleep/scripts/python/llm_miner.py +0 -134
  285. package/template/skills/skillopt-sleep/scripts/python/memory.py +0 -129
  286. package/template/skills/skillopt-sleep/scripts/python/mine.py +0 -312
  287. package/template/skills/skillopt-sleep/scripts/python/replay.py +0 -146
  288. package/template/skills/skillopt-sleep/scripts/python/rollout.py +0 -153
  289. package/template/skills/skillopt-sleep/scripts/python/scheduler.py +0 -138
  290. package/template/skills/skillopt-sleep/scripts/python/slow_update.py +0 -142
  291. package/template/skills/skillopt-sleep/scripts/python/staging.py +0 -103
  292. package/template/skills/skillopt-sleep/scripts/python/state.py +0 -96
  293. package/template/skills/skillopt-sleep/scripts/python/tasks_file.py +0 -81
  294. package/template/skills/skillopt-sleep/scripts/python/types.py +0 -146
  295. package/template/skills/skillopt-sleep/scripts/shell/__init__.py +0 -0
  296. package/template/skills/skillopt-sleep/scripts/shell/eval_only.py +0 -466
  297. package/template/skills/skillopt-sleep/scripts/shell/materialize_searchqa.py +0 -148
  298. package/template/skills/skillopt-sleep/scripts/shell/run_alfworld.sh +0 -60
  299. package/template/skills/skillopt-sleep/scripts/shell/run_searchqa.sh +0 -40
  300. package/template/skills/skillopt-sleep/scripts/shell/run_spreadsheetbench.sh +0 -39
  301. package/template/skills/skillopt-sleep/scripts/shell/train.py +0 -556
@@ -1,312 +0,0 @@
1
- """SkillOpt-Sleep — Stage 2: mine.
2
-
3
- Turn :class:`SessionDigest` objects into :class:`TaskRecord` training units.
4
-
5
- Two miners:
6
- * heuristic_mine — deterministic, no API. Detects retry chains (a prompt
7
- re-asked after negative feedback => the early attempt failed), extracts
8
- the user's recurring intents, and labels outcomes from feedback signals.
9
- * llm_mine — optional; uses an optimizer backend to produce richer
10
- TaskRecords with checkable references. Falls back to heuristic on error.
11
-
12
- The heuristic miner is what makes the whole cycle runnable offline and is the
13
- basis of the deterministic experiment.
14
- """
15
- from __future__ import annotations
16
-
17
- import hashlib
18
- import os
19
- import re
20
- from collections import Counter
21
- from typing import Any, Callable, List, Optional, Set, Tuple
22
-
23
- from skillopt_sleep.types import SessionDigest, TaskRecord
24
-
25
-
26
- def _tid(project: str, intent: str) -> str:
27
- h = hashlib.sha256((project + "::" + intent).encode("utf-8")).hexdigest()[:12]
28
- return "task_" + h
29
-
30
-
31
- def _short(text: str, n: int = 600) -> str:
32
- text = (text or "").strip()
33
- return text if len(text) <= n else text[:n] + " …"
34
-
35
-
36
- def _looks_negative(signals: List[str]) -> bool:
37
- return any(s.startswith("neg:") for s in signals)
38
-
39
-
40
- def _looks_positive(signals: List[str]) -> bool:
41
- return any(s.startswith("pos:") for s in signals)
42
-
43
-
44
- _TARGET_STOPWORDS = {
45
- "about", "after", "again", "agent", "agents", "all", "also", "always",
46
- "and", "any", "are", "before", "being", "but", "can", "codex",
47
- "current", "default", "docs", "does", "done", "each", "file", "files",
48
- "for", "from", "have", "into", "keep", "must", "not", "only", "path",
49
- "paths", "project", "read", "repo", "request", "requests", "rule",
50
- "rules", "same", "should", "skill", "skills", "source", "start",
51
- "task", "tasks", "that", "the", "their", "then", "this", "unless",
52
- "update", "user", "users", "when", "with", "work", "workflow",
53
- }
54
-
55
-
56
- def _target_tokens(text: str) -> List[str]:
57
- tokens: List[str] = []
58
- for raw in re.findall(r"[\w][\w.-]*", (text or "").lower(), flags=re.UNICODE):
59
- parts = [raw] + re.split(r"[\W_]+", raw, flags=re.UNICODE)
60
- for part in parts:
61
- if len(part) < 3 or part.isdigit() or part in _TARGET_STOPWORDS:
62
- continue
63
- tokens.append(part)
64
- return tokens
65
-
66
-
67
- def _expand_target_keywords(keywords: Set[str]) -> None:
68
- if "mcp" in keywords:
69
- keywords.update({
70
- "configure", "configuration", "connect", "connected", "enable",
71
- "enabled", "install", "installed", "server", "servers",
72
- "настрой", "настроить", "подключи", "подключить",
73
- })
74
- if {"conflict", "conflicts"} & keywords:
75
- keywords.update({
76
- "cherry", "conflict", "conflicts", "git", "merge", "rebase",
77
- "unmerged", "конфликт", "конфликты",
78
- })
79
-
80
-
81
- def target_task_keywords(
82
- target_skill_text: str,
83
- target_skill_path: str = "",
84
- *,
85
- limit: int = 180,
86
- ) -> Tuple[Set[str], Set[str]]:
87
- """Return (strong, weak) keywords that describe a target skill."""
88
- path_text = (target_skill_path or "").replace(os.sep, " ")
89
- headings = "\n".join(re.findall(r"(?m)^#+\s+(.+)$", target_skill_text or ""))
90
- strong = set(_target_tokens(path_text + "\n" + headings))
91
- weak = set(strong)
92
- counts = Counter(_target_tokens(target_skill_text or ""))
93
- for token, _count in counts.most_common(limit):
94
- weak.add(token)
95
- _expand_target_keywords(strong)
96
- _expand_target_keywords(weak)
97
- return strong, weak
98
-
99
-
100
- def _task_search_text(task: TaskRecord) -> str:
101
- return "\n".join([
102
- task.intent or "",
103
- task.context_excerpt or "",
104
- " ".join(task.tags or []),
105
- ])
106
-
107
-
108
- def filter_tasks_for_target(
109
- tasks: List[TaskRecord],
110
- target_skill_text: str,
111
- target_skill_path: str = "",
112
- ) -> List[TaskRecord]:
113
- """Prefer tasks whose language overlaps the explicit target skill.
114
-
115
- If nothing matches, return the original list. This keeps a target run useful
116
- even when transcripts are too sparse or the skill is too generic.
117
- """
118
- strong, weak = target_task_keywords(target_skill_text, target_skill_path)
119
- if not tasks or not (strong or weak):
120
- return tasks
121
-
122
- ranked = []
123
- for idx, task in enumerate(tasks):
124
- tokens = set(_target_tokens(_task_search_text(task)))
125
- strong_hits = tokens & strong
126
- weak_hits = tokens & weak
127
- if not strong_hits and len(weak_hits) < 2:
128
- continue
129
- score = len(strong_hits) * 3 + len(weak_hits)
130
- ranked.append((score, idx, task))
131
- if not ranked:
132
- return tasks
133
- ranked.sort(key=lambda item: (-item[0], item[1]))
134
- return [task for _score, _idx, task in ranked]
135
-
136
-
137
- def heuristic_mine(
138
- digests: List[SessionDigest],
139
- *,
140
- max_tasks: int = 40,
141
- ) -> List[TaskRecord]:
142
- """Deterministic miner — no API calls.
143
-
144
- Strategy:
145
- * Each session with >=1 real user prompt yields one TaskRecord whose
146
- intent is the FIRST substantive prompt (the original ask).
147
- * Outcome is inferred:
148
- - negative feedback present and no later positive -> "fail"
149
- - positive feedback present -> "success"
150
- - re-asks (multiple user turns) without resolution -> "mixed"
151
- - otherwise -> "unknown"
152
- * attempted_solution = the last assistant final (what was produced).
153
- * reference_kind defaults to "none"; the consolidation step will use a
154
- rubric judge for these. (Exact refs are added by the experiment data
155
- or by the LLM miner when it can derive a checkable answer.)
156
- """
157
- tasks: List[TaskRecord] = []
158
- for d in digests:
159
- if not d.user_prompts:
160
- continue
161
- intent = d.user_prompts[0]
162
- if len(intent.strip()) < 8:
163
- continue
164
- if _looks_positive(d.feedback_signals) and not _looks_negative(d.feedback_signals):
165
- outcome = "success"
166
- elif _looks_negative(d.feedback_signals):
167
- outcome = "fail"
168
- elif d.n_user_turns >= 3:
169
- outcome = "mixed"
170
- else:
171
- outcome = "unknown"
172
-
173
- attempted = d.assistant_finals[-1] if d.assistant_finals else ""
174
- context = ""
175
- if len(d.user_prompts) > 1:
176
- # later prompts often carry the corrective detail / real constraints
177
- context = "Follow-up constraints from the same session:\n- " + "\n- ".join(
178
- _short(p, 200) for p in d.user_prompts[1:4]
179
- )
180
- tags = []
181
- if d.tools_used:
182
- tags.append("tools:" + "+".join(d.tools_used[:4]))
183
- if d.git_branch:
184
- tags.append("branch:" + d.git_branch)
185
-
186
- tasks.append(
187
- TaskRecord(
188
- id=_tid(d.project, intent),
189
- project=d.project,
190
- intent=_short(intent, 800),
191
- context_excerpt=_short(context, 600),
192
- attempted_solution=_short(attempted, 600),
193
- outcome=outcome,
194
- reference_kind="none",
195
- reference="",
196
- tags=tags,
197
- source_sessions=[d.session_id],
198
- )
199
- )
200
- if len(tasks) >= max_tasks:
201
- break
202
- return tasks
203
-
204
-
205
- def dedup_tasks(tasks: List[TaskRecord]) -> List[TaskRecord]:
206
- """Merge tasks sharing an id (same project+intent across sessions)."""
207
- by_id: dict = {}
208
- for t in tasks:
209
- if t.id in by_id:
210
- ex = by_id[t.id]
211
- ex.source_sessions = list(dict.fromkeys(ex.source_sessions + t.source_sessions))
212
- # prefer a resolved outcome if either session resolved it
213
- order = {"success": 3, "fail": 2, "mixed": 1, "unknown": 0}
214
- if order.get(t.outcome, 0) > order.get(ex.outcome, 0):
215
- ex.outcome = t.outcome
216
- else:
217
- by_id[t.id] = t
218
- return list(by_id.values())
219
-
220
-
221
- def assign_splits(
222
- tasks: List[TaskRecord],
223
- *,
224
- val_fraction: float = 0.34,
225
- test_fraction: float = 0.0,
226
- holdout_fraction: float | None = None, # legacy alias for val_fraction
227
- seed: int = 42,
228
- ) -> List[TaskRecord]:
229
- """Deterministically split tasks into train / val / test.
230
-
231
- Anti-overfitting contract (the user's design):
232
- * ``val`` and ``test`` are drawn ONLY from REAL mined tasks (origin=='real')
233
- and never overlap. val gates updates; test is the final held-out measure.
234
- * ``train`` may include DREAM-augmented tasks (origin=='dream'); those are
235
- NEVER placed in val/test.
236
-
237
- A stable hash of the task id keeps the same real task in the same split across
238
- nights (a fixed held-out gate, like SkillOpt's D_sel/D_test).
239
-
240
- Back-compat: if ``test_fraction`` is 0 (default), this behaves like the old
241
- two-way replay/holdout split — real tasks divide into train + val, no test.
242
- ``holdout_fraction`` is accepted as an alias for ``val_fraction``.
243
- """
244
- if holdout_fraction is not None:
245
- val_fraction = holdout_fraction
246
-
247
- dream = [t for t in tasks if t.origin == "dream"]
248
- real = [t for t in tasks if t.origin != "dream"]
249
-
250
- # all dream tasks go to train, unconditionally
251
- for t in dream:
252
- t.split = "train"
253
-
254
- val_cut = int(round(val_fraction * 100))
255
- test_cut = val_cut + int(round(test_fraction * 100))
256
- for t in real:
257
- bucket = int(hashlib.sha256((str(seed) + t.id).encode()).hexdigest(), 16) % 100
258
- if bucket < val_cut:
259
- t.split = "val"
260
- elif bucket < test_cut:
261
- t.split = "test"
262
- else:
263
- t.split = "train"
264
-
265
- # guarantee val (the gate) is non-empty when we have >=2 real tasks
266
- real_splits = {t.split for t in real}
267
- if len(real) >= 2 and "val" not in real_splits:
268
- real[-1].split = "val"
269
- # guarantee a train pool exists (dream or real) when possible
270
- if not any(t.split == "train" for t in tasks) and len(real) >= 2:
271
- real[0].split = "train"
272
- # if test was requested but ended up empty with >=3 real tasks, carve one
273
- if test_fraction > 0 and len(real) >= 3 and not any(t.split == "test" for t in real):
274
- for t in real:
275
- if t.split == "train":
276
- t.split = "test"
277
- break
278
- return tasks
279
-
280
-
281
- def normalize_legacy_split(value: str) -> str:
282
- """Map old split names to the new vocabulary."""
283
- return {"replay": "train", "holdout": "val"}.get(value, value)
284
-
285
-
286
- def mine(
287
- digests: List[SessionDigest],
288
- *,
289
- max_tasks: int = 40,
290
- candidate_limit: int = 0,
291
- holdout_fraction: float = 0.34,
292
- seed: int = 42,
293
- llm_miner: Optional[Callable[[List[SessionDigest]], List[TaskRecord]]] = None,
294
- target_skill_text: str = "",
295
- target_skill_path: str = "",
296
- ) -> List[TaskRecord]:
297
- """Top-level miner. Uses ``llm_miner`` if provided, else heuristic."""
298
- candidate_limit = candidate_limit or max_tasks
299
- tasks: List[TaskRecord] = []
300
- if llm_miner is not None:
301
- try:
302
- tasks = llm_miner(digests) or []
303
- except Exception:
304
- tasks = []
305
- if not tasks:
306
- tasks = heuristic_mine(digests, max_tasks=candidate_limit)
307
- tasks = dedup_tasks(tasks)
308
- if target_skill_text or target_skill_path:
309
- tasks = filter_tasks_for_target(tasks, target_skill_text, target_skill_path)
310
- tasks = tasks[:max_tasks]
311
- tasks = assign_splits(tasks, holdout_fraction=holdout_fraction, seed=seed)
312
- return tasks
@@ -1,146 +0,0 @@
1
- """SkillOpt-Sleep — Stage 3: replay.
2
-
3
- Re-run mined TaskRecords offline under a given (skill, memory) and score
4
- them, producing the (hard, soft) signal SkillOpt's gate consumes.
5
-
6
- Single-shot text replay by default. Tasks whose rule judge requires a tool
7
- call (gbrain's `tool_called`) are run through the backend's real tool loop
8
- (attempt_with_tools), so tool use is verified honestly rather than self-reported.
9
- """
10
- from __future__ import annotations
11
-
12
- from typing import List, Tuple
13
-
14
- from skillopt_sleep.backend import Backend
15
- from skillopt_sleep.types import ReplayResult, TaskRecord
16
-
17
-
18
- def _required_tools(task: TaskRecord) -> List[str]:
19
- """Tool names a rule judge requires (op == 'tool_called')."""
20
- if task.reference_kind != "rule" or not task.judge:
21
- return []
22
- tools = []
23
- for c in task.judge.get("checks", []) or []:
24
- if isinstance(c, dict) and c.get("op") == "tool_called" and c.get("arg"):
25
- tools.append(str(c["arg"]))
26
- return tools
27
-
28
-
29
- def replay_one(backend: Backend, task: TaskRecord, skill: str, memory: str,
30
- sample_id: int = 0) -> ReplayResult:
31
- """``sample_id`` distinguishes repeated dream rollouts of the same
32
- (task, skill, memory) in the attempt cache — without it all K rollouts
33
- collapse to one cached response and the contrastive signal is always 0."""
34
- import time
35
- tools = _required_tools(task)
36
- tools_called: List[str] = []
37
- t0 = time.time()
38
- tok_before = backend.tokens_used()
39
- if tools:
40
- response, tools_called = backend.attempt_with_tools(task, skill, memory, tools)
41
- else:
42
- response = backend.attempt(task, skill, memory, sample_id=sample_id)
43
- latency_ms = (time.time() - t0) * 1000.0
44
- tokens = max(0, backend.tokens_used() - tok_before)
45
- # if the backend doesn't track tokens (e.g. mock), approximate from text length
46
- if tokens == 0:
47
- tokens = (len(skill) + len(memory) + len(task.intent) + len(response)) // 4
48
-
49
- # rule judges may need the detected tool calls; score locally when possible
50
- if task.reference_kind == "rule" and task.judge:
51
- from skillopt_sleep.judges import score_rule_judge
52
- hard, soft, rationale = score_rule_judge(task.judge, response, tools_called)
53
- else:
54
- hard, soft, rationale = backend.judge(task, response)
55
-
56
- return ReplayResult(
57
- id=task.id,
58
- hard=float(hard),
59
- soft=float(soft),
60
- response=response,
61
- fail_reason="" if hard >= 1.0 else (rationale or "below threshold"),
62
- task_type=(task.tags[0] if task.tags else "task"),
63
- judge_rationale=rationale,
64
- tools_called=tools_called,
65
- tokens=int(tokens),
66
- latency_ms=round(latency_ms, 1),
67
- )
68
-
69
-
70
- import os
71
- from concurrent.futures import ThreadPoolExecutor
72
-
73
-
74
- def replay_batch(
75
- backend: Backend,
76
- tasks: List[TaskRecord],
77
- skill: str,
78
- memory: str,
79
- *,
80
- workers: int = 0,
81
- ) -> List[Tuple[TaskRecord, ReplayResult]]:
82
- """Replay tasks, optionally in parallel.
83
-
84
- Real backends are network-bound, so a thread pool gives a large speedup on
85
- big test sets (like the research harness's --workers). ``workers`` defaults
86
- to env SKILLOPT_SLEEP_WORKERS or 1 (sequential). Mock stays sequential
87
- (deterministic) unless asked otherwise.
88
- """
89
- if workers <= 0:
90
- workers = int(os.environ.get("SKILLOPT_SLEEP_WORKERS", "1") or "1")
91
- if workers <= 1 or len(tasks) <= 1:
92
- return [(t, replay_one(backend, t, skill, memory)) for t in tasks]
93
- results: List = [None] * len(tasks)
94
- with ThreadPoolExecutor(max_workers=min(workers, len(tasks))) as ex:
95
- futs = {ex.submit(replay_one, backend, t, skill, memory): i
96
- for i, t in enumerate(tasks)}
97
- for fut in futs:
98
- i = futs[fut]
99
- results[i] = (tasks[i], fut.result())
100
- return results
101
-
102
-
103
- def aggregate_scores(pairs: List[Tuple[TaskRecord, ReplayResult]]) -> Tuple[float, float]:
104
- if not pairs:
105
- return 0.0, 0.0
106
- hard = sum(r.hard for _t, r in pairs) / len(pairs)
107
- soft = sum(r.soft for _t, r in pairs) / len(pairs)
108
- return hard, soft
109
-
110
-
111
- def aggregate_cost(pairs: List[Tuple[TaskRecord, ReplayResult]]) -> Tuple[float, float]:
112
- """Mean (tokens, latency_ms) per task — the cost objectives."""
113
- if not pairs:
114
- return 0.0, 0.0
115
- tok = sum(r.tokens for _t, r in pairs) / len(pairs)
116
- lat = sum(r.latency_ms for _t, r in pairs) / len(pairs)
117
- return tok, lat
118
-
119
-
120
- def multi_objective_reward(
121
- pairs: List[Tuple[TaskRecord, ReplayResult]],
122
- *,
123
- w_acc: float = 1.0,
124
- w_tokens: float = 0.0,
125
- w_latency: float = 0.0,
126
- token_ref: float = 2000.0,
127
- latency_ref_ms: float = 15000.0,
128
- ) -> float:
129
- """Weighted reward = accuracy↑, tokens↓, latency↓.
130
-
131
- Cost terms are normalized against a reference and clamped to [0,1], so a
132
- response at/under the reference cost contributes ~1.0 and an expensive one
133
- less. Weights let the user trade off (default = accuracy only, backward
134
- compatible).
135
- """
136
- if not pairs:
137
- return 0.0
138
- acc, _soft = aggregate_scores(pairs)
139
- tok, lat = aggregate_cost(pairs)
140
- tok_score = max(0.0, 1.0 - tok / max(1.0, token_ref)) if token_ref else 0.0
141
- lat_score = max(0.0, 1.0 - lat / max(1.0, latency_ref_ms)) if latency_ref_ms else 0.0
142
- total_w = w_acc + w_tokens + w_latency
143
- if total_w <= 0:
144
- return acc
145
- return (w_acc * acc + w_tokens * tok_score + w_latency * lat_score) / total_w
146
-
@@ -1,153 +0,0 @@
1
- """SkillOpt-Sleep — multi-rollout + contrastive reflection (the imagination core).
2
-
3
- The core idea: let the agent re-run the SAME task many times, then look at
4
- which rollouts went well vs badly and distill a rule from the *contrast*. This
5
- is a much stronger learning signal than a single failure, and it is the essence
6
- of the offline "dream/imagination" process — train-time rollouts are synthetic,
7
- so doing many is fine.
8
-
9
- Pieces:
10
- * multi_rollout — run one task K times under (skill, memory), return scored attempts
11
- * contrastive_reflect — given good vs bad attempts of the same tasks, ask the
12
- optimizer what distinguishes them and propose a general rule
13
-
14
- Driven through the Backend abstraction (mock/claude/codex), import-light.
15
- """
16
- from __future__ import annotations
17
-
18
- from dataclasses import dataclass, field
19
- from typing import List, Optional, Tuple
20
-
21
- from skillopt_sleep.backend import Backend, _extract_json
22
- from skillopt_sleep.replay import replay_one
23
- from skillopt_sleep.types import EditRecord, ReplayResult, TaskRecord
24
-
25
-
26
- @dataclass
27
- class RolloutSet:
28
- """K scored attempts at one task under a fixed (skill, memory)."""
29
- task: TaskRecord
30
- attempts: List[ReplayResult] = field(default_factory=list)
31
-
32
- @property
33
- def best(self) -> Optional[ReplayResult]:
34
- return max(self.attempts, key=lambda r: r.hard, default=None)
35
-
36
- @property
37
- def worst(self) -> Optional[ReplayResult]:
38
- return min(self.attempts, key=lambda r: r.hard, default=None)
39
-
40
- @property
41
- def spread(self) -> float:
42
- if not self.attempts:
43
- return 0.0
44
- hs = [r.hard for r in self.attempts]
45
- return max(hs) - min(hs)
46
-
47
- @property
48
- def pass_rate(self) -> float:
49
- if not self.attempts:
50
- return 0.0
51
- return sum(1 for r in self.attempts if r.hard >= 1.0) / len(self.attempts)
52
-
53
-
54
- def multi_rollout(
55
- backend: Backend,
56
- task: TaskRecord,
57
- skill: str,
58
- memory: str,
59
- *,
60
- k: int = 3,
61
- workers: int = 0,
62
- ) -> RolloutSet:
63
- """Run ``task`` K times. replay_one is deterministic for mock; for real
64
- backends the model's own sampling yields variation across attempts.
65
-
66
- The K attempts are independent, so they run concurrently (this is the dream
67
- phase's dominant cost). ``workers`` defaults to the SKILLOPT_SLEEP_WORKERS
68
- env (capped at k); set to 1 to force serial (used by the mock tests).
69
- """
70
- import os
71
- rs = RolloutSet(task=task)
72
- k = max(1, k)
73
- if workers <= 0:
74
- try:
75
- workers = int(os.environ.get("SKILLOPT_SLEEP_WORKERS", "1"))
76
- except ValueError:
77
- workers = 1
78
- workers = max(1, min(workers, k))
79
- if workers == 1:
80
- for i in range(k):
81
- rs.attempts.append(replay_one(backend, task, skill, memory, sample_id=i))
82
- return rs
83
- from concurrent.futures import ThreadPoolExecutor
84
- with ThreadPoolExecutor(max_workers=workers) as ex:
85
- futs = [ex.submit(replay_one, backend, task, skill, memory, sample_id=i)
86
- for i in range(k)]
87
- for f in futs:
88
- rs.attempts.append(f.result())
89
- return rs
90
-
91
-
92
- def contrastive_reflect(
93
- backend: Backend,
94
- rollout_sets: List[RolloutSet],
95
- skill: str,
96
- memory: str,
97
- *,
98
- edit_budget: int = 4,
99
- target: str = "skill",
100
- ) -> List[EditRecord]:
101
- """Distill a rule from the contrast between good and bad attempts.
102
-
103
- We pick tasks with the highest score *spread* (some attempts passed, some
104
- failed) — those are the most informative — and show the optimizer a
105
- high-scoring vs a low-scoring attempt of each, asking what general rule makes
106
- the good behavior reliable.
107
- """
108
- informative = [rs for rs in rollout_sets if rs.spread > 0 and rs.best and rs.worst]
109
- informative.sort(key=lambda rs: rs.spread, reverse=True)
110
- informative = informative[:6]
111
- if not informative:
112
- return []
113
-
114
- blocks = []
115
- for rs in informative:
116
- blocks.append(
117
- f"## Task: {rs.task.intent[:160]}\n"
118
- f"- GOOD attempt (score {rs.best.hard:.1f}): {rs.best.response[:200]}\n"
119
- f"- BAD attempt (score {rs.worst.hard:.1f}): {rs.worst.response[:200]}\n"
120
- f" (bad failed: {rs.worst.fail_reason[:100]})"
121
- )
122
- # the output contract the proposed rules must not violate (same guardrail the
123
- # single-shot reflect uses — prevents harness-violating rules like "return VBA"
124
- # or "ask the user for the range" on SpreadsheetBench).
125
- from skillopt_sleep.backend import _task_guardrail
126
- guard = _task_guardrail([(rs.task, rs.best) for rs in informative])
127
- prompt = (
128
- "You are SkillOpt's optimizer doing CONTRASTIVE reflection. For each task "
129
- "below the agent was run multiple times; some attempts succeeded and some "
130
- "failed. Identify what the GOOD attempts did that the BAD ones did not, "
131
- f"and propose at most {edit_budget} SHORT, GENERAL, reusable rules for the "
132
- f"{target} that would make the good behavior reliable every time. Quote "
133
- "concrete thresholds/formats verbatim; do not paraphrase vaguely. "
134
- "Every rule MUST obey the task output contract (if shown) — never propose "
135
- "a rule that changes the required output format/language or tells the agent "
136
- "to ask the user a question; such a rule scores ZERO.\n"
137
- f"{guard}"
138
- 'Return ONLY a JSON array: '
139
- '[{"op":"add","content":"<rule>","rationale":"<what good did that bad didnt>"}].\n\n'
140
- + "\n\n".join(blocks)
141
- )
142
- raw = backend._call(prompt, max_tokens=1024) # type: ignore[attr-defined]
143
- arr = _extract_json(raw, "array")
144
- edits: List[EditRecord] = []
145
- if isinstance(arr, list):
146
- for e in arr[:edit_budget]:
147
- if isinstance(e, dict) and str(e.get("content", "")).strip():
148
- edits.append(EditRecord(
149
- target=target, op=str(e.get("op", "add")).strip().lower(),
150
- content=str(e["content"]).strip(),
151
- rationale=str(e.get("rationale", "")).strip(),
152
- ))
153
- return edits