cmpnd 0.50.0__tar.gz → 0.52.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cmpnd-0.50.0 → cmpnd-0.52.0}/PKG-INFO +25 -34
- {cmpnd-0.50.0 → cmpnd-0.52.0}/README.md +24 -33
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/callback.py +9 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/__init__.py +20 -3
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/programs.py +59 -10
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/top.py +111 -30
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/shell.py +17 -9
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/client.py +63 -40
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/configuration.py +31 -4
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/deployment.py +132 -17
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/identity.py +23 -4
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/named_programs.py +25 -1
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/optimization.py +42 -16
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/packaging.py +12 -6
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/programs.py +46 -10
- {cmpnd-0.50.0 → cmpnd-0.52.0}/docs/cli.md +34 -28
- {cmpnd-0.50.0 → cmpnd-0.52.0}/docs/client.md +39 -20
- {cmpnd-0.50.0 → cmpnd-0.52.0}/docs/sdk-instrumentation.md +29 -18
- {cmpnd-0.50.0 → cmpnd-0.52.0}/pyproject.toml +1 -1
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_authored_metric_contract.py +1 -1
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_authored_optimize.py +4 -2
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_top.py +4 -4
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_client.py +43 -22
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_client_program_names.py +99 -29
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_deploy.py +3 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_deploy_mcp_tool_references.py +3 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_deploy_program_id.py +14 -8
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_execute_run_identity.py +3 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_optimize.py +6 -1
- cmpnd-0.52.0/tests/test_program_id_deprecation.py +306 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_program_identity.py +4 -1
- cmpnd-0.52.0/tests/test_program_names_in_deploy.py +643 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_programs_create.py +5 -1
- {cmpnd-0.50.0 → cmpnd-0.52.0}/uv.lock +1 -1
- {cmpnd-0.50.0 → cmpnd-0.52.0}/.gitignore +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/AGENTS.md +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/CLAUDE.md +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_assessments.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_authored_import.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_deployments.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_exporter_pool.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_gepa_patch.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_http.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_program_patch.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_rlm_patch.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_runtime_tools.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_timespec.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_traces.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/_valsets.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/authored.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/api_client.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/admin.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/assessments.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/auth.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/datasets.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/deployments.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/evals.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/login.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/optimizations.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/org.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/provider_credentials.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/signatures.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/tool_servers.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/traces.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/commands/valsets.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/credentials.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/deprecation.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/pagination.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/trace_render.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/tree_help.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/cli/verbs.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/context.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/dataset_sync.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/datasets.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/decorators.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/deployment_metadata.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/deployment_runs.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/eval_handler.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/execution.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/exporter.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/exporter_http.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/helpers.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/imaging.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/ir/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/ir/decode.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/ir/encode.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/ir/hash.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/ir/program.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/ir/reflection.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/ir/types.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/ir/xxh64.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/lm_configuration.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/mcp_servers.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/models.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/optimizers/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/optimizers/gepa.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/optimizers/gepa_callback.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/optimizers/resume.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/optimizers/tracker.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/references.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/retry.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/cmpnd/traces.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/docs/2026-04-02-code-review.md +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/docs/custom-proposer.md +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/docs/plans/2026-04-05-train-val-dataset-capture-design.md +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/docs/plans/2026-04-05-train-val-dataset-capture.md +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/docs/reading-traces.md +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/examples/generalizing_proposer.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/examples/local_ollama.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/LINEAGE.md +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/README.md +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/cmpnd_ingest/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/cmpnd_ingest/bodies.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/cmpnd_ingest/client_floor.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/cmpnd_ingest/exporter_http.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/cmpnd_ingest/program_names.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/cmpnd_ingest/protocols.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/cmpnd_ingest/py.typed +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/cmpnd_ingest/request_log.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/cmpnd_ingest/retry.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/cmpnd_ingest/trace_facts.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/ingest/pyproject.toml +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/scripts/audit-sdist.sh +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/scripts/capture_review_run.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/scripts/check-pip-install.sh +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/scripts/check_release_artifacts.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/scripts/fixtures/review_run.json.gz +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/scripts/gepa_resume_bug.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/scripts/release-stress.sh +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/scripts/require_version_bump.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/scripts/seed_review_run.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/scripts/test-in-linux.sh +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/stubs/dspy/__init__.pyi +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/stubs/dspy/primitives/__init__.pyi +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/stubs/dspy/primitives/prediction.pyi +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/stubs/dspy/utils/__init__.pyi +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/stubs/dspy/utils/callback.pyi +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/stubs/dspy/utils/dummies.pyi +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/_deployment_signature_helpers.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/_exporter_helpers.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/_fake_clock.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/_identity_helpers.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/_resolve_refs.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/_traced_run.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/conftest.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/committee_task.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/conftest.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/data/committee_train.ndjson.gz +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/data/committee_val.ndjson.gz +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/fake_lm.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/helpers.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/target_capabilities.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_assessments_cli.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_capture_prompts.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_composite_module.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_dataset_auto_creation.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_deploy_execute.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_deploy_pandas.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_deploy_programs.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_edge_cases.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_example_hash.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_gepa_optimization.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_interpreter_spans.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_lm_accuracy.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_module_tracing.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_optimization_lineage.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_optimization_metric_identity.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_optimize_failures.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_optimize_loop.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_optimize_review_committee.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_optimize_server_owned_completion.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_parallel_export.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_project_attribution.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_react_tool_spans.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_save_load.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_trace_structure.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_traces_read.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_user_attribution.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/e2e/test_valsets_cli.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/01_predict_qa.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/02_predict_renamed_field.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/03_chain_of_thought_qa.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/04_predict_richer_types.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/05_composite_two_predicts.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/06_multichaincomparison.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/07_program_of_thought.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/08_opaque_module.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/09_predict_pydantic_field.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/10_react.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/11_refine.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/12_retrieve.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/13_knn.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/14_parallel.json +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/identity_vectors/README.md +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/ingest_conformance.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/authored_optimize/judge.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/authored_optimize/optimize_hosted.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/conftest.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/hosted_mcp_tool_optimize_probe.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/hosted_optimize_probe.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/optimization_run_probe.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/test_cli_deploy_smoketest.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/test_logs_renders_traces.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/test_optimization_run.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/test_optimizing_progress.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/integration/test_unhappy_path.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/load/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/load/__main__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/load/drain.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/load/ingest.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/load/latency_transport.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/load/rlm_shape.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/load/rlm_size_report.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/load/sweep.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/load/test_rlm_shape.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/load/test_rlm_size_report.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/conftest.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/seed_parity.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/test_auth.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/test_datasets.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/test_deployments.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/test_evals.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/test_health.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/test_modules.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/test_optimizations.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/test_programs.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/test_signatures.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/test_trace_streaming.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/parity/test_traces.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/span_reference_fixture.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/_provider.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/_readiness.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/_reliability.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/_result.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/mint_bedrock_token.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_deploy_programs.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_multi_client_stress.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_optimize_client_committee.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_optimize_loop.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_optimize_loop_wasm.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_optimize_stress.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_provider_roles.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_readiness.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_real_provider_twins.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_reliability.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_reliability_classify.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_rlm_wasm.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/stress/test_trace_search.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_adapter_reentrancy.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_assessments_api.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_authored.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_authored_bundle_collisions.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_authored_named_models.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_callback.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_candidate_lineage.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/conftest.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_admin.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_api_client.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_assessments.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_auth.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_credentials.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_datasets.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_deployment_runs.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_deployments.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_evals.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_login.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_main.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_optimizations.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_org.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_pagination.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_parity.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_programs.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_provider_credentials.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_schema_sample.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_shell.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_signatures.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_tool_servers.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_traces.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_traces_search_wire.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_tree_help.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cli/test_valsets.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_client_floor.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_clustering/__init__.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_clustering/conftest.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_clustering/test_edge_cases.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_clustering/test_hash_consistency.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_clustering/test_type_conversion.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_cmp551_grouping_identity.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_configuration.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_context.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_context_propagation.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_dataset_polling.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_dataset_sync.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_datasets.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_decision_client_spans.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_decorators.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_deployment_metadata.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_deployment_runs.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_deployments_read.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_eval.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_eval_example_attribution.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_eval_start.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_eval_trace_grouping.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_exception_paths.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_execute.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_exporter.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_exporter_program_names.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_exporter_queue.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_exporter_real.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_fake_lm.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_gepa_callback.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_gepa_integration.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_gepa_output_normalization.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_gepa_resume.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_identity.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_imaging.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_import_weight.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_ingest_conformance.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_ingest_second_producer.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_integration.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_interpreter_callback.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_ir_encoder_properties.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_ir_golden_vectors.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_ir_roundtrip.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_lm15_native_calls.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_lm_configuration.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_lm_usage_shapes.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_mcp_tools.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_models.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_multi_client_stress_readiness.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_optimization_progress.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_optimization_start.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_optimize_budget.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_optimize_lift.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_optimize_lms.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_optimize_proposer.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_optimize_reflection_lm.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_optimize_terminal_failure.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_packaging.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_packaging_callable_source.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_packaging_mcp_tools.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_packaging_program_source.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_poll_until.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_program_lineage_persist.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_project_payload.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_real_provider_twins_readiness.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_reflector_properties.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_reflector_smoke.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_release_stress_script.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_repro_reactv2_bugs.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_require_version_bump.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_retry.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_reversible_failures.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_rlm_patch.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_run_attribution_paths.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_runtime_tools.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_schemas.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_seed_review_run.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_signature_inputs.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_span_references.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_span_sent_once.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_system_one.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_trace_context_concurrency.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_trace_fact_wire_contract.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_trace_facts.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_trace_render.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_traces_read.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_tracked_gepa.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_tracker_enrich.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_truncation.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_upload_auth_headers.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_valsets_api.py +0 -0
- {cmpnd-0.50.0 → cmpnd-0.52.0}/tests/test_xxh64.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: cmpnd
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.52.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>
|
|
@@ -88,7 +88,6 @@ no arguments. The endpoint defaults to `https://platform.cmpnd.ai`.
|
|
|
88
88
|
```bash
|
|
89
89
|
export CMPND_API_KEY="ck_your_api_key"
|
|
90
90
|
export CMPND_ENDPOINT="https://platform.cmpnd.ai" # optional
|
|
91
|
-
export CMPND_PROGRAM_ID="p_0123456789Ab" # optional: the program these traces belong to
|
|
92
91
|
```
|
|
93
92
|
|
|
94
93
|
```python
|
|
@@ -96,7 +95,6 @@ cmpnd.configure(
|
|
|
96
95
|
api_key="ck_xxx", # required, or CMPND_API_KEY
|
|
97
96
|
endpoint="https://platform.cmpnd.ai", # optional, or CMPND_ENDPOINT
|
|
98
97
|
project_tags="my-project", # optional: one tag or a list of tags
|
|
99
|
-
program_id="p_0123456789Ab", # optional, or CMPND_PROGRAM_ID: the id `cmpnd programs create` prints
|
|
100
98
|
batch_size=100, # optional: spans per export batch
|
|
101
99
|
flush_interval_seconds=5.0, # optional: seconds between flushes
|
|
102
100
|
capture_inputs=True, # optional: record span inputs
|
|
@@ -111,24 +109,18 @@ captured input and output size limits, 65,536 bytes each by default.
|
|
|
111
109
|
|
|
112
110
|
## Deployment
|
|
113
111
|
|
|
114
|
-
Every deployment belongs to a program, and
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
cmpnd programs create --name qa
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
Then deploy a DSPy module under that program for server-side execution:
|
|
112
|
+
Every deployment belongs to a program, and each program has a program name.
|
|
113
|
+
Give a DSPy module a program name with `cmpnd.Program`, then deploy it for
|
|
114
|
+
server-side execution:
|
|
122
115
|
|
|
123
116
|
```python
|
|
124
117
|
import cmpnd
|
|
125
118
|
import dspy
|
|
126
119
|
|
|
127
|
-
cmpnd.configure(api_key="ck_xxx"
|
|
128
|
-
dspy.configure(lm=dspy.LM("openai/gpt-6-luna"))
|
|
120
|
+
cmpnd.configure(api_key="ck_xxx")
|
|
129
121
|
|
|
130
|
-
|
|
131
|
-
deployed = cmpnd.deploy(
|
|
122
|
+
qa = cmpnd.Program("qa", module=dspy.Predict("question -> answer"), lm=dspy.LM("openai/gpt-6-luna"))
|
|
123
|
+
deployed = cmpnd.deploy(qa)
|
|
132
124
|
|
|
133
125
|
result = deployed(question="What is DSPy?") # runs server-side
|
|
134
126
|
print(result.answer)
|
|
@@ -143,26 +135,26 @@ when the platform has inspected it. An unknown interface leaves `input_fields`
|
|
|
143
135
|
and `output_fields` as `None`. A known interface with no fields returns empty
|
|
144
136
|
lists.
|
|
145
137
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
138
|
+
The platform makes the program the first time your organization uses the
|
|
139
|
+
program name. Later deploys under the same program name go to the same
|
|
140
|
+
program. `@cmpnd.program("qa")` above a `dspy.Module`
|
|
141
|
+
class declares the same program name. [`docs/client.md`](docs/client.md)
|
|
142
|
+
describes both forms.
|
|
149
143
|
|
|
150
|
-
To deploy a source file, run `cmpnd deploy program.py
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
covers the CLI.
|
|
144
|
+
To deploy a source file, run `cmpnd deploy program.py qa`. The CLI uploads
|
|
145
|
+
the file's exact bytes and does not reconstruct the source from a live object.
|
|
146
|
+
Use `--source-root` and repeated `--include` flags for sibling modules or
|
|
147
|
+
data, and `cmpnd inspect <id> --source` to read the deployed entry file back.
|
|
148
|
+
[`docs/cli.md`](docs/cli.md) covers the CLI.
|
|
156
149
|
|
|
157
150
|
### Options
|
|
158
151
|
|
|
159
152
|
```python
|
|
160
153
|
cmpnd.deploy(
|
|
161
|
-
|
|
154
|
+
program, # required: a cmpnd.Program
|
|
162
155
|
metric=None, # optional: a metric callable, packaged for optimization
|
|
163
156
|
timeout=300, # optional: seconds to wait for the parser after the upload
|
|
164
157
|
metadata=None, # optional: a JSON-serializable dict, at most 64 KiB, stored with the deployment
|
|
165
|
-
program_id="p_…", # the program the deployment belongs to; serve requires it after self-host 2026-001
|
|
166
158
|
)
|
|
167
159
|
```
|
|
168
160
|
|
|
@@ -190,10 +182,9 @@ it returns a `DeployedProgram` that you call directly, and the program's
|
|
|
190
182
|
import cmpnd
|
|
191
183
|
import dspy
|
|
192
184
|
|
|
193
|
-
cmpnd.configure(api_key="ck_xxx"
|
|
194
|
-
dspy.configure(lm=dspy.LM("openai/gpt-6-luna"))
|
|
185
|
+
cmpnd.configure(api_key="ck_xxx")
|
|
195
186
|
|
|
196
|
-
program = dspy.ChainOfThought("topic -> haiku")
|
|
187
|
+
program = cmpnd.Program("haiku", module=dspy.ChainOfThought("topic -> haiku"), lm=dspy.LM("openai/gpt-6-luna"))
|
|
197
188
|
|
|
198
189
|
# GEPA needs a five-argument feedback metric that returns dspy.Prediction(score=, feedback=)
|
|
199
190
|
def metric(example, pred, trace=None, pred_name=None, pred_trace=None):
|
|
@@ -327,13 +318,13 @@ raises `cmpnd.OptimizeFailed` when a step reaches `failed`.
|
|
|
327
318
|
### From the CLI
|
|
328
319
|
|
|
329
320
|
```bash
|
|
330
|
-
cmpnd optimize gepa task.py
|
|
321
|
+
cmpnd optimize gepa task.py haiku --reflection-model openai/gpt-6-luna --auto light
|
|
331
322
|
```
|
|
332
323
|
|
|
333
324
|
The file, or `-` for stdin, binds `program`, `trainset`, `valset` and
|
|
334
325
|
`metric`. The CLI prints the best deployment ID. The CLI deploys the file's
|
|
335
|
-
program first
|
|
336
|
-
|
|
326
|
+
program first under the program name, here `haiku`. With `--deployment-id`,
|
|
327
|
+
the CLI starts from that deployment and needs no program name.
|
|
337
328
|
|
|
338
329
|
## Custom spans
|
|
339
330
|
|
|
@@ -403,8 +394,8 @@ dspy.configure(callbacks=[cmpnd.CmpndCallback()])
|
|
|
403
394
|
|
|
404
395
|
### `cmpnd.deploy()`
|
|
405
396
|
|
|
406
|
-
Deploys a
|
|
407
|
-
`DeployedProgram`.
|
|
397
|
+
Deploys a `cmpnd.Program` under its program name and returns a callable
|
|
398
|
+
`DeployedProgram`.
|
|
408
399
|
|
|
409
400
|
### `cmpnd.optimize()`
|
|
410
401
|
|
|
@@ -37,7 +37,6 @@ no arguments. The endpoint defaults to `https://platform.cmpnd.ai`.
|
|
|
37
37
|
```bash
|
|
38
38
|
export CMPND_API_KEY="ck_your_api_key"
|
|
39
39
|
export CMPND_ENDPOINT="https://platform.cmpnd.ai" # optional
|
|
40
|
-
export CMPND_PROGRAM_ID="p_0123456789Ab" # optional: the program these traces belong to
|
|
41
40
|
```
|
|
42
41
|
|
|
43
42
|
```python
|
|
@@ -45,7 +44,6 @@ cmpnd.configure(
|
|
|
45
44
|
api_key="ck_xxx", # required, or CMPND_API_KEY
|
|
46
45
|
endpoint="https://platform.cmpnd.ai", # optional, or CMPND_ENDPOINT
|
|
47
46
|
project_tags="my-project", # optional: one tag or a list of tags
|
|
48
|
-
program_id="p_0123456789Ab", # optional, or CMPND_PROGRAM_ID: the id `cmpnd programs create` prints
|
|
49
47
|
batch_size=100, # optional: spans per export batch
|
|
50
48
|
flush_interval_seconds=5.0, # optional: seconds between flushes
|
|
51
49
|
capture_inputs=True, # optional: record span inputs
|
|
@@ -60,24 +58,18 @@ captured input and output size limits, 65,536 bytes each by default.
|
|
|
60
58
|
|
|
61
59
|
## Deployment
|
|
62
60
|
|
|
63
|
-
Every deployment belongs to a program, and
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
cmpnd programs create --name qa
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Then deploy a DSPy module under that program for server-side execution:
|
|
61
|
+
Every deployment belongs to a program, and each program has a program name.
|
|
62
|
+
Give a DSPy module a program name with `cmpnd.Program`, then deploy it for
|
|
63
|
+
server-side execution:
|
|
71
64
|
|
|
72
65
|
```python
|
|
73
66
|
import cmpnd
|
|
74
67
|
import dspy
|
|
75
68
|
|
|
76
|
-
cmpnd.configure(api_key="ck_xxx"
|
|
77
|
-
dspy.configure(lm=dspy.LM("openai/gpt-6-luna"))
|
|
69
|
+
cmpnd.configure(api_key="ck_xxx")
|
|
78
70
|
|
|
79
|
-
|
|
80
|
-
deployed = cmpnd.deploy(
|
|
71
|
+
qa = cmpnd.Program("qa", module=dspy.Predict("question -> answer"), lm=dspy.LM("openai/gpt-6-luna"))
|
|
72
|
+
deployed = cmpnd.deploy(qa)
|
|
81
73
|
|
|
82
74
|
result = deployed(question="What is DSPy?") # runs server-side
|
|
83
75
|
print(result.answer)
|
|
@@ -92,26 +84,26 @@ when the platform has inspected it. An unknown interface leaves `input_fields`
|
|
|
92
84
|
and `output_fields` as `None`. A known interface with no fields returns empty
|
|
93
85
|
lists.
|
|
94
86
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
87
|
+
The platform makes the program the first time your organization uses the
|
|
88
|
+
program name. Later deploys under the same program name go to the same
|
|
89
|
+
program. `@cmpnd.program("qa")` above a `dspy.Module`
|
|
90
|
+
class declares the same program name. [`docs/client.md`](docs/client.md)
|
|
91
|
+
describes both forms.
|
|
98
92
|
|
|
99
|
-
To deploy a source file, run `cmpnd deploy program.py
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
covers the CLI.
|
|
93
|
+
To deploy a source file, run `cmpnd deploy program.py qa`. The CLI uploads
|
|
94
|
+
the file's exact bytes and does not reconstruct the source from a live object.
|
|
95
|
+
Use `--source-root` and repeated `--include` flags for sibling modules or
|
|
96
|
+
data, and `cmpnd inspect <id> --source` to read the deployed entry file back.
|
|
97
|
+
[`docs/cli.md`](docs/cli.md) covers the CLI.
|
|
105
98
|
|
|
106
99
|
### Options
|
|
107
100
|
|
|
108
101
|
```python
|
|
109
102
|
cmpnd.deploy(
|
|
110
|
-
|
|
103
|
+
program, # required: a cmpnd.Program
|
|
111
104
|
metric=None, # optional: a metric callable, packaged for optimization
|
|
112
105
|
timeout=300, # optional: seconds to wait for the parser after the upload
|
|
113
106
|
metadata=None, # optional: a JSON-serializable dict, at most 64 KiB, stored with the deployment
|
|
114
|
-
program_id="p_…", # the program the deployment belongs to; serve requires it after self-host 2026-001
|
|
115
107
|
)
|
|
116
108
|
```
|
|
117
109
|
|
|
@@ -139,10 +131,9 @@ it returns a `DeployedProgram` that you call directly, and the program's
|
|
|
139
131
|
import cmpnd
|
|
140
132
|
import dspy
|
|
141
133
|
|
|
142
|
-
cmpnd.configure(api_key="ck_xxx"
|
|
143
|
-
dspy.configure(lm=dspy.LM("openai/gpt-6-luna"))
|
|
134
|
+
cmpnd.configure(api_key="ck_xxx")
|
|
144
135
|
|
|
145
|
-
program = dspy.ChainOfThought("topic -> haiku")
|
|
136
|
+
program = cmpnd.Program("haiku", module=dspy.ChainOfThought("topic -> haiku"), lm=dspy.LM("openai/gpt-6-luna"))
|
|
146
137
|
|
|
147
138
|
# GEPA needs a five-argument feedback metric that returns dspy.Prediction(score=, feedback=)
|
|
148
139
|
def metric(example, pred, trace=None, pred_name=None, pred_trace=None):
|
|
@@ -276,13 +267,13 @@ raises `cmpnd.OptimizeFailed` when a step reaches `failed`.
|
|
|
276
267
|
### From the CLI
|
|
277
268
|
|
|
278
269
|
```bash
|
|
279
|
-
cmpnd optimize gepa task.py
|
|
270
|
+
cmpnd optimize gepa task.py haiku --reflection-model openai/gpt-6-luna --auto light
|
|
280
271
|
```
|
|
281
272
|
|
|
282
273
|
The file, or `-` for stdin, binds `program`, `trainset`, `valset` and
|
|
283
274
|
`metric`. The CLI prints the best deployment ID. The CLI deploys the file's
|
|
284
|
-
program first
|
|
285
|
-
|
|
275
|
+
program first under the program name, here `haiku`. With `--deployment-id`,
|
|
276
|
+
the CLI starts from that deployment and needs no program name.
|
|
286
277
|
|
|
287
278
|
## Custom spans
|
|
288
279
|
|
|
@@ -352,8 +343,8 @@ dspy.configure(callbacks=[cmpnd.CmpndCallback()])
|
|
|
352
343
|
|
|
353
344
|
### `cmpnd.deploy()`
|
|
354
345
|
|
|
355
|
-
Deploys a
|
|
356
|
-
`DeployedProgram`.
|
|
346
|
+
Deploys a `cmpnd.Program` under its program name and returns a callable
|
|
347
|
+
`DeployedProgram`.
|
|
357
348
|
|
|
358
349
|
### `cmpnd.optimize()`
|
|
359
350
|
|
|
@@ -651,6 +651,15 @@ class _CallbackBase:
|
|
|
651
651
|
self._last_eval_trace_ids.clear()
|
|
652
652
|
self._unclaimed_eval_trace_ids.clear()
|
|
653
653
|
|
|
654
|
+
@property
|
|
655
|
+
def traces_globally(self) -> bool:
|
|
656
|
+
"""Whether this is the ``auto_instrument()`` callback, which reads the global config.
|
|
657
|
+
|
|
658
|
+
A client's callback has its own config. The global callback records sketch
|
|
659
|
+
mode, which declares no program names.
|
|
660
|
+
"""
|
|
661
|
+
return self._own_config is None
|
|
662
|
+
|
|
654
663
|
def _resolve_project_tags(self) -> list[str] | None:
|
|
655
664
|
"""The project tags this callback stamps on the builders it creates.
|
|
656
665
|
|
|
@@ -61,8 +61,7 @@ class _LazyVersionAction(argparse.Action):
|
|
|
61
61
|
_EPILOG = """\
|
|
62
62
|
deploy-flow workflow (Docker-style; the path an agent should reach for first):
|
|
63
63
|
|
|
64
|
-
cmpnd
|
|
65
|
-
cmpnd deploy program.py --program-id p_… --run '{"question": "..."}' # deploy + smoke test
|
|
64
|
+
cmpnd deploy program.py qa --run '{"question": "..."}' # deploy program name qa + smoke test
|
|
66
65
|
cmpnd ps # list deployments
|
|
67
66
|
cmpnd status <id> -f # wait for terminal state
|
|
68
67
|
cmpnd run <id> '{"...": "..."}' # invoke a ready deployment
|
|
@@ -88,6 +87,24 @@ Auth: set CMPND_API_KEY and (optionally) CMPND_ENDPOINT, or pass --api-key /
|
|
|
88
87
|
"""
|
|
89
88
|
|
|
90
89
|
|
|
90
|
+
def parse(parser: argparse.ArgumentParser, argv: list[str]) -> argparse.Namespace:
|
|
91
|
+
"""Parse ``argv``, and give a late positional the one word argparse could not place.
|
|
92
|
+
|
|
93
|
+
argparse fills optional positionals from the first run of bare words, so in
|
|
94
|
+
``cmpnd deploy program.py --entrypoint qa capital-qa`` the program name comes too
|
|
95
|
+
late and is left over. A command that sets ``_late_positional`` takes one such
|
|
96
|
+
word into that argument when it is still empty. Anything else left over is the
|
|
97
|
+
usual usage error.
|
|
98
|
+
"""
|
|
99
|
+
args, extras = parser.parse_known_args(argv)
|
|
100
|
+
late = getattr(args, "_late_positional", None)
|
|
101
|
+
if late and len(extras) == 1 and not extras[0].startswith("-") and getattr(args, late) is None:
|
|
102
|
+
setattr(args, late, extras.pop())
|
|
103
|
+
if extras:
|
|
104
|
+
parser.error("unrecognized arguments: " + " ".join(extras))
|
|
105
|
+
return args
|
|
106
|
+
|
|
107
|
+
|
|
91
108
|
def main() -> None:
|
|
92
109
|
parser = tree_help.TreeHelpParser(
|
|
93
110
|
prog="cmpnd",
|
|
@@ -165,7 +182,7 @@ def main() -> None:
|
|
|
165
182
|
# Top-level Docker-style shortcuts (human-readable by default; --json opts in)
|
|
166
183
|
top.register(subparsers)
|
|
167
184
|
|
|
168
|
-
args = parser.
|
|
185
|
+
args = parse(parser, sys.argv[1:])
|
|
169
186
|
|
|
170
187
|
if not args.resource:
|
|
171
188
|
# Bare `cmpnd` drops into an interactive Python shell with platform
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import argparse
|
|
5
6
|
import sys
|
|
6
7
|
from argparse import ArgumentParser, _SubParsersAction
|
|
7
8
|
from typing import Any
|
|
@@ -21,15 +22,25 @@ def register(subparsers: _SubParsersAction[ArgumentParser]) -> None:
|
|
|
21
22
|
|
|
22
23
|
create = sub.add_parser(
|
|
23
24
|
"create",
|
|
24
|
-
help="Create a program
|
|
25
|
+
help="Create a program with a name",
|
|
25
26
|
description=(
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
27
|
+
"Create a program with PROGRAM_NAME in your organization. A program name that already "
|
|
28
|
+
"has a program is refused. A deploy makes the program the first time it uses the program "
|
|
29
|
+
"name, so this command is needed only to make the program first. Deploy under the program "
|
|
30
|
+
"name with `cmpnd deploy SOURCE PROGRAM_NAME`, and declare it in Python with "
|
|
31
|
+
"cmpnd.Program(PROGRAM_NAME, module=..., lm=...)."
|
|
30
32
|
),
|
|
31
33
|
)
|
|
32
|
-
create.add_argument(
|
|
34
|
+
create.add_argument(
|
|
35
|
+
"name", nargs="?", default=None, metavar="PROGRAM_NAME", help="Program name, unique in your organization"
|
|
36
|
+
)
|
|
37
|
+
# Deprecated program id input: --name, the display name of an unnamed program, goes when it is removed.
|
|
38
|
+
create.add_argument(
|
|
39
|
+
"--name",
|
|
40
|
+
dest="display_name",
|
|
41
|
+
default=None,
|
|
42
|
+
help=argparse.SUPPRESS,
|
|
43
|
+
)
|
|
33
44
|
create.add_argument("--json", action="store_true", help="Emit the created program as JSON instead of its id")
|
|
34
45
|
create.set_defaults(func=handle_create)
|
|
35
46
|
|
|
@@ -87,12 +98,20 @@ def register(subparsers: _SubParsersAction[ArgumentParser]) -> None:
|
|
|
87
98
|
|
|
88
99
|
|
|
89
100
|
def handle_create(client: api_client.ApiClient, args: Any) -> Any:
|
|
90
|
-
"""Create a program. Prints the bare id on stdout
|
|
91
|
-
|
|
92
|
-
|
|
101
|
+
"""Create a program. Prints the bare id on stdout and says what it made on stderr;
|
|
102
|
+
``--json`` returns serve's whole answer instead, printed like the group's reads.
|
|
103
|
+
|
|
104
|
+
The form without a program name, with or without ``--name``, makes an unnamed
|
|
105
|
+
program. It is deprecated, and warns."""
|
|
93
106
|
from ... import programs
|
|
94
107
|
|
|
95
|
-
|
|
108
|
+
if args.name is not None:
|
|
109
|
+
return _create_named(client, args)
|
|
110
|
+
# Deprecated program id input: a create without a program name, and this warning, go when it is removed.
|
|
111
|
+
from . import top
|
|
112
|
+
|
|
113
|
+
top.warn_program_id_input("`cmpnd programs create` without a program name", top.hint_programs_create())
|
|
114
|
+
row = programs.send_create(client, name=args.display_name)
|
|
96
115
|
if getattr(args, "json", False):
|
|
97
116
|
return row
|
|
98
117
|
print(row["id"])
|
|
@@ -101,6 +120,36 @@ def handle_create(client: api_client.ApiClient, args: Any) -> Any:
|
|
|
101
120
|
return None
|
|
102
121
|
|
|
103
122
|
|
|
123
|
+
def _create_named(client: api_client.ApiClient, args: Any) -> Any:
|
|
124
|
+
"""Create the program named ``args.name``, and refuse a name that already has one."""
|
|
125
|
+
from ... import programs
|
|
126
|
+
from . import top
|
|
127
|
+
|
|
128
|
+
if args.display_name is not None:
|
|
129
|
+
raise api_client.CliError("give a program name or --name, not both: --name is the older display name")
|
|
130
|
+
try:
|
|
131
|
+
answer = programs.send_resolve(client, args.name)
|
|
132
|
+
except ValueError as exc:
|
|
133
|
+
raise api_client.CliError(str(exc)) from exc
|
|
134
|
+
if answer is None:
|
|
135
|
+
raise api_client.CliError(
|
|
136
|
+
"This server has no program names, so it cannot create a program from a program name. A serve from "
|
|
137
|
+
"before program names, such as self-host release 2026-001, needs no program first: "
|
|
138
|
+
f"`{top._hint_program_name('deploy', source='SOURCE', name='PROGRAM_NAME')}` deploys there without "
|
|
139
|
+
"a program id."
|
|
140
|
+
)
|
|
141
|
+
if not answer.get("created"):
|
|
142
|
+
raise api_client.CliError(
|
|
143
|
+
f"the program name {args.name!r} already has a program, {answer['program_id']}. "
|
|
144
|
+
f"Deploy under it with `{top._hint_program_name('deploy', source='SOURCE', name=args.name)}`."
|
|
145
|
+
)
|
|
146
|
+
if getattr(args, "json", False):
|
|
147
|
+
return answer
|
|
148
|
+
print(answer["program_id"])
|
|
149
|
+
print(f"created program {answer['program_id']} named {args.name}", file=sys.stderr)
|
|
150
|
+
return None
|
|
151
|
+
|
|
152
|
+
|
|
104
153
|
def handle_list(client: api_client.ApiClient, args: Any) -> Any:
|
|
105
154
|
params: dict[str, str] = pagination.wire(args, "per_page", as_str=True)
|
|
106
155
|
params["order_by"] = args.order_by
|