Skip to content

Commit e5a7366

Browse files
committed
feat(langchain): support multi-provider model dispatch
- Fix ModelService.model_info() to propagate provider field to BaseInfo, which also fixes the litellm direct call path defaulting to "openai" - Modify LangChainModelAdapter.wrap_model() to dispatch to provider-specific LangChain chat model classes based on BaseInfo.provider: - anthropic -> ChatAnthropic - gemini/vertex_ai -> ChatGoogleGenerativeAI - others (openai-compatible) -> ChatOpenAI - Add optional dependency groups: langchain-anthropic, langchain-google 类型检查通过,检查文件数 303 Change-Id: I9362b0b1e2c110007ca3aab50700c28d5d7fa7ed Co-developed-by: Cursor <noreply@cursor.com> Signed-off-by: congxiao.wxx <congxiao.wxx@alibaba-inc.com>
1 parent 1d658fb commit e5a7366

File tree

4 files changed

+89
-7
lines changed

4 files changed

+89
-7
lines changed

agentrun/integration/langchain/model_adapter.py

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,106 @@
22
33
将 CommonModel 包装为 LangChain BaseChatModel。"""
44

5-
import inspect
6-
import json
7-
from typing import Any, List, Optional
5+
from typing import Any, Set
86

97
from agentrun.integration.langchain.message_adapter import (
108
LangChainMessageAdapter,
119
)
1210
from agentrun.integration.utils.adapter import ModelAdapter
1311

12+
OPENAI_COMPATIBLE_PROVIDERS: Set[str] = {
13+
"openai",
14+
"tongyi",
15+
"deepseek",
16+
"moonshot",
17+
"baichuan",
18+
"hunyuan",
19+
"minimax",
20+
"spark",
21+
"stepfun",
22+
"wenxin",
23+
"yi",
24+
"zhipuai",
25+
"custom",
26+
}
27+
1428

1529
class LangChainModelAdapter(ModelAdapter):
1630
"""LangChain 模型适配器 / LangChain Model Adapter
1731
18-
将 CommonModel 包装为 LangChain BaseChatModel。"""
32+
将 CommonModel 包装为 LangChain BaseChatModel。
33+
根据 provider 自动选择对应的 LangChain Chat Model 类。"""
1934

2035
def __init__(self):
2136
"""初始化适配器,创建内部的消息适配器 / LangChain Message Adapter"""
2237
self._message_adapter = LangChainMessageAdapter()
2338

2439
def wrap_model(self, common_model: Any) -> Any:
25-
"""包装 CommonModel 为 LangChain BaseChatModel / LangChain Model Adapter"""
40+
"""包装 CommonModel 为 LangChain BaseChatModel / LangChain Model Adapter
41+
42+
根据 BaseInfo.provider 分发到对应的 LangChain Chat Model 类:
43+
- anthropic -> ChatAnthropic
44+
- gemini / vertex_ai -> ChatGoogleGenerativeAI
45+
- 其他(openai 兼容) -> ChatOpenAI
46+
"""
47+
info = common_model.get_model_info()
48+
provider = (info.provider or "").lower()
49+
50+
if provider == "anthropic":
51+
return self._create_anthropic(info)
52+
elif provider in ("gemini", "vertex_ai"):
53+
return self._create_google(info)
54+
else:
55+
return self._create_openai(info)
56+
57+
def _create_openai(self, info: Any) -> Any:
2658
from langchain_openai import ChatOpenAI
2759

28-
info = common_model.get_model_info() # 确保模型可用
2960
return ChatOpenAI(
3061
name=info.model,
3162
api_key=info.api_key,
3263
model=info.model,
3364
base_url=info.base_url,
3465
default_headers=info.headers,
3566
stream_usage=True,
36-
streaming=True, # 启用流式输出以支持 token by token
67+
streaming=True,
3768
)
69+
70+
def _create_anthropic(self, info: Any) -> Any:
71+
try:
72+
from langchain_anthropic import ChatAnthropic
73+
except ImportError as e:
74+
raise ImportError(
75+
"langchain-anthropic is required for Anthropic models. "
76+
"Install it with: "
77+
'pip install "agentrun-sdk[langchain-anthropic]"'
78+
) from e
79+
80+
kwargs: dict[str, Any] = {
81+
"model": info.model or "",
82+
"anthropic_api_key": info.api_key,
83+
"default_headers": info.headers or {},
84+
"streaming": True,
85+
}
86+
if info.base_url:
87+
kwargs["anthropic_api_url"] = info.base_url
88+
89+
return ChatAnthropic(**kwargs)
90+
91+
def _create_google(self, info: Any) -> Any:
92+
try:
93+
from langchain_google_genai import ChatGoogleGenerativeAI
94+
except ImportError as e:
95+
raise ImportError(
96+
"langchain-google-genai is required for Google / "
97+
"Vertex AI models. Install it with: "
98+
'pip install "agentrun-sdk[langchain-google]"'
99+
) from e
100+
101+
kwargs: dict[str, Any] = {
102+
"model": info.model or "",
103+
"google_api_key": info.api_key,
104+
"default_headers": info.headers or {},
105+
}
106+
107+
return ChatGoogleGenerativeAI(**kwargs)

agentrun/model/__model_service_async_template.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,4 +231,5 @@ def model_info(self, config: Optional[Config] = None) -> BaseInfo:
231231
base_url=self.provider_settings.base_url,
232232
model=default_model,
233233
headers=cfg.get_headers(),
234+
provider=self.provider,
234235
)

agentrun/model/model_service.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,4 +402,5 @@ def model_info(self, config: Optional[Config] = None) -> BaseInfo:
402402
base_url=self.provider_settings.base_url,
403403
model=default_model,
404404
headers=cfg.get_headers(),
405+
provider=self.provider,
405406
)

pyproject.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ langchain = [
3434
"langchain-openai>=1.0.0; python_version >= '3.10'",
3535
]
3636

37+
langchain-anthropic = [
38+
"langchain>=1.0.0; python_version >= '3.10'",
39+
"langchain-anthropic>=0.3.0; python_version >= '3.10'",
40+
]
41+
42+
langchain-google = [
43+
"langchain>=1.0.0; python_version >= '3.10'",
44+
"langchain-google-genai>=2.1.0; python_version >= '3.10'",
45+
]
46+
3747
google-adk = [
3848
"google-adk>=1.18.0",
3949
]

0 commit comments

Comments
 (0)