Skip to content

Instantly share code, notes, and snippets.

@codesoda
Forked from hamelsmu/webhook-circleback.py
Created May 15, 2024 10:30
Show Gist options
  • Save codesoda/4f74d5abc6f7daf64cbdfa950fa1d516 to your computer and use it in GitHub Desktop.
Save codesoda/4f74d5abc6f7daf64cbdfa950fa1d516 to your computer and use it in GitHub Desktop.
Generate a project proposal automatically from a meeting transcript
from fastapi import Request, HTTPException
from pydantic import BaseModel, BaseModel, HttpUrl
from modal import Secret, App, web_endpoint, Image
from typing import Optional, List
from example import proposal
import os
app = App(name="circleback", image=Image.debian_slim().pip_install("openai", "pydantic", "fastapi"))
class Attendee(BaseModel):
name: Optional[str]
email: Optional[str]
def markdown(self) -> str:
if self.name:
return f"- {self.name} ({self.email})"
return f"- {self.email}"
class Assignee(BaseModel):
name: Optional[str]
email: Optional[str]
def markdown(self) -> str:
if self.name:
return f"{self.name} ({self.email})"
return f"{self.email}"
class ActionItem(BaseModel):
id: int
title: str
description: str
assignee: Optional[Assignee]
status: str
def markdown(self) -> str:
assignee_info = self.assignee.markdown() if self.assignee else "Unassigned"
return f"**{self.title}** (Status: {self.status})\n" \
f"- Description: {self.description}\n" \
f"- Assignee: {assignee_info}\n"
class MeetingNotes(BaseModel):
id: int
name: str
createdAt: str
duration: int
url: Optional[HttpUrl]
recordingUrl: Optional[HttpUrl]
attendees: List[Attendee]
notes: str
actionItems: List[ActionItem]
def to_markdown(self) -> str:
attendees_md = "\n".join([attendee.markdown() for attendee in self.attendees])
action_items_md = "\n".join([item.markdown() for item in self.actionItems])
return f"# Meeting: {self.name}\n\n" \
f"**Created At:** {self.createdAt}\n" \
f"**Duration:** {self.duration} seconds\n" \
f"**URL:** {self.url if self.url else 'N/A'}\n\n" \
f"**Attendees:**\n{attendees_md}\n\n" \
f"# Notes\n\n{self.notes}\n\n" \
f"# Action Items\n\n{action_items_md}\n"
@app.function(secrets=[Secret.from_name("OPENAI_API_KEY")])
@web_endpoint(method="POST")
async def f(request: Request):
body = await request.json()
try:
webhook_data = MeetingNotes(**body)
except Exception as e:
raise HTTPException(status_code=400, detail=str(e)) from e
transcript = webhook_data.to_markdown()
print('PROMPT:\n', '==='*10, '\n', prompt(transcript), '\n', '==='*10)
proposal = gen_proposal(transcript)
print('\n\nAI GENERATED PROPOSAL:\n\n', '==='*10, '\n', proposal, '\n', '==='*10)
def prompt(transcript: str):
return f"""
Here is an example consulting proposal:
<example>
{proposal}
</example>
Here is a transcript of a recent call with a potential client (the client name is in the transcript):
<transcript>
{transcript}
</transcript>
Write a detailed project proposal, but do not worry about the pricing or the rate. Focus on fleshing out the different tasks we would do that is compelling and convincing for a founder.
Flesh out these ideas and add more as necessary. Do not anchor too much on the given examples, instead write a convincing proposal.
"""
def gen_proposal(transcript: str):
from openai import OpenAI
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
response = client.chat.completions.create(
model="gpt-4-turbo",
messages=[
{"role": "system", "content": "You are an expert AI consultant. Your task is to write a project proposal for a potential client. The client is interested in your services and wants to know more about your approach to solving their problems. Write a detailed proposal that outlines the tasks you would do to help them grow their business. Focus on the value you can provide and how you can help them achieve their goals. Be persuasive and convincing."},
{"role": "user", "content": prompt(transcript)}
]
)
return response.choices[0].message.content
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment