Update Gpt4oDemo.py
Browse files- Gpt4oDemo.py +411 -401
Gpt4oDemo.py
CHANGED
@@ -1,402 +1,412 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
import plotly.graph_objs as go
|
3 |
-
import numpy as np
|
4 |
-
import time
|
5 |
-
from openai import OpenAI
|
6 |
-
import os
|
7 |
-
from hardCodedData import *
|
8 |
-
from Helper import *
|
9 |
-
import cv2
|
10 |
-
from moviepy.editor import VideoFileClip
|
11 |
-
import time
|
12 |
-
import base64
|
13 |
-
import whisperx
|
14 |
-
import gc
|
15 |
-
from moviepy.editor import VideoFileClip
|
16 |
-
from dotenv import load_dotenv
|
17 |
-
|
18 |
-
load_dotenv()
|
19 |
-
|
20 |
-
'''
|
21 |
-
Model Information
|
22 |
-
GPT4o
|
23 |
-
'''
|
24 |
-
|
25 |
-
import openai
|
26 |
-
api_key = os.getenv("OPENAI_API_KEY")
|
27 |
-
client = openai.OpenAI(
|
28 |
-
api_key=api_key,
|
29 |
-
base_url="https://openai.gateway.salt-lab.org/v1",
|
30 |
-
)
|
31 |
-
MODEL="gpt-4o"
|
32 |
-
|
33 |
-
# Whisperx config
|
34 |
-
device = "cpu"
|
35 |
-
batch_size = 16 # reduce if low on GPU mem
|
36 |
-
compute_type = "int8" # change to "int8" if low on GPU mem (may reduce accuracy)
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
#
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
#
|
89 |
-
#
|
90 |
-
#
|
91 |
-
#
|
92 |
-
#
|
93 |
-
#
|
94 |
-
#
|
95 |
-
|
96 |
-
#
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
[
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
#
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
402 |
demo.launch(share=True)
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import plotly.graph_objs as go
|
3 |
+
import numpy as np
|
4 |
+
import time
|
5 |
+
from openai import OpenAI
|
6 |
+
import os
|
7 |
+
from hardCodedData import *
|
8 |
+
from Helper import *
|
9 |
+
import cv2
|
10 |
+
from moviepy.editor import VideoFileClip
|
11 |
+
import time
|
12 |
+
import base64
|
13 |
+
import whisperx
|
14 |
+
import gc
|
15 |
+
from moviepy.editor import VideoFileClip
|
16 |
+
from dotenv import load_dotenv
|
17 |
+
|
18 |
+
load_dotenv()
|
19 |
+
|
20 |
+
'''
|
21 |
+
Model Information
|
22 |
+
GPT4o
|
23 |
+
'''
|
24 |
+
|
25 |
+
import openai
|
26 |
+
api_key = os.getenv("OPENAI_API_KEY")
|
27 |
+
client = openai.OpenAI(
|
28 |
+
api_key=api_key,
|
29 |
+
base_url="https://openai.gateway.salt-lab.org/v1",
|
30 |
+
)
|
31 |
+
MODEL="gpt-4o"
|
32 |
+
|
33 |
+
# Whisperx config
|
34 |
+
device = "cpu"
|
35 |
+
batch_size = 16 # reduce if low on GPU mem
|
36 |
+
compute_type = "int8" # change to "int8" if low on GPU mem (may reduce accuracy)
|
37 |
+
max_new_tokens = 512 # Example value, adjust as needed
|
38 |
+
clip_timestamps = True # Example value, adjust as needed
|
39 |
+
hallucination_silence_threshold = 0.5 # Example value, adjust as needed
|
40 |
+
|
41 |
+
# Load the model with the required arguments
|
42 |
+
default_asr_options = {
|
43 |
+
"max_new_tokens": max_new_tokens,
|
44 |
+
"clip_timestamps": clip_timestamps,
|
45 |
+
"hallucination_silence_threshold": hallucination_silence_threshold
|
46 |
+
}
|
47 |
+
|
48 |
+
model = whisperx.load_model("large-v2", device, compute_type=compute_type, **default_asr_options)
|
49 |
+
'''
|
50 |
+
Video
|
51 |
+
'''
|
52 |
+
video_file = None
|
53 |
+
audio_path=None
|
54 |
+
base64Frames = []
|
55 |
+
transcript=""
|
56 |
+
|
57 |
+
def process_video(video_path, seconds_per_frame=2):
|
58 |
+
global base64Frames, audio_path
|
59 |
+
base_video_path, _ = os.path.splitext(video_path)
|
60 |
+
|
61 |
+
video = cv2.VideoCapture(video_path)
|
62 |
+
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
|
63 |
+
fps = video.get(cv2.CAP_PROP_FPS)
|
64 |
+
frames_to_skip = int(fps * seconds_per_frame)
|
65 |
+
curr_frame=0
|
66 |
+
|
67 |
+
while curr_frame < total_frames - 1:
|
68 |
+
video.set(cv2.CAP_PROP_POS_FRAMES, curr_frame)
|
69 |
+
success, frame = video.read()
|
70 |
+
if not success:
|
71 |
+
break
|
72 |
+
_, buffer = cv2.imencode(".jpg", frame)
|
73 |
+
base64Frames.append(base64.b64encode(buffer).decode("utf-8"))
|
74 |
+
curr_frame += frames_to_skip
|
75 |
+
video.release()
|
76 |
+
|
77 |
+
audio_path = "./TEST.mp3"
|
78 |
+
clip = VideoFileClip(video_path)
|
79 |
+
clip.audio.write_audiofile(audio_path, bitrate="32k")
|
80 |
+
clip.audio.close()
|
81 |
+
clip.close()
|
82 |
+
# transcribe_video(audio_path)
|
83 |
+
print(f"Extracted {len(base64Frames)} frames")
|
84 |
+
print(f"Extracted audio to {audio_path}")
|
85 |
+
return base64Frames, audio_path
|
86 |
+
|
87 |
+
chat_history = []
|
88 |
+
# chat_history.append({
|
89 |
+
# "role": "system",
|
90 |
+
# "content": (
|
91 |
+
# """
|
92 |
+
# You are an assistant chatbot for a Speech Language Pathologist (SLP).
|
93 |
+
# Your task is to help analyze a provided video of a therapy session and answer questions accurately.
|
94 |
+
# Provide timestamps for specific events or behaviors mentioned. Conclude each response with possible follow-up questions.
|
95 |
+
|
96 |
+
# Follow these steps:
|
97 |
+
|
98 |
+
# 1. Suggest to the user to ask, “To get started, you can try asking me how many people there are in the video.”
|
99 |
+
# 2. Detect how many people are in the video.
|
100 |
+
# 2. Suggest to the user to tell you the names of the people in the video, starting from left to right.
|
101 |
+
# 3. After receiving the names, respond with, “Ok thank you! Now you can ask me any questions about this video.”
|
102 |
+
# 4. If the user asks about a behavior, respond with, “My understanding of this behavior is [xxx - AI generated output]. Is this a behavior that you want to track? If it is, please define this behavior and tell me more about it so I can analyze it more accurately according to your practice.”
|
103 |
+
# 5. If you receive names, confirm that these are the names of the people from left to right.
|
104 |
+
# """
|
105 |
+
# )
|
106 |
+
# })
|
107 |
+
|
108 |
+
def transcribe_video(filename):
|
109 |
+
global transcript
|
110 |
+
if not audio_path:
|
111 |
+
raise ValueError("Audio path is None")
|
112 |
+
print(audio_path)
|
113 |
+
audio = whisperx.load_audio(audio_path)
|
114 |
+
result = model.transcribe(audio, batch_size=batch_size)
|
115 |
+
|
116 |
+
model_a, metadata = whisperx.load_align_model(language_code=result["language"], device=device)
|
117 |
+
result = whisperx.align(result["segments"], model_a, metadata, audio, device, return_char_alignments=False)
|
118 |
+
|
119 |
+
|
120 |
+
hf_auth_token = os.getenv("HF_AUTH_TOKEN")
|
121 |
+
diarize_model = whisperx.DiarizationPipeline(use_auth_token=hf_auth_token, device=device)
|
122 |
+
|
123 |
+
diarize_segments = diarize_model(audio)
|
124 |
+
|
125 |
+
dia_result = whisperx.assign_word_speakers(diarize_segments, result)
|
126 |
+
|
127 |
+
for res in dia_result["segments"]:
|
128 |
+
# transcript += "Speaker: " + str(res.get("speaker", None)) + "\n"
|
129 |
+
transcript += "Dialogue: " + str(res["text"].lstrip()) + "\n"
|
130 |
+
transcript += "start: " + str(int(res["start"])) + "\n"
|
131 |
+
transcript += "end: " + str(int(res["end"])) + "\n"
|
132 |
+
transcript += "\n"
|
133 |
+
|
134 |
+
return transcript
|
135 |
+
|
136 |
+
|
137 |
+
def handle_video(video=None):
|
138 |
+
global video_file, base64Frames, audio_path, chat_history, transcript
|
139 |
+
|
140 |
+
if video is None:
|
141 |
+
# Load example video
|
142 |
+
video = "./TEST.mp4"
|
143 |
+
|
144 |
+
base64Frames, audio_path = process_video(video_path=video, seconds_per_frame=100)
|
145 |
+
chat_history.append({
|
146 |
+
"role": "user",
|
147 |
+
"content": [
|
148 |
+
{"type": "text", "text": "These are the frames from the video."},
|
149 |
+
*map(lambda x: {"type": "image_url", "image_url": {"url": f'data:image/jpg;base64,{x}', "detail": "low"}}, base64Frames)
|
150 |
+
]
|
151 |
+
})
|
152 |
+
|
153 |
+
if transcript:
|
154 |
+
chat_history[-1]['content'].append({
|
155 |
+
"type": "text",
|
156 |
+
"text": f"Also, below is the template of transcript from the video:\n"
|
157 |
+
"Speaker: <the speaker of the dialogue>\n"
|
158 |
+
"Dialogue: <the text of the dialogue>\n"
|
159 |
+
"start: <the starting timestamp of the dialogue in the video in second>\n"
|
160 |
+
"end: <the ending timestamp of the dialogue in the video in second>\n"
|
161 |
+
f"Transcription: {transcript}"
|
162 |
+
})
|
163 |
+
|
164 |
+
video_file = video
|
165 |
+
return video_file
|
166 |
+
|
167 |
+
'''
|
168 |
+
Chatbot
|
169 |
+
'''
|
170 |
+
|
171 |
+
def new_prompt(prompt):
|
172 |
+
global chat_history, video_file
|
173 |
+
chat_history.append({"role": "user","content": prompt,})
|
174 |
+
MODEL="gpt-4o"
|
175 |
+
# print(chat_history)
|
176 |
+
print(transcript)
|
177 |
+
try:
|
178 |
+
if video_file:
|
179 |
+
# Video exists and is processed
|
180 |
+
response = client.chat.completions.create(model=MODEL,messages=chat_history,temperature=0,)
|
181 |
+
else:
|
182 |
+
# No video uploaded yet
|
183 |
+
response = client.chat.completions.create(model=MODEL,messages=chat_history,temperature=0,)
|
184 |
+
|
185 |
+
# Extract the text content from the response and append it to the chat history
|
186 |
+
assistant_message = response.choices[0].message.content
|
187 |
+
chat_history.append({'role': 'model', 'content': assistant_message})
|
188 |
+
print(assistant_message)
|
189 |
+
except Exception as e:
|
190 |
+
print("Error: ",e)
|
191 |
+
assistant_message = "API rate limit has been reached. Please wait a moment and try again."
|
192 |
+
chat_history.append({'role': 'model', 'content': assistant_message})
|
193 |
+
|
194 |
+
# except google.api_core.exceptions.ResourceExhausted:
|
195 |
+
# assistant_message = "API rate limit has been reached. Please wait a moment and try again."
|
196 |
+
# chat_history.append({'role': 'model', 'parts': [assistant_message]})
|
197 |
+
# except Exception as e:
|
198 |
+
# assistant_message = f"An error occurred: {str(e)}"
|
199 |
+
# chat_history.append({'role': 'model', 'parts': [assistant_message]})
|
200 |
+
|
201 |
+
return chat_history
|
202 |
+
|
203 |
+
def user_input(user_message, history):
|
204 |
+
return "", history + [[user_message, None]]
|
205 |
+
|
206 |
+
def bot_response(history):
|
207 |
+
user_message = history[-1][0]
|
208 |
+
updated_history = new_prompt(user_message)
|
209 |
+
assistant_message = updated_history[-1]['content']
|
210 |
+
history[-1][1] = assistant_message
|
211 |
+
yield history
|
212 |
+
|
213 |
+
|
214 |
+
'''
|
215 |
+
Behaivor box
|
216 |
+
'''
|
217 |
+
initial_behaviors = [
|
218 |
+
("Initiating Behavioral Request (IBR)",
|
219 |
+
("The child's skill in using behavior(s) to elicit aid in obtaining an object, or object related event",
|
220 |
+
["00:10", "00:45", "01:30"])),
|
221 |
+
|
222 |
+
("Initiating Joint Attention (IJA)",
|
223 |
+
("The child's skill in using behavior(s) to initiate shared attention to objects or events.",
|
224 |
+
["00:15", "00:50", "01:40"])),
|
225 |
+
|
226 |
+
("Responding to Joint Attention (RJA)",
|
227 |
+
("The child's skill in following the examiner’s line of regard and pointing gestures.",
|
228 |
+
["00:20", "01:00", "02:00"])),
|
229 |
+
|
230 |
+
("Initiating Social Interaction (ISI)",
|
231 |
+
("The child's skill at initiating turn-taking sequences and the tendency to tease the tester",
|
232 |
+
["00:20", "00:50", "02:00"])),
|
233 |
+
|
234 |
+
("Responding to Social Interaction (RSI)",
|
235 |
+
("The child’s skill in responding to turn-taking interactions initiated by the examiner.",
|
236 |
+
["00:20", "01:00", "02:00"]))
|
237 |
+
]
|
238 |
+
|
239 |
+
behaviors = initial_behaviors
|
240 |
+
behavior_bank = []
|
241 |
+
|
242 |
+
def add_or_update_behavior(name, definition, timestamps, selected_behavior):
|
243 |
+
global behaviors, behavior_bank
|
244 |
+
if selected_behavior: # Update existing behavior
|
245 |
+
for i, (old_name, _) in enumerate(behaviors):
|
246 |
+
if old_name == selected_behavior:
|
247 |
+
behaviors[i] = (name, (definition, timestamps))
|
248 |
+
break
|
249 |
+
# Update behavior in the bank if it exists
|
250 |
+
behavior_bank = [name if b == selected_behavior else b for b in behavior_bank]
|
251 |
+
else: # Add new behavior
|
252 |
+
new_behavior = (name, (definition, timestamps))
|
253 |
+
behaviors.append(new_behavior)
|
254 |
+
choices = [b[0] for b in behaviors]
|
255 |
+
return gr.Dropdown(choices=choices, value=None, interactive=True), gr.CheckboxGroup(choices=behavior_bank, value=behavior_bank, interactive=True), "", "", ""
|
256 |
+
|
257 |
+
def add_to_behaivor_bank(selected_behavior, checkbox_group_values):
|
258 |
+
global behavior_bank
|
259 |
+
if selected_behavior and selected_behavior not in checkbox_group_values:
|
260 |
+
checkbox_group_values.append(selected_behavior)
|
261 |
+
behavior_bank = checkbox_group_values
|
262 |
+
return gr.CheckboxGroup(choices=checkbox_group_values, value=checkbox_group_values, interactive=True), gr.Dropdown(value=None,interactive=True)
|
263 |
+
|
264 |
+
def delete_behavior(selected_behavior, checkbox_group_values):
|
265 |
+
global behaviors, behavior_bank
|
266 |
+
behaviors = [b for b in behaviors if b[0] != selected_behavior]
|
267 |
+
behavior_bank = [b for b in behavior_bank if b != selected_behavior]
|
268 |
+
updated_choices = [b[0] for b in behaviors]
|
269 |
+
updated_checkbox_group = [cb for cb in checkbox_group_values if cb != selected_behavior]
|
270 |
+
return gr.Dropdown(choices=updated_choices, value=None, interactive=True), gr.CheckboxGroup(choices=updated_checkbox_group, value=updated_checkbox_group, interactive=True)
|
271 |
+
|
272 |
+
def edit_behavior(selected_behavior):
|
273 |
+
for name, (definition, timestamps) in behaviors:
|
274 |
+
if name == selected_behavior:
|
275 |
+
# Return values to populate textboxes
|
276 |
+
return name, definition, timestamps
|
277 |
+
return "", "", ""
|
278 |
+
|
279 |
+
|
280 |
+
welcome_message = """
|
281 |
+
Hello! I'm your AI assistant.
|
282 |
+
I can help you analyze your video sessions following your instructions.
|
283 |
+
To get started, please upload a video or add your behaviors to the Behavior Bank using the Behavior Manager.
|
284 |
+
"""
|
285 |
+
#If you want to tell me about the people in the video, please name them starting from left to right.
|
286 |
+
|
287 |
+
css="""
|
288 |
+
body {
|
289 |
+
background-color: #edf1fa; /* offwhite */
|
290 |
+
}
|
291 |
+
.gradio-container {
|
292 |
+
background-color: #edf1fa; /* offwhite */
|
293 |
+
}
|
294 |
+
.column-form .wrap {
|
295 |
+
flex-direction: column;
|
296 |
+
}
|
297 |
+
.sidebar {
|
298 |
+
background: #ffffff;
|
299 |
+
padding: 10px;
|
300 |
+
border-right: 1px solid #dee2e6;
|
301 |
+
}
|
302 |
+
.content {
|
303 |
+
padding: 10px;
|
304 |
+
}
|
305 |
+
"""
|
306 |
+
|
307 |
+
'''
|
308 |
+
Gradio Demo
|
309 |
+
'''
|
310 |
+
with gr.Blocks(theme='base', css=css, title="Soap.AI") as demo:
|
311 |
+
gr.Markdown("# 🤖 AI-Supported SOAP Generation")
|
312 |
+
|
313 |
+
with gr.Row():
|
314 |
+
with gr.Column():
|
315 |
+
video = gr.Video(label="Video", visible=True, height=360, container=True)
|
316 |
+
with gr.Row():
|
317 |
+
with gr.Column(min_width=1, scale=1):
|
318 |
+
video_upload_button = gr.Button("Analyze Video", variant="primary")
|
319 |
+
with gr.Column(min_width=1, scale=1):
|
320 |
+
example_video_button = gr.Button("Load Example Video")
|
321 |
+
|
322 |
+
video_upload_button.click(handle_video, inputs=video, outputs=video)
|
323 |
+
example_video_button.click(handle_video, None, outputs=video)
|
324 |
+
|
325 |
+
with gr.Column():
|
326 |
+
chat_section = gr.Group(visible=True)
|
327 |
+
with chat_section:
|
328 |
+
chatbot = gr.Chatbot(elem_id="chatbot",
|
329 |
+
container=True,
|
330 |
+
likeable=True,
|
331 |
+
value=[[None, welcome_message]],
|
332 |
+
avatar_images=(None, "./avatar.webp"))
|
333 |
+
with gr.Row():
|
334 |
+
txt = gr.Textbox(show_label=False, placeholder="Type here!")
|
335 |
+
with gr.Row():
|
336 |
+
send_btn = gr.Button("Send Message", elem_id="send-btn", variant="primary")
|
337 |
+
clear_btn = gr.Button("Clear Chat", elem_id="clear-btn")
|
338 |
+
|
339 |
+
with gr.Row():
|
340 |
+
behaivor_bank = gr.CheckboxGroup(label="Behavior Bank",
|
341 |
+
choices=[],
|
342 |
+
interactive=True,
|
343 |
+
info="A space to store all the behaviors you want to analyze.")
|
344 |
+
open_sidebar_btn = gr.Button("Show Behavior Manager", scale=0)
|
345 |
+
close_sidebar_btn = gr.Button("Hide Behavior Manager", visible=False, scale=0)
|
346 |
+
|
347 |
+
txt.submit(user_input, [txt, chatbot], [txt, chatbot], queue=False).then(
|
348 |
+
bot_response, chatbot, chatbot)
|
349 |
+
send_btn.click(user_input, [txt, chatbot], [txt, chatbot], queue=False).then(
|
350 |
+
bot_response, chatbot, chatbot)
|
351 |
+
clear_btn.click(lambda: None, None, chatbot, queue=False)
|
352 |
+
|
353 |
+
# Define a sidebar column that is initially hidden
|
354 |
+
with gr.Column(visible=False, min_width=200, scale=0.5, elem_classes="sidebar") as sidebar:
|
355 |
+
behavior_dropdown = gr.Dropdown(label="Behavior Collection",
|
356 |
+
choices=behaviors,
|
357 |
+
interactive=True,
|
358 |
+
container=True,
|
359 |
+
elem_classes="column-form",
|
360 |
+
info="Choose a behavior to add to the bank, edit or remove.")
|
361 |
+
with gr.Row():
|
362 |
+
add_toBank_button = gr.Button("Add Behavior to Bank", variant="primary")
|
363 |
+
edit_button = gr.Button("Edit Behavior")
|
364 |
+
delete_button = gr.Button("Remove Behavior")
|
365 |
+
|
366 |
+
with gr.Row():
|
367 |
+
name_input = gr.Textbox(label="Behavior Name",
|
368 |
+
placeholder="(e.g., IBR)",
|
369 |
+
info="The name you give to the specific behavior you're tracking or analyzing.")
|
370 |
+
timestamps_input = gr.Textbox(label="Timestamps MM:SS",
|
371 |
+
placeholder="(e.g., (01:15,01:35) )",
|
372 |
+
info="The exact times during a session when you saw the behavior. The first two digits represent minutes and the last two digits represent seconds.")
|
373 |
+
definition_input = gr.Textbox(lines=3,
|
374 |
+
label="Behavior Definition",
|
375 |
+
placeholder="(e.g., the child's skill in using behavior(s) to elicit aid in obtaining an object, or object related event)",
|
376 |
+
info="Provide a clear definition of the behavior.")
|
377 |
+
|
378 |
+
with gr.Row():
|
379 |
+
submit_button = gr.Button("Save Behavior", variant="primary")
|
380 |
+
|
381 |
+
submit_button.click(fn=add_or_update_behavior,
|
382 |
+
inputs=[name_input, definition_input, timestamps_input, behavior_dropdown],
|
383 |
+
outputs=[behavior_dropdown, behaivor_bank, name_input, definition_input, timestamps_input])
|
384 |
+
|
385 |
+
add_toBank_button.click(fn=add_to_behaivor_bank,
|
386 |
+
inputs=[behavior_dropdown, behaivor_bank],
|
387 |
+
outputs=[behaivor_bank, behavior_dropdown])
|
388 |
+
|
389 |
+
delete_button.click(fn=delete_behavior,
|
390 |
+
inputs=[behavior_dropdown, behaivor_bank],
|
391 |
+
outputs=[behavior_dropdown, behaivor_bank])
|
392 |
+
|
393 |
+
edit_button.click(fn=edit_behavior,
|
394 |
+
inputs=[behavior_dropdown],
|
395 |
+
outputs=[name_input, definition_input, timestamps_input])
|
396 |
+
|
397 |
+
# Function to open the sidebar
|
398 |
+
open_sidebar_btn.click(lambda: {
|
399 |
+
open_sidebar_btn: gr.Button(visible=False),
|
400 |
+
close_sidebar_btn: gr.Button(visible=True),
|
401 |
+
sidebar: gr.Column(visible=True)
|
402 |
+
}, outputs=[open_sidebar_btn, close_sidebar_btn, sidebar])
|
403 |
+
|
404 |
+
# Function to close the sidebar
|
405 |
+
close_sidebar_btn.click(lambda: {
|
406 |
+
open_sidebar_btn: gr.Button(visible=True),
|
407 |
+
close_sidebar_btn: gr.Button(visible=False),
|
408 |
+
sidebar: gr.Column(visible=False)
|
409 |
+
}, outputs=[open_sidebar_btn, close_sidebar_btn, sidebar])
|
410 |
+
|
411 |
+
# Launch the demo
|
412 |
demo.launch(share=True)
|