cmpnd 0.18.2__tar.gz → 0.18.3__tar.gz
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.
- {cmpnd-0.18.2 → cmpnd-0.18.3}/PKG-INFO +1 -1
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/optimization.py +25 -2
- {cmpnd-0.18.2 → cmpnd-0.18.3}/pyproject.toml +1 -1
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_optimize_budget.py +36 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/uv.lock +1 -1
- {cmpnd-0.18.2 → cmpnd-0.18.3}/.gitignore +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/CLAUDE.md +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/README.md +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/_gepa_patch.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/_program_patch.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/_rlm_patch.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/callback.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/api_client.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/admin.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/auth.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/datasets.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/deployments.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/evals.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/login.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/optimizations.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/org.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/programs.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/provider_credentials.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/signatures.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/tool_servers.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/top.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/commands/traces.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/credentials.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/deprecation.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/pagination.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/shell.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/trace_render.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/cli/verbs.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/configuration.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/context.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/dataset_sync.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/datasets.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/decorators.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/deployment.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/eval_handler.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/execution.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/exporter.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/exporter_http.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/helpers.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/identity.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/imaging.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/ir/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/ir/decode.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/ir/encode.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/ir/hash.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/ir/program.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/ir/reflection.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/ir/types.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/ir/xxh64.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/mcp_servers.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/models.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/optimizers/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/optimizers/gepa.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/optimizers/gepa_callback.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/optimizers/resume.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/optimizers/tracker.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/packaging.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/cmpnd/retry.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/docs/2026-04-02-code-review.md +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/docs/cli.md +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/docs/custom-proposer.md +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/docs/plans/2026-04-05-train-val-dataset-capture-design.md +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/docs/plans/2026-04-05-train-val-dataset-capture.md +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/docs/sdk-instrumentation.md +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/examples/generalizing_proposer.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/examples/local_ollama.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/ingest/LINEAGE.md +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/ingest/README.md +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/ingest/cmpnd_ingest/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/ingest/cmpnd_ingest/bodies.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/ingest/cmpnd_ingest/exporter_http.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/ingest/cmpnd_ingest/protocols.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/ingest/cmpnd_ingest/py.typed +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/ingest/cmpnd_ingest/request_log.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/ingest/cmpnd_ingest/retry.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/ingest/pyproject.toml +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/scripts/audit-sdist.sh +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/scripts/capture_review_run.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/scripts/check_release_artifacts.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/scripts/fixtures/review_run.json.gz +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/scripts/gepa_resume_bug.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/scripts/require_version_bump.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/scripts/seed_review_run.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/scripts/test-in-linux.sh +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/stubs/dspy/__init__.pyi +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/stubs/dspy/primitives/__init__.pyi +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/stubs/dspy/primitives/prediction.pyi +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/stubs/dspy/utils/__init__.pyi +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/stubs/dspy/utils/callback.pyi +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/_exporter_helpers.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/_fake_clock.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/_identity_helpers.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/conftest.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/committee_task.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/conftest.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/data/committee_train.ndjson.gz +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/data/committee_val.ndjson.gz +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/fake_lm.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/helpers.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/target_capabilities.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_capture_prompts.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_composite_module.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_dataset_auto_creation.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_deploy_execute.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_deploy_programs.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_edge_cases.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_example_hash.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_gepa_optimization.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_interpreter_spans.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_lm_accuracy.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_module_tracing.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_optimization_lineage.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_optimization_metric_identity.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_optimize_failures.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_optimize_loop.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_optimize_review_committee.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_optimize_server_owned_completion.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_parallel_export.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_project_attribution.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_react_tool_spans.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_save_load.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_trace_structure.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/e2e/test_user_attribution.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/01_predict_qa.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/02_predict_renamed_field.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/03_chain_of_thought_qa.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/04_predict_richer_types.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/05_composite_two_predicts.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/06_multichaincomparison.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/07_program_of_thought.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/08_opaque_module.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/09_predict_pydantic_field.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/10_react.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/11_refine.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/12_retrieve.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/13_knn.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/14_parallel.json +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/identity_vectors/README.md +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/ingest_conformance.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/integration/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/integration/conftest.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/integration/hosted_optimize_probe.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/integration/optimization_run_probe.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/integration/test_cli_deploy_smoketest.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/integration/test_logs_renders_traces.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/integration/test_optimization_run.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/integration/test_optimizing_progress.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/integration/test_unhappy_path.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/load/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/load/__main__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/load/drain.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/load/ingest.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/load/latency_transport.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/load/rlm_shape.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/load/sweep.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/load/test_rlm_shape.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/conftest.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/seed_parity.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/test_auth.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/test_datasets.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/test_deployments.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/test_evals.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/test_health.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/test_modules.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/test_optimizations.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/test_programs.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/test_signatures.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/test_trace_streaming.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/parity/test_traces.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/_provider.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/_reliability.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/_result.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/mint_bedrock_token.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_deploy_programs.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_multi_client_stress.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_optimize_client_committee.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_optimize_loop.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_optimize_loop_wasm.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_optimize_stress.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_provider_roles.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_real_provider_twins.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_reliability.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_reliability_classify.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_rlm_wasm.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/stress/test_trace_search.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_callback.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_candidate_lineage.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/conftest.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_admin.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_api_client.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_auth.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_credentials.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_datasets.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_deployments.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_evals.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_login.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_main.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_optimizations.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_org.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_pagination.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_parity.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_programs.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_provider_credentials.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_schema_sample.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_shell.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_signatures.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_tool_servers.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_top.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_traces.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cli/test_traces_search_wire.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_clustering/__init__.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_clustering/conftest.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_clustering/test_edge_cases.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_clustering/test_hash_consistency.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_clustering/test_type_conversion.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_cmp551_grouping_identity.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_configuration.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_context.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_context_propagation.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_dataset_polling.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_dataset_sync.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_datasets.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_decorators.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_deploy.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_deploy_mcp_tool_references.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_eval.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_eval_start.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_eval_trace_grouping.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_exception_paths.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_execute.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_exporter.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_exporter_queue.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_exporter_real.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_fake_lm.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_gepa_callback.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_gepa_integration.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_gepa_resume.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_identity.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_imaging.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_import_weight.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_ingest_conformance.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_ingest_second_producer.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_integration.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_interpreter_callback.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_ir_encoder_properties.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_ir_golden_vectors.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_ir_roundtrip.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_mcp_tools.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_models.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_optimization_progress.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_optimization_start.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_optimize.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_optimize_lift.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_optimize_lms.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_optimize_proposer.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_optimize_reflection_lm.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_optimize_terminal_failure.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_packaging.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_packaging_callable_source.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_packaging_mcp_tools.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_packaging_program_source.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_poll_until.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_program_lineage_persist.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_project_payload.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_reflector_properties.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_reflector_smoke.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_repro_reactv2_bugs.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_require_version_bump.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_retry.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_reversible_failures.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_rlm_patch.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_schemas.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_seed_review_run.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_stats_export.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_trace_render.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_tracked_gepa.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_tracker_enrich.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_truncation.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/tests/test_xxh64.py +0 -0
- {cmpnd-0.18.2 → cmpnd-0.18.3}/todo.md +0 -0
|
@@ -704,6 +704,7 @@ def optimize(
|
|
|
704
704
|
lms: dict[str, Any] | None = None,
|
|
705
705
|
max_metric_calls: int | None = None,
|
|
706
706
|
auto: str | None = None,
|
|
707
|
+
may_author_code: bool | None = None,
|
|
707
708
|
max_steps: int = 10,
|
|
708
709
|
patience: int = 2,
|
|
709
710
|
seed: int = 0,
|
|
@@ -842,6 +843,16 @@ def optimize(
|
|
|
842
843
|
``"heavy"`` — sized from the program's predictor count and the
|
|
843
844
|
valset, using GEPA's own settings. Easier to reach for than a call
|
|
844
845
|
count when you do not yet know what a run costs.
|
|
846
|
+
may_author_code: Whether this run may rewrite the SOURCE of the program's
|
|
847
|
+
``dspy.Flex`` submodules, rather than only their instructions. Left
|
|
848
|
+
unset, the platform's answer is yes — writing a ``dspy.Flex`` is
|
|
849
|
+
already asking for its source to be optimized.
|
|
850
|
+
|
|
851
|
+
Pass ``False`` for "improve my prompts, don't rewrite my code" on a
|
|
852
|
+
program that has both: a cheaper, lower-variance search that still
|
|
853
|
+
optimizes every ordinary predictor and leaves each ``dspy.Flex`` at
|
|
854
|
+
the source you deployed. A program with no ``dspy.Flex`` in it is
|
|
855
|
+
unaffected either way.
|
|
845
856
|
max_steps: How many times to re-optimize the winner, each step a fresh
|
|
846
857
|
``optimize`` call with an advanced seed (default 10). Distinct from
|
|
847
858
|
the budget above, which bounds ONE step's search: total spend is
|
|
@@ -901,7 +912,14 @@ def optimize(
|
|
|
901
912
|
step_config["seed"] = seed
|
|
902
913
|
|
|
903
914
|
initiated = _initiate_step(
|
|
904
|
-
client,
|
|
915
|
+
client,
|
|
916
|
+
cfg.endpoint,
|
|
917
|
+
headers,
|
|
918
|
+
current_deployment_id,
|
|
919
|
+
optimizer,
|
|
920
|
+
data,
|
|
921
|
+
step_config,
|
|
922
|
+
may_author_code,
|
|
905
923
|
)
|
|
906
924
|
optimization_id = initiated["optimization_id"]
|
|
907
925
|
|
|
@@ -1040,6 +1058,7 @@ def _initiate_step(
|
|
|
1040
1058
|
optimizer: str,
|
|
1041
1059
|
data: str,
|
|
1042
1060
|
config: dict[str, Any],
|
|
1061
|
+
may_author_code: bool | None = None,
|
|
1043
1062
|
) -> dict[str, Any]:
|
|
1044
1063
|
"""POST one optimize step to serve; return the 201 body. Raises
|
|
1045
1064
|
OptimizeError carrying the server's error on any non-2xx (e.g. 409/422).
|
|
@@ -1058,7 +1077,11 @@ def _initiate_step(
|
|
|
1058
1077
|
resp = _request(
|
|
1059
1078
|
lambda: client.post(
|
|
1060
1079
|
f"{endpoint}/api/v1/deployments/{deployment_id}/optimize/{optimizer}",
|
|
1061
|
-
json=
|
|
1080
|
+
json=(
|
|
1081
|
+
{"data": data, "config": config}
|
|
1082
|
+
if may_author_code is None
|
|
1083
|
+
else {"data": data, "config": config, "may_author_code": may_author_code}
|
|
1084
|
+
),
|
|
1062
1085
|
headers=headers,
|
|
1063
1086
|
),
|
|
1064
1087
|
what,
|
|
@@ -5,7 +5,7 @@ name = "cmpnd"
|
|
|
5
5
|
# it's new) — no git tags. Bump with `uv version --bump {minor,patch}` or by
|
|
6
6
|
# hand. Runtime `cmpnd.__version__` reads installed metadata, so it tracks
|
|
7
7
|
# this automatically. See docs/plans/2026-07-02-sdk-pypi-tag-free-publish.md.
|
|
8
|
-
version = "0.18.
|
|
8
|
+
version = "0.18.3"
|
|
9
9
|
description = "DSPy observability and deployment SDK for cmpnd"
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
requires-python = ">=3.10"
|
|
@@ -14,9 +14,11 @@ before ``configuration.require_config()``.
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
+
import httpx
|
|
17
18
|
import pytest
|
|
18
19
|
|
|
19
20
|
import cmpnd
|
|
21
|
+
from cmpnd import optimization
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
def _feedback_metric(gold, pred, trace, pred_name, pred_trace):
|
|
@@ -103,3 +105,37 @@ def test_a_budget_passes_the_check_and_the_run_proceeds(budget):
|
|
|
103
105
|
**budget,
|
|
104
106
|
)
|
|
105
107
|
assert "budget" not in str(exc.value)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def test_the_declaration_about_code_travels_only_when_it_is_made():
|
|
111
|
+
"""`may_author_code` reaches serve as the caller's word, or not at all.
|
|
112
|
+
|
|
113
|
+
Omitted when unset, because the DEFAULT is the platform's — writing a `dspy.Flex` is
|
|
114
|
+
already the declaration — and an SDK that stamped `true` would put a second copy of
|
|
115
|
+
that default in the place hardest to change, since every released SDK keeps sending
|
|
116
|
+
whatever it was built with.
|
|
117
|
+
"""
|
|
118
|
+
sent: list[dict] = []
|
|
119
|
+
|
|
120
|
+
class Recorder:
|
|
121
|
+
def post(self, url, json, headers): # noqa: A002 — httpx's own parameter name
|
|
122
|
+
sent.append(json)
|
|
123
|
+
return httpx.Response(201, json={"optimization_id": "op_1", "status": "awaiting_data"})
|
|
124
|
+
|
|
125
|
+
for declared, want in ((None, None), (False, False), (True, True)):
|
|
126
|
+
sent.clear()
|
|
127
|
+
optimization._initiate_step(
|
|
128
|
+
Recorder(), # pyright: ignore[reportArgumentType] — only `.post` is reached
|
|
129
|
+
"https://serve.test",
|
|
130
|
+
{},
|
|
131
|
+
"d_1",
|
|
132
|
+
"gepa",
|
|
133
|
+
"upload",
|
|
134
|
+
{"max_metric_calls": 10},
|
|
135
|
+
declared,
|
|
136
|
+
)
|
|
137
|
+
assert len(sent) == 1
|
|
138
|
+
if want is None:
|
|
139
|
+
assert "may_author_code" not in sent[0], "an unset declaration must not be sent"
|
|
140
|
+
else:
|
|
141
|
+
assert sent[0]["may_author_code"] is want
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|