cmpnd 0.40.0__tar.gz → 0.40.1__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 (369) hide show
  1. {cmpnd-0.40.0 → cmpnd-0.40.1}/PKG-INFO +1 -1
  2. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/callback.py +11 -0
  3. {cmpnd-0.40.0 → cmpnd-0.40.1}/docs/sdk-instrumentation.md +11 -11
  4. {cmpnd-0.40.0 → cmpnd-0.40.1}/pyproject.toml +1 -1
  5. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/load/rlm_size_report.py +10 -1
  6. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_interpreter_callback.py +31 -0
  7. {cmpnd-0.40.0 → cmpnd-0.40.1}/uv.lock +39 -39
  8. {cmpnd-0.40.0 → cmpnd-0.40.1}/.gitignore +0 -0
  9. {cmpnd-0.40.0 → cmpnd-0.40.1}/AGENTS.md +0 -0
  10. {cmpnd-0.40.0 → cmpnd-0.40.1}/CLAUDE.md +0 -0
  11. {cmpnd-0.40.0 → cmpnd-0.40.1}/README.md +0 -0
  12. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/__init__.py +0 -0
  13. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_assessments.py +0 -0
  14. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_authored_import.py +0 -0
  15. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_deployments.py +0 -0
  16. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_exporter_pool.py +0 -0
  17. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_gepa_patch.py +0 -0
  18. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_http.py +0 -0
  19. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_program_patch.py +0 -0
  20. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_rlm_patch.py +0 -0
  21. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_runtime_tools.py +0 -0
  22. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_timespec.py +0 -0
  23. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_traces.py +0 -0
  24. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/_valsets.py +0 -0
  25. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/authored.py +0 -0
  26. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/__init__.py +0 -0
  27. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/api_client.py +0 -0
  28. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/__init__.py +0 -0
  29. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/admin.py +0 -0
  30. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/assessments.py +0 -0
  31. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/auth.py +0 -0
  32. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/datasets.py +0 -0
  33. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/deployments.py +0 -0
  34. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/evals.py +0 -0
  35. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/login.py +0 -0
  36. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/optimizations.py +0 -0
  37. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/org.py +0 -0
  38. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/programs.py +0 -0
  39. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/provider_credentials.py +0 -0
  40. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/signatures.py +0 -0
  41. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/tool_servers.py +0 -0
  42. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/top.py +0 -0
  43. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/traces.py +0 -0
  44. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/commands/valsets.py +0 -0
  45. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/credentials.py +0 -0
  46. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/deprecation.py +0 -0
  47. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/pagination.py +0 -0
  48. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/shell.py +0 -0
  49. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/trace_render.py +0 -0
  50. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/tree_help.py +0 -0
  51. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/cli/verbs.py +0 -0
  52. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/client.py +0 -0
  53. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/configuration.py +0 -0
  54. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/context.py +0 -0
  55. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/dataset_sync.py +0 -0
  56. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/datasets.py +0 -0
  57. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/decorators.py +0 -0
  58. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/deployment.py +0 -0
  59. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/deployment_metadata.py +0 -0
  60. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/deployment_runs.py +0 -0
  61. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/eval_handler.py +0 -0
  62. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/execution.py +0 -0
  63. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/exporter.py +0 -0
  64. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/exporter_http.py +0 -0
  65. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/helpers.py +0 -0
  66. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/identity.py +0 -0
  67. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/imaging.py +0 -0
  68. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/ir/__init__.py +0 -0
  69. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/ir/decode.py +0 -0
  70. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/ir/encode.py +0 -0
  71. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/ir/hash.py +0 -0
  72. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/ir/program.py +0 -0
  73. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/ir/reflection.py +0 -0
  74. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/ir/types.py +0 -0
  75. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/ir/xxh64.py +0 -0
  76. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/lm_configuration.py +0 -0
  77. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/mcp_servers.py +0 -0
  78. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/models.py +0 -0
  79. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/optimization.py +0 -0
  80. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/optimizers/__init__.py +0 -0
  81. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/optimizers/gepa.py +0 -0
  82. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/optimizers/gepa_callback.py +0 -0
  83. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/optimizers/resume.py +0 -0
  84. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/optimizers/tracker.py +0 -0
  85. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/packaging.py +0 -0
  86. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/programs.py +0 -0
  87. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/references.py +0 -0
  88. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/retry.py +0 -0
  89. {cmpnd-0.40.0 → cmpnd-0.40.1}/cmpnd/traces.py +0 -0
  90. {cmpnd-0.40.0 → cmpnd-0.40.1}/docs/2026-04-02-code-review.md +0 -0
  91. {cmpnd-0.40.0 → cmpnd-0.40.1}/docs/cli.md +0 -0
  92. {cmpnd-0.40.0 → cmpnd-0.40.1}/docs/client.md +0 -0
  93. {cmpnd-0.40.0 → cmpnd-0.40.1}/docs/custom-proposer.md +0 -0
  94. {cmpnd-0.40.0 → cmpnd-0.40.1}/docs/plans/2026-04-05-train-val-dataset-capture-design.md +0 -0
  95. {cmpnd-0.40.0 → cmpnd-0.40.1}/docs/plans/2026-04-05-train-val-dataset-capture.md +0 -0
  96. {cmpnd-0.40.0 → cmpnd-0.40.1}/docs/reading-traces.md +0 -0
  97. {cmpnd-0.40.0 → cmpnd-0.40.1}/examples/generalizing_proposer.py +0 -0
  98. {cmpnd-0.40.0 → cmpnd-0.40.1}/examples/local_ollama.py +0 -0
  99. {cmpnd-0.40.0 → cmpnd-0.40.1}/ingest/LINEAGE.md +0 -0
  100. {cmpnd-0.40.0 → cmpnd-0.40.1}/ingest/README.md +0 -0
  101. {cmpnd-0.40.0 → cmpnd-0.40.1}/ingest/cmpnd_ingest/__init__.py +0 -0
  102. {cmpnd-0.40.0 → cmpnd-0.40.1}/ingest/cmpnd_ingest/bodies.py +0 -0
  103. {cmpnd-0.40.0 → cmpnd-0.40.1}/ingest/cmpnd_ingest/exporter_http.py +0 -0
  104. {cmpnd-0.40.0 → cmpnd-0.40.1}/ingest/cmpnd_ingest/protocols.py +0 -0
  105. {cmpnd-0.40.0 → cmpnd-0.40.1}/ingest/cmpnd_ingest/py.typed +0 -0
  106. {cmpnd-0.40.0 → cmpnd-0.40.1}/ingest/cmpnd_ingest/request_log.py +0 -0
  107. {cmpnd-0.40.0 → cmpnd-0.40.1}/ingest/cmpnd_ingest/retry.py +0 -0
  108. {cmpnd-0.40.0 → cmpnd-0.40.1}/ingest/cmpnd_ingest/trace_facts.py +0 -0
  109. {cmpnd-0.40.0 → cmpnd-0.40.1}/ingest/pyproject.toml +0 -0
  110. {cmpnd-0.40.0 → cmpnd-0.40.1}/scripts/audit-sdist.sh +0 -0
  111. {cmpnd-0.40.0 → cmpnd-0.40.1}/scripts/capture_review_run.py +0 -0
  112. {cmpnd-0.40.0 → cmpnd-0.40.1}/scripts/check_release_artifacts.py +0 -0
  113. {cmpnd-0.40.0 → cmpnd-0.40.1}/scripts/fixtures/review_run.json.gz +0 -0
  114. {cmpnd-0.40.0 → cmpnd-0.40.1}/scripts/gepa_resume_bug.py +0 -0
  115. {cmpnd-0.40.0 → cmpnd-0.40.1}/scripts/release-stress.sh +0 -0
  116. {cmpnd-0.40.0 → cmpnd-0.40.1}/scripts/require_version_bump.py +0 -0
  117. {cmpnd-0.40.0 → cmpnd-0.40.1}/scripts/seed_review_run.py +0 -0
  118. {cmpnd-0.40.0 → cmpnd-0.40.1}/scripts/test-in-linux.sh +0 -0
  119. {cmpnd-0.40.0 → cmpnd-0.40.1}/stubs/dspy/__init__.pyi +0 -0
  120. {cmpnd-0.40.0 → cmpnd-0.40.1}/stubs/dspy/primitives/__init__.pyi +0 -0
  121. {cmpnd-0.40.0 → cmpnd-0.40.1}/stubs/dspy/primitives/prediction.pyi +0 -0
  122. {cmpnd-0.40.0 → cmpnd-0.40.1}/stubs/dspy/utils/__init__.pyi +0 -0
  123. {cmpnd-0.40.0 → cmpnd-0.40.1}/stubs/dspy/utils/callback.pyi +0 -0
  124. {cmpnd-0.40.0 → cmpnd-0.40.1}/stubs/dspy/utils/dummies.pyi +0 -0
  125. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/__init__.py +0 -0
  126. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/_deployment_signature_helpers.py +0 -0
  127. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/_exporter_helpers.py +0 -0
  128. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/_fake_clock.py +0 -0
  129. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/_identity_helpers.py +0 -0
  130. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/_resolve_refs.py +0 -0
  131. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/_traced_run.py +0 -0
  132. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/conftest.py +0 -0
  133. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/__init__.py +0 -0
  134. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/committee_task.py +0 -0
  135. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/conftest.py +0 -0
  136. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/data/committee_train.ndjson.gz +0 -0
  137. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/data/committee_val.ndjson.gz +0 -0
  138. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/fake_lm.py +0 -0
  139. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/helpers.py +0 -0
  140. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/target_capabilities.py +0 -0
  141. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_assessments_cli.py +0 -0
  142. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_capture_prompts.py +0 -0
  143. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_composite_module.py +0 -0
  144. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_dataset_auto_creation.py +0 -0
  145. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_deploy_execute.py +0 -0
  146. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_deploy_pandas.py +0 -0
  147. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_deploy_programs.py +0 -0
  148. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_edge_cases.py +0 -0
  149. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_example_hash.py +0 -0
  150. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_gepa_optimization.py +0 -0
  151. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_interpreter_spans.py +0 -0
  152. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_lm_accuracy.py +0 -0
  153. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_module_tracing.py +0 -0
  154. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_optimization_lineage.py +0 -0
  155. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_optimization_metric_identity.py +0 -0
  156. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_optimize_failures.py +0 -0
  157. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_optimize_loop.py +0 -0
  158. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_optimize_review_committee.py +0 -0
  159. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_optimize_server_owned_completion.py +0 -0
  160. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_parallel_export.py +0 -0
  161. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_project_attribution.py +0 -0
  162. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_react_tool_spans.py +0 -0
  163. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_save_load.py +0 -0
  164. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_trace_structure.py +0 -0
  165. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_traces_read.py +0 -0
  166. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_user_attribution.py +0 -0
  167. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/e2e/test_valsets_cli.py +0 -0
  168. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/01_predict_qa.json +0 -0
  169. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/02_predict_renamed_field.json +0 -0
  170. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/03_chain_of_thought_qa.json +0 -0
  171. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/04_predict_richer_types.json +0 -0
  172. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/05_composite_two_predicts.json +0 -0
  173. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/06_multichaincomparison.json +0 -0
  174. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/07_program_of_thought.json +0 -0
  175. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/08_opaque_module.json +0 -0
  176. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/09_predict_pydantic_field.json +0 -0
  177. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/10_react.json +0 -0
  178. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/11_refine.json +0 -0
  179. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/12_retrieve.json +0 -0
  180. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/13_knn.json +0 -0
  181. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/14_parallel.json +0 -0
  182. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/identity_vectors/README.md +0 -0
  183. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/ingest_conformance.py +0 -0
  184. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/__init__.py +0 -0
  185. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/authored_optimize/judge.py +0 -0
  186. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/authored_optimize/optimize_hosted.py +0 -0
  187. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/conftest.py +0 -0
  188. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/hosted_mcp_tool_optimize_probe.py +0 -0
  189. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/hosted_optimize_probe.py +0 -0
  190. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/optimization_run_probe.py +0 -0
  191. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/test_cli_deploy_smoketest.py +0 -0
  192. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/test_logs_renders_traces.py +0 -0
  193. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/test_optimization_run.py +0 -0
  194. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/test_optimizing_progress.py +0 -0
  195. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/integration/test_unhappy_path.py +0 -0
  196. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/load/__init__.py +0 -0
  197. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/load/__main__.py +0 -0
  198. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/load/drain.py +0 -0
  199. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/load/ingest.py +0 -0
  200. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/load/latency_transport.py +0 -0
  201. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/load/rlm_shape.py +0 -0
  202. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/load/sweep.py +0 -0
  203. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/load/test_rlm_shape.py +0 -0
  204. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/load/test_rlm_size_report.py +0 -0
  205. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/__init__.py +0 -0
  206. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/conftest.py +0 -0
  207. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/seed_parity.py +0 -0
  208. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/test_auth.py +0 -0
  209. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/test_datasets.py +0 -0
  210. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/test_deployments.py +0 -0
  211. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/test_evals.py +0 -0
  212. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/test_health.py +0 -0
  213. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/test_modules.py +0 -0
  214. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/test_optimizations.py +0 -0
  215. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/test_programs.py +0 -0
  216. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/test_signatures.py +0 -0
  217. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/test_trace_streaming.py +0 -0
  218. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/parity/test_traces.py +0 -0
  219. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/span_reference_fixture.py +0 -0
  220. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/__init__.py +0 -0
  221. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/_provider.py +0 -0
  222. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/_readiness.py +0 -0
  223. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/_reliability.py +0 -0
  224. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/_result.py +0 -0
  225. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/mint_bedrock_token.py +0 -0
  226. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_deploy_programs.py +0 -0
  227. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_multi_client_stress.py +0 -0
  228. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_optimize_client_committee.py +0 -0
  229. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_optimize_loop.py +0 -0
  230. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_optimize_loop_wasm.py +0 -0
  231. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_optimize_stress.py +0 -0
  232. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_provider_roles.py +0 -0
  233. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_readiness.py +0 -0
  234. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_real_provider_twins.py +0 -0
  235. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_reliability.py +0 -0
  236. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_reliability_classify.py +0 -0
  237. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_rlm_wasm.py +0 -0
  238. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/stress/test_trace_search.py +0 -0
  239. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_adapter_reentrancy.py +0 -0
  240. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_assessments_api.py +0 -0
  241. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_authored.py +0 -0
  242. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_authored_bundle_collisions.py +0 -0
  243. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_authored_metric_contract.py +0 -0
  244. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_authored_named_models.py +0 -0
  245. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_authored_optimize.py +0 -0
  246. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_callback.py +0 -0
  247. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_candidate_lineage.py +0 -0
  248. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/__init__.py +0 -0
  249. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/conftest.py +0 -0
  250. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_admin.py +0 -0
  251. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_api_client.py +0 -0
  252. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_assessments.py +0 -0
  253. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_auth.py +0 -0
  254. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_credentials.py +0 -0
  255. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_datasets.py +0 -0
  256. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_deployment_runs.py +0 -0
  257. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_deployments.py +0 -0
  258. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_evals.py +0 -0
  259. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_login.py +0 -0
  260. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_main.py +0 -0
  261. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_optimizations.py +0 -0
  262. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_org.py +0 -0
  263. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_pagination.py +0 -0
  264. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_parity.py +0 -0
  265. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_programs.py +0 -0
  266. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_provider_credentials.py +0 -0
  267. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_schema_sample.py +0 -0
  268. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_shell.py +0 -0
  269. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_signatures.py +0 -0
  270. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_tool_servers.py +0 -0
  271. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_top.py +0 -0
  272. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_traces.py +0 -0
  273. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_traces_search_wire.py +0 -0
  274. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_tree_help.py +0 -0
  275. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cli/test_valsets.py +0 -0
  276. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_client.py +0 -0
  277. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_clustering/__init__.py +0 -0
  278. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_clustering/conftest.py +0 -0
  279. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_clustering/test_edge_cases.py +0 -0
  280. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_clustering/test_hash_consistency.py +0 -0
  281. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_clustering/test_type_conversion.py +0 -0
  282. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_cmp551_grouping_identity.py +0 -0
  283. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_configuration.py +0 -0
  284. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_context.py +0 -0
  285. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_context_propagation.py +0 -0
  286. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_dataset_polling.py +0 -0
  287. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_dataset_sync.py +0 -0
  288. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_datasets.py +0 -0
  289. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_decorators.py +0 -0
  290. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_deploy.py +0 -0
  291. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_deploy_mcp_tool_references.py +0 -0
  292. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_deploy_program_id.py +0 -0
  293. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_deployment_metadata.py +0 -0
  294. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_deployment_runs.py +0 -0
  295. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_deployments_read.py +0 -0
  296. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_eval.py +0 -0
  297. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_eval_example_attribution.py +0 -0
  298. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_eval_start.py +0 -0
  299. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_eval_trace_grouping.py +0 -0
  300. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_exception_paths.py +0 -0
  301. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_execute.py +0 -0
  302. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_execute_run_identity.py +0 -0
  303. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_exporter.py +0 -0
  304. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_exporter_queue.py +0 -0
  305. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_exporter_real.py +0 -0
  306. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_fake_lm.py +0 -0
  307. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_gepa_callback.py +0 -0
  308. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_gepa_integration.py +0 -0
  309. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_gepa_output_normalization.py +0 -0
  310. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_gepa_resume.py +0 -0
  311. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_identity.py +0 -0
  312. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_imaging.py +0 -0
  313. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_import_weight.py +0 -0
  314. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_ingest_conformance.py +0 -0
  315. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_ingest_second_producer.py +0 -0
  316. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_integration.py +0 -0
  317. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_ir_encoder_properties.py +0 -0
  318. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_ir_golden_vectors.py +0 -0
  319. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_ir_roundtrip.py +0 -0
  320. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_lm15_native_calls.py +0 -0
  321. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_lm_configuration.py +0 -0
  322. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_lm_usage_shapes.py +0 -0
  323. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_mcp_tools.py +0 -0
  324. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_models.py +0 -0
  325. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_multi_client_stress_readiness.py +0 -0
  326. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_optimization_progress.py +0 -0
  327. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_optimization_start.py +0 -0
  328. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_optimize.py +0 -0
  329. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_optimize_budget.py +0 -0
  330. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_optimize_lift.py +0 -0
  331. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_optimize_lms.py +0 -0
  332. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_optimize_proposer.py +0 -0
  333. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_optimize_reflection_lm.py +0 -0
  334. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_optimize_terminal_failure.py +0 -0
  335. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_packaging.py +0 -0
  336. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_packaging_callable_source.py +0 -0
  337. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_packaging_mcp_tools.py +0 -0
  338. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_packaging_program_source.py +0 -0
  339. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_poll_until.py +0 -0
  340. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_program_identity.py +0 -0
  341. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_program_lineage_persist.py +0 -0
  342. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_programs_create.py +0 -0
  343. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_project_payload.py +0 -0
  344. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_real_provider_twins_readiness.py +0 -0
  345. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_reflector_properties.py +0 -0
  346. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_reflector_smoke.py +0 -0
  347. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_release_stress_script.py +0 -0
  348. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_repro_reactv2_bugs.py +0 -0
  349. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_require_version_bump.py +0 -0
  350. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_retry.py +0 -0
  351. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_reversible_failures.py +0 -0
  352. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_rlm_patch.py +0 -0
  353. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_run_attribution_paths.py +0 -0
  354. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_runtime_tools.py +0 -0
  355. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_schemas.py +0 -0
  356. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_seed_review_run.py +0 -0
  357. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_signature_inputs.py +0 -0
  358. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_span_references.py +0 -0
  359. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_span_sent_once.py +0 -0
  360. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_trace_context_concurrency.py +0 -0
  361. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_trace_fact_wire_contract.py +0 -0
  362. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_trace_facts.py +0 -0
  363. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_trace_render.py +0 -0
  364. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_traces_read.py +0 -0
  365. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_tracked_gepa.py +0 -0
  366. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_tracker_enrich.py +0 -0
  367. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_truncation.py +0 -0
  368. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_valsets_api.py +0 -0
  369. {cmpnd-0.40.0 → cmpnd-0.40.1}/tests/test_xxh64.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: cmpnd
3
- Version: 0.40.0
3
+ Version: 0.40.1
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>
@@ -1949,6 +1949,14 @@ class _ToolMixin(_CallbackBase):
1949
1949
  exp.export_span(span)
1950
1950
 
1951
1951
 
1952
+ # The variable DSPy (3.4.1 and later) hands the interpreter when RLM installs its
1953
+ # sandboxed `dspy` stand-in, as `dspy.primitives.facade.HOST_TOKEN_VAR`. That setup runs
1954
+ # as the session's first cell on every forward, and it is DSPy's machinery rather than a
1955
+ # step the program took, so it records no span. Spelled out rather than imported because
1956
+ # older DSPy has no such module.
1957
+ SANDBOX_SETUP_VARIABLE = "__dspy_host_token"
1958
+
1959
+
1952
1960
  class _InterpreterMixin(_CallbackBase):
1953
1961
  """DSPy CodeInterpreter callbacks — one span per REPL code execution.
1954
1962
 
@@ -1975,6 +1983,9 @@ class _InterpreterMixin(_CallbackBase):
1975
1983
  # has no span to attach to and no trace to root, so drop it.
1976
1984
  if context.get_current_trace() is None and context.get_current_span() is None:
1977
1985
  return
1986
+ variables = inputs.get("variables")
1987
+ if isinstance(variables, dict) and SANDBOX_SETUP_VARIABLE in variables:
1988
+ return
1978
1989
 
1979
1990
  span = self._new_span(f"{instance.__class__.__name__}.execute", models.SpanType.INTERPRETER_EXECUTE)
1980
1991
 
@@ -20,11 +20,11 @@ cmpnd.auto_instrument()
20
20
  ```
21
21
 
22
22
  - **`cmpnd.configure()`** — `cmpnd/configuration.py`. Reads `api_key`, `endpoint` and `program_id` from args or `CMPND_API_KEY` / `CMPND_ENDPOINT` / `CMPND_PROGRAM_ID` env vars, builds a `Config` dataclass (`configuration.py`), and stores it under a lock. This call does not start any threads. It also does not touch DSPy. You can call `configure()` in a library and let the user decide whether to instrument. See [The program id](#the-program-id) for what `program_id` does.
23
- - **`cmpnd.auto_instrument()`** — `python-sdk/cmpnd/__init__.py:272`. Requires `configure()` to have been called. It instantiates a `CmpndCallback`, appends it to `dspy.settings.callbacks` (deduplicating if already installed), and patches `dspy.GEPA.__init__` / `GEPA.compile` so optimization runs are tracked automatically. See [`./optimization-tracking.md`](../../docs/optimization-tracking.md) for what that patch does.
23
+ - **`cmpnd.auto_instrument()`** — `auto_instrument` in `python-sdk/cmpnd/__init__.py`. Requires `configure()` to have been called. It instantiates a `CmpndCallback`, appends it to `dspy.settings.callbacks` (deduplicating if already installed), and patches `dspy.GEPA.__init__` / `GEPA.compile` so optimization runs are tracked automatically. See [`./optimization-tracking.md`](../../docs/optimization-tracking.md) for what that patch does.
24
24
 
25
25
  The exporter thread isn't started here directly. It is lazily started on first export via `ensure_exporter_started()` in `python-sdk/cmpnd/exporter.py:41`.
26
26
 
27
- If you want to instrument manually (for example, to wire the callback into a non-global `dspy.Settings`), you can construct `CmpndCallback` yourself from `python-sdk/cmpnd/callback.py:88` and hand it to DSPy. `auto_instrument` is just the convenient path.
27
+ If you want to instrument manually (for example, to wire the callback into a non-global `dspy.Settings`), you can construct `CmpndCallback` yourself from `python-sdk/cmpnd/callback.py` and hand it to DSPy. `auto_instrument` is just the convenient path.
28
28
 
29
29
  For an explicit, scoped alternative that traces only the programs you run through it — with its own tags and credentials, orthogonal to this global path — see [`./client.md`](./client.md) (`cmpnd.Client`). `cmpnd.de_instrument()` removes this global instrumentation and restores the patched classes; it is documented there too.
30
30
 
@@ -79,12 +79,12 @@ capability lookup.
79
79
 
80
80
  The hook methods, in the order you'd expect them to fire for a typical `dspy.ChainOfThought` call:
81
81
 
82
- - **Module lifecycle** — `on_module_start` (`callback.py:195`) creates a new `SpanBuilder`, and, if this is the root module call, also creates a new `TraceBuilder` via `_create_trace` (`callback.py:579`). `on_module_end` (`callback.py:307`) closes the span, attaches outputs, and, if it was the root, exports the trace. A call is root when no span is on the stack — or when the only span above it is the `Evaluate` span, which contains many independent program runs and parents none of them, so each run under a `dspy.Evaluate` roots its own trace. Such a root span is built with `create_child_span(..., root=True)` so it does not adopt the `Evaluate` span as its parent.
82
+ - **Module lifecycle** — `on_module_start` (`callback.py`) creates a new `SpanBuilder`, and, if this is the root module call, also creates a new `TraceBuilder` via `_create_trace`. `on_module_end` closes the span, attaches outputs, and, if it was the root, exports the trace. A call is root when no span is on the stack — or when the only span above it is the `Evaluate` span, which contains many independent program runs and parents none of them, so each run under a `dspy.Evaluate` roots its own trace. Such a root span is built with `create_child_span(..., root=True)` so it does not adopt the `Evaluate` span as its parent.
83
83
  - **LM calls.** `on_lm_start` and `on_lm_end` wrap the provider call. The callback records the model, the current span token projections, and a versioned `lm_usage` evidence object. `capture_prompts` controls whether the prompt payload is recorded.
84
84
  - **Adapter format/parse** — `on_adapter_format_start` / `_end` and `on_adapter_parse_start` / `_end`. Both route through the shared helpers `_start_adapter_span` and `_end_adapter_span`. The callback records one span per adapter call. DSPy's `Adapter.__init_subclass__` wraps `format` and `parse` on every subclass, so a `JSONAdapter.format` call fires the hooks twice and a `BAMLAdapter.format` call three times, each with a fresh `call_id` and the same instance. `_start_adapter_span` skips a call when the current span is the same method's adapter span on the same instance, and `_end_adapter_span` returns early for the skipped `call_id`. The outermost span is kept, since its output is what reaches the LM. `tests/test_adapter_reentrancy.py` runs the real adapters under DSPy's dispatch. An adapter span's inputs are the method's arguments, so they include the predictor's `signature`. `helpers.clean_inputs` records any signature class among a span's inputs by its label, the class name or the `in1, in2 -> out1` fields of a string signature. It never records the repr, which embeds the whole instructions and every field's metadata. The same rule covers a `Predict` called with `signature=`, as DSPy's RLM does on every turn from DSPy `main` on. The span records the signature's fields and instructions once, as its own attributes.
85
- - **Tools** — `on_tool_start` (`callback.py:700`) / `on_tool_end` (`callback.py:733`). One span per `dspy.Tool` invocation, with the tool's args as inputs.
86
- - **Interpreter (code execution)** — `_InterpreterMixin` (`callback.py:1119`), for the DSPy `CodeInterpreter` hooks DSPy >= 3.3.1 fires around a program running code in the interpreter (`RLM`, `ProgramOfThought`, `CodeAct`, `Flex` — every module reaching it through `_create_interpreter`; `ReAct` / `ReActV2` use no interpreter and fire none). `on_interpreter_execute_start` / `_end` emit one `INTERPRETER_EXECUTE` span per REPL cell — the code in, its captured stdout out, and the `SUBMIT()` result (a DSPy `FinalOutput`) recorded distinctly from stdout. `on_interpreter_tool_call_start` / `_end` synthesize a `TOOL` span for a tool called from interpreter code **only when no real `dspy.Tool` span covered the call** (a user tool routes through `Tool.__call__` and fires `on_tool_*`, so its row is suppressed to avoid a duplicate; the `llm_query` builtins fire no tool hook, so they get the synthesized span). `on_interpreter_startup_*` / `on_interpreter_shutdown_*` emit no span — their duration folds into an `interpreter.startup_ms` / `interpreter.shutdown_ms` attribute on the enclosing span, and an event with no enclosing span (a pooled pre-warm) is dropped.
87
- - **Evaluate** — `on_evaluate_start` (`callback.py:773`) / `on_evaluate_end` (`callback.py:782`). These are thin forwarders that delegate to `EvalHandler` (see "Eval handling" below).
85
+ - **Tools** — `on_tool_start` / `on_tool_end` (`callback.py`). One span per `dspy.Tool` invocation, with the tool's args as inputs.
86
+ - **Interpreter (code execution)** — `_InterpreterMixin` (`callback.py`), for the DSPy `CodeInterpreter` hooks DSPy >= 3.3.1 fires around a program running code in the interpreter (`RLM`, `ProgramOfThought`, `CodeAct`, `Flex` — every module reaching it through `_create_interpreter`; `ReAct` / `ReActV2` use no interpreter and fire none). `on_interpreter_execute_start` / `_end` emit one `INTERPRETER_EXECUTE` span per REPL cell — the code in, its captured stdout out, and the `SUBMIT()` result (a DSPy `FinalOutput`) recorded distinctly from stdout. On DSPy 3.4.1 and later, `RLM` runs the sandbox side of its `dspy` stand-in as each session's first cell, marked by the `__dspy_host_token` variable (`dspy.primitives.facade.HOST_TOKEN_VAR`). That cell is DSPy's machinery rather than a step the program took, so it emits no span. `on_interpreter_tool_call_start` / `_end` synthesize a `TOOL` span for a tool called from interpreter code **only when no real `dspy.Tool` span covered the call** (a user tool routes through `Tool.__call__` and fires `on_tool_*`, so its row is suppressed to avoid a duplicate; the `llm_query` builtins fire no tool hook, so they get the synthesized span). `on_interpreter_startup_*` / `on_interpreter_shutdown_*` emit no span — their duration folds into an `interpreter.startup_ms` / `interpreter.shutdown_ms` attribute on the enclosing span, and an event with no enclosing span (a pooled pre-warm) is dropped.
87
+ - **Evaluate** — `on_evaluate_start` / `on_evaluate_end` (`callback.py`). These are thin forwarders that delegate to `EvalHandler` (see "Eval handling" below).
88
88
 
89
89
  During a GEPA evaluation, DSPy wraps the program prediction with its internal
90
90
  bootstrap trace. The callback recognizes this pair only while an optimization
@@ -108,8 +108,8 @@ so the next release that adds a hook is caught by CI rather than by a user's log
108
108
 
109
109
  This doc does not re-derive hash semantics — see [`./clustering.md`](../../docs/CLUSTERING.md) for why `signature_hash` exists and how xxhash maps to a signed Int64. Here's only _where_ it gets attached:
110
110
 
111
- - **On a span** — `_capture_module_attributes` in `callback.py:810`. After walking `instance.signature.input_fields` / `output_fields` and recording types and schemas, it calls `compute_signature_hash(signature)` at `callback.py:870` and stores the result on `span.signature_hash`. Composite modules (multi-child `dspy.Module` subclasses) take the `compute_composite_signature_hash` branch at `callback.py:889`.
112
- - **On a trace** — `_create_trace` in `callback.py:897`. Same split: single-signature modules hash directly at `callback.py:945`; composite modules walk `dspy.Predict` children and call the composite helper at `callback.py:964`.
111
+ - **On a span** — `_capture_module_attributes` in `callback.py`. After walking `instance.signature.input_fields` / `output_fields` and recording types and schemas, it calls `compute_signature_hash(signature)` and stores the result on `span.signature_hash`. Composite modules (multi-child `dspy.Module` subclasses) take the `compute_composite_signature_hash` branch.
112
+ - **On a trace** — `_create_trace` in `callback.py`. Same split: single-signature modules hash directly; composite modules walk `dspy.Predict` children and call the composite helper.
113
113
 
114
114
  Both code paths import from `python-sdk/cmpnd/identity.py`, which is the authoritative home of every hash the SDK computes.
115
115
 
@@ -117,11 +117,11 @@ Both code paths import from `python-sdk/cmpnd/identity.py`, which is the authori
117
117
 
118
118
  ## Span types
119
119
 
120
- `SpanType` is an enum defined in `python-sdk/cmpnd/models.py:157`. Grouped by hook that produces them:
120
+ `SpanType` is an enum defined in `python-sdk/cmpnd/models.py`. Grouped by hook that produces them:
121
121
 
122
122
  | Group | Values | Triggered when... |
123
123
  | ------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
124
- | Module-ish | `MODULE`, `PREDICT`, `CHAIN_OF_THOUGHT`, `REACT`, `RLM`, `RETRIEVE` | `on_module_start` fires. The concrete type is chosen by `_get_span_type_for_module` at `callback.py:793`. |
124
+ | Module-ish | `MODULE`, `PREDICT`, `CHAIN_OF_THOUGHT`, `REACT`, `RLM`, `RETRIEVE` | `on_module_start` fires. The concrete type is chosen by `_get_span_type_for_module`. |
125
125
  | LM | `LM_CALL` | `on_lm_start` fires — one per provider round-trip. |
126
126
  | Adapter | `ADAPTER_FORMAT`, `ADAPTER_PARSE` | DSPy's adapter serializes the prompt or parses the response. |
127
127
  | Tool | `TOOL` | `dspy.Tool` is invoked (inside a ReAct loop), or synthesized for a builtin called from interpreter code. |
@@ -660,7 +660,7 @@ Two files, both kept deliberately thin:
660
660
  - **`python-sdk/cmpnd/datasets.py`** — the user-facing `load_dataset()` helper (`datasets.py:142`). Fetches a named dataset + version from the backend, applies an optional field mapping via `_apply_field_mapping` (`datasets.py:33`), and returns DSPy `Example` objects. This is how you _pull_ a dataset down.
661
661
  - **`python-sdk/cmpnd/dataset_sync.py`** — utilities for _pushing_ a dataset up during an eval or optimization. `check_dataset_exists` at `dataset_sync.py:21` hits `GET /api/v1/datasets/check/:hash` to skip the upload if the backend already has it. `build_dataset_payload` at `dataset_sync.py:55` computes example hashes and assembles the payload.
662
662
 
663
- The callers are `python-sdk/cmpnd/eval_handler.py:192` (eval-time dataset capture) and `python-sdk/cmpnd/optimizers/tracker.py:866` (optimization-time capture, where it fires per compile and also per reflective dataset in GEPA). The devset never leaves the SDK unless the backend actually asks for it via the existence check — that's the whole reason these two modules are split from `datasets.py`.
663
+ The callers are `python-sdk/cmpnd/eval_handler.py` (eval-time dataset capture) and `python-sdk/cmpnd/optimizers/tracker.py` (optimization-time capture, where it fires per compile and also per reflective dataset in GEPA). The devset never leaves the SDK unless the backend actually asks for it via the existence check — that's the whole reason these two modules are split from `datasets.py`.
664
664
 
665
665
  ---
666
666
 
@@ -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.40.0"
8
+ version = "0.40.1"
9
9
  description = "DSPy observability and deployment SDK for cmpnd"
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10"
@@ -44,6 +44,11 @@ from dspy.utils.dummies import DummyLM
44
44
 
45
45
  ADAPTERS = {"chat": dspy.ChatAdapter, "json": dspy.JSONAdapter, "xml": dspy.XMLAdapter}
46
46
 
47
+ # The variable that marks RLM's sandboxed-dspy setup run on DSPy 3.4.1 and later
48
+ # (`dspy.primitives.facade.HOST_TOKEN_VAR`). Spelled out rather than imported from
49
+ # `cmpnd.callback`, because `--at` measures revisions of cmpnd that predate it.
50
+ SANDBOX_SETUP_VARIABLE = "__dspy_host_token"
51
+
47
52
 
48
53
  def interpreter_output(turn: int, size: int) -> str:
49
54
  """About ``size`` characters of interpreter output only ``turn`` produces.
@@ -91,7 +96,11 @@ class FakeInterpreter:
91
96
 
92
97
  @with_callbacks
93
98
  def execute(self, code: str, variables: Any = None) -> str:
94
- del code, variables # the answer depends on the turn alone
99
+ del code # the answer depends on the turn alone
100
+ # DSPy 3.4.1's RLM runs its sandboxed-dspy setup as the session's first cell.
101
+ # That is no turn of the program's, so it takes no turn's output.
102
+ if isinstance(variables, dict) and SANDBOX_SETUP_VARIABLE in variables:
103
+ return ""
95
104
  self.turn += 1
96
105
  return self._output(self.turn)
97
106
 
@@ -8,6 +8,7 @@ interpreter-level rather than coupled to ``RLM``.
8
8
  """
9
9
 
10
10
  import contextvars
11
+ import importlib.util
11
12
  from unittest import mock
12
13
  from uuid import uuid4
13
14
 
@@ -308,6 +309,36 @@ class TestInterpreterExecuteSpan:
308
309
  assert [s.attributes.get("tool.name") for s in synth] == ["llm_query"]
309
310
  assert [s.attributes.get("tool.name") for s in real] == ["add"]
310
311
 
312
+ def test_the_sandboxed_dspy_setup_run_records_no_span(self):
313
+ # DSPy 3.4.1's RLM starts each forward by running the sandbox side of its dspy
314
+ # stand-in as the session's first cell, marked by the host-token variable. That
315
+ # cell is DSPy's machinery rather than a step the program took, so it records
316
+ # nothing, and the program's own first cell is the first span.
317
+ callback = _callback()
318
+ parent = _root_rlm_span(uuid4())
319
+ exp = _CaptureExporter()
320
+
321
+ interp = FakeInterpreter(result="")
322
+ with mock.patch("cmpnd.exporter.get_exporter", autospec=True, return_value=exp):
323
+ with dspy.context(callbacks=[callback]):
324
+ interp.execute('"""Sandbox side of the dspy facade."""', variables={"__dspy_host_token": "t0k"})
325
+ assert exp.spans == []
326
+ assert get_current_span() is parent
327
+ interp.execute("print(rows[0])")
328
+
329
+ assert [span.inputs for span in exp.spans] == [{"code": "print(rows[0])"}]
330
+
331
+ @pytest.mark.skipif(
332
+ importlib.util.find_spec("dspy.primitives.facade") is None,
333
+ reason="DSPy before 3.4.1 runs no sandboxed-dspy setup",
334
+ )
335
+ def test_the_setup_run_is_recognized_by_dspys_own_variable_name(self):
336
+ from dspy.primitives import facade
337
+
338
+ from cmpnd.callback import SANDBOX_SETUP_VARIABLE
339
+
340
+ assert facade.HOST_TOKEN_VAR == SANDBOX_SETUP_VARIABLE
341
+
311
342
  def test_no_span_when_no_trace_and_no_span_are_active(self):
312
343
  callback = _callback()
313
344
  exp = _CaptureExporter()
@@ -1,5 +1,5 @@
1
1
  version = 1
2
- revision = 5
2
+ revision = 3
3
3
  requires-python = ">=3.10"
4
4
  resolution-markers = [
5
5
  "python_full_version >= '3.15' and sys_platform == 'win32'",
@@ -503,7 +503,7 @@ wheels = [
503
503
 
504
504
  [[package]]
505
505
  name = "cmpnd"
506
- version = "0.40.0"
506
+ version = "0.40.1"
507
507
  source = { editable = "." }
508
508
  dependencies = [
509
509
  { name = "dspy" },
@@ -720,7 +720,7 @@ name = "exceptiongroup"
720
720
  version = "1.3.1"
721
721
  source = { registry = "https://pypi.org/simple" }
722
722
  dependencies = [
723
- { name = "typing-extensions" },
723
+ { name = "typing-extensions", marker = "python_full_version < '3.11'" },
724
724
  ]
725
725
  sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" }
726
726
  wheels = [
@@ -1117,17 +1117,17 @@ resolution-markers = [
1117
1117
  "python_full_version < '3.11'",
1118
1118
  ]
1119
1119
  dependencies = [
1120
- { name = "colorama", marker = "sys_platform == 'win32'" },
1121
- { name = "decorator" },
1122
- { name = "exceptiongroup" },
1123
- { name = "jedi" },
1124
- { name = "matplotlib-inline" },
1125
- { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
1126
- { name = "prompt-toolkit" },
1127
- { name = "pygments" },
1128
- { name = "stack-data" },
1129
- { name = "traitlets" },
1130
- { name = "typing-extensions" },
1120
+ { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" },
1121
+ { name = "decorator", marker = "python_full_version < '3.11'" },
1122
+ { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
1123
+ { name = "jedi", marker = "python_full_version < '3.11'" },
1124
+ { name = "matplotlib-inline", marker = "python_full_version < '3.11'" },
1125
+ { name = "pexpect", marker = "python_full_version < '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" },
1126
+ { name = "prompt-toolkit", marker = "python_full_version < '3.11'" },
1127
+ { name = "pygments", marker = "python_full_version < '3.11'" },
1128
+ { name = "stack-data", marker = "python_full_version < '3.11'" },
1129
+ { name = "traitlets", marker = "python_full_version < '3.11'" },
1130
+ { name = "typing-extensions", marker = "python_full_version < '3.11'" },
1131
1131
  ]
1132
1132
  sdist = { url = "https://files.pythonhosted.org/packages/40/18/f8598d287006885e7136451fdea0755af4ebcbfe342836f24deefaed1164/ipython-8.39.0.tar.gz", hash = "sha256:4110ae96012c379b8b6db898a07e186c40a2a1ef5d57a7fa83166047d9da7624", size = 5513971, upload-time = "2026-03-27T10:02:13.94Z" }
1133
1133
  wheels = [
@@ -1152,18 +1152,18 @@ resolution-markers = [
1152
1152
  "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'",
1153
1153
  ]
1154
1154
  dependencies = [
1155
- { name = "colorama", marker = "sys_platform == 'win32'" },
1156
- { name = "decorator" },
1157
- { name = "ipython-pygments-lexers" },
1158
- { name = "jedi" },
1159
- { name = "matplotlib-inline" },
1160
- { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
1161
- { name = "prompt-toolkit" },
1162
- { name = "psutil" },
1163
- { name = "pygments" },
1164
- { name = "stack-data" },
1165
- { name = "traitlets" },
1166
- { name = "typing-extensions", marker = "python_full_version < '3.12'" },
1155
+ { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" },
1156
+ { name = "decorator", marker = "python_full_version >= '3.11'" },
1157
+ { name = "ipython-pygments-lexers", marker = "python_full_version >= '3.11'" },
1158
+ { name = "jedi", marker = "python_full_version >= '3.11'" },
1159
+ { name = "matplotlib-inline", marker = "python_full_version >= '3.11'" },
1160
+ { name = "pexpect", marker = "python_full_version >= '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" },
1161
+ { name = "prompt-toolkit", marker = "python_full_version >= '3.11'" },
1162
+ { name = "psutil", marker = "python_full_version >= '3.11'" },
1163
+ { name = "pygments", marker = "python_full_version >= '3.11'" },
1164
+ { name = "stack-data", marker = "python_full_version >= '3.11'" },
1165
+ { name = "traitlets", marker = "python_full_version >= '3.11'" },
1166
+ { name = "typing-extensions", marker = "python_full_version == '3.11.*'" },
1167
1167
  ]
1168
1168
  sdist = { url = "https://files.pythonhosted.org/packages/cd/c4/87cda5842cf5c31837c06ddb588e11c3c35d8ece89b7a0108c06b8c9b00a/ipython-9.13.0.tar.gz", hash = "sha256:7e834b6afc99f020e3f05966ced34792f40267d64cb1ea9043886dab0dde5967", size = 4430549, upload-time = "2026-04-24T12:24:55.221Z" }
1169
1169
  wheels = [
@@ -1175,7 +1175,7 @@ name = "ipython-pygments-lexers"
1175
1175
  version = "1.1.1"
1176
1176
  source = { registry = "https://pypi.org/simple" }
1177
1177
  dependencies = [
1178
- { name = "pygments" },
1178
+ { name = "pygments", marker = "python_full_version >= '3.11'" },
1179
1179
  ]
1180
1180
  sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" }
1181
1181
  wheels = [
@@ -2129,10 +2129,10 @@ resolution-markers = [
2129
2129
  "python_full_version < '3.11'",
2130
2130
  ]
2131
2131
  dependencies = [
2132
- { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } },
2133
- { name = "python-dateutil" },
2134
- { name = "pytz" },
2135
- { name = "tzdata" },
2132
+ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
2133
+ { name = "python-dateutil", marker = "python_full_version < '3.11'" },
2134
+ { name = "pytz", marker = "python_full_version < '3.11'" },
2135
+ { name = "tzdata", marker = "python_full_version < '3.11'" },
2136
2136
  ]
2137
2137
  sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" }
2138
2138
  wheels = [
@@ -2203,10 +2203,10 @@ resolution-markers = [
2203
2203
  "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'",
2204
2204
  ]
2205
2205
  dependencies = [
2206
- { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
2206
+ { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
2207
2207
  { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
2208
- { name = "python-dateutil" },
2209
- { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" },
2208
+ { name = "python-dateutil", marker = "python_full_version >= '3.11'" },
2209
+ { name = "tzdata", marker = "(python_full_version >= '3.11' and sys_platform == 'emscripten') or (python_full_version >= '3.11' and sys_platform == 'win32')" },
2210
2210
  ]
2211
2211
  sdist = { url = "https://files.pythonhosted.org/packages/e2/17/d7b106e05bfa642e8694451e7d3d759c6a241c5386a5d962e4f66c047e06/pandas-3.0.6.tar.gz", hash = "sha256:66b07ef7315a31bfe1089cd3d71a7de781c9dca986762d0b4fe7c0ef17465d10", size = 4667686, upload-time = "2026-09-17T23:23:18.345Z" }
2212
2212
  wheels = [
@@ -2283,7 +2283,7 @@ name = "pexpect"
2283
2283
  version = "4.9.0"
2284
2284
  source = { registry = "https://pypi.org/simple" }
2285
2285
  dependencies = [
2286
- { name = "ptyprocess" },
2286
+ { name = "ptyprocess", marker = "(python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32') or (python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" },
2287
2287
  ]
2288
2288
  sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" }
2289
2289
  wheels = [
@@ -3302,8 +3302,8 @@ name = "secretstorage"
3302
3302
  version = "3.5.0"
3303
3303
  source = { registry = "https://pypi.org/simple" }
3304
3304
  dependencies = [
3305
- { name = "cryptography" },
3306
- { name = "jeepney" },
3305
+ { name = "cryptography", marker = "(python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32') or (python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" },
3306
+ { name = "jeepney", marker = "(python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32') or (python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" },
3307
3307
  ]
3308
3308
  sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" }
3309
3309
  wheels = [
@@ -3637,8 +3637,8 @@ name = "uvicorn"
3637
3637
  version = "0.52.4"
3638
3638
  source = { registry = "https://pypi.org/simple" }
3639
3639
  dependencies = [
3640
- { name = "click" },
3641
- { name = "h11" },
3640
+ { name = "click", marker = "python_full_version < '3.11' or sys_platform != 'emscripten'" },
3641
+ { name = "h11", marker = "python_full_version < '3.11' or sys_platform != 'emscripten'" },
3642
3642
  { name = "typing-extensions", marker = "python_full_version < '3.11'" },
3643
3643
  ]
3644
3644
  sdist = { url = "https://files.pythonhosted.org/packages/f2/0f/3f86e61397dd33bf2ccf28188c40db6a740658aeebbbf6e7dbc101a1f487/uvicorn-0.52.4.tar.gz", hash = "sha256:73acfee47a0b133c5de13d219492d62d8a31e935f4fe6e41a232451a15379f86", size = 100627, upload-time = "2026-08-19T06:27:41.821Z" }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes