cmpnd 0.69.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.
Files changed (400) hide show
  1. {cmpnd-0.69.0 → cmpnd-0.70.0}/PKG-INFO +1 -1
  2. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/evals.py +13 -1
  3. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/dataset_sync.py +8 -5
  4. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/eval_handler.py +35 -9
  5. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/models.py +13 -3
  6. {cmpnd-0.69.0 → cmpnd-0.70.0}/docs/cli.md +12 -0
  7. {cmpnd-0.69.0 → cmpnd-0.70.0}/docs/sdk-instrumentation.md +2 -0
  8. {cmpnd-0.69.0 → cmpnd-0.70.0}/pyproject.toml +1 -1
  9. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_evals.py +16 -2
  10. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_eval.py +1 -1
  11. cmpnd-0.70.0/tests/test_eval_program_id.py +192 -0
  12. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_eval_start.py +2 -2
  13. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_ingest_conformance.py +2 -1
  14. {cmpnd-0.69.0 → cmpnd-0.70.0}/uv.lock +1 -1
  15. {cmpnd-0.69.0 → cmpnd-0.70.0}/.gitignore +0 -0
  16. {cmpnd-0.69.0 → cmpnd-0.70.0}/AGENTS.md +0 -0
  17. {cmpnd-0.69.0 → cmpnd-0.70.0}/CLAUDE.md +0 -0
  18. {cmpnd-0.69.0 → cmpnd-0.70.0}/README.md +0 -0
  19. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/__init__.py +0 -0
  20. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_assessments.py +0 -0
  21. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_authored_import.py +0 -0
  22. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_deployments.py +0 -0
  23. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_exporter_pool.py +0 -0
  24. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_gepa_patch.py +0 -0
  25. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_http.py +0 -0
  26. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_program_patch.py +0 -0
  27. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_rlm_patch.py +0 -0
  28. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_runtime_tools.py +0 -0
  29. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_timespec.py +0 -0
  30. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_traces.py +0 -0
  31. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/_valsets.py +0 -0
  32. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/authored.py +0 -0
  33. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/callback.py +0 -0
  34. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/__init__.py +0 -0
  35. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/api_client.py +0 -0
  36. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/__init__.py +0 -0
  37. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/admin.py +0 -0
  38. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/assessments.py +0 -0
  39. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/auth.py +0 -0
  40. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/datasets.py +0 -0
  41. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/deployments.py +0 -0
  42. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/login.py +0 -0
  43. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/optimizations.py +0 -0
  44. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/org.py +0 -0
  45. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/programs.py +0 -0
  46. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/provider_credentials.py +0 -0
  47. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/tool_servers.py +0 -0
  48. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/top.py +0 -0
  49. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/traces.py +0 -0
  50. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/commands/valsets.py +0 -0
  51. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/credentials.py +0 -0
  52. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/deprecation.py +0 -0
  53. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/pagination.py +0 -0
  54. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/shell.py +0 -0
  55. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/trace_render.py +0 -0
  56. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/tree_help.py +0 -0
  57. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/verbs.py +0 -0
  58. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/cli/views.py +0 -0
  59. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/client.py +0 -0
  60. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/configuration.py +0 -0
  61. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/context.py +0 -0
  62. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/credentials.py +0 -0
  63. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/datasets.py +0 -0
  64. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/decorators.py +0 -0
  65. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/deployment.py +0 -0
  66. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/deployment_metadata.py +0 -0
  67. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/deployment_runs.py +0 -0
  68. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/execution.py +0 -0
  69. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/exporter.py +0 -0
  70. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/exporter_http.py +0 -0
  71. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/helpers.py +0 -0
  72. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/identity.py +0 -0
  73. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/imaging.py +0 -0
  74. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/ir/__init__.py +0 -0
  75. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/ir/decode.py +0 -0
  76. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/ir/encode.py +0 -0
  77. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/ir/hash.py +0 -0
  78. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/ir/program.py +0 -0
  79. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/ir/reflection.py +0 -0
  80. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/ir/types.py +0 -0
  81. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/ir/xxh64.py +0 -0
  82. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/lm_configuration.py +0 -0
  83. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/mcp_servers.py +0 -0
  84. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/named_programs.py +0 -0
  85. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/optimization.py +0 -0
  86. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/optimizers/__init__.py +0 -0
  87. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/optimizers/gepa.py +0 -0
  88. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/optimizers/gepa_callback.py +0 -0
  89. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/optimizers/resume.py +0 -0
  90. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/optimizers/tracker.py +0 -0
  91. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/packaging.py +0 -0
  92. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/programs.py +0 -0
  93. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/references.py +0 -0
  94. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/retry.py +0 -0
  95. {cmpnd-0.69.0 → cmpnd-0.70.0}/cmpnd/traces.py +0 -0
  96. {cmpnd-0.69.0 → cmpnd-0.70.0}/docs/2026-04-02-code-review.md +0 -0
  97. {cmpnd-0.69.0 → cmpnd-0.70.0}/docs/client.md +0 -0
  98. {cmpnd-0.69.0 → cmpnd-0.70.0}/docs/custom-proposer.md +0 -0
  99. {cmpnd-0.69.0 → cmpnd-0.70.0}/docs/plans/2026-04-05-train-val-dataset-capture-design.md +0 -0
  100. {cmpnd-0.69.0 → cmpnd-0.70.0}/docs/plans/2026-04-05-train-val-dataset-capture.md +0 -0
  101. {cmpnd-0.69.0 → cmpnd-0.70.0}/docs/reading-traces.md +0 -0
  102. {cmpnd-0.69.0 → cmpnd-0.70.0}/examples/generalizing_proposer.py +0 -0
  103. {cmpnd-0.69.0 → cmpnd-0.70.0}/examples/local_ollama.py +0 -0
  104. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/LINEAGE.md +0 -0
  105. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/README.md +0 -0
  106. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/__init__.py +0 -0
  107. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/bodies.py +0 -0
  108. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/client_floor.py +0 -0
  109. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/exporter_http.py +0 -0
  110. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/program_names.py +0 -0
  111. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/protocols.py +0 -0
  112. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/py.typed +0 -0
  113. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/request_log.py +0 -0
  114. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/retry.py +0 -0
  115. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/cmpnd_ingest/trace_facts.py +0 -0
  116. {cmpnd-0.69.0 → cmpnd-0.70.0}/ingest/pyproject.toml +0 -0
  117. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/audit-sdist.sh +0 -0
  118. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/capture_review_run.py +0 -0
  119. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/check-pip-install.sh +0 -0
  120. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/check_release_artifacts.py +0 -0
  121. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/fixtures/review_run.json.gz +0 -0
  122. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/gepa_resume_bug.py +0 -0
  123. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/install-test-env.sh +0 -0
  124. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/release-gate.sh +0 -0
  125. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/release-real-models.sh +0 -0
  126. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/require_version_bump.py +0 -0
  127. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/seed_review_run.py +0 -0
  128. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/selfhost_compat.py +0 -0
  129. {cmpnd-0.69.0 → cmpnd-0.70.0}/scripts/test-in-linux.sh +0 -0
  130. {cmpnd-0.69.0 → cmpnd-0.70.0}/stubs/dspy/__init__.pyi +0 -0
  131. {cmpnd-0.69.0 → cmpnd-0.70.0}/stubs/dspy/primitives/__init__.pyi +0 -0
  132. {cmpnd-0.69.0 → cmpnd-0.70.0}/stubs/dspy/primitives/prediction.pyi +0 -0
  133. {cmpnd-0.69.0 → cmpnd-0.70.0}/stubs/dspy/utils/__init__.pyi +0 -0
  134. {cmpnd-0.69.0 → cmpnd-0.70.0}/stubs/dspy/utils/callback.pyi +0 -0
  135. {cmpnd-0.69.0 → cmpnd-0.70.0}/stubs/dspy/utils/dummies.pyi +0 -0
  136. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/__init__.py +0 -0
  137. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/_credential_route.py +0 -0
  138. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/_deployment_signature_helpers.py +0 -0
  139. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/_exporter_helpers.py +0 -0
  140. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/_fake_clock.py +0 -0
  141. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/_identity_helpers.py +0 -0
  142. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/_resolve_refs.py +0 -0
  143. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/_traced_run.py +0 -0
  144. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/conftest.py +0 -0
  145. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/__init__.py +0 -0
  146. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/committee_task.py +0 -0
  147. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/conftest.py +0 -0
  148. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/continuation_task.py +0 -0
  149. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/data/committee_train.ndjson.gz +0 -0
  150. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/data/committee_val.ndjson.gz +0 -0
  151. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/fake_lm.py +0 -0
  152. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/helpers.py +0 -0
  153. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/target_capabilities.py +0 -0
  154. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_assessments_cli.py +0 -0
  155. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_capture_prompts.py +0 -0
  156. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_composite_module.py +0 -0
  157. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_dataset_auto_creation.py +0 -0
  158. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_deploy_execute.py +0 -0
  159. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_deploy_pandas.py +0 -0
  160. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_deploy_programs.py +0 -0
  161. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_edge_cases.py +0 -0
  162. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_example_hash.py +0 -0
  163. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_gepa_optimization.py +0 -0
  164. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_interpreter_spans.py +0 -0
  165. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_lm_accuracy.py +0 -0
  166. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_module_tracing.py +0 -0
  167. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_optimization_lineage.py +0 -0
  168. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_optimization_metric_identity.py +0 -0
  169. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_authored_metric.py +0 -0
  170. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_continuation.py +0 -0
  171. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_custom_proposer.py +0 -0
  172. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_failures.py +0 -0
  173. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_loop.py +0 -0
  174. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_review_committee.py +0 -0
  175. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_optimize_server_owned_completion.py +0 -0
  176. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_parallel_export.py +0 -0
  177. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_project_attribution.py +0 -0
  178. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_react_tool_spans.py +0 -0
  179. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_save_load.py +0 -0
  180. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_trace_structure.py +0 -0
  181. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_traces_read.py +0 -0
  182. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_user_attribution.py +0 -0
  183. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/e2e/test_valsets_cli.py +0 -0
  184. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/01_predict_qa.json +0 -0
  185. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/02_predict_renamed_field.json +0 -0
  186. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/03_chain_of_thought_qa.json +0 -0
  187. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/04_predict_richer_types.json +0 -0
  188. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/05_composite_two_predicts.json +0 -0
  189. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/06_multichaincomparison.json +0 -0
  190. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/07_program_of_thought.json +0 -0
  191. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/08_opaque_module.json +0 -0
  192. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/09_predict_pydantic_field.json +0 -0
  193. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/10_react.json +0 -0
  194. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/11_refine.json +0 -0
  195. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/12_retrieve.json +0 -0
  196. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/13_knn.json +0 -0
  197. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/14_parallel.json +0 -0
  198. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/identity_vectors/README.md +0 -0
  199. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/ingest_conformance.py +0 -0
  200. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/__init__.py +0 -0
  201. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/authored_optimize/judge.py +0 -0
  202. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/authored_optimize/optimize_hosted.py +0 -0
  203. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/conftest.py +0 -0
  204. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/hosted_mcp_tool_optimize_probe.py +0 -0
  205. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/hosted_optimize_probe.py +0 -0
  206. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/optimization_run_probe.py +0 -0
  207. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/test_cli_deploy_smoketest.py +0 -0
  208. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/test_logs_renders_traces.py +0 -0
  209. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/test_optimization_run.py +0 -0
  210. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/test_optimizing_progress.py +0 -0
  211. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/integration/test_unhappy_path.py +0 -0
  212. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/load/__init__.py +0 -0
  213. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/load/__main__.py +0 -0
  214. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/load/drain.py +0 -0
  215. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/load/ingest.py +0 -0
  216. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/load/latency_transport.py +0 -0
  217. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/load/rlm_shape.py +0 -0
  218. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/load/rlm_size_report.py +0 -0
  219. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/load/sweep.py +0 -0
  220. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/load/test_rlm_shape.py +0 -0
  221. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/load/test_rlm_size_report.py +0 -0
  222. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/__init__.py +0 -0
  223. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/conftest.py +0 -0
  224. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/seed_parity.py +0 -0
  225. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/test_auth.py +0 -0
  226. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/test_datasets.py +0 -0
  227. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/test_deployments.py +0 -0
  228. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/test_evals.py +0 -0
  229. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/test_health.py +0 -0
  230. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/test_modules.py +0 -0
  231. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/test_optimizations.py +0 -0
  232. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/test_programs.py +0 -0
  233. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/test_signatures.py +0 -0
  234. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/test_trace_streaming.py +0 -0
  235. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/parity/test_traces.py +0 -0
  236. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/__init__.py +0 -0
  237. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/_provider.py +0 -0
  238. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/_readiness.py +0 -0
  239. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/_reliability.py +0 -0
  240. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/_result.py +0 -0
  241. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/mint_bedrock_token.py +0 -0
  242. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_bedrock_converse.py +0 -0
  243. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_deploy_programs.py +0 -0
  244. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_multi_client_stress.py +0 -0
  245. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_optimize_client_committee.py +0 -0
  246. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_optimize_continuation.py +0 -0
  247. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_optimize_loop.py +0 -0
  248. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_optimize_loop_wasm.py +0 -0
  249. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_optimize_stress.py +0 -0
  250. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_provider_roles.py +0 -0
  251. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_readiness.py +0 -0
  252. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_real_provider_twins.py +0 -0
  253. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_reliability.py +0 -0
  254. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_reliability_classify.py +0 -0
  255. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_rlm_wasm.py +0 -0
  256. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/real_models/test_trace_search.py +0 -0
  257. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/span_reference_fixture.py +0 -0
  258. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_adapter_reentrancy.py +0 -0
  259. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_assessments_api.py +0 -0
  260. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_authored.py +0 -0
  261. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_authored_binding_credentials.py +0 -0
  262. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_authored_bundle_collisions.py +0 -0
  263. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_authored_metric_contract.py +0 -0
  264. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_authored_named_models.py +0 -0
  265. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_authored_optimize.py +0 -0
  266. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_callback.py +0 -0
  267. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_candidate_lineage.py +0 -0
  268. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/__init__.py +0 -0
  269. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/conftest.py +0 -0
  270. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_admin.py +0 -0
  271. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_api_client.py +0 -0
  272. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_assessments.py +0 -0
  273. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_auth.py +0 -0
  274. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_credentials.py +0 -0
  275. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_datasets.py +0 -0
  276. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_deployment_runs.py +0 -0
  277. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_deployments.py +0 -0
  278. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_login.py +0 -0
  279. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_main.py +0 -0
  280. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_optimizations.py +0 -0
  281. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_org.py +0 -0
  282. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_pagination.py +0 -0
  283. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_parity.py +0 -0
  284. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_programs.py +0 -0
  285. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_provider_credentials.py +0 -0
  286. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_schema_sample.py +0 -0
  287. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_shell.py +0 -0
  288. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_tool_servers.py +0 -0
  289. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_top.py +0 -0
  290. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_traces.py +0 -0
  291. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_traces_program_and_module.py +0 -0
  292. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_traces_search_wire.py +0 -0
  293. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_tree_help.py +0 -0
  294. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cli/test_valsets.py +0 -0
  295. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_client.py +0 -0
  296. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_client_floor.py +0 -0
  297. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_client_program_names.py +0 -0
  298. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_clustering/__init__.py +0 -0
  299. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_clustering/conftest.py +0 -0
  300. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_clustering/test_edge_cases.py +0 -0
  301. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_clustering/test_hash_consistency.py +0 -0
  302. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_clustering/test_type_conversion.py +0 -0
  303. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_cmp551_grouping_identity.py +0 -0
  304. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_configuration.py +0 -0
  305. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_context.py +0 -0
  306. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_context_propagation.py +0 -0
  307. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_credential_kwargs.py +0 -0
  308. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_credential_selection.py +0 -0
  309. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_credential_values.py +0 -0
  310. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_dataset_polling.py +0 -0
  311. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_dataset_sync.py +0 -0
  312. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_datasets.py +0 -0
  313. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_decision_client_spans.py +0 -0
  314. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_decorators.py +0 -0
  315. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_deploy.py +0 -0
  316. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_deploy_mcp_tool_references.py +0 -0
  317. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_deploy_program_id.py +0 -0
  318. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_deployment_metadata.py +0 -0
  319. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_deployment_runs.py +0 -0
  320. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_deployments_read.py +0 -0
  321. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_eval_example_attribution.py +0 -0
  322. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_eval_trace_grouping.py +0 -0
  323. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_exception_paths.py +0 -0
  324. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_execute.py +0 -0
  325. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_execute_run_identity.py +0 -0
  326. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_exporter.py +0 -0
  327. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_exporter_program_names.py +0 -0
  328. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_exporter_queue.py +0 -0
  329. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_exporter_real.py +0 -0
  330. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_fake_lm.py +0 -0
  331. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_gepa_callback.py +0 -0
  332. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_gepa_integration.py +0 -0
  333. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_gepa_output_normalization.py +0 -0
  334. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_gepa_resume.py +0 -0
  335. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_identity.py +0 -0
  336. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_imaging.py +0 -0
  337. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_import_weight.py +0 -0
  338. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_ingest_second_producer.py +0 -0
  339. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_integration.py +0 -0
  340. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_interpreter_callback.py +0 -0
  341. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_ir_encoder_properties.py +0 -0
  342. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_ir_golden_vectors.py +0 -0
  343. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_ir_roundtrip.py +0 -0
  344. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_lm15_native_calls.py +0 -0
  345. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_lm_configuration.py +0 -0
  346. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_lm_usage_shapes.py +0 -0
  347. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_mcp_tools.py +0 -0
  348. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_models.py +0 -0
  349. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_multi_client_stress_readiness.py +0 -0
  350. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_optimization_progress.py +0 -0
  351. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_optimization_start.py +0 -0
  352. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_optimize.py +0 -0
  353. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_optimize_budget.py +0 -0
  354. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_optimize_lift.py +0 -0
  355. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_optimize_lms.py +0 -0
  356. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_optimize_proposer.py +0 -0
  357. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_optimize_reflection_lm.py +0 -0
  358. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_optimize_terminal_failure.py +0 -0
  359. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_packaging.py +0 -0
  360. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_packaging_callable_source.py +0 -0
  361. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_packaging_mcp_tools.py +0 -0
  362. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_packaging_program_source.py +0 -0
  363. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_poll_until.py +0 -0
  364. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_program_id_deprecation.py +0 -0
  365. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_program_identity.py +0 -0
  366. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_program_lineage_persist.py +0 -0
  367. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_program_names_in_deploy.py +0 -0
  368. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_programs_create.py +0 -0
  369. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_project_payload.py +0 -0
  370. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_real_provider_twins_readiness.py +0 -0
  371. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_reflector_properties.py +0 -0
  372. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_reflector_smoke.py +0 -0
  373. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_release_gate_script.py +0 -0
  374. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_release_real_models_script.py +0 -0
  375. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_replaced_names.py +0 -0
  376. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_repro_reactv2_bugs.py +0 -0
  377. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_require_version_bump.py +0 -0
  378. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_retry.py +0 -0
  379. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_reversible_failures.py +0 -0
  380. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_rlm_patch.py +0 -0
  381. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_run_attribution_paths.py +0 -0
  382. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_runtime_tools.py +0 -0
  383. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_schemas.py +0 -0
  384. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_seal_lm_credential.py +0 -0
  385. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_seed_review_run.py +0 -0
  386. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_signature_inputs.py +0 -0
  387. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_span_references.py +0 -0
  388. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_span_sent_once.py +0 -0
  389. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_system_one.py +0 -0
  390. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_trace_context_concurrency.py +0 -0
  391. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_trace_fact_wire_contract.py +0 -0
  392. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_trace_facts.py +0 -0
  393. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_trace_render.py +0 -0
  394. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_traces_read.py +0 -0
  395. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_tracked_gepa.py +0 -0
  396. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_tracker_enrich.py +0 -0
  397. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_truncation.py +0 -0
  398. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_upload_auth_headers.py +0 -0
  399. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_valsets_api.py +0 -0
  400. {cmpnd-0.69.0 → cmpnd-0.70.0}/tests/test_xxh64.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: cmpnd
3
- Version: 0.69.0
3
+ Version: 0.70.0
4
4
  Summary: DSPy observability and deployment SDK for cmpnd
5
5
  Project-URL: Homepage, https://cmpnd.ai
6
6
  Author-email: cmpnd <hello@cmpnd.ai>
@@ -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("--program", dest="program_name", help="Filter by program name")
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
- try:
31
- config = configuration.require_config()
32
- except RuntimeError:
33
- return False
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
 
@@ -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, exporter, helpers, identity, models
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.program_name = program.__class__.__name__
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(eval_run.dataset_hash)
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: program_name={eval_run.program_name}, "
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.program_name"] = eval_run.program_name or ""
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 = exporter.get_exporter()
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 = exporter.get_exporter()
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
- program_name: str | None = None
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
- "program_name": self.program_name or "",
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
- "program_name": self.program_name or "",
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`.
@@ -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.69.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"
@@ -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(program_name=None, metric_name=None, status=None, limit=50, offset=0)
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(program_name="RAG", metric_name="accuracy", status="completed", limit=50, offset=0)
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()
@@ -199,7 +199,7 @@ class TestEvalLifecycle:
199
199
  eval_run = exporter.eval_runs[0]
200
200
 
201
201
  # Program metadata
202
- assert eval_run.program_name == "TestProgram"
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
 
@@ -0,0 +1,192 @@
1
+ """An eval run names its program by id, and its module by class.
2
+
3
+ The SDK resolves the program name a call declares to the program's id, once per
4
+ process through the exporter, and sends it as ``program_id`` on the eval run's
5
+ start and completion. The evaluated module's class goes as ``module_class``, and
6
+ again under ``program_name``, where a serve from before ``module_class`` reads it.
7
+ """
8
+
9
+ from unittest import mock
10
+
11
+ import httpx
12
+ import pytest
13
+
14
+ from tests import _traced_run
15
+ from tests._exporter_helpers import decode_body
16
+
17
+ pytest.importorskip("dspy")
18
+
19
+ import dspy # noqa: E402
20
+
21
+ from cmpnd import _http, configuration # noqa: E402
22
+ from cmpnd.callback import DECLARED_PROGRAM_SETTING # noqa: E402
23
+ from cmpnd.configuration import Config, configure # noqa: E402
24
+ from cmpnd.context import clear_context # noqa: E402
25
+ from cmpnd.exporter import BatchExporter # noqa: E402
26
+ from cmpnd.models import EvalRunBuilder # noqa: E402
27
+ from tests.test_eval import MockExporter # noqa: E402
28
+
29
+ PROGRAM_ID = "p_3pQr7t8sK2mN"
30
+
31
+
32
+ def test_the_start_and_the_completion_carry_the_program_id_and_the_class():
33
+ eval_run = EvalRunBuilder(module_class="ReAct", program_id=PROGRAM_ID, metric_name="m")
34
+ for body in (eval_run.to_start_dict(), eval_run.to_api_dict()):
35
+ assert body["program_id"] == PROGRAM_ID
36
+ assert body["module_class"] == "ReAct"
37
+ assert body["program_name"] == "ReAct"
38
+
39
+
40
+ def test_a_run_with_no_program_sends_no_id():
41
+ eval_run = EvalRunBuilder(module_class="Predict")
42
+ for body in (eval_run.to_start_dict(), eval_run.to_api_dict()):
43
+ assert body["program_id"] is None
44
+ assert body["module_class"] == "Predict"
45
+
46
+
47
+ def test_the_start_puts_the_program_id_on_the_wire():
48
+ captured = {}
49
+
50
+ def handler(request: httpx.Request) -> httpx.Response:
51
+ captured["body"] = decode_body(request)
52
+ return httpx.Response(202, json={"eval_run_id": "ev_SERVERMINTED"})
53
+
54
+ config = Config(api_key="test", endpoint="http://localhost:9999")
55
+ exporter = BatchExporter(config, transport=httpx.MockTransport(handler))
56
+ exporter.export_eval_start(EvalRunBuilder(module_class="ReAct", program_id=PROGRAM_ID))
57
+
58
+ assert captured["body"]["program_id"] == PROGRAM_ID
59
+ assert captured["body"]["module_class"] == "ReAct"
60
+ assert captured["body"]["program_name"] == "ReAct"
61
+
62
+
63
+ class QuestionAnswer(dspy.Module):
64
+ def __init__(self):
65
+ super().__init__()
66
+ self.predict = dspy.Predict("question -> answer")
67
+
68
+ def forward(self, question):
69
+ return self.predict(question=question)
70
+
71
+
72
+ def _exact(example, prediction, trace=None):
73
+ return example.answer == prediction.answer
74
+
75
+
76
+ class ResolvingExporter(MockExporter):
77
+ """A MockExporter that resolves declared program names, as BatchExporter does."""
78
+
79
+ def __init__(self, ids: dict[str, str | None]):
80
+ super().__init__()
81
+ self.ids = ids
82
+ self.resolved: list[str] = []
83
+
84
+ def resolve_program_name(self, name: str) -> str | None:
85
+ self.resolved.append(name)
86
+ return self.ids.get(name)
87
+
88
+
89
+ class TestTheEvalHandlerNamesTheProgram:
90
+ def setup_method(self):
91
+ configure(api_key="test_key", endpoint="http://localhost:8000")
92
+
93
+ def teardown_method(self):
94
+ clear_context()
95
+ import cmpnd.configuration
96
+
97
+ cmpnd.configuration._config = None
98
+
99
+ def _start(self, exporter, *, declared: str | None = None, callback=None):
100
+ callback = callback or _traced_run.make_callback()
101
+ evaluate = dspy.Evaluate(devset=[], metric=_exact)
102
+ settings = {DECLARED_PROGRAM_SETTING: declared} if declared is not None else {}
103
+ with mock.patch("cmpnd.exporter.get_exporter", autospec=True, return_value=exporter), dspy.context(**settings):
104
+ callback.on_evaluate_start(call_id="c", instance=evaluate, inputs={"program": QuestionAnswer()})
105
+ return exporter.eval_starts[0]
106
+
107
+ def test_a_declared_name_resolves_to_its_program_id(self):
108
+ exporter = ResolvingExporter({"capital-qa": PROGRAM_ID})
109
+ eval_run = self._start(exporter, declared="capital-qa")
110
+ assert exporter.resolved == ["capital-qa"]
111
+ assert eval_run.program_id == PROGRAM_ID
112
+ assert eval_run.module_class == "QuestionAnswer"
113
+
114
+ def test_a_name_serve_refuses_sends_no_id(self):
115
+ exporter = ResolvingExporter({})
116
+ eval_run = self._start(exporter, declared="capital-qa")
117
+ assert eval_run.program_id is None
118
+
119
+ def test_the_callbacks_program_id_applies_when_no_name_is_declared(self):
120
+ callback = _traced_run.make_callback()
121
+ exporter = ResolvingExporter({})
122
+ with mock.patch.object(callback, "_resolve_program_id", autospec=True, return_value=PROGRAM_ID):
123
+ eval_run = self._start(exporter, callback=callback)
124
+ assert exporter.resolved == []
125
+ assert eval_run.program_id == PROGRAM_ID
126
+
127
+ def test_a_declared_name_wins_over_the_callbacks_program_id(self):
128
+ callback = _traced_run.make_callback()
129
+ other = "p_000000000000"
130
+ exporter = ResolvingExporter({"capital-qa": PROGRAM_ID})
131
+ with mock.patch.object(callback, "_resolve_program_id", autospec=True, return_value=other):
132
+ eval_run = self._start(exporter, declared="capital-qa", callback=callback)
133
+ assert eval_run.program_id == PROGRAM_ID
134
+
135
+ def test_a_run_that_names_no_program_carries_no_id(self):
136
+ eval_run = self._start(MockExporter())
137
+ assert eval_run.program_id is None
138
+ assert eval_run.module_class == "QuestionAnswer"
139
+
140
+
141
+ GLOBAL_ENDPOINT = "http://global-account.invalid"
142
+ CLIENT_ENDPOINT = "http://client-account.invalid"
143
+
144
+
145
+ class TestTheDatasetPreflightAsksTheAccountTheRunPublishesTo:
146
+ """The eval start asks serve whether the dataset exists, so the completion can
147
+ leave its examples out. It must ask the account the run publishes to: a client
148
+ publishes to its own account, which may lack a dataset the global one holds."""
149
+
150
+ def teardown_method(self):
151
+ clear_context()
152
+ configuration._config = None
153
+
154
+ def _start(self, callback):
155
+ """Start an eval of a one-example devset, and return the eval run and the
156
+ (url, authorization) of every dataset check. Only the global account holds
157
+ the dataset."""
158
+ checks: list[tuple[str, str]] = []
159
+
160
+ def handler(request: httpx.Request) -> httpx.Response:
161
+ authorization = request.headers["Authorization"]
162
+ checks.append((str(request.url), authorization))
163
+ return httpx.Response(200, json={"exists": authorization == "Bearer ck_global"})
164
+
165
+ real_new_client = _http.new_client
166
+
167
+ def new_client(**kwargs):
168
+ return real_new_client(transport=httpx.MockTransport(handler), **kwargs)
169
+
170
+ devset = [dspy.Example(question="2+2?", answer="4").with_inputs("question")]
171
+ evaluate = dspy.Evaluate(devset=devset, metric=_exact)
172
+ exporter = MockExporter()
173
+ with (
174
+ mock.patch("cmpnd._http.new_client", autospec=True, side_effect=new_client),
175
+ mock.patch("cmpnd.exporter.get_exporter", autospec=True, return_value=exporter),
176
+ mock.patch("cmpnd._exporter_pool.ensure_exporter_started", autospec=True, return_value=exporter),
177
+ ):
178
+ callback.on_evaluate_start(call_id="c", instance=evaluate, inputs={"program": QuestionAnswer()})
179
+ return exporter.eval_starts[0], checks
180
+
181
+ def test_a_clients_eval_checks_the_clients_account(self):
182
+ configure(api_key="ck_global", endpoint=GLOBAL_ENDPOINT)
183
+ own = Config(api_key="ck_client", endpoint=CLIENT_ENDPOINT)
184
+ eval_run, checks = self._start(_traced_run.make_callback(own_config=own))
185
+ assert checks == [(f"{CLIENT_ENDPOINT}/api/v1/datasets/check/{eval_run.dataset_hash}", "Bearer ck_client")]
186
+ assert eval_run._dataset_exists is False
187
+
188
+ def test_the_global_callbacks_eval_checks_the_global_account(self):
189
+ configure(api_key="ck_global", endpoint=GLOBAL_ENDPOINT)
190
+ eval_run, checks = self._start(_traced_run.make_callback())
191
+ assert checks == [(f"{GLOBAL_ENDPOINT}/api/v1/datasets/check/{eval_run.dataset_hash}", "Bearer ck_global")]
192
+ assert eval_run._dataset_exists is True
@@ -32,7 +32,7 @@ def test_export_eval_start_is_synchronous_and_returns_server_id():
32
32
  return httpx.Response(200, json={"eval_run_id": "ev_SERVERMINTED"})
33
33
 
34
34
  exporter = BatchExporter(_config(), transport=httpx.MockTransport(handler))
35
- eval_run = EvalRunBuilder(program_name="P", metric_name="m")
35
+ eval_run = EvalRunBuilder(module_class="P", metric_name="m")
36
36
 
37
37
  assigned = exporter.export_eval_start(eval_run)
38
38
 
@@ -76,7 +76,7 @@ def test_eval_start_fails_loud_after_retries():
76
76
  return httpx.Response(500, json={"error": "boom"})
77
77
 
78
78
  exporter = BatchExporter(_config(), transport=httpx.MockTransport(handler))
79
- eval_run = EvalRunBuilder(program_name="P")
79
+ eval_run = EvalRunBuilder(module_class="P")
80
80
 
81
81
  with pytest.raises(RuntimeError):
82
82
  exporter.export_eval_start(eval_run)
@@ -249,7 +249,8 @@ def _eval_run() -> EvalRunBuilder:
249
249
  now = datetime.now(timezone.utc)
250
250
  run = EvalRunBuilder(
251
251
  start_time=now,
252
- program_name="QAProgram",
252
+ program_id="p_3pQr7t8sK2mN",
253
+ module_class="QAProgram",
253
254
  metric_name="exact_match",
254
255
  dataset_hash="0123456789abcdef",
255
256
  dataset_size=2,
@@ -505,7 +505,7 @@ wheels = [
505
505
 
506
506
  [[package]]
507
507
  name = "cmpnd"
508
- version = "0.69.0"
508
+ version = "0.70.0"
509
509
  source = { editable = "." }
510
510
  default-groups = ["dspy-3-4-1"]
511
511
  dependencies = [
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes