fix(cli): add together provider to bundler deps and optional extras (#2670)

Closes #2663

---

`together` was already wired into `_MODEL_PROVIDER_ENV`, so deploy-time
validation accepted `TOGETHER_API_KEY` — but the bundler had no mapping
for it, the project had no `together` optional extra, and the parity
test (`test_deps_cover_all_validated_providers`) was masking the gap via
a `no_partner_pkg` exemption. A `model = "together:..."` config silently
produced a bundle missing `langchain-together` and crashed at runtime
with `ImportError: No module named 'langchain_together'`.

Wires `together` end-to-end:

- Adds `together` to `_MODEL_PROVIDER_DEPS` so the deploy bundler
includes `langchain-together` whenever a `together:` model string (or
`[subagents.*]` model override) is configured.
- Adds the `together` optional dependency
(`langchain-together>=0.4.0,<2.0.0`) and folds it into the
`all-providers` composite extra.
- Removes the `together` carve-out from the bundler parity test, so any
future provider added to `_MODEL_PROVIDER_ENV` without a corresponding
bundler dep fails CI instead of slipping through.

---------

Co-authored-by: Mason Daugherty <mason@langchain.dev>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
This commit is contained in:
Mohammad Mohtashim
2026-05-12 02:33:57 +05:00
committed by GitHub
parent dcc48f48d2
commit 4290953e44
6 changed files with 33 additions and 7 deletions
@@ -68,6 +68,7 @@ _MODEL_PROVIDER_DEPS: dict[str, str] = {
"openai": "langchain-openai",
"openrouter": "langchain-openrouter",
"perplexity": "langchain-perplexity",
"together": "langchain-together",
"xai": "langchain-xai",
}
"""Dependencies inferred from a provider: prefix on the model string."""
+1
View File
@@ -49,6 +49,7 @@ MODEL_PROVIDER_EXTRAS: frozenset[str] = frozenset(
"openai",
"openrouter",
"perplexity",
"together",
"vertexai",
"xai",
}
+2 -1
View File
@@ -100,10 +100,11 @@ ollama = ["langchain-ollama>=1.1.0,<2.0.0"]
openai = ["langchain-openai>=1.2.1,<2.0.0"]
openrouter = ["langchain-openrouter>=0.2.3,<2.0.0"]
perplexity = ["langchain-perplexity>=1.2.0,<2.0.0"]
together = ["langchain-together>=0.4.0,<2.0.0"]
vertexai = ["langchain-google-vertexai>=3.2.3,<4.0.0"]
xai = ["langchain-xai>=1.2.2,<2.0.0"]
all-providers = [
"deepagents-cli[anthropic,baseten,bedrock,cohere,deepseek,fireworks,google-genai,groq,huggingface,ibm,litellm,mistralai,nvidia,ollama,openai,openrouter,perplexity,vertexai,xai]",
"deepagents-cli[anthropic,baseten,bedrock,cohere,deepseek,fireworks,google-genai,groq,huggingface,ibm,litellm,mistralai,nvidia,ollama,openai,openrouter,perplexity,together,vertexai,xai]",
]
# Sandbox providers
@@ -156,8 +156,7 @@ class TestRenderPyproject:
def test_deps_cover_all_validated_providers(self) -> None:
"""Every validated provider must have a bundler dep."""
no_partner_pkg = {"together"}
missing = set(_MODEL_PROVIDER_ENV) - set(_MODEL_PROVIDER_DEPS) - no_partner_pkg
missing = set(_MODEL_PROVIDER_ENV) - set(_MODEL_PROVIDER_DEPS)
assert not missing, (
f"Providers validated but missing from bundler deps: {missing}"
)
+25 -2
View File
@@ -1081,6 +1081,7 @@ all-providers = [
{ name = "langchain-openai" },
{ name = "langchain-openrouter" },
{ name = "langchain-perplexity" },
{ name = "langchain-together" },
{ name = "langchain-xai" },
]
all-sandboxes = [
@@ -1149,6 +1150,9 @@ perplexity = [
runloop = [
{ name = "langchain-runloop" },
]
together = [
{ name = "langchain-together" },
]
vertexai = [
{ name = "langchain-google-vertexai" },
]
@@ -1182,7 +1186,7 @@ requires-dist = [
{ name = "deepagents", editable = "../deepagents" },
{ name = "deepagents-acp", specifier = ">=0.0.4" },
{ name = "deepagents-cli", extras = ["agentcore", "daytona", "modal", "runloop"], marker = "extra == 'all-sandboxes'" },
{ name = "deepagents-cli", extras = ["anthropic", "baseten", "bedrock", "cohere", "deepseek", "fireworks", "google-genai", "groq", "huggingface", "ibm", "litellm", "mistralai", "nvidia", "ollama", "openai", "openrouter", "perplexity", "vertexai", "xai"], marker = "extra == 'all-providers'" },
{ name = "deepagents-cli", extras = ["anthropic", "baseten", "bedrock", "cohere", "deepseek", "fireworks", "google-genai", "groq", "huggingface", "ibm", "litellm", "mistralai", "nvidia", "ollama", "openai", "openrouter", "perplexity", "together", "vertexai", "xai"], marker = "extra == 'all-providers'" },
{ name = "httpx", specifier = ">=0.28.1,<1.0.0" },
{ name = "langchain", specifier = ">=1.2.17,<2.0.0" },
{ name = "langchain-agentcore-codeinterpreter", marker = "extra == 'agentcore'", specifier = ">=0.0.2" },
@@ -1211,6 +1215,7 @@ requires-dist = [
{ name = "langchain-openrouter", marker = "extra == 'openrouter'", specifier = ">=0.2.3,<2.0.0" },
{ name = "langchain-perplexity", marker = "extra == 'perplexity'", specifier = ">=1.2.0,<2.0.0" },
{ name = "langchain-runloop", marker = "extra == 'runloop'", editable = "../partners/runloop" },
{ name = "langchain-together", marker = "extra == 'together'", specifier = ">=0.4.0,<2.0.0" },
{ name = "langchain-xai", marker = "extra == 'xai'", specifier = ">=1.2.2,<2.0.0" },
{ name = "langgraph", specifier = ">=1.1.10,<2.0.0" },
{ name = "langgraph-checkpoint-sqlite", specifier = ">=3.0.3,<4.0.0" },
@@ -1234,7 +1239,7 @@ requires-dist = [
{ name = "tomli-w", specifier = ">=1.0.0,<2.0.0" },
{ name = "uuid-utils", specifier = ">=0.10.0,<1.0.0" },
]
provides-extras = ["anthropic", "baseten", "bedrock", "cohere", "deepseek", "fireworks", "google-genai", "groq", "huggingface", "ibm", "litellm", "mistralai", "nvidia", "ollama", "openai", "openrouter", "perplexity", "vertexai", "xai", "all-providers", "agentcore", "daytona", "modal", "runloop", "all-sandboxes"]
provides-extras = ["anthropic", "baseten", "bedrock", "cohere", "deepseek", "fireworks", "google-genai", "groq", "huggingface", "ibm", "litellm", "mistralai", "nvidia", "ollama", "openai", "openrouter", "perplexity", "together", "vertexai", "xai", "all-providers", "agentcore", "daytona", "modal", "runloop", "all-sandboxes"]
[package.metadata.requires-dev]
test = [
@@ -3005,6 +3010,24 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d3/26/1ef06f56198d631296d646a6223de35bcc6cf9795ceb2442816bc963b84c/langchain_text_splitters-1.1.2-py3-none-any.whl", hash = "sha256:a2de0d799ff31886429fd6e2e0032df275b60ec817c19059a7b46181cc1c2f10", size = 35903, upload-time = "2026-04-16T14:20:38.243Z" },
]
[[package]]
name = "langchain-together"
version = "0.4.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "aiohttp" },
{ name = "h11" },
{ name = "langchain-core" },
{ name = "langchain-openai" },
{ name = "langsmith" },
{ name = "requests" },
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/fa/a9/2624fffd4d341454a292dde416c3d2cfbbb6354a2388a57a3d06d6ca4014/langchain_together-0.4.0.tar.gz", hash = "sha256:f488392ecdfeb05c5f2f8162596aff43a3b4d6a4ccf2f821d6e2602a0c5563c6", size = 11031, upload-time = "2026-03-24T20:56:37.903Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/bb/95/733358fb831b73585a40dfa3c59b170772e89ce06af1c888254fbaaaf5d9/langchain_together-0.4.0-py3-none-any.whl", hash = "sha256:a94a0d15b0c01844edf22941aef6fe0f065d0e31e2ba215a544b366d8a1eba89", size = 12909, upload-time = "2026-03-24T20:56:37.081Z" },
]
[[package]]
name = "langchain-xai"
version = "1.2.2"
+3 -2
View File
@@ -519,7 +519,7 @@ requires-dist = [
{ name = "deepagents", editable = "../deepagents" },
{ name = "deepagents-acp", specifier = ">=0.0.4" },
{ name = "deepagents-cli", extras = ["agentcore", "daytona", "modal", "runloop"], marker = "extra == 'all-sandboxes'" },
{ name = "deepagents-cli", extras = ["anthropic", "baseten", "bedrock", "cohere", "deepseek", "fireworks", "google-genai", "groq", "huggingface", "ibm", "litellm", "mistralai", "nvidia", "ollama", "openai", "openrouter", "perplexity", "vertexai", "xai"], marker = "extra == 'all-providers'" },
{ name = "deepagents-cli", extras = ["anthropic", "baseten", "bedrock", "cohere", "deepseek", "fireworks", "google-genai", "groq", "huggingface", "ibm", "litellm", "mistralai", "nvidia", "ollama", "openai", "openrouter", "perplexity", "together", "vertexai", "xai"], marker = "extra == 'all-providers'" },
{ name = "httpx", specifier = ">=0.28.1,<1.0.0" },
{ name = "langchain", specifier = ">=1.2.17,<2.0.0" },
{ name = "langchain-agentcore-codeinterpreter", marker = "extra == 'agentcore'", specifier = ">=0.0.2" },
@@ -548,6 +548,7 @@ requires-dist = [
{ name = "langchain-openrouter", marker = "extra == 'openrouter'", specifier = ">=0.2.3,<2.0.0" },
{ name = "langchain-perplexity", marker = "extra == 'perplexity'", specifier = ">=1.2.0,<2.0.0" },
{ name = "langchain-runloop", marker = "extra == 'runloop'", editable = "../partners/runloop" },
{ name = "langchain-together", marker = "extra == 'together'", specifier = ">=0.4.0,<2.0.0" },
{ name = "langchain-xai", marker = "extra == 'xai'", specifier = ">=1.2.2,<2.0.0" },
{ name = "langgraph", specifier = ">=1.1.10,<2.0.0" },
{ name = "langgraph-checkpoint-sqlite", specifier = ">=3.0.3,<4.0.0" },
@@ -571,7 +572,7 @@ requires-dist = [
{ name = "tomli-w", specifier = ">=1.0.0,<2.0.0" },
{ name = "uuid-utils", specifier = ">=0.10.0,<1.0.0" },
]
provides-extras = ["anthropic", "baseten", "bedrock", "cohere", "deepseek", "fireworks", "google-genai", "groq", "huggingface", "ibm", "litellm", "mistralai", "nvidia", "ollama", "openai", "openrouter", "perplexity", "vertexai", "xai", "all-providers", "agentcore", "daytona", "modal", "runloop", "all-sandboxes"]
provides-extras = ["anthropic", "baseten", "bedrock", "cohere", "deepseek", "fireworks", "google-genai", "groq", "huggingface", "ibm", "litellm", "mistralai", "nvidia", "ollama", "openai", "openrouter", "perplexity", "together", "vertexai", "xai", "all-providers", "agentcore", "daytona", "modal", "runloop", "all-sandboxes"]
[package.metadata.requires-dev]
test = [