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,979 +0,0 @@
1
- """SpreadsheetBench rollout — codegen & ReAct batch execution.
2
-
3
- Provides:
4
- - process_one_codegen(): single/multi-round code generation (no tool-call)
5
- - run_spreadsheet_batch_codegen(): batch wrapper for codegen
6
- - process_one(): ReAct agent with tool-call (legacy)
7
- - run_spreadsheet_batch(): batch wrapper for ReAct (legacy)
8
- - load_items(): load benchmark .json/.jsonl files
9
- """
10
- from __future__ import annotations
11
-
12
- import glob as _glob
13
- import json
14
- import os
15
- import shutil
16
- import tempfile
17
- import time
18
- import traceback
19
- from concurrent.futures import (
20
- FIRST_COMPLETED,
21
- ThreadPoolExecutor,
22
- wait,
23
- TimeoutError as FuturesTimeoutError,
24
- )
25
-
26
- import openpyxl
27
-
28
- from skillopt.envs.spreadsheetbench.react_agent import run_react
29
- from skillopt.envs.spreadsheetbench.evaluator import (
30
- evaluate, _generate_cell_names, _compare_cell_value,
31
- )
32
- from skillopt.envs.spreadsheetbench.executor import run_generated_code
33
-
34
-
35
- # ── Data loading ─────────────────────────────────────────────────────────────
36
-
37
-
38
- def load_items(path: str) -> list[dict]:
39
- """Load a benchmark file. Supports both .jsonl and .json (list of dicts)."""
40
- if path.endswith(".json"):
41
- with open(path) as f:
42
- data = json.load(f)
43
- if isinstance(data, dict):
44
- data = data.get("data") or list(data.values())
45
- return list(data)
46
- items = []
47
- with open(path) as f:
48
- for line in f:
49
- line = line.strip()
50
- if line:
51
- items.append(json.loads(line))
52
- return items
53
-
54
-
55
- # ── Test case discovery ──────────────────────────────────────────────────────
56
-
57
-
58
- def _find_test_cases(task_dir: str) -> list[tuple[str, str, str]]:
59
- """Return [(case_no, input_path, answer_path), ...] sorted by case_no.
60
-
61
- Supports naming conventions used by SpreadsheetBench releases:
62
- * ``{no}_{id}_input.xlsx`` + ``{no}_{id}_answer.xlsx`` (original)
63
- * ``{no}_{id}_init.xlsx`` + ``{no}_{id}_golden.xlsx`` (verified_400)
64
- * ``initial.xlsx`` + ``golden.xlsx`` (verified_400, no prefix)
65
- """
66
- cases: list[tuple[str, str, str]] = []
67
- inputs = sorted(_glob.glob(os.path.join(task_dir, "*_input.xlsx")))
68
- for ip in inputs:
69
- no = os.path.basename(ip).split("_", 1)[0]
70
- ap = ip.replace("_input.xlsx", "_answer.xlsx")
71
- if os.path.exists(ap):
72
- cases.append((no, ip, ap))
73
- inits = sorted(_glob.glob(os.path.join(task_dir, "*_init.xlsx")))
74
- for ip in inits:
75
- no = os.path.basename(ip).split("_", 1)[0]
76
- ap = ip.replace("_init.xlsx", "_golden.xlsx")
77
- if os.path.exists(ap):
78
- cases.append((no, ip, ap))
79
-
80
- # Fallback: bare initial.xlsx + golden.xlsx (no numbered prefix)
81
- if not cases:
82
- bare_init = os.path.join(task_dir, "initial.xlsx")
83
- bare_gold = os.path.join(task_dir, "golden.xlsx")
84
- if os.path.exists(bare_init) and os.path.exists(bare_gold):
85
- cases.append(("1", bare_init, bare_gold))
86
-
87
- return cases
88
-
89
-
90
- # ── Auto-verify helper ──────────────────────────────────────────────────────
91
-
92
- # The official SpreadsheetBench evaluator never serialises cells to text — it
93
- # compares in memory and returns only a pass/fail bool. The per-cell report
94
- # below is a repo-local training aid (fed back to the model on retry and saved
95
- # into the trajectory for reflection). On most tasks the answer range is a
96
- # handful of cells, so the full report is tiny. But a few tasks have answer
97
- # ranges spanning tens of thousands of cells (e.g. 80-42 =
98
- # 'Consolidate_ALL'!A2:L8000 ≈ 96k cells); dumping every cell explodes the
99
- # report to several MB, floods the model's context and bloats conversation
100
- # files. We therefore apply the same head+tail character truncation the rest of
101
- # the codebase uses for oversized trajectory text (cf. reflect.py / slow_update.py
102
- # `text[:half] + "...[truncated]...\n" + text[-half:]`): keep the first and last
103
- # `_MAX_REPORT_CHARS // 2` chars so both the leading and trailing wrong cells
104
- # stay visible. Small reports are unchanged.
105
- _MAX_REPORT_CHARS = 12000 # head+tail char budget (~6000 head + 6000 tail)
106
-
107
-
108
- def _auto_verify_output(
109
- pred_path: str,
110
- gold_path: str,
111
- answer_position: str,
112
- ) -> str:
113
- """Reopen the predicted xlsx and compare cells at answer_position with gold.
114
-
115
- Returns a human-readable verification report that can be appended to the
116
- trajectory so the error analyst can see exactly what went wrong (e.g.
117
- ``cell A1: got=None, expected=420``). Oversized reports are head+tail
118
- truncated to `_MAX_REPORT_CHARS` chars, matching the rest of the codebase.
119
- """
120
- if not os.path.exists(pred_path):
121
- return "Verification: output file does not exist."
122
- try:
123
- wb_pred = openpyxl.load_workbook(pred_path, data_only=True)
124
- wb_gold = openpyxl.load_workbook(gold_path, data_only=True)
125
- except Exception as e:
126
- return f"Verification: could not open workbooks: {e}"
127
-
128
- lines = ["## Output Verification"]
129
- try:
130
- for scr in (answer_position or "").split(","):
131
- scr = scr.strip()
132
- if not scr:
133
- continue
134
- if "!" in scr:
135
- sheet_name, cell_range = scr.split("!", 1)
136
- sheet_name = sheet_name.strip().strip("'\"")
137
- else:
138
- sheet_name = wb_gold.sheetnames[0]
139
- cell_range = scr
140
- cell_range = cell_range.strip().strip("'\"")
141
-
142
- cell_names = _generate_cell_names(cell_range)
143
- ws_pred = wb_pred[sheet_name] if sheet_name in wb_pred.sheetnames else None
144
- ws_gold = wb_gold[sheet_name] if sheet_name in wb_gold.sheetnames else None
145
-
146
- if ws_pred is None:
147
- lines.append(f" Sheet '{sheet_name}' NOT FOUND in output.")
148
- continue
149
-
150
- n_empty_correct = 0 # empty-on-both correct cells collapsed to a count
151
- for cn in cell_names:
152
- gv = ws_gold[cn].value if ws_gold else "N/A"
153
- pv = ws_pred[cn].value
154
- # Use the official cell comparator so this report's ✓/✗ agrees
155
- # with the real scorer (evaluate). repr() equality would wrongly
156
- # flag e.g. 5 vs 5.0 or None vs "" as mismatches and mislead the
157
- # model into "fixing" cells that already pass scoring.
158
- ok_cell = ws_gold is not None and _compare_cell_value(gv, pv)
159
- # Collapse only cells that are correct AND empty on both sides
160
- # (got=None, expected=None ✓): pure noise. Every other cell —
161
- # including non-empty correct cells — is listed in full; the
162
- # final head+tail char cap keeps the report bounded.
163
- if ok_cell and gv in (None, "") and pv in (None, ""):
164
- n_empty_correct += 1
165
- continue
166
- match = "✓" if ok_cell else "✗"
167
- lines.append(f" {sheet_name}!{cn}: got={pv!r}, expected={gv!r} {match}")
168
- if n_empty_correct:
169
- lines.append(
170
- f" (+{n_empty_correct} empty cells correct, omitted)"
171
- )
172
-
173
- # Also check if any cells in the output contain formula strings
174
- formula_cells = []
175
- for sn in wb_pred.sheetnames:
176
- ws = wb_pred[sn]
177
- for row in ws.iter_rows(max_row=min(ws.max_row, 200), values_only=False):
178
- for cell in row:
179
- if isinstance(cell.value, str) and cell.value.startswith("="):
180
- formula_cells.append(f"{sn}!{cell.coordinate}={cell.value}")
181
- if len(formula_cells) >= 10:
182
- break
183
- if len(formula_cells) >= 10:
184
- break
185
- if len(formula_cells) >= 10:
186
- break
187
- if formula_cells:
188
- lines.append(f"\n WARNING: {len(formula_cells)} cells contain Excel formulas (openpyxl cannot evaluate them):")
189
- for fc in formula_cells[:5]:
190
- lines.append(f" {fc}")
191
- if len(formula_cells) > 5:
192
- lines.append(f" ... and {len(formula_cells) - 5} more")
193
- finally:
194
- wb_pred.close()
195
- wb_gold.close()
196
-
197
- report = "\n".join(lines)
198
- # Head+tail truncation, matching reflect.py / slow_update.py: keep the first
199
- # and last half so both leading and trailing wrong cells remain visible.
200
- if len(report) > _MAX_REPORT_CHARS:
201
- half = _MAX_REPORT_CHARS // 2
202
- report = (
203
- report[:half]
204
- + f"\n ...[verification report truncated, {len(report)} chars total]...\n"
205
- + report[-half:]
206
- )
207
- return report
208
-
209
-
210
- # ── Per-task worker ──────────────────────────────────────────────────────────
211
-
212
-
213
- def process_one(
214
- item: dict,
215
- data_root: str,
216
- out_root: str,
217
- skill_content: str,
218
- max_turns: int,
219
- diagnostic_mode: bool = False,
220
- diagnostic_instruction: str = "",
221
- diagnostic_trace_context: str = "",
222
- max_completion_tokens: int = 16384,
223
- ) -> dict:
224
- """Run the ReAct agent on a single SpreadsheetBench task.
225
-
226
- Returns a result dict compatible with ``compute_score()``.
227
- """
228
- task_id = str(item["id"])
229
- instruction = item["instruction"]
230
- instruction_type = item.get("instruction_type", "")
231
- answer_position = item.get("answer_position", "")
232
- answer_sheet = item.get("answer_sheet", "")
233
- if answer_position and answer_sheet and "!" not in answer_position:
234
- answer_position_eval = f"{answer_sheet}!{answer_position}"
235
- else:
236
- answer_position_eval = answer_position
237
-
238
- # Determine task_type from instruction_type
239
- itype_lower = (instruction_type or "").lower()
240
- if "cell" in itype_lower:
241
- task_type = "cell_level"
242
- elif "sheet" in itype_lower:
243
- task_type = "sheet_level"
244
- else:
245
- task_type = "other"
246
-
247
- sp = item.get("spreadsheet_path", f"spreadsheet/{task_id}")
248
- task_dir = sp if os.path.isabs(sp) else os.path.join(data_root, sp)
249
-
250
- result = {
251
- "id": task_id,
252
- "ok": False,
253
- "instruction_type": instruction_type,
254
- "task_type": task_type,
255
- "task_description": instruction,
256
- "phase": "setup",
257
- "fail_reason": "",
258
- "agent_ok": False,
259
- "exec_ok": False,
260
- "n_cases": 0,
261
- "n_exec_pass": 0,
262
- "n_pass": 0,
263
- "soft": 0.0,
264
- "hard": 0,
265
- "n_turns": 0,
266
- "cases": [],
267
- "error": "",
268
- }
269
-
270
- try:
271
- cases = _find_test_cases(task_dir)
272
- result["n_cases"] = len(cases)
273
- if not cases:
274
- result["fail_reason"] = "no-test-cases"
275
- return result
276
-
277
- task_out_dir = os.path.join(out_root, "predictions", task_id)
278
- os.makedirs(task_out_dir, exist_ok=True)
279
-
280
- no1, ip1, _ = cases[0]
281
- pred_path_1 = os.path.join(task_out_dir, f"{no1}_pred.xlsx")
282
- target_prompt_parts = [
283
- f"# Instruction\n{instruction}",
284
- f"# Input file\n{ip1}",
285
- f"# Output file\n{pred_path_1}",
286
- ]
287
- if instruction_type:
288
- target_prompt_parts.append(f"# Instruction type\n{instruction_type}")
289
- if answer_position_eval:
290
- target_prompt_parts.append(f"# Answer position\n{answer_position_eval}")
291
- if diagnostic_trace_context.strip():
292
- target_prompt_parts.insert(
293
- 0,
294
- "# Previous Codex Trace Snapshot\n"
295
- "This is a partial transcript from an earlier attempt. Use it as your current reasoning context.\n\n"
296
- f"{diagnostic_trace_context.strip()}",
297
- )
298
- if diagnostic_mode and diagnostic_instruction.strip():
299
- target_prompt_parts.append(f"# Training readout\n{diagnostic_instruction.strip()}")
300
- target_user_prompt = "\n\n".join(target_prompt_parts)
301
- try:
302
- from skillopt.envs.spreadsheetbench.react_agent import _build_system
303
- target_system_prompt = _build_system(skill_content)
304
- except Exception:
305
- target_system_prompt = ""
306
- if target_system_prompt:
307
- with open(os.path.join(task_out_dir, "target_system_prompt.txt"), "w") as f:
308
- f.write(target_system_prompt)
309
- result["target_system_prompt"] = target_system_prompt
310
- with open(os.path.join(task_out_dir, "target_user_prompt.txt"), "w") as f:
311
- f.write(target_user_prompt)
312
- result["target_user_prompt"] = target_user_prompt
313
-
314
- # ── Stage 1: run ReAct agent on test case 1 ─────────────────────
315
- result["phase"] = "agent"
316
-
317
- work_dir = tempfile.mkdtemp(prefix=f"react_{task_id}_")
318
- try:
319
- # Copy input so agent works in an isolated directory
320
- work_input = os.path.join(work_dir, os.path.basename(ip1))
321
- shutil.copy2(ip1, work_input)
322
-
323
- agent_result = run_react(
324
- instruction=instruction,
325
- input_path=work_input,
326
- output_path=pred_path_1,
327
- work_dir=work_dir,
328
- instruction_type=instruction_type,
329
- answer_position=answer_position_eval,
330
- skill_content=skill_content,
331
- max_turns=max_turns,
332
- max_output_tokens=max_completion_tokens,
333
- diagnostic_mode=diagnostic_mode,
334
- diagnostic_instruction=diagnostic_instruction,
335
- diagnostic_trace_context=diagnostic_trace_context,
336
- )
337
- result["n_turns"] = agent_result.get("n_turns", 0)
338
- if agent_result.get("target_system_prompt"):
339
- with open(os.path.join(task_out_dir, "target_system_prompt.txt"), "w") as f:
340
- f.write(agent_result["target_system_prompt"])
341
- result["target_system_prompt"] = agent_result["target_system_prompt"]
342
- if agent_result.get("target_user_prompt"):
343
- with open(os.path.join(task_out_dir, "target_user_prompt.txt"), "w") as f:
344
- f.write(agent_result["target_user_prompt"])
345
- result["target_user_prompt"] = agent_result["target_user_prompt"]
346
-
347
- # Save conversation log
348
- with open(os.path.join(task_out_dir, "conversation.json"), "w") as f:
349
- json.dump(
350
- agent_result.get("conversation", []),
351
- f, ensure_ascii=False, indent=2,
352
- )
353
-
354
- # Copy solution.py if the agent wrote one
355
- solution_src = os.path.join(work_dir, "solution.py")
356
- solution_dst = os.path.join(task_out_dir, "solution.py")
357
- if os.path.exists(solution_src):
358
- shutil.copy2(solution_src, solution_dst)
359
-
360
- except Exception as e:
361
- result["fail_reason"] = f"agent-error: {type(e).__name__}: {e}"
362
- result["error"] = traceback.format_exc()
363
- return result
364
- finally:
365
- shutil.rmtree(work_dir, ignore_errors=True)
366
-
367
- result["agent_ok"] = True
368
-
369
- # ── Stage 2: evaluate all test cases ─────────────────────────────
370
- result["phase"] = "eval"
371
- solution_path = os.path.join(task_out_dir, "solution.py")
372
- all_exec = True
373
-
374
- for i, (no, ip, ap) in enumerate(cases):
375
- pred_path = os.path.join(task_out_dir, f"{no}_pred.xlsx")
376
-
377
- if i > 0:
378
- # Re-apply solution.py to subsequent test cases
379
- if not os.path.exists(solution_path):
380
- all_exec = False
381
- result["cases"].append(
382
- {"no": no, "stage": "exec", "ok": False, "error": "no-solution-py"}
383
- )
384
- if not result["fail_reason"]:
385
- result["fail_reason"] = "no-solution-py-for-other-cases"
386
- continue
387
-
388
- with open(solution_path) as f:
389
- code = f.read()
390
-
391
- # Prepend new INPUT_PATH / OUTPUT_PATH
392
- preamble = (
393
- f"INPUT_PATH = {ip!r}\n"
394
- f"OUTPUT_PATH = {pred_path!r}\n"
395
- )
396
- full_code = preamble + code
397
-
398
- ok_exec, err = run_generated_code(full_code, ip, pred_path)
399
- if not ok_exec:
400
- all_exec = False
401
- result["cases"].append(
402
- {"no": no, "stage": "exec", "ok": False, "error": err[:500]}
403
- )
404
- if not result["fail_reason"]:
405
- tail = err.strip().splitlines()[-1][:200] if err.strip() else "unknown"
406
- result["fail_reason"] = f"exec-error: {tail}"
407
- continue
408
-
409
- # ── Evaluate ─────────────────────────────────────────────────
410
- if not os.path.exists(pred_path):
411
- all_exec = False
412
- result["cases"].append(
413
- {"no": no, "stage": "exec", "ok": False, "error": "output-not-found"}
414
- )
415
- if not result["fail_reason"]:
416
- result["fail_reason"] = "output-not-found"
417
- continue
418
-
419
- result["n_exec_pass"] += 1
420
- try:
421
- ev = evaluate(pred_path, ap, instruction_type, answer_position_eval)
422
- except Exception as e: # noqa: BLE001
423
- ev = {"ok": False, "reason": f"eval-exception: {type(e).__name__}: {e}"}
424
-
425
- if ev["ok"]:
426
- result["n_pass"] += 1
427
- else:
428
- if not result["fail_reason"]:
429
- result["fail_reason"] = f"eval-mismatch: {ev['reason'][:200]}"
430
- result["cases"].append(
431
- {"no": no, "stage": "eval", "ok": ev["ok"], "reason": ev.get("reason", "")}
432
- )
433
-
434
- result["exec_ok"] = all_exec
435
- n_cases = result["n_cases"]
436
- n_pass = result["n_pass"]
437
- result["soft"] = (n_pass / n_cases) if n_cases else 0.0
438
- result["hard"] = 1 if (n_cases > 0 and n_pass == n_cases) else 0
439
- result["ok"] = bool(result["hard"])
440
- if result["ok"]:
441
- result["fail_reason"] = ""
442
- return result
443
-
444
- except Exception as e: # noqa: BLE001
445
- result["fail_reason"] = f"unexpected: {type(e).__name__}: {e}"
446
- result["error"] = traceback.format_exc()
447
- return result
448
-
449
-
450
- # ── Batch runner ─────────────────────────────────────────────────────────────
451
-
452
-
453
- def run_spreadsheet_batch(
454
- items: list[dict],
455
- data_root: str,
456
- out_root: str,
457
- skill_content: str,
458
- max_turns: int = 30,
459
- max_completion_tokens: int = 16384,
460
- max_api_workers: int = 64,
461
- task_timeout: int = 600,
462
- diagnostic_mode: bool = False,
463
- diagnostic_instruction: str = "",
464
- diagnostic_trace_context_by_id: dict[str, str] | None = None,
465
- ) -> list[dict]:
466
- """Run the ReAct agent on all items with ThreadPoolExecutor.
467
-
468
- Returns list of result dicts compatible with ``compute_score()``.
469
- """
470
- os.makedirs(out_root, exist_ok=True)
471
-
472
- # Check for already-done items (resume support)
473
- results_path = os.path.join(out_root, "results.jsonl")
474
- done_ids: set[str] = set()
475
- existing: list[dict] = []
476
- if os.path.exists(results_path):
477
- with open(results_path) as f:
478
- for line in f:
479
- try:
480
- r = json.loads(line)
481
- done_ids.add(str(r["id"]))
482
- existing.append(r)
483
- except Exception:
484
- pass
485
-
486
- pending = [it for it in items if str(it["id"]) not in done_ids]
487
- print(
488
- f" [spreadsheet rollout] total={len(items)} done={len(done_ids)} "
489
- f"pending={len(pending)} workers={max_api_workers} task_timeout={task_timeout}s"
490
- )
491
-
492
- if not pending:
493
- return existing
494
-
495
- t0 = time.time()
496
- results = list(existing)
497
- started_at: dict[str, float] = {}
498
-
499
- def _timeout_result(item: dict) -> dict:
500
- return {
501
- "id": str(item["id"]),
502
- "ok": False,
503
- "phase": "timeout",
504
- "fail_reason": f"task-timeout-{task_timeout}s",
505
- "n_cases": 0, "n_pass": 0, "soft": 0.0, "hard": 0,
506
- "n_turns": 0, "cases": [], "error": "timeout",
507
- }
508
-
509
- def _error_result(item: dict, exc: Exception) -> dict:
510
- return {
511
- "id": str(item["id"]),
512
- "ok": False,
513
- "phase": "error",
514
- "fail_reason": f"unexpected: {type(exc).__name__}: {exc}",
515
- "n_cases": 0, "n_pass": 0, "soft": 0.0, "hard": 0,
516
- "n_turns": 0, "cases": [], "error": str(exc),
517
- }
518
-
519
- def _run_one(it: dict) -> dict:
520
- started_at[str(it["id"])] = time.time()
521
- return process_one(
522
- it,
523
- data_root,
524
- out_root,
525
- skill_content,
526
- max_turns,
527
- diagnostic_mode,
528
- diagnostic_instruction,
529
- (diagnostic_trace_context_by_id or {}).get(str(it["id"]), ""),
530
- max_completion_tokens,
531
- )
532
-
533
- ex = ThreadPoolExecutor(max_workers=max_api_workers)
534
- try:
535
- futs = {ex.submit(_run_one, it): it for it in pending}
536
- pending_futs = set(futs)
537
- finished = 0
538
- while pending_futs:
539
- done, _ = wait(pending_futs, timeout=5, return_when=FIRST_COMPLETED)
540
- now = time.time()
541
- timed_out = [
542
- fut for fut in pending_futs - done
543
- if str(futs[fut]["id"]) in started_at
544
- and now - started_at[str(futs[fut]["id"])] >= task_timeout
545
- ]
546
- for fut in done:
547
- pending_futs.remove(fut)
548
- item = futs[fut]
549
- try:
550
- res = fut.result()
551
- except FuturesTimeoutError:
552
- res = _timeout_result(item)
553
- except Exception as e: # noqa: BLE001
554
- res = _error_result(item, e)
555
- results.append(res)
556
- finished += 1
557
- status = "PASS" if res.get("hard") else ("TIMEOUT" if res.get("phase") == "timeout" else "FAIL")
558
- dt = time.time() - t0
559
- print(
560
- f" {finished}/{len(pending)} id={res['id']:<10} {status} "
561
- f"turns={res.get('n_turns', 0):<3} "
562
- f"cases={res.get('n_pass', 0)}/{res.get('n_cases', 0)} "
563
- f"dt={dt:.0f}s"
564
- )
565
- for fut in timed_out:
566
- pending_futs.remove(fut)
567
- res = _timeout_result(futs[fut])
568
- results.append(res)
569
- finished += 1
570
- status = "TIMEOUT"
571
- dt = time.time() - t0
572
- print(
573
- f" {finished}/{len(pending)} id={res['id']:<10} {status} "
574
- f"turns={res.get('n_turns', 0):<3} "
575
- f"cases={res.get('n_pass', 0)}/{res.get('n_cases', 0)} "
576
- f"dt={dt:.0f}s"
577
- )
578
- finally:
579
- ex.shutdown(wait=False, cancel_futures=True)
580
-
581
- return results
582
-
583
-
584
- # ── Codegen per-task worker (no tool-call) ──────────────────────────────────
585
-
586
-
587
- def process_one_codegen(
588
- item: dict,
589
- data_root: str,
590
- out_root: str,
591
- skill_content: str,
592
- mode: str = "single",
593
- max_turns: int = 5,
594
- max_completion_tokens: int = 16384,
595
- task_timeout: int = 600,
596
- use_eval_feedback: bool = False,
597
- diagnostic_mode: bool = False,
598
- diagnostic_instruction: str = "",
599
- diagnostic_trace_context: str = "",
600
- ) -> dict:
601
- """Run codegen agent (single or multi-round) on one SpreadsheetBench task.
602
-
603
- This matches the official evaluation setting: LLM generates a Python code
604
- block, no function-calling / tool-use.
605
- """
606
- from skillopt.envs.spreadsheetbench.codegen_agent import run_single, run_multi
607
-
608
- task_id = str(item["id"])
609
- instruction = item["instruction"]
610
- instruction_type = item.get("instruction_type", "")
611
- answer_position = item.get("answer_position", "")
612
- answer_sheet = item.get("answer_sheet", "")
613
- if answer_position and answer_sheet and "!" not in answer_position:
614
- answer_position_eval = f"{answer_sheet}!{answer_position}"
615
- else:
616
- answer_position_eval = answer_position
617
-
618
- itype_lower = (instruction_type or "").lower()
619
- if "cell" in itype_lower:
620
- task_type = "cell_level"
621
- elif "sheet" in itype_lower:
622
- task_type = "sheet_level"
623
- else:
624
- task_type = "other"
625
-
626
- sp = item.get("spreadsheet_path", f"spreadsheet/{task_id}")
627
- task_dir = sp if os.path.isabs(sp) else os.path.join(data_root, sp)
628
-
629
- result = {
630
- "id": task_id,
631
- "ok": False,
632
- "instruction_type": instruction_type,
633
- "task_type": task_type,
634
- "task_description": instruction,
635
- "phase": "setup",
636
- "fail_reason": "",
637
- "llm_ok": False,
638
- "code_ok": False,
639
- "exec_ok": False,
640
- "n_cases": 0,
641
- "n_exec_pass": 0,
642
- "n_pass": 0,
643
- "soft": 0.0,
644
- "hard": 0,
645
- "n_turns": 0,
646
- "cases": [],
647
- "error": "",
648
- }
649
-
650
- try:
651
- cases = _find_test_cases(task_dir)
652
- result["n_cases"] = len(cases)
653
- if not cases:
654
- result["fail_reason"] = "no-test-cases"
655
- return result
656
-
657
- task_out_dir = os.path.join(out_root, "predictions", task_id)
658
- os.makedirs(task_out_dir, exist_ok=True)
659
-
660
- # ── Save context for Optimizer (Reflect stage) ──────────────────
661
- from skillopt.envs.spreadsheetbench.codegen_agent import (
662
- _preview_workbook, _build_system, _build_user,
663
- )
664
- first_input_for_preview = cases[0][1]
665
- try:
666
- preview_text = _preview_workbook(first_input_for_preview)
667
- except Exception:
668
- preview_text = "(preview failed)"
669
- target_system = _build_system(skill_content)
670
- target_user = _build_user(
671
- instruction,
672
- first_input_for_preview,
673
- instruction_type,
674
- answer_position_eval,
675
- diagnostic_mode=diagnostic_mode,
676
- diagnostic_instruction=diagnostic_instruction,
677
- diagnostic_trace_context=diagnostic_trace_context,
678
- )
679
-
680
- with open(os.path.join(task_out_dir, "spreadsheet_preview.txt"), "w") as f:
681
- f.write(preview_text)
682
- with open(os.path.join(task_out_dir, "target_system_prompt.txt"), "w") as f:
683
- f.write(target_system)
684
- with open(os.path.join(task_out_dir, "target_user_prompt.txt"), "w") as f:
685
- f.write(target_user)
686
-
687
- result["spreadsheet_preview"] = preview_text
688
- result["target_system_prompt"] = target_system
689
- result["target_user_prompt"] = target_user
690
-
691
- # ── LLM phase ──────────────────────────────────────────────────
692
- result["phase"] = "llm"
693
- first_input = cases[0][1]
694
- first_gold = cases[0][2]
695
- first_pred = os.path.join(task_out_dir, f"{cases[0][0]}_pred.xlsx")
696
-
697
- try:
698
- if mode == "multi":
699
- agent_result = run_multi(
700
- instruction=instruction,
701
- input_xlsx=first_input,
702
- output_path=first_pred,
703
- instruction_type=instruction_type,
704
- answer_position=answer_position_eval,
705
- skill_content=skill_content,
706
- max_turns=max_turns,
707
- max_output_tokens=max_completion_tokens,
708
- task_timeout=task_timeout,
709
- gold_path=first_gold if use_eval_feedback else "",
710
- diagnostic_mode=diagnostic_mode,
711
- diagnostic_instruction=diagnostic_instruction,
712
- diagnostic_trace_context=diagnostic_trace_context,
713
- )
714
- else:
715
- agent_result = run_single(
716
- instruction=instruction,
717
- input_xlsx=first_input,
718
- output_path=first_pred,
719
- instruction_type=instruction_type,
720
- answer_position=answer_position_eval,
721
- skill_content=skill_content,
722
- max_output_tokens=max_completion_tokens,
723
- task_timeout=task_timeout,
724
- diagnostic_mode=diagnostic_mode,
725
- diagnostic_instruction=diagnostic_instruction,
726
- diagnostic_trace_context=diagnostic_trace_context,
727
- )
728
- except Exception as e: # noqa: BLE001
729
- result["fail_reason"] = f"llm-call-failed: {type(e).__name__}: {e}"
730
- result["error"] = traceback.format_exc()
731
- return result
732
-
733
- result["llm_ok"] = True
734
- result["n_turns"] = agent_result.get("n_turns", 1)
735
- code = agent_result.get("code", "")
736
- raw = agent_result.get("raw", "")
737
-
738
- # Save artifacts
739
- with open(os.path.join(task_out_dir, "code.py"), "w") as f:
740
- f.write(code)
741
- with open(os.path.join(task_out_dir, "raw.txt"), "w") as f:
742
- f.write(raw)
743
- if agent_result.get("conversation"):
744
- with open(os.path.join(task_out_dir, "conversation.json"), "w") as f:
745
- json.dump(agent_result["conversation"], f, ensure_ascii=False, indent=2)
746
-
747
- if not code.strip():
748
- result["phase"] = "extract"
749
- result["fail_reason"] = "empty-code-block"
750
- return result
751
- result["code_ok"] = True
752
-
753
- # ── Exec + eval per test case ──────────────────────────────────
754
- result["phase"] = "exec"
755
- all_exec = True
756
- # Collect enrichment info for the conversation/trajectory
757
- enrichment_parts: list[str] = []
758
-
759
- for no, ip, ap in cases:
760
- pred_path = os.path.join(task_out_dir, f"{no}_pred.xlsx")
761
-
762
- # For multi mode, the first case may already be produced
763
- if not os.path.exists(pred_path):
764
- ok_exec, err = run_generated_code(code, ip, pred_path)
765
- if not ok_exec:
766
- all_exec = False
767
- result["cases"].append(
768
- {"no": no, "stage": "exec", "ok": False, "error": err[:500]}
769
- )
770
- if not result["fail_reason"]:
771
- tail = err.strip().splitlines()[-1][:200] if err.strip() else "unknown"
772
- result["fail_reason"] = f"exec-error: {tail}"
773
- enrichment_parts.append(
774
- f"## Execution (case {no})\nERROR: {err[:500]}"
775
- )
776
- continue
777
-
778
- if not os.path.exists(pred_path):
779
- all_exec = False
780
- result["cases"].append(
781
- {"no": no, "stage": "exec", "ok": False, "error": "output-not-found"}
782
- )
783
- if not result["fail_reason"]:
784
- result["fail_reason"] = "output-not-found"
785
- continue
786
-
787
- result["n_exec_pass"] += 1
788
- try:
789
- ev = evaluate(pred_path, ap, instruction_type, answer_position_eval)
790
- except Exception as e: # noqa: BLE001
791
- ev = {"ok": False, "reason": f"eval-exception: {type(e).__name__}: {e}"}
792
-
793
- if ev["ok"]:
794
- result["n_pass"] += 1
795
- else:
796
- if not result["fail_reason"]:
797
- result["fail_reason"] = f"eval-mismatch: {ev['reason'][:200]}"
798
- result["cases"].append(
799
- {"no": no, "stage": "eval", "ok": ev["ok"], "reason": ev.get("reason", "")}
800
- )
801
-
802
- # Auto-verify: reopen output and compare cells at answer_position
803
- if answer_position_eval:
804
- verify_report = _auto_verify_output(pred_path, ap, answer_position_eval)
805
- enrichment_parts.append(
806
- f"## Eval Result (case {no}): {'PASS' if ev['ok'] else 'FAIL'}\n"
807
- f"{ev.get('reason', '')}\n\n{verify_report}"
808
- )
809
-
810
- result["exec_ok"] = all_exec
811
-
812
- # ── Enrich conversation with eval details ──────────────────────
813
- if enrichment_parts:
814
- enrichment_msg = "\n\n---\n\n".join(enrichment_parts)
815
- conversation = agent_result.get("conversation", [])
816
- conversation.append({
817
- "role": "system",
818
- "content": f"[POST-EXECUTION VERIFICATION]\n\n{enrichment_msg}",
819
- })
820
- # Re-save the enriched conversation
821
- with open(os.path.join(task_out_dir, "conversation.json"), "w") as f:
822
- json.dump(conversation, f, ensure_ascii=False, indent=2)
823
- n_cases = result["n_cases"]
824
- n_pass = result["n_pass"]
825
- result["soft"] = (n_pass / n_cases) if n_cases else 0.0
826
- result["hard"] = 1 if (n_cases > 0 and n_pass == n_cases) else 0
827
- result["ok"] = bool(result["hard"])
828
- if result["ok"]:
829
- result["fail_reason"] = ""
830
- return result
831
-
832
- except Exception as e: # noqa: BLE001
833
- result["fail_reason"] = f"unexpected: {type(e).__name__}: {e}"
834
- result["error"] = traceback.format_exc()
835
- return result
836
-
837
-
838
- # ── Codegen batch runner ────────────────────────────────────────────────────
839
-
840
-
841
- def run_spreadsheet_batch_codegen(
842
- items: list[dict],
843
- data_root: str,
844
- out_root: str,
845
- skill_content: str,
846
- mode: str = "single",
847
- max_turns: int = 5,
848
- max_completion_tokens: int = 16384,
849
- max_api_workers: int = 32,
850
- task_timeout: int = 0,
851
- use_eval_feedback: bool = False,
852
- diagnostic_mode: bool = False,
853
- diagnostic_instruction: str = "",
854
- diagnostic_trace_context_by_id: dict[str, str] | None = None,
855
- ) -> list[dict]:
856
- """Run codegen agent on all items (no tool-call).
857
-
858
- Args:
859
- mode: "single" or "multi".
860
- task_timeout: Hard per-task timeout in seconds at the future level.
861
- 0 or negative disables the per-task timeout.
862
- """
863
- no_task_timeout = task_timeout <= 0
864
- task_timeout_label = "none" if no_task_timeout else f"{task_timeout}s"
865
-
866
- os.makedirs(out_root, exist_ok=True)
867
-
868
- results_path = os.path.join(out_root, "results.jsonl")
869
- done_ids: set[str] = set()
870
- existing: list[dict] = []
871
- if os.path.exists(results_path):
872
- with open(results_path) as f:
873
- for line in f:
874
- try:
875
- r = json.loads(line)
876
- done_ids.add(str(r["id"]))
877
- existing.append(r)
878
- except Exception:
879
- pass
880
-
881
- pending = [it for it in items if str(it["id"]) not in done_ids]
882
- print(
883
- f" [spreadsheet codegen-{mode}] total={len(items)} done={len(done_ids)} "
884
- f"pending={len(pending)} workers={max_api_workers} task_timeout={task_timeout_label}"
885
- )
886
-
887
- if not pending:
888
- return existing
889
-
890
- t0 = time.time()
891
- results = list(existing)
892
-
893
- started_at: dict[str, float] = {}
894
-
895
- def _run_one(it: dict) -> dict:
896
- started_at[str(it["id"])] = time.time()
897
- return process_one_codegen(
898
- it,
899
- data_root,
900
- out_root,
901
- skill_content,
902
- mode,
903
- max_turns,
904
- max_completion_tokens,
905
- task_timeout,
906
- use_eval_feedback,
907
- diagnostic_mode,
908
- diagnostic_instruction,
909
- (diagnostic_trace_context_by_id or {}).get(str(it["id"]), ""),
910
- )
911
-
912
- def _timeout_result(item: dict) -> dict:
913
- return {
914
- "id": str(item["id"]),
915
- "ok": False,
916
- "instruction_type": item.get("instruction_type", ""),
917
- "task_type": "other",
918
- "phase": "timeout",
919
- "fail_reason": f"task-timeout-{task_timeout}s",
920
- "n_cases": 0, "n_pass": 0, "soft": 0.0, "hard": 0,
921
- "n_turns": 0, "cases": [], "error": "timeout",
922
- }
923
-
924
- def _error_result(item: dict, e: Exception) -> dict:
925
- return {
926
- "id": str(item["id"]),
927
- "ok": False,
928
- "instruction_type": item.get("instruction_type", ""),
929
- "task_type": "other",
930
- "phase": "error",
931
- "fail_reason": f"unexpected: {type(e).__name__}: {e}",
932
- "n_cases": 0, "n_pass": 0, "soft": 0.0, "hard": 0,
933
- "n_turns": 0, "cases": [], "error": str(e),
934
- }
935
-
936
- def _record(res: dict, i: int) -> None:
937
- results.append(res)
938
- status = "PASS" if res.get("hard") else ("TIMEOUT" if res.get("phase") == "timeout" else "FAIL")
939
- dt = time.time() - t0
940
- print(
941
- f" {i}/{len(pending)} id={res['id']:<10} {status} "
942
- f"turns={res.get('n_turns', 0):<3} "
943
- f"cases={res.get('n_pass', 0)}/{res.get('n_cases', 0)} "
944
- f"dt={dt:.0f}s"
945
- )
946
-
947
- ex = ThreadPoolExecutor(max_workers=max_api_workers)
948
- try:
949
- futs = {ex.submit(_run_one, it): it for it in pending}
950
- pending_futs = set(futs)
951
- finished = 0
952
- while pending_futs:
953
- done, _ = wait(pending_futs, timeout=5, return_when=FIRST_COMPLETED)
954
- now = time.time()
955
- timed_out = [] if no_task_timeout else [
956
- fut for fut in pending_futs - done
957
- if str(futs[fut]["id"]) in started_at
958
- and now - started_at[str(futs[fut]["id"])] >= task_timeout
959
- ]
960
- for fut in done:
961
- pending_futs.remove(fut)
962
- item = futs[fut]
963
- try:
964
- res = fut.result()
965
- except FuturesTimeoutError:
966
- res = _timeout_result(item)
967
- except Exception as e: # noqa: BLE001
968
- res = _error_result(item, e)
969
- finished += 1
970
- _record(res, finished)
971
- for fut in timed_out:
972
- pending_futs.remove(fut)
973
- fut.cancel()
974
- finished += 1
975
- _record(_timeout_result(futs[fut]), finished)
976
- finally:
977
- ex.shutdown(wait=False, cancel_futures=True)
978
-
979
- return results