01. 設計摘要
核心決策只有一個:不要把 Hermes Agent 魔改成 JARVIS;要把 JARVIS 做成 Hermes Agent 外層的 Voice / Presence Shell。
JARVIS
Hear · Speak · Display · Interrupt · Route · Presence
Hermes
Understand · Think · Remember · Plan · Execute
設計原則:整個系統永遠只保留一個真正的 Agent Brain。JARVIS Runtime 不再跑第二個 LLM、不維護第二份記憶、不做第二層規劃。
02. 目標與非目標
目標
- 本機常駐,可用「Hey Jarvis」喚醒。
- 中文 / 英文自然對話,支援 streaming STT 與 TTS。
- Hermes 執行 tool 時,HUD 即時顯示目前正在做什麼。
- 支援 barge-in:JARVIS 說話時可被使用者直接打斷。
- Hermes 的 approval / clarification 能以 UI 與語音完成。
- STT / VAD / Wake Word 預設完全在本機運行。
- Desktop UI 與 Voice Runtime 都可獨立替換,不綁死 Hermes internals。
- 未來可以延伸到 screen context、Home Assistant、multi-room satellite、speaker verification。
非目標
- 不重新實作 Hermes 的 memory、skills、tool system 或 MCP。
- 不額外加入 LangGraph / CrewAI / AutoGen。
- MVP 不做全天候錄音保存。
- MVP 不把 speaker verification 假裝成已完成的強驗證。
- 不直接複製 Marvel / Iron Man 的版權 UI 或音效素材。
03. 系統架構
┌─────────────────────────────┐
│ JARVIS Desktop │
│ Tauri + React + TypeScript │
│ │
│ Orb / HUD / Transcript │
│ Tool Activity │
│ Approval / Clarification │
└──────────────┬──────────────┘
│
Local WebSocket
│
┌──────────────▼──────────────┐
Microphone ───────►│ JARVIS Voice Runtime │──────► Speaker
│ Python asyncio │
│ │
│ Wake Word · VAD · STT │
│ TTS · Barge-in · FSM │
│ HermesAdapter · Event Router│
└──────────────┬──────────────┘
│
JSON-RPC/WS or HTTP/SSE
│
┌──────────────▼──────────────┐
│ Hermes Agent │
│ │
│ LLM · Memory · Skills │
│ MCP · Browser · Shell │
│ Tools · Cron · Subagents │
└─────────────────────────────┘
JARVIS Runtime 應被視為 I/O runtime + presentation layer,而不是 agent framework。這個邊界讓未來 Hermes protocol、STT、TTS 或桌面 UI 任一部分都能被單獨替換。
04. 元件責任
| 元件 | 責任 | 不得負責 |
| JARVIS Desktop | HUD、動畫、事件視覺化、Allow/Deny、文字輸入、設定 | Agent 推理、Memory、直接執行 tool |
| Voice Runtime | Mic、Wake Word、VAD、STT、TTS、Barge-in、Session FSM | 業務規劃、工具選擇 |
| HermesAdapter | 把 Hermes raw protocol 轉成 typed event | 把 Hermes 行為重新解釋成另一套 Agent |
| Hermes Agent | 理解、推理、記憶、規劃、Tools、Skills、MCP | JARVIS UI rendering |
05. Voice Pipeline
Microphone
│
▼
AudioProcessor
│
├── optional AEC
├── Noise Suppression
└── AGC
│
▼
openWakeWord ── "Hey Jarvis"
│
▼
Silero VAD
│
▼
faster-whisper
│
▼
Transcript
│
▼
HermesAdapter.submit_prompt()
│
▼
message.delta
│
▼
Sentence Chunker
│
▼
TTS Provider
│
▼
Speaker
Wake Word
Idle 狀態只跑本機 Wake Word,不把房間聲音送入 Hermes 或外部 API。喚醒詞預設 hey jarvis,但必須可配置。
VAD
使用 Silero VAD 判斷 utterance 結束。預設先從約 600–900ms 的 min silence tuning,避免自然停頓被切成多句。
STT
faster-whisper model 需在 runtime 啟動時 warm,不能每次喚醒重新載入。預設 local model,並保留 provider interface。
TTS
預設 Piper 走 local;另外提供 ElevenLabs adapter。TTS 接收的是「語意 chunk / sentence」,不是每個 LLM token,否則會造成卡頓與不自然 prosody。
Barge-in
使用者一旦在 SPEAKING 狀態開始講話,系統立即:停止播放 → 清掉 TTS queue → Hermes session.interrupt → 回 LISTENING。這是 JARVIS 感最重要的互動之一。
06. Session State Machine
IDLE
│ wake word
▼
WAKE_ACK
│
▼
LISTENING
│ utterance end
▼
TRANSCRIBING
│ transcript
▼
THINKING
│ tool event │ text stream
▼ ▼
ACTING SPEAKING
│ │
├──── approval ─────► WAITING_APPROVAL
├──── clarify ──────► WAITING_CLARIFICATION
│ │
└──────── result ─────────┘
SPEAKING + user speech
└──► INTERRUPTED ───► LISTENING
inactivity timeout
└──► IDLE
狀態轉移必須集中在 runtime state machine,不可散落在 React component、STT callback 或 Hermes event handler 裡。
07. Hermes Agent 整合
JARVIS 不應直接 import Hermes internals。應透過 Hermes 目前官方可用的 programmatic interface,優先使用 JSON-RPC / WebSocket Gateway;如果實際版本不適合,再 fallback 到 HTTP/SSE。
Adapter Interface
HermesAdapter
├── connect()
├── create_session()
├── submit_prompt()
├── interrupt()
├── steer()
├── send_approval()
├── send_clarification()
├── attach_image()
└── get_history()
Typed Events
Runtime 與 UI 僅接受 typed internal events,不直接處理 Hermes raw JSON。
MessageDelta
MessageComplete
ToolStart
ToolProgress
ToolComplete
ApprovalRequest
ClarifyRequest
SessionStatus
ErrorEvent
版本注意:One-Shot Prompt 會要求 Codex 在真正寫 integration 前先 inspect 當前 Hermes Agent source / docs,確認 method / event / endpoint 名稱。不要把 2026-08-15 的介面名稱永久 hard-code 成假定事實。
事件映射
| Hermes 事件 | JARVIS 行為 |
message.delta | 更新 transcript,送入 sentence chunker |
message.complete | 完成回覆,更新 conversation state |
tool.start | HUD 顯示工具名稱與執行狀態 |
tool.progress | HUD 即時更新 progress / summary |
tool.complete | 顯示完成狀態與結果摘要 |
approval.request | 進入 WAITING_APPROVAL,顯示 Allow / Deny |
clarify.request | 進入 WAITING_CLARIFICATION,可用 voice 回答 |
08. JARVIS HUD / UX
Core / Orb
以動畫呈現 IDLE、LISTENING、THINKING、ACTING、SPEAKING。
Transcript
即時顯示使用者 transcript 與 Hermes streaming response。
Tool Rail
顯示目前正在查資料、讀檔、呼叫 MCP、執行 Shell 等。
Approval
顯示高風險 action、參數摘要、Allow / Deny。
UX 原則
- 喚醒後應在 300ms 等級內提供本機 visual / audio acknowledgement,不需要等 LLM。
- 「我查一下」、「正在讀取」這類 feedback 應由 tool state 驅動,而不是讓另一個 LLM猜。
- Hermes 還在執行時即可透過 tool events 呈現 progress。
- 任何時候都要有明確 STOP / Interrupt。
- HUD 必須可縮成 always-on-top companion window。
09. 安全與隱私模型
- Local runtime 只 bind
127.0.0.1。
- Idle audio 不落盤、不送 cloud。
- Screen capture 必須由明確指令或 UI action 觸發。
- 所有 API token 放
.env / OS keychain,不進 repo。
- Log 需 redact secret / token。
- 高風險 action 的 Allow / Deny 以 Hermes approval event 為 source of truth。
- Speaker Verification 做成 interface,但 MVP 不把它當作真正 authentication。
Wake Word 不是身份驗證。未來若 JARVIS 能寄信、控制 Home Assistant、刪檔或執行 shell,應再加入 Speaker Verification / device presence / OS authentication。
10. 建議技術棧
| Layer | 建議 | 備註 |
| Desktop | Tauri 2 + React + TypeScript | macOS 優先,較 Electron 輕量 |
| UI State | Zustand | 同步 runtime event 與 HUD |
| Voice Runtime | Python 3.12 + asyncio + FastAPI | 本機 service / WS bridge |
| Wake Word | openWakeWord | 預設 local |
| VAD | Silero VAD | local |
| STT | faster-whisper | local model warm |
| TTS | Piper / ElevenLabs | provider interface |
| Agent | Hermes Agent | 唯一 Brain |
| Transport | JSON-RPC/WS,HTTP/SSE fallback | 以 Hermes 實際版本為準 |
| Python package | uv | 快速、可鎖版 |
| Node package | pnpm | desktop workspace |
11. Repo 結構
jarvis-hermes/
├── apps/
│ └── desktop/
│ ├── src/
│ │ ├── components/
│ │ ├── hud/
│ │ ├── approvals/
│ │ ├── stores/
│ │ └── lib/
│ └── src-tauri/
│
├── services/
│ └── voice/
│ ├── jarvis_voice/
│ │ ├── audio/
│ │ ├── wake/
│ │ ├── vad/
│ │ ├── stt/
│ │ ├── tts/
│ │ ├── state_machine/
│ │ ├── hermes/
│ │ ├── api/
│ │ └── config/
│ └── tests/
│
├── plugins/
│ └── hud_display/
├── config/
│ └── jarvis.example.yaml
├── docs/
├── scripts/
├── .env.example
├── Makefile
└── README.md
12. Config 範例
jarvis:
wake_word: "hey jarvis"
session_timeout_sec: 45
audio:
input_device: null
sample_rate: 16000
vad:
provider: silero
threshold: 0.5
min_silence_ms: 700
stt:
provider: faster_whisper
model: small
language: auto
device: auto
tts:
provider: piper
voice: null
hermes:
url: "http://127.0.0.1:8642"
transport: auto
security:
bind_host: "127.0.0.1"
persist_audio: false
transcript_logging: minimal
13. MVP Scope 與驗收標準
- 可啟動 Hermes Agent 與 JARVIS Desktop。
- 「Hey Jarvis」成功喚醒。
- 可說中文或英文。
- faster-whisper 本機完成 STT。
- Transcript 送入 Hermes 的既有 session。
- Hermes streaming 回覆在 HUD 即時出現。
- 答案尚未完全產生前,TTS 就開始說話。
- Tool calls 即時出現在 HUD。
- Approval request 顯示 Allow / Deny。
- 說話途中可被使用者打斷。
- Barge-in 會 stop TTS 並 interrupt Hermes。
- Session timeout 後回 Wake Word idle。
- 可明確觸發 screen capture 並送 Hermes。
- Hermes 斷線時 UI 不 crash,清楚顯示 disconnected。
- 核心 unit tests 通過。
14. 建議開發階段
| Phase | 內容 | Done Definition |
| 0 | Inspect Hermes 現行 API / Gateway | 確認可用 endpoint / events |
| 1 | Runtime skeleton + fake Hermes | State machine / WS / HUD demo 跑通 |
| 2 | Hermes real adapter | prompt / stream / interrupt / approval 通 |
| 3 | Wake + VAD + STT | 本機語音輸入可用 |
| 4 | TTS + barge-in | 可 streaming speak,並能即時打斷 |
| 5 | HUD refinement | Tool / Approval / Clarification 完整呈現 |
| 6 | Screen context + packaging | 可日常啟動使用 |
| 7 | Speaker verification / ambient extensions | 後續版本 |
15. Codex Agent One-Shot Prompt
下面這段可以直接貼給 Codex Agent。它的目標不是請 Codex「規劃」,而是要求它直接 scaffold、實作、測試、修正,直到產出可執行 MVP。
建議在一個新的空 repo 或你準備好的 jarvis-hermes repo 根目錄執行。
你是一名資深 AI Agent / Voice Assistant / Desktop App 工程師。請在目前工作目錄中,直接建立一個可執行的專案:
專案名稱:jarvis-hermes
目標:打造一個「JARVIS Voice + HUD Shell」,把 Hermes Agent 當成唯一 Brain / Memory / Tool Executor;JARVIS 只負責 Hear / Speak / Display / Interrupt / Route / Presence。
# 0. 核心原則(不可違反)
1. 不要建立第二個 Agent Brain。
2. 不要在 JARVIS layer 再加入 LangGraph、AutoGen、CrewAI 或其他 LLM orchestration。
3. Hermes Agent 是唯一負責:
- 理解
- 推理
- 記憶
- 規劃
- Tool Calling
- Skills
- MCP
- Shell / Browser / API actions
4. JARVIS layer 只負責:
- Wake word
- Mic / audio pipeline
- VAD
- STT
- TTS
- Barge-in
- Session state machine
- HUD
- Approval / Clarification UI
- Screen context / attachments
- Hermes transport adapter
5. 優先採用 Hermes 官方目前提供的 programmatic interface。
6. 在寫 integration code 前,先閱讀目前安裝版本或官方 repo 的 Hermes Agent source / docs,確認:
- serve command
- host / port
- HTTP / SSE API
- JSON-RPC / WebSocket Gateway
- prompt.submit
- session.create
- session.history
- session.interrupt
- session.steer
- approval.respond
- clarify.respond
- image.attach
- message.delta
- message.complete
- tool.start / tool.progress / tool.complete
- approval.request / clarify.request
若實際名稱或 transport 已改版,以目前 Hermes source code 為準,並在 README 記錄差異。
7. 不要修改 Hermes Agent core source。JARVIS 必須是可替換、可獨立啟停的外層 runtime。
8. 預設 Local-first:
- STT:faster-whisper
- VAD:Silero VAD
- Wake Word:openWakeWord
- TTS:Piper(預設)/ ElevenLabs(optional provider)
9. macOS 為第一優先支援平台;架構不可故意綁死 macOS。
10. 所有危險 / irreversible action 必須由 Hermes approval event 驅動 UI confirmation,不可由 JARVIS 自行猜測。
# 1. 技術棧
Desktop:
- Tauri 2
- React
- TypeScript
- Vite
- Zustand(UI state)
- WebSocket client
Voice Runtime:
- Python 3.12+
- asyncio
- FastAPI(只作為 local runtime API / WebSocket bridge)
- pydantic-settings
- sounddevice 或等價、穩定的跨平台 microphone capture
- numpy
- openWakeWord
- Silero VAD
- faster-whisper
- Piper 作為預設 local TTS adapter
- ElevenLabs adapter 作為 optional provider
Hermes Adapter:
- 優先 JSON-RPC / WebSocket Gateway
- 若目前 Hermes 版本的 Gateway 不適合,實作 HTTP/SSE fallback
- transport 必須被抽象成 interface,讓未來可換 Hermes protocol 而不影響 Voice / HUD
Packaging:
- Python 使用 uv
- Node 使用 pnpm
- Makefile 或 justfile 提供一鍵開發指令
# 2. Repo 結構
請建立:
jarvis-hermes/
apps/
desktop/
src/
components/
hud/
approvals/
stores/
lib/
src-tauri/
services/
voice/
jarvis_voice/
audio/
wake/
vad/
stt/
tts/
state_machine/
hermes/
api/
config/
tests/
pyproject.toml
plugins/
hud_display/
config/
jarvis.example.yaml
scripts/
docs/
architecture.md
hermes-integration.md
security.md
troubleshooting.md
.env.example
Makefile
README.md
# 3. Runtime Architecture
資料流:
Microphone
→ Audio preprocessing
→ Wake word ("hey jarvis")
→ LISTENING
→ Silero VAD
→ faster-whisper
→ transcript
→ HermesAdapter.prompt_submit()
→ Hermes streaming events
→ HUD event router
→ sentence chunker
→ TTS
→ Speaker
同時:
- tool.start / progress / complete → HUD
- approval.request → Approval Card
- clarify.request → Clarification Card
- message.delta → streaming text + TTS chunker
- user barge-in → stop TTS immediately + session.interrupt()
- image.attach / screen context → Hermes attachment flow
# 4. State Machine
至少實作:
IDLE
WAKE_ACK
LISTENING
TRANSCRIBING
THINKING
ACTING
SPEAKING
WAITING_APPROVAL
WAITING_CLARIFICATION
INTERRUPTED
ERROR
合法轉移請集中定義,不要散落在 UI code。
需求:
- IDLE 偵測 wake word
- 喚醒後播放極短 acknowledgement sound 或 visual pulse
- LISTENING 使用 VAD 結束 utterance
- THINKING 顯示 Hermes processing state
- ACTING 顯示目前 tool
- SPEAKING 時仍持續監聽 barge-in
- 偵測使用者插話後:
1. 立即停止 speaker
2. 清除未播放的 TTS queue
3. 呼叫 Hermes session.interrupt
4. 轉回 LISTENING
- session inactivity timeout 後回 IDLE
# 5. Audio / Voice 要求
Wake word:
- provider interface
- default: openWakeWord
- phrase configurable,預設 "hey jarvis"
- 不把 idle room audio 傳給 Hermes 或 cloud
VAD:
- Silero
- threshold / min_speech / min_silence 可配置
STT:
- faster-whisper
- model configurable
- default 建議 small 或 distil model(依目前套件實際支援)
- language = auto,並可指定 zh / en
- model 需 warm / persistent,不要每次 utterance reload
TTS:
- provider interface
- Piper default local
- ElevenLabs optional
- 支援 stop()
- 支援 sentence / phrase chunking
- Hermes message.delta 不要每個 token 都呼叫一次 TTS
- 累積到標點 /合理 chunk 後送 TTS
- TTS queue 可因 barge-in 立即 cancel
AEC:
- 先實作 AudioProcessor interface
- MVP 可使用 OS/WebRTC 可得的 echo cancellation 能力
- 若 Python native AEC 在目標平台不穩定,保留 feature flag 並在 docs 說明
- 不要因 AEC 阻塞整個 MVP
# 6. HermesAdapter
建立抽象介面,例如:
class HermesAdapter(Protocol):
async def connect(...)
async def create_session(...)
async def submit_prompt(...)
async def interrupt(...)
async def steer(...)
async def send_approval(...)
async def send_clarification(...)
async def attach_image(...)
async def get_history(...)
建立 typed event model:
MessageDelta
MessageComplete
ToolStart
ToolProgress
ToolComplete
ApprovalRequest
ClarifyRequest
ErrorEvent
SessionStatus
Voice runtime 與 UI 不得直接依賴 Hermes raw JSON。
請實作:
- gateway_jsonrpc.py
- http_sse.py(fallback)
- adapter_factory.py
並根據實際 Hermes source/docs 實作真正可用的 endpoint / method,不要憑空假設。
# 7. Local Runtime API
Python FastAPI 只綁:
127.0.0.1
至少提供:
- GET /health
- GET /state
- POST /wake
- POST /interrupt
- POST /text
- POST /approval/{id}
- POST /clarification/{id}
- POST /screen
- WS /events
/events 對 Desktop 推:
- state.changed
- transcript.partial
- transcript.final
- assistant.delta
- assistant.complete
- tool.started
- tool.progress
- tool.completed
- approval.requested
- clarification.requested
- audio.level
- error
# 8. Desktop HUD
做一個乾淨的 sci-fi HUD,但不要直接複製 Marvel / Iron Man copyrighted assets。
畫面至少包含:
1. 中央 Orb / Core
- IDLE
- LISTENING
- THINKING
- SPEAKING
不同動畫狀態
2. Transcript Panel
- user transcript
- assistant streaming response
3. Tool Activity Rail
- tool name
- status
- elapsed time
- result summary
4. Approval Card
- 顯示 action
- arguments summary
- Allow
- Deny
5. Clarification Card
- 顯示 Hermes clarification request
- 可 voice reply 或 text reply
6. Connection Indicators
- Voice runtime
- Hermes Agent
- Mic
- STT
- TTS
7. STOP / Interrupt button
8. Settings drawer
- wake word
- STT model
- TTS provider
- Hermes URL
- microphone
- language
- session timeout
UI 必須可在 1440px desktop 正常使用,也要能縮成小型 always-on-top companion window。
# 9. Screen Context
實作明確觸發的 screen capture:
- 不要背景連續截圖
- 使用者說「看一下我的螢幕」或按 UI button 時才 capture
- 透過 Hermes image attachment API 傳送
- capture 前顯示短暫 visual indicator
- 未來可擴充 active-window only
# 10. Security
預設:
- local API bind 127.0.0.1
- 不接受 LAN connection
- secrets 只進 .env / OS keychain,禁止寫進 repo
- sensitive action 由 Hermes approval 事件決定
- idle microphone audio 不落盤
- transcript logging configurable,預設 minimal
- screen capture 明確觸發
- error log redact tokens / secrets
另外建立 SpeakerVerifier interface,但 MVP 先提供:
- disabled provider
- future adapter stub
不可假裝已完成真正 voice authentication。
# 11. Config
建立 config/jarvis.example.yaml:
jarvis:
wake_word: "hey jarvis"
session_timeout_sec: 45
audio:
input_device: null
sample_rate: 16000
vad:
provider: silero
threshold: 0.5
min_silence_ms: 700
stt:
provider: faster_whisper
model: small
language: auto
device: auto
tts:
provider: piper
voice: null
hermes:
url: "http://127.0.0.1:8642"
transport: auto
security:
bind_host: "127.0.0.1"
persist_audio: false
transcript_logging: minimal
# 12. Developer Experience
請提供:
make setup
make dev
make voice
make desktop
make test
make lint
make doctor
make doctor 要檢查:
- Python
- uv
- Node
- pnpm
- Rust
- Tauri prerequisites
- microphone permission
- Hermes 是否 reachable
- STT dependencies
- TTS dependencies
README 必須有:
- Architecture
- Prerequisites
- Hermes setup
- Voice model setup
- First run
- Troubleshooting
- macOS microphone permission
- How to switch STT/TTS provider
- How to use text mode when microphone unavailable
# 13. 測試
至少建立 unit tests:
- state machine transitions
- TTS sentence chunker
- barge-in cancellation
- Hermes raw event → typed event mapping
- config loading
- approval routing
建立 fake Hermes server / adapter,讓測試與 Desktop demo 不需要真的呼叫 LLM。
另外做:
make demo
demo mode 可模擬:
wake
→ transcript
→ thinking
→ tool.start
→ tool.complete
→ streaming response
→ approval request
→ speaking
方便檢查 HUD。
# 14. MVP Acceptance Criteria
完成後我必須能:
1. 啟動 Hermes Agent。
2. 執行 make dev。
3. 看到 Tauri HUD。
4. 說 "Hey Jarvis" 喚醒。
5. 說中文或英文問題。
6. local faster-whisper 產生 transcript。
7. transcript 送入既有 Hermes session。
8. Hermes streaming 回覆即時顯示。
9. TTS 在完整答案結束前就開始說。
10. Hermes tool calls 即時顯示在 HUD。
11. approval.request 出現可操作的 Allow / Deny。
12. Jarvis 說話途中,我講話可立即 stop TTS 並 interrupt Hermes。
13. session timeout 後回到 IDLE / wake-word mode。
14. 可以按按鈕 capture screen 並送給 Hermes。
15. 沒有 Hermes 時,UI 明確顯示 disconnected,不 crash。
16. 所有核心單元測試通過。
# 15. 實作策略
請不要只輸出計畫。直接建立檔案並實作。
工作順序:
A. Inspect 現有 repo / Hermes integration
B. Scaffold monorepo
C. Build Python runtime + fake adapter
D. Build Hermes real adapter
E. Build Tauri HUD
F. Wire WebSocket events
G. Implement STT/VAD/Wake/TTS adapters
H. Implement barge-in
I. Implement approvals/clarification
J. Tests
K. Docs
L. Run formatter/linter/tests/build
M. 修正直到可執行
如果外部 binary/model 在此環境不能下載:
- 仍完成 adapter、setup script、清楚錯誤訊息與 docs
- 使用 fake/demo provider 保證專案可以跑起來
- 不要用 placeholder function 冒充完成
# 16. 品質要求
- typed code
- no giant god files
- dependency injection
- provider interfaces
- structured logging
- cancellation-safe asyncio
- graceful shutdown
- clear error states
- no secrets
- no hard-coded absolute paths
- no fake Hermes methods
- 不要為了快速完成把核心邏輯塞進 React component
- 不要修改 Hermes core
- 不要建立第二個 LLM/Agent layer
# 17. 最後輸出
完成實作後:
1. 執行 tests / lint / build。
2. 列出通過與未通過項目。
3. 顯示實際啟動指令。
4. 說明 Hermes 目前實際採用的 protocol / endpoint。
5. 列出任何因環境因素無法完整驗證的功能。
6. 不要只提供 code snippets;專案檔案必須實際寫入工作目錄。
現在開始實作。
16. 參考專案
本設計文件刻意把外部專案當作參考,而不是把它們全部堆進 dependency tree。MVP 應保持:Hermes + 自己的薄 Voice Runtime + 自己的 Desktop Shell。