Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
269e74f
Docker deployment with TORIS persona and flexible auth
ToruGuy Jan 25, 2026
10ff64f
Fix Docker: use Python 3.11 (available in Debian bookworm)
Jan 25, 2026
5598a1b
Add Telegram-based token configuration commands
ToruGuy Jan 25, 2026
1556fe5
Fix security, async I/O, error handling + real tests
ToruGuy Apr 5, 2026
6c57dd7
feat(B11): connect MEGG MCP to TORIS Claude sessions
ToruGuy Apr 5, 2026
e29c1f1
feat(B1): add photo/vision handler
ToruGuy Apr 5, 2026
546a414
feat(B3): add /cancel command to interrupt active Claude requests
ToruGuy Apr 5, 2026
dca89cf
feat(B4): add /compact command to summarize and compress sessions
ToruGuy Apr 5, 2026
a663dea
feat(B5): add MCP server status to /health command
ToruGuy Apr 5, 2026
98731e9
feat: live tool activity in processing message
ToruGuy Apr 5, 2026
bb6fe39
fix: resolve CLAUDE_SETTINGS_FILE to absolute path at startup
ToruGuy Apr 5, 2026
0b74f1b
fix(B11): load MCP servers via options.mcp_servers not settings_file
ToruGuy Apr 5, 2026
db09748
fix(B11): use megg as CLI tool via Bash, not MCP server
ToruGuy Apr 5, 2026
c2f2cb9
feat: watch_mode OFF|LIVE|DEBUG replaces watch_enabled+show_activity
ToruGuy Apr 5, 2026
4df841b
fix: remove stale watch_enabled reference in debug log
ToruGuy Apr 5, 2026
53ef2a4
feat: add continuous typing indicator during message processing
ToruGuy Apr 5, 2026
a7a4d4a
fix: restore processing_msg in handle_text (typing indicator runs alo…
ToruGuy Apr 5, 2026
f23969c
chore: rename 'Asking Claude...' to 'Toris thinking...'
ToruGuy Apr 5, 2026
8728b82
fix: typing indicator fires immediately on receive; remove eager debu…
ToruGuy Apr 5, 2026
2e462eb
docs: automations UI design spec
ToruGuy Apr 6, 2026
0ed5b8b
docs: automations UI implementation plan
ToruGuy Apr 6, 2026
63249d1
feat: add cron_to_human helper with tests
ToruGuy Apr 6, 2026
2f983b2
feat: add run_remote_trigger helpers
ToruGuy Apr 6, 2026
41b350d
fix: use asyncio.run() in test helper, consolidate imports
ToruGuy Apr 6, 2026
886a513
feat: add automations list and card message builders
ToruGuy Apr 6, 2026
3124c18
fix: clarify run button label in automations list
ToruGuy Apr 6, 2026
0685660
feat: add /automations command handler
ToruGuy Apr 6, 2026
5ecc36c
feat: add handle_automations_callback with all auto_* patterns
ToruGuy Apr 6, 2026
3082aea
fix: handle_automations_callback - one query.answer() per branch, add…
ToruGuy Apr 6, 2026
a0fa693
fix: answer() before edit_message_text in toggle branch for consistency
ToruGuy Apr 6, 2026
9f780db
feat: add automation_card_style setting (compact/full toggle)
ToruGuy Apr 6, 2026
05eaac9
chore: add .superpowers to .gitignore
ToruGuy Apr 6, 2026
1c9b5f0
fix: correct toggle trigger_id parsing (off_ is 4 chars), single quer…
ToruGuy Apr 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude-settings
Submodule .claude-settings added at eb757c
64 changes: 64 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
.venv/
venv/
ENV/
env/
*.egg-info/
dist/
build/

# Environment files with secrets
.env
.env.*
!.env.example
docker/*.env
!docker/*.env.example

# State and session files
sessions_state.json
user_settings.json
state/
*.db
*.sqlite

# Sandboxes and temporary files
*sandbox*/
*.log
*.tmp

# Git
.git/
.gitignore
.gitattributes

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# Documentation (not needed in image)
README.md
LICENSE
docs/

# Testing
test_*.py
.pytest_cache/
.coverage
htmlcov/

# CI/CD
.github/
.gitlab-ci.yml

# Docker
docker-compose.yml
Dockerfile
.dockerignore
33 changes: 29 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,24 @@ TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here
TELEGRAM_DEFAULT_CHAT_ID=0

# =============================================================================
# REQUIRED - ElevenLabs API
# VOICE PROVIDERS - Use ElevenLabs OR OpenAI (or both)
# At least one must be set. ElevenLabs takes priority if both are set.
# Override with TTS_PROVIDER=openai or STT_PROVIDER=openai
# =============================================================================

# --- ElevenLabs (optional if OpenAI key is set) ---
ELEVENLABS_API_KEY=your_elevenlabs_api_key_here

# --- OpenAI (optional if ElevenLabs key is set) ---
# OPENAI_API_KEY=sk-...

# =============================================================================
# VOICE PROVIDER SELECTION (Optional - auto-detected from keys if not set)
# =============================================================================
# TTS_PROVIDER=elevenlabs # "elevenlabs" or "openai"
# STT_PROVIDER=elevenlabs # "elevenlabs" or "openai"
# STT_LANGUAGE= # e.g. "en", "pl" — empty = auto-detect

# =============================================================================
# PERSONA CONFIGURATION
# =============================================================================
Expand All @@ -22,12 +36,22 @@ PERSONA_NAME=V
# Leave empty for default minimal prompt
SYSTEM_PROMPT_FILE=prompts/v.md

# ElevenLabs voice ID
# --- ElevenLabs voice ---
# George: JBFqnCBsd6RMkjVDRZzb (default)
# Daniel: onwK4e9ZLuTAKqWW03F9
# Charlie: IKne3meq5aSn9XLyUdCD
ELEVENLABS_VOICE_ID=JBFqnCBsd6RMkjVDRZzb

# --- OpenAI voice ---
# Voices: alloy, ash, ballad, cedar, coral (default), echo, fable,
# juniper, marin, onyx, nova, sage, shimmer, verse
# OPENAI_VOICE_ID=coral
# OPENAI_TTS_MODEL=gpt-4o-mini-tts # or: tts-1, tts-1-hd
# OPENAI_STT_MODEL=whisper-1 # or: gpt-4o-mini-transcribe, gpt-4o-transcribe

# Speaking style prompt (only for gpt-4o-mini-tts)
# OPENAI_VOICE_INSTRUCTIONS=Speak as a calm, direct advisor. Clear and natural pace.

# =============================================================================
# TOPIC FILTERING (Optional)
# =============================================================================
Expand All @@ -39,10 +63,11 @@ TELEGRAM_TOPIC_ID=
# DIRECTORIES
# =============================================================================
# Directory for Claude to read files from
CLAUDE_WORKING_DIR=/home/dev
CLAUDE_WORKING_DIR=/home/youruser

# Sandbox directory - Claude can write/execute here
CLAUDE_SANDBOX_DIR=/home/dev/claude-voice-sandbox
CLAUDE_SANDBOX_DIR=/home/youruser/claude-voice-sandbox
CLAUDE_SETTINGS_FILE=settings.json

# Optional: Settings file for Claude permissions (restricts Edit/Write to sandbox)
# CLAUDE_SETTINGS_FILE=/path/to/settings.json
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ bot.log
# State files (user-specific, not for repo)
sessions_state.json
user_settings.json
settings.json

# Test artifacts
.coverage
Expand All @@ -34,3 +35,5 @@ htmlcov/
.vscode/
*.swp
*.swo
credentials.json
.superpowers/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule ".claude-settings"]
path = .claude-settings
url = git@github.com:ToruAI/toru-claude-settings.git
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Thanks for your interest in contributing! This document outlines how to get star

1. Clone the repository:
```bash
git clone https://github.com/toruai/claude-voice-assistant.git
cd claude-voice-assistant
git clone https://github.com/toruai/toris-voice.git
cd toris-voice
```

2. Create a virtual environment:
Expand Down Expand Up @@ -78,7 +78,7 @@ pytest test_bot.py -v
## Project Structure

```
claude-voice-assistant/
toris-voice/
├── bot.py # Main bot code
├── test_bot.py # Test suite
├── prompts/ # Persona prompt files
Expand Down
70 changes: 70 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Claude Voice Assistant - Production Docker Image
# Multi-stage build for efficient image size

# ============================================================================
# Stage 1: Base with Node.js and Python
# ============================================================================
FROM node:20-slim AS base

# Install Python and system dependencies
# Note: Debian bookworm has Python 3.11, which is compatible
RUN apt-get update && apt-get install -y \
python3 \
python3-venv \
python3-pip \
curl \
&& rm -rf /var/lib/apt/lists/*

# Create non-root user (uid 1000 required by Claude CLI)
# Delete existing node user first (it has UID 1000)
RUN userdel -r node && \
useradd -m -u 1000 -s /bin/bash claude && \
mkdir -p /home/claude/.claude && \
chown -R claude:claude /home/claude

# ============================================================================
# Stage 2: Application Setup
# ============================================================================
FROM base AS app

# Install Claude Code CLI globally
RUN npm install -g @anthropic-ai/claude-code

# Switch to non-root user
USER claude
WORKDIR /home/claude/app

# Copy requirements first for better caching
COPY --chown=claude:claude requirements.txt .

# Create virtual environment and install dependencies
RUN python3 -m venv .venv && \
.venv/bin/pip install --no-cache-dir --upgrade pip && \
.venv/bin/pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY --chown=claude:claude bot.py .
COPY --chown=claude:claude prompts/ ./prompts/

# Copy Claude settings (agents, skills, config from toru-claude-settings submodule)
COPY --chown=claude:claude .claude-settings/ /home/claude/.claude/

# Create necessary directories
RUN mkdir -p /home/claude/sandbox /home/claude/state

# ============================================================================
# Runtime Configuration
# ============================================================================

# Health check - verify bot can start
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD pgrep -f "python.*bot.py" || exit 1

# Set environment variables
ENV PYTHONUNBUFFERED=1 \
CLAUDE_WORKING_DIR=/home/claude/app \
CLAUDE_SANDBOX_DIR=/home/claude/sandbox \
PATH="/home/claude/app/.venv/bin:$PATH"

# Default command
CMD ["python", "bot.py"]
Loading