langchain-dev-utils 1.2.5__tar.gz → 1.2.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/PKG-INFO +9 -6
  2. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/README.md +8 -5
  3. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/README_cn.md +8 -6
  4. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/pyproject.toml +1 -1
  5. langchain_dev_utils-1.2.6/src/langchain_dev_utils/__init__.py +1 -0
  6. langchain_dev_utils-1.2.6/src/langchain_dev_utils/_utils.py +39 -0
  7. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/chat_models/base.py +10 -37
  8. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/embeddings/base.py +7 -30
  9. langchain_dev_utils-1.2.5/src/langchain_dev_utils/__init__.py +0 -1
  10. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/.gitignore +0 -0
  11. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/.python-version +0 -0
  12. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/.vscode/settings.json +0 -0
  13. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/LICENSE +0 -0
  14. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/__init__.py +0 -0
  15. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/factory.py +0 -0
  16. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/file_system.py +0 -0
  17. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/middleware/__init__.py +0 -0
  18. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/middleware/model_fallback.py +0 -0
  19. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/middleware/model_router.py +0 -0
  20. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/middleware/plan.py +0 -0
  21. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/middleware/summarization.py +0 -0
  22. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/middleware/tool_emulator.py +0 -0
  23. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/middleware/tool_selection.py +0 -0
  24. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/plan.py +0 -0
  25. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/agents/wrap.py +0 -0
  26. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/chat_models/__init__.py +0 -0
  27. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/chat_models/adapters/__init__.py +0 -0
  28. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/chat_models/adapters/openai_compatible.py +0 -0
  29. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/chat_models/types.py +0 -0
  30. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/embeddings/__init__.py +0 -0
  31. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/message_convert/__init__.py +0 -0
  32. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/message_convert/content.py +0 -0
  33. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/message_convert/format.py +0 -0
  34. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/pipeline/__init__.py +0 -0
  35. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/pipeline/parallel.py +0 -0
  36. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/pipeline/sequential.py +0 -0
  37. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/pipeline/types.py +0 -0
  38. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/py.typed +0 -0
  39. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/tool_calling/__init__.py +0 -0
  40. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/tool_calling/human_in_the_loop.py +0 -0
  41. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/src/langchain_dev_utils/tool_calling/utils.py +0 -0
  42. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/__init__.py +0 -0
  43. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_agent.py +0 -0
  44. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_chat_models.py +0 -0
  45. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_human_in_the_loop.py +0 -0
  46. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_load_embbeding.py +0 -0
  47. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_load_model.py +0 -0
  48. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_messages.py +0 -0
  49. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_model_tool_emulator.py +0 -0
  50. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_pipline.py +0 -0
  51. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_plan_middleware.py +0 -0
  52. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_router_model.py +0 -0
  53. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_tool_calling.py +0 -0
  54. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/tests/test_wrap_agent.py +0 -0
  55. {langchain_dev_utils-1.2.5 → langchain_dev_utils-1.2.6}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langchain-dev-utils
3
- Version: 1.2.5
3
+ Version: 1.2.6
4
4
  Summary: A practical utility library for LangChain and LangGraph development
5
5
  Project-URL: Source Code, https://github.com/TBice123123/langchain-dev-utils
6
6
  Project-URL: repository, https://github.com/TBice123123/langchain-dev-utils
@@ -157,6 +157,8 @@ For stream responses obtained using `stream()` and `astream()`, you can use `mer
157
157
  | `chunks` | List[AIMessageChunk] | Yes | - | List of AIMessageChunk objects |
158
158
 
159
159
  ```python
160
+ from langchain_dev_utils.message_convert import merge_ai_message_chunk
161
+
160
162
  chunks = list(model.stream("Hello"))
161
163
  merged = merge_ai_message_chunk(chunks)
162
164
  ```
@@ -174,6 +176,7 @@ For a list, you can use `format_sequence` to format it.
174
176
  | `with_num` | bool | No | False | If True, add a numeric prefix to each item (e.g., "1. Hello") |
175
177
 
176
178
  ```python
179
+ from langchain_dev_utils.message_convert import format_sequence
177
180
  text = format_sequence([
178
181
  "str1",
179
182
  "str2",
@@ -205,7 +208,7 @@ Includes the following features:
205
208
  | Parameter | Type | Required | Default | Description |
206
209
  |-----------|------|----------|---------|-------------|
207
210
  | `message` | AIMessage | Yes | - | AIMessage object |
208
- | `first_tool_call_only` | bool | No | False | Whether to only check the first tool call |
211
+ | `first_tool_call_only` | bool | No | False | Whether to only parse the first tool call |
209
212
 
210
213
  ```python
211
214
  import datetime
@@ -234,7 +237,7 @@ if has_tool_calling(response):
234
237
  Both can accept a `handler` parameter for custom breakpoint return and response handling logic.
235
238
 
236
239
  ```python
237
- from langchain_dev_utils import human_in_the_loop
240
+ from langchain_dev_utils.tool_calling import human_in_the_loop
238
241
  from langchain_core.tools import tool
239
242
  import datetime
240
243
 
@@ -262,7 +265,7 @@ In LangChain v1, the officially provided `create_agent` function can be used to
262
265
 
263
266
  | Parameter | Type | Required | Default | Description |
264
267
  |-----------|------|----------|---------|-------------|
265
- | `model` | str \| BaseChatModel | Yes | - | Model name or model instance. Can be a string identifier for a model registered with `register_model_provider` or a BaseChatModel instance. |
268
+ | `model` | str | Yes | - | Model name or model instance. Can be a string identifier for a model registered with `register_model_provider` or a BaseChatModel instance. |
266
269
  | Other parameters | Various | No | - | All other parameters are the same as in `langchain.agents.create_agent` |
267
270
 
268
271
  Usage example:
@@ -317,7 +320,7 @@ Uses `create_sequential_pipeline`, supported parameters:
317
320
 
318
321
  | Parameter | Type | Required | Default | Description |
319
322
  |-----------|------|----------|---------|-------------|
320
- | `sub_graphs` | List[StateGraph] | Yes | - | List of state graphs to combine (must be StateGraph instances) |
323
+ | `sub_graphs` | List[StateGraph\|CompiledStateGraph] | Yes | - | List of state graphs to combine (must be StateGraph instances or CompiledStateGraph instances) |
321
324
  | `state_schema` | type | Yes | - | State Schema for the final generated graph |
322
325
  | `graph_name` | str | No | - | Name of the final generated graph |
323
326
  | `context_schema` | type | No | - | Context Schema for the final generated graph |
@@ -378,7 +381,7 @@ Uses `create_parallel_pipeline`, supported parameters:
378
381
 
379
382
  | Parameter | Type | Required | Default | Description |
380
383
  |-----------|------|----------|---------|-------------|
381
- | `sub_graphs` | List[StateGraph] | Yes | - | List of state graphs to combine |
384
+ | `sub_graphs` | List[StateGraph\|CompiledStateGraph] | Yes | - | List of state graphs to combine (must be StateGraph instances or CompiledStateGraph instances) |
382
385
  | `state_schema` | type | Yes | - | State Schema for the final generated graph |
383
386
  | `branches_fn` | Callable | Yes | - | Parallel branch function, returns a list of Send objects to control parallel execution |
384
387
  | `graph_name` | str | No | - | Name of the final generated graph |
@@ -141,6 +141,8 @@ For stream responses obtained using `stream()` and `astream()`, you can use `mer
141
141
  | `chunks` | List[AIMessageChunk] | Yes | - | List of AIMessageChunk objects |
142
142
 
143
143
  ```python
144
+ from langchain_dev_utils.message_convert import merge_ai_message_chunk
145
+
144
146
  chunks = list(model.stream("Hello"))
145
147
  merged = merge_ai_message_chunk(chunks)
146
148
  ```
@@ -158,6 +160,7 @@ For a list, you can use `format_sequence` to format it.
158
160
  | `with_num` | bool | No | False | If True, add a numeric prefix to each item (e.g., "1. Hello") |
159
161
 
160
162
  ```python
163
+ from langchain_dev_utils.message_convert import format_sequence
161
164
  text = format_sequence([
162
165
  "str1",
163
166
  "str2",
@@ -189,7 +192,7 @@ Includes the following features:
189
192
  | Parameter | Type | Required | Default | Description |
190
193
  |-----------|------|----------|---------|-------------|
191
194
  | `message` | AIMessage | Yes | - | AIMessage object |
192
- | `first_tool_call_only` | bool | No | False | Whether to only check the first tool call |
195
+ | `first_tool_call_only` | bool | No | False | Whether to only parse the first tool call |
193
196
 
194
197
  ```python
195
198
  import datetime
@@ -218,7 +221,7 @@ if has_tool_calling(response):
218
221
  Both can accept a `handler` parameter for custom breakpoint return and response handling logic.
219
222
 
220
223
  ```python
221
- from langchain_dev_utils import human_in_the_loop
224
+ from langchain_dev_utils.tool_calling import human_in_the_loop
222
225
  from langchain_core.tools import tool
223
226
  import datetime
224
227
 
@@ -246,7 +249,7 @@ In LangChain v1, the officially provided `create_agent` function can be used to
246
249
 
247
250
  | Parameter | Type | Required | Default | Description |
248
251
  |-----------|------|----------|---------|-------------|
249
- | `model` | str \| BaseChatModel | Yes | - | Model name or model instance. Can be a string identifier for a model registered with `register_model_provider` or a BaseChatModel instance. |
252
+ | `model` | str | Yes | - | Model name or model instance. Can be a string identifier for a model registered with `register_model_provider` or a BaseChatModel instance. |
250
253
  | Other parameters | Various | No | - | All other parameters are the same as in `langchain.agents.create_agent` |
251
254
 
252
255
  Usage example:
@@ -301,7 +304,7 @@ Uses `create_sequential_pipeline`, supported parameters:
301
304
 
302
305
  | Parameter | Type | Required | Default | Description |
303
306
  |-----------|------|----------|---------|-------------|
304
- | `sub_graphs` | List[StateGraph] | Yes | - | List of state graphs to combine (must be StateGraph instances) |
307
+ | `sub_graphs` | List[StateGraph\|CompiledStateGraph] | Yes | - | List of state graphs to combine (must be StateGraph instances or CompiledStateGraph instances) |
305
308
  | `state_schema` | type | Yes | - | State Schema for the final generated graph |
306
309
  | `graph_name` | str | No | - | Name of the final generated graph |
307
310
  | `context_schema` | type | No | - | Context Schema for the final generated graph |
@@ -362,7 +365,7 @@ Uses `create_parallel_pipeline`, supported parameters:
362
365
 
363
366
  | Parameter | Type | Required | Default | Description |
364
367
  |-----------|------|----------|---------|-------------|
365
- | `sub_graphs` | List[StateGraph] | Yes | - | List of state graphs to combine |
368
+ | `sub_graphs` | List[StateGraph\|CompiledStateGraph] | Yes | - | List of state graphs to combine (must be StateGraph instances or CompiledStateGraph instances) |
366
369
  | `state_schema` | type | Yes | - | State Schema for the final generated graph |
367
370
  | `branches_fn` | Callable | Yes | - | Parallel branch function, returns a list of Send objects to control parallel execution |
368
371
  | `graph_name` | str | No | - | Name of the final generated graph |
@@ -141,6 +141,7 @@ print(emb)
141
141
  | `chunks` | List[AIMessageChunk] | 是 | - | AIMessageChunk 列表 |
142
142
 
143
143
  ```python
144
+ from langchain_dev_utils.message_convert import merge_ai_message_chunk
144
145
  chunks = list(model.stream("Hello"))
145
146
  merged = merge_ai_message_chunk(chunks)
146
147
  ```
@@ -158,6 +159,7 @@ merged = merge_ai_message_chunk(chunks)
158
159
  | `with_num` | bool | 否 | False | 如果为 True,为每个项目添加数字前缀(例如 "1. 你好") |
159
160
 
160
161
  ```python
162
+ from langchain_dev_utils.message_convert import format_sequence
161
163
  text = format_sequence([
162
164
  "str1",
163
165
  "str2",
@@ -189,7 +191,7 @@ text = format_sequence([
189
191
  | 参数名 | 类型 | 必填 | 默认值 | 描述 |
190
192
  |--------|------|------|--------|------|
191
193
  | `message` | AIMessage | 是 | - | AIMessage 对象 |
192
- | `first_tool_call_only` | bool | 否 | False | 是否只检查第一个工具调用 |
194
+ | `first_tool_call_only` | bool | 否 | False | 是否只解析第一个工具调用 |
193
195
 
194
196
  ```python
195
197
  import datetime
@@ -218,7 +220,7 @@ if has_tool_calling(response):
218
220
  其中都可以传递`handler`参数,用于自定义断点返回和响应处理逻辑。
219
221
 
220
222
  ```python
221
- from langchain_dev_utils import human_in_the_loop
223
+ from langchain_dev_utils.tool_calling import human_in_the_loop
222
224
  from langchain_core.tools import tool
223
225
  import datetime
224
226
 
@@ -246,9 +248,9 @@ LangChain v1 版本中,官方提供的 `create_agent` 函数可以用于创建
246
248
 
247
249
  | 参数名 | 类型 | 必填 | 默认值 | 描述 |
248
250
  |--------|------|------|--------|------|
249
- | `model` | str \| BaseChatModel | 是 | - | 模型名称或模型实例 |
251
+ | `model` | str | 是 | - | 模型名称|
252
+ | 其余参数 | Various | No | - | 其余参数与 `langchain.agents.create_agent` 函数相同|
250
253
 
251
- **其余参数与 `langchain.agents.create_agent` 函数相同。**
252
254
 
253
255
  使用示例:
254
256
 
@@ -302,7 +304,7 @@ print(response)
302
304
 
303
305
  | 参数名 | 类型 | 必填 | 默认值 | 描述 |
304
306
  |--------|------|------|--------|------|
305
- | `sub_graphs` | List[StateGraph] | 是 | - | 要组合的状态图列表(必须是 StateGraph 实例) |
307
+ | `sub_graphs` | List[StateGraph\|CompiledStateGraph] | 是 | - | 要组合的状态图列表(必须是 StateGraph 实例 或 CompiledStateGraph 实例) |
306
308
  | `state_schema` | type | 是 | - | 最终生成图的 State Schema |
307
309
  | `graph_name` | str | 否 | - | 最终生成图的名称 |
308
310
  | `context_schema` | type | 否 | - | 最终生成图的 Context Schema |
@@ -363,7 +365,7 @@ print(response)
363
365
 
364
366
  | 参数名 | 类型 | 必填 | 默认值 | 描述 |
365
367
  |--------|------|------|--------|------|
366
- | `sub_graphs` | List[StateGraph] | 是 | - | 要组合的状态图列表 |
368
+ | `sub_graphs` | List[StateGraph\|CompiledStateGraph] | 是 | - | 要组合的状态图列表(必须是 StateGraph 实例 或 CompiledStateGraph 实例) |
367
369
  | `state_schema` | type | 是 | - | 最终生成图的 State Schema |
368
370
  | `branches_fn` | Callable | 是 | - | 并行分支函数,返回 Send 对象列表控制并行执行 |
369
371
  | `graph_name` | str | 否 | - | 最终生成图的名称 |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "langchain-dev-utils"
3
- version = "1.2.5"
3
+ version = "1.2.6"
4
4
  description = "A practical utility library for LangChain and LangGraph development"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "tiebingice", email = "tiebingice123@outlook.com" }]
@@ -0,0 +1 @@
1
+ __version__ = "1.2.6"
@@ -0,0 +1,39 @@
1
+ from importlib import util
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ def _check_langchain_openai_install() -> None:
7
+ if not util.find_spec("langchain_openai"):
8
+ msg = (
9
+ "Please install langchain_dev_utils[standard],when use 'openai-compatible'"
10
+ )
11
+ raise ImportError(msg)
12
+
13
+
14
+ def _get_base_url_field_name(model_cls: type[BaseModel]) -> str | None:
15
+ """
16
+ Return 'base_url' if the model has a field named or aliased as 'base_url',
17
+ else return 'api_base' if it has a field named or aliased as 'api_base',
18
+ else return None.
19
+ The return value is always either 'base_url', 'api_base', or None.
20
+ """
21
+ model_fields = model_cls.model_fields
22
+
23
+ # try model_fields first
24
+ if "base_url" in model_fields:
25
+ return "base_url"
26
+
27
+ if "api_base" in model_fields:
28
+ return "api_base"
29
+
30
+ # then try aliases
31
+ for field_info in model_fields.values():
32
+ if field_info.alias == "base_url":
33
+ return "base_url"
34
+
35
+ for field_info in model_fields.values():
36
+ if field_info.alias == "api_base":
37
+ return "api_base"
38
+
39
+ return None
@@ -3,7 +3,11 @@ from typing import Any, NotRequired, Optional, TypedDict, cast
3
3
  from langchain.chat_models.base import _SUPPORTED_PROVIDERS, _init_chat_model_helper
4
4
  from langchain_core.language_models.chat_models import BaseChatModel
5
5
  from langchain_core.utils import from_env
6
- from pydantic import BaseModel
6
+
7
+ from langchain_dev_utils._utils import (
8
+ _check_langchain_openai_install,
9
+ _get_base_url_field_name,
10
+ )
7
11
 
8
12
  from .types import ChatModelType, CompatibilityOptions
9
13
 
@@ -18,34 +22,6 @@ class ChatModelProvider(TypedDict):
18
22
  compatibility_options: NotRequired[CompatibilityOptions]
19
23
 
20
24
 
21
- def _get_base_url_field_name(model_cls: type[BaseModel]) -> str | None:
22
- """
23
- Return 'base_url' if the model has a field named or aliased as 'base_url',
24
- else return 'api_base' if it has a field named or aliased as 'api_base',
25
- else return None.
26
- The return value is always either 'base_url', 'api_base', or None.
27
- """
28
- model_fields = model_cls.model_fields
29
-
30
- # try model_fields first
31
- if "base_url" in model_fields:
32
- return "base_url"
33
-
34
- if "api_base" in model_fields:
35
- return "api_base"
36
-
37
- # then try aliases
38
- for field_info in model_fields.values():
39
- if field_info.alias == "base_url":
40
- return "base_url"
41
-
42
- for field_info in model_fields.values():
43
- if field_info.alias == "api_base":
44
- return "api_base"
45
-
46
- return None
47
-
48
-
49
25
  def _parse_model(model: str, model_provider: Optional[str]) -> tuple[str, str]:
50
26
  """Parse model string and provider.
51
27
 
@@ -89,7 +65,7 @@ def _load_chat_model_helper(
89
65
  BaseChatModel: Initialized chat model instance
90
66
  """
91
67
  model, model_provider = _parse_model(model, model_provider)
92
- if model_provider in _MODEL_PROVIDERS_DICT.keys():
68
+ if model_provider in _MODEL_PROVIDERS_DICT:
93
69
  chat_model = _MODEL_PROVIDERS_DICT[model_provider]["chat_model"]
94
70
  if base_url := _MODEL_PROVIDERS_DICT[model_provider].get("base_url"):
95
71
  url_key = _get_base_url_field_name(chat_model)
@@ -98,7 +74,7 @@ def _load_chat_model_helper(
98
74
  if model_profiles := _MODEL_PROVIDERS_DICT[model_provider].get(
99
75
  "model_profiles"
100
76
  ):
101
- if model in model_profiles:
77
+ if model in model_profiles and "profile" not in kwargs:
102
78
  kwargs.update({"profile": model_profiles[model]})
103
79
  return chat_model(model=model, **kwargs)
104
80
 
@@ -145,12 +121,9 @@ def register_model_provider(
145
121
  """
146
122
  base_url = base_url or from_env(f"{provider_name.upper()}_API_BASE", default=None)()
147
123
  if isinstance(chat_model, str):
148
- try:
149
- from .adapters.openai_compatible import _create_openai_compatible_model
150
- except ImportError:
151
- raise ImportError(
152
- "Please install langchain_dev_utils[standard],when chat_model is a 'openai-compatible'"
153
- )
124
+ _check_langchain_openai_install()
125
+ from .adapters.openai_compatible import _create_openai_compatible_model
126
+
154
127
  if base_url is None:
155
128
  raise ValueError(
156
129
  f"base_url must be provided or set {provider_name.upper()}_API_BASE environment variable when chat_model is a string"
@@ -2,7 +2,11 @@ from typing import Any, Literal, NotRequired, Optional, TypedDict, Union
2
2
 
3
3
  from langchain.embeddings.base import Embeddings, _SUPPORTED_PROVIDERS, init_embeddings
4
4
  from langchain_core.utils import from_env, secret_from_env
5
- from pydantic import BaseModel
5
+
6
+ from langchain_dev_utils._utils import (
7
+ _check_langchain_openai_install,
8
+ _get_base_url_field_name,
9
+ )
6
10
 
7
11
  _EMBEDDINGS_PROVIDERS_DICT = {}
8
12
 
@@ -15,34 +19,6 @@ class EmbeddingProvider(TypedDict):
15
19
  base_url: NotRequired[str]
16
20
 
17
21
 
18
- def _get_base_url_field_name(model_cls: type[BaseModel]) -> str | None:
19
- """
20
- Return 'base_url' if the model has a field named or aliased as 'base_url',
21
- else return 'api_base' if it has a field named or aliased as 'api_base',
22
- else return None.
23
- The return value is always either 'base_url', 'api_base', or None.
24
- """
25
- model_fields = model_cls.model_fields
26
-
27
- # try model_fields first
28
- if "base_url" in model_fields:
29
- return "base_url"
30
-
31
- if "api_base" in model_fields:
32
- return "api_base"
33
-
34
- # then try aliases
35
- for field_info in model_fields.values():
36
- if field_info.alias == "base_url":
37
- return "base_url"
38
-
39
- for field_info in model_fields.values():
40
- if field_info.alias == "api_base":
41
- return "api_base"
42
-
43
- return None
44
-
45
-
46
22
  def _parse_model_string(model_name: str) -> tuple[str, str]:
47
23
  """Parse model string into provider and model name.
48
24
 
@@ -119,6 +95,8 @@ def register_embeddings_provider(
119
95
  "when embeddings_model is a string, the value must be 'openai-compatible'"
120
96
  )
121
97
 
98
+ _check_langchain_openai_install()
99
+
122
100
  _EMBEDDINGS_PROVIDERS_DICT.update(
123
101
  {
124
102
  provider_name: {
@@ -238,7 +216,6 @@ def load_embeddings(
238
216
  if embeddings == "openai-compatible":
239
217
  kwargs["check_embedding_ctx_length"] = False
240
218
  embeddings = "openai"
241
-
242
219
  return init_embeddings(
243
220
  model=model,
244
221
  provider=embeddings,
@@ -1 +0,0 @@
1
- __version__ = "1.2.5"