infinity_llm_client 0.1.0__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.
- infinity_llm_client-0.1.0/LICENSE.md +21 -0
- infinity_llm_client-0.1.0/PKG-INFO +110 -0
- infinity_llm_client-0.1.0/README.md +76 -0
- infinity_llm_client-0.1.0/pyproject.toml +114 -0
- infinity_llm_client-0.1.0/setup.cfg +4 -0
- infinity_llm_client-0.1.0/src/infinity_llm_client.egg-info/PKG-INFO +110 -0
- infinity_llm_client-0.1.0/src/infinity_llm_client.egg-info/SOURCES.txt +29 -0
- infinity_llm_client-0.1.0/src/infinity_llm_client.egg-info/dependency_links.txt +1 -0
- infinity_llm_client-0.1.0/src/infinity_llm_client.egg-info/requires.txt +14 -0
- infinity_llm_client-0.1.0/src/infinity_llm_client.egg-info/top_level.txt +1 -0
- infinity_llm_client-0.1.0/src/llm/__init__.py +60 -0
- infinity_llm_client-0.1.0/src/llm/clients/__init__.py +63 -0
- infinity_llm_client-0.1.0/src/llm/clients/base.py +78 -0
- infinity_llm_client-0.1.0/src/llm/clients/config.py +28 -0
- infinity_llm_client-0.1.0/src/llm/clients/exceptions.py +129 -0
- infinity_llm_client-0.1.0/src/llm/clients/open_ai/__init__.py +27 -0
- infinity_llm_client-0.1.0/src/llm/clients/open_ai/aggregation.py +63 -0
- infinity_llm_client-0.1.0/src/llm/clients/open_ai/client.py +261 -0
- infinity_llm_client-0.1.0/src/llm/clients/open_ai/config.py +34 -0
- infinity_llm_client-0.1.0/src/llm/clients/open_ai/connection.py +167 -0
- infinity_llm_client-0.1.0/src/llm/clients/open_ai/open_ai_models.py +121 -0
- infinity_llm_client-0.1.0/src/llm/clients/open_ai/response_format.py +42 -0
- infinity_llm_client-0.1.0/src/llm/clients/provider.py +38 -0
- infinity_llm_client-0.1.0/src/llm/models/__init__.py +58 -0
- infinity_llm_client-0.1.0/src/llm/models/chunks.py +47 -0
- infinity_llm_client-0.1.0/src/llm/models/messages.py +131 -0
- infinity_llm_client-0.1.0/src/llm/models/tools.py +213 -0
- infinity_llm_client-0.1.0/src/llm/py.typed +0 -0
- infinity_llm_client-0.1.0/src/llm/tools/__init__.py +6 -0
- infinity_llm_client-0.1.0/src/llm/tools/introspection.py +378 -0
- infinity_llm_client-0.1.0/src/llm/tools/registry.py +251 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 infinity_system
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: infinity_llm_client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 强类型、可扩展的 LLM 异步客户端库,支持 OpenAI 兼容 API、流式对话、工具调用与多模型消息格式
|
|
5
|
+
Author: infinity_system: yin_bailiang
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/yinbailiang/infinity_llm
|
|
8
|
+
Keywords: llm,openai,async,asyncio,function-calling,tool-calling,streaming,chat
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
+
Classifier: Framework :: AsyncIO
|
|
18
|
+
Requires-Python: >=3.12
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE.md
|
|
21
|
+
Requires-Dist: pydantic
|
|
22
|
+
Requires-Dist: aiohttp
|
|
23
|
+
Provides-Extra: test
|
|
24
|
+
Requires-Dist: pytest; extra == "test"
|
|
25
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
26
|
+
Requires-Dist: pytest-asyncio; extra == "test"
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: interrogate; extra == "dev"
|
|
29
|
+
Requires-Dist: ruff; extra == "dev"
|
|
30
|
+
Requires-Dist: pyright; extra == "dev"
|
|
31
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
32
|
+
Requires-Dist: infinity_llm_client[test]; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# InfinityLLM — Async LLM Client
|
|
36
|
+
|
|
37
|
+
[](https://github.com/yinbailiang/infinity_llm/actions/workflows/test.yml)
|
|
38
|
+
[](ENGINEERING.md)
|
|
39
|
+
[](LICENSE.md)
|
|
40
|
+
[](https://pypi.org/project/infinity_llm/)
|
|
41
|
+
|
|
42
|
+
**强类型、可扩展的 LLM 异步客户端库 — 支持 OpenAI 兼容 API、流式对话、工具调用。**
|
|
43
|
+
|
|
44
|
+
## ✨ Features
|
|
45
|
+
|
|
46
|
+
| 类别 | 能力 |
|
|
47
|
+
| - | - |
|
|
48
|
+
| 类型安全 | Pydantic 负载校验 · pyright **strict** |
|
|
49
|
+
| 多 Provider | 工厂注册模式,轻松扩展新 LLM 服务商 |
|
|
50
|
+
| OpenAI 兼容 | 完整实现 OpenAI Chat Completions 流式 API |
|
|
51
|
+
| 工具调用 | ToolRegistry 自动从 Python 函数推断 Tool Schema |
|
|
52
|
+
| 流式对话 | `stream_chat()` 异步生成器,支持 Text / ToolCall / Usage chunk |
|
|
53
|
+
| 多模态消息 | 文本 + 图片 URL 混合内容 |
|
|
54
|
+
| 连接管理 | 指数退避重试 + 抖动 + 连接池复用 |
|
|
55
|
+
|
|
56
|
+
## 📦 Installation
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install infinity_llm
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 🚀 Quick Start
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from llm import (
|
|
66
|
+
Message, Messages,
|
|
67
|
+
OpenAIConfig, create_client,
|
|
68
|
+
ToolRegistry,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# 创建客户端
|
|
72
|
+
config = OpenAIConfig(
|
|
73
|
+
model="gpt-4o-mini",
|
|
74
|
+
api_key="sk-...",
|
|
75
|
+
)
|
|
76
|
+
client = create_client(config)
|
|
77
|
+
|
|
78
|
+
# 流式对话
|
|
79
|
+
messages = Messages([
|
|
80
|
+
Message.system("你是一个有用的助手"),
|
|
81
|
+
Message.user("你好"),
|
|
82
|
+
])
|
|
83
|
+
|
|
84
|
+
async with client:
|
|
85
|
+
async for chunk in client.stream_chat(messages):
|
|
86
|
+
print(chunk)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 🧱 Architecture
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
llm/
|
|
93
|
+
├── clients/ # 客户端抽象 + provider 实现
|
|
94
|
+
│ ├── base.py # LLMClient 抽象基类
|
|
95
|
+
│ ├── config.py # ConnectionConfig / LLMConfig
|
|
96
|
+
│ ├── exceptions.py # 异常层级
|
|
97
|
+
│ ├── provider.py # 工厂注册表
|
|
98
|
+
│ └── open_ai/ # OpenAI 兼容实现
|
|
99
|
+
├── models/ # 消息 / Chunk / 工具定义
|
|
100
|
+
│ ├── messages.py # Message, Messages, ToolCall
|
|
101
|
+
│ ├── chunks.py # StreamChunk 子类
|
|
102
|
+
│ └── tools.py # ToolDefinition, ParameterProperty
|
|
103
|
+
└── tools/ # 工具注册与类型推断
|
|
104
|
+
├── registry.py # ToolRegistry
|
|
105
|
+
└── introspection.py # 函数 → ToolDefinition 自动推断
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 📄 License
|
|
109
|
+
|
|
110
|
+
MIT
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# InfinityLLM — Async LLM Client
|
|
2
|
+
|
|
3
|
+
[](https://github.com/yinbailiang/infinity_llm/actions/workflows/test.yml)
|
|
4
|
+
[](ENGINEERING.md)
|
|
5
|
+
[](LICENSE.md)
|
|
6
|
+
[](https://pypi.org/project/infinity_llm/)
|
|
7
|
+
|
|
8
|
+
**强类型、可扩展的 LLM 异步客户端库 — 支持 OpenAI 兼容 API、流式对话、工具调用。**
|
|
9
|
+
|
|
10
|
+
## ✨ Features
|
|
11
|
+
|
|
12
|
+
| 类别 | 能力 |
|
|
13
|
+
| - | - |
|
|
14
|
+
| 类型安全 | Pydantic 负载校验 · pyright **strict** |
|
|
15
|
+
| 多 Provider | 工厂注册模式,轻松扩展新 LLM 服务商 |
|
|
16
|
+
| OpenAI 兼容 | 完整实现 OpenAI Chat Completions 流式 API |
|
|
17
|
+
| 工具调用 | ToolRegistry 自动从 Python 函数推断 Tool Schema |
|
|
18
|
+
| 流式对话 | `stream_chat()` 异步生成器,支持 Text / ToolCall / Usage chunk |
|
|
19
|
+
| 多模态消息 | 文本 + 图片 URL 混合内容 |
|
|
20
|
+
| 连接管理 | 指数退避重试 + 抖动 + 连接池复用 |
|
|
21
|
+
|
|
22
|
+
## 📦 Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install infinity_llm
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 🚀 Quick Start
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from llm import (
|
|
32
|
+
Message, Messages,
|
|
33
|
+
OpenAIConfig, create_client,
|
|
34
|
+
ToolRegistry,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# 创建客户端
|
|
38
|
+
config = OpenAIConfig(
|
|
39
|
+
model="gpt-4o-mini",
|
|
40
|
+
api_key="sk-...",
|
|
41
|
+
)
|
|
42
|
+
client = create_client(config)
|
|
43
|
+
|
|
44
|
+
# 流式对话
|
|
45
|
+
messages = Messages([
|
|
46
|
+
Message.system("你是一个有用的助手"),
|
|
47
|
+
Message.user("你好"),
|
|
48
|
+
])
|
|
49
|
+
|
|
50
|
+
async with client:
|
|
51
|
+
async for chunk in client.stream_chat(messages):
|
|
52
|
+
print(chunk)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 🧱 Architecture
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
llm/
|
|
59
|
+
├── clients/ # 客户端抽象 + provider 实现
|
|
60
|
+
│ ├── base.py # LLMClient 抽象基类
|
|
61
|
+
│ ├── config.py # ConnectionConfig / LLMConfig
|
|
62
|
+
│ ├── exceptions.py # 异常层级
|
|
63
|
+
│ ├── provider.py # 工厂注册表
|
|
64
|
+
│ └── open_ai/ # OpenAI 兼容实现
|
|
65
|
+
├── models/ # 消息 / Chunk / 工具定义
|
|
66
|
+
│ ├── messages.py # Message, Messages, ToolCall
|
|
67
|
+
│ ├── chunks.py # StreamChunk 子类
|
|
68
|
+
│ └── tools.py # ToolDefinition, ParameterProperty
|
|
69
|
+
└── tools/ # 工具注册与类型推断
|
|
70
|
+
├── registry.py # ToolRegistry
|
|
71
|
+
└── introspection.py # 函数 → ToolDefinition 自动推断
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 📄 License
|
|
75
|
+
|
|
76
|
+
MIT
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "infinity_llm_client"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "强类型、可扩展的 LLM 异步客户端库,支持 OpenAI 兼容 API、流式对话、工具调用与多模型消息格式"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = { text = "MIT" }
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "infinity_system: yin_bailiang" }
|
|
9
|
+
]
|
|
10
|
+
keywords = [
|
|
11
|
+
"llm",
|
|
12
|
+
"openai",
|
|
13
|
+
"async",
|
|
14
|
+
"asyncio",
|
|
15
|
+
"function-calling",
|
|
16
|
+
"tool-calling",
|
|
17
|
+
"streaming",
|
|
18
|
+
"chat",
|
|
19
|
+
]
|
|
20
|
+
classifiers = [
|
|
21
|
+
"Development Status :: 3 - Alpha",
|
|
22
|
+
"Intended Audience :: Developers",
|
|
23
|
+
"License :: OSI Approved :: MIT License",
|
|
24
|
+
"Operating System :: OS Independent",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
29
|
+
"Framework :: AsyncIO",
|
|
30
|
+
]
|
|
31
|
+
requires-python = ">=3.12"
|
|
32
|
+
|
|
33
|
+
dependencies = [
|
|
34
|
+
"pydantic",
|
|
35
|
+
"aiohttp",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Repository = "https://github.com/yinbailiang/infinity_llm"
|
|
40
|
+
|
|
41
|
+
[project.optional-dependencies]
|
|
42
|
+
test = [
|
|
43
|
+
"pytest",
|
|
44
|
+
"pytest-cov",
|
|
45
|
+
"pytest-asyncio",
|
|
46
|
+
]
|
|
47
|
+
dev = [
|
|
48
|
+
"interrogate",
|
|
49
|
+
"ruff",
|
|
50
|
+
"pyright",
|
|
51
|
+
"pre-commit",
|
|
52
|
+
"infinity_llm_client[test]",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[tool.pytest.ini_options]
|
|
56
|
+
asyncio_mode = "auto"
|
|
57
|
+
addopts = "-m 'not slow'"
|
|
58
|
+
markers = [
|
|
59
|
+
"slow: long-running stress / stability tests",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
[build-system]
|
|
63
|
+
requires = ["setuptools>=61.0"]
|
|
64
|
+
build-backend = "setuptools.build_meta"
|
|
65
|
+
|
|
66
|
+
[tool.setuptools]
|
|
67
|
+
package-dir = {"" = "src"}
|
|
68
|
+
|
|
69
|
+
[tool.setuptools.packages.find]
|
|
70
|
+
where = ["src"]
|
|
71
|
+
|
|
72
|
+
[tool.ruff]
|
|
73
|
+
line-length = 120
|
|
74
|
+
target-version = "py312"
|
|
75
|
+
exclude = ["tests"]
|
|
76
|
+
|
|
77
|
+
[tool.ruff.lint]
|
|
78
|
+
select = [
|
|
79
|
+
"E", # pycodestyle errors
|
|
80
|
+
"F", # pyflakes
|
|
81
|
+
"I", # isort
|
|
82
|
+
"ASYNC", # async/await best practices
|
|
83
|
+
"PLE", # pylint errors
|
|
84
|
+
]
|
|
85
|
+
ignore = [
|
|
86
|
+
"E501", # line too long (handled by formatter)
|
|
87
|
+
"ASYNC109", # async function with timeout parameter (intentional API design)
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
[tool.ruff.lint.isort]
|
|
91
|
+
known-first-party = ["llm"]
|
|
92
|
+
|
|
93
|
+
[tool.ruff.format]
|
|
94
|
+
indent-style = "space"
|
|
95
|
+
quote-style = "single"
|
|
96
|
+
line-ending = "lf"
|
|
97
|
+
|
|
98
|
+
[tool.pyright]
|
|
99
|
+
typeCheckingMode = "strict"
|
|
100
|
+
reportMissingTypeStubs = false
|
|
101
|
+
reportMissingImports = "error"
|
|
102
|
+
exclude = ["tests", "**/node_modules", "**/__pycache__", "**/.*", ".venv"]
|
|
103
|
+
venvPath = "."
|
|
104
|
+
venv = ".venv"
|
|
105
|
+
|
|
106
|
+
[tool.interrogate]
|
|
107
|
+
fail-under = 60
|
|
108
|
+
ignore-init-method = true
|
|
109
|
+
ignore-init-module = true
|
|
110
|
+
ignore-magic = true
|
|
111
|
+
ignore-private = true
|
|
112
|
+
ignore-semiprivate = true
|
|
113
|
+
ignore-nested-functions = true
|
|
114
|
+
exclude = ["tests", "benchmarks", "experimental", "docs"]
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: infinity_llm_client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 强类型、可扩展的 LLM 异步客户端库,支持 OpenAI 兼容 API、流式对话、工具调用与多模型消息格式
|
|
5
|
+
Author: infinity_system: yin_bailiang
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/yinbailiang/infinity_llm
|
|
8
|
+
Keywords: llm,openai,async,asyncio,function-calling,tool-calling,streaming,chat
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
+
Classifier: Framework :: AsyncIO
|
|
18
|
+
Requires-Python: >=3.12
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE.md
|
|
21
|
+
Requires-Dist: pydantic
|
|
22
|
+
Requires-Dist: aiohttp
|
|
23
|
+
Provides-Extra: test
|
|
24
|
+
Requires-Dist: pytest; extra == "test"
|
|
25
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
26
|
+
Requires-Dist: pytest-asyncio; extra == "test"
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: interrogate; extra == "dev"
|
|
29
|
+
Requires-Dist: ruff; extra == "dev"
|
|
30
|
+
Requires-Dist: pyright; extra == "dev"
|
|
31
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
32
|
+
Requires-Dist: infinity_llm_client[test]; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# InfinityLLM — Async LLM Client
|
|
36
|
+
|
|
37
|
+
[](https://github.com/yinbailiang/infinity_llm/actions/workflows/test.yml)
|
|
38
|
+
[](ENGINEERING.md)
|
|
39
|
+
[](LICENSE.md)
|
|
40
|
+
[](https://pypi.org/project/infinity_llm/)
|
|
41
|
+
|
|
42
|
+
**强类型、可扩展的 LLM 异步客户端库 — 支持 OpenAI 兼容 API、流式对话、工具调用。**
|
|
43
|
+
|
|
44
|
+
## ✨ Features
|
|
45
|
+
|
|
46
|
+
| 类别 | 能力 |
|
|
47
|
+
| - | - |
|
|
48
|
+
| 类型安全 | Pydantic 负载校验 · pyright **strict** |
|
|
49
|
+
| 多 Provider | 工厂注册模式,轻松扩展新 LLM 服务商 |
|
|
50
|
+
| OpenAI 兼容 | 完整实现 OpenAI Chat Completions 流式 API |
|
|
51
|
+
| 工具调用 | ToolRegistry 自动从 Python 函数推断 Tool Schema |
|
|
52
|
+
| 流式对话 | `stream_chat()` 异步生成器,支持 Text / ToolCall / Usage chunk |
|
|
53
|
+
| 多模态消息 | 文本 + 图片 URL 混合内容 |
|
|
54
|
+
| 连接管理 | 指数退避重试 + 抖动 + 连接池复用 |
|
|
55
|
+
|
|
56
|
+
## 📦 Installation
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install infinity_llm
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 🚀 Quick Start
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from llm import (
|
|
66
|
+
Message, Messages,
|
|
67
|
+
OpenAIConfig, create_client,
|
|
68
|
+
ToolRegistry,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# 创建客户端
|
|
72
|
+
config = OpenAIConfig(
|
|
73
|
+
model="gpt-4o-mini",
|
|
74
|
+
api_key="sk-...",
|
|
75
|
+
)
|
|
76
|
+
client = create_client(config)
|
|
77
|
+
|
|
78
|
+
# 流式对话
|
|
79
|
+
messages = Messages([
|
|
80
|
+
Message.system("你是一个有用的助手"),
|
|
81
|
+
Message.user("你好"),
|
|
82
|
+
])
|
|
83
|
+
|
|
84
|
+
async with client:
|
|
85
|
+
async for chunk in client.stream_chat(messages):
|
|
86
|
+
print(chunk)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 🧱 Architecture
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
llm/
|
|
93
|
+
├── clients/ # 客户端抽象 + provider 实现
|
|
94
|
+
│ ├── base.py # LLMClient 抽象基类
|
|
95
|
+
│ ├── config.py # ConnectionConfig / LLMConfig
|
|
96
|
+
│ ├── exceptions.py # 异常层级
|
|
97
|
+
│ ├── provider.py # 工厂注册表
|
|
98
|
+
│ └── open_ai/ # OpenAI 兼容实现
|
|
99
|
+
├── models/ # 消息 / Chunk / 工具定义
|
|
100
|
+
│ ├── messages.py # Message, Messages, ToolCall
|
|
101
|
+
│ ├── chunks.py # StreamChunk 子类
|
|
102
|
+
│ └── tools.py # ToolDefinition, ParameterProperty
|
|
103
|
+
└── tools/ # 工具注册与类型推断
|
|
104
|
+
├── registry.py # ToolRegistry
|
|
105
|
+
└── introspection.py # 函数 → ToolDefinition 自动推断
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 📄 License
|
|
109
|
+
|
|
110
|
+
MIT
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
LICENSE.md
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/infinity_llm_client.egg-info/PKG-INFO
|
|
5
|
+
src/infinity_llm_client.egg-info/SOURCES.txt
|
|
6
|
+
src/infinity_llm_client.egg-info/dependency_links.txt
|
|
7
|
+
src/infinity_llm_client.egg-info/requires.txt
|
|
8
|
+
src/infinity_llm_client.egg-info/top_level.txt
|
|
9
|
+
src/llm/__init__.py
|
|
10
|
+
src/llm/py.typed
|
|
11
|
+
src/llm/clients/__init__.py
|
|
12
|
+
src/llm/clients/base.py
|
|
13
|
+
src/llm/clients/config.py
|
|
14
|
+
src/llm/clients/exceptions.py
|
|
15
|
+
src/llm/clients/provider.py
|
|
16
|
+
src/llm/clients/open_ai/__init__.py
|
|
17
|
+
src/llm/clients/open_ai/aggregation.py
|
|
18
|
+
src/llm/clients/open_ai/client.py
|
|
19
|
+
src/llm/clients/open_ai/config.py
|
|
20
|
+
src/llm/clients/open_ai/connection.py
|
|
21
|
+
src/llm/clients/open_ai/open_ai_models.py
|
|
22
|
+
src/llm/clients/open_ai/response_format.py
|
|
23
|
+
src/llm/models/__init__.py
|
|
24
|
+
src/llm/models/chunks.py
|
|
25
|
+
src/llm/models/messages.py
|
|
26
|
+
src/llm/models/tools.py
|
|
27
|
+
src/llm/tools/__init__.py
|
|
28
|
+
src/llm/tools/introspection.py
|
|
29
|
+
src/llm/tools/registry.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
llm
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""LLM 模块公共 API"""
|
|
2
|
+
|
|
3
|
+
__version__ = '0.1.0'
|
|
4
|
+
|
|
5
|
+
from .models.chunks import (
|
|
6
|
+
DoneChunk,
|
|
7
|
+
FinishChunk,
|
|
8
|
+
StreamChunk,
|
|
9
|
+
TextChunk,
|
|
10
|
+
ToolCallCompleteChunk,
|
|
11
|
+
UsageChunk,
|
|
12
|
+
UsageStats,
|
|
13
|
+
)
|
|
14
|
+
from .models.messages import (
|
|
15
|
+
ContentType,
|
|
16
|
+
FunctionCall,
|
|
17
|
+
ImageUrl,
|
|
18
|
+
Message,
|
|
19
|
+
MessageContent,
|
|
20
|
+
MessageRole,
|
|
21
|
+
Messages,
|
|
22
|
+
MultiModalContent,
|
|
23
|
+
ToolCall,
|
|
24
|
+
)
|
|
25
|
+
from .models.tools import (
|
|
26
|
+
ParameterProperty,
|
|
27
|
+
ToolDefinition,
|
|
28
|
+
ToolDefinitions,
|
|
29
|
+
ToolFunction,
|
|
30
|
+
ToolParameters,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
'__version__',
|
|
35
|
+
# -- 消息 --
|
|
36
|
+
'Message',
|
|
37
|
+
'MessageRole',
|
|
38
|
+
'Messages',
|
|
39
|
+
'MessageContent',
|
|
40
|
+
'ContentType',
|
|
41
|
+
'MultiModalContent',
|
|
42
|
+
'ImageUrl',
|
|
43
|
+
# -- 工具调用 --
|
|
44
|
+
'ToolCall',
|
|
45
|
+
'FunctionCall',
|
|
46
|
+
# -- 工具定义 --
|
|
47
|
+
'ToolDefinition',
|
|
48
|
+
'ToolDefinitions',
|
|
49
|
+
'ToolFunction',
|
|
50
|
+
'ToolParameters',
|
|
51
|
+
'ParameterProperty',
|
|
52
|
+
# -- 流式 Chunk --
|
|
53
|
+
'StreamChunk',
|
|
54
|
+
'TextChunk',
|
|
55
|
+
'ToolCallCompleteChunk',
|
|
56
|
+
'UsageChunk',
|
|
57
|
+
'FinishChunk',
|
|
58
|
+
'DoneChunk',
|
|
59
|
+
'UsageStats',
|
|
60
|
+
]
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from ..models import (
|
|
2
|
+
DoneChunk,
|
|
3
|
+
FinishChunk,
|
|
4
|
+
StreamChunk,
|
|
5
|
+
TextChunk,
|
|
6
|
+
ToolCallCompleteChunk,
|
|
7
|
+
UsageChunk,
|
|
8
|
+
UsageStats,
|
|
9
|
+
)
|
|
10
|
+
from .base import LLMClient
|
|
11
|
+
from .config import ConnectionConfig, LLMConfig
|
|
12
|
+
from .exceptions import (
|
|
13
|
+
LLMAuthError,
|
|
14
|
+
LLMConfigError,
|
|
15
|
+
LLMContentFilterError,
|
|
16
|
+
LLMContextLengthError,
|
|
17
|
+
LLMError,
|
|
18
|
+
LLMHTTPError,
|
|
19
|
+
LLMInsufficientBalanceError,
|
|
20
|
+
LLMNetworkError,
|
|
21
|
+
LLMRateLimitError,
|
|
22
|
+
LLMRequestError,
|
|
23
|
+
LLMServerError,
|
|
24
|
+
LLMStreamError,
|
|
25
|
+
build_http_error,
|
|
26
|
+
)
|
|
27
|
+
from .open_ai import OpenAIConfig
|
|
28
|
+
from .provider import create_client, register_client
|
|
29
|
+
|
|
30
|
+
__all__: list[str] = [
|
|
31
|
+
# -- 客户端 --
|
|
32
|
+
'LLMClient',
|
|
33
|
+
# -- 配置 --
|
|
34
|
+
'ConnectionConfig',
|
|
35
|
+
'LLMConfig',
|
|
36
|
+
'create_client',
|
|
37
|
+
'register_client',
|
|
38
|
+
# -- provider 配置 --
|
|
39
|
+
'OpenAIConfig',
|
|
40
|
+
# -- 流式 Chunk --
|
|
41
|
+
'StreamChunk',
|
|
42
|
+
'TextChunk',
|
|
43
|
+
'ToolCallCompleteChunk',
|
|
44
|
+
'UsageChunk',
|
|
45
|
+
'FinishChunk',
|
|
46
|
+
'DoneChunk',
|
|
47
|
+
'UsageStats',
|
|
48
|
+
# -- 异常 --
|
|
49
|
+
'LLMError',
|
|
50
|
+
'LLMConfigError',
|
|
51
|
+
'LLMRequestError',
|
|
52
|
+
'LLMNetworkError',
|
|
53
|
+
'LLMHTTPError',
|
|
54
|
+
'LLMAuthError',
|
|
55
|
+
'LLMInsufficientBalanceError',
|
|
56
|
+
'LLMRateLimitError',
|
|
57
|
+
'LLMServerError',
|
|
58
|
+
'LLMContentFilterError',
|
|
59
|
+
'LLMContextLengthError',
|
|
60
|
+
'LLMStreamError',
|
|
61
|
+
# -- 工具函数 --
|
|
62
|
+
'build_http_error',
|
|
63
|
+
]
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""LLM 客户端抽象基类"""
|
|
2
|
+
|
|
3
|
+
import types
|
|
4
|
+
from abc import ABC, abstractmethod
|
|
5
|
+
from typing import AsyncGenerator, Optional
|
|
6
|
+
|
|
7
|
+
from ..models import (
|
|
8
|
+
Message,
|
|
9
|
+
Messages,
|
|
10
|
+
StreamChunk,
|
|
11
|
+
TextChunk,
|
|
12
|
+
ToolCall,
|
|
13
|
+
ToolCallCompleteChunk,
|
|
14
|
+
ToolDefinitions,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class LLMClient(ABC):
|
|
19
|
+
"""LLM 客户端抽象基类"""
|
|
20
|
+
|
|
21
|
+
@abstractmethod
|
|
22
|
+
async def __aenter__(self) -> 'LLMClient':
|
|
23
|
+
"""支持 async with 资源管理"""
|
|
24
|
+
...
|
|
25
|
+
|
|
26
|
+
@abstractmethod
|
|
27
|
+
async def __aexit__(
|
|
28
|
+
self,
|
|
29
|
+
exc_type: Optional[type[BaseException]],
|
|
30
|
+
exc_val: Optional[BaseException],
|
|
31
|
+
exc_tb: Optional[types.TracebackType],
|
|
32
|
+
) -> Optional[bool]: ...
|
|
33
|
+
|
|
34
|
+
# ---------- 核心对话接口 ----------
|
|
35
|
+
|
|
36
|
+
@abstractmethod
|
|
37
|
+
def stream_chat(
|
|
38
|
+
self,
|
|
39
|
+
messages: Messages,
|
|
40
|
+
tools: Optional[ToolDefinitions] = None,
|
|
41
|
+
) -> AsyncGenerator[StreamChunk, None]:
|
|
42
|
+
"""
|
|
43
|
+
流式对话接口
|
|
44
|
+
|
|
45
|
+
:param messages: 消息列表
|
|
46
|
+
:param tools: 工具列表
|
|
47
|
+
:yield: StreamChunk 子类实例,调用方通过 isinstance 分支处理
|
|
48
|
+
:raise: LLMError
|
|
49
|
+
"""
|
|
50
|
+
...
|
|
51
|
+
|
|
52
|
+
# ---------- 工具方法 ----------
|
|
53
|
+
|
|
54
|
+
@staticmethod
|
|
55
|
+
def chunks_to_message(chunks: list[StreamChunk]) -> Message:
|
|
56
|
+
"""
|
|
57
|
+
将流式 chunks 聚合为一条完整的 assistant Message
|
|
58
|
+
|
|
59
|
+
遍历所有 chunk,拼接文本内容并收集工具调用,
|
|
60
|
+
最终产出一条可直接追加到对话历史的 assistant 消息。
|
|
61
|
+
|
|
62
|
+
:param chunks: 完整的流式 chunk 列表
|
|
63
|
+
:return: role=assistant 的 Message
|
|
64
|
+
"""
|
|
65
|
+
text_parts: list[str] = []
|
|
66
|
+
tool_calls: list[ToolCall] = []
|
|
67
|
+
|
|
68
|
+
for chunk in chunks:
|
|
69
|
+
if isinstance(chunk, TextChunk):
|
|
70
|
+
text_parts.append(chunk.text)
|
|
71
|
+
elif isinstance(chunk, ToolCallCompleteChunk):
|
|
72
|
+
tool_calls.extend(chunk.tool_calls)
|
|
73
|
+
|
|
74
|
+
content = ''.join(text_parts) if text_parts else None
|
|
75
|
+
return Message.assistant(
|
|
76
|
+
content=content,
|
|
77
|
+
tool_calls=tool_calls if tool_calls else None,
|
|
78
|
+
)
|