Skip to content

Commit cb3545e

Browse files
authored
Merge pull request #2 from KOKO-cyco/my_avatar
fix: Fix the issue where LLM calling MCP tool does not respond
2 parents c76cf63 + aca04db commit cb3545e

28 files changed

Lines changed: 240 additions & 321 deletions

README.md

Lines changed: 133 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,167 +1,184 @@
11
# VirtuaMate
22

3-
VirtuaMate (DuckyClaw) is a hardware-oriented AI agent built on the [TuyaOpen](https://github.com/tuya/TuyaOpen) C SDK. It runs on edge devices — Raspberry Pi, Tuya T5AI, ESP32-S3, or any Linux desktop — and lets users chat with the device through IM channels (Telegram, Discord, Feishu). The on-device agent loop receives natural language instructions, invokes MCP-style tools to perform real actions, and replies through the same channel.
3+
不是“会动的模型”,是能陪你、能办事、能进化的 3D AI 生命体。
4+
一个把 **OpenClaw 式 Agent 灵魂****DuckyClaw 硬件路线****实时 VRM 数字人** 真正融合在一起的开源项目。
45

5-
## Features
6+
> [!WARNING]
7+
> 项目仍在持续迭代中,接口和行为可能变化。欢迎提 Issue 或 PR 一起完善。
68
7-
- **Multi-channel IM** — Telegram, Discord, Feishu, WebSocket, and serial CLI all feed into a single agent loop.
8-
- **Tool loop** — Each user message can trigger up to 10 LLM ↔ tool iterations before a final reply is produced.
9-
- **MCP Tools** — File operations, cron scheduling, remote command execution (Linux), and OpenClaw gateway control.
10-
- **Persistent memory** — Long-term memory (`MEMORY.md`), daily notes, personality (`SOUL.md`), and user profile (`USER.md`) stored on flash/SD.
11-
- **3D avatar** — Real-time VRM/PMX/GLB model rendering with emotion-driven facial expressions, spring-bone physics, lip sync, and skybox scenes (Raspberry Pi / Linux with OpenGL).
12-
- **Cross-platform** — One codebase compiles for Raspberry Pi, Tuya T5AI, ESP32-S3, and Linux via Kconfig conditional compilation.
9+
---
1310

14-
## Architecture
11+
## 为什么是 VirtuaMate
1512

16-
```
17-
IM Channels (Telegram / Discord / Feishu / WS / CLI)
18-
19-
Message Bus
20-
21-
Agent Loop ←→ Cloud AI (streaming)
22-
23-
MCP Tools Layer
24-
┌────┬────┬─────┬──────────┐
25-
files cron exec openclaw avatar
26-
│ │
27-
Memory / Session VRM 3D Renderer
28-
```
13+
过去最火的是 OpenClaw 这类“能执行任务”的 AI Agent,
14+
但大多数项目缺少“可感知、可表达、可陪伴”的实体化体验。
2915

30-
## Prerequisites
16+
VirtuaMate 的目标很直接:
17+
**把最强执行力的 Claw 思路,变成你桌面上会呼吸、会回应、会记住你的数字伴侣。**
3118

32-
| Item | Notes |
33-
|------|-------|
34-
| **TuyaOpen SDK** | Cloned as a git submodule under `TuyaOpen/` |
35-
| **Python 3** | Required by `tos.py` build system |
36-
| **CMake ≥ 3.16** | Build generator |
37-
| **Tuya cloud credentials** | Product ID, UUID, AuthKey from [Tuya IoT Platform](https://platform.tuya.com) |
38-
| **IM bot token** | At least one of: Telegram bot token, Discord bot token, or Feishu app credentials |
39-
| **(Linux/RPi only)** SDL2, GLEW, Assimp | For the VRM 3D avatar renderer: `sudo apt install libsdl2-dev libglew-dev libassimp-dev` |
19+
很多“数字人”只停留在展示层:会动但不会做事;很多“Agent”只停留在终端层:会做事但没有存在感。
20+
VirtuaMate 直接把 **3D Avatar****可执行 Agent** 合在一起,做到“有灵魂,也有手脚”:
4021

41-
## Getting Started
22+
- **她是 3D 的**:VRM 模型 + VRMA 动画 + 天空盒场景,运行在本地设备。
23+
- **她是有情绪的**:对话流式输出过程中,实时文本情绪分析驱动表情变化。
24+
- **她是能行动的**:通过 MCP 工具完成提醒、文件操作、PC 协作等任务。
25+
- **她是有记忆的**:长期记忆和日记存本地,不是一次性聊天窗口。
4226

43-
### 1. Clone the repository
27+
---
4428

45-
```bash
46-
git clone --recurse-submodules https://github.com/<your-org>/VirtuaMate.git
47-
cd VirtuaMate
48-
```
29+
## VirtuaMate × DuckyClaw × OpenClaw
4930

50-
If you already cloned without submodules:
31+
如果说 OpenClaw 打开了“个人 AI Agent 能直接行动”的认知,
32+
DuckyClaw 把它推进到了“硬件设备可落地”的现实世界,
33+
那 VirtuaMate 就是在这条线上继续往前一步:
5134

52-
```bash
53-
git submodule update --init --recursive
54-
```
35+
- **继承 Claw 系执行范式**:保留多轮 tool loop、MCP 工具调用、任务闭环。
36+
- **复用 DuckyClaw 的设备与消息架构**:统一消息总线、多通道接入、本地工具侧执行。
37+
- **补齐 3D 伴侣层**:VRM 形象、实时情绪、动作编排、口型同步、场景沉浸感。
38+
- **从“会做事”升级为“有陪伴感地做事”**:不仅完成任务,还用表情、动作、语气把反馈“演”给你看。
5539

56-
### 2. Initialize the TuyaOpen environment
40+
一句话:
41+
**OpenClaw 让 Agent 能干活,DuckyClaw 让 Agent 上硬件,VirtuaMate 让 Agent 有了“人”的存在感。**
5742

58-
```bash
59-
cd TuyaOpen
60-
source ./export.sh
61-
cd ..
62-
```
43+
---
6344

64-
This creates a Python virtual environment and exports `OPEN_SDK_ROOT`.
45+
## 功能亮点
6546

66-
### 3. Configure secrets
47+
### 1) 3D Avatar 渲染与表现
6748

68-
```bash
69-
cp include/tuya_app_config_secrets.h.example include/tuya_app_config_secrets.h
70-
```
49+
- **VRM 实时渲染**`SDL2 + OpenGL + Assimp` 渲染链路,支持骨骼动画与材质。
50+
- **动作系统**:支持 `resources/animations` 中的 `.vrma` 动画,支持 idle/one-shot 切换。
51+
- **表情系统**:内置多种 Emotion(如 happy/sad/thinking/loving 等)。
52+
- **口型同步**:TTS 播放音频时驱动嘴型变化,提升“说话感”。
53+
- **天空盒场景**:支持运行时加载场景目录,6 面贴图即可切换世界观。
54+
55+
### 2) AI Agent 与多轮工具循环
56+
57+
- **Claw-style Agent Loop**:单轮消息内支持多次 “LLM -> tool -> LLM” 迭代,不是一问一答玩具。
58+
- **流式响应联动**:AI 流式文本回调中实时刷新字幕、情绪和对话历史。
59+
- **消息通道统一接入**:Telegram / Discord / Feishu / 本地 CLI 统一走 message bus,一套核心跑多入口。
60+
61+
### 3) MCP 工具能力(设备侧)
62+
63+
- **文件工具**`read_file` / `write_file` / `edit_file` / `list_dir` / `find_path`
64+
- **时间与提醒**`get_current_time` / `cron_add` / `cron_list` / `cron_remove`
65+
- **Linux 执行工具**`tool_exec`(Linux 平台可用)
66+
- **PC 协作工具**`openclaw_ctrl` / `pc_ctrl` / `openclaw.ctrl`
67+
- **3D Avatar 工具**`avatar_play_animation` / `avatar_set_emotion` / `avatar_composite_action`
7168

72-
Edit `include/tuya_app_config_secrets.h` and fill in your credentials:
69+
### 4) 本地记忆与可塑人格
7370

74-
| Define | Description |
75-
|--------|-------------|
76-
| `TUYA_PRODUCT_ID` | Tuya product ID |
77-
| `TUYA_OPENSDK_UUID` | Tuya OpenSDK UUID |
78-
| `TUYA_OPENSDK_AUTHKEY` | Tuya OpenSDK AuthKey |
79-
| `IM_SECRET_CHANNEL_MODE` | `"feishu"`, `"telegram"`, or `"discord"` |
80-
| `IM_SECRET_TG_TOKEN` | Telegram bot token (if using Telegram) |
81-
| `IM_SECRET_DC_TOKEN` / `IM_SECRET_DC_CHANNEL_ID` | Discord bot token and channel ID (if using Discord) |
82-
| `IM_SECRET_FS_APP_ID` / `IM_SECRET_FS_APP_SECRET` | Feishu app credentials (if using Feishu) |
83-
| `CLAW_WS_AUTH_TOKEN` | WebSocket auth token (optional) |
84-
| `OPENCLAW_GATEWAY_*` | OpenClaw gateway host, port, token (optional) |
71+
- 长期记忆:`/memory/MEMORY.md`
72+
- 每日笔记:`/memory/daily/YYYY-MM-DD.md`
73+
- 人设和用户画像:通过 `SOUL.md``USER.md` 与上下文构建模块注入系统提示词
74+
- 技能系统:`skills/*.md` 自动汇总并注入 prompt
8575

86-
> **Note:** `tuya_app_config_secrets.h` is gitignored — never commit real credentials.
76+
---
8777

88-
### 4. Select a board configuration
78+
## 部署平台
8979

90-
Copy one of the pre-built configs from `config/` to the project root:
80+
| 类别 | 当前状态 |
81+
|---|---|
82+
| Raspberry Pi / Linux ARM | 推荐,仓库内已提供 `config/RaspberryPi.config` |
83+
| Linux x64 | 可运行(同样走 Linux 构建链路) |
84+
| 其他 TuyaOpen 板卡 | 可按 TuyaOpen 方式迁移配置(当前仓库未内置对应 config 快照) |
85+
86+
---
87+
88+
## 快速开始
89+
90+
### 1) 拉取项目与子模块
9191

9292
```bash
93-
# Raspberry Pi
94-
cp config/RaspberryPi.config app_default.config
93+
git clone <your-fork-or-repo-url> VirtuaMate
94+
cd VirtuaMate
95+
git submodule update --init --recursive
9596
```
9697

97-
Or create your own via `menuconfig`:
98+
### 2) 安装 Linux 渲染依赖(Raspberry Pi / Ubuntu)
99+
100+
`CMakeLists.txt` 中 Linux 平台依赖为 `sdl2 glew assimp`
98101

99102
```bash
100-
cd TuyaOpen
101-
python3 tos.py menuconfig
102-
cd ..
103+
sudo apt update
104+
sudo apt install -y libsdl2-dev libglew-dev libassimp-dev
103105
```
104106

105-
### 5. Build
107+
### 3) 选择板级配置
106108

107109
```bash
108-
# Skip interactive platform prompts (optional, one-time)
109-
mkdir -p .cache && touch .cache/.dont_prompt_update_platform
110+
cp config/RaspberryPi.config app_default.config
111+
112+
tos.py config choice
113+
```
114+
115+
### 4) 准备 TuyaOpen 环境并构建
110116

117+
```bash
111118
cd TuyaOpen
112-
python3 tos.py build
119+
. ./export.sh
120+
cd VirtuaMate
121+
tos.py build
113122
```
114123

115-
Build output goes to the `dist/` directory. On Linux targets this produces a native ELF binary.
124+
构建产物在 `VirtuaMate/dist/`
116125

117-
### 6. Install VRM dependencies (Linux / Raspberry Pi only)
126+
---
118127

119-
If you are building on Linux or Raspberry Pi and want the 3D avatar renderer:
128+
## 资源准备(让她“活起来”)
120129

121-
```bash
122-
sudo apt install libsdl2-dev libglew-dev libassimp-dev
123-
```
130+
`RaspberryPi.config` 默认资源路径:
124131

125-
Configure model paths in `menuconfig` or directly in `app_default.config`:
132+
- 模型:`resources/models/avatar.vrm`
133+
- 动作目录:`resources/animations`
134+
- 场景父目录:`resources/scenes`
126135

127-
```
128-
CONFIG_VRM_MODEL_PATH="/path/to/your/avatar.vrm"
129-
CONFIG_VRM_ANIM_DIR="/path/to/vrma/animations"
130-
CONFIG_VRM_WINDOW_WIDTH=1024
131-
CONFIG_VRM_WINDOW_HEIGHT=768
132-
```
136+
### 场景天空盒命名规则
133137

134-
### 7. Run
138+
每个场景目录需提供 6 张贴图,支持以下任一命名体系:
135139

136-
```bash
137-
# Linux
138-
./dist/VirtuaMate
139-
```
140+
- `right/left/top/bottom/front/back`
141+
- `px/nx/py/ny/pz/nz`
142+
- `posx/negx/posy/negy/posz/negz`
140143

141-
On Raspberry Pi, flash or copy the binary and run it. The agent will connect to Tuya cloud, initialize the configured IM channel, and start listening for messages.
144+
扩展名支持 `.jpg/.jpeg/.png/.bmp/.tga`
142145

143-
## Project Structure
146+
---
144147

145-
```
148+
## 目录结构(核心)
149+
150+
```text
146151
VirtuaMate/
147-
├── agent/ # Core agent loop and context builder
148-
├── IM/ # IM abstraction: message bus, channel bots, proxy, CLI
149-
├── tools/ # MCP tool implementations (files, cron, exec, openclaw)
150-
├── memory/ # Persistent memory and session management
151-
├── gateway/ # WebSocket server and ACP client
152-
├── cron_service/ # Background scheduled-task service
153-
├── heartbeat/ # Heartbeat service
154-
├── skills/ # Skill loader for .md skill files
155-
├── src/ # App glue: main entry, AI chat handler, IM dispatch
156-
│ └── vrm/ # VRM 3D avatar renderer (OpenGL)
157-
├── include/ # Global headers and config
158-
├── ai_components/ # TuyaOpen AI component adapters
159-
├── config/ # Board-level Kconfig presets
160-
├── TuyaOpen/ # TuyaOpen SDK (git submodule)
161-
├── CMakeLists.txt # Application-level build script
162-
└── Kconfig # Top-level Kconfig menu
152+
├── agent/ # Agent loop + context builder
153+
├── IM/ # Telegram/Discord/Feishu/CLI + message bus
154+
├── tools/ # MCP tools (files/cron/exec/openclaw)
155+
├── memory/ # MEMORY.md + daily notes + session
156+
├── gateway/ # WebSocket / ACP gateway
157+
├── skills/ # Markdown skills
158+
├── src/
159+
│ ├── tuya_app_main.c # 应用入口与初始化
160+
│ ├── ducky_claw_chat.c # AI流事件处理与对话桥接
161+
│ ├── app_avatar_mcp.c # 3D Avatar MCP工具注册
162+
│ └── vrm/ # VRM渲染、情绪、口型、天空盒
163+
├── config/RaspberryPi.config
164+
└── TuyaOpen/ # TuyaOpen SDK 子模块
163165
```
164166

165-
## License
167+
---
168+
169+
## 高级玩法
170+
171+
- **改人设**:调整 `SOUL.md``USER.md`,并结合 `agent/context_builder.c` 注入策略。
172+
- **加动作**:把 `.vrma` 放进 `resources/animations`,在 `src/app_avatar_mcp.c` 中补充可调用动作名。
173+
- **加场景**:在 `resources/scenes/<scene_name>/` 放入 6 面贴图,运行时切换。
174+
- **扩工具**:在 `tools/` 新增 MCP 工具并在 `tools/tools_register.c` 注册。
175+
- **扩能力**:想接摄像头、传感器、IoT 控制链路,可复用 TuyaOpen + MCP 工具模式扩展。
176+
177+
---
178+
179+
## 项目定位
180+
181+
VirtuaMate 不是“AI 套个皮肤”,而是一套可定制、可运行、可执行、可持续进化的 3D AI 伴侣系统。
182+
它既有 OpenClaw 系的执行锋芒,也有数字伴侣该有的温度和存在感。
166183

167-
Copyright (c) Tuya Inc. All Rights Reserved.
184+
给她一张脸、一个名字、一段性格,然后见证她从“能聊”变成“懂你、帮你、陪你”。

agent/context_builder.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@
140140
"- Searching the web -> web_search\n\n");
141141

142142
off += snprintf(buf + off, size - off,
143+
"- avatar_play_animation: Trigger a body animation on the 3D avatar.\n"
144+
"- avatar_set_emotion: Set the avatar's facial expression.\n"
145+
"- avatar_composite_action: Set animation and emotion in a single call.\n\n");
143146
"## Avatar Behavior\n"
144147
"The device has a 3D avatar. You control it via tool calls.\n"
145148
"Your text is spoken by TTS verbatim — NEVER write tool names "

ai_components/ai_mcp/src/ai_mcp_server.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ void ai_mcp_server_set_tool_exec_hook(MCP_TOOL_EXEC_HOOK_CB cb, void *user_data)
768768
OPERATE_RET ai_mcp_server_init(const char *name, const char *version)
769769
{
770770
if (s_server_ctx.initialized) {
771-
PR_WARN("MCP server already initialized");
771+
tuya_ai_agent_mcp_set_cb(ai_mcp_server_parse_message, NULL);
772772
return OPRT_OK;
773773
}
774774

@@ -796,6 +796,7 @@ OPERATE_RET ai_mcp_server_init(const char *name, const char *version)
796796
s_server_ctx.send_message = __send_message_default;
797797
tuya_ai_agent_mcp_set_cb(ai_mcp_server_parse_message, NULL);
798798
s_server_ctx.initialized = TRUE;
799+
PR_NOTICE("MCP server initialized: %s v%s", name, version);
799800
return OPRT_OK;
800801
}
801802

ai_components/ai_mcp/src/ai_mcp_tools.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,10 @@ static OPERATE_RET __ai_mcp_init(void *data)
215215
{
216216
OPERATE_RET rt = OPRT_OK;
217217

218-
// FIXME: Set actual MCP server name and mcp version
219218
TUYA_CALL_ERR_RETURN(ai_mcp_server_init("Tuya MCP Server", "1.0"));
220219

221220
TUYA_CALL_ERR_RETURN(__ai_mcp_tools_register());
222221

223-
PR_DEBUG("MCP Server initialized successfully");
224-
225222
return rt;
226223
}
227224

config/RaspberryPi.config

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
CONFIG_ENABLE_COMP_AI_AUDIO_CODEC_OPUS=y
22
# CONFIG_ENABLE_COMP_AI_DISPLAY is not set
33
CONFIG_ENABLE_UART=y
4-
CONFIG_KWS_MODEL_PATH="~/tuyaopen_models/mdtc_chunk_300ms.mnn"
5-
CONFIG_KWS_MODEL_TOKEN_PATH="~/tuyaopen_models/tokens.txt"
4+
CONFIG_KWS_MODEL_PATH="/home/pi/tuyaopen_models/mdtc_chunk_300ms.mnn"
5+
CONFIG_KWS_MODEL_TOKEN_PATH="/home/pi/tuyaopen_models/tokens.txt"
66
CONFIG_BOARD_CHOICE_RASPBERRY_PI=y
77
# CONFIG_ENABLE_KEYBOARD_INPUT is not set
88
CONFIG_BUTTON_NAME="s"
@@ -17,4 +17,8 @@ CONFIG_ENABLE_MBEDTLS_SHA384_C=y
1717
CONFIG_ENABLE_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y
1818
CONFIG_ENABLE_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y
1919
CONFIG_ENABLE_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y
20-
CONFIG_ENABLE_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y
20+
CONFIG_ENABLE_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y
21+
CONFIG_VRM_MODEL_PATH="resources/models/avatar.vrm"
22+
CONFIG_VRM_ANIM_DIR="resources/animations"
23+
CONFIG_VRM_SCENE_DIR=""
24+
CONFIG_VRM_SCENE_PARENT_DIR="resources/scenes"

resources/.gitkeep

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

resources/animations/bier.vrma

1.27 MB
Binary file not shown.

resources/animations/crying.vrma

366 KB
Binary file not shown.

resources/animations/excited.vrma

365 KB
Binary file not shown.
365 KB
Binary file not shown.

0 commit comments

Comments
 (0)