AhmadMustafa commited on
Commit
21057c0
·
1 Parent(s): a4fc8e5

update: dyanmic input for call id, rsid, session id, transcript url

Browse files
Files changed (1) hide show
  1. app.py +198 -69
app.py CHANGED
@@ -8,8 +8,6 @@ import requests
8
  from bs4 import BeautifulSoup
9
  from openai import OpenAI
10
 
11
- street_interview = False
12
-
13
 
14
  @dataclass
15
  class TranscriptSegment:
@@ -21,15 +19,23 @@ class TranscriptSegment:
21
 
22
 
23
  class TranscriptProcessor:
24
- def __init__(self, transcript_file: str):
25
  self.transcript_file = transcript_file
26
- self.transcript_data = None
27
  self.formatted_transcript = None
28
  self.segments = []
29
  self.text_windows = []
30
  self.window_size = 2
31
  self.speaker_mapping = {}
32
- self._load_transcript()
 
 
 
 
 
 
 
 
33
  self._process_transcript()
34
  self.map_speaker_ids_to_names()
35
 
@@ -273,13 +279,55 @@ def setup_openai_key() -> None:
273
  # )
274
 
275
 
276
- def get_initial_analysis(transcript_processor: TranscriptProcessor) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  """Perform initial analysis of the transcript using OpenAI."""
278
  try:
279
  transcript = transcript_processor.get_transcript()
280
- # print("Transcript is: ", transcript)
281
  client = OpenAI()
282
- if street_interview:
283
  prompt = f"""This is a transcript for a street interview. Transcript: {transcript}
284
  In this street interview, the host asks multiple questions to the interviewees.
285
  The interviewee can repeat a single answer multiple time to get the best take.
@@ -289,19 +337,28 @@ Question 1 should always be the introduction if the speaker has introduced thems
289
  Return format is:
290
  1. Question: question
291
  Number of takes: number
292
- Best Answer timestamp: start_time - end_time
293
- You can visit the call segment on this URL: https://roll.ai/call_id/colab_id?starttime=start_time?endtime=end_time."
 
 
294
  """
295
  else:
296
  prompt = f"""Given the transcript {transcript}, For All the speakers, short list all people, news, events, trends, and source that are discussed by speakers along with the start time of that topic and end time of that topic from the transcript. Rank all topics based on what would make for the best social clips. I need atleast 3 topics per speaker.
297
- You should mention the Speaker Name first, then 3 posts with their timestamps, and so on.
298
- Return format is: Speaker Name\n1.Topic: topic, Start Time: start_time, End Time: end_time\n2...."""
 
 
 
 
 
299
 
300
- print(prompt)
301
  completion = client.chat.completions.create(
302
  model="gpt-4o-mini",
303
  messages=[
304
- {"role": "system", "content": "You are a helpful assistant."},
 
 
 
305
  {"role": "user", "content": prompt},
306
  ],
307
  )
@@ -311,33 +368,28 @@ Return format is: Speaker Name\n1.Topic: topic, Start Time: start_time, End Time
311
  return "An error occurred during initial analysis. Please check your API key and file path."
312
 
313
 
314
- call_id = "20240226t210135"
315
- colab_id = "1231412431212"
316
-
317
-
318
- def generate_call_link(start_time: str) -> str:
319
- """Generate a link to the call at a specific timestamp."""
320
- formatted_time = start_time.replace(":", ".")
321
- return f"https://roll.ai/{call_id}/{colab_id}?t={formatted_time}"
322
-
323
-
324
  def chat(
325
- message: str, chat_history: List, transcript_processor: TranscriptProcessor
 
 
 
 
 
 
326
  ) -> str:
327
  try:
328
  client = OpenAI()
329
- # if street_interview:
330
- # prompt = f"""You are a helpful assistant analyzing transcripts and generating timestamps and URL. Call ID is {call_id} and Colab ID is {colab_id}.
331
- # Transcript: {transcript_processor.get_transcript()}
332
- # If a user asks t
333
- # """
334
- # else:
335
- prompt = f"""You are a helpful assistant analyzing transcripts and generating timestamps and URL. Call ID is {call_id} and Colab ID is {colab_id}.
336
- Transcript: {transcript_processor.get_transcript()}
337
- If a user asks timestamps for a specific topic, find the start time and end time of that specific topic and return answer in the format: 'Timestamp: start_time - end_time'.
338
- You can visit the call segment on this URL: https://roll.ai/call_id/colab_id?starttime=start_time?endtime=end_time."
339
- If a user requests a link to a specific segment topic, generate a link to that segment using the following format: https://roll.ai/call_id/colab_id?starttime=start_time?endtime=end_time."""
340
 
 
 
 
 
 
 
 
 
 
 
341
  messages = [{"role": "system", "content": prompt}]
342
 
343
  for user_msg, assistant_msg in chat_history:
@@ -366,31 +418,122 @@ If a user requests a link to a specific segment topic, generate a link to that s
366
  return "Sorry, there was an error processing your request."
367
 
368
 
369
- def create_chat_interface(transcript_processor: TranscriptProcessor):
370
  """Create and configure the chat interface."""
371
-
372
- def respond(message: str, chat_history: List) -> Tuple[str, List]:
373
- if not message:
374
- return "", chat_history
375
-
376
- bot_message = chat(message, chat_history, transcript_processor)
377
- new_history = list(chat_history)
378
- new_history.append((message, bot_message))
379
- return "", new_history
380
-
381
  with gr.Blocks() as demo:
382
  chatbot = gr.Chatbot()
383
  msg = gr.Textbox()
384
- clear = gr.ClearButton([msg, chatbot])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
 
386
- # Initialize with transcript analysis
387
- initial_analysis = get_initial_analysis(transcript_processor)
 
 
 
 
 
 
 
 
 
 
 
388
 
389
- def init_chat():
390
- return [(None, initial_analysis)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
391
 
392
- chatbot.value = init_chat()
393
- msg.submit(respond, [msg, chatbot], [msg, chatbot])
 
 
 
 
 
 
 
 
 
394
 
395
  return demo
396
 
@@ -399,22 +542,8 @@ def main():
399
  """Main function to run the application."""
400
  try:
401
  setup_openai_key()
402
-
403
- current_dir = os.path.dirname(os.path.abspath(__file__))
404
- transcript_file = os.path.join(current_dir, "step_take19AWS.json")
405
-
406
- if not os.path.exists(transcript_file):
407
- raise FileNotFoundError(
408
- "Transcript file not found. Please check the file path."
409
- )
410
-
411
- transcript_processor = TranscriptProcessor(transcript_file)
412
- transcript_processor.correct_speaker_mapping_with_agenda(
413
- "https://lu.ma/STEPSF24"
414
- )
415
- demo = create_chat_interface(transcript_processor)
416
  demo.launch(share=True)
417
-
418
  except Exception as e:
419
  print(f"Error starting application: {str(e)}")
420
  raise
 
8
  from bs4 import BeautifulSoup
9
  from openai import OpenAI
10
 
 
 
11
 
12
  @dataclass
13
  class TranscriptSegment:
 
19
 
20
 
21
  class TranscriptProcessor:
22
+ def __init__(self, transcript_file: str = None, transcript_data: dict = None):
23
  self.transcript_file = transcript_file
24
+ self.transcript_data = transcript_data
25
  self.formatted_transcript = None
26
  self.segments = []
27
  self.text_windows = []
28
  self.window_size = 2
29
  self.speaker_mapping = {}
30
+ if self.transcript_file:
31
+ self._load_transcript()
32
+ elif self.transcript_data:
33
+ pass # transcript_data is already set
34
+ else:
35
+ raise ValueError(
36
+ "Either transcript_file or transcript_data must be provided."
37
+ )
38
+
39
  self._process_transcript()
40
  self.map_speaker_ids_to_names()
41
 
 
279
  # )
280
 
281
 
282
+ def get_transcript_for_url(url: str) -> dict:
283
+ """
284
+ This function fetches the transcript data for a signed URL.
285
+ If the URL results in a direct download, it processes the downloaded content.
286
+
287
+ :param url: Signed URL for the JSON file
288
+ :return: Parsed JSON data as a dictionary
289
+ """
290
+ headers = {
291
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
292
+ }
293
+
294
+ try:
295
+ response = requests.get(url, headers=headers)
296
+ response.raise_for_status()
297
+
298
+ if "application/json" in response.headers.get("Content-Type", ""):
299
+ return response.json() # Parse and return JSON directly
300
+
301
+ # If not JSON, assume it's a file download (e.g., content-disposition header)
302
+ content_disposition = response.headers.get("Content-Disposition", "")
303
+ if "attachment" in content_disposition:
304
+ # Process the content as JSON
305
+ return json.loads(response.content)
306
+
307
+ return json.loads(response.content)
308
+
309
+ except requests.exceptions.HTTPError as http_err:
310
+ print(f"HTTP error occurred: {http_err}")
311
+ except requests.exceptions.RequestException as req_err:
312
+ print(f"Request error occurred: {req_err}")
313
+ except json.JSONDecodeError as json_err:
314
+ print(f"JSON decoding error: {json_err}")
315
+
316
+ return {}
317
+
318
+
319
+ def get_initial_analysis(
320
+ transcript_processor: TranscriptProcessor,
321
+ cid,
322
+ rsid,
323
+ origin,
324
+ ct,
325
+ ) -> str:
326
  """Perform initial analysis of the transcript using OpenAI."""
327
  try:
328
  transcript = transcript_processor.get_transcript()
 
329
  client = OpenAI()
330
+ if ct == "si": # street interview
331
  prompt = f"""This is a transcript for a street interview. Transcript: {transcript}
332
  In this street interview, the host asks multiple questions to the interviewees.
333
  The interviewee can repeat a single answer multiple time to get the best take.
 
337
  Return format is:
338
  1. Question: question
339
  Number of takes: number
340
+ Best Answer timestamp: [Timestamp: start_time - end_time](https://{{origin}}/collab/{{cid}}/{{rsid}}&st={{start_time_in_sec}}&et={{end_time_in_sec}}"').
341
+ For Example:
342
+ If the start time is 10:13 and end time is 10:18, the url will be:
343
+ https://roll.ai/colab/1234aq_12314/51234151?st=613&et=618
344
  """
345
  else:
346
  prompt = f"""Given the transcript {transcript}, For All the speakers, short list all people, news, events, trends, and source that are discussed by speakers along with the start time of that topic and end time of that topic from the transcript. Rank all topics based on what would make for the best social clips. I need atleast 3 topics per speaker.
347
+ You should mention the Speaker Name first, then atleast 3 posts with their timestamps, and so on.
348
+ Return format is:
349
+ Speaker Name
350
+ 1.Topic: topic,
351
+ [Timestamp: start_time - end_time](https://{{origin}}/collab/{{cid}}/{{rsid}}&st={{start_time_in_sec}}&et={{end_time_in_sec}}"').
352
+ 2....
353
+ """
354
 
 
355
  completion = client.chat.completions.create(
356
  model="gpt-4o-mini",
357
  messages=[
358
+ {
359
+ "role": "system",
360
+ "content": f"You are a helpful assistant who is analyzing the transcript. The transcript is for Call ID: {cid}, Session ID: {rsid}, Origin: {origin}, Call Type: {ct}.",
361
+ },
362
  {"role": "user", "content": prompt},
363
  ],
364
  )
 
368
  return "An error occurred during initial analysis. Please check your API key and file path."
369
 
370
 
 
 
 
 
 
 
 
 
 
 
371
  def chat(
372
+ message: str,
373
+ chat_history: List,
374
+ transcript_processor: TranscriptProcessor,
375
+ cid,
376
+ rsid,
377
+ origin,
378
+ ct,
379
  ) -> str:
380
  try:
381
  client = OpenAI()
 
 
 
 
 
 
 
 
 
 
 
382
 
383
+ prompt = f"""You are a helpful assistant analyzing transcripts and generating timestamps and URL. Call ID is {cid}, Session ID is {rsid}, origin is {origin}, Call Type is {ct}.
384
+ Transcript:\n{transcript_processor.get_transcript()}
385
+ If a user asks timestamps for a specific topic, find the start time and end time of that specific topic and return answer in the format:
386
+ Answer format:
387
+ Topic: Heading [Timestamp: start_time - end_time](https://{{origin}}/collab/{{cid}}/{{rsid}}&st={{start_time_in_sec}}&et={{end_time_in_sec}}"').
388
+
389
+ For Example:
390
+ If the start time is 10:13 and end time is 10:18, the url will be:
391
+ https://roll.ai/colab/1234aq_12314/51234151?st=613&et=618
392
+ """
393
  messages = [{"role": "system", "content": prompt}]
394
 
395
  for user_msg, assistant_msg in chat_history:
 
418
  return "Sorry, there was an error processing your request."
419
 
420
 
421
+ def create_chat_interface():
422
  """Create and configure the chat interface."""
 
 
 
 
 
 
 
 
 
 
423
  with gr.Blocks() as demo:
424
  chatbot = gr.Chatbot()
425
  msg = gr.Textbox()
426
+ transcript_processor_state = gr.State() # maintain state of imp things
427
+ call_id_state = gr.State()
428
+ colab_id_state = gr.State()
429
+ origin_state = gr.State()
430
+ ct_state = gr.State()
431
+ turl_state = gr.State()
432
+
433
+ def on_app_load(request: gr.Request):
434
+ cid = request.query_params.get("cid", None)
435
+ rsid = request.query_params.get("rsid", None)
436
+ origin = request.query_params.get("origin", None)
437
+ ct = request.query_params.get("ct", None)
438
+ turl = request.query_params.get("turl", None)
439
+
440
+ # if any param is missing, return error
441
+ if not cid or not rsid or not origin or not ct or not turl:
442
+ error_message = "Error processing"
443
+ chatbot_value = [(None, error_message)]
444
+ return [
445
+ chatbot_value,
446
+ None,
447
+ None,
448
+ None,
449
+ None,
450
+ None,
451
+ None,
452
+ ]
453
+
454
+ try:
455
+ transcript_data = get_transcript_for_url(turl)
456
+ transcript_processor = TranscriptProcessor(
457
+ transcript_data=transcript_data
458
+ )
459
+ initial_analysis = get_initial_analysis(
460
+ transcript_processor, cid, rsid, origin, ct
461
+ )
462
+
463
+ chatbot_value = [
464
+ (None, initial_analysis)
465
+ ] # initialized with initial analysis and assistant is None
466
+ return [
467
+ chatbot_value,
468
+ transcript_processor,
469
+ cid,
470
+ rsid,
471
+ origin,
472
+ ct,
473
+ turl,
474
+ ]
475
+ except Exception as e:
476
+ error_message = f"Error processing call_id {cid}: {str(e)}"
477
+ chatbot_value = [(None, error_message)]
478
+ return [
479
+ chatbot_value,
480
+ None,
481
+ None,
482
+ None,
483
+ None,
484
+ None,
485
+ None,
486
+ ]
487
 
488
+ demo.load(
489
+ on_app_load,
490
+ inputs=None,
491
+ outputs=[
492
+ chatbot,
493
+ transcript_processor_state,
494
+ call_id_state,
495
+ colab_id_state,
496
+ origin_state,
497
+ ct_state,
498
+ turl_state,
499
+ ],
500
+ )
501
 
502
+ def respond(
503
+ message: str,
504
+ chat_history: List,
505
+ transcript_processor,
506
+ cid,
507
+ rsid,
508
+ origin,
509
+ ct,
510
+ ):
511
+ if not transcript_processor:
512
+ bot_message = "Transcript processor not initialized."
513
+ else:
514
+ bot_message = chat(
515
+ message,
516
+ chat_history,
517
+ transcript_processor,
518
+ cid,
519
+ rsid,
520
+ origin,
521
+ ct,
522
+ )
523
+ chat_history.append((message, bot_message))
524
+ return "", chat_history
525
 
526
+ msg.submit(
527
+ respond,
528
+ [
529
+ msg,
530
+ chatbot,
531
+ transcript_processor_state,
532
+ call_id_state,
533
+ colab_id_state,
534
+ ],
535
+ [msg, chatbot],
536
+ )
537
 
538
  return demo
539
 
 
542
  """Main function to run the application."""
543
  try:
544
  setup_openai_key()
545
+ demo = create_chat_interface()
 
 
 
 
 
 
 
 
 
 
 
 
 
546
  demo.launch(share=True)
 
547
  except Exception as e:
548
  print(f"Error starting application: {str(e)}")
549
  raise