sonuprasad23 commited on
Commit
d75f4a0
Β·
1 Parent(s): f2ac968
Files changed (3) hide show
  1. .streamlit/config.toml +2 -0
  2. Dockerfile +10 -9
  3. app.py +6 -40
.streamlit/config.toml ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ [browser]
2
+ gatherUsageStats = false
Dockerfile CHANGED
@@ -1,27 +1,28 @@
1
  # Use a stable, official Python image
2
  FROM python:3.10-slim
3
 
4
- # --- THIS IS THE FIX ---
5
- # Install system-level dependencies needed to build audio packages like PyAudio.
6
- # `build-essential` contains the gcc compiler.
7
- # `portaudio19-dev` contains the development headers for PortAudio.
8
  RUN apt-get update && apt-get install -y \
9
  build-essential \
10
  portaudio19-dev \
11
  && rm -rf /var/lib/apt/lists/*
12
 
13
- # Set the working directory inside the container
14
  WORKDIR /app
15
 
16
- # Copy the requirements file and install dependencies
17
- # This leverages Docker caching to speed up future builds
 
 
 
 
18
  COPY requirements.txt .
19
  RUN pip install --no-cache-dir -r requirements.txt
20
 
21
- # Copy the rest of your application files into the container
22
  COPY . .
23
 
24
- # Expose the port that Hugging Face uses for Streamlit apps
25
  EXPOSE 7860
26
 
27
  # Command to run the application
 
1
  # Use a stable, official Python image
2
  FROM python:3.10-slim
3
 
4
+ # --- FIX 1: Install system dependencies for audio package compilation ---
 
 
 
5
  RUN apt-get update && apt-get install -y \
6
  build-essential \
7
  portaudio19-dev \
8
  && rm -rf /var/lib/apt/lists/*
9
 
10
+ # Set the working directory
11
  WORKDIR /app
12
 
13
+ # --- FIX 2: Create a directory for Streamlit config and copy our new config file ---
14
+ # This prevents the PermissionError by disabling telemetry.
15
+ RUN mkdir -p .streamlit
16
+ COPY .streamlit/config.toml .streamlit/
17
+
18
+ # Copy requirements and install them
19
  COPY requirements.txt .
20
  RUN pip install --no-cache-dir -r requirements.txt
21
 
22
+ # Copy the rest of the application files
23
  COPY . .
24
 
25
+ # Expose the port Hugging Face uses
26
  EXPOSE 7860
27
 
28
  # Command to run the application
app.py CHANGED
@@ -24,7 +24,6 @@ def load_and_set_config():
24
 
25
  # --- VAPI Call Logic ---
26
  def place_vapi_call(config, customer_number, raw_intent, target_name):
27
- # Process intent to generate a good first message
28
  genai.configure(api_key=config["GEMINI_API_KEY"])
29
  model = genai.GenerativeModel('gemini-1.5-flash')
30
 
@@ -47,10 +46,9 @@ def place_vapi_call(config, customer_number, raw_intent, target_name):
47
  st.error(f"Error with Gemini: {e}")
48
  return None
49
 
50
- # Place the actual call
51
  try:
52
  vapi = Vapi(token=config["VAPI_API_KEY"])
53
- system_prompt = "You are a helpful and polite AI assistant named Alex. Your first sentence has already been spoken. You are now in an active conversation. Listen carefully and respond naturally. Continue the conversation in the language the other person is speaking (English or Hindi)."
54
 
55
  return vapi.calls.create(
56
  assistant_id=config["VAPI_ASSISTANT_ID"],
@@ -68,12 +66,11 @@ def place_vapi_call(config, customer_number, raw_intent, target_name):
68
  st.error(f"An error occurred placing the Vapi call: {e}")
69
  return None
70
 
71
- # --- FLASK WEBHOOK (Runs in the Background) ---
72
  flask_app = Flask(__name__)
73
 
74
  def log_to_google_sheet(row_data, config):
75
  try:
76
- print("[Log] Attempting to log to Google Sheets...")
77
  if not os.path.exists("credentials.json"):
78
  print("[Log] FATAL: 'credentials.json' not found.")
79
  return
@@ -89,7 +86,7 @@ def log_to_google_sheet(row_data, config):
89
 
90
  @flask_app.route("/webhook", methods=['POST'])
91
  def webhook_handler():
92
- print(f"\n--- Webhook received POST request from Vapi at {datetime.now()} ---")
93
  try:
94
  payload = request.json
95
  if payload.get('message', {}).get('type') == 'hang':
@@ -108,45 +105,19 @@ def webhook_handler():
108
  return jsonify({'status': 'success'}), 200
109
 
110
  def run_flask():
111
- # Running on a different port than Streamlit
112
  flask_app.run(host="0.0.0.0", port=8080)
113
 
114
- # --- STREAMLIT UI (Main Application) ---
115
  def run_streamlit():
116
  st.set_page_config(page_title="Voice AI Coordinator", layout="centered")
117
-
118
- # Custom CSS for a pleasing look
119
- st.markdown("""
120
- <style>
121
- .stApp {
122
- background-color: #f0f2f5;
123
- }
124
- .stForm {
125
- background-color: white;
126
- padding: 2em;
127
- border-radius: 10px;
128
- box-shadow: 0 4px 12px rgba(0,0,0,0.1);
129
- }
130
- .stButton>button {
131
- width: 100%;
132
- border: none;
133
- border-radius: 5px;
134
- padding: 10px;
135
- font-weight: bold;
136
- color: white;
137
- background-color: #ff4b4b;
138
- }
139
- </style>
140
- """, unsafe_allow_html=True)
141
-
142
  st.title("πŸš€ Voice AI Coordination Tool")
143
  st.markdown("A unified interface to deploy intelligent voice agents on your behalf.")
144
 
145
- # Load configuration
146
  try:
147
  config = load_and_set_config()
148
  except Exception as e:
149
- st.error(f"Failed to load configuration. Please ensure APP_CONFIG_JSON secret is set correctly. Error: {e}")
150
  st.stop()
151
 
152
  with st.form(key="call_form"):
@@ -154,7 +125,6 @@ def run_streamlit():
154
  target_name = st.text_input("Whom are you calling? (Optional)", placeholder="e.g., Jane Doe")
155
  phone_number = st.text_input("Phone Number (with country code)", placeholder="+911234567890")
156
  raw_intent = st.text_area("Reason for Calling", placeholder="Ask if they would prefer tea or coffee", height=100)
157
-
158
  submit_button = st.form_submit_button(label="Deploy Call")
159
 
160
  if submit_button:
@@ -165,15 +135,11 @@ def run_streamlit():
165
  call_response = place_vapi_call(config, phone_number, raw_intent, target_name)
166
  if call_response and call_response.id:
167
  st.success(f"βœ… Call deployed successfully! Call ID: {call_response.id}")
168
- st.info("The call is being connected. Once it ends, the data will be logged to your Google Sheet.")
169
  st.balloons()
170
  else:
171
  st.error("❌ Failed to deploy the call. Please check the Space logs for errors.")
172
 
173
  if __name__ == "__main__":
174
- # Run Flask in a background daemon thread
175
  flask_thread = threading.Thread(target=run_flask, daemon=True)
176
  flask_thread.start()
177
-
178
- # Run the main Streamlit app
179
  run_streamlit()
 
24
 
25
  # --- VAPI Call Logic ---
26
  def place_vapi_call(config, customer_number, raw_intent, target_name):
 
27
  genai.configure(api_key=config["GEMINI_API_KEY"])
28
  model = genai.GenerativeModel('gemini-1.5-flash')
29
 
 
46
  st.error(f"Error with Gemini: {e}")
47
  return None
48
 
 
49
  try:
50
  vapi = Vapi(token=config["VAPI_API_KEY"])
51
+ system_prompt = "You are a helpful and polite AI assistant named Alex. Your first sentence has already been spoken. Listen carefully and respond naturally. Continue the conversation in the language the other person is speaking (English or Hindi)."
52
 
53
  return vapi.calls.create(
54
  assistant_id=config["VAPI_ASSISTANT_ID"],
 
66
  st.error(f"An error occurred placing the Vapi call: {e}")
67
  return None
68
 
69
+ # --- FLASK WEBHOOK ---
70
  flask_app = Flask(__name__)
71
 
72
  def log_to_google_sheet(row_data, config):
73
  try:
 
74
  if not os.path.exists("credentials.json"):
75
  print("[Log] FATAL: 'credentials.json' not found.")
76
  return
 
86
 
87
  @flask_app.route("/webhook", methods=['POST'])
88
  def webhook_handler():
89
+ print(f"\n--- Webhook received POST request at {datetime.now()} ---")
90
  try:
91
  payload = request.json
92
  if payload.get('message', {}).get('type') == 'hang':
 
105
  return jsonify({'status': 'success'}), 200
106
 
107
  def run_flask():
 
108
  flask_app.run(host="0.0.0.0", port=8080)
109
 
110
+ # --- STREAMLIT UI ---
111
  def run_streamlit():
112
  st.set_page_config(page_title="Voice AI Coordinator", layout="centered")
113
+ st.markdown("""<style>.stApp{background-color: #f0f2f5;} .stForm{background-color: white; padding: 2em; border-radius: 10px; box-shadow: 0 4px 12px rgba(0,0,0,0.1);} .stButton>button{width: 100%; border: none; border-radius: 5px; padding: 10px; font-weight: bold; color: white; background-color: #ff4b4b;}</style>""", unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  st.title("πŸš€ Voice AI Coordination Tool")
115
  st.markdown("A unified interface to deploy intelligent voice agents on your behalf.")
116
 
 
117
  try:
118
  config = load_and_set_config()
119
  except Exception as e:
120
+ st.error(f"Failed to load configuration. Error: {e}")
121
  st.stop()
122
 
123
  with st.form(key="call_form"):
 
125
  target_name = st.text_input("Whom are you calling? (Optional)", placeholder="e.g., Jane Doe")
126
  phone_number = st.text_input("Phone Number (with country code)", placeholder="+911234567890")
127
  raw_intent = st.text_area("Reason for Calling", placeholder="Ask if they would prefer tea or coffee", height=100)
 
128
  submit_button = st.form_submit_button(label="Deploy Call")
129
 
130
  if submit_button:
 
135
  call_response = place_vapi_call(config, phone_number, raw_intent, target_name)
136
  if call_response and call_response.id:
137
  st.success(f"βœ… Call deployed successfully! Call ID: {call_response.id}")
 
138
  st.balloons()
139
  else:
140
  st.error("❌ Failed to deploy the call. Please check the Space logs for errors.")
141
 
142
  if __name__ == "__main__":
 
143
  flask_thread = threading.Thread(target=run_flask, daemon=True)
144
  flask_thread.start()
 
 
145
  run_streamlit()