nonebot-plugin-cs2radar 0.2.0__tar.gz → 0.2.1__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.
- nonebot_plugin_cs2radar-0.2.1/PKG-INFO +206 -0
- nonebot_plugin_cs2radar-0.2.1/README.md +173 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/__init__.py +93 -41
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/crawler.py +59 -0
- nonebot_plugin_cs2radar-0.2.1/nonebot_plugin_cs2radar/llm.py +652 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/storage.py +4 -1
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/templates/pw_stats.html +95 -5
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/templates/stats.html +3 -3
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/pyproject.toml +1 -1
- nonebot_plugin_cs2radar-0.2.0/PKG-INFO +0 -145
- nonebot_plugin_cs2radar-0.2.0/README.md +0 -112
- nonebot_plugin_cs2radar-0.2.0/nonebot_plugin_cs2radar/llm.py +0 -346
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/.gitignore +0 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/LICENSE +0 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/binding_store.py +0 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/config.py +0 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/match_service.py +0 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/renderer.py +0 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/templates/events.html +0 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/templates/match_detail.html +0 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/templates/match_results.html +0 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/templates/matches.html +0 -0
- {nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/templates/player_detail.html +0 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: nonebot-plugin-cs2radar
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: NoneBot2 CS2 雷达插件,支持赛事/选手、5E、完美与官匹战绩查询及对局分析
|
|
5
|
+
Project-URL: Homepage, https://github.com/luojisama/nonebot-plugin-cs2radar
|
|
6
|
+
Project-URL: Repository, https://github.com/luojisama/nonebot-plugin-cs2radar
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/luojisama/nonebot-plugin-cs2radar/issues
|
|
8
|
+
Author-email: luojisama <2534316454@qq.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: 5e,cs2,csgo,nonebot,nonebot2,onebot,perfectworld
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Framework :: AsyncIO
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Communications :: Chat
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Requires-Dist: httpx>=0.23.0
|
|
25
|
+
Requires-Dist: jinja2>=3.0.0
|
|
26
|
+
Requires-Dist: nonebot-adapter-onebot>=2.2.0
|
|
27
|
+
Requires-Dist: nonebot-plugin-htmlrender>=0.6.0
|
|
28
|
+
Requires-Dist: nonebot-plugin-localstore>=0.6.0
|
|
29
|
+
Requires-Dist: nonebot2>=2.2.0
|
|
30
|
+
Requires-Dist: playwright>=1.30.0
|
|
31
|
+
Requires-Dist: pydantic<3.0,>=1.10
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# nonebot-plugin-cs2radar
|
|
35
|
+
|
|
36
|
+
NoneBot2 CS2 综合数据插件,支持职业选手查询、近期赛事与赛果、5E / 完美世界 / 官匹战绩查询、详细对局深度复盘及基于 HLTV 官方职业选手的智能战术画像与天梯瓶颈突破诊断。
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 功能特性
|
|
41
|
+
|
|
42
|
+
- **职业与赛事追踪**:支持查询 HLTV 职业选手资料卡、近期国际大赛赛程与赛果。
|
|
43
|
+
- **双平台天梯战绩**:支持 5E 对战平台(专属橙色主题)与完美世界电竞平台(科技蓝主题)综合生涯战绩查询,卡片视口统一为 960px 宽度并针对移动端进行排版优化。
|
|
44
|
+
- **智能战术画像与职业对标**:对接 HLTV 近 3 个月 Top 30 职业选手 7 维基准库(donk, b1t, ropz, sh1ro, m0NESY, apEX 等),将玩家数据结构化呈现为 4 维微卡片(【战力定位】【技术风格与职业对标】【偏科与武器地图】【天梯瓶颈突破】)。
|
|
45
|
+
- **零依赖智能兜底**:大模型未配置、网络超时或额度耗尽时,系统自动根据玩家真实 Rating、ADR、爆头率、首杀率及六维雷达指标进行智能模式匹配,100% 优雅生成结构化分析卡片。
|
|
46
|
+
- **单局详细复盘**:支持通过 `/match` 命令查询最近第 N 把比赛(5E、完美、官匹),呈现双方攻防半场走势、回合序列、击杀贡献与深度战局走势复盘。
|
|
47
|
+
- **元数据支持**:插件元数据内置完整的 `usage`、`extra["help"]` 与结构化 `extra["menu"]`,便于其他帮助插件或管理菜单反射查询。
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 安装
|
|
52
|
+
|
|
53
|
+
### 使用 nb-cli
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
nb plugin install nonebot-plugin-cs2radar
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 使用 pip
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install nonebot-plugin-cs2radar
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 安装 Playwright 渲染依赖
|
|
66
|
+
|
|
67
|
+
本插件依赖 Playwright 渲染战绩图片,安装插件后需执行:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
playwright install chromium
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 适配器支持
|
|
76
|
+
|
|
77
|
+
- `OneBot V11`
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 命令列表
|
|
82
|
+
|
|
83
|
+
| 命令 | 别名 | 参数说明 | 功能说明 |
|
|
84
|
+
| :--- | :--- | :--- | :--- |
|
|
85
|
+
| `cs查询` | `cs选手`, `csplayer` | `<选手名>` | 查询职业选手资料卡与能力评分 |
|
|
86
|
+
| `cs赛事` | `赛事`, `csgo赛事`, `cs2赛事` | 无 | 查询近期国际赛事与进行中赛程 |
|
|
87
|
+
| `赛果` | `cs赛果`, `赛事赛果` | 无 | 查询近几日完赛赛果与比分 |
|
|
88
|
+
| `5e` | `5e战绩`, `5e查询`, `cs战绩` | `[ID/昵称] [-r]` | 查询 5E 平台综合战绩与 4 维战术画像,无参数查绑定 |
|
|
89
|
+
| `pw` | `pw战绩`, `pw查询`, `完美战绩` | `[昵称/SteamID] [-r]` | 查询完美平台综合战绩与 4 维战术画像,无参数查绑定 |
|
|
90
|
+
| `pwlogin` | `完美登录` | `<手机号> <验证码>` | 登录完美世界电竞平台并保存本地会话 |
|
|
91
|
+
| `bind` | `绑定`, `添加`, `绑定用户` | `<5e\|pw> <玩家名>` | 绑定发送者 QQ 的常用查询玩家 |
|
|
92
|
+
| `match` | `战绩`, `查询战绩` | `[5e\|pw\|mm] [@群友] [局数] [-r]` | 查询指定平台最近第 N 把详细对局并生成四维战术复盘 |
|
|
93
|
+
|
|
94
|
+
> **提示**:查询命令后缀加上 `-r`(例如 `/pw 丰川NiKola -r` 或 `/5e -r`)可强制跳过本地缓存,刷新战绩与 AI 战术分析结果。
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 配置项说明
|
|
99
|
+
|
|
100
|
+
环境变量统一使用 `cs2radar_*` 前缀;旧版 `cs_pro_*` 前缀保持向后兼容。在 NoneBot2 项目根目录的 `.env` 或 `.env.prod` 中按需配置:
|
|
101
|
+
|
|
102
|
+
```env
|
|
103
|
+
# 基础配置
|
|
104
|
+
cs2radar_priority=5
|
|
105
|
+
cs2radar_http_timeout=15
|
|
106
|
+
|
|
107
|
+
# 主 LLM 配置
|
|
108
|
+
cs2radar_llm_enabled=true
|
|
109
|
+
cs2radar_llm_api_type=openai
|
|
110
|
+
cs2radar_llm_api_url=https://api.openai.com/v1
|
|
111
|
+
cs2radar_llm_api_key=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
112
|
+
cs2radar_llm_model=gpt-4o-mini
|
|
113
|
+
cs2radar_llm_timeout=30
|
|
114
|
+
|
|
115
|
+
# 备用 LLM 配置(可选容灾)
|
|
116
|
+
cs2radar_llm_backup_enabled=false
|
|
117
|
+
cs2radar_llm_backup_api_type=openai
|
|
118
|
+
cs2radar_llm_backup_api_url=https://api.openai.com/v1
|
|
119
|
+
cs2radar_llm_backup_api_key=
|
|
120
|
+
cs2radar_llm_backup_model=gpt-4o-mini
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 完整配置项清单
|
|
124
|
+
|
|
125
|
+
| 配置项 | 类型 | 默认值 | 旧版兼容名称 | 说明 |
|
|
126
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
127
|
+
| `cs2radar_priority` | int | `5` | `cs_pro_priority` | 插件事件响应优先级(1-20) |
|
|
128
|
+
| `cs2radar_bind_db_path` | str | `None` | `cs_pro_bind_db_path` | 账号绑定 SQLite 数据库路径,留空时默认存放在 localstore 数据目录 |
|
|
129
|
+
| `cs2radar_http_timeout` | int | `15` | `cs_pro_http_timeout` | 战绩与接口数据抓取超时时间(秒,5-60) |
|
|
130
|
+
| `cs2radar_llm_enabled` | bool | `true` | `cs_pro_llm_enabled` | 是否启用 LLM 战术分析与智能对标画像 |
|
|
131
|
+
| `cs2radar_llm_api_type` | str | `"openai"` | `cs_pro_llm_api_type` | 主大模型接口协议类型,支持 `openai`、`gemini`、`anthropic` |
|
|
132
|
+
| `cs2radar_llm_api_url` | str | `"https://api.openai.com/v1"` | `cs_pro_llm_api_url` | 主大模型接口 Base URL(支持各大中转/代理格式) |
|
|
133
|
+
| `cs2radar_llm_api_key` | str | `""` | `cs_pro_llm_api_key` | 主大模型 API Key(未配置时自动降级走智能动态兜底算法) |
|
|
134
|
+
| `cs2radar_llm_model` | str | `"gpt-4o-mini"` | `cs_pro_llm_model` | 主大模型调用模型名称 |
|
|
135
|
+
| `cs2radar_llm_timeout` | int | `30` | `cs_pro_llm_timeout` | 大模型请求超时时间(秒,5-120) |
|
|
136
|
+
| `cs2radar_llm_system_prompt` | str | `None` | `cs_pro_llm_system_prompt` | 自定义单局复盘 System Prompt(为空时使用内置电竞分析师预设) |
|
|
137
|
+
| `cs2radar_llm_backup_enabled` | bool | `false` | `cs_pro_llm_backup_enabled` | 是否启用备用大模型容灾链路 |
|
|
138
|
+
| `cs2radar_llm_backup_api_type` | str | `"openai"` | `cs_pro_llm_backup_api_type` | 备用大模型接口协议类型 |
|
|
139
|
+
| `cs2radar_llm_backup_api_url` | str | `"https://api.openai.com/v1"` | `cs_pro_llm_backup_api_url` | 备用大模型接口 Base URL |
|
|
140
|
+
| `cs2radar_llm_backup_api_key` | str | `""` | `cs_pro_llm_backup_api_key` | 备用大模型 API Key |
|
|
141
|
+
| `cs2radar_llm_backup_model` | str | `"gpt-4o-mini"` | `cs_pro_llm_backup_model` | 备用大模型调用模型名称 |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 元数据与插件联动
|
|
146
|
+
|
|
147
|
+
为便于第三方插件(如帮助菜单、权限管理或机器人总控后台)自动获取命令信息,本插件在 `__plugin_meta__` 中暴露了标准化的元数据结构:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from nonebot import get_plugin
|
|
151
|
+
|
|
152
|
+
plugin = get_plugin("nonebot_plugin_cs2radar")
|
|
153
|
+
if plugin and plugin.metadata:
|
|
154
|
+
# 纯文本帮助内容
|
|
155
|
+
help_text = plugin.metadata.usage
|
|
156
|
+
# 或者通过 extra 读取扩展字典
|
|
157
|
+
menu_list = plugin.metadata.extra.get("menu", [])
|
|
158
|
+
config_dict = plugin.metadata.extra.get("configs", {})
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 数据存储与旧版本迁移
|
|
164
|
+
|
|
165
|
+
插件严格遵循 NoneBot2 `nonebot-plugin-localstore` 标准规范,自动管理数据与持久化存储。启动时会自动检测并平滑迁移旧版本(如 `data/cs_pro/`)中的以下历史文件:
|
|
166
|
+
|
|
167
|
+
- `user_bindings.db`(用户平台绑定数据)
|
|
168
|
+
- `user_data.db` / `user_data.json`(历史战绩缓存)
|
|
169
|
+
- `pw_session.json`(完美平台登录态)
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 常见问题
|
|
174
|
+
|
|
175
|
+
### 1. 提示找不到浏览器或渲染失败
|
|
176
|
+
Playwright 核心依赖未安装,请在运行环境中执行:
|
|
177
|
+
```bash
|
|
178
|
+
playwright install chromium
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### 2. 完美战绩查询提示请先登录
|
|
182
|
+
完美世界官方接口需要已绑定的移动端登录态。初次使用时请执行一次:
|
|
183
|
+
```text
|
|
184
|
+
/pwlogin <手机号> <验证码>
|
|
185
|
+
```
|
|
186
|
+
会话态将加密保存在本地并自动保持心跳。
|
|
187
|
+
|
|
188
|
+
### 3. 未配置大模型或 API 欠费时能否正常使用?
|
|
189
|
+
可以。插件内置了全量智能动态兜底算法。当未配置 API Key 或上游接口不可用时,系统会自动基于玩家的实际数据(Rating、ADR、爆头率、首杀率及雷达指标)对标职业选手并输出 4 维微报告,不会中断查询流程。
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 构建与发布
|
|
194
|
+
|
|
195
|
+
本仓库已配置 GitHub Actions 自动构建与发布工作流。推送语义化版本 Tag 即可自动构建并发布 Wheel 至 PyPI:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
git tag v0.2.1
|
|
199
|
+
git push origin v0.2.1
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# nonebot-plugin-cs2radar
|
|
2
|
+
|
|
3
|
+
NoneBot2 CS2 综合数据插件,支持职业选手查询、近期赛事与赛果、5E / 完美世界 / 官匹战绩查询、详细对局深度复盘及基于 HLTV 官方职业选手的智能战术画像与天梯瓶颈突破诊断。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 功能特性
|
|
8
|
+
|
|
9
|
+
- **职业与赛事追踪**:支持查询 HLTV 职业选手资料卡、近期国际大赛赛程与赛果。
|
|
10
|
+
- **双平台天梯战绩**:支持 5E 对战平台(专属橙色主题)与完美世界电竞平台(科技蓝主题)综合生涯战绩查询,卡片视口统一为 960px 宽度并针对移动端进行排版优化。
|
|
11
|
+
- **智能战术画像与职业对标**:对接 HLTV 近 3 个月 Top 30 职业选手 7 维基准库(donk, b1t, ropz, sh1ro, m0NESY, apEX 等),将玩家数据结构化呈现为 4 维微卡片(【战力定位】【技术风格与职业对标】【偏科与武器地图】【天梯瓶颈突破】)。
|
|
12
|
+
- **零依赖智能兜底**:大模型未配置、网络超时或额度耗尽时,系统自动根据玩家真实 Rating、ADR、爆头率、首杀率及六维雷达指标进行智能模式匹配,100% 优雅生成结构化分析卡片。
|
|
13
|
+
- **单局详细复盘**:支持通过 `/match` 命令查询最近第 N 把比赛(5E、完美、官匹),呈现双方攻防半场走势、回合序列、击杀贡献与深度战局走势复盘。
|
|
14
|
+
- **元数据支持**:插件元数据内置完整的 `usage`、`extra["help"]` 与结构化 `extra["menu"]`,便于其他帮助插件或管理菜单反射查询。
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 安装
|
|
19
|
+
|
|
20
|
+
### 使用 nb-cli
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
nb plugin install nonebot-plugin-cs2radar
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 使用 pip
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install nonebot-plugin-cs2radar
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 安装 Playwright 渲染依赖
|
|
33
|
+
|
|
34
|
+
本插件依赖 Playwright 渲染战绩图片,安装插件后需执行:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
playwright install chromium
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 适配器支持
|
|
43
|
+
|
|
44
|
+
- `OneBot V11`
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 命令列表
|
|
49
|
+
|
|
50
|
+
| 命令 | 别名 | 参数说明 | 功能说明 |
|
|
51
|
+
| :--- | :--- | :--- | :--- |
|
|
52
|
+
| `cs查询` | `cs选手`, `csplayer` | `<选手名>` | 查询职业选手资料卡与能力评分 |
|
|
53
|
+
| `cs赛事` | `赛事`, `csgo赛事`, `cs2赛事` | 无 | 查询近期国际赛事与进行中赛程 |
|
|
54
|
+
| `赛果` | `cs赛果`, `赛事赛果` | 无 | 查询近几日完赛赛果与比分 |
|
|
55
|
+
| `5e` | `5e战绩`, `5e查询`, `cs战绩` | `[ID/昵称] [-r]` | 查询 5E 平台综合战绩与 4 维战术画像,无参数查绑定 |
|
|
56
|
+
| `pw` | `pw战绩`, `pw查询`, `完美战绩` | `[昵称/SteamID] [-r]` | 查询完美平台综合战绩与 4 维战术画像,无参数查绑定 |
|
|
57
|
+
| `pwlogin` | `完美登录` | `<手机号> <验证码>` | 登录完美世界电竞平台并保存本地会话 |
|
|
58
|
+
| `bind` | `绑定`, `添加`, `绑定用户` | `<5e\|pw> <玩家名>` | 绑定发送者 QQ 的常用查询玩家 |
|
|
59
|
+
| `match` | `战绩`, `查询战绩` | `[5e\|pw\|mm] [@群友] [局数] [-r]` | 查询指定平台最近第 N 把详细对局并生成四维战术复盘 |
|
|
60
|
+
|
|
61
|
+
> **提示**:查询命令后缀加上 `-r`(例如 `/pw 丰川NiKola -r` 或 `/5e -r`)可强制跳过本地缓存,刷新战绩与 AI 战术分析结果。
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 配置项说明
|
|
66
|
+
|
|
67
|
+
环境变量统一使用 `cs2radar_*` 前缀;旧版 `cs_pro_*` 前缀保持向后兼容。在 NoneBot2 项目根目录的 `.env` 或 `.env.prod` 中按需配置:
|
|
68
|
+
|
|
69
|
+
```env
|
|
70
|
+
# 基础配置
|
|
71
|
+
cs2radar_priority=5
|
|
72
|
+
cs2radar_http_timeout=15
|
|
73
|
+
|
|
74
|
+
# 主 LLM 配置
|
|
75
|
+
cs2radar_llm_enabled=true
|
|
76
|
+
cs2radar_llm_api_type=openai
|
|
77
|
+
cs2radar_llm_api_url=https://api.openai.com/v1
|
|
78
|
+
cs2radar_llm_api_key=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
79
|
+
cs2radar_llm_model=gpt-4o-mini
|
|
80
|
+
cs2radar_llm_timeout=30
|
|
81
|
+
|
|
82
|
+
# 备用 LLM 配置(可选容灾)
|
|
83
|
+
cs2radar_llm_backup_enabled=false
|
|
84
|
+
cs2radar_llm_backup_api_type=openai
|
|
85
|
+
cs2radar_llm_backup_api_url=https://api.openai.com/v1
|
|
86
|
+
cs2radar_llm_backup_api_key=
|
|
87
|
+
cs2radar_llm_backup_model=gpt-4o-mini
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 完整配置项清单
|
|
91
|
+
|
|
92
|
+
| 配置项 | 类型 | 默认值 | 旧版兼容名称 | 说明 |
|
|
93
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
94
|
+
| `cs2radar_priority` | int | `5` | `cs_pro_priority` | 插件事件响应优先级(1-20) |
|
|
95
|
+
| `cs2radar_bind_db_path` | str | `None` | `cs_pro_bind_db_path` | 账号绑定 SQLite 数据库路径,留空时默认存放在 localstore 数据目录 |
|
|
96
|
+
| `cs2radar_http_timeout` | int | `15` | `cs_pro_http_timeout` | 战绩与接口数据抓取超时时间(秒,5-60) |
|
|
97
|
+
| `cs2radar_llm_enabled` | bool | `true` | `cs_pro_llm_enabled` | 是否启用 LLM 战术分析与智能对标画像 |
|
|
98
|
+
| `cs2radar_llm_api_type` | str | `"openai"` | `cs_pro_llm_api_type` | 主大模型接口协议类型,支持 `openai`、`gemini`、`anthropic` |
|
|
99
|
+
| `cs2radar_llm_api_url` | str | `"https://api.openai.com/v1"` | `cs_pro_llm_api_url` | 主大模型接口 Base URL(支持各大中转/代理格式) |
|
|
100
|
+
| `cs2radar_llm_api_key` | str | `""` | `cs_pro_llm_api_key` | 主大模型 API Key(未配置时自动降级走智能动态兜底算法) |
|
|
101
|
+
| `cs2radar_llm_model` | str | `"gpt-4o-mini"` | `cs_pro_llm_model` | 主大模型调用模型名称 |
|
|
102
|
+
| `cs2radar_llm_timeout` | int | `30` | `cs_pro_llm_timeout` | 大模型请求超时时间(秒,5-120) |
|
|
103
|
+
| `cs2radar_llm_system_prompt` | str | `None` | `cs_pro_llm_system_prompt` | 自定义单局复盘 System Prompt(为空时使用内置电竞分析师预设) |
|
|
104
|
+
| `cs2radar_llm_backup_enabled` | bool | `false` | `cs_pro_llm_backup_enabled` | 是否启用备用大模型容灾链路 |
|
|
105
|
+
| `cs2radar_llm_backup_api_type` | str | `"openai"` | `cs_pro_llm_backup_api_type` | 备用大模型接口协议类型 |
|
|
106
|
+
| `cs2radar_llm_backup_api_url` | str | `"https://api.openai.com/v1"` | `cs_pro_llm_backup_api_url` | 备用大模型接口 Base URL |
|
|
107
|
+
| `cs2radar_llm_backup_api_key` | str | `""` | `cs_pro_llm_backup_api_key` | 备用大模型 API Key |
|
|
108
|
+
| `cs2radar_llm_backup_model` | str | `"gpt-4o-mini"` | `cs_pro_llm_backup_model` | 备用大模型调用模型名称 |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 元数据与插件联动
|
|
113
|
+
|
|
114
|
+
为便于第三方插件(如帮助菜单、权限管理或机器人总控后台)自动获取命令信息,本插件在 `__plugin_meta__` 中暴露了标准化的元数据结构:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from nonebot import get_plugin
|
|
118
|
+
|
|
119
|
+
plugin = get_plugin("nonebot_plugin_cs2radar")
|
|
120
|
+
if plugin and plugin.metadata:
|
|
121
|
+
# 纯文本帮助内容
|
|
122
|
+
help_text = plugin.metadata.usage
|
|
123
|
+
# 或者通过 extra 读取扩展字典
|
|
124
|
+
menu_list = plugin.metadata.extra.get("menu", [])
|
|
125
|
+
config_dict = plugin.metadata.extra.get("configs", {})
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 数据存储与旧版本迁移
|
|
131
|
+
|
|
132
|
+
插件严格遵循 NoneBot2 `nonebot-plugin-localstore` 标准规范,自动管理数据与持久化存储。启动时会自动检测并平滑迁移旧版本(如 `data/cs_pro/`)中的以下历史文件:
|
|
133
|
+
|
|
134
|
+
- `user_bindings.db`(用户平台绑定数据)
|
|
135
|
+
- `user_data.db` / `user_data.json`(历史战绩缓存)
|
|
136
|
+
- `pw_session.json`(完美平台登录态)
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 常见问题
|
|
141
|
+
|
|
142
|
+
### 1. 提示找不到浏览器或渲染失败
|
|
143
|
+
Playwright 核心依赖未安装,请在运行环境中执行:
|
|
144
|
+
```bash
|
|
145
|
+
playwright install chromium
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 2. 完美战绩查询提示请先登录
|
|
149
|
+
完美世界官方接口需要已绑定的移动端登录态。初次使用时请执行一次:
|
|
150
|
+
```text
|
|
151
|
+
/pwlogin <手机号> <验证码>
|
|
152
|
+
```
|
|
153
|
+
会话态将加密保存在本地并自动保持心跳。
|
|
154
|
+
|
|
155
|
+
### 3. 未配置大模型或 API 欠费时能否正常使用?
|
|
156
|
+
可以。插件内置了全量智能动态兜底算法。当未配置 API Key 或上游接口不可用时,系统会自动基于玩家的实际数据(Rating、ADR、爆头率、首杀率及雷达指标)对标职业选手并输出 4 维微报告,不会中断查询流程。
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 构建与发布
|
|
161
|
+
|
|
162
|
+
本仓库已配置 GitHub Actions 自动构建与发布工作流。推送语义化版本 Tag 即可自动构建并发布 Wheel 至 PyPI:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
git tag v0.2.1
|
|
166
|
+
git push origin v0.2.1
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
[MIT](LICENSE)
|
{nonebot_plugin_cs2radar-0.2.0 → nonebot_plugin_cs2radar-0.2.1}/nonebot_plugin_cs2radar/__init__.py
RENAMED
|
@@ -27,7 +27,7 @@ from .renderer import (
|
|
|
27
27
|
)
|
|
28
28
|
from .storage import get_bind_db_path
|
|
29
29
|
|
|
30
|
-
__version__ = "0.2.
|
|
30
|
+
__version__ = "0.2.1"
|
|
31
31
|
|
|
32
32
|
plugin_config = get_plugin_config(Config)
|
|
33
33
|
driver_config = get_driver().config
|
|
@@ -52,19 +52,25 @@ for legacy_name in (
|
|
|
52
52
|
if getattr(plugin_config, legacy_name, None) is not None:
|
|
53
53
|
logger.warning(f"[nonebot_plugin_cs2radar] `{legacy_name}` is deprecated; migrate to `cs2radar_*` config names.")
|
|
54
54
|
|
|
55
|
+
_USAGE_HELP = """CS2 Radar 插件命令一览:
|
|
56
|
+
1. 职业与赛事:
|
|
57
|
+
- cs查询 <选手名> - 查询职业选手资料卡与能力评分 (别名: cs选手, csplayer)
|
|
58
|
+
- cs赛事 - 查询近期重要赛事与进行中比赛 (别名: 赛事, csgo赛事, cs2赛事)
|
|
59
|
+
- 赛果 - 查询近几日完赛比分与赛果 (别名: cs赛果, 赛事赛果)
|
|
60
|
+
2. 平台生涯战绩:
|
|
61
|
+
- 5e [ID/昵称] [-r] - 查询 5E 平台综合战绩与 4 维智能战术画像 (别名: 5e战绩, 5e查询, cs战绩)
|
|
62
|
+
- pw [昵称/SteamID] [-r] - 查询完美平台综合战绩与 4 维智能战术画像 (别名: pw战绩, pw查询, 完美战绩)
|
|
63
|
+
- pwlogin <手机号> <验证码> - 登录完美世界电竞平台并保存本地会话 (别名: 完美登录)
|
|
64
|
+
3. 账号绑定与复盘:
|
|
65
|
+
- bind <5e|pw> <玩家名> - 绑定当前 QQ 的默认查询对象 (别名: 绑定, 添加)
|
|
66
|
+
- match [5e|pw|mm] [@群友] [局数] [-r] - 查询最近第 N 把详细对局并生成四维战术复盘 (别名: 战绩, 查询战绩)
|
|
67
|
+
|
|
68
|
+
说明:命令支持 [-r] 参数强制刷新战绩与 AI 战术分析缓存。未配置大模型时会自动基于选手真实数据智能对标职业哥并诊断天梯瓶颈。"""
|
|
69
|
+
|
|
55
70
|
__plugin_meta__ = PluginMetadata(
|
|
56
71
|
name="CS2 Radar",
|
|
57
72
|
description="CS2 赛事、选手、5E/完美/官匹战绩查询与详细对局分析",
|
|
58
|
-
usage=
|
|
59
|
-
"cs查询 [选手]\n"
|
|
60
|
-
"cs赛事\n"
|
|
61
|
-
"赛果\n"
|
|
62
|
-
"5e [ID/昵称] [-r]\n"
|
|
63
|
-
"pw [ID/昵称/SteamID] [-r]\n"
|
|
64
|
-
"pwlogin [手机号] [验证码]\n"
|
|
65
|
-
"bind [5e|pw] [玩家名]\n"
|
|
66
|
-
"match [platform] [@群友] [round] [-r]"
|
|
67
|
-
),
|
|
73
|
+
usage=_USAGE_HELP,
|
|
68
74
|
type="application",
|
|
69
75
|
homepage="https://github.com/luojisama/nonebot-plugin-cs2radar",
|
|
70
76
|
config=Config,
|
|
@@ -73,6 +79,34 @@ __plugin_meta__ = PluginMetadata(
|
|
|
73
79
|
"author": "luojisama",
|
|
74
80
|
"version": __version__,
|
|
75
81
|
"pypi": "nonebot-plugin-cs2radar",
|
|
82
|
+
"help": _USAGE_HELP,
|
|
83
|
+
"menu": [
|
|
84
|
+
{"cmd": "cs查询 <选手>", "desc": "查询职业选手战队与技术画像", "alias": ["cs选手", "csplayer"]},
|
|
85
|
+
{"cmd": "cs赛事", "desc": "查询近期国际大赛与重要赛程", "alias": ["赛事", "csgo赛事", "cs2赛事"]},
|
|
86
|
+
{"cmd": "赛果", "desc": "查询近几日比赛赛果与比分", "alias": ["cs赛果", "赛事赛果"]},
|
|
87
|
+
{"cmd": "5e [ID/昵称] [-r]", "desc": "查询 5E 平台综合战绩与 4 维智能战术画像", "alias": ["5e战绩", "5e查询", "cs战绩"]},
|
|
88
|
+
{"cmd": "pw [ID/昵称/SteamID] [-r]", "desc": "查询完美平台综合战绩与 4 维智能战术画像", "alias": ["pw战绩", "pw查询", "完美战绩"]},
|
|
89
|
+
{"cmd": "pwlogin <手机号> <验证码>", "desc": "登录完美平台获取会话态", "alias": ["完美登录"]},
|
|
90
|
+
{"cmd": "bind <5e|pw> <玩家名>", "desc": "绑定当前 QQ 的常用查询玩家", "alias": ["绑定", "添加"]},
|
|
91
|
+
{"cmd": "match [5e|pw|mm] [@群友] [局数] [-r]", "desc": "查询最近第 N 把详细对局并生成四维战术复盘", "alias": ["战绩", "查询战绩"]},
|
|
92
|
+
],
|
|
93
|
+
"configs": {
|
|
94
|
+
"cs2radar_priority": "插件优先级 (默认: 5)",
|
|
95
|
+
"cs2radar_bind_db_path": "绑定数据库路径 (默认: 自动定位至 localstore)",
|
|
96
|
+
"cs2radar_http_timeout": "HTTP 请求超时秒数 (默认: 15)",
|
|
97
|
+
"cs2radar_llm_enabled": "是否启用 LLM 战术分析与智能对标 (默认: true)",
|
|
98
|
+
"cs2radar_llm_api_type": "LLM 接口类型 (openai/gemini/anthropic, 默认: openai)",
|
|
99
|
+
"cs2radar_llm_api_url": "LLM 接口地址 (默认: https://api.openai.com/v1)",
|
|
100
|
+
"cs2radar_llm_api_key": "LLM API Key",
|
|
101
|
+
"cs2radar_llm_model": "LLM 模型名称 (默认: gpt-4o-mini)",
|
|
102
|
+
"cs2radar_llm_backup_enabled": "是否启用备用 LLM (默认: false)",
|
|
103
|
+
"cs2radar_llm_backup_api_type": "备用 LLM 接口类型",
|
|
104
|
+
"cs2radar_llm_backup_api_url": "备用 LLM 接口地址",
|
|
105
|
+
"cs2radar_llm_backup_api_key": "备用 LLM API Key",
|
|
106
|
+
"cs2radar_llm_backup_model": "备用 LLM 模型名称",
|
|
107
|
+
"cs2radar_llm_timeout": "LLM 请求超时秒数 (默认: 30)",
|
|
108
|
+
"cs2radar_llm_system_prompt": "自定义战术复盘 System Prompt",
|
|
109
|
+
},
|
|
76
110
|
},
|
|
77
111
|
)
|
|
78
112
|
|
|
@@ -171,7 +205,7 @@ def _parse_llm_sections(text: str) -> list[dict]:
|
|
|
171
205
|
return [{"tag": "复盘点评", "content": text.strip()}]
|
|
172
206
|
|
|
173
207
|
|
|
174
|
-
def _build_profile_context_5e(data: dict) -> dict:
|
|
208
|
+
def _build_profile_context_5e(data: dict, hltv_benchmarks: list[dict] | None = None) -> dict:
|
|
175
209
|
nickname = data.get("nickname", "5E玩家")
|
|
176
210
|
stats = data.get("stats", {})
|
|
177
211
|
career = stats.get("career", {})
|
|
@@ -205,7 +239,7 @@ def _build_profile_context_5e(data: dict) -> dict:
|
|
|
205
239
|
"adr": rm.get("adr"),
|
|
206
240
|
})
|
|
207
241
|
|
|
208
|
-
|
|
242
|
+
ctx = {
|
|
209
243
|
"platform": "5E ARENA 对战平台",
|
|
210
244
|
"player_name": nickname,
|
|
211
245
|
"elo": career.get("elo_9") or career.get("elo", 0),
|
|
@@ -224,9 +258,12 @@ def _build_profile_context_5e(data: dict) -> dict:
|
|
|
224
258
|
"role_level": role.get("score_level", ""),
|
|
225
259
|
"recent_matches": recent_list,
|
|
226
260
|
}
|
|
261
|
+
if hltv_benchmarks:
|
|
262
|
+
ctx["hltv_pro_benchmarks"] = hltv_benchmarks[:6]
|
|
263
|
+
return ctx
|
|
227
264
|
|
|
228
265
|
|
|
229
|
-
def _build_profile_context(data: dict) -> dict:
|
|
266
|
+
def _build_profile_context(data: dict, hltv_benchmarks: list[dict] | None = None) -> dict:
|
|
230
267
|
summary = data.get("summary", {})
|
|
231
268
|
stats = data.get("stats", {})
|
|
232
269
|
recent_matches = data.get("recent_matches", [])
|
|
@@ -258,7 +295,7 @@ def _build_profile_context(data: dict) -> dict:
|
|
|
258
295
|
for rm in recent_matches[:5]
|
|
259
296
|
]
|
|
260
297
|
|
|
261
|
-
|
|
298
|
+
ctx = {
|
|
262
299
|
"player_name": summary.get("nickname", "未知"),
|
|
263
300
|
"steam_id": str(summary.get("steamId", "")),
|
|
264
301
|
"season": stats.get("seasonId", "当前赛季"),
|
|
@@ -288,6 +325,9 @@ def _build_profile_context(data: dict) -> dict:
|
|
|
288
325
|
"hot_weapons": hot_weapons,
|
|
289
326
|
"recent_matches": recent_list
|
|
290
327
|
}
|
|
328
|
+
if hltv_benchmarks:
|
|
329
|
+
ctx["hltv_pro_benchmarks"] = hltv_benchmarks[:6]
|
|
330
|
+
return ctx
|
|
291
331
|
|
|
292
332
|
|
|
293
333
|
def _build_match_view_data(match_data, llm_title: str, llm_detail: str) -> dict:
|
|
@@ -439,15 +479,25 @@ async def handle_match(bot: Bot, event: MessageEvent, args: Message = CommandArg
|
|
|
439
479
|
except Exception as e:
|
|
440
480
|
await match_cmd.finish(f"查询失败: {e}")
|
|
441
481
|
|
|
442
|
-
llm_title = "
|
|
443
|
-
llm_detail = "
|
|
482
|
+
llm_title = "风格待定"
|
|
483
|
+
llm_detail = "【战局走势】比赛数据分析中。【核心表现】战术复盘计算中。【团队对比】正在比对双方攻防数据。【改进建议】保持稳定沟通与道具配合。"
|
|
444
484
|
try:
|
|
445
485
|
result = await llm.evaluate(match_data.llm_context(), refresh=refresh)
|
|
446
486
|
if result:
|
|
447
487
|
llm_title = result.title
|
|
448
488
|
llm_detail = result.detail
|
|
489
|
+
else:
|
|
490
|
+
fallback = llm._generate_smart_match_fallback(match_data.llm_context())
|
|
491
|
+
llm_title = fallback.title
|
|
492
|
+
llm_detail = fallback.detail
|
|
449
493
|
except Exception as e:
|
|
450
494
|
logger.warning(f"[cs2radar] llm evaluate failed: {e}")
|
|
495
|
+
try:
|
|
496
|
+
fallback = llm._generate_smart_match_fallback(match_data.llm_context())
|
|
497
|
+
llm_title = fallback.title
|
|
498
|
+
llm_detail = fallback.detail
|
|
499
|
+
except Exception:
|
|
500
|
+
pass
|
|
451
501
|
|
|
452
502
|
view_data = _build_match_view_data(match_data, llm_title, llm_detail)
|
|
453
503
|
image_bytes = await render_match_detail_card(view_data)
|
|
@@ -591,7 +641,12 @@ async def handle_five_e_stats(bot: Bot, event: MessageEvent, arg: Message = Comm
|
|
|
591
641
|
|
|
592
642
|
# 生成 / 获取 LLM 主页评价
|
|
593
643
|
try:
|
|
594
|
-
|
|
644
|
+
benchmarks = []
|
|
645
|
+
try:
|
|
646
|
+
benchmarks = await event_crawler.get_hltv_pro_benchmarks()
|
|
647
|
+
except Exception:
|
|
648
|
+
pass
|
|
649
|
+
profile_ctx = _build_profile_context_5e(data, hltv_benchmarks=benchmarks)
|
|
595
650
|
career = data.get("stats", {}).get("career", {})
|
|
596
651
|
cnt = int(career.get("match_total") or 0)
|
|
597
652
|
season_id = str(career.get("best_season") or "")
|
|
@@ -603,19 +658,15 @@ async def handle_five_e_stats(bot: Bot, event: MessageEvent, arg: Message = Comm
|
|
|
603
658
|
match_cnt=cnt,
|
|
604
659
|
season_id=season_id,
|
|
605
660
|
)
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
data["llm_sections"] = _parse_llm_sections(llm_res.detail)
|
|
610
|
-
else:
|
|
611
|
-
data["llm_title"] = "天梯强力进攻先锋"
|
|
612
|
-
data["llm_detail"] = "【战力定位】在5E高分天梯打出极高攻防效率。【技术风格】拼抢激进,单兵摧毁力强。【武器地图】主力枪械覆盖全面。【进阶建议】保持进攻侵略性,协同团队进退。"
|
|
613
|
-
data["llm_sections"] = _parse_llm_sections(data["llm_detail"])
|
|
661
|
+
data["llm_title"] = llm_res.title
|
|
662
|
+
data["llm_detail"] = llm_res.detail
|
|
663
|
+
data["llm_sections"] = _parse_llm_sections(llm_res.detail)
|
|
614
664
|
except Exception as e:
|
|
615
665
|
logger.warning(f"生成5E主页LLM评价失败: {e}")
|
|
616
|
-
|
|
617
|
-
data["
|
|
618
|
-
data["
|
|
666
|
+
fallback_res = llm._generate_smart_profile_fallback(_build_profile_context_5e(data))
|
|
667
|
+
data["llm_title"] = fallback_res.title
|
|
668
|
+
data["llm_detail"] = fallback_res.detail
|
|
669
|
+
data["llm_sections"] = _parse_llm_sections(fallback_res.detail)
|
|
619
670
|
|
|
620
671
|
image_bytes = await render_stats_card(data)
|
|
621
672
|
await five_e_stats.finish(MessageSegment.image(image_bytes))
|
|
@@ -714,7 +765,12 @@ async def handle_pw_stats(bot: Bot, event: MessageEvent, arg: Message = CommandA
|
|
|
714
765
|
|
|
715
766
|
# 生成 / 获取 LLM 主页评价
|
|
716
767
|
try:
|
|
717
|
-
|
|
768
|
+
benchmarks = []
|
|
769
|
+
try:
|
|
770
|
+
benchmarks = await event_crawler.get_hltv_pro_benchmarks()
|
|
771
|
+
except Exception:
|
|
772
|
+
pass
|
|
773
|
+
profile_ctx = _build_profile_context(data, hltv_benchmarks=benchmarks)
|
|
718
774
|
cnt = data.get("stats", {}).get("cnt", 0)
|
|
719
775
|
season_id = str(data.get("stats", {}).get("seasonId") or "")
|
|
720
776
|
llm_res = await llm.evaluate_profile(
|
|
@@ -724,19 +780,15 @@ async def handle_pw_stats(bot: Bot, event: MessageEvent, arg: Message = CommandA
|
|
|
724
780
|
match_cnt=cnt,
|
|
725
781
|
season_id=season_id,
|
|
726
782
|
)
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
data["llm_sections"] = _parse_llm_sections(llm_res.detail)
|
|
731
|
-
else:
|
|
732
|
-
data["llm_title"] = "全能型竞技核心"
|
|
733
|
-
data["llm_detail"] = "该玩家数据积累中,展现出扎实的技术功底与极高的成长潜力。"
|
|
734
|
-
data["llm_sections"] = []
|
|
783
|
+
data["llm_title"] = llm_res.title
|
|
784
|
+
data["llm_detail"] = llm_res.detail
|
|
785
|
+
data["llm_sections"] = _parse_llm_sections(llm_res.detail)
|
|
735
786
|
except Exception as e:
|
|
736
787
|
logger.warning(f"生成主页LLM评价失败: {e}")
|
|
737
|
-
|
|
738
|
-
data["
|
|
739
|
-
data["
|
|
788
|
+
fallback_res = llm._generate_smart_profile_fallback(_build_profile_context(data))
|
|
789
|
+
data["llm_title"] = fallback_res.title
|
|
790
|
+
data["llm_detail"] = fallback_res.detail
|
|
791
|
+
data["llm_sections"] = _parse_llm_sections(fallback_res.detail)
|
|
740
792
|
|
|
741
793
|
image_bytes = await render_pw_stats_card(data)
|
|
742
794
|
await pw_stats.finish(MessageSegment.image(image_bytes))
|