From 72f7d140d4dcfeba86f5905a7c41b1de6dc9b8e4 Mon Sep 17 00:00:00 2001 From: Ben Xu Date: Tue, 11 Jun 2024 20:12:36 -0700 Subject: [PATCH] add realtime tts streaming --- software/poetry.lock | 743 +++++--------------- software/pyproject.toml | 9 +- software/source/clients/base_device.py | 82 ++- software/source/server/async_interpreter.py | 45 +- software/source/server/async_server.py | 42 +- software/source/server/server.py | 2 + software/start.py | 28 +- 7 files changed, 344 insertions(+), 607 deletions(-) diff --git a/software/poetry.lock b/software/poetry.lock index 528ed12e..45f3b5c4 100644 --- a/software/poetry.lock +++ b/software/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "absl-py" @@ -11,17 +11,6 @@ files = [ {file = "absl_py-2.1.0-py3-none-any.whl", hash = "sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308"}, ] -[[package]] -name = "aifs" -version = "0.0.15" -description = "Local semantic search. Stupidly simple." -optional = false -python-versions = "<4,>=3.9" -files = [ - {file = "aifs-0.0.15-py3-none-any.whl", hash = "sha256:ea15d7702499c1af21a49a0b32248fbf1aef57857e4ffa11107e7f834613ad49"}, - {file = "aifs-0.0.15.tar.gz", hash = "sha256:385a975a135dbc6ab117dc9572f63faf4ac46dc594e7a8707b6f3408a0c0abab"}, -] - [[package]] name = "aiohttp" version = "3.9.5" @@ -327,17 +316,17 @@ files = [ [[package]] name = "azure-cognitiveservices-speech" -version = "1.36.0" +version = "1.37.0" description = "Microsoft Cognitive Services Speech SDK for Python" optional = false python-versions = ">=3.7" files = [ - {file = "azure_cognitiveservices_speech-1.36.0-py3-none-macosx_10_14_x86_64.whl", hash = "sha256:76542b7b0f010d9b2304382b9f146f8e57ba14c6f0c6d90580c81f55c22baf1f"}, - {file = "azure_cognitiveservices_speech-1.36.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:81ac075c6f2cb97a35fa88306adbddabfe54a7de2b582f349a484ee2b8bd81e0"}, - {file = "azure_cognitiveservices_speech-1.36.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:ed1f6ba3dd439d8f7771d4e32a1e2224e1b4103e050f07120eb9d0cfb5aae82e"}, - {file = "azure_cognitiveservices_speech-1.36.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:208517147f59fdf3fcce5e62584763d7710d4fbfd3af6d63d1240d3da34ff2c8"}, - {file = "azure_cognitiveservices_speech-1.36.0-py3-none-win32.whl", hash = "sha256:ee6fbd600e025900591e2a7eca1b2bec287cb7460c8719fd564682b065d12948"}, - {file = "azure_cognitiveservices_speech-1.36.0-py3-none-win_amd64.whl", hash = "sha256:37b1d977ab961389c89e499d00a7c3ff64ead988e16cee8c563dab3464750871"}, + {file = "azure_cognitiveservices_speech-1.37.0-py3-none-macosx_10_14_x86_64.whl", hash = "sha256:906d6bf65176e93464e2d763dd074ca00c48cfe1a896371fcdcb155a500910f7"}, + {file = "azure_cognitiveservices_speech-1.37.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:54ec8dd55d4dbd9058c61909e08485d3761d6d30954da189e1b17d84daf5e2e0"}, + {file = "azure_cognitiveservices_speech-1.37.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:685424689725d2d4115485998c0888c8b5b502259037ff533e5a834575f80b66"}, + {file = "azure_cognitiveservices_speech-1.37.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:384f66786c2335165035270897b34d0b91736a1fdf38f7696e9a227075cb2489"}, + {file = "azure_cognitiveservices_speech-1.37.0-py3-none-win32.whl", hash = "sha256:343d5f449ccd6c9b53cd37dd46a70ece0905243517df7a0c047779e55072254c"}, + {file = "azure_cognitiveservices_speech-1.37.0-py3-none-win_amd64.whl", hash = "sha256:a18fb45490cdcd681407ccaad9560fb14dda1c8276de297e219ea1a880467e28"}, ] [[package]] @@ -354,28 +343,6 @@ files = [ [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bangla" -version = "0.0.2" -description = "Bangla is a package for Bangla language users with various functionalities including Bangla date and Bangla numeric conversation." -optional = false -python-versions = "*" -files = [ - {file = "bangla-0.0.2-py2.py3-none-any.whl", hash = "sha256:60c52bb4614894de4a91ee997bf950d03545d1fb9b01196577ce04ed4fa00ff8"}, - {file = "bangla-0.0.2.tar.gz", hash = "sha256:17c8fd501321660077d5ab6a79b746bba71f9e4939ef78ac0d9a75d7bd715da8"}, -] - [[package]] name = "black" version = "24.4.2" @@ -438,17 +405,6 @@ jinxed = {version = ">=1.1.0", markers = "platform_system == \"Windows\""} six = ">=1.9.0" wcwidth = ">=0.1.4" -[[package]] -name = "blinker" -version = "1.8.2" -description = "Fast, simple object-to-object and broadcast signaling" -optional = false -python-versions = ">=3.8" -files = [ - {file = "blinker-1.8.2-py3-none-any.whl", hash = "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01"}, - {file = "blinker-1.8.2.tar.gz", hash = "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83"}, -] - [[package]] name = "blis" version = "0.7.11" @@ -495,27 +451,6 @@ files = [ [package.dependencies] numpy = {version = ">=1.19.0", markers = "python_version >= \"3.9\""} -[[package]] -name = "bnnumerizer" -version = "0.0.2" -description = "Bangla Number text to String Converter" -optional = false -python-versions = "*" -files = [ - {file = "bnnumerizer-0.0.2.tar.gz", hash = "sha256:41df6fd0b7b51aa4ec4776b6643cedebee5fd11e335d7d56d4a20c08515e5f0d"}, -] - -[[package]] -name = "bnunicodenormalizer" -version = "0.1.7" -description = "Bangla Unicode Normalization Toolkit" -optional = false -python-versions = "*" -files = [ - {file = "bnunicodenormalizer-0.1.7-py3-none-any.whl", hash = "sha256:42b6a9720bca52c02a944a0876770e86694eb081a096f3c644ccd8add40f7cee"}, - {file = "bnunicodenormalizer-0.1.7.tar.gz", hash = "sha256:86a3489cc81c73d2afb4e265bd2d0d8bc52fc8a2374e210c899e0260940bc091"}, -] - [[package]] name = "bottle" version = "0.12.25" @@ -916,6 +851,82 @@ files = [ {file = "coqpit-0.0.17.tar.gz", hash = "sha256:dc129c2a741f8feec35c16d0b603afafdf66064822638b4e4fd7a02a7ce05011"}, ] +[[package]] +name = "coqui-tts" +version = "0.24.1" +description = "Deep learning for Text to Speech." +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "coqui_tts-0.24.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:7feb9502f03e6c3c0b5e47c0f6166335ff03aac55dece61497233168bf8ea750"}, + {file = "coqui_tts-0.24.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:da2fadf99aa1556dc4a26df90d14745a2ff508be4bf6ac143b778cb2ffa3f313"}, + {file = "coqui_tts-0.24.1-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:05b56d58c495b05738957198ea6130f0543a0c84d5b9e97872c852dd72760786"}, + {file = "coqui_tts-0.24.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:09ce255368528f61cef8ce29f4718e91d7f46a348eb0696502f2c10575024eb7"}, + {file = "coqui_tts-0.24.1.tar.gz", hash = "sha256:a6a1251bf2ffb9be8efc8fbecd54331579a1d80255aa7e18b31bd9f002e4abc5"}, +] + +[package.dependencies] +anyascii = ">=0.3.0" +coqpit = ">=0.0.16" +coqui-tts-trainer = ">=0.1" +cython = ">=0.29.30" +einops = ">=0.6.0" +encodec = ">=0.1.1" +fsspec = {version = ">=2023.6.0", extras = ["http"]} +gruut = {version = "2.2.3", extras = ["de", "es", "fr"]} +inflect = ">=5.6.0" +librosa = ">=0.10.1" +matplotlib = ">=3.7.0" +num2words = "*" +numpy = ">=1.24.3" +packaging = ">=23.1" +pysbd = ">=0.3.4" +pyyaml = ">=6.0" +scipy = ">=1.11.2" +soundfile = ">=0.12.0" +spacy = {version = ">=3", extras = ["ja"]} +torch = ">=2.1" +torchaudio = "*" +tqdm = ">=4.64.1" +transformers = ">=4.33.0,<4.41.0" +umap-learn = ">=0.5.1" + +[package.extras] +all = ["coqui-tts[bn,ja,ko,notebooks,server,zh]"] +bn = ["bangla", "bnnumerizer", "bnunicodenormalizer"] +dev = ["black (==24.2.0)", "coverage[toml]", "nose2", "pre-commit", "ruff (==0.3.0)", "tomli"] +docs = ["furo", "linkify-it-py", "myst-parser (==2.0.0)", "sphinx (==7.2.5)", "sphinx-copybutton", "sphinx-inline-tabs"] +ja = ["cutlet", "mecab-python3", "unidic-lite (==1.0.8)"] +ko = ["g2pkk (>=0.1.1)", "hangul-romanize", "jamo"] +languages = ["coqui-tts[bn,ja,ko,zh]"] +notebooks = ["bokeh (==1.4.0)", "pandas (>=1.4,<2.0)"] +server = ["flask (>=2.0.1)"] +zh = ["jieba", "pypinyin"] + +[[package]] +name = "coqui-tts-trainer" +version = "0.1.1" +description = "General purpose model trainer for PyTorch that is more flexible than it should be, by 🐸Coqui." +optional = false +python-versions = "<3.13,>=3.6.0" +files = [ + {file = "coqui_tts_trainer-0.1.1-py3-none-any.whl", hash = "sha256:ffff1bbeca300c86c42e75baf427f3dd96851a141d9c7a8829634ec92e5a109f"}, + {file = "coqui_tts_trainer-0.1.1.tar.gz", hash = "sha256:c8c73e76e48b3e5c5e348e356ffff29176a1a7646ec4087c2714d144647655d6"}, +] + +[package.dependencies] +coqpit = "*" +fsspec = "*" +psutil = "*" +soundfile = "*" +tensorboard = "*" +torch = ">=1.7" + +[package.extras] +all = ["accelerate", "black (==24.2.0)", "coqpit", "coverage", "fsspec", "isort", "psutil", "pylint", "pytest", "soundfile", "tensorboard", "torch (>=1.7)", "torchvision"] +dev = ["accelerate", "black (==24.2.0)", "coverage", "isort", "pylint", "pytest"] +test = ["torchvision"] + [[package]] name = "ctranslate2" version = "4.1.0" @@ -1203,19 +1214,21 @@ files = [ [[package]] name = "elevenlabs" -version = "0.2.27" -description = "The official elevenlabs python package." +version = "1.2.2" +description = "" optional = false -python-versions = "*" +python-versions = "<4.0,>=3.8" files = [ - {file = "elevenlabs-0.2.27-py3-none-any.whl", hash = "sha256:c31ea892d5668002bc26d0bb46a6466b0b4e2fe5aaed75cbc1b7011f01d3fa29"}, - {file = "elevenlabs-0.2.27.tar.gz", hash = "sha256:1b17d3c997557e5aa654b296e3960c25ea183525cfdbd0ec53070b038ba5fd95"}, + {file = "elevenlabs-1.2.2-py3-none-any.whl", hash = "sha256:60b92b0e2aabdfba93a43569f207f8a2ad397492519b8e11a2eebb32807ddefa"}, + {file = "elevenlabs-1.2.2.tar.gz", hash = "sha256:ebd02869b95602b8956874dd727981bb49ad16b9a3c2f5901193d838213694aa"}, ] [package.dependencies] +httpx = ">=0.21.2" ipython = ">=7.0" -pydantic = ">=2.0" +pydantic = ">=1.9.2" requests = ">=2.20" +typing_extensions = ">=4.0.0" websockets = ">=11.0" [[package]] @@ -1375,29 +1388,6 @@ docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1 testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] typing = ["typing-extensions (>=4.8)"] -[[package]] -name = "flask" -version = "3.0.3" -description = "A simple framework for building complex web applications." -optional = false -python-versions = ">=3.8" -files = [ - {file = "flask-3.0.3-py3-none-any.whl", hash = "sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3"}, - {file = "flask-3.0.3.tar.gz", hash = "sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842"}, -] - -[package.dependencies] -blinker = ">=1.6.2" -click = ">=8.1.3" -importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} -itsdangerous = ">=2.1.2" -Jinja2 = ">=3.1.2" -Werkzeug = ">=3.0.0" - -[package.extras] -async = ["asgiref (>=3.2)"] -dotenv = ["python-dotenv"] - [[package]] name = "flatbuffers" version = "24.3.25" @@ -1571,6 +1561,9 @@ files = [ {file = "fsspec-2024.5.0.tar.gz", hash = "sha256:1d021b0b0f933e3b3029ed808eb400c08ba101ca2de4b3483fbc9ca23fcee94a"}, ] +[package.dependencies] +aiohttp = {version = "<4.0.0a0 || >4.0.0a0,<4.0.0a1 || >4.0.0a1", optional = true, markers = "extra == \"http\""} + [package.extras] abfs = ["adlfs"] adl = ["adlfs"] @@ -1609,21 +1602,6 @@ files = [ {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"}, ] -[[package]] -name = "g2pkk" -version = "0.1.2" -description = "g2pkk: g2p module for Korean(cross platform)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "g2pkk-0.1.2-py3-none-any.whl", hash = "sha256:f1d551f35d3b9065f75749c724e65b28731fdc3262e5e9657cb57e3f7b5dcac3"}, - {file = "g2pkk-0.1.2.tar.gz", hash = "sha256:61aad5d41b67d71dd29b8570fc90d2c89cb76493170101d92492649521b447e4"}, -] - -[package.dependencies] -jamo = "*" -nltk = "*" - [[package]] name = "git-python" version = "1.0.3" @@ -1840,6 +1818,25 @@ files = [ {file = "gruut_lang_fr-2.0.2.tar.gz", hash = "sha256:d2de9fc2f92ede277cb6dfe72afdba1b902d329b3cc1f1c706e66b31f0d436bd"}, ] +[[package]] +name = "gtts" +version = "2.5.1" +description = "gTTS (Google Text-to-Speech), a Python library and CLI tool to interface with Google Translate text-to-speech API" +optional = false +python-versions = ">=3.7" +files = [ + {file = "gTTS-2.5.1-py3-none-any.whl", hash = "sha256:273ec8a5077b25e60ca5a266ed254b54d1f14032b0af3ba00092d14966148664"}, + {file = "gTTS-2.5.1.tar.gz", hash = "sha256:02d0a9874f945dee9cd5092991c60bc88d4b7767b8cd81144b6fb49dc3de6897"}, +] + +[package.dependencies] +click = ">=7.1,<8.2" +requests = ">=2.27,<3" + +[package.extras] +docs = ["sphinx", "sphinx-autobuild", "sphinx-click", "sphinx-mdinclude", "sphinx-rtd-theme"] +tests = ["pytest (>=7.1.3,<8.1.0)", "pytest-cov", "testfixtures"] + [[package]] name = "h11" version = "0.14.0" @@ -1872,17 +1869,6 @@ termcolor = ">=1.1.0" [package.extras] ipython = ["IPython (==5.7.0)", "ipywidgets (==7.1.0)"] -[[package]] -name = "hangul-romanize" -version = "0.1.0" -description = "Rominize Hangul strings." -optional = false -python-versions = "*" -files = [ - {file = "hangul-romanize-0.1.0.tar.gz", hash = "sha256:fae69ba181af6e75a86460fd7f57a6b304cd5f1973d8c425ed8602fee2c9276c"}, - {file = "hangul_romanize-0.1.0-py3-none-any.whl", hash = "sha256:7b8ba54b624ca3b17b2c9394b971cd595c4240a31cc0fc6bc1c3e971eca8c4d5"}, -] - [[package]] name = "html2image" version = "2.0.4.3" @@ -2184,28 +2170,6 @@ files = [ [package.extras] colors = ["colorama (>=0.4.6)"] -[[package]] -name = "itsdangerous" -version = "2.2.0" -description = "Safely pass data to untrusted environments and back." -optional = false -python-versions = ">=3.8" -files = [ - {file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"}, - {file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"}, -] - -[[package]] -name = "jamo" -version = "0.4.1" -description = "A Hangul syllable and jamo analyzer." -optional = false -python-versions = "*" -files = [ - {file = "jamo-0.4.1-py3-none-any.whl", hash = "sha256:d4b94fd23324c606ed2fbc4037c603e2c3a7ae9390c05d3473aea1ccb6b1c3fb"}, - {file = "jamo-0.4.1.tar.gz", hash = "sha256:ea65cf9d35338d0e0af48d75ff426d8a369b0ebde6f07051c3ac37256f56d025"}, -] - [[package]] name = "jedi" version = "0.19.1" @@ -2225,16 +2189,6 @@ docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alab qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] -[[package]] -name = "jieba" -version = "0.42.1" -description = "Chinese Words Segmentation Utilities" -optional = false -python-versions = "*" -files = [ - {file = "jieba-0.42.1.tar.gz", hash = "sha256:055ca12f62674fafed09427f176506079bc135638a14e23e25be909131928db2"}, -] - [[package]] name = "jinja2" version = "3.1.4" @@ -2516,37 +2470,6 @@ dev = ["changelist (==0.5)"] lint = ["pre-commit (==3.7.0)"] test = ["pytest (>=7.4)", "pytest-cov (>=4.1)"] -[[package]] -name = "librosa" -version = "0.10.0" -description = "Python module for audio and music processing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "librosa-0.10.0-py3-none-any.whl", hash = "sha256:6db29c1467168da21313203dcef405a73a678d3aad0fbc67607250b2f08a3f5a"}, - {file = "librosa-0.10.0.tar.gz", hash = "sha256:8e8669e5084002d1a87f6c82b732f370784a368d0e55c2dd7d7aef3fa02fd058"}, -] - -[package.dependencies] -audioread = ">=2.1.9" -decorator = ">=4.3.0" -joblib = ">=0.14" -lazy-loader = ">=0.1" -msgpack = ">=1.0" -numba = ">=0.51.0" -numpy = ">=1.20.3" -pooch = ">=1.0" -scikit-learn = ">=0.20.0" -scipy = ">=1.2.0" -soundfile = ">=0.12.1" -soxr = ">=0.3.2" -typing-extensions = ">=4.1.1" - -[package.extras] -display = ["matplotlib (>=3.3.0)"] -docs = ["ipython (>=7.0)", "matplotlib (>=3.3.0)", "mir-eval (>=0.5)", "numba (>=0.51)", "numpydoc", "presets", "sphinx (!=1.3.1,<6)", "sphinx-gallery (>=0.7)", "sphinx-multiversion (>=0.2.3)", "sphinx-rtd-theme (==1.*)", "sphinxcontrib-svg2pdfconverter"] -tests = ["matplotlib (>=3.3.0)", "packaging (>=20.0)", "pytest", "pytest-cov", "pytest-mpl", "resampy (>=0.2.2)", "samplerate", "types-decorator"] - [[package]] name = "librosa" version = "0.10.2.post1" @@ -2884,55 +2807,6 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] -[[package]] -name = "matplotlib" -version = "3.8.4" -description = "Python plotting package" -optional = false -python-versions = ">=3.9" -files = [ - {file = "matplotlib-3.8.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:abc9d838f93583650c35eca41cfcec65b2e7cb50fd486da6f0c49b5e1ed23014"}, - {file = "matplotlib-3.8.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f65c9f002d281a6e904976007b2d46a1ee2bcea3a68a8c12dda24709ddc9106"}, - {file = "matplotlib-3.8.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce1edd9f5383b504dbc26eeea404ed0a00656c526638129028b758fd43fc5f10"}, - {file = "matplotlib-3.8.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecd79298550cba13a43c340581a3ec9c707bd895a6a061a78fa2524660482fc0"}, - {file = "matplotlib-3.8.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:90df07db7b599fe7035d2f74ab7e438b656528c68ba6bb59b7dc46af39ee48ef"}, - {file = "matplotlib-3.8.4-cp310-cp310-win_amd64.whl", hash = "sha256:ac24233e8f2939ac4fd2919eed1e9c0871eac8057666070e94cbf0b33dd9c338"}, - {file = "matplotlib-3.8.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:72f9322712e4562e792b2961971891b9fbbb0e525011e09ea0d1f416c4645661"}, - {file = "matplotlib-3.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:232ce322bfd020a434caaffbd9a95333f7c2491e59cfc014041d95e38ab90d1c"}, - {file = "matplotlib-3.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6addbd5b488aedb7f9bc19f91cd87ea476206f45d7116fcfe3d31416702a82fa"}, - {file = "matplotlib-3.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc4ccdc64e3039fc303defd119658148f2349239871db72cd74e2eeaa9b80b71"}, - {file = "matplotlib-3.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b7a2a253d3b36d90c8993b4620183b55665a429da8357a4f621e78cd48b2b30b"}, - {file = "matplotlib-3.8.4-cp311-cp311-win_amd64.whl", hash = "sha256:8080d5081a86e690d7688ffa542532e87f224c38a6ed71f8fbed34dd1d9fedae"}, - {file = "matplotlib-3.8.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6485ac1f2e84676cff22e693eaa4fbed50ef5dc37173ce1f023daef4687df616"}, - {file = "matplotlib-3.8.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c89ee9314ef48c72fe92ce55c4e95f2f39d70208f9f1d9db4e64079420d8d732"}, - {file = "matplotlib-3.8.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50bac6e4d77e4262c4340d7a985c30912054745ec99756ce213bfbc3cb3808eb"}, - {file = "matplotlib-3.8.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f51c4c869d4b60d769f7b4406eec39596648d9d70246428745a681c327a8ad30"}, - {file = "matplotlib-3.8.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b12ba985837e4899b762b81f5b2845bd1a28f4fdd1a126d9ace64e9c4eb2fb25"}, - {file = "matplotlib-3.8.4-cp312-cp312-win_amd64.whl", hash = "sha256:7a6769f58ce51791b4cb8b4d7642489df347697cd3e23d88266aaaee93b41d9a"}, - {file = "matplotlib-3.8.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:843cbde2f0946dadd8c5c11c6d91847abd18ec76859dc319362a0964493f0ba6"}, - {file = "matplotlib-3.8.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c13f041a7178f9780fb61cc3a2b10423d5e125480e4be51beaf62b172413b67"}, - {file = "matplotlib-3.8.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb44f53af0a62dc80bba4443d9b27f2fde6acfdac281d95bc872dc148a6509cc"}, - {file = "matplotlib-3.8.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:606e3b90897554c989b1e38a258c626d46c873523de432b1462f295db13de6f9"}, - {file = "matplotlib-3.8.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9bb0189011785ea794ee827b68777db3ca3f93f3e339ea4d920315a0e5a78d54"}, - {file = "matplotlib-3.8.4-cp39-cp39-win_amd64.whl", hash = "sha256:6209e5c9aaccc056e63b547a8152661324404dd92340a6e479b3a7f24b42a5d0"}, - {file = "matplotlib-3.8.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c7064120a59ce6f64103c9cefba8ffe6fba87f2c61d67c401186423c9a20fd35"}, - {file = "matplotlib-3.8.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0e47eda4eb2614300fc7bb4657fced3e83d6334d03da2173b09e447418d499f"}, - {file = "matplotlib-3.8.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:493e9f6aa5819156b58fce42b296ea31969f2aab71c5b680b4ea7a3cb5c07d94"}, - {file = "matplotlib-3.8.4.tar.gz", hash = "sha256:8aac397d5e9ec158960e31c381c5ffc52ddd52bd9a47717e2a694038167dffea"}, -] - -[package.dependencies] -contourpy = ">=1.0.1" -cycler = ">=0.10" -fonttools = ">=4.22.0" -importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} -kiwisolver = ">=1.3.1" -numpy = ">=1.21" -packaging = ">=20.0" -pillow = ">=8" -pyparsing = ">=2.3.1" -python-dateutil = ">=2.7" - [[package]] name = "matplotlib" version = "3.9.0" @@ -3030,17 +2904,6 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] -[[package]] -name = "monotonic" -version = "1.6" -description = "An implementation of time.monotonic() for Python 2 & < 3.3" -optional = false -python-versions = "*" -files = [ - {file = "monotonic-1.6-py2.py3-none-any.whl", hash = "sha256:68687e19a14f11f26d140dd5c86f3dba4bf5df58003000ed467e0e2a69bca96c"}, - {file = "monotonic-1.6.tar.gz", hash = "sha256:3a55207bcfed53ddd5c5bae174524062935efed17792e9de2ad0205ce9ad63f7"}, -] - [[package]] name = "more-itertools" version = "10.2.0" @@ -3433,37 +3296,6 @@ files = [ llvmlite = "==0.42.*" numpy = ">=1.22,<1.27" -[[package]] -name = "numpy" -version = "1.22.0" -description = "NumPy is the fundamental package for array computing with Python." -optional = false -python-versions = ">=3.8" -files = [ - {file = "numpy-1.22.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d22662b4b10112c545c91a0741f2436f8ca979ab3d69d03d19322aa970f9695"}, - {file = "numpy-1.22.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:11a1f3816ea82eed4178102c56281782690ab5993251fdfd75039aad4d20385f"}, - {file = "numpy-1.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5dc65644f75a4c2970f21394ad8bea1a844104f0fe01f278631be1c7eae27226"}, - {file = "numpy-1.22.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42c16cec1c8cf2728f1d539bd55aaa9d6bb48a7de2f41eb944697293ef65a559"}, - {file = "numpy-1.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97e82c39d9856fe7d4f9b86d8a1e66eff99cf3a8b7ba48202f659703d27c46f"}, - {file = "numpy-1.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:e41e8951749c4b5c9a2dc5fdbc1a4eec6ab2a140fdae9b460b0f557eed870f4d"}, - {file = "numpy-1.22.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bece0a4a49e60e472a6d1f70ac6cdea00f9ab80ff01132f96bd970cdd8a9e5a9"}, - {file = "numpy-1.22.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:818b9be7900e8dc23e013a92779135623476f44a0de58b40c32a15368c01d471"}, - {file = "numpy-1.22.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47ee7a839f5885bc0c63a74aabb91f6f40d7d7b639253768c4199b37aede7982"}, - {file = "numpy-1.22.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a024181d7aef0004d76fb3bce2a4c9f2e67a609a9e2a6ff2571d30e9976aa383"}, - {file = "numpy-1.22.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f71d57cc8645f14816ae249407d309be250ad8de93ef61d9709b45a0ddf4050c"}, - {file = "numpy-1.22.0-cp38-cp38-win32.whl", hash = "sha256:283d9de87c0133ef98f93dfc09fad3fb382f2a15580de75c02b5bb36a5a159a5"}, - {file = "numpy-1.22.0-cp38-cp38-win_amd64.whl", hash = "sha256:2762331de395739c91f1abb88041f94a080cb1143aeec791b3b223976228af3f"}, - {file = "numpy-1.22.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:76ba7c40e80f9dc815c5e896330700fd6e20814e69da9c1267d65a4d051080f1"}, - {file = "numpy-1.22.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0cfe07133fd00b27edee5e6385e333e9eeb010607e8a46e1cd673f05f8596595"}, - {file = "numpy-1.22.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6ed0d073a9c54ac40c41a9c2d53fcc3d4d4ed607670b9e7b0de1ba13b4cbfe6f"}, - {file = "numpy-1.22.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41388e32e40b41dd56eb37fcaa7488b2b47b0adf77c66154d6b89622c110dfe9"}, - {file = "numpy-1.22.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b55b953a1bdb465f4dc181758570d321db4ac23005f90ffd2b434cc6609a63dd"}, - {file = "numpy-1.22.0-cp39-cp39-win32.whl", hash = "sha256:5a311ee4d983c487a0ab546708edbdd759393a3dc9cd30305170149fedd23c88"}, - {file = "numpy-1.22.0-cp39-cp39-win_amd64.whl", hash = "sha256:a97a954a8c2f046d3817c2bce16e3c7e9a9c2afffaf0400f5c16df5172a67c9c"}, - {file = "numpy-1.22.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb02929b0d6bfab4c48a79bd805bd7419114606947ec8284476167415171f55b"}, - {file = "numpy-1.22.0.zip", hash = "sha256:a955e4128ac36797aaffd49ab44ec74a71c11d6938df83b1285492d277db5397"}, -] - [[package]] name = "numpy" version = "1.26.4" @@ -3694,57 +3526,54 @@ sympy = "*" [[package]] name = "open-interpreter" -version = "0.2.5" +version = "0.2.6" description = "Let language models run code" optional = false python-versions = "<4,>=3.9" files = [ - {file = "open_interpreter-0.2.5-py3-none-any.whl", hash = "sha256:cfe97416e779e29d431900a25238a29afa78c8befd577072d92d3d38d8b6c782"}, - {file = "open_interpreter-0.2.5.tar.gz", hash = "sha256:67eef85daa23841ba008cdb58388937beab346cfa28a9b84fa319df1fbbddfcc"}, + {file = "open_interpreter-0.2.6-py3-none-any.whl", hash = "sha256:b00d99935bda0359f3be3a8003d66381ffcb315c2413714dcafaf516d001ed8c"}, + {file = "open_interpreter-0.2.6.tar.gz", hash = "sha256:bd4cf9455d526bfbc300d7e6f5e3c1c342078f862d496a861235fc2465447703"}, ] [package.dependencies] -aifs = ">=0.0.15,<0.0.16" astor = ">=0.8.1,<0.9.0" -fastapi = ">=0.110.0,<0.111.0" git-python = ">=1.0.3,<2.0.0" html2image = ">=2.0.4.3,<3.0.0.0" inquirer = ">=3.1.3,<4.0.0" ipykernel = ">=6.26.0,<7.0.0" jupyter-client = ">=8.6.0,<9.0.0" -litellm = ">=1.34.38,<2.0.0" +litellm = ">=1.35.32,<2.0.0" matplotlib = ">=3.8.2,<4.0.0" nltk = ">=3.8.1,<4.0.0" platformdirs = ">=4.2.0,<5.0.0" -posthog = ">=3.1.0,<4.0.0" -prompt-toolkit = ">=3.0.43,<4.0.0" psutil = ">=5.9.6,<6.0.0" pydantic = ">=2.6.4,<3.0.0" pyreadline3 = {version = ">=3.4.1,<4.0.0", markers = "sys_platform == \"win32\""} pyyaml = ">=6.0.1,<7.0.0" rich = ">=13.4.2,<14.0.0" -screeninfo = ">=0.8.1,<0.9.0" send2trash = ">=1.8.2,<2.0.0" +setuptools = "*" six = ">=1.16.0,<2.0.0" tiktoken = ">=0.6.0,<0.7.0" tokentrim = ">=0.1.13,<0.2.0" toml = ">=0.10.2,<0.11.0" -uvicorn = ">=0.27.0,<0.28.0" wget = ">=3.2,<4.0" [package.extras] -os = ["ipywidgets (>=8.1.2,<9.0.0)", "opencv-python (>=4.8.1.78,<5.0.0.0)", "plyer (>=2.1.0,<3.0.0)", "pyautogui (>=0.9.54,<0.10.0)", "pytesseract (>=0.3.10,<0.4.0)", "pywinctl (>=0.3,<0.4)", "sentence-transformers (>=2.5.1,<3.0.0)", "timm (>=0.9.16,<0.10.0)", "torch (>=2.2.1,<3.0.0)"] +local = ["einops (>=0.8.0,<0.9.0)", "opencv-python (>=4.8.1.78,<5.0.0.0)", "pytesseract (>=0.3.10,<0.4.0)", "torch (>=2.2.1,<3.0.0)", "torchvision (>=0.18.0,<0.19.0)", "transformers (>=4.40.1,<5.0.0)"] +os = ["ipywidgets (>=8.1.2,<9.0.0)", "opencv-python (>=4.8.1.78,<5.0.0.0)", "plyer (>=2.1.0,<3.0.0)", "pyautogui (>=0.9.54,<0.10.0)", "pytesseract (>=0.3.10,<0.4.0)", "pywinctl (>=0.3,<0.4)", "screeninfo (>=0.8.1,<0.9.0)", "sentence-transformers (>=2.5.1,<3.0.0)", "timm (>=0.9.16,<0.10.0)", "torch (>=2.2.1,<3.0.0)"] safe = ["semgrep (>=1.52.0,<2.0.0)", "yaspin (>=3.0.1,<4.0.0)"] +server = ["fastapi (>=0.111.0,<0.112.0)", "pynput (>=1.7.7,<2.0.0)", "uvicorn (>=0.30.1,<0.31.0)"] [[package]] name = "openai" -version = "1.13.3" +version = "1.30.5" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.13.3-py3-none-any.whl", hash = "sha256:5769b62abd02f350a8dd1a3a242d8972c947860654466171d60fb0972ae0a41c"}, - {file = "openai-1.13.3.tar.gz", hash = "sha256:ff6c6b3bc7327e715e4b3592a923a5a1c7519ff5dd764a83d69f633d49e77a7b"}, + {file = "openai-1.30.5-py3-none-any.whl", hash = "sha256:2ad95e926de0d2e09cde632a9204b0a6dca4a03c2cdcc84329b01f355784355a"}, + {file = "openai-1.30.5.tar.gz", hash = "sha256:5366562eb2c5917e6116ae0391b7ae6e3acd62b0ae3f565ada32b35d8fcfa106"}, ] [package.dependencies] @@ -3795,54 +3624,6 @@ files = [ {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] -[[package]] -name = "pandas" -version = "1.5.3" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, - {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, - {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"}, - {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354"}, - {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23"}, - {file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc"}, - {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae"}, - {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6"}, - {file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792"}, - {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7"}, - {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf"}, - {file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51"}, - {file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a"}, - {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0"}, - {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5"}, - {file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a"}, - {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"}, - {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.20.3", markers = "python_version < \"3.10\""}, - {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, - {version = ">=1.21.0", markers = "python_version >= \"3.10\" and python_version < \"3.11\""}, -] -python-dateutil = ">=2.8.1" -pytz = ">=2020.1" - -[package.extras] -test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] - [[package]] name = "parso" version = "0.8.4" @@ -4021,29 +3802,6 @@ progress = ["tqdm (>=4.41.0,<5.0.0)"] sftp = ["paramiko (>=2.7.0)"] xxhash = ["xxhash (>=1.4.3)"] -[[package]] -name = "posthog" -version = "3.5.0" -description = "Integrate PostHog into any python application." -optional = false -python-versions = "*" -files = [ - {file = "posthog-3.5.0-py2.py3-none-any.whl", hash = "sha256:3c672be7ba6f95d555ea207d4486c171d06657eb34b3ce25eb043bfe7b6b5b76"}, - {file = "posthog-3.5.0.tar.gz", hash = "sha256:8f7e3b2c6e8714d0c0c542a2109b83a7549f63b7113a133ab2763a89245ef2ef"}, -] - -[package.dependencies] -backoff = ">=1.10.0" -monotonic = ">=1.5" -python-dateutil = ">2.1" -requests = ">=2.7,<3.0" -six = ">=1.5" - -[package.extras] -dev = ["black", "flake8", "flake8-print", "isort", "pre-commit"] -sentry = ["django", "sentry-sdk"] -test = ["coverage", "flake8", "freezegun (==0.3.15)", "mock (>=2.0.0)", "pylint", "pytest", "pytest-timeout"] - [[package]] name = "pre-commit" version = "3.7.1" @@ -7130,17 +6888,6 @@ files = [ {file = "pyperclip-1.8.2.tar.gz", hash = "sha256:105254a8b04934f0bc84e9c24eb360a591aaf6535c9def5f29d92af107a9bf57"}, ] -[[package]] -name = "pypinyin" -version = "0.51.0" -description = "汉字拼音转换模块/工具." -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, <4" -files = [ - {file = "pypinyin-0.51.0-py2.py3-none-any.whl", hash = "sha256:ae8878f08fee15d0c5c11053a737e68a4158c22c63dc632b4de060af5c95bf84"}, - {file = "pypinyin-0.51.0.tar.gz", hash = "sha256:cede34fc35a79ef6c799f161e2c280e7b6755ee072fb741cae5ce2a60c4ae0c5"}, -] - [[package]] name = "pypiwin32" version = "223" @@ -7691,26 +7438,27 @@ webrtcvad = "2.0.10" [[package]] name = "realtimetts" -version = "0.3.46" +version = "0.4.1" description = "*Stream text into audio with an easy-to-use, highly configurable library delivering voice output with minimal latency." optional = false python-versions = "<3.12,>=3.9" files = [ - {file = "RealTimeTTS-0.3.46-py3-none-any.whl", hash = "sha256:40b39b0cd38bfae22093df14069ce77d121992c5f9383690abad55bd3f2923c6"}, - {file = "RealTimeTTS-0.3.46.tar.gz", hash = "sha256:e4a618d7784606e7cbc661c392700cd0f691c70314661f1b7f89eb153b5e655d"}, + {file = "RealTimeTTS-0.4.1-py3-none-any.whl", hash = "sha256:916483016ffabbf7c3e6fb489dc1bd693ff08fb4cd139ea634cacc88bce7c7d2"}, + {file = "RealTimeTTS-0.4.1.tar.gz", hash = "sha256:4564400c5a96a3e79b251956f2585849ca1494cdbc36737733b86f64e71e4032"}, ] [package.dependencies] -azure-cognitiveservices-speech = "1.36.0" -elevenlabs = "0.2.27" -openai = "1.13.3" +azure-cognitiveservices-speech = "1.37.0" +coqui-tts = "0.24.1" +elevenlabs = "1.2.2" +gtts = "2.5.1" +openai = "1.30.5" PyAudio = "0.2.14" pydub = "0.25.1" pyttsx3 = "2.90" -requests = "2.31.0" +requests = "2.32.3" stream2sentence = "0.2.3" -tqdm = "4.66.2" -TTS = "0.22.0" +tqdm = "4.66.4" [[package]] name = "regex" @@ -7802,13 +7550,13 @@ files = [ [[package]] name = "requests" -version = "2.31.0" +version = "2.32.3" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] @@ -8035,48 +7783,6 @@ install = ["joblib (>=1.2.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)", "threadpoo maintenance = ["conda-lock (==2.5.6)"] tests = ["black (>=24.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.9)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "polars (>=0.20.23)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pyarrow (>=12.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.2.1)", "scikit-image (>=0.17.2)"] -[[package]] -name = "scipy" -version = "1.11.4" -description = "Fundamental algorithms for scientific computing in Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "scipy-1.11.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc9a714581f561af0848e6b69947fda0614915f072dfd14142ed1bfe1b806710"}, - {file = "scipy-1.11.4-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:cf00bd2b1b0211888d4dc75656c0412213a8b25e80d73898083f402b50f47e41"}, - {file = "scipy-1.11.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9999c008ccf00e8fbcce1236f85ade5c569d13144f77a1946bef8863e8f6eb4"}, - {file = "scipy-1.11.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:933baf588daa8dc9a92c20a0be32f56d43faf3d1a60ab11b3f08c356430f6e56"}, - {file = "scipy-1.11.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8fce70f39076a5aa62e92e69a7f62349f9574d8405c0a5de6ed3ef72de07f446"}, - {file = "scipy-1.11.4-cp310-cp310-win_amd64.whl", hash = "sha256:6550466fbeec7453d7465e74d4f4b19f905642c89a7525571ee91dd7adabb5a3"}, - {file = "scipy-1.11.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f313b39a7e94f296025e3cffc2c567618174c0b1dde173960cf23808f9fae4be"}, - {file = "scipy-1.11.4-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:1b7c3dca977f30a739e0409fb001056484661cb2541a01aba0bb0029f7b68db8"}, - {file = "scipy-1.11.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00150c5eae7b610c32589dda259eacc7c4f1665aedf25d921907f4d08a951b1c"}, - {file = "scipy-1.11.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:530f9ad26440e85766509dbf78edcfe13ffd0ab7fec2560ee5c36ff74d6269ff"}, - {file = "scipy-1.11.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5e347b14fe01003d3b78e196e84bd3f48ffe4c8a7b8a1afbcb8f5505cb710993"}, - {file = "scipy-1.11.4-cp311-cp311-win_amd64.whl", hash = "sha256:acf8ed278cc03f5aff035e69cb511741e0418681d25fbbb86ca65429c4f4d9cd"}, - {file = "scipy-1.11.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:028eccd22e654b3ea01ee63705681ee79933652b2d8f873e7949898dda6d11b6"}, - {file = "scipy-1.11.4-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2c6ff6ef9cc27f9b3db93a6f8b38f97387e6e0591600369a297a50a8e96e835d"}, - {file = "scipy-1.11.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b030c6674b9230d37c5c60ab456e2cf12f6784596d15ce8da9365e70896effc4"}, - {file = "scipy-1.11.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad669df80528aeca5f557712102538f4f37e503f0c5b9541655016dd0932ca79"}, - {file = "scipy-1.11.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ce7fff2e23ab2cc81ff452a9444c215c28e6305f396b2ba88343a567feec9660"}, - {file = "scipy-1.11.4-cp312-cp312-win_amd64.whl", hash = "sha256:36750b7733d960d7994888f0d148d31ea3017ac15eef664194b4ef68d36a4a97"}, - {file = "scipy-1.11.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e619aba2df228a9b34718efb023966da781e89dd3d21637b27f2e54db0410d7"}, - {file = "scipy-1.11.4-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:f3cd9e7b3c2c1ec26364856f9fbe78695fe631150f94cd1c22228456404cf1ec"}, - {file = "scipy-1.11.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d10e45a6c50211fe256da61a11c34927c68f277e03138777bdebedd933712fea"}, - {file = "scipy-1.11.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91af76a68eeae0064887a48e25c4e616fa519fa0d38602eda7e0f97d65d57937"}, - {file = "scipy-1.11.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6df1468153a31cf55ed5ed39647279beb9cfb5d3f84369453b49e4b8502394fd"}, - {file = "scipy-1.11.4-cp39-cp39-win_amd64.whl", hash = "sha256:ee410e6de8f88fd5cf6eadd73c135020bfbbbdfcd0f6162c36a7638a1ea8cc65"}, - {file = "scipy-1.11.4.tar.gz", hash = "sha256:90a2b78e7f5733b9de748f589f09225013685f9b218275257f8a8168ededaeaa"}, -] - -[package.dependencies] -numpy = ">=1.21.6,<1.28.0" - -[package.extras] -dev = ["click", "cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] -doc = ["jupytext", "matplotlib (>2)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] -test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] - [[package]] name = "scipy" version = "1.13.1" @@ -8119,21 +7825,6 @@ dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pyde doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] -[[package]] -name = "screeninfo" -version = "0.8.1" -description = "Fetch location and size of physical screens." -optional = false -python-versions = ">=3.6.2,<4.0.0" -files = [ - {file = "screeninfo-0.8.1-py3-none-any.whl", hash = "sha256:e97d6b173856edcfa3bd282f81deb528188aff14b11ec3e195584e7641be733c"}, - {file = "screeninfo-0.8.1.tar.gz", hash = "sha256:9983076bcc7e34402a1a9e4d7dabf3729411fd2abb3f3b4be7eba73519cd2ed1"}, -] - -[package.dependencies] -Cython = {version = "*", markers = "sys_platform == \"darwin\""} -pyobjc-framework-Cocoa = {version = "*", markers = "sys_platform == \"darwin\""} - [[package]] name = "send2trash" version = "1.8.3" @@ -8150,6 +7841,56 @@ nativelib = ["pyobjc-framework-Cocoa", "pywin32"] objc = ["pyobjc-framework-Cocoa"] win32 = ["pywin32"] +[[package]] +name = "sentry-sdk" +version = "2.4.0" +description = "Python client for Sentry (https://sentry.io)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "sentry_sdk-2.4.0-py2.py3-none-any.whl", hash = "sha256:a42b70981cd4ed7da3c85d0360502d2ac932a15a4a420b360e1ebded2fc19a92"}, + {file = "sentry_sdk-2.4.0.tar.gz", hash = "sha256:62b9bb0489e731ecbce008f9647899b51d220067a75c3adfd46f8187660c0029"}, +] + +[package.dependencies] +certifi = "*" +urllib3 = ">=1.26.11" + +[package.extras] +aiohttp = ["aiohttp (>=3.5)"] +anthropic = ["anthropic (>=0.16)"] +arq = ["arq (>=0.23)"] +asyncpg = ["asyncpg (>=0.23)"] +beam = ["apache-beam (>=2.12)"] +bottle = ["bottle (>=0.12.13)"] +celery = ["celery (>=3)"] +celery-redbeat = ["celery-redbeat (>=2)"] +chalice = ["chalice (>=1.16.0)"] +clickhouse-driver = ["clickhouse-driver (>=0.2.0)"] +django = ["django (>=1.8)"] +falcon = ["falcon (>=1.4)"] +fastapi = ["fastapi (>=0.79.0)"] +flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"] +grpcio = ["grpcio (>=1.21.1)", "protobuf (>=3.8.0)"] +httpx = ["httpx (>=0.16.0)"] +huey = ["huey (>=2)"] +huggingface-hub = ["huggingface-hub (>=0.22)"] +langchain = ["langchain (>=0.0.210)"] +loguru = ["loguru (>=0.5)"] +openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"] +opentelemetry = ["opentelemetry-distro (>=0.35b0)"] +opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"] +pure-eval = ["asttokens", "executing", "pure-eval"] +pymongo = ["pymongo (>=3.1)"] +pyspark = ["pyspark (>=2.4.4)"] +quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] +rq = ["rq (>=0.6)"] +sanic = ["sanic (>=0.8)"] +sqlalchemy = ["sqlalchemy (>=1.2)"] +starlette = ["starlette (>=0.19.1)"] +starlite = ["starlite (>=1.48)"] +tornado = ["tornado (>=5)"] + [[package]] name = "setuptools" version = "70.0.0" @@ -9100,13 +8841,13 @@ files = [ [[package]] name = "tqdm" -version = "4.66.2" +version = "4.66.4" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.2-py3-none-any.whl", hash = "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9"}, - {file = "tqdm-4.66.2.tar.gz", hash = "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531"}, + {file = "tqdm-4.66.4-py3-none-any.whl", hash = "sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644"}, + {file = "tqdm-4.66.4.tar.gz", hash = "sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb"}, ] [package.dependencies] @@ -9118,30 +8859,6 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] -[[package]] -name = "trainer" -version = "0.0.36" -description = "General purpose model trainer for PyTorch that is more flexible than it should be, by 🐸Coqui." -optional = false -python-versions = ">=3.6.0, <3.12" -files = [ - {file = "trainer-0.0.36-py3-none-any.whl", hash = "sha256:d986702c6d6d988e74a4f8da0f9c11a8c7d89274a11436957e91217a19b487a6"}, - {file = "trainer-0.0.36.tar.gz", hash = "sha256:3afff4d1ce70f828d32ba698331768bca5be1cc21a60c2b8acd8fa117eb95c5a"}, -] - -[package.dependencies] -coqpit = "*" -fsspec = "*" -psutil = "*" -soundfile = "*" -tensorboard = "*" -torch = ">=1.7" - -[package.extras] -all = ["accelerate", "black", "coqpit", "coverage", "fsspec", "isort", "psutil", "pylint", "pytest", "soundfile", "tensorboard", "torch (>=1.7)", "torchvision"] -dev = ["accelerate", "black", "coverage", "isort", "pylint", "pytest"] -test = ["torchvision"] - [[package]] name = "traitlets" version = "5.14.3" @@ -9248,69 +8965,6 @@ build = ["cmake (>=3.20)", "lit"] tests = ["autopep8", "flake8", "isort", "numpy", "pytest", "scipy (>=1.7.1)", "torch"] tutorials = ["matplotlib", "pandas", "tabulate", "torch"] -[[package]] -name = "tts" -version = "0.22.0" -description = "Deep learning for Text to Speech by Coqui." -optional = false -python-versions = ">=3.9.0, <3.12" -files = [ - {file = "TTS-0.22.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:6dce2e3a9434bd4d3815b51f4080ccdddd82466cf40fc0e0a70eff14b7cc1d3f"}, - {file = "TTS-0.22.0-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:332cdf63a7d9f91dcb38c50c3e778a8080b3551cd4e1a901cfc58acb90cd3f58"}, - {file = "TTS-0.22.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:9d75e27e5998f379d72f04192e3cf0f5cf939c08c0f71bb74ef1cf9ccc4fa499"}, - {file = "TTS-0.22.0.tar.gz", hash = "sha256:b91119da7ff2ae7b3dae7328edf9af4db3b48c40eb4ce15d11ed8f5ee9bd7086"}, -] - -[package.dependencies] -aiohttp = ">=3.8.1" -anyascii = ">=0.3.0" -bangla = "*" -bnnumerizer = "*" -bnunicodenormalizer = "*" -coqpit = ">=0.0.16" -cython = ">=0.29.30" -einops = ">=0.6.0" -encodec = ">=0.1.1" -flask = ">=2.0.1" -fsspec = ">=2023.6.0" -g2pkk = ">=0.1.1" -gruut = {version = "2.2.3", extras = ["de", "es", "fr"]} -hangul-romanize = "*" -inflect = ">=5.6.0" -jamo = "*" -jieba = "*" -librosa = ">=0.10.0" -matplotlib = ">=3.7.0" -nltk = "*" -num2words = "*" -numba = {version = ">=0.57.0", markers = "python_version >= \"3.9\""} -numpy = [ - {version = "1.22.0", markers = "python_version <= \"3.10\""}, - {version = ">=1.24.3", markers = "python_version > \"3.10\""}, -] -packaging = ">=23.1" -pandas = ">=1.4,<2.0" -pypinyin = "*" -pysbd = ">=0.3.4" -pyyaml = ">=6.0" -scikit-learn = ">=1.3.0" -scipy = ">=1.11.2" -soundfile = ">=0.12.0" -spacy = {version = ">=3", extras = ["ja"]} -torch = ">=2.1" -torchaudio = "*" -tqdm = ">=4.64.1" -trainer = ">=0.0.32" -transformers = ">=4.33.0" -umap-learn = ">=0.5.1" -unidecode = ">=1.3.2" - -[package.extras] -all = ["black", "bokeh (==1.4.0)", "coverage", "cutlet", "isort", "mecab-python3 (==1.0.6)", "nose2", "pylint (==2.10.2)", "unidic-lite (==1.0.8)"] -dev = ["black", "coverage", "isort", "nose2", "pylint (==2.10.2)"] -ja = ["cutlet", "mecab-python3 (==1.0.6)", "unidic-lite (==1.0.8)"] -notebooks = ["bokeh (==1.4.0)"] - [[package]] name = "typeguard" version = "4.3.0" @@ -9428,17 +9082,6 @@ parametric-umap = ["tensorflow (>=2.1)"] plot = ["bokeh", "colorcet", "datashader", "holoviews", "matplotlib", "pandas", "scikit-image", "seaborn"] tbb = ["tbb (>=2019.0)"] -[[package]] -name = "unidecode" -version = "1.3.8" -description = "ASCII transliterations of Unicode text" -optional = false -python-versions = ">=3.5" -files = [ - {file = "Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39"}, - {file = "Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4"}, -] - [[package]] name = "urllib3" version = "2.2.1" @@ -9811,4 +9454,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "4485960e763dd7bfc94c700a5858750a1d6abb660455fe6ee51896779bfac4f5" +content-hash = "de07d24f74d39335d2c89d83cbe681bacbeaeffdb30227cb9f6955dc4614dfca" diff --git a/software/pyproject.toml b/software/pyproject.toml index 44498175..ab54d5c6 100644 --- a/software/pyproject.toml +++ b/software/pyproject.toml @@ -33,19 +33,20 @@ python-crontab = "^3.0.0" inquirer = "^3.2.4" pyqrcode = "^1.2.1" realtimestt = "^0.1.12" -realtimetts = "^0.3.44" +realtimetts = "^0.4.1" keyboard = "^0.13.5" pyautogui = "^0.9.54" ctranslate2 = "4.1.0" py3-tts = "^3.5" -elevenlabs = "0.2.27" +elevenlabs = "1.2.2" groq = "^0.5.0" -open-interpreter = "^0.2.5" +open-interpreter = "^0.2.6" litellm = "1.35.35" -openai = "1.13.3" +openai = "1.30.5" pywebview = "*" pyobjc = "*" +sentry-sdk = "^2.4.0" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" diff --git a/software/source/clients/base_device.py b/software/source/clients/base_device.py index 9013e07b..923ee9e1 100644 --- a/software/source/clients/base_device.py +++ b/software/source/clients/base_device.py @@ -2,6 +2,7 @@ load_dotenv() # take environment variables from .env. +import subprocess import os import sys import asyncio @@ -46,7 +47,7 @@ CHUNK = 1024 # Record in chunks of 1024 samples FORMAT = pyaudio.paInt16 # 16 bits per sample CHANNELS = 1 # Mono -RATE = 44100 # Sample rate +RATE = 16000 # Sample rate RECORDING = False # Flag to control recording state SPACEBAR_PRESSED = False # Flag to track spacebar press state @@ -86,10 +87,10 @@ class Device: def __init__(self): self.pressed_keys = set() self.captured_images = [] - self.audiosegments = [] + self.audiosegments = asyncio.Queue() self.server_url = "" self.ctrl_pressed = False - # self.latency = None + self.playback_latency = None def fetch_image_from_camera(self, camera_index=CAMERA_DEVICE_INDEX): """Captures an image from the specified camera device and saves it to a temporary file. Adds the image to the captured_images list.""" @@ -153,14 +154,26 @@ async def play_audiosegments(self): """Plays them sequentially.""" while True: try: - for audio in self.audiosegments: - # if self.latency: - # elapsed_time = time.time() - self.latency - # print(f"Time from request to playback: {elapsed_time} seconds") - # self.latency = None - play(audio) - self.audiosegments.remove(audio) - await asyncio.sleep(0.1) + audio = await self.audiosegments.get() + # print("got audio segment!!!!") + if self.playback_latency: + elapsed_time = time.time() - self.playback_latency + print(f"Time from request to playback: {elapsed_time} seconds") + self.playback_latency = None + + args = ["ffplay", "-autoexit", "-", "-nodisp"] + proc = subprocess.Popen( + args=args, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + out, err = proc.communicate(input=audio) + proc.poll() + + # play(audio) + # self.audiosegments.remove(audio) + # await asyncio.sleep(0.1) except asyncio.exceptions.CancelledError: # This happens once at the start? pass @@ -208,7 +221,7 @@ def record_audio(self): stream.stop_stream() stream.close() print("Recording stopped.") - # self.latency = time.time() + self.playback_latency = time.time() duration = wav_file.getnframes() / RATE if duration < 0.3: @@ -315,18 +328,21 @@ def on_release(self, key): async def message_sender(self, websocket): while True: - message = await asyncio.get_event_loop().run_in_executor( - None, send_queue.get - ) + try: + message = await asyncio.get_event_loop().run_in_executor( + None, send_queue.get + ) - if isinstance(message, bytes): - await websocket.send(message) + if isinstance(message, bytes): + await websocket.send(message) - else: - await websocket.send(json.dumps(message)) + else: + await websocket.send(json.dumps(message)) - send_queue.task_done() - await asyncio.sleep(0.01) + send_queue.task_done() + await asyncio.sleep(0.01) + except: + traceback.print_exc() async def websocket_communication(self, WS_URL): print("websocket communication was called!!!!") @@ -343,7 +359,7 @@ async def exec_ws_communication(websocket): asyncio.create_task(self.message_sender(websocket)) while True: - await asyncio.sleep(0.01) + await asyncio.sleep(0.0001) chunk = await websocket.recv() logger.debug(f"Got this message from the server: {type(chunk)} {chunk}") @@ -351,31 +367,38 @@ async def exec_ws_communication(websocket): if type(chunk) == str: chunk = json.loads(chunk) - message = accumulator.accumulate(chunk) + # message = accumulator.accumulate(chunk) + message = chunk if message == None: # Will be None until we have a full message ready continue # At this point, we have our message + # print("checkpoint reached!", message) + if isinstance(message, bytes): - if message["type"] == "audio" and message["format"].startswith("bytes"): + # if message["type"] == "audio" and message["format"].startswith("bytes"): # Convert bytes to audio file - audio_bytes = message["content"] + # audio_bytes = message["content"] + audio_bytes = message # Create an AudioSegment instance with the raw data + """ audio = AudioSegment( # raw audio data (bytes) data=audio_bytes, # signed 16-bit little-endian format sample_width=2, - # 16,000 Hz frame rate - frame_rate=16000, + # 24,000 Hz frame rate + frame_rate=24000, # mono sound channels=1, ) + """ - self.audiosegments.append(audio) + # print("audio segment was created") + await self.audiosegments.put(audio_bytes) # Run the code if that's the client's job if os.getenv("CODE_RUNNER") == "client": @@ -399,6 +422,7 @@ async def exec_ws_communication(websocket): while True: try: async with websockets.connect(WS_URL) as websocket: + print("awaiting exec_ws_communication") await exec_ws_communication(websocket) except: logger.info(traceback.format_exc()) @@ -410,7 +434,7 @@ async def exec_ws_communication(websocket): async def start_async(self): print("start async was called!!!!!") # Configuration for WebSocket - WS_URL = f"ws://{self.server_url}" + WS_URL = f"ws://{self.server_url}/ws" # Start the WebSocket communication asyncio.create_task(self.websocket_communication(WS_URL)) diff --git a/software/source/server/async_interpreter.py b/software/source/server/async_interpreter.py index e601e561..b4a11d3f 100644 --- a/software/source/server/async_interpreter.py +++ b/software/source/server/async_interpreter.py @@ -12,7 +12,14 @@ ### from pynput import keyboard -from RealtimeTTS import TextToAudioStream, OpenAIEngine, CoquiEngine +from RealtimeTTS import ( + TextToAudioStream, + OpenAIEngine, + CoquiEngine, + ElevenlabsEngine, + SystemEngine, + GTTSEngine, +) from RealtimeSTT import AudioToTextRecorder import time import asyncio @@ -21,11 +28,14 @@ class AsyncInterpreter: def __init__(self, interpreter): + self.stt_latency = None + self.tts_latency = None + self.interpreter_latency = None self.interpreter = interpreter # STT self.stt = AudioToTextRecorder( - model="tiny", spinner=False, use_microphone=False + model="tiny.en", spinner=False, use_microphone=False ) self.stt.stop() # It needs this for some reason @@ -34,6 +44,16 @@ def __init__(self, interpreter): engine = CoquiEngine() elif self.interpreter.tts == "openai": engine = OpenAIEngine() + elif self.interpreter.tts == "gtts": + engine = GTTSEngine() + elif self.interpreter.tts == "elevenlabs": + engine = ElevenlabsEngine( + api_key="sk_077cb1cabdf67e62b85f8782e66e5d8e11f78b450c7ce171" + ) + elif self.interpreter.tts == "system": + engine = SystemEngine() + else: + raise ValueError(f"Unsupported TTS engine: {self.interpreter.tts}") self.tts = TextToAudioStream(engine) self.active_chat_messages = [] @@ -112,7 +132,11 @@ async def run(self): # print("INPUT QUEUE:", input_queue) # message = [i for i in input_queue if i["type"] == "message"][0]["content"] + start_stt = time.time() message = self.stt.text() + end_stt = time.time() + self.stt_latency = end_stt - start_stt + print("STT LATENCY", self.stt_latency) # print(message) @@ -141,7 +165,7 @@ def generate(message): # Experimental: The AI voice sounds better with replacements like these, but it should happen at the TTS layer # content = content.replace(". ", ". ... ").replace(", ", ", ... ").replace("!", "! ... ").replace("?", "? ... ") - + print("yielding this", content) yield content # Handle code blocks @@ -172,17 +196,24 @@ def generate(message): ) # Send a completion signal - + end_interpreter = time.time() + self.interpreter_latency = end_interpreter - start_interpreter + print("INTERPRETER LATENCY", self.interpreter_latency) # self.add_to_output_queue_sync({"role": "server","type": "completion", "content": "DONE"}) # Feed generate to RealtimeTTS self.add_to_output_queue_sync( {"role": "assistant", "type": "audio", "format": "bytes.wav", "start": True} ) - self.tts.feed(generate(message)) + start_interpreter = time.time() + text_iterator = generate(message) + + self.tts.feed(text_iterator) self.tts.play_async(on_audio_chunk=self.on_tts_chunk, muted=True) + while True: if self.tts.is_playing(): + start_tts = time.time() break await asyncio.sleep(0.1) while True: @@ -197,6 +228,9 @@ def generate(message): "end": True, } ) + end_tts = time.time() + self.tts_latency = end_tts - start_tts + print("TTS LATENCY", self.tts_latency) break async def _on_tts_chunk_async(self, chunk): @@ -204,6 +238,7 @@ async def _on_tts_chunk_async(self, chunk): await self._add_to_queue(self._output_queue, chunk) def on_tts_chunk(self, chunk): + # print("ye") asyncio.run(self._on_tts_chunk_async(chunk)) async def output(self): diff --git a/software/source/server/async_server.py b/software/source/server/async_server.py index c2f33644..ff8a466f 100644 --- a/software/source/server/async_server.py +++ b/software/source/server/async_server.py @@ -12,6 +12,18 @@ import argparse import os +# import sentry_sdk + +base_interpreter.system_message = ( + "You are a helpful assistant that can answer questions and help with tasks." +) +base_interpreter.computer.import_computer_api = False +base_interpreter.llm.model = "groq/mixtral-8x7b-32768" +base_interpreter.llm.api_key = ( + "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" +) +base_interpreter.llm.supports_functions = False + os.environ["STT_RUNNER"] = "server" os.environ["TTS_RUNNER"] = "server" @@ -20,11 +32,24 @@ parser.add_argument("--port", type=int, default=8000, help="Port to run on.") args = parser.parse_args() -base_interpreter.tts = "openai" -base_interpreter.llm.model = "gpt-4-turbo" +base_interpreter.tts = "elevenlabs" async def main(): + """ + sentry_sdk.init( + dsn="https://a1465f62a31c7dfb23e1616da86341e9@o4506046614667264.ingest.us.sentry.io/4507374662385664", + enable_tracing=True, + # Set traces_sample_rate to 1.0 to capture 100% + # of transactions for performance monitoring. + traces_sample_rate=1.0, + # Set profiles_sample_rate to 1.0 to profile 100% + # of sampled transactions. + # We recommend adjusting this value in production. + profiles_sample_rate=1.0, + ) + """ + interpreter = AsyncInterpreter(base_interpreter) app = FastAPI() @@ -51,6 +76,9 @@ async def websocket_endpoint(websocket: WebSocket): async def receive_input(): while True: + if websocket.client_state == "DISCONNECTED": + break + data = await websocket.receive() if isinstance(data, bytes): @@ -65,19 +93,23 @@ async def receive_input(): async def send_output(): while True: output = await interpreter.output() + if isinstance(output, bytes): + # print(f"Sending {len(output)} bytes of audio data.") await websocket.send_bytes(output) # we dont send out bytes rn, no TTS - pass + elif isinstance(output, dict): + # print("sending text") await websocket.send_text(json.dumps(output)) - await asyncio.gather(receive_input(), send_output()) + await asyncio.gather(send_output(), receive_input()) except Exception as e: print(f"WebSocket connection closed with exception: {e}") traceback.print_exc() finally: - await websocket.close() + if not websocket.client_state == "DISCONNECTED": + await websocket.close() config = Config(app, host="0.0.0.0", port=8000, lifespan="on") server = Server(config) diff --git a/software/source/server/server.py b/software/source/server/server.py index a906ba94..d15ca8d3 100644 --- a/software/source/server/server.py +++ b/software/source/server/server.py @@ -23,6 +23,7 @@ import base64 import shutil from ..utils.print_markdown import print_markdown +import time os.environ["STT_RUNNER"] = "server" os.environ["TTS_RUNNER"] = "server" @@ -383,6 +384,7 @@ async def stream_tts_to_device(sentence, mobile: bool): def stream_tts(sentence, mobile: bool): + audio_file = tts(sentence, mobile) # Read the entire WAV file diff --git a/software/start.py b/software/start.py index 8ad7b643..5f99fef7 100644 --- a/software/start.py +++ b/software/start.py @@ -5,7 +5,7 @@ import os import importlib from source.server.tunnel import create_tunnel -from source.server.server import main +from source.server.async_server import main from source.server.utils.local_mode import select_local_model import signal @@ -152,18 +152,18 @@ def handle_exit(signum, frame): target=loop.run_until_complete, args=( main( - server_host, - server_port, - llm_service, - model, - llm_supports_vision, - llm_supports_functions, - context_window, - max_tokens, - temperature, - tts_service, - stt_service, - mobile, + # server_host, + # server_port, + # llm_service, + # model, + # llm_supports_vision, + # llm_supports_functions, + # context_window, + # max_tokens, + # temperature, + # tts_service, + # stt_service, + # mobile, ), ), ) @@ -196,7 +196,7 @@ def handle_exit(signum, frame): module = importlib.import_module( f".clients.{client_type}.device", package="source" ) - + server_url = "0.0.0.0:8000" client_thread = threading.Thread(target=module.main, args=[server_url]) print("client thread started") client_thread.start()