Files
langchain/pyproject.toml
Copilot 54542b9385 docs(openai): add comprehensive documentation and examples for extra_body + others (#32149)
This PR addresses the common issue where users struggle to pass custom
parameters to OpenAI-compatible APIs like LM Studio, vLLM, and others.
The problem occurs when users try to use `model_kwargs` for custom
parameters, which causes API errors.

## Problem

Users attempting to pass custom parameters (like LM Studio's `ttl`
parameter) were getting errors:

```python
#  This approach fails
llm = ChatOpenAI(
    base_url="http://localhost:1234/v1",
    model="mlx-community/QwQ-32B-4bit",
    model_kwargs={"ttl": 5}  # Causes TypeError: unexpected keyword argument 'ttl'
)
```

## Solution

The `extra_body` parameter is the correct way to pass custom parameters
to OpenAI-compatible APIs:

```python
#  This approach works correctly
llm = ChatOpenAI(
    base_url="http://localhost:1234/v1",
    model="mlx-community/QwQ-32B-4bit",
    extra_body={"ttl": 5}  # Custom parameters go in extra_body
)
```

## Changes Made

1. **Enhanced Documentation**: Updated the `extra_body` parameter
docstring with comprehensive examples for LM Studio, vLLM, and other
providers

2. **Added Documentation Section**: Created a new "OpenAI-compatible
APIs" section in the main class docstring with practical examples

3. **Unit Tests**: Added tests to verify `extra_body` functionality
works correctly:
- `test_extra_body_parameter()`: Verifies custom parameters are included
in request payload
- `test_extra_body_with_model_kwargs()`: Ensures `extra_body` and
`model_kwargs` work together

4. **Clear Guidance**: Documented when to use `extra_body` vs
`model_kwargs`

## Examples Added

**LM Studio with TTL (auto-eviction):**
```python
ChatOpenAI(
    base_url="http://localhost:1234/v1",
    api_key="lm-studio",
    model="mlx-community/QwQ-32B-4bit",
    extra_body={"ttl": 300}  # Auto-evict after 5 minutes
)
```

**vLLM with custom sampling:**
```python
ChatOpenAI(
    base_url="http://localhost:8000/v1",
    api_key="EMPTY",
    model="meta-llama/Llama-2-7b-chat-hf",
    extra_body={
        "use_beam_search": True,
        "best_of": 4
    }
)
```

## Why This Works

- `model_kwargs` parameters are passed directly to the OpenAI client's
`create()` method, causing errors for non-standard parameters
- `extra_body` parameters are included in the HTTP request body, which
is exactly what OpenAI-compatible APIs expect for custom parameters

Fixes #32115.

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 Share your feedback on Copilot coding agent for the chance to win a
$200 gift card! Click
[here](https://survey.alchemer.com/s3/8343779/Copilot-Coding-agent) to
start the survey.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: mdrxy <61371264+mdrxy@users.noreply.github.com>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
Co-authored-by: Mason Daugherty <mason@langchain.dev>
2025-07-24 16:43:16 -04:00

99 lines
3.6 KiB
TOML

[project]
authors = []
license = { text = "MIT" }
requires-python = ">=3.9"
dependencies = []
name = "langchain-monorepo"
version = "0.0.1"
description = "LangChain mono-repo"
readme = "README.md"
[project.urls]
repository = "https://www.github.com/langchain-ai/langchain"
[dependency-groups]
lint = ["ruff<0.13,>=0.12.2"]
dev = [
"langchain-core",
"langchain-text-splitters",
"langchain-community",
"langchain",
"langchain-openai",
"ipykernel<7.0.0,>=6.29.2",
]
codespell = ["codespell<3.0.0,>=2.2.0"]
typing = []
test = [
"langchain-experimental @ git+https://github.com/langchain-ai/langchain-experimental.git#subdirectory=libs/experimental",
"langchain-anthropic",
"langchain-aws @ git+https://github.com/langchain-ai/langchain-aws.git#subdirectory=libs/aws",
"langchain-chroma",
"langchain-fireworks",
"langchain-google-vertexai @ git+https://github.com/langchain-ai/langchain-google.git#subdirectory=libs/vertexai",
"langchain-google-genai @ git+https://github.com/langchain-ai/langchain-google.git#subdirectory=libs/genai",
"langchain-groq",
"langchain-mistralai",
"langchain-tavily",
"langchain-together @ git+https://github.com/langchain-ai/langchain-together.git#subdirectory=libs/together",
"langchain-unstructured @ git+https://github.com/langchain-ai/langchain-unstructured.git#subdirectory=libs/unstructured",
"langgraph",
"msgpack",
"jupyter<2.0.0,>=1.1.1",
"click<9.0.0,>=8.1.7",
"aiofiles<25.0.0,>=24.1.0",
"faiss-cpu<2.0.0,>=1.7.4",
"grandalf<1.0,>=0.8",
"lark<2.0.0,>=1.1.9",
"pandas<3,>=2",
"rank-bm25<1.0.0,>=0.2.2",
"tabulate<1.0.0,>=0.9.0",
"unstructured[md]<1.0.0,>=0.16.11; python_version < \"3.13\"",
"wikipedia<2.0.0,>=1.4.0",
"pypdf<6.0.0,>=5.0.0",
"vcrpy<7.0.0,>=6.0.1",
]
[tool.uv.sources]
langchain-core = { path = "./libs/core", editable = true }
langchain-text-splitters = { path = "./libs/text-splitters", editable = true }
langchain-tests = { path = "./libs/standard-tests", editable = true }
langchain = { path = "./libs/langchain", editable = true }
langchain-openai = { path = "./libs/partners/openai", editable = true }
langchain-anthropic = { path = "./libs/partners/anthropic", editable = true }
langchain-chroma = { path = "./libs/partners/chroma", editable = true }
langchain-fireworks = { path = "./libs/partners/fireworks", editable = true }
langchain-groq = { path = "./libs/partners/groq", editable = true }
langchain-mistralai = { path = "./libs/partners/mistralai", editable = true }
[build-system]
requires = ["pdm-backend"]
build-backend = "pdm.backend"
[tool.codespell]
skip = '.git,*.pdf,*.svg,*.pdf,*.yaml,*.ipynb,poetry.lock,*.min.js,*.css,package-lock.json,example_data,_dist,examples,templates,*.trig'
# Ignore latin etc
ignore-regex = '.*(Stati Uniti|Tense=Pres).*'
# whats is a typo but used frequently in queries so kept as is
# aapply - async apply
# unsecure - typo but part of API, decided to not bother for now
ignore-words-list = 'momento,collison,ned,foor,reworkd,parth,whats,aapply,mysogyny,unsecure,damon,crate,aadd,symbl,precesses,accademia,nin,cann'
[tool.ruff]
extend-include = ["*.ipynb"]
[tool.ruff.lint]
select = ["D"] # global select for pydocstyle
pydocstyle = { convention = "google" }
[tool.ruff.lint.per-file-ignores]
"**/{cookbook,docs}/*" = [
"E402", # allow imports to appear anywhere in docs
"F401", # allow "imported but unused" example code
"F811", # allow re-importing the same module, so that cells can stay independent
"F841", # allow assignments to variables that are never read -- it's example code
]
"!libs/langchain/langchain/model_laboratory.py" = ["D"]