Merge pull request #98 from daily-co/use-pip-features

use pip optional dependencies
This commit is contained in:
Aleix Conchillo Flaqué
2024-04-05 01:00:21 +08:00
committed by GitHub
31 changed files with 993 additions and 122 deletions

44
.github/workflows/build.yaml vendored Normal file
View File

@@ -0,0 +1,44 @@
name: build
on:
workflow_dispatch:
push:
branches:
- main
pull_request:
branches:
- "**"
paths-ignore:
- "docs/**"
concurrency:
group: build-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build:
name: "Build and Install"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
id: setup_python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Setup virtual environment
run: |
python -m venv .venv
- name: Install basic Python dependencies
run: |
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r dev-requirements.txt
- name: Build project
run: |
source .venv/bin/activate
python -m build
- name: Install project and other Python dependencies
run: |
source .venv/bin/activate
pip install --editable .

View File

@@ -29,11 +29,11 @@ jobs:
- name: Setup virtual environment
run: |
python -m venv .venv
- name: Install basic Python dependencies
- name: Install development Python dependencies
run: |
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r dev-requirements.txt
- name: autopep8
id: autopep8
run: |

69
.github/workflows/publish.yaml vendored Normal file
View File

@@ -0,0 +1,69 @@
name: publish
on:
workflow_dispatch:
inputs:
gitref:
type: string
description: "what git ref to build"
required: true
jobs:
build:
name: "Build and upload wheels"
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.gitref }}
- name: Set up Python
id: setup_python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Cache virtual environment
uses: actions/cache@v3
with:
# We are hashing requirements-dev.txt and requirements-extra.txt which
# contain all dependencies needed to run the tests and examples.
key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }}
path: .venv
- name: Install system packages
run: sudo apt-get install -y portaudio19-dev
- name: Setup virtual environment
run: |
python -m venv .venv
- name: Install basic Python dependencies
run: |
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r linux-py3.10-requirements.txt -r dev-requirements.txt
- name: Build project
run: |
source .venv/bin/activate
python -m build
- name: Upload wheels
uses: actions/upload-artifact@v4
with:
path: ./dist
publish-to-pypi:
name: "Publish to PyPI"
runs-on: ubuntu-latest
needs: [ build ]
environment:
name: pypi
url: https://pypi.org/p/dailyai
permissions:
id-token: write
steps:
- name: Download wheels
uses: actions/download-artifact@v4
with:
path: ./dist
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
verbose: true
print-hash: true

59
.github/workflows/publish_test.yaml vendored Normal file
View File

@@ -0,0 +1,59 @@
name: publish-test
on:
workflow_dispatch:
push:
branches:
- main
jobs:
build:
name: "Build and upload wheels"
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.gitref }}
- name: Set up Python
id: setup_python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Setup virtual environment
run: |
python -m venv .venv
- name: Install basic Python dependencies
run: |
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r dev-requirements.txt
- name: Build project
run: |
source .venv/bin/activate
python -m build
- name: Upload wheels
uses: actions/upload-artifact@v4
with:
path: ./dist
publish-to-pypi:
name: "Test publish to PyPI"
runs-on: ubuntu-latest
needs: [ build ]
environment:
name: pypi
url: https://pypi.org/p/dailyai
permissions:
id-token: write
steps:
- name: Download wheels
uses: actions/download-artifact@v4
with:
path: ./dist
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
verbose: true
print-hash: true
repository-url: https://test.pypi.org/legacy/

View File

@@ -29,9 +29,9 @@ jobs:
- name: Cache virtual environment
uses: actions/cache@v3
with:
# TODO: we are hashing requirements.txt but that doesn't contain all
# our dependencies pinned.
key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }}
# We are hashing requirements-dev.txt and requirements-extra.txt which
# contain all dependencies needed to run the tests and examples.
key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }}
path: .venv
- name: Install system packages
run: sudo apt-get install -y portaudio19-dev
@@ -42,17 +42,8 @@ jobs:
run: |
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Build project
run: |
source .venv/bin/activate
python -m build
- name: Install project and other Python dependencies
run: |
source .venv/bin/activate
pip install --editable .
pip install -r linux-py3.10-requirements.txt -r dev-requirements.txt
- name: Test with pytest
run: |
source .venv/bin/activate
pip install pytest
pytest --doctest-modules --ignore-glob="*to_be_updated*" src tests

View File

@@ -4,12 +4,8 @@ Build things like this:
[![AI-powered voice patient intake for healthcare](https://img.youtube.com/vi/lDevgsp9vn0/0.jpg)](https://www.youtube.com/watch?v=lDevgsp9vn0)
**`dailyai` started as a toolkit for implementing generative AI voice bots.** Things like personal coaches, meeting assistants, story-telling toys for kids, customer support bots, and snarky social companions.
In 2023 a *lot* of us got excited about the possibility of having open-ended conversations with LLMs. It became clear pretty quickly that we were all solving the same [low-level problems](https://www.daily.co/blog/how-to-talk-to-an-llm-with-your-voice/):
- low-latency, reliable audio transport
- echo cancellation
@@ -48,7 +44,7 @@ If you'd like to [implement a service]((https://github.com/daily-co/daily-ai-sdk
## Getting started
Today, the easiest way to get started with `dailyai` is to use [Daily](https://www.daily.co/) as your transport service. This toolkit started life as an internal SDK at Daily and millions of minutes of AI conversation have been served using it and its earlier prototype incarnations. (The [transport base class](https://github.com/daily-co/daily-ai-sdk/blob/main/src/dailyai/services/base_transport_service.py) is easy to extend, though, so feel free to submit PRs if you'd like to implement another transport service.)
Today, the easiest way to get started with `dailyai` is to use [Daily](https://www.daily.co/) as your transport service. This toolkit started life as an internal SDK at Daily and millions of minutes of AI conversation have been served using it and its earlier prototype incarnations. (The [transport base class](https://github.com/daily-co/daily-ai-sdk/blob/main/src/dailyai/transports/abstract_transport.py) is easy to extend, though, so feel free to submit PRs if you'd like to implement another transport service.)
```
# install the module
@@ -58,6 +54,18 @@ pip install dailyai
cp dot-env.template .env
```
By default, in order to minimize dependencies, only the basic framework functionality is available. Some third-party AI services require additional
dependencies that you can install with:
```
pip install dailyai[option,...]
```
Your project may or may not need these, so they're made available as optional requirements. Here is a list:
- **AI services**: `anthropic`, `azure`, `fal`, `openai`, `playht`, `silero`, `whisper`
- **Transports**: `daily`, `local`, `websocket`
## Code examples
There are two directories of examples:
@@ -65,6 +73,12 @@ There are two directories of examples:
- [foundational](https://github.com/daily-co/daily-ai-sdk/tree/main/examples/foundational) — demos that build on each other, introducing one or two concepts at a time
- [starter apps](https://github.com/daily-co/daily-ai-sdk/tree/main/examples/starter-apps) — complete applications that you can use as starting points for development
Before running the examples you need to install the dependencies (which will install all the dependencies to run all of the examples):
```
pip install -r {env}-requirements.txt
```
To run the example below you need to sign up for a [free Daily account](https://dashboard.daily.co/u/signup) and create a Daily room (so you can hear the LLM talking). After that, join the room's URL directly from a browser tab and run:
```
@@ -76,14 +90,14 @@ python examples/foundational/02-llm-say-one-thing.py
_Note that you may need to set up a virtual environment before following the instructions below. For instance, you might need to run the following from the root of the repo:_
```
python3 -m venv env
source env/bin/activate
python3 -m venv venv
source venv/bin/activate
```
From the root of this repo, run the following:
```
pip install -r requirements.txt
pip install -r {env}-requirements.txt -r dev-requirements.txt
python -m build
```
@@ -101,13 +115,7 @@ pip install path_to_this_repo
### Running tests
To run tests you need to install `pytest`:
```
pip install pytest
```
Then, from the root directory, run:
From the root directory, run:
```
pytest --doctest-modules --ignore-glob="*to_be_updated*" src tests

6
dev-requirements.txt Normal file
View File

@@ -0,0 +1,6 @@
autopep8==2.0.4
build==1.0.3
pip-tools==7.4.1
pytest==8.1.1
setuptools==69.2.0
setuptools_scm==8.0.4

View File

@@ -1,5 +1,25 @@
OPENAI_API_KEY=...
ELEVENLABS_API_KEY=...
ELEVENLABS_VOICE_ID=...
# Anthropic
ANTHROPIC_API_KEY=...
# Azure
SPEECH_KEY=...
SPEECH_REGION=...
# Daily
DAILY_API_KEY=...
DAILY_SAMPLE_ROOM_URL=https://...
# ElevenLabs
ELEVENLABS_API_KEY=...
ELEVENLABS_VOICE_ID=...
# Fal
FAL_KEY_ID=...
FAL_KEY_SECRET=...
# PlayHT
PLAY_HT_USER_ID=...
PLAY_HT_API_KEY=...
# OpenAI
OPENAI_API_KEY=...

View File

@@ -19,12 +19,12 @@ from dailyai.services.open_ai_services import OpenAILLMService
# from dailyai.services.deepgram_ai_services import DeepgramTTSService
from dailyai.services.elevenlabs_ai_service import ElevenLabsTTSService
from dailyai.pipeline.frames import (
OpenAILLMContextFrame,
Frame,
LLMFunctionCallFrame,
LLMFunctionStartFrame,
AudioFrame,
)
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
from dailyai.services.ai_services import FrameLogger, AIService
from openai._types import NotGiven, NOT_GIVEN

View File

@@ -0,0 +1,319 @@
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --all-extras pyproject.toml
#
aiohttp==3.9.3
# via dailyai (pyproject.toml)
aiosignal==1.3.1
# via aiohttp
anthropic==0.20.0
# via dailyai (pyproject.toml)
anyio==4.3.0
# via
# anthropic
# httpx
# openai
# starlette
async-timeout==4.0.3
# via aiohttp
attrs==23.2.0
# via
# aiohttp
# fal
av==11.0.0
# via faster-whisper
azure-cognitiveservices-speech==1.36.0
# via dailyai (pyproject.toml)
blinker==1.7.0
# via flask
certifi==2024.2.2
# via
# httpcore
# httpx
# requests
charset-normalizer==3.3.2
# via requests
click==8.1.7
# via
# fal
# flask
colorama==0.4.6
# via fal
coloredlogs==15.0.1
# via onnxruntime
ctranslate2==4.1.0
# via faster-whisper
daily-python==0.7.2
# via dailyai (pyproject.toml)
deprecated==1.2.14
# via opentelemetry-api
dill==0.3.7
# via fal
distlib==0.3.8
# via virtualenv
distro==1.9.0
# via
# anthropic
# openai
exceptiongroup==1.2.0
# via anyio
fal==0.12.3
# via dailyai (pyproject.toml)
fastapi==0.99.1
# via fal
faster-whisper==1.0.1
# via dailyai (pyproject.toml)
filelock==3.13.3
# via
# huggingface-hub
# pyht
# torch
# triton
# virtualenv
flask==3.0.2
# via
# dailyai (pyproject.toml)
# flask-cors
flask-cors==4.0.0
# via dailyai (pyproject.toml)
flatbuffers==24.3.25
# via onnxruntime
frozenlist==1.4.1
# via
# aiohttp
# aiosignal
fsspec==2024.3.1
# via
# huggingface-hub
# torch
grpc-interceptor==0.15.4
# via fal
grpcio==1.62.1
# via
# fal
# grpc-interceptor
# isolate
# isolate-proto
# pyht
h11==0.14.0
# via httpcore
httpcore==1.0.5
# via httpx
httpx==0.27.0
# via
# anthropic
# fal
# openai
huggingface-hub==0.22.2
# via
# faster-whisper
# tokenizers
humanfriendly==10.0
# via coloredlogs
idna==3.6
# via
# anyio
# httpx
# requests
# yarl
importlib-metadata==7.0.0
# via opentelemetry-api
isolate[build]==0.12.7
# via
# fal
# isolate-proto
isolate-proto==0.3.3
# via fal
itsdangerous==2.1.2
# via flask
jinja2==3.1.3
# via
# flask
# torch
markdown-it-py==3.0.0
# via rich
markupsafe==2.1.5
# via
# jinja2
# werkzeug
mdurl==0.1.2
# via markdown-it-py
mpmath==1.3.0
# via sympy
msgpack==1.0.8
# via fal
multidict==6.0.5
# via
# aiohttp
# yarl
networkx==3.2.1
# via torch
numpy==1.26.4
# via
# ctranslate2
# dailyai (pyproject.toml)
# onnxruntime
nvidia-cublas-cu12==12.1.3.1
# via
# nvidia-cudnn-cu12
# nvidia-cusolver-cu12
# torch
nvidia-cuda-cupti-cu12==12.1.105
# via torch
nvidia-cuda-nvrtc-cu12==12.1.105
# via torch
nvidia-cuda-runtime-cu12==12.1.105
# via torch
nvidia-cudnn-cu12==8.9.2.26
# via torch
nvidia-cufft-cu12==11.0.2.54
# via torch
nvidia-curand-cu12==10.3.2.106
# via torch
nvidia-cusolver-cu12==11.4.5.107
# via torch
nvidia-cusparse-cu12==12.1.0.106
# via
# nvidia-cusolver-cu12
# torch
nvidia-nccl-cu12==2.19.3
# via torch
nvidia-nvjitlink-cu12==12.4.127
# via
# nvidia-cusolver-cu12
# nvidia-cusparse-cu12
nvidia-nvtx-cu12==12.1.105
# via torch
onnxruntime==1.17.1
# via faster-whisper
openai==1.14.2
# via dailyai (pyproject.toml)
opentelemetry-api==1.24.0
# via
# fal
# opentelemetry-sdk
opentelemetry-sdk==1.24.0
# via fal
opentelemetry-semantic-conventions==0.45b0
# via opentelemetry-sdk
packaging==24.0
# via
# fal
# huggingface-hub
# onnxruntime
pathspec==0.11.2
# via fal
pillow==10.2.0
# via
# dailyai (pyproject.toml)
# fal
platformdirs==4.2.0
# via
# isolate
# virtualenv
portalocker==2.8.2
# via fal
protobuf==4.25.3
# via
# isolate
# isolate-proto
# onnxruntime
# pyht
pyaudio==0.2.14
# via dailyai (pyproject.toml)
pydantic==1.10.15
# via
# anthropic
# fal
# fastapi
# openai
pygments==2.17.2
# via rich
pyht==0.0.26
# via dailyai (pyproject.toml)
pyjwt==2.8.0
# via fal
python-dateutil==2.9.0.post0
# via fal
python-dotenv==1.0.1
# via dailyai (pyproject.toml)
pyyaml==6.0.1
# via
# ctranslate2
# huggingface-hub
# isolate
requests==2.31.0
# via
# huggingface-hub
# pyht
rich==13.7.1
# via fal
six==1.16.0
# via python-dateutil
sniffio==1.3.1
# via
# anthropic
# anyio
# httpx
# openai
starlette==0.27.0
# via fastapi
structlog==22.3.0
# via fal
sympy==1.12
# via
# onnxruntime
# torch
tblib==3.0.0
# via isolate
tokenizers==0.15.2
# via
# anthropic
# faster-whisper
torch==2.2.1
# via
# dailyai (pyproject.toml)
# torchaudio
torchaudio==2.2.1
# via dailyai (pyproject.toml)
tqdm==4.66.2
# via
# huggingface-hub
# openai
triton==2.2.0
# via torch
types-python-dateutil==2.9.0.20240316
# via fal
typing-extensions==4.10.0
# via
# anthropic
# anyio
# dailyai (pyproject.toml)
# fal
# fastapi
# huggingface-hub
# openai
# opentelemetry-sdk
# pydantic
# torch
urllib3==2.2.1
# via requests
virtualenv==20.25.1
# via isolate
websockets==12.0
# via
# dailyai (pyproject.toml)
# fal
werkzeug==3.0.2
# via flask
wrapt==1.16.0
# via deprecated
yarl==1.9.4
# via aiohttp
zipp==3.18.1
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
# setuptools

View File

@@ -0,0 +1,285 @@
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --all-extras pyproject.toml
#
aiohttp==3.9.3
# via dailyai (pyproject.toml)
aiosignal==1.3.1
# via aiohttp
anthropic==0.20.0
# via dailyai (pyproject.toml)
anyio==4.3.0
# via
# anthropic
# httpx
# openai
# starlette
async-timeout==4.0.3
# via aiohttp
attrs==23.2.0
# via
# aiohttp
# fal
av==11.0.0
# via faster-whisper
azure-cognitiveservices-speech==1.36.0
# via dailyai (pyproject.toml)
blinker==1.7.0
# via flask
certifi==2024.2.2
# via
# httpcore
# httpx
# requests
charset-normalizer==3.3.2
# via requests
click==8.1.7
# via
# fal
# flask
colorama==0.4.6
# via fal
coloredlogs==15.0.1
# via onnxruntime
ctranslate2==4.1.0
# via faster-whisper
daily-python==0.7.2
# via dailyai (pyproject.toml)
deprecated==1.2.14
# via opentelemetry-api
dill==0.3.7
# via fal
distlib==0.3.8
# via virtualenv
distro==1.9.0
# via
# anthropic
# openai
exceptiongroup==1.2.0
# via anyio
fal==0.12.3
# via dailyai (pyproject.toml)
fastapi==0.99.1
# via fal
faster-whisper==1.0.1
# via dailyai (pyproject.toml)
filelock==3.13.3
# via
# huggingface-hub
# pyht
# torch
# virtualenv
flask==3.0.2
# via
# dailyai (pyproject.toml)
# flask-cors
flask-cors==4.0.0
# via dailyai (pyproject.toml)
flatbuffers==24.3.25
# via onnxruntime
frozenlist==1.4.1
# via
# aiohttp
# aiosignal
fsspec==2024.3.1
# via
# huggingface-hub
# torch
grpc-interceptor==0.15.4
# via fal
grpcio==1.62.1
# via
# fal
# grpc-interceptor
# isolate
# isolate-proto
# pyht
h11==0.14.0
# via httpcore
httpcore==1.0.5
# via httpx
httpx==0.27.0
# via
# anthropic
# fal
# openai
huggingface-hub==0.22.2
# via
# faster-whisper
# tokenizers
humanfriendly==10.0
# via coloredlogs
idna==3.6
# via
# anyio
# httpx
# requests
# yarl
importlib-metadata==7.0.0
# via opentelemetry-api
isolate[build]==0.12.7
# via
# fal
# isolate-proto
isolate-proto==0.3.3
# via fal
itsdangerous==2.1.2
# via flask
jinja2==3.1.3
# via
# flask
# torch
markdown-it-py==3.0.0
# via rich
markupsafe==2.1.5
# via
# jinja2
# werkzeug
mdurl==0.1.2
# via markdown-it-py
mpmath==1.3.0
# via sympy
msgpack==1.0.8
# via fal
multidict==6.0.5
# via
# aiohttp
# yarl
networkx==3.2.1
# via torch
numpy==1.26.4
# via
# ctranslate2
# dailyai (pyproject.toml)
# onnxruntime
onnxruntime==1.17.1
# via faster-whisper
openai==1.14.2
# via dailyai (pyproject.toml)
opentelemetry-api==1.24.0
# via
# fal
# opentelemetry-sdk
opentelemetry-sdk==1.24.0
# via fal
opentelemetry-semantic-conventions==0.45b0
# via opentelemetry-sdk
packaging==24.0
# via
# fal
# huggingface-hub
# onnxruntime
pathspec==0.11.2
# via fal
pillow==10.2.0
# via
# dailyai (pyproject.toml)
# fal
platformdirs==4.2.0
# via
# isolate
# virtualenv
portalocker==2.8.2
# via fal
protobuf==4.25.3
# via
# isolate
# isolate-proto
# onnxruntime
# pyht
pyaudio==0.2.14
# via dailyai (pyproject.toml)
pydantic==1.10.15
# via
# anthropic
# fal
# fastapi
# openai
pygments==2.17.2
# via rich
pyht==0.0.26
# via dailyai (pyproject.toml)
pyjwt==2.8.0
# via fal
python-dateutil==2.9.0.post0
# via fal
python-dotenv==1.0.1
# via dailyai (pyproject.toml)
pyyaml==6.0.1
# via
# ctranslate2
# huggingface-hub
# isolate
requests==2.31.0
# via
# huggingface-hub
# pyht
rich==13.7.1
# via fal
six==1.16.0
# via python-dateutil
sniffio==1.3.1
# via
# anthropic
# anyio
# httpx
# openai
starlette==0.27.0
# via fastapi
structlog==22.3.0
# via fal
sympy==1.12
# via
# onnxruntime
# torch
tblib==3.0.0
# via isolate
tokenizers==0.15.2
# via
# anthropic
# faster-whisper
torch==2.2.1
# via
# dailyai (pyproject.toml)
# torchaudio
torchaudio==2.2.1
# via dailyai (pyproject.toml)
tqdm==4.66.2
# via
# huggingface-hub
# openai
types-python-dateutil==2.9.0.20240316
# via fal
typing-extensions==4.10.0
# via
# anthropic
# anyio
# dailyai (pyproject.toml)
# fal
# fastapi
# huggingface-hub
# openai
# opentelemetry-sdk
# pydantic
# torch
urllib3==2.2.1
# via requests
virtualenv==20.25.1
# via isolate
websockets==12.0
# via
# dailyai (pyproject.toml)
# fal
werkzeug==3.0.2
# via flask
wrapt==1.16.0
# via deprecated
yarl==1.9.4
# via aiohttp
zipp==3.18.1
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
# setuptools

View File

@@ -1,10 +1,10 @@
[build-system]
requires = ["setuptools"]
requires = ["setuptools>=64", "setuptools_scm>=8"]
build-backend = "setuptools.build_meta"
[project]
name = "dailyai"
version = "0.0.3.1"
dynamic = ["version"]
description = "An open source framework for real-time, multi-modal, conversational AI applications"
license = { text = "BSD 2-Clause License" }
readme = "README.md"
@@ -20,31 +20,35 @@ classifiers = [
"Topic :: Scientific/Engineering :: Artificial Intelligence"
]
dependencies = [
"aiohttp",
"anthropic",
"azure-cognitiveservices-speech",
"daily-python",
"fal",
"faster_whisper",
"flask",
"flask_cors",
"google-cloud-texttospeech",
"numpy",
"openai",
"Pillow",
"pyht",
"python-dotenv",
"typing-extensions",
"websockets"
"aiohttp==3.9.3",
"numpy==1.26.4",
"Pillow==10.2.0",
"typing-extensions==4.10.0",
]
[project.urls]
Source = "https://github.com/daily-co/daily-ai-sdk"
Website = "https://daily.co"
[project.optional-dependencies]
anthropic = [ "anthropic==0.20.0" ]
azure = [ "azure-cognitiveservices-speech==1.36.0" ]
daily = [ "daily-python==0.7.2" ]
examples = [ "python-dotenv==1.0.1", "flask==3.0.2", "flask_cors==4.0.0" ]
fal = [ "fal==0.12.3" ]
local = [ "pyaudio==0.2.14" ]
openai = [ "openai==1.14.2" ]
playht = [ "pyht==0.0.26" ]
silero = [ "torch==2.2.1", "torchaudio==2.2.1" ]
websocket = [ "websockets==12.0" ]
whisper = [ "faster_whisper==1.0.1" ]
[tool.setuptools.packages.find]
# All the following settings are optional:
where = ["src"]
[tool.pytest.ini_options]
pythonpath = ["src"]
[tool.setuptools_scm]
# Empty

View File

@@ -1,4 +0,0 @@
autopep8==2.0.4
build==1.0.3
packaging==23.2
pyproject_hooks==1.0.0

View File

@@ -1,9 +1,6 @@
from dataclasses import dataclass
from typing import Any, List
from dailyai.services.openai_llm_context import OpenAILLMContext
import dailyai.pipeline.protobufs.frames_pb2 as frame_protos
class Frame:
def __str__(self):
@@ -135,14 +132,6 @@ class LLMMessagesFrame(Frame):
messages: List[dict]
@dataclass()
class OpenAILLMContextFrame(Frame):
"""Like an LLMMessagesFrame, but with extra context specific to the
OpenAI API. The context in this message is also mutable, and will be
changed by the OpenAIContextAggregator frame processor."""
context: OpenAILLMContext
@dataclass()
class ReceivedAppMessageFrame(Frame):
message: Any

View File

@@ -4,15 +4,21 @@ from dailyai.pipeline.frames import (
Frame,
LLMResponseEndFrame,
LLMResponseStartFrame,
OpenAILLMContextFrame,
TextFrame,
TranscriptionFrame,
UserStartedSpeakingFrame,
UserStoppedSpeakingFrame,
)
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
from dailyai.services.openai_llm_context import OpenAILLMContext
from openai.types.chat import ChatCompletionRole
try:
from openai.types.chat import ChatCompletionRole
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use OpenAI, you need to `pip install dailyai[openai]`. Also, set `OPENAI_API_KEY` environment variable.")
raise Exception(f"Missing module: {e}")
class OpenAIContextAggregator(FrameProcessor):

View File

@@ -0,0 +1,12 @@
from dataclasses import dataclass
from dailyai.pipeline.frames import Frame
from dailyai.services.openai_llm_context import OpenAILLMContext
@dataclass()
class OpenAILLMContextFrame(Frame):
"""Like an LLMMessagesFrame, but with extra context specific to the
OpenAI API. The context in this message is also mutable, and will be
changed by the OpenAIContextAggregator frame processor."""
context: OpenAILLMContext

View File

@@ -1,9 +1,16 @@
from typing import AsyncGenerator
from anthropic import AsyncAnthropic
from dailyai.pipeline.frames import Frame, LLMMessagesFrame, TextFrame
from dailyai.services.ai_services import LLMService
try:
from anthropic import AsyncAnthropic
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use Anthropic, you need to `pip install dailyai[anthropic]`. Also, set `ANTHROPIC_API_KEY` environment variable.")
raise Exception(f"Missing module: {e}")
class AnthropicLLMService(LLMService):

View File

@@ -9,12 +9,18 @@ from dailyai.services.ai_services import TTSService, ImageGenService
from PIL import Image
# See .env.example for Azure configuration needed
from azure.cognitiveservices.speech import (
SpeechSynthesizer,
SpeechConfig,
ResultReason,
CancellationReason,
)
try:
from azure.cognitiveservices.speech import (
SpeechSynthesizer,
SpeechConfig,
ResultReason,
CancellationReason,
)
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use Azure TTS, you need to `pip install dailyai[azure]`. Also, set `SPEECH_KEY` and `SPEECH_REGION` environment variables.")
raise Exception(f"Missing module: {e}")
from dailyai.services.openai_api_llm_service import BaseOpenAILLMService

View File

@@ -1,4 +1,3 @@
import fal
import aiohttp
import asyncio
import io
@@ -10,7 +9,13 @@ from dailyai.services.ai_services import ImageGenService
from dailyai.services.ai_services import ImageGenService
# Fal expects FAL_KEY_ID and FAL_KEY_SECRET to be set in the env
try:
import fal
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use Fal, you need to `pip install dailyai[fal]`. Also, set `FAL_KEY_ID` and `FAL_KEY_SECRET` environment variables.")
raise Exception(f"Missing module: {e}")
class FalImageGenService(ImageGenService):

View File

@@ -1,12 +1,20 @@
import aiohttp
from PIL import Image
import io
from openai import AsyncOpenAI
from dailyai.services.ai_services import ImageGenService
from dailyai.services.openai_api_llm_service import BaseOpenAILLMService
try:
from openai import AsyncOpenAI
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use OpenAI, you need to `pip install dailyai[openai]`. Also, set `OPENAI_API_KEY` environment variable.")
raise Exception(f"Missing module: {e}")
class OpenAILLMService(BaseOpenAILLMService):
def __init__(self, model="gpt-4", * args, **kwargs):

View File

@@ -1,7 +1,6 @@
import json
import time
from typing import AsyncGenerator, List
from openai import AsyncOpenAI, AsyncStream
from dailyai.pipeline.frames import (
Frame,
LLMFunctionCallFrame,
@@ -9,17 +8,25 @@ from dailyai.pipeline.frames import (
LLMMessagesFrame,
LLMResponseEndFrame,
LLMResponseStartFrame,
OpenAILLMContextFrame,
TextFrame,
)
from dailyai.services.ai_services import LLMService
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
from dailyai.services.openai_llm_context import OpenAILLMContext
from openai.types.chat import (
ChatCompletion,
ChatCompletionChunk,
ChatCompletionMessageParam,
)
try:
from openai import AsyncOpenAI, AsyncStream
from openai.types.chat import (
ChatCompletion,
ChatCompletionChunk,
ChatCompletionMessageParam,
)
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use OpenAI, you need to `pip install dailyai[openai]`. Also, set `OPENAI_API_KEY` environment variable.")
raise Exception(f"Missing module: {e}")
class BaseOpenAILLMService(LLMService):

View File

@@ -1,11 +1,18 @@
from typing import List
from openai._types import NOT_GIVEN, NotGiven
from openai.types.chat import (
ChatCompletionToolParam,
ChatCompletionToolChoiceOptionParam,
ChatCompletionMessageParam,
)
try:
from openai._types import NOT_GIVEN, NotGiven
from openai.types.chat import (
ChatCompletionToolParam,
ChatCompletionToolChoiceOptionParam,
ChatCompletionMessageParam,
)
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use OpenAI, you need to `pip install dailyai[openai]`. Also, set `OPENAI_API_KEY` environment variable.")
raise Exception(f"Missing module: {e}")
class OpenAILLMContext:

View File

@@ -1,11 +1,18 @@
import io
import struct
from pyht import Client
from pyht.client import TTSOptions
from pyht.protos.api_pb2 import Format
from dailyai.services.ai_services import TTSService
try:
from pyht import Client
from pyht.client import TTSOptions
from pyht.protos.api_pb2 import Format
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use PlayHT, you need to `pip install dailyai[playht]`. Also, set `PLAY_HT_USER_ID` and `PLAY_HT_API_KEY` environment variables.")
raise Exception(f"Missing module: {e}")
class PlayHTAIService(TTSService):

View File

@@ -3,10 +3,18 @@ import asyncio
from enum import Enum
import logging
from typing import BinaryIO
from faster_whisper import WhisperModel
from dailyai.services.local_stt_service import LocalSTTService
try:
from faster_whisper import WhisperModel
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use Whisper, you need to `pip install dailyai[whisper]`.")
raise Exception(f"Missing module: {e}")
class Model(Enum):
"""Class of basic Whisper model selection options"""
TINY = "tiny"

View File

@@ -15,14 +15,21 @@ from dailyai.pipeline.frames import (
from threading import Event
from daily import (
EventHandler,
CallClient,
Daily,
VirtualCameraDevice,
VirtualMicrophoneDevice,
VirtualSpeakerDevice,
)
try:
from daily import (
EventHandler,
CallClient,
Daily,
VirtualCameraDevice,
VirtualMicrophoneDevice,
VirtualSpeakerDevice,
)
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use the Daily transport, you need to `pip install dailyai[daily]`.")
raise Exception(f"Missing module: {e}")
from dailyai.transports.threaded_transport import ThreadedTransport

View File

@@ -4,17 +4,18 @@ import tkinter as tk
from dailyai.transports.threaded_transport import ThreadedTransport
try:
import pyaudio
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use the local transport, you need to `pip install dailyai[local]`. On MacOS, you also need to `brew install portaudio`.")
raise Exception(f"Missing module: {e}")
class LocalTransport(ThreadedTransport):
def __init__(self, **kwargs):
super().__init__(**kwargs)
try:
global pyaudio
import pyaudio
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print("In order to use the local transport, you'll need to `pip install pyaudio`. On MacOS, you'll also need to `brew install portaudio`.")
raise Exception(f"Missing module: {e}")
self._sample_width = kwargs.get("sample_width") or 2
self._n_channels = kwargs.get("n_channels") or 1
self._tk_root = kwargs.get("tk_root") or None

View File

@@ -1,7 +1,6 @@
from abc import abstractmethod
import asyncio
import itertools
import logging
import numpy as np
import queue

View File

@@ -1,7 +1,6 @@
import asyncio
import time
from typing import AsyncGenerator, List
import websockets
from dailyai.pipeline.frame_processor import FrameProcessor
from dailyai.pipeline.frames import AudioFrame, ControlFrame, EndFrame, Frame, TTSEndFrame, TTSStartFrame, TextFrame
@@ -10,6 +9,14 @@ from dailyai.serializers.protobuf_serializer import ProtobufFrameSerializer
from dailyai.transports.abstract_transport import AbstractTransport
from dailyai.transports.threaded_transport import ThreadedTransport
try:
import websockets
except ModuleNotFoundError as e:
print(f"Exception: {e}")
print(
"In order to use the websocket transport, you need to `pip install dailyai[websocket]`.")
raise Exception(f"Missing module: {e}")
class WebSocketFrameProcessor(FrameProcessor):
"""This FrameProcessor filters and mutates frames before they're sent over the websocket.

View File

@@ -1,8 +1,6 @@
import asyncio
import os
from dailyai.pipeline.frames import (
OpenAILLMContextFrame,
)
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
from dailyai.services.azure_ai_services import AzureLLMService
from dailyai.services.openai_llm_context import OpenAILLMContext

View File

@@ -1,7 +1,5 @@
import asyncio
from dailyai.pipeline.frames import (
OpenAILLMContextFrame,
)
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
from dailyai.services.openai_llm_context import OpenAILLMContext
from openai.types.chat import (

View File

@@ -1,8 +1,6 @@
import asyncio
import os
from dailyai.pipeline.frames import (
OpenAILLMContextFrame,
)
from dailyai.pipeline.openai_frames import OpenAILLMContextFrame
from dailyai.services.openai_llm_context import OpenAILLMContext
from openai.types.chat import (