thinkai-framework 0.2.2__tar.gz → 0.3.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.
Files changed (61) hide show
  1. {thinkai_framework-0.2.2/thinkai_framework.egg-info → thinkai_framework-0.3.0}/PKG-INFO +43 -19
  2. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/README.md +42 -18
  3. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/pyproject.toml +1 -1
  4. thinkai_framework-0.3.0/tests/test_function_calling_skill.py +363 -0
  5. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/tests/test_thinkai.py +1 -1
  6. thinkai_framework-0.3.0/thinkai/__init__.py +40 -0
  7. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/agent/__init__.py +2 -0
  8. thinkai_framework-0.3.0/thinkai/agent/function_calling.py +162 -0
  9. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/providers/base.py +25 -4
  10. thinkai_framework-0.3.0/thinkai/skill/__init__.py +258 -0
  11. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0/thinkai_framework.egg-info}/PKG-INFO +43 -19
  12. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai_framework.egg-info/SOURCES.txt +3 -0
  13. thinkai_framework-0.2.2/thinkai/__init__.py +0 -24
  14. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/.env.example +0 -0
  15. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/LICENSE +0 -0
  16. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/MANIFEST.in +0 -0
  17. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/config.example.yaml +0 -0
  18. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/examples/agent_example.py +0 -0
  19. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/examples/basic_usage.py +0 -0
  20. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/examples/fastapi_demo.py +0 -0
  21. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/examples/rag_example.py +0 -0
  22. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/setup.cfg +0 -0
  23. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/agent/base.py +0 -0
  24. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/agent/react.py +0 -0
  25. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/agent/tool.py +0 -0
  26. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/core/__init__.py +0 -0
  27. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/core/client.py +0 -0
  28. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/core/config.py +0 -0
  29. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/core/models.py +0 -0
  30. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/exceptions.py +0 -0
  31. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/middleware/__init__.py +0 -0
  32. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/middleware/base.py +0 -0
  33. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/middleware/logging_middleware.py +0 -0
  34. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/middleware/retry_middleware.py +0 -0
  35. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/prompt/template.py +0 -0
  36. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/providers/__init__.py +0 -0
  37. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/providers/claude.py +0 -0
  38. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/providers/deepseek.py +0 -0
  39. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/providers/gemini.py +0 -0
  40. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/providers/ollama.py +0 -0
  41. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/providers/openai.py +0 -0
  42. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/providers/openai_compatible.py +0 -0
  43. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/providers/qwen.py +0 -0
  44. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/providers/registry.py +0 -0
  45. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/providers/shortcuts.py +0 -0
  46. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/rag/__init__.py +0 -0
  47. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/rag/chroma_store.py +0 -0
  48. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/rag/document_loader.py +0 -0
  49. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/rag/pipeline.py +0 -0
  50. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/rag/text_splitter.py +0 -0
  51. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/rag/vector_store.py +0 -0
  52. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/session/__init__.py +0 -0
  53. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/session/context.py +0 -0
  54. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/session/manager.py +0 -0
  55. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/session/memory.py +0 -0
  56. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/session/storage.py +0 -0
  57. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai/streaming.py +0 -0
  58. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai_framework.egg-info/dependency_links.txt +0 -0
  59. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai_framework.egg-info/entry_points.txt +0 -0
  60. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai_framework.egg-info/requires.txt +0 -0
  61. {thinkai_framework-0.2.2 → thinkai_framework-0.3.0}/thinkai_framework.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: thinkai-framework
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: Enterprise-grade AI framework for seamless LLM integration
5
5
  Author-email: ThinkAi Team <thinkai@example.com>
6
6
  License-Expression: MIT
@@ -60,6 +60,15 @@ Dynamic: license-file
60
60
 
61
61
  基于Python异步的企业级AI大模型集成框架 - **开箱即用,简单易用,功能全面**
62
62
 
63
+ [![Gitee](https://img.shields.io/badge/Gitee-ThinkAi-red)](https://gitee.com/hongxinge/think-ai)
64
+ [![GitHub](https://img.shields.io/badge/GitHub-ThinkAi-black)](https://github.com/hongxinge/ThinkAi)
65
+ [![PyPI](https://img.shields.io/pypi/v/thinkai-framework)](https://pypi.org/project/thinkai-framework/)
66
+ [![License](https://img.shields.io/badge/License-MIT-green)](LICENSE)
67
+
68
+ - 🏠 Gitee: https://gitee.com/hongxinge/think-ai
69
+ - 🌐 GitHub: https://github.com/hongxinge/ThinkAi
70
+ - 📦 PyPI: https://pypi.org/project/thinkai-framework/
71
+
63
72
  ## 特性
64
73
 
65
74
  - **轻量零依赖** - 核心框架不依赖任何Web框架,完全脱离FastAPI
@@ -70,7 +79,8 @@ Dynamic: license-file
70
79
  - **流式响应** - 支持SSE流式输出
71
80
  - **会话管理** - 内置多轮对话上下文管理
72
81
  - **RAG支持** - 3行代码实现检索增强生成
73
- - **Agent系统** - 内置ReAct Agent,支持工具调用
82
+ - **Agent系统** - 内置ReAct Agent和Function Calling Agent
83
+ - **Skill系统** - 可复用AI能力包(搜索/代码/数学/文件操作)
74
84
  - **中间件管道** - 日志、重试、缓存、限流
75
85
  - **企业级性能** - 异步架构,连接池,自动重试
76
86
 
@@ -181,33 +191,41 @@ answer = await rag.query("ThinkAi框架支持哪些AI模型?")
181
191
  print(answer)
182
192
  ```
183
193
 
184
- ### 7. Agent(智能体)
194
+ ### 7. Function Calling Agent(函数调用智能体)
185
195
 
186
196
  ```python
187
197
  from thinkai import ThinkAI
188
- from thinkai.agent import ReActAgent, Tool
198
+ from thinkai.agent import FunctionCallingAgent
199
+ from thinkai.skill import MathSkill, CodeSkill
189
200
 
190
- # 定义工具
191
- @Tool(name="calculator", description="计算数学表达式")
192
- def calculator(expression: str) -> str:
193
- return str(eval(expression))
201
+ ai = ThinkAI(provider="openai", api_key="your-key")
194
202
 
195
- @Tool(name="search", description="搜索信息")
196
- async def search(query: str) -> str:
197
- # 实现搜索逻辑
198
- return "搜索结果"
203
+ agent = FunctionCallingAgent(
204
+ name="math-coder",
205
+ tools=[MathSkill().get_tools(), CodeSkill().get_tools()],
206
+ ai_client=ai,
207
+ verbose=True,
208
+ )
199
209
 
200
- ai = ThinkAI()
210
+ result = await agent.run("计算123*456,然后用Python写一个斐波那契数列函数")
211
+ print(result)
212
+ ```
213
+
214
+ ### 8. Skill(技能组合)
201
215
 
202
- # 创建Agent
203
- agent = ReActAgent(
204
- tools=[calculator, search],
216
+ ```python
217
+ from thinkai import ThinkAI
218
+ from thinkai.skill import skill_manager, MathSkill, WebSearchSkill
219
+
220
+ ai = ThinkAI(provider="openai", api_key="your-key")
221
+
222
+ agent = skill_manager.create_agent(
205
223
  ai_client=ai,
206
- verbose=True,
224
+ skill_names=["math", "code"],
225
+ system_prompt="You are a helpful assistant with math and coding skills.",
207
226
  )
208
227
 
209
- # 运行任务
210
- result = await agent.run("计算25*48,然后搜索Python的相关信息")
228
+ result = await agent.run("计算2的10次方")
211
229
  print(result)
212
230
  ```
213
231
 
@@ -294,6 +312,12 @@ thinkai/
294
312
  │ ├── middleware/ # 中间件
295
313
  │ ├── rag/ # RAG模块
296
314
  │ ├── agent/ # Agent模块
315
+ │ │ ├── base.py # Agent基类
316
+ │ │ ├── react.py # ReAct Agent
317
+ │ │ ├── function_calling.py # Function Calling Agent
318
+ │ │ └── tool.py # Tool定义
319
+ │ ├── skill/ # Skill系统
320
+ │ │ ├── __init__.py # Skill基类和内置Skill
297
321
  │ ├── streaming.py # 流式处理
298
322
  │ └── exceptions.py # 异常定义
299
323
  ├── examples/ # 示例代码
@@ -2,6 +2,15 @@
2
2
 
3
3
  基于Python异步的企业级AI大模型集成框架 - **开箱即用,简单易用,功能全面**
4
4
 
5
+ [![Gitee](https://img.shields.io/badge/Gitee-ThinkAi-red)](https://gitee.com/hongxinge/think-ai)
6
+ [![GitHub](https://img.shields.io/badge/GitHub-ThinkAi-black)](https://github.com/hongxinge/ThinkAi)
7
+ [![PyPI](https://img.shields.io/pypi/v/thinkai-framework)](https://pypi.org/project/thinkai-framework/)
8
+ [![License](https://img.shields.io/badge/License-MIT-green)](LICENSE)
9
+
10
+ - 🏠 Gitee: https://gitee.com/hongxinge/think-ai
11
+ - 🌐 GitHub: https://github.com/hongxinge/ThinkAi
12
+ - 📦 PyPI: https://pypi.org/project/thinkai-framework/
13
+
5
14
  ## 特性
6
15
 
7
16
  - **轻量零依赖** - 核心框架不依赖任何Web框架,完全脱离FastAPI
@@ -12,7 +21,8 @@
12
21
  - **流式响应** - 支持SSE流式输出
13
22
  - **会话管理** - 内置多轮对话上下文管理
14
23
  - **RAG支持** - 3行代码实现检索增强生成
15
- - **Agent系统** - 内置ReAct Agent,支持工具调用
24
+ - **Agent系统** - 内置ReAct Agent和Function Calling Agent
25
+ - **Skill系统** - 可复用AI能力包(搜索/代码/数学/文件操作)
16
26
  - **中间件管道** - 日志、重试、缓存、限流
17
27
  - **企业级性能** - 异步架构,连接池,自动重试
18
28
 
@@ -123,33 +133,41 @@ answer = await rag.query("ThinkAi框架支持哪些AI模型?")
123
133
  print(answer)
124
134
  ```
125
135
 
126
- ### 7. Agent(智能体)
136
+ ### 7. Function Calling Agent(函数调用智能体)
127
137
 
128
138
  ```python
129
139
  from thinkai import ThinkAI
130
- from thinkai.agent import ReActAgent, Tool
140
+ from thinkai.agent import FunctionCallingAgent
141
+ from thinkai.skill import MathSkill, CodeSkill
131
142
 
132
- # 定义工具
133
- @Tool(name="calculator", description="计算数学表达式")
134
- def calculator(expression: str) -> str:
135
- return str(eval(expression))
143
+ ai = ThinkAI(provider="openai", api_key="your-key")
136
144
 
137
- @Tool(name="search", description="搜索信息")
138
- async def search(query: str) -> str:
139
- # 实现搜索逻辑
140
- return "搜索结果"
145
+ agent = FunctionCallingAgent(
146
+ name="math-coder",
147
+ tools=[MathSkill().get_tools(), CodeSkill().get_tools()],
148
+ ai_client=ai,
149
+ verbose=True,
150
+ )
141
151
 
142
- ai = ThinkAI()
152
+ result = await agent.run("计算123*456,然后用Python写一个斐波那契数列函数")
153
+ print(result)
154
+ ```
155
+
156
+ ### 8. Skill(技能组合)
143
157
 
144
- # 创建Agent
145
- agent = ReActAgent(
146
- tools=[calculator, search],
158
+ ```python
159
+ from thinkai import ThinkAI
160
+ from thinkai.skill import skill_manager, MathSkill, WebSearchSkill
161
+
162
+ ai = ThinkAI(provider="openai", api_key="your-key")
163
+
164
+ agent = skill_manager.create_agent(
147
165
  ai_client=ai,
148
- verbose=True,
166
+ skill_names=["math", "code"],
167
+ system_prompt="You are a helpful assistant with math and coding skills.",
149
168
  )
150
169
 
151
- # 运行任务
152
- result = await agent.run("计算25*48,然后搜索Python的相关信息")
170
+ result = await agent.run("计算2的10次方")
153
171
  print(result)
154
172
  ```
155
173
 
@@ -236,6 +254,12 @@ thinkai/
236
254
  │ ├── middleware/ # 中间件
237
255
  │ ├── rag/ # RAG模块
238
256
  │ ├── agent/ # Agent模块
257
+ │ │ ├── base.py # Agent基类
258
+ │ │ ├── react.py # ReAct Agent
259
+ │ │ ├── function_calling.py # Function Calling Agent
260
+ │ │ └── tool.py # Tool定义
261
+ │ ├── skill/ # Skill系统
262
+ │ │ ├── __init__.py # Skill基类和内置Skill
239
263
  │ ├── streaming.py # 流式处理
240
264
  │ └── exceptions.py # 异常定义
241
265
  ├── examples/ # 示例代码
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "thinkai-framework"
8
- version = "0.2.2"
8
+ version = "0.3.0"
9
9
  description = "Enterprise-grade AI framework for seamless LLM integration"
10
10
  readme = "README.md"
11
11
  license = "MIT"
@@ -0,0 +1,363 @@
1
+ """Function Calling 和 Skill 系统测试"""
2
+ import pytest
3
+ import asyncio
4
+ from unittest.mock import AsyncMock, MagicMock, patch
5
+
6
+
7
+ class TestFunctionCallingAgent:
8
+ """Function Calling Agent 测试"""
9
+
10
+ def test_import(self):
11
+ """测试导入"""
12
+ from thinkai.agent import FunctionCallingAgent
13
+ assert FunctionCallingAgent is not None
14
+
15
+ def test_import_from_thinkai(self):
16
+ """测试从 thinkai 导入"""
17
+ from thinkai import FunctionCallingAgent
18
+ assert FunctionCallingAgent is not None
19
+
20
+ def test_create_agent(self):
21
+ """测试创建 Agent"""
22
+ from thinkai.agent import FunctionCallingAgent
23
+ from thinkai.skill import MathSkill
24
+
25
+ agent = FunctionCallingAgent(
26
+ name="test-agent",
27
+ tools=MathSkill().get_tools(),
28
+ verbose=False,
29
+ )
30
+ assert agent.name == "test-agent"
31
+ assert len(agent.tools) == 1
32
+ assert agent.tools[0].name == "calculate"
33
+
34
+ def test_agent_has_ai_client(self):
35
+ """测试 Agent 带有 ai_client"""
36
+ from thinkai.agent import FunctionCallingAgent
37
+ from thinkai.skill import MathSkill
38
+ from thinkai import ThinkAI
39
+
40
+ ai = ThinkAI(provider="ollama", model="llama3")
41
+ agent = FunctionCallingAgent(
42
+ ai_client=ai,
43
+ tools=MathSkill().get_tools(),
44
+ )
45
+ assert agent.ai_client is ai
46
+
47
+ def test_build_tools_spec(self):
48
+ """测试构建工具规范"""
49
+ from thinkai.agent import FunctionCallingAgent
50
+ from thinkai.skill import MathSkill
51
+
52
+ agent = FunctionCallingAgent(tools=MathSkill().get_tools())
53
+ tools_spec = agent._build_tools_spec()
54
+
55
+ assert len(tools_spec) == 1
56
+ assert tools_spec[0]["type"] == "function"
57
+ assert tools_spec[0]["function"]["name"] == "calculate"
58
+ assert "description" in tools_spec[0]["function"]
59
+ assert "parameters" in tools_spec[0]["function"]
60
+
61
+
62
+ class TestSkillSystem:
63
+ """Skill 系统测试"""
64
+
65
+ def test_import_skills(self):
66
+ """测试导入 Skills"""
67
+ from thinkai.skill import Skill, SkillManager
68
+ from thinkai.skill import WebSearchSkill, CodeSkill, MathSkill, FileSkill
69
+
70
+ assert Skill is not None
71
+ assert SkillManager is not None
72
+ assert WebSearchSkill is not None
73
+ assert CodeSkill is not None
74
+ assert MathSkill is not None
75
+ assert FileSkill is not None
76
+
77
+ def test_import_from_thinkai(self):
78
+ """测试从 thinkai 导入"""
79
+ from thinkai import Skill, SkillManager, skill_manager
80
+ from thinkai import WebSearchSkill, CodeSkill, MathSkill, FileSkill
81
+
82
+ assert Skill is not None
83
+ assert SkillManager is not None
84
+ assert skill_manager is not None
85
+
86
+ def test_web_search_skill(self):
87
+ """测试 WebSearchSkill"""
88
+ from thinkai.skill import WebSearchSkill
89
+
90
+ skill = WebSearchSkill()
91
+ assert skill.name == "web_search"
92
+ tools = skill.get_tools()
93
+ assert len(tools) == 1
94
+ assert tools[0].name == "web_search"
95
+
96
+ def test_code_skill(self):
97
+ """测试 CodeSkill"""
98
+ from thinkai.skill import CodeSkill
99
+
100
+ skill = CodeSkill()
101
+ assert skill.name == "code"
102
+ tools = skill.get_tools()
103
+ assert len(tools) == 1
104
+ assert tools[0].name == "execute_python"
105
+
106
+ def test_code_skill_execute(self):
107
+ """测试 CodeSkill 执行代码"""
108
+ from thinkai.skill import CodeSkill
109
+ import asyncio
110
+
111
+ skill = CodeSkill()
112
+ tools = skill.get_tools()
113
+
114
+ async def test_execute():
115
+ result = await tools[0].execute(code="result = 2 + 3")
116
+ return result
117
+
118
+ result = asyncio.run(test_execute())
119
+ assert "5" in result
120
+
121
+ def test_math_skill(self):
122
+ """测试 MathSkill"""
123
+ from thinkai.skill import MathSkill
124
+
125
+ skill = MathSkill()
126
+ assert skill.name == "math"
127
+ tools = skill.get_tools()
128
+ assert len(tools) == 1
129
+ assert tools[0].name == "calculate"
130
+
131
+ def test_math_skill_calculate(self):
132
+ """测试 MathSkill 计算"""
133
+ from thinkai.skill import MathSkill
134
+ import asyncio
135
+
136
+ skill = MathSkill()
137
+ tools = skill.get_tools()
138
+
139
+ async def test_calculate():
140
+ result = await tools[0].execute(expression="2 + 3 * 4")
141
+ return result
142
+
143
+ result = asyncio.run(test_calculate())
144
+ assert result == "14"
145
+
146
+ def test_file_skill(self):
147
+ """测试 FileSkill"""
148
+ from thinkai.skill import FileSkill
149
+
150
+ skill = FileSkill()
151
+ assert skill.name == "file"
152
+ tools = skill.get_tools()
153
+ assert len(tools) == 2
154
+ tool_names = [t.name for t in tools]
155
+ assert "read_file" in tool_names
156
+ assert "write_file" in tool_names
157
+
158
+ def test_skill_manager(self):
159
+ """测试 SkillManager"""
160
+ from thinkai.skill import SkillManager, MathSkill
161
+
162
+ manager = SkillManager()
163
+ manager.register(MathSkill())
164
+
165
+ skills = manager.list_skills()
166
+ assert len(skills) == 1
167
+ assert skills[0].name == "math"
168
+
169
+ skill = manager.get("math")
170
+ assert skill is not None
171
+ assert skill.name == "math"
172
+
173
+ def test_skill_manager_get_all_tools(self):
174
+ """测试 SkillManager 获取所有工具"""
175
+ from thinkai.skill import SkillManager, MathSkill, CodeSkill
176
+
177
+ manager = SkillManager()
178
+ manager.register(MathSkill())
179
+ manager.register(CodeSkill())
180
+
181
+ all_tools = manager.get_all_tools()
182
+ assert len(all_tools) == 2
183
+ tool_names = [t.name for t in all_tools]
184
+ assert "calculate" in tool_names
185
+ assert "execute_python" in tool_names
186
+
187
+ def test_global_skill_manager(self):
188
+ """测试全局 skill_manager 预注册"""
189
+ from thinkai.skill import skill_manager
190
+
191
+ skills = skill_manager.list_skills()
192
+ skill_names = [s.name for s in skills]
193
+
194
+ assert "web_search" in skill_names
195
+ assert "code" in skill_names
196
+ assert "math" in skill_names
197
+ assert "file" in skill_names
198
+
199
+ def test_skill_get_agent(self):
200
+ """测试 Skill 创建 Agent"""
201
+ from thinkai.skill import MathSkill
202
+ from thinkai.agent import FunctionCallingAgent
203
+
204
+ skill = MathSkill()
205
+ agent = skill.get_agent()
206
+
207
+ assert isinstance(agent, FunctionCallingAgent)
208
+ assert agent.name == "math-agent"
209
+
210
+
211
+ class TestToolOpenAIFormat:
212
+ """工具 OpenAI 格式转换测试"""
213
+
214
+ def test_tool_to_openai_format(self):
215
+ """测试工具转 OpenAI 格式"""
216
+ from thinkai.agent import Tool
217
+
218
+ def dummy_tool_func(x: int, y: str) -> str:
219
+ """Dummy tool"""
220
+ return y * x
221
+
222
+ tool = Tool(
223
+ name="dummy",
224
+ description="Dummy tool",
225
+ func=dummy_tool_func,
226
+ )
227
+
228
+ spec = tool.to_openai_format()
229
+ assert spec["type"] == "function"
230
+ assert spec["function"]["name"] == "dummy"
231
+ assert spec["function"]["description"] == "Dummy tool"
232
+ assert "parameters" in spec["function"]
233
+
234
+ def test_tool_parameters_inference(self):
235
+ """测试参数推断"""
236
+ from thinkai.agent import Tool
237
+
238
+ def calc(a: int, b: float, c: str) -> str:
239
+ return c
240
+
241
+ tool = Tool(name="calc", description="calc", func=calc)
242
+ params = tool.parameters
243
+
244
+ assert params["properties"]["a"]["type"] == "integer"
245
+ assert params["properties"]["b"]["type"] == "number"
246
+ assert params["properties"]["c"]["type"] == "string"
247
+
248
+
249
+ class TestToolCallsParsing:
250
+ """Tool Calls 解析测试"""
251
+
252
+ def test_parse_response_with_tool_calls(self):
253
+ """测试解析带 tool_calls 的响应"""
254
+ from thinkai.providers.base import BaseProvider
255
+ from thinkai.core.models import ToolCall, FunctionCall, ChatMessage
256
+
257
+ response_data = {
258
+ "id": "test-123",
259
+ "model": "gpt-4",
260
+ "choices": [
261
+ {
262
+ "index": 0,
263
+ "message": {
264
+ "role": "assistant",
265
+ "content": None,
266
+ "tool_calls": [
267
+ {
268
+ "id": "call_abc",
269
+ "type": "function",
270
+ "function": {
271
+ "name": "calculate",
272
+ "arguments": '{"expression": "2+3"}',
273
+ },
274
+ }
275
+ ],
276
+ },
277
+ "finish_reason": "tool_calls",
278
+ }
279
+ ],
280
+ "usage": {"prompt_tokens": 10, "completion_tokens": 20, "total_tokens": 30},
281
+ }
282
+
283
+ class MockProvider(BaseProvider):
284
+ name = "mock"
285
+ default_model = "mock-model"
286
+ default_api_base = "http://mock.com"
287
+
288
+ async def chat(self, request):
289
+ pass
290
+
291
+ async def chat_stream(self, request):
292
+ pass
293
+
294
+ provider = MockProvider()
295
+ parsed = provider._parse_response(response_data)
296
+
297
+ assert parsed.id == "test-123"
298
+ assert len(parsed.choices) == 1
299
+ assert parsed.choices[0].message.tool_calls is not None
300
+ assert len(parsed.choices[0].message.tool_calls) == 1
301
+ assert parsed.choices[0].message.tool_calls[0].function.name == "calculate"
302
+
303
+
304
+ class TestModelDefinitions:
305
+ """模型定义测试"""
306
+
307
+ def test_tool_call_model(self):
308
+ """测试 ToolCall 模型"""
309
+ from thinkai.core.models import ToolCall, FunctionCall
310
+
311
+ tc = ToolCall(
312
+ id="call_123",
313
+ type="function",
314
+ function=FunctionCall(
315
+ name="search",
316
+ arguments='{"query": "test"}',
317
+ ),
318
+ )
319
+
320
+ assert tc.id == "call_123"
321
+ assert tc.function.name == "search"
322
+
323
+ def test_chat_message_with_tool_calls(self):
324
+ """测试带 tool_calls 的 ChatMessage"""
325
+ from thinkai.core.models import ChatMessage, ToolCall, FunctionCall, MessageRole
326
+
327
+ tc = ToolCall(
328
+ id="call_123",
329
+ function=FunctionCall(name="calc", arguments='{"expr": "1+1"}'),
330
+ )
331
+
332
+ msg = ChatMessage.assistant(content=None, tool_calls=[tc])
333
+
334
+ assert msg.role == MessageRole.ASSISTANT
335
+ assert msg.content is None
336
+ assert len(msg.tool_calls) == 1
337
+
338
+ def test_chat_request_with_tools(self):
339
+ """测试带 tools 的 ChatRequest"""
340
+ from thinkai.core.models import ChatRequest, ChatMessage, Tool, FunctionDefinition
341
+
342
+ tool = Tool(
343
+ type="function",
344
+ function=FunctionDefinition(
345
+ name="calculate",
346
+ description="Calculate",
347
+ parameters={"type": "object", "properties": {}},
348
+ ),
349
+ )
350
+
351
+ request = ChatRequest(
352
+ model="gpt-4",
353
+ messages=[ChatMessage.user("1+1=?")],
354
+ tools=[tool],
355
+ )
356
+
357
+ assert request.tools is not None
358
+ assert len(request.tools) == 1
359
+ assert request.tools[0].function.name == "calculate"
360
+
361
+
362
+ if __name__ == "__main__":
363
+ pytest.main([__file__, "-v"])
@@ -14,7 +14,7 @@ class TestThinkAICore:
14
14
  """测试导入"""
15
15
  import thinkai
16
16
  assert hasattr(thinkai, '__version__')
17
- assert thinkai.__version__ == "0.2.2"
17
+ assert thinkai.__version__ == "0.3.0"
18
18
 
19
19
  def test_create_client(self):
20
20
  """测试创建客户端"""
@@ -0,0 +1,40 @@
1
+ """
2
+ ThinkAi - Enterprise-grade AI Framework
3
+ 基于Python异步的企业级AI大模型集成框架
4
+ 开箱即用,支持多模型,RAG,Agent,Skill等核心能力
5
+ """
6
+
7
+ __version__ = "0.3.0"
8
+ __author__ = "ThinkAi Team"
9
+
10
+ from thinkai.core.client import ThinkAI
11
+ from thinkai.core.config import Settings
12
+ from thinkai.session.manager import SessionManager
13
+ from thinkai.prompt.template import PromptTemplate
14
+ from thinkai.rag.pipeline import RAGPipeline
15
+ from thinkai.agent.base import Agent
16
+ from thinkai.agent.react import ReActAgent
17
+ from thinkai.agent.function_calling import FunctionCallingAgent
18
+ from thinkai.agent.tool import Tool, tool
19
+ from thinkai.skill import Skill, SkillManager, skill_manager
20
+ from thinkai.skill import WebSearchSkill, CodeSkill, MathSkill, FileSkill
21
+
22
+ __all__ = [
23
+ "ThinkAI",
24
+ "Settings",
25
+ "SessionManager",
26
+ "PromptTemplate",
27
+ "RAGPipeline",
28
+ "Agent",
29
+ "ReActAgent",
30
+ "FunctionCallingAgent",
31
+ "Tool",
32
+ "tool",
33
+ "Skill",
34
+ "SkillManager",
35
+ "skill_manager",
36
+ "WebSearchSkill",
37
+ "CodeSkill",
38
+ "MathSkill",
39
+ "FileSkill",
40
+ ]
@@ -2,6 +2,7 @@
2
2
  from thinkai.agent.base import Agent, AgentConfig
3
3
  from thinkai.agent.tool import Tool, tool
4
4
  from thinkai.agent.react import ReActAgent
5
+ from thinkai.agent.function_calling import FunctionCallingAgent
5
6
 
6
7
  __all__ = [
7
8
  "Agent",
@@ -9,4 +10,5 @@ __all__ = [
9
10
  "Tool",
10
11
  "tool",
11
12
  "ReActAgent",
13
+ "FunctionCallingAgent",
12
14
  ]