cmpnd 0.47.1__tar.gz → 0.49.0__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.47.1 → cmpnd-0.49.0}/PKG-INFO +1 -1
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/deployments.py +16 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/verbs.py +1 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/deployment_runs.py +40 -4
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/optimization.py +6 -1
- {cmpnd-0.47.1 → cmpnd-0.49.0}/docs/cli.md +10 -1
- {cmpnd-0.47.1 → cmpnd-0.49.0}/docs/sdk-instrumentation.md +3 -1
- {cmpnd-0.47.1 → cmpnd-0.49.0}/pyproject.toml +1 -1
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_deployment_runs.py +45 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_optimize_reflection_lm.py +12 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/uv.lock +1 -1
- {cmpnd-0.47.1 → cmpnd-0.49.0}/.gitignore +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/AGENTS.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/CLAUDE.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/README.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_assessments.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_authored_import.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_deployments.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_exporter_pool.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_gepa_patch.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_http.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_program_patch.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_rlm_patch.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_runtime_tools.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_timespec.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_traces.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/_valsets.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/authored.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/callback.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/api_client.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/admin.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/assessments.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/auth.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/datasets.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/evals.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/login.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/optimizations.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/org.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/programs.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/provider_credentials.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/signatures.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/tool_servers.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/top.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/traces.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/commands/valsets.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/credentials.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/deprecation.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/pagination.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/shell.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/trace_render.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/cli/tree_help.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/client.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/configuration.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/context.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/dataset_sync.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/datasets.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/decorators.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/deployment.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/deployment_metadata.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/eval_handler.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/execution.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/exporter.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/exporter_http.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/helpers.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/identity.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/imaging.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/ir/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/ir/decode.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/ir/encode.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/ir/hash.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/ir/program.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/ir/reflection.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/ir/types.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/ir/xxh64.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/lm_configuration.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/mcp_servers.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/models.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/named_programs.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/optimizers/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/optimizers/gepa.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/optimizers/gepa_callback.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/optimizers/resume.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/optimizers/tracker.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/packaging.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/programs.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/references.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/retry.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/cmpnd/traces.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/docs/2026-04-02-code-review.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/docs/client.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/docs/custom-proposer.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/docs/plans/2026-04-05-train-val-dataset-capture-design.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/docs/plans/2026-04-05-train-val-dataset-capture.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/docs/reading-traces.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/examples/generalizing_proposer.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/examples/local_ollama.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/LINEAGE.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/README.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/cmpnd_ingest/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/cmpnd_ingest/bodies.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/cmpnd_ingest/client_floor.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/cmpnd_ingest/exporter_http.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/cmpnd_ingest/program_names.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/cmpnd_ingest/protocols.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/cmpnd_ingest/py.typed +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/cmpnd_ingest/request_log.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/cmpnd_ingest/retry.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/cmpnd_ingest/trace_facts.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/ingest/pyproject.toml +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/scripts/audit-sdist.sh +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/scripts/capture_review_run.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/scripts/check-pip-install.sh +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/scripts/check_release_artifacts.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/scripts/fixtures/review_run.json.gz +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/scripts/gepa_resume_bug.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/scripts/release-stress.sh +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/scripts/require_version_bump.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/scripts/seed_review_run.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/scripts/test-in-linux.sh +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/stubs/dspy/__init__.pyi +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/stubs/dspy/primitives/__init__.pyi +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/stubs/dspy/primitives/prediction.pyi +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/stubs/dspy/utils/__init__.pyi +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/stubs/dspy/utils/callback.pyi +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/stubs/dspy/utils/dummies.pyi +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/_deployment_signature_helpers.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/_exporter_helpers.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/_fake_clock.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/_identity_helpers.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/_resolve_refs.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/_traced_run.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/conftest.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/committee_task.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/conftest.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/data/committee_train.ndjson.gz +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/data/committee_val.ndjson.gz +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/fake_lm.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/helpers.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/target_capabilities.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_assessments_cli.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_capture_prompts.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_composite_module.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_dataset_auto_creation.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_deploy_execute.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_deploy_pandas.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_deploy_programs.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_edge_cases.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_example_hash.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_gepa_optimization.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_interpreter_spans.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_lm_accuracy.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_module_tracing.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_optimization_lineage.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_optimization_metric_identity.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_optimize_failures.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_optimize_loop.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_optimize_review_committee.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_optimize_server_owned_completion.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_parallel_export.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_project_attribution.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_react_tool_spans.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_save_load.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_trace_structure.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_traces_read.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_user_attribution.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/e2e/test_valsets_cli.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/01_predict_qa.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/02_predict_renamed_field.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/03_chain_of_thought_qa.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/04_predict_richer_types.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/05_composite_two_predicts.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/06_multichaincomparison.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/07_program_of_thought.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/08_opaque_module.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/09_predict_pydantic_field.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/10_react.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/11_refine.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/12_retrieve.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/13_knn.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/14_parallel.json +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/identity_vectors/README.md +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/ingest_conformance.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/authored_optimize/judge.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/authored_optimize/optimize_hosted.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/conftest.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/hosted_mcp_tool_optimize_probe.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/hosted_optimize_probe.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/optimization_run_probe.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/test_cli_deploy_smoketest.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/test_logs_renders_traces.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/test_optimization_run.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/test_optimizing_progress.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/integration/test_unhappy_path.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/load/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/load/__main__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/load/drain.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/load/ingest.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/load/latency_transport.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/load/rlm_shape.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/load/rlm_size_report.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/load/sweep.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/load/test_rlm_shape.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/load/test_rlm_size_report.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/conftest.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/seed_parity.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/test_auth.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/test_datasets.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/test_deployments.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/test_evals.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/test_health.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/test_modules.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/test_optimizations.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/test_programs.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/test_signatures.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/test_trace_streaming.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/parity/test_traces.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/span_reference_fixture.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/_provider.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/_readiness.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/_reliability.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/_result.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/mint_bedrock_token.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_deploy_programs.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_multi_client_stress.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_optimize_client_committee.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_optimize_loop.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_optimize_loop_wasm.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_optimize_stress.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_provider_roles.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_readiness.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_real_provider_twins.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_reliability.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_reliability_classify.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_rlm_wasm.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/stress/test_trace_search.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_adapter_reentrancy.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_assessments_api.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_authored.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_authored_bundle_collisions.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_authored_metric_contract.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_authored_named_models.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_authored_optimize.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_callback.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_candidate_lineage.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/conftest.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_admin.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_api_client.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_assessments.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_auth.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_credentials.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_datasets.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_deployments.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_evals.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_login.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_main.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_optimizations.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_org.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_pagination.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_parity.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_programs.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_provider_credentials.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_schema_sample.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_shell.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_signatures.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_tool_servers.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_top.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_traces.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_traces_search_wire.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_tree_help.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cli/test_valsets.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_client.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_client_floor.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_client_program_names.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_clustering/__init__.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_clustering/conftest.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_clustering/test_edge_cases.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_clustering/test_hash_consistency.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_clustering/test_type_conversion.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_cmp551_grouping_identity.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_configuration.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_context.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_context_propagation.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_dataset_polling.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_dataset_sync.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_datasets.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_decision_client_spans.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_decorators.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_deploy.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_deploy_mcp_tool_references.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_deploy_program_id.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_deployment_metadata.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_deployment_runs.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_deployments_read.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_eval.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_eval_example_attribution.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_eval_start.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_eval_trace_grouping.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_exception_paths.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_execute.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_execute_run_identity.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_exporter.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_exporter_program_names.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_exporter_queue.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_exporter_real.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_fake_lm.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_gepa_callback.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_gepa_integration.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_gepa_output_normalization.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_gepa_resume.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_identity.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_imaging.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_import_weight.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_ingest_conformance.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_ingest_second_producer.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_integration.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_interpreter_callback.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_ir_encoder_properties.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_ir_golden_vectors.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_ir_roundtrip.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_lm15_native_calls.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_lm_configuration.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_lm_usage_shapes.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_mcp_tools.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_models.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_multi_client_stress_readiness.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_optimization_progress.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_optimization_start.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_optimize.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_optimize_budget.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_optimize_lift.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_optimize_lms.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_optimize_proposer.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_optimize_terminal_failure.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_packaging.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_packaging_callable_source.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_packaging_mcp_tools.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_packaging_program_source.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_poll_until.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_program_identity.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_program_lineage_persist.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_programs_create.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_project_payload.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_real_provider_twins_readiness.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_reflector_properties.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_reflector_smoke.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_release_stress_script.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_repro_reactv2_bugs.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_require_version_bump.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_retry.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_reversible_failures.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_rlm_patch.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_run_attribution_paths.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_runtime_tools.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_schemas.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_seed_review_run.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_signature_inputs.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_span_references.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_span_sent_once.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_system_one.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_trace_context_concurrency.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_trace_fact_wire_contract.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_trace_facts.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_trace_render.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_traces_read.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_tracked_gepa.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_tracker_enrich.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_truncation.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_upload_auth_headers.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_valsets_api.py +0 -0
- {cmpnd-0.47.1 → cmpnd-0.49.0}/tests/test_xxh64.py +0 -0
|
@@ -73,6 +73,12 @@ def register(subparsers: _SubParsersAction[ArgumentParser]) -> None:
|
|
|
73
73
|
if name == "wait":
|
|
74
74
|
command.add_argument("--timeout", type=float, default=None, help=TIMEOUT_HELP)
|
|
75
75
|
command.set_defaults(func=handler)
|
|
76
|
+
cancel = run_sub.add_parser(
|
|
77
|
+
"cancel",
|
|
78
|
+
help="Cancel a queued or running deployment run. It settles as failed with error_code cancelled",
|
|
79
|
+
)
|
|
80
|
+
cancel.add_argument("id", help="Deployment run ID")
|
|
81
|
+
cancel.set_defaults(func=handle_runs_cancel)
|
|
76
82
|
|
|
77
83
|
openapi = sub.add_parser(
|
|
78
84
|
"openapi",
|
|
@@ -251,6 +257,16 @@ def handle_runs_wait(client: api_client.ApiClient, args: Any) -> Any:
|
|
|
251
257
|
return settled
|
|
252
258
|
|
|
253
259
|
|
|
260
|
+
def handle_runs_cancel(client: api_client.ApiClient, args: Any) -> Any:
|
|
261
|
+
"""Settle an open run as cancelled and return its header.
|
|
262
|
+
|
|
263
|
+
Serve stops dispatching and collecting the run at once. A run already
|
|
264
|
+
executing on a worker runs on there until its deadline and may spend model
|
|
265
|
+
calls, but its answer is discarded.
|
|
266
|
+
"""
|
|
267
|
+
return client.post(f"/api/v1/deployments/runs/{args.id}/cancel")
|
|
268
|
+
|
|
269
|
+
|
|
254
270
|
def handle_openapi(client: api_client.ApiClient, args: Any) -> None:
|
|
255
271
|
"""Write the deployment's OpenAPI document to stdout.
|
|
256
272
|
|
|
@@ -152,6 +152,7 @@ DOMAIN_VERBS: dict[str, str] = {
|
|
|
152
152
|
"revoke-invite": "withdraws the open owner invites to an address; bare revoke would read as revoking the org",
|
|
153
153
|
"run": "submits a deployment execution and optionally waits for its retained answer",
|
|
154
154
|
"wait": "polls one accepted run until it settles or the local budget expires",
|
|
155
|
+
"cancel": "settles an open run as cancelled and keeps its record; delete would read as removing the run",
|
|
155
156
|
"follow": "tails a record until it settles — a list over time rather than a snapshot",
|
|
156
157
|
"select": "marks one candidate as the program's chosen version",
|
|
157
158
|
"refresh": "re-reads a record from the system of record it mirrors; nothing the caller supplies is written",
|
|
@@ -100,11 +100,28 @@ class RunSubmissionUncertain(RuntimeError):
|
|
|
100
100
|
_set_run_id(self, run_id)
|
|
101
101
|
|
|
102
102
|
|
|
103
|
+
def _cancel_command(run_id: str) -> str:
|
|
104
|
+
return f"cmpnd deployments runs cancel {run_id}"
|
|
105
|
+
|
|
106
|
+
|
|
103
107
|
class RunWaitTimeout(TimeoutError):
|
|
104
|
-
"""The local budget ran out; the accepted run continues.
|
|
108
|
+
"""The local budget ran out; the accepted run continues.
|
|
105
109
|
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
``status`` and ``status_reason`` are the run's last header read, when one
|
|
111
|
+
arrived: why the run is still open, such as a queued run waiting for a
|
|
112
|
+
credential or a worker.
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
def __init__(self, run_id: str, *, status: str | None = None, status_reason: str | None = None):
|
|
116
|
+
state = ""
|
|
117
|
+
if status:
|
|
118
|
+
state = f" ({status}: {status_reason})" if status_reason else f" ({status})"
|
|
119
|
+
super().__init__(
|
|
120
|
+
f"Deployment run {run_id} has not settled{state}. "
|
|
121
|
+
f"Resume with `{_wait_command(run_id)}`, or stop it with `{_cancel_command(run_id)}`."
|
|
122
|
+
)
|
|
123
|
+
self.status = status
|
|
124
|
+
self.status_reason = status_reason
|
|
108
125
|
_set_run_id(self, run_id)
|
|
109
126
|
|
|
110
127
|
|
|
@@ -325,6 +342,9 @@ class _RunClient:
|
|
|
325
342
|
self.api_key = api_key
|
|
326
343
|
self.client: httpx.Client | None = None
|
|
327
344
|
self.retry_after = 0.0
|
|
345
|
+
# The last run header a wait read, so a wait that runs out can say why
|
|
346
|
+
# the run is still open.
|
|
347
|
+
self.last_header: dict[str, Any] | None = None
|
|
328
348
|
|
|
329
349
|
def __enter__(self) -> _RunClient:
|
|
330
350
|
self.client = _http.new_client(headers={"X-API-Key": self.api_key})
|
|
@@ -444,8 +464,23 @@ class _RunClient:
|
|
|
444
464
|
"""Follow an accepted run until its retained answer is read or the budget ends.
|
|
445
465
|
|
|
446
466
|
Reads only. A read refused with 401, 403 or 404 raises at once; timeouts,
|
|
447
|
-
408, 429 and server errors are retried with backoff and jitter.
|
|
467
|
+
408, 429 and server errors are retried with backoff and jitter. When the
|
|
468
|
+
budget runs out, the timeout names the run's last status and reason.
|
|
448
469
|
"""
|
|
470
|
+
self.last_header = initial
|
|
471
|
+
try:
|
|
472
|
+
return self._follow(run_id, deadline, initial)
|
|
473
|
+
except RunWaitTimeout:
|
|
474
|
+
header = self.last_header
|
|
475
|
+
if header is None:
|
|
476
|
+
raise
|
|
477
|
+
reason = header.get("status_reason")
|
|
478
|
+
raise RunWaitTimeout(
|
|
479
|
+
run_id, status=header.get("status"), status_reason=reason if isinstance(reason, str) else None
|
|
480
|
+
) from None
|
|
481
|
+
|
|
482
|
+
def _follow(self, run_id: str, deadline: float | None, initial: dict[str, Any] | None) -> dict[str, Any]:
|
|
483
|
+
"""The wait loop. It records each header it reads in ``last_header``."""
|
|
449
484
|
header = initial
|
|
450
485
|
need_status = header is None
|
|
451
486
|
delay = _FIRST_POLL_DELAY
|
|
@@ -455,6 +490,7 @@ class _RunClient:
|
|
|
455
490
|
response = self._poll(status_path, deadline, run_id)
|
|
456
491
|
if response is not None:
|
|
457
492
|
header = _validate_run(_json(response, "status", run_id), submitted=False)
|
|
493
|
+
self.last_header = header
|
|
458
494
|
need_status = True
|
|
459
495
|
if header is not None and header["status"] in _TERMINAL:
|
|
460
496
|
# The status is settled, so only the answer remains to be read.
|
|
@@ -862,7 +862,12 @@ def optimize(
|
|
|
862
862
|
in ``config["reflection_model"]``, which is what the server
|
|
863
863
|
establishes this run's reflection credential from, and its sampling in
|
|
864
864
|
``config["reflection_sampling"]``, which only the reflecting tier
|
|
865
|
-
reads.
|
|
865
|
+
reads. A reflection turn that names no output cap or temperature
|
|
866
|
+
gets the platform's (a large ``max_tokens`` and ``temperature=1.0``).
|
|
867
|
+
To send none and let the model's own defaults apply, pass the model
|
|
868
|
+
name as a string and set those keys to ``None`` in
|
|
869
|
+
``config["reflection_sampling"]``, e.g.
|
|
870
|
+
``{"max_tokens": None, "temperature": None}``. An ``api_key``, ``api_base`` or ``base_url`` on it is refused
|
|
866
871
|
rather than dropped: the credential a run spends and the endpoint it
|
|
867
872
|
is spent at are both the platform's, so one set here would be
|
|
868
873
|
discarded without a word. The server refuses a gepa run
|
|
@@ -88,6 +88,9 @@ within the budget.
|
|
|
88
88
|
|
|
89
89
|
The budget or Ctrl-C stops the local wait, and an accepted run continues.
|
|
90
90
|
After acceptance the CLI prints `cmpnd deployments runs wait <id>` on stderr.
|
|
91
|
+
A wait that runs out also names the run's last status and `status_reason`,
|
|
92
|
+
such as `queued: execution_authority_unavailable`, and the command that
|
|
93
|
+
cancels it.
|
|
91
94
|
When the submission reply is lost or fails, acceptance is uncertain. The CLI
|
|
92
95
|
then prints `cmpnd deployments runs list --deployment <id>`. Check that list
|
|
93
96
|
before you submit again.
|
|
@@ -104,7 +107,13 @@ with `--deployment ID`. It takes these filters:
|
|
|
104
107
|
Each page reports `total`, the number of matching runs, and `has_more` when another page follows.
|
|
105
108
|
|
|
106
109
|
`show ID` prints one run, `result ID` reads its retained answer, and
|
|
107
|
-
`wait ID [--timeout SECONDS]` resumes waiting.
|
|
110
|
+
`wait ID [--timeout SECONDS]` resumes waiting. `cancel ID` settles a queued or
|
|
111
|
+
running run as `failed` with `error_code` `cancelled` and prints it. Serve
|
|
112
|
+
stops dispatching and collecting the run at once. A run already executing on a
|
|
113
|
+
worker runs on there until its deadline and may spend model calls, but its
|
|
114
|
+
answer is discarded. A key with `deployments:write` cancels any run, and a key
|
|
115
|
+
with only `deployments:execute` cancels the runs it submitted. Cancelling a run
|
|
116
|
+
that already settled exits nonzero. The run commands' JSON output
|
|
108
117
|
needs no DSPy install.
|
|
109
118
|
|
|
110
119
|
### A file deploys as the source you wrote
|
|
@@ -407,7 +407,9 @@ lost POST reply or a server `5xx` leaves acceptance uncertain, so the SDK raises
|
|
|
407
407
|
names the command to list recent runs. Reads that time out or answer `408`,
|
|
408
408
|
`429` or `5xx` are retried with backoff and jitter, honoring `Retry-After`. A
|
|
409
409
|
`401`, `403` or `404` read raises at once. A spent budget raises
|
|
410
|
-
`RunWaitTimeout`, and the accepted run continues.
|
|
410
|
+
`RunWaitTimeout`, and the accepted run continues. Its `status` and
|
|
411
|
+
`status_reason` hold the run's last header read, and its message names them
|
|
412
|
+
with the commands that resume the wait and cancel the run. Ctrl-C prints the run ID and
|
|
411
413
|
`cmpnd deployments runs wait <id>` on stderr, or before acceptance the list
|
|
412
414
|
command, and re-raises.
|
|
413
415
|
|
|
@@ -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.
|
|
8
|
+
version = "0.49.0"
|
|
9
9
|
description = "DSPy observability and deployment SDK for cmpnd"
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
requires-python = ">=3.11"
|
|
@@ -215,6 +215,51 @@ def test_interrupted_run_names_the_accepted_run(monkeypatch: pytest.MonkeyPatch,
|
|
|
215
215
|
assert f"cmpnd deployments runs wait {RUN_ID}" in capsys.readouterr().err
|
|
216
216
|
|
|
217
217
|
|
|
218
|
+
@pytest.mark.parametrize("verb", [["run", DEPLOYMENT_ID, "{}"], ["deployments", "runs", "wait", RUN_ID]])
|
|
219
|
+
def test_a_wait_that_runs_out_names_why_the_run_is_still_open(monkeypatch: pytest.MonkeyPatch, capsys, verb):
|
|
220
|
+
from cmpnd import deployment_runs
|
|
221
|
+
|
|
222
|
+
clock = iter(float(tick) for tick in range(1000))
|
|
223
|
+
monkeypatch.setattr(deployment_runs, "_now", lambda: next(clock))
|
|
224
|
+
monkeypatch.setattr(deployment_runs, "_sleep", lambda _: None)
|
|
225
|
+
waiting = {**_envelope("queued"), "status_reason": "execution_authority_unavailable"}
|
|
226
|
+
|
|
227
|
+
def answer(req):
|
|
228
|
+
return httpx.Response(202 if req.method == "POST" else 200, json=waiting, request=req)
|
|
229
|
+
|
|
230
|
+
with pytest.raises(SystemExit) as caught:
|
|
231
|
+
_run_cli(monkeypatch, [*verb, "--timeout", "6"], answer)
|
|
232
|
+
assert caught.value.code != 0
|
|
233
|
+
err = capsys.readouterr().err
|
|
234
|
+
assert f"Deployment run {RUN_ID} has not settled" in err
|
|
235
|
+
assert "queued: execution_authority_unavailable" in err
|
|
236
|
+
assert f"cmpnd deployments runs wait {RUN_ID}" in err
|
|
237
|
+
assert f"cmpnd deployments runs cancel {RUN_ID}" in err
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def test_runs_cancel_posts_the_cancel_and_prints_the_settled_run(monkeypatch: pytest.MonkeyPatch, capsys):
|
|
241
|
+
seen = []
|
|
242
|
+
cancelled = {**_envelope("failed"), "error_code": "cancelled"}
|
|
243
|
+
|
|
244
|
+
def answer(req):
|
|
245
|
+
seen.append(req)
|
|
246
|
+
return httpx.Response(200, json=cancelled, request=req)
|
|
247
|
+
|
|
248
|
+
_run_cli(monkeypatch, ["deployments", "runs", "cancel", RUN_ID], answer)
|
|
249
|
+
assert [(req.method, req.url.path) for req in seen] == [("POST", f"/api/v1/deployments/runs/{RUN_ID}/cancel")]
|
|
250
|
+
assert json.loads(capsys.readouterr().out)["error_code"] == "cancelled"
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def test_runs_cancel_of_a_settled_run_exits_nonzero(monkeypatch: pytest.MonkeyPatch, capsys):
|
|
254
|
+
def answer(req):
|
|
255
|
+
return httpx.Response(409, json={"error": "deployment run already settled as completed"}, request=req)
|
|
256
|
+
|
|
257
|
+
with pytest.raises(SystemExit) as caught:
|
|
258
|
+
_run_cli(monkeypatch, ["deployments", "runs", "cancel", RUN_ID], answer)
|
|
259
|
+
assert caught.value.code != 0
|
|
260
|
+
assert "already settled as completed" in capsys.readouterr().err
|
|
261
|
+
|
|
262
|
+
|
|
218
263
|
def test_interrupted_submission_reports_uncertainty(monkeypatch: pytest.MonkeyPatch, capsys):
|
|
219
264
|
def answer(req):
|
|
220
265
|
raise KeyboardInterrupt
|
|
@@ -189,6 +189,18 @@ def test_the_refusal_fires_even_when_the_lm_would_have_overwritten_it():
|
|
|
189
189
|
optimization._reflection_config(config, _LM("openai/gpt-4o", top_p=0.9))
|
|
190
190
|
|
|
191
191
|
|
|
192
|
+
def test_a_none_in_config_sampling_travels_as_none():
|
|
193
|
+
"""``None`` asks the reflecting tier to drop its own default for that key, so the
|
|
194
|
+
model's default applies. This layer must carry it rather than filter it out as
|
|
195
|
+
"unset", which is what it means everywhere an LM's own state is read."""
|
|
196
|
+
config = {"reflection_sampling": {"max_tokens": None, "temperature": None}}
|
|
197
|
+
optimization._reflection_config(config, "openai/gpt-4o")
|
|
198
|
+
assert config == {
|
|
199
|
+
"reflection_model": "openai/gpt-4o",
|
|
200
|
+
"reflection_sampling": {"max_tokens": None, "temperature": None},
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
|
|
192
204
|
def test_a_model_name_beside_config_sampling_stays_legal():
|
|
193
205
|
"""The string path is the one way left to name sampling through ``config``, so it
|
|
194
206
|
keeps working — a name says nothing about sampling and so contradicts nothing."""
|
|
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
|