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,1057 +0,0 @@
1
- """Helpers for running exec backends as the target harness."""
2
- from __future__ import annotations
3
-
4
- import asyncio
5
- import json
6
- import os
7
- import re
8
- import shutil
9
- import subprocess
10
- import threading
11
- import traceback
12
- from typing import Any
13
-
14
- from skillopt.model.backend_config import (
15
- get_claude_code_exec_config,
16
- get_codex_exec_config,
17
- get_target_backend,
18
- )
19
-
20
-
21
- ANSWER_SCHEMA: dict[str, Any] = {
22
- "type": "object",
23
- "properties": {
24
- "final_response": {
25
- "type": "string",
26
- "description": "The exact final answer text to return, preserving required <answer>...</answer> tags.",
27
- },
28
- "final_answer": {
29
- "type": "string",
30
- "description": "The concise answer value without explanation, if separable.",
31
- },
32
- },
33
- "required": ["final_response", "final_answer"],
34
- "additionalProperties": False,
35
- }
36
-
37
-
38
- def render_skill_md(
39
- skill_content: str,
40
- *,
41
- name: str = "skillopt-target",
42
- description: str = "Dynamic ReflACT skill for the current benchmark task.",
43
- preamble: str = "",
44
- ) -> str:
45
- body = skill_content.strip() or "No additional dynamic guidance was provided for this task."
46
- chunks = [
47
- "---",
48
- f'name: "{name}"',
49
- f'description: "{description}"',
50
- "---",
51
- "",
52
- "# ReflACT Target Skill",
53
- "",
54
- ]
55
- if preamble.strip():
56
- chunks.append(preamble.strip())
57
- chunks.append("")
58
- chunks.extend([
59
- "## Dynamic Guidance",
60
- "",
61
- body,
62
- "",
63
- ])
64
- return "\n".join(chunks)
65
-
66
-
67
- def prepare_workspace(
68
- *,
69
- work_dir: str,
70
- skill_md: str,
71
- task_text: str = "",
72
- task_filename: str = "task.md",
73
- images: list[str] | None = None,
74
- extra_files: dict[str, str] | None = None,
75
- copy_files: list[tuple[str, str]] | None = None,
76
- link_dirs: list[tuple[str, str]] | None = None,
77
- ) -> tuple[str, str]:
78
- if os.path.exists(work_dir):
79
- shutil.rmtree(work_dir)
80
- os.makedirs(os.path.join(work_dir, ".agents", "skills", "skillopt-target"), exist_ok=True)
81
-
82
- skill_path = os.path.join(work_dir, ".agents", "skills", "skillopt-target", "SKILL.md")
83
- with open(skill_path, "w", encoding="utf-8") as f:
84
- f.write(skill_md)
85
-
86
- task_path = os.path.join(work_dir, task_filename)
87
- if task_text:
88
- with open(task_path, "w", encoding="utf-8") as f:
89
- f.write(task_text)
90
-
91
- if extra_files:
92
- for rel_path, content in extra_files.items():
93
- full_path = os.path.join(work_dir, rel_path)
94
- parent = os.path.dirname(full_path)
95
- if parent:
96
- os.makedirs(parent, exist_ok=True)
97
- with open(full_path, "w", encoding="utf-8") as f:
98
- f.write(content)
99
-
100
- if copy_files:
101
- for src, rel_dst in copy_files:
102
- dst = os.path.join(work_dir, rel_dst)
103
- parent = os.path.dirname(dst)
104
- if parent:
105
- os.makedirs(parent, exist_ok=True)
106
- shutil.copy2(src, dst)
107
-
108
- if link_dirs:
109
- for src, rel_dst in link_dirs:
110
- dst = os.path.join(work_dir, rel_dst)
111
- parent = os.path.dirname(dst)
112
- if parent:
113
- os.makedirs(parent, exist_ok=True)
114
- os.symlink(os.path.abspath(src), dst)
115
-
116
- attachment_lines: list[str] = []
117
- if images:
118
- attachments_dir = os.path.join(work_dir, "attachments")
119
- os.makedirs(attachments_dir, exist_ok=True)
120
- for index, image in enumerate(images, 1):
121
- if not os.path.exists(image):
122
- raise FileNotFoundError(image)
123
- src = os.path.abspath(image)
124
- base = os.path.basename(src) or f"image_{index}"
125
- dst_name = f"{index:02d}_{base}"
126
- dst = os.path.join(attachments_dir, dst_name)
127
- if os.path.abspath(src) != os.path.abspath(dst):
128
- shutil.copy2(src, dst)
129
- rel_dst = os.path.relpath(dst, work_dir)
130
- attachment_lines.append(f"- `{rel_dst}` (source: `{src}`)")
131
-
132
- if attachment_lines:
133
- with open(os.path.join(work_dir, "ATTACHMENTS.md"), "w", encoding="utf-8") as f:
134
- f.write(
135
- "# Attachments\n\n"
136
- "Use these local files when the task refers to attached images or documents.\n\n"
137
- + "\n".join(attachment_lines)
138
- + "\n"
139
- )
140
-
141
- return skill_path, task_path
142
-
143
-
144
- def _build_codex_trace_summary(raw: str, response: str) -> str:
145
- lines = [ln.rstrip() for ln in (raw or "").splitlines()]
146
-
147
- def _find(prefix: str) -> str:
148
- for ln in lines:
149
- if ln.startswith(prefix):
150
- return ln[len(prefix):].strip()
151
- return ""
152
-
153
- sandbox = _find("sandbox: ")
154
- reasoning = _find("reasoning effort: ")
155
- task_read = "unknown"
156
- skill_read = "unknown"
157
- exec_errors: list[str] = []
158
- tokens_used = ""
159
-
160
- for idx, ln in enumerate(lines):
161
- if ln.startswith("exec"):
162
- cmd = lines[idx + 1] if idx + 1 < len(lines) else ""
163
- outcome = lines[idx + 2] if idx + 2 < len(lines) else ""
164
- joined = f"{cmd}\n{outcome}"
165
- if "task.md" in joined:
166
- if "succeeded" in outcome:
167
- task_read = "success"
168
- elif "failed" in outcome or "ERROR" in outcome:
169
- task_read = "failed"
170
- if "SKILL.md" in joined:
171
- if "succeeded" in outcome:
172
- skill_read = "success"
173
- elif "failed" in outcome or "ERROR" in outcome:
174
- skill_read = "failed"
175
- if ln.startswith("ERROR:"):
176
- exec_errors.append(ln[len("ERROR:"):].strip())
177
- if ln == "tokens used" and idx + 1 < len(lines):
178
- tokens_used = lines[idx + 1].strip()
179
-
180
- match = re.search(r"<answer>\s*([A-E])\s*</answer>", response or "", re.IGNORECASE)
181
- if match:
182
- answer_format = "well_formed"
183
- answer_label = match.group(1).upper()
184
- elif "<answer>" in (response or "").lower():
185
- answer_format = "tagged_nonlabel"
186
- answer_label = ""
187
- elif (response or "").strip():
188
- answer_format = "plain_text"
189
- answer_label = ""
190
- else:
191
- answer_format = "missing"
192
- answer_label = ""
193
-
194
- parts = ["Codex Trace Summary"]
195
- if sandbox:
196
- parts.append(f"- sandbox: {sandbox}")
197
- if reasoning:
198
- parts.append(f"- reasoning: {reasoning}")
199
- parts.append(f"- read task.md: {task_read}")
200
- parts.append(f"- read SKILL.md: {skill_read}")
201
- if exec_errors:
202
- parts.append(f"- shell/tool errors: {' | '.join(exec_errors[:3])}")
203
- else:
204
- parts.append("- shell/tool errors: none")
205
- parts.append(f"- final answer format: {answer_format}")
206
- parts.append(f"- final answer label: {answer_label or '(none)'}")
207
- if tokens_used:
208
- parts.append(f"- tokens used: {tokens_used}")
209
- return "\n".join(parts)
210
-
211
-
212
- def _build_claude_trace_summary(raw: str, response: str) -> str:
213
- answer_format = "missing"
214
- if "<answer>" in (response or "").lower():
215
- answer_format = "tagged"
216
- elif (response or "").strip():
217
- answer_format = "plain_text"
218
- errors: list[str] = []
219
- for ln in (raw or "").splitlines():
220
- if "error" in ln.lower() or "traceback" in ln.lower():
221
- errors.append(ln.strip())
222
- if len(errors) >= 3:
223
- break
224
- parts = ["Claude Code Trace Summary", f"- final answer format: {answer_format}"]
225
- parts.append(f"- final response chars: {len(response or '')}")
226
- parts.append(f"- errors: {' | '.join(errors) if errors else 'none'}")
227
- return "\n".join(parts)
228
-
229
-
230
- def _persist_artifacts(
231
- *,
232
- work_dir: str,
233
- raw: str,
234
- response: str,
235
- prefix: str,
236
- summary_builder,
237
- ) -> None:
238
- pred_dir = os.path.dirname(work_dir.rstrip(os.sep))
239
- raw_path = os.path.join(pred_dir, f"{prefix}_raw.txt")
240
- summary_path = os.path.join(pred_dir, f"{prefix}_trace_summary.txt")
241
-
242
- combined_raw = raw
243
- if os.path.exists(raw_path):
244
- with open(raw_path, encoding="utf-8") as f:
245
- prev = f.read()
246
- combined_raw = f"{prev}\n\n===== TURN BREAK =====\n\n{raw}" if prev.strip() else raw
247
-
248
- with open(raw_path, "w", encoding="utf-8") as f:
249
- f.write(combined_raw)
250
- with open(summary_path, "w", encoding="utf-8") as f:
251
- f.write(summary_builder(combined_raw, response))
252
-
253
-
254
- def _persist_codex_artifacts(work_dir: str, raw: str, response: str) -> None:
255
- _persist_artifacts(
256
- work_dir=work_dir,
257
- raw=raw,
258
- response=response,
259
- prefix="codex",
260
- summary_builder=_build_codex_trace_summary,
261
- )
262
-
263
-
264
- def _persist_claude_artifacts(work_dir: str, raw: str, response: str) -> None:
265
- _persist_artifacts(
266
- work_dir=work_dir,
267
- raw=raw,
268
- response=response,
269
- prefix="claude",
270
- summary_builder=_build_claude_trace_summary,
271
- )
272
-
273
-
274
- def parse_codex_raw(raw: str) -> dict:
275
- """Parse raw Codex CLI output into step sections.
276
-
277
- Returns a dict with:
278
- - ``steps``: ordered sections beginning at the first ``user/codex/exec`` marker
279
- - ``trace_body``: raw trace starting at the first marker
280
- """
281
- lines = (raw or "").splitlines()
282
- markers = {"user", "codex", "exec"}
283
- first_step_line: int | None = None
284
- for idx, line in enumerate(lines):
285
- if line in markers:
286
- first_step_line = idx
287
- break
288
- if first_step_line is None:
289
- return {"steps": [], "trace_body": ""}
290
-
291
- steps: list[dict] = []
292
- current: dict | None = None
293
- for idx in range(first_step_line, len(lines)):
294
- line = lines[idx]
295
- if line in markers:
296
- if current is not None:
297
- current["end_line"] = idx
298
- current["content"] = "\n".join(current["content_lines"]).strip()
299
- current.pop("content_lines", None)
300
- steps.append(current)
301
- current = {
302
- "index": len(steps) + 1,
303
- "type": line,
304
- "start_line": idx,
305
- "content_lines": [],
306
- }
307
- continue
308
- if current is not None:
309
- current["content_lines"].append(line)
310
- if current is not None:
311
- current["end_line"] = len(lines)
312
- current["content"] = "\n".join(current["content_lines"]).strip()
313
- current.pop("content_lines", None)
314
- steps.append(current)
315
-
316
- trace_body = "\n".join(lines[first_step_line:]).strip()
317
- return {"steps": steps, "trace_body": trace_body}
318
-
319
-
320
- def format_codex_trace_steps(raw: str, *, max_chars: int = 4000) -> str:
321
- """Render parsed Codex trace into numbered compact steps for optimizer prompts."""
322
- parsed = parse_codex_raw(raw)
323
- steps = parsed["steps"]
324
- if not steps:
325
- return ""
326
-
327
- rendered: list[str] = []
328
- for step in steps:
329
- summary = ""
330
- content = str(step.get("content") or "").strip()
331
- if step["type"] == "exec":
332
- body_lines = [ln.strip() for ln in content.splitlines() if ln.strip()]
333
- cmd = body_lines[0] if body_lines else ""
334
- status = ""
335
- for ln in body_lines[1:]:
336
- low = ln.lower()
337
- if "succeeded in" in low or "failed in" in low or "timed out" in low or low.startswith("error"):
338
- status = ln
339
- break
340
- summary = cmd
341
- if status:
342
- summary = f"{summary} | {status}" if summary else status
343
- else:
344
- summary = " ".join(content.splitlines())
345
- summary = summary[:500] if summary else "(empty)"
346
- rendered.append(f"[{step['index']}] {step['type']}: {summary}")
347
-
348
- text = "\n".join(rendered)
349
- if len(text) > max_chars:
350
- text = text[:max_chars] + "\n...[trace steps truncated]..."
351
- return text
352
-
353
-
354
- def extract_codex_trace_prefix(raw: str, *, after_step: int) -> str:
355
- """Return raw trace body up to and including ``after_step``.
356
-
357
- ``after_step <= 0`` yields an empty string.
358
- """
359
- if after_step <= 0:
360
- return ""
361
- parsed = parse_codex_raw(raw)
362
- steps = parsed["steps"]
363
- if not steps:
364
- return ""
365
- clamped = min(after_step, len(steps))
366
- lines = parsed["trace_body"].splitlines()
367
- end_line = int(steps[clamped - 1]["end_line"]) - int(steps[0]["start_line"])
368
- return "\n".join(lines[:end_line]).strip()
369
-
370
-
371
- _DENIED_DATA_DIR_NAMES = {"officeqa_split", "sealqa_split"}
372
-
373
-
374
- def _normalize_tools(allowed_tools: list[str] | str | None) -> str:
375
- if allowed_tools is None:
376
- return ""
377
- if isinstance(allowed_tools, str):
378
- return ",".join(part.strip() for part in allowed_tools.split(",") if part.strip())
379
- return ",".join(str(tool).strip() for tool in allowed_tools if str(tool).strip())
380
-
381
-
382
- def _tools_list(allowed_tools: list[str] | str | None) -> list[str]:
383
- tools = _normalize_tools(allowed_tools)
384
- return [part.strip() for part in tools.split(",") if part.strip()]
385
-
386
-
387
- def _validate_exec_path(path: str) -> str:
388
- resolved = os.path.realpath(os.path.abspath(path))
389
- parts = set(resolved.split(os.sep))
390
- denied = parts & _DENIED_DATA_DIR_NAMES
391
- if denied:
392
- raise ValueError(f"Refusing to expose denied data directory to exec backend: {', '.join(sorted(denied))}")
393
- return resolved
394
-
395
-
396
- def _validated_add_dirs(work_dir: str, data_dirs: list[str] | None, images: list[str] | None) -> list[str]:
397
- add_dirs = [_validate_exec_path(work_dir)]
398
- for data_dir in data_dirs or []:
399
- add_dirs.append(_validate_exec_path(data_dir))
400
- for image in images or []:
401
- add_dirs.append(_validate_exec_path(os.path.dirname(image) or work_dir))
402
- deduped: list[str] = []
403
- for path in add_dirs:
404
- if path not in deduped:
405
- deduped.append(path)
406
- return deduped
407
-
408
-
409
- def _sdk_mode(value: Any) -> str:
410
- mode = str(value or "auto").strip().lower()
411
- if mode in {"1", "true", "yes", "on", "sdk"}:
412
- return "sdk"
413
- if mode in {"0", "false", "no", "off", "cli"}:
414
- return "cli"
415
- return "auto"
416
-
417
-
418
- def _claude_effort(value: Any) -> str:
419
- effort = str(value or "medium").strip().lower()
420
- if effort in {"", "none", "off"}:
421
- return ""
422
- if effort == "xhigh":
423
- return "max"
424
- if effort not in {"low", "medium", "high", "max"}:
425
- return "medium"
426
- return effort
427
-
428
-
429
- def _json_default(obj: Any) -> Any:
430
- if isinstance(obj, (str, int, float, bool)) or obj is None:
431
- return obj
432
- if isinstance(obj, (list, tuple)):
433
- return list(obj)
434
- if isinstance(obj, dict):
435
- return obj
436
- if hasattr(obj, "model_dump"):
437
- return obj.model_dump(mode="json")
438
- if hasattr(obj, "__dict__"):
439
- return {k: v for k, v in vars(obj).items() if not k.startswith("_")}
440
- return str(obj)
441
-
442
-
443
- def _json_dumps(data: Any) -> str:
444
- return json.dumps(data, ensure_ascii=False, indent=2, default=_json_default)
445
-
446
-
447
- def _run_async(coro):
448
- try:
449
- asyncio.get_running_loop()
450
- except RuntimeError:
451
- return asyncio.run(coro)
452
-
453
- box: dict[str, Any] = {}
454
-
455
- def _target() -> None:
456
- try:
457
- box["result"] = asyncio.run(coro)
458
- except BaseException as exc: # noqa: BLE001
459
- box["exception"] = exc
460
-
461
- thread = threading.Thread(target=_target, daemon=True)
462
- thread.start()
463
- thread.join()
464
- if "exception" in box:
465
- raise box["exception"]
466
- return box.get("result")
467
-
468
-
469
- def _exec_prompt(prompt: str, *, allow_file_edits: bool = False) -> str:
470
- edit_instruction = (
471
- "You may modify files in the workspace when the task asks you to create an artifact. "
472
- if allow_file_edits
473
- else "Do not modify files. "
474
- )
475
- return (
476
- "Use the workspace files to solve the task. Read task.md and the skill at "
477
- ".agents/skills/skillopt-target/SKILL.md before answering. "
478
- "If ATTACHMENTS.md exists, read it and inspect the listed local files. "
479
- "Do not call a Skill tool; the ReflACT guidance is a local markdown file. "
480
- f"Do not ask for permission. {edit_instruction}"
481
- "Return only the final answer text, keeping any required <answer>...</answer> tags exactly.\n\n"
482
- f"{_normalize_target_exec_prompt(prompt)}"
483
- )
484
-
485
-
486
- def _retry_prompt(prompt: str, attempt: int) -> str:
487
- if attempt <= 0:
488
- return prompt
489
- return (
490
- f"{prompt}\n\n"
491
- "Previous execution returned an empty final response. Re-read task.md and "
492
- ".agents/skills/skillopt-target/SKILL.md. If ATTACHMENTS.md exists, use the listed files. "
493
- "Then produce the final answer inside <answer>...</answer>."
494
- )
495
-
496
-
497
- def _normalize_target_exec_prompt(prompt: str) -> str:
498
- """Avoid wording that makes Claude Code call an unregistered Skill tool."""
499
- text = prompt or ""
500
- replacements = {
501
- "Use the `skillopt-target` skill available in this workspace.": (
502
- "Read `.agents/skills/skillopt-target/SKILL.md` directly; do not call a Skill tool."
503
- ),
504
- "- Use the local `skillopt-target` skill before writing code.": (
505
- "- Read `.agents/skills/skillopt-target/SKILL.md` before writing code; do not call a Skill tool."
506
- ),
507
- }
508
- for old, new in replacements.items():
509
- text = text.replace(old, new)
510
- return text
511
-
512
-
513
- def _strict_schema(schema: dict[str, Any]) -> dict[str, Any]:
514
- strict = json.loads(json.dumps(schema))
515
- strict["additionalProperties"] = False
516
- properties = strict.get("properties") or {}
517
- strict["required"] = list(properties.keys())
518
- return strict
519
-
520
-
521
- def _structured_response(data: Any) -> tuple[str, str]:
522
- if not isinstance(data, dict):
523
- return "", f"Structured output was not an object: {type(data).__name__}"
524
- final_response = str(data.get("final_response") or "").strip()
525
- final_answer = str(data.get("final_answer") or "").strip()
526
- if final_response:
527
- return final_response, ""
528
- if final_answer:
529
- if "<answer>" in final_answer.lower():
530
- return final_answer, ""
531
- return f"<answer>{final_answer}</answer>", ""
532
- return "", "Structured output did not contain a final response."
533
-
534
-
535
- def _extract_claude_structured_output(messages: list[Any]) -> Any:
536
- """Claude Code SDK can finish with error_during_execution after StructuredOutput."""
537
- for msg in reversed(messages):
538
- structured = getattr(msg, "structured_output", None)
539
- if isinstance(structured, dict):
540
- return structured
541
-
542
- content = getattr(msg, "content", None)
543
- if content is None and isinstance(msg, dict):
544
- content = msg.get("content")
545
- if not isinstance(content, list):
546
- continue
547
-
548
- for item in reversed(content):
549
- name = getattr(item, "name", None)
550
- payload = getattr(item, "input", None)
551
- if isinstance(item, dict):
552
- name = item.get("name", name)
553
- payload = item.get("input", payload)
554
- if name == "StructuredOutput" and isinstance(payload, dict):
555
- return payload
556
- return None
557
-
558
-
559
- def _raw_exception(label: str, exc: BaseException) -> str:
560
- return _json_dumps({
561
- "backend": label,
562
- "is_error": True,
563
- "error_type": type(exc).__name__,
564
- "error": str(exc),
565
- "traceback": traceback.format_exc(),
566
- })
567
-
568
-
569
- def _run_claude_code_sdk_exec(
570
- *,
571
- work_dir: str,
572
- prompt: str,
573
- model: str,
574
- timeout: int,
575
- images: list[str] | None = None,
576
- data_dirs: list[str] | None = None,
577
- allowed_tools: list[str] | str | None = None,
578
- permission_mode: str | None = None,
579
- allow_file_edits: bool = False,
580
- ) -> tuple[str, str]:
581
- from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
582
-
583
- async def _query() -> tuple[str, str]:
584
- system_prompt: dict[str, Any] = {
585
- "type": "preset",
586
- "preset": "claude_code",
587
- "append": (
588
- "Use the workspace files to solve the task. Read task.md and the skill at "
589
- ".agents/skills/skillopt-target/SKILL.md before answering. "
590
- "If ATTACHMENTS.md exists, read it and inspect the listed local files. "
591
- "Do not call a Skill tool; the ReflACT guidance is a local markdown file. "
592
- + (
593
- "You may modify files in the workspace when the task asks you to create an artifact. "
594
- if allow_file_edits
595
- else "Do not modify files. "
596
- )
597
- + "Return structured output whose final_response preserves required <answer>...</answer> tags."
598
- ),
599
- }
600
- kwargs: dict[str, Any] = {
601
- "system_prompt": system_prompt,
602
- "output_format": {"type": "json_schema", "schema": ANSWER_SCHEMA},
603
- "allowed_tools": _tools_list(allowed_tools) or ["Read", "Bash"],
604
- "cwd": str(work_dir),
605
- "permission_mode": permission_mode or "bypassPermissions",
606
- "add_dirs": _validated_add_dirs(work_dir, data_dirs, images),
607
- "max_buffer_size": 8 * 1024 * 1024,
608
- }
609
- config = get_claude_code_exec_config()
610
- effort = _claude_effort(config.get("effort"))
611
- if effort:
612
- kwargs["effort"] = effort
613
- max_thinking_tokens = int(config.get("max_thinking_tokens", 0) or 0)
614
- if max_thinking_tokens > 0:
615
- kwargs["max_thinking_tokens"] = max_thinking_tokens
616
- options = ClaudeAgentOptions(**kwargs)
617
- if model:
618
- options.model = model.split("/", 1)[1] if model.startswith("anthropic/") else model
619
-
620
- messages = []
621
- async with ClaudeSDKClient(options) as client:
622
- await client.query(_normalize_target_exec_prompt(prompt))
623
- messages = [msg async for msg in client.receive_response()]
624
- last = messages[-1] if messages else None
625
- raw_structured_output = _extract_claude_structured_output(messages)
626
- response, parse_error = _structured_response(raw_structured_output)
627
- first = messages[0] if messages else None
628
- first_data = getattr(first, "data", {}) if first is not None else {}
629
- terminal_is_error = bool(getattr(last, "is_error", False)) if last is not None else False
630
- raw = _json_dumps({
631
- "backend": "claude_code_sdk",
632
- "uuid": first_data.get("uuid", "") if isinstance(first_data, dict) else "",
633
- "session_id": getattr(last, "session_id", "") if last is not None else "",
634
- "model": first_data.get("model", model) if isinstance(first_data, dict) else model,
635
- "tools": first_data.get("tools", _tools_list(allowed_tools)) if isinstance(first_data, dict) else _tools_list(allowed_tools),
636
- "duration_ms": getattr(last, "duration_ms", 0) if last is not None else 0,
637
- "total_cost_usd": getattr(last, "total_cost_usd", 0.0) if last is not None else 0.0,
638
- "num_turns": getattr(last, "num_turns", 0) if last is not None else 0,
639
- "usage": getattr(last, "usage", {}) if last is not None else {},
640
- "result": getattr(last, "result", "") if last is not None else "",
641
- "is_error": bool(parse_error) or (terminal_is_error and not response.strip()),
642
- "terminal_is_error": terminal_is_error,
643
- "parse_error": parse_error,
644
- "raw_structured_output": raw_structured_output,
645
- "messages": messages,
646
- })
647
- return response, raw
648
-
649
- return _run_async(asyncio.wait_for(_query(), timeout=timeout))
650
-
651
-
652
- def _run_claude_code_cli_exec(
653
- *,
654
- work_dir: str,
655
- prompt: str,
656
- model: str,
657
- timeout: int,
658
- images: list[str] | None = None,
659
- data_dirs: list[str] | None = None,
660
- allowed_tools: list[str] | str | None = None,
661
- permission_mode: str | None = None,
662
- allow_file_edits: bool = False,
663
- ) -> tuple[str, str]:
664
- config = get_claude_code_exec_config()
665
- tools = "Read,Bash" if allowed_tools is None else _normalize_tools(allowed_tools)
666
- cmd = [
667
- str(config["path"]),
668
- "-p",
669
- "--output-format",
670
- "text",
671
- "--permission-mode",
672
- permission_mode or "bypassPermissions",
673
- "--add-dir",
674
- work_dir,
675
- "--tools",
676
- tools,
677
- "--allowedTools",
678
- tools,
679
- ]
680
- if config.get("profile"):
681
- cmd.extend(["--settings", '{"env":{"CLAUDE_CODE_USE_BEDROCK":"0"}}'])
682
- cmd.extend(["--append-system-prompt", f"Profile: {config['profile']}"])
683
- if model:
684
- cmd.extend(["--model", model])
685
- effort = _claude_effort(config.get("effort"))
686
- if effort:
687
- cmd.extend(["--effort", effort])
688
- max_thinking_tokens = int(config.get("max_thinking_tokens", 0) or 0)
689
- if max_thinking_tokens > 0:
690
- cmd.extend(["--max-thinking-tokens", str(max_thinking_tokens)])
691
- for data_dir in data_dirs or []:
692
- cmd.extend(["--add-dir", _validate_exec_path(data_dir)])
693
- if images:
694
- for image in images:
695
- cmd.extend(["--add-dir", _validate_exec_path(os.path.dirname(image) or work_dir)])
696
- cmd.extend(["--", _exec_prompt(prompt, allow_file_edits=allow_file_edits)])
697
-
698
- try:
699
- proc = subprocess.run(
700
- cmd,
701
- cwd=work_dir,
702
- capture_output=True,
703
- text=True,
704
- timeout=timeout,
705
- )
706
- except subprocess.TimeoutExpired as exc:
707
- stdout = exc.stdout or ""
708
- stderr = exc.stderr or ""
709
- raw = stdout
710
- if stderr:
711
- raw = f"{raw}\n[stderr]\n{stderr}" if raw else stderr
712
- return "", raw
713
-
714
- stdout = proc.stdout or ""
715
- stderr = proc.stderr or ""
716
- raw = stdout
717
- if stderr:
718
- raw = f"{raw}\n[stderr]\n{stderr}" if raw else stderr
719
- response = stdout.strip()
720
- if proc.returncode != 0 and not response:
721
- return "", raw
722
- return response, raw
723
-
724
-
725
- def run_claude_code_exec(
726
- *,
727
- work_dir: str,
728
- prompt: str,
729
- model: str,
730
- timeout: int,
731
- images: list[str] | None = None,
732
- data_dirs: list[str] | None = None,
733
- allowed_tools: list[str] | str | None = None,
734
- permission_mode: str | None = None,
735
- allow_file_edits: bool = False,
736
- ) -> tuple[str, str]:
737
- config = get_claude_code_exec_config()
738
- mode = _sdk_mode(config.get("use_sdk"))
739
- retries = int(config.get("empty_response_retries", 0) or 0)
740
- last_response = ""
741
- all_raw: list[str] = []
742
-
743
- for attempt in range(retries + 1):
744
- attempt_prompt = _retry_prompt(prompt, attempt)
745
- if mode != "cli":
746
- try:
747
- response, raw = _run_claude_code_sdk_exec(
748
- work_dir=work_dir,
749
- prompt=attempt_prompt,
750
- model=model,
751
- timeout=timeout,
752
- images=images,
753
- data_dirs=data_dirs,
754
- allowed_tools=allowed_tools,
755
- permission_mode=permission_mode,
756
- allow_file_edits=allow_file_edits,
757
- )
758
- all_raw.append(f"===== CLAUDE SDK ATTEMPT {attempt + 1} =====\n{raw}")
759
- if response.strip():
760
- combined = "\n\n".join(all_raw)
761
- _persist_claude_artifacts(work_dir, combined, response)
762
- return response, combined
763
- except (ImportError, ModuleNotFoundError) as exc:
764
- raw = _raw_exception("claude_code_sdk", exc)
765
- all_raw.append(f"===== CLAUDE SDK ATTEMPT {attempt + 1} =====\n{raw}")
766
- if mode == "sdk":
767
- _persist_claude_artifacts(work_dir, "\n\n".join(all_raw), "")
768
- raise
769
- except Exception as exc: # noqa: BLE001
770
- raw = _raw_exception("claude_code_sdk", exc)
771
- all_raw.append(f"===== CLAUDE SDK ATTEMPT {attempt + 1} =====\n{raw}")
772
- if mode == "sdk" and attempt >= retries:
773
- _persist_claude_artifacts(work_dir, "\n\n".join(all_raw), "")
774
- raise
775
- if mode != "sdk":
776
- response, raw = _run_claude_code_cli_exec(
777
- work_dir=work_dir,
778
- prompt=attempt_prompt,
779
- model=model,
780
- timeout=timeout,
781
- images=images,
782
- data_dirs=data_dirs,
783
- allowed_tools=allowed_tools,
784
- permission_mode=permission_mode,
785
- allow_file_edits=allow_file_edits,
786
- )
787
- all_raw.append(f"===== CLAUDE CLI ATTEMPT {attempt + 1} =====\n{raw}")
788
- last_response = response
789
- if response.strip():
790
- combined = "\n\n".join(all_raw)
791
- _persist_claude_artifacts(work_dir, combined, response)
792
- return response, combined
793
-
794
- combined = "\n\n".join(all_raw)
795
- _persist_claude_artifacts(work_dir, combined, last_response)
796
- return last_response, combined
797
-
798
-
799
- def _run_codex_sdk_exec(
800
- *,
801
- work_dir: str,
802
- prompt: str,
803
- model: str,
804
- timeout: int,
805
- images: list[str] | None = None,
806
- data_dirs: list[str] | None = None,
807
- ) -> tuple[str, str]:
808
- from openai_codex_sdk import Codex
809
-
810
- for data_dir in data_dirs or []:
811
- _validate_exec_path(data_dir)
812
- for image in images or []:
813
- _validate_exec_path(os.path.dirname(image) or work_dir)
814
-
815
- async def _query() -> tuple[str, str]:
816
- config = get_codex_exec_config()
817
- reasoning_effort = str(config.get("reasoning_effort", "") or "").strip()
818
- thread_options: dict[str, Any] = {
819
- "working_directory": work_dir,
820
- "skip_git_repo_check": True,
821
- "sandbox_mode": str(config.get("sandbox") or "workspace-write"),
822
- "network_access_enabled": bool(config.get("network_access", False)),
823
- "web_search_enabled": bool(config.get("web_search", False)),
824
- "approval_policy": str(config.get("approval_policy") or "never"),
825
- }
826
- if model:
827
- thread_options["model"] = model
828
- if data_dirs:
829
- thread_options["additional_directories"] = data_dirs
830
- if reasoning_effort and reasoning_effort != "none":
831
- thread_options["model_reasoning_effort"] = reasoning_effort
832
-
833
- codex_options: dict[str, Any] = {"env": os.environ.copy()}
834
- codex_path = str(config.get("path") or "").strip()
835
- if codex_path:
836
- codex_options["codexPathOverride"] = codex_path
837
- codex = Codex(codex_options)
838
- thread = codex.start_thread(thread_options)
839
- turn = await thread.run(prompt, {"output_schema": _strict_schema(ANSWER_SCHEMA)})
840
- result_text = str(getattr(turn, "final_response", "") or "")
841
- parsed: Any = None
842
- parse_error = ""
843
- response = ""
844
- if result_text.strip():
845
- try:
846
- parsed = json.loads(result_text)
847
- response, parse_error = _structured_response(parsed)
848
- except Exception as exc: # noqa: BLE001
849
- parse_error = f"{type(exc).__name__}: {exc}"
850
- else:
851
- parse_error = "No response from Codex SDK (final_response is empty)."
852
- raw = _json_dumps({
853
- "backend": "codex_sdk",
854
- "id": getattr(turn, "id", ""),
855
- "thread_id": getattr(turn, "thread_id", ""),
856
- "model": model,
857
- "thread_options": thread_options,
858
- "final_response": result_text,
859
- "raw_structured_output": parsed,
860
- "parse_error": parse_error,
861
- "is_error": bool(parse_error),
862
- "items": getattr(turn, "items", []),
863
- })
864
- return response, raw
865
-
866
- return _run_async(asyncio.wait_for(_query(), timeout=timeout))
867
-
868
-
869
- def _run_codex_cli_exec(
870
- *,
871
- work_dir: str,
872
- prompt: str,
873
- model: str,
874
- timeout: int,
875
- images: list[str] | None = None,
876
- data_dirs: list[str] | None = None,
877
- sandbox: str | None = None,
878
- full_auto: bool | None = None,
879
- ) -> tuple[str, str]:
880
- config = get_codex_exec_config()
881
- last_message_path = os.path.join(work_dir, "codex_last_message.txt")
882
- cmd = [
883
- str(config["path"]),
884
- "exec",
885
- "--skip-git-repo-check",
886
- "--color",
887
- "never",
888
- "-C",
889
- work_dir,
890
- ]
891
- if config.get("profile"):
892
- cmd.extend(["-p", str(config["profile"])])
893
- reasoning_effort = str(config.get("reasoning_effort", "")).strip()
894
- if reasoning_effort:
895
- cmd.extend(["-c", f'model_reasoning_effort="{reasoning_effort}"'])
896
- actual_full_auto = bool(config.get("full_auto", True)) if full_auto is None else bool(full_auto)
897
- actual_sandbox = str(sandbox or config["sandbox"])
898
- if actual_full_auto:
899
- cmd.append("--full-auto")
900
- else:
901
- cmd.extend(["--sandbox", actual_sandbox])
902
- if model:
903
- cmd.extend(["-m", model])
904
- for data_dir in data_dirs or []:
905
- _validate_exec_path(data_dir)
906
- for image in images or []:
907
- _validate_exec_path(os.path.dirname(image) or work_dir)
908
- cmd.extend(["-i", image])
909
- cmd.extend(["--output-last-message", last_message_path, prompt])
910
-
911
- try:
912
- proc = subprocess.run(
913
- cmd,
914
- cwd=work_dir,
915
- capture_output=True,
916
- text=True,
917
- timeout=timeout,
918
- )
919
- except subprocess.TimeoutExpired as exc:
920
- stdout = exc.stdout or ""
921
- stderr = exc.stderr or ""
922
- raw = stdout
923
- if stderr:
924
- raw = f"{raw}\n[stderr]\n{stderr}" if raw else stderr
925
- _persist_codex_artifacts(work_dir, raw, "")
926
- raise
927
- try:
928
- from skillopt.model import azure_openai as _openai
929
- _openai.tracker.record("rollout", 0, 0)
930
- except Exception:
931
- pass
932
- stdout = proc.stdout or ""
933
- stderr = proc.stderr or ""
934
- last_message = ""
935
- if os.path.exists(last_message_path):
936
- with open(last_message_path, encoding="utf-8") as f:
937
- last_message = f.read()
938
- raw = stdout
939
- if stderr:
940
- raw = f"{raw}\n[stderr]\n{stderr}" if raw else stderr
941
- if proc.returncode != 0:
942
- _persist_codex_artifacts(work_dir, raw, last_message)
943
- detail = (stderr or stdout).strip()
944
- raise RuntimeError(
945
- f"codex exec failed with exit code {proc.returncode}: {detail[:4000]}"
946
- )
947
- return last_message, raw
948
-
949
-
950
- def run_codex_exec(
951
- *,
952
- work_dir: str,
953
- prompt: str,
954
- model: str,
955
- timeout: int,
956
- images: list[str] | None = None,
957
- data_dirs: list[str] | None = None,
958
- sandbox: str | None = None,
959
- full_auto: bool | None = None,
960
- ) -> tuple[str, str]:
961
- config = get_codex_exec_config()
962
- mode = _sdk_mode(config.get("use_sdk"))
963
- retries = int(config.get("empty_response_retries", 0) or 0)
964
- last_response = ""
965
- all_raw: list[str] = []
966
-
967
- for attempt in range(retries + 1):
968
- attempt_prompt = _retry_prompt(prompt, attempt)
969
- if mode != "cli":
970
- try:
971
- response, raw = _run_codex_sdk_exec(
972
- work_dir=work_dir,
973
- prompt=attempt_prompt,
974
- model=model,
975
- timeout=timeout,
976
- images=images,
977
- data_dirs=data_dirs,
978
- )
979
- all_raw.append(f"===== CODEX SDK ATTEMPT {attempt + 1} =====\n{raw}")
980
- if response.strip():
981
- combined = "\n\n".join(all_raw)
982
- _persist_codex_artifacts(work_dir, combined, response)
983
- return response, combined
984
- except (ImportError, ModuleNotFoundError) as exc:
985
- raw = _raw_exception("codex_sdk", exc)
986
- all_raw.append(f"===== CODEX SDK ATTEMPT {attempt + 1} =====\n{raw}")
987
- if mode == "sdk":
988
- _persist_codex_artifacts(work_dir, "\n\n".join(all_raw), "")
989
- raise
990
- except Exception as exc: # noqa: BLE001
991
- raw = _raw_exception("codex_sdk", exc)
992
- all_raw.append(f"===== CODEX SDK ATTEMPT {attempt + 1} =====\n{raw}")
993
- if mode == "sdk" and attempt >= retries:
994
- _persist_codex_artifacts(work_dir, "\n\n".join(all_raw), "")
995
- raise
996
- if mode != "sdk":
997
- response, raw = _run_codex_cli_exec(
998
- work_dir=work_dir,
999
- prompt=attempt_prompt,
1000
- model=model,
1001
- timeout=timeout,
1002
- images=images,
1003
- data_dirs=data_dirs,
1004
- sandbox=sandbox,
1005
- full_auto=full_auto,
1006
- )
1007
- all_raw.append(f"===== CODEX CLI ATTEMPT {attempt + 1} =====\n{raw}")
1008
- last_response = response
1009
- if response.strip():
1010
- combined = "\n\n".join(all_raw)
1011
- _persist_codex_artifacts(work_dir, combined, response)
1012
- return response, combined
1013
-
1014
- combined = "\n\n".join(all_raw)
1015
- _persist_codex_artifacts(work_dir, combined, last_response)
1016
- return last_response, combined
1017
-
1018
-
1019
- def run_target_exec(
1020
- *,
1021
- work_dir: str,
1022
- prompt: str,
1023
- model: str,
1024
- timeout: int,
1025
- images: list[str] | None = None,
1026
- data_dirs: list[str] | None = None,
1027
- allowed_tools: list[str] | str | None = None,
1028
- permission_mode: str | None = None,
1029
- sandbox: str | None = None,
1030
- full_auto: bool | None = None,
1031
- allow_file_edits: bool = False,
1032
- ) -> tuple[str, str]:
1033
- backend = get_target_backend()
1034
- if backend == "codex_exec":
1035
- return run_codex_exec(
1036
- work_dir=work_dir,
1037
- prompt=prompt,
1038
- model=model,
1039
- timeout=timeout,
1040
- images=images,
1041
- data_dirs=data_dirs,
1042
- sandbox=sandbox,
1043
- full_auto=full_auto,
1044
- )
1045
- if backend == "claude_code_exec":
1046
- return run_claude_code_exec(
1047
- work_dir=work_dir,
1048
- prompt=prompt,
1049
- model=model,
1050
- timeout=timeout,
1051
- images=images,
1052
- data_dirs=data_dirs,
1053
- allowed_tools=allowed_tools,
1054
- permission_mode=permission_mode,
1055
- allow_file_edits=allow_file_edits,
1056
- )
1057
- raise ValueError(f"Unsupported exec backend: {backend}")