Skip to content

Commit

Permalink
Merge branch 'vocodedev-main'
Browse files Browse the repository at this point in the history
  • Loading branch information
arpagon committed Apr 20, 2024
2 parents 236deb3 + 890728c commit 81cbab7
Show file tree
Hide file tree
Showing 63 changed files with 7,314 additions and 5,802 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: "Close stale issues"

on:
schedule:
- cron: "30 1 * * *"

permissions:
contents: write
issues: write
pull-requests: write

jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 60
days-before-close: 7
stale-issue-label: 'stale'
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
close-issue-message: 'This issue has been automatically closed due to inactivity. Thank you for your contributions.'
stale-pr-label: 'stale'
stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
close-pr-message: 'This PR has been automatically closed due to inactivity. Thank you for your contributions.'
exempt-all-pr-milestones: true
enable-statistics: true
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- "3.10"
- "3.11"
poetry-version:
- "1.4.2"
- "1.7.1"

runs-on: ubuntu-latest

Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repos:
hooks:
- id: black
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.3.0
rev: v1.8.0
hooks:
- id: mypy
args: [--ignore-missing-imports, ./]
Expand Down
2,418 changes: 1,255 additions & 1,163 deletions apps/client_backend/poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/client_backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.9,<3.12"
python-dotenv = "^1.0.0"
vocode = "0.1.111a3"
vocode = "0.1.111"
elevenlabs = "^0.2.23"


Expand Down
2 changes: 1 addition & 1 deletion apps/langchain_agent/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# langchain_agent

See https://docs.vocode.dev/langchain-agent for setup steps!
See https://docs.vocode.dev/open-source/langchain-agent for setup steps!
2,587 changes: 1,361 additions & 1,226 deletions apps/langchain_agent/poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/langchain_agent/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ redis = "^4.5.4"
twilio = "^8.1.0"
vonage = "^3.5.1"
python-dotenv = "^1.0.0"
vocode = "0.1.111a3"
vocode = "0.1.111"
google-cloud-texttospeech = "^2.14.1"


Expand Down
2 changes: 1 addition & 1 deletion apps/telegram_bot/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.11
FROM python:3.9-bullseye

# get portaudio and ffmpeg
RUN apt-get update \
Expand Down
40 changes: 26 additions & 14 deletions apps/telegram_bot/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import logging
import inspect
from collections import defaultdict
from pydantic import BaseModel
from pydantic.v1 import BaseModel
from typing import Tuple, Union, Optional, Dict, Type, List
from pydub import AudioSegment
from telegram import Update
Expand All @@ -28,6 +28,10 @@
BaseSynthesizer,
)

from dotenv import load_dotenv

load_dotenv()

logging.basicConfig(
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
)
Expand All @@ -46,7 +50,7 @@
# Required environment variables containing API key: OPENAI_API_KEY, TELEGRAM_BOT_KEY, and your Vocode synthesizers classes corresponding API key variable

# Your chosen synthesizer provider's corresponding Vocode turn_based class instance
SYNTH = CoquiSynthesizer(use_xtts=True)
SYNTH = AzureSynthesizer(voice_name="en-US-SteffanNeural")

# Instructions to the language model responsible for generating response transcript.
SYSTEM_PROMPT = "You are having a voice-to-voice conversation with a user. Always pretend you are a real human. Do not avoid or decline to answer questions because you are not human."
Expand Down Expand Up @@ -76,33 +80,36 @@

# Define a Voice model with id, name and description fields
class Voice(BaseModel):
id: Optional[str] = None # Optional id for the voice
name: Optional[str] = None # Optional name for the voice
description: Optional[str] = None # Optional description for the voice
id: Optional[str] = None # Optional id for the voice
name: Optional[str] = None # Optional name for the voice
description: Optional[str] = None # Optional description for the voice


# Array of tuples (synthesizer's voice id, nickname, description if text to voice)
DEFAULT_VOICES: List[Voice] = [Voice(id=None, name="Coqui Default", description=None)]


# Define a Chat model with voices, current_voice and current_conversation fields
class Chat(BaseModel):
voices: List[Voice] = DEFAULT_VOICES # List of available voices for the chat
current_voice: Voice = DEFAULT_VOICES[0] # Current voice for the chat
current_conversation: Optional[bytes] = None # Current conversation as a pickled object
voices: List[Voice] = DEFAULT_VOICES # List of available voices for the chat
current_voice: Voice = DEFAULT_VOICES[0] # Current voice for the chat
current_conversation: Optional[
bytes
] = None # Current conversation as a pickled object


class VocodeBotResponder:
def __init__(
self,
transcriber: BaseTranscriber,
system_prompt: str,
synthesizer: BaseSynthesizer
synthesizer: BaseSynthesizer,
) -> None:
self.transcriber = transcriber
self.system_prompt = system_prompt
self.synthesizer = synthesizer
self.db: Dict[int, Chat] = defaultdict(Chat)


def get_agent(self, chat_id: int) -> ChatGPTAgent:
# Get current voice name and description from DB
user = self.db[chat_id]
Expand Down Expand Up @@ -142,13 +149,16 @@ async def get_response(
voice_description = user.current_voice.description

# If we have a Coqui voice prompt, use that. Otherwise, set ID as synthesizer expects.
if voice_description is not None and isinstance(self.synthesizer, CoquiSynthesizer):
if voice_description is not None and isinstance(
self.synthesizer, CoquiSynthesizer
):
self.synthesizer.voice_prompt = voice_description
elif voice_id is not None:
setattr(self.synthesizer, voice_attr_of[type(self.synthesizer)], voice_id)

# Synthesize response
synth_response = await self.synthesizer.async_synthesize(agent_response)
# TODO make async
synth_response = self.synthesizer.synthesize(agent_response)

# Save conversation to DB
self.db[chat_id].current_conversation = pickle.dumps(agent.memory)
Expand All @@ -162,7 +172,9 @@ async def handle_telegram_start(
start_text = """
I'm a voice chatbot, send a voice message to me and I'll send one back!" Use /help to see available commands.
"""
await context.bot.send_message(chat_id=update.effective_chat.id, text=start_text)
await context.bot.send_message(
chat_id=update.effective_chat.id, text=start_text
)

async def handle_telegram_message(
self, update: Update, context: ContextTypes.DEFAULT_TYPE
Expand Down Expand Up @@ -302,7 +314,7 @@ async def handle_telegram_help(
- Use /help to see this help message again.
"""
assert update.effective_chat, "Chat must be defined!"
if isinstance(self.synthesizer, CoquiSynthesizer):
if isinstance(self.synthesizer, CoquiSynthesizer):
help_text += "\n- Use /create <voice_description> to create a new Coqui voice from a text prompt and switch to it."
await context.bot.send_message(chat_id=update.effective_chat.id, text=help_text)

Expand Down
Loading

0 comments on commit 81cbab7

Please sign in to comment.