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,500 @@
1
+ import json
2
+ import logging
3
+ from typing import Any
4
+
5
+ import dspy
6
+ from dspy.adapters.types.base_type import Type
7
+
8
+ from gepa.core.adapter import ProposalFn
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ # Type alias for reflective examples
14
+ ReflectiveExample = dict[str, Any]
15
+
16
+
17
+ class GenerateEnhancedMultimodalInstructionFromFeedback(dspy.Signature):
18
+ """I provided an assistant with instructions to perform a task involving visual content, but the assistant's performance needs improvement based on the examples and feedback below.
19
+
20
+ Your task is to write a better instruction for the assistant that addresses the specific issues identified in the feedback, with particular attention to how visual and textual information should be analyzed and integrated.
21
+
22
+ ## Analysis Steps:
23
+ 1. **Read the inputs carefully** and identify both the visual and textual input formats, understanding how they work together
24
+ 2. **Read all the assistant responses and corresponding feedback** to understand what went wrong with visual analysis, text processing, or their integration
25
+ 3. **Identify visual analysis patterns** - what visual features, relationships, or details are important for this task
26
+ 4. **Identify domain-specific knowledge** about both visual and textual aspects, as this information may not be available to the assistant in the future
27
+ 5. **Look for successful visual-textual integration strategies** and include these patterns in the instruction
28
+ 6. **Address specific visual analysis issues** mentioned in the feedback
29
+
30
+ ## Instruction Requirements:
31
+ - **Clear task definition** explaining how to process both visual and textual inputs
32
+ - **Visual analysis guidance** specific to this task (what to look for, how to describe, what features matter)
33
+ - **Integration strategies** for combining visual observations with textual information
34
+ - **Domain-specific knowledge** about visual concepts, terminology, or relationships
35
+ - **Error prevention guidance** for common visual analysis mistakes shown in the feedback
36
+ - **Precise, actionable language** for both visual and textual processing
37
+
38
+ Focus on creating an instruction that helps the assistant properly analyze visual content, integrate it with textual information, and avoid the specific visual analysis mistakes shown in the examples."""
39
+
40
+ current_instruction = dspy.InputField(
41
+ desc="The current instruction that was provided to the assistant to perform the multimodal task"
42
+ )
43
+ examples_with_feedback = dspy.InputField(
44
+ desc="Task examples with visual content showing inputs, assistant outputs, and feedback. "
45
+ "Pay special attention to feedback about visual analysis accuracy, visual-textual integration, "
46
+ "and any domain-specific visual knowledge that the assistant missed."
47
+ )
48
+
49
+ improved_instruction = dspy.OutputField(
50
+ desc="A better instruction for the assistant that addresses visual analysis issues, provides "
51
+ "clear guidance on how to process and integrate visual and textual information, includes "
52
+ "necessary visual domain knowledge, and prevents the visual analysis mistakes shown in the examples."
53
+ )
54
+
55
+
56
+ class SingleComponentMultiModalProposer(dspy.Module):
57
+ """
58
+ dspy.Module for proposing improved instructions based on feedback.
59
+ """
60
+
61
+ def __init__(self):
62
+ super().__init__()
63
+ self.propose_instruction = dspy.Predict(GenerateEnhancedMultimodalInstructionFromFeedback)
64
+
65
+ def forward(self, current_instruction: str, reflective_dataset: list[ReflectiveExample]) -> str:
66
+ """
67
+ Generate an improved instruction based on current instruction and feedback examples.
68
+
69
+ Args:
70
+ current_instruction: The current instruction that needs improvement
71
+ reflective_dataset: List of examples with inputs, outputs, and feedback
72
+ May contain dspy.Image objects in inputs
73
+
74
+ Returns:
75
+ str: Improved instruction text
76
+ """
77
+ # Format examples with enhanced pattern recognition
78
+ formatted_examples, image_map = self._format_examples_with_pattern_analysis(reflective_dataset)
79
+
80
+ # Build kwargs for the prediction call
81
+ predict_kwargs = {
82
+ "current_instruction": current_instruction,
83
+ "examples_with_feedback": formatted_examples,
84
+ }
85
+
86
+ # Create a rich multimodal examples_with_feedback that includes both text and images
87
+ predict_kwargs["examples_with_feedback"] = self._create_multimodal_examples(formatted_examples, image_map)
88
+
89
+ # Use current dspy LM settings (GEPA will pass reflection_lm via context)
90
+ result = self.propose_instruction(**predict_kwargs)
91
+
92
+ return result.improved_instruction
93
+
94
+ def _format_examples_with_pattern_analysis(
95
+ self, reflective_dataset: list[ReflectiveExample]
96
+ ) -> tuple[str, dict[int, list[Type]]]:
97
+ """
98
+ Format examples with pattern analysis and feedback categorization.
99
+
100
+ Returns:
101
+ tuple: (formatted_text_with_patterns, image_map)
102
+ """
103
+ # First, use the existing proven formatting approach
104
+ formatted_examples, image_map = self._format_examples_for_instruction_generation(reflective_dataset)
105
+
106
+ # Enhanced analysis: categorize feedback patterns
107
+ feedback_analysis = self._analyze_feedback_patterns(reflective_dataset)
108
+
109
+ # Add pattern analysis to the formatted examples
110
+ if feedback_analysis["summary"]:
111
+ pattern_summary = self._create_pattern_summary(feedback_analysis)
112
+ enhanced_examples = f"{pattern_summary}\n\n{formatted_examples}"
113
+ return enhanced_examples, image_map
114
+
115
+ return formatted_examples, image_map
116
+
117
+ def _analyze_feedback_patterns(self, reflective_dataset: list[ReflectiveExample]) -> dict[str, Any]:
118
+ """
119
+ Analyze feedback patterns to provide better context for instruction generation.
120
+
121
+ Categorizes feedback into:
122
+ - Error patterns: Common mistakes and their types
123
+ - Success patterns: What worked well and should be preserved/emphasized
124
+ - Domain knowledge gaps: Missing information that should be included
125
+ - Task-specific guidance: Specific requirements or edge cases
126
+ """
127
+ analysis = {
128
+ "error_patterns": [],
129
+ "success_patterns": [],
130
+ "domain_knowledge_gaps": [],
131
+ "task_specific_guidance": [],
132
+ "summary": "",
133
+ }
134
+
135
+ # Simple pattern recognition - could be enhanced further
136
+ for example in reflective_dataset:
137
+ feedback = example.get("Feedback", "").lower()
138
+
139
+ # Identify error patterns
140
+ if any(error_word in feedback for error_word in ["incorrect", "wrong", "error", "failed", "missing"]):
141
+ analysis["error_patterns"].append(feedback)
142
+
143
+ # Identify success patterns
144
+ if any(
145
+ success_word in feedback for success_word in ["correct", "good", "accurate", "well", "successfully"]
146
+ ):
147
+ analysis["success_patterns"].append(feedback)
148
+
149
+ # Identify domain knowledge needs
150
+ if any(
151
+ knowledge_word in feedback
152
+ for knowledge_word in ["should know", "domain", "specific", "context", "background"]
153
+ ):
154
+ analysis["domain_knowledge_gaps"].append(feedback)
155
+
156
+ # Create summary if patterns were found
157
+ if any(analysis[key] for key in ["error_patterns", "success_patterns", "domain_knowledge_gaps"]):
158
+ analysis["summary"] = (
159
+ f"Patterns identified: {len(analysis['error_patterns'])} error(s), {len(analysis['success_patterns'])} success(es), {len(analysis['domain_knowledge_gaps'])} knowledge gap(s)"
160
+ )
161
+
162
+ return analysis
163
+
164
+ def _create_pattern_summary(self, feedback_analysis: dict[str, Any]) -> str:
165
+ """Create a summary of feedback patterns to help guide instruction generation."""
166
+
167
+ summary_parts = ["## Feedback Pattern Analysis\n"]
168
+
169
+ if feedback_analysis["error_patterns"]:
170
+ summary_parts.append(f"**Common Issues Found ({len(feedback_analysis['error_patterns'])} examples):**")
171
+ summary_parts.append("Focus on preventing these types of mistakes in the new instruction.\n")
172
+
173
+ if feedback_analysis["success_patterns"]:
174
+ summary_parts.append(
175
+ f"**Successful Approaches Found ({len(feedback_analysis['success_patterns'])} examples):**"
176
+ )
177
+ summary_parts.append("Build on these successful strategies in the new instruction.\n")
178
+
179
+ if feedback_analysis["domain_knowledge_gaps"]:
180
+ summary_parts.append(
181
+ f"**Domain Knowledge Needs Identified ({len(feedback_analysis['domain_knowledge_gaps'])} examples):**"
182
+ )
183
+ summary_parts.append("Include this specialized knowledge in the new instruction.\n")
184
+
185
+ return "\n".join(summary_parts)
186
+
187
+ def _format_examples_for_instruction_generation(
188
+ self, reflective_dataset: list[ReflectiveExample]
189
+ ) -> tuple[str, dict[int, list[Type]]]:
190
+ """
191
+ Format examples using GEPA's markdown structure while preserving image objects.
192
+
193
+ Returns:
194
+ tuple: (formatted_text, image_map) where image_map maps example_index -> list[images]
195
+ """
196
+
197
+ def render_value_with_images(value, level=3, example_images=None):
198
+ if example_images is None:
199
+ example_images = []
200
+
201
+ if isinstance(value, Type):
202
+ image_idx = len(example_images) + 1
203
+ example_images.append(value)
204
+ return f"[IMAGE-{image_idx} - see visual content]\n\n"
205
+ elif isinstance(value, dict):
206
+ s = ""
207
+ for k, v in value.items():
208
+ s += f"{'#' * level} {k}\n"
209
+ s += render_value_with_images(v, min(level + 1, 6), example_images)
210
+ if not value:
211
+ s += "\n"
212
+ return s
213
+ elif isinstance(value, list | tuple):
214
+ s = ""
215
+ for i, item in enumerate(value):
216
+ s += f"{'#' * level} Item {i + 1}\n"
217
+ s += render_value_with_images(item, min(level + 1, 6), example_images)
218
+ if not value:
219
+ s += "\n"
220
+ return s
221
+ else:
222
+ return f"{str(value).strip()}\n\n"
223
+
224
+ def convert_sample_to_markdown_with_images(sample, example_num):
225
+ example_images = []
226
+ s = f"# Example {example_num}\n"
227
+
228
+ for key, val in sample.items():
229
+ s += f"## {key}\n"
230
+ s += render_value_with_images(val, level=3, example_images=example_images)
231
+
232
+ return s, example_images
233
+
234
+ formatted_parts = []
235
+ image_map = {}
236
+
237
+ for i, example_data in enumerate(reflective_dataset):
238
+ formatted_example, example_images = convert_sample_to_markdown_with_images(example_data, i + 1)
239
+ formatted_parts.append(formatted_example)
240
+
241
+ if example_images:
242
+ image_map[i] = example_images
243
+
244
+ formatted_text = "\n\n".join(formatted_parts)
245
+
246
+ if image_map:
247
+ total_images = sum(len(imgs) for imgs in image_map.values())
248
+ formatted_text = (
249
+ f"The examples below include visual content ({total_images} images total). "
250
+ "Please analyze both the text and visual elements when suggesting improvements.\n\n" + formatted_text
251
+ )
252
+
253
+ return formatted_text, image_map
254
+
255
+ def _create_multimodal_examples(self, formatted_text: str, image_map: dict[int, list[Type]]) -> Any:
256
+ """
257
+ Create a multimodal input that contains both text and images for the reflection LM.
258
+
259
+ Args:
260
+ formatted_text: The formatted text with image placeholders
261
+ image_map: Dictionary mapping example_index -> list[images] for structured access
262
+ """
263
+ if not image_map:
264
+ return formatted_text
265
+
266
+ # Collect all images from all examples
267
+ all_images = []
268
+ for example_images in image_map.values():
269
+ all_images.extend(example_images)
270
+
271
+ multimodal_content = [formatted_text]
272
+ multimodal_content.extend(all_images)
273
+ return multimodal_content
274
+
275
+
276
+ class MultiModalInstructionProposer(ProposalFn):
277
+ """GEPA-compatible multimodal instruction proposer.
278
+
279
+ This class handles multimodal inputs (like dspy.Image) during GEPA optimization by using
280
+ a single-component proposer for each component that needs to be updated.
281
+ """
282
+
283
+ def __init__(self):
284
+ self.single_proposer = SingleComponentMultiModalProposer()
285
+
286
+ def __call__(
287
+ self,
288
+ candidate: dict[str, str],
289
+ reflective_dataset: dict[str, list[ReflectiveExample]],
290
+ components_to_update: list[str],
291
+ ) -> dict[str, str]:
292
+ """GEPA-compatible proposal function.
293
+
294
+ Args:
295
+ candidate: Current component name -> instruction mapping
296
+ reflective_dataset: Component name -> list of reflective examples
297
+ components_to_update: List of component names to update
298
+
299
+ Returns:
300
+ dict: Component name -> new instruction mapping
301
+ """
302
+ updated_components = {}
303
+
304
+ for component_name in components_to_update:
305
+ if component_name in candidate and component_name in reflective_dataset:
306
+ current_instruction = candidate[component_name]
307
+ component_reflective_data = reflective_dataset[component_name]
308
+
309
+ # Call the single-instruction proposer.
310
+ #
311
+ # In the future, proposals could consider multiple components instructions,
312
+ # instead of just the current instruction, for more holistic instruction proposals.
313
+ new_instruction = self.single_proposer(
314
+ current_instruction=current_instruction, reflective_dataset=component_reflective_data
315
+ )
316
+
317
+ updated_components[component_name] = new_instruction
318
+
319
+ return updated_components
320
+
321
+
322
+ class GenerateImprovedToolModuleDescriptionsFromFeedback(dspy.Signature):
323
+ """I provided an assistant with predictor instructions and tool descriptions,
324
+ but its performance needs improvement based on the examples_with_feedback below.
325
+
326
+ Your task is to propose better predictor instructions, tool descriptions, and tool argument descriptions that address the issues shown in these examples.
327
+ Focus on reinforcing patterns that clearly improve the assistant's performance on similar tasks, rather than rewriting everything from scratch unless necessary.
328
+ These components are progressively optimized - refine only what needs to change.
329
+
330
+ Analyze the examples_with_feedback to identify success and failure patterns, and write improved instructions and descriptions at their appropriate level of abstraction and/or specificity,
331
+ so that each layer plays a clear, complementary role without unnecessary repetition or verbosity unless redundancy clearly helps the assistant's performance.
332
+ """
333
+
334
+ current_predictor_instruction = dspy.InputField(desc="Current instruction guiding the predictor")
335
+ current_tools = dspy.InputField(annotation=list[dspy.Tool], desc="Available tools with their complete schemas")
336
+ examples_with_feedback = dspy.InputField(desc="Execution examples with feedback showing successes and failures")
337
+
338
+ improved_predictor_instruction: str | None = dspy.OutputField(
339
+ desc="Improved instruction for the predictor", default=None
340
+ )
341
+
342
+
343
+ class ToolProposer(ProposalFn):
344
+ """Proposer for optimizing tool-using module configurations.
345
+
346
+ Supports two types of modules:
347
+ - Tool modules (1 predictor): Optimizes predictor instruction and tool descriptions
348
+ - ReAct modules (2 predictors): Jointly optimizes react instruction, extract instruction, and tool descriptions
349
+
350
+ Uses dynamic signature generation to create output fields for each tool and parameter,
351
+ enabling the reflection LM to optimize all components cohesively based on execution feedback.
352
+
353
+ This joint optimization approach allows the LM to see how instructions and tool descriptions
354
+ work together, leading to more coherent improvements than optimizing each component separately.
355
+ """
356
+
357
+ def __call__(
358
+ self,
359
+ candidate: dict[str, str],
360
+ reflective_dataset: dict[str, list[ReflectiveExample]],
361
+ components_to_update: list[str],
362
+ ) -> dict[str, str]:
363
+ """Optimize tool-using module components.
364
+
365
+ Args:
366
+ candidate: Current component name -> JSON config mapping
367
+ reflective_dataset: Component name -> list of reflective examples
368
+ components_to_update: List of tool-using module component names to update
369
+
370
+ Returns:
371
+ dict: Mapping of component names to improved JSON configs
372
+ """
373
+
374
+ updated_components = {}
375
+
376
+ for module_key in components_to_update:
377
+ if module_key not in candidate or module_key not in reflective_dataset:
378
+ logger.debug(
379
+ f"Skipping {module_key}: not in candidate={module_key not in candidate}, not in "
380
+ "reflective_dataset={module_key not in reflective_dataset}"
381
+ )
382
+ continue
383
+ current_module_config = json.loads(candidate[module_key])
384
+
385
+ # Predictor keys: ReAct has 2 predictors (react + extract)
386
+ predictor_keys = [k for k, v in current_module_config.items() if isinstance(v, str)]
387
+ primary_predictor_key = predictor_keys[0]
388
+ extract_predictor_key = predictor_keys[1] if len(predictor_keys) > 1 else None
389
+
390
+ # Reconstruct Tool objects from JSON (func is placeholder since it can't be serialized)
391
+ current_tools_dict = current_module_config.get("tools", {})
392
+ tools_list = []
393
+ for tool_name, tool_info in current_tools_dict.items():
394
+ tool = dspy.Tool(
395
+ func=lambda *args, **kwargs: None, # Placeholder - Tool requires Callable, but only schema is used
396
+ name=tool_name,
397
+ desc=tool_info.get("desc", ""),
398
+ )
399
+ tool.args = tool_info.get("args", {})
400
+ tools_list.append(tool)
401
+
402
+ # Build dynamic signature with tool-specific output fields
403
+ signature = GenerateImprovedToolModuleDescriptionsFromFeedback
404
+
405
+ for tool in tools_list:
406
+ tool_name = tool.name
407
+ tool_info = current_tools_dict[tool_name]
408
+
409
+ signature = signature.append(
410
+ f"improved_tool_{tool_name}_desc",
411
+ dspy.OutputField(desc=f"Improved description of tool '{tool_name}'", default=None),
412
+ )
413
+
414
+ for arg_name in tool_info["args"].keys():
415
+ signature = signature.append(
416
+ f"improved_tool_{tool_name}_arg_{arg_name}_desc",
417
+ dspy.OutputField(
418
+ desc=f"Improved description of the argument '{arg_name}' of tool '{tool_name}'",
419
+ default=None,
420
+ ),
421
+ )
422
+
423
+ kwargs = {
424
+ "current_predictor_instruction": current_module_config[primary_predictor_key],
425
+ "current_tools": tools_list,
426
+ "examples_with_feedback": self._format_examples(reflective_dataset[module_key]),
427
+ }
428
+ # If module has extract predictor, add extract fields
429
+ if extract_predictor_key is not None:
430
+ signature = signature.append(
431
+ "current_extract_instruction", dspy.InputField(desc="Current instruction for extraction predictor")
432
+ )
433
+ signature = signature.append(
434
+ "improved_extract_instruction",
435
+ dspy.OutputField(desc="Improved instruction for extraction", default=None),
436
+ )
437
+ kwargs["current_extract_instruction"] = current_module_config[extract_predictor_key]
438
+
439
+ propose_descriptions = dspy.Predict(signature)
440
+ result = propose_descriptions(**kwargs)
441
+
442
+ # Build improved config (reflection LM returns None to keep original, or new text)
443
+ improved_module_config = {}
444
+
445
+ if result.improved_predictor_instruction is not None:
446
+ improved_module_config[primary_predictor_key] = result.improved_predictor_instruction
447
+
448
+ if extract_predictor_key is not None and result.improved_extract_instruction is not None:
449
+ improved_module_config[extract_predictor_key] = result.improved_extract_instruction
450
+
451
+ improved_module_config["tools"] = {}
452
+ for tool_name, tool_info in current_tools_dict.items():
453
+ # Update tool description if LM proposed a change
454
+ improved_tool_desc = getattr(result, f"improved_tool_{tool_name}_desc", None)
455
+ if improved_tool_desc is not None:
456
+ tool_info["desc"] = improved_tool_desc
457
+
458
+ # Update arg descriptions if LM proposed changes
459
+ for arg_name in tool_info["args"].keys():
460
+ improved_tool_arg_desc = getattr(result, f"improved_tool_{tool_name}_arg_{arg_name}_desc", None)
461
+ if improved_tool_arg_desc is not None:
462
+ tool_info["args"][arg_name]["description"] = improved_tool_arg_desc
463
+
464
+ improved_module_config["tools"][tool_name] = tool_info
465
+
466
+ updated_components[module_key] = json.dumps(improved_module_config, indent=2)
467
+
468
+ return updated_components
469
+
470
+ def _format_examples(self, reflective_dataset: list[ReflectiveExample]) -> str:
471
+ """Format reflective examples using GEPA's markdown structure."""
472
+
473
+ def render_value(value, level=3):
474
+ if isinstance(value, dict):
475
+ s = ""
476
+ for key, val in value.items():
477
+ s += f"{'#' * level} {key}\n"
478
+ s += render_value(val, min(level + 1, 6))
479
+ if not value:
480
+ s += "\n"
481
+ return s
482
+ if isinstance(value, list | tuple):
483
+ s = ""
484
+ for index, item in enumerate(value):
485
+ s += f"{'#' * level} Item {index + 1}\n"
486
+ s += render_value(item, min(level + 1, 6))
487
+ if not value:
488
+ s += "\n"
489
+ return s
490
+ return f"{str(value).strip()}\n\n"
491
+
492
+ def convert_sample_to_markdown(sample, example_num):
493
+ s = f"# Example {example_num}\n"
494
+ for key, val in sample.items():
495
+ s += f"## {key}\n"
496
+ s += render_value(val, level=3)
497
+ return s
498
+
499
+ formatted_parts = [convert_sample_to_markdown(example, i + 1) for i, example in enumerate(reflective_dataset)]
500
+ return "\n\n".join(formatted_parts)
@@ -0,0 +1,6 @@
1
+ # Copyright (c) 2025 Lakshya A Agrawal and the GEPA contributors
2
+ # https://github.com/gepa-ai/gepa
3
+
4
+ from gepa.adapters.dspy_full_program_adapter.full_program_adapter import DspyAdapter
5
+
6
+ __all__ = ["DspyAdapter"]
@@ -0,0 +1,137 @@
1
+ # Copyright (c) 2025 Lakshya A Agrawal and the GEPA contributors
2
+ # https://github.com/gepa-ai/gepa
3
+
4
+ from typing import Any, ClassVar
5
+
6
+ import yaml
7
+
8
+ from gepa.proposer.reflective_mutation.base import Signature
9
+
10
+
11
+ class DSPyProgramProposalSignature(Signature):
12
+ prompt_template = """I am trying to solve a task using the DSPy framework. Here's a comprehensive overview of DSPy concepts to guide your improvements:
13
+
14
+ Signatures:
15
+ - Signatures define tasks declaratively through input/output fields and explicit instructions.
16
+ - They serve as blueprints for what the LM needs to accomplish.
17
+
18
+ Signature Types:
19
+ - Simple signatures: Specified as strings like "input1, ..., inputN -> output1, ..., outputM" (e.g., "topic -> tweet").
20
+ - Typed signatures: Create a subclass of dspy.Signature with a detailed docstring that includes task instructions, common pitfalls, edge cases, and successful strategies. Define fields using dspy.InputField(desc="...", type=...) and dspy.OutputField(desc="...", type=...) with pydantic types such as str, List[str], Literal["option1", "option2"], or custom classes.
21
+
22
+ Modules:
23
+ - Modules specify __how__ to solve the task defined by a signature.
24
+ - They are composable units inspired by PyTorch layers, using language models to process inputs and produce outputs.
25
+ - Inputs are provided as keyword arguments matching the signature's input fields.
26
+ - Outputs are returned as dspy.Prediction objects containing the signature's output fields.
27
+ - Key built-in modules:
28
+ - dspy.Predict(signature): Performs a single LM call to directly generate the outputs from the inputs.
29
+ - dspy.ChainOfThought(signature): Performs a single LM call that first generates a reasoning chain, then the outputs (adds a 'reasoning' field to the prediction).
30
+ - Other options: dspy.ReAct(signature) for reasoning and acting, or custom chains.
31
+ - Custom modules: Subclass dspy.Module. In __init__, compose sub-modules (e.g., other Predict or ChainOfThought instances). In forward(self, **kwargs), define the data flow: call sub-modules, execute Python logic if needed, and return dspy.Prediction with the output fields.
32
+
33
+ Example Usage:
34
+ ```
35
+ # Simple signature
36
+ simple_signature = "question -> answer"
37
+
38
+ # Typed signature
39
+ class ComplexSignature(dspy.Signature):
40
+ \"\"\"
41
+ <Detailed instructions for completing the task: Include steps, common pitfalls, edge cases, successful strategies. Include domain knowledge...>
42
+ \"\"\"
43
+ question: str = dspy.InputField(desc="The question to answer")
44
+ answer: str = dspy.OutputField(desc="Concise and accurate answer")
45
+
46
+ # Built-in module
47
+ simple_program = dspy.Predict(simple_signature) # or dspy.ChainOfThought(ComplexSignature)
48
+
49
+ # Custom module
50
+ class ComplexModule(dspy.Module):
51
+ def __init__(self):
52
+ self.reasoner = dspy.ChainOfThought("question -> intermediate_answer")
53
+ self.finalizer = dspy.Predict("intermediate_answer -> answer")
54
+
55
+ def forward(self, question: str):
56
+ intermediate = self.reasoner(question=question)
57
+ final = self.finalizer(intermediate_answer=intermediate.intermediate_answer)
58
+ return dspy.Prediction(answer=final.answer, reasoning=intermediate.reasoning) # dspy.ChainOfThought returns 'reasoning' in addition to the signature outputs.
59
+
60
+ complex_program = ComplexModule()
61
+ ```
62
+
63
+ DSPy Improvement Strategies:
64
+ 1. Analyze traces for LM overload: If a single call struggles (e.g., skips steps or hallucinates), decompose into multi-step modules with ChainOfThought or custom logic for stepwise reasoning.
65
+ 2. Avoid over-decomposition: If the program is too fragmented, consolidate related steps into fewer modules for efficiency and coherence.
66
+ 3. Refine signatures: Enhance docstrings with actionable guidance from traces—address specific errors, incorporate domain knowledge, document edge cases, and suggest reasoning patterns. Ensure docstrings are self-contained, as the LM won't have access external traces during runtime.
67
+ 4. Balance LM and Python: Use Python for symbolic/logical operations (e.g., loops, conditionals); delegate complex reasoning or generation to LM calls.
68
+ 5. Incorporate control flow: Add loops, conditionals, sub-modules in custom modules if the task requires iteration (e.g., multi-turn reasoning, selection, voting, etc.).
69
+ 6. Leverage LM strengths: For code-heavy tasks, define signatures with 'code' outputs, extract and execute the generated code in the module's forward pass.
70
+
71
+ Here's my current code:
72
+ ```
73
+ <curr_program>
74
+ ```
75
+
76
+ Here is the execution trace of the current code on example inputs, their outputs, and detailed feedback on improvements:
77
+ ```
78
+ <dataset_with_feedback>
79
+ ```
80
+
81
+ Assignment:
82
+ - Think step-by-step: First, deeply analyze the current code, traces, and feedback to identify failure modes, strengths, and opportunities.
83
+ - Create a concise checklist (3-7 bullets) outlining your high-level improvement plan, focusing on conceptual changes (e.g., "Decompose step X into a multi-stage module").
84
+ - Then, propose a drop-in replacement code that instantiates an improved 'program' object.
85
+ - Ensure the code is modular, efficient, and directly addresses feedback.
86
+ - Output everything in a single code block using triple backticks—no additional explanations, comments, or language markers outside the block.
87
+ - The code must be a valid, self-contained Python script with all necessary imports, definitions, and assignment to 'program'.
88
+
89
+ Output Format:
90
+ - Start with the checklist in plain text (3-7 short bullets).
91
+ - Follow immediately with one code block in triple backticks containing the complete Python code, including assigning a `program` object."""
92
+ input_keys: ClassVar[list[str]] = ["curr_program", "dataset_with_feedback"]
93
+ output_keys: ClassVar[list[str]] = ["new_program"]
94
+
95
+ @classmethod
96
+ def prompt_renderer(cls, input_dict: dict[str, Any]) -> str:
97
+ curr_program = input_dict["curr_program"]
98
+ if not isinstance(curr_program, str):
99
+ raise TypeError("curr_program must be a string")
100
+
101
+ dataset = input_dict["dataset_with_feedback"]
102
+ if not isinstance(dataset, list):
103
+ raise TypeError("dataset_with_feedback must be a list")
104
+
105
+ def format_samples(samples):
106
+ # Serialize the samples list to YAML for concise, structured representation
107
+ yaml_str = yaml.dump(samples, sort_keys=False, default_flow_style=False, indent=2)
108
+ # Optionally, wrap or label it for clarity in the prompt
109
+ return yaml_str
110
+
111
+ prompt = cls.prompt_template
112
+ prompt = prompt.replace("<curr_program>", curr_program)
113
+ prompt = prompt.replace("<dataset_with_feedback>", format_samples(dataset))
114
+ return prompt
115
+
116
+ @staticmethod
117
+ def output_extractor(lm_out: str) -> dict[str, str]:
118
+ # Extract ``` blocks
119
+ new_instruction = None
120
+ if lm_out.count("```") >= 2:
121
+ start = lm_out.find("```")
122
+ end = lm_out.rfind("```")
123
+ if start >= end:
124
+ new_instruction = lm_out
125
+ if start == -1 or end == -1:
126
+ new_instruction = lm_out
127
+ else:
128
+ new_instruction = lm_out[start + 3 : end].strip()
129
+ else:
130
+ lm_out = lm_out.strip()
131
+ if lm_out.startswith("```"):
132
+ lm_out = lm_out[3:]
133
+ if lm_out.endswith("```"):
134
+ lm_out = lm_out[:-3]
135
+ new_instruction = lm_out
136
+
137
+ return {"new_program": new_instruction}