#
tokens: 49472/50000 159/391 files (page 1/17)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 1 of 17. Use http://codebase.md/stanfordnlp/dspy?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .github
│   ├── .internal_dspyai
│   │   ├── internals
│   │   │   ├── build-and-release.md
│   │   │   └── release-checklist.md
│   │   └── pyproject.toml
│   ├── .tmp
│   │   └── .generated-actions
│   │       └── run-pypi-publish-in-docker-container
│   │           └── action.yml
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.yml
│   │   └── feature_request.yml
│   ├── PULL_REQUEST_TEMPLATE
│   │   └── pull_request_template.md
│   ├── workflow_scripts
│   │   └── install_testpypi_pkg.sh
│   └── workflows
│       ├── build_and_release.yml
│       ├── build_utils
│       │   └── test_version.py
│       ├── docs-push.yml
│       ├── precommits_check.yml
│       └── run_tests.yml
├── .gitignore
├── .pre-commit-config.yaml
├── CONTRIBUTING.md
├── docs
│   ├── .gitignore
│   ├── docs
│   │   ├── api
│   │   │   ├── adapters
│   │   │   │   ├── Adapter.md
│   │   │   │   ├── ChatAdapter.md
│   │   │   │   ├── JSONAdapter.md
│   │   │   │   └── TwoStepAdapter.md
│   │   │   ├── evaluation
│   │   │   │   ├── answer_exact_match.md
│   │   │   │   ├── answer_passage_match.md
│   │   │   │   ├── CompleteAndGrounded.md
│   │   │   │   ├── Evaluate.md
│   │   │   │   ├── EvaluationResult.md
│   │   │   │   └── SemanticF1.md
│   │   │   ├── experimental
│   │   │   │   ├── Citations.md
│   │   │   │   └── Document.md
│   │   │   ├── index.md
│   │   │   ├── models
│   │   │   │   ├── Embedder.md
│   │   │   │   └── LM.md
│   │   │   ├── modules
│   │   │   │   ├── BestOfN.md
│   │   │   │   ├── ChainOfThought.md
│   │   │   │   ├── CodeAct.md
│   │   │   │   ├── Module.md
│   │   │   │   ├── MultiChainComparison.md
│   │   │   │   ├── Parallel.md
│   │   │   │   ├── Predict.md
│   │   │   │   ├── ProgramOfThought.md
│   │   │   │   ├── ReAct.md
│   │   │   │   └── Refine.md
│   │   │   ├── optimizers
│   │   │   │   ├── BetterTogether.md
│   │   │   │   ├── BootstrapFewShot.md
│   │   │   │   ├── BootstrapFewShotWithRandomSearch.md
│   │   │   │   ├── BootstrapFinetune.md
│   │   │   │   ├── BootstrapRS.md
│   │   │   │   ├── COPRO.md
│   │   │   │   ├── Ensemble.md
│   │   │   │   ├── GEPA
│   │   │   │   │   ├── GEPA_Advanced.md
│   │   │   │   │   └── overview.md
│   │   │   │   ├── InferRules.md
│   │   │   │   ├── KNN.md
│   │   │   │   ├── KNNFewShot.md
│   │   │   │   ├── LabeledFewShot.md
│   │   │   │   ├── MIPROv2.md
│   │   │   │   └── SIMBA.md
│   │   │   ├── primitives
│   │   │   │   ├── Audio.md
│   │   │   │   ├── Code.md
│   │   │   │   ├── Example.md
│   │   │   │   ├── History.md
│   │   │   │   ├── Image.md
│   │   │   │   ├── Prediction.md
│   │   │   │   ├── Tool.md
│   │   │   │   └── ToolCalls.md
│   │   │   ├── signatures
│   │   │   │   ├── InputField.md
│   │   │   │   ├── OutputField.md
│   │   │   │   └── Signature.md
│   │   │   ├── tools
│   │   │   │   ├── ColBERTv2.md
│   │   │   │   ├── Embeddings.md
│   │   │   │   └── PythonInterpreter.md
│   │   │   └── utils
│   │   │       ├── asyncify.md
│   │   │       ├── configure_cache.md
│   │   │       ├── disable_litellm_logging.md
│   │   │       ├── disable_logging.md
│   │   │       ├── enable_litellm_logging.md
│   │   │       ├── enable_logging.md
│   │   │       ├── inspect_history.md
│   │   │       ├── load.md
│   │   │       ├── StatusMessage.md
│   │   │       ├── StatusMessageProvider.md
│   │   │       ├── streamify.md
│   │   │       └── StreamListener.md
│   │   ├── cheatsheet.md
│   │   ├── community
│   │   │   ├── community-resources.md
│   │   │   ├── how-to-contribute.md
│   │   │   └── use-cases.md
│   │   ├── deep-dive
│   │   │   └── data-handling
│   │   │       ├── built-in-datasets.md
│   │   │       ├── examples.md
│   │   │       ├── img
│   │   │       │   └── data-loading.png
│   │   │       └── loading-custom-data.md
│   │   ├── faqs.md
│   │   ├── index.md
│   │   ├── js
│   │   │   └── runllm-widget.js
│   │   ├── learn
│   │   │   ├── evaluation
│   │   │   │   ├── data.md
│   │   │   │   ├── metrics.md
│   │   │   │   └── overview.md
│   │   │   ├── figures
│   │   │   │   ├── native_tool_call.png
│   │   │   │   └── teleprompter-classes.png
│   │   │   ├── index.md
│   │   │   ├── optimization
│   │   │   │   ├── optimizers.md
│   │   │   │   └── overview.md
│   │   │   └── programming
│   │   │       ├── 7-assertions.md
│   │   │       ├── adapters.md
│   │   │       ├── language_models.md
│   │   │       ├── mcp.md
│   │   │       ├── modules.md
│   │   │       ├── overview.md
│   │   │       ├── signatures.md
│   │   │       └── tools.md
│   │   ├── production
│   │   │   └── index.md
│   │   ├── roadmap.md
│   │   ├── static
│   │   │   ├── .nojekyll
│   │   │   └── img
│   │   │       ├── dspy_logo.png
│   │   │       ├── logo.png
│   │   │       ├── mlflow-tracing-rag.png
│   │   │       ├── modular.png
│   │   │       ├── optimize.png
│   │   │       ├── undraw_docusaurus_mountain.svg
│   │   │       ├── undraw_docusaurus_react.svg
│   │   │       ├── undraw_docusaurus_tree.svg
│   │   │       └── universal_compatibility.png
│   │   ├── stylesheets
│   │   │   └── extra.css
│   │   └── tutorials
│   │       ├── agents
│   │       │   ├── index.ipynb
│   │       │   └── mlflow-tracing-agent.png
│   │       ├── ai_text_game
│   │       │   └── index.md
│   │       ├── async
│   │       │   └── index.md
│   │       ├── audio
│   │       │   └── index.ipynb
│   │       ├── build_ai_program
│   │       │   └── index.md
│   │       ├── cache
│   │       │   └── index.md
│   │       ├── classification
│   │       │   └── index.md
│   │       ├── classification_finetuning
│   │       │   ├── index.ipynb
│   │       │   └── mlflow-tracing-classification.png
│   │       ├── conversation_history
│   │       │   └── index.md
│   │       ├── core_development
│   │       │   └── index.md
│   │       ├── custom_module
│   │       │   ├── index.ipynb
│   │       │   └── mlflow-tracing-custom-module.png
│   │       ├── customer_service_agent
│   │       │   ├── index.ipynb
│   │       │   └── mlflow-tracing-customer-service-agent.png
│   │       ├── deployment
│   │       │   ├── dspy_mlflow_ui.png
│   │       │   └── index.md
│   │       ├── email_extraction
│   │       │   ├── index.md
│   │       │   └── mlflow-tracing-email-extraction.png
│   │       ├── entity_extraction
│   │       │   ├── index.ipynb
│   │       │   └── mlflow-tracing-entity-extraction.png
│   │       ├── games
│   │       │   ├── index.ipynb
│   │       │   └── mlflow-tracing-agent.png
│   │       ├── gepa_ai_program
│   │       │   └── index.md
│   │       ├── gepa_aime
│   │       │   ├── index.ipynb
│   │       │   ├── mlflow-tracing-gepa-aime.png
│   │       │   └── mlflow-tracking-gepa-aime-optimization.png
│   │       ├── gepa_facilitysupportanalyzer
│   │       │   ├── index.ipynb
│   │       │   ├── mlflow-tracing-gepa-support.png
│   │       │   └── mlflow-tracking-gepa-support-optimization.png
│   │       ├── gepa_papillon
│   │       │   ├── index.ipynb
│   │       │   ├── mlflow-tracing-gepa-papilon.png
│   │       │   └── mlflow-tracking-gepa-papilon-optimization.png
│   │       ├── image_generation_prompting
│   │       │   └── index.ipynb
│   │       ├── index.md
│   │       ├── llms_txt_generation
│   │       │   └── index.md
│   │       ├── math
│   │       │   ├── index.ipynb
│   │       │   └── mlflow-tracing-math.png
│   │       ├── mcp
│   │       │   └── index.md
│   │       ├── mem0_react_agent
│   │       │   └── index.md
│   │       ├── multihop_search
│   │       │   ├── index.ipynb
│   │       │   └── mlflow-tracing-multi-hop.png
│   │       ├── observability
│   │       │   ├── index.md
│   │       │   ├── mlflow_trace_ui_navigation.gif
│   │       │   ├── mlflow_trace_ui.png
│   │       │   └── mlflow_trace_view.png
│   │       ├── optimize_ai_program
│   │       │   └── index.md
│   │       ├── optimizer_tracking
│   │       │   ├── child_run.png
│   │       │   ├── experiment.png
│   │       │   ├── index.md
│   │       │   └── parent_run.png
│   │       ├── output_refinement
│   │       │   └── best-of-n-and-refine.md
│   │       ├── papillon
│   │       │   └── index.md
│   │       ├── program_of_thought
│   │       │   └── index.ipynb
│   │       ├── rag
│   │       │   ├── index.ipynb
│   │       │   └── mlflow-tracing-rag.png
│   │       ├── real_world_examples
│   │       │   └── index.md
│   │       ├── rl_ai_program
│   │       │   └── index.md
│   │       ├── rl_multihop
│   │       │   └── index.ipynb
│   │       ├── rl_papillon
│   │       │   └── index.ipynb
│   │       ├── sample_code_generation
│   │       │   └── index.md
│   │       ├── saving
│   │       │   └── index.md
│   │       ├── streaming
│   │       │   └── index.md
│   │       ├── tool_use
│   │       │   └── index.ipynb
│   │       └── yahoo_finance_react
│   │           └── index.md
│   ├── mkdocs.yml
│   ├── overrides
│   │   ├── home.html
│   │   ├── main.html
│   │   └── partials
│   │       └── tabs.html
│   ├── Pipfile
│   ├── Pipfile.lock
│   ├── README.md
│   ├── requirements.txt
│   ├── scripts
│   │   ├── generate_api_docs.py
│   │   └── generate_api_summary.py
│   └── vercel.json
├── dspy
│   ├── __init__.py
│   ├── __metadata__.py
│   ├── adapters
│   │   ├── __init__.py
│   │   ├── baml_adapter.py
│   │   ├── base.py
│   │   ├── chat_adapter.py
│   │   ├── json_adapter.py
│   │   ├── two_step_adapter.py
│   │   ├── types
│   │   │   ├── __init__.py
│   │   │   ├── audio.py
│   │   │   ├── base_type.py
│   │   │   ├── citation.py
│   │   │   ├── code.py
│   │   │   ├── document.py
│   │   │   ├── history.py
│   │   │   ├── image.py
│   │   │   └── tool.py
│   │   ├── utils.py
│   │   └── xml_adapter.py
│   ├── clients
│   │   ├── __init__.py
│   │   ├── base_lm.py
│   │   ├── cache.py
│   │   ├── databricks.py
│   │   ├── embedding.py
│   │   ├── lm_local_arbor.py
│   │   ├── lm_local.py
│   │   ├── lm.py
│   │   ├── openai.py
│   │   ├── provider.py
│   │   └── utils_finetune.py
│   ├── datasets
│   │   ├── __init__.py
│   │   ├── alfworld
│   │   │   ├── __init__.py
│   │   │   ├── alfworld.py
│   │   │   └── base_config.yml
│   │   ├── colors.py
│   │   ├── dataloader.py
│   │   ├── dataset.py
│   │   ├── gsm8k.py
│   │   ├── hotpotqa.py
│   │   └── math.py
│   ├── dsp
│   │   ├── __init__.py
│   │   ├── colbertv2.py
│   │   └── utils
│   │       ├── __init__.py
│   │       ├── dpr.py
│   │       ├── settings.py
│   │       └── utils.py
│   ├── evaluate
│   │   ├── __init__.py
│   │   ├── auto_evaluation.py
│   │   ├── evaluate.py
│   │   └── metrics.py
│   ├── experimental
│   │   └── __init__.py
│   ├── predict
│   │   ├── __init__.py
│   │   ├── aggregation.py
│   │   ├── avatar
│   │   │   ├── __init__.py
│   │   │   ├── avatar.py
│   │   │   ├── models.py
│   │   │   └── signatures.py
│   │   ├── best_of_n.py
│   │   ├── chain_of_thought.py
│   │   ├── code_act.py
│   │   ├── knn.py
│   │   ├── multi_chain_comparison.py
│   │   ├── parallel.py
│   │   ├── parameter.py
│   │   ├── predict.py
│   │   ├── program_of_thought.py
│   │   ├── react.py
│   │   ├── refine.py
│   │   └── retry.py
│   ├── primitives
│   │   ├── __init__.py
│   │   ├── base_module.py
│   │   ├── example.py
│   │   ├── module.py
│   │   ├── prediction.py
│   │   ├── python_interpreter.py
│   │   └── runner.js
│   ├── propose
│   │   ├── __init__.py
│   │   ├── dataset_summary_generator.py
│   │   ├── grounded_proposer.py
│   │   ├── propose_base.py
│   │   └── utils.py
│   ├── retrievers
│   │   ├── __init__.py
│   │   ├── databricks_rm.py
│   │   ├── embeddings.py
│   │   ├── retrieve.py
│   │   └── weaviate_rm.py
│   ├── signatures
│   │   ├── __init__.py
│   │   ├── field.py
│   │   ├── signature.py
│   │   └── utils.py
│   ├── streaming
│   │   ├── __init__.py
│   │   ├── messages.py
│   │   ├── streamify.py
│   │   └── streaming_listener.py
│   ├── teleprompt
│   │   ├── __init__.py
│   │   ├── avatar_optimizer.py
│   │   ├── bettertogether.py
│   │   ├── bootstrap_finetune.py
│   │   ├── bootstrap_trace.py
│   │   ├── bootstrap.py
│   │   ├── copro_optimizer.py
│   │   ├── ensemble.py
│   │   ├── gepa
│   │   │   ├── __init__.py
│   │   │   ├── gepa_utils.py
│   │   │   ├── gepa.py
│   │   │   └── instruction_proposal.py
│   │   ├── grpo.py
│   │   ├── infer_rules.py
│   │   ├── knn_fewshot.py
│   │   ├── mipro_optimizer_v2.py
│   │   ├── random_search.py
│   │   ├── signature_opt.py
│   │   ├── simba_utils.py
│   │   ├── simba.py
│   │   ├── teleprompt_optuna.py
│   │   ├── teleprompt.py
│   │   ├── utils.py
│   │   └── vanilla.py
│   └── utils
│       ├── __init__.py
│       ├── annotation.py
│       ├── asyncify.py
│       ├── caching.py
│       ├── callback.py
│       ├── dummies.py
│       ├── exceptions.py
│       ├── hasher.py
│       ├── inspect_history.py
│       ├── langchain_tool.py
│       ├── logging_utils.py
│       ├── mcp.py
│       ├── parallelizer.py
│       ├── saving.py
│       ├── syncify.py
│       ├── unbatchify.py
│       └── usage_tracker.py
├── LICENSE
├── pyproject.toml
├── README.md
├── tests
│   ├── __init__.py
│   ├── adapters
│   │   ├── test_adapter_utils.py
│   │   ├── test_baml_adapter.py
│   │   ├── test_base_type.py
│   │   ├── test_chat_adapter.py
│   │   ├── test_citation.py
│   │   ├── test_code.py
│   │   ├── test_document.py
│   │   ├── test_json_adapter.py
│   │   ├── test_tool.py
│   │   ├── test_two_step_adapter.py
│   │   └── test_xml_adapter.py
│   ├── callback
│   │   └── test_callback.py
│   ├── clients
│   │   ├── test_cache.py
│   │   ├── test_databricks.py
│   │   ├── test_embedding.py
│   │   ├── test_inspect_global_history.py
│   │   └── test_lm.py
│   ├── conftest.py
│   ├── datasets
│   │   └── test_dataset.py
│   ├── docs
│   │   └── test_mkdocs_links.py
│   ├── evaluate
│   │   ├── test_evaluate.py
│   │   └── test_metrics.py
│   ├── examples
│   │   └── test_baleen.py
│   ├── metadata
│   │   └── test_metadata.py
│   ├── predict
│   │   ├── test_aggregation.py
│   │   ├── test_best_of_n.py
│   │   ├── test_chain_of_thought.py
│   │   ├── test_code_act.py
│   │   ├── test_knn.py
│   │   ├── test_multi_chain_comparison.py
│   │   ├── test_parallel.py
│   │   ├── test_predict.py
│   │   ├── test_program_of_thought.py
│   │   ├── test_react.py
│   │   ├── test_refine.py
│   │   └── test_retry.py
│   ├── primitives
│   │   ├── resources
│   │   │   └── saved_program.json
│   │   ├── test_base_module.py
│   │   ├── test_example.py
│   │   ├── test_module.py
│   │   └── test_python_interpreter.py
│   ├── propose
│   │   └── test_grounded_proposer.py
│   ├── README.md
│   ├── reliability
│   │   ├── __init__.py
│   │   ├── complex_types
│   │   │   └── generated
│   │   │       ├── test_many_types_1
│   │   │       │   ├── inputs
│   │   │       │   │   ├── input1.json
│   │   │       │   │   └── input2.json
│   │   │       │   ├── program.py
│   │   │       │   └── schema.json
│   │   │       ├── test_nesting_1
│   │   │       │   ├── inputs
│   │   │       │   │   ├── input1.json
│   │   │       │   │   └── input2.json
│   │   │       │   ├── program.py
│   │   │       │   └── schema.json
│   │   │       └── test_nesting_2
│   │   │           ├── inputs
│   │   │           │   └── input1.json
│   │   │           ├── program.py
│   │   │           └── schema.json
│   │   ├── conftest.py
│   │   ├── generate
│   │   │   ├── __init__.py
│   │   │   ├── __main__.py
│   │   │   └── utils.py
│   │   ├── input_formats
│   │   │   └── generated
│   │   │       └── test_markdown_1
│   │   │           ├── inputs
│   │   │           │   ├── input1.json
│   │   │           │   └── input2.json
│   │   │           ├── program.py
│   │   │           └── schema.json
│   │   ├── README.md
│   │   ├── reliability_conf.yaml
│   │   ├── test_generated.py
│   │   ├── test_pydantic_models.py
│   │   └── utils.py
│   ├── retrievers
│   │   └── test_embeddings.py
│   ├── signatures
│   │   ├── test_adapter_image.py
│   │   ├── test_custom_types.py
│   │   └── test_signature.py
│   ├── streaming
│   │   └── test_streaming.py
│   ├── teleprompt
│   │   ├── gepa_dummy_lm_custom_component_selector_custom_instruction_proposer.json
│   │   ├── gepa_dummy_lm.json
│   │   ├── test_bootstrap_finetune.py
│   │   ├── test_bootstrap_trace.py
│   │   ├── test_bootstrap.py
│   │   ├── test_copro_optimizer.py
│   │   ├── test_ensemble.py
│   │   ├── test_finetune.py
│   │   ├── test_gepa_instruction_proposer.py
│   │   ├── test_gepa.py
│   │   ├── test_grpo.py
│   │   ├── test_knn_fewshot.py
│   │   ├── test_random_search.py
│   │   ├── test_teleprompt.py
│   │   └── test_utils.py
│   ├── test_utils
│   │   ├── __init__.py
│   │   └── server
│   │       ├── __init__.py
│   │       ├── litellm_server_config.yaml
│   │       └── litellm_server.py
│   └── utils
│       ├── __init__.py
│       ├── resources
│       │   └── mcp_server.py
│       ├── test_annotation.py
│       ├── test_asyncify.py
│       ├── test_exceptions.py
│       ├── test_langchain_tool.py
│       ├── test_mcp.py
│       ├── test_parallelizer.py
│       ├── test_saving.py
│       ├── test_settings.py
│       ├── test_syncify.py
│       ├── test_unbatchify.py
│       └── test_usage_tracker.py
└── uv.lock
```

# Files

--------------------------------------------------------------------------------
/docs/docs/static/.nojekyll:
--------------------------------------------------------------------------------

```
1 | 
```

--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------

```
1 | site
2 | .cache
```

--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | default_language_version:
 2 |   python: python3.10
 3 | 
 4 | default_stages: [pre-commit]
 5 | default_install_hook_types: [pre-commit]
 6 | 
 7 | repos:
 8 |   - repo: local
 9 |     hooks:
10 |       - id: ruff-check
11 |         name: ruff (lint)
12 |         entry: ruff
13 |         language: system
14 |         types_or: [python, pyi]
15 |         files: ^(dspy|tests)/.*\.py$
16 |         exclude: ^(dspy/__metadata__\.py|tests/reliability/.*\.py)$
17 |         args: [check, --fix-only]
18 | 
19 |   - repo: https://github.com/pre-commit/pre-commit-hooks
20 |     rev: v5.0.0
21 |     hooks:
22 |       - id: check-yaml
23 |         args: ["--allow-multiple-documents", "--unsafe"]
24 |       - id: check-toml
25 |       - id: check-added-large-files
26 |         args: ["--maxkb=1024"]
27 |       - id: check-merge-conflict
28 |       - id: debug-statements
29 | 
```

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
 1 | /experiments/
 2 | /checkpoints/
 3 | # /data/
 4 | /logs/
 5 | /mlruns/
 6 | /profiler/
 7 | /logs/
 8 | /docs/downloads/
 9 | /docs/experiments/
10 | 
11 | /examples/qa/hotpot/MIPRO_notebook_cache/
12 | /examples/nli/scone/MIPRO_notebook_cache/
13 | /examples/nli/scone/ScoNe/
14 | /examples/nli/scone/compiled_program.dspy
15 | /examples/qa/hotpot/compiled_program.dspy
16 | /ScoNe/
17 | testing/outputs/
18 | testing/playbook.ipynb
19 | 
20 | # Byte-compiled / optimized / DLL files
21 | __pycache__/
22 | *.py[cod]
23 | *$py.class
24 | 
25 | # Vim
26 | *.swp
27 | 
28 | # Jupyter Notebook
29 | .ipynb_checkpoints
30 | # notebooks/
31 | 
32 | # mac
33 | .DS_Store
34 | 
35 | # Other
36 | .vscode
37 | *.tsv
38 | *.pt
39 | gpt*.txt
40 | *.env
41 | local/
42 | local_*
43 | build/
44 | *.egg-info/
45 | # *.jsonl
46 | # *.json
47 | !/data/*.json
48 | /dist/
49 | # **/*.pkl
50 | checklist.md
51 | finetuning_ckpts/
52 | # cache/
53 | * copy*
54 | .idea
55 | assertion.log
56 | *.log
57 | *.db
58 | /.devcontainer/.personalization.sh
59 | 
60 | .mypy_cache
61 | CLAUDE.local.md
62 | dummy.csv
63 | docs/docs/**/*.json*
64 | *.index
65 | *.pkl
66 | *.tar.gz
67 | 
68 | test_before_pypi/
69 | .github/.internal_dspyai/dist/
70 | 
```

--------------------------------------------------------------------------------
/tests/README.md:
--------------------------------------------------------------------------------

```markdown
1 | The tests in this directory are primarily concerned with code correctness and Adapter reliability.
2 | 
3 | If you're looking for testing the end-to-end quality of DSPy modules and optimizer, refer to [LangProBe](https://github.com/Shangyint/langProBe).
```

--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | **If you're looking to understand the framework, please go to the [DSPy Docs at dspy.ai](https://dspy.ai)**
 2 | 
 3 |  
 4 | 
 5 | --------
 6 | 
 7 |  
 8 | 
 9 | The content below is focused on how to modify the documentation site.
10 | 
11 |  
12 | 
13 | # Modifying the DSPy Documentation
14 | 
15 | 
16 | This website is built using [Material for MKDocs](https://squidfunk.github.io/mkdocs-material/), a Material UI inspired theme for MKDocs.
17 | 
18 | ## Building docs locally
19 | 
20 | To build and test the documentation locally:
21 | 
22 | 1. Navigate to the `docs` directory:
23 |    ```bash
24 |    cd docs
25 |    ```
26 | 
27 | 2. Install the necessary dependencies:
28 |    ```bash
29 |    pip install -r requirements.txt
30 |    ```
31 | 
32 | 3. In docs/ directory, run the command below to generate the API docs and index them:
33 |    ```bash
34 |    python scripts/generate_api_docs.py
35 |    python scripts/generate_api_summary.py
36 |    ```
37 | 
38 | 4. (Optional) On MacOS you may also need to install libraries for building the site
39 |    ```bash
40 |    brew install cairo freetype libffi libjpeg libpng zlib
41 |    export DYLD_FALLBACK_LIBRARY_PATH=/opt/homebrew/lib
42 |    ```
43 | 
44 | 5. Run the build command:
45 |    ```bash
46 |    mkdocs build
47 |    ```
48 | 
49 | This will generate a static build of the documentation site in the `site` directory. You can then serve this directory to view the site locally using:
50 | 
51 | ```bash
52 | mkdocs serve
53 | ```
54 | 
55 | If you see the build failing make sure to fix it before pushing.
56 | 
57 | ## Continuous Integration (CI) Build Checks
58 | 
59 | We have automated build checks set up in our CI pipeline to ensure the documentation builds successfully before merging changes. These checks:
60 | 
61 | 1. Run the `mkdocs build` command
62 | 2. Verify that the build completes without errors
63 | 3. Help catch potential issues early in the development process
64 | 
65 | If the CI build check fails, please review your changes and ensure the documentation builds correctly locally before pushing updates.
66 | 
67 | ## Contributing to the `docs` Folder
68 | 
69 | This guide is for contributors looking to make changes to the documentation in the `dspy/docs` folder. 
70 | 
71 | 1. **Pull the up-to-date version of the website**: Please pull the latest version of the live documentation site via cloning the dspy repo.  The current docs are in the `dspy/docs` folder.
72 | 
73 | 2. **Push your new changes on a new branch**: Feel free to add or edit existing documentation and open a PR for your changes. Once your PR is reviewed and approved, the changes will be ready to merge into main. 
74 | 
75 | 3. **Updating the website**: Once your changes are merged to main, the changes would be reflected on live websites usually in 5-15 mins.
76 | 
77 | ## LLMs.txt
78 | 
79 | The build process generates an `/llms.txt` file for LLM consumption using [mkdocs-llmstxt](https://github.com/pawamoy/mkdocs-llmstxt). Configure sections in `mkdocs.yml` under the `llmstxt` plugin.
80 | 
81 | 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | <p align="center">
 2 |   <img align="center" src="docs/docs/static/img/dspy_logo.png" width="460px" />
 3 | </p>
 4 | <p align="left">
 5 | 
 6 | 
 7 | ## DSPy: _Programming_—not prompting—Foundation Models
 8 | 
 9 | **Documentation:** [DSPy Docs](https://dspy.ai/)
10 | 
11 | [![PyPI Downloads](https://static.pepy.tech/badge/dspy/month)](https://pepy.tech/projects/dspy)
12 | 
13 | 
14 | ----
15 | 
16 | DSPy is the framework for _programming—rather than prompting—language models_. It allows you to iterate fast on **building modular AI systems** and offers algorithms for **optimizing their prompts and weights**, whether you're building simple classifiers, sophisticated RAG pipelines, or Agent loops.
17 | 
18 | DSPy stands for Declarative Self-improving Python. Instead of brittle prompts, you write compositional _Python code_ and use DSPy to **teach your LM to deliver high-quality outputs**. Learn more via our [official documentation site](https://dspy.ai/) or meet the community, seek help, or start contributing via this GitHub repo and our [Discord server](https://discord.gg/XCGy2WDCQB).
19 | 
20 | 
21 | ## Documentation: [dspy.ai](https://dspy.ai)
22 | 
23 | 
24 | **Please go to the [DSPy Docs at dspy.ai](https://dspy.ai)**
25 | 
26 | 
27 | ## Installation
28 | 
29 | 
30 | ```bash
31 | pip install dspy
32 | ```
33 | 
34 | To install the very latest from `main`:
35 | 
36 | ```bash
37 | pip install git+https://github.com/stanfordnlp/dspy.git
38 | ````
39 | 
40 | 
41 | 
42 | 
43 | ## 📜 Citation & Reading More
44 | 
45 | If you're looking to understand the framework, please go to the [DSPy Docs at dspy.ai](https://dspy.ai).
46 | 
47 | If you're looking to understand the underlying research, this is a set of our papers:
48 | 
49 | **[Jul'25] [GEPA: Reflective Prompt Evolution Can Outperform Reinforcement Learning](https://arxiv.org/abs/2507.19457)**       
50 | **[Jun'24] [Optimizing Instructions and Demonstrations for Multi-Stage Language Model Programs](https://arxiv.org/abs/2406.11695)**       
51 | **[Oct'23] [DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines](https://arxiv.org/abs/2310.03714)**     
52 | [Jul'24] [Fine-Tuning and Prompt Optimization: Two Great Steps that Work Better Together](https://arxiv.org/abs/2407.10930)     
53 | [Jun'24] [Prompts as Auto-Optimized Training Hyperparameters](https://arxiv.org/abs/2406.11706)    
54 | [Feb'24] [Assisting in Writing Wikipedia-like Articles From Scratch with Large Language Models](https://arxiv.org/abs/2402.14207)         
55 | [Jan'24] [In-Context Learning for Extreme Multi-Label Classification](https://arxiv.org/abs/2401.12178)       
56 | [Dec'23] [DSPy Assertions: Computational Constraints for Self-Refining Language Model Pipelines](https://arxiv.org/abs/2312.13382)   
57 | [Dec'22] [Demonstrate-Search-Predict: Composing Retrieval & Language Models for Knowledge-Intensive NLP](https://arxiv.org/abs/2212.14024.pdf)
58 | 
59 | To stay up to date or learn more, follow [@DSPyOSS](https://twitter.com/DSPyOSS) on Twitter or the DSPy page on LinkedIn.
60 | 
61 | The **DSPy** logo is designed by **Chuyi Zhang**.
62 | 
63 | If you use DSPy or DSP in a research paper, please cite our work as follows:
64 | 
65 | ```
66 | @inproceedings{khattab2024dspy,
67 |   title={DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines},
68 |   author={Khattab, Omar and Singhvi, Arnav and Maheshwari, Paridhi and Zhang, Zhiyuan and Santhanam, Keshav and Vardhamanan, Sri and Haq, Saiful and Sharma, Ashutosh and Joshi, Thomas T. and Moazam, Hanna and Miller, Heather and Zaharia, Matei and Potts, Christopher},
69 |   journal={The Twelfth International Conference on Learning Representations},
70 |   year={2024}
71 | }
72 | @article{khattab2022demonstrate,
73 |   title={Demonstrate-Search-Predict: Composing Retrieval and Language Models for Knowledge-Intensive {NLP}},
74 |   author={Khattab, Omar and Santhanam, Keshav and Li, Xiang Lisa and Hall, David and Liang, Percy and Potts, Christopher and Zaharia, Matei},
75 |   journal={arXiv preprint arXiv:2212.14024},
76 |   year={2022}
77 | }
78 | ```
79 | 
80 | <!-- You can also read more about the evolution of the framework from Demonstrate-Search-Predict to DSPy:
81 | 
82 | * [**DSPy Assertions: Computational Constraints for Self-Refining Language Model Pipelines**](https://arxiv.org/abs/2312.13382)   (Academic Paper, Dec 2023) 
83 | * [**DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines**](https://arxiv.org/abs/2310.03714) (Academic Paper, Oct 2023) 
84 | * [**Releasing DSPy, the latest iteration of the framework**](https://twitter.com/lateinteraction/status/1694748401374490946) (Twitter Thread, Aug 2023)
85 | * [**Releasing the DSP Compiler (v0.1)**](https://twitter.com/lateinteraction/status/1625231662849073160)  (Twitter Thread, Feb 2023)
86 | * [**Introducing DSP**](https://twitter.com/lateinteraction/status/1617953413576425472)  (Twitter Thread, Jan 2023)
87 | * [**Demonstrate-Search-Predict: Composing retrieval and language models for knowledge-intensive NLP**](https://arxiv.org/abs/2212.14024.pdf) (Academic Paper, Dec 2022) -->
88 | 
89 | 
```

--------------------------------------------------------------------------------
/tests/reliability/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # DSPy Reliability Tests
 2 | 
 3 | This directory contains reliability tests for DSPy programs. The purpose of these tests is to verify that DSPy programs reliably produce expected outputs across multiple large language models (LLMs), regardless of model size or capability. These tests are designed to ensure that DSPy programs maintain robustness and accuracy across diverse LLM configurations.
 4 | 
 5 | ### Overview
 6 | 
 7 | Each test in this directory executes a DSPy program using various LLMs. By running the same tests across different models, these tests help validate that DSPy programs handle a wide range of inputs effectively and produce reliable outputs, even in cases where the model might struggle with the input or task.
 8 | 
 9 | ### Key Features
10 | 
11 | - **Diverse LLMs**: Each DSPy program is tested with multiple LLMs, ranging from smaller models to more advanced, high-performance models. This approach allows us to assess the consistency and generality of DSPy program outputs across different model capabilities.
12 | - **Challenging and Adversarial Tests**: Some of the tests are intentionally challenging or adversarial, crafted to push the boundaries of DSPy. These challenging cases allow us to gauge the robustness of DSPy and identify areas for potential improvement.
13 | - **Cross-Model Compatibility**: By testing with different LLMs, we aim to ensure that DSPy programs perform well across model types and configurations, reducing model-specific edge cases and enhancing program versatility.
14 | 
15 | ### Running the Tests
16 | 
17 | - First, populate the configuration file `reliability_tests_conf.yaml` (located in this directory) with the necessary LiteLLM model/provider names and access credentials for 1. each LLM you want to test and 2. the LLM judge that you want to use for assessing the correctness of outputs in certain test cases. These should be placed in the `litellm_params` section for each model in the defined `model_list`. You can also use `litellm_params` to specify values for LLM hyperparameters like `temperature`. Any model that lacks configured `litellm_params` in the configuration file will be ignored during testing.
18 | 
19 |   The configuration must also specify a DSPy adapter to use when testing, e.g. `"chat"` (for `dspy.ChatAdapter`) or `"json"` (for `dspy.JSONAdapter`).
20 | 
21 |   An example of `reliability_tests_conf.yaml`:
22 | 
23 |       ```yaml
24 |       adapter: chat
25 |       model_list:
26 |         # The model to use for judging the correctness of program
27 |         # outputs throughout reliability test suites. We recommend using
28 |         # a high quality model as the judge, such as OpenAI GPT-4o
29 |         - model_name: "judge"
30 |           litellm_params:
31 |             model: "openai/gpt-4o"
32 |             api_key: "<my_openai_api_key>"
33 |         - model_name: "gpt-4o"
34 |           litellm_params:
35 |             model: "openai/gpt-4o"
36 |             api_key: "<my_openai_api_key>"
37 |         - model_name: "claude-3.5-sonnet"
38 |           litellm_params:
39 |             model: "anthropic/claude-3.5"
40 |             api_key: "<my_anthropic_api_key>"
41 | 
42 | - Second, to run the tests, run the following command from this directory:
43 | 
44 |   ```bash
45 |       pytest .
46 |   ```
47 | 
48 |   This will execute all tests for the configured models and display detailed results for each model configuration. Tests are set up to mark expected failures for known challenging cases where a specific model might struggle, while actual (unexpected) DSPy reliability issues are flagged as failures (see below).
49 | 
50 | #### Running specific generated tests
51 | 
52 | You can run specific generated tests by using the `-k` flag with `pytest`. For example, to test the generated program located at `tests/reliability/complex_types/generated/test_nesting_1` against generated test input `input1.json`, you can run the following command from this directory:
53 | 
54 | ```bash
55 | pytest test_generated.py -k "test_nesting_1-input1"
56 | ```
57 | 
58 | ### Test generation
59 | 
60 | You can generate test DSPy programs and test inputs from text descriptions using the `tests.reliability.generate` CLI, or the `tests.reliability.generate.generate_test_cases` API. For example, to generate a test classification program and 3 challenging test inputs in the `tests/reliability/classification/generated` directory, you can run the following command from the DSPy repository root directory:
61 | 
62 | ```bash
63 | python \
64 |     -m tests.reliability.generate \
65 |     -d tests/reliability/classification/generated/test_example \
66 |     -p "Generate a program that performs a classification task involving objects with multiple properties. The task should be realistic" \
67 |     -i "Based on the program description, generate a challenging example" \
68 |     -n 3
69 | ```
70 | 
71 | The test program will be written to `tests/reliability/classification/generated/test_example/program.py`, and the test inputs will be written as JSON files to the `tests/reliability/classification/generated/test_exaple/inputs/` directory.
72 | 
73 | All generated tests should be located in directories with the structure `tests/reliability/<test_type>/generated/<test_name>`, where `<test_type>` is the type of test (e.g., `classification`, `complex_types`, `chat`, etc.), and `<test_name>` is a descriptive name for the test.
74 | 
75 | ### Known Failing Models
76 | 
77 | Some tests may be expected to fail with certain models, especially in challenging cases. These known failures are logged but do not affect the overall test result. This setup allows us to keep track of model-specific limitations without obstructing general test outcomes. Models that are known to fail a particular test case are specified using the `@known_failing_models` decorator. For example:
78 | 
79 | ```
80 | @known_failing_models(["llama-3.2-3b-instruct"])
81 | def test_program_with_complex_deeply_nested_output_structure():
82 |     ...
83 | ```
84 | 
```

--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Contribution Guide
  2 | 
  3 | DSPy is an actively growing project and community! We welcome your contributions and involvement. Below are instructions for how to contribute to DSPy.
  4 | 
  5 | ## Finding an Issue
  6 | 
  7 | The fastest way to contribute is to find open issues that need an assignee. We maintain two lists of GitHub tags for contributors:
  8 | 
  9 | - [good first issue](https://github.com/stanfordnlp/dspy/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22good%20first%20issue%22):
 10 |   a list of small, well-defined issues for newcomers to the project.
 11 | - [help wanted](https://github.com/stanfordnlp/dspy/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22help%20wanted%22):
 12 |   a list of issues that welcome community contributions. These issues have a wide range of complexity.
 13 | 
 14 | We also welcome new ideas! If you would like to propose a new feature, please open a feature request to
 15 | discuss. If you already have a design in mind, please include a notebook/code example to demonstrate
 16 | your idea. Keep in mind that designing a new feature or use case may take longer than contributing to
 17 | an open issue.
 18 | 
 19 | ## Contributing Code
 20 | 
 21 | Follow these steps to submit your code contribution.
 22 | 
 23 | ### Step 1. Open an Issue
 24 | 
 25 | Before making any changes, we recommend opening an issue (if one doesn't already exist) and discussing your
 26 | proposed changes. This way, we can give you feedback and validate the proposed changes.
 27 | 
 28 | If your code change involves fixing a bug, please include a code snippet or notebook
 29 | to show how to reproduce the broken behavior.
 30 | 
 31 | For minor changes (simple bug fixes or documentation fixes), feel free to open a PR without discussion.
 32 | 
 33 | ### Step 2. Make Code Changes
 34 | 
 35 | To make code changes, fork the repository and set up your local development environment following the
 36 | instructions in the "Environment Setup" section below.
 37 | 
 38 | ### Step 3 Commit Your Code and Run Autoformatting
 39 | 
 40 | We follow the [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html) and use `ruff` for both linting and formatting. To ensure consistent code quality, we use pre-commit hooks that automatically check and fix common issues.
 41 | 
 42 | 
 43 | First you need to set up the pre-commit hooks (do this once after cloning the repository):
 44 | 
 45 | ```shell
 46 | pre-commit install
 47 | ```
 48 | 
 49 | Then stage and commit your changes. When you run `git commit`, the pre-commit hook will be
 50 | automatically run.
 51 | 
 52 | ```shell
 53 | git add .
 54 | git commit -m "your commit message"
 55 | ```
 56 | 
 57 | If the hooks make any changes, you'll need to stage and commit those changes as well.
 58 | 
 59 | You can also run the hooks manually:
 60 | 
 61 | - Check staged files only:
 62 | 
 63 |   ```shell
 64 |   pre-commit run
 65 |   ```
 66 | 
 67 | - Check specific files:
 68 | 
 69 |   ```shell
 70 |   pre-commit run --files path/to/file1.py path/to/file2.py
 71 |   ```
 72 | 
 73 | Please ensure all pre-commit checks pass before creating your pull request. If you're unsure about any
 74 | formatting issues, feel free to commit your changes and let the pre-commit hooks fix them automatically.
 75 | 
 76 | ### Step 4. Create a Pull Request
 77 | 
 78 | Once your changes are ready, open a pull request from your branch in your fork to the main branch in the
 79 | [DSPy repo](https://github.com/stanfordnlp/dspy).
 80 | 
 81 | ### Step 5. Code Review
 82 | 
 83 | Once your PR is up and passes all CI tests, we will assign reviewers to review the code. There may be
 84 | several rounds of comments and code changes before the pull request gets approved by the reviewer.
 85 | 
 86 | ### Step 6. Merging
 87 | 
 88 | Once the pull request is approved, a team member will take care of merging.
 89 | 
 90 | ## Environment Setup
 91 | 
 92 | Python 3.10 or later is required.
 93 | 
 94 | Setting up your DSPy development environment requires you to fork the DSPy repository and clone it locally.
 95 | If you are not familiar with the GitHub fork process, please refer to [Fork a repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo). After creating the fork, clone
 96 | it to your local development device:
 97 | 
 98 | ```shell
 99 | git clone {url-to-your-fork}
100 | cd dspy
101 | ```
102 | 
103 | Next, we must set up a Python environment with the correct dependencies. There are two recommended ways to set up the
104 | dev environment.
105 | 
106 | ### [Recommended] Set Up Environment Using uv
107 | 
108 | [uv](https://github.com/astral-sh/uv) is a rust-based Python package and project manager that provides a fast
109 | way to set up the development environment. First, install uv by following the
110 | [installation guide](https://docs.astral.sh/uv/getting-started/installation/).
111 | 
112 | After uv is installed, in your working directory (`dspy/`), run:
113 | 
114 | ```shell
115 | uv sync --extra dev
116 | ```
117 | 
118 | Then you are all set!
119 | 
120 | To verify that your environment is set up successfully, run some unit tests:
121 | 
122 | ```shell
123 | uv run pytest tests/predict
124 | ```
125 | 
126 | Note: You need to use the `uv run` prefix for every Python command, as uv creates a Python virtual
127 | environment and `uv run` points the command to that environment. For example, to execute a Python script you will need
128 | `uv run python script.py`.
129 | 
130 | ### Set Up Environment Using conda + pip
131 | 
132 | You can also set up the virtual environment via conda + pip, which takes a few extra steps but offers more flexibility. Before starting,
133 | make sure you have conda installed. If not, please follow the instructions
134 | [here](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html).
135 | 
136 | To set up the environment, run:
137 | 
138 | ```shell
139 | conda create -n dspy-dev python=3.11
140 | conda activate dspy-dev
141 | pip install -e ".[dev]"
142 | ```
143 | 
144 | Then verify the installation by running some unit tests:
145 | 
146 | ```shell
147 | pytest tests/predict
148 | ```
149 | 
150 | 
```

--------------------------------------------------------------------------------
/dspy/dsp/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
```

--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
```

--------------------------------------------------------------------------------
/tests/reliability/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
```

--------------------------------------------------------------------------------
/tests/test_utils/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
```

--------------------------------------------------------------------------------
/tests/utils/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
```

--------------------------------------------------------------------------------
/tests/teleprompt/test_finetune.py:
--------------------------------------------------------------------------------

```python
1 | # TODO
2 | 
```

--------------------------------------------------------------------------------
/dspy/predict/parameter.py:
--------------------------------------------------------------------------------

```python
1 | class Parameter:
2 |     pass
3 | 
```

--------------------------------------------------------------------------------
/dspy/datasets/alfworld/__init__.py:
--------------------------------------------------------------------------------

```python
1 | from dspy.datasets.alfworld.alfworld import AlfWorld
2 | 
```

--------------------------------------------------------------------------------
/dspy/teleprompt/gepa/__init__.py:
--------------------------------------------------------------------------------

```python
1 | from dspy.teleprompt.gepa.gepa import GEPA
2 | 
3 | __all__ = ["GEPA"]
4 | 
```

--------------------------------------------------------------------------------
/dspy/propose/__init__.py:
--------------------------------------------------------------------------------

```python
1 | from dspy.propose.grounded_proposer import GroundedProposer
2 | 
3 | __all__ = [
4 |     "GroundedProposer",
5 | ]
6 | 
```

--------------------------------------------------------------------------------
/dspy/dsp/utils/__init__.py:
--------------------------------------------------------------------------------

```python
1 | from dspy.dsp.utils.dpr import *
2 | from dspy.dsp.utils.settings import *
3 | from dspy.dsp.utils.utils import *
4 | 
```

--------------------------------------------------------------------------------
/dspy/predict/avatar/__init__.py:
--------------------------------------------------------------------------------

```python
1 | from dspy.predict.avatar.avatar import *
2 | from dspy.predict.avatar.models import *
3 | from dspy.predict.avatar.signatures import *
4 | 
```

--------------------------------------------------------------------------------
/dspy/retrievers/__init__.py:
--------------------------------------------------------------------------------

```python
1 | from dspy.retrievers.embeddings import Embeddings
2 | from dspy.retrievers.retrieve import Retrieve
3 | 
4 | __all__ = ["Embeddings", "Retrieve"]
5 | 
```

--------------------------------------------------------------------------------
/dspy/experimental/__init__.py:
--------------------------------------------------------------------------------

```python
1 | from dspy.adapters.types.citation import Citations
2 | from dspy.adapters.types.document import Document
3 | 
4 | __all__ = [
5 |     "Citations",
6 |     "Document",
7 | ]
8 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/index.md:
--------------------------------------------------------------------------------

```markdown
1 | # API Reference
2 | 
3 | Welcome to the DSPy API reference documentation. This section provides detailed information about DSPy's classes, modules, and functions.
```

--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------

```
 1 | git+https://github.com/stanfordnlp/dspy.git
 2 | mkdocs-material
 3 | mkdocs-jupyter
 4 | mkdocs-material[imaging]
 5 | mkdocs-redirects
 6 | mkdocstrings
 7 | mkdocstrings-python
 8 | mkdocs-llmstxt>=0.3.0
 9 | urllib3==1.26.6
10 | mistune==3.0.2
11 | 
```

--------------------------------------------------------------------------------
/docs/vercel.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "trailingSlash": true,
 3 |   "headers": [
 4 |     {
 5 |       "source": "/(.*).md",
 6 |       "headers": [
 7 |         {
 8 |           "key": "Content-Type",
 9 |           "value": "text/markdown; charset=utf-8"
10 |         }
11 |       ]
12 |     }
13 |   ]
14 | }
15 | 
```

--------------------------------------------------------------------------------
/dspy/__metadata__.py:
--------------------------------------------------------------------------------

```python
1 | #replace_package_name_marker
2 | __name__="dspy"
3 | #replace_package_version_marker
4 | __version__="3.0.4b1"
5 | __description__="DSPy"
6 | __url__="https://github.com/stanfordnlp/dspy"
7 | __author__="Omar Khattab"
8 | __author_email__="[email protected]"
```

--------------------------------------------------------------------------------
/dspy/propose/propose_base.py:
--------------------------------------------------------------------------------

```python
 1 | from abc import ABC, abstractmethod
 2 | 
 3 | 
 4 | class Proposer(ABC):
 5 |     def __init__(self):
 6 |         pass
 7 | 
 8 |     @abstractmethod
 9 |     def propose_instructions_for_program(self):
10 |         pass
11 | 
12 |     def propose_instruction_for_predictor(self):
13 |         pass
14 | 
```

--------------------------------------------------------------------------------
/docs/docs/community/how-to-contribute.md:
--------------------------------------------------------------------------------

```markdown
1 | # Contributing
2 | 
3 | DSPy is an actively growing project and community, and we welcome your contributions and involvement! Please read the
4 | [contributing guide](https://github.com/stanfordnlp/dspy/blob/main/CONTRIBUTING.md) for how to contribute to DSPy.
5 | 
6 | 
7 | 
```

--------------------------------------------------------------------------------
/docs/docs/tutorials/classification/index.md:
--------------------------------------------------------------------------------

```markdown
1 | Please refer to [this tutorial from Drew Breunig](https://www.dbreunig.com/2024/12/12/pipelines-prompt-optimization-with-dspy.html) using DSPy.
2 | 
3 | This tutorial demonstrates a few aspects of using DSPy in a highly-accessible, concrete context for categorizing historic events with a tiny LM.
```

--------------------------------------------------------------------------------
/docs/overrides/main.html:
--------------------------------------------------------------------------------

```html
 1 | {% extends "base.html" %}
 2 | 
 3 | {% block extrahead %}
 4 | <script async src="https://www.googletagmanager.com/gtag/js?id=G-G728W2L8KQ"></script>
 5 | <script>
 6 |   window.dataLayer = window.dataLayer || [];
 7 |   function gtag(){dataLayer.push(arguments);}
 8 |   gtag('js', new Date());
 9 | 
10 |   gtag('config', 'G-G728W2L8KQ');
11 | </script>
12 | {% endblock %}
```

--------------------------------------------------------------------------------
/dspy/signatures/utils.py:
--------------------------------------------------------------------------------

```python
 1 | from typing import Literal
 2 | 
 3 | from pydantic.fields import FieldInfo
 4 | 
 5 | 
 6 | def get_dspy_field_type(field: FieldInfo) -> Literal["input", "output"]:
 7 |     field_type = field.json_schema_extra.get("__dspy_field_type")
 8 |     if field_type is None:
 9 |         raise ValueError(f"Field {field} does not have a __dspy_field_type")
10 |     return field_type
11 | 
```

--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md:
--------------------------------------------------------------------------------

```markdown
 1 | ## 📝 Changes Description
 2 | 
 3 | This MR/PR contains the following changes:
 4 | ...
 5 | 
 6 | ## ✅ Contributor Checklist
 7 | 
 8 | - [] Pre-Commit checks are passing (locally and remotely)
 9 | - [] Title of your PR / MR corresponds to the required format
10 | - [] Commit message follows required format {label}(dspy): {message}
11 | 
12 | ## ⚠️ Warnings
13 | 
14 | Anything we should be aware of ?
15 | 
```

--------------------------------------------------------------------------------
/dspy/datasets/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.datasets.alfworld import AlfWorld
 2 | from dspy.datasets.colors import Colors
 3 | from dspy.datasets.dataloader import DataLoader
 4 | from dspy.datasets.dataset import Dataset
 5 | from dspy.datasets.hotpotqa import HotPotQA
 6 | from dspy.datasets.math import MATH
 7 | 
 8 | __all__ = [
 9 |     "Colors",
10 |     "DataLoader",
11 |     "Dataset",
12 |     "HotPotQA",
13 |     "MATH",
14 | ]
15 | 
```

--------------------------------------------------------------------------------
/tests/metadata/test_metadata.py:
--------------------------------------------------------------------------------

```python
 1 | import re
 2 | 
 3 | import dspy
 4 | 
 5 | 
 6 | def test_metadata():
 7 |     assert dspy.__name__ == "dspy"
 8 |     assert re.match(r"\d+\.\d+\.\d+", dspy.__version__)
 9 |     assert dspy.__author__ == "Omar Khattab"
10 |     assert dspy.__author_email__ == "[email protected]"
11 |     assert dspy.__url__ == "https://github.com/stanfordnlp/dspy"
12 |     assert dspy.__description__ == "DSPy"
13 | 
```

--------------------------------------------------------------------------------
/dspy/adapters/types/__init__.py:
--------------------------------------------------------------------------------

```python
1 | from dspy.adapters.types.audio import Audio
2 | from dspy.adapters.types.base_type import Type
3 | from dspy.adapters.types.code import Code
4 | from dspy.adapters.types.history import History
5 | from dspy.adapters.types.image import Image
6 | from dspy.adapters.types.tool import Tool, ToolCalls
7 | 
8 | __all__ = ["History", "Image", "Audio", "Type", "Tool", "ToolCalls", "Code"]
9 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/load.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.load
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.load
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/primitives/History.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.History
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.History
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/asyncify.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.asyncify
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.asyncify
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/streamify.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.streamify
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.streamify
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/signatures/InputField.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.InputField
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.InputField
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/signatures/OutputField.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.OutputField
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.OutputField
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/enable_logging.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.enable_logging
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.enable_logging
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/configure_cache.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.configure_cache
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.configure_cache
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/disable_logging.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.disable_logging
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.disable_logging
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/inspect_history.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.inspect_history
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.inspect_history
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/dspy/primitives/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.primitives.base_module import BaseModule
 2 | from dspy.primitives.example import Example
 3 | from dspy.primitives.module import Module
 4 | from dspy.primitives.prediction import Completions, Prediction
 5 | from dspy.primitives.python_interpreter import PythonInterpreter
 6 | 
 7 | __all__ = [
 8 |     "Example",
 9 |     "BaseModule",
10 |     "Prediction",
11 |     "Completions",
12 |     "Module",
13 |     "PythonInterpreter",
14 | ]
15 | 
```

--------------------------------------------------------------------------------
/.github/workflow_scripts/install_testpypi_pkg.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash  
 2 | 
 3 | # The $1 argument is the version number passed from the workflow  
 4 | VERSION=$1
 5 | 
 6 | echo "version: $VERSION"
 7 | 
 8 | for i in {1..5}; do  
 9 |   if python3 -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple dspy-ai-test=="$VERSION"; then  
10 |     break  
11 |   else  
12 |     echo "Attempt $i failed. Waiting before retrying..."  
13 |     sleep 10  
14 |   fi  
15 | done
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/enable_litellm_logging.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.enable_litellm_logging
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.enable_litellm_logging
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/tests/test_utils/server/litellm_server_config.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | model_list:
 2 |   - model_name: "dspy-test-model"
 3 |     litellm_params:
 4 |       model: "dspy-test-provider/dspy-test-model"
 5 |   - model_name: "dspy-test-model-2"
 6 |     litellm_params:
 7 |       model: "dspy-test-provider/dspy-test-model"
 8 | 
 9 | litellm_settings:
10 |   num_retries: 0
11 |   custom_provider_map:
12 |     - {
13 |         "provider": "dspy-test-provider",
14 |         "custom_handler": litellm_server.dspy_test_model,
15 |       }
16 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/KNN.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.KNN
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.KNN
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |         show_source: true
10 |         show_root_heading: true
11 |         heading_level: 2
12 |         docstring_style: google
13 |         show_root_full_path: true
14 |         show_object_full_path: false
15 |         separate_signature: false
16 |         inherited_members: true
17 | :::
18 | <!-- END_API_REF -->
19 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/disable_litellm_logging.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.disable_litellm_logging
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.disable_litellm_logging
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/StatusMessage.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.streaming.StatusMessage
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.streaming.StatusMessage
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/evaluation/answer_exact_match.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.evaluate.answer_exact_match
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.evaluate.answer_exact_match
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/evaluation/Evaluate.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Evaluate
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Evaluate
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |         show_source: true
10 |         show_root_heading: true
11 |         heading_level: 2
12 |         docstring_style: google
13 |         show_root_full_path: true
14 |         show_object_full_path: false
15 |         separate_signature: false
16 |         inherited_members: true
17 | :::
18 | <!-- END_API_REF -->
19 | 
```

--------------------------------------------------------------------------------
/tests/reliability/test_generated.py:
--------------------------------------------------------------------------------

```python
 1 | import os
 2 | 
 3 | import pytest
 4 | 
 5 | from tests.reliability.generate.utils import load_generated_cases, run_generated_case
 6 | 
 7 | _DIR_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)))
 8 | 
 9 | 
10 | @pytest.mark.reliability
11 | @pytest.mark.parametrize(
12 |     "generated_case",
13 |     load_generated_cases(_DIR_PATH),
14 |     ids=lambda case: case.name,
15 | )
16 | def test_generated_cases(generated_case):
17 |     run_generated_case(generated_case)
18 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/evaluation/answer_passage_match.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.evaluate.answer_passage_match
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.evaluate.answer_passage_match
 5 |     handler: python
 6 |     options:
 7 |         show_source: true
 8 |         show_root_heading: true
 9 |         heading_level: 2
10 |         docstring_style: google
11 |         show_root_full_path: true
12 |         show_object_full_path: false
13 |         separate_signature: false
14 |         inherited_members: true
15 | :::
16 | <!-- END_API_REF -->
17 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/tools/ColBERTv2.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.ColBERTv2
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.ColBERTv2
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |         show_source: true
10 |         show_root_heading: true
11 |         heading_level: 2
12 |         docstring_style: google
13 |         show_root_full_path: true
14 |         show_object_full_path: false
15 |         separate_signature: false
16 |         inherited_members: true
17 | :::
18 | <!-- END_API_REF -->
19 | 
```

--------------------------------------------------------------------------------
/dspy/evaluate/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.evaluate.auto_evaluation import CompleteAndGrounded, SemanticF1
 2 | from dspy.evaluate.evaluate import Evaluate, EvaluationResult
 3 | from dspy.evaluate.metrics import EM, answer_exact_match, answer_passage_match, normalize_text
 4 | 
 5 | __all__ = [
 6 |     "EM",
 7 |     "normalize_text",
 8 |     "answer_exact_match",
 9 |     "answer_passage_match",
10 |     "Evaluate",
11 |     "SemanticF1",
12 |     "CompleteAndGrounded",
13 |     "EvaluationResult",
14 | ]
15 | 
```

--------------------------------------------------------------------------------
/dspy/streaming/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.streaming.messages import StatusMessage, StatusMessageProvider, StreamResponse
 2 | from dspy.streaming.streamify import apply_sync_streaming, streamify, streaming_response
 3 | from dspy.streaming.streaming_listener import StreamListener
 4 | 
 5 | __all__ = [
 6 |     "StatusMessage",
 7 |     "StatusMessageProvider",
 8 |     "streamify",
 9 |     "StreamListener",
10 |     "StreamResponse",
11 |     "streaming_response",
12 |     "apply_sync_streaming",
13 | ]
14 | 
```

--------------------------------------------------------------------------------
/dspy/utils/caching.py:
--------------------------------------------------------------------------------

```python
 1 | import os
 2 | from pathlib import Path
 3 | 
 4 | _DEFAULT_CACHE_DIR = os.path.join(Path.home(), ".dspy_cache")
 5 | DSPY_CACHEDIR = os.environ.get("DSPY_CACHEDIR") or _DEFAULT_CACHE_DIR
 6 | 
 7 | 
 8 | def create_subdir_in_cachedir(subdir: str) -> str:
 9 |     """Create a subdirectory in the DSPy cache directory."""
10 |     subdir = os.path.join(DSPY_CACHEDIR, subdir)
11 |     subdir = os.path.abspath(subdir)
12 |     os.makedirs(subdir, exist_ok=True)
13 |     return subdir
14 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/COPRO.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.COPRO
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.COPRO
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - compile
 9 |             - get_params
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/models/Embedder.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Embedder
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Embedder
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/modules/Parallel.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Parallel
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Parallel
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - forward
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/Ensemble.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Ensemble
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Ensemble
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - compile
 9 |             - get_params
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/KNNFewShot.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.KNNFewShot
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.KNNFewShot
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - compile
 9 |             - get_params
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/BootstrapRS.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.BootstrapRS
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.BootstrapRS
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - compile
 9 |             - get_params
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/BetterTogether.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.BetterTogether
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.BetterTogether
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - compile
 9 |             - get_params
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/LabeledFewShot.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.LabeledFewShot
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.LabeledFewShot
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - compile
 9 |             - get_params
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/tools/Embeddings.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.retrievers.Embeddings
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Embeddings
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - forward
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/BootstrapFewShot.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.BootstrapFewShot
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.BootstrapFewShot
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - compile
 9 |             - get_params
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/dspy/signatures/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.signatures.field import InputField, OldField, OldInputField, OldOutputField, OutputField
 2 | from dspy.signatures.signature import (
 3 |     Signature,
 4 |     SignatureMeta,
 5 |     ensure_signature,
 6 |     infer_prefix,
 7 |     make_signature,
 8 | )
 9 | 
10 | __all__ = [
11 |     "InputField",
12 |     "OutputField",
13 |     "OldField",
14 |     "OldInputField",
15 |     "OldOutputField",
16 |     "SignatureMeta",
17 |     "Signature",
18 |     "infer_prefix",
19 |     "ensure_signature",
20 |     "make_signature",
21 | ]
22 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/StreamListener.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.streaming.StreamListener
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.streaming.StreamListener
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - flush
 9 |             - receive
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/tools/PythonInterpreter.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.PythonInterpreter
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.PythonInterpreter
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - execute
10 |             - shutdown
11 |         show_source: true
12 |         show_root_heading: true
13 |         heading_level: 2
14 |         docstring_style: google
15 |         show_root_full_path: true
16 |         show_object_full_path: false
17 |         separate_signature: false
18 |         inherited_members: true
19 | :::
20 | <!-- END_API_REF -->
21 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/BootstrapFewShotWithRandomSearch.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.BootstrapFewShotWithRandomSearch
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.BootstrapFewShotWithRandomSearch
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - compile
 9 |             - get_params
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | :::
19 | <!-- END_API_REF -->
20 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/BootstrapFinetune.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.BootstrapFinetune
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.BootstrapFinetune
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - compile
 9 |             - convert_to_lm_dict
10 |             - finetune_lms
11 |             - get_params
12 |         show_source: true
13 |         show_root_heading: true
14 |         heading_level: 2
15 |         docstring_style: google
16 |         show_root_full_path: true
17 |         show_object_full_path: false
18 |         separate_signature: false
19 |         inherited_members: true
20 | :::
21 | <!-- END_API_REF -->
22 | 
```

--------------------------------------------------------------------------------
/tests/teleprompt/test_teleprompt.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.teleprompt.teleprompt import Teleprompter
 2 | 
 3 | 
 4 | class DummyTeleprompter(Teleprompter):
 5 |     def __init__(self, param1: int, param2: str):
 6 |         super().__init__()
 7 |         self.param1 = param1
 8 |         self.param2 = param2
 9 | 
10 |     def compile(self, student, *, trainset, teacher=None, valset=None, **kwargs):
11 |         return student
12 | 
13 | 
14 | def test_get_params():
15 |     teleprompter = DummyTeleprompter(param1=1, param2="test")
16 |     params = teleprompter.get_params()
17 |     assert params == {"param1": 1, "param2": "test"}
18 | 
```

--------------------------------------------------------------------------------
/dspy/adapters/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.adapters.base import Adapter
 2 | from dspy.adapters.chat_adapter import ChatAdapter
 3 | from dspy.adapters.json_adapter import JSONAdapter
 4 | from dspy.adapters.two_step_adapter import TwoStepAdapter
 5 | from dspy.adapters.types import Audio, Code, History, Image, Tool, ToolCalls, Type
 6 | from dspy.adapters.xml_adapter import XMLAdapter
 7 | 
 8 | __all__ = [
 9 |     "Adapter",
10 |     "ChatAdapter",
11 |     "Type",
12 |     "History",
13 |     "Image",
14 |     "Audio",
15 |     "Code",
16 |     "JSONAdapter",
17 |     "XMLAdapter",
18 |     "TwoStepAdapter",
19 |     "Tool",
20 |     "ToolCalls",
21 | ]
22 | 
```

--------------------------------------------------------------------------------
/docs/docs/tutorials/papillon/index.md:
--------------------------------------------------------------------------------

```markdown
1 | Please refer to [this tutorial from the PAPILLON authors](https://colab.research.google.com/github/Columbia-NLP-Lab/PAPILLON/blob/main/papillon_tutorial.ipynb) using DSPy.
2 | 
3 | This tutorial demonstrates a few aspects of using DSPy in a more advanced context:
4 | 
5 | 1. It builds a multi-stage `dspy.Module` that involves a small local LM using an external tool.
6 | 2. It builds a multi-stage _judge_ in DSPy, and uses it as a metric for evaluation.
7 | 3. It uses this judge for optimizing the `dspy.Module`, using a large model as a teacher for a small local LM.
8 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/primitives/Example.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Example
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Example
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - copy
 9 |             - get
10 |             - inputs
11 |             - items
12 |             - keys
13 |             - labels
14 |             - toDict
15 |             - values
16 |             - with_inputs
17 |             - without
18 |         show_source: true
19 |         show_root_heading: true
20 |         heading_level: 2
21 |         docstring_style: google
22 |         show_root_full_path: true
23 |         show_object_full_path: false
24 |         separate_signature: false
25 |         inherited_members: true
26 | :::
27 | <!-- END_API_REF -->
28 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/signatures/Signature.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Signature
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Signature
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - append
 9 |             - delete
10 |             - dump_state
11 |             - equals
12 |             - insert
13 |             - load_state
14 |             - prepend
15 |             - with_instructions
16 |             - with_updated_fields
17 |         show_source: true
18 |         show_root_heading: true
19 |         heading_level: 2
20 |         docstring_style: google
21 |         show_root_full_path: true
22 |         show_object_full_path: false
23 |         separate_signature: false
24 |         inherited_members: true
25 | :::
26 | <!-- END_API_REF -->
27 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/InferRules.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.InferRules
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.InferRules
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - compile
 9 |             - evaluate_program
10 |             - format_examples
11 |             - get_params
12 |             - get_predictor_demos
13 |             - induce_natural_language_rules
14 |             - update_program_instructions
15 |         show_source: true
16 |         show_root_heading: true
17 |         heading_level: 2
18 |         docstring_style: google
19 |         show_root_full_path: true
20 |         show_object_full_path: false
21 |         separate_signature: false
22 |         inherited_members: true
23 | :::
24 | <!-- END_API_REF -->
25 | 
```

--------------------------------------------------------------------------------
/.github/.internal_dspyai/pyproject.toml:
--------------------------------------------------------------------------------

```toml
 1 | [project]  
 2 | #replace_package_name_marker
 3 | name="dspy-ai"  
 4 | #replace_package_version_marker
 5 | version="3.0.4b1"  
 6 | description = "DSPy"  
 7 | readme = "README.md"  
 8 | authors = [  
 9 |     { name = "Omar Khattab", email = "[email protected]" }  
10 | ]  
11 | license = { text = "MIT License" }  
12 | requires-python = ">=3.9" 
13 | #replace_dspy_version_marker 
14 | dependencies = ["dspy>=3.0.4b1"]  
15 | urls = { "Homepage" = "https://github.com/stanfordnlp/dsp" }  
16 |   
17 | [build-system]  
18 | requires = ["setuptools>=40.8.0", "wheel"]  
19 | build-backend = "setuptools.build_meta"  
20 |   
21 | [tool.setuptools.packages.find]  
22 | include = ["dsp.*", "dspy.*", "dsp", "dspy"] 
23 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/primitives/Code.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Code
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Code
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - description
 9 |             - extract_custom_type_from_annotation
10 |             - format
11 |             - is_streamable
12 |             - parse_lm_response
13 |             - parse_stream_chunk
14 |             - serialize_model
15 |             - validate_input
16 |         show_source: true
17 |         show_root_heading: true
18 |         heading_level: 2
19 |         docstring_style: google
20 |         show_root_full_path: true
21 |         show_object_full_path: false
22 |         separate_signature: false
23 |         inherited_members: true
24 | :::
25 | <!-- END_API_REF -->
26 | 
```

--------------------------------------------------------------------------------
/dspy/predict/avatar/models.py:
--------------------------------------------------------------------------------

```python
 1 | from typing import Any
 2 | 
 3 | from pydantic import BaseModel, Field
 4 | 
 5 | 
 6 | class Tool(BaseModel):
 7 |     tool: Any
 8 |     name: str
 9 |     desc: str | None
10 |     input_type: str | None = None
11 | 
12 |     def __str__(self) -> str:
13 |         return f"{self.name}{f'(valid_input: {self.input_type})' if self.input_type else ''}: {self.desc}"
14 | 
15 |     def __repr__(self) -> str:
16 |         return self.__str__()
17 | 
18 | 
19 | class Action(BaseModel):
20 |     tool_name: Any = Field(..., description="Name of the tool to use.")
21 |     tool_input_query: Any = Field(..., description="Query to pass as input to the tool.")
22 | 
23 | 
24 | class ActionOutput(BaseModel):
25 |     tool_name: str
26 |     tool_input_query: str
27 |     tool_output: str
28 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/experimental/Document.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.experimental.Document
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.experimental.Document
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - description
 9 |             - extract_custom_type_from_annotation
10 |             - format
11 |             - is_streamable
12 |             - parse_lm_response
13 |             - parse_stream_chunk
14 |             - serialize_model
15 |             - validate_input
16 |         show_source: true
17 |         show_root_heading: true
18 |         heading_level: 2
19 |         docstring_style: google
20 |         show_root_full_path: true
21 |         show_object_full_path: false
22 |         separate_signature: false
23 |         inherited_members: true
24 | :::
25 | <!-- END_API_REF -->
26 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/primitives/ToolCalls.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.ToolCalls
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.ToolCalls
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - description
 9 |             - extract_custom_type_from_annotation
10 |             - format
11 |             - from_dict_list
12 |             - is_streamable
13 |             - parse_lm_response
14 |             - parse_stream_chunk
15 |             - serialize_model
16 |             - validate_input
17 |         show_source: true
18 |         show_root_heading: true
19 |         heading_level: 2
20 |         docstring_style: google
21 |         show_root_full_path: true
22 |         show_object_full_path: false
23 |         separate_signature: false
24 |         inherited_members: true
25 | :::
26 | <!-- END_API_REF -->
27 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/utils/StatusMessageProvider.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.streaming.StatusMessageProvider
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.streaming.StatusMessageProvider
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - lm_end_status_message
 9 |             - lm_start_status_message
10 |             - module_end_status_message
11 |             - module_start_status_message
12 |             - tool_end_status_message
13 |             - tool_start_status_message
14 |         show_source: true
15 |         show_root_heading: true
16 |         heading_level: 2
17 |         docstring_style: google
18 |         show_root_full_path: true
19 |         show_object_full_path: false
20 |         separate_signature: false
21 |         inherited_members: true
22 | :::
23 | <!-- END_API_REF -->
24 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/primitives/Image.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Image
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Image
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - description
 9 |             - extract_custom_type_from_annotation
10 |             - format
11 |             - from_PIL
12 |             - from_file
13 |             - from_url
14 |             - is_streamable
15 |             - parse_lm_response
16 |             - parse_stream_chunk
17 |             - serialize_model
18 |         show_source: true
19 |         show_root_heading: true
20 |         heading_level: 2
21 |         docstring_style: google
22 |         show_root_full_path: true
23 |         show_object_full_path: false
24 |         separate_signature: false
25 |         inherited_members: true
26 | :::
27 | <!-- END_API_REF -->
28 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/models/LM.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.LM
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.LM
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - aforward
11 |             - copy
12 |             - dump_state
13 |             - finetune
14 |             - forward
15 |             - infer_provider
16 |             - inspect_history
17 |             - kill
18 |             - launch
19 |             - reinforce
20 |             - update_history
21 |         show_source: true
22 |         show_root_heading: true
23 |         heading_level: 2
24 |         docstring_style: google
25 |         show_root_full_path: true
26 |         show_object_full_path: false
27 |         separate_signature: false
28 |         inherited_members: true
29 | :::
30 | <!-- END_API_REF -->
31 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/primitives/Prediction.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Prediction
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Prediction
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - copy
 9 |             - from_completions
10 |             - get
11 |             - get_lm_usage
12 |             - inputs
13 |             - items
14 |             - keys
15 |             - labels
16 |             - set_lm_usage
17 |             - toDict
18 |             - values
19 |             - with_inputs
20 |             - without
21 |         show_source: true
22 |         show_root_heading: true
23 |         heading_level: 2
24 |         docstring_style: google
25 |         show_root_full_path: true
26 |         show_object_full_path: false
27 |         separate_signature: false
28 |         inherited_members: true
29 | :::
30 | <!-- END_API_REF -->
31 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/experimental/Citations.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.experimental.Citations
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.experimental.Citations
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - description
 9 |             - extract_custom_type_from_annotation
10 |             - format
11 |             - from_dict_list
12 |             - is_streamable
13 |             - parse_lm_response
14 |             - parse_stream_chunk
15 |             - serialize_model
16 |             - validate_input
17 |         show_source: true
18 |         show_root_heading: true
19 |         heading_level: 2
20 |         docstring_style: google
21 |         show_root_full_path: true
22 |         show_object_full_path: false
23 |         separate_signature: false
24 |         inherited_members: true
25 | :::
26 | <!-- END_API_REF -->
27 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/primitives/Audio.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Audio
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Audio
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - description
 9 |             - extract_custom_type_from_annotation
10 |             - format
11 |             - from_array
12 |             - from_file
13 |             - from_url
14 |             - is_streamable
15 |             - parse_lm_response
16 |             - parse_stream_chunk
17 |             - serialize_model
18 |             - validate_input
19 |         show_source: true
20 |         show_root_heading: true
21 |         heading_level: 2
22 |         docstring_style: google
23 |         show_root_full_path: true
24 |         show_object_full_path: false
25 |         separate_signature: false
26 |         inherited_members: true
27 | :::
28 | <!-- END_API_REF -->
29 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/evaluation/EvaluationResult.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.evaluate.EvaluationResult
 2 | 
 3 | 
 4 | <!-- START_API_REF -->
 5 | ::: dspy.evaluate.EvaluationResult
 6 |     handler: python
 7 |     options:
 8 |         members:
 9 |             - copy
10 |             - from_completions
11 |             - get
12 |             - get_lm_usage
13 |             - inputs
14 |             - items
15 |             - keys
16 |             - labels
17 |             - set_lm_usage
18 |             - toDict
19 |             - values
20 |             - with_inputs
21 |             - without
22 |         show_source: true
23 |         show_root_heading: true
24 |         heading_level: 2
25 |         docstring_style: google
26 |         show_root_full_path: true
27 |         show_object_full_path: false
28 |         separate_signature: false
29 |         inherited_members: true
30 | :::
31 | <!-- END_API_REF -->
32 | 
```

--------------------------------------------------------------------------------
/docs/docs/js/runllm-widget.js:
--------------------------------------------------------------------------------

```javascript
 1 | document.addEventListener("DOMContentLoaded", function () {
 2 |     var script = document.createElement("script");
 3 |     script.defer = true;
 4 |     script.type = "module";
 5 |     script.id = "runllm-widget-script";
 6 |     script.src =
 7 |       "https://widget.runllm.com";
 8 |     script.setAttribute("runllm-name", "DSPy");
 9 |     script.setAttribute("runllm-preset", "mkdocs");
10 |     script.setAttribute("runllm-server-address", "https://api.runllm.com");
11 |     script.setAttribute("runllm-assistant-id", "132");
12 |     script.setAttribute("runllm-position", "BOTTOM_RIGHT");
13 |     script.setAttribute("runllm-keyboard-shortcut", "Mod+j");
14 |     script.setAttribute(
15 |       "runllm-slack-community-url",
16 |       ""
17 |     );
18 |   
19 |     document.head.appendChild(script);
20 |   });
```

--------------------------------------------------------------------------------
/dspy/predict/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.predict.aggregation import majority
 2 | from dspy.predict.best_of_n import BestOfN
 3 | from dspy.predict.chain_of_thought import ChainOfThought
 4 | from dspy.predict.code_act import CodeAct
 5 | from dspy.predict.knn import KNN
 6 | from dspy.predict.multi_chain_comparison import MultiChainComparison
 7 | from dspy.predict.parallel import Parallel
 8 | from dspy.predict.predict import Predict
 9 | from dspy.predict.program_of_thought import ProgramOfThought
10 | from dspy.predict.react import ReAct, Tool
11 | from dspy.predict.refine import Refine
12 | 
13 | __all__ = [
14 |     "majority",
15 |     "BestOfN",
16 |     "ChainOfThought",
17 |     "CodeAct",
18 |     "KNN",
19 |     "MultiChainComparison",
20 |     "Predict",
21 |     "ProgramOfThought",
22 |     "ReAct",
23 |     "Refine",
24 |     "Tool",
25 |     "Parallel",
26 | ]
27 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/adapters/Adapter.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Adapter
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Adapter
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - format
11 |             - format_assistant_message_content
12 |             - format_conversation_history
13 |             - format_demos
14 |             - format_field_description
15 |             - format_field_structure
16 |             - format_task_description
17 |             - format_user_message_content
18 |             - parse
19 |         show_source: true
20 |         show_root_heading: true
21 |         heading_level: 2
22 |         docstring_style: google
23 |         show_root_full_path: true
24 |         show_object_full_path: false
25 |         separate_signature: false
26 |         inherited_members: true
27 | :::
28 | <!-- END_API_REF -->
29 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/primitives/Tool.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Tool
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Tool
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - description
11 |             - extract_custom_type_from_annotation
12 |             - format
13 |             - format_as_litellm_function_call
14 |             - from_langchain
15 |             - from_mcp_tool
16 |             - is_streamable
17 |             - parse_lm_response
18 |             - parse_stream_chunk
19 |             - serialize_model
20 |         show_source: true
21 |         show_root_heading: true
22 |         heading_level: 2
23 |         docstring_style: google
24 |         show_root_full_path: true
25 |         show_object_full_path: false
26 |         separate_signature: false
27 |         inherited_members: true
28 | :::
29 | <!-- END_API_REF -->
30 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/adapters/TwoStepAdapter.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.TwoStepAdapter
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.TwoStepAdapter
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - format
11 |             - format_assistant_message_content
12 |             - format_conversation_history
13 |             - format_demos
14 |             - format_field_description
15 |             - format_field_structure
16 |             - format_task_description
17 |             - format_user_message_content
18 |             - parse
19 |         show_source: true
20 |         show_root_heading: true
21 |         heading_level: 2
22 |         docstring_style: google
23 |         show_root_full_path: true
24 |         show_object_full_path: false
25 |         separate_signature: false
26 |         inherited_members: true
27 | :::
28 | <!-- END_API_REF -->
29 | 
```

--------------------------------------------------------------------------------
/tests/predict/test_chain_of_thought.py:
--------------------------------------------------------------------------------

```python
 1 | import pytest
 2 | 
 3 | import dspy
 4 | from dspy import ChainOfThought
 5 | from dspy.utils import DummyLM
 6 | 
 7 | 
 8 | def test_initialization_with_string_signature():
 9 |     lm = DummyLM([{"reasoning": "find the number after 1", "answer": "2"}])
10 |     dspy.settings.configure(lm=lm)
11 |     predict = ChainOfThought("question -> answer")
12 |     assert list(predict.predict.signature.output_fields.keys()) == [
13 |         "reasoning",
14 |         "answer",
15 |     ]
16 |     assert predict(question="What is 1+1?").answer == "2"
17 | 
18 | 
19 | @pytest.mark.asyncio
20 | async def test_async_chain_of_thought():
21 |     lm = DummyLM([{"reasoning": "find the number after 1", "answer": "2"}])
22 |     with dspy.context(lm=lm):
23 |         program = ChainOfThought("question -> answer")
24 |         result = await program.acall(question="What is 1+1?")
25 |         assert result.answer == "2"
26 | 
```

--------------------------------------------------------------------------------
/tests/utils/resources/mcp_server.py:
--------------------------------------------------------------------------------

```python
 1 | from mcp.server.fastmcp import FastMCP
 2 | from pydantic import BaseModel
 3 | 
 4 | mcp = FastMCP("test")
 5 | 
 6 | 
 7 | class Profile(BaseModel):
 8 |     name: str
 9 |     age: int
10 | 
11 | 
12 | class Account(BaseModel):
13 |     profile: Profile
14 |     account_id: str
15 | 
16 | 
17 | @mcp.tool()
18 | def add(a: int, b: int) -> int:
19 |     """Add two numbers"""
20 |     return a + b
21 | 
22 | 
23 | @mcp.tool()
24 | def hello(names: list[str]) -> str:
25 |     """Greet people"""
26 |     return [f"Hello, {name}!" for name in names]
27 | 
28 | 
29 | @mcp.tool()
30 | def wrong_tool():
31 |     """This tool raises an error"""
32 |     raise ValueError("error!")
33 | 
34 | 
35 | @mcp.tool()
36 | def get_account_name(account: Account):
37 |     """This extracts the name from account"""
38 |     return account.profile.name
39 | 
40 | 
41 | @mcp.tool()
42 | def current_datetime() -> str:
43 |     """Get the current datetime"""
44 |     return "2025-07-23T09:10:10.0+00:00"
45 | 
46 | 
47 | if __name__ == "__main__":
48 |     mcp.run()
49 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/modules/Module.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Module
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Module
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - batch
11 |             - deepcopy
12 |             - dump_state
13 |             - get_lm
14 |             - inspect_history
15 |             - load
16 |             - load_state
17 |             - map_named_predictors
18 |             - named_parameters
19 |             - named_predictors
20 |             - named_sub_modules
21 |             - parameters
22 |             - predictors
23 |             - reset_copy
24 |             - save
25 |             - set_lm
26 |         show_source: true
27 |         show_root_heading: true
28 |         heading_level: 2
29 |         docstring_style: google
30 |         show_root_full_path: true
31 |         show_object_full_path: false
32 |         separate_signature: false
33 |         inherited_members: true
34 | :::
35 | <!-- END_API_REF -->
36 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/modules/Refine.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Refine
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Refine
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - batch
11 |             - deepcopy
12 |             - dump_state
13 |             - forward
14 |             - get_lm
15 |             - inspect_history
16 |             - load
17 |             - load_state
18 |             - map_named_predictors
19 |             - named_parameters
20 |             - named_predictors
21 |             - named_sub_modules
22 |             - parameters
23 |             - predictors
24 |             - reset_copy
25 |             - save
26 |             - set_lm
27 |         show_source: true
28 |         show_root_heading: true
29 |         heading_level: 2
30 |         docstring_style: google
31 |         show_root_full_path: true
32 |         show_object_full_path: false
33 |         separate_signature: false
34 |         inherited_members: true
35 | :::
36 | <!-- END_API_REF -->
37 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/modules/BestOfN.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.BestOfN
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.BestOfN
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - batch
11 |             - deepcopy
12 |             - dump_state
13 |             - forward
14 |             - get_lm
15 |             - inspect_history
16 |             - load
17 |             - load_state
18 |             - map_named_predictors
19 |             - named_parameters
20 |             - named_predictors
21 |             - named_sub_modules
22 |             - parameters
23 |             - predictors
24 |             - reset_copy
25 |             - save
26 |             - set_lm
27 |         show_source: true
28 |         show_root_heading: true
29 |         heading_level: 2
30 |         docstring_style: google
31 |         show_root_full_path: true
32 |         show_object_full_path: false
33 |         separate_signature: false
34 |         inherited_members: true
35 | :::
36 | <!-- END_API_REF -->
37 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/adapters/ChatAdapter.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.ChatAdapter
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.ChatAdapter
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - format
11 |             - format_assistant_message_content
12 |             - format_conversation_history
13 |             - format_demos
14 |             - format_field_description
15 |             - format_field_structure
16 |             - format_field_with_value
17 |             - format_finetune_data
18 |             - format_task_description
19 |             - format_user_message_content
20 |             - parse
21 |             - user_message_output_requirements
22 |         show_source: true
23 |         show_root_heading: true
24 |         heading_level: 2
25 |         docstring_style: google
26 |         show_root_full_path: true
27 |         show_object_full_path: false
28 |         separate_signature: false
29 |         inherited_members: true
30 | :::
31 | <!-- END_API_REF -->
32 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/adapters/JSONAdapter.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.JSONAdapter
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.JSONAdapter
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - format
11 |             - format_assistant_message_content
12 |             - format_conversation_history
13 |             - format_demos
14 |             - format_field_description
15 |             - format_field_structure
16 |             - format_field_with_value
17 |             - format_finetune_data
18 |             - format_task_description
19 |             - format_user_message_content
20 |             - parse
21 |             - user_message_output_requirements
22 |         show_source: true
23 |         show_root_heading: true
24 |         heading_level: 2
25 |         docstring_style: google
26 |         show_root_full_path: true
27 |         show_object_full_path: false
28 |         separate_signature: false
29 |         inherited_members: true
30 | :::
31 | <!-- END_API_REF -->
32 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/modules/ProgramOfThought.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.ProgramOfThought
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.ProgramOfThought
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - batch
11 |             - deepcopy
12 |             - dump_state
13 |             - forward
14 |             - get_lm
15 |             - inspect_history
16 |             - load
17 |             - load_state
18 |             - map_named_predictors
19 |             - named_parameters
20 |             - named_predictors
21 |             - named_sub_modules
22 |             - parameters
23 |             - predictors
24 |             - reset_copy
25 |             - save
26 |             - set_lm
27 |         show_source: true
28 |         show_root_heading: true
29 |         heading_level: 2
30 |         docstring_style: google
31 |         show_root_full_path: true
32 |         show_object_full_path: false
33 |         separate_signature: false
34 |         inherited_members: true
35 | :::
36 | <!-- END_API_REF -->
37 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/evaluation/SemanticF1.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.evaluate.SemanticF1
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.evaluate.SemanticF1
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - batch
11 |             - deepcopy
12 |             - dump_state
13 |             - forward
14 |             - get_lm
15 |             - inspect_history
16 |             - load
17 |             - load_state
18 |             - map_named_predictors
19 |             - named_parameters
20 |             - named_predictors
21 |             - named_sub_modules
22 |             - parameters
23 |             - predictors
24 |             - reset_copy
25 |             - save
26 |             - set_lm
27 |         show_source: true
28 |         show_root_heading: true
29 |         heading_level: 2
30 |         docstring_style: google
31 |         show_root_full_path: true
32 |         show_object_full_path: false
33 |         separate_signature: false
34 |         inherited_members: true
35 | :::
36 | <!-- END_API_REF -->
37 | 
```

--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: Feature Request
 2 | description: Suggest a new feature or improvement
 3 | title: "[Feature] "
 4 | labels: enhancement
 5 | body:
 6 |   - type: markdown
 7 |     attributes:
 8 |       value: |
 9 |         ## 🚀 Feature Request
10 |         Please fill out the following details.
11 | 
12 |   - type: textarea
13 |     id: description
14 |     attributes:
15 |       label: "What feature would you like to see?"
16 |       description: "Describe the feature clearly."
17 |     validations:
18 |       required: true
19 | 
20 |   - type: checkboxes
21 |     id: contribute
22 |     attributes:
23 |       label: "Would you like to contribute?"
24 |       options:
25 |         - label: Yes, I'd like to help implement this.
26 |         - label: No, I just want to request it.
27 | 
28 |   - type: textarea
29 |     id: additional-info
30 |     attributes:
31 |       label: "Additional Context"
32 |       description: "Any links, references, or extra details?"
33 |       placeholder: "Example: This feature exists in XYZ tool."
34 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/modules/MultiChainComparison.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.MultiChainComparison
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.MultiChainComparison
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - batch
11 |             - deepcopy
12 |             - dump_state
13 |             - forward
14 |             - get_lm
15 |             - inspect_history
16 |             - load
17 |             - load_state
18 |             - map_named_predictors
19 |             - named_parameters
20 |             - named_predictors
21 |             - named_sub_modules
22 |             - parameters
23 |             - predictors
24 |             - reset_copy
25 |             - save
26 |             - set_lm
27 |         show_source: true
28 |         show_root_heading: true
29 |         heading_level: 2
30 |         docstring_style: google
31 |         show_root_full_path: true
32 |         show_object_full_path: false
33 |         separate_signature: false
34 |         inherited_members: true
35 | :::
36 | <!-- END_API_REF -->
37 | 
```

--------------------------------------------------------------------------------
/tests/reliability/complex_types/generated/test_nesting_1/inputs/input2.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "assertions": [
 3 |     "The output should have a top-level field named 'resultLevel1'.",
 4 |     "Within 'resultLevel1', there should be a nested field named 'resultLevel2'.",
 5 |     "Within 'resultLevel2', there should be a nested field named 'resultLevel3'.",
 6 |     "Within 'resultLevel3', there should be a nested field named 'resultLevel4'.",
 7 |     "Within 'resultLevel4', there should be a nested field named 'resultLevel5'.",
 8 |     "Within 'resultLevel5', there should be a field named 'outputField1' which must be of type boolean.",
 9 |     "Within 'resultLevel5', there should be a field named 'outputField2' which must be an array of strings."
10 |   ],
11 |   "input": {
12 |     "level1": {
13 |       "level2": {
14 |         "level3": {
15 |           "level4": {
16 |             "level5": {
17 |               "field1": "test string",
18 |               "field2": 123.45
19 |             }
20 |           }
21 |         }
22 |       }
23 |     }
24 |   }
25 | }
26 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/modules/ChainOfThought.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.ChainOfThought
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.ChainOfThought
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - aforward
11 |             - batch
12 |             - deepcopy
13 |             - dump_state
14 |             - forward
15 |             - get_lm
16 |             - inspect_history
17 |             - load
18 |             - load_state
19 |             - map_named_predictors
20 |             - named_parameters
21 |             - named_predictors
22 |             - named_sub_modules
23 |             - parameters
24 |             - predictors
25 |             - reset_copy
26 |             - save
27 |             - set_lm
28 |         show_source: true
29 |         show_root_heading: true
30 |         heading_level: 2
31 |         docstring_style: google
32 |         show_root_full_path: true
33 |         show_object_full_path: false
34 |         separate_signature: false
35 |         inherited_members: true
36 | :::
37 | <!-- END_API_REF -->
38 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/evaluation/CompleteAndGrounded.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.evaluate.CompleteAndGrounded
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.evaluate.CompleteAndGrounded
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - batch
11 |             - deepcopy
12 |             - dump_state
13 |             - forward
14 |             - get_lm
15 |             - inspect_history
16 |             - load
17 |             - load_state
18 |             - map_named_predictors
19 |             - named_parameters
20 |             - named_predictors
21 |             - named_sub_modules
22 |             - parameters
23 |             - predictors
24 |             - reset_copy
25 |             - save
26 |             - set_lm
27 |         show_source: true
28 |         show_root_heading: true
29 |         heading_level: 2
30 |         docstring_style: google
31 |         show_root_full_path: true
32 |         show_object_full_path: false
33 |         separate_signature: false
34 |         inherited_members: true
35 | :::
36 | <!-- END_API_REF -->
37 | 
```

--------------------------------------------------------------------------------
/dspy/predict/avatar/signatures.py:
--------------------------------------------------------------------------------

```python
 1 | import dspy
 2 | from dspy.predict.avatar.models import Action
 3 | 
 4 | 
 5 | class Actor(dspy.Signature):
 6 |     """You will be given `Tools` which will be a list of tools to use to accomplish the `Goal`. Given the user query, your task is to decide which tool to use and what input values to provide.
 7 | 
 8 |     You will output action needed to accomplish the `Goal`. `Action` should have a tool to use and the input query to pass to the tool.
 9 | 
10 |     Note: You can opt to use no tools and provide the final answer directly. You can also one tool multiple times with different input queries if applicable."""
11 | 
12 |     goal: str = dspy.InputField(
13 |         prefix="Goal:",
14 |         desc="Task to be accomplished.",
15 |     )
16 |     tools: list[str] = dspy.InputField(
17 |         prefix="Tools:",
18 |         desc="list of tools to use",
19 |     )
20 |     action_1: Action = dspy.OutputField(
21 |         prefix="Action 1:",
22 |         desc="1st action to take.",
23 |     )
24 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/modules/ReAct.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.ReAct
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.ReAct
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - aforward
11 |             - batch
12 |             - deepcopy
13 |             - dump_state
14 |             - forward
15 |             - get_lm
16 |             - inspect_history
17 |             - load
18 |             - load_state
19 |             - map_named_predictors
20 |             - named_parameters
21 |             - named_predictors
22 |             - named_sub_modules
23 |             - parameters
24 |             - predictors
25 |             - reset_copy
26 |             - save
27 |             - set_lm
28 |             - truncate_trajectory
29 |         show_source: true
30 |         show_root_heading: true
31 |         heading_level: 2
32 |         docstring_style: google
33 |         show_root_full_path: true
34 |         show_object_full_path: false
35 |         separate_signature: false
36 |         inherited_members: true
37 | :::
38 | <!-- END_API_REF -->
39 | 
```

--------------------------------------------------------------------------------
/tests/reliability/complex_types/generated/test_nesting_1/inputs/input1.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "assertions": [
 3 |     "The top-level output should contain the key 'resultLevel1'.",
 4 |     "'resultLevel1' should contain the key 'resultLevel2'.",
 5 |     "'resultLevel2' should contain the key 'resultLevel3'.",
 6 |     "'resultLevel3' should contain the key 'resultLevel4'.",
 7 |     "'resultLevel4' should contain the key 'resultLevel5'.",
 8 |     "'resultLevel5' should contain the key 'outputField1' which should be of type boolean.",
 9 |     "'resultLevel5' should contain the key 'outputField2' which should be an array of strings.",
10 |     "'outputField1' should indicate success or failure with a boolean value.",
11 |     "'outputField2' should contain messages represented as strings."
12 |   ],
13 |   "input": {
14 |     "level1": {
15 |       "level2": {
16 |         "level3": {
17 |           "level4": {
18 |             "level5": {
19 |               "field1": "test_string",
20 |               "field2": 42
21 |             }
22 |           }
23 |         }
24 |       }
25 |     }
26 |   }
27 | }
28 | 
```

--------------------------------------------------------------------------------
/dspy/teleprompt/teleprompt.py:
--------------------------------------------------------------------------------

```python
 1 | from typing import Any
 2 | 
 3 | from dspy.primitives import Example, Module
 4 | 
 5 | 
 6 | class Teleprompter:
 7 |     def __init__(self):
 8 |         pass
 9 | 
10 |     def compile(self, student: Module, *, trainset: list[Example], teacher: Module | None = None, valset: list[Example] | None = None, **kwargs) -> Module:
11 |         """
12 |         Optimize the student program.
13 | 
14 |         Args:
15 |             student: The student program to optimize.
16 |             trainset: The training set to use for optimization.
17 |             teacher: The teacher program to use for optimization.
18 |             valset: The validation set to use for optimization.
19 | 
20 |         Returns:
21 |             The optimized student program.
22 |         """
23 |         raise NotImplementedError
24 | 
25 |     def get_params(self) -> dict[str, Any]:
26 |         """
27 |         Get the parameters of the teleprompter.
28 | 
29 |         Returns:
30 |             The parameters of the teleprompter.
31 |         """
32 |         return self.__dict__
33 | 
```

--------------------------------------------------------------------------------
/tests/reliability/input_formats/generated/test_markdown_1/inputs/input2.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "assertions": [
 3 |     "Each entry in the TOC should be a markdown link pointing to the corresponding section in the document.",
 4 |     "The hierarchy of the TOC should match the levels of headings in the input markdown content (e.g., H1 headings as top-level, H2 headings nested under H1, etc.).",
 5 |     "The TOC should include all headings from the input markdown content, in the order they appear.",
 6 |     "The TOC should not include any non-heading content from the input markdown document."
 7 |   ],
 8 |   "input": {
 9 |     "markdown_content": "# Introduction\n\nThis is the introduction section.\n\n## Overview\n\nAn overview of the document.\n\n### Details\n\nMore detailed information.\n\n#### Subdetails\n\nEven more detailed information.\n\n## Another Section\n\nContent of another section.\n\n### Subsection\n\nDetails of the subsection.\n\n```python\ndef example_function():\n    print(\"Hello, World!\")\n```\n\n# Conclusion\n\nFinal thoughts."
10 |   }
11 | }
12 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/modules/Predict.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.Predict
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.Predict
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - __call__
 9 |             - acall
10 |             - aforward
11 |             - batch
12 |             - deepcopy
13 |             - dump_state
14 |             - forward
15 |             - get_config
16 |             - get_lm
17 |             - inspect_history
18 |             - load
19 |             - load_state
20 |             - map_named_predictors
21 |             - named_parameters
22 |             - named_predictors
23 |             - named_sub_modules
24 |             - parameters
25 |             - predictors
26 |             - reset
27 |             - reset_copy
28 |             - save
29 |             - set_lm
30 |             - update_config
31 |         show_source: true
32 |         show_root_heading: true
33 |         heading_level: 2
34 |         docstring_style: google
35 |         show_root_full_path: true
36 |         show_object_full_path: false
37 |         separate_signature: false
38 |         inherited_members: true
39 | :::
40 | <!-- END_API_REF -->
41 | 
```

--------------------------------------------------------------------------------
/tests/evaluate/test_metrics.py:
--------------------------------------------------------------------------------

```python
 1 | # FILEPATH: /Users/ahle/repos/dspy/tests/evaluate/test_metrics.py
 2 | 
 3 | import dspy
 4 | from dspy.evaluate.metrics import answer_exact_match
 5 | from dspy.predict import Predict
 6 | 
 7 | 
 8 | def test_answer_exact_match_string():
 9 |     example = dspy.Example(
10 |         question="What is 1+1?",
11 |         answer="2",
12 |     ).with_inputs("question")
13 |     pred = Predict("question -> answer")
14 |     pred.answer = "2"
15 |     assert answer_exact_match(example, pred)
16 | 
17 | 
18 | def test_answer_exact_match_list():
19 |     example = dspy.Example(
20 |         question="What is 1+1?",
21 |         answer=["2", "two"],
22 |     ).with_inputs("question")
23 |     pred = Predict("question -> answer")
24 |     pred.answer = "2"
25 |     assert answer_exact_match(example, pred)
26 | 
27 | 
28 | def test_answer_exact_match_no_match():
29 |     example = dspy.Example(
30 |         question="What is 1+1?",
31 |         answer="2",
32 |     ).with_inputs("question")
33 |     pred = Predict("question -> answer")
34 |     pred.answer = "3"
35 |     assert not answer_exact_match(example, pred)
36 | 
```

--------------------------------------------------------------------------------
/dspy/teleprompt/vanilla.py:
--------------------------------------------------------------------------------

```python
 1 | import random
 2 | 
 3 | from dspy.teleprompt.teleprompt import Teleprompter
 4 | 
 5 | 
 6 | class LabeledFewShot(Teleprompter):
 7 |     def __init__(self, k=16):
 8 |         self.k = k
 9 | 
10 |     def compile(self, student, *, trainset, sample=True):
11 |         self.student = student.reset_copy()
12 |         self.trainset = trainset
13 | 
14 |         if len(self.trainset) == 0:
15 |             return self.student
16 | 
17 |         rng = random.Random(0)
18 | 
19 |         for predictor in self.student.predictors():
20 |             if sample:
21 |                 predictor.demos = rng.sample(self.trainset, min(self.k, len(self.trainset)))
22 |             else:
23 |                 predictor.demos = self.trainset[: min(self.k, len(self.trainset))]
24 | 
25 |         return self.student
26 | 
27 | 
28 | # NOTE: I believe templatev2 keeps rdemos as long as they have the last field.
29 | # This may change later, especially with the introduction of required vs optional fields.
30 | # NOTE: Since we're relying on downstream code to handle the demos, this sampling may be sub-sampled.
31 | 
```

--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------

```yaml
 1 | 
 2 | name: Bug Report
 3 | description: Report a bug in the project
 4 | title: "[Bug] "
 5 | labels: bug
 6 | body:
 7 |   - type: markdown
 8 |     attributes:
 9 |       value: |
10 |         ## 🐛 Bug Report
11 |         Please fill out all required fields to help us diagnose and fix the issue.
12 | 
13 |   - type: textarea
14 |     id: description
15 |     attributes:
16 |       label: "What happened?"
17 |       description: "Clearly describe the unexpected behavior."
18 |       placeholder: "Example: When I try to save a file, I get an error message..."
19 |     validations:
20 |       required: true
21 | 
22 |   - type: textarea
23 |     id: steps-to-reproduce
24 |     attributes:
25 |       label: "Steps to reproduce"
26 |       description: "Tell us how to reproduce the issue."
27 |       placeholder: "Please provide a code snippet or a github gist for reproducing purpose."
28 |     validations:
29 |       required: true
30 | 
31 |   - type: input
32 |     id: environment
33 |     attributes:
34 |       label: "DSPy version"
35 |       description: "Tell us your DSPy version."
36 |     validations:
37 |       required: true
38 | 
39 | 
```

--------------------------------------------------------------------------------
/docs/docs/learn/index.md:
--------------------------------------------------------------------------------

```markdown
 1 | ---
 2 | sidebar_position: 1
 3 | ---
 4 | 
 5 | # Learning DSPy: An Overview
 6 | 
 7 | DSPy exposes a very small API that you can learn quickly. However, building a new AI system is a more open-ended journey of iterative development, in which you compose the tools and design patterns of DSPy to optimize for _your_ objectives. The three stages of building AI systems in DSPy are:
 8 | 
 9 | 1) **DSPy Programming.** This is about defining your task, its constraints, exploring a few examples, and using that to inform your initial pipeline design.
10 | 
11 | 2) **DSPy Evaluation.** Once your system starts working, this is the stage where you collect an initial development set, define your DSPy metric, and use these to iterate on your system more systematically.
12 | 
13 | 3) **DSPy Optimization.** Once you have a way to evaluate your system, you use DSPy optimizers to tune the prompts or weights in your program.
14 | 
15 | We suggest learning and applying DSPy in this order. For example, it's unproductive to launch optimization runs using a poorly designed program or a bad metric.
16 | 
```

--------------------------------------------------------------------------------
/docs/docs/tutorials/rl_ai_program/index.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Experimental RL Optimization for DSPy
 2 | 
 3 | This section explores cutting-edge reinforcement learning (RL) approaches for optimizing DSPy programs. These experimental techniques represent the frontier of AI program optimization, combining the power of RL with DSPy's modular programming paradigm to achieve even better performance on complex tasks.
 4 | 
 5 | ## Advanced RL Optimization Techniques
 6 | 
 7 | ### [RL for Privacy-Conscious Delegation](../rl_papillon/index.ipynb)
 8 | Explore how reinforcement learning can optimize privacy-conscious AI systems. This tutorial demonstrates how RL agents can learn to balance task performance with privacy constraints, making intelligent decisions about when and how to delegate sensitive operations.
 9 | 
10 | ### [RL for Multi-Hop Research](../rl_multihop/index.ipynb)
11 | Learn to apply reinforcement learning to multi-hop reasoning tasks. This advanced tutorial shows how RL can optimize the search strategy in complex information retrieval scenarios, learning to navigate through multiple information sources more effectively.
12 | 
```

--------------------------------------------------------------------------------
/tests/reliability/generate/__main__.py:
--------------------------------------------------------------------------------

```python
 1 | import argparse
 2 | 
 3 | from tests.reliability.generate import generate_test_cases
 4 | 
 5 | if __name__ == "__main__":
 6 |     parser = argparse.ArgumentParser(
 7 |         description="Generate test cases by specifying configuration and input instructions."
 8 |     )
 9 |     parser.add_argument(
10 |         "-d", "--dst_path", type=str, required=True, help="Destination path where generated test cases will be saved."
11 |     )
12 |     parser.add_argument(
13 |         "-n", "--num_inputs", type=int, default=1, help="Number of input cases to generate (default: 1)."
14 |     )
15 |     parser.add_argument(
16 |         "-p", "--program_instructions", type=str, help="Additional instructions for the generated test program."
17 |     )
18 |     parser.add_argument(
19 |         "-i", "--input_instructions", type=str, help="Additional instructions for generating test inputs."
20 |     )
21 | 
22 |     args = parser.parse_args()
23 | 
24 |     generate_test_cases(
25 |         dst_path=args.dst_path,
26 |         num_inputs=args.num_inputs,
27 |         program_instructions=args.program_instructions,
28 |         input_instructions=args.input_instructions,
29 |     )
30 | 
```

--------------------------------------------------------------------------------
/dspy/utils/exceptions.py:
--------------------------------------------------------------------------------

```python
 1 | 
 2 | from dspy.signatures.signature import Signature
 3 | 
 4 | 
 5 | class AdapterParseError(Exception):
 6 |     """Exception raised when adapter cannot parse the LM response."""
 7 | 
 8 |     def __init__(
 9 |         self,
10 |         adapter_name: str,
11 |         signature: Signature,
12 |         lm_response: str,
13 |         message: str | None = None,
14 |         parsed_result: str | None = None,
15 |     ):
16 |         self.adapter_name = adapter_name
17 |         self.signature = signature
18 |         self.lm_response = lm_response
19 |         self.parsed_result = parsed_result
20 | 
21 |         message = f"{message}\n\n" if message else ""
22 |         message = (
23 |             f"{message}"
24 |             f"Adapter {adapter_name} failed to parse the LM response. \n\n"
25 |             f"LM Response: {lm_response} \n\n"
26 |             f"Expected to find output fields in the LM response: [{', '.join(signature.output_fields.keys())}] \n\n"
27 |         )
28 | 
29 |         if parsed_result is not None:
30 |             message += f"Actual output fields parsed from the LM response: [{', '.join(parsed_result.keys())}] \n\n"
31 | 
32 |         super().__init__(message)
33 | 
```

--------------------------------------------------------------------------------
/tests/reliability/input_formats/generated/test_markdown_1/schema.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "description": "The program is designed to generate a table of contents (TOC) from a given markdown document. It will parse the markdown content, identify headings, and create a hierarchical TOC based on the heading levels. The TOC will be presented in markdown format, with each entry linked to the corresponding section in the document.",
 3 |   "properties": {
 4 |     "markdown_content": {
 5 |       "desc": "The content of the markdown document from which the table of contents will be generated.",
 6 |       "description": "The content of the markdown document from which the table of contents will be generated.",
 7 |       "prefix": "Markdown Content:",
 8 |       "type": "string"
 9 |     },
10 |     "table_of_contents": {
11 |       "desc": "The content of the markdown document from which the table of contents will be generated.",
12 |       "description": "The content of the markdown document from which the table of contents will be generated.",
13 |       "prefix": "Table Of Contents:",
14 |       "type": "string"
15 |     }
16 |   },
17 |   "required": ["markdown_content", "table_of_contents"],
18 |   "type": "object"
19 | }
20 | 
```

--------------------------------------------------------------------------------
/.github/.tmp/.generated-actions/run-pypi-publish-in-docker-container/action.yml:
--------------------------------------------------------------------------------

```yaml
1 | {"name": "🏃", "description": "Run Docker container to upload Python distribution packages to PyPI", "inputs": {"user": {"description": "PyPI user", "required": false}, "password": {"description": "Password for your PyPI user or an access token", "required": false}, "repository-url": {"description": "The repository URL to use", "required": false}, "packages-dir": {"description": "The target directory for distribution", "required": false}, "verify-metadata": {"description": "Check metadata before uploading", "required": false}, "skip-existing": {"description": "Do not fail if a Python package distribution exists in the target package index", "required": false}, "verbose": {"description": "Show verbose output.", "required": false}, "print-hash": {"description": "Show hash values of files to be uploaded", "required": false}, "attestations": {"description": "[EXPERIMENTAL] Enable experimental support for PEP 740 attestations. Only works with PyPI and TestPyPI via Trusted Publishing.", "required": false}}, "runs": {"using": "docker", "image": "docker://ghcr.io/pypa/gh-action-pypi-publish:release-v1"}}
```

--------------------------------------------------------------------------------
/dspy/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.predict import *
 2 | from dspy.primitives import *
 3 | from dspy.retrievers import *
 4 | from dspy.signatures import *
 5 | from dspy.teleprompt import *
 6 | 
 7 | from dspy.evaluate import Evaluate  # isort: skip
 8 | from dspy.clients import *  # isort: skip
 9 | from dspy.adapters import Adapter, ChatAdapter, JSONAdapter, XMLAdapter, TwoStepAdapter, Image, Audio, History, Type, Tool, ToolCalls, Code  # isort: skip
10 | from dspy.utils.logging_utils import configure_dspy_loggers, disable_logging, enable_logging
11 | from dspy.utils.asyncify import asyncify
12 | from dspy.utils.syncify import syncify
13 | from dspy.utils.saving import load
14 | from dspy.streaming.streamify import streamify
15 | from dspy.utils.usage_tracker import track_usage
16 | 
17 | from dspy.dsp.utils.settings import settings
18 | from dspy.dsp.colbertv2 import ColBERTv2
19 | from dspy.clients import DSPY_CACHE
20 | from dspy.__metadata__ import __name__, __version__, __description__, __url__, __author__, __author_email__
21 | 
22 | configure_dspy_loggers(__name__)
23 | 
24 | # Singleton definitions and aliasing
25 | configure = settings.configure
26 | context = settings.context
27 | 
28 | BootstrapRS = BootstrapFewShotWithRandomSearch
29 | 
30 | cache = DSPY_CACHE
31 | 
```

--------------------------------------------------------------------------------
/dspy/utils/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | import os
 2 | 
 3 | import requests
 4 | 
 5 | from dspy.streaming.messages import StatusMessage, StatusMessageProvider
 6 | from dspy.utils import exceptions
 7 | from dspy.utils.annotation import experimental
 8 | from dspy.utils.callback import BaseCallback, with_callbacks
 9 | from dspy.utils.dummies import DummyLM, DummyVectorizer, dummy_rm
10 | from dspy.utils.inspect_history import pretty_print_history
11 | from dspy.utils.syncify import syncify
12 | 
13 | 
14 | def download(url):
15 |     filename = os.path.basename(url)
16 |     remote_size = int(requests.head(url, allow_redirects=True).headers.get("Content-Length", 0))
17 |     local_size = os.path.getsize(filename) if os.path.exists(filename) else 0
18 | 
19 |     if local_size != remote_size:
20 |         print(f"Downloading '{filename}'...")
21 |         with requests.get(url, stream=True) as r, open(filename, "wb") as f:
22 |             for chunk in r.iter_content(chunk_size=8192):
23 |                 f.write(chunk)
24 | 
25 | 
26 | __all__ = [
27 |     "download",
28 |     "exceptions",
29 |     "BaseCallback",
30 |     "with_callbacks",
31 |     "DummyLM",
32 |     "DummyVectorizer",
33 |     "dummy_rm",
34 |     "experimental",
35 |     "StatusMessage",
36 |     "StatusMessageProvider",
37 |     "pretty_print_history",
38 | ]
39 | 
```

--------------------------------------------------------------------------------
/docs/docs/api/optimizers/SIMBA.md:
--------------------------------------------------------------------------------

```markdown
 1 | # dspy.SIMBA
 2 | 
 3 | <!-- START_API_REF -->
 4 | ::: dspy.SIMBA
 5 |     handler: python
 6 |     options:
 7 |         members:
 8 |             - compile
 9 |             - get_params
10 |         show_source: true
11 |         show_root_heading: true
12 |         heading_level: 2
13 |         docstring_style: google
14 |         show_root_full_path: true
15 |         show_object_full_path: false
16 |         separate_signature: false
17 |         inherited_members: true
18 | <!-- END_API_REF -->
19 | 
20 | ## Example Usage
21 | 
22 | ```python
23 | optimizer = dspy.SIMBA(metric=your_metric)
24 | optimized_program = optimizer.compile(your_program, trainset=your_trainset)
25 | 
26 | # Save optimize program for future use
27 | optimized_program.save(f"optimized.json")
28 | ```
29 | 
30 | ## How `SIMBA` works
31 | SIMBA (Stochastic Introspective Mini-Batch Ascent) is a DSPy optimizer that uses the LLM to analyze its own performance and generate improvement rules. It samples mini-batches, identifies challenging examples with high output variability, then either creates self-reflective rules or adds successful examples as demonstrations. See [this great blog post](https://blog.mariusvach.com/posts/dspy-simba) from [Marius](https://x.com/rasmus1610) for more details.
```

--------------------------------------------------------------------------------
/.github/workflows/docs-push.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: Update DSPy Docs
 2 | 
 3 | on:
 4 |   push:
 5 |     branches:
 6 |       - main
 7 |     paths:
 8 |       - "docs/**"
 9 |   pull_request:
10 |     paths:
11 |       - "docs/**"
12 | 
13 | jobs:
14 |   build-test:
15 |     if: github.event_name == 'pull_request'
16 |     runs-on: ubuntu-latest
17 |     steps:
18 |       - name: Checkout code
19 |         uses: actions/checkout@v3
20 |       - name: Set up Node.js
21 |         uses: actions/setup-node@v3
22 |         with:
23 |           node-version: "18"
24 |       - name: Install dependencies and build
25 |         run: |
26 |           cd docs
27 |           pip install -r requirements.txt
28 |           mkdocs build
29 | 
30 |   update-docs-subtree:
31 |     if: github.event_name == 'push' && github.repository == 'stanfordnlp/dspy'
32 |     runs-on: ubuntu-latest
33 |     steps:
34 |       - uses: actions/checkout@v3
35 |         with:
36 |           fetch-depth: 0
37 |       - name: Push docs to separate repo
38 |         uses: cpina/github-action-push-to-another-repository@main
39 |         env:
40 |           API_TOKEN_GITHUB: ${{ secrets.GH_PAT }}
41 |         with:
42 |           source-directory: "docs"
43 |           destination-github-username: "krypticmouse"
44 |           destination-repository-name: "dspy-docs"
45 |           user-email: [email protected]
46 |           target-branch: master
47 | 
```

--------------------------------------------------------------------------------
/tests/docs/test_mkdocs_links.py:
--------------------------------------------------------------------------------

```python
 1 | import os
 2 | 
 3 | 
 4 | def test_nav_files_exist():
 5 |     # Read mkdocs.yml
 6 |     docs_dir = os.path.join(os.path.dirname(__file__), "..", "..", "docs", "docs")
 7 |     yaml_path = os.path.join(os.path.dirname(__file__), "..", "..", "docs", "mkdocs.yml")
 8 | 
 9 |     # Read file and extract nav section
10 |     with open(yaml_path) as f:
11 |         content = f.read()
12 | 
13 |     # Find nav section
14 |     nav_start = content.find("nav:")
15 |     lines = content[nav_start:].split("\n")
16 | 
17 |     # Get markdown files
18 |     md_files = []
19 |     for line in lines:
20 |         if ".md" in line:
21 |             # Extract the markdown filename and clean it up
22 |             md_file = line.strip().split(":")[-1].strip()
23 |             # Remove list markers and quotes
24 |             md_file = md_file.lstrip("- ").strip("'").strip('"')
25 |             if md_file.endswith(".md"):
26 |                 md_files.append(md_file)
27 | 
28 |     # Check if files exist
29 |     missing = []
30 |     for file in md_files:
31 |         if not os.path.exists(os.path.join(docs_dir, file)):
32 |             missing.append(file)
33 | 
34 |     print("\nChecking files in:", docs_dir)
35 |     print("Found MD files:", md_files)
36 |     print("Missing files:", missing)
37 | 
38 |     assert not missing, f"Missing files: {missing}"
39 | 
```

--------------------------------------------------------------------------------
/dspy/teleprompt/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.teleprompt.avatar_optimizer import AvatarOptimizer
 2 | from dspy.teleprompt.bettertogether import BetterTogether
 3 | from dspy.teleprompt.bootstrap import BootstrapFewShot
 4 | from dspy.teleprompt.bootstrap_finetune import BootstrapFinetune
 5 | from dspy.teleprompt.bootstrap_trace import bootstrap_trace_data
 6 | from dspy.teleprompt.copro_optimizer import COPRO
 7 | from dspy.teleprompt.ensemble import Ensemble
 8 | from dspy.teleprompt.infer_rules import InferRules
 9 | from dspy.teleprompt.knn_fewshot import KNNFewShot
10 | from dspy.teleprompt.mipro_optimizer_v2 import MIPROv2
11 | from dspy.teleprompt.random_search import BootstrapFewShotWithRandomSearch
12 | from dspy.teleprompt.simba import SIMBA
13 | from dspy.teleprompt.teleprompt import Teleprompter
14 | from dspy.teleprompt.teleprompt_optuna import BootstrapFewShotWithOptuna
15 | from dspy.teleprompt.vanilla import LabeledFewShot
16 | 
17 | from .gepa.gepa import GEPA
18 | 
19 | __all__ = [
20 |     "AvatarOptimizer",
21 |     "BetterTogether",
22 |     "BootstrapFewShot",
23 |     "BootstrapFinetune",
24 |     "COPRO",
25 |     "Ensemble",
26 |     "GEPA",
27 |     "KNNFewShot",
28 |     "MIPROv2",
29 |     "BootstrapFewShotWithRandomSearch",
30 |     "BootstrapFewShotWithOptuna",
31 |     "LabeledFewShot",
32 |     "InferRules",
33 |     "SIMBA",
34 |     "bootstrap_trace_data",
35 | ]
36 | 
```

--------------------------------------------------------------------------------
/tests/reliability/complex_types/generated/test_many_types_1/inputs/input1.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "assertions": [
 3 |     "The 'processedTupleField' should be a tuple containing a string and a number.",
 4 |     "The 'processedEnumField' should be one of the allowed enum values: 'option1', 'option2', or 'option3'.",
 5 |     "The 'processedDatetimeField' should be a date-time",
 6 |     "The 'processedLiteralField' should be exactly 'literalValue'.",
 7 |     "The 'processedObjectField' should contain 'subField1' (string), 'subField2' (number), and an additional boolean field 'additionalField'.",
 8 |     "The 'processedNestedObjectField' should contain 'tupleField' as a tuple with a string and float, 'enumField' (one of the allowed enum values), 'datetimeField' (string formatted as date-time), 'literalField' (exactly 'literalValue'), and an additional boolean field 'additionalField'."
 9 |   ],
10 |   "input": {
11 |     "datetimeField": "2023-10-12T07:20:50.52Z",
12 |     "enumField": "option1",
13 |     "literalField": "literalValue",
14 |     "nestedObjectField": {
15 |       "datetimeField": "2023-10-12T07:20:50.52Z",
16 |       "enumField": "option2",
17 |       "literalField": "literalValue",
18 |       "tupleField": ["nestedString", 789]
19 |     },
20 |     "objectField": {
21 |       "subField1": "example",
22 |       "subField2": 456
23 |     },
24 |     "tupleField": ["string1", 123]
25 |   }
26 | }
27 | 
```

--------------------------------------------------------------------------------
/.github/workflows/precommits_check.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: Pre-commit checks
 2 | on:
 3 |   workflow_dispatch:
 4 | 
 5 | jobs:
 6 |   pre-commit-checks:
 7 |     runs-on: ubuntu-latest
 8 |     steps:
 9 |       - uses: actions/checkout@v3
10 |       - name: Set up Python
11 |         uses: actions/setup-python@v4
12 |         with:
13 |           python-version: "3.10"
14 |           cache: "pip"
15 |       - name: Check Pull Request Title
16 |         uses: Slashgear/action-check-pr-title@main
17 |         with:
18 |           regexp: '(break|build|ci|docs|feat|fix|perf|refactor|style|test|ops|hotfix|release|maint|init|enh|revert)\([a-z,A-Z,0-9,\-,\_,\/,:]+\)(:)\s{1}([\w\s]+)' # Regex the title should match.
19 |       - name: Getting changed files list
20 |         id: files
21 |         uses: jitterbit/get-changed-files@master
22 |       - name: Checking changed files
23 |         shell: bash
24 |         run: |
25 |           echo "Changed files"
26 |           echo ${{ steps.files.outputs.all }}
27 |           echo "GitHub Client version"
28 |           echo $(gh --version)
29 |       - name: Pre-Commit Checks
30 |         run: |
31 |           python -m pip install --upgrade pip
32 |           pip install pre-commit
33 |           echo "Running pre-commit scans:"
34 |           # adding log display in case of pre-commit errors
35 |           pre-commit run -v --files ${{ steps.files.outputs.all }}
36 |         shell: bash
37 | 
```

--------------------------------------------------------------------------------
/tests/reliability/generate/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | import os
 2 | from typing import List, Optional
 3 | 
 4 | from tests.reliability.generate.utils import (
 5 |     GeneratedTestCase,
 6 |     generate_test_inputs,
 7 |     generate_test_program,
 8 |     load_generated_cases,
 9 |     load_generated_program,
10 | )
11 | 
12 | 
13 | def generate_test_cases(
14 |     dst_path: str,
15 |     num_inputs: int = 1,
16 |     program_instructions: Optional[str] = None,
17 |     input_instructions: Optional[str] = None,
18 | ) -> list[GeneratedTestCase]:
19 |     os.makedirs(dst_path, exist_ok=True)
20 |     if _directory_contains_program(dst_path):
21 |         print(f"Found an existing test program at path {dst_path}. Generating new" f" test inputs for this program.")
22 |     else:
23 |         print("Generating a new test program and test inputs")
24 |         generate_test_program(
25 |             dst_path=dst_path,
26 |             additional_instructions=program_instructions,
27 |         )
28 |     generate_test_inputs(
29 |         dst_path=os.path.join(dst_path, "inputs"),
30 |         program_path=os.path.join(dst_path, "program.py"),
31 |         num_inputs=num_inputs,
32 |         additional_instructions=input_instructions,
33 |     )
34 |     return load_generated_cases(dir_path=dst_path)
35 | 
36 | 
37 | def _directory_contains_program(dir_path: str) -> bool:
38 |     return any(file == "program.py" for file in os.listdir(dir_path))
39 | 
```

--------------------------------------------------------------------------------
/tests/predict/test_multi_chain_comparison.py:
--------------------------------------------------------------------------------

```python
 1 | import dspy
 2 | from dspy.utils.dummies import DummyLM
 3 | 
 4 | 
 5 | class BasicQA(dspy.Signature):
 6 |     """Answer questions with short factoid answers."""
 7 | 
 8 |     question = dspy.InputField()
 9 |     answer = dspy.OutputField(desc="often between 1 and 5 words")
10 | 
11 | 
12 | # Example completions generated by a model for reference
13 | completions = [
14 |     dspy.Prediction(
15 |         rationale="I recall that during clear days, the sky often appears this color.",
16 |         answer="blue",
17 |     ),
18 |     dspy.Prediction(
19 |         rationale="Based on common knowledge, I believe the sky is typically seen as this color.",
20 |         answer="green",
21 |     ),
22 |     dspy.Prediction(
23 |         rationale="From images and depictions in media, the sky is frequently represented with this hue.",
24 |         answer="blue",
25 |     ),
26 | ]
27 | 
28 | 
29 | def test_basic_example():
30 |     # Pass signature to MultiChainComparison module
31 |     compare_answers = dspy.MultiChainComparison(BasicQA)
32 | 
33 |     # Call the MultiChainComparison on the completions
34 |     question = "What is the color of the sky?"
35 |     lm = DummyLM([{"rationale": "my rationale", "answer": "blue"}])
36 |     dspy.settings.configure(lm=lm)
37 |     final_pred = compare_answers(completions, question=question)
38 | 
39 |     assert final_pred.rationale == "my rationale"
40 |     assert final_pred.answer == "blue"
41 | 
```

--------------------------------------------------------------------------------
/tests/teleprompt/test_random_search.py:
--------------------------------------------------------------------------------

```python
 1 | import dspy
 2 | from dspy import Example
 3 | from dspy.predict import Predict
 4 | from dspy.teleprompt import BootstrapFewShotWithRandomSearch
 5 | from dspy.utils.dummies import DummyLM
 6 | 
 7 | 
 8 | class SimpleModule(dspy.Module):
 9 |     def __init__(self, signature):
10 |         super().__init__()
11 |         self.predictor = Predict(signature)
12 | 
13 |     def forward(self, **kwargs):
14 |         return self.predictor(**kwargs)
15 | 
16 | 
17 | def simple_metric(example, prediction, trace=None):
18 |     return example.output == prediction.output
19 | 
20 | 
21 | def test_basic_workflow():
22 |     """Test to ensure the basic compile flow runs without errors."""
23 |     student = SimpleModule("input -> output")
24 |     teacher = SimpleModule("input -> output")
25 | 
26 |     lm = DummyLM(
27 |         [
28 |             "Initial thoughts",
29 |             "Finish[blue]",  # Expected output for both training and validation
30 |         ]
31 |     )
32 |     dspy.settings.configure(lm=lm)
33 | 
34 |     optimizer = BootstrapFewShotWithRandomSearch(metric=simple_metric, max_bootstrapped_demos=1, max_labeled_demos=1)
35 |     trainset = [
36 |         Example(input="What is the color of the sky?", output="blue").with_inputs("input"),
37 |         Example(input="What does the fox say?", output="Ring-ding-ding-ding-dingeringeding!").with_inputs("input"),
38 |     ]
39 |     optimizer.compile(student, teacher=teacher, trainset=trainset)
40 | 
```

--------------------------------------------------------------------------------
/tests/reliability/complex_types/generated/test_nesting_2/inputs/input1.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "assertions": [
 3 |     "The output should contain a 'customer_summary' object with the required properties: 'customer_id', 'customer_type', and 'value'.",
 4 |     "'customer_summary.customer_id' should be a string and match the 'customer_id' from the input.",
 5 |     "'customer_summary.customer_type' should be an object containing 'is_premium' (a boolean) and 'category' (a string).",
 6 |     "'customer_summary.value' should be a string and reflect the 'value' from the input's customer details.",
 7 |     "The output should contain a 'transaction_summary' object with the required properties: 'transaction_id', 'total_amount', and 'details'.",
 8 |     "'transaction_summary.transaction_id' should be a string and match the 'transaction_id' from the input.",
 9 |     "'transaction_summary.total_amount' should be a number and match the 'amount' from the input.",
10 |     "'transaction_summary.details' should be an object containing 'value' (a number) and 'timestamp' (a date-time value)."
11 |   ],
12 |   "input": {
13 |     "customer": {
14 |       "customer_id": "C12345",
15 |       "customer_type": true,
16 |       "details": {
17 |         "age": 30,
18 |         "value": "Gold"
19 |       }
20 |     },
21 |     "transaction": {
22 |       "amount": 150.75,
23 |       "details": {
24 |         "timestamp": "2023-10-01T10:00:00Z",
25 |         "value": 150.75
26 |       },
27 |       "transaction_id": "T98765"
28 |     }
29 |   }
30 | }
31 | 
```

--------------------------------------------------------------------------------
/dspy/teleprompt/ensemble.py:
--------------------------------------------------------------------------------

```python
 1 | import random
 2 | 
 3 | from dspy.teleprompt.teleprompt import Teleprompter
 4 | 
 5 | """
 6 | TODO: The EnsembledProgram should actually imitate the structure of the individual programs (IF they are all compatible). This allows compiling with an ensemble program as a (singular) teacher. Basically the top majority-compatible trace will end up being used, if dspy.majority is the reduce_fn.
 7 | """
 8 | 
 9 | 
10 | class Ensemble(Teleprompter):
11 |     def __init__(self, *, reduce_fn=None, size=None, deterministic=False):
12 |         """A common reduce_fn is dspy.majority."""
13 | 
14 |         assert deterministic is False, "TODO: Implement example hashing for deterministic ensemble."
15 | 
16 |         self.reduce_fn = reduce_fn
17 |         self.size = size
18 |         self.deterministic = deterministic
19 | 
20 |     def compile(self, programs):
21 |         size = self.size
22 |         reduce_fn = self.reduce_fn
23 | 
24 |         import dspy
25 | 
26 |         class EnsembledProgram(dspy.Module):
27 |             def __init__(self):
28 |                 super().__init__()
29 |                 self.programs = programs
30 | 
31 |             def forward(self, *args, **kwargs):
32 |                 programs = random.sample(self.programs, size) if size else self.programs
33 |                 outputs = [prog(*args, **kwargs) for prog in programs]
34 | 
35 |                 if reduce_fn:
36 |                     return reduce_fn(outputs)
37 | 
38 |                 return outputs
39 | 
40 |         return EnsembledProgram()
41 | 
```

--------------------------------------------------------------------------------
/dspy/utils/hasher.py:
--------------------------------------------------------------------------------

```python
 1 | from pickle import dumps
 2 | from typing import Any
 3 | 
 4 | import xxhash
 5 | 
 6 | """
 7 | The following class was pulled from the `datasets` package from Hugging Face.
 8 | The reason for vendoring this code is to avoid a hard dependency on `datasets`,
 9 | which is a large package that is not needed for the majority of use cases.
10 | 
11 | License: Apache License 2.0
12 | Author: Hugging Face Inc.
13 | URL: https://github.com/huggingface/datasets/blob/fa73ab472eecf9136a3daf7a0fbff16a3dffa7a6/src/datasets/fingerprint.py#L170
14 | Changes: 2025-08-10 - Ran ruff to format the code to DSPy styles.
15 | """
16 | class Hasher:
17 |     """Hasher that accepts python objects as inputs."""
18 | 
19 |     dispatch: dict = {}
20 | 
21 |     def __init__(self):
22 |         self.m = xxhash.xxh64()
23 | 
24 |     @classmethod
25 |     def hash_bytes(cls, value: bytes | list[bytes]) -> str:
26 |         value = [value] if isinstance(value, bytes) else value
27 |         m = xxhash.xxh64()
28 |         for x in value:
29 |             m.update(x)
30 |         return m.hexdigest()
31 | 
32 |     @classmethod
33 |     def hash(cls, value: Any) -> str:
34 |         return cls.hash_bytes(dumps(value))
35 | 
36 |     def update(self, value: Any) -> None:
37 |         header_for_update = f"=={type(value)}=="
38 |         value_for_update = self.hash(value)
39 |         self.m.update(header_for_update.encode("utf8"))
40 |         self.m.update(value_for_update.encode("utf-8"))
41 | 
42 |     def hexdigest(self) -> str:
43 |         return self.m.hexdigest()
44 | 
```

--------------------------------------------------------------------------------
/tests/datasets/test_dataset.py:
--------------------------------------------------------------------------------

```python
 1 | import tempfile
 2 | import uuid
 3 | 
 4 | import pytest
 5 | 
 6 | from dspy import Example
 7 | from dspy.datasets.dataset import Dataset
 8 | 
 9 | dummy_data = """content,question,answer
10 | "This is content 1","What is this?","This is answer 1"
11 | "This is content 2","What is that?","This is answer 2"
12 | """
13 | 
14 | 
15 | class CSVDataset(Dataset):
16 |     def __init__(self, file_path, input_keys=None, **kwargs) -> None:
17 |         import pandas as pd
18 |         super().__init__(input_keys=input_keys, **kwargs)
19 |         df = pd.read_csv(file_path)
20 |         data = df.to_dict(orient="records")
21 |         self._train = [
22 |             Example(**record, dspy_uuid=str(uuid.uuid4()), dspy_split="train").with_inputs(*input_keys)
23 |             for record in data[:1]
24 |         ]
25 |         self._dev = [
26 |             Example(**record, dspy_uuid=str(uuid.uuid4()), dspy_split="dev").with_inputs(*input_keys)
27 |             for record in data[1:2]
28 |         ]
29 | 
30 | 
31 | @pytest.fixture
32 | def csv_file():
33 |     with tempfile.NamedTemporaryFile(mode="w+", suffix=".csv") as tmp_file:
34 |         tmp_file.write(dummy_data)
35 |         tmp_file.flush()
36 |         yield tmp_file.name
37 | 
38 | 
39 | @pytest.mark.extra
40 | def test_input_keys(csv_file):
41 |     dataset = CSVDataset(csv_file, input_keys=["content", "question"])
42 |     assert dataset.train is not None
43 | 
44 |     for example in dataset.train:
45 |         inputs = example.inputs()
46 |         assert inputs is not None
47 |         assert "content" in inputs
48 |         assert "question" in inputs
49 |         assert set(example._input_keys) == {"content", "question"}
50 | 
```

--------------------------------------------------------------------------------
/dspy/utils/langchain_tool.py:
--------------------------------------------------------------------------------

```python
 1 | from typing import TYPE_CHECKING, Any
 2 | 
 3 | from dspy.adapters.types.tool import Tool, convert_input_schema_to_tool_args
 4 | 
 5 | if TYPE_CHECKING:
 6 |     from langchain.tools import BaseTool
 7 | 
 8 | 
 9 | 
10 | def convert_langchain_tool(tool: "BaseTool") -> Tool:
11 |     """Build a DSPy tool from a LangChain tool.
12 |     
13 |     This function converts a LangChain tool (either created with @tool decorator
14 |     or by subclassing BaseTool) into a DSPy Tool.
15 | 
16 |     Args:
17 |         tool: The LangChain tool to convert.
18 | 
19 |     Returns:
20 |         A DSPy Tool object.
21 |     """
22 |     async def func(**kwargs):
23 |         try:
24 |             result = await tool.ainvoke(kwargs)
25 |             return result
26 |         except Exception as e:
27 |             raise RuntimeError(f"Failed to call LangChain tool {tool.name}: {e!s}")
28 | 
29 |     # Get args_schema from the tool
30 |     # https://python.langchain.com/api_reference/core/tools/langchain_core.tools.base.BaseTool.html#langchain_core.tools.base.BaseTool.args_schema
31 |     args_schema = tool.args_schema
32 |     args, _, arg_desc = convert_input_schema_to_tool_args(args_schema.model_json_schema())
33 | 
34 |     # The args_schema of Langchain tool is a pydantic model, so we can get the type hints from the model fields
35 |     arg_types = {
36 |         key: field.annotation if field.annotation is not None else Any
37 |         for key, field in args_schema.model_fields.items()
38 |     }
39 | 
40 |     return Tool(
41 |         func=func,
42 |         name=tool.name,
43 |         desc=tool.description,
44 |         args=args,
45 |         arg_types=arg_types,
46 |         arg_desc=arg_desc
47 |     )
48 | 
```

--------------------------------------------------------------------------------
/tests/predict/test_aggregation.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.evaluate import normalize_text
 2 | from dspy.predict.aggregation import majority
 3 | from dspy.primitives.prediction import Completions, Prediction
 4 | 
 5 | 
 6 | def test_majority_with_prediction():
 7 |     prediction = Prediction.from_completions([{"answer": "2"}, {"answer": "2"}, {"answer": "3"}])
 8 |     result = majority(prediction)
 9 |     assert result.completions[0]["answer"] == "2"
10 | 
11 | 
12 | def test_majority_with_completions():
13 |     completions = Completions([{"answer": "2"}, {"answer": "2"}, {"answer": "3"}])
14 |     result = majority(completions)
15 |     assert result.completions[0]["answer"] == "2"
16 | 
17 | 
18 | def test_majority_with_list():
19 |     completions = [{"answer": "2"}, {"answer": "2"}, {"answer": "3"}]
20 |     result = majority(completions)
21 |     assert result.completions[0]["answer"] == "2"
22 | 
23 | 
24 | def test_majority_with_normalize():
25 |     completions = [{"answer": "2"}, {"answer": " 2"}, {"answer": "3"}]
26 |     result = majority(completions, normalize=normalize_text)
27 |     assert result.completions[0]["answer"] == "2"
28 | 
29 | 
30 | def test_majority_with_field():
31 |     completions = [
32 |         {"answer": "2", "other": "1"},
33 |         {"answer": "2", "other": "1"},
34 |         {"answer": "3", "other": "2"},
35 |     ]
36 |     result = majority(completions, field="other")
37 |     assert result.completions[0]["other"] == "1"
38 | 
39 | 
40 | def test_majority_with_no_majority():
41 |     completions = [{"answer": "2"}, {"answer": "3"}, {"answer": "4"}]
42 |     result = majority(completions)
43 |     assert result.completions[0]["answer"] == "2"  # The first completion is returned in case of a tie
44 | 
```

--------------------------------------------------------------------------------
/tests/conftest.py:
--------------------------------------------------------------------------------

```python
 1 | import copy
 2 | import os
 3 | 
 4 | import pytest
 5 | 
 6 | from tests.test_utils.server import litellm_test_server, read_litellm_test_server_request_logs  # noqa: F401
 7 | 
 8 | SKIP_DEFAULT_FLAGS = ["reliability", "extra", "llm_call"]
 9 | 
10 | 
11 | @pytest.fixture(autouse=True)
12 | def clear_settings():
13 |     """Ensures that the settings are cleared after each test."""
14 | 
15 |     yield
16 | 
17 |     import dspy
18 |     from dspy.dsp.utils.settings import DEFAULT_CONFIG
19 | 
20 |     dspy.settings.configure(**copy.deepcopy(DEFAULT_CONFIG), inherit_config=False)
21 | 
22 | 
23 | @pytest.fixture
24 | def anyio_backend():
25 |     return "asyncio"
26 | 
27 | 
28 | # Taken from: https://gist.github.com/justinmklam/b2aca28cb3a6896678e2e2927c6b6a38
29 | def pytest_addoption(parser):
30 |     for flag in SKIP_DEFAULT_FLAGS:
31 |         parser.addoption(
32 |             f"--{flag}",
33 |             action="store_true",
34 |             default=False,
35 |             help=f"run {flag} tests",
36 |         )
37 | 
38 | 
39 | def pytest_configure(config):
40 |     for flag in SKIP_DEFAULT_FLAGS:
41 |         config.addinivalue_line("markers", flag)
42 | 
43 | 
44 | def pytest_collection_modifyitems(config, items):
45 |     for flag in SKIP_DEFAULT_FLAGS:
46 |         if config.getoption(f"--{flag}"):
47 |             return
48 | 
49 |         skip_mark = pytest.mark.skip(reason=f"need --{flag} option to run")
50 |         for item in items:
51 |             if flag in item.keywords:
52 |                 item.add_marker(skip_mark)
53 | 
54 | 
55 | @pytest.fixture
56 | def lm_for_test():
57 |     model = os.environ.get("LM_FOR_TEST", None)
58 |     if model is None:
59 |         pytest.skip("LM_FOR_TEST is not set in the environment variables")
60 |     return model
61 | 
```

--------------------------------------------------------------------------------
/tests/reliability/input_formats/generated/test_markdown_1/program.py:
--------------------------------------------------------------------------------

```python
 1 | ### Input models ###
 2 | 
 3 | 
 4 | from pydantic import BaseModel, Field
 5 | 
 6 | 
 7 | class ProgramInputs(BaseModel):
 8 |     markdown_content: str = Field(
 9 |         ...,
10 |         description="The content of the markdown document from which the table of contents will be generated.",
11 |     )
12 | 
13 | 
14 | ### Output models ###
15 | 
16 | 
17 | from pydantic import BaseModel, Field
18 | 
19 | 
20 | class ProgramOutputs(BaseModel):
21 |     table_of_contents: str = Field(..., description="The generated table of contents in markdown format.")
22 | 
23 | 
24 | ### Program definition ###
25 | 
26 | import dspy
27 | 
28 | 
29 | class BaseSignature(dspy.Signature):
30 |     """
31 |     The program is designed to generate a table of contents (TOC) from a given markdown document. It will parse the markdown content, identify headings, and create a hierarchical TOC based on the heading levels. The TOC will be presented in markdown format, with each entry linked to the corresponding section in the document.
32 |     """
33 | 
34 | 
35 | program_signature = BaseSignature
36 | for input_field_name, input_field in ProgramInputs.model_fields.items():
37 |     program_signature = program_signature.append(
38 |         name=input_field_name,
39 |         field=dspy.InputField(description=input_field.description),
40 |         type_=input_field.annotation,
41 |     )
42 | for output_field_name, output_field in ProgramOutputs.model_fields.items():
43 |     program_signature = program_signature.append(
44 |         name=output_field_name,
45 |         field=dspy.OutputField(description=input_field.description),
46 |         type_=output_field.annotation,
47 |     )
48 | 
49 | program = dspy.ChainOfThought(program_signature)
50 | 
```

--------------------------------------------------------------------------------
/dspy/utils/mcp.py:
--------------------------------------------------------------------------------

```python
 1 | from typing import TYPE_CHECKING, Any
 2 | 
 3 | from dspy.adapters.types.tool import Tool, convert_input_schema_to_tool_args
 4 | 
 5 | if TYPE_CHECKING:
 6 |     import mcp
 7 | 
 8 | 
 9 | def _convert_mcp_tool_result(call_tool_result: "mcp.types.CallToolResult") -> str | list[Any]:
10 |     from mcp.types import TextContent
11 | 
12 |     text_contents: list[TextContent] = []
13 |     non_text_contents = []
14 |     for content in call_tool_result.content:
15 |         if isinstance(content, TextContent):
16 |             text_contents.append(content)
17 |         else:
18 |             non_text_contents.append(content)
19 | 
20 |     tool_content = [content.text for content in text_contents]
21 |     if len(text_contents) == 1:
22 |         tool_content = tool_content[0]
23 | 
24 |     if call_tool_result.isError:
25 |         raise RuntimeError(f"Failed to call a MCP tool: {tool_content}")
26 | 
27 |     return tool_content or non_text_contents
28 | 
29 | 
30 | def convert_mcp_tool(session: "mcp.ClientSession", tool: "mcp.types.Tool") -> Tool:
31 |     """Build a DSPy tool from an MCP tool.
32 | 
33 |     Args:
34 |         session: The MCP session to use.
35 |         tool: The MCP tool to convert.
36 | 
37 |     Returns:
38 |         A dspy Tool object.
39 |     """
40 |     args, arg_types, arg_desc = convert_input_schema_to_tool_args(tool.inputSchema)
41 | 
42 |     # Convert the MCP tool and Session to a single async method
43 |     async def func(*args, **kwargs):
44 |         result = await session.call_tool(tool.name, arguments=kwargs)
45 |         return _convert_mcp_tool_result(result)
46 | 
47 |     return Tool(func=func, name=tool.name, desc=tool.description, args=args, arg_types=arg_types, arg_desc=arg_desc)
48 | 
```

--------------------------------------------------------------------------------
/tests/teleprompt/test_utils.py:
--------------------------------------------------------------------------------

```python
 1 | from unittest.mock import Mock
 2 | 
 3 | import dspy
 4 | from dspy.teleprompt.utils import eval_candidate_program
 5 | 
 6 | 
 7 | class DummyModule(dspy.Module):
 8 |     def __init__(self):
 9 |         super().__init__()
10 | 
11 |     def forward(self, **kwargs):
12 |         pass
13 | 
14 | 
15 | def test_eval_candidate_program_full_trainset():
16 |     trainset = [1, 2, 3, 4, 5]
17 |     candidate_program = DummyModule()
18 |     evaluate = Mock(return_value=0)
19 |     batch_size = 10
20 | 
21 |     result = eval_candidate_program(batch_size, trainset, candidate_program, evaluate)
22 | 
23 |     evaluate.assert_called_once()
24 |     _, called_kwargs = evaluate.call_args
25 |     assert len(called_kwargs["devset"]) == len(trainset)
26 |     assert called_kwargs["callback_metadata"] == {"metric_key": "eval_full"}
27 |     assert result == 0
28 | 
29 | 
30 | def test_eval_candidate_program_minibatch():
31 |     trainset = [1, 2, 3, 4, 5]
32 |     candidate_program = DummyModule()
33 |     evaluate = Mock(return_value=0)
34 |     batch_size = 3
35 | 
36 |     result = eval_candidate_program(batch_size, trainset, candidate_program, evaluate)
37 | 
38 |     evaluate.assert_called_once()
39 |     _, called_kwargs = evaluate.call_args
40 |     assert len(called_kwargs["devset"]) == batch_size
41 |     assert called_kwargs["callback_metadata"] == {"metric_key": "eval_minibatch"}
42 |     assert result == 0
43 | 
44 | def test_eval_candidate_program_failure():
45 |     trainset = [1, 2, 3, 4, 5]
46 |     candidate_program = DummyModule()
47 |     evaluate = Mock(side_effect=ValueError("Error"))
48 |     batch_size = 3
49 | 
50 |     result = eval_candidate_program(batch_size, trainset, candidate_program, evaluate)
51 | 
52 |     assert result.score == 0.0
53 | 
```

--------------------------------------------------------------------------------
/docs/docs/tutorials/optimize_ai_program/index.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Optimize AI Programs with DSPy
 2 | 
 3 | This section focuses on DSPy's powerful optimization capabilities, demonstrating how to systematically improve your AI programs using various optimizers. These tutorials are lighter on programming concepts and instead showcase how DSPy optimizers can automatically enhance the quality and performance of your applications.
 4 | 
 5 | ## Mathematical and Reasoning Tasks
 6 | 
 7 | ### [Math Reasoning](../math/index.ipynb)
 8 | Learn how to optimize DSPy programs for mathematical reasoning tasks. This tutorial demonstrates how optimizers can dramatically improve performance on complex math problems by finding better prompting strategies and few-shot examples.
 9 | 
10 | ## Model Optimization
11 | 
12 | ### [Classification Finetuning](../classification_finetuning/index.ipynb)
13 | Discover how to use DSPy's finetuning optimizers to distill knowledge from large language models into smaller, more efficient models. Learn the complete workflow from prompt optimization to model finetuning for classification tasks.
14 | 
15 | ## Advanced Tool Integration
16 | 
17 | ### [Advanced Tool Use](../tool_use/index.ipynb)
18 | Explore how to optimize AI programs that use external tools and APIs. This tutorial shows how DSPy optimizers can learn to use tools more effectively, improving both accuracy and efficiency in tool-calling scenarios.
19 | 
20 | ### [Finetuning Agents](../games/index.ipynb)
21 | Learn to optimize complex agent-based systems through finetuning. This tutorial demonstrates how to improve agent performance in interactive environments like games, where strategic thinking and adaptation are crucial.
22 | 
```

--------------------------------------------------------------------------------
/tests/adapters/test_base_type.py:
--------------------------------------------------------------------------------

```python
 1 | import pydantic
 2 | 
 3 | import dspy
 4 | 
 5 | 
 6 | def test_basic_extract_custom_type_from_annotation():
 7 |     class Event(dspy.Type):
 8 |         event_name: str
 9 |         start_date_time: str
10 |         end_date_time: str | None
11 |         location: str | None
12 | 
13 |     class ExtractEvent(dspy.Signature):
14 |         """Extract all events from the email content."""
15 | 
16 |         email: str = dspy.InputField()
17 |         event: Event = dspy.OutputField()
18 | 
19 |     assert dspy.Type.extract_custom_type_from_annotation(ExtractEvent.output_fields["event"].annotation) == [Event]
20 | 
21 |     class ExtractEvents(dspy.Signature):
22 |         """Extract all events from the email content."""
23 | 
24 |         email: str = dspy.InputField()
25 |         events: list[Event] = dspy.OutputField()
26 | 
27 |     assert dspy.Type.extract_custom_type_from_annotation(ExtractEvents.output_fields["events"].annotation) == [Event]
28 | 
29 | 
30 | def test_extract_custom_type_from_annotation_with_nested_type():
31 |     class Event(dspy.Type):
32 |         event_name: str
33 |         start_date_time: str
34 |         end_date_time: str | None
35 |         location: str | None
36 | 
37 |     class EventIdentifier(dspy.Type):
38 |         model_config = pydantic.ConfigDict(frozen=True)  # Make it hashable
39 |         event_id: str
40 |         event_name: str
41 | 
42 |     class ExtractEvents(dspy.Signature):
43 |         """Extract all events from the email content."""
44 | 
45 |         email: str = dspy.InputField()
46 |         events: list[dict[EventIdentifier, Event]] = dspy.OutputField()
47 | 
48 |     assert dspy.Type.extract_custom_type_from_annotation(ExtractEvents.output_fields["events"].annotation) == [
49 |         EventIdentifier,
50 |         Event,
51 |     ]
52 | 
```

--------------------------------------------------------------------------------
/dspy/predict/chain_of_thought.py:
--------------------------------------------------------------------------------

```python
 1 | from typing import Any
 2 | 
 3 | from pydantic.fields import FieldInfo
 4 | 
 5 | import dspy
 6 | from dspy.primitives.module import Module
 7 | from dspy.signatures.signature import Signature, ensure_signature
 8 | 
 9 | 
10 | class ChainOfThought(Module):
11 |     def __init__(
12 |         self,
13 |         signature: str | type[Signature],
14 |         rationale_field: FieldInfo | None = None,
15 |         rationale_field_type: type = str,
16 |         **config: dict[str, Any],
17 |     ):
18 |         """
19 |         A module that reasons step by step in order to predict the output of a task.
20 | 
21 |         Args:
22 |             signature (Type[dspy.Signature]): The signature of the module.
23 |             rationale_field (Optional[Union[dspy.OutputField, pydantic.fields.FieldInfo]]): The field that will contain the reasoning.
24 |             rationale_field_type (Type): The type of the rationale field.
25 |             **config: The configuration for the module.
26 |         """
27 |         super().__init__()
28 |         signature = ensure_signature(signature)
29 |         prefix = "Reasoning: Let's think step by step in order to"
30 |         desc = "${reasoning}"
31 |         rationale_field_type = rationale_field.annotation if rationale_field else rationale_field_type
32 |         rationale_field = rationale_field if rationale_field else dspy.OutputField(prefix=prefix, desc=desc)
33 |         extended_signature = signature.prepend(name="reasoning", field=rationale_field, type_=rationale_field_type)
34 |         self.predict = dspy.Predict(extended_signature, **config)
35 | 
36 |     def forward(self, **kwargs):
37 |         return self.predict(**kwargs)
38 | 
39 |     async def aforward(self, **kwargs):
40 |         return await self.predict.acall(**kwargs)
41 | 
```

--------------------------------------------------------------------------------
/docs/docs/production/index.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Using DSPy in Production
 2 | 
 3 | <div class="grid cards" style="text-align: left;" markdown>
 4 | 
 5 | - :material-earth:{ .lg .middle } __Real-World Use Cases__
 6 | 
 7 |     ---
 8 | 
 9 |     DSPy is deployed in production by many enterprises and startups. Explore real-world case studies.
10 | 
11 |     [:octicons-arrow-right-24: Use Cases](../community/use-cases.md)
12 | 
13 | - :material-magnify-expand:{ .lg .middle } __Monitoring & Observability__
14 | 
15 |     ---
16 | 
17 |     Monitor your DSPy programs using **MLflow Tracing**, based on OpenTelemetry.
18 | 
19 |     [:octicons-arrow-right-24: Set Up Observability](../tutorials/observability/index.md#tracing)
20 | 
21 | - :material-ab-testing: __Reproducibility__
22 | 
23 |     ---
24 | 
25 |     Log programs, metrics, configs, and environments for full reproducibility with DSPy's native MLflow integration.
26 | 
27 |     [:octicons-arrow-right-24: MLflow Integration](https://mlflow.org/docs/latest/llms/dspy/index.html)
28 | 
29 | - :material-rocket-launch: __Deployment__
30 | 
31 |     ---
32 | 
33 |     When it's time to productionize, deploy your application easily with DSPy's integration with MLflow Model Serving.
34 | 
35 |     [:octicons-arrow-right-24: Deployment Guide](../tutorials/deployment/index.md)
36 | 
37 | - :material-arrow-up-right-bold: __Scalability__
38 | 
39 |     ---
40 | 
41 |     DSPy is designed with thread-safety in mind and offers native asynchronous execution support for high-throughput environments.
42 | 
43 |     [:octicons-arrow-right-24: Async Program](../api/utils/asyncify.md)
44 | 
45 | - :material-alert-rhombus: __Guardrails & Controllability__
46 | 
47 |     ---
48 | 
49 |     DSPy's **Signatures**, **Modules**, and **Optimizers** help you control and guide LM outputs.
50 | 
51 |     [:octicons-arrow-right-24: Learn Signature](../learn/programming/signatures.md)
52 | 
53 | </div>
54 | 
```

--------------------------------------------------------------------------------
/tests/adapters/test_document.py:
--------------------------------------------------------------------------------

```python
 1 | import pydantic
 2 | import pytest
 3 | 
 4 | from dspy.experimental import Document
 5 | 
 6 | 
 7 | def test_document_validate_input():
 8 |     # Create a `Document` instance with valid data.
 9 |     doc = Document(data="The Earth orbits the Sun.")
10 |     assert doc.data == "The Earth orbits the Sun."
11 | 
12 |     with pytest.raises(pydantic.ValidationError):
13 |         # Try to create a `Document` instance with invalid type.
14 |         Document(data=123)
15 | 
16 | 
17 | def test_document_in_nested_type():
18 |     class Wrapper(pydantic.BaseModel):
19 |         document: Document
20 | 
21 |     doc = Document(data="Hello, world!")
22 |     wrapper = Wrapper(document=doc)
23 |     assert wrapper.document.data == "Hello, world!"
24 | 
25 | 
26 | def test_document_with_all_fields():
27 |     doc = Document(
28 |         data="Water boils at 100°C at standard pressure.",
29 |         title="Physics Facts",
30 |         media_type="application/pdf",
31 |         context="Laboratory conditions"
32 |     )
33 |     assert doc.data == "Water boils at 100°C at standard pressure."
34 |     assert doc.title == "Physics Facts"
35 |     assert doc.media_type == "application/pdf"
36 |     assert doc.context == "Laboratory conditions"
37 | 
38 | 
39 | def test_document_format():
40 |     doc = Document(
41 |         data="The sky is blue.",
42 |         title="Color Facts",
43 |         media_type="text/plain"
44 |     )
45 | 
46 |     formatted = doc.format()
47 | 
48 |     assert isinstance(formatted, list)
49 |     assert len(formatted) == 1
50 | 
51 |     doc_block = formatted[0]
52 |     assert doc_block["type"] == "document"
53 |     assert doc_block["source"]["type"] == "text"
54 |     assert doc_block["source"]["media_type"] == "text/plain"
55 |     assert doc_block["source"]["data"] == "The sky is blue."
56 |     assert doc_block["title"] == "Color Facts"
57 |     assert doc_block["citations"]["enabled"] is True
58 | 
```

--------------------------------------------------------------------------------
/tests/utils/test_langchain_tool.py:
--------------------------------------------------------------------------------

```python
 1 | import importlib
 2 | 
 3 | import pytest
 4 | 
 5 | if importlib.util.find_spec("langchain_core") is None:
 6 |     pytest.skip(reason="langchain_core is not installed", allow_module_level=True)
 7 | 
 8 | from pydantic import BaseModel
 9 | 
10 | from dspy.utils.langchain_tool import convert_langchain_tool
11 | 
12 | 
13 | @pytest.mark.asyncio
14 | @pytest.mark.extra
15 | async def test_convert_custom_simple_tool():
16 |     from langchain_core.tools import tool
17 | 
18 |     @tool
19 |     def add(a: int, b: int) -> int:
20 |         """Add two numbers."""
21 |         return a + b
22 | 
23 |     tool = convert_langchain_tool(add)
24 |     assert tool.name == "add"
25 |     assert tool.desc == "Add two numbers."
26 |     assert tool.args == {"a": {"title": "A", "type": "integer"}, "b": {"title": "B", "type": "integer"}}
27 |     assert tool.arg_types == {"a": int, "b": int}
28 |     assert tool.arg_desc == {"a": "No description provided. (Required)", "b": "No description provided. (Required)"}
29 |     assert await tool.acall(a=1, b=2) == 3
30 | 
31 | 
32 | @pytest.mark.asyncio
33 | @pytest.mark.extra
34 | async def test_convert_custom_tool_with_custom_class():
35 |     from langchain_core.tools import tool
36 | 
37 |     class Profile(BaseModel):
38 |         name: str
39 |         age: int
40 | 
41 |     @tool
42 |     def get_age(profile: Profile) -> int:
43 |         """Get the age of the profile."""
44 |         return profile.age
45 | 
46 |     tool = convert_langchain_tool(get_age)
47 |     assert tool.name == "get_age"
48 |     assert tool.desc == "Get the age of the profile."
49 |     assert tool.args == {"profile": {"title": "Profile", "type": "object", "properties": {"name": {"title": "Name", "type": "string"}, "age": {"title": "Age", "type": "integer"}}, "required": ["name", "age"]}}
50 |     assert tool.arg_types == {"profile": Profile}
51 |     assert tool.arg_desc == {"profile": "No description provided. (Required)"}
52 |     assert await tool.acall(profile=Profile(name="John", age=20)) == 20
53 | 
```

--------------------------------------------------------------------------------
/tests/adapters/test_code.py:
--------------------------------------------------------------------------------

```python
 1 | import inspect
 2 | 
 3 | import pydantic
 4 | import pytest
 5 | 
 6 | import dspy
 7 | 
 8 | 
 9 | def test_code_validate_input():
10 |     # Create a `dspy.Code` instance with valid code.
11 |     code = dspy.Code["python"](code="print('Hello, world!')")
12 |     assert code.code == "print('Hello, world!')"
13 | 
14 |     with pytest.raises(ValueError):
15 |         # Try to create a `dspy.Code` instance with invalid type.
16 |         dspy.Code["python"](code=123)
17 | 
18 |     def foo(x):
19 |         return x + 1
20 | 
21 |     code_source = inspect.getsource(foo)
22 |     code = dspy.Code["python"](code=code_source)
23 | 
24 |     assert code.code == code_source
25 | 
26 | 
27 | def test_code_in_nested_type():
28 |     class Wrapper(pydantic.BaseModel):
29 |         code: dspy.Code
30 | 
31 |     code = dspy.Code(code="print('Hello, world!')")
32 |     wrapper = Wrapper(code=code)
33 |     assert wrapper.code.code == "print('Hello, world!')"
34 | 
35 | 
36 | def test_code_with_language():
37 |     java_code = dspy.Code["java"](code="System.out.println('Hello, world!');")
38 |     assert java_code.code == "System.out.println('Hello, world!');"
39 |     assert java_code.language == "java"
40 |     assert "Programming language: java" in java_code.description()
41 | 
42 |     cpp_code = dspy.Code["cpp"](code="std::cout << 'Hello, world!' << std::endl;")
43 |     assert cpp_code.code == "std::cout << 'Hello, world!' << std::endl;"
44 |     assert cpp_code.language == "cpp"
45 |     assert "Programming language: cpp" in cpp_code.description()
46 | 
47 | 
48 | def test_code_parses_from_dirty_code():
49 |     dirty_code = "```python\nprint('Hello, world!')```"
50 |     code = dspy.Code(code=dirty_code)
51 |     assert code.code == "print('Hello, world!')"
52 | 
53 |     dirty_code_with_reasoning = """
54 | The generated code is:
55 | ```python
56 | print('Hello, world!')
57 | ```
58 | 
59 | The reasoning is:
60 | The code is a simple print statement.
61 | """
62 |     code = dspy.Code(code=dirty_code_with_reasoning)
63 |     assert code.code == "print('Hello, world!')"
64 | 
```

--------------------------------------------------------------------------------
/dspy/utils/saving.py:
--------------------------------------------------------------------------------

```python
 1 | import logging
 2 | import sys
 3 | from pathlib import Path
 4 | from typing import TYPE_CHECKING
 5 | 
 6 | import cloudpickle
 7 | import orjson
 8 | 
 9 | if TYPE_CHECKING:
10 |     from dspy.primitives.module import Module
11 | 
12 | logger = logging.getLogger(__name__)
13 | 
14 | 
15 | def get_dependency_versions():
16 |     import dspy
17 | 
18 |     cloudpickle_version = ".".join(cloudpickle.__version__.split(".")[:2])
19 | 
20 |     return {
21 |         "python": f"{sys.version_info.major}.{sys.version_info.minor}",
22 |         "dspy": dspy.__version__,
23 |         "cloudpickle": cloudpickle_version,
24 |     }
25 | 
26 | 
27 | def load(path: str) -> "Module":
28 |     """Load saved DSPy model.
29 | 
30 |     This method is used to load a saved DSPy model with `save_program=True`, i.e., the model is saved with cloudpickle.
31 | 
32 |     Args:
33 |         path (str): Path to the saved model.
34 | 
35 |     Returns:
36 |         The loaded model, a `dspy.Module` instance.
37 |     """
38 |     path = Path(path)
39 |     if not path.exists():
40 |         raise FileNotFoundError(f"The path '{path}' does not exist.")
41 | 
42 |     with open(path / "metadata.json") as f:
43 |         metadata = orjson.loads(f.read())
44 | 
45 |     dependency_versions = get_dependency_versions()
46 |     saved_dependency_versions = metadata["dependency_versions"]
47 |     for key, saved_version in saved_dependency_versions.items():
48 |         if dependency_versions[key] != saved_version:
49 |             logger.warning(
50 |                 f"There is a mismatch of {key} version between saved model and current environment. You saved with "
51 |                 f"`{key}=={saved_version}`, but now you have `{key}=={dependency_versions[key]}`. This might cause "
52 |                 "errors or performance downgrade on the loaded model, please consider loading the model in the same "
53 |                 "environment as the saving environment."
54 |             )
55 | 
56 |     with open(path / "program.pkl", "rb") as f:
57 |         return cloudpickle.load(f)
58 | 
```

--------------------------------------------------------------------------------
/dspy/predict/aggregation.py:
--------------------------------------------------------------------------------

```python
 1 | from dspy.evaluate import normalize_text
 2 | from dspy.primitives.prediction import Completions, Prediction
 3 | 
 4 | 
 5 | def default_normalize(s):
 6 |     return normalize_text(s) or None
 7 | 
 8 | 
 9 | def majority(prediction_or_completions, normalize=default_normalize, field=None):
10 |     """
11 |     Returns the most common completion for the target field (or the last field) in the signature.
12 |     When normalize returns None, that completion is ignored.
13 |     In case of a tie, earlier completion are prioritized.
14 |     """
15 | 
16 |     assert any(isinstance(prediction_or_completions, t) for t in [Prediction, Completions, list])
17 |     type(prediction_or_completions)
18 | 
19 |     # Get the completions
20 |     if isinstance(prediction_or_completions, Prediction):
21 |         completions = prediction_or_completions.completions
22 |     else:
23 |         completions = prediction_or_completions
24 | 
25 |     try:
26 |         signature = completions.signature
27 |     except Exception:
28 |         signature = None
29 | 
30 |     if not field:
31 |         if signature:
32 |             field = list(signature.output_fields.keys())[-1]
33 |         else:
34 |             field = list(completions[0].keys())[-1]
35 | 
36 |     # Normalize
37 |     normalize = normalize if normalize else lambda x: x
38 |     normalized_values = [normalize(completion[field]) for completion in completions]
39 |     normalized_values_ = [x for x in normalized_values if x is not None]
40 | 
41 |     # Count
42 |     value_counts = {}
43 |     for value in normalized_values_ or normalized_values:
44 |         value_counts[value] = value_counts.get(value, 0) + 1
45 | 
46 |     majority_value = max(value_counts, key=value_counts.get)
47 | 
48 |     # Return the first completion with the majority value in the field
49 |     for completion in completions:
50 |         if normalize(completion[field]) == majority_value:
51 |             break
52 | 
53 |     # if input_type == Prediction:
54 |     return Prediction.from_completions([completion], signature=signature)
55 | 
```

--------------------------------------------------------------------------------
/docs/docs/tutorials/gepa_ai_program/index.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Reflective Prompt Evolution with GEPA
 2 | 
 3 | This section introduces GEPA, a reflective prompt optimizer for DSPy. GEPA works by leveraging LM's ability to reflect on the DSPy program's trajectory, identifying what went well, what didn't, and what can be improved. Based on this reflection, GEPA proposes new prompts, building a tree of evolved prompt candidates, accumulating improvements as the optimization progresses. Since GEPA can leverage domain-specific text feedback (as opposed to only the scalar metric), GEPA can often propose high performing prompts in very few rollouts. GEPA was introduced in the paper [GEPA: Reflective Prompt Evolution Can Outperform Reinforcement Learning](https://arxiv.org/abs/2507.19457) and available as `dspy.GEPA` which internally uses the GEPA implementation provided in [gepa-ai/gepa](https://github.com/gepa-ai/gepa).
 4 | 
 5 | ## `dspy.GEPA` Tutorials
 6 | 
 7 | ### [GEPA for AIME (Math)](../gepa_aime/index.ipynb)
 8 | This tutorial explores how GEPA can optimize a single `dspy.ChainOfThought` based program to achieve 10% gains on AIME 2025 with GPT-4.1 Mini!
 9 | 
10 | ### [GEPA for Structured Information Extraction for Enterprise Tasks](../gepa_facilitysupportanalyzer/index.ipynb)
11 | This tutorial explores how GEPA leverages predictor-level feedback to improve GPT-4.1 Nano's performance on a three-part task for structured information extraction and classification in an enterprise setting.
12 | 
13 | ### [GEPA for Privacy-Conscious Delegation](../gepa_papillon/index.ipynb)
14 | This tutorial explores how GEPA can improve rapidly in as few as 1 iteration, while leveraging a simple feedback provided by a LLM-as-a-judge metric. The tutorial also explores how GEPA benefits from the textual feedback showing a breakdown of aggregate metrics into sub-components, allowing the reflection LM to identify what aspects of the task need improvement.
```
Page 1/17FirstPrevNextLast