ErisPulse 1.1.14.dev1__tar.gz → 1.1.15__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 (49) hide show
  1. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.github/config/notify.json +0 -1
  2. erispulse-1.1.15/.github/tools/merge_md.py +39 -0
  3. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.github/tools/update-api-docs.py +1 -1
  4. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.gitignore +12 -1
  5. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/PKG-INFO +1 -1
  6. erispulse-1.1.15/docs/ADAPTERS.md +125 -0
  7. erispulse-1.1.15/docs/AI-Module-Generation.md +125 -0
  8. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/docs/CHANGELOG.md +11 -1
  9. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/docs/CLI.md +2 -2
  10. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/docs/DEVELOPMENT.md +3 -3
  11. erispulse-1.1.15/docs/ForAIDocs/ErisPulseDevelop.md +2485 -0
  12. erispulse-1.1.15/docs/REFERENCE.md +1745 -0
  13. erispulse-1.1.15/gitc/cd_branch.sh +17 -0
  14. erispulse-1.1.15/gitc/commit.sh +28 -0
  15. erispulse-1.1.15/gitc/create_branch.sh +20 -0
  16. erispulse-1.1.15/gitc/create_pr.sh +28 -0
  17. erispulse-1.1.15/gitc/merge_dev.sh +55 -0
  18. erispulse-1.1.15/gitc/usage.md +29 -0
  19. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/pyproject.toml +3 -3
  20. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/src/ErisPulse/__main__.py +73 -1
  21. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/src/ErisPulse/adapter.py +335 -31
  22. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/src/ErisPulse/db.py +436 -36
  23. erispulse-1.1.15/src/ErisPulse/logger.py +479 -0
  24. erispulse-1.1.15/src/ErisPulse/mods.py +422 -0
  25. erispulse-1.1.15/src/ErisPulse/raiserr.py +232 -0
  26. erispulse-1.1.14.dev1/docs/REFERENCE.md +0 -343
  27. erispulse-1.1.14.dev1/src/ErisPulse/logger.py +0 -201
  28. erispulse-1.1.14.dev1/src/ErisPulse/mods.py +0 -129
  29. erispulse-1.1.14.dev1/src/ErisPulse/raiserr.py +0 -109
  30. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  31. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  32. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.github/assets/erispulse_logo.png +0 -0
  33. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.github/workflows/notifications.yml +0 -0
  34. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.github/workflows/pypi-publish.yml +0 -0
  35. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.github/workflows/send-email/action.yml +0 -0
  36. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.github/workflows/send-email/send_mail.py +0 -0
  37. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.github/workflows/send-email/send_mail_old.py +0 -0
  38. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/.python-version +0 -0
  39. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/LICENSE +0 -0
  40. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/README.md +0 -0
  41. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/devs/test.py +0 -0
  42. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/devs/test_adapter.py +0 -0
  43. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/devs/test_files/test.docx +0 -0
  44. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/devs/test_files/test.jpg +0 -0
  45. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/devs/test_files/test.mp4 +0 -0
  46. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/docs/ORIGIN.md +0 -0
  47. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/docs/quick-start.md +0 -0
  48. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/src/ErisPulse/__init__.py +0 -0
  49. {erispulse-1.1.14.dev1 → erispulse-1.1.15}/src/ErisPulse/util.py +0 -0
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "emails": [
3
3
  "wsu2059@qq.com",
4
- "suyu@anran.xyz",
5
4
  "dev@oneall.eu.org",
6
5
  "yuzi6666@outlook.com",
7
6
  "ybrinpds@icloud.com",
@@ -0,0 +1,39 @@
1
+ def merge_markdown_files(file_paths, output_file):
2
+ with open(output_file, 'w', encoding='utf-8') as outfile:
3
+ # 写入头部说明:介绍每个文件的作用(不包含路径)
4
+ outfile.write("# ErisPulse 开发文档合集\n\n")
5
+ outfile.write("本文件由多个开发文档合并而成,用于辅助 AI 理解 ErisPulse 的模块开发规范与 SDK 使用方式。\n\n")
6
+
7
+ outfile.write("## 各文件对应内容说明\n\n")
8
+ outfile.write("| 文件名 | 作用 |\n")
9
+ outfile.write("|--------|------|\n")
10
+ outfile.write("| README.md | 项目概览、安装说明和快速入门指南 |\n")
11
+ outfile.write("| DEVELOPMENT.md | 模块结构定义、入口文件格式、Main 类规范 |\n")
12
+ outfile.write("| ADAPTERS.md | 平台适配器说明,包括事件监听和消息发送方式 |\n")
13
+ outfile.write("| REFERENCE.md | SDK 接口调用方式(如 `sdk.env`, `sdk.logger`, `sdk.adapter` 等) |\n\n")
14
+
15
+ outfile.write("## 合并内容开始\n\n")
16
+
17
+ for file_path in file_paths:
18
+ filename = file_path.split("/")[-1]
19
+ with open(file_path, 'r', encoding='utf-8') as infile:
20
+ content = infile.read()
21
+ outfile.write(f"<!-- {filename} -->\n\n")
22
+ outfile.write(content)
23
+ outfile.write(f"\n\n<!--- End of {filename} -->\n\n")
24
+
25
+ if __name__ == "__main__":
26
+ files_to_merge = [
27
+ "README.md",
28
+
29
+ "docs/DEVELOPMENT.md",
30
+
31
+ "docs/REFERENCE.md",
32
+
33
+ "docs/ADAPTERS.md",
34
+
35
+ "docs/CLI.md"
36
+ ]
37
+ output_file = "docs/ForAIDocs/ErisPulseDevelop.md"
38
+
39
+ merge_markdown_files(files_to_merge, output_file)
@@ -57,7 +57,7 @@ def update_reference_docs(module_name, docs, reference_path, module_path):
57
57
  print(f"Updated docs for {module_name} in REFERENCE.md")
58
58
 
59
59
  def main():
60
- module_dir = Path('ErisPulse')
60
+ module_dir = Path('src/ErisPulse')
61
61
  reference_path = Path('docs/REFERENCE.md')
62
62
 
63
63
  modules = ['__init__', '__main__', 'adapter', 'db', 'logger', 'mods', 'raiserr', 'util']
@@ -1,5 +1,6 @@
1
1
  # dev gnore ignore file for Python projects
2
2
  env.py
3
+ adapters
3
4
  uv.lock
4
5
  snapshots/
5
6
  config.db*
@@ -196,4 +197,14 @@ cython_debug/
196
197
  .cursorindexingignore
197
198
 
198
199
  # osx
199
- .DS_Store
200
+ .DS_Store
201
+
202
+ # pyvenv
203
+ bin
204
+ include
205
+ lib
206
+ pyvenv.cfg
207
+
208
+ # erispulse
209
+ my_bot
210
+ modules
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ErisPulse
3
- Version: 1.1.14.dev1
3
+ Version: 1.1.15
4
4
  Summary: ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。
5
5
  Author-email: "艾莉丝·格雷拉特(WSu2059)" <wsu2059@qq.com>, runoneall <runoobsteve@gmail.com>
6
6
  License: MIT License
@@ -0,0 +1,125 @@
1
+ # AI 模块生成指南
2
+
3
+ 使用本指南,你可以通过AI快速生成符合ErisPulse规范的模块代码,无需从零开始编写。
4
+
5
+ ## 快速开始
6
+
7
+ 1. **获取开发文档**
8
+ 下载 `docs/ForAIDocs/ErisPulseDevelop.md` - 它包含了所有AI需要的开发规范、适配器接口和SDK参考。
9
+
10
+ 2. **明确你的需求**
11
+ 确定模块功能、使用的适配器、依赖关系等核心要素。
12
+
13
+ 3. **向AI描述需求**
14
+ 使用下面的标准格式清晰地描述你的模块需求。
15
+
16
+ ## 需求描述规范
17
+
18
+ 请按照以下格式描述你的模块需求:
19
+
20
+ ```
21
+ 我需要一个用于处理用户指令的模块,名为 CommandProcessor。
22
+ 该模块应该能够:
23
+ - 监听 Yunhu 平台的指令事件
24
+ - 当用户发送 "/help" 时,回复帮助信息
25
+
26
+ 请根据 ErisPulse 的模块规范和文档,为我生成完整的模块文件结构和代码
27
+ ```
28
+
29
+ ### AI生成代码示例
30
+
31
+ ## 示例:生成一个天气查询模块
32
+
33
+ ### 用户输入需求:
34
+
35
+ > 我需要一个天气查询模块 WeatherBot,当用户在群聊中发送“/weather 上海”时,机器人会调用 OpenWeatherMap API 查询天气,并返回中文格式的天气信息。
36
+ > 要求:
37
+ > - 使用 YunhuAdapter 监听指令消息;
38
+ > - 使用 sdk.util.cache 缓存结果;
39
+ > - 模块结构符合 ErisPulse 规范。
40
+
41
+ 并且将刚刚下载的 `ErisPulseDevelop.md` 作为附件发送给 AI。
42
+
43
+ ### AI 输出示例:
44
+
45
+ ```python
46
+ # __init__.py
47
+ moduleInfo = {
48
+ "meta": {
49
+ "name": "WeatherBot",
50
+ "version": "1.0.0",
51
+ "description": "天气查询模块",
52
+ "author": "YourName",
53
+ "license": "MIT"
54
+ },
55
+ "dependencies": {
56
+ "requires": [
57
+ "YunhuAdapter"
58
+ ],
59
+ "optional": [],
60
+ "pip": ["aiohttp"]
61
+ }
62
+ }
63
+
64
+ from .Core import Main
65
+ ```
66
+
67
+ ```python
68
+ # Core.py
69
+ import aiohttp
70
+ import time
71
+
72
+ class Main:
73
+ def __init__(self, sdk):
74
+ self.sdk = sdk
75
+ self.logger = sdk.logger
76
+ self.env = sdk.env
77
+ self.util = sdk.util
78
+
79
+ @sdk.adapter.Yunhu.on("command")
80
+ async def handle_weather(data):
81
+ if data.event.message.commandName.lower() == "weather":
82
+ city = data.event.message.content.text.strip()
83
+ chat_type = data.event.chatType
84
+ sender_type = "group" if chat_type == "group" else "user"
85
+ sender_id = data.chat.chatId if chat_type == "group" else data.event.sender.senderId
86
+
87
+ if not city:
88
+ await self.sdk.adapter.Yunhu.Send.To(sender_type, sender_id).Text("请指定城市名称,例如:/weather 上海")
89
+ return
90
+ await self.reply_weather(sender_type, sender_id, city)
91
+
92
+ @sdk.util.cache
93
+ async def get_weather_data(self, city: str):
94
+ api_key = self.env.get("WEATHER_API_KEY")
95
+ url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}"
96
+ async with aiohttp.ClientSession() as session:
97
+ async with session.get(url) as resp:
98
+ if resp.status == 200:
99
+ return await resp.json()
100
+ else:
101
+ raise Exception("无法获取天气信息")
102
+
103
+ async def reply_weather(self, sender_type, sender_id, city):
104
+ try:
105
+ data = await self.get_weather_data(city)
106
+ temperature = data["main"]["temp"] - 273.15
107
+ await self.sdk.adapter.Yunhu.Send.To(sender_type, sender_id).Text(f"{city} 的温度是 {temperature:.1f}℃")
108
+ except Exception as e:
109
+ self.logger.error(f"获取天气失败: {e}")
110
+ await self.sdk.adapter.Yunhu.Send.To(sender_type, sender_id).Text(f"获取天气失败,请稍后再试。")
111
+ ```
112
+
113
+ ## 常见问题
114
+
115
+ Q: 如何测试生成的模块?
116
+ A: 将生成的代码放入ErisPulse项目(初始化过的你自己的项目内会有这个文件夹)的modules目录,重启服务即可加载测试。
117
+
118
+ Q: 生成的代码不符合我的需求怎么办?
119
+ A: 可以调整需求描述后重新生成,或直接在生成代码基础上进行修改。
120
+
121
+ Q: 需要更复杂的功能怎么办?
122
+ A: 可以将复杂功能拆分为多个简单模块,或分阶段实现。
123
+
124
+ Q: 我可以把这个模块发布到ErisPulse吗?
125
+ A: 当然可以!但是我们会审查你的代码,确保它符合我们的规范。
@@ -0,0 +1,125 @@
1
+ # AI 模块生成指南
2
+
3
+ 使用本指南,你可以通过AI快速生成符合ErisPulse规范的模块代码,无需从零开始编写。
4
+
5
+ ## 快速开始
6
+
7
+ 1. **获取开发文档**
8
+ 下载 `docs/ForAIDocs/ErisPulseDevelop.md` - 它包含了所有AI需要的开发规范、适配器接口和SDK参考。
9
+
10
+ 2. **明确你的需求**
11
+ 确定模块功能、使用的适配器、依赖关系等核心要素。
12
+
13
+ 3. **向AI描述需求**
14
+ 使用下面的标准格式清晰地描述你的模块需求。
15
+
16
+ ## 需求描述规范
17
+
18
+ 请按照以下格式描述你的模块需求:
19
+
20
+ ```
21
+ 我需要一个用于处理用户指令的模块,名为 CommandProcessor。
22
+ 该模块应该能够:
23
+ - 监听 Yunhu 平台的指令事件
24
+ - 当用户发送 "/help" 时,回复帮助信息
25
+
26
+ 请根据 ErisPulse 的模块规范和文档,为我生成完整的模块文件结构和代码
27
+ ```
28
+
29
+ ### AI生成代码示例
30
+
31
+ ## 示例:生成一个天气查询模块
32
+
33
+ ### 用户输入需求:
34
+
35
+ > 我需要一个天气查询模块 WeatherBot,当用户在群聊中发送“/weather 上海”时,机器人会调用 OpenWeatherMap API 查询天气,并返回中文格式的天气信息。
36
+ > 要求:
37
+ > - 使用 YunhuAdapter 监听指令消息;
38
+ > - 使用 sdk.util.cache 缓存结果;
39
+ > - 模块结构符合 ErisPulse 规范。
40
+
41
+ 并且将刚刚下载的 `ErisPulseDevelop.md` 作为附件发送给 AI。
42
+
43
+ ### AI 输出示例:
44
+
45
+ ```python
46
+ # __init__.py
47
+ moduleInfo = {
48
+ "meta": {
49
+ "name": "WeatherBot",
50
+ "version": "1.0.0",
51
+ "description": "天气查询模块",
52
+ "author": "YourName",
53
+ "license": "MIT"
54
+ },
55
+ "dependencies": {
56
+ "requires": [
57
+ "YunhuAdapter"
58
+ ],
59
+ "optional": [],
60
+ "pip": ["aiohttp"]
61
+ }
62
+ }
63
+
64
+ from .Core import Main
65
+ ```
66
+
67
+ ```python
68
+ # Core.py
69
+ import aiohttp
70
+ import time
71
+
72
+ class Main:
73
+ def __init__(self, sdk):
74
+ self.sdk = sdk
75
+ self.logger = sdk.logger
76
+ self.env = sdk.env
77
+ self.util = sdk.util
78
+
79
+ @sdk.adapter.Yunhu.on("command")
80
+ async def handle_weather(data):
81
+ if data.event.message.commandName.lower() == "weather":
82
+ city = data.event.message.content.text.strip()
83
+ chat_type = data.event.chatType
84
+ sender_type = "group" if chat_type == "group" else "user"
85
+ sender_id = data.chat.chatId if chat_type == "group" else data.event.sender.senderId
86
+
87
+ if not city:
88
+ await self.sdk.adapter.Yunhu.Send.To(sender_type, sender_id).Text("请指定城市名称,例如:/weather 上海")
89
+ return
90
+ await self.reply_weather(sender_type, sender_id, city)
91
+
92
+ @sdk.util.cache
93
+ async def get_weather_data(self, city: str):
94
+ api_key = self.env.get("WEATHER_API_KEY")
95
+ url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}"
96
+ async with aiohttp.ClientSession() as session:
97
+ async with session.get(url) as resp:
98
+ if resp.status == 200:
99
+ return await resp.json()
100
+ else:
101
+ raise Exception("无法获取天气信息")
102
+
103
+ async def reply_weather(self, sender_type, sender_id, city):
104
+ try:
105
+ data = await self.get_weather_data(city)
106
+ temperature = data["main"]["temp"] - 273.15
107
+ await self.sdk.adapter.Yunhu.Send.To(sender_type, sender_id).Text(f"{city} 的温度是 {temperature:.1f}℃")
108
+ except Exception as e:
109
+ self.logger.error(f"获取天气失败: {e}")
110
+ await self.sdk.adapter.Yunhu.Send.To(sender_type, sender_id).Text(f"获取天气失败,请稍后再试。")
111
+ ```
112
+
113
+ ## 常见问题
114
+
115
+ Q: 如何测试生成的模块?
116
+ A: 将生成的代码放入ErisPulse项目(初始化过的你自己的项目内会有这个文件夹)的modules目录,重启服务即可加载测试。
117
+
118
+ Q: 生成的代码不符合我的需求怎么办?
119
+ A: 可以调整需求描述后重新生成,或直接在生成代码基础上进行修改。
120
+
121
+ Q: 需要更复杂的功能怎么办?
122
+ A: 可以将复杂功能拆分为多个简单模块,或分阶段实现。
123
+
124
+ Q: 我可以把这个模块发布到ErisPulse吗?
125
+ A: 当然可以!但是我们会审查你的代码,确保它符合我们的规范。
@@ -8,11 +8,21 @@
8
8
  > **贡献日志**
9
9
  > 如需为新版本添加日志,请在对应版本号下补充内容,并注明日期和主要贡献者。
10
10
 
11
+ ## [1.1.15]
12
+ > 此版本为回滚版本,版本基于1.1.14.dev1:re | 为了修复多项目带来的严重问题,建议升级前先备份数据
13
+ ### 新增
14
+ - 拓展CLI:install命令,现在可以指定本地目录直接安装模块
15
+
16
+ ### 修复
17
+ - 修复多项目下模块初始化时可能出现的错误(回滚为单模块项目)
18
+
11
19
  ---
12
- ## [1.1.14.dev1]
20
+ ## [1.1.14.dev1:re]
13
21
  > 此版本为开发版本,不保证兼容性,仅用于测试和开发
14
22
 
15
23
  > dev1 的改动为sdk初始化功能优化 | 修复上个版本留下的bug
24
+ ### 新增
25
+ - 添加新的 ForAIDocs 项目文档
16
26
 
17
27
  ### 修复
18
28
  - 修复自动快照初始化时`_last_snapshot_time`和`_snapshot_interval`可能为None的问题
@@ -12,7 +12,7 @@
12
12
  | `list` | `[--module=<name>] [--init]` | 列出模块(可筛选) | `epsdk list --module=payment` |
13
13
  | `update` | - | 更新模块索引 | `epsdk update` |
14
14
  | `upgrade` | `[--force] [--init]` | 升级模块(`--force` 强制覆盖) | `epsdk upgrade --force --init` |
15
- | `install` | `<module...> [--init]` | 安装一个或多个模块(空格分隔) | `epsdk install YunhuAdapter OpenAI` |
15
+ | `install` | `<module...> [--init]` | 安装一个或多个模块(空格分隔),支持本地目录路径 | `epsdk install YunhuAdapter OpenAI`<br>`epsdk install .`<br>`epsdk install /path/to/module` |
16
16
  | `uninstall`| `<module> [--init]` | 移除指定模块 | `epsdk uninstall old-module --init` |
17
17
 
18
18
  ## 源管理
@@ -46,4 +46,4 @@ epsdk run main.py --reload
46
46
  ---
47
47
 
48
48
  ## 反馈与支持
49
- 如遇到 CLI 使用问题,请在 GitHub Issues 提交反馈。
49
+ 如遇到 CLI 使用问题,请在 GitHub Issues 提交反馈。
@@ -279,7 +279,7 @@ class Main:
279
279
  # 在 MyPlatformAdapter 中的方法可以使用 sdk.adapter.<适配器注册名>.<方法名> 访问
280
280
 
281
281
  class MyPlatformAdapter(sdk.BaseAdapter):
282
- class Send(sdk.BaseAdapter.Send): # 继承BaseAdapter内置的Send类
282
+ class Send(super().Send): # 继承BaseAdapter内置的Send类
283
283
  # 底层SendDSL中提供了To方法,用户调用的时候类会被定义 `self._target_type` 和 `self._target_id`/`self._target_to` 三个属性
284
284
  # 当你只需要一个接受的To时,例如 mail 的To只是一个邮箱,那么你可以使用 `self.To(email)`,这时只会有 `self._target_id`/`self._target_to` 两个属性被定义
285
285
  # 或者说你不需要用户的To,那么用户也可以直接使用 Send.Func(text) 的方式直接调用这里的方法
@@ -343,7 +343,7 @@ class MyPlatformAdapter(sdk.BaseAdapter):
343
343
 
344
344
  > ⚠️ 注意:
345
345
  > - 适配器类必须继承 `sdk.BaseAdapter`;
346
- > - 必须实现 `call_api`, `start`, `shutdown` 方法 和 `Send`类并继承自 `sdk.BaseAdapter.Send`;
346
+ > - 必须实现 `call_api`, `start`, `shutdown` 方法 和 `Send`类并继承自 `super().Send`;
347
347
  > - 推荐实现 `.Text(...)` 方法作为基础消息发送接口。
348
348
 
349
349
  ## 4. DSL 风格消息接口(SendDSL)
@@ -351,7 +351,7 @@ class MyPlatformAdapter(sdk.BaseAdapter):
351
351
  每个适配器可定义一组链式调用风格的方法,例如:
352
352
 
353
353
  ```python
354
- class Send(sdk.BaseAdapter.Send):
354
+ class Send(super().Send):
355
355
  def Text(self, text: str):
356
356
  return asyncio.create_task(
357
357
  self._adapter.call_api(...)