cmpnd 0.71.0__tar.gz → 0.72.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.71.0 → cmpnd-0.72.0}/PKG-INFO +1 -1
  2. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/deployments.py +3 -0
  3. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/client.py +13 -0
  4. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/execution.py +22 -1
  5. {cmpnd-0.71.0 → cmpnd-0.72.0}/docs/cli.md +4 -0
  6. {cmpnd-0.71.0 → cmpnd-0.72.0}/docs/client.md +3 -1
  7. {cmpnd-0.71.0 → cmpnd-0.72.0}/docs/sdk-instrumentation.md +8 -1
  8. {cmpnd-0.71.0 → cmpnd-0.72.0}/pyproject.toml +1 -1
  9. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_deployment_runs.py +34 -0
  10. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_deployment_runs.py +68 -0
  11. {cmpnd-0.71.0 → cmpnd-0.72.0}/uv.lock +1 -1
  12. {cmpnd-0.71.0 → cmpnd-0.72.0}/.gitignore +0 -0
  13. {cmpnd-0.71.0 → cmpnd-0.72.0}/AGENTS.md +0 -0
  14. {cmpnd-0.71.0 → cmpnd-0.72.0}/CLAUDE.md +0 -0
  15. {cmpnd-0.71.0 → cmpnd-0.72.0}/README.md +0 -0
  16. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/__init__.py +0 -0
  17. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_assessments.py +0 -0
  18. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_authored_import.py +0 -0
  19. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_deployments.py +0 -0
  20. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_exporter_pool.py +0 -0
  21. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_gepa_patch.py +0 -0
  22. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_http.py +0 -0
  23. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_program_patch.py +0 -0
  24. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_rlm_patch.py +0 -0
  25. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_runtime_tools.py +0 -0
  26. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_timespec.py +0 -0
  27. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_traces.py +0 -0
  28. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/_valsets.py +0 -0
  29. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/authored.py +0 -0
  30. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/callback.py +0 -0
  31. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/__init__.py +0 -0
  32. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/api_client.py +0 -0
  33. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/__init__.py +0 -0
  34. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/admin.py +0 -0
  35. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/assessments.py +0 -0
  36. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/auth.py +0 -0
  37. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/datasets.py +0 -0
  38. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/evals.py +0 -0
  39. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/login.py +0 -0
  40. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/optimizations.py +0 -0
  41. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/org.py +0 -0
  42. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/programs.py +0 -0
  43. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/provider_credentials.py +0 -0
  44. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/tool_servers.py +0 -0
  45. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/top.py +0 -0
  46. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/traces.py +0 -0
  47. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/commands/valsets.py +0 -0
  48. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/credentials.py +0 -0
  49. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/deprecation.py +0 -0
  50. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/pagination.py +0 -0
  51. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/shell.py +0 -0
  52. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/trace_render.py +0 -0
  53. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/tree_help.py +0 -0
  54. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/verbs.py +0 -0
  55. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/cli/views.py +0 -0
  56. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/configuration.py +0 -0
  57. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/context.py +0 -0
  58. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/credentials.py +0 -0
  59. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/dataset_sync.py +0 -0
  60. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/datasets.py +0 -0
  61. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/decorators.py +0 -0
  62. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/deployment.py +0 -0
  63. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/deployment_metadata.py +0 -0
  64. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/deployment_runs.py +0 -0
  65. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/eval_handler.py +0 -0
  66. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/exporter.py +0 -0
  67. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/exporter_http.py +0 -0
  68. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/helpers.py +0 -0
  69. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/identity.py +0 -0
  70. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/imaging.py +0 -0
  71. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/ir/__init__.py +0 -0
  72. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/ir/decode.py +0 -0
  73. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/ir/encode.py +0 -0
  74. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/ir/hash.py +0 -0
  75. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/ir/program.py +0 -0
  76. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/ir/reflection.py +0 -0
  77. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/ir/types.py +0 -0
  78. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/ir/xxh64.py +0 -0
  79. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/lm_configuration.py +0 -0
  80. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/mcp_servers.py +0 -0
  81. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/models.py +0 -0
  82. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/named_programs.py +0 -0
  83. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/optimization.py +0 -0
  84. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/optimizers/__init__.py +0 -0
  85. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/optimizers/gepa.py +0 -0
  86. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/optimizers/gepa_callback.py +0 -0
  87. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/optimizers/resume.py +0 -0
  88. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/optimizers/tracker.py +0 -0
  89. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/packaging.py +0 -0
  90. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/programs.py +0 -0
  91. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/references.py +0 -0
  92. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/retry.py +0 -0
  93. {cmpnd-0.71.0 → cmpnd-0.72.0}/cmpnd/traces.py +0 -0
  94. {cmpnd-0.71.0 → cmpnd-0.72.0}/docs/2026-04-02-code-review.md +0 -0
  95. {cmpnd-0.71.0 → cmpnd-0.72.0}/docs/custom-proposer.md +0 -0
  96. {cmpnd-0.71.0 → cmpnd-0.72.0}/docs/plans/2026-04-05-train-val-dataset-capture-design.md +0 -0
  97. {cmpnd-0.71.0 → cmpnd-0.72.0}/docs/plans/2026-04-05-train-val-dataset-capture.md +0 -0
  98. {cmpnd-0.71.0 → cmpnd-0.72.0}/docs/reading-traces.md +0 -0
  99. {cmpnd-0.71.0 → cmpnd-0.72.0}/examples/generalizing_proposer.py +0 -0
  100. {cmpnd-0.71.0 → cmpnd-0.72.0}/examples/local_ollama.py +0 -0
  101. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/LINEAGE.md +0 -0
  102. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/README.md +0 -0
  103. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/cmpnd_ingest/__init__.py +0 -0
  104. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/cmpnd_ingest/bodies.py +0 -0
  105. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/cmpnd_ingest/client_floor.py +0 -0
  106. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/cmpnd_ingest/exporter_http.py +0 -0
  107. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/cmpnd_ingest/program_names.py +0 -0
  108. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/cmpnd_ingest/protocols.py +0 -0
  109. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/cmpnd_ingest/py.typed +0 -0
  110. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/cmpnd_ingest/request_log.py +0 -0
  111. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/cmpnd_ingest/retry.py +0 -0
  112. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/cmpnd_ingest/trace_facts.py +0 -0
  113. {cmpnd-0.71.0 → cmpnd-0.72.0}/ingest/pyproject.toml +0 -0
  114. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/audit-sdist.sh +0 -0
  115. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/capture_review_run.py +0 -0
  116. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/check-pip-install.sh +0 -0
  117. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/check_release_artifacts.py +0 -0
  118. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/fixtures/review_run.json.gz +0 -0
  119. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/gepa_resume_bug.py +0 -0
  120. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/install-test-env.sh +0 -0
  121. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/release-gate.sh +0 -0
  122. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/release-real-models.sh +0 -0
  123. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/require_version_bump.py +0 -0
  124. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/seed_review_run.py +0 -0
  125. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/selfhost_compat.py +0 -0
  126. {cmpnd-0.71.0 → cmpnd-0.72.0}/scripts/test-in-linux.sh +0 -0
  127. {cmpnd-0.71.0 → cmpnd-0.72.0}/stubs/dspy/__init__.pyi +0 -0
  128. {cmpnd-0.71.0 → cmpnd-0.72.0}/stubs/dspy/primitives/__init__.pyi +0 -0
  129. {cmpnd-0.71.0 → cmpnd-0.72.0}/stubs/dspy/primitives/prediction.pyi +0 -0
  130. {cmpnd-0.71.0 → cmpnd-0.72.0}/stubs/dspy/utils/__init__.pyi +0 -0
  131. {cmpnd-0.71.0 → cmpnd-0.72.0}/stubs/dspy/utils/callback.pyi +0 -0
  132. {cmpnd-0.71.0 → cmpnd-0.72.0}/stubs/dspy/utils/dummies.pyi +0 -0
  133. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/__init__.py +0 -0
  134. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/_credential_route.py +0 -0
  135. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/_deployment_signature_helpers.py +0 -0
  136. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/_exporter_helpers.py +0 -0
  137. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/_fake_clock.py +0 -0
  138. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/_identity_helpers.py +0 -0
  139. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/_resolve_refs.py +0 -0
  140. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/_traced_run.py +0 -0
  141. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/conftest.py +0 -0
  142. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/__init__.py +0 -0
  143. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/committee_task.py +0 -0
  144. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/conftest.py +0 -0
  145. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/continuation_task.py +0 -0
  146. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/data/committee_train.ndjson.gz +0 -0
  147. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/data/committee_val.ndjson.gz +0 -0
  148. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/fake_lm.py +0 -0
  149. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/helpers.py +0 -0
  150. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/target_capabilities.py +0 -0
  151. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_assessments_cli.py +0 -0
  152. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_capture_prompts.py +0 -0
  153. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_composite_module.py +0 -0
  154. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_dataset_auto_creation.py +0 -0
  155. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_deploy_execute.py +0 -0
  156. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_deploy_pandas.py +0 -0
  157. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_deploy_programs.py +0 -0
  158. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_edge_cases.py +0 -0
  159. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_example_hash.py +0 -0
  160. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_gepa_optimization.py +0 -0
  161. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_interpreter_spans.py +0 -0
  162. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_lm_accuracy.py +0 -0
  163. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_module_tracing.py +0 -0
  164. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_optimization_lineage.py +0 -0
  165. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_optimization_metric_identity.py +0 -0
  166. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_optimize_authored_metric.py +0 -0
  167. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_optimize_continuation.py +0 -0
  168. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_optimize_custom_proposer.py +0 -0
  169. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_optimize_failures.py +0 -0
  170. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_optimize_loop.py +0 -0
  171. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_optimize_review_committee.py +0 -0
  172. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_optimize_server_owned_completion.py +0 -0
  173. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_parallel_export.py +0 -0
  174. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_project_attribution.py +0 -0
  175. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_react_tool_spans.py +0 -0
  176. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_save_load.py +0 -0
  177. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_trace_structure.py +0 -0
  178. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_traces_read.py +0 -0
  179. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_user_attribution.py +0 -0
  180. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/e2e/test_valsets_cli.py +0 -0
  181. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/01_predict_qa.json +0 -0
  182. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/02_predict_renamed_field.json +0 -0
  183. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/03_chain_of_thought_qa.json +0 -0
  184. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/04_predict_richer_types.json +0 -0
  185. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/05_composite_two_predicts.json +0 -0
  186. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/06_multichaincomparison.json +0 -0
  187. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/07_program_of_thought.json +0 -0
  188. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/08_opaque_module.json +0 -0
  189. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/09_predict_pydantic_field.json +0 -0
  190. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/10_react.json +0 -0
  191. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/11_refine.json +0 -0
  192. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/12_retrieve.json +0 -0
  193. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/13_knn.json +0 -0
  194. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/14_parallel.json +0 -0
  195. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/identity_vectors/README.md +0 -0
  196. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/ingest_conformance.py +0 -0
  197. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/__init__.py +0 -0
  198. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/authored_optimize/judge.py +0 -0
  199. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/authored_optimize/optimize_hosted.py +0 -0
  200. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/conftest.py +0 -0
  201. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/hosted_mcp_tool_optimize_probe.py +0 -0
  202. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/hosted_optimize_probe.py +0 -0
  203. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/optimization_run_probe.py +0 -0
  204. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/test_cli_deploy_smoketest.py +0 -0
  205. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/test_logs_renders_traces.py +0 -0
  206. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/test_optimization_run.py +0 -0
  207. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/test_optimizing_progress.py +0 -0
  208. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/integration/test_unhappy_path.py +0 -0
  209. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/load/__init__.py +0 -0
  210. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/load/__main__.py +0 -0
  211. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/load/drain.py +0 -0
  212. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/load/ingest.py +0 -0
  213. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/load/latency_transport.py +0 -0
  214. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/load/rlm_shape.py +0 -0
  215. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/load/rlm_size_report.py +0 -0
  216. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/load/sweep.py +0 -0
  217. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/load/test_rlm_shape.py +0 -0
  218. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/load/test_rlm_size_report.py +0 -0
  219. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/__init__.py +0 -0
  220. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/conftest.py +0 -0
  221. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/seed_parity.py +0 -0
  222. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/test_auth.py +0 -0
  223. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/test_datasets.py +0 -0
  224. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/test_deployments.py +0 -0
  225. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/test_evals.py +0 -0
  226. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/test_health.py +0 -0
  227. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/test_modules.py +0 -0
  228. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/test_optimizations.py +0 -0
  229. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/test_programs.py +0 -0
  230. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/test_signatures.py +0 -0
  231. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/test_trace_streaming.py +0 -0
  232. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/parity/test_traces.py +0 -0
  233. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/__init__.py +0 -0
  234. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/_provider.py +0 -0
  235. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/_readiness.py +0 -0
  236. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/_reliability.py +0 -0
  237. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/_result.py +0 -0
  238. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/mint_bedrock_token.py +0 -0
  239. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_bedrock_converse.py +0 -0
  240. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_deploy_programs.py +0 -0
  241. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_multi_client_stress.py +0 -0
  242. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_optimize_client_committee.py +0 -0
  243. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_optimize_continuation.py +0 -0
  244. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_optimize_loop.py +0 -0
  245. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_optimize_loop_wasm.py +0 -0
  246. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_optimize_stress.py +0 -0
  247. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_provider_roles.py +0 -0
  248. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_readiness.py +0 -0
  249. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_real_provider_twins.py +0 -0
  250. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_reliability.py +0 -0
  251. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_reliability_classify.py +0 -0
  252. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_rlm_wasm.py +0 -0
  253. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/real_models/test_trace_search.py +0 -0
  254. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/span_reference_fixture.py +0 -0
  255. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_adapter_reentrancy.py +0 -0
  256. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_assessments_api.py +0 -0
  257. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_authored.py +0 -0
  258. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_authored_binding_credentials.py +0 -0
  259. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_authored_bundle_collisions.py +0 -0
  260. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_authored_metric_contract.py +0 -0
  261. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_authored_named_models.py +0 -0
  262. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_authored_optimize.py +0 -0
  263. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_callback.py +0 -0
  264. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_candidate_lineage.py +0 -0
  265. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/__init__.py +0 -0
  266. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/conftest.py +0 -0
  267. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_admin.py +0 -0
  268. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_api_client.py +0 -0
  269. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_assessments.py +0 -0
  270. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_auth.py +0 -0
  271. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_credentials.py +0 -0
  272. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_datasets.py +0 -0
  273. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_deployments.py +0 -0
  274. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_evals.py +0 -0
  275. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_login.py +0 -0
  276. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_main.py +0 -0
  277. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_optimizations.py +0 -0
  278. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_org.py +0 -0
  279. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_pagination.py +0 -0
  280. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_parity.py +0 -0
  281. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_programs.py +0 -0
  282. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_provider_credentials.py +0 -0
  283. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_schema_sample.py +0 -0
  284. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_shell.py +0 -0
  285. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_tool_servers.py +0 -0
  286. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_top.py +0 -0
  287. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_traces.py +0 -0
  288. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_traces_program_and_module.py +0 -0
  289. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_traces_search_wire.py +0 -0
  290. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_tree_help.py +0 -0
  291. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cli/test_valsets.py +0 -0
  292. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_client.py +0 -0
  293. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_client_floor.py +0 -0
  294. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_client_program_names.py +0 -0
  295. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_clustering/__init__.py +0 -0
  296. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_clustering/conftest.py +0 -0
  297. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_clustering/test_edge_cases.py +0 -0
  298. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_clustering/test_hash_consistency.py +0 -0
  299. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_clustering/test_type_conversion.py +0 -0
  300. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_cmp551_grouping_identity.py +0 -0
  301. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_configuration.py +0 -0
  302. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_context.py +0 -0
  303. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_context_propagation.py +0 -0
  304. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_credential_kwargs.py +0 -0
  305. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_credential_selection.py +0 -0
  306. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_credential_values.py +0 -0
  307. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_dataset_polling.py +0 -0
  308. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_dataset_sync.py +0 -0
  309. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_datasets.py +0 -0
  310. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_decision_client_spans.py +0 -0
  311. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_decorators.py +0 -0
  312. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_deploy.py +0 -0
  313. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_deploy_mcp_tool_references.py +0 -0
  314. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_deploy_program_id.py +0 -0
  315. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_deployment_metadata.py +0 -0
  316. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_deployments_read.py +0 -0
  317. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_eval.py +0 -0
  318. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_eval_example_attribution.py +0 -0
  319. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_eval_program_id.py +0 -0
  320. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_eval_start.py +0 -0
  321. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_eval_trace_grouping.py +0 -0
  322. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_exception_paths.py +0 -0
  323. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_execute.py +0 -0
  324. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_execute_run_identity.py +0 -0
  325. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_exporter.py +0 -0
  326. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_exporter_program_names.py +0 -0
  327. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_exporter_queue.py +0 -0
  328. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_exporter_real.py +0 -0
  329. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_fake_lm.py +0 -0
  330. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_gepa_callback.py +0 -0
  331. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_gepa_integration.py +0 -0
  332. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_gepa_output_normalization.py +0 -0
  333. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_gepa_resume.py +0 -0
  334. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_identity.py +0 -0
  335. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_imaging.py +0 -0
  336. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_import_weight.py +0 -0
  337. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_ingest_conformance.py +0 -0
  338. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_ingest_second_producer.py +0 -0
  339. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_integration.py +0 -0
  340. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_interpreter_callback.py +0 -0
  341. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_ir_encoder_properties.py +0 -0
  342. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_ir_golden_vectors.py +0 -0
  343. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_ir_roundtrip.py +0 -0
  344. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_lm15_native_calls.py +0 -0
  345. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_lm_configuration.py +0 -0
  346. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_lm_usage_shapes.py +0 -0
  347. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_mcp_tools.py +0 -0
  348. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_models.py +0 -0
  349. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_multi_client_stress_readiness.py +0 -0
  350. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_optimization_progress.py +0 -0
  351. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_optimization_start.py +0 -0
  352. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_optimize.py +0 -0
  353. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_optimize_budget.py +0 -0
  354. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_optimize_lift.py +0 -0
  355. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_optimize_lms.py +0 -0
  356. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_optimize_proposer.py +0 -0
  357. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_optimize_reflection_lm.py +0 -0
  358. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_optimize_terminal_failure.py +0 -0
  359. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_packaging.py +0 -0
  360. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_packaging_callable_source.py +0 -0
  361. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_packaging_mcp_tools.py +0 -0
  362. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_packaging_program_source.py +0 -0
  363. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_poll_until.py +0 -0
  364. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_program_id_deprecation.py +0 -0
  365. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_program_identity.py +0 -0
  366. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_program_lineage_persist.py +0 -0
  367. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_program_names_in_deploy.py +0 -0
  368. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_programs_create.py +0 -0
  369. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_project_payload.py +0 -0
  370. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_real_provider_twins_readiness.py +0 -0
  371. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_reflector_properties.py +0 -0
  372. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_reflector_smoke.py +0 -0
  373. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_release_gate_script.py +0 -0
  374. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_release_real_models_script.py +0 -0
  375. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_replaced_names.py +0 -0
  376. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_repro_reactv2_bugs.py +0 -0
  377. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_require_version_bump.py +0 -0
  378. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_retry.py +0 -0
  379. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_reversible_failures.py +0 -0
  380. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_rlm_patch.py +0 -0
  381. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_run_attribution_paths.py +0 -0
  382. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_runtime_tools.py +0 -0
  383. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_schemas.py +0 -0
  384. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_seal_lm_credential.py +0 -0
  385. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_seed_review_run.py +0 -0
  386. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_signature_inputs.py +0 -0
  387. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_span_references.py +0 -0
  388. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_span_sent_once.py +0 -0
  389. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_system_one.py +0 -0
  390. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_trace_context_concurrency.py +0 -0
  391. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_trace_fact_wire_contract.py +0 -0
  392. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_trace_facts.py +0 -0
  393. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_trace_render.py +0 -0
  394. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_traces_read.py +0 -0
  395. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_tracked_gepa.py +0 -0
  396. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_tracker_enrich.py +0 -0
  397. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_truncation.py +0 -0
  398. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_upload_auth_headers.py +0 -0
  399. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_valsets_api.py +0 -0
  400. {cmpnd-0.71.0 → cmpnd-0.72.0}/tests/test_xxh64.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: cmpnd
3
- Version: 0.71.0
3
+ Version: 0.72.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>
@@ -191,6 +191,9 @@ def submit_cli_run(
191
191
  raise
192
192
  except httpx.HTTPStatusError as exc:
193
193
  raise _http_refusal(exc) from exc
194
+ trace_id = settled.get("trace_id")
195
+ if isinstance(trace_id, str) and trace_id:
196
+ print(f"Trace: {trace_id}", file=sys.stderr)
194
197
  if settled["status"] == "failed":
195
198
  return settled, None
196
199
  result = settled.get("result")
@@ -390,6 +390,19 @@ class Client:
390
390
 
391
391
  return execution.deployment_run_id(result_or_error)
392
392
 
393
+ def get_trace_id(self, result_or_error: Any) -> str | None:
394
+ """The root trace id of a ``run_deployment`` prediction or exception.
395
+
396
+ It reads the id serve returned with the settled run and sends no
397
+ request. ``get_trace`` opens the trace.
398
+ The id lives outside the prediction's output fields. A run that stored no
399
+ trace, a server that names none, and a failure before serve accepted a run
400
+ all return ``None``.
401
+ """
402
+ from . import execution
403
+
404
+ return execution.get_trace_id(result_or_error)
405
+
393
406
  def submit_deployment_run(
394
407
  self,
395
408
  deployment_or_id: Any,
@@ -33,6 +33,21 @@ def deployment_run_id(result_or_error: Any) -> str | None:
33
33
  return getattr(result_or_error, "_cmpnd_deployment_run_id", None)
34
34
 
35
35
 
36
+ def get_trace_id(result_or_error: Any) -> str | None:
37
+ """Return the root trace id serve named for a run's prediction or exception.
38
+
39
+ The id lives outside the prediction's program output fields. A run that
40
+ stored no trace, a server that names none, and a failure before serve
41
+ accepted a run all return ``None``.
42
+ """
43
+ return getattr(result_or_error, "_cmpnd_deployment_trace_id", None)
44
+
45
+
46
+ def _settled_trace_id(settled: dict[str, Any]) -> str | None:
47
+ trace_id = settled.get("trace_id")
48
+ return trace_id if isinstance(trace_id, str) and trace_id else None
49
+
50
+
36
51
  def _with_run_id(error: Exception, run_id: str | None) -> Exception:
37
52
  error._cmpnd_deployment_run_id = run_id # pyright: ignore[reportAttributeAccessIssue]
38
53
  return error
@@ -247,14 +262,20 @@ def run_deployment(
247
262
  raise
248
263
 
249
264
  settled_id: str = settled["deployment_run_id"]
265
+ trace_id = _settled_trace_id(settled)
250
266
  result = settled["result"]
251
267
  if settled["status"] == "failed":
252
- _raise_stored_failure(settled_id, result, config.endpoint)
268
+ try:
269
+ _raise_stored_failure(settled_id, result, config.endpoint)
270
+ except Exception as error:
271
+ error._cmpnd_deployment_trace_id = trace_id # pyright: ignore[reportAttributeAccessIssue]
272
+ raise
253
273
  if not isinstance(result, dict) or "output" not in result:
254
274
  raise _with_run_id(RuntimeError("Deployment run result has no program output"), settled_id)
255
275
  output = result["output"]
256
276
  prediction = Prediction(**output) if isinstance(output, dict) else Prediction(**{"output": output})
257
277
  setattr(prediction, "_cmpnd_deployment_run_id", settled_id)
278
+ setattr(prediction, "_cmpnd_deployment_trace_id", trace_id)
258
279
  return prediction
259
280
 
260
281
 
@@ -228,6 +228,10 @@ seconds, unless `--timeout` sets the budget. The CLI prints the accepted run ID
228
228
  on stderr as soon as serve replies, which can take up to serve's five-second
229
229
  wait. A failed run exits nonzero. Human mode prints the stored error code,
230
230
  message and provider status. `--json` prints the whole settled run on stdout.
231
+ When a settled run names its root trace, the CLI prints `Trace: <id>` on
232
+ stderr, completed or failed. `cmpnd traces show <id>` opens that trace. The
233
+ run's `trace_id` field holds the same ID, and serve leaves it out when the run
234
+ stored no trace.
231
235
  The CLI retries status reads that time out or answer `408`, `429` or `5xx`
232
236
  within the budget.
233
237
 
@@ -147,7 +147,9 @@ endpoint. None of these reads the global config:
147
147
  - `sdk.submit_deployment_run`, `list_deployment_runs`, `get_deployment_run`,
148
148
  `get_deployment_run_result` and `wait_deployment_run` submit, find and resume
149
149
  runs without waiting in one call. `sdk.deployment_run_id(result)` reads the run
150
- id of a prediction or an exception.
150
+ id of a prediction or an exception. `sdk.get_trace_id(result)` reads the
151
+ id of the run's root trace the same way, or returns `None` when serve named no
152
+ trace.
151
153
  - `sdk.optimize_deployment(deployment, optimizer="gepa", ...)` runs the
152
154
  platform's optimization on a deployment and returns the best
153
155
  `DeployedProgram`, with `.score`. It never deploys. The program's model comes
@@ -432,7 +432,12 @@ command, and re-raises.
432
432
  `client.deployment_run_id(result)` reads the ID from
433
433
  private prediction metadata, so a program can use `output` or
434
434
  `deployment_run_id` as an output field. The accessor also accepts a stored
435
- execution error, a refused read, `RunWaitTimeout` and `RunResultExpired`. A
435
+ execution error, a refused read, `RunWaitTimeout` and `RunResultExpired`.
436
+ `client.get_trace_id(result)` reads the id of the run's root trace from
437
+ the same metadata, for a completed run's prediction and a failed run's error.
438
+ `cmpnd traces show` opens that trace. It returns `None` when the run stored no
439
+ trace, when the server names none, and when the run failed before serve
440
+ accepted it. A
436
441
  retained provider failure keeps its structured `RetryableProviderError` type but
437
442
  does not start another run. Trace delivery can finish after the result is
438
443
  available.
@@ -454,8 +459,10 @@ header readable.
454
459
  try:
455
460
  result = client.run_deployment(deployed, question="What changed?")
456
461
  run_id = client.deployment_run_id(result)
462
+ trace_id = client.get_trace_id(result)
457
463
  except Exception as error:
458
464
  run_id = client.deployment_run_id(error)
465
+ trace_id = client.get_trace_id(error)
459
466
  raise
460
467
  ```
461
468
 
@@ -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.71.0"
8
+ version = "0.72.0"
9
9
  description = "DSPy observability and deployment SDK for cmpnd"
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.11"
@@ -537,3 +537,37 @@ def test_json_run_commands_do_not_import_dspy(argv: list[str], replies: list):
537
537
  assert "JSON run command imported dspy" not in result.stderr
538
538
  out = json.loads(result.stdout)
539
539
  assert RUN_ID in result.stdout or "yes" in json.dumps(out)
540
+
541
+
542
+ TRACE_ID = "0b9c6f2e-4f1d-4c3a-9e2b-7a1d5c3e8f00"
543
+
544
+
545
+ def test_failed_run_names_its_trace_on_stderr(monkeypatch: pytest.MonkeyPatch, capsys):
546
+ failure = {"error": {"type": "ProgramError", "message": "bad input"}, "execution_status": 500}
547
+
548
+ def answer(req):
549
+ return httpx.Response(200, json={**_envelope("failed", failure), "trace_id": TRACE_ID}, request=req)
550
+
551
+ with pytest.raises(SystemExit):
552
+ _run_cli(monkeypatch, ["run", DEPLOYMENT_ID, "{}"], answer)
553
+ assert f"Trace: {TRACE_ID}" in capsys.readouterr().err
554
+
555
+
556
+ def test_completed_run_names_its_trace_on_stderr_and_keeps_stdout_the_output(monkeypatch: pytest.MonkeyPatch, capsys):
557
+ def answer(req):
558
+ return httpx.Response(
559
+ 200, json={**_envelope("completed", {"output": {"answer": "yes"}}), "trace_id": TRACE_ID}, request=req
560
+ )
561
+
562
+ _run_cli(monkeypatch, ["run", DEPLOYMENT_ID, "{}", "--json"], answer)
563
+ out = capsys.readouterr()
564
+ assert json.loads(out.out) == {"answer": "yes"}
565
+ assert f"Trace: {TRACE_ID}" in out.err
566
+
567
+
568
+ def test_run_without_a_trace_names_none(monkeypatch: pytest.MonkeyPatch, capsys):
569
+ def answer(req):
570
+ return httpx.Response(200, json=_envelope("completed", {"output": {"answer": "yes"}}), request=req)
571
+
572
+ _run_cli(monkeypatch, ["run", DEPLOYMENT_ID, "{}", "--json"], answer)
573
+ assert "Trace:" not in capsys.readouterr().err
@@ -505,3 +505,71 @@ def test_failure_summary_names_code_message_and_provider_status():
505
505
  f"Deployment run {RUN_ID} failed: EgressFailed: provider failed (provider status 429)"
506
506
  )
507
507
  assert deployment_runs.failure_summary(_run("failed", {"error": "boom"})) == f"Deployment run {RUN_ID} failed: boom"
508
+
509
+
510
+ TRACE_ID = "0b9c6f2e-4f1d-4c3a-9e2b-7a1d5c3e8f00"
511
+
512
+
513
+ def test_a_completed_run_names_its_trace_beside_its_run_id(monkeypatch: pytest.MonkeyPatch):
514
+ def answer(req: httpx.Request) -> httpx.Response:
515
+ body = {**_run("completed", {"output": {"answer": "yes"}}, available=True), "trace_id": TRACE_ID}
516
+ return httpx.Response(200, json=body, request=req)
517
+
518
+ _transport(monkeypatch, answer)
519
+ prediction = _client().run_deployment(DEPLOYMENT_ID, question="hi")
520
+ assert prediction.answer == "yes"
521
+ assert _client().get_trace_id(prediction) == TRACE_ID
522
+ assert _client().deployment_run_id(prediction) == RUN_ID
523
+ assert "trace_id" not in prediction.keys()
524
+
525
+
526
+ def test_a_failed_run_names_its_trace_on_the_raised_error(monkeypatch: pytest.MonkeyPatch):
527
+ failure = {"error": {"type": "ProgramError", "message": "bad input"}, "execution_status": 500}
528
+
529
+ def answer(req: httpx.Request) -> httpx.Response:
530
+ return httpx.Response(200, json={**_run("failed", failure, available=True), "trace_id": TRACE_ID}, request=req)
531
+
532
+ _transport(monkeypatch, answer)
533
+ with pytest.raises(httpx.HTTPStatusError) as caught:
534
+ _client().run_deployment(DEPLOYMENT_ID)
535
+ assert _client().get_trace_id(caught.value) == TRACE_ID
536
+ assert _client().deployment_run_id(caught.value) == RUN_ID
537
+
538
+
539
+ def test_a_retryable_provider_failure_names_its_trace(monkeypatch: pytest.MonkeyPatch):
540
+ failure = {
541
+ "error": {"type": "EgressFailed", "message": "provider refused"},
542
+ "execution_status": 503,
543
+ "retryable": True,
544
+ "failure": {"domain": "provider", "upstream_status": 429, "attempts": 3},
545
+ }
546
+
547
+ def answer(req: httpx.Request) -> httpx.Response:
548
+ return httpx.Response(200, json={**_run("failed", failure, available=True), "trace_id": TRACE_ID}, request=req)
549
+
550
+ _transport(monkeypatch, answer)
551
+ with pytest.raises(cmpnd.RetryableProviderError) as caught:
552
+ _client().run_deployment(DEPLOYMENT_ID)
553
+ assert _client().get_trace_id(caught.value) == TRACE_ID
554
+
555
+
556
+ @pytest.mark.parametrize("trace_field", [{}, {"trace_id": None}, {"trace_id": ""}, {"trace_id": 7}])
557
+ def test_a_run_serve_names_no_trace_for_has_none(monkeypatch: pytest.MonkeyPatch, trace_field: dict):
558
+ def answer(req: httpx.Request) -> httpx.Response:
559
+ body = {**_run("completed", {"output": {"answer": "yes"}}, available=True), **trace_field}
560
+ return httpx.Response(200, json=body, request=req)
561
+
562
+ _transport(monkeypatch, answer)
563
+ prediction = _client().run_deployment(DEPLOYMENT_ID, question="hi")
564
+ assert _client().get_trace_id(prediction) is None
565
+
566
+
567
+ def test_a_failure_before_acceptance_has_no_trace(monkeypatch: pytest.MonkeyPatch):
568
+ def answer(req: httpx.Request) -> httpx.Response:
569
+ return httpx.Response(404, json={"error": "not found"}, request=req)
570
+
571
+ _transport(monkeypatch, answer)
572
+ with pytest.raises(httpx.HTTPStatusError) as caught:
573
+ _client().run_deployment(DEPLOYMENT_ID)
574
+ assert _client().get_trace_id(caught.value) is None
575
+ assert _client().get_trace_id(object()) is None
@@ -505,7 +505,7 @@ wheels = [
505
505
 
506
506
  [[package]]
507
507
  name = "cmpnd"
508
- version = "0.71.0"
508
+ version = "0.72.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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes