From 03c34fa831c458ef03995ef2a5ddea498290048c Mon Sep 17 00:00:00 2001 From: Vadim Shestopalov <31348740+vchulski@users.noreply.github.com> Date: Fri, 8 Mar 2024 17:59:00 +0100 Subject: [PATCH 1/6] Add requests to requirements.txt Addressing the following issue: https://github.com/VapiAI/python/issues/3 --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index fb06e04..d65b871 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ daily-python -pyaudio \ No newline at end of file +pyaudio +requests From 1ab83455a5e2a77f096c31e0332cce129b1bc473 Mon Sep 17 00:00:00 2001 From: Edwin Zhang Date: Wed, 1 May 2024 23:55:24 -0400 Subject: [PATCH 2/6] Update Python SDK to support assistant overrides (#6) - Bump version to 0.1.9 - Add docs for assistant_overrides field - Add assistant_overrides to start --- README.md | 22 ++++++++++++++++++---- README.rst | 16 +++++++++++++++- setup.py | 2 +- vapi_python/vapi_python.py | 6 +++--- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 84bd081..f873299 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ You can install the package via pip: pip install vapi_python ``` -On Mac, you might need to install `brew install portaudio` to satisfy `pyaudio`'s dependency requirement. +On Mac, you might need to install `brew install portaudio` to satisfy `pyaudio`'s dependency requirement. ## Usage @@ -31,7 +31,9 @@ You can start a new call by calling the `start` method and passing an `assistant ```python vapi.start(assistant_id='your-assistant-id') ``` + or + ```python assistant = { 'firstMessage': 'Hey, how are you?', @@ -45,7 +47,21 @@ assistant = { vapi.start(assistant=assistant) ``` -The `start` method will initiate a new call. +The `start` method will initiate a new call. + +You can override existing assistant parameters or set variables with the `assistant_overrides` parameter. +Assume the first message is `Hey, {{name}} how are you?` and you want to set the value of `name` to `John`: + +```python +assistant_overrides = { + "recordingEnabled": False, + "variableValues": { + "name": "John" + } +} + +vapi.start(assistant_id='your-assistant-id', assistant_overrides=assistant_overrides) +``` You can stop the session by calling the `stop` method: @@ -80,5 +96,3 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` - - diff --git a/README.rst b/README.rst index f27df0f..fe0672c 100644 --- a/README.rst +++ b/README.rst @@ -75,7 +75,21 @@ or vapi.start(assistant=assistant) -The `start` method will initiate a new call. +The `start` method will initiate a new call. + +You can override existing assistant parameters or set variables with the `assistant_overrides` parameter. +Assume the first message is `Hey, {{name}} how are you?` and you want to set the value of `name` to `John`: + +.. code-block:: python + + assistant_overrides = { + "recordingEnabled": False, + "variableValues": { + "name": "John" + } + } + + vapi.start(assistant_id='your-assistant-id', assistant_overrides=assistant_overrides) You can stop the session by calling the `stop` method: diff --git a/setup.py b/setup.py index ed5e1e5..1ed5194 100644 --- a/setup.py +++ b/setup.py @@ -49,6 +49,6 @@ def read_requirements(file): test_suite='tests', tests_require=test_requirements, url='https://github.com/jordan.cde/vapi_python', - version='0.1.8', + version='0.1.9', zip_safe=False, ) diff --git a/vapi_python/vapi_python.py b/vapi_python/vapi_python.py index 44fe220..e6f5ac8 100644 --- a/vapi_python/vapi_python.py +++ b/vapi_python/vapi_python.py @@ -27,12 +27,12 @@ def __init__(self, *, api_key, api_url="https://api.vapi.ai"): self.api_key = api_key self.api_url = api_url - def start(self, *, assistant_id=None, assistant=None): + def start(self, *, assistant_id=None, assistant=None, assistant_overrides=None): # Start a new call if assistant_id: - assistant = {'assistantId': assistant_id} + assistant = {'assistantId': assistant_id, 'assistantOverrides': assistant_overrides} elif assistant: - assistant = {'assistant': assistant} + assistant = {'assistant': assistant, 'assistantOverrides': assistant_overrides} call_id, web_call_url = create_web_call( self.api_url, self.api_key, assistant) From b00183ea793f78128e3def6d68c6b3380c8908ae Mon Sep 17 00:00:00 2001 From: Edwin Zhang Date: Wed, 29 May 2024 17:22:32 -0400 Subject: [PATCH 3/6] Support squads in start (#8) --- vapi_python/vapi_python.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/vapi_python/vapi_python.py b/vapi_python/vapi_python.py index e6f5ac8..e114948 100644 --- a/vapi_python/vapi_python.py +++ b/vapi_python/vapi_python.py @@ -6,13 +6,13 @@ CHANNELS = 1 -def create_web_call(api_url, api_key, assistant): +def create_web_call(api_url, api_key, payload): url = f"{api_url}/call/web" headers = { 'Authorization': 'Bearer ' + api_key, 'Content-Type': 'application/json' } - response = requests.post(url, headers=headers, json=assistant) + response = requests.post(url, headers=headers, json=payload) data = response.json() if response.status_code == 201: call_id = data.get('id') @@ -27,15 +27,29 @@ def __init__(self, *, api_key, api_url="https://api.vapi.ai"): self.api_key = api_key self.api_url = api_url - def start(self, *, assistant_id=None, assistant=None, assistant_overrides=None): + def start( + self, + *, + assistant_id=None, + assistant=None, + assistant_overrides=None, + squad_id=None, + squad=None, + ): # Start a new call if assistant_id: - assistant = {'assistantId': assistant_id, 'assistantOverrides': assistant_overrides} + payload = {'assistantId': assistant_id, 'assistantOverrides': assistant_overrides} elif assistant: - assistant = {'assistant': assistant, 'assistantOverrides': assistant_overrides} + payload = {'assistant': assistant, 'assistantOverrides': assistant_overrides} + elif squad_id: + payload = {'squadId': squad_id} + elif squad: + payload = {'squad': squad} + else: + raise Exception("Error: No assistant specified.") call_id, web_call_url = create_web_call( - self.api_url, self.api_key, assistant) + self.api_url, self.api_key, payload) if not web_call_url: raise Exception("Error: Unable to create call.") From 581975a7cc000c709c3df75afb5e5ab7a9d1ca16 Mon Sep 17 00:00:00 2001 From: venkatram-dev Date: Wed, 21 Aug 2024 17:02:02 -0700 Subject: [PATCH 4/6] add_send_text_message --- vapi_python/daily_call.py | 13 +++++++++++++ vapi_python/vapi_python.py | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/vapi_python/daily_call.py b/vapi_python/daily_call.py index 5dcc1cd..f1ee47c 100644 --- a/vapi_python/daily_call.py +++ b/vapi_python/daily_call.py @@ -1,6 +1,7 @@ import daily import threading import pyaudio +import json SAMPLE_RATE = 16000 NUM_CHANNELS = 1 @@ -160,3 +161,15 @@ def receive_bot_audio(self): if len(buffer) > 0: self.__output_audio_stream.write(buffer, CHUNK_SIZE) + + def send_app_message(self, message): + """ + Send an application message to the assistant. + + :param message: The message to send. + """ + try: + serialized_message = json.dumps(message) + self.__call_client.send_app_message(serialized_message) + except Exception as e: + print(f"Failed to send app message: {e}") diff --git a/vapi_python/vapi_python.py b/vapi_python/vapi_python.py index e114948..10adc33 100644 --- a/vapi_python/vapi_python.py +++ b/vapi_python/vapi_python.py @@ -62,3 +62,21 @@ def start( def stop(self): self.__client.leave() self.__client = None + + def send(self, message_type, message_content): + """ + Send a message to the assistant. + + :param message_type: Type of message, such as 'add-message'. + :param message_content: The content of the message. + """ + if not self.__client: + raise Exception("Call not started. Please start the call first.") + + message = { + "type": message_type, + "message": message_content + } + + # Simulate sending a message by calling the appropriate method on the client + self.__client.send_app_message(message) From 747d00776805adf62dfa51f2fbd05c468f2cba8a Mon Sep 17 00:00:00 2001 From: venkatram-dev Date: Wed, 21 Aug 2024 21:33:58 -0700 Subject: [PATCH 5/6] use generic send message --- vapi_python/daily_call.py | 5 ++++- vapi_python/vapi_python.py | 31 ++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/vapi_python/daily_call.py b/vapi_python/daily_call.py index f1ee47c..b3551df 100644 --- a/vapi_python/daily_call.py +++ b/vapi_python/daily_call.py @@ -166,9 +166,12 @@ def send_app_message(self, message): """ Send an application message to the assistant. - :param message: The message to send. + :param message: The message to send (expects a dictionary). """ try: + if not isinstance(message, dict): + raise ValueError("Message must be a dictionary.") + serialized_message = json.dumps(message) self.__call_client.send_app_message(serialized_message) except Exception as e: diff --git a/vapi_python/vapi_python.py b/vapi_python/vapi_python.py index 10adc33..69e9797 100644 --- a/vapi_python/vapi_python.py +++ b/vapi_python/vapi_python.py @@ -63,20 +63,33 @@ def stop(self): self.__client.leave() self.__client = None - def send(self, message_type, message_content): + def send(self, message): """ - Send a message to the assistant. + Send a generic message to the assistant. - :param message_type: Type of message, such as 'add-message'. - :param message_content: The content of the message. + :param message: A dictionary containing the message type and content. """ if not self.__client: raise Exception("Call not started. Please start the call first.") + # Check message format here instead of serialization + if not isinstance(message, dict) or 'type' not in message: + raise ValueError("Invalid message format.") + + try: + self.__client.send_app_message(message) # Send dictionary directly + except Exception as e: + print(f"Failed to send message: {e}") + + def add_message(self, role, content): + """ + method to send text messages with specific parameters. + """ message = { - "type": message_type, - "message": message_content + 'type': 'add-message', + 'message': { + 'role': role, + 'content': content + } } - - # Simulate sending a message by calling the appropriate method on the client - self.__client.send_app_message(message) + self.send(message) From 1ef5541c7cadb72d156a6faf63d1fb8a76264dcd Mon Sep 17 00:00:00 2001 From: venkatram-dev Date: Wed, 21 Aug 2024 21:50:02 -0700 Subject: [PATCH 6/6] remove redundant type check --- vapi_python/daily_call.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/vapi_python/daily_call.py b/vapi_python/daily_call.py index b3551df..f4a7911 100644 --- a/vapi_python/daily_call.py +++ b/vapi_python/daily_call.py @@ -169,9 +169,6 @@ def send_app_message(self, message): :param message: The message to send (expects a dictionary). """ try: - if not isinstance(message, dict): - raise ValueError("Message must be a dictionary.") - serialized_message = json.dumps(message) self.__call_client.send_app_message(serialized_message) except Exception as e: