Twin Workspace is the control surface for running a real digital twin on top of Hermes.
It lets you create, schedule, and run real-world interactions using your own voice, avatar, and persona. The workspace is where you define intent, review state, and manage execution. Hermes owns the runtime and orchestration underneath.
Twin is a programmable identity that can:
- make outbound voice calls
- host realtime and video sessions
- generate content with your voice and avatar
- execute tasks through a delegation model
Everything is modeled as a task and managed through a single workspace.
Many interactions are simple in theory but costly in practice.
Things like:
- making quick calls
- checking availability
- asking for pricing
- confirming bookings
- handling follow-ups
- joining a video conversation
- creating videos where you speak on camera
These tasks require timing, attention, and the right headspace. Because of that, they often get delayed, skipped, or handled inefficiently.
They matter, but they do not always require your direct involvement.
Twin is built to take ownership of this layer: taking your intent, and turning it into communication and content.
You define the intent, goal and context once. Twin executes it when time comes.
Before using Twin, you need to configure the core identity and communication setup.
This includes:
- setting up a Twilio phone number (either purchasing one or verifying your own number)
- cloning your voice in ElevenLabs or selecting an existing voice ID
- creating your own avatar in LiveAvatar or using a different avatar ID
Once configured, you can define how your Twin behaves:
- interaction style (formal, casual, concise, etc.)
- tone and communication preferences
- boundaries (what it should or should not say)
- authority rules (what it can act on autonomously)
Twin can then operate in two distinct modes depending on how you want it to represent you:
- Personal mode: Twin uses your cloned voice and LiveAvatar, and speaks as you
- Assistant mode: Twin represents you while speaking with its own configured identity
In assistant mode, this means you can use:
- a different ElevenLabs voice
- a different LiveAvatar
- a different Twilio phone number
- a separate assistant persona
This is useful when you do not want Twin to sound exactly like you, but still want it to make calls, join video sessions, or handle delegated tasks on your behalf.
- Hermes is the owner and orchestration layer
- Twin Workspace is the control surface
- Twin runtime and execution live inside Hermes
- profile, delegation, content, call, and session state stay Hermes-owned
+------------------------------------------------------+
| Twin Workspace |
| Hermes operator cockpit / control plane |
| React + Vite UI + FastAPI facade |
+-------------------------+----------------------------+
|
| drives / manages
v
+------------------------------------------------------+
| skills/twin |
| Twin core skill inside Hermes |
| brain + contract + canonical Twin logic |
| identity, profile, delegations, approvals, |
| call/video/content orchestration, workspace state |
+-------------------------+----------------------------+
|
+-----------+-----------+
| |
executes calls| | executes live video/avatar
v v
+---------------------------+ +---------------------------+
| twin-telephony runtime | | twin-realtime runtime |
| optional Hermes runtime | | optional Hermes runtime |
| Twilio + ElevenLabs | | LiveAvatar + LiveKit/STT |
+---------------------------+ +---------------------------+
|
v
+------------------------------------------------------+
| Hermes-owned Twin outputs |
| profiles / delegations / runs / video_sessions |
+------------------------------------------------------+
- Node.js 18+
- npm
- Python 3.11+
git clone <PRIVATE_REPO_URL> twin-workspace
cd twin-workspaceThis workspace expects a Hermes-backed Twin surface.
If this repo includes an embedded hermes-agent/ subtree, you do not need to clone Hermes separately. If it does not, set HERMES_ROOT in backend/.env to your existing Hermes checkout.
Create the backend env file:
cp backend/.env.example backend/.env| Variable | Required | Purpose |
|---|---|---|
HERMES_ROOT |
Yes | Path to the Hermes checkout or embedded Hermes subtree |
HERMES_OUTPUTS |
Yes | Hermes Twin outputs root |
TWIN_OUTPUT_ROOT |
Yes | Twin output root used by the workspace contract |
TWIN_PROFILE_SLUG |
Yes | Active Twin profile slug |
HERMES_API_SERVER_URL |
Yes | Hermes API server used for sign-in verification |
TWIN_SUMMARY_LANGUAGE |
No | Summary/output language for call logging flows |
In the embedded-repo layout, the default is:
HERMES_ROOT=../hermes-agentOnly change it if Hermes lives somewhere else.
If the repo includes hermes-agent/.env.example, also create the Hermes env file:
cp hermes-agent/.env.example hermes-agent/.env| Flow | Required Variables | Notes |
|---|---|---|
| Basic workspace / profile / delegations | TWIN_PROFILE_SLUG |
Core workspace flows can load without every provider enabled |
| Content: script/text generation | OPENAI_API_KEY |
OpenAI is required for generated text flows |
| Content: audio narration | OPENAI_API_KEY, ELEVENLABS_API_KEY, ELEVENLABS_VOICE_ID |
OpenAI writes the script, ElevenLabs generates spoken audio |
| Content: avatar video via HeyGen | OPENAI_API_KEY, HEYGEN_API_KEY, HEYGEN_AVATAR_ID or HEYGEN_AVATAR_GROUP_ID, HEYGEN_VOICE_ID |
Use when Twin should generate avatar-based video output |
| Outbound voice calling | TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_PHONE_NUMBER, ELEVENLABS_API_KEY, ELEVENLABS_AGENT_ID, ELEVENLABS_PHONE_NUMBER_ID |
Powers the Twin telephony runtime |
| Realtime avatar / live video sessions | OPENAI_API_KEY, LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEAVATAR_API_KEY, LIVEAVATAR_AVATAR_ID, DEEPGRAM_API_KEY, ELEVENLABS_API_KEY |
Powers the Twin realtime runtime |
| External guest video invites | TWIN_PUBLIC_BASE_URL |
Must be a public HTTPS URL, not localhost |
These IDs do not serve the same purpose.
| Value | Used For |
|---|---|
ELEVENLABS_VOICE_ID |
Twin's canonical speaking voice for audio narration, realtime speech, and telephony |
HEYGEN_VOICE_ID |
HeyGen-specific voice selection for avatar video generation |
HEYGEN_AVATAR_ID |
The HeyGen avatar used for generated videos |
HEYGEN_AVATAR_GROUP_ID |
The HeyGen avatar group associated with that avatar |
LIVEAVATAR_AVATAR_ID |
The avatar used by the realtime LiveAvatar runtime |
Notes:
ELEVENLABS_VOICE_IDis the main speech identity for Twin.HEYGEN_VOICE_IDdoes not replace ElevenLabs voice in telephony or narration flows.HEYGEN_*values are specific to HeyGen video generation.LIVEAVATAR_AVATAR_IDis only for the realtime avatar runtime.
If you want external guests to join Twin video sessions, the workspace must be reachable through a public URL.
Set:
TWIN_PUBLIC_BASE_URL=https://your-public-url.example.comThis base URL is used when Twin generates external video invite links.
For local development, this usually means exposing the workspace through a tunnel such as:
- ngrok
- Cloudflare Tunnel
- another HTTPS public tunnel
Example:
TWIN_PUBLIC_BASE_URL=https://my-workspace-tunnel.ngrok-free.appNotes:
- localhost URLs will not work for external guest invites
- the public URL should point to the workspace surface that serves the join flow
- local self-test flows do not require a public URL
Install frontend dependencies:
npm installCreate one Python environment for the workspace backend and Hermes Twin surface together:
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r backend/requirements.txt
pip install -r hermes-agent/requirements-twin.txtCreate the Twin outputs root once:
mkdir -p hermes-agent/outputs/twinStart both servers from the same active Python environment:
source .venv/bin/activate
bash ./start.shThis starts:
- frontend:
http://localhost:5175 - backend:
http://localhost:8000
Twin state is resolved through the Hermes workspace contract and stored under the Twin outputs root.
At minimum, set a profile slug and ensure a profile exists for it.
Typical location:
hermes-agent/outputs/twin/profiles/<slug>/profile.json
Set the same TWIN_PROFILE_SLUG in your env configuration and use that profile for workspace flows.
Twin core lives in Hermes under:
hermes-agent/skills/twin/
Runtime surfaces live under:
hermes-agent/optional-skills/productivity/twin-telephony/hermes-agent/optional-skills/creative/twin-realtime/
These are required for live calling and realtime/avatar execution.
Hermes-owned Twin core:
hermes-agent/skills/twin/
Workspace control surface:
src/backend/routes/*backend/twin_bridge.pybackend/delegations_facade.py
- This is not a standalone frontend-only app.
- The workspace backend depends on the Hermes Twin surface.
- Start the stack with the Python environment activated so backend and Hermes imports resolve in the same runtime.