orizu 0.5.19 → 0.5.21

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 (378) hide show
  1. package/README.md +23 -0
  2. package/dist/archive-artifacts-cli.d.ts +50 -0
  3. package/dist/archive-artifacts-cli.d.ts.map +1 -0
  4. package/dist/artifact-archive.d.ts +48 -0
  5. package/dist/artifact-archive.d.ts.map +1 -0
  6. package/dist/artifact-pull.d.ts +22 -0
  7. package/dist/artifact-pull.d.ts.map +1 -0
  8. package/dist/banner.d.ts +3 -0
  9. package/dist/banner.d.ts.map +1 -0
  10. package/dist/connectors-cli.d.ts +31 -0
  11. package/dist/connectors-cli.d.ts.map +1 -0
  12. package/dist/credentials.d.ts +46 -0
  13. package/dist/credentials.d.ts.map +1 -0
  14. package/dist/csv.d.ts +49 -0
  15. package/dist/csv.d.ts.map +1 -0
  16. package/dist/dataset-download.d.ts +6 -0
  17. package/dist/dataset-download.d.ts.map +1 -0
  18. package/dist/dataset-edit-rows.d.ts +10 -0
  19. package/dist/dataset-edit-rows.d.ts.map +1 -0
  20. package/dist/dataset-upload-snapshot.d.ts +13 -0
  21. package/dist/dataset-upload-snapshot.d.ts.map +1 -0
  22. package/dist/daytona-slice-rehearsal.d.ts +89 -0
  23. package/dist/daytona-slice-rehearsal.d.ts.map +1 -0
  24. package/dist/daytona-slice.d.ts +106 -0
  25. package/dist/daytona-slice.d.ts.map +1 -0
  26. package/dist/deploy-key-merge-core.d.ts +121 -0
  27. package/dist/deploy-key-merge-core.d.ts.map +1 -0
  28. package/dist/diff-comments-cli.d.ts +12 -0
  29. package/dist/diff-comments-cli.d.ts.map +1 -0
  30. package/dist/diff-comments-cli.js +21 -2
  31. package/dist/egress-allowlist-cli.d.ts +23 -0
  32. package/dist/egress-allowlist-cli.d.ts.map +1 -0
  33. package/dist/egress-policy.d.ts +108 -0
  34. package/dist/egress-policy.d.ts.map +1 -0
  35. package/dist/error-response.d.ts +9 -0
  36. package/dist/error-response.d.ts.map +1 -0
  37. package/dist/file-parser.d.ts +5 -0
  38. package/dist/file-parser.d.ts.map +1 -0
  39. package/dist/gepa-engine-dispatch.d.ts +9 -0
  40. package/dist/gepa-engine-dispatch.d.ts.map +1 -0
  41. package/dist/gepa-engine-dispatch.js +307 -0
  42. package/dist/gepa-python-command.d.ts +6 -0
  43. package/dist/gepa-python-command.d.ts.map +1 -0
  44. package/dist/gepa-python-command.js +26 -0
  45. package/dist/gepa-python-paths.d.ts +6 -0
  46. package/dist/gepa-python-paths.d.ts.map +1 -0
  47. package/dist/gepa-python-paths.js +42 -0
  48. package/dist/git-credential.d.ts +69 -0
  49. package/dist/git-credential.d.ts.map +1 -0
  50. package/dist/git-recovery-environment.d.ts +31 -0
  51. package/dist/git-recovery-environment.d.ts.map +1 -0
  52. package/dist/github-setup.d.ts +122 -0
  53. package/dist/github-setup.d.ts.map +1 -0
  54. package/dist/global-flags.d.ts +12 -0
  55. package/dist/global-flags.d.ts.map +1 -0
  56. package/dist/help.d.ts +46 -0
  57. package/dist/help.d.ts.map +1 -0
  58. package/dist/help.js +93 -25
  59. package/dist/hosted-boot.d.ts +273 -0
  60. package/dist/hosted-boot.d.ts.map +1 -0
  61. package/dist/hosted-bootstrap-rehearsal.d.ts +86 -0
  62. package/dist/hosted-bootstrap-rehearsal.d.ts.map +1 -0
  63. package/dist/hosted-bootstrap.d.ts +188 -0
  64. package/dist/hosted-bootstrap.d.ts.map +1 -0
  65. package/dist/hosted-broker-server.d.ts +50 -0
  66. package/dist/hosted-broker-server.d.ts.map +1 -0
  67. package/dist/hosted-git-http-server.d.ts +36 -0
  68. package/dist/hosted-git-http-server.d.ts.map +1 -0
  69. package/dist/hosted-harness-claude.d.ts +195 -0
  70. package/dist/hosted-harness-claude.d.ts.map +1 -0
  71. package/dist/hosted-harness-opencode.d.ts +227 -0
  72. package/dist/hosted-harness-opencode.d.ts.map +1 -0
  73. package/dist/hosted-harness.d.ts +118 -0
  74. package/dist/hosted-harness.d.ts.map +1 -0
  75. package/dist/hosted-harvest.d.ts +68 -0
  76. package/dist/hosted-harvest.d.ts.map +1 -0
  77. package/dist/hosted-headless.d.ts +72 -0
  78. package/dist/hosted-headless.d.ts.map +1 -0
  79. package/dist/hosted-loop-lifecycle.d.ts +206 -0
  80. package/dist/hosted-loop-lifecycle.d.ts.map +1 -0
  81. package/dist/hosted-loop.d.ts +170 -0
  82. package/dist/hosted-loop.d.ts.map +1 -0
  83. package/dist/hosted-run-event-sink.d.ts +222 -0
  84. package/dist/hosted-run-event-sink.d.ts.map +1 -0
  85. package/dist/hosted-runtime-assets.d.ts +186 -0
  86. package/dist/hosted-runtime-assets.d.ts.map +1 -0
  87. package/dist/hosted-session-cli.d.ts +258 -0
  88. package/dist/hosted-session-cli.d.ts.map +1 -0
  89. package/dist/hosted-skill-staging.d.ts +73 -0
  90. package/dist/hosted-skill-staging.d.ts.map +1 -0
  91. package/dist/http.d.ts +8 -0
  92. package/dist/http.d.ts.map +1 -0
  93. package/dist/index.d.ts +22 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +119 -129
  96. package/dist/instruction-set-gepa-launch.d.ts +3 -0
  97. package/dist/instruction-set-gepa-launch.d.ts.map +1 -0
  98. package/dist/instruction-set-gepa-launch.js +15 -0
  99. package/dist/instruction-set-loader.d.ts +6 -0
  100. package/dist/instruction-set-loader.d.ts.map +1 -0
  101. package/dist/instruction-set-loader.js +59 -0
  102. package/dist/instruction-set-manifest.d.ts +14 -0
  103. package/dist/instruction-set-manifest.d.ts.map +1 -0
  104. package/dist/instruction-set-manifest.js +162 -0
  105. package/dist/instruction-sets-cli.d.ts +40 -0
  106. package/dist/instruction-sets-cli.d.ts.map +1 -0
  107. package/dist/instruction-sets-cli.js +361 -0
  108. package/dist/json-response.d.ts +4 -0
  109. package/dist/json-response.d.ts.map +1 -0
  110. package/dist/jsonl-stream.d.ts +8 -0
  111. package/dist/jsonl-stream.d.ts.map +1 -0
  112. package/dist/kill-switch-cli.d.ts +30 -0
  113. package/dist/kill-switch-cli.d.ts.map +1 -0
  114. package/dist/loopback-serve.d.ts +25 -0
  115. package/dist/loopback-serve.d.ts.map +1 -0
  116. package/dist/manifests-cli.d.ts +22 -0
  117. package/dist/manifests-cli.d.ts.map +1 -0
  118. package/dist/markdown-report-input.d.ts +7 -0
  119. package/dist/markdown-report-input.d.ts.map +1 -0
  120. package/dist/markdown-report-input.js +15 -1
  121. package/dist/merge-job.d.ts +155 -0
  122. package/dist/merge-job.d.ts.map +1 -0
  123. package/dist/model-configs-cli.d.ts +19 -0
  124. package/dist/model-configs-cli.d.ts.map +1 -0
  125. package/dist/model-configs-cli.js +104 -0
  126. package/dist/optimization-export-cli.d.ts +19 -0
  127. package/dist/optimization-export-cli.d.ts.map +1 -0
  128. package/dist/optimizations-list-cli.d.ts +20 -0
  129. package/dist/optimizations-list-cli.d.ts.map +1 -0
  130. package/dist/optimizations-promote-cli.d.ts +8 -0
  131. package/dist/optimizations-promote-cli.d.ts.map +1 -0
  132. package/dist/optimizations-promote-cli.js +34 -0
  133. package/dist/option-validation.d.ts +15 -0
  134. package/dist/option-validation.d.ts.map +1 -0
  135. package/dist/preview-runtime.d.ts +63 -0
  136. package/dist/preview-runtime.d.ts.map +1 -0
  137. package/dist/prompt-draft-push.d.ts +60 -0
  138. package/dist/prompt-draft-push.d.ts.map +1 -0
  139. package/dist/prompt-label-cli.d.ts +11 -0
  140. package/dist/prompt-label-cli.d.ts.map +1 -0
  141. package/dist/prompt-label-cli.js +29 -0
  142. package/dist/prompt-length-wire.d.ts +28 -0
  143. package/dist/prompt-length-wire.d.ts.map +1 -0
  144. package/dist/prompt-length-wire.js +2 -2
  145. package/dist/prompt-report-cli.d.ts +10 -0
  146. package/dist/prompt-report-cli.d.ts.map +1 -0
  147. package/dist/prompt-report-cli.js +2 -2
  148. package/dist/prompt-summary-table.d.ts +15 -0
  149. package/dist/prompt-summary-table.d.ts.map +1 -0
  150. package/dist/prompt-summary-table.js +6 -0
  151. package/dist/registration-tag-warning.d.ts +32 -0
  152. package/dist/registration-tag-warning.d.ts.map +1 -0
  153. package/dist/report-comments-cli.d.ts +16 -0
  154. package/dist/report-comments-cli.d.ts.map +1 -0
  155. package/dist/report-markdown-blankness.d.ts +2 -0
  156. package/dist/report-markdown-blankness.d.ts.map +1 -0
  157. package/dist/report-markdown-blankness.js +6 -0
  158. package/dist/report-replacement-warning.d.ts +17 -0
  159. package/dist/report-replacement-warning.d.ts.map +1 -0
  160. package/dist/report-replacement-warning.js +31 -0
  161. package/dist/repository-backup-core.d.ts +225 -0
  162. package/dist/repository-backup-core.d.ts.map +1 -0
  163. package/dist/repository-recovery-manifest.d.ts +83 -0
  164. package/dist/repository-recovery-manifest.d.ts.map +1 -0
  165. package/dist/run-event-digest.d.ts +74 -0
  166. package/dist/run-event-digest.d.ts.map +1 -0
  167. package/dist/runner-dir-verify.d.ts +66 -0
  168. package/dist/runner-dir-verify.d.ts.map +1 -0
  169. package/dist/runner-instruction-set-contract.d.ts +24 -0
  170. package/dist/runner-instruction-set-contract.d.ts.map +1 -0
  171. package/dist/runner-instruction-set-contract.js +50 -0
  172. package/dist/sandbox-hygiene.d.ts +45 -0
  173. package/dist/sandbox-hygiene.d.ts.map +1 -0
  174. package/dist/sandbox-provider.d.ts +193 -0
  175. package/dist/sandbox-provider.d.ts.map +1 -0
  176. package/dist/scorer-draft-push.d.ts +50 -0
  177. package/dist/scorer-draft-push.d.ts.map +1 -0
  178. package/dist/scorers-cli.d.ts +20 -0
  179. package/dist/scorers-cli.d.ts.map +1 -0
  180. package/dist/scorers-cli.js +22 -0
  181. package/dist/scorers-verify-parity-bridge.d.ts +16 -0
  182. package/dist/scorers-verify-parity-bridge.d.ts.map +1 -0
  183. package/dist/scorers-verify-parity-bridge.js +90 -0
  184. package/dist/scorers-verify-parity.d.ts +81 -0
  185. package/dist/scorers-verify-parity.d.ts.map +1 -0
  186. package/dist/scorers-verify-parity.js +502 -0
  187. package/dist/scores-accept-cli.d.ts +21 -0
  188. package/dist/scores-accept-cli.d.ts.map +1 -0
  189. package/dist/secret-redaction.d.ts +47 -0
  190. package/dist/secret-redaction.d.ts.map +1 -0
  191. package/dist/session-timeline.d.ts +54 -0
  192. package/dist/session-timeline.d.ts.map +1 -0
  193. package/dist/setup-prompt.d.ts +5 -0
  194. package/dist/setup-prompt.d.ts.map +1 -0
  195. package/dist/skill-installer.d.ts +68 -0
  196. package/dist/skill-installer.d.ts.map +1 -0
  197. package/dist/skilled-proposer-launch.d.ts +7 -0
  198. package/dist/skilled-proposer-launch.d.ts.map +1 -0
  199. package/dist/skilled-proposer-launch.js +60 -0
  200. package/dist/smoke.d.ts +102 -0
  201. package/dist/smoke.d.ts.map +1 -0
  202. package/dist/start-intent.d.ts +12 -0
  203. package/dist/start-intent.d.ts.map +1 -0
  204. package/dist/task-assignment-manifest.d.ts +15 -0
  205. package/dist/task-assignment-manifest.d.ts.map +1 -0
  206. package/dist/task-create-error.d.ts +18 -0
  207. package/dist/task-create-error.d.ts.map +1 -0
  208. package/dist/team-connectors-cli.d.ts +29 -0
  209. package/dist/team-connectors-cli.d.ts.map +1 -0
  210. package/dist/types.d.ts +39 -0
  211. package/dist/types.d.ts.map +1 -0
  212. package/dist/vercel-sandbox-provider.d.ts +156 -0
  213. package/dist/vercel-sandbox-provider.d.ts.map +1 -0
  214. package/dist/workbench-cli.d.ts +233 -0
  215. package/dist/workbench-cli.d.ts.map +1 -0
  216. package/dist/workspace-sync.d.ts +207 -0
  217. package/dist/workspace-sync.d.ts.map +1 -0
  218. package/dist/workspace.d.ts +92 -0
  219. package/dist/workspace.d.ts.map +1 -0
  220. package/dist/zip-draft-push.d.ts +55 -0
  221. package/dist/zip-draft-push.d.ts.map +1 -0
  222. package/package.json +15 -2
  223. package/requirements/README.md +138 -0
  224. package/requirements/skilled-proposer.in +66 -0
  225. package/requirements/skilled-proposer.lock +265 -0
  226. package/scripts/build-cli-dist.mjs +30 -0
  227. package/scripts/ensure-skilled-proposer-venv.mjs +5 -0
  228. package/scripts/orizu-source-checkout.d.mts +1 -0
  229. package/scripts/orizu-source-checkout.mjs +10 -0
  230. package/scripts/refresh-skilled-proposer-lock.mjs +256 -0
  231. package/scripts/vendor-gepa-python.mjs +187 -4
  232. package/src/diff-comments-cli.ts +41 -3
  233. package/src/gepa-engine-dispatch.ts +340 -0
  234. package/src/gepa-python-command.ts +31 -0
  235. package/src/gepa-python-paths.ts +56 -0
  236. package/src/help.ts +95 -25
  237. package/src/index.ts +131 -166
  238. package/src/instruction-set-gepa-launch.ts +28 -0
  239. package/src/instruction-set-loader.ts +37 -0
  240. package/src/instruction-set-manifest.ts +120 -0
  241. package/src/instruction-sets-cli.ts +306 -0
  242. package/src/markdown-report-input.ts +19 -1
  243. package/src/model-configs-cli.ts +119 -0
  244. package/src/optimizations-promote-cli.ts +41 -0
  245. package/src/prompt-label-cli.ts +55 -0
  246. package/src/prompt-length-wire.ts +1 -1
  247. package/src/prompt-report-cli.ts +2 -2
  248. package/src/prompt-summary-table.ts +12 -0
  249. package/src/report-markdown-blankness.ts +6 -0
  250. package/src/report-replacement-warning.ts +35 -0
  251. package/src/runner-instruction-set-contract.ts +64 -0
  252. package/src/scorers-cli.ts +40 -0
  253. package/src/scorers-verify-parity-bridge.ts +90 -0
  254. package/src/scorers-verify-parity.ts +564 -0
  255. package/src/skilled-proposer-launch.ts +89 -0
  256. package/src/skilled-proposer-venv-manager.mjs +757 -0
  257. package/tsconfig.json +2 -0
  258. package/vendor/gepa-python/LICENSE +7 -0
  259. package/vendor/gepa-python/manifest.json +107 -0
  260. package/vendor/gepa-python/src/gepa/__init__.py +22 -0
  261. package/vendor/gepa-python/src/gepa/adapters/__init__.py +0 -0
  262. package/vendor/gepa-python/src/gepa/adapters/anymaths_adapter/__init__.py +1 -0
  263. package/vendor/gepa-python/src/gepa/adapters/anymaths_adapter/anymaths_adapter.py +174 -0
  264. package/vendor/gepa-python/src/gepa/adapters/confidence_adapter/__init__.py +26 -0
  265. package/vendor/gepa-python/src/gepa/adapters/confidence_adapter/confidence_adapter.py +618 -0
  266. package/vendor/gepa-python/src/gepa/adapters/confidence_adapter/scoring.py +206 -0
  267. package/vendor/gepa-python/src/gepa/adapters/default_adapter/__init__.py +0 -0
  268. package/vendor/gepa-python/src/gepa/adapters/default_adapter/default_adapter.py +206 -0
  269. package/vendor/gepa-python/src/gepa/adapters/dspy_adapter/__init__.py +0 -0
  270. package/vendor/gepa-python/src/gepa/adapters/dspy_adapter/dspy_adapter.py +525 -0
  271. package/vendor/gepa-python/src/gepa/adapters/dspy_adapter/instruction_proposal.py +500 -0
  272. package/vendor/gepa-python/src/gepa/adapters/dspy_full_program_adapter/__init__.py +6 -0
  273. package/vendor/gepa-python/src/gepa/adapters/dspy_full_program_adapter/dspy_program_proposal_signature.py +137 -0
  274. package/vendor/gepa-python/src/gepa/adapters/dspy_full_program_adapter/full_program_adapter.py +269 -0
  275. package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/__init__.py +56 -0
  276. package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/evaluation_metrics.py +226 -0
  277. package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/generic_rag_adapter.py +496 -0
  278. package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/rag_pipeline.py +238 -0
  279. package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_store_interface.py +212 -0
  280. package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/__init__.py +2 -0
  281. package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/chroma_store.py +196 -0
  282. package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/lancedb_store.py +422 -0
  283. package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/milvus_store.py +409 -0
  284. package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/qdrant_store.py +368 -0
  285. package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/weaviate_store.py +418 -0
  286. package/vendor/gepa-python/src/gepa/adapters/langchain_adapter/__init__.py +11 -0
  287. package/vendor/gepa-python/src/gepa/adapters/langchain_adapter/langchain_adapter.py +261 -0
  288. package/vendor/gepa-python/src/gepa/adapters/mcp_adapter/__init__.py +37 -0
  289. package/vendor/gepa-python/src/gepa/adapters/mcp_adapter/mcp_adapter.py +693 -0
  290. package/vendor/gepa-python/src/gepa/adapters/mcp_adapter/mcp_client.py +364 -0
  291. package/vendor/gepa-python/src/gepa/adapters/optimize_anything_adapter/optimize_anything_adapter.py +879 -0
  292. package/vendor/gepa-python/src/gepa/adapters/terminal_bench_adapter/__init__.py +0 -0
  293. package/vendor/gepa-python/src/gepa/adapters/terminal_bench_adapter/terminal_bench_adapter.py +217 -0
  294. package/vendor/gepa-python/src/gepa/api.py +468 -0
  295. package/vendor/gepa-python/src/gepa/core/__init__.py +0 -0
  296. package/vendor/gepa-python/src/gepa/core/adapter.py +227 -0
  297. package/vendor/gepa-python/src/gepa/core/callbacks.py +551 -0
  298. package/vendor/gepa-python/src/gepa/core/data_loader.py +74 -0
  299. package/vendor/gepa-python/src/gepa/core/engine.py +1025 -0
  300. package/vendor/gepa-python/src/gepa/core/result.py +271 -0
  301. package/vendor/gepa-python/src/gepa/core/state.py +706 -0
  302. package/vendor/gepa-python/src/gepa/examples/__init__.py +0 -0
  303. package/vendor/gepa-python/src/gepa/examples/aime.py +24 -0
  304. package/vendor/gepa-python/src/gepa/examples/anymaths-bench/eval_default.py +111 -0
  305. package/vendor/gepa-python/src/gepa/examples/anymaths-bench/train_anymaths.py +177 -0
  306. package/vendor/gepa-python/src/gepa/examples/mcp_adapter/__init__.py +4 -0
  307. package/vendor/gepa-python/src/gepa/examples/mcp_adapter/mcp_optimization_example.py +456 -0
  308. package/vendor/gepa-python/src/gepa/examples/rag_adapter/__init__.py +9 -0
  309. package/vendor/gepa-python/src/gepa/examples/rag_adapter/rag_optimization.py +824 -0
  310. package/vendor/gepa-python/src/gepa/examples/terminal-bench/train_terminus.py +161 -0
  311. package/vendor/gepa-python/src/gepa/gepa_utils.py +117 -0
  312. package/vendor/gepa-python/src/gepa/gskill/__init__.py +1 -0
  313. package/vendor/gepa-python/src/gepa/gskill/gskill/__init__.py +0 -0
  314. package/vendor/gepa-python/src/gepa/gskill/gskill/cost_tracker.py +194 -0
  315. package/vendor/gepa-python/src/gepa/gskill/gskill/evaluate/__init__.py +0 -0
  316. package/vendor/gepa-python/src/gepa/gskill/gskill/evaluate/claude_code.py +1117 -0
  317. package/vendor/gepa-python/src/gepa/gskill/gskill/evaluate/claude_code_skills.py +613 -0
  318. package/vendor/gepa-python/src/gepa/gskill/gskill/evaluate/mini_swe_agent.py +440 -0
  319. package/vendor/gepa-python/src/gepa/gskill/gskill/experiment_logger.py +367 -0
  320. package/vendor/gepa-python/src/gepa/gskill/gskill/swe_fitness_fn.py +209 -0
  321. package/vendor/gepa-python/src/gepa/gskill/gskill/swe_harness.py +352 -0
  322. package/vendor/gepa-python/src/gepa/gskill/gskill/train_optimize_anything.py +830 -0
  323. package/vendor/gepa-python/src/gepa/image.py +104 -0
  324. package/vendor/gepa-python/src/gepa/lm.py +261 -0
  325. package/vendor/gepa-python/src/gepa/logging/__init__.py +0 -0
  326. package/vendor/gepa-python/src/gepa/logging/experiment_tracker.py +457 -0
  327. package/vendor/gepa-python/src/gepa/logging/logger.py +75 -0
  328. package/vendor/gepa-python/src/gepa/logging/utils.py +130 -0
  329. package/vendor/gepa-python/src/gepa/optimize_anything.py +1701 -0
  330. package/vendor/gepa-python/src/gepa/proposer/__init__.py +0 -0
  331. package/vendor/gepa-python/src/gepa/proposer/base.py +53 -0
  332. package/vendor/gepa-python/src/gepa/proposer/merge.py +403 -0
  333. package/vendor/gepa-python/src/gepa/proposer/reflective_mutation/__init__.py +0 -0
  334. package/vendor/gepa-python/src/gepa/proposer/reflective_mutation/base.py +64 -0
  335. package/vendor/gepa-python/src/gepa/proposer/reflective_mutation/reflection_lm.py +178 -0
  336. package/vendor/gepa-python/src/gepa/proposer/reflective_mutation/reflective_mutation.py +641 -0
  337. package/vendor/gepa-python/src/gepa/py.typed +0 -0
  338. package/vendor/gepa-python/src/gepa/strategies/__init__.py +0 -0
  339. package/vendor/gepa-python/src/gepa/strategies/acceptance.py +66 -0
  340. package/vendor/gepa-python/src/gepa/strategies/batch_sampler.py +103 -0
  341. package/vendor/gepa-python/src/gepa/strategies/candidate_selector.py +82 -0
  342. package/vendor/gepa-python/src/gepa/strategies/component_selector.py +36 -0
  343. package/vendor/gepa-python/src/gepa/strategies/eval_policy.py +64 -0
  344. package/vendor/gepa-python/src/gepa/strategies/instruction_proposal.py +153 -0
  345. package/vendor/gepa-python/src/gepa/strategies/proposal_sampling.py +128 -0
  346. package/vendor/gepa-python/src/gepa/strategies/proposal_selection.py +84 -0
  347. package/vendor/gepa-python/src/gepa/utils/__init__.py +63 -0
  348. package/vendor/gepa-python/src/gepa/utils/code_execution.py +626 -0
  349. package/vendor/gepa-python/src/gepa/utils/stdio_capture.py +145 -0
  350. package/vendor/gepa-python/src/gepa/utils/stop_condition.py +230 -0
  351. package/vendor/gepa-python/src/gepa/visualization.py +359 -0
  352. package/vendor/orizu-gepa/pyproject.toml +18 -0
  353. package/vendor/orizu-gepa/src/orizu_gepa_connector/__init__.py +9 -0
  354. package/vendor/orizu-gepa/src/orizu_gepa_connector/__main__.py +5 -0
  355. package/vendor/orizu-gepa/src/orizu_gepa_connector/adapter.py +138 -0
  356. package/vendor/orizu-gepa/src/orizu_gepa_connector/callbacks.py +666 -0
  357. package/vendor/orizu-gepa/src/orizu_gepa_connector/cli.py +7 -0
  358. package/vendor/orizu-gepa/src/orizu_gepa_connector/engine.py +269 -0
  359. package/vendor/orizu-gepa/src/orizu_gepa_connector/instruction_set_loader.py +52 -0
  360. package/vendor/orizu-gepa/src/orizu_gepa_connector/preflight.py +64 -0
  361. package/vendor/orizu-gepa/src/orizu_gepa_connector/reflection.py +186 -0
  362. package/vendor/orizu-gepa/src/orizu_gepa_connector/runtime.py +721 -0
  363. package/vendor/orizu-gepa/src/orizu_gepa_connector/skilled_proposer_bridge.py +381 -0
  364. package/vendor/orizu-gepa/src/orizu_gepa_connector/stop_conditions.py +55 -0
  365. package/vendor/orizu-gepa/src/orizu_gepa_connector/translator.py +203 -0
  366. package/vendor/orizu-gepa-python/pyproject.toml +1 -1
  367. package/vendor/orizu-gepa-python/src/orizu_gepa/cli.py +1 -0
  368. package/vendor/orizu-gepa-python/src/orizu_gepa/client.py +52 -7
  369. package/vendor/orizu-gepa-python/src/orizu_gepa/local_log.py +52 -0
  370. package/vendor/orizu-gepa-python/src/orizu_gepa/optimizer.py +10 -5
  371. package/vendor/orizu-gepa-python/src/orizu_gepa/reflection.py +323 -68
  372. package/vendor/orizu-gepa-python/src/orizu_gepa/runner.py +207 -13
  373. package/vendor/skills/orizu-cli/SKILL.md +3 -1
  374. package/vendor/skills/orizu-cli/references/cli-reference.md +85 -1
  375. package/vendor/skills/orizu-cli/references/migrate-existing-gepa-setup.md +303 -0
  376. package/vendor/skills/orizu-cli/references/optimization-reports.md +1 -1
  377. package/vendor/skills/orizu-cli/references/optimization-with-gepa.md +26 -1
  378. package/vendor/skills/orizu-cli/references/prompt-control-plane.md +113 -10
@@ -0,0 +1,359 @@
1
+ # Copyright (c) 2025 Lakshya A Agrawal and the GEPA contributors
2
+ # https://github.com/gepa-ai/gepa
3
+
4
+ """Candidate tree visualization for GEPA optimization runs.
5
+
6
+ Generates Graphviz DOT and self-contained HTML visualizations of the
7
+ candidate lineage tree. No external dependencies are required.
8
+
9
+ Both :class:`~gepa.core.state.GEPAState` and :class:`~gepa.core.result.GEPAResult`
10
+ are supported via thin wrappers that extract the required data and delegate
11
+ to shared ``*_from_data`` functions.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import html
17
+ import json
18
+ from typing import TYPE_CHECKING, Any, Mapping, Sequence
19
+
20
+ if TYPE_CHECKING:
21
+ from gepa.core.state import GEPAState, ProgramIdx
22
+
23
+
24
+ def _escape(text: str) -> str:
25
+ """Escape text for safe inclusion in DOT labels and HTML tooltips."""
26
+ return html.escape(text, quote=True)
27
+
28
+
29
+ # ---------------------------------------------------------------------------
30
+ # Data-driven core (works with raw lists/dicts — no GEPAState required)
31
+ # ---------------------------------------------------------------------------
32
+
33
+
34
+ def candidate_tree_dot_from_data(
35
+ candidates: Sequence[dict[str, str]],
36
+ parents: Sequence[Sequence[int | None]],
37
+ val_scores: Sequence[float],
38
+ pareto_front_programs: Mapping[Any, set[ProgramIdx]],
39
+ ) -> str:
40
+ """Generate a Graphviz DOT string from raw optimization data.
41
+
42
+ Args:
43
+ candidates: List of candidate dicts (index → component name → text).
44
+ parents: ``parents[i]`` is a list of parent indices for candidate *i*.
45
+ val_scores: Per-candidate aggregate validation score.
46
+ pareto_front_programs: Per-val-example best candidate sets.
47
+
48
+ Returns:
49
+ A Graphviz DOT string.
50
+ """
51
+ from gepa.gepa_utils import find_dominator_programs
52
+
53
+ n = len(candidates)
54
+ best_idx = max(range(n), key=lambda i: val_scores[i]) if n > 0 else 0
55
+ dominator_ids = set(find_dominator_programs(pareto_front_programs, list(val_scores)))
56
+
57
+ dot_lines = [
58
+ "digraph G {",
59
+ " rankdir=TB;",
60
+ " node [style=filled, shape=circle, fontsize=14, width=0.6, height=0.6];",
61
+ ]
62
+
63
+ for idx in range(n):
64
+ score = val_scores[idx]
65
+ candidate = candidates[idx]
66
+ pars = parents[idx]
67
+
68
+ # Tooltip
69
+ tooltip_parts = [f"Candidate {idx}"]
70
+ tooltip_parts.append(f"Val Score: {score:.4f}")
71
+ parent_str = ", ".join(str(p) for p in pars if p is not None) or "seed"
72
+ tooltip_parts.append(f"Parent(s): {parent_str}")
73
+ if idx == best_idx:
74
+ tooltip_parts.append("Role: BEST")
75
+ elif idx in dominator_ids:
76
+ tooltip_parts.append("Role: Pareto Front")
77
+ elif idx == 0:
78
+ tooltip_parts.append("Role: Seed")
79
+ tooltip_parts.append("")
80
+ for comp_name, comp_text in sorted(candidate.items()):
81
+ tooltip_parts.append(f"--- {comp_name} ---")
82
+ tooltip_parts.append(comp_text)
83
+
84
+ tooltip = _escape("\n".join(tooltip_parts))
85
+ label = f"{idx}\\n({score:.2f})"
86
+
87
+ if idx == best_idx:
88
+ color = "cyan"
89
+ elif idx in dominator_ids:
90
+ color = "orange"
91
+ else:
92
+ color = "lightgray"
93
+
94
+ dot_lines.append(f' {idx} [label="{label}", fillcolor={color}, tooltip=" "];')
95
+
96
+ for child in range(n):
97
+ for parent in parents[child]:
98
+ if parent is not None:
99
+ dot_lines.append(f" {parent} -> {child};")
100
+
101
+ dot_lines.append("}")
102
+ return "\n".join(dot_lines)
103
+
104
+
105
+ def candidate_tree_html_from_data(
106
+ candidates: Sequence[dict[str, str]],
107
+ parents: Sequence[Sequence[int | None]],
108
+ val_scores: Sequence[float],
109
+ pareto_front_programs: Mapping[Any, set[ProgramIdx]],
110
+ ) -> str:
111
+ """Generate a self-contained HTML page from raw optimization data.
112
+
113
+ The page uses ``@viz-js/viz`` loaded from a CDN to render the DOT
114
+ graph client-side. Hovering over a node shows a rich tooltip with
115
+ the full candidate text and metadata.
116
+
117
+ Args:
118
+ candidates: List of candidate dicts.
119
+ parents: Lineage list.
120
+ val_scores: Per-candidate aggregate val scores.
121
+ pareto_front_programs: Pareto front mapping.
122
+
123
+ Returns:
124
+ A self-contained HTML string.
125
+ """
126
+ from gepa.gepa_utils import find_dominator_programs
127
+
128
+ n = len(candidates)
129
+ best_idx = max(range(n), key=lambda i: val_scores[i]) if n > 0 else 0
130
+ dominator_ids = set(find_dominator_programs(pareto_front_programs, list(val_scores)))
131
+
132
+ nodes_json_parts: list[str] = []
133
+ for idx in range(n):
134
+ candidate = candidates[idx]
135
+ pars = parents[idx]
136
+ parent_str = ", ".join(str(p) for p in pars if p is not None) or "seed"
137
+
138
+ if idx == best_idx:
139
+ role = "Best"
140
+ elif idx in dominator_ids:
141
+ role = "Pareto Front"
142
+ elif idx == 0:
143
+ role = "Seed"
144
+ else:
145
+ role = ""
146
+
147
+ node_data = {
148
+ "idx": idx,
149
+ "score": round(val_scores[idx], 4),
150
+ "parents": parent_str,
151
+ "role": role,
152
+ "components": dict(sorted(candidate.items())),
153
+ }
154
+ nodes_json_parts.append(json.dumps(node_data))
155
+
156
+ nodes_json = "[" + ",\n".join(nodes_json_parts) + "]"
157
+ dot_string = candidate_tree_dot_from_data(candidates, parents, val_scores, pareto_front_programs)
158
+ dot_escaped = dot_string.replace("\\", "\\\\").replace("`", "\\`").replace("${", "\\${")
159
+
160
+ return _HTML_TEMPLATE.replace("__DOT_STRING__", dot_escaped).replace("__NODES_JSON__", nodes_json)
161
+
162
+
163
+ # ---------------------------------------------------------------------------
164
+ # GEPAState convenience wrappers
165
+ # ---------------------------------------------------------------------------
166
+
167
+
168
+ def candidate_tree_dot(state: GEPAState) -> str:
169
+ """Generate a Graphviz DOT string from a :class:`GEPAState`."""
170
+ return candidate_tree_dot_from_data(
171
+ candidates=state.program_candidates,
172
+ parents=state.parent_program_for_candidate,
173
+ val_scores=state.program_full_scores_val_set,
174
+ pareto_front_programs=state.program_at_pareto_front_valset,
175
+ )
176
+
177
+
178
+ def candidate_tree_html(state: GEPAState) -> str:
179
+ """Generate a self-contained HTML page from a :class:`GEPAState`."""
180
+ return candidate_tree_html_from_data(
181
+ candidates=state.program_candidates,
182
+ parents=state.parent_program_for_candidate,
183
+ val_scores=state.program_full_scores_val_set,
184
+ pareto_front_programs=state.program_at_pareto_front_valset,
185
+ )
186
+
187
+
188
+ # ---------------------------------------------------------------------------
189
+ # HTML template
190
+ # ---------------------------------------------------------------------------
191
+
192
+ _HTML_TEMPLATE = """\
193
+ <!DOCTYPE html>
194
+ <html lang="en">
195
+ <head>
196
+ <meta charset="UTF-8">
197
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
198
+ <title>GEPA Candidate Tree</title>
199
+ <style>
200
+ * { margin: 0; padding: 0; box-sizing: border-box; }
201
+ html, body { height: 100%; width: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #f8f9fa; display: flex; flex-direction: column; }
202
+ #header { background: #fff; border-bottom: 1px solid #dee2e6; padding: 12px 20px; display: flex; align-items: center; gap: 16px; flex-shrink: 0; }
203
+ #header h1 { font-size: 18px; font-weight: 600; color: #212529; }
204
+ .legend { display: flex; gap: 14px; font-size: 13px; color: #495057; }
205
+ .legend-item { display: flex; align-items: center; gap: 4px; }
206
+ .legend-dot { width: 12px; height: 12px; border-radius: 50%; border: 1px solid #adb5bd; }
207
+ #graph-container { flex: 1 1 auto; width: 100%; overflow: auto; padding: 20px; text-align: center; }
208
+ #graph-container svg { width: 100%; height: 100%; }
209
+ #tooltip {
210
+ display: none; position: fixed; background: #fff; border: 1px solid #dee2e6;
211
+ border-radius: 8px; padding: 14px 16px; max-width: 560px; max-height: 70vh; overflow-y: auto;
212
+ box-shadow: 0 4px 16px rgba(0,0,0,0.18); z-index: 1000; font-size: 13px; line-height: 1.5;
213
+ }
214
+ #tooltip .tt-header { font-weight: 700; font-size: 15px; margin-bottom: 6px; color: #212529; }
215
+ #tooltip .tt-meta { color: #6c757d; margin-bottom: 4px; }
216
+ #tooltip .tt-hint { color: #adb5bd; font-size: 11px; font-style: italic; margin-bottom: 10px; }
217
+ #tooltip .tt-comp-name { font-weight: 600; color: #495057; margin-top: 10px; border-bottom: 1px solid #e9ecef; padding-bottom: 2px; }
218
+ #tooltip .tt-comp-text {
219
+ white-space: pre-wrap; word-break: break-word; background: #f8f9fa;
220
+ border: 1px solid #e9ecef; border-radius: 4px; padding: 8px 10px; margin-top: 4px;
221
+ font-family: "SF Mono", SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px;
222
+ max-height: 200px; overflow-y: auto;
223
+ }
224
+ .role-badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; margin-left: 6px; }
225
+ .role-best { background: #00e5ff33; color: #006064; }
226
+ .role-pareto { background: #ff980033; color: #e65100; }
227
+ .role-seed { background: #e0e0e0; color: #424242; }
228
+ </style>
229
+ </head>
230
+ <body>
231
+ <div id="header">
232
+ <h1>GEPA Candidate Tree</h1>
233
+ <div class="legend">
234
+ <div class="legend-item"><div class="legend-dot" style="background:cyan"></div> Best</div>
235
+ <div class="legend-item"><div class="legend-dot" style="background:orange"></div> Pareto Front</div>
236
+ <div class="legend-item"><div class="legend-dot" style="background:lightgray"></div> Other</div>
237
+ </div>
238
+ </div>
239
+ <div id="graph-container"><p>Loading graph&hellip;</p></div>
240
+ <div id="tooltip"></div>
241
+
242
+ <script type="module">
243
+ const NODES = __NODES_JSON__;
244
+ const DOT = `__DOT_STRING__`;
245
+
246
+ const nodeMap = {};
247
+ NODES.forEach(n => { nodeMap[n.idx] = n; });
248
+
249
+ let pinnedIdx = null; // non-null when tooltip is click-pinned (scrollable)
250
+ let hoverIdx = null; // non-null when hovering over a node
251
+
252
+ function renderTooltip(idx) {
253
+ const n = nodeMap[idx];
254
+ if (!n) return "";
255
+ let roleBadge = "";
256
+ if (n.role === "Best") roleBadge = '<span class="role-badge role-best">BEST</span>';
257
+ else if (n.role === "Pareto Front") roleBadge = '<span class="role-badge role-pareto">PARETO</span>';
258
+ else if (n.role === "Seed") roleBadge = '<span class="role-badge role-seed">SEED</span>';
259
+
260
+ let comps = "";
261
+ for (const [name, text] of Object.entries(n.components)) {
262
+ const escaped = text.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
263
+ comps += '<div class="tt-comp-name">' + name + '</div><div class="tt-comp-text">' + escaped + '</div>';
264
+ }
265
+
266
+ return '<div class="tt-header">Candidate ' + n.idx + roleBadge + '</div>' +
267
+ '<div class="tt-meta">Score: <strong>' + n.score + '</strong>&nbsp;&nbsp;|&nbsp;&nbsp;Parent(s): ' + n.parents +
268
+ '</div><div class="tt-hint">' + (pinnedIdx === idx ? 'Click node again to dismiss' : 'Click to pin &amp; scroll') + '</div>' +
269
+ comps;
270
+ }
271
+
272
+ function positionTooltip(x, y) {
273
+ const tt = document.getElementById("tooltip");
274
+ let tx = x + 16, ty = y + 16;
275
+ const r = tt.getBoundingClientRect();
276
+ if (tx + r.width > window.innerWidth - 8) tx = x - r.width - 16;
277
+ if (ty + r.height > window.innerHeight - 8) ty = y - r.height - 16;
278
+ if (tx < 8) tx = 8;
279
+ if (ty < 8) ty = 8;
280
+ tt.style.left = tx + "px";
281
+ tt.style.top = ty + "px";
282
+ }
283
+
284
+ function showTooltip(idx, x, y) {
285
+ const tt = document.getElementById("tooltip");
286
+ tt.innerHTML = renderTooltip(idx);
287
+ tt.style.display = "block";
288
+ positionTooltip(x, y);
289
+ }
290
+
291
+ function hideTooltip() {
292
+ pinnedIdx = null;
293
+ hoverIdx = null;
294
+ document.getElementById("tooltip").style.display = "none";
295
+ }
296
+
297
+ // Click outside tooltip and outside nodes dismisses pinned tooltip
298
+ document.addEventListener("mousedown", function(e) {
299
+ const tt = document.getElementById("tooltip");
300
+ if (pinnedIdx !== null && tt.style.display === "block"
301
+ && !tt.contains(e.target) && !e.target.closest(".node")) {
302
+ hideTooltip();
303
+ }
304
+ });
305
+
306
+ async function render() {
307
+ const { instance } = await import("https://cdn.jsdelivr.net/npm/@viz-js/viz@3.11.0/lib/viz-standalone.mjs");
308
+ const viz = await instance();
309
+ const svg = viz.renderSVGElement(DOT);
310
+ const container = document.getElementById("graph-container");
311
+ container.innerHTML = "";
312
+ container.appendChild(svg);
313
+
314
+ // Attach hover listeners and strip native <title> tooltips to avoid double tooltips
315
+ svg.querySelectorAll(".node").forEach(node => {
316
+ const title = node.querySelector("title");
317
+ if (!title) return;
318
+ const idx = parseInt(title.textContent, 10);
319
+ if (isNaN(idx)) return;
320
+ title.remove(); // remove native SVG tooltip
321
+ node.style.cursor = "pointer";
322
+ // Hover: show tooltip following the mouse (non-interactive)
323
+ node.addEventListener("mouseenter", e => {
324
+ if (pinnedIdx !== null) return; // don't override a pinned tooltip
325
+ hoverIdx = idx;
326
+ showTooltip(idx, e.clientX, e.clientY);
327
+ });
328
+ node.addEventListener("mousemove", e => {
329
+ if (pinnedIdx !== null || hoverIdx !== idx) return;
330
+ positionTooltip(e.clientX, e.clientY);
331
+ });
332
+ node.addEventListener("mouseleave", () => {
333
+ if (pinnedIdx !== null) return;
334
+ hoverIdx = null;
335
+ document.getElementById("tooltip").style.display = "none";
336
+ });
337
+ // Click: pin the tooltip so user can scroll it
338
+ node.addEventListener("click", e => {
339
+ e.stopPropagation();
340
+ if (pinnedIdx === idx) { hideTooltip(); return; }
341
+ pinnedIdx = idx;
342
+ showTooltip(idx, e.clientX, e.clientY);
343
+ });
344
+ });
345
+ // Also strip <title> from edges and the graph itself
346
+ svg.querySelectorAll(".edge title").forEach(t => t.remove());
347
+ const graphTitle = svg.querySelector(":scope > title");
348
+ if (graphTitle) graphTitle.remove();
349
+ }
350
+
351
+ render().catch(err => {
352
+ document.getElementById("graph-container").innerHTML =
353
+ "<p style='color:red'>Failed to render graph: " + err.message + "</p>" +
354
+ "<pre>" + DOT.replace(/</g,"&lt;") + "</pre>";
355
+ });
356
+ </script>
357
+ </body>
358
+ </html>
359
+ """
@@ -0,0 +1,18 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "orizu-gepa"
7
+ version = "0.0.0"
8
+ description = "Official GEPA connector for Orizu."
9
+ requires-python = ">=3.10"
10
+ # M1 imports frozen ``orizu_gepa`` directly from PYTHONPATH. Packaging that
11
+ # sibling source is deferred to M2 / ALI-1503; do not add a pip dependency.
12
+ dependencies = ["gepa==0.1.4"]
13
+
14
+ [project.scripts]
15
+ orizu-gepa-connector = "orizu_gepa_connector.cli:main"
16
+
17
+ [tool.setuptools.packages.find]
18
+ where = ["src"]
@@ -0,0 +1,9 @@
1
+ """Official-GEPA connector namespace."""
2
+
3
+ from .adapter import RunnerEvaluationAdapter
4
+ from .callbacks import LifecycleHooks, OrizuCallback
5
+ from .engine import SeedValidationRefused, run_official_gepa
6
+ from .cli import main
7
+ from .instruction_set_loader import load_instruction_set
8
+
9
+ __all__ = ["LifecycleHooks", "OrizuCallback", "RunnerEvaluationAdapter", "SeedValidationRefused", "load_instruction_set", "main", "run_official_gepa"]
@@ -0,0 +1,5 @@
1
+ from .cli import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ main()
@@ -0,0 +1,138 @@
1
+ """Official GEPA adapter backed by Orizu's existing runner subprocess contract."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from typing import Any
7
+
8
+ from gepa.core.adapter import EvaluationBatch
9
+
10
+ # Import the frozen contract rather than duplicating subprocess/env handling.
11
+ from orizu_gepa.optimizer import Budget, RowEvaluation, evaluate_candidate, resolve_num_threads
12
+ from orizu_gepa.runner import make_candidate_runner, make_scorer_runner
13
+
14
+
15
+ class ScorerContractError(RuntimeError):
16
+ """The scorer runner returned a shape the frozen scorer contract rejects."""
17
+
18
+
19
+ class RunnerEvaluationAdapter:
20
+ """GEPAAdapter implementation with per-row Orizu side information."""
21
+
22
+ # GEPA 0.1.4 reads this optional protocol member directly. ``None`` hands
23
+ # proposal generation to its ReflectionLM, which is our frozen provider
24
+ # bridge supplied by ``run_official_gepa``.
25
+ propose_new_texts = None
26
+
27
+ def __init__(
28
+ self,
29
+ *,
30
+ candidate_runner_dir: str,
31
+ scorer_runner_dir: str,
32
+ run_id: str | None,
33
+ prompt_context: Any,
34
+ scorer_context: Any,
35
+ scorer_input_contract: str | None = None,
36
+ scorer_candidate_field: str | None = None,
37
+ num_threads: int | str = "auto",
38
+ minibatch_size: int | None = None,
39
+ validation_count: int = 0,
40
+ ):
41
+ self.prompt_context = prompt_context
42
+ self.scorer_context = scorer_context
43
+ self.scorer_runner_dir = scorer_runner_dir
44
+ self.candidate_runner = make_candidate_runner(candidate_runner_dir, run_id)
45
+ self.scorer_runner = make_scorer_runner(
46
+ scorer_runner_dir,
47
+ run_id,
48
+ input_contract=scorer_input_contract,
49
+ candidate_field=scorer_candidate_field,
50
+ )
51
+ # Use the frozen memory-/CPU-/FD-bounded plan; the adapter only
52
+ # supplies official GEPA's EvaluationBatch boundary around it.
53
+ self.num_threads_plan = resolve_num_threads(
54
+ num_threads,
55
+ minibatch_size=minibatch_size or 1,
56
+ validation_count=validation_count,
57
+ )
58
+ self.metric_calls_used = 0
59
+ self.last_row_evaluations: list[RowEvaluation] = []
60
+ self.last_candidate: dict[str, str] | None = None
61
+
62
+ def evaluate(self, batch: list[Any], candidate: dict[str, str], capture_traces: bool = False) -> EvaluationBatch:
63
+ # The exec-context can describe a multi-component wrapper for a
64
+ # legacy prompt run. The candidate is the execution contract: only a
65
+ # map with more than one value is a tuple rewrite.
66
+ is_multi_component_tuple = len(candidate) > 1
67
+ component = next(iter(candidate))
68
+ candidate_text: str | dict[str, str] = dict(candidate) if is_multi_component_tuple else candidate[component]
69
+ candidate_id = json.dumps(candidate, sort_keys=True, separators=(",", ":")) if is_multi_component_tuple else component
70
+ outputs: list[dict[str, Any]] = []
71
+ scores: list[float] = []
72
+ trajectories: list[dict[str, Any]] = []
73
+ for row in batch:
74
+ if not hasattr(row, "id"):
75
+ raise TypeError("RunnerEvaluationAdapter requires legacy DatasetRow inputs")
76
+ # The frozen evaluator owns both scorer extraction and bounded worker
77
+ # scheduling. In particular, ``score_from_scorer`` preserves the
78
+ # model_response.feedback/reasoning fallback used by legacy runs.
79
+ budget = Budget("max_metric_calls", max(1, len(batch)))
80
+ try:
81
+ row_evaluations = evaluate_candidate(
82
+ candidate_text=candidate_text,
83
+ candidate_id=candidate_id,
84
+ rows=batch,
85
+ split="official_gepa",
86
+ prompt_context=self.prompt_context,
87
+ scorer_context=self.scorer_context,
88
+ candidate_runner=self.candidate_runner,
89
+ scorer_runner=self.scorer_runner,
90
+ budget=budget,
91
+ num_threads=self.num_threads_plan.resolved,
92
+ )
93
+ except ValueError as error:
94
+ if str(error).startswith("Scorer result"):
95
+ raise ScorerContractError(
96
+ "scorer contract failure for "
97
+ f"{self.scorer_runner_dir}: {error}"
98
+ ) from error
99
+ raise
100
+
101
+ self.metric_calls_used += budget.used_metric_calls
102
+ for evaluation in row_evaluations:
103
+ raw_score = evaluation.score
104
+ # Official GEPA maximizes. Preserve the legacy scorer direction by
105
+ # normalizing lower-is-better metrics before they enter its state.
106
+ score = raw_score if self.scorer_context.higher_is_better else 1.0 - raw_score
107
+ scores.append(score)
108
+ outputs.append({
109
+ "row_id": evaluation.row_id,
110
+ "output": evaluation.output,
111
+ "raw_score": raw_score,
112
+ "feedback": evaluation.feedback,
113
+ "error": evaluation.error,
114
+ "error_source": evaluation.error_source,
115
+ "scorer_output": evaluation.scorer_response,
116
+ "scorer_error": evaluation.error if evaluation.error_source == "scorer" else None,
117
+ "cached": evaluation.cached,
118
+ "latency_ms": evaluation.latency_ms,
119
+ "token_in": evaluation.token_in,
120
+ "token_out": evaluation.token_out,
121
+ "cost_usd": evaluation.cost_usd,
122
+ })
123
+ if capture_traces:
124
+ trajectories.append({
125
+ "row_id": evaluation.row_id,
126
+ "Feedback": evaluation.feedback,
127
+ "error": evaluation.error,
128
+ "output": evaluation.output,
129
+ })
130
+ self.last_row_evaluations = row_evaluations
131
+ self.last_candidate = dict(candidate)
132
+ return EvaluationBatch(outputs=outputs, scores=scores, trajectories=trajectories if capture_traces else None,
133
+ num_metric_calls=len(batch))
134
+
135
+ def make_reflective_dataset(self, candidate: dict[str, str], evaluation: EvaluationBatch,
136
+ components_to_update: list[str]) -> dict[str, list[dict[str, Any]]]:
137
+ return {component: [{"Feedback": trace.get("Feedback"), "Generated Outputs": trace.get("output")}
138
+ for trace in (evaluation.trajectories or [])] for component in components_to_update}