CoolFace
Apppublic

fracapuano/transcript2notes

sourceHugging Faceapache-2.0updated 2y agoView on Hugging Face
0likes
meeting_notes.py202 linesDownload Raw Back to root
1from openai import OpenAI2from dotenv import load_dotenv3from typing import List, Optional4from tqdm import tqdm5 6load_dotenv()7client = OpenAI()8 9def extract_topics(meeting_transcript):10    prompt_text = f"""11    ## Transcript12    <transcript>13    {meeting_transcript}14    </transcript>15 16    You are a topic extractor whose main task is to identify and list the top 5 most important topics discussed17    in a meeting, to whom you have access thanks to the provided meeting transcript.18    Provided the transcript available under the <transcript> tags, analyze it and extract the main topics discussed. 19    Format your output as a list of skills I could iterate on.20    21    An ideal output for a meeting covering budgeting budget concers, project handling and staffing looks like22    [Budgeting, Project Deadlines, Staffing, New Policies, Client Feedback]23    """24 25    response = client.chat.completions.create(26        model="gpt-4-turbo",27        messages=[{"role": "user", "content": prompt_text}],28        max_tokens=100,  # short list of topics discussed29        temperature=0.0,30        stop=["\n", "]"]  # Stops to help ensure the list format is respected31    )32 33    topics = response.choices[0].message.content.strip('][').split(', ')  # Processing the string output into a Python list34    return topics35 36def generate_bullet_point_summary(topic, meeting_transcript):37    prompt_text = f"""38    <topic>39    {topic}40    </topic>41    <transcript>42    {meeting_transcript}43    </transcript>44 45    You are an AI assistant tasked with assisting in summarizing meeting discussions. 46    Below is the transcript of a meeting, and a specific topic to focus on.47    Please provide a summary of all the discussions related to this topic in bullet points. Be very48    concise and to the point. Each bullet point must contain one concept only.49    """50 51    response = client.chat.completions.create(52        model="gpt-4-turbo",53        messages=[{"role": "user", "content": prompt_text}],54        max_tokens=400,  # Increase if more detailed summaries are needed55        stop=["\n\n"]  # A double newline to signify the end of the summary list56    )57    summary = response.choices[0].message.content.strip()58    return summary59 60def summarize_topics(topics, meeting_transcript):61    # Generate summaries for each topic62    summaries = {}63    for topic in topics:64        summaries[topic] = generate_bullet_point_summary(topic, meeting_transcript)65    66    return summaries67 68def extract_actionable_items(meeting_transcript):69    prompt_text = f"""70    Please carefully analyze the following meeting transcript, which will be provided between XML tags:71 72    <meeting_transcript>73    {meeting_transcript}74    </meeting_transcript>75 76    First, identify each unique speaker who participated in the meeting.77 78    Then, for each speaker you identified, carefully extract any concrete action items, tasks, or next79    steps that were assigned to them during the meeting. Use the full context of the meeting to80    determine what the key next steps are for each person.81 82    Format your response as a bulleted list, with each speaker's full name followed by a sublist of the83    specific action items you identified for them. Here is an example of the desired format:84 85    ## John Smith:86    - Follow up with the client by next Wednesday.87    - Prepare a detailed budget proposal for the next meeting.88    - Jane Doe:89    - Coordinate with the marketing team to draft the new campaign outline.90    - Send updated staffing requirements to HR by Friday.91 92    Omit any speakers for whom no clear action items or next steps were specified in the meeting. Focus93    on extracting the most concrete and actionable items for each speaker.94 95    Write your full list of speakers and action items inside <result> tags.96    If you are unable to identify the speakers' names, please write "Speaker 1", "Speaker 2", etc.97    """98    response = client.chat.completions.create(99        model="gpt-4-turbo",100        messages=[{"role": "user", "content": prompt_text}],101        stop=["\n\n"]  # A double newline to signify the end of the list102    )103    action_items = response.choices[0].message.content.strip()104    return action_items105 106def cleanup_meeting_notes(meeting_notes, speakers_list=None):107    prompt_text = f"""108    <meeting_notes_draft>109    {meeting_notes}110    </meeting_notes_draft>111    <speakers_list>112    {speakers_list if speakers_list else "No speakers list provided"}113    </speakers_list>114 115    You are a meeting notes editor who has been tasked with cleaning up the draft of a meeting notes document.116    You must not modify the content you receive in any way or form, your task is simply to reformat the text to make it adhere to117    the following guidelines:118    - Production-ready meeting notes are always formatted in markdown. Ensure that the text is properly formatted in markdown.119    - Production-ready meeting notes always have 3 sections: "Speakers", "Meeting Summary", "Action Items". These sections are always H1 in markdown (#Speakers, #Meeting Summary, #Action Items).120    - Production-ready meeting notes always have a horizontal rule (---) between each section.121    - Production-ready meeting notes always present the topics discussed in the #Meeting Summary section, with each topic being a toggle subheading (> ##Topic).122    - Production-ready meeting notes always present the bullet points under each topic as markdown bullet points points.123    - Production-ready meeting notes always have each speaker's name in bold.124    - Production-ready meeting notes always have the action items in a bulleted list.125    - Production-ready meeting notes always have the action items grouped by the speaker who is responsible for them.126    - Production-ready meetings always presents speakers mapped to the name in the <speakers_list> tag, if available, in the same order. This means that for ["Francesco", "Carlo", "Antonio"]127    you would have that "Francesco" is the "Speaker 0", "Carlo" is the "Speaker 1", and "Antonio" is the "Speaker 2".128    129    Your output must exactly match the format described above. You must not modify the content of the meeting notes in any way, only the formatting. You will be 130    penalized if you change the content of the meeting notes.131    An example template for the meeting notes is as follows:132    # Speakers133    - **Speaker 0**134    - **Speaker 1**135    ...136 137    ---138    # Meeting Summary139    > ## Topic 1140    - Bullet point 1141    - Bullet point 2142    ...143    > ## Topic 2144    - Bullet point 1145    - Bullet point 2146    ...147 148    ---149    # Action Items150    ## <Speaker 0's name> to own151    - Action item 1152    - Action item 2153    ## <Speaker 1's name> to own154    - Action item 1155    - Action item 2156    """157 158    response = client.chat.completions.create(159        model="gpt-4-turbo",160        messages=[{"role": "user", "content": prompt_text}]161    )162    return response.choices[0].message.content163 164def transcript_to_notes(meeting_transcript: str, speakers_list:Optional[List[str]]=None) -> str:165    """Converts a meeting transcript into formatted meeting notes.166    167    Args:168        meeting_transcript (str): The text of the meeting transcript169        speakers_list (Optional[List[str]]): A list of speakers in the meeting170    171    Returns:172        str: The formatted meeting notes173    """174    pbar = tqdm(total=3)175    topics = extract_topics(meeting_transcript)176    pbar.update(1)177    by_topic_summaries = summarize_topics(topics, meeting_transcript)178    pbar.update(1)179    actions_by_speaker = extract_actionable_items(meeting_transcript)180    pbar.update(1)181 182    draft_notes = f"""183    topics: {topics}184    summaries: {by_topic_summaries}185    actions: {actions_by_speaker}186    """187 188    meeting_notes = cleanup_meeting_notes(draft_notes, speakers_list)189    return meeting_notes190 191# Example usage192if __name__ == "__main__":193    with open("tanguy-off-boarding-meeting.txt", "r") as file:194        meeting_transcript = file.read()195 196    speakers_list = ["Tanguy", "Francesco"]197 198    notes = transcript_to_notes(meeting_transcript, speakers_list)199    with open("meeting_notes.md", "w") as file:200        file.write(notes)201    202    print("Meeting notes generated successfully!")