cmpnd 0.68.0__tar.gz → 0.70.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.68.0 → cmpnd-0.70.0}/PKG-INFO +1 -1
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_authored_import.py +0 -1
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/authored.py +0 -5
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/evals.py +13 -1
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/dataset_sync.py +8 -5
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/deployment.py +1 -4
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/eval_handler.py +35 -9
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/models.py +13 -3
- {cmpnd-0.68.0 → cmpnd-0.70.0}/docs/cli.md +12 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/docs/sdk-instrumentation.md +5 -1
- {cmpnd-0.68.0 → cmpnd-0.70.0}/pyproject.toml +1 -1
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_deploy_programs.py +0 -1
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_loop.py +7 -11
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_authored.py +2 -1
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_evals.py +16 -2
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_deploy.py +3 -4
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_deploy_program_id.py +1 -1
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_eval.py +1 -1
- cmpnd-0.70.0/tests/test_eval_program_id.py +192 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_eval_start.py +2 -2
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_ingest_conformance.py +2 -1
- {cmpnd-0.68.0 → cmpnd-0.70.0}/uv.lock +1 -1
- {cmpnd-0.68.0 → cmpnd-0.70.0}/.gitignore +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/AGENTS.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/CLAUDE.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/README.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_assessments.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_deployments.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_exporter_pool.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_gepa_patch.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_http.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_program_patch.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_rlm_patch.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_runtime_tools.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_timespec.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_traces.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/_valsets.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/callback.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/api_client.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/admin.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/assessments.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/auth.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/datasets.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/deployments.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/login.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/optimizations.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/org.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/programs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/provider_credentials.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/tool_servers.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/top.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/traces.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/commands/valsets.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/credentials.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/deprecation.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/pagination.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/shell.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/trace_render.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/tree_help.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/verbs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/cli/views.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/client.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/configuration.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/context.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/credentials.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/datasets.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/decorators.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/deployment_metadata.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/deployment_runs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/execution.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/exporter.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/exporter_http.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/helpers.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/identity.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/imaging.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/ir/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/ir/decode.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/ir/encode.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/ir/hash.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/ir/program.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/ir/reflection.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/ir/types.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/ir/xxh64.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/lm_configuration.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/mcp_servers.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/named_programs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/optimization.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/optimizers/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/optimizers/gepa.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/optimizers/gepa_callback.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/optimizers/resume.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/optimizers/tracker.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/packaging.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/programs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/references.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/retry.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/cmpnd/traces.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/docs/2026-04-02-code-review.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/docs/client.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/docs/custom-proposer.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/docs/plans/2026-04-05-train-val-dataset-capture-design.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/docs/plans/2026-04-05-train-val-dataset-capture.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/docs/reading-traces.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/examples/generalizing_proposer.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/examples/local_ollama.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/LINEAGE.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/README.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/bodies.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/client_floor.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/exporter_http.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/program_names.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/protocols.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/py.typed +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/request_log.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/retry.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/trace_facts.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/ingest/pyproject.toml +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/audit-sdist.sh +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/capture_review_run.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/check-pip-install.sh +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/check_release_artifacts.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/fixtures/review_run.json.gz +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/gepa_resume_bug.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/install-test-env.sh +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/release-gate.sh +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/release-real-models.sh +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/require_version_bump.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/seed_review_run.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/selfhost_compat.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/scripts/test-in-linux.sh +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/stubs/dspy/__init__.pyi +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/stubs/dspy/primitives/__init__.pyi +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/stubs/dspy/primitives/prediction.pyi +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/stubs/dspy/utils/__init__.pyi +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/stubs/dspy/utils/callback.pyi +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/stubs/dspy/utils/dummies.pyi +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/_credential_route.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/_deployment_signature_helpers.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/_exporter_helpers.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/_fake_clock.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/_identity_helpers.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/_resolve_refs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/_traced_run.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/conftest.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/committee_task.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/conftest.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/continuation_task.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/data/committee_train.ndjson.gz +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/data/committee_val.ndjson.gz +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/fake_lm.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/helpers.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/target_capabilities.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_assessments_cli.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_capture_prompts.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_composite_module.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_dataset_auto_creation.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_deploy_execute.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_deploy_pandas.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_edge_cases.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_example_hash.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_gepa_optimization.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_interpreter_spans.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_lm_accuracy.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_module_tracing.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_optimization_lineage.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_optimization_metric_identity.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_authored_metric.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_continuation.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_custom_proposer.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_failures.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_review_committee.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_server_owned_completion.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_parallel_export.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_project_attribution.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_react_tool_spans.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_save_load.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_trace_structure.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_traces_read.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_user_attribution.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/e2e/test_valsets_cli.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/01_predict_qa.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/02_predict_renamed_field.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/03_chain_of_thought_qa.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/04_predict_richer_types.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/05_composite_two_predicts.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/06_multichaincomparison.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/07_program_of_thought.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/08_opaque_module.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/09_predict_pydantic_field.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/10_react.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/11_refine.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/12_retrieve.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/13_knn.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/14_parallel.json +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/identity_vectors/README.md +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/ingest_conformance.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/authored_optimize/judge.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/authored_optimize/optimize_hosted.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/conftest.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/hosted_mcp_tool_optimize_probe.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/hosted_optimize_probe.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/optimization_run_probe.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/test_cli_deploy_smoketest.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/test_logs_renders_traces.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/test_optimization_run.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/test_optimizing_progress.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/integration/test_unhappy_path.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/load/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/load/__main__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/load/drain.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/load/ingest.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/load/latency_transport.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/load/rlm_shape.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/load/rlm_size_report.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/load/sweep.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/load/test_rlm_shape.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/load/test_rlm_size_report.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/conftest.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/seed_parity.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/test_auth.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/test_datasets.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/test_deployments.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/test_evals.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/test_health.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/test_modules.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/test_optimizations.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/test_programs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/test_signatures.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/test_trace_streaming.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/parity/test_traces.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/_provider.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/_readiness.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/_reliability.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/_result.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/mint_bedrock_token.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_bedrock_converse.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_deploy_programs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_multi_client_stress.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_optimize_client_committee.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_optimize_continuation.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_optimize_loop.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_optimize_loop_wasm.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_optimize_stress.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_provider_roles.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_readiness.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_real_provider_twins.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_reliability.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_reliability_classify.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_rlm_wasm.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/real_models/test_trace_search.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/span_reference_fixture.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_adapter_reentrancy.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_assessments_api.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_authored_binding_credentials.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_authored_bundle_collisions.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_authored_metric_contract.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_authored_named_models.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_authored_optimize.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_callback.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_candidate_lineage.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/conftest.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_admin.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_api_client.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_assessments.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_auth.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_credentials.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_datasets.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_deployment_runs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_deployments.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_login.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_main.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_optimizations.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_org.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_pagination.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_parity.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_programs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_provider_credentials.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_schema_sample.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_shell.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_tool_servers.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_top.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_traces.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_traces_program_and_module.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_traces_search_wire.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_tree_help.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cli/test_valsets.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_client.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_client_floor.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_client_program_names.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_clustering/__init__.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_clustering/conftest.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_clustering/test_edge_cases.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_clustering/test_hash_consistency.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_clustering/test_type_conversion.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_cmp551_grouping_identity.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_configuration.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_context.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_context_propagation.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_credential_kwargs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_credential_selection.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_credential_values.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_dataset_polling.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_dataset_sync.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_datasets.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_decision_client_spans.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_decorators.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_deploy_mcp_tool_references.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_deployment_metadata.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_deployment_runs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_deployments_read.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_eval_example_attribution.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_eval_trace_grouping.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_exception_paths.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_execute.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_execute_run_identity.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_exporter.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_exporter_program_names.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_exporter_queue.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_exporter_real.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_fake_lm.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_gepa_callback.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_gepa_integration.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_gepa_output_normalization.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_gepa_resume.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_identity.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_imaging.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_import_weight.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_ingest_second_producer.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_integration.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_interpreter_callback.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_ir_encoder_properties.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_ir_golden_vectors.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_ir_roundtrip.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_lm15_native_calls.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_lm_configuration.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_lm_usage_shapes.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_mcp_tools.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_models.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_multi_client_stress_readiness.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_optimization_progress.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_optimization_start.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_optimize.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_optimize_budget.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_optimize_lift.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_optimize_lms.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_optimize_proposer.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_optimize_reflection_lm.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_optimize_terminal_failure.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_packaging.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_packaging_callable_source.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_packaging_mcp_tools.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_packaging_program_source.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_poll_until.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_program_id_deprecation.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_program_identity.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_program_lineage_persist.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_program_names_in_deploy.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_programs_create.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_project_payload.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_real_provider_twins_readiness.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_reflector_properties.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_reflector_smoke.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_release_gate_script.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_release_real_models_script.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_replaced_names.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_repro_reactv2_bugs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_require_version_bump.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_retry.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_reversible_failures.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_rlm_patch.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_run_attribution_paths.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_runtime_tools.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_schemas.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_seal_lm_credential.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_seed_review_run.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_signature_inputs.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_span_references.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_span_sent_once.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_system_one.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_trace_context_concurrency.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_trace_fact_wire_contract.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_trace_facts.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_trace_render.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_traces_read.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_tracked_gepa.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_tracker_enrich.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_truncation.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_upload_auth_headers.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_valsets_api.py +0 -0
- {cmpnd-0.68.0 → cmpnd-0.70.0}/tests/test_xxh64.py +0 -0
|
@@ -263,7 +263,6 @@ def _program_facts(
|
|
|
263
263
|
lm = packaging._extract_lm_object(program)
|
|
264
264
|
lm_kwargs = getattr(lm, "kwargs", {}) if lm is not None else {}
|
|
265
265
|
facts = ProgramFacts(
|
|
266
|
-
program_signature_hash=identity.compute_program_hash(program),
|
|
267
266
|
entrypoint_kind=kind,
|
|
268
267
|
module_class=type(program).__name__,
|
|
269
268
|
litellm_model=getattr(lm, "model", None),
|
|
@@ -43,7 +43,6 @@ class SourceCheckError(ValueError):
|
|
|
43
43
|
class ProgramFacts:
|
|
44
44
|
"""Facts derived by importing the staged program without calling forward."""
|
|
45
45
|
|
|
46
|
-
program_signature_hash: int | None = None
|
|
47
46
|
entrypoint_kind: str = "instance"
|
|
48
47
|
module_class: str | None = None
|
|
49
48
|
signature_name: str | None = None
|
|
@@ -72,11 +71,7 @@ class ProgramFacts:
|
|
|
72
71
|
|
|
73
72
|
def deploy_body(self) -> dict[str, Any]:
|
|
74
73
|
"""Return fields the deployment create route accepts."""
|
|
75
|
-
from . import identity
|
|
76
|
-
|
|
77
74
|
body: dict[str, Any] = {}
|
|
78
|
-
if self.program_signature_hash is not None:
|
|
79
|
-
body["program_signature_hash"] = identity.format_signature_hash(self.program_signature_hash)
|
|
80
75
|
for name in (
|
|
81
76
|
"module_class",
|
|
82
77
|
"signature_name",
|
|
@@ -9,7 +9,18 @@ from .. import api_client, deprecation, pagination
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def _add_list_args(p: ArgumentParser) -> None:
|
|
12
|
-
p.add_argument(
|
|
12
|
+
p.add_argument(
|
|
13
|
+
"--program",
|
|
14
|
+
dest="program_name",
|
|
15
|
+
metavar="NAME",
|
|
16
|
+
help="Only the runs of the program with this name, current or retired",
|
|
17
|
+
)
|
|
18
|
+
p.add_argument(
|
|
19
|
+
"--module",
|
|
20
|
+
dest="module_class",
|
|
21
|
+
metavar="CLASS",
|
|
22
|
+
help="Only the runs that evaluated this module class, matched exactly (e.g. ReAct)",
|
|
23
|
+
)
|
|
13
24
|
p.add_argument("--metric", dest="metric_name", help="Filter by metric name")
|
|
14
25
|
p.add_argument("--status", help="Filter by status (running, completed, failed, cancelled)")
|
|
15
26
|
pagination.add_args(p, with_page_aliases=True, default_limit=50)
|
|
@@ -63,6 +74,7 @@ def handle_list(client: api_client.ApiClient, args: Any) -> Any:
|
|
|
63
74
|
body: dict[str, Any] = pagination.wire(args, "page_size")
|
|
64
75
|
for attr, key in [
|
|
65
76
|
("program_name", "program_name"),
|
|
77
|
+
("module_class", "module_class"),
|
|
66
78
|
("metric_name", "metric"),
|
|
67
79
|
("status", "status"),
|
|
68
80
|
]:
|
|
@@ -15,7 +15,7 @@ from . import _http, configuration, identity, models
|
|
|
15
15
|
logger = logging.getLogger(__name__)
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
def check_dataset_exists(dataset_hash: str) -> bool:
|
|
18
|
+
def check_dataset_exists(dataset_hash: str, config: configuration.Config | None = None) -> bool:
|
|
19
19
|
"""Check if a dataset with this hash already exists on the backend.
|
|
20
20
|
|
|
21
21
|
Makes a GET request to /api/v1/datasets/check/{dataset_hash}.
|
|
@@ -23,14 +23,17 @@ def check_dataset_exists(dataset_hash: str) -> bool:
|
|
|
23
23
|
|
|
24
24
|
Args:
|
|
25
25
|
dataset_hash: The SHA256[:16] hash of the dataset.
|
|
26
|
+
config: The account to ask, which must be the account the run publishes
|
|
27
|
+
to. None asks the process-global account.
|
|
26
28
|
|
|
27
29
|
Returns:
|
|
28
30
|
True if the dataset exists, False otherwise (including on errors).
|
|
29
31
|
"""
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
if config is None:
|
|
33
|
+
try:
|
|
34
|
+
config = configuration.require_config()
|
|
35
|
+
except RuntimeError:
|
|
36
|
+
return False
|
|
34
37
|
|
|
35
38
|
url = f"{config.endpoint}/api/v1/datasets/check/{dataset_hash}"
|
|
36
39
|
|
|
@@ -527,13 +527,10 @@ def deploy_module_under(
|
|
|
527
527
|
# Package the module
|
|
528
528
|
zip_bytes = packaging.generate_source_zip(module, metric, mcp_tools=pinned_mcp_tools)
|
|
529
529
|
|
|
530
|
-
#
|
|
531
|
-
# tag included); the signature is kept around only for display metadata.
|
|
530
|
+
# The deployment names its program by id alone; the signature only describes it.
|
|
532
531
|
sig = packaging._get_module_signature(module)
|
|
533
|
-
program_signature_hash = identity.compute_program_hash(module) or 0
|
|
534
532
|
|
|
535
533
|
deploy_body: dict[str, Any] = {
|
|
536
|
-
"program_signature_hash": identity.format_signature_hash(program_signature_hash),
|
|
537
534
|
# Declare the ZIP's exact length so the server can reject an oversized
|
|
538
535
|
# deploy before the upload.
|
|
539
536
|
"declared_content_length": len(zip_bytes),
|
|
@@ -10,7 +10,7 @@ import logging
|
|
|
10
10
|
from datetime import datetime, timezone
|
|
11
11
|
from typing import Any
|
|
12
12
|
|
|
13
|
-
from . import context,
|
|
13
|
+
from . import context, helpers, identity, models
|
|
14
14
|
|
|
15
15
|
logger = logging.getLogger(__name__)
|
|
16
16
|
|
|
@@ -85,7 +85,7 @@ class EvalHandler:
|
|
|
85
85
|
logger.debug(f"Extracted program: {program}, type: {type(program) if program else None}")
|
|
86
86
|
|
|
87
87
|
if program:
|
|
88
|
-
eval_run.
|
|
88
|
+
eval_run.module_class = program.__class__.__name__
|
|
89
89
|
|
|
90
90
|
# Hash via the IR reflector on the live module so the class tag
|
|
91
91
|
# discriminates correctly; signature_summary is still derived from
|
|
@@ -165,16 +165,23 @@ class EvalHandler:
|
|
|
165
165
|
if not input_fields and devset and hasattr(devset[0], "_input_keys"):
|
|
166
166
|
input_fields = set(devset[0]._input_keys)
|
|
167
167
|
eval_run._input_fields = input_fields
|
|
168
|
-
# Fire pre-flight check (synchronous, short timeout)
|
|
168
|
+
# Fire pre-flight check (synchronous, short timeout). It asks the
|
|
169
|
+
# account the run publishes to: a client's own, else the global one.
|
|
169
170
|
from . import dataset_sync
|
|
170
171
|
|
|
171
172
|
try:
|
|
172
|
-
eval_run._dataset_exists = dataset_sync.check_dataset_exists(
|
|
173
|
+
eval_run._dataset_exists = dataset_sync.check_dataset_exists(
|
|
174
|
+
eval_run.dataset_hash, self._callback._own_config
|
|
175
|
+
)
|
|
173
176
|
except Exception:
|
|
174
177
|
eval_run._dataset_exists = None # Will include examples as fallback
|
|
175
178
|
|
|
179
|
+
exp = self._callback._current_exporter()
|
|
180
|
+
eval_run.program_id = self._program_id(exp)
|
|
181
|
+
|
|
176
182
|
logger.info(
|
|
177
|
-
f"EvalRun created:
|
|
183
|
+
f"EvalRun created: program_id={eval_run.program_id}, "
|
|
184
|
+
f"module_class={eval_run.module_class}, "
|
|
178
185
|
f"metric_name={eval_run.metric_name}, "
|
|
179
186
|
f"dataset_hash={eval_run.dataset_hash}, "
|
|
180
187
|
f"dataset_size={eval_run.dataset_size}"
|
|
@@ -184,7 +191,6 @@ class EvalHandler:
|
|
|
184
191
|
# the exporter (serve/observe, or deploy in-Lambda) assigns it. Obtain
|
|
185
192
|
# it synchronously now, before any eval trace ships, since every
|
|
186
193
|
# in-flight trace and the dict keys / span below are stamped with it.
|
|
187
|
-
exp = exporter.get_exporter()
|
|
188
194
|
if exp:
|
|
189
195
|
eval_run.eval_run_id = exp.export_eval_start(eval_run)
|
|
190
196
|
|
|
@@ -201,13 +207,33 @@ class EvalHandler:
|
|
|
201
207
|
|
|
202
208
|
# Capture evaluation config in span attributes
|
|
203
209
|
span.attributes["eval.run_id"] = str(eval_run.eval_run_id)
|
|
204
|
-
span.attributes["eval.
|
|
210
|
+
span.attributes["eval.module_class"] = eval_run.module_class or ""
|
|
205
211
|
span.attributes["eval.metric_name"] = eval_run.metric_name or ""
|
|
206
212
|
span.attributes["eval.dataset_size"] = str(eval_run.dataset_size)
|
|
207
213
|
|
|
208
214
|
self._callback._call_id_to_span[call_id] = span
|
|
209
215
|
context.push_span(span)
|
|
210
216
|
|
|
217
|
+
def _program_id(self, exp: Any) -> str | None:
|
|
218
|
+
"""The program id the eval run carries, resolved the way a trace's is.
|
|
219
|
+
|
|
220
|
+
A program name the call declares wins over the callback's program id. The
|
|
221
|
+
exporter resolves the name now, on the caller's thread, because the run's
|
|
222
|
+
start is sent synchronously and must carry the id. The exporter keeps the
|
|
223
|
+
answer for the process, so a name its traces already resolved costs no
|
|
224
|
+
request. A name the exporter cannot resolve leaves the run without an id.
|
|
225
|
+
"""
|
|
226
|
+
from . import callback
|
|
227
|
+
|
|
228
|
+
name = callback._declared_program_name()
|
|
229
|
+
if name is None:
|
|
230
|
+
return self._callback._resolve_program_id()
|
|
231
|
+
# Read with getattr because the member is optional: an in-memory collector
|
|
232
|
+
# that resolves no names has none.
|
|
233
|
+
resolve = getattr(exp, "resolve_program_name", None)
|
|
234
|
+
program_id = resolve(name) if callable(resolve) else None
|
|
235
|
+
return program_id if isinstance(program_id, str) else None
|
|
236
|
+
|
|
211
237
|
def on_evaluate_end(
|
|
212
238
|
self,
|
|
213
239
|
call_id: str,
|
|
@@ -228,7 +254,7 @@ class EvalHandler:
|
|
|
228
254
|
span.status = models.TraceStatus.OK
|
|
229
255
|
context.pop_span()
|
|
230
256
|
if self._callback._should_stream_span(span):
|
|
231
|
-
exp =
|
|
257
|
+
exp = self._callback._current_exporter()
|
|
232
258
|
if exp:
|
|
233
259
|
exp.export_span(span)
|
|
234
260
|
|
|
@@ -373,7 +399,7 @@ class EvalHandler:
|
|
|
373
399
|
span.attributes["eval.score"] = str(overall_score)
|
|
374
400
|
|
|
375
401
|
# Export the eval run
|
|
376
|
-
exp =
|
|
402
|
+
exp = self._callback._current_exporter()
|
|
377
403
|
if exp:
|
|
378
404
|
exp.export_eval_run(eval_run)
|
|
379
405
|
|
|
@@ -1274,7 +1274,11 @@ class EvalRunBuilder:
|
|
|
1274
1274
|
start_time: datetime | None = None
|
|
1275
1275
|
|
|
1276
1276
|
# Eval Identity (defines comparability)
|
|
1277
|
-
|
|
1277
|
+
# The program the run evaluates: the id serve gave the program name the call
|
|
1278
|
+
# declared, or the client's program id. None when the run names no program.
|
|
1279
|
+
program_id: str | None = None
|
|
1280
|
+
# The evaluated module's class, such as "ReAct".
|
|
1281
|
+
module_class: str | None = None
|
|
1278
1282
|
metric_name: str | None = None
|
|
1279
1283
|
dataset_hash: str | None = None
|
|
1280
1284
|
dataset_size: int = 0
|
|
@@ -1393,7 +1397,10 @@ class EvalRunBuilder:
|
|
|
1393
1397
|
return {
|
|
1394
1398
|
"eval_run_id": "new",
|
|
1395
1399
|
"status": EvalRunStatus.RUNNING.value,
|
|
1396
|
-
"
|
|
1400
|
+
"program_id": self.program_id,
|
|
1401
|
+
"module_class": self.module_class or "",
|
|
1402
|
+
# Also under the key a serve from before module_class reads.
|
|
1403
|
+
"program_name": self.module_class or "",
|
|
1397
1404
|
"metric_name": self.metric_name or "",
|
|
1398
1405
|
"dataset_hash": self.dataset_hash or "",
|
|
1399
1406
|
"dataset_size": self.dataset_size,
|
|
@@ -1411,7 +1418,10 @@ class EvalRunBuilder:
|
|
|
1411
1418
|
"""Convert to API-compatible dictionary."""
|
|
1412
1419
|
d = {
|
|
1413
1420
|
"eval_run_id": str(self.eval_run_id) if self.eval_run_id else None,
|
|
1414
|
-
"
|
|
1421
|
+
"program_id": self.program_id,
|
|
1422
|
+
"module_class": self.module_class or "",
|
|
1423
|
+
# Also under the key a serve from before module_class reads.
|
|
1424
|
+
"program_name": self.module_class or "",
|
|
1415
1425
|
"metric_name": self.metric_name or "",
|
|
1416
1426
|
"dataset_hash": self.dataset_hash or "",
|
|
1417
1427
|
"dataset_size": self.dataset_size,
|
|
@@ -458,6 +458,18 @@ program signature hash. `cmpnd programs optimized` commands and
|
|
|
458
458
|
optimization result, not a program. Each group's `--help` names the column its
|
|
459
459
|
IDs come from.
|
|
460
460
|
|
|
461
|
+
`cmpnd evals list [--program NAME] [--module CLASS] [--metric] [--status]`
|
|
462
|
+
lists eval runs, newest first. `--program` takes the program's name, current
|
|
463
|
+
or retired, and a name no program answers to is an error that names it.
|
|
464
|
+
`--module` takes the evaluated module's class, such as `ReAct`, and matches it
|
|
465
|
+
exactly. The CLI sends them as `program_name` and `module_class`. Each eval
|
|
466
|
+
run in `evals list`, `evals show` and `programs evals` names what it evaluated
|
|
467
|
+
in three fields, as a trace does. `program_name` is the program's name, empty
|
|
468
|
+
when the program has none or the run names no program. `program_id` is the
|
|
469
|
+
program's `p_` id, and `module_class` is the evaluated module's class. A server
|
|
470
|
+
that predates `module_class` sends the class in `program_name` and filters
|
|
471
|
+
`--program` by class.
|
|
472
|
+
|
|
461
473
|
`cmpnd deployments openapi <id>` prints the OpenAPI document a deployment
|
|
462
474
|
serves, which an agent reads before it calls the deployment.
|
|
463
475
|
|
|
@@ -727,6 +727,8 @@ What it captures beyond the normal span flow:
|
|
|
727
727
|
- An `EvalRunBuilder` (constructed at `eval_handler.py:79`) that groups all per-example traces under one eval ID.
|
|
728
728
|
- The metric name (via `get_metric_name` from `python-sdk/cmpnd/helpers.py`) and inferred provider.
|
|
729
729
|
- Links to the enclosing optimization run when one exists (`eval_handler.py:85`), so eval runs triggered inside `GEPA.compile` roll up under the optimization in the UI.
|
|
730
|
+
- The program the run evaluates, as `program_id`. A program name the call declares wins: the exporter resolves it with `resolve_program_name`, the same once-per-process answer its traces use, on the caller's thread because the eval start is sent synchronously. Without a declared name, the run takes the callback's program id. A name serve refuses leaves the run without an id. The evaluated module's class goes as `module_class`, and again under `program_name`, the key a serve from before `module_class` reads.
|
|
731
|
+
- The exporter it publishes through: the callback's own (`_current_exporter`), so a client's eval runs go to the client's account.
|
|
730
732
|
- The dataset — on `on_evaluate_start` it triggers the `dataset_sync` pre-flight described above.
|
|
731
733
|
|
|
732
734
|
Per-example results (scores, statuses, example hashes) are collected in `on_evaluate_end` and shipped as part of the `EvalRunBuilder`'s `to_api_dict()`, which the exporter routes to `/api/v1/eval_runs`.
|
|
@@ -803,7 +805,9 @@ name form. A program name wins over the config's id. `configure()`
|
|
|
803
805
|
checks the id's shape and raises `ValueError` on a bad one, and a `Config` built directly
|
|
804
806
|
is checked the same way.
|
|
805
807
|
|
|
806
|
-
The id rides every body that can declare a program
|
|
808
|
+
The id rides every body that can declare a program. A deployment create names its program
|
|
809
|
+
by the id alone and sends no `program_signature_hash`. The other bodies still carry the
|
|
810
|
+
hash beside the id:
|
|
807
811
|
|
|
808
812
|
| Body | Where | Built by |
|
|
809
813
|
|---|---|---|
|
|
@@ -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.70.0"
|
|
9
9
|
description = "DSPy observability and deployment SDK for cmpnd"
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
requires-python = ">=3.11"
|
|
@@ -219,7 +219,6 @@ class TestDeployBadImportRejected:
|
|
|
219
219
|
create_resp = client.post(
|
|
220
220
|
f"{config.endpoint}/api/v1/deployments",
|
|
221
221
|
json={
|
|
222
|
-
"program_signature_hash": 0,
|
|
223
222
|
"declared_content_length": len(zip_bytes),
|
|
224
223
|
"program_id": program_id_for(f"test_deploy_programs-{uuid.uuid4().hex[:8]}"),
|
|
225
224
|
# A worker that spends egress tokens needs the model a token names, so
|
|
@@ -32,7 +32,6 @@ import dspy
|
|
|
32
32
|
import pytest
|
|
33
33
|
|
|
34
34
|
import cmpnd
|
|
35
|
-
from tests import _identity_helpers
|
|
36
35
|
from tests.e2e import committee_task, fake_lm
|
|
37
36
|
from tests.e2e.helpers import named_program, platform_client, poll_until, program_id_for
|
|
38
37
|
from tests.e2e.target_capabilities import needs_an_optimizer
|
|
@@ -190,7 +189,6 @@ class TestOptimizeGepaDeployDetail:
|
|
|
190
189
|
|
|
191
190
|
def test_gepa_deploy_run_stamps_traces_and_lands_detail(self, deployed_source, program_id, server_client):
|
|
192
191
|
program, trainset, valset, deployed = deployed_source
|
|
193
|
-
sig_hash = _identity_helpers.program_hash_for_sig(program.signature)
|
|
194
192
|
before = time.time()
|
|
195
193
|
|
|
196
194
|
platform_client().optimize_deployment(
|
|
@@ -210,10 +208,10 @@ class TestOptimizeGepaDeployDetail:
|
|
|
210
208
|
|
|
211
209
|
# Correlate to THIS run through the optimization index, not by scanning
|
|
212
210
|
# the trace stream: `deployed_source` is module-scoped, so every other test
|
|
213
|
-
# in this file emits traces under the SAME
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
# match it on the returned row, which
|
|
211
|
+
# in this file emits traces under the SAME program. This run is the only
|
|
212
|
+
# one of this optimizer + program started after `before`. A run serve
|
|
213
|
+
# starts names its deployment's program_id. The optimization search does
|
|
214
|
+
# not filter by program, so match it on the returned row, which carries it.
|
|
217
215
|
#
|
|
218
216
|
# Poll, don't sleep-once: on serve the deploy run's detail + traces land
|
|
219
217
|
# via a background completion watcher (5s poll cadence) AFTER optimize_deployment()
|
|
@@ -228,11 +226,11 @@ class TestOptimizeGepaDeployDetail:
|
|
|
228
226
|
order_direction="desc",
|
|
229
227
|
per_page=50,
|
|
230
228
|
).get("optimization_runs", [])
|
|
231
|
-
return [r for r in runs if
|
|
229
|
+
return [r for r in runs if r.get("program_id") == program_id]
|
|
232
230
|
|
|
233
231
|
mine = poll_until(_find_run, timeout=60.0, interval=3.0)
|
|
234
232
|
assert mine, (
|
|
235
|
-
f"no GEPA optimization run for
|
|
233
|
+
f"no GEPA optimization run for program_id={program_id} after {start_from} "
|
|
236
234
|
"(serve completion watcher didn't land it within 60s)"
|
|
237
235
|
)
|
|
238
236
|
run_id = mine[0]["run_id"]
|
|
@@ -254,9 +252,7 @@ class TestOptimizeGepaDeployDetail:
|
|
|
254
252
|
assert candidates, f"GEPA deploy run {run_id} landed a header but no candidate detail (CMP-323)"
|
|
255
253
|
|
|
256
254
|
# The worker's tracker stamps the run id onto the run's traces (the collector
|
|
257
|
-
# stamps only deployment_id), and
|
|
258
|
-
# program_signature_hash through the poll without float-rounding it, so the
|
|
259
|
-
# run row matches this signature. Its traces land under the deployment's program.
|
|
255
|
+
# stamps only deployment_id), and the traces land under the deployment's program.
|
|
260
256
|
# Page wide (page_size=500, the API max) so this run's few traces aren't crowded
|
|
261
257
|
# out of the default window by the other tests' runs — module-scoped
|
|
262
258
|
# `deployed_source` means they all share this program —
|
|
@@ -142,8 +142,9 @@ def test_bundle_pins_tools_without_importing_the_program_twice(monkeypatch):
|
|
|
142
142
|
check.assert_called_once()
|
|
143
143
|
|
|
144
144
|
|
|
145
|
-
def
|
|
145
|
+
def test_deploy_body_omits_trace_limits_and_sends_no_hash():
|
|
146
146
|
assert authored.ProgramFacts.minimal().deploy_body() == {}
|
|
147
|
+
assert "program_signature_hash" not in authored.ProgramFacts(module_class="Predict").deploy_body()
|
|
147
148
|
|
|
148
149
|
|
|
149
150
|
def test_deploy_body_preserves_empty_signature_field_lists():
|
|
@@ -86,20 +86,34 @@ class TestEvalsList:
|
|
|
86
86
|
# own spelling passes while the filter does nothing.
|
|
87
87
|
def test_minimal_list(self, mock_client):
|
|
88
88
|
mock_client.post.return_value = {"eval_runs": []}
|
|
89
|
-
args = argparse.Namespace(
|
|
89
|
+
args = argparse.Namespace(
|
|
90
|
+
program_name=None, module_class=None, metric_name=None, status=None, limit=50, offset=0
|
|
91
|
+
)
|
|
90
92
|
handle_list(mock_client, args)
|
|
91
93
|
body = mock_client.post.call_args[1]["json"]
|
|
92
94
|
assert body == {"page": 1, "page_size": 50}
|
|
93
95
|
|
|
94
96
|
def test_with_filters(self, mock_client):
|
|
95
97
|
mock_client.post.return_value = {"eval_runs": []}
|
|
96
|
-
args = argparse.Namespace(
|
|
98
|
+
args = argparse.Namespace(
|
|
99
|
+
program_name="RAG", module_class=None, metric_name="accuracy", status="completed", limit=50, offset=0
|
|
100
|
+
)
|
|
97
101
|
handle_list(mock_client, args)
|
|
98
102
|
body = mock_client.post.call_args[1]["json"]
|
|
99
103
|
assert body["program_name"] == "RAG"
|
|
100
104
|
assert body["metric"] == "accuracy"
|
|
101
105
|
assert body["status"] == "completed"
|
|
102
106
|
|
|
107
|
+
def test_program_names_the_program_and_module_names_the_class(self, mock_client):
|
|
108
|
+
# --program is the program's name; --module is the evaluated module's
|
|
109
|
+
# class, which the server matches exactly under module_class.
|
|
110
|
+
mock_client.post.return_value = {"eval_runs": []}
|
|
111
|
+
args = _build_parser().parse_args(["evals", "list", "--program", "capital-qa", "--module", "ReAct"])
|
|
112
|
+
handle_list(mock_client, args)
|
|
113
|
+
body = mock_client.post.call_args[1]["json"]
|
|
114
|
+
assert body["program_name"] == "capital-qa"
|
|
115
|
+
assert body["module_class"] == "ReAct"
|
|
116
|
+
|
|
103
117
|
def test_deprecated_search_verb_dispatches_and_is_marked(self, mock_client):
|
|
104
118
|
# The warning is the dispatcher's job (see test_main.py); the wiring is this one's.
|
|
105
119
|
parser = _build_parser()
|
|
@@ -414,7 +414,8 @@ class TestDeploy:
|
|
|
414
414
|
create_call = client.post.call_args_list[0]
|
|
415
415
|
assert "ct_test_key" in str(create_call)
|
|
416
416
|
|
|
417
|
-
def
|
|
417
|
+
def test_sends_no_program_signature_hash(self, mock_httpx):
|
|
418
|
+
# A deployment names its program by id alone.
|
|
418
419
|
client = self._setup_mocks(mock_httpx)
|
|
419
420
|
|
|
420
421
|
with mock.patch.object(deployment, "time") as mock_time:
|
|
@@ -425,9 +426,7 @@ class TestDeploy:
|
|
|
425
426
|
|
|
426
427
|
create_call = client.post.call_args_list[0]
|
|
427
428
|
body = create_call.kwargs.get("json", {})
|
|
428
|
-
assert "program_signature_hash" in body
|
|
429
|
-
# CMP-331: carried as a quoted decimal string on the wire, not a number.
|
|
430
|
-
assert isinstance(body["program_signature_hash"], str)
|
|
429
|
+
assert "program_signature_hash" not in body
|
|
431
430
|
|
|
432
431
|
def test_sends_the_programs_signature(self, mock_httpx):
|
|
433
432
|
# A program's signature is known the moment the module is packaged, and the
|
|
@@ -108,7 +108,7 @@ class TestDeployBody:
|
|
|
108
108
|
lambda: deployment.deploy_module_under(dspy.Predict("question -> answer"), None, 300, None, None, config)
|
|
109
109
|
)
|
|
110
110
|
assert "program_id" not in body
|
|
111
|
-
assert "program_signature_hash" in body
|
|
111
|
+
assert "program_signature_hash" not in body
|
|
112
112
|
|
|
113
113
|
def test_an_undeclared_bundle_deploy_omits_the_key(self):
|
|
114
114
|
_configure()
|
|
@@ -199,7 +199,7 @@ class TestEvalLifecycle:
|
|
|
199
199
|
eval_run = exporter.eval_runs[0]
|
|
200
200
|
|
|
201
201
|
# Program metadata
|
|
202
|
-
assert eval_run.
|
|
202
|
+
assert eval_run.module_class == "TestProgram"
|
|
203
203
|
assert eval_run.metric_name == "exact_match"
|
|
204
204
|
assert eval_run.dataset_size == 3
|
|
205
205
|
|