roneia 1.0.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.
- roneia-1.0.0/LICENSE +21 -0
- roneia-1.0.0/PKG-INFO +595 -0
- roneia-1.0.0/README.md +543 -0
- roneia-1.0.0/pyproject.toml +80 -0
- roneia-1.0.0/roneia.egg-info/PKG-INFO +595 -0
- roneia-1.0.0/roneia.egg-info/SOURCES.txt +35 -0
- roneia-1.0.0/roneia.egg-info/dependency_links.txt +1 -0
- roneia-1.0.0/roneia.egg-info/entry_points.txt +2 -0
- roneia-1.0.0/roneia.egg-info/requires.txt +35 -0
- roneia-1.0.0/roneia.egg-info/top_level.txt +2 -0
- roneia-1.0.0/roneia_client/__init__.py +20 -0
- roneia-1.0.0/roneia_client/__main__.py +5 -0
- roneia-1.0.0/roneia_client/client.py +929 -0
- roneia-1.0.0/roneia_client/config.py +340 -0
- roneia-1.0.0/roneia_client/dep_manager.py +173 -0
- roneia-1.0.0/roneia_client/local_skill_executor.py +142 -0
- roneia-1.0.0/roneia_client/main.py +671 -0
- roneia-1.0.0/roneia_client/permission_ui.py +267 -0
- roneia-1.0.0/roneia_client/setup_wizard.py +236 -0
- roneia-1.0.0/roneia_client/skill_store.py +286 -0
- roneia-1.0.0/roneia_client/voice/__init__.py +34 -0
- roneia-1.0.0/roneia_client/voice/audio_io.py +222 -0
- roneia-1.0.0/roneia_client/voice/base_stt.py +90 -0
- roneia-1.0.0/roneia_client/voice/base_tts.py +94 -0
- roneia-1.0.0/roneia_client/voice/edge_tts_engine.py +91 -0
- roneia-1.0.0/roneia_client/voice/sherpa_stt.py +181 -0
- roneia-1.0.0/roneia_client/voice/text_utils.py +56 -0
- roneia-1.0.0/roneia_client/voice/vad.py +125 -0
- roneia-1.0.0/roneia_client/voice/voice_manager.py +376 -0
- roneia-1.0.0/roneia_core/__init__.py +62 -0
- roneia-1.0.0/roneia_core/builtin_skills/__init__.py +12 -0
- roneia-1.0.0/roneia_core/builtin_skills/local_file.py +175 -0
- roneia-1.0.0/roneia_core/builtin_skills/screen_capture.py +195 -0
- roneia-1.0.0/roneia_core/builtin_skills/web_search.py +268 -0
- roneia-1.0.0/roneia_core/permission_manager.py +761 -0
- roneia-1.0.0/roneia_core/protocol.py +701 -0
- roneia-1.0.0/setup.cfg +4 -0
roneia-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Ruixywie
|
|
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.
|
roneia-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: roneia
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Roneia 数字人助手 - 本地客户端
|
|
5
|
+
Author: Ruixywie
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Ruixywie/Roneia
|
|
8
|
+
Keywords: ai,assistant,agent,llm
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
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.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: websockets>=12.0
|
|
21
|
+
Requires-Dist: pyyaml>=6.0
|
|
22
|
+
Requires-Dist: pydantic>=2.0
|
|
23
|
+
Provides-Extra: voice
|
|
24
|
+
Requires-Dist: sherpa-onnx<1.12,>=1.10; extra == "voice"
|
|
25
|
+
Requires-Dist: edge-tts>=6.0; extra == "voice"
|
|
26
|
+
Requires-Dist: webrtcvad-wheels>=2.0; extra == "voice"
|
|
27
|
+
Requires-Dist: sounddevice>=0.4; extra == "voice"
|
|
28
|
+
Requires-Dist: pydub>=0.25; extra == "voice"
|
|
29
|
+
Requires-Dist: numpy>=1.24; extra == "voice"
|
|
30
|
+
Provides-Extra: search
|
|
31
|
+
Requires-Dist: tavily-python>=0.5; extra == "search"
|
|
32
|
+
Requires-Dist: ddgs>=6.0; extra == "search"
|
|
33
|
+
Requires-Dist: requests>=2.28; extra == "search"
|
|
34
|
+
Requires-Dist: beautifulsoup4>=4.12; extra == "search"
|
|
35
|
+
Provides-Extra: screen
|
|
36
|
+
Requires-Dist: pillow>=9.0; extra == "screen"
|
|
37
|
+
Requires-Dist: pyautogui>=0.9; extra == "screen"
|
|
38
|
+
Provides-Extra: all
|
|
39
|
+
Requires-Dist: sherpa-onnx<1.12,>=1.10; extra == "all"
|
|
40
|
+
Requires-Dist: edge-tts>=6.0; extra == "all"
|
|
41
|
+
Requires-Dist: webrtcvad-wheels>=2.0; extra == "all"
|
|
42
|
+
Requires-Dist: sounddevice>=0.4; extra == "all"
|
|
43
|
+
Requires-Dist: pydub>=0.25; extra == "all"
|
|
44
|
+
Requires-Dist: numpy>=1.24; extra == "all"
|
|
45
|
+
Requires-Dist: tavily-python>=0.5; extra == "all"
|
|
46
|
+
Requires-Dist: ddgs>=6.0; extra == "all"
|
|
47
|
+
Requires-Dist: requests>=2.28; extra == "all"
|
|
48
|
+
Requires-Dist: beautifulsoup4>=4.12; extra == "all"
|
|
49
|
+
Requires-Dist: pillow>=9.0; extra == "all"
|
|
50
|
+
Requires-Dist: pyautogui>=0.9; extra == "all"
|
|
51
|
+
Dynamic: license-file
|
|
52
|
+
|
|
53
|
+
# Roneia Client - 本地客户端
|
|
54
|
+
|
|
55
|
+
Roneia 数字人助手的本地客户端,连接云端服务器执行本地任务。
|
|
56
|
+
|
|
57
|
+
## 架构角色
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Client 是 Skill 的"执行者"
|
|
61
|
+
|
|
62
|
+
Server 发送工具调用请求
|
|
63
|
+
│
|
|
64
|
+
▼
|
|
65
|
+
┌─────────────────────────────────────────────┐
|
|
66
|
+
│ Client │
|
|
67
|
+
│ │
|
|
68
|
+
│ ┌────────────────────────────────────────┐ │
|
|
69
|
+
│ │ LocalSkillExecutor │ │
|
|
70
|
+
│ │ ┌──────────────────────────────────┐ │ │
|
|
71
|
+
│ │ │ SKILL_MODULES = { │ │ │
|
|
72
|
+
│ │ │ "local_file": local_file, │ │ │
|
|
73
|
+
│ │ │ "web_search": web_search, │ │ │
|
|
74
|
+
│ │ │ "screen_capture": screen_cap, │ │ │
|
|
75
|
+
│ │ │ } │ │ │
|
|
76
|
+
│ │ └──────────────────────────────────┘ │ │
|
|
77
|
+
│ └────────────────────────────────────────┘ │
|
|
78
|
+
│ │ │
|
|
79
|
+
│ ▼ │
|
|
80
|
+
│ ┌────────────────────────────────────────┐ │
|
|
81
|
+
│ │ builtin_skills/local_file.py │ │
|
|
82
|
+
│ │ ┌──────────────────────────────────┐ │ │
|
|
83
|
+
│ │ │ async def open_file(path): │ │ │
|
|
84
|
+
│ │ │ os.startfile(path) │ │ │
|
|
85
|
+
│ │ │ return {"success": True} │ │ │
|
|
86
|
+
│ │ │ │ │ │
|
|
87
|
+
│ │ │ TOOLS = {"open_file": open_file}│ │ │
|
|
88
|
+
│ │ └──────────────────────────────────┘ │ │
|
|
89
|
+
│ └────────────────────────────────────────┘ │
|
|
90
|
+
│ │
|
|
91
|
+
└─────────────────────────────────────────────┘
|
|
92
|
+
│
|
|
93
|
+
▼
|
|
94
|
+
返回执行结果给 Server
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 安装
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# 从 pip 安装
|
|
103
|
+
pip install roneia
|
|
104
|
+
|
|
105
|
+
# 或从源码安装
|
|
106
|
+
cd roneia-client
|
|
107
|
+
pip install -e .
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 安装可选依赖
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# 语音功能
|
|
114
|
+
pip install roneia[voice]
|
|
115
|
+
|
|
116
|
+
# 网页搜索功能(Tavily + DuckDuckGo 双引擎)
|
|
117
|
+
pip install roneia[search]
|
|
118
|
+
|
|
119
|
+
# 屏幕截图功能
|
|
120
|
+
pip install roneia[screen]
|
|
121
|
+
|
|
122
|
+
# 全部可选依赖
|
|
123
|
+
pip install roneia[all]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
> 可选依赖也可以在 `roneia setup` 或 `/skills enable` 时自动安装,无需手动操作。
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 快速开始
|
|
131
|
+
|
|
132
|
+
### 方式 1:一键配置(推荐)
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
roneia setup
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
配置向导会引导你完成:
|
|
139
|
+
1. 输入服务器地址和认证令牌
|
|
140
|
+
2. 自动测试连接
|
|
141
|
+
3. 选择要启用的 Skill(自动安装所需依赖)
|
|
142
|
+
4. 保存配置到 `~/.roneia/config.yaml`
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
============================================================
|
|
146
|
+
Roneia - 初始配置向导
|
|
147
|
+
============================================================
|
|
148
|
+
|
|
149
|
+
1) 服务器连接
|
|
150
|
+
服务器地址 [ws://localhost:8765/ws]: ws://my-server:8765/ws
|
|
151
|
+
认证令牌: ********
|
|
152
|
+
|
|
153
|
+
正在测试连接... 连接成功!
|
|
154
|
+
|
|
155
|
+
2) Skill 配置
|
|
156
|
+
从服务器获取到 3 个可用 Skill:
|
|
157
|
+
|
|
158
|
+
[1] local_file - 本地文件 (无额外依赖)
|
|
159
|
+
[2] web_search - 网页搜索 (需安装依赖)
|
|
160
|
+
[3] screen_capture - 屏幕截图 (需安装依赖)
|
|
161
|
+
|
|
162
|
+
选择要启用的 Skill (逗号分隔, 回车全部跳过): 1,2
|
|
163
|
+
|
|
164
|
+
正在安装 web_search 依赖...
|
|
165
|
+
依赖安装完成
|
|
166
|
+
已启用: local_file, web_search
|
|
167
|
+
|
|
168
|
+
3) 保存配置
|
|
169
|
+
配置已保存到: C:\Users\xxx\.roneia\config.yaml
|
|
170
|
+
|
|
171
|
+
============================================================
|
|
172
|
+
配置完成! 运行 roneia 开始使用
|
|
173
|
+
============================================================
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
配置完成后启动:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
roneia
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 方式 2:手动配置
|
|
183
|
+
|
|
184
|
+
```yaml
|
|
185
|
+
# ~/.roneia/config.yaml
|
|
186
|
+
server:
|
|
187
|
+
url: "ws://your-server-ip:8765/ws"
|
|
188
|
+
token: "your-auth-token"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
roneia
|
|
193
|
+
# 或指定配置文件
|
|
194
|
+
roneia --config config.yaml
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 安装并启用 Skill
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
你: /skills list
|
|
201
|
+
你: /skills install local_file
|
|
202
|
+
你: /skills enable local_file # 自动检测并提示安装缺失依赖
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 语音模式
|
|
208
|
+
|
|
209
|
+
支持语音聊天,类似 GPT/豆包语音对话。基于 sherpa-onnx 流式识别,支持 **YouTube 风格实时字幕**。语音配置自动从 Server 拉取,Client 零配置。
|
|
210
|
+
|
|
211
|
+
TTS 采用**分句流水线**模式:长文本自动按句拆分,第一句合成完即开始播放,同时并行合成后续句子,首句延迟从 3-5 秒降至 0.5-1.5 秒。短文本(单句)走快速路径,无额外开销。
|
|
212
|
+
|
|
213
|
+
### 使用
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
你: /voice
|
|
217
|
+
[语音] 正在初始化语音模块...
|
|
218
|
+
[语音] 正在下载模型 sherpa-onnx-streaming-zipformer-bilingual-zh-en (~191MB)...
|
|
219
|
+
[语音] 模型下载完成
|
|
220
|
+
[语音] 模块初始化完成
|
|
221
|
+
已切换到语音模式(按 Ctrl+C 切回文字模式)
|
|
222
|
+
|
|
223
|
+
[等待说话...]
|
|
224
|
+
[正在听...]
|
|
225
|
+
[听到] 今天 ← 流式逐字更新
|
|
226
|
+
[听到] 今天天气怎么样 ← 自动修正前文
|
|
227
|
+
你: 今天天气怎么样 # 检测到说完
|
|
228
|
+
|
|
229
|
+
Roneia: 今天北京天气晴朗... # 文字 + 语音回复
|
|
230
|
+
(TTS 播放中,大声说话可打断)
|
|
231
|
+
|
|
232
|
+
你: /text # 切回文字模式
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### 技术栈
|
|
236
|
+
|
|
237
|
+
| 组件 | 库 | 说明 |
|
|
238
|
+
|------|----|------|
|
|
239
|
+
| STT | sherpa-onnx | 流式语音识别(逐帧转录,无 torch 依赖,模型 ~191MB) |
|
|
240
|
+
| TTS | edge-tts | 微软 Edge TTS(免费,中文质量好) |
|
|
241
|
+
| VAD | webrtcvad | 语音活动检测(轻量 C 库,~200KB) |
|
|
242
|
+
| 录音 | sounddevice | 麦克风实时录音 |
|
|
243
|
+
| 播放 | pydub | MP3 音频播放 |
|
|
244
|
+
|
|
245
|
+
### 覆盖 Server 配置
|
|
246
|
+
|
|
247
|
+
Client 可以在 config.yaml 中覆盖 Server 下发的语音配置:
|
|
248
|
+
|
|
249
|
+
```yaml
|
|
250
|
+
voice:
|
|
251
|
+
tts_voice: "zh-CN-YunxiNeural" # 覆盖为男声
|
|
252
|
+
tts_rate: "+10%" # 覆盖语速
|
|
253
|
+
tts_pitch: "+5Hz" # 覆盖音调
|
|
254
|
+
tts_volume: "+10%" # 覆盖音量
|
|
255
|
+
silence_duration_ms: 2000 # 等待更久再判定说完
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## /skills 命令
|
|
261
|
+
|
|
262
|
+
| 命令 | 说明 |
|
|
263
|
+
|------|------|
|
|
264
|
+
| `/skills list` | 显示云端可用的 Skill |
|
|
265
|
+
| `/skills installed` | 显示本地已安装的 Skill |
|
|
266
|
+
| `/skills install <name>` | 安装 Skill(标记为已安装) |
|
|
267
|
+
| `/skills enable <name>` | 启用 Skill(同步到服务端) |
|
|
268
|
+
| `/skills disable <name>` | 禁用 Skill |
|
|
269
|
+
| `/skills remove <name>` | 删除本地 Skill |
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## /persona 命令
|
|
274
|
+
|
|
275
|
+
管理数字人的性格和说话风格,实时生效无需重启。
|
|
276
|
+
|
|
277
|
+
| 命令 | 说明 |
|
|
278
|
+
|------|------|
|
|
279
|
+
| `/persona` | 显示当前人设 |
|
|
280
|
+
| `/persona set` | 进入多行输入模式,设置新人设(输入空行结束) |
|
|
281
|
+
| `/persona reset` | 恢复默认人设 |
|
|
282
|
+
|
|
283
|
+
### 示例
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
你: /persona
|
|
287
|
+
当前人设:
|
|
288
|
+
────────────────────────────────────────
|
|
289
|
+
你是 Roneia,用户最好的朋友。
|
|
290
|
+
...
|
|
291
|
+
────────────────────────────────────────
|
|
292
|
+
|
|
293
|
+
你: /persona set
|
|
294
|
+
请输入新的人设(输入空行结束):
|
|
295
|
+
> 你是一个冷酷的机器人,只用最简短的话回答
|
|
296
|
+
>
|
|
297
|
+
人设已更新!
|
|
298
|
+
|
|
299
|
+
你: /persona reset
|
|
300
|
+
已恢复默认人设
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## 内置 Skills
|
|
306
|
+
|
|
307
|
+
| Skill | 功能 | 所需依赖 |
|
|
308
|
+
|-------|------|----------|
|
|
309
|
+
| local_file | 本地文件管理 | 无 |
|
|
310
|
+
| web_search | 网页搜索(Tavily/DuckDuckGo 双引擎) | tavily-python (可选), ddgs, requests, beautifulsoup4 |
|
|
311
|
+
| screen_capture | 屏幕截图 | pillow, pyautogui |
|
|
312
|
+
|
|
313
|
+
### local_file 工具
|
|
314
|
+
|
|
315
|
+
| 工具 | 说明 |
|
|
316
|
+
|------|------|
|
|
317
|
+
| `open_file(path)` | 使用系统默认程序打开文件/文件夹 |
|
|
318
|
+
| `read_file(path, encoding, max_lines)` | 读取文本文件内容 |
|
|
319
|
+
| `search_files(pattern, directory, recursive, max_results)` | 搜索文件 |
|
|
320
|
+
|
|
321
|
+
### web_search 工具
|
|
322
|
+
|
|
323
|
+
支持 **Tavily**(主力)+ **DuckDuckGo**(降级)双引擎搜索。Tavily 专为 AI Agent 设计,返回结构化结果和 AI 摘要,免费额度 1000 次/月。Server 配置 `TAVILY_API_KEY` 后自动启用 Tavily;未配置或 Tavily 失败时自动降级到 DuckDuckGo。
|
|
324
|
+
|
|
325
|
+
| 工具 | 说明 |
|
|
326
|
+
|------|------|
|
|
327
|
+
| `search(query, num_results)` | 网页搜索(自动选择 Tavily 或 DuckDuckGo) |
|
|
328
|
+
| `fetch_page(url, extract_text, max_length)` | 获取网页内容 |
|
|
329
|
+
|
|
330
|
+
### screen_capture 工具
|
|
331
|
+
|
|
332
|
+
| 工具 | 说明 |
|
|
333
|
+
|------|------|
|
|
334
|
+
| `capture_screen(region, save_path)` | 截取屏幕 |
|
|
335
|
+
| `find_on_screen(target, confidence)` | 在屏幕上查找目标图像 |
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## 目录结构
|
|
340
|
+
|
|
341
|
+
```
|
|
342
|
+
roneia-client/
|
|
343
|
+
├── pyproject.toml # pip 配置(包名: roneia)
|
|
344
|
+
│
|
|
345
|
+
├── roneia_client/ # 客户端模块
|
|
346
|
+
│ ├── __main__.py # python -m roneia_client 入口
|
|
347
|
+
│ ├── main.py # 主入口(含 setup 子命令)
|
|
348
|
+
│ ├── client.py # WebSocket 客户端
|
|
349
|
+
│ ├── config.py # 配置加载
|
|
350
|
+
│ ├── setup_wizard.py # 初始配置向导 [新增]
|
|
351
|
+
│ ├── dep_manager.py # 依赖管理器 [新增]
|
|
352
|
+
│ ├── skill_store.py # Skill 状态存储
|
|
353
|
+
│ ├── local_skill_executor.py # Skill 执行器 [核心]
|
|
354
|
+
│ ├── permission_ui.py # 权限 UI
|
|
355
|
+
│ └── voice/ # 语音模块 [内置功能]
|
|
356
|
+
│ ├── __init__.py # 模块导出 + 自动注册
|
|
357
|
+
│ ├── voice_manager.py # 核心协调器(分句流水线 TTS)
|
|
358
|
+
│ ├── text_utils.py # 文本分句工具
|
|
359
|
+
│ ├── base_stt.py # STT 抽象基类 + 工厂
|
|
360
|
+
│ ├── base_tts.py # TTS 抽象基类 + 工厂
|
|
361
|
+
│ ├── sherpa_stt.py # 流式 STT (sherpa-onnx)
|
|
362
|
+
│ ├── edge_tts_engine.py # Edge TTS
|
|
363
|
+
│ ├── vad.py # WebRTC VAD
|
|
364
|
+
│ └── audio_io.py # 麦克风录音 + 播放(含队列播放)
|
|
365
|
+
│
|
|
366
|
+
└── roneia_core/ # 核心框架
|
|
367
|
+
├── protocol.py # 通信协议
|
|
368
|
+
├── permission_manager.py # 权限管理
|
|
369
|
+
└── builtin_skills/ # Skill 代码实现 [核心]
|
|
370
|
+
├── __init__.py
|
|
371
|
+
├── local_file.py # 文件操作
|
|
372
|
+
├── web_search.py # 网页搜索
|
|
373
|
+
└── screen_capture.py # 屏幕截图
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## 工作流程
|
|
379
|
+
|
|
380
|
+
```
|
|
381
|
+
用户输入任务
|
|
382
|
+
│
|
|
383
|
+
▼
|
|
384
|
+
┌────────────────┐
|
|
385
|
+
│ WebSocket 发送 │
|
|
386
|
+
│ task.request │
|
|
387
|
+
└───────┬────────┘
|
|
388
|
+
│
|
|
389
|
+
▼
|
|
390
|
+
[Server 处理]
|
|
391
|
+
Phase 1: 若启用多个 Skill,
|
|
392
|
+
先选择相关 Skill
|
|
393
|
+
Phase 2: 仅加载选中 Skill 的工具
|
|
394
|
+
│
|
|
395
|
+
▼
|
|
396
|
+
┌────────────────┐
|
|
397
|
+
│ 接收 skill.call│ <── Server 决定调用哪个工具
|
|
398
|
+
└───────┬────────┘
|
|
399
|
+
│
|
|
400
|
+
▼
|
|
401
|
+
┌────────────────────────────────────────┐
|
|
402
|
+
│ LocalSkillExecutor │
|
|
403
|
+
│ │
|
|
404
|
+
│ 1. 查找 SKILL_MODULES[skill_name] │
|
|
405
|
+
│ 2. 查找 module.TOOLS[tool_name] │
|
|
406
|
+
│ 3. 执行 await tool_func(**arguments) │
|
|
407
|
+
│ 4. 返回结果 │
|
|
408
|
+
└───────┬────────────────────────────────┘
|
|
409
|
+
│
|
|
410
|
+
▼
|
|
411
|
+
┌────────────────┐
|
|
412
|
+
│ 发送 skill.result│
|
|
413
|
+
└───────┬────────┘
|
|
414
|
+
│
|
|
415
|
+
▼
|
|
416
|
+
[Server 处理]
|
|
417
|
+
│
|
|
418
|
+
▼
|
|
419
|
+
┌────────────────┐
|
|
420
|
+
│ 接收 task.response│
|
|
421
|
+
└───────┬────────┘
|
|
422
|
+
│
|
|
423
|
+
▼
|
|
424
|
+
显示给用户
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
> **注意**:两阶段 Skill 选择完全在 Server 端完成,Client 无需任何改动。当启用多个 Skill 时,Server 会先用轻量 LLM 调用筛选相关 Skill,再只加载选中 Skill 的工具定义,减少 token 消耗。
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## 添加新 Skill
|
|
432
|
+
|
|
433
|
+
### 步骤 1:创建 Skill 代码
|
|
434
|
+
|
|
435
|
+
新建 `roneia_core/builtin_skills/my_skill.py`:
|
|
436
|
+
|
|
437
|
+
```python
|
|
438
|
+
"""我的 Skill 实现"""
|
|
439
|
+
|
|
440
|
+
from typing import Any, Dict
|
|
441
|
+
|
|
442
|
+
async def my_tool(param1: str, param2: int = 10) -> Dict[str, Any]:
|
|
443
|
+
"""
|
|
444
|
+
我的工具
|
|
445
|
+
|
|
446
|
+
Args:
|
|
447
|
+
param1: 参数1
|
|
448
|
+
param2: 参数2(可选)
|
|
449
|
+
|
|
450
|
+
Returns:
|
|
451
|
+
执行结果
|
|
452
|
+
"""
|
|
453
|
+
try:
|
|
454
|
+
# 实现你的逻辑
|
|
455
|
+
result = f"处理了 {param1},数量 {param2}"
|
|
456
|
+
|
|
457
|
+
return {
|
|
458
|
+
"success": True,
|
|
459
|
+
"message": result,
|
|
460
|
+
}
|
|
461
|
+
except Exception as e:
|
|
462
|
+
return {
|
|
463
|
+
"success": False,
|
|
464
|
+
"error": str(e),
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
# 工具映射(必需)
|
|
468
|
+
TOOLS = {
|
|
469
|
+
"my_tool": my_tool,
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### 步骤 2:注册到执行器
|
|
474
|
+
|
|
475
|
+
编辑 `roneia_client/local_skill_executor.py`:
|
|
476
|
+
|
|
477
|
+
```python
|
|
478
|
+
from roneia_core.builtin_skills import local_file, web_search, screen_capture, my_skill
|
|
479
|
+
|
|
480
|
+
SKILL_MODULES = {
|
|
481
|
+
"local_file": local_file,
|
|
482
|
+
"web_search": web_search,
|
|
483
|
+
"screen_capture": screen_capture,
|
|
484
|
+
"my_skill": my_skill, # 添加这行
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### 步骤 3:Server 端添加定义
|
|
489
|
+
|
|
490
|
+
在 Server 的 `skill_registry/builtin_skills.py` 中添加 Skill 定义(参数、描述等)。
|
|
491
|
+
|
|
492
|
+
---
|
|
493
|
+
|
|
494
|
+
## 命令行参数
|
|
495
|
+
|
|
496
|
+
```
|
|
497
|
+
roneia [命令] [选项]
|
|
498
|
+
|
|
499
|
+
命令:
|
|
500
|
+
setup 运行初始配置向导
|
|
501
|
+
(无) 启动交互模式
|
|
502
|
+
|
|
503
|
+
选项:
|
|
504
|
+
--config, -c FILE 配置文件路径
|
|
505
|
+
--server URL 服务器 WebSocket URL
|
|
506
|
+
--token TOKEN 认证令牌
|
|
507
|
+
--no-gui 禁用 GUI 弹窗
|
|
508
|
+
--debug 调试模式
|
|
509
|
+
|
|
510
|
+
交互命令:
|
|
511
|
+
/voice 切换到语音模式
|
|
512
|
+
/text 切回文字模式
|
|
513
|
+
/skills ... Skill 管理(enable 时自动检测依赖)
|
|
514
|
+
/persona 人设管理
|
|
515
|
+
/status 显示状态
|
|
516
|
+
/help 帮助
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
---
|
|
520
|
+
|
|
521
|
+
## 配置文件
|
|
522
|
+
|
|
523
|
+
```yaml
|
|
524
|
+
server:
|
|
525
|
+
url: "ws://localhost:8765/ws" # 服务器地址
|
|
526
|
+
token: "" # 认证令牌
|
|
527
|
+
reconnect_interval: 5 # 重连间隔(秒)
|
|
528
|
+
max_reconnect_attempts: -1 # 最大重连次数 (-1=无限)
|
|
529
|
+
heartbeat_interval: 30 # 心跳间隔(秒)
|
|
530
|
+
|
|
531
|
+
permissions:
|
|
532
|
+
auto_grant: [] # 自动授权的权限
|
|
533
|
+
use_gui: true # 使用GUI弹窗请求权限
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
---
|
|
537
|
+
|
|
538
|
+
## 数据存储
|
|
539
|
+
|
|
540
|
+
客户端数据存储位置:
|
|
541
|
+
|
|
542
|
+
- `~/.roneia/config.yaml` - 客户端配置(`roneia setup` 生成)
|
|
543
|
+
- `~/.roneia/skills.json` - 已安装 Skill 的状态
|
|
544
|
+
|
|
545
|
+
---
|
|
546
|
+
|
|
547
|
+
## 故障排除
|
|
548
|
+
|
|
549
|
+
### 无法连接服务器
|
|
550
|
+
|
|
551
|
+
1. 检查服务器地址是否正确
|
|
552
|
+
2. 检查网络是否通畅
|
|
553
|
+
3. 检查认证令牌是否正确
|
|
554
|
+
4. 使用 `--debug` 查看详细日志
|
|
555
|
+
|
|
556
|
+
### Skill 不可用
|
|
557
|
+
|
|
558
|
+
1. 检查是否已安装:`/skills installed`
|
|
559
|
+
2. 检查是否已启用:`/status`
|
|
560
|
+
3. 检查依赖是否安装(如 web_search 需要 requests)
|
|
561
|
+
|
|
562
|
+
### 工具执行失败
|
|
563
|
+
|
|
564
|
+
1. 检查参数是否正确
|
|
565
|
+
2. 检查权限是否已授予
|
|
566
|
+
3. 查看日志中的错误信息
|
|
567
|
+
|
|
568
|
+
---
|
|
569
|
+
|
|
570
|
+
## 开发
|
|
571
|
+
|
|
572
|
+
### 从源码运行
|
|
573
|
+
|
|
574
|
+
```bash
|
|
575
|
+
cd roneia-client
|
|
576
|
+
pip install -e .
|
|
577
|
+
roneia setup # 初始配置
|
|
578
|
+
roneia --debug # 启动(调试模式)
|
|
579
|
+
python -m roneia_client # 或通过 python -m 启动
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### 运行测试
|
|
583
|
+
|
|
584
|
+
```bash
|
|
585
|
+
# 测试 Skill 模块导入
|
|
586
|
+
python -c "from roneia_core.builtin_skills import local_file; print(local_file.TOOLS)"
|
|
587
|
+
|
|
588
|
+
# 测试工具执行
|
|
589
|
+
python -c "
|
|
590
|
+
import asyncio
|
|
591
|
+
from roneia_core.builtin_skills import local_file
|
|
592
|
+
result = asyncio.run(local_file.search_files('*.py', '.', max_results=3))
|
|
593
|
+
print(result)
|
|
594
|
+
"
|
|
595
|
+
```
|