cmpnd 0.6.2__tar.gz → 0.7.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 (224) hide show
  1. {cmpnd-0.6.2 → cmpnd-0.7.0}/PKG-INFO +1 -1
  2. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/__init__.py +9 -4
  3. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/optimizations.py +40 -0
  4. {cmpnd-0.6.2 → cmpnd-0.7.0}/pyproject.toml +1 -1
  5. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_main.py +13 -0
  6. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_optimizations.py +41 -1
  7. {cmpnd-0.6.2 → cmpnd-0.7.0}/uv.lock +1 -1
  8. {cmpnd-0.6.2 → cmpnd-0.7.0}/.gitignore +0 -0
  9. {cmpnd-0.6.2 → cmpnd-0.7.0}/CLAUDE.md +0 -0
  10. {cmpnd-0.6.2 → cmpnd-0.7.0}/README.md +0 -0
  11. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/__init__.py +0 -0
  12. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/_gepa_patch.py +0 -0
  13. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/_program_patch.py +0 -0
  14. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/_rlm_patch.py +0 -0
  15. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/callback.py +0 -0
  16. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/api_client.py +0 -0
  17. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/__init__.py +0 -0
  18. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/admin.py +0 -0
  19. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/auth.py +0 -0
  20. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/datasets.py +0 -0
  21. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/deployments.py +0 -0
  22. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/evals.py +0 -0
  23. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/login.py +0 -0
  24. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/org.py +0 -0
  25. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/programs.py +0 -0
  26. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/top.py +0 -0
  27. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/commands/traces.py +0 -0
  28. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/credentials.py +0 -0
  29. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/shell.py +0 -0
  30. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/trace_render.py +0 -0
  31. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/cli/verbs.py +0 -0
  32. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/configuration.py +0 -0
  33. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/context.py +0 -0
  34. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/dataset_sync.py +0 -0
  35. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/datasets.py +0 -0
  36. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/decorators.py +0 -0
  37. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/deployment.py +0 -0
  38. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/eval_handler.py +0 -0
  39. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/execution.py +0 -0
  40. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/exporter.py +0 -0
  41. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/exporter_http.py +0 -0
  42. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/helpers.py +0 -0
  43. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/identity.py +0 -0
  44. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/ir/__init__.py +0 -0
  45. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/ir/decode.py +0 -0
  46. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/ir/encode.py +0 -0
  47. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/ir/hash.py +0 -0
  48. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/ir/program.py +0 -0
  49. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/ir/reflection.py +0 -0
  50. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/ir/types.py +0 -0
  51. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/ir/xxh64.py +0 -0
  52. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/models.py +0 -0
  53. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/optimization.py +0 -0
  54. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/optimizers/__init__.py +0 -0
  55. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/optimizers/gepa.py +0 -0
  56. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/optimizers/gepa_callback.py +0 -0
  57. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/optimizers/resume.py +0 -0
  58. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/optimizers/tracker.py +0 -0
  59. {cmpnd-0.6.2 → cmpnd-0.7.0}/cmpnd/packaging.py +0 -0
  60. {cmpnd-0.6.2 → cmpnd-0.7.0}/docs/2026-04-02-code-review.md +0 -0
  61. {cmpnd-0.6.2 → cmpnd-0.7.0}/docs/plans/2026-04-05-train-val-dataset-capture-design.md +0 -0
  62. {cmpnd-0.6.2 → cmpnd-0.7.0}/docs/plans/2026-04-05-train-val-dataset-capture.md +0 -0
  63. {cmpnd-0.6.2 → cmpnd-0.7.0}/docs/sdk-instrumentation.md +0 -0
  64. {cmpnd-0.6.2 → cmpnd-0.7.0}/examples/local_ollama.py +0 -0
  65. {cmpnd-0.6.2 → cmpnd-0.7.0}/scripts/capture_review_run.py +0 -0
  66. {cmpnd-0.6.2 → cmpnd-0.7.0}/scripts/fixtures/review_run.json.gz +0 -0
  67. {cmpnd-0.6.2 → cmpnd-0.7.0}/scripts/gepa_resume_bug.py +0 -0
  68. {cmpnd-0.6.2 → cmpnd-0.7.0}/scripts/seed_review_run.py +0 -0
  69. {cmpnd-0.6.2 → cmpnd-0.7.0}/stubs/dspy/__init__.pyi +0 -0
  70. {cmpnd-0.6.2 → cmpnd-0.7.0}/stubs/dspy/primitives/__init__.pyi +0 -0
  71. {cmpnd-0.6.2 → cmpnd-0.7.0}/stubs/dspy/primitives/prediction.pyi +0 -0
  72. {cmpnd-0.6.2 → cmpnd-0.7.0}/stubs/dspy/utils/__init__.pyi +0 -0
  73. {cmpnd-0.6.2 → cmpnd-0.7.0}/stubs/dspy/utils/callback.pyi +0 -0
  74. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/__init__.py +0 -0
  75. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/_exporter_helpers.py +0 -0
  76. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/_identity_helpers.py +0 -0
  77. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/__init__.py +0 -0
  78. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/committee_task.py +0 -0
  79. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/conftest.py +0 -0
  80. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/data/committee_train.ndjson.gz +0 -0
  81. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/data/committee_val.ndjson.gz +0 -0
  82. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/fake_lm.py +0 -0
  83. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/helpers.py +0 -0
  84. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_capture_prompts.py +0 -0
  85. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_composite_module.py +0 -0
  86. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_dataset_auto_creation.py +0 -0
  87. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_deploy_execute.py +0 -0
  88. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_deploy_programs.py +0 -0
  89. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_edge_cases.py +0 -0
  90. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_example_hash.py +0 -0
  91. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_gepa_optimization.py +0 -0
  92. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_lm_accuracy.py +0 -0
  93. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_module_tracing.py +0 -0
  94. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_optimization_lineage.py +0 -0
  95. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_optimization_metric_identity.py +0 -0
  96. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_optimize_failures.py +0 -0
  97. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_optimize_loop.py +0 -0
  98. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_optimize_review_committee.py +0 -0
  99. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_optimize_server_owned_completion.py +0 -0
  100. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_parallel_export.py +0 -0
  101. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_project_attribution.py +0 -0
  102. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_react_tool_spans.py +0 -0
  103. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_save_load.py +0 -0
  104. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_trace_structure.py +0 -0
  105. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/e2e/test_user_attribution.py +0 -0
  106. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/01_predict_qa.json +0 -0
  107. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/02_predict_renamed_field.json +0 -0
  108. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/03_chain_of_thought_qa.json +0 -0
  109. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/04_predict_richer_types.json +0 -0
  110. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/05_composite_two_predicts.json +0 -0
  111. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/06_multichaincomparison.json +0 -0
  112. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/07_program_of_thought.json +0 -0
  113. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/08_opaque_module.json +0 -0
  114. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/09_predict_pydantic_field.json +0 -0
  115. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/10_react.json +0 -0
  116. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/11_refine.json +0 -0
  117. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/12_retrieve.json +0 -0
  118. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/13_knn.json +0 -0
  119. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/14_parallel.json +0 -0
  120. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/identity_vectors/README.md +0 -0
  121. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/integration/__init__.py +0 -0
  122. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/integration/conftest.py +0 -0
  123. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/integration/test_cli_deploy_smoketest.py +0 -0
  124. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/integration/test_logs_renders_traces.py +0 -0
  125. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/integration/test_optimizing_progress.py +0 -0
  126. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/integration/test_unhappy_path.py +0 -0
  127. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/__init__.py +0 -0
  128. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/conftest.py +0 -0
  129. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/seed_parity.py +0 -0
  130. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/test_auth.py +0 -0
  131. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/test_datasets.py +0 -0
  132. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/test_deployments.py +0 -0
  133. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/test_evals.py +0 -0
  134. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/test_health.py +0 -0
  135. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/test_modules.py +0 -0
  136. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/test_optimizations.py +0 -0
  137. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/test_programs.py +0 -0
  138. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/test_signatures.py +0 -0
  139. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/test_trace_streaming.py +0 -0
  140. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/parity/test_traces.py +0 -0
  141. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/__init__.py +0 -0
  142. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/_provider.py +0 -0
  143. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/_reliability.py +0 -0
  144. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/mint_bedrock_token.py +0 -0
  145. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/test_deploy_programs.py +0 -0
  146. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/test_multi_client_stress.py +0 -0
  147. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/test_optimize_client_committee.py +0 -0
  148. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/test_optimize_loop.py +0 -0
  149. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/test_optimize_loop_wasm.py +0 -0
  150. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/test_optimize_stress.py +0 -0
  151. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/test_real_provider_twins.py +0 -0
  152. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/test_reliability.py +0 -0
  153. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/stress/test_reliability_classify.py +0 -0
  154. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_callback.py +0 -0
  155. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/__init__.py +0 -0
  156. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/conftest.py +0 -0
  157. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_admin.py +0 -0
  158. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_api_client.py +0 -0
  159. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_auth.py +0 -0
  160. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_credentials.py +0 -0
  161. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_datasets.py +0 -0
  162. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_deployments.py +0 -0
  163. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_evals.py +0 -0
  164. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_login.py +0 -0
  165. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_org.py +0 -0
  166. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_parity.py +0 -0
  167. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_programs.py +0 -0
  168. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_shell.py +0 -0
  169. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_top.py +0 -0
  170. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cli/test_traces.py +0 -0
  171. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_clustering/__init__.py +0 -0
  172. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_clustering/conftest.py +0 -0
  173. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_clustering/test_edge_cases.py +0 -0
  174. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_clustering/test_hash_consistency.py +0 -0
  175. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_clustering/test_type_conversion.py +0 -0
  176. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_cmp551_grouping_identity.py +0 -0
  177. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_configuration.py +0 -0
  178. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_context.py +0 -0
  179. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_context_propagation.py +0 -0
  180. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_dataset_polling.py +0 -0
  181. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_dataset_sync.py +0 -0
  182. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_datasets.py +0 -0
  183. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_decorators.py +0 -0
  184. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_deploy.py +0 -0
  185. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_eval.py +0 -0
  186. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_eval_start.py +0 -0
  187. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_exception_paths.py +0 -0
  188. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_execute.py +0 -0
  189. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_exporter.py +0 -0
  190. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_exporter_real.py +0 -0
  191. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_fake_lm.py +0 -0
  192. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_gepa_callback.py +0 -0
  193. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_gepa_integration.py +0 -0
  194. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_gepa_resume.py +0 -0
  195. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_identity.py +0 -0
  196. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_import_weight.py +0 -0
  197. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_integration.py +0 -0
  198. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_ir_encoder_properties.py +0 -0
  199. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_ir_golden_vectors.py +0 -0
  200. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_ir_roundtrip.py +0 -0
  201. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_models.py +0 -0
  202. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_optimization_progress.py +0 -0
  203. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_optimization_start.py +0 -0
  204. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_optimize.py +0 -0
  205. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_optimize_lift.py +0 -0
  206. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_optimize_terminal_failure.py +0 -0
  207. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_packaging.py +0 -0
  208. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_packaging_callable_source.py +0 -0
  209. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_packaging_program_source.py +0 -0
  210. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_program_lineage_persist.py +0 -0
  211. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_project_payload.py +0 -0
  212. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_reflector_properties.py +0 -0
  213. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_reflector_smoke.py +0 -0
  214. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_repro_reactv2_bugs.py +0 -0
  215. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_rlm_patch.py +0 -0
  216. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_schemas.py +0 -0
  217. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_seed_review_run.py +0 -0
  218. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_stats_export.py +0 -0
  219. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_trace_render.py +0 -0
  220. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_tracked_gepa.py +0 -0
  221. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_tracker_enrich.py +0 -0
  222. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_truncation.py +0 -0
  223. {cmpnd-0.6.2 → cmpnd-0.7.0}/tests/test_xxh64.py +0 -0
  224. {cmpnd-0.6.2 → cmpnd-0.7.0}/todo.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cmpnd
3
- Version: 0.6.2
3
+ Version: 0.7.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>
@@ -99,13 +99,18 @@ def main() -> None:
99
99
  if os.environ.get("CMPND_CLI_ADMIN") == "1":
100
100
  admin.register(subparsers)
101
101
 
102
- # Resource subcommands are dev-only until productized.
103
- # Set CMPND_CLI_DEV=1 to expose programs, traces, optimizations,
104
- # evals, datasets, and deployments in --help.
102
+ # Optimizations is productized: the program-scoped failing-examples flow is
103
+ # a supported power-user path, so the group is always registered — the
104
+ # server gates each read on optimizations:read, so a caller without scope
105
+ # just gets a 403, not a hidden command.
106
+ optimizations.register(subparsers)
107
+
108
+ # The remaining resource subcommands are dev-only until productized. Set
109
+ # CMPND_CLI_DEV=1 to expose programs, traces, evals, datasets, and
110
+ # deployments in --help.
105
111
  if os.environ.get("CMPND_CLI_DEV") == "1":
106
112
  programs.register(subparsers)
107
113
  traces.register(subparsers)
108
- optimizations.register(subparsers)
109
114
  evals.register(subparsers)
110
115
  datasets.register(subparsers)
111
116
  deployments.register(subparsers)
@@ -33,6 +33,33 @@ def register(subparsers: _SubParsersAction[ArgumentParser]) -> None:
33
33
  cands.add_argument("id", help="Optimization run ID (UUID)")
34
34
  cands.set_defaults(func=handle_candidates)
35
35
 
36
+ failing = sub.add_parser(
37
+ "failing-examples",
38
+ help="Datapoints that fail across a program's optimizations",
39
+ )
40
+ failing.add_argument("--program", dest="program", required=True, help="Program name")
41
+ failing.add_argument(
42
+ "--min-failures",
43
+ dest="min_failures",
44
+ type=int,
45
+ default=2,
46
+ help="Min distinct models that must fail an example (default 2)",
47
+ )
48
+ failing.add_argument(
49
+ "--all",
50
+ dest="all_models",
51
+ action="store_true",
52
+ help="Require failure under EVERY model in each family (overrides --min-failures)",
53
+ )
54
+ failing.set_defaults(func=handle_failing_examples)
55
+
56
+ analysis = sub.add_parser(
57
+ "dataset-analysis",
58
+ help="Per-run always-fail / inconsistent example classification",
59
+ )
60
+ analysis.add_argument("id", help="Optimization run ID (op_...)")
61
+ analysis.set_defaults(func=handle_dataset_analysis)
62
+
36
63
 
37
64
  def handle_search(client: api_client.ApiClient, args: Any) -> Any:
38
65
  body: dict[str, Any] = {"page": args.page, "per_page": args.per_page}
@@ -58,3 +85,16 @@ def handle_iterations(client: api_client.ApiClient, args: Any) -> Any:
58
85
 
59
86
  def handle_candidates(client: api_client.ApiClient, args: Any) -> Any:
60
87
  return client.get(f"/api/v1/optimizations/{args.id}/candidates")
88
+
89
+
90
+ def handle_failing_examples(client: api_client.ApiClient, args: Any) -> Any:
91
+ params: dict[str, Any] = {"program": args.program}
92
+ if getattr(args, "all_models", False):
93
+ params["all"] = "true"
94
+ else:
95
+ params["min_failures"] = args.min_failures
96
+ return client.get("/api/v1/optimizations/failing-examples", params=params)
97
+
98
+
99
+ def handle_dataset_analysis(client: api_client.ApiClient, args: Any) -> Any:
100
+ return client.get(f"/api/v1/optimizations/{args.id}/dataset-analysis")
@@ -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.6.2"
8
+ version = "0.7.0"
9
9
  description = "DSPy observability and deployment SDK for cmpnd"
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10"
@@ -90,6 +90,19 @@ class TestDevGate:
90
90
  captured = capsys.readouterr()
91
91
  assert "(no deployments)" in captured.out
92
92
 
93
+ def test_optimizations_works_without_flag(self, capsys):
94
+ # optimizations is productized — available without CMPND_CLI_DEV.
95
+ env = {k: v for k, v in os.environ.items() if k != "CMPND_CLI_DEV"}
96
+ env["CMPND_API_KEY"] = "test-key"
97
+ mock_response = {"families": [], "total": 0}
98
+ with mock.patch("sys.argv", ["cmpnd", "optimizations", "failing-examples", "--program", "RAG"]):
99
+ with mock.patch.dict(os.environ, env, clear=True):
100
+ with mock.patch("cmpnd.cli.api_client.ApiClient.get", return_value=mock_response):
101
+ main()
102
+ captured = capsys.readouterr()
103
+ output = json.loads(captured.out)
104
+ assert "families" in output
105
+
93
106
 
94
107
  class TestAdminGate:
95
108
  """CMP-126: `admin` commands gated behind CMPND_CLI_ADMIN=1; the
@@ -4,7 +4,14 @@ from __future__ import annotations
4
4
 
5
5
  import argparse
6
6
 
7
- from cmpnd.cli.commands.optimizations import handle_candidates, handle_iterations, handle_search, handle_show
7
+ from cmpnd.cli.commands.optimizations import (
8
+ handle_candidates,
9
+ handle_dataset_analysis,
10
+ handle_failing_examples,
11
+ handle_iterations,
12
+ handle_search,
13
+ handle_show,
14
+ )
8
15
 
9
16
 
10
17
  class TestOptimizationsSearch:
@@ -50,3 +57,36 @@ class TestOptimizationsCandidates:
50
57
  args = argparse.Namespace(id="abc")
51
58
  handle_candidates(mock_client, args)
52
59
  mock_client.get.assert_called_once_with("/api/v1/optimizations/abc/candidates")
60
+
61
+
62
+ class TestOptimizationsFailingExamples:
63
+ def test_default_uses_min_failures(self, mock_client):
64
+ mock_client.get.return_value = {"families": [], "total": 0}
65
+ args = argparse.Namespace(program="RAG", min_failures=2, all_models=False)
66
+ handle_failing_examples(mock_client, args)
67
+ mock_client.get.assert_called_once_with(
68
+ "/api/v1/optimizations/failing-examples",
69
+ params={"program": "RAG", "min_failures": 2},
70
+ )
71
+
72
+ def test_custom_min_failures(self, mock_client):
73
+ mock_client.get.return_value = {"families": []}
74
+ args = argparse.Namespace(program="RAG", min_failures=3, all_models=False)
75
+ handle_failing_examples(mock_client, args)
76
+ assert mock_client.get.call_args[1]["params"]["min_failures"] == 3
77
+
78
+ def test_all_flag_overrides_min_failures(self, mock_client):
79
+ mock_client.get.return_value = {"families": []}
80
+ args = argparse.Namespace(program="RAG", min_failures=2, all_models=True)
81
+ handle_failing_examples(mock_client, args)
82
+ params = mock_client.get.call_args[1]["params"]
83
+ assert params == {"program": "RAG", "all": "true"}
84
+ assert "min_failures" not in params
85
+
86
+
87
+ class TestOptimizationsDatasetAnalysis:
88
+ def test_calls_correct_endpoint(self, mock_client):
89
+ mock_client.get.return_value = {"total_examples": 0}
90
+ args = argparse.Namespace(id="op_abc")
91
+ handle_dataset_analysis(mock_client, args)
92
+ mock_client.get.assert_called_once_with("/api/v1/optimizations/op_abc/dataset-analysis")
@@ -497,7 +497,7 @@ wheels = [
497
497
 
498
498
  [[package]]
499
499
  name = "cmpnd"
500
- version = "0.6.2"
500
+ version = "0.7.0"
501
501
  source = { editable = "." }
502
502
  dependencies = [
503
503
  { name = "dspy" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes