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.
- package/README.md +23 -0
- package/dist/archive-artifacts-cli.d.ts +50 -0
- package/dist/archive-artifacts-cli.d.ts.map +1 -0
- package/dist/artifact-archive.d.ts +48 -0
- package/dist/artifact-archive.d.ts.map +1 -0
- package/dist/artifact-pull.d.ts +22 -0
- package/dist/artifact-pull.d.ts.map +1 -0
- package/dist/banner.d.ts +3 -0
- package/dist/banner.d.ts.map +1 -0
- package/dist/connectors-cli.d.ts +31 -0
- package/dist/connectors-cli.d.ts.map +1 -0
- package/dist/credentials.d.ts +46 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/csv.d.ts +49 -0
- package/dist/csv.d.ts.map +1 -0
- package/dist/dataset-download.d.ts +6 -0
- package/dist/dataset-download.d.ts.map +1 -0
- package/dist/dataset-edit-rows.d.ts +10 -0
- package/dist/dataset-edit-rows.d.ts.map +1 -0
- package/dist/dataset-upload-snapshot.d.ts +13 -0
- package/dist/dataset-upload-snapshot.d.ts.map +1 -0
- package/dist/daytona-slice-rehearsal.d.ts +89 -0
- package/dist/daytona-slice-rehearsal.d.ts.map +1 -0
- package/dist/daytona-slice.d.ts +106 -0
- package/dist/daytona-slice.d.ts.map +1 -0
- package/dist/deploy-key-merge-core.d.ts +121 -0
- package/dist/deploy-key-merge-core.d.ts.map +1 -0
- package/dist/diff-comments-cli.d.ts +12 -0
- package/dist/diff-comments-cli.d.ts.map +1 -0
- package/dist/diff-comments-cli.js +21 -2
- package/dist/egress-allowlist-cli.d.ts +23 -0
- package/dist/egress-allowlist-cli.d.ts.map +1 -0
- package/dist/egress-policy.d.ts +108 -0
- package/dist/egress-policy.d.ts.map +1 -0
- package/dist/error-response.d.ts +9 -0
- package/dist/error-response.d.ts.map +1 -0
- package/dist/file-parser.d.ts +5 -0
- package/dist/file-parser.d.ts.map +1 -0
- package/dist/gepa-engine-dispatch.d.ts +9 -0
- package/dist/gepa-engine-dispatch.d.ts.map +1 -0
- package/dist/gepa-engine-dispatch.js +307 -0
- package/dist/gepa-python-command.d.ts +6 -0
- package/dist/gepa-python-command.d.ts.map +1 -0
- package/dist/gepa-python-command.js +26 -0
- package/dist/gepa-python-paths.d.ts +6 -0
- package/dist/gepa-python-paths.d.ts.map +1 -0
- package/dist/gepa-python-paths.js +42 -0
- package/dist/git-credential.d.ts +69 -0
- package/dist/git-credential.d.ts.map +1 -0
- package/dist/git-recovery-environment.d.ts +31 -0
- package/dist/git-recovery-environment.d.ts.map +1 -0
- package/dist/github-setup.d.ts +122 -0
- package/dist/github-setup.d.ts.map +1 -0
- package/dist/global-flags.d.ts +12 -0
- package/dist/global-flags.d.ts.map +1 -0
- package/dist/help.d.ts +46 -0
- package/dist/help.d.ts.map +1 -0
- package/dist/help.js +93 -25
- package/dist/hosted-boot.d.ts +273 -0
- package/dist/hosted-boot.d.ts.map +1 -0
- package/dist/hosted-bootstrap-rehearsal.d.ts +86 -0
- package/dist/hosted-bootstrap-rehearsal.d.ts.map +1 -0
- package/dist/hosted-bootstrap.d.ts +188 -0
- package/dist/hosted-bootstrap.d.ts.map +1 -0
- package/dist/hosted-broker-server.d.ts +50 -0
- package/dist/hosted-broker-server.d.ts.map +1 -0
- package/dist/hosted-git-http-server.d.ts +36 -0
- package/dist/hosted-git-http-server.d.ts.map +1 -0
- package/dist/hosted-harness-claude.d.ts +195 -0
- package/dist/hosted-harness-claude.d.ts.map +1 -0
- package/dist/hosted-harness-opencode.d.ts +227 -0
- package/dist/hosted-harness-opencode.d.ts.map +1 -0
- package/dist/hosted-harness.d.ts +118 -0
- package/dist/hosted-harness.d.ts.map +1 -0
- package/dist/hosted-harvest.d.ts +68 -0
- package/dist/hosted-harvest.d.ts.map +1 -0
- package/dist/hosted-headless.d.ts +72 -0
- package/dist/hosted-headless.d.ts.map +1 -0
- package/dist/hosted-loop-lifecycle.d.ts +206 -0
- package/dist/hosted-loop-lifecycle.d.ts.map +1 -0
- package/dist/hosted-loop.d.ts +170 -0
- package/dist/hosted-loop.d.ts.map +1 -0
- package/dist/hosted-run-event-sink.d.ts +222 -0
- package/dist/hosted-run-event-sink.d.ts.map +1 -0
- package/dist/hosted-runtime-assets.d.ts +186 -0
- package/dist/hosted-runtime-assets.d.ts.map +1 -0
- package/dist/hosted-session-cli.d.ts +258 -0
- package/dist/hosted-session-cli.d.ts.map +1 -0
- package/dist/hosted-skill-staging.d.ts +73 -0
- package/dist/hosted-skill-staging.d.ts.map +1 -0
- package/dist/http.d.ts +8 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +119 -129
- package/dist/instruction-set-gepa-launch.d.ts +3 -0
- package/dist/instruction-set-gepa-launch.d.ts.map +1 -0
- package/dist/instruction-set-gepa-launch.js +15 -0
- package/dist/instruction-set-loader.d.ts +6 -0
- package/dist/instruction-set-loader.d.ts.map +1 -0
- package/dist/instruction-set-loader.js +59 -0
- package/dist/instruction-set-manifest.d.ts +14 -0
- package/dist/instruction-set-manifest.d.ts.map +1 -0
- package/dist/instruction-set-manifest.js +162 -0
- package/dist/instruction-sets-cli.d.ts +40 -0
- package/dist/instruction-sets-cli.d.ts.map +1 -0
- package/dist/instruction-sets-cli.js +361 -0
- package/dist/json-response.d.ts +4 -0
- package/dist/json-response.d.ts.map +1 -0
- package/dist/jsonl-stream.d.ts +8 -0
- package/dist/jsonl-stream.d.ts.map +1 -0
- package/dist/kill-switch-cli.d.ts +30 -0
- package/dist/kill-switch-cli.d.ts.map +1 -0
- package/dist/loopback-serve.d.ts +25 -0
- package/dist/loopback-serve.d.ts.map +1 -0
- package/dist/manifests-cli.d.ts +22 -0
- package/dist/manifests-cli.d.ts.map +1 -0
- package/dist/markdown-report-input.d.ts +7 -0
- package/dist/markdown-report-input.d.ts.map +1 -0
- package/dist/markdown-report-input.js +15 -1
- package/dist/merge-job.d.ts +155 -0
- package/dist/merge-job.d.ts.map +1 -0
- package/dist/model-configs-cli.d.ts +19 -0
- package/dist/model-configs-cli.d.ts.map +1 -0
- package/dist/model-configs-cli.js +104 -0
- package/dist/optimization-export-cli.d.ts +19 -0
- package/dist/optimization-export-cli.d.ts.map +1 -0
- package/dist/optimizations-list-cli.d.ts +20 -0
- package/dist/optimizations-list-cli.d.ts.map +1 -0
- package/dist/optimizations-promote-cli.d.ts +8 -0
- package/dist/optimizations-promote-cli.d.ts.map +1 -0
- package/dist/optimizations-promote-cli.js +34 -0
- package/dist/option-validation.d.ts +15 -0
- package/dist/option-validation.d.ts.map +1 -0
- package/dist/preview-runtime.d.ts +63 -0
- package/dist/preview-runtime.d.ts.map +1 -0
- package/dist/prompt-draft-push.d.ts +60 -0
- package/dist/prompt-draft-push.d.ts.map +1 -0
- package/dist/prompt-label-cli.d.ts +11 -0
- package/dist/prompt-label-cli.d.ts.map +1 -0
- package/dist/prompt-label-cli.js +29 -0
- package/dist/prompt-length-wire.d.ts +28 -0
- package/dist/prompt-length-wire.d.ts.map +1 -0
- package/dist/prompt-length-wire.js +2 -2
- package/dist/prompt-report-cli.d.ts +10 -0
- package/dist/prompt-report-cli.d.ts.map +1 -0
- package/dist/prompt-report-cli.js +2 -2
- package/dist/prompt-summary-table.d.ts +15 -0
- package/dist/prompt-summary-table.d.ts.map +1 -0
- package/dist/prompt-summary-table.js +6 -0
- package/dist/registration-tag-warning.d.ts +32 -0
- package/dist/registration-tag-warning.d.ts.map +1 -0
- package/dist/report-comments-cli.d.ts +16 -0
- package/dist/report-comments-cli.d.ts.map +1 -0
- package/dist/report-markdown-blankness.d.ts +2 -0
- package/dist/report-markdown-blankness.d.ts.map +1 -0
- package/dist/report-markdown-blankness.js +6 -0
- package/dist/report-replacement-warning.d.ts +17 -0
- package/dist/report-replacement-warning.d.ts.map +1 -0
- package/dist/report-replacement-warning.js +31 -0
- package/dist/repository-backup-core.d.ts +225 -0
- package/dist/repository-backup-core.d.ts.map +1 -0
- package/dist/repository-recovery-manifest.d.ts +83 -0
- package/dist/repository-recovery-manifest.d.ts.map +1 -0
- package/dist/run-event-digest.d.ts +74 -0
- package/dist/run-event-digest.d.ts.map +1 -0
- package/dist/runner-dir-verify.d.ts +66 -0
- package/dist/runner-dir-verify.d.ts.map +1 -0
- package/dist/runner-instruction-set-contract.d.ts +24 -0
- package/dist/runner-instruction-set-contract.d.ts.map +1 -0
- package/dist/runner-instruction-set-contract.js +50 -0
- package/dist/sandbox-hygiene.d.ts +45 -0
- package/dist/sandbox-hygiene.d.ts.map +1 -0
- package/dist/sandbox-provider.d.ts +193 -0
- package/dist/sandbox-provider.d.ts.map +1 -0
- package/dist/scorer-draft-push.d.ts +50 -0
- package/dist/scorer-draft-push.d.ts.map +1 -0
- package/dist/scorers-cli.d.ts +20 -0
- package/dist/scorers-cli.d.ts.map +1 -0
- package/dist/scorers-cli.js +22 -0
- package/dist/scorers-verify-parity-bridge.d.ts +16 -0
- package/dist/scorers-verify-parity-bridge.d.ts.map +1 -0
- package/dist/scorers-verify-parity-bridge.js +90 -0
- package/dist/scorers-verify-parity.d.ts +81 -0
- package/dist/scorers-verify-parity.d.ts.map +1 -0
- package/dist/scorers-verify-parity.js +502 -0
- package/dist/scores-accept-cli.d.ts +21 -0
- package/dist/scores-accept-cli.d.ts.map +1 -0
- package/dist/secret-redaction.d.ts +47 -0
- package/dist/secret-redaction.d.ts.map +1 -0
- package/dist/session-timeline.d.ts +54 -0
- package/dist/session-timeline.d.ts.map +1 -0
- package/dist/setup-prompt.d.ts +5 -0
- package/dist/setup-prompt.d.ts.map +1 -0
- package/dist/skill-installer.d.ts +68 -0
- package/dist/skill-installer.d.ts.map +1 -0
- package/dist/skilled-proposer-launch.d.ts +7 -0
- package/dist/skilled-proposer-launch.d.ts.map +1 -0
- package/dist/skilled-proposer-launch.js +60 -0
- package/dist/smoke.d.ts +102 -0
- package/dist/smoke.d.ts.map +1 -0
- package/dist/start-intent.d.ts +12 -0
- package/dist/start-intent.d.ts.map +1 -0
- package/dist/task-assignment-manifest.d.ts +15 -0
- package/dist/task-assignment-manifest.d.ts.map +1 -0
- package/dist/task-create-error.d.ts +18 -0
- package/dist/task-create-error.d.ts.map +1 -0
- package/dist/team-connectors-cli.d.ts +29 -0
- package/dist/team-connectors-cli.d.ts.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/vercel-sandbox-provider.d.ts +156 -0
- package/dist/vercel-sandbox-provider.d.ts.map +1 -0
- package/dist/workbench-cli.d.ts +233 -0
- package/dist/workbench-cli.d.ts.map +1 -0
- package/dist/workspace-sync.d.ts +207 -0
- package/dist/workspace-sync.d.ts.map +1 -0
- package/dist/workspace.d.ts +92 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/zip-draft-push.d.ts +55 -0
- package/dist/zip-draft-push.d.ts.map +1 -0
- package/package.json +15 -2
- package/requirements/README.md +138 -0
- package/requirements/skilled-proposer.in +66 -0
- package/requirements/skilled-proposer.lock +265 -0
- package/scripts/build-cli-dist.mjs +30 -0
- package/scripts/ensure-skilled-proposer-venv.mjs +5 -0
- package/scripts/orizu-source-checkout.d.mts +1 -0
- package/scripts/orizu-source-checkout.mjs +10 -0
- package/scripts/refresh-skilled-proposer-lock.mjs +256 -0
- package/scripts/vendor-gepa-python.mjs +187 -4
- package/src/diff-comments-cli.ts +41 -3
- package/src/gepa-engine-dispatch.ts +340 -0
- package/src/gepa-python-command.ts +31 -0
- package/src/gepa-python-paths.ts +56 -0
- package/src/help.ts +95 -25
- package/src/index.ts +131 -166
- package/src/instruction-set-gepa-launch.ts +28 -0
- package/src/instruction-set-loader.ts +37 -0
- package/src/instruction-set-manifest.ts +120 -0
- package/src/instruction-sets-cli.ts +306 -0
- package/src/markdown-report-input.ts +19 -1
- package/src/model-configs-cli.ts +119 -0
- package/src/optimizations-promote-cli.ts +41 -0
- package/src/prompt-label-cli.ts +55 -0
- package/src/prompt-length-wire.ts +1 -1
- package/src/prompt-report-cli.ts +2 -2
- package/src/prompt-summary-table.ts +12 -0
- package/src/report-markdown-blankness.ts +6 -0
- package/src/report-replacement-warning.ts +35 -0
- package/src/runner-instruction-set-contract.ts +64 -0
- package/src/scorers-cli.ts +40 -0
- package/src/scorers-verify-parity-bridge.ts +90 -0
- package/src/scorers-verify-parity.ts +564 -0
- package/src/skilled-proposer-launch.ts +89 -0
- package/src/skilled-proposer-venv-manager.mjs +757 -0
- package/tsconfig.json +2 -0
- package/vendor/gepa-python/LICENSE +7 -0
- package/vendor/gepa-python/manifest.json +107 -0
- package/vendor/gepa-python/src/gepa/__init__.py +22 -0
- package/vendor/gepa-python/src/gepa/adapters/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/adapters/anymaths_adapter/__init__.py +1 -0
- package/vendor/gepa-python/src/gepa/adapters/anymaths_adapter/anymaths_adapter.py +174 -0
- package/vendor/gepa-python/src/gepa/adapters/confidence_adapter/__init__.py +26 -0
- package/vendor/gepa-python/src/gepa/adapters/confidence_adapter/confidence_adapter.py +618 -0
- package/vendor/gepa-python/src/gepa/adapters/confidence_adapter/scoring.py +206 -0
- package/vendor/gepa-python/src/gepa/adapters/default_adapter/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/adapters/default_adapter/default_adapter.py +206 -0
- package/vendor/gepa-python/src/gepa/adapters/dspy_adapter/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/adapters/dspy_adapter/dspy_adapter.py +525 -0
- package/vendor/gepa-python/src/gepa/adapters/dspy_adapter/instruction_proposal.py +500 -0
- package/vendor/gepa-python/src/gepa/adapters/dspy_full_program_adapter/__init__.py +6 -0
- package/vendor/gepa-python/src/gepa/adapters/dspy_full_program_adapter/dspy_program_proposal_signature.py +137 -0
- package/vendor/gepa-python/src/gepa/adapters/dspy_full_program_adapter/full_program_adapter.py +269 -0
- package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/__init__.py +56 -0
- package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/evaluation_metrics.py +226 -0
- package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/generic_rag_adapter.py +496 -0
- package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/rag_pipeline.py +238 -0
- package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_store_interface.py +212 -0
- package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/__init__.py +2 -0
- package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/chroma_store.py +196 -0
- package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/lancedb_store.py +422 -0
- package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/milvus_store.py +409 -0
- package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/qdrant_store.py +368 -0
- package/vendor/gepa-python/src/gepa/adapters/generic_rag_adapter/vector_stores/weaviate_store.py +418 -0
- package/vendor/gepa-python/src/gepa/adapters/langchain_adapter/__init__.py +11 -0
- package/vendor/gepa-python/src/gepa/adapters/langchain_adapter/langchain_adapter.py +261 -0
- package/vendor/gepa-python/src/gepa/adapters/mcp_adapter/__init__.py +37 -0
- package/vendor/gepa-python/src/gepa/adapters/mcp_adapter/mcp_adapter.py +693 -0
- package/vendor/gepa-python/src/gepa/adapters/mcp_adapter/mcp_client.py +364 -0
- package/vendor/gepa-python/src/gepa/adapters/optimize_anything_adapter/optimize_anything_adapter.py +879 -0
- package/vendor/gepa-python/src/gepa/adapters/terminal_bench_adapter/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/adapters/terminal_bench_adapter/terminal_bench_adapter.py +217 -0
- package/vendor/gepa-python/src/gepa/api.py +468 -0
- package/vendor/gepa-python/src/gepa/core/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/core/adapter.py +227 -0
- package/vendor/gepa-python/src/gepa/core/callbacks.py +551 -0
- package/vendor/gepa-python/src/gepa/core/data_loader.py +74 -0
- package/vendor/gepa-python/src/gepa/core/engine.py +1025 -0
- package/vendor/gepa-python/src/gepa/core/result.py +271 -0
- package/vendor/gepa-python/src/gepa/core/state.py +706 -0
- package/vendor/gepa-python/src/gepa/examples/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/examples/aime.py +24 -0
- package/vendor/gepa-python/src/gepa/examples/anymaths-bench/eval_default.py +111 -0
- package/vendor/gepa-python/src/gepa/examples/anymaths-bench/train_anymaths.py +177 -0
- package/vendor/gepa-python/src/gepa/examples/mcp_adapter/__init__.py +4 -0
- package/vendor/gepa-python/src/gepa/examples/mcp_adapter/mcp_optimization_example.py +456 -0
- package/vendor/gepa-python/src/gepa/examples/rag_adapter/__init__.py +9 -0
- package/vendor/gepa-python/src/gepa/examples/rag_adapter/rag_optimization.py +824 -0
- package/vendor/gepa-python/src/gepa/examples/terminal-bench/train_terminus.py +161 -0
- package/vendor/gepa-python/src/gepa/gepa_utils.py +117 -0
- package/vendor/gepa-python/src/gepa/gskill/__init__.py +1 -0
- package/vendor/gepa-python/src/gepa/gskill/gskill/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/gskill/gskill/cost_tracker.py +194 -0
- package/vendor/gepa-python/src/gepa/gskill/gskill/evaluate/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/gskill/gskill/evaluate/claude_code.py +1117 -0
- package/vendor/gepa-python/src/gepa/gskill/gskill/evaluate/claude_code_skills.py +613 -0
- package/vendor/gepa-python/src/gepa/gskill/gskill/evaluate/mini_swe_agent.py +440 -0
- package/vendor/gepa-python/src/gepa/gskill/gskill/experiment_logger.py +367 -0
- package/vendor/gepa-python/src/gepa/gskill/gskill/swe_fitness_fn.py +209 -0
- package/vendor/gepa-python/src/gepa/gskill/gskill/swe_harness.py +352 -0
- package/vendor/gepa-python/src/gepa/gskill/gskill/train_optimize_anything.py +830 -0
- package/vendor/gepa-python/src/gepa/image.py +104 -0
- package/vendor/gepa-python/src/gepa/lm.py +261 -0
- package/vendor/gepa-python/src/gepa/logging/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/logging/experiment_tracker.py +457 -0
- package/vendor/gepa-python/src/gepa/logging/logger.py +75 -0
- package/vendor/gepa-python/src/gepa/logging/utils.py +130 -0
- package/vendor/gepa-python/src/gepa/optimize_anything.py +1701 -0
- package/vendor/gepa-python/src/gepa/proposer/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/proposer/base.py +53 -0
- package/vendor/gepa-python/src/gepa/proposer/merge.py +403 -0
- package/vendor/gepa-python/src/gepa/proposer/reflective_mutation/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/proposer/reflective_mutation/base.py +64 -0
- package/vendor/gepa-python/src/gepa/proposer/reflective_mutation/reflection_lm.py +178 -0
- package/vendor/gepa-python/src/gepa/proposer/reflective_mutation/reflective_mutation.py +641 -0
- package/vendor/gepa-python/src/gepa/py.typed +0 -0
- package/vendor/gepa-python/src/gepa/strategies/__init__.py +0 -0
- package/vendor/gepa-python/src/gepa/strategies/acceptance.py +66 -0
- package/vendor/gepa-python/src/gepa/strategies/batch_sampler.py +103 -0
- package/vendor/gepa-python/src/gepa/strategies/candidate_selector.py +82 -0
- package/vendor/gepa-python/src/gepa/strategies/component_selector.py +36 -0
- package/vendor/gepa-python/src/gepa/strategies/eval_policy.py +64 -0
- package/vendor/gepa-python/src/gepa/strategies/instruction_proposal.py +153 -0
- package/vendor/gepa-python/src/gepa/strategies/proposal_sampling.py +128 -0
- package/vendor/gepa-python/src/gepa/strategies/proposal_selection.py +84 -0
- package/vendor/gepa-python/src/gepa/utils/__init__.py +63 -0
- package/vendor/gepa-python/src/gepa/utils/code_execution.py +626 -0
- package/vendor/gepa-python/src/gepa/utils/stdio_capture.py +145 -0
- package/vendor/gepa-python/src/gepa/utils/stop_condition.py +230 -0
- package/vendor/gepa-python/src/gepa/visualization.py +359 -0
- package/vendor/orizu-gepa/pyproject.toml +18 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/__init__.py +9 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/__main__.py +5 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/adapter.py +138 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/callbacks.py +666 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/cli.py +7 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/engine.py +269 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/instruction_set_loader.py +52 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/preflight.py +64 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/reflection.py +186 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/runtime.py +721 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/skilled_proposer_bridge.py +381 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/stop_conditions.py +55 -0
- package/vendor/orizu-gepa/src/orizu_gepa_connector/translator.py +203 -0
- package/vendor/orizu-gepa-python/pyproject.toml +1 -1
- package/vendor/orizu-gepa-python/src/orizu_gepa/cli.py +1 -0
- package/vendor/orizu-gepa-python/src/orizu_gepa/client.py +52 -7
- package/vendor/orizu-gepa-python/src/orizu_gepa/local_log.py +52 -0
- package/vendor/orizu-gepa-python/src/orizu_gepa/optimizer.py +10 -5
- package/vendor/orizu-gepa-python/src/orizu_gepa/reflection.py +323 -68
- package/vendor/orizu-gepa-python/src/orizu_gepa/runner.py +207 -13
- package/vendor/skills/orizu-cli/SKILL.md +3 -1
- package/vendor/skills/orizu-cli/references/cli-reference.md +85 -1
- package/vendor/skills/orizu-cli/references/migrate-existing-gepa-setup.md +303 -0
- package/vendor/skills/orizu-cli/references/optimization-reports.md +1 -1
- package/vendor/skills/orizu-cli/references/optimization-with-gepa.md +26 -1
- 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…</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,"&").replace(/</g,"<").replace(/>/g,">");
|
|
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> | Parent(s): ' + n.parents +
|
|
268
|
+
'</div><div class="tt-hint">' + (pinnedIdx === idx ? 'Click node again to dismiss' : 'Click to pin & 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,"<") + "</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,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}
|