# Project export: Chillbert

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 11.0
- Tagline: Your emotional sidekick with all the cool vibes!
- Devpost: https://devpost.com/software/chillbert-your-emotional-sidekick-with-all-the-cool-vibes
- GitHub: https://github.com/jyothiv-codes/calhacks_github_app
- Video: https://www.youtube.com/embed/oLZIwUN0kR8?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — Mrunmayeed (10 commits)

## Devpost submission (written by the team)

### Inspiration

We’re on a mission to make mental health check-ins less awkward—our mood-savvy assistant listens to your vibes, cracks a joke, and keeps your therapist in the loop with all the feels!

### What it does

This is a voice-powered agent designed to engage users and mental health patients in casual, mood-lifting check-ins throughout the day. The agent provides friendly interactions, helping users pass time while boosting their mood. After each conversation, a summary is automatically shared with the assigned mental health practitioner via WhatsApp. Additionally, users receive personalized, helpful links based on the topics discussed. Practitioners are equipped with a dashboard, allowing them to explore the conversation further and ask follow-up questions, ensuring more tailored and insightful care

### How we built it

We developed a conversational voice agent using HumeAI, which tracks, stores, and analyzes the emotions embedded in each conversation. These emotional insights, along with the conversation data, are processed using a Gemini RAG model within LangChain for real-time analysis. At the end of each conversation, a summarized report is generated and automatically sent to the health practitioner via WhatsApp. This ensures timely delivery of emotional insights, enabling practitioners to make informed decisions based on the conversation's emotional dynamics

### Challenges we ran into

Twilio integration with python was complicated

### Accomplishments we're proud of

This is a step towards de-stigmatizing mental health

### What we learned

First time using voice platforms it is really easy to use and integrate.

### What's next

User Profiles Practitioner Analytics

## README (from the GitHub repository)

<div align="center">
  <!-- <img src="https://storage.googleapis.com/hume-public-logos/hume/hume-banner.png"> -->
  <h1>CHILLBERT : Your emotional sidekick with all the cool vibes!</h1>
</div>

## Overview

<p>
  <strong>We’re on a mission to make mental health check-ins less awkward—our mood-savvy assistant listens to your vibes, cracks a joke, and keeps your therapist in the loop with all the feels!</strong>
</p>

This is a voice-powered agent designed to engage users and mental health patients in casual, mood-lifting check-ins throughout the day. The agent provides friendly interactions, helping users pass time while boosting their mood. After each conversation, a summary is automatically shared with the assigned mental health practitioner via WhatsApp. Additionally, users receive personalized, helpful links based on the topics discussed. Practitioners are equipped with a dashboard, allowing them to explore the conversation further and ask follow-up questions, ensuring more tailored and insightful care.

## Technologies Used

We used model on HumeAI for creating a conversational voice agent. These converations and their emotions are tracked, stored and analysed with a Gemini RAG model in LangChain. A summary of the conversation is sent to the health practitioner via Whatsapp.

## Demo
[![Conversational Voice Agent Demo](https://img.youtube.com/vi/oLZIwUN0kR8/0.jpg)](https://youtu.be/oLZIwUN0kR8?si=5sEKzh9diwHg1u-V)



## Setting up a virtual environment 

Before you install the dependencies, you might want to create a virtual environment to isolate your package installations. To create a virtual environment, run the following commands in your terminal:

```bash
# Create a virtual environment in the directory 'evi-env'
python -m venv venv

# Activate the virtual environment
# On Mac/Linux:
source venv/bin/activate
```

After activating the virtual environment, you can proceed with the installation of dependencies as described below.

## Dependencies

In order to run it, you need to install the `requirements.txt` using `pip`:

### Mac

```bash
pip install -r requirements.txt
```


## Environment variables

Create a `.env` file or set environment variables. You will need a HUME account, a Google AI Studio account and a Twilio account.

Example `.env` file:

```bash
HUME_API_KEY="<HUME API KEY>"
HUME_SECRET_KEY="<HUME SECRET KEY>"
TWILIO_ACCOUNT_SID="<TWILIO ACCOUNT SID>"
TWILIO_AUTH_TOKEN="<TWILIO AUTH TOKEN>"
TWILIO_RECIPIENT="<TWILIO RECIPIENT>"
GOOGLE_API_KEY="<GOOGLE API KEY>"
```

## Usage

```bash
streamlit run chillbert.py
```


## Detected evidence (automated analysis)

Indexed codebase: 16 recognized source files, 50 KB.
- LangChain (technology) — detected in the code
- Python (language) — detected in the code
- Streamlit (technology) — detected in the code
- Google Gemini (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (22 of 22)

```
.DS_Store
.gitignore
chill.py
chillbert.py
LICENSE
logs/emotion_logs_cleaned.txt
logs/emotion_logs.txt
README.md
requirements.txt
src/analyse_chat.py
src/authenticator.py
src/chatbot.py
src/connection.py
src/data_formatting.py
src/devices.py
src/fileprocessing.py
src/llm_learns_vertex.py
src/llm_learns.py
src/main.py
src/messanger.py
src/remove_audio_data.py
src/text_to_pdf.py
```

### Dependencies

- requirements.txt: certifi@==2024.2.2, cffi@==1.16.0, charset-normalizer@==3.3.2, chromadb, fpdf, gevent@==24.2.1, greenlet@==3.0.3, idna@==3.6, langchain, langchain_chroma, langchain_google_genai, langchain-community, numpy@==1.26.4, playsound@==1.3.0, PyAudio@==0.2.14, pycparser@==2.21, pyobjc@==10.1, pyobjc-core@==10.1, pyobjc-framework-Accessibility@==10.1, pyobjc-framework-Accounts@==10.1, pyobjc-framework-AddressBook@==10.1, pyobjc-framework-AdServices@==10.1, pyobjc-framework-AdSupport@==10.1, pyobjc-framework-AppleScriptKit@==10.1, pyobjc-framework-AppleScriptObjC@==10.1, pyobjc-framework-ApplicationServices@==10.1, pyobjc-framework-AppTrackingTransparency@==10.1, pyobjc-framework-AudioVideoBridging@==10.1, pyobjc-framework-AuthenticationServices@==10.1, pyobjc-framework-AutomaticAssessmentConfiguration@==10.1, pyobjc-framework-Automator@==10.1, pyobjc-framework-AVFoundation@==10.1, pyobjc-framework-AVKit@==10.1, pyobjc-framework-AVRouting@==10.1, pyobjc-framework-BackgroundAssets@==10.1, pyobjc-framework-BusinessChat@==10.1, pyobjc-framework-CalendarStore@==10.1, pyobjc-framework-CallKit@==10.1, pyobjc-framework-CFNetwork@==10.1, pyobjc-framework-Cinematic@==10.1, pyobjc-framework-ClassKit@==10.1, pyobjc-framework-CloudKit@==10.1, pyobjc-framework-Cocoa@==10.1, pyobjc-framework-Collaboration@==10.1, pyobjc-framework-ColorSync@==10.1, pyobjc-framework-Contacts@==10.1, pyobjc-framework-ContactsUI@==10.1, pyobjc-framework-CoreAudio@==10.1, pyobjc-framework-CoreAudioKit@==10.1, pyobjc-framework-CoreBluetooth@==10.1, pyobjc-framework-CoreData@==10.1, pyobjc-framework-CoreHaptics@==10.1, pyobjc-framework-CoreLocation@==10.1, pyobjc-framework-CoreMedia@==10.1, pyobjc-framework-CoreMediaIO@==10.1, pyobjc-framework-CoreMIDI@==10.1, pyobjc-framework-CoreML@==10.1, pyobjc-framework-CoreMotion@==10.1, pyobjc-framework-CoreServices@==10.1, pyobjc-framework-CoreSpotlight@==10.1, pyobjc-framework-CoreText@==10.1, pyobjc-framework-CoreWLAN@==10.1, pyobjc-framework-CryptoTokenKit@==10.1, pyobjc-framework-DataDetection@==10.1, pyobjc-framework-DeviceCheck@==10.1, pyobjc-framework-DictionaryServices@==10.1, pyobjc-framework-DiscRecording@==10.1, pyobjc-framework-DiscRecordingUI@==10.1, pyobjc-framework-DiskArbitration@==10.1, pyobjc-framework-DVDPlayback@==10.1, pyobjc-framework-EventKit@==10.1, pyobjc-framework-ExceptionHandling@==10.1, pyobjc-framework-ExecutionPolicy@==10.1, pyobjc-framework-ExtensionKit@==10.1, pyobjc-framework-ExternalAccessory@==10.1, pyobjc-framework-FileProvider@==10.1, pyobjc-framework-FileProviderUI@==10.1, pyobjc-framework-FinderSync@==10.1, pyobjc-framework-FSEvents@==10.1, pyobjc-framework-GameCenter@==10.1, pyobjc-framework-GameController@==10.1, pyobjc-framework-GameKit@==10.1, pyobjc-framework-GameplayKit@==10.1, pyobjc-framework-HealthKit@==10.1, pyobjc-framework-ImageCaptureCore@==10.1, pyobjc-framework-InputMethodKit@==10.1, pyobjc-framework-InstallerPlugins@==10.1, pyobjc-framework-InstantMessage@==10.1, pyobjc-framework-Intents@==10.1, pyobjc-framework-IntentsUI@==10.1, pyobjc-framework-IOBluetooth@==10.1, pyobjc-framework-IOBluetoothUI@==10.1, pyobjc-framework-IOSurface@==10.1, pyobjc-framework-iTunesLibrary@==10.1, pyobjc-framework-KernelManagement@==10.1, pyobjc-framework-LatentSemanticMapping@==10.1, pyobjc-framework-LaunchServices@==10.1, pyobjc-framework-libdispatch@==10.1, pyobjc-framework-libxpc@==10.1, pyobjc-framework-LinkPresentation@==10.1, pyobjc-framework-LocalAuthentication@==10.1, pyobjc-framework-LocalAuthenticationEmbeddedUI@==10.1, pyobjc-framework-MailKit@==10.1, pyobjc-framework-MapKit@==10.1, pyobjc-framework-MediaAccessibility@==10.1, pyobjc-framework-MediaLibrary@==10.1, pyobjc-framework-MediaPlayer@==10.1, pyobjc-framework-MediaToolbox@==10.1, pyobjc-framework-Metal@==10.1, pyobjc-framework-MetalFX@==10.1, pyobjc-framework-MetalKit@==10.1, pyobjc-framework-MetalPerformanceShaders@==10.1, pyobjc-framework-MetalPerformanceShadersGraph@==10.1, pyobjc-framework-MetricKit@==10.1, pyobjc-framework-MLCompute@==10.1, pyobjc-framework-ModelIO@==10.1, pyobjc-framework-MultipeerConnectivity@==10.1, pyobjc-framework-NaturalLanguage@==10.1, pyobjc-framework-NetFS@==10.1, pyobjc-framework-Network@==10.1, pyobjc-framework-NetworkExtension@==10.1, pyobjc-framework-NotificationCenter@==10.1, pyobjc-framework-OpenDirectory@==10.1, pyobjc-framework-OSAKit@==10.1, pyobjc-framework-OSLog@==10.1, pyobjc-framework-PassKit@==10.1, pyobjc-framework-PencilKit@==10.1, pyobjc-framework-PHASE@==10.1, pyobjc-framework-Photos@==10.1, pyobjc-framework-PhotosUI@==10.1, pyobjc-framework-PreferencePanes@==10.1, pyobjc-framework-PushKit@==10.1, pyobjc-framework-Quartz@==10.1, pyobjc-framework-QuickLookThumbnailing@==10.1, pyobjc-framework-ReplayKit@==10.1, pyobjc-framework-SafariServices@==10.1, pyobjc-framework-SafetyKit@==10.1, pyobjc-framework-SceneKit@==10.1, pyobjc-framework-ScreenCaptureKit@==10.1, pyobjc-framework-ScreenSaver@==10.1, pyobjc-framework-ScreenTime@==10.1, pyobjc-framework-ScriptingBridge@==10.1, pyobjc-framework-SearchKit@==10.1, pyobjc-framework-Security@==10.1, pyobjc-framework-SecurityFoundation@==10.1, pyobjc-framework-SecurityInterface@==10.1, pyobjc-framework-SensitiveContentAnalysis@==10.1, pyobjc-framework-ServiceManagement@==10.1, pyobjc-framework-SharedWithYou@==10.1, pyobjc-framework-SharedWithYouCore@==10.1, pyobjc-framework-ShazamKit@==10.1, pyobjc-framework-Social@==10.1, pyobjc-framework-SoundAnalysis@==10.1, pyobjc-framework-Speech@==10.1, pyobjc-framework-SpriteKit@==10.1, pyobjc-framework-StoreKit@==10.1, pyobjc-framework-Symbols@==10.1, pyobjc-framework-SyncServices@==10.1, pyobjc-framework-SystemConfiguration@==10.1, pyobjc-framework-SystemExtensions@==10.1, pyobjc-framework-ThreadNetwork@==10.1, pyobjc-framework-UniformTypeIdentifiers@==10.1, pyobjc-framework-UserNotifications@==10.1, pyobjc-framework-UserNotificationsUI@==10.1, pyobjc-framework-VideoSubscriberAccount@==10.1, pyobjc-framework-VideoToolbox@==10.1, pyobjc-framework-Virtualization@==10.1, pyobjc-framework-Vision@==10.1, pyobjc-framework-WebKit@==10.1, pypdf, python-dotenv, requests@==2.31.0, setuptools@==69.1.1, simpleaudio@==1.0.4, sounddevice@==0.4.6, soundfile@==0.12.1, streamlit, twilio, urllib3@==2.2.1, websockets@==12.0, wheel@==0.42.0, zope.event@==5.0, zope.interface@==6.2

### Recent commits (newest first)

- Merge pull request #1 from jyothiv-codes/mrunmayee_changes
- Merge branch 'main' into mrunmayee_changes
- readme update
- Update chill.py
- Update main.py
- Update llm_learns.py
- REMOVE KEYS
- Update llm_learns_vertex.py
- logo change
- final file chillbert.py
- integrate others
- Merge remote-tracking branch 'origin/main' into mrunmayee_changes
- reordering the folder structure
- Editing front-end
- analyse chat code
- Merge remote-tracking branch 'refs/remotes/origin/mrunmayee_changes' into mrunmayee_changes
- combined_fileprocessing
- combined_fileprocessing
- logging text
- title change

## Key source files (fetched from GitHub, selected and truncated for size)

### requirements.txt

```
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
gevent==24.2.1
greenlet==3.0.3
idna==3.6
numpy==1.26.4
playsound==1.3.0
PyAudio==0.2.14
pycparser==2.21
pyobjc==10.1
pyobjc-core==10.1
pyobjc-framework-Accessibility==10.1
pyobjc-framework-Accounts==10.1
pyobjc-framework-AddressBook==10.1
pyobjc-framework-AdServices==10.1
pyobjc-framework-AdSupport==10.1
pyobjc-framework-AppleScriptKit==10.1
pyobjc-framework-AppleScriptObjC==10.1
pyobjc-framework-ApplicationServices==10.1
pyobjc-framework-AppTrackingTransparency==10.1
pyobjc-framework-AudioVideoBridging==10.1
pyobjc-framework-AuthenticationServices==10.1
pyobjc-framework-AutomaticAssessmentConfiguration==10.1
pyobjc-framework-Automator==10.1
pyobjc-framework-AVFoundation==10.1
pyobjc-framework-AVKit==10.1
pyobjc-framework-AVRouting==10.1
pyobjc-framework-BackgroundAssets==10.1
pyobjc-framework-BusinessChat==10.1
pyobjc-framework-CalendarStore==10.1
pyobjc-framework-CallKit==10.1
pyobjc-framework-CFNetwork==10.1
pyobjc-framework-Cinematic==10.1
pyobjc-framework-ClassKit==10.1
pyobjc-framework-CloudKit==10.1
pyobjc-framework-Cocoa==10.1
pyobjc-framework-Collaboration==10.1
pyobjc-framework-ColorSync==10.1
pyobjc-framework-Contacts==10.1
pyobjc-framework-ContactsUI==10.1
pyobjc-framework-CoreAudio==10.1
pyobjc-framework-CoreAudioKit==10.1
pyobjc-framework-CoreBluetooth==10.1
pyobjc-framework-CoreData==10.1
pyobjc-framework-CoreHaptics==10.1
pyobjc-framework-CoreLocation==10.1
pyobjc-framework-CoreMedia==10.1
pyobjc-framework-CoreMediaIO==10.1
pyobjc-framework-CoreMIDI==10.1
pyobjc-framework-CoreML==10.1
pyobjc-framework-CoreMotion==10.1
pyobjc-framework-CoreServices==10.1
pyobjc-framework-CoreSpotlight==10.1
pyobjc-framework-CoreText==10.1
pyobjc-framework-CoreWLAN==10.1
pyobjc-framework-CryptoTokenKit==10.1
pyobjc-framework-DataDetection==10.1
pyobjc-framework-DeviceCheck==10.1
pyobjc-framework-DictionaryServices==10.1
pyobjc-framework-DiscRecording==10.1
pyobjc-framework-DiscRecordingUI==10.1
pyobjc-framework-DiskArbitration==10.1
pyobjc-framework-DVDPlayback==10.1
pyobjc-framework-EventKit==10.1
pyobjc-framework-ExceptionHandling==10.1
pyobjc-framework-ExecutionPolicy==10.1
pyobjc-framework-ExtensionKit==10.1
pyobjc-framework-ExternalAccessory==10.1
pyobjc-framework-FileProvider==10.1
pyobjc-framework-FileProviderUI==10.1
pyobjc-framework-FinderSync==10.1
pyobjc-framework-FSEvents==10.1
pyobjc-framework-GameCenter==10.1
pyobjc-framework-GameController==10.1
pyobjc-framework-GameKit==10.1
pyobjc-framework-GameplayKit==10.1
pyobjc-framework-HealthKit==10.1
pyobjc-framework-ImageCaptureCore==10.1
pyobjc-framework-InputMethodKit==10.1
pyobjc-framework-InstallerPlugins==10.1
pyobjc-framework-InstantMessage==10.1
pyobjc-framework-Intents==10.1
pyobjc-framework-IntentsUI==10.1
pyobjc-framework-IOBluetooth==10.1
pyobjc-framework-IOBluetoothUI==10.1
pyobjc-framework-IOSurface==10.1
pyobjc-framework-iTunesLibrary==10.1
pyobjc-framework-KernelManagement==10.1
pyobjc-framework-LatentSemanticMapping==10.1
pyobjc-framework-LaunchServices==10.1
pyobjc-framework-libdispatch==10.1
pyobjc-framework-libxpc==10.1
pyobjc-framework-LinkPresentation==10.1
pyobjc-framework-LocalAuthentication==10.1
pyobjc-framework-LocalAuthenticationEmbeddedUI==10.1
pyobjc-framework-MailKit==10.1
pyobjc-framework-MapKit==10.1
pyobjc-framework-MediaAccessibility==10.1
pyobjc-framework-MediaLibrary==10.1
pyobjc-framework-MediaPlayer==10.1
pyobjc-framework-MediaToolbox==10.1
pyobjc-framework-Metal==10.1
pyobjc-framework-MetalFX==10.1
pyobjc-framework-MetalKit==10.1
pyobjc-framework-MetalPerformanceShaders==10.1
pyobjc-framework-MetalPerformanceShadersGraph==10.1
pyobjc-framework-MetricKit==10.1
pyobjc-framework-MLCompute==10.1
pyobjc-framework-ModelIO==10.1
pyobjc-framework-MultipeerConnectivity==10.1
pyobjc-framework-NaturalLanguage==10.1
pyobjc-framework-NetFS==10.1
pyobjc-framework-Network==10.1
pyobjc-framework-NetworkExtension==10.1
pyobjc-framework-NotificationCenter==10.1
pyobjc-framework-OpenDirectory==10.1
pyobjc-framework-OSAKit==10.1
pyobjc-framework-OSLog==10.1
pyobjc-framework-PassKit==10.1
pyobjc-framework-PencilKit==10.1
pyobjc-framework-PHASE==10.1
pyobjc-framework-Photos==10.1
pyobjc-framework-PhotosUI==10.1
pyobjc-framework-PreferencePanes==10.1
pyobjc-framework-PushKit==10.1
pyobjc-framework-Quartz==10.1
pyobjc-framework-QuickLookThumbnailing==10.1
pyobjc-framework-ReplayKit==10.1
pyobjc-framework-SafariServices==10.1
pyobjc-framework-SafetyKit==10.1
pyobjc-framework-SceneKit==10.1
pyobjc-framework-ScreenCaptureKit==10.1
pyobjc-framework-ScreenSaver==10.1
pyobjc-framework-ScreenTime==10.1
pyobjc-framework-ScriptingBridge==10.1
pyobjc-framework-SearchKit==10.1
pyobjc-framework-Security==10.1
pyobjc-framework-SecurityFoundation==10.1
pyobjc-framework-SecurityInterface==10.1
pyobjc-framework-SensitiveContentAnalysis==10.1
pyobjc-framework-ServiceManagement==10.1
pyobjc-framework-SharedWithYou==10.1
pyobjc-framework-SharedWithYouCore==10.1
pyobjc-framework-ShazamKit==10.1
pyobjc-framework-Social==10.1
pyobjc-framework-SoundAnalysis==10.1
pyobjc-framework-Speech==10.1
pyobjc-framework-SpriteKit==10.1
pyobjc-framework-StoreKit==10.1
pyobjc-framework-Symbols==10.1
pyobjc-framework-SyncServices==10.1
pyobjc-framework-SystemConfiguration==10.1
pyobjc-framework-SystemExtensions==10.1
pyobjc-framework-ThreadNetwork==10.1
pyobjc-framework-UniformTypeIdentifiers==10.1
pyobjc-framework-UserNotifications==10.1
pyobjc-framework-UserNotificationsUI==10.1
pyobjc-framework-VideoSubscriberAccount==10.1
pyobjc-framework-VideoToolbox==10.1
pyobjc-framework-Virtualization==10.1
pyobjc-framework-Vision==10.1
pyobjc-framework-WebKit==10.1
requests==2.31.0
setuptools==69.1.1
simpleaudio==1.0.4
sounddevice==0.4.6
soundfile==0.12.1
urllib3==2.2.1
websockets==12.0
wheel==0.42.0
zope.event==5.0
zope.interface==6.2
python-dotenv
langchain
langchain_google_genai
langchain-community
pypdf
chromadb
twilio
langchain_chroma
fpdf
streamlit
```

### src/main.py

```python
import asyncio
import os
import streamlit as st  # Streamlit framework
from authenticator import Authenticator
from connection import Connection
from dotenv import load_dotenv
from pyaudio import PyAudio, paInt16


# Apply custom CSS for white background and black text
st.markdown(
    """
    <style>
        body {
            background-color: #FFFFFF !important;
            color: #000000 !important;
        }
        .stButton button {
            background-color: #000000;
            color: #FFFFFF;
            font-size: 18px;
            border-radius: 10px;
            width: 200px;
            height: 50px;
        }
    </style>
    """,
    unsafe_allow_html=True,

)

# Streamlit Title
st.title("Hi! I'm Chillbert")

# Audio format and parameters
FORMAT = paInt16
CHANNELS = 1
SAMPLE_WIDTH = 2  # PyAudio.get_sample_size(pyaudio, format=paInt16)
CHUNK_SIZE = 1024

# Hardcoded audio device indices and sample rate
INPUT_DEVICE_INDEX = 0  # Replace with correct input device index if needed
OUTPUT_DEVICE_INDEX = 1  # Replace with correct output device index if needed
SAMPLE_RATE = 48000  # Set your desired sample rate

# Initialize session state variables
if "task" not in st.session_state:
    st.session_state.task = None
if "loop" not in st.session_state:
    st.session_state.loop = asyncio.new_event_loop()

# Main asynchronous function
async def main():
    """
    Main asynchronous function to set up audio devices, authenticate, and connect to the Hume AI websocket.
    """
    # Initialize PyAudio instance
    pyaudio = PyAudio()

    # Open the audio stream with the selected parameters
    audio_stream = pyaudio.open(
        format=FORMAT,
        channels=CHANNELS,
        frames_per_buffer=CHUNK_SIZE,
        rate=SAMPLE_RATE,
        input=True,
        output=True,
        input_device_index=INPUT_DEVICE_INDEX,
        output_device_index=OUTPUT_DEVICE_INDEX,
    )

    # Fetch the access token for authentication
    access_token = get_access_token()

    # Construct the websocket URL with the access token
    socket_url = (
        "wss://api.hume.ai/v0/assistant/chat?"
        f"access_token={access_token}&"
        f"config_id=9a7e6382-efba-4cff-9dd2-1d16eceefce2"
    )

    try:
        # Connect to the websocket and start the audio stream
        await Connection.connect(
            socket_url,
            audio_stream,
            SAMPLE_RATE,
            SAMPLE_WIDTH,
            CHANNELS,
            CHUNK_SIZE,
        )
    except asyncio.CancelledError:
        st.write("Conversation ended.")
    finally:
        # Close the PyAudio stream and terminate PyAudio
        audio_stream.stop_stream()
        audio_stream.close()
        pyaudio.terminate()


def get_access_token() -> str:
    """
    Load API credentials from environment variables and fetch an access token.
    """
    load_dotenv()

    # Retrieve API key and Secret key from environment variables
    HUME_API_KEY = os.getenv("HUME_API_KEY")
    HUME_SECRET_KEY = os.getenv("HUME_SECRET_KEY")
    HUME_CONFIG_ID=os.getenv("HUME_CONFIG_ID")

    if HUME_API_KEY is None or HUME_SECRET_KEY is None:
        st.error("HUME_API_KEY and HUME_SECRET_KEY must be set in environment variables.")
        st.stop()

    authenticator = Authenticator(HUME_API_KEY, HUME_SECRET_KEY)
    return authenticator.fetch_access_token()


# Start conversation button with a unique key
if st.button("Start Conversation", key="start_button"):
    st.write("Let's fetch your buddy!")
    
    # Run the async task using the custom event loop
    loop = st.session_state.loop
    st.session_state.task = loop.create_task(main())
    loop.run_until_complete(st.session_state.task)

```

### chill.py

```python
import streamlit as st
import asyncio
import os
from src.authenticator import Authenticator
from src.connection import Connection
from src.analyse_chat import AnalyseChat
from dotenv import load_dotenv
from pyaudio import PyAudio, paInt16


load_dotenv()

# Audio format and parameters
FORMAT = paInt16
CHANNELS = 1
SAMPLE_WIDTH = 2  # PyAudio.get_sample_size(pyaudio, format=paInt16)
CHUNK_SIZE = 1024

# Hardcoded audio device indices and sample rate
INPUT_DEVICE_INDEX = 0  # Replace with correct input device index if needed
OUTPUT_DEVICE_INDEX = 1  # Replace with correct output device index if needed
SAMPLE_RATE = 48000  # Set your desired sample rate

if "task" not in st.session_state:
    st.session_state.task = None
if "loop" not in st.session_state:
    st.session_state.loop = asyncio.new_event_loop()


# Main asynchronous function
async def main():
    """
    Main asynchronous function to set up audio devices, authenticate, and connect to the Hume AI websocket.
    """
    # Initialize PyAudio instance
    pyaudio = PyAudio()

    # Open the audio stream with the selected parameters
    audio_stream = pyaudio.open(
        format=FORMAT,
        channels=CHANNELS,
        frames_per_buffer=CHUNK_SIZE,
        rate=SAMPLE_RATE,
        input=True,
        output=True,
        input_device_index=INPUT_DEVICE_INDEX,
        output_device_index=OUTPUT_DEVICE_INDEX,
    )

    # Fetch the access token for authentication
    access_token = get_access_token()

    # Construct the websocket URL with the access token
    socket_url = (
        "wss://api.hume.ai/v0/assistant/chat?"
        f"access_token={access_token}&"
        f"config_id=9a7e6382-efba-4cff-9dd2-1d16eceefce2"
    )

    try:
        # Connect to the websocket and start the audio stream
        await Connection.connect(
            socket_url,
            audio_stream,
            SAMPLE_RATE,
            SAMPLE_WIDTH,
            CHANNELS,
            CHUNK_SIZE,
        )
    except asyncio.CancelledError:
        st.write("Conversation ended.")
    finally:
        # Close the PyAudio stream and terminate PyAudio
        audio_stream.stop_stream()
        audio_stream.close()
        pyaudio.terminate()


def get_access_token() -> str:

    # Retrieve API key and Secret key from environment variables
    HUME_API_KEY = os.getenv("HUME_API_KEY")
    HUME_SECRET_KEY = os.getenv("HUME_SECRET_KEY")
    HUME_CONFIG_ID=os.getenv("HUME_CONFIG_ID")

    if HUME_API_KEY is None or HUME_SECRET_KEY is None:
        st.error("HUME_API_KEY and HUME_SECRET_KEY must be set in environment variables.")
        st.stop()

    authenticator = Authenticator(HUME_API_KEY, HUME_SECRET_KEY)
    return authenticator.fetch_access_token()

def chillbert_response():
    #return "Hello! I'm Chillbert, how can I help you today?"
    """ = st.session_state.loop
    st.session_state.task = loop.create_task(main())
    loop.run_until_complete(st.session_state.task)"""
    return

# Streamlit layout
st.set_page_config(page_title="Chillbert - Mood-Driven Voice Assistant", layout="wide")


# Add custom CSS for background color and other styles
st.markdown("""
    <style>
    #      [data-testid=stSidebar] {
    #     background-color:rgb(11 87 137);
    #     opacity: 0.1
    #     color:white
    # } 
            
    /* Full background color for the first column behind the image */
    .col1-background {
        background-color: #F0F8FF; /* Light blue color */
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 50%; /* Adjust depending on the column width */
        z-index: -1; /* Put the background behind the content */
    }

    /* Flexbox to keep the image centered */
    .image-container {
        display: flex;
        align-items: center;
        justify-content: center;
        /* height: 100vh; Full height to ensure vertical centering */
    }

    /* Button hover effect */
    .stButton > button:hover {
        background-color: #FF5733;
        color: white;
    }

    /* Button style */
    .stButton > button {
        font-size: 18px;
        padding: 10px 20px;
        border-radius: 10px;
    }
    </style>
    """, unsafe_allow_html=True)


# Sidebar for navigation
#st.sidebar.title("Chillbert")
st.sidebar.markdown('<h1 style="text-align:center; color:white">Chillbert</h1>', unsafe_allow_html=True)
page = st.sidebar.radio("Navigate", ["Start Conversation", "For Practitioners"])

# First Page: Start Conversation with Chillbert
if page == "Start Conversation":
    st.title("Welcome to Chillbert!")
    
    # Layout with two columns
    col1, col2 = st.columns(2)
    
    with col1:
        # Apply background color to the whole column without affecting the image
        st.markdown('<div class="col1-background"></div>', unsafe_allow_html=True)
        
        # Flexbox to center the image properly
        st.markdown('<div class="image-container">', unsafe_allow_html=True)
        st.image("chillbert3.png", caption="Chillbert", use_column_width=True)
        st.markdown('</div>', unsafe_allow_html=True)
        
    with col2:
        # Create a centered container
        st.markdown('<div class="centered-text">', unsafe_allow_html=True)
        st.write("### Ask Chillbert Anything!")
        if st.button("Say Hello"):
            loop = st.session_state.loop
            st.session_state.task = loop.create_task(main())
            loop.run_until_complete(st.session_state.task)
        if st.button('Stop Conversation'):
            ac = AnalyseChat()
            ac.setup()
            st.session_state['ac'] = ac
            print("AC UPDATED")
            if st.session_state.task is not None and not st.session_state.task.done():
                st.session_state.task.cancel()  # Cancel the WebSocket connection task
                try:
                    loop.run_until_complete(st.session_state.task)  # Ensure it's fully canceled
                except asyncio.CancelledError:
                    
[truncated — 1671 more characters]
```

### chillbert.py

```python
import streamlit as st
import asyncio
import os
from src.authenticator import Authenticator
from src.connection import Connection
from src.analyse_chat import AnalyseChat
from dotenv import load_dotenv
from pyaudio import PyAudio, paInt16


load_dotenv()

# Audio format and parameters
FORMAT = paInt16
CHANNELS = 1
SAMPLE_WIDTH = 2  # PyAudio.get_sample_size(pyaudio, format=paInt16)
CHUNK_SIZE = 1024

# Hardcoded audio device indices and sample rate
INPUT_DEVICE_INDEX = 0  # Replace with correct input device index if needed
OUTPUT_DEVICE_INDEX = 1  # Replace with correct output device index if needed
SAMPLE_RATE = 48000  # Set your desired sample rate

if "task" not in st.session_state:
    st.session_state.task = None
if "loop" not in st.session_state:
    st.session_state.loop = asyncio.new_event_loop()


# Main asynchronous function
async def main():
    """
    Main asynchronous function to set up audio devices, authenticate, and connect to the Hume AI websocket.
    """
    # Initialize PyAudio instance
    pyaudio = PyAudio()

    # Open the audio stream with the selected parameters
    audio_stream = pyaudio.open(
        format=FORMAT,
        channels=CHANNELS,
        frames_per_buffer=CHUNK_SIZE,
        rate=SAMPLE_RATE,
        input=True,
        output=True,
        input_device_index=INPUT_DEVICE_INDEX,
        output_device_index=OUTPUT_DEVICE_INDEX,
    )

    # Fetch the access token for authentication
    access_token = get_access_token()

    # Construct the websocket URL with the access token
    socket_url = (
        "wss://api.hume.ai/v0/assistant/chat?"
        f"access_token={access_token}&"
        f"config_id=9a7e6382-efba-4cff-9dd2-1d16eceefce2"
    )

    try:
        # Connect to the websocket and start the audio stream
        await Connection.connect(
            socket_url,
            audio_stream,
            SAMPLE_RATE,
            SAMPLE_WIDTH,
            CHANNELS,
            CHUNK_SIZE,
        )
    except asyncio.CancelledError:
        st.write("Conversation ended.")
    finally:
        # Close the PyAudio stream and terminate PyAudio
        audio_stream.stop_stream()
        audio_stream.close()
        pyaudio.terminate()


def get_access_token() -> str:

    # Retrieve API key and Secret key from environment variables
    HUME_API_KEY = os.getenv("HUME_API_KEY")
    HUME_SECRET_KEY = os.getenv("HUME_SECRET_KEY")

    if HUME_API_KEY is None or HUME_SECRET_KEY is None:
        st.error("HUME_API_KEY and HUME_SECRET_KEY must be set in environment variables.")
        st.stop()

    authenticator = Authenticator(HUME_API_KEY, HUME_SECRET_KEY)
    return authenticator.fetch_access_token()

# def start_convo():

# def end_convo():
    

def ac_setup():
    if 'ac' not in st.session_state:
        ac = AnalyseChat()
        ac.setup()
        st.session_state['ac'] = ac
    
def chillbert_response(question):
    ac = st.session_state['ac']
    return ac.askChatbot(question) 
                

st.set_page_config(page_title="Chillbert - Mood-Driven Voice Assistant", layout="wide")


# Add custom CSS for background color and other styles
st.markdown("""
    <style>
    #      [data-testid=stSidebar] {
    #     background-color:rgb(11 87 137);
    #     opacity: 0.1
    #     color:white
    # } 
            
    /* Full background color for the first column behind the image */
    .col1-background {
        background-color: #F0F8FF; /* Light blue color */
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 50%; /* Adjust depending on the column width */
        z-index: -1; /* Put the background behind the content */
    }

    /* Flexbox to keep the image centered */
    .image-container {
        display: flex;
        align-items: center;
        justify-content: center;
        /* height: 100vh; Full height to ensure vertical centering */
    }

    /* Button hover effect */
    .stButton > button:hover {
        background-color: rgb(16 180 197);
        color: white;
    }

    /* Button style */
    .stButton > button {
        font-size: 18px;
        padding: 10px 20px;
        border-radius: 10px;
        border: 5px solid rgb(16 180 197);
        font-family: ui-monospace;
    }
    </style>
    """, unsafe_allow_html=True)


# Sidebar for navigation
#st.sidebar.title("Chillbert")
#st.sidebar.markdown('<h1 style="text-align:center; color:rgb(16 180 197)">Chillbert</h1>', unsafe_allow_html=True)
#st.sidebar.write(':robot_face:')
 
st.sidebar.image("ChillbertLogo-removebg-preview.png", use_column_width=True)
#st.sidebar.markdown('<h1 style="text-align:center; color:rgb(c:\Users\Checkout\Downloads\ChillbertLogo-removebg-preview.png); font-style: bold-italic"> CHILLBERT</h1>', unsafe_allow_html=True)
page = st.sidebar.radio("Navigate", ["Start Conversation", "For Practitioners"])

# First Page: Start Conversation with Chillbert
if page == "Start Conversation":
    #st.title("Welcome to Chillbert!")
    
    # Layout with two columns
    col1, col2 = st.columns(2)
    
    with col1:
        # Apply background color to the whole column without affecting the image
        st.markdown('<div class="col1-background"></div>', unsafe_allow_html=True)
        
        # Flexbox to center the image properly
        st.markdown('<div class="image-container">', unsafe_allow_html=True)
        st.markdown("![chillbert.gif](https://cdn.dribbble.com/users/7421625/screenshots/18722183/media/57f4bd5aea84c23e226069f65e417704.gif)")
        st.markdown('</div>', unsafe_allow_html=True)
        
    with col2:
        # Create a centered container
        st.write('###')
        st.write()
        st.markdown('<div class="centered-text">', unsafe_allow_html=True)
        #st.write("### Ask Chillbert Anything!")

        loop = st.session_state.loop
        st.markdown('<h4 style="text-align:center; color:rgb(16 180 197); font-style: italic">Your emotional sidekick with all the cool vibes!</h1>', unsafe_allow_html=T
[truncated — 2597 more characters]
```

### src/messanger.py

```python
from twilio.rest import Client
import os

class Messanger:
        
	def __init__(self):
		account_sid = os.environ['TWILIO_ACCOUNT_SID']
		auth_token = os.environ['TWILIO_AUTH_TOKEN']
		self.client = Client(account_sid, auth_token)

	def sendMessage(self, msg, recipient):
		if len(msg)>1500:
			msg = msg[:1500]
		self.client.messages.create(
		from_='whatsapp:+14155238886',
		body=msg,
		to=f'whatsapp:{recipient}'
		)
		# print("Message sent")

```

### src/remove_audio_data.py

```python
import re
import json

def remove_data_key_from_file(input_file, output_file):
    with open(input_file, 'r') as file:
        content = file.read()  # Read the entire content of the file

    # Regular expression to match `'data': <value>` patterns
    cleaned_content = re.sub(r"'data':\s*'[^']*'", '', content)

    # Optionally, remove any trailing commas left behind by the removal
    cleaned_content = re.sub(r",\s*}", '}', cleaned_content)

    with open(output_file, 'w') as file:
        file.write(cleaned_content)  # Write the modified content to a new file

    print(f"Cleaned content saved to {output_file}")

# Usage
input_file = 'audio_responses_log.txt'   # Replace with the path to your input file
output_file = 'audio_responses_cleaned.txt' # Replace with the desired output file path

remove_data_key_from_file(input_file, output_file)

```

### src/text_to_pdf.py

```python
from fpdf import FPDF

class PDF(FPDF):
    def __init__(self):
        super().__init__()
        # Add Arial Unicode font during initialization
        self.add_font("ArialUnicode", "", "/Library/Fonts/Arial Unicode.ttf")

    def header(self):
        # Set the font for the header after it's added
        self.set_font("ArialUnicode", "", 12)
        self.cell(0, 10, "Text to PDF Conversion", 0, 1, "C")

def txt_to_pdf(txt_file, pdf_file):
    pdf = PDF()
    pdf.add_page()

    # Set the same font for the main content
    pdf.set_font("ArialUnicode", "", 12)

    # Read the .txt file and add its content to the PDF
    with open(txt_file, 'r', encoding='utf-8') as file:
        for line in file:
            pdf.multi_cell(0, 10, line)

    # Save the PDF
    pdf.output(pdf_file)
    print(f"PDF saved at: {pdf_file}")


txt_file = "audio_responses_cleaned.txt"  # Replace with your .txt file path
pdf_file = "audio_responses_cleaned.pdf"  # Desired .pdf file path
txt_to_pdf(txt_file, pdf_file)

```

### src/llm_learns.py

```python
import openai

# Set your OpenAI API key

from openai import OpenAI

# Sample content to include in the system prompt
with open("audio_responses_cleaned.txt", "r", encoding="utf-8") as file:
    sample_content = file.read()

def fetch_answer(user_input):
    # Initialize the OpenAI client
    client = OpenAI(
    # This is the default and can be omitted
    api_key=openai.api_key
)
    # Creating the chat completion request
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",  # Model selection
        messages=[
            {
                "role": "system",
                "content": f"You will be provided with a question, and you have to fetch insights for the same from {sample_content}"
            },
            {
                "role": "user",
                "content": user_input
            }
        ],
        temperature=0.2,  # Controls randomness: lower values make output more focused
        max_tokens=1000,   # Limits the response length
        top_p=1.0,         # Nucleus sampling; 1.0 means no filtering
    )
   

    # Print the model's response
    print(response.choices[0].message.content)

user_input=input("Enter your question: ")
fetch_answer(user_input)

```

### src/llm_learns_vertex.py

```python
import streamlit as st
#Gen AI code 
import markdown
import pathlib
import textwrap

import google.generativeai as genai

from IPython.display import display
from IPython.display import Markdown


# Or use `os.getenv('GOOGLE_API_KEY')` to fetch an environment variable.

model = genai.GenerativeModel('gemini-pro')

genai.configure(api_key=GOOGLE_API_KEY)

for m in genai.list_models():
  if 'generateContent' in m.supported_generation_methods:
    print(m.name)

with st.form("get_recommendation"):
   
   st.write("What would you like to watch today?")
   search = st.text_input('', '')
   submitted = st.form_submit_button("Submit")
   if submitted:
       
       confirm=model.generate_content("is the following sentence asking for movie recommendation "+search+".If yes, then is the confidence percentage greater than or equal to 90. Only say yes or no")
       print("Related to movies, yes or no?",confirm.text)
       percentage=confirm.text
       if percentage=="yes":
        response = model.generate_content(search)
        answer=response.text
        markdown.markdown(answer)
        st.write(answer)
       else:
          st.write("I'm not sure if what you are searching for is related to movies? Could you please check again?")
    
    
if submitted:
    st.write("Hope you like these recommendations! Enjoy with popcorn and a soda!")

```

### src/analyse_chat.py

```python
from src.fileprocessing import FileProcessing
from src.chatbot import ChatBot
from src.messanger import Messanger
import os

from dotenv import load_dotenv


load_dotenv()


class AnalyseChat:

    def __init__(self):
        self.fp = FileProcessing('logs/emotion_logs')
        self.m = Messanger()
        self.setup_complete=False

    def setup(self):


        print('Setting up Chat Analysis')
        output_file = self.fp.processFile()
        self.cb = ChatBot(output_file)

        summary = self.cb.summarize()
        links = self.cb.getlinks(summary)
        self.sendChatSummary(summary)
        self.sendHelpfulLinks(links)
        print('sent messages')
        # self.cb.ask_anything_continuous()

    def sendChatSummary(self, summary_message):
        msg = f'Your patient XYZ recently spoke to me. Here is the summary of our conversation. \n{summary_message}'
        self.m.sendMessage(msg, os.environ['TWILIO_RECIPIENT'])

    def sendHelpfulLinks(self, link_message):
        msg = f'I really enjoyed our converation today. Based on our chat, here are a few helpful links for you!\n{link_message}'
        self.m.sendMessage(msg, os.environ['TWILIO_RECIPIENT'])

    def askChatbot(self, question):
        resp = self.cb.ask_anything(question)
        # print(f'Response:{resp}')
        return resp

# ac = AnalyseChat()
# ac.setup()
# print(ac.askChatbot('How are the users emotions?'))
```

[6 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]