Skip to main content

Roneia 数字人助手 - 本地客户端

Project description

Roneia Client - 本地客户端

Roneia 数字人助手的本地客户端,连接云端服务器执行本地任务。

架构角色

Client 是 Skill 的"执行者"

Server 发送工具调用请求
         │
         ▼
┌─────────────────────────────────────────────┐
│                   Client                     │
│                                              │
│  ┌────────────────────────────────────────┐ │
│  │          LocalSkillExecutor            │ │
│  │  ┌──────────────────────────────────┐  │ │
│  │  │  SKILL_MODULES = {               │  │ │
│  │  │    "local_file": local_file,     │  │ │
│  │  │    "web_search": web_search,     │  │ │
│  │  │    "screen_capture": screen_cap, │  │ │
│  │  │  }                               │  │ │
│  │  └──────────────────────────────────┘  │ │
│  └────────────────────────────────────────┘ │
│                      │                       │
│                      ▼                       │
│  ┌────────────────────────────────────────┐ │
│  │      builtin_skills/local_file.py      │ │
│  │  ┌──────────────────────────────────┐  │ │
│  │  │  async def open_file(path):      │  │ │
│  │  │      os.startfile(path)          │  │ │
│  │  │      return {"success": True}    │  │ │
│  │  │                                  │  │ │
│  │  │  TOOLS = {"open_file": open_file}│  │ │
│  │  └──────────────────────────────────┘  │ │
│  └────────────────────────────────────────┘ │
│                                              │
└─────────────────────────────────────────────┘
         │
         ▼
返回执行结果给 Server

安装

# 从 pip 安装
pip install roneia

# 或从源码安装
cd roneia-client
pip install -e .

安装可选依赖

# 语音功能
pip install roneia[voice]

# 网页搜索功能(Tavily + DuckDuckGo 双引擎)
pip install roneia[search]

# 屏幕截图功能
pip install roneia[screen]

# 全部可选依赖
pip install roneia[all]

可选依赖也可以在 roneia setup/skills enable 时自动安装,无需手动操作。


快速开始

方式 1:一键配置(推荐)

roneia setup

配置向导会引导你完成:

  1. 输入服务器地址和认证令牌
  2. 自动测试连接
  3. 选择要启用的 Skill(自动安装所需依赖)
  4. 保存配置到 ~/.roneia/config.yaml
============================================================
           Roneia - 初始配置向导
============================================================

1) 服务器连接
   服务器地址 [ws://localhost:8765/ws]: ws://my-server:8765/ws
   认证令牌: ********

   正在测试连接... 连接成功!

2) Skill 配置
   从服务器获取到 3 个可用 Skill:

     [1] local_file          - 本地文件 (无额外依赖)
     [2] web_search          - 网页搜索 (需安装依赖)
     [3] screen_capture      - 屏幕截图 (需安装依赖)

   选择要启用的 Skill (逗号分隔, 回车全部跳过): 1,2

   正在安装 web_search 依赖...
   依赖安装完成
   已启用: local_file, web_search

3) 保存配置
   配置已保存到: C:\Users\xxx\.roneia\config.yaml

============================================================
   配置完成! 运行 roneia 开始使用
============================================================

配置完成后启动:

roneia

方式 2:手动配置

# ~/.roneia/config.yaml
server:
  url: "ws://your-server-ip:8765/ws"
  token: "your-auth-token"
roneia
# 或指定配置文件
roneia --config config.yaml

安装并启用 Skill

你: /skills list
你: /skills install local_file
你: /skills enable local_file    # 自动检测并提示安装缺失依赖

语音模式

支持语音聊天,类似 GPT/豆包语音对话。基于 sherpa-onnx 流式识别,支持 YouTube 风格实时字幕。语音配置自动从 Server 拉取,Client 零配置。

TTS 采用分句流水线模式:长文本自动按句拆分,第一句合成完即开始播放,同时并行合成后续句子,首句延迟从 3-5 秒降至 0.5-1.5 秒。短文本(单句)走快速路径,无额外开销。

使用

你: /voice
[语音] 正在初始化语音模块...
[语音] 正在下载模型 sherpa-onnx-streaming-zipformer-bilingual-zh-en (~191MB)...
[语音] 模型下载完成
[语音] 模块初始化完成
已切换到语音模式(按 Ctrl+C 切回文字模式)

  [等待说话...]
  [正在听...]
  [听到] 今天                        ← 流式逐字更新
  [听到] 今天天气怎么样              ← 自动修正前文
你: 今天天气怎么样                   # 检测到说完

Roneia: 今天北京天气晴朗...          # 文字 + 语音回复
(TTS 播放中,大声说话可打断)

你: /text                            # 切回文字模式

技术栈

组件 说明
STT sherpa-onnx 流式语音识别(逐帧转录,无 torch 依赖,模型 ~191MB)
TTS edge-tts 微软 Edge TTS(免费,中文质量好)
VAD webrtcvad 语音活动检测(轻量 C 库,~200KB)
录音 sounddevice 麦克风实时录音
播放 pydub MP3 音频播放

覆盖 Server 配置

Client 可以在 config.yaml 中覆盖 Server 下发的语音配置:

voice:
  tts_voice: "zh-CN-YunxiNeural"    # 覆盖为男声
  tts_rate: "+10%"                   # 覆盖语速
  tts_pitch: "+5Hz"                  # 覆盖音调
  tts_volume: "+10%"                 # 覆盖音量
  silence_duration_ms: 2000          # 等待更久再判定说完

/skills 命令

命令 说明
/skills list 显示云端可用的 Skill
/skills installed 显示本地已安装的 Skill
/skills install <name> 安装 Skill(标记为已安装)
/skills enable <name> 启用 Skill(同步到服务端)
/skills disable <name> 禁用 Skill
/skills remove <name> 删除本地 Skill

/persona 命令

管理数字人的性格和说话风格,实时生效无需重启。

命令 说明
/persona 显示当前人设
/persona set 进入多行输入模式,设置新人设(输入空行结束)
/persona reset 恢复默认人设

示例

你: /persona
当前人设:
────────────────────────────────────────
你是 Roneia,用户最好的朋友。
...
────────────────────────────────────────

你: /persona set
请输入新的人设(输入空行结束):
> 你是一个冷酷的机器人,只用最简短的话回答
>
人设已更新!

你: /persona reset
已恢复默认人设

内置 Skills

Skill 功能 所需依赖
local_file 本地文件管理
web_search 网页搜索(Tavily/DuckDuckGo 双引擎) tavily-python (可选), ddgs, requests, beautifulsoup4
screen_capture 屏幕截图 pillow, pyautogui

local_file 工具

工具 说明
open_file(path) 使用系统默认程序打开文件/文件夹
read_file(path, encoding, max_lines) 读取文本文件内容
search_files(pattern, directory, recursive, max_results) 搜索文件

web_search 工具

支持 Tavily(主力)+ DuckDuckGo(降级)双引擎搜索。Tavily 专为 AI Agent 设计,返回结构化结果和 AI 摘要,免费额度 1000 次/月。Server 配置 TAVILY_API_KEY 后自动启用 Tavily;未配置或 Tavily 失败时自动降级到 DuckDuckGo。

工具 说明
search(query, num_results) 网页搜索(自动选择 Tavily 或 DuckDuckGo)
fetch_page(url, extract_text, max_length) 获取网页内容

screen_capture 工具

工具 说明
capture_screen(region, save_path) 截取屏幕
find_on_screen(target, confidence) 在屏幕上查找目标图像

目录结构

roneia-client/
├── pyproject.toml              # pip 配置(包名: roneia)
│
├── roneia_client/              # 客户端模块
│   ├── __main__.py             # python -m roneia_client 入口
│   ├── main.py                 # 主入口(含 setup 子命令)
│   ├── client.py               # WebSocket 客户端
│   ├── config.py               # 配置加载
│   ├── setup_wizard.py         # 初始配置向导 [新增]
│   ├── dep_manager.py          # 依赖管理器 [新增]
│   ├── skill_store.py          # Skill 状态存储
│   ├── local_skill_executor.py # Skill 执行器 [核心]
│   ├── permission_ui.py        # 权限 UI
│   └── voice/                  # 语音模块 [内置功能]
│       ├── __init__.py         # 模块导出 + 自动注册
│       ├── voice_manager.py    # 核心协调器(分句流水线 TTS)
│       ├── text_utils.py       # 文本分句工具
│       ├── base_stt.py         # STT 抽象基类 + 工厂
│       ├── base_tts.py         # TTS 抽象基类 + 工厂
│       ├── sherpa_stt.py       # 流式 STT (sherpa-onnx)
│       ├── edge_tts_engine.py  # Edge TTS
│       ├── vad.py              # WebRTC VAD
│       └── audio_io.py         # 麦克风录音 + 播放(含队列播放)
│
└── roneia_core/                # 核心框架
    ├── protocol.py             # 通信协议
    ├── permission_manager.py   # 权限管理
    └── builtin_skills/         # Skill 代码实现 [核心]
        ├── __init__.py
        ├── local_file.py       # 文件操作
        ├── web_search.py       # 网页搜索
        └── screen_capture.py   # 屏幕截图

工作流程

用户输入任务
     │
     ▼
┌────────────────┐
│ WebSocket 发送 │
│ task.request   │
└───────┬────────┘
        │
        ▼
   [Server 处理]
   Phase 1: 若启用多个 Skill,
            先选择相关 Skill
   Phase 2: 仅加载选中 Skill 的工具
        │
        ▼
┌────────────────┐
│ 接收 skill.call│  <── Server 决定调用哪个工具
└───────┬────────┘
        │
        ▼
┌────────────────────────────────────────┐
│          LocalSkillExecutor            │
│                                        │
│  1. 查找 SKILL_MODULES[skill_name]     │
│  2. 查找 module.TOOLS[tool_name]       │
│  3. 执行 await tool_func(**arguments)  │
│  4. 返回结果                            │
└───────┬────────────────────────────────┘
        │
        ▼
┌────────────────┐
│ 发送 skill.result│
└───────┬────────┘
        │
        ▼
   [Server 处理]
        │
        ▼
┌────────────────┐
│ 接收 task.response│
└───────┬────────┘
        │
        ▼
   显示给用户

注意:两阶段 Skill 选择完全在 Server 端完成,Client 无需任何改动。当启用多个 Skill 时,Server 会先用轻量 LLM 调用筛选相关 Skill,再只加载选中 Skill 的工具定义,减少 token 消耗。


添加新 Skill

步骤 1:创建 Skill 代码

新建 roneia_core/builtin_skills/my_skill.py

"""我的 Skill 实现"""

from typing import Any, Dict

async def my_tool(param1: str, param2: int = 10) -> Dict[str, Any]:
    """
    我的工具

    Args:
        param1: 参数1
        param2: 参数2(可选)

    Returns:
        执行结果
    """
    try:
        # 实现你的逻辑
        result = f"处理了 {param1},数量 {param2}"

        return {
            "success": True,
            "message": result,
        }
    except Exception as e:
        return {
            "success": False,
            "error": str(e),
        }

# 工具映射(必需)
TOOLS = {
    "my_tool": my_tool,
}

步骤 2:注册到执行器

编辑 roneia_client/local_skill_executor.py

from roneia_core.builtin_skills import local_file, web_search, screen_capture, my_skill

SKILL_MODULES = {
    "local_file": local_file,
    "web_search": web_search,
    "screen_capture": screen_capture,
    "my_skill": my_skill,  # 添加这行
}

步骤 3:Server 端添加定义

在 Server 的 skill_registry/builtin_skills.py 中添加 Skill 定义(参数、描述等)。


命令行参数

roneia [命令] [选项]

命令:
  setup                 运行初始配置向导
  (无)                  启动交互模式

选项:
  --config, -c FILE     配置文件路径
  --server URL          服务器 WebSocket URL
  --token TOKEN         认证令牌
  --no-gui              禁用 GUI 弹窗
  --debug               调试模式

交互命令:
  /voice                切换到语音模式
  /text                 切回文字模式
  /skills ...           Skill 管理(enable 时自动检测依赖)
  /persona              人设管理
  /status               显示状态
  /help                 帮助

配置文件

server:
  url: "ws://localhost:8765/ws"   # 服务器地址
  token: ""                        # 认证令牌
  reconnect_interval: 5            # 重连间隔(秒)
  max_reconnect_attempts: -1       # 最大重连次数 (-1=无限)
  heartbeat_interval: 30           # 心跳间隔(秒)

permissions:
  auto_grant: []                   # 自动授权的权限
  use_gui: true                    # 使用GUI弹窗请求权限

数据存储

客户端数据存储位置:

  • ~/.roneia/config.yaml - 客户端配置(roneia setup 生成)
  • ~/.roneia/skills.json - 已安装 Skill 的状态

故障排除

无法连接服务器

  1. 检查服务器地址是否正确
  2. 检查网络是否通畅
  3. 检查认证令牌是否正确
  4. 使用 --debug 查看详细日志

Skill 不可用

  1. 检查是否已安装:/skills installed
  2. 检查是否已启用:/status
  3. 检查依赖是否安装(如 web_search 需要 requests)

工具执行失败

  1. 检查参数是否正确
  2. 检查权限是否已授予
  3. 查看日志中的错误信息

开发

从源码运行

cd roneia-client
pip install -e .
roneia setup                       # 初始配置
roneia --debug                     # 启动(调试模式)
python -m roneia_client             # 或通过 python -m 启动

运行测试

# 测试 Skill 模块导入
python -c "from roneia_core.builtin_skills import local_file; print(local_file.TOOLS)"

# 测试工具执行
python -c "
import asyncio
from roneia_core.builtin_skills import local_file
result = asyncio.run(local_file.search_files('*.py', '.', max_results=3))
print(result)
"

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

roneia-1.0.0.tar.gz (57.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

roneia-1.0.0-py3-none-any.whl (67.0 kB view details)

Uploaded Python 3

File details

Details for the file roneia-1.0.0.tar.gz.

File metadata

  • Download URL: roneia-1.0.0.tar.gz
  • Upload date:
  • Size: 57.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for roneia-1.0.0.tar.gz
Algorithm Hash digest
SHA256 cdf03e621bfceecca5a6c575c81acd3c7f5cfc06e2d0a285f14b1f9e0e7acb92
MD5 44fe86a7335d1320878417df457d7bc3
BLAKE2b-256 b6df179f33a6f6c2e7e3ca12d5e5e14ab8a24d540e8497771c71ef99315be19e

See more details on using hashes here.

File details

Details for the file roneia-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: roneia-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 67.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for roneia-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9316c27d16fb9cc653bd66270dc33d50cdd3c580379ee6da6e00e735f94e216b
MD5 622826eb794948f81a89268c7f99fc0e
BLAKE2b-256 ec3c1fd8fe8286b656da3c54b8e1586f0c524438f58f126d5123c6002d8424b1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page