Files

1 line
30 KiB
JSON

{"repo": "chainatao/my-agents", "files": {"2_openai/3_lab3.ipynb": {"edd8d028aa38a82a56bf367bca91b95282afa2bc": {"t": 1785745469.2356212, "n": 13558, "h": "2d80909806049089", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Week 2 Day 3\\n\",\n \"\\n\",\n \"Now we get to more detail:\\n\",\n \"\\n\",\n \"1. Different models\\n\",\n \"\\n\",\n \"2. Structured Outputs\\n\",\n \"\\n\",\n \"3. Guardrails\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 14,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"from dotenv import load_dotenv\\n\",\n \"from openai import AsyncOpenAI\\n\",\n \"from agents import Agent, Runner, trace, function_tool, OpenAIChatCompletionsModel, input_guardrail, output_guardrail, GuardrailFunctionOutput, RunContextWrapper\\n\",\n \"from typing import Dict\\n\",\n \"import sendgrid\\n\",\n \"import os\\n\",\n \"from sendgrid.helpers.mail import Mail, Email, To, Content\\n\",\n \"from pydantic import BaseModel\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 2,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"True\"\n ]\n },\n \"execution_count\": 2,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"load_dotenv(override=True)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 3,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"OpenAI API Key exists and begins sk-proj-\\n\",\n \"Google API Key exists and begins AI\\n\",\n \"DeepSeek API Key exists and begins sk-\\n\",\n \"Groq API Key exists and begins gsk_\\n\"\n ]\n }\n ],\n \"source\": [\n \"openai_api_key = os.getenv('OPENAI_API_KEY')\\n\",\n \"google_api_key = os.getenv('GOOGLE_API_KEY')\\n\",\n \"deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\\n\",\n \"groq_api_key = os.getenv('GROQ_API_KEY')\\n\",\n \"\\n\",\n \"if openai_api_key:\\n\",\n \" print(f\\\"OpenAI API Key exists and begins {openai_api_key[:8]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"OpenAI API Key not set\\\")\\n\",\n \"\\n\",\n \"if google_api_key:\\n\",\n \" print(f\\\"Google API Key exists and begins {google_api_key[:2]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Google API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if deepseek_api_key:\\n\",\n \" print(f\\\"DeepSeek API Key exists and begins {deepseek_api_key[:3]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"DeepSeek API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if groq_api_key:\\n\",\n \" print(f\\\"Groq API Key exists and begins {groq_api_key[:4]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Groq API Key not set (and this is optional)\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 4,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"instructions1 = \\\"You are a sales agent working for ComplAI, \\\\\\n\",\n \"a company that provides a SaaS tool for ensuring SOC2 compliance and preparing for audits, powered by AI. \\\\\\n\",\n \"You write professional, serious cold emails.\\\"\\n\",\n \"\\n\",\n \"instructions2 = \\\"You are a humorous, engaging sales agent working for ComplAI, \\\\\\n\",\n \"a company that provides a SaaS tool for ensuring SOC2 compliance and preparing for audits, powered by AI. \\\\\\n\",\n \"You write witty, engaging cold emails that are likely to get a response.\\\"\\n\",\n \"\\n\",\n \"instructions3 = \\\"You are a busy sales agent working for ComplAI, \\\\\\n\",\n \"a company that provides a SaaS tool for ensuring SOC2 compliance and preparing for audits, powered by AI. \\\\\\n\",\n \"You write concise, to the point cold emails.\\\"\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### It's easy to use any models with OpenAI compatible endpoints\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 5,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 6,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.0-flash\\\", openai_client=gemini_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 7,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"sales_agent1 = Agent(name=\\\"DeepSeek Sales Agent\\\", instructions=instructions1, model=deepseek_model)\\n\",\n \"sales_agent2 = Agent(name=\\\"Gemini Sales Agent\\\", instructions=instructions2, model=gemini_model)\\n\",\n \"sales_agent3 = Agent(name=\\\"Llama3.3 Sales Agent\\\",instructions=instructions3,model=llama3_3_model)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 8,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"description = \\\"Write a cold sales email\\\"\\n\",\n \"\\n\",\n \"tool1 = sales_agent1.as_tool(tool_name=\\\"sales_agent1\\\", tool_description=description)\\n\",\n \"tool2 = sales_agent2.as_tool(tool_name=\\\"sales_agent2\\\", tool_description=description)\\n\",\n \"tool3 = sales_agent3.as_tool(tool_name=\\\"sales_agent3\\\", tool_description=description)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 9,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"@function_tool\\n\",\n \"def send_html_email(subject: str, html_body: str) -> Dict[str, str]:\\n\",\n \" \\\"\\\"\\\" Send out an email with the given subject and HTML body to all sales prospects \\\"\\\"\\\"\\n\",\n \" sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))\\n\",\n \" from_email = Email(\\\"inform@acion.es\\\") # Change to your verified sender\\n\",\n \" to_email = To(\\\"dmitriiblokhin@gmail.com\\\") # Change to your recipient\\n\",\n \" content = Content(\\\"text/html\\\", html_body)\\n\",\n \" mail = Mail(from_email, to_email, subject, content).get()\\n\",\n \" sg.client.mail.send.post(request_body=mail)\\n\",\n \" return {\\\"status\\\": \\\"success\\\"}\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 10,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"subject_instructions = \\\"You can write a subject for a cold sales email. \\\\\\n\",\n \"You are given a message and you need to write a subject for an email that is likely to get a response.\\\"\\n\",\n \"\\n\",\n \"html_instructions = \\\"You can convert a text email body to an HTML email body. \\\\\\n\",\n \"You are given a text email body which might have some markdown \\\\\\n\",\n \"and you need to convert it to an HTML email body with simple, clear, compelling layout and design.\\\"\\n\",\n \"\\n\",\n \"class SubjectStructure(BaseModel):\\n\",\n \" subject: str\\n\",\n \"\\n\",\n \"class HtmlStructure(BaseModel):\\n\",\n \" html_body: str\\n\",\n \"\\n\",\n \"\\n\",\n \"subject_writer = Agent(name=\\\"Email subject writer\\\", instructions=subject_instructions, model=\\\"gpt-4o-mini\\\", output_type=SubjectStructure)\\n\",\n \"subject_tool = subject_writer.as_tool(tool_name=\\\"subject_writer\\\", tool_description=\\\"Write a subject for a cold sales email\\\")\\n\",\n \"\\n\",\n \"html_converter = Agent(name=\\\"HTML email body converter\\\", instructions=html_instructions, model=\\\"gpt-4o-mini\\\", output_type=HtmlStructure)\\n\",\n \"html_tool = html_converter.as_tool(tool_name=\\\"html_converter\\\",tool_description=\\\"Convert a text email body to an HTML email body\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 11,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"email_tools = [subject_tool, html_tool, send_html_email]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 42,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"instructions =\\\"You are an email formatter and sender. You receive the body of an email to be sent. \\\\\\n\",\n \"You first use the subject_writer tool to write a subject for the email, then use the html_converter tool to convert the body to HTML. \\\\\\n\",\n \"Finally, you use the send_html_email tool to send the email with the subject and HTML body.\\\"\\n\",\n \" \\n\",\n \"\\n\",\n \"emailer_agent = Agent(\\n\",\n \" name=\\\"Email Manager\\\",\\n\",\n \" instructions=instructions,\\n\",\n \" tools=email_tools,\\n\",\n \" model=\\\"gpt-4o-mini\\\",\\n\",\n \" handoff_description=\\\"Convert an email to HTML and send it\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 43,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"tools = [tool1, tool2, tool3]\\n\",\n \"handoffs = [emailer_agent]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"sales_manager_instructions = \\\"\\\"\\\"\\n\",\n \"You are a Sales Manager working for ComplAI. You use the tools given to you to generate cold sales emails. \\n\",\n \"You never generate sales emails yourself; you always use the tools.\\n\",\n \"You try all 3 sales agent tools at least once before choosing the best one.\\n\",\n \"You can use the tools multiple times if you're not satisfied with the results from the first try.\\n\",\n \"You select the single best email using your own judgement of which email will be most effective.\\n\",\n \"After picking the email, you handoff to the Email Manager agent to format and send the email.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"\\n\",\n \"sales_manager = Agent(\\n\",\n \" name=\\\"Sales Manager\\\",\\n\",\n \" instructions=sales_manager_instructions,\\n\",\n \" tools=tools,\\n\",\n \" handoffs=handoffs,\\n\",\n \" model=\\\"gpt-4o-mini\\\")\\n\",\n \"\\n\",\n \"message = \\\"Send out a cold sales email addressed to Dear CEO from Alice\\\"\\n\",\n \"\\n\",\n \"with trace(\\\"Automated SDR\\\"):\\n\",\n \" result = await Runner.run(sales_manager, message)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Check out the trace:\\n\",\n \"\\n\",\n \"https://platform.openai.com/traces\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 32,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"class NameCheckOutput(BaseModel):\\n\",\n \" is_name_in_message: bool\\n\",\n \" name: str\\n\",\n \"\\n\",\n \"guardrail_agent = Agent( \\n\",\n \" name=\\\"Name check\\\",\\n\",\n \" instructions=\\\"Check if the user is including someone's personal name in what they want you to do.\\\",\\n\",\n \" output_type=NameCheckOutput,\\n\",\n \" model=\\\"gpt-4o-mini\\\"\\n\",\n \")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 24,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"@input_guardrail\\n\",\n \"async def guardrail_against_name(ctx, agent, message):\\n\",\n \" result = await Runner.run(guardrail_agent, message, context=ctx.context)\\n\",\n \" is_name_in_message = result.final_output.is_name_in_message\\n\",\n \" return GuardrailFunctionOutput(output_info={\\\"found_name\\\": result.final_output},tripwire_triggered=is_name_in_message)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"careful_sales_manager = Agent(\\n\",\n \" name=\\\"Sales Manager\\\",\\n\",\n \" instructions=sales_manager_instructions,\\n\",\n \" tools=tools,\\n\",\n \" handoffs=[emailer_agent],\\n\",\n \" model=\\\"gpt-4o-mini\\\",\\n\",\n \" )\\n\",\n \"\\n\",\n \"message = \\\"Send out a cold sales email addressed to Dear CEO from Alice\\\"\\n\",\n \"\\n\",\n \"with trace(\\\"Protected Automated SDR\\\"):\\n\",\n \" result = await Runner.run(careful_sales_manager, message)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Check out the trace:\\n\",\n \"\\n\",\n \"https://platform.openai.com/traces\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 26,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\n\",\n \"message = \\\"Send out a cold sales email addressed to Dear CEO from Head of Business Development\\\"\\n\",\n \"\\n\",\n \"with trace(\\\"Protected Automated SDR\\\"):\\n\",\n \" result = await Runner.run(careful_sales_manager, message)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/exercise.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Exercise</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">• Try different models<br/>• Add more input and output guardrails<br/>• Use structured outputs for the email generation\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": []\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \"agents\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.11\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "8a9789b4fe7e37435099a047b9718cea50723146": {"t": 1785753565.570554, "n": 13558, "h": "2d80909806049089", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Week 2 Day 3\\n\",\n \"\\n\",\n \"Now we get to more detail:\\n\",\n \"\\n\",\n \"1. Different models\\n\",\n \"\\n\",\n \"2. Structured Outputs\\n\",\n \"\\n\",\n \"3. Guardrails\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 14,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"from dotenv import load_dotenv\\n\",\n \"from openai import AsyncOpenAI\\n\",\n \"from agents import Agent, Runner, trace, function_tool, OpenAIChatCompletionsModel, input_guardrail, output_guardrail, GuardrailFunctionOutput, RunContextWrapper\\n\",\n \"from typing import Dict\\n\",\n \"import sendgrid\\n\",\n \"import os\\n\",\n \"from sendgrid.helpers.mail import Mail, Email, To, Content\\n\",\n \"from pydantic import BaseModel\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 2,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"True\"\n ]\n },\n \"execution_count\": 2,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"load_dotenv(override=True)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 3,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"OpenAI API Key exists and begins sk-proj-\\n\",\n \"Google API Key exists and begins AI\\n\",\n \"DeepSeek API Key exists and begins sk-\\n\",\n \"Groq API Key exists and begins gsk_\\n\"\n ]\n }\n ],\n \"source\": [\n \"openai_api_key = os.getenv('OPENAI_API_KEY')\\n\",\n \"google_api_key = os.getenv('GOOGLE_API_KEY')\\n\",\n \"deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\\n\",\n \"groq_api_key = os.getenv('GROQ_API_KEY')\\n\",\n \"\\n\",\n \"if openai_api_key:\\n\",\n \" print(f\\\"OpenAI API Key exists and begins {openai_api_key[:8]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"OpenAI API Key not set\\\")\\n\",\n \"\\n\",\n \"if google_api_key:\\n\",\n \" print(f\\\"Google API Key exists and begins {google_api_key[:2]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Google API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if deepseek_api_key:\\n\",\n \" print(f\\\"DeepSeek API Key exists and begins {deepseek_api_key[:3]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"DeepSeek API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if groq_api_key:\\n\",\n \" print(f\\\"Groq API Key exists and begins {groq_api_key[:4]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Groq API Key not set (and this is optional)\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 4,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"instructions1 = \\\"You are a sales agent working for ComplAI, \\\\\\n\",\n \"a company that provides a SaaS tool for ensuring SOC2 compliance and preparing for audits, powered by AI. \\\\\\n\",\n \"You write professional, serious cold emails.\\\"\\n\",\n \"\\n\",\n \"instructions2 = \\\"You are a humorous, engaging sales agent working for ComplAI, \\\\\\n\",\n \"a company that provides a SaaS tool for ensuring SOC2 compliance and preparing for audits, powered by AI. \\\\\\n\",\n \"You write witty, engaging cold emails that are likely to get a response.\\\"\\n\",\n \"\\n\",\n \"instructions3 = \\\"You are a busy sales agent working for ComplAI, \\\\\\n\",\n \"a company that provides a SaaS tool for ensuring SOC2 compliance and preparing for audits, powered by AI. \\\\\\n\",\n \"You write concise, to the point cold emails.\\\"\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### It's easy to use any models with OpenAI compatible endpoints\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 5,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 6,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.0-flash\\\", openai_client=gemini_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 7,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"sales_agent1 = Agent(name=\\\"DeepSeek Sales Agent\\\", instructions=instructions1, model=deepseek_model)\\n\",\n \"sales_agent2 = Agent(name=\\\"Gemini Sales Agent\\\", instructions=instructions2, model=gemini_model)\\n\",\n \"sales_agent3 = Agent(name=\\\"Llama3.3 Sales Agent\\\",instructions=instructions3,model=llama3_3_model)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 8,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"description = \\\"Write a cold sales email\\\"\\n\",\n \"\\n\",\n \"tool1 = sales_agent1.as_tool(tool_name=\\\"sales_agent1\\\", tool_description=description)\\n\",\n \"tool2 = sales_agent2.as_tool(tool_name=\\\"sales_agent2\\\", tool_description=description)\\n\",\n \"tool3 = sales_agent3.as_tool(tool_name=\\\"sales_agent3\\\", tool_description=description)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 9,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"@function_tool\\n\",\n \"def send_html_email(subject: str, html_body: str) -> Dict[str, str]:\\n\",\n \" \\\"\\\"\\\" Send out an email with the given subject and HTML body to all sales prospects \\\"\\\"\\\"\\n\",\n \" sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))\\n\",\n \" from_email = Email(\\\"inform@acion.es\\\") # Change to your verified sender\\n\",\n \" to_email = To(\\\"dmitriiblokhin@gmail.com\\\") # Change to your recipient\\n\",\n \" content = Content(\\\"text/html\\\", html_body)\\n\",\n \" mail = Mail(from_email, to_email, subject, content).get()\\n\",\n \" sg.client.mail.send.post(request_body=mail)\\n\",\n \" return {\\\"status\\\": \\\"success\\\"}\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 10,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"subject_instructions = \\\"You can write a subject for a cold sales email. \\\\\\n\",\n \"You are given a message and you need to write a subject for an email that is likely to get a response.\\\"\\n\",\n \"\\n\",\n \"html_instructions = \\\"You can convert a text email body to an HTML email body. \\\\\\n\",\n \"You are given a text email body which might have some markdown \\\\\\n\",\n \"and you need to convert it to an HTML email body with simple, clear, compelling layout and design.\\\"\\n\",\n \"\\n\",\n \"class SubjectStructure(BaseModel):\\n\",\n \" subject: str\\n\",\n \"\\n\",\n \"class HtmlStructure(BaseModel):\\n\",\n \" html_body: str\\n\",\n \"\\n\",\n \"\\n\",\n \"subject_writer = Agent(name=\\\"Email subject writer\\\", instructions=subject_instructions, model=\\\"gpt-4o-mini\\\", output_type=SubjectStructure)\\n\",\n \"subject_tool = subject_writer.as_tool(tool_name=\\\"subject_writer\\\", tool_description=\\\"Write a subject for a cold sales email\\\")\\n\",\n \"\\n\",\n \"html_converter = Agent(name=\\\"HTML email body converter\\\", instructions=html_instructions, model=\\\"gpt-4o-mini\\\", output_type=HtmlStructure)\\n\",\n \"html_tool = html_converter.as_tool(tool_name=\\\"html_converter\\\",tool_description=\\\"Convert a text email body to an HTML email body\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 11,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"email_tools = [subject_tool, html_tool, send_html_email]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 42,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"instructions =\\\"You are an email formatter and sender. You receive the body of an email to be sent. \\\\\\n\",\n \"You first use the subject_writer tool to write a subject for the email, then use the html_converter tool to convert the body to HTML. \\\\\\n\",\n \"Finally, you use the send_html_email tool to send the email with the subject and HTML body.\\\"\\n\",\n \" \\n\",\n \"\\n\",\n \"emailer_agent = Agent(\\n\",\n \" name=\\\"Email Manager\\\",\\n\",\n \" instructions=instructions,\\n\",\n \" tools=email_tools,\\n\",\n \" model=\\\"gpt-4o-mini\\\",\\n\",\n \" handoff_description=\\\"Convert an email to HTML and send it\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 43,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"tools = [tool1, tool2, tool3]\\n\",\n \"handoffs = [emailer_agent]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"sales_manager_instructions = \\\"\\\"\\\"\\n\",\n \"You are a Sales Manager working for ComplAI. You use the tools given to you to generate cold sales emails. \\n\",\n \"You never generate sales emails yourself; you always use the tools.\\n\",\n \"You try all 3 sales agent tools at least once before choosing the best one.\\n\",\n \"You can use the tools multiple times if you're not satisfied with the results from the first try.\\n\",\n \"You select the single best email using your own judgement of which email will be most effective.\\n\",\n \"After picking the email, you handoff to the Email Manager agent to format and send the email.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"\\n\",\n \"sales_manager = Agent(\\n\",\n \" name=\\\"Sales Manager\\\",\\n\",\n \" instructions=sales_manager_instructions,\\n\",\n \" tools=tools,\\n\",\n \" handoffs=handoffs,\\n\",\n \" model=\\\"gpt-4o-mini\\\")\\n\",\n \"\\n\",\n \"message = \\\"Send out a cold sales email addressed to Dear CEO from Alice\\\"\\n\",\n \"\\n\",\n \"with trace(\\\"Automated SDR\\\"):\\n\",\n \" result = await Runner.run(sales_manager, message)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Check out the trace:\\n\",\n \"\\n\",\n \"https://platform.openai.com/traces\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 32,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"class NameCheckOutput(BaseModel):\\n\",\n \" is_name_in_message: bool\\n\",\n \" name: str\\n\",\n \"\\n\",\n \"guardrail_agent = Agent( \\n\",\n \" name=\\\"Name check\\\",\\n\",\n \" instructions=\\\"Check if the user is including someone's personal name in what they want you to do.\\\",\\n\",\n \" output_type=NameCheckOutput,\\n\",\n \" model=\\\"gpt-4o-mini\\\"\\n\",\n \")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 24,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"@input_guardrail\\n\",\n \"async def guardrail_against_name(ctx, agent, message):\\n\",\n \" result = await Runner.run(guardrail_agent, message, context=ctx.context)\\n\",\n \" is_name_in_message = result.final_output.is_name_in_message\\n\",\n \" return GuardrailFunctionOutput(output_info={\\\"found_name\\\": result.final_output},tripwire_triggered=is_name_in_message)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"careful_sales_manager = Agent(\\n\",\n \" name=\\\"Sales Manager\\\",\\n\",\n \" instructions=sales_manager_instructions,\\n\",\n \" tools=tools,\\n\",\n \" handoffs=[emailer_agent],\\n\",\n \" model=\\\"gpt-4o-mini\\\",\\n\",\n \" )\\n\",\n \"\\n\",\n \"message = \\\"Send out a cold sales email addressed to Dear CEO from Alice\\\"\\n\",\n \"\\n\",\n \"with trace(\\\"Protected Automated SDR\\\"):\\n\",\n \" result = await Runner.run(careful_sales_manager, message)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Check out the trace:\\n\",\n \"\\n\",\n \"https://platform.openai.com/traces\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 26,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\n\",\n \"message = \\\"Send out a cold sales email addressed to Dear CEO from Head of Business Development\\\"\\n\",\n \"\\n\",\n \"with trace(\\\"Protected Automated SDR\\\"):\\n\",\n \" result = await Runner.run(careful_sales_manager, message)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/exercise.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Exercise</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">• Try different models<br/>• Add more input and output guardrails<br/>• Use structured outputs for the email generation\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": []\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \"agents\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.11\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}}}}