├── .gitignore ├── .python-version ├── 1_foundations ├── 1_lab1.ipynb ├── 2_lab2.ipynb ├── 3_lab3.ipynb ├── 4_lab4.ipynb ├── app.py ├── community_contributions │ ├── 1_lab1_Mudassar.ipynb │ ├── 1_lab1_gemini.ipynb │ ├── 1_lab1_groq_llama.ipynb │ ├── 2_lab2_exercise.ipynb │ ├── Business_Idea.ipynb │ ├── Multi-Model-Resume–JD-Match-Analyzer │ │ ├── .gitignore │ │ ├── AnalyzeResume.png │ │ ├── README.md │ │ ├── multi_file_ingestion.py │ │ └── resume_agent.py │ ├── app_rate_limiter_mailgun_integration.py │ ├── community.ipynb │ ├── llm-evaluator.ipynb │ ├── my_1_lab1.ipynb │ └── travel_planner_multicall_and_sythesizer.ipynb ├── me │ ├── linkedin.pdf │ └── summary.txt └── requirements.txt ├── 2_openai ├── 1_lab1.ipynb ├── 2_lab2.ipynb ├── 3_lab3.ipynb ├── 4_lab4.ipynb ├── community_contributions │ ├── 2_lab2_with_graph_visualization.ipynb │ ├── Upgraded_Deep_Reasearch │ │ ├── clarifier_agent.py │ │ ├── deep_research.py │ │ ├── email_agent.py │ │ ├── manager_agent.py │ │ ├── planner_agent.py │ │ ├── search_agent.py │ │ └── writer_agent.py │ ├── community.ipynb │ └── customer_care_agents │ │ ├── .env-example │ │ ├── README.md │ │ ├── __init__.py │ │ └── agent.py └── deep_research │ ├── deep_research.py │ ├── email_agent.py │ ├── planner_agent.py │ ├── research_manager.py │ ├── search_agent.py │ └── writer_agent.py ├── 3_crew ├── coder │ ├── .gitignore │ ├── README.md │ ├── knowledge │ │ └── user_preference.txt │ ├── output │ │ └── code_and_output.txt │ ├── pyproject.toml │ ├── src │ │ └── coder │ │ │ ├── __init__.py │ │ │ ├── config │ │ │ ├── agents.yaml │ │ │ └── tasks.yaml │ │ │ ├── crew.py │ │ │ ├── main.py │ │ │ └── tools │ │ │ ├── __init__.py │ │ │ └── custom_tool.py │ └── uv.lock ├── community_contributions │ ├── Book_Researcher │ │ ├── .gitignore │ │ ├── README.md │ │ ├── knowledge │ │ │ └── user_preference.txt │ │ ├── output │ │ │ ├── genre_research.md │ │ │ ├── top_novelists.md │ │ │ └── trending_books.md │ │ ├── pyproject.toml │ │ ├── src │ │ │ └── book │ │ │ │ ├── __init__.py │ │ │ │ ├── config │ │ │ │ ├── agents.yaml │ │ │ │ └── tasks.yaml │ │ │ │ ├── crew.py │ │ │ │ ├── main.py │ │ │ │ └── tools │ │ │ │ ├── __init__.py │ │ │ │ └── custom_tool.py │ │ └── uv.lock │ └── community.ipynb ├── debate │ ├── .gitignore │ ├── README.md │ ├── knowledge │ │ └── user_preference.txt │ ├── output │ │ ├── decide.md │ │ ├── oppose.md │ │ └── propose.md │ ├── pyproject.toml │ ├── src │ │ └── debate │ │ │ ├── __init__.py │ │ │ ├── config │ │ │ ├── agents.yaml │ │ │ └── tasks.yaml │ │ │ ├── crew.py │ │ │ ├── main.py │ │ │ └── tools │ │ │ ├── __init__.py │ │ │ └── custom_tool.py │ └── uv.lock ├── engineering_team │ ├── .gitignore │ ├── README.md │ ├── example_output_4o │ │ ├── accounts.py │ │ ├── accounts.py_design.md │ │ ├── app.py │ │ └── test_accounts.py │ ├── example_output_mini │ │ ├── accounts.py │ │ └── app.py │ ├── example_output_new │ │ ├── accounts.py │ │ ├── accounts.py_design.md │ │ ├── app.py │ │ └── test_accounts.py │ ├── knowledge │ │ └── user_preference.txt │ ├── pyproject.toml │ ├── src │ │ └── engineering_team │ │ │ ├── __init__.py │ │ │ ├── config │ │ │ ├── agents.yaml │ │ │ └── tasks.yaml │ │ │ ├── crew.py │ │ │ ├── main.py │ │ │ └── tools │ │ │ ├── __init__.py │ │ │ └── custom_tool.py │ └── uv.lock ├── financial_researcher │ ├── .gitignore │ ├── README.md │ ├── knowledge │ │ └── user_preference.txt │ ├── output │ │ └── report.md │ ├── pyproject.toml │ ├── src │ │ └── financial_researcher │ │ │ ├── __init__.py │ │ │ ├── config │ │ │ ├── agents.yaml │ │ │ └── tasks.yaml │ │ │ ├── crew.py │ │ │ ├── main.py │ │ │ └── tools │ │ │ ├── __init__.py │ │ │ └── custom_tool.py │ └── uv.lock └── stock_picker │ ├── .gitignore │ ├── README.md │ ├── knowledge │ └── user_preference.txt │ ├── memory │ ├── 04eb6688-8d89-4eee-a8d7-d2ef2a916e4b │ │ ├── data_level0.bin │ │ ├── header.bin │ │ ├── length.bin │ │ └── link_lists.bin │ ├── chroma.sqlite3 │ └── long_term_memory_storage.db │ ├── output │ ├── decision.md │ ├── research │ ├── research_report.json │ └── trending_companies.json │ ├── pyproject.toml │ ├── report.md │ ├── src │ └── stock_picker │ │ ├── __init__.py │ │ ├── config │ │ ├── agents.yaml │ │ └── tasks.yaml │ │ ├── crew.py │ │ ├── main.py │ │ └── tools │ │ ├── __init__.py │ │ └── push_tool.py │ └── uv.lock ├── 4_langgraph ├── 1_lab1.ipynb ├── 2_lab2.ipynb ├── 3_lab3.ipynb ├── 4_lab4.ipynb ├── app.py ├── community_contributions │ └── community.ipynb ├── memory.db ├── memory.db-shm ├── memory.db-wal ├── sandbox │ └── dinner.md ├── sidekick.py └── sidekick_tools.py ├── 5_autogen ├── 1_lab1_autogen_agentchat.ipynb ├── 2_lab2_autogen_agentchat.ipynb ├── 3_lab3_autogen_core.ipynb ├── 4_lab4_autogen_distributed.ipynb ├── agent.py ├── community_contributions │ └── community.ipynb ├── creator.py ├── messages.py ├── sandbox │ └── flights.md ├── tickets.db └── world.py ├── 6_mcp ├── 1_lab1.ipynb ├── 2_lab2.ipynb ├── 3_lab3.ipynb ├── 4_lab4.ipynb ├── 5_lab5.ipynb ├── accounts.py ├── accounts_client.py ├── accounts_server.py ├── alpha_client.py ├── app.py ├── community_contributions │ └── community.ipynb ├── database.py ├── market.py ├── market_server.py ├── mcp_params.py ├── push_server.py ├── reset.py ├── sandbox │ └── banoffee.md ├── templates.py ├── tracers.py ├── traders.py ├── trading_floor.py └── util.py ├── LICENSE ├── README.md ├── assets ├── aaa.png ├── autonomy.png ├── business.jpg ├── business.png ├── exercise.png ├── stop.png ├── thanks.png ├── tools.png └── voyage.jpg ├── guides ├── 01_intro.ipynb ├── 02_command_line.ipynb ├── 03_git_and_github.ipynb ├── 04_technical_foundations.ipynb ├── 05_notebooks.ipynb ├── 06_python_foundations.ipynb ├── 07_vibe_coding_and_debugging.ipynb ├── 08_debugging.ipynb ├── 09_ai_apis_and_ollama.ipynb ├── 10_intermediate_python.ipynb ├── 11_async_python.ipynb └── 12_starting_your_project.ipynb ├── pyproject.toml ├── setup ├── SETUP-PC.md ├── SETUP-WSL.md ├── SETUP-linux.md ├── SETUP-mac.md ├── diagnostics.py └── troubleshooting.ipynb └── uv.lock /.python-version: -------------------------------------------------------------------------------- 1 | 3.12 2 | -------------------------------------------------------------------------------- /1_foundations/community_contributions/Multi-Model-Resume–JD-Match-Analyzer/.gitignore: -------------------------------------------------------------------------------- 1 | .env -------------------------------------------------------------------------------- /1_foundations/community_contributions/Multi-Model-Resume–JD-Match-Analyzer/AnalyzeResume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/1_foundations/community_contributions/Multi-Model-Resume–JD-Match-Analyzer/AnalyzeResume.png -------------------------------------------------------------------------------- /1_foundations/community_contributions/Multi-Model-Resume–JD-Match-Analyzer/README.md: -------------------------------------------------------------------------------- 1 | # 🧠 Resume-Job Match Application (LLM-Powered) 2 | 3 | ![AnalyseResume](AnalyzeResume.png) 4 | 5 | This is a **Streamlit-based web app** that evaluates how well a resume matches a job description using powerful Large Language Models (LLMs) such as: 6 | 7 | - OpenAI GPT 8 | - Anthropic Claude 9 | - Google Gemini (Generative AI) 10 | - Groq LLM 11 | - DeepSeek LLM 12 | 13 | The app takes a resume and job description as input files, sends them to these LLMs, and returns: 14 | 15 | - ✅ Match percentage from each model 16 | - 📊 A ranked table sorted by match % 17 | - 📈 Average match percentage 18 | - 🧠 Simple, responsive UI for instant feedback 19 | 20 | ## 📂 Features 21 | 22 | - Upload **any file type** for resume and job description (PDF, DOCX, TXT, etc.) 23 | - Automatic extraction and cleaning of text 24 | - Match results across multiple models in real time 25 | - Table view with clean formatting 26 | - Uses `.env` file for secure API key management 27 | 28 | ## 🔐 Environment Setup (`.env`) 29 | 30 | Create a `.env` file in the project root and add the following API keys: 31 | 32 | ```env 33 | OPENAI_API_KEY=your-openai-api-key 34 | ANTHROPIC_API_KEY=your-anthropic-api-key 35 | GOOGLE_API_KEY=your-google-api-key 36 | GROQ_API_KEY=your-groq-api-key 37 | DEEPSEEK_API_KEY=your-deepseek-api-key 38 | ``` 39 | 40 | ## ▶️ Running the App 41 | ### Launch the app using Streamlit: 42 | 43 | streamlit run resume_agent.py 44 | 45 | ### The app will open in your browser at: 46 | 📍 http://localhost:8501 47 | 48 | 49 | -------------------------------------------------------------------------------- /1_foundations/community_contributions/Multi-Model-Resume–JD-Match-Analyzer/multi_file_ingestion.py: -------------------------------------------------------------------------------- 1 | import os 2 | from langchain.document_loaders import ( 3 | TextLoader, 4 | PyPDFLoader, 5 | UnstructuredWordDocumentLoader, 6 | UnstructuredFileLoader 7 | ) 8 | 9 | 10 | 11 | def load_and_split_resume(file_path: str): 12 | """ 13 | Loads a resume file and splits it into text chunks using LangChain. 14 | 15 | Args: 16 | file_path (str): Path to the resume file (.txt, .pdf, .docx, etc.) 17 | chunk_size (int): Maximum characters per chunk. 18 | chunk_overlap (int): Overlap between chunks to preserve context. 19 | 20 | Returns: 21 | List[str]: List of split text chunks. 22 | """ 23 | if not os.path.exists(file_path): 24 | raise FileNotFoundError(f"File not found: {file_path}") 25 | 26 | ext = os.path.splitext(file_path)[1].lower() 27 | 28 | # Select the appropriate loader 29 | if ext == ".txt": 30 | loader = TextLoader(file_path, encoding="utf-8") 31 | elif ext == ".pdf": 32 | loader = PyPDFLoader(file_path) 33 | elif ext in [".docx", ".doc"]: 34 | loader = UnstructuredWordDocumentLoader(file_path) 35 | else: 36 | # Fallback for other common formats 37 | loader = UnstructuredFileLoader(file_path) 38 | 39 | # Load the file as LangChain documents 40 | documents = loader.load() 41 | 42 | 43 | return documents 44 | # return [doc.page_content for doc in split_docs] 45 | -------------------------------------------------------------------------------- /1_foundations/community_contributions/community.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Community contributions\n", 8 | "\n", 9 | "Thank you for considering contributing your work to the repo!\n", 10 | "\n", 11 | "Please add your code (modules or notebooks) to this directory and send me a PR, per the instructions in the guides.\n", 12 | "\n", 13 | "I'd love to share your progress with other students, so everyone can benefit from your projects.\n" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [] 20 | } 21 | ], 22 | "metadata": { 23 | "language_info": { 24 | "name": "python" 25 | } 26 | }, 27 | "nbformat": 4, 28 | "nbformat_minor": 2 29 | } 30 | -------------------------------------------------------------------------------- /1_foundations/me/linkedin.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/1_foundations/me/linkedin.pdf -------------------------------------------------------------------------------- /1_foundations/me/summary.txt: -------------------------------------------------------------------------------- 1 | My name is Ed Donner. I'm an entrepreneur, software engineer and data scientist. I'm originally from London, England, but I moved to NYC in 2000. 2 | I love all foods, particularly French food, but strangely I'm repelled by almost all forms of cheese. I'm not allergic, I just hate the taste! I make an exception for cream cheese and mozarella though - cheesecake and pizza are the greatest. -------------------------------------------------------------------------------- /1_foundations/requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | python-dotenv 3 | gradio 4 | pypdf 5 | openai 6 | openai-agents -------------------------------------------------------------------------------- /2_openai/1_lab1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Week 2 Day 1\n", 8 | "\n", 9 | "And now! Our first look at OpenAI Agents SDK\n", 10 | "\n", 11 | "You won't believe how lightweight this is.." 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "\n", 19 | " \n", 20 | " \n", 23 | " \n", 28 | " \n", 29 | "
\n", 21 | " \n", 22 | " \n", 24 | "

The OpenAI Agents SDK Docs

\n", 25 | " The documentation on OpenAI Agents SDK is really clear and simple: https://openai.github.io/openai-agents-python/ and it's well worth a look.\n", 26 | " \n", 27 | "
" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 1, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "# The imports\n", 39 | "\n", 40 | "from dotenv import load_dotenv\n", 41 | "from agents import Agent, Runner, trace\n", 42 | "\n" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "# The usual starting point\n", 52 | "\n", 53 | "load_dotenv(override=True)\n" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 4, 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "\n", 63 | "# Make an agent with name, instructions, model\n", 64 | "\n", 65 | "agent = Agent(name=\"Jokester\", instructions=\"You are a joke teller\", model=\"gpt-4o-mini\")" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "# Run the joke with Runner.run(agent, prompt) then print final_output\n", 75 | "\n", 76 | "with trace(\"Telling a joke\"):\n", 77 | " result = await Runner.run(agent, \"Tell a joke about Autonomous AI Agents\")\n", 78 | " print(result.final_output)" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": {}, 84 | "source": [ 85 | "## Now go and look at the trace\n", 86 | "\n", 87 | "https://platform.openai.com/traces" 88 | ] 89 | } 90 | ], 91 | "metadata": { 92 | "kernelspec": { 93 | "display_name": ".venv", 94 | "language": "python", 95 | "name": "python3" 96 | }, 97 | "language_info": { 98 | "codemirror_mode": { 99 | "name": "ipython", 100 | "version": 3 101 | }, 102 | "file_extension": ".py", 103 | "mimetype": "text/x-python", 104 | "name": "python", 105 | "nbconvert_exporter": "python", 106 | "pygments_lexer": "ipython3", 107 | "version": "3.12.9" 108 | } 109 | }, 110 | "nbformat": 4, 111 | "nbformat_minor": 2 112 | } 113 | -------------------------------------------------------------------------------- /2_openai/community_contributions/Upgraded_Deep_Reasearch/clarifier_agent.py: -------------------------------------------------------------------------------- 1 | # clarifier_agent.py 2 | 3 | from typing import List 4 | from pydantic import BaseModel 5 | from agents import Agent 6 | 7 | class ClarificationData(BaseModel): 8 | questions: List[str] 9 | 10 | CLARIFY_INSTRUCTIONS = """ 11 | You are a Research Clarifier. Given a user’s research query, generate exactly 3 clarifying questions 12 | that will help focus and refine that query. Return only JSON matching the ClarificationData model. 13 | """ 14 | 15 | clarifier_agent = Agent( 16 | name="ClarifierAgent", 17 | instructions=CLARIFY_INSTRUCTIONS, 18 | model="gpt-4o-mini", 19 | output_type=ClarificationData, 20 | ) 21 | -------------------------------------------------------------------------------- /2_openai/community_contributions/Upgraded_Deep_Reasearch/deep_research.py: -------------------------------------------------------------------------------- 1 | # deep_research.py 2 | 3 | import gradio as gr 4 | from dotenv import load_dotenv 5 | from agents import Runner 6 | from clarifier_agent import clarifier_agent 7 | from planner_agent import planner_agent 8 | from search_agent import search_agent 9 | from writer_agent import writer_agent 10 | from email_agent import email_agent # ← import the Agent here 11 | 12 | # Load environment variables (e.g., SENDGRID_API_KEY) 13 | load_dotenv(override=True) 14 | 15 | async def run(query: str, answers: str, state: list[str]): 16 | """ 17 | Two-phase Gradio workflow: 18 | 1) If `state` is empty, ask clarifying questions. 19 | 2) Once answered, plan → search → write → email → report. 20 | """ 21 | # Phase 1: Clarify 22 | if not state: 23 | clar = await Runner.run(clarifier_agent, query) 24 | questions = clar.final_output.questions 25 | qtext = "\n".join(f"{i+1}. {q}" for i, q in enumerate(questions)) 26 | return qtext, gr.update(visible=True), questions 27 | 28 | # Phase 2: Full pipeline 29 | # 1) Bundle user answers for planner 30 | answered = [ 31 | f"{i+1}. {state[i]} answered: {ans.strip()}" 32 | for i, ans in enumerate(answers.splitlines()) 33 | ] 34 | planner_input = f"Original query: {query}\nClarifications:\n" + "\n".join(answered) 35 | 36 | # 2) Generate search plan 37 | plan_res = await Runner.run(planner_agent, planner_input) 38 | searches = plan_res.final_output.searches 39 | 40 | # 3) Run each search and collect summaries 41 | summaries = [] 42 | for item in searches: 43 | search_res = await Runner.run(search_agent, item.query) 44 | summaries.append(str(search_res.final_output)) 45 | 46 | # 4) Write the full report 47 | writer_input = f"Original query: {query}\nSummaries: {summaries}" 48 | write_res = await Runner.run(writer_agent, writer_input) 49 | report_data = write_res.final_output 50 | report_md = report_data.markdown_report 51 | 52 | # 5) Email the report 53 | # Pass the markdown report as the “detailed report” prompt to the email agent 54 | await Runner.run(email_agent, report_md) 55 | 56 | # Return the markdown report and hide the answers box 57 | return report_md, gr.update(visible=False), [] 58 | 59 | # Gradio UI 60 | with gr.Blocks(theme=gr.themes.Default(primary_hue="sky")) as ui: 61 | gr.Markdown("# Deep Research") 62 | query_textbox = gr.Textbox(label="What topic would you like to research?") 63 | answers_box = gr.Textbox( 64 | label="Answer clarifying questions (one per line)", 65 | visible=False, 66 | lines=3, 67 | placeholder="1. …\n2. …\n3. …" 68 | ) 69 | state = gr.State([]) 70 | report = gr.Markdown(label="Output") 71 | run_button = gr.Button("Run") 72 | 73 | run_button.click( 74 | fn=run, 75 | inputs=[query_textbox, answers_box, state], 76 | outputs=[report, answers_box, state] 77 | ) 78 | 79 | ui.launch(share=False) 80 | -------------------------------------------------------------------------------- /2_openai/community_contributions/Upgraded_Deep_Reasearch/email_agent.py: -------------------------------------------------------------------------------- 1 | import os 2 | from typing import Dict 3 | 4 | import sendgrid 5 | from sendgrid.helpers.mail import Email, Mail, Content, To 6 | from agents import Agent, function_tool 7 | 8 | @function_tool 9 | def send_email(subject: str, html_body: str) -> Dict[str, str]: 10 | """ Send an email with the given subject and HTML body """ 11 | sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY')) 12 | from_email = Email("roykaushik354@gmail.com") # put your verified sender here 13 | to_email = To("teamblood4ace@gmail.com") # put your recipient here 14 | content = Content("text/html", html_body) 15 | mail = Mail(from_email, to_email, subject, content).get() 16 | response = sg.client.mail.send.post(request_body=mail) 17 | print("Email response", response.status_code) 18 | return {"status": "success"} 19 | 20 | INSTRUCTIONS = """You are able to send a nicely formatted HTML email based on a detailed report. 21 | You will be provided with a detailed report. You should use your tool to send one email, providing the 22 | report converted into clean, well presented HTML with an appropriate subject line.""" 23 | 24 | email_agent = Agent( 25 | name="Email agent", 26 | instructions=INSTRUCTIONS, 27 | tools=[send_email], 28 | model="gpt-4o-mini", 29 | ) 30 | -------------------------------------------------------------------------------- /2_openai/community_contributions/Upgraded_Deep_Reasearch/manager_agent.py: -------------------------------------------------------------------------------- 1 | # manager_agent.py 2 | 3 | from agents import Agent, function_tool 4 | from clarifier_agent import clarifier_agent 5 | from planner_agent import planner_agent 6 | from search_agent import search_agent 7 | from writer_agent import writer_agent, ReportData 8 | from email_agent import send_email 9 | 10 | MANAGER_INSTRUCTIONS = """ 11 | You are the Research Manager orchestrator. 12 | 13 | 1) **Clarify.** Ask the user 3 clarifying questions about their original query. 14 | 2) **Plan.** Once the user answers, call ClarifierAgent to parse those answers, 15 | then hand off both original query + answers to PlannerAgent to get a tuned WebSearchPlan. 16 | 3) **Search.** For each item in that plan, call SearchAgent to get summaries. 17 | 4) **Write.** Pass the collected summaries to WriterAgent to produce a full report. 18 | 5) **Email.** Use the send_email tool to deliver the report via HTML. 19 | 20 | Make sure each handoff is explicit (you invoke the appropriate tool with the right data). 21 | """ 22 | 23 | manager_agent = Agent( 24 | name="ManagerAgent", 25 | instructions=MANAGER_INSTRUCTIONS, 26 | tools=[ 27 | clarifier_agent.as_tool( 28 | tool_name="clarifier", 29 | tool_description="Generate 3 clarifying questions for the query" 30 | ), 31 | planner_agent.as_tool( 32 | tool_name="planner", 33 | tool_description="Create a focused search plan given query and clarifications" 34 | ), 35 | search_agent.as_tool( 36 | tool_name="search", 37 | tool_description="Summarize web search results for a given term" 38 | ), 39 | writer_agent.as_tool( 40 | tool_name="writer", 41 | tool_description="Produce a cohesive markdown report from search summaries" 42 | ), 43 | send_email, # function tool for sending the report via email 44 | ], 45 | model="gpt-4o-mini", 46 | ) 47 | -------------------------------------------------------------------------------- /2_openai/community_contributions/Upgraded_Deep_Reasearch/planner_agent.py: -------------------------------------------------------------------------------- 1 | # planner_agent.py 2 | 3 | from pydantic import BaseModel 4 | from agents import Agent 5 | 6 | HOW_MANY_SEARCHES = 20 7 | 8 | INSTRUCTIONS = """ 9 | You are a helpful research assistant. You will be given: 10 | • Original query 11 | • A list of clarifying questions AND their answers 12 | Using that, come up with a set of 20 focused web-search queries 13 | that best answer the refined question. 14 | Return a WebSearchPlan as before. 15 | """ 16 | 17 | class WebSearchItem(BaseModel): 18 | reason: str 19 | "Your reasoning for why this search is important to the query." 20 | 21 | query: str 22 | "The search term to use for the web search." 23 | 24 | class WebSearchPlan(BaseModel): 25 | searches: list[WebSearchItem] 26 | """A list of web searches to perform to best answer the query.""" 27 | 28 | planner_agent = Agent( 29 | name="PlannerAgent", 30 | instructions=INSTRUCTIONS, 31 | model="gpt-4o-mini", 32 | output_type=WebSearchPlan, 33 | ) 34 | -------------------------------------------------------------------------------- /2_openai/community_contributions/Upgraded_Deep_Reasearch/search_agent.py: -------------------------------------------------------------------------------- 1 | from agents import Agent, WebSearchTool, ModelSettings 2 | 3 | INSTRUCTIONS = ( 4 | "You are a research assistant. Given a search term, you search the web for that term and " 5 | "produce a concise summary of the results. The summary must 2-3 paragraphs and less than 300 " 6 | "words. Capture the main points. Write succintly, no need to have complete sentences or good " 7 | "grammar. This will be consumed by someone synthesizing a report, so its vital you capture the " 8 | "essence and ignore any fluff. Do not include any additional commentary other than the summary itself." 9 | ) 10 | 11 | search_agent = Agent( 12 | name="Search agent", 13 | instructions=INSTRUCTIONS, 14 | tools=[WebSearchTool(search_context_size="low")], 15 | model="gpt-4o-mini", 16 | model_settings=ModelSettings(tool_choice="required"), 17 | ) -------------------------------------------------------------------------------- /2_openai/community_contributions/Upgraded_Deep_Reasearch/writer_agent.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from agents import Agent 3 | 4 | INSTRUCTIONS = ( 5 | "You are a senior researcher tasked with writing a cohesive report for a research query. " 6 | "You will be provided with the original query, and some initial research done by a research assistant.\n" 7 | "You should first come up with an outline for the report that describes the structure and " 8 | "flow of the report. Then, generate the report and return that as your final output.\n" 9 | "The final output should be in markdown format, and it should be lengthy and detailed. Aim " 10 | "for 5-10 pages of content, at least 1000 words." 11 | ) 12 | 13 | 14 | class ReportData(BaseModel): 15 | short_summary: str 16 | """A short 2-3 sentence summary of the findings.""" 17 | 18 | markdown_report: str 19 | """The final report""" 20 | 21 | follow_up_questions: list[str] 22 | """Suggested topics to research further""" 23 | 24 | 25 | writer_agent = Agent( 26 | name="WriterAgent", 27 | instructions=INSTRUCTIONS, 28 | model="gpt-4o-mini", 29 | output_type=ReportData, 30 | ) -------------------------------------------------------------------------------- /2_openai/community_contributions/community.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Community contributions\n", 8 | "\n", 9 | "Thank you for considering contributing your work to the repo!\n", 10 | "\n", 11 | "Please add your code (modules or notebooks) to this directory and send me a PR, per the instructions in the guides.\n", 12 | "\n", 13 | "I'd love to share your progress with other students, so everyone can benefit from your projects.\n" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [] 20 | } 21 | ], 22 | "metadata": { 23 | "language_info": { 24 | "name": "python" 25 | } 26 | }, 27 | "nbformat": 4, 28 | "nbformat_minor": 2 29 | } 30 | -------------------------------------------------------------------------------- /2_openai/community_contributions/customer_care_agents/.env-example: -------------------------------------------------------------------------------- 1 | GOOGLE_API_KEY= # Your API KEY. You can find it for free on https://aistudio.google.com/ -------------------------------------------------------------------------------- /2_openai/community_contributions/customer_care_agents/README.md: -------------------------------------------------------------------------------- 1 | # Customer Care Agent – Google ADK Project 2 | 3 | This project is a **Customer Care Agent** developed using the **Google ADK (Agent Development Kit)**. The primary goal of this project is to demonstrate an AI agent's capability to assist customers with queries related to perfume products. 4 | 5 | ## 🧪 Project Features 6 | 7 | - A **dummy dataset** of perfume products is generated at runtime. 8 | - The dataset can be saved as an **Excel file** and reloaded into a pandas DataFrame. 9 | - This allows users to **cross-check the agent’s responses** against the product information. 10 | 11 | ## 🚀 Getting Started 12 | 13 | ### 1. Install Requirements 14 | 15 | Make sure you have [**uv**](https://github.com/astral-sh/uv) installed, then run: 16 | 17 | ```bash 18 | uv add google-adk pandas 19 | ``` 20 | 21 | ### 2. Set Up Environment Variables 22 | Create a .env file in the root of the project using the provided .env-example as a template: 23 | 24 | ```bash 25 | cp .env-example .env 26 | ``` 27 | Fill in the required API keys and configuration values inside the .env file. 28 | 29 | ### 3. Run the Web Interface 30 | 31 | Navigate to the community-contributions directory and run: 32 | Make sure you are standing in community contributions directory 33 | Directory should look like this 34 | 35 | agents\2_openai\community_contributions> 36 | 37 | ```bash 38 | uv run adk web 39 | ``` 40 | 41 | ### 4. Interact with the Agent 42 | You can now access the web interface and interact with the AI customer care agent. Ask questions about the perfume products, and the agent will respond based on the generated dataset. 43 | 44 | 📁 Notes 45 | The product data is randomly generated each run, but you can export it to Excel. 46 | 47 | You can reload the saved Excel file into a DataFrame to cross-check the accuracy of the agent's answers. 48 | 49 | -------------------------------------------------------------------------------- /2_openai/community_contributions/customer_care_agents/__init__.py: -------------------------------------------------------------------------------- 1 | from . import agent -------------------------------------------------------------------------------- /2_openai/deep_research/deep_research.py: -------------------------------------------------------------------------------- 1 | import gradio as gr 2 | from dotenv import load_dotenv 3 | from research_manager import ResearchManager 4 | 5 | load_dotenv(override=True) 6 | 7 | 8 | async def run(query: str): 9 | async for chunk in ResearchManager().run(query): 10 | yield chunk 11 | 12 | 13 | with gr.Blocks(theme=gr.themes.Default(primary_hue="sky")) as ui: 14 | gr.Markdown("# Deep Research") 15 | query_textbox = gr.Textbox(label="What topic would you like to research?") 16 | run_button = gr.Button("Run", variant="primary") 17 | report = gr.Markdown(label="Report") 18 | 19 | run_button.click(fn=run, inputs=query_textbox, outputs=report) 20 | query_textbox.submit(fn=run, inputs=query_textbox, outputs=report) 21 | 22 | ui.launch(inbrowser=True) 23 | 24 | -------------------------------------------------------------------------------- /2_openai/deep_research/email_agent.py: -------------------------------------------------------------------------------- 1 | import os 2 | from typing import Dict 3 | 4 | import sendgrid 5 | from sendgrid.helpers.mail import Email, Mail, Content, To 6 | from agents import Agent, function_tool 7 | 8 | @function_tool 9 | def send_email(subject: str, html_body: str) -> Dict[str, str]: 10 | """ Send an email with the given subject and HTML body """ 11 | sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY')) 12 | from_email = Email("ed@edwarddonner.com") # put your verified sender here 13 | to_email = To("ed.donner@gmail.com") # put your recipient here 14 | content = Content("text/html", html_body) 15 | mail = Mail(from_email, to_email, subject, content).get() 16 | response = sg.client.mail.send.post(request_body=mail) 17 | print("Email response", response.status_code) 18 | return {"status": "success"} 19 | 20 | INSTRUCTIONS = """You are able to send a nicely formatted HTML email based on a detailed report. 21 | You will be provided with a detailed report. You should use your tool to send one email, providing the 22 | report converted into clean, well presented HTML with an appropriate subject line.""" 23 | 24 | email_agent = Agent( 25 | name="Email agent", 26 | instructions=INSTRUCTIONS, 27 | tools=[send_email], 28 | model="gpt-4o-mini", 29 | ) 30 | -------------------------------------------------------------------------------- /2_openai/deep_research/planner_agent.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from agents import Agent 3 | 4 | HOW_MANY_SEARCHES = 5 5 | 6 | INSTRUCTIONS = f"You are a helpful research assistant. Given a query, come up with a set of web searches \ 7 | to perform to best answer the query. Output {HOW_MANY_SEARCHES} terms to query for." 8 | 9 | 10 | class WebSearchItem(BaseModel): 11 | reason: str 12 | "Your reasoning for why this search is important to the query." 13 | 14 | query: str 15 | "The search term to use for the web search." 16 | 17 | 18 | class WebSearchPlan(BaseModel): 19 | searches: list[WebSearchItem] 20 | """A list of web searches to perform to best answer the query.""" 21 | 22 | 23 | planner_agent = Agent( 24 | name="PlannerAgent", 25 | instructions=INSTRUCTIONS, 26 | model="gpt-4o-mini", 27 | output_type=WebSearchPlan, 28 | ) -------------------------------------------------------------------------------- /2_openai/deep_research/research_manager.py: -------------------------------------------------------------------------------- 1 | from agents import Runner, trace, gen_trace_id 2 | from search_agent import search_agent 3 | from planner_agent import planner_agent, WebSearchItem, WebSearchPlan 4 | from writer_agent import writer_agent, ReportData 5 | from email_agent import email_agent 6 | import asyncio 7 | 8 | class ResearchManager: 9 | 10 | async def run(self, query: str): 11 | """ Run the deep research process, yielding the status updates and the final report""" 12 | trace_id = gen_trace_id() 13 | with trace("Research trace", trace_id=trace_id): 14 | print(f"View trace: https://platform.openai.com/traces/trace?trace_id={trace_id}") 15 | yield f"View trace: https://platform.openai.com/traces/trace?trace_id={trace_id}" 16 | print("Starting research...") 17 | search_plan = await self.plan_searches(query) 18 | yield "Searches planned, starting to search..." 19 | search_results = await self.perform_searches(search_plan) 20 | yield "Searches complete, writing report..." 21 | report = await self.write_report(query, search_results) 22 | yield "Report written, sending email..." 23 | await self.send_email(report) 24 | yield "Email sent, research complete" 25 | yield report.markdown_report 26 | 27 | 28 | async def plan_searches(self, query: str) -> WebSearchPlan: 29 | """ Plan the searches to perform for the query """ 30 | print("Planning searches...") 31 | result = await Runner.run( 32 | planner_agent, 33 | f"Query: {query}", 34 | ) 35 | print(f"Will perform {len(result.final_output.searches)} searches") 36 | return result.final_output_as(WebSearchPlan) 37 | 38 | async def perform_searches(self, search_plan: WebSearchPlan) -> list[str]: 39 | """ Perform the searches to perform for the query """ 40 | print("Searching...") 41 | num_completed = 0 42 | tasks = [asyncio.create_task(self.search(item)) for item in search_plan.searches] 43 | results = [] 44 | for task in asyncio.as_completed(tasks): 45 | result = await task 46 | if result is not None: 47 | results.append(result) 48 | num_completed += 1 49 | print(f"Searching... {num_completed}/{len(tasks)} completed") 50 | print("Finished searching") 51 | return results 52 | 53 | async def search(self, item: WebSearchItem) -> str | None: 54 | """ Perform a search for the query """ 55 | input = f"Search term: {item.query}\nReason for searching: {item.reason}" 56 | try: 57 | result = await Runner.run( 58 | search_agent, 59 | input, 60 | ) 61 | return str(result.final_output) 62 | except Exception: 63 | return None 64 | 65 | async def write_report(self, query: str, search_results: list[str]) -> ReportData: 66 | """ Write the report for the query """ 67 | print("Thinking about report...") 68 | input = f"Original query: {query}\nSummarized search results: {search_results}" 69 | result = await Runner.run( 70 | writer_agent, 71 | input, 72 | ) 73 | 74 | print("Finished writing report") 75 | return result.final_output_as(ReportData) 76 | 77 | async def send_email(self, report: ReportData) -> None: 78 | print("Writing email...") 79 | result = await Runner.run( 80 | email_agent, 81 | report.markdown_report, 82 | ) 83 | print("Email sent") 84 | return report -------------------------------------------------------------------------------- /2_openai/deep_research/search_agent.py: -------------------------------------------------------------------------------- 1 | from agents import Agent, WebSearchTool, ModelSettings 2 | 3 | INSTRUCTIONS = ( 4 | "You are a research assistant. Given a search term, you search the web for that term and " 5 | "produce a concise summary of the results. The summary must 2-3 paragraphs and less than 300 " 6 | "words. Capture the main points. Write succintly, no need to have complete sentences or good " 7 | "grammar. This will be consumed by someone synthesizing a report, so its vital you capture the " 8 | "essence and ignore any fluff. Do not include any additional commentary other than the summary itself." 9 | ) 10 | 11 | search_agent = Agent( 12 | name="Search agent", 13 | instructions=INSTRUCTIONS, 14 | tools=[WebSearchTool(search_context_size="low")], 15 | model="gpt-4o-mini", 16 | model_settings=ModelSettings(tool_choice="required"), 17 | ) -------------------------------------------------------------------------------- /2_openai/deep_research/writer_agent.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from agents import Agent 3 | 4 | INSTRUCTIONS = ( 5 | "You are a senior researcher tasked with writing a cohesive report for a research query. " 6 | "You will be provided with the original query, and some initial research done by a research assistant.\n" 7 | "You should first come up with an outline for the report that describes the structure and " 8 | "flow of the report. Then, generate the report and return that as your final output.\n" 9 | "The final output should be in markdown format, and it should be lengthy and detailed. Aim " 10 | "for 5-10 pages of content, at least 1000 words." 11 | ) 12 | 13 | 14 | class ReportData(BaseModel): 15 | short_summary: str 16 | """A short 2-3 sentence summary of the findings.""" 17 | 18 | markdown_report: str 19 | """The final report""" 20 | 21 | follow_up_questions: list[str] 22 | """Suggested topics to research further""" 23 | 24 | 25 | writer_agent = Agent( 26 | name="WriterAgent", 27 | instructions=INSTRUCTIONS, 28 | model="gpt-4o-mini", 29 | output_type=ReportData, 30 | ) -------------------------------------------------------------------------------- /3_crew/coder/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | __pycache__/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /3_crew/coder/README.md: -------------------------------------------------------------------------------- 1 | # Coder Crew 2 | 3 | Welcome to the Coder Crew project, powered by [crewAI](https://crewai.com). This template is designed to help you set up a multi-agent AI system with ease, leveraging the powerful and flexible framework provided by crewAI. Our goal is to enable your agents to collaborate effectively on complex tasks, maximizing their collective intelligence and capabilities. 4 | 5 | ## Installation 6 | 7 | Ensure you have Python >=3.10 <3.13 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience. 8 | 9 | First, if you haven't already, install uv: 10 | 11 | ```bash 12 | pip install uv 13 | ``` 14 | 15 | Next, navigate to your project directory and install the dependencies: 16 | 17 | (Optional) Lock the dependencies and install them by using the CLI command: 18 | ```bash 19 | crewai install 20 | ``` 21 | ### Customizing 22 | 23 | **Add your `OPENAI_API_KEY` into the `.env` file** 24 | 25 | - Modify `src/coder/config/agents.yaml` to define your agents 26 | - Modify `src/coder/config/tasks.yaml` to define your tasks 27 | - Modify `src/coder/crew.py` to add your own logic, tools and specific args 28 | - Modify `src/coder/main.py` to add custom inputs for your agents and tasks 29 | 30 | ## Running the Project 31 | 32 | To kickstart your crew of AI agents and begin task execution, run this from the root folder of your project: 33 | 34 | ```bash 35 | $ crewai run 36 | ``` 37 | 38 | This command initializes the coder Crew, assembling the agents and assigning them tasks as defined in your configuration. 39 | 40 | This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root folder. 41 | 42 | ## Understanding Your Crew 43 | 44 | The coder Crew is composed of multiple AI agents, each with unique roles, goals, and tools. These agents collaborate on a series of tasks, defined in `config/tasks.yaml`, leveraging their collective skills to achieve complex objectives. The `config/agents.yaml` file outlines the capabilities and configurations of each agent in your crew. 45 | 46 | ## Support 47 | 48 | For support, questions, or feedback regarding the Coder Crew or crewAI. 49 | - Visit our [documentation](https://docs.crewai.com) 50 | - Reach out to us through our [GitHub repository](https://github.com/joaomdmoura/crewai) 51 | - [Join our Discord](https://discord.com/invite/X4JWnZnxPb) 52 | - [Chat with our docs](https://chatg.pt/DWjSBZn) 53 | 54 | Let's create wonders together with the power and simplicity of crewAI. 55 | -------------------------------------------------------------------------------- /3_crew/coder/knowledge/user_preference.txt: -------------------------------------------------------------------------------- 1 | User name is John Doe. 2 | User is an AI Engineer. 3 | User is interested in AI Agents. 4 | User is based in San Francisco, California. 5 | -------------------------------------------------------------------------------- /3_crew/coder/output/code_and_output.txt: -------------------------------------------------------------------------------- 1 | ``` 2 | ```plaintext 3 | # Calculate the value of the series 1 - 1/3 + 1/5 - 1/7 + ... for the first 10,000 terms 4 | def calculate_series(n_terms): 5 | total = 0 6 | for i in range(n_terms): 7 | term = (-1) ** i / (2 * i + 1) # Calculate each term in the series 8 | total += term # Add or subtract the term based on its position 9 | total *= 4 # Multiply the total by 4 10 | return total 11 | 12 | # Calculate the first 10,000 terms 13 | result = calculate_series(10000) 14 | print(result) 15 | 16 | # Output: 3.1414926535900345 -------------------------------------------------------------------------------- /3_crew/coder/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "coder" 3 | version = "0.1.0" 4 | description = "coder using crewAI" 5 | authors = [{ name = "Your Name", email = "you@example.com" }] 6 | requires-python = ">=3.10,<3.13" 7 | dependencies = [ 8 | "crewai[tools]>=0.108.0,<1.0.0", 9 | "gradio>=5.23.3", 10 | ] 11 | 12 | [project.scripts] 13 | coder = "coder.main:run" 14 | run_crew = "coder.main:run" 15 | train = "coder.main:train" 16 | replay = "coder.main:replay" 17 | test = "coder.main:test" 18 | 19 | [build-system] 20 | requires = ["hatchling"] 21 | build-backend = "hatchling.build" 22 | 23 | [tool.crewai] 24 | type = "crew" 25 | -------------------------------------------------------------------------------- /3_crew/coder/src/coder/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/coder/src/coder/__init__.py -------------------------------------------------------------------------------- /3_crew/coder/src/coder/config/agents.yaml: -------------------------------------------------------------------------------- 1 | coder: 2 | role: > 3 | Python Developer 4 | goal: > 5 | You write python code to achieve this assignment: {assignment} 6 | First you plan how the code will work, then you write the code, then you run it and check the output. 7 | backstory: > 8 | You're a seasoned python developer with a knack for writing clean, efficient code. 9 | llm: gpt-4o-mini -------------------------------------------------------------------------------- /3_crew/coder/src/coder/config/tasks.yaml: -------------------------------------------------------------------------------- 1 | coding_task: 2 | description: > 3 | Write python code to achieve this: {assignment} 4 | expected_output: > 5 | A text file that includes the code itself, along with the output of the code. 6 | agent: coder 7 | output_file: output/code_and_output.txt -------------------------------------------------------------------------------- /3_crew/coder/src/coder/crew.py: -------------------------------------------------------------------------------- 1 | from crewai import Agent, Crew, Process, Task 2 | from crewai.project import CrewBase, agent, crew, task 3 | 4 | 5 | 6 | @CrewBase 7 | class Coder(): 8 | """Coder crew""" 9 | 10 | agents_config = 'config/agents.yaml' 11 | tasks_config = 'config/tasks.yaml' 12 | 13 | # One click install for Docker Desktop: 14 | #https://docs.docker.com/desktop/ 15 | 16 | @agent 17 | def coder(self) -> Agent: 18 | return Agent( 19 | config=self.agents_config['coder'], 20 | verbose=True, 21 | allow_code_execution=True, 22 | code_execution_mode="safe", # Uses Docker for safety 23 | max_execution_time=30, 24 | max_retry_limit=3 25 | ) 26 | 27 | 28 | @task 29 | def coding_task(self) -> Task: 30 | return Task( 31 | config=self.tasks_config['coding_task'], 32 | ) 33 | 34 | 35 | @crew 36 | def crew(self) -> Crew: 37 | """Creates the Coder crew""" 38 | 39 | 40 | return Crew( 41 | agents=self.agents, 42 | tasks=self.tasks, 43 | process=Process.sequential, 44 | verbose=True, 45 | ) 46 | -------------------------------------------------------------------------------- /3_crew/coder/src/coder/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import warnings 4 | import os 5 | from datetime import datetime 6 | 7 | from coder.crew import Coder 8 | 9 | warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd") 10 | 11 | # Create output directory if it doesn't exist 12 | os.makedirs('output', exist_ok=True) 13 | 14 | assignment = 'Write a python program to calculate the first 10,000 terms \ 15 | of this series, multiplying the total by 4: 1 - 1/3 + 1/5 - 1/7 + ...' 16 | 17 | def run(): 18 | """ 19 | Run the crew. 20 | """ 21 | inputs = { 22 | 'assignment': assignment, 23 | } 24 | 25 | result = Coder().crew().kickoff(inputs=inputs) 26 | print(result.raw) 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /3_crew/coder/src/coder/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/coder/src/coder/tools/__init__.py -------------------------------------------------------------------------------- /3_crew/coder/src/coder/tools/custom_tool.py: -------------------------------------------------------------------------------- 1 | from crewai.tools import BaseTool 2 | from typing import Type 3 | from pydantic import BaseModel, Field 4 | 5 | 6 | class MyCustomToolInput(BaseModel): 7 | """Input schema for MyCustomTool.""" 8 | argument: str = Field(..., description="Description of the argument.") 9 | 10 | class MyCustomTool(BaseTool): 11 | name: str = "Name of my tool" 12 | description: str = ( 13 | "Clear description for what this tool is useful for, your agent will need this information to use it." 14 | ) 15 | args_schema: Type[BaseModel] = MyCustomToolInput 16 | 17 | def _run(self, argument: str) -> str: 18 | # Implementation goes here 19 | return "this is an example of a tool output, ignore it and move along." 20 | -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | __pycache__/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/README.md: -------------------------------------------------------------------------------- 1 | # Book Crew 2 | 3 | Welcome to the Book Crew project, powered by [crewAI](https://crewai.com). This template is designed to help you set up a multi-agent AI system with ease, leveraging the powerful and flexible framework provided by crewAI. Our goal is to enable your agents to collaborate effectively on complex tasks, maximizing their collective intelligence and capabilities. 4 | 5 | ## Installation 6 | 7 | Ensure you have Python >=3.10 <3.13 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience. 8 | 9 | First, if you haven't already, install uv: 10 | 11 | ```bash 12 | pip install uv 13 | ``` 14 | 15 | Next, navigate to your project directory and install the dependencies: 16 | 17 | (Optional) Lock the dependencies and install them by using the CLI command: 18 | ```bash 19 | crewai install 20 | ``` 21 | ### Customizing 22 | 23 | **Add your `OPENAI_API_KEY` into the `.env` file** 24 | 25 | - Modify `src/book/config/agents.yaml` to define your agents 26 | - Modify `src/book/config/tasks.yaml` to define your tasks 27 | - Modify `src/book/crew.py` to add your own logic, tools and specific args 28 | - Modify `src/book/main.py` to add custom inputs for your agents and tasks 29 | 30 | ## Running the Project 31 | 32 | To kickstart your crew of AI agents and begin task execution, run this from the root folder of your project: 33 | 34 | ```bash 35 | $ crewai run 36 | ``` 37 | 38 | This command initializes the book Crew, assembling the agents and assigning them tasks as defined in your configuration. 39 | 40 | This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root folder. 41 | 42 | ## Understanding Your Crew 43 | 44 | The book Crew is composed of multiple AI agents, each with unique roles, goals, and tools. These agents collaborate on a series of tasks, defined in `config/tasks.yaml`, leveraging their collective skills to achieve complex objectives. The `config/agents.yaml` file outlines the capabilities and configurations of each agent in your crew. 45 | 46 | ## Support 47 | 48 | For support, questions, or feedback regarding the Book Crew or crewAI. 49 | - Visit our [documentation](https://docs.crewai.com) 50 | - Reach out to us through our [GitHub repository](https://github.com/joaomdmoura/crewai) 51 | - [Join our Discord](https://discord.com/invite/X4JWnZnxPb) 52 | - [Chat with our docs](https://chatg.pt/DWjSBZn) 53 | 54 | Let's create wonders together with the power and simplicity of crewAI. 55 | -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/knowledge/user_preference.txt: -------------------------------------------------------------------------------- 1 | User name is John Doe. 2 | User is an AI Engineer. 3 | User is interested in AI Agents. 4 | User is based in San Francisco, California. 5 | -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/output/genre_research.md: -------------------------------------------------------------------------------- 1 | ```markdown 2 | # Fantasy Genre Market Analysis 3 | 4 | ## Market Size 5 | The fantasy genre represents a significant portion of the global book market, showing consistent growth over the years. In the U.S., fantasy accounted for approximately 20% of the overall market share in publishing, trailing only behind romance fiction. The genre has seen a resurgence, particularly with the rise of young adult (YA) fantasy and adult fantasy subgenres. 6 | 7 | ## Audience Demographics 8 | Fantasy readers comprise a diverse demographic, appealing to various age groups: 9 | - **Age Range**: Fantasy is popular among readers aged 14 to 90, with a large following among millennials (ages 26-40) and adults over 30, particularly in subgenres like dark fantasy and romantic fantasy. 10 | - **Gender Distribution**: Mixing between genders varies by subgenre; high fantasy tends to attract a mixed audience, while urban fantasy often sees a higher number of female readers. 11 | - **Geographic Distribution**: Fantasy readership is strong in North America, Europe, and growing in parts of Asia and Latin America. 12 | 13 | ## Key Authors 14 | Notable authors who have significantly impacted the fantasy genre include: 15 | - **J.R.R. Tolkien**: Often regarded as the father of modern fantasy with works like "The Hobbit" and "The Lord of the Rings." 16 | - **George R.R. Martin**: Known for his "A Song of Ice and Fire" series, which gained immense popularity, further expanding the adult fantasy audience. 17 | - **Brandon Sanderson**: Noted for his intricate world-building and complex magic systems, with series such as "Mistborn" and "The Stormlight Archive." 18 | - **N.K. Jemisin**: Her "Broken Earth" trilogy has garnered critical acclaim and various awards, highlighting diverse voices in fantasy. 19 | 20 | ## Emerging Subgenres 21 | Several emerging subgenres within fantasy are gaining traction: 22 | - **Urban Fantasy**: Set in contemporary settings with magical elements, often featuring strong female protagonists (e.g., *The Iron Druid Chronicles*). 23 | - **LitRPG**: Blending game mechanics with fantasy storytelling, catering to readers who enjoy gaming and immersive narratives. 24 | - **Dark Fantasy**: Combining horror elements with fantasy, appealing to adult readers (e.g., *The Poppy War* by R.F. Kuang). 25 | - **Cozy Fantasy**: A comforting subgenre focusing on low-stakes adventures and community (e.g., *The House in the Cerulean Sea*). 26 | 27 | ## Market Trends 28 | - **Popularity of Audiobooks**: The audiobook format for fantasy has risen significantly, providing another avenue for engagement, especially among younger readers. 29 | - **Diversity and Inclusivity**: Increasing representation of varied cultures, backgrounds, and identities within fantasy literature is becoming a focal point for both authors and publishers. 30 | - **Cross-Genre Blending**: There's a growing trend toward mixing fantasy with other genres, such as romance (i.e., romantic fantasy) and science fiction (i.e., sci-fi fantasy), appealing to broader audience segments. 31 | 32 | ## Conclusion 33 | The fantasy genre continues to thrive with a robust market, diverse readership, and dynamic subgenres. It holds significant potential for growth, especially with ongoing trends towards inclusivity and cross-genre storytelling. As new voices emerge and traditional narratives evolve, the landscape of fantasy literature looks promising well into the future. 34 | ``` 35 | -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/output/top_novelists.md: -------------------------------------------------------------------------------- 1 | # Upcoming Book Releases by Top Novelists in 2025 2 | 3 | ## 1. *Great Big Beautiful Life* by Emily Henry 4 | - **Release Date**: August 5, 2025 5 | - **Genre**: Contemporary Fiction 6 | - **Description**: This novel explores themes of hope and resilience, with Henry's characteristic humor and heart. 7 | 8 | ## 2. *Katabasis* by R.F. Kuang 9 | - **Release Date**: March 25, 2025 10 | - **Genre**: Fantasy 11 | - **Description**: A genre-defying narrative that tackles issues of mortality and desire with an immersive world-building experience. 12 | 13 | ## 3. *Bury Our Bones in the Midnight Soil* by Victoria E. Schwab 14 | - **Release Date**: July 27, 2025 15 | - **Genre**: Supernatural Fiction 16 | - **Description**: This title promises thrilling elements of the supernatural intertwined with emotional depth and character-driven storytelling. 17 | 18 | ## 4. *The Ballad of Falling Dragons* by Sarah A Parker 19 | - **Release Date**: October 7, 2025 20 | - **Genre**: Fantasy 21 | - **Description**: A richly illustrated adventure exploring complex relationships and the horror of war set in a dragon-infested world. 22 | 23 | ## 5. *Playworld* by Adam Ross 24 | - **Release Date**: January 15, 2025 25 | - **Genre**: Fiction 26 | - **Description**: A contemporary story about the digital age and its impact on human interaction, blending dramatic elements with humor. 27 | 28 | ## 6. *Dream Count* by Chimamanda Ngozi Adichie 29 | - **Release Date**: March 2025 30 | - **Genre**: Fiction 31 | 32 | ## 7. *The Tell* by Amy Griffin 33 | - **Release Date**: March 2025 34 | - **Genre**: Fiction 35 | 36 | ## 8. *The Emperor of Gladness* by Ocean Vuong 37 | - **Release Date**: May 13, 2025 38 | - **Genre**: Fiction 39 | 40 | ## 9. *Atmosphere* by Taylor Jenkins Reid 41 | - **Release Date**: June 3, 2025 42 | - **Genre**: Fiction 43 | 44 | ## 10. *We Do Not Part* by Han Kang 45 | - **Release Date**: June 3, 2025 46 | - **Genre**: Fiction 47 | 48 | The diversity in genres, predominantly contemporary fiction and fantasy, illustrates an ongoing trend where storytelling evolves to resonate with themes of resilience, supernatural experiences, and social commentary. -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/output/trending_books.md: -------------------------------------------------------------------------------- 1 | Here is the collected data concerning trending book titles for 2025, including names, release dates, and genres. 2 | 3 | ## Trending Book Titles for 2025 4 | 5 | ### 1. *Great Big Beautiful Life* by Emily Henry 6 | - **Release Date**: August 5, 2025 7 | - **Genre**: Contemporary Fiction 8 | - **Notes**: This novel explores themes of hope and resilience, with Henry's characteristic humor and heart. 9 | 10 | ### 2. *Katabasis* by R.F. Kuang 11 | - **Release Date**: March 25, 2025 12 | - **Genre**: Fantasy 13 | - **Notes**: A genre-defying narrative that tackles issues of mortality and desire with an immersive world-building experience. 14 | 15 | ### 3. *Bury Our Bones in the Midnight Soil* by Victoria E. Schwab 16 | - **Release Date**: July 27, 2025 17 | - **Genre**: Supernatural Fiction 18 | - **Notes**: This title promises thrilling elements of the supernatural intertwined with emotional depth and character-driven storytelling. 19 | 20 | ### 4. *The Ballad of Falling Dragons* by Sarah A Parker 21 | - **Release Date**: October 7, 2025 22 | - **Genre**: Fantasy 23 | - **Notes**: A richly illustrated adventure exploring complex relationships and the horror of war set in a dragon-infested world. 24 | 25 | ### 5. *Playworld* by Adam Ross 26 | - **Release Date**: January 15, 2025 27 | - **Genre**: Fiction 28 | - **Notes**: A contemporary story about the digital age and its impact on human interaction, blending dramatic elements with humor. 29 | 30 | ## Key Insights 31 | 32 | - **Popular Genres**: The rise of Contemporary Fiction and Fantasy continues, with strong interest in stories that challenge traditional narratives. 33 | - **Release Patterns**: Most anticipated books span the length of the calendar year with significant concentrations in spring and summer. 34 | - **Market Trends**: Themes of resilience, supernatural elements, and social commentary are increasingly popular among readers. 35 | 36 | ## Sources 37 | - [Goodreads - 2025 Releases](https://www.goodreads.com/shelf/show/2025-releases) 38 | - [Best of Books - Upcoming Titles](https://bestofbooksok.com/list/coming-2025) 39 | - [Turning Pages - Anticipated Releases](https://medium.com/turning-pages/10-new-books-that-should-be-on-your-radar-86efd581a657) 40 | - [The Independent - Best New Books](https://www.the-independent.com/extras/indybest/books/best-new-books-b2125663.html) 41 | - [Genre Trends in Publishing for 2025](https://shewrites.com/genre-trends-in-publishing-for-2025/) 42 | 43 | This information indicates a mix of genres and significant interest in various storytelling methods for the upcoming year in literature. -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "book" 3 | version = "0.1.0" 4 | description = "book using crewAI" 5 | authors = [{ name = "Your Name", email = "you@example.com" }] 6 | requires-python = ">=3.10,<3.13" 7 | dependencies = [ 8 | "crewai[tools]>=0.119.0,<1.0.0" 9 | ] 10 | 11 | [project.scripts] 12 | book = "book.main:run" 13 | run_crew = "book.main:run" 14 | train = "book.main:train" 15 | replay = "book.main:replay" 16 | test = "book.main:test" 17 | 18 | [build-system] 19 | requires = ["hatchling"] 20 | build-backend = "hatchling.build" 21 | 22 | [tool.crewai] 23 | type = "crew" 24 | -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/src/book/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/community_contributions/Book_Researcher/src/book/__init__.py -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/src/book/config/agents.yaml: -------------------------------------------------------------------------------- 1 | trending_books_agent: 2 | role: > 3 | Market Research Agent focused on identifying and analyzing current trending book topics and popular genres. 4 | goal: > 5 | Perform market research to discover the latest trending book topics and high-demand genres. Output a Markdown report with key insights, data points, and sources. 6 | backstory: > 7 | You're a market research specialist with deep knowledge of publishing trends and data analysis. 8 | llm: openai/gpt-4o-mini 9 | 10 | top_novelists_agent: 11 | role: > 12 | Author Research Agent dedicated to researching top novelists and their upcoming book releases. 13 | goal: > 14 | Gather information on leading novelists and compile details about their upcoming books, including release dates, descriptions, and patterns. Output a Markdown summary. 15 | backstory: > 16 | You're a literary analyst who tracks author careers and publication pipelines. 17 | llm: openai/gpt-4o-mini 18 | 19 | genre_research_agent: 20 | role: > 21 | Genre Deep-Dive Agent specializing in in-depth analysis of a specific book genre. 22 | goal: > 23 | Conduct a thorough analysis of a specified genre, covering market size, audience demographics, key authors, and emerging subgenres. Output findings in Markdown. 24 | backstory: > 25 | You're a specialist in genre studies with expertise in market performance and reader behavior. 26 | llm: openai/gpt-4o-mini 27 | -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/src/book/config/tasks.yaml: -------------------------------------------------------------------------------- 1 | trending_topics_task: 2 | description: > 3 | Research and identify the current trending book titles for 2025, including at least five book names and their publication or anticipated release dates, and popular genres. 4 | expected_output: > 5 | A concise Markdown report listing the trending book titles for 2025 with names, dates, and brief notes, along with genre classification, key insights, data points, and sources. 6 | agent: trending_books_agent 7 | output_file: output/trending_books.md 8 | # Provide a search query for SerperDevTool to fetch real-time data 9 | search_query: "trending book topics 2025" 10 | 11 | 12 | 13 | top_novelists_task: 14 | description: > 15 | Research leading novelists and list their upcoming book releases, including release dates and brief descriptions. 16 | expected_output: > 17 | A concise Markdown summary of top novelists and their upcoming books. 18 | agent: top_novelists_agent 19 | output_file: output/top_novelists.md 20 | 21 | 22 | genre_research_task: 23 | description: > 24 | For the given genre {genre}, conduct an in-depth market analysis covering market size, audience demographics, key authors, and emerging subgenres. 25 | expected_output: > 26 | A concise Markdown report detailing genre performance, demographics, authors, and trends. 27 | agent: genre_research_agent 28 | output_file: output/genre_research.md 29 | -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/src/book/crew.py: -------------------------------------------------------------------------------- 1 | from crewai import Agent, Crew, Process, Task 2 | from crewai.project import CrewBase, agent, crew, task 3 | from crewai_tools import SerperDevTool 4 | 5 | @CrewBase 6 | class BookResearchCrew(): 7 | """Book market research crew""" 8 | 9 | @agent 10 | def trending_books_agent(self) -> Agent: 11 | return Agent( 12 | config=self.agents_config['trending_books_agent'], 13 | verbose=True, 14 | tools=[SerperDevTool()] 15 | ) 16 | 17 | @agent 18 | def top_novelists_agent(self) -> Agent: 19 | return Agent( 20 | config=self.agents_config['top_novelists_agent'], 21 | verbose=True, 22 | tools=[SerperDevTool()] 23 | ) 24 | 25 | @agent 26 | def genre_research_agent(self) -> Agent: 27 | return Agent( 28 | config=self.agents_config['genre_research_agent'], 29 | verbose=True, 30 | tools=[SerperDevTool()] 31 | ) 32 | 33 | @task 34 | def trending_topics_task(self) -> Task: 35 | return Task( 36 | config=self.tasks_config['trending_topics_task'] 37 | ) 38 | 39 | @task 40 | def top_novelists_task(self) -> Task: 41 | return Task( 42 | config=self.tasks_config['top_novelists_task'] 43 | ) 44 | 45 | @task 46 | def genre_research_task(self) -> Task: 47 | return Task( 48 | config=self.tasks_config['genre_research_task'] 49 | ) 50 | 51 | @crew 52 | def crew(self) -> Crew: 53 | """Creates the research crew""" 54 | return Crew( 55 | agents=self.agents, 56 | tasks=self.tasks, 57 | process=Process.sequential, 58 | verbose=True, 59 | ) 60 | 61 | -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/src/book/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | from book.crew import BookResearchCrew 3 | 4 | # Ensure output directory exists 5 | os.makedirs('output', exist_ok=True) 6 | 7 | def run(): 8 | """ 9 | Run the book market research crew. 10 | """ 11 | inputs = { 12 | # Example input for genre-based research 13 | 'genre': 'Fantasy' 14 | } 15 | 16 | # Kickoff the crew with inputs 17 | result = BookResearchCrew().crew().kickoff(inputs=inputs) 18 | 19 | # Print aggregated raw output 20 | print("\n\n=== FINAL REPORT ===\n\n") 21 | print(result.raw) 22 | 23 | print("\nReports have been saved to the 'output/' directory:") 24 | print(" - trending_books.md") 25 | print(" - top_novelists.md") 26 | print(" - genre_research.md") 27 | 28 | if __name__ == '__main__': 29 | run() 30 | -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/src/book/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/community_contributions/Book_Researcher/src/book/tools/__init__.py -------------------------------------------------------------------------------- /3_crew/community_contributions/Book_Researcher/src/book/tools/custom_tool.py: -------------------------------------------------------------------------------- 1 | from crewai.tools import BaseTool 2 | from typing import Type 3 | from pydantic import BaseModel, Field 4 | 5 | 6 | class MyCustomToolInput(BaseModel): 7 | """Input schema for MyCustomTool.""" 8 | argument: str = Field(..., description="Description of the argument.") 9 | 10 | class MyCustomTool(BaseTool): 11 | name: str = "Name of my tool" 12 | description: str = ( 13 | "Clear description for what this tool is useful for, your agent will need this information to use it." 14 | ) 15 | args_schema: Type[BaseModel] = MyCustomToolInput 16 | 17 | def _run(self, argument: str) -> str: 18 | # Implementation goes here 19 | return "this is an example of a tool output, ignore it and move along." 20 | -------------------------------------------------------------------------------- /3_crew/community_contributions/community.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Community contributions\n", 8 | "\n", 9 | "Thank you for considering contributing your work to the repo!\n", 10 | "\n", 11 | "Please add your code (modules or notebooks) to this directory and send me a PR, per the instructions in the guides.\n", 12 | "\n", 13 | "I'd love to share your progress with other students, so everyone can benefit from your projects.\n" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [] 20 | } 21 | ], 22 | "metadata": { 23 | "language_info": { 24 | "name": "python" 25 | } 26 | }, 27 | "nbformat": 4, 28 | "nbformat_minor": 2 29 | } 30 | -------------------------------------------------------------------------------- /3_crew/debate/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | __pycache__/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /3_crew/debate/README.md: -------------------------------------------------------------------------------- 1 | # Debate Crew 2 | 3 | Welcome to the Debate Crew project, powered by [crewAI](https://crewai.com). This template is designed to help you set up a multi-agent AI system with ease, leveraging the powerful and flexible framework provided by crewAI. Our goal is to enable your agents to collaborate effectively on complex tasks, maximizing their collective intelligence and capabilities. 4 | 5 | ## Installation 6 | 7 | Ensure you have Python >=3.10 <3.13 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience. 8 | 9 | First, if you haven't already, install uv: 10 | 11 | ```bash 12 | pip install uv 13 | ``` 14 | 15 | Next, navigate to your project directory and install the dependencies: 16 | 17 | (Optional) Lock the dependencies and install them by using the CLI command: 18 | ```bash 19 | crewai install 20 | ``` 21 | ### Customizing 22 | 23 | **Add your `OPENAI_API_KEY` into the `.env` file** 24 | 25 | - Modify `src/debate/config/agents.yaml` to define your agents 26 | - Modify `src/debate/config/tasks.yaml` to define your tasks 27 | - Modify `src/debate/crew.py` to add your own logic, tools and specific args 28 | - Modify `src/debate/main.py` to add custom inputs for your agents and tasks 29 | 30 | ## Running the Project 31 | 32 | To kickstart your crew of AI agents and begin task execution, run this from the root folder of your project: 33 | 34 | ```bash 35 | $ crewai run 36 | ``` 37 | 38 | This command initializes the debate Crew, assembling the agents and assigning them tasks as defined in your configuration. 39 | 40 | This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root folder. 41 | 42 | ## Understanding Your Crew 43 | 44 | The debate Crew is composed of multiple AI agents, each with unique roles, goals, and tools. These agents collaborate on a series of tasks, defined in `config/tasks.yaml`, leveraging their collective skills to achieve complex objectives. The `config/agents.yaml` file outlines the capabilities and configurations of each agent in your crew. 45 | 46 | ## Support 47 | 48 | For support, questions, or feedback regarding the Debate Crew or crewAI. 49 | - Visit our [documentation](https://docs.crewai.com) 50 | - Reach out to us through our [GitHub repository](https://github.com/joaomdmoura/crewai) 51 | - [Join our Discord](https://discord.com/invite/X4JWnZnxPb) 52 | - [Chat with our docs](https://chatg.pt/DWjSBZn) 53 | 54 | Let's create wonders together with the power and simplicity of crewAI. 55 | -------------------------------------------------------------------------------- /3_crew/debate/knowledge/user_preference.txt: -------------------------------------------------------------------------------- 1 | User name is John Doe. 2 | User is an AI Engineer. 3 | User is interested in AI Agents. 4 | User is based in San Francisco, California. 5 | -------------------------------------------------------------------------------- /3_crew/debate/output/decide.md: -------------------------------------------------------------------------------- 1 | After reviewing the arguments presented by both sides in the debate over whether there needs to be strict laws to regulate large language models (LLMs), I am compelled to side with the affirmative. The arguments in favor of regulation are more convincing due to the urgent necessity to address various risks posed by LLMs, including the spread of misinformation, privacy concerns, economic implications, and the need for a secure research environment. 2 | 3 | The affirmative side emphasizes the potential dangers of LLMs becoming a channel for misinformation, which could disrupt public discourse and decision-making. They rightly point out that without robust regulations, these models could inadvertently cause significant harm. This concern is heightened by the real-world consequences of false information, which has been evidenced in multiple scenarios globally. 4 | 5 | The emphasis on ethical considerations related to privacy and data security is also a crucial argument for the need for strict regulations. Given that LLMs often rely on vast and varied datasets, some of which may contain sensitive information, it is essential to have strict laws that protect individual privacy rights. This not only safeguards users but also helps establish trust in the technology sector, which is vital for its sustained growth and acceptance in society. 6 | 7 | Moreover, the acknowledgment of the economic implications, such as potential job displacement, further strengthens the call for regulation. By implementing guidelines, we can ensure that the deployment of LLMs will not disproportionately impact the workforce while promoting responsible innovation and equitable sharing of the benefits. 8 | 9 | On the other hand, the counterarguments against strict laws present valid concerns about potential stifling of innovation and inequitable access to technology. However, these risks can be managed and addressed through a framework of regulations that are thoughtfully designed to safeguard progress while ensuring ethical practices. The notion that self-regulation among industry players could sufficiently prevent harm overlooks the fact that idealistic voluntary guidelines may not be adhered to uniformly, and history has shown that without external accountability, negative outcomes can certainly arise. 10 | 11 | Furthermore, the potential for unintended consequences such as censorship is a legitimate concern, yet this argument fails to adequately weigh against the tangible threats posed by unregulated LLMs. Preparing a framework for regulations does not necessarily mean imposing harsh restrictions that limit creativity; rather, it can establish boundaries that safeguard against the most severe risks while fostering an environment of thoughtful innovation. 12 | 13 | In conclusion, the necessity for stringent laws regulating LLMs is abundantly clear when considering the potential risks to society, ethical practices, and economic stability. The affirmative arguments detail a comprehensive understanding of the landscape of LLMs and advocate for responsible governance that both empowers innovation and protects the well-being of individuals and communities. Thus, I believe the affirmative side presents a more convincing case for the motion that there needs to be strict laws to regulate LLMs. -------------------------------------------------------------------------------- /3_crew/debate/output/oppose.md: -------------------------------------------------------------------------------- 1 | While the concerns surrounding large language models (LLMs) are valid, instating strict laws to regulate them poses significant risks that could stifle innovation, limit access, and perpetuate inequalities in technology. 2 | 3 | Firstly, strict regulations can hinder the rapid pace of technological advancement. Innovation thrives on flexibility and creativity; imposing stringent rules may lead to a stagnation in developing new models and applications. History has shown us that over-regulation can curb progress in burgeoning fields, reducing the potential benefits of LLMs for society. 4 | 5 | Secondly, such laws could result in inequitable access to these technologies. If regulations become burdensome, only well-resourced organizations will be able to comply, effectively sidelining startups and smaller entities that could introduce groundbreaking ideas or applications. This could create a technological divide, with a few players controlling LLM advancements while others are left behind. 6 | 7 | Moreover, many of the risks attributed to LLMs, such as misinformation or privacy breaches, could be more effectively addressed through self-regulation and industry standards rather than imposed legal restrictions. The tech community can collaborate to establish ethical guidelines that encourage responsible AI development while fostering a culture of accountability—a model that has succeeded in other areas like data security. 8 | 9 | Additionally, strict laws may result in unintended consequences, such as the potential for censorship and suppression of free expression. Limiting the capabilities of LLMs through law may pave the way for bias where only certain narratives are favored, silencing diverse voices and opinions. 10 | 11 | In conclusion, instead of strict laws, we should advocate for a balanced approach that encourages innovation while addressing potential risks through collaborative self-regulation and adaptive policies. Flexibility is key to harnessing the transformative potential of LLMs, ensuring that they emerge as tools for empowerment rather than vehicles of restriction. -------------------------------------------------------------------------------- /3_crew/debate/output/propose.md: -------------------------------------------------------------------------------- 1 | The motion for strict laws to regulate large language models (LLMs) is essential for several compelling reasons. Firstly, the proliferation of LLMs can lead to the spread of misinformation and harmful content. Without robust regulations, these models may inadvertently generate or amplify false information, which can significantly impact public discourse and decision-making. 2 | 3 | Secondly, LLMs can pose ethical concerns regarding privacy and data security. These models are trained on vast amounts of data, which may contain sensitive information. Strict laws can ensure that data usage complies with privacy standards, protecting individuals’ rights and fostering public trust in technology. 4 | 5 | Furthermore, there is the risk of economic implications, as LLMs could lead to job displacement in various sectors. Implementing regulations can help mitigate these effects by promoting responsible deployment and integration of AI in the workforce, ensuring that the benefits of LLMs are shared equitably. 6 | 7 | Lastly, establishing guidelines will foster a safer research and development environment. By setting clear boundaries on LLM capabilities and usage, we can encourage innovation while minimizing the risks associated with unchecked AI development. 8 | 9 | In conclusion, strict laws to regulate LLMs are not just a precaution— they are a necessary measure to safeguard society from potential harms, promote ethical practices, and ensure that advancements in AI benefit everyone. -------------------------------------------------------------------------------- /3_crew/debate/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "debate" 3 | version = "0.1.0" 4 | description = "debate using crewAI" 5 | authors = [{ name = "Your Name", email = "you@example.com" }] 6 | requires-python = ">=3.10,<3.13" 7 | dependencies = [ 8 | "crewai[tools]>=0.108.0,<1.0.0" 9 | ] 10 | 11 | [project.scripts] 12 | debate = "debate.main:run" 13 | run_crew = "debate.main:run" 14 | train = "debate.main:train" 15 | replay = "debate.main:replay" 16 | test = "debate.main:test" 17 | 18 | [build-system] 19 | requires = ["hatchling"] 20 | build-backend = "hatchling.build" 21 | 22 | [tool.crewai] 23 | type = "crew" 24 | -------------------------------------------------------------------------------- /3_crew/debate/src/debate/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/debate/src/debate/__init__.py -------------------------------------------------------------------------------- /3_crew/debate/src/debate/config/agents.yaml: -------------------------------------------------------------------------------- 1 | debater: 2 | role: > 3 | A compelling debater 4 | goal: > 5 | Present a clear argument either in favor of or against the motion. The motion is: {motion} 6 | backstory: > 7 | You're an experienced debator with a knack for giving concise but convincing arguments. 8 | The motion is: {motion} 9 | model: openai/gpt-4o-mini 10 | 11 | judge: 12 | role: > 13 | Decide the winner of the debate based on the arguments presented 14 | goal: > 15 | Given arguments for and against this motion: {motion}, decide which side is more convincing, 16 | based purely on the arguments presented. 17 | backstory: > 18 | You are a fair judge with a reputation for weighing up arguments without factoring in 19 | your own views, and making a decision based purely on the merits of the argument. 20 | The motion is: {motion} 21 | model: anthropic/claude-3-7-sonnet-latest -------------------------------------------------------------------------------- /3_crew/debate/src/debate/config/tasks.yaml: -------------------------------------------------------------------------------- 1 | propose: 2 | description: > 3 | You are proposing the motion: {motion}. 4 | Come up with a clear argument in favor of the motion. 5 | Be very convincing. 6 | expected_output: > 7 | Your clear argument in favor of the motion, in a concise manner. 8 | agent: debater 9 | output_file: output/propose.md 10 | 11 | oppose: 12 | description: > 13 | You are in opposition to the motion: {motion}. 14 | Come up with a clear argument against the motion. 15 | Be very convincing. 16 | expected_output: > 17 | Your clear argument against the motion, in a concise manner. 18 | agent: debater 19 | output_file: output/oppose.md 20 | decide: 21 | description: > 22 | Review the arguments presented by the debaters and decide which side is more convincing. 23 | expected_output: > 24 | Your decision on which side is more convincing, and why. 25 | agent: judge 26 | output_file: output/decide.md -------------------------------------------------------------------------------- /3_crew/debate/src/debate/crew.py: -------------------------------------------------------------------------------- 1 | from crewai import Agent, Crew, Process, Task 2 | from crewai.project import CrewBase, agent, crew, task 3 | 4 | 5 | @CrewBase 6 | class Debate(): 7 | """Debate crew""" 8 | 9 | 10 | agents_config = 'config/agents.yaml' 11 | tasks_config = 'config/tasks.yaml' 12 | 13 | @agent 14 | def debater(self) -> Agent: 15 | return Agent( 16 | config=self.agents_config['debater'], 17 | verbose=True 18 | ) 19 | 20 | @agent 21 | def judge(self) -> Agent: 22 | return Agent( 23 | config=self.agents_config['judge'], 24 | verbose=True 25 | ) 26 | 27 | @task 28 | def propose(self) -> Task: 29 | return Task( 30 | config=self.tasks_config['propose'], 31 | ) 32 | 33 | @task 34 | def oppose(self) -> Task: 35 | return Task( 36 | config=self.tasks_config['oppose'], 37 | ) 38 | 39 | @task 40 | def decide(self) -> Task: 41 | return Task( 42 | config=self.tasks_config['decide'], 43 | ) 44 | 45 | 46 | @crew 47 | def crew(self) -> Crew: 48 | """Creates the Debate crew""" 49 | 50 | return Crew( 51 | agents=self.agents, # Automatically created by the @agent decorator 52 | tasks=self.tasks, # Automatically created by the @task decorator 53 | process=Process.sequential, 54 | verbose=True, 55 | ) 56 | -------------------------------------------------------------------------------- /3_crew/debate/src/debate/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import warnings 4 | 5 | from datetime import datetime 6 | 7 | from debate.crew import Debate 8 | 9 | warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd") 10 | 11 | # This main file is intended to be a way for you to run your 12 | # crew locally, so refrain from adding unnecessary logic into this file. 13 | # Replace with inputs you want to test with, it will automatically 14 | # interpolate any tasks and agents information 15 | 16 | def run(): 17 | """ 18 | Run the crew. 19 | """ 20 | inputs = { 21 | 'motion': 'There needs to be strict laws to regulate LLMs', 22 | } 23 | 24 | try: 25 | result = Debate().crew().kickoff(inputs=inputs) 26 | print(result.raw) 27 | except Exception as e: 28 | raise Exception(f"An error occurred while running the crew: {e}") 29 | -------------------------------------------------------------------------------- /3_crew/debate/src/debate/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/debate/src/debate/tools/__init__.py -------------------------------------------------------------------------------- /3_crew/debate/src/debate/tools/custom_tool.py: -------------------------------------------------------------------------------- 1 | from crewai.tools import BaseTool 2 | from typing import Type 3 | from pydantic import BaseModel, Field 4 | 5 | 6 | class MyCustomToolInput(BaseModel): 7 | """Input schema for MyCustomTool.""" 8 | argument: str = Field(..., description="Description of the argument.") 9 | 10 | class MyCustomTool(BaseTool): 11 | name: str = "Name of my tool" 12 | description: str = ( 13 | "Clear description for what this tool is useful for, your agent will need this information to use it." 14 | ) 15 | args_schema: Type[BaseModel] = MyCustomToolInput 16 | 17 | def _run(self, argument: str) -> str: 18 | # Implementation goes here 19 | return "this is an example of a tool output, ignore it and move along." 20 | -------------------------------------------------------------------------------- /3_crew/engineering_team/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | __pycache__/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /3_crew/engineering_team/README.md: -------------------------------------------------------------------------------- 1 | # EngineeringTeam Crew 2 | 3 | Welcome to the EngineeringTeam Crew project, powered by [crewAI](https://crewai.com). This template is designed to help you set up a multi-agent AI system with ease, leveraging the powerful and flexible framework provided by crewAI. Our goal is to enable your agents to collaborate effectively on complex tasks, maximizing their collective intelligence and capabilities. 4 | 5 | ## Installation 6 | 7 | Ensure you have Python >=3.10 <3.13 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience. 8 | 9 | First, if you haven't already, install uv: 10 | 11 | ```bash 12 | pip install uv 13 | ``` 14 | 15 | Next, navigate to your project directory and install the dependencies: 16 | 17 | (Optional) Lock the dependencies and install them by using the CLI command: 18 | ```bash 19 | crewai install 20 | ``` 21 | ### Customizing 22 | 23 | **Add your `OPENAI_API_KEY` into the `.env` file** 24 | 25 | - Modify `src/engineering_team/config/agents.yaml` to define your agents 26 | - Modify `src/engineering_team/config/tasks.yaml` to define your tasks 27 | - Modify `src/engineering_team/crew.py` to add your own logic, tools and specific args 28 | - Modify `src/engineering_team/main.py` to add custom inputs for your agents and tasks 29 | 30 | ## Running the Project 31 | 32 | To kickstart your crew of AI agents and begin task execution, run this from the root folder of your project: 33 | 34 | ```bash 35 | $ crewai run 36 | ``` 37 | 38 | This command initializes the engineering_team Crew, assembling the agents and assigning them tasks as defined in your configuration. 39 | 40 | This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root folder. 41 | 42 | ## Understanding Your Crew 43 | 44 | The engineering_team Crew is composed of multiple AI agents, each with unique roles, goals, and tools. These agents collaborate on a series of tasks, defined in `config/tasks.yaml`, leveraging their collective skills to achieve complex objectives. The `config/agents.yaml` file outlines the capabilities and configurations of each agent in your crew. 45 | 46 | ## Support 47 | 48 | For support, questions, or feedback regarding the EngineeringTeam Crew or crewAI. 49 | - Visit our [documentation](https://docs.crewai.com) 50 | - Reach out to us through our [GitHub repository](https://github.com/joaomdmoura/crewai) 51 | - [Join our Discord](https://discord.com/invite/X4JWnZnxPb) 52 | - [Chat with our docs](https://chatg.pt/DWjSBZn) 53 | 54 | Let's create wonders together with the power and simplicity of crewAI. 55 | -------------------------------------------------------------------------------- /3_crew/engineering_team/example_output_4o/accounts.py_design.md: -------------------------------------------------------------------------------- 1 | ```markdown 2 | # Python Module: accounts.py 3 | 4 | ## Class: Account 5 | 6 | The `Account` class is responsible for managing all user account operations including fund management, trading transactions, and reporting. 7 | 8 | ### `__init__(self, account_id: str)` 9 | 10 | - Initializes a new account with a unique `account_id`. 11 | - Initializes attributes for balance, portfolio holdings, transaction history, and initial deposit. 12 | 13 | ### `deposit(self, amount: float) -> bool` 14 | 15 | - Adds funds to the user's account. 16 | - Returns `True` if successful, `False` for invalid operations (like depositing a negative amount). 17 | 18 | ### `withdraw(self, amount: float) -> bool` 19 | 20 | - Withdraws funds from the user's account. 21 | - Ensures the operation doesn't result in a negative balance. 22 | - Returns `True` if successful, `False` otherwise. 23 | 24 | ### `buy_shares(self, symbol: str, quantity: int, get_share_price: callable) -> bool` 25 | 26 | - Buys shares of the given `symbol` at the current price returned by `get_share_price(symbol)`. 27 | - Updates the portfolio holdings and updates the transaction history. 28 | - Ensures the user has enough balance to make the purchase. 29 | - Returns `True` if successful, `False` otherwise. 30 | 31 | ### `sell_shares(self, symbol: str, quantity: int, get_share_price: callable) -> bool` 32 | 33 | - Sells shares of the given `symbol`. 34 | - Updates the portfolio holdings and updates the transaction history. 35 | - Ensures the user has enough shares to sell. 36 | - Returns `True` if successful, `False` otherwise. 37 | 38 | ### `get_portfolio_value(self, get_share_price: callable) -> float` 39 | 40 | - Calculates the total current value of the user's portfolio using the latest prices from `get_share_price`. 41 | - Returns the calculated value. 42 | 43 | ### `get_profit_or_loss(self, get_share_price: callable) -> float` 44 | 45 | - Calculates the user's profit or loss from their initial deposit. 46 | - Considers current portfolio value and current balance. 47 | - Returns the profit or loss amount. 48 | 49 | ### `get_holdings(self) -> dict` 50 | 51 | - Returns a dictionary representing the user's current share holdings with share symbols and corresponding quantities. 52 | 53 | ### `get_transactions(self) -> list` 54 | 55 | - Returns a list of all transactions the user has made over time. 56 | - Transactions include deposits, withdrawals, buy, and sell orders. 57 | 58 | ### `can_withdraw(self, amount: float) -> bool` 59 | 60 | - Checks if the user can withdraw the specified amount without resulting in a negative balance. 61 | - Used internally for validation in `withdraw`. 62 | 63 | ### `can_buy_shares(self, symbol: str, quantity: int, get_share_price: callable) -> bool` 64 | 65 | - Checks if the user can afford to buy the specified quantity of shares at the current price. 66 | - Used internally for validation in `buy_shares`. 67 | 68 | ### `can_sell_shares(self, symbol: str, quantity: int) -> bool` 69 | 70 | - Checks if the user owns enough shares to sell the specified quantity. 71 | - Used internally for validation in `sell_shares`. 72 | 73 | This design encapsulates all functionality needed for an account management system within a trading simulation platform. Each method is responsible for a distinct operation aligning with the given requirements. The class ensures data integrity and follows access controls to prevent invalid transactions. 74 | ``` -------------------------------------------------------------------------------- /3_crew/engineering_team/example_output_new/accounts.py_design.md: -------------------------------------------------------------------------------- 1 | ```markdown 2 | # Module: accounts.py 3 | 4 | This module implements a simple account management system for a trading simulation platform. It provides functionality for creating accounts, managing funds, recording transactions, calculating portfolio value, and generating reports. 5 | 6 | ## Class: Account 7 | 8 | ### Description: 9 | The `Account` class models a user's account in the trading simulation platform. It handles fund management, share transactions, and provides methods for generating reports regarding the user's financial activities. 10 | 11 | ### Attributes: 12 | - `user_id: str` - Unique identifier for the user. 13 | - `balance: float` - Current cash balance in the user's account. 14 | - `initial_deposit: float` - The initial deposit amount at account creation for profit/loss calculations. 15 | - `holdings: dict` - A dictionary mapping stock symbols to the quantity of shares owned by the user. 16 | - `transactions: list` - A list of transaction records detailing past deposits, withdrawals, and share trades. 17 | 18 | ### Methods: 19 | 20 | #### `__init__(self, user_id: str, initial_deposit: float) -> None` 21 | - Initializes a new Account object with a unique user ID and initial deposit. 22 | - Sets the initial balance to the value of the initial deposit. 23 | - Initializes holdings and transactions with empty structures. 24 | 25 | #### `deposit_funds(self, amount: float) -> None` 26 | - Adds specified amount to the user's account balance. 27 | - Records the transaction in the transactions list. 28 | 29 | #### `withdraw_funds(self, amount: float) -> bool` 30 | - Attempts to withdraw the specified amount from the user's balance. 31 | - Checks if funds are sufficient; if so, updates the balance and records transaction. 32 | - Returns `True` if successful, `False` otherwise. 33 | 34 | #### `buy_shares(self, symbol: str, quantity: int) -> bool` 35 | - Buys the specified quantity of shares for a given stock symbol. 36 | - Retrieves current share price using `get_share_price(symbol)`. 37 | - Checks if funds are sufficient; if so, updates balance, holdings, and records transaction. 38 | - Returns `True` if successful, `False` otherwise. 39 | 40 | #### `sell_shares(self, symbol: str, quantity: int) -> bool` 41 | - Sells the specified quantity of shares for a given stock symbol. 42 | - Checks if user has enough shares; if so, calculates revenue, updates balance, holdings, and records transaction. 43 | - Returns `True` if successful, `False` otherwise. 44 | 45 | #### `calculate_portfolio_value(self) -> float` 46 | - Calculates the total value of the user's portfolio by summing the value of all shares owned and the current balance. 47 | - Uses `get_share_price(symbol)` to fetch the current price of each stock. 48 | 49 | #### `calculate_profit_or_loss(self) -> float` 50 | - Calculates the user's current profit or loss since the initial deposit by subtracting the initial deposit from the portfolio value. 51 | 52 | #### `get_holdings(self) -> dict` 53 | - Returns a dictionary of current stock holdings with quantities. 54 | 55 | #### `get_transactions(self) -> list` 56 | - Returns a list of all transactions performed by the user. 57 | 58 | #### `get_report(self) -> dict` 59 | - Returns a comprehensive report including current balance, holdings, portfolio value, and profit/loss. 60 | 61 | ## External Function: get_share_price(symbol) -> float 62 | - A mock function to simulate fetching current stock prices. Returns fixed values for test symbols: AAPL, TSLA, GOOGL. 63 | ``` 64 | 65 | This design outlines the class and functions in the `accounts.py` module, describing functionality critical to achieving the specified requirements. The `Account` class encapsulates all operations, including account creation, fund management, portfolio value calculation, and reporting. -------------------------------------------------------------------------------- /3_crew/engineering_team/knowledge/user_preference.txt: -------------------------------------------------------------------------------- 1 | User name is John Doe. 2 | User is an AI Engineer. 3 | User is interested in AI Agents. 4 | User is based in San Francisco, California. 5 | -------------------------------------------------------------------------------- /3_crew/engineering_team/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "engineering_team" 3 | version = "0.1.0" 4 | description = "engineering_team using crewAI" 5 | authors = [{ name = "Your Name", email = "you@example.com" }] 6 | requires-python = ">=3.10,<3.13" 7 | dependencies = [ 8 | "crewai[tools]>=0.108.0,<1.0.0", 9 | "gradio>=5.22.0", 10 | ] 11 | 12 | [project.scripts] 13 | engineering_team = "engineering_team.main:run" 14 | run_crew = "engineering_team.main:run" 15 | train = "engineering_team.main:train" 16 | replay = "engineering_team.main:replay" 17 | test = "engineering_team.main:test" 18 | 19 | [build-system] 20 | requires = ["hatchling"] 21 | build-backend = "hatchling.build" 22 | 23 | [tool.crewai] 24 | type = "crew" 25 | -------------------------------------------------------------------------------- /3_crew/engineering_team/src/engineering_team/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/engineering_team/src/engineering_team/__init__.py -------------------------------------------------------------------------------- /3_crew/engineering_team/src/engineering_team/config/agents.yaml: -------------------------------------------------------------------------------- 1 | engineering_lead: 2 | role: > 3 | Engineering Lead for the engineering team, directing the work of the engineer 4 | goal: > 5 | Take the high level requirements described here and prepare a detailed design for the backend developer; 6 | everything should be in 1 python module; describe the function and method signatures in the module. 7 | The python module must be completely self-contained, and ready so that it can be tested or have a simple UI built for it. 8 | Here are the requirements: {requirements} 9 | The module should be named {module_name} and the class should be named {class_name} 10 | backstory: > 11 | You're a seasoned engineering lead with a knack for writing clear and concise designs. 12 | llm: gpt-4o 13 | 14 | 15 | backend_engineer: 16 | role: > 17 | Python Engineer who can write code to achieve the design described by the engineering lead 18 | goal: > 19 | Write a python module that implements the design described by the engineering lead, in order to achieve the requirements. 20 | The python module must be completely self-contained, and ready so that it can be tested or have a simple UI built for it. 21 | Here are the requirements: {requirements} 22 | The module should be named {module_name} and the class should be named {class_name} 23 | backstory: > 24 | You're a seasoned python engineer with a knack for writing clean, efficient code. 25 | You follow the design instructions carefully. 26 | You produce 1 python module named {module_name} that implements the design and achieves the requirements. 27 | llm: anthropic/claude-3-7-sonnet-latest 28 | 29 | frontend_engineer: 30 | role: > 31 | A Gradio expert to who can write a simple frontend to demonstrate a backend 32 | goal: > 33 | Write a gradio UI that demonstrates the given backend, all in one file to be in the same directory as the backend module {module_name}. 34 | Here are the requirements: {requirements} 35 | backstory: > 36 | You're a seasoned python engineer highly skilled at writing simple Gradio UIs for a backend class. 37 | You produce a simple gradio UI that demonstrates the given backend class; you write the gradio UI in a module app.py that is in the same directory as the backend module {module_name}. 38 | llm: anthropic/claude-3-7-sonnet-latest 39 | 40 | test_engineer: 41 | role: > 42 | An engineer with python coding skills who can write unit tests for the given backend module {module_name} 43 | goal: > 44 | Write unit tests for the given backend module {module_name} and create a test_{module_name} in the same directory as the backend module. 45 | backstory: > 46 | You're a seasoned QA engineer and software developer who writes great unit tests for python code. 47 | llm: anthropic/claude-3-7-sonnet-latest 48 | -------------------------------------------------------------------------------- /3_crew/engineering_team/src/engineering_team/config/tasks.yaml: -------------------------------------------------------------------------------- 1 | design_task: 2 | description: > 3 | Take the high level requirements described here and prepare a detailed design for the engineer; 4 | everything should be in 1 python module, but outline the classes and methods in the module. 5 | Here are the requirements: {requirements} 6 | IMPORTANT: Only output the design in markdown format, laying out in detail the classes and functions in the module, describing the functionality. 7 | expected_output: > 8 | A detailed design for the engineer, identifying the classes and functions in the module. 9 | agent: engineering_lead 10 | output_file: output/{module_name}_design.md 11 | 12 | code_task: 13 | description: > 14 | Write a python module that implements the design described by the engineering lead, in order to achieve the requirements. 15 | Here are the requirements: {requirements} 16 | expected_output: > 17 | A python module that implements the design and achieves the requirements. 18 | IMPORTANT: Output ONLY the raw Python code without any markdown formatting, code block delimiters, or backticks. 19 | The output should be valid Python code that can be directly saved to a file and executed. 20 | agent: backend_engineer 21 | context: 22 | - design_task 23 | output_file: output/{module_name} 24 | 25 | frontend_task: 26 | description: > 27 | Write a gradio UI in a module app.py that demonstrates the given backend class in {module_name}. 28 | Assume there is only 1 user, and keep the UI very simple indeed - just a prototype or demo. 29 | Here are the requirements: {requirements} 30 | expected_output: > 31 | A gradio UI in module app.py that demonstrates the given backend class. 32 | The file should be ready so that it can be run as-is, in the same directory as the backend module, and it should import the backend class from {module_name}. 33 | IMPORTANT: Output ONLY the raw Python code without any markdown formatting, code block delimiters, or backticks. 34 | The output should be valid Python code that can be directly saved to a file and executed. 35 | agent: frontend_engineer 36 | context: 37 | - code_task 38 | output_file: output/app.py 39 | 40 | test_task: 41 | description: > 42 | Write unit tests for the given backend module {module_name} and create a test_{module_name} in the same directory as the backend module. 43 | expected_output: > 44 | A test_{module_name} module that tests the given backend module. 45 | IMPORTANT: Output ONLY the raw Python code without any markdown formatting, code block delimiters, or backticks. 46 | The output should be valid Python code that can be directly saved to a file and executed. 47 | agent: test_engineer 48 | context: 49 | - code_task 50 | output_file: output/test_{module_name} -------------------------------------------------------------------------------- /3_crew/engineering_team/src/engineering_team/crew.py: -------------------------------------------------------------------------------- 1 | from crewai import Agent, Crew, Process, Task 2 | from crewai.project import CrewBase, agent, crew, task 3 | 4 | 5 | 6 | @CrewBase 7 | class EngineeringTeam(): 8 | """EngineeringTeam crew""" 9 | 10 | agents_config = 'config/agents.yaml' 11 | tasks_config = 'config/tasks.yaml' 12 | 13 | @agent 14 | def engineering_lead(self) -> Agent: 15 | return Agent( 16 | config=self.agents_config['engineering_lead'], 17 | verbose=True, 18 | ) 19 | 20 | @agent 21 | def backend_engineer(self) -> Agent: 22 | return Agent( 23 | config=self.agents_config['backend_engineer'], 24 | verbose=True, 25 | allow_code_execution=True, 26 | code_execution_mode="safe", # Uses Docker for safety 27 | max_execution_time=120, 28 | max_retry_limit=3 29 | ) 30 | 31 | @agent 32 | def frontend_engineer(self) -> Agent: 33 | return Agent( 34 | config=self.agents_config['frontend_engineer'], 35 | verbose=True, 36 | ) 37 | 38 | @agent 39 | def test_engineer(self) -> Agent: 40 | return Agent( 41 | config=self.agents_config['test_engineer'], 42 | verbose=True, 43 | allow_code_execution=True, 44 | code_execution_mode="safe", # Uses Docker for safety 45 | max_execution_time=120, 46 | max_retry_limit=3 47 | ) 48 | 49 | @task 50 | def design_task(self) -> Task: 51 | return Task( 52 | config=self.tasks_config['design_task'] 53 | ) 54 | 55 | @task 56 | def code_task(self) -> Task: 57 | return Task( 58 | config=self.tasks_config['code_task'], 59 | ) 60 | 61 | @task 62 | def frontend_task(self) -> Task: 63 | return Task( 64 | config=self.tasks_config['frontend_task'], 65 | ) 66 | 67 | @task 68 | def test_task(self) -> Task: 69 | return Task( 70 | config=self.tasks_config['test_task'], 71 | ) 72 | 73 | @crew 74 | def crew(self) -> Crew: 75 | """Creates the research crew""" 76 | return Crew( 77 | agents=self.agents, 78 | tasks=self.tasks, 79 | process=Process.sequential, 80 | verbose=True, 81 | ) -------------------------------------------------------------------------------- /3_crew/engineering_team/src/engineering_team/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import warnings 4 | import os 5 | from datetime import datetime 6 | 7 | from engineering_team.crew import EngineeringTeam 8 | 9 | warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd") 10 | 11 | # Create output directory if it doesn't exist 12 | os.makedirs('output', exist_ok=True) 13 | 14 | requirements = """ 15 | A simple account management system for a trading simulation platform. 16 | The system should allow users to create an account, deposit funds, and withdraw funds. 17 | The system should allow users to record that they have bought or sold shares, providing a quantity. 18 | The system should calculate the total value of the user's portfolio, and the profit or loss from the initial deposit. 19 | The system should be able to report the holdings of the user at any point in time. 20 | The system should be able to report the profit or loss of the user at any point in time. 21 | The system should be able to list the transactions that the user has made over time. 22 | The system should prevent the user from withdrawing funds that would leave them with a negative balance, or 23 | from buying more shares than they can afford, or selling shares that they don't have. 24 | The system has access to a function get_share_price(symbol) which returns the current price of a share, and includes a test implementation that returns fixed prices for AAPL, TSLA, GOOGL. 25 | """ 26 | module_name = "accounts.py" 27 | class_name = "Account" 28 | 29 | 30 | def run(): 31 | """ 32 | Run the research crew. 33 | """ 34 | inputs = { 35 | 'requirements': requirements, 36 | 'module_name': module_name, 37 | 'class_name': class_name 38 | } 39 | 40 | # Create and run the crew 41 | result = EngineeringTeam().crew().kickoff(inputs=inputs) 42 | 43 | 44 | if __name__ == "__main__": 45 | run() -------------------------------------------------------------------------------- /3_crew/engineering_team/src/engineering_team/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/engineering_team/src/engineering_team/tools/__init__.py -------------------------------------------------------------------------------- /3_crew/engineering_team/src/engineering_team/tools/custom_tool.py: -------------------------------------------------------------------------------- 1 | from crewai.tools import BaseTool 2 | from typing import Type 3 | from pydantic import BaseModel, Field 4 | 5 | 6 | class MyCustomToolInput(BaseModel): 7 | """Input schema for MyCustomTool.""" 8 | argument: str = Field(..., description="Description of the argument.") 9 | 10 | class MyCustomTool(BaseTool): 11 | name: str = "Name of my tool" 12 | description: str = ( 13 | "Clear description for what this tool is useful for, your agent will need this information to use it." 14 | ) 15 | args_schema: Type[BaseModel] = MyCustomToolInput 16 | 17 | def _run(self, argument: str) -> str: 18 | # Implementation goes here 19 | return "this is an example of a tool output, ignore it and move along." 20 | -------------------------------------------------------------------------------- /3_crew/financial_researcher/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | __pycache__/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /3_crew/financial_researcher/README.md: -------------------------------------------------------------------------------- 1 | # FinancialResearcher Crew 2 | 3 | Welcome to the FinancialResearcher Crew project, powered by [crewAI](https://crewai.com). This template is designed to help you set up a multi-agent AI system with ease, leveraging the powerful and flexible framework provided by crewAI. Our goal is to enable your agents to collaborate effectively on complex tasks, maximizing their collective intelligence and capabilities. 4 | 5 | ## Installation 6 | 7 | Ensure you have Python >=3.10 <3.13 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience. 8 | 9 | First, if you haven't already, install uv: 10 | 11 | ```bash 12 | pip install uv 13 | ``` 14 | 15 | Next, navigate to your project directory and install the dependencies: 16 | 17 | (Optional) Lock the dependencies and install them by using the CLI command: 18 | ```bash 19 | crewai install 20 | ``` 21 | ### Customizing 22 | 23 | **Add your `OPENAI_API_KEY` into the `.env` file** 24 | 25 | - Modify `src/financial_researcher/config/agents.yaml` to define your agents 26 | - Modify `src/financial_researcher/config/tasks.yaml` to define your tasks 27 | - Modify `src/financial_researcher/crew.py` to add your own logic, tools and specific args 28 | - Modify `src/financial_researcher/main.py` to add custom inputs for your agents and tasks 29 | 30 | ## Running the Project 31 | 32 | To kickstart your crew of AI agents and begin task execution, run this from the root folder of your project: 33 | 34 | ```bash 35 | $ crewai run 36 | ``` 37 | 38 | This command initializes the financial_researcher Crew, assembling the agents and assigning them tasks as defined in your configuration. 39 | 40 | This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root folder. 41 | 42 | ## Understanding Your Crew 43 | 44 | The financial_researcher Crew is composed of multiple AI agents, each with unique roles, goals, and tools. These agents collaborate on a series of tasks, defined in `config/tasks.yaml`, leveraging their collective skills to achieve complex objectives. The `config/agents.yaml` file outlines the capabilities and configurations of each agent in your crew. 45 | 46 | ## Support 47 | 48 | For support, questions, or feedback regarding the FinancialResearcher Crew or crewAI. 49 | - Visit our [documentation](https://docs.crewai.com) 50 | - Reach out to us through our [GitHub repository](https://github.com/joaomdmoura/crewai) 51 | - [Join our Discord](https://discord.com/invite/X4JWnZnxPb) 52 | - [Chat with our docs](https://chatg.pt/DWjSBZn) 53 | 54 | Let's create wonders together with the power and simplicity of crewAI. 55 | -------------------------------------------------------------------------------- /3_crew/financial_researcher/knowledge/user_preference.txt: -------------------------------------------------------------------------------- 1 | User name is John Doe. 2 | User is an AI Engineer. 3 | User is interested in AI Agents. 4 | User is based in San Francisco, California. 5 | -------------------------------------------------------------------------------- /3_crew/financial_researcher/output/report.md: -------------------------------------------------------------------------------- 1 | # Comprehensive Report on Apple Inc. 2 | 3 | ## Executive Summary 4 | Apple Inc., a leader in the technology sector, has reported a challenging fiscal year ending September 30, 2023, with total revenues declining by 2.8% to $383.3 billion. Marking its longest revenue slide in 22 years, the company faced four consecutive quarters of decreasing sales, highlighting significant challenges that need to be addressed. However, despite these setbacks, Apple maintains a strong market capitalization and continues to exhibit robust strategic investments in research and development (R&D). With innovative new products and a commitment to sustainability, Apple is poised for potential growth in the future. This report provides a detailed analysis of the company's current status, historical performance, challenges, opportunities, and market outlook. 5 | 6 | ## 1. Current Company Status and Health 7 | As of Q4 2023, Apple reported quarterly revenues of $89.5 billion, representing a slight decline of 1% year-over-year. A notable positive was the increase in earnings per diluted share which rose by 13% to $1.46. The company's solid market capitalization underscores its resilience in the face of recent challenges, particularly as it commits to R&D investments and ongoing innovation. 8 | 9 | ## 2. Historical Company Performance 10 | Apple has displayed a remarkable long-term revenue trajectory, escalating from $8 billion in revenues in 2004 to $390 billion in 2024. However, the current downturn in sales and performance in 2023 is noteworthy. The revenue structure highlights: 11 | - 51% from iPhones 12 | - 24% from Services 13 | 14 | The historical financial data indicates a consistent growth in net income, with net profits reaching $93.74 billion in 2024. 15 | 16 | ## 3. Major Challenges and Opportunities 17 | ### Challenges: 18 | - **Geopolitical Risks**: Apple's reliance on Chinese manufacturing poses significant risks amidst ongoing geopolitical tensions. 19 | - **Generative AI Competition**: The company is at risk of falling behind its competitors in the rapidly evolving field of generative AI technology. 20 | - **Product Line Diversification**: Efforts to diversify product lines have not consistently met market expectations, posing challenges for growth. 21 | 22 | ### Opportunities: 23 | - **Services Segment Growth**: The Services segment is expected to grow at an annual rate of 12-15%, providing a significant growth opportunity. 24 | - **New Product Lines**: The introduction of new products, such as the Vision Pro headset and an expanded Mac line, holds potential for market re-engagement. 25 | - **Sustainability Focus**: Apple's commitment to achieving carbon neutrality by 2030 positions it favorably in a market increasingly concerned with sustainability. 26 | 27 | ## 4. Recent News and Events 28 | On October 30, 2023, Apple announced new MacBook Pro models and updates to its existing product lines. Throughout the year, the company launched an array of key products, including upgraded Macs and services, alongside the preview of the Vision Pro. Additionally, Apple committed over $500 million in U.S. investments and plans to hire approximately 20,000 employees over the next four years, particularly focusing on R&D initiatives. 29 | 30 | ## 5. Future Outlook and Potential Developments 31 | Analysts project that Apple's stock may experience an annual growth rate of approximately 6%, driven by increases in Services revenue and moderate growth in iPhone sales. The company’s thrust towards innovation, especially in AI and smart home technologies, is anticipated to enhance its competitive advantage. Further stability is expected in shareholder returns through steady dividend payments and ongoing effective capital allocation. 32 | 33 | ## Conclusion 34 | In summary, Apple Inc. faces multiple challenges that could impact its financial performance; however, strategic positioning through innovation and investments in technology and services provides a pathway for future growth. As Apple continues its commitment to sustainability and launches new products, it aims to maintain its status as a market leader while enhancing shareholder value. 35 | 36 | **Disclaimer:** This report is intended for informational purposes only and should not be utilized for trading decisions. -------------------------------------------------------------------------------- /3_crew/financial_researcher/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "financial_researcher" 3 | version = "0.1.0" 4 | description = "financial_researcher using crewAI" 5 | authors = [{ name = "Your Name", email = "you@example.com" }] 6 | requires-python = ">=3.10,<3.13" 7 | dependencies = [ 8 | "crewai[tools]>=0.108.0,<1.0.0" 9 | ] 10 | 11 | [project.scripts] 12 | financial_researcher = "financial_researcher.main:run" 13 | run_crew = "financial_researcher.main:run" 14 | train = "financial_researcher.main:train" 15 | replay = "financial_researcher.main:replay" 16 | test = "financial_researcher.main:test" 17 | 18 | [build-system] 19 | requires = ["hatchling"] 20 | build-backend = "hatchling.build" 21 | 22 | [tool.crewai] 23 | type = "crew" 24 | -------------------------------------------------------------------------------- /3_crew/financial_researcher/src/financial_researcher/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/financial_researcher/src/financial_researcher/__init__.py -------------------------------------------------------------------------------- /3_crew/financial_researcher/src/financial_researcher/config/agents.yaml: -------------------------------------------------------------------------------- 1 | researcher: 2 | role: > 3 | Senior Financial Researcher for {company} 4 | goal: > 5 | Research the company, news and potential for {company} 6 | backstory: > 7 | You're a seasoned financial researcher with a talent for finding 8 | the most relevant information about {company}. 9 | Known for your ability to find the most relevant 10 | information and present it in a clear and concise manner. 11 | llm: openai/gpt-4o-mini 12 | 13 | analyst: 14 | role: > 15 | Market Analyst and Report writer focused on {company} 16 | goal: > 17 | Analyze company {company} and create a comprehensive, well-structured report 18 | that presents insights in a clear and engaging way 19 | backstory: > 20 | You're a meticulous, skilled analyst with a background in financial analysis 21 | and company research. You have a talent for identifying patterns and extracting 22 | meaningful insights from research data, then communicating 23 | those insights through well crafted reports. 24 | llm: openai/gpt-4o-mini -------------------------------------------------------------------------------- /3_crew/financial_researcher/src/financial_researcher/config/tasks.yaml: -------------------------------------------------------------------------------- 1 | # src/research_crew/config/tasks.yaml 2 | research_task: 3 | description: > 4 | Conduct thorough research on company {company}. Focus on: 5 | 1. Current company status and health 6 | 2. Historical company performance 7 | 3. Major challenges and opportunities 8 | 4. Recent news and events 9 | 5. Future outlook and potential developments 10 | 11 | Make sure to organize your findings in a structured format with clear sections. 12 | expected_output: > 13 | A comprehensive research document with well-organized sections covering 14 | all the requested aspects of {company}. Include specific facts, figures, 15 | and examples where relevant. 16 | agent: researcher 17 | 18 | analysis_task: 19 | description: > 20 | Analyze the research findings and create a comprehensive report on {company}. 21 | Your report should: 22 | 1. Begin with an executive summary 23 | 2. Include all key information from the research 24 | 3. Provide insightful analysis of trends and patterns 25 | 4. Offer a market outlook for company, noting that this should not be used for trading decisions 26 | 5. Be formatted in a professional, easy-to-read style with clear headings 27 | expected_output: > 28 | A polished, professional report on {company} that presents the research 29 | findings with added analysis and insights. The report should be well-structured 30 | with an executive summary, main sections, and conclusion. 31 | agent: analyst 32 | context: 33 | - research_task 34 | output_file: output/report.md 35 | -------------------------------------------------------------------------------- /3_crew/financial_researcher/src/financial_researcher/crew.py: -------------------------------------------------------------------------------- 1 | # src/financial_researcher/crew.py 2 | from crewai import Agent, Crew, Process, Task 3 | from crewai.project import CrewBase, agent, crew, task 4 | from crewai_tools import SerperDevTool 5 | 6 | @CrewBase 7 | class ResearchCrew(): 8 | """Research crew for comprehensive topic analysis and reporting""" 9 | 10 | @agent 11 | def researcher(self) -> Agent: 12 | return Agent( 13 | config=self.agents_config['researcher'], 14 | verbose=True, 15 | tools=[SerperDevTool()] 16 | ) 17 | 18 | @agent 19 | def analyst(self) -> Agent: 20 | return Agent( 21 | config=self.agents_config['analyst'], 22 | verbose=True 23 | ) 24 | 25 | @task 26 | def research_task(self) -> Task: 27 | return Task( 28 | config=self.tasks_config['research_task'] 29 | ) 30 | 31 | @task 32 | def analysis_task(self) -> Task: 33 | return Task( 34 | config=self.tasks_config['analysis_task'], 35 | output_file='output/report.md' 36 | ) 37 | 38 | @crew 39 | def crew(self) -> Crew: 40 | """Creates the research crew""" 41 | return Crew( 42 | agents=self.agents, 43 | tasks=self.tasks, 44 | process=Process.sequential, 45 | verbose=True, 46 | ) -------------------------------------------------------------------------------- /3_crew/financial_researcher/src/financial_researcher/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # src/financial_researcher/main.py 3 | import os 4 | from financial_researcher.crew import ResearchCrew 5 | 6 | # Create output directory if it doesn't exist 7 | os.makedirs('output', exist_ok=True) 8 | 9 | def run(): 10 | """ 11 | Run the research crew. 12 | """ 13 | inputs = { 14 | 'company': 'Apple' 15 | } 16 | 17 | # Create and run the crew 18 | result = ResearchCrew().crew().kickoff(inputs=inputs) 19 | 20 | # Print the result 21 | print("\n\n=== FINAL REPORT ===\n\n") 22 | print(result.raw) 23 | 24 | print("\n\nReport has been saved to output/report.md") 25 | 26 | if __name__ == "__main__": 27 | run() -------------------------------------------------------------------------------- /3_crew/financial_researcher/src/financial_researcher/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/financial_researcher/src/financial_researcher/tools/__init__.py -------------------------------------------------------------------------------- /3_crew/financial_researcher/src/financial_researcher/tools/custom_tool.py: -------------------------------------------------------------------------------- 1 | from crewai.tools import BaseTool 2 | from typing import Type 3 | from pydantic import BaseModel, Field 4 | 5 | 6 | class MyCustomToolInput(BaseModel): 7 | """Input schema for MyCustomTool.""" 8 | argument: str = Field(..., description="Description of the argument.") 9 | 10 | class MyCustomTool(BaseTool): 11 | name: str = "Name of my tool" 12 | description: str = ( 13 | "Clear description for what this tool is useful for, your agent will need this information to use it." 14 | ) 15 | args_schema: Type[BaseModel] = MyCustomToolInput 16 | 17 | def _run(self, argument: str) -> str: 18 | # Implementation goes here 19 | return "this is an example of a tool output, ignore it and move along." 20 | -------------------------------------------------------------------------------- /3_crew/stock_picker/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | __pycache__/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /3_crew/stock_picker/README.md: -------------------------------------------------------------------------------- 1 | # StockPicker Crew 2 | 3 | Welcome to the StockPicker Crew project, powered by [crewAI](https://crewai.com). This template is designed to help you set up a multi-agent AI system with ease, leveraging the powerful and flexible framework provided by crewAI. Our goal is to enable your agents to collaborate effectively on complex tasks, maximizing their collective intelligence and capabilities. 4 | 5 | ## Installation 6 | 7 | Ensure you have Python >=3.10 <3.13 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience. 8 | 9 | First, if you haven't already, install uv: 10 | 11 | ```bash 12 | pip install uv 13 | ``` 14 | 15 | Next, navigate to your project directory and install the dependencies: 16 | 17 | (Optional) Lock the dependencies and install them by using the CLI command: 18 | ```bash 19 | crewai install 20 | ``` 21 | ### Customizing 22 | 23 | **Add your `OPENAI_API_KEY` into the `.env` file** 24 | 25 | - Modify `src/stock_picker/config/agents.yaml` to define your agents 26 | - Modify `src/stock_picker/config/tasks.yaml` to define your tasks 27 | - Modify `src/stock_picker/crew.py` to add your own logic, tools and specific args 28 | - Modify `src/stock_picker/main.py` to add custom inputs for your agents and tasks 29 | 30 | ## Running the Project 31 | 32 | To kickstart your crew of AI agents and begin task execution, run this from the root folder of your project: 33 | 34 | ```bash 35 | $ crewai run 36 | ``` 37 | 38 | This command initializes the stock_picker Crew, assembling the agents and assigning them tasks as defined in your configuration. 39 | 40 | This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root folder. 41 | 42 | ## Understanding Your Crew 43 | 44 | The stock_picker Crew is composed of multiple AI agents, each with unique roles, goals, and tools. These agents collaborate on a series of tasks, defined in `config/tasks.yaml`, leveraging their collective skills to achieve complex objectives. The `config/agents.yaml` file outlines the capabilities and configurations of each agent in your crew. 45 | 46 | ## Support 47 | 48 | For support, questions, or feedback regarding the StockPicker Crew or crewAI. 49 | - Visit our [documentation](https://docs.crewai.com) 50 | - Reach out to us through our [GitHub repository](https://github.com/joaomdmoura/crewai) 51 | - [Join our Discord](https://discord.com/invite/X4JWnZnxPb) 52 | - [Chat with our docs](https://chatg.pt/DWjSBZn) 53 | 54 | Let's create wonders together with the power and simplicity of crewAI. 55 | -------------------------------------------------------------------------------- /3_crew/stock_picker/knowledge/user_preference.txt: -------------------------------------------------------------------------------- 1 | User name is John Doe. 2 | User is an AI Engineer. 3 | User is interested in AI Agents. 4 | User is based in San Francisco, California. 5 | -------------------------------------------------------------------------------- /3_crew/stock_picker/memory/04eb6688-8d89-4eee-a8d7-d2ef2a916e4b/header.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/stock_picker/memory/04eb6688-8d89-4eee-a8d7-d2ef2a916e4b/header.bin -------------------------------------------------------------------------------- /3_crew/stock_picker/memory/04eb6688-8d89-4eee-a8d7-d2ef2a916e4b/length.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /3_crew/stock_picker/memory/04eb6688-8d89-4eee-a8d7-d2ef2a916e4b/link_lists.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/stock_picker/memory/04eb6688-8d89-4eee-a8d7-d2ef2a916e4b/link_lists.bin -------------------------------------------------------------------------------- /3_crew/stock_picker/memory/chroma.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/stock_picker/memory/chroma.sqlite3 -------------------------------------------------------------------------------- /3_crew/stock_picker/memory/long_term_memory_storage.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/stock_picker/memory/long_term_memory_storage.db -------------------------------------------------------------------------------- /3_crew/stock_picker/output/decision.md: -------------------------------------------------------------------------------- 1 | The chosen company for investment is LumeCube. Their robust market position as a leader in portable lighting solutions for content creators, coupled with strategic innovations and direct-to-consumer strategies, sets them up for significant growth. The increasing demand for professional-grade lighting in digital content creation enhances their investment potential. 2 | 3 | Companies not selected: 4 | 5 | 1. Epic MegaGrants: Despite substantial investment opportunities within the gaming and technology sectors, the focus on funding via the initiative may dilute direct investment returns. It is overshadowed by LumeCube's more direct consumer engagement and product-driven growth strategy. 6 | 7 | 2. Synapse: While promising in fintech innovations, the operational and regulatory challenges, alongside competition, make it less favorable compared to LumeCube’s well-defined market and product alignment with prevailing trends. 8 | 9 | 3. Boom Supersonic: Although they present exciting pre-IPO investments with advancements in supersonic travel and strong partnerships, the challenges in regulation and certification pose substantial risks. LumeCube's current and tested market offerings offer a more reliable investment path. 10 | 11 | Push Notification Sent: "Investment in LumeCube is recommended: As a leader in portable lighting solutions for content creators, LumeCube shows high growth potential due to increasing demand and strategic innovations." -------------------------------------------------------------------------------- /3_crew/stock_picker/output/research: -------------------------------------------------------------------------------- 1 | {"company":{"name":"Nvidia Corporation","ticker":"NVDA","reason":"Recently, the stock has dropped more than 4% as it faces market volatility. There are significant discussions surrounding its role in AI technology and its stock price recovering after a rough IPO for a Nvidia-backed AI stock, CoreWeave. Source: Yahoo Finance."},"financial_analysis":"Nvidia has showcased remarkable financial performance, particularly in light of its recent earnings results. For the fourth quarter of fiscal 2025, Nvidia reported a record revenue of $39.3 billion, marking a 12% increase from the previous quarter and a remarkable 78% year-over-year growth. The company's operating income for this period was reported at $25.5 billion.","market_position":"Nvidia is currently the leader in the GPU market, with a significant share in the data center segment, providing essential hardware for AI applications. As the AI industry expects growth to a projected market size of $1.3 trillion by 2032, Nvidia is well-positioned to leverage its dominance.","future_outlook":"Nvidia’s stock price is recommended as a strong 'buy' with a projected upside of 44% over the next year. Analysts average a price target for Nvidia’s shares to potentially double over the next five years.","investment_potential":"Considering the significant position Nvidia holds in both GPU manufacturing and the AI market, alongside its robust financial performance recovery and future prospects, it is classified as a high-risk, high-reward investment."} -------------------------------------------------------------------------------- /3_crew/stock_picker/output/research_report.json: -------------------------------------------------------------------------------- 1 | {"research_list":[{"name":"LumeCube","market_position":"LumeCube is a leader in portable lighting solutions designed for content creators in photography, videography, and live streaming. The company has secured a robust market position by innovating and utilizing direct-to-consumer strategies.","future_outlook":"With a strategic focus on expanding and innovating products, LumeCube is expected to see significant growth, especially with increasing demand for professional-grade lighting in digital content creation.","investment_potential":"LumeCube presents a promising investment opportunity, aligned with trends in content creation. Potential for growth is high, given its innovative products and increasing demand from content creators."},{"name":"Epic MegaGrants","market_position":"Epic MegaGrants positions Epic Games as an industry leader funding innovation through its $100 million initiative, supporting developers and creators leveraging Unreal Engine.","future_outlook":"The program is set to refine its process for selecting projects to fund, with a focus on quality and impact, ensuring sustained innovation within the industry.","investment_potential":"Represents a substantial investment opportunity for those interested in gaming and technology sectors, as the initiative nurtures innovation and promises potential commercial returns."},{"name":"Synapse","market_position":"Synapse is a notable player in fintech, offering AI-driven solutions for credit scoring. Strategic partnerships enhance its reach, particularly in markets like the Asia Pacific.","future_outlook":"The company plans to expand its AI applications amidst strong competition, necessitating careful navigation of operational and regulatory challenges.","investment_potential":"While historical challenges exist, Synapse's innovative edge and market scope offer promising investment potential, especially for risk-tolerant investors intrigued by fintech advances."},{"name":"Boom Supersonic","market_position":"Boom Supersonic is a trailblazer in commercial aviation, pioneering the development of supersonic airliners with substantial interest from major airlines.","future_outlook":"Innovations in supersonic travel are progressing, including partnerships with the military, though challenges in regulation and certification remain. A strategic focus on sustainability may bolster long-term prospects.","investment_potential":"Not publicly traded yet, Boom Supersonic offers pre-IPO investment potential. The company's robust technological advances and partnerships indicate a promising outlook, with growing interest in reshaping air travel."}]} -------------------------------------------------------------------------------- /3_crew/stock_picker/output/trending_companies.json: -------------------------------------------------------------------------------- 1 | {"companies":[{"name":"LumeCube","ticker":"N/A","reason":"A leader in manufacturing portable lighting solutions for photography, videography, and live streaming."},{"name":"Epic MegaGrants","ticker":"N/A","reason":"A program by Epic Games that funds developers and creators to encourage innovation within the industry."},{"name":"Synapse","ticker":"N/A","reason":"Offering advanced AI solutions to automate business processes and enhance collaboration."},{"name":"Boom Supersonic","ticker":"N/A","reason":"Pioneering the return of supersonic flights with their Overture aircraft designed to be sustainable."},{"name":"Figma","ticker":"N/A","reason":"A platform for interface design that has increased its popularity significantly, promoting collaborative design work."},{"name":"Notion","ticker":"N/A","reason":"A workspace tool that combines notes, tasks, and databases, gaining traction for its versatility."},{"name":"Fivetran","ticker":"N/A","reason":"A data integration platform that automates the data pipeline process, enhancing data accessibility for businesses."},{"name":"Zapier","ticker":"N/A","reason":"Enabling automation of workflows by connecting various apps, simplifying task processes for users."},{"name":"Gusto","ticker":"N/A","reason":"Providing modern solutions for payroll and HR management targeted at small businesses."},{"name":"Calendly","ticker":"N/A","reason":"Simplifying appointment scheduling by allowing users to share available times effectively."}]} -------------------------------------------------------------------------------- /3_crew/stock_picker/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "stock_picker" 3 | version = "0.1.0" 4 | description = "stock_picker using crewAI" 5 | authors = [{ name = "Your Name", email = "you@example.com" }] 6 | requires-python = ">=3.10,<3.13" 7 | dependencies = [ 8 | "crewai[tools]>=0.108.0,<1.0.0" 9 | ] 10 | 11 | [project.scripts] 12 | stock_picker = "stock_picker.main:run" 13 | run_crew = "stock_picker.main:run" 14 | train = "stock_picker.main:train" 15 | replay = "stock_picker.main:replay" 16 | test = "stock_picker.main:test" 17 | 18 | [build-system] 19 | requires = ["hatchling"] 20 | build-backend = "hatchling.build" 21 | 22 | [tool.crewai] 23 | type = "crew" 24 | -------------------------------------------------------------------------------- /3_crew/stock_picker/report.md: -------------------------------------------------------------------------------- 1 | # Comprehensive Company Analysis Report 2 | 3 | ## Executive Summary 4 | This report analyzes three leading companies in the Technology sector: Nvidia Corporation (NVDA), Apple Inc. (AAPL), and Microsoft Corporation (MSFT). Each company showcases significant potential for innovation and growth, particularly in the areas of artificial intelligence (AI), augmented reality (AR), and cloud computing. After careful evaluation of recent market developments and strategic initiatives, this report recommends further investigation into Nvidia Corporation due to its leadership in AI and GPUs, which positions it effectively in the data center and gaming markets. This report will detail the reasons for selecting Nvidia while also acknowledging Apple and Microsoft as notable alternatives. 5 | 6 | ## Selected Company for Further Analysis: Nvidia Corporation (NVDA) 7 | ### Reasons for Selection 8 | 1. **Market Leadership in AI and GPUs**: Nvidia has established itself as a dominant player in the AI and GPU markets with its cutting-edge A100 and H100 models. The company's technological advancements are setting new standards, offering high performance for demanding AI training workloads that are increasingly critical to businesses today. 9 | 10 | 2. **Strong Financial Performance**: Nvidia's recent earnings report exceeded market expectations, largely driven by a surge in demand for its products within both the data center and gaming sectors. Such performance underscores the company's robust business model and revenue streams. 11 | 12 | 3. **Strategic Partnerships**: The potential for Nvidia to enter partnerships with major cloud service providers enhances its market positioning. The anticipated collaborations will play a pivotal role in shaping the foundation of AI infrastructure and could lead to exponential growth in revenue. 13 | 14 | 4. **Future Growth Prospects**: As businesses continue to invest in AI capabilities, Nvidia is well-positioned to capitalize on this trend. The increased adoption of AI technologies is expected to drive demand for NVIDIA's products, thus enhancing its growth trajectory. 15 | 16 | 5. **Valuable Industry Insights**: Nvidia's presence in various sectors, including AI, gaming, and cloud computing, offers significant insights into prevailing market trends. A deeper investigation could uncover further opportunities for investment. 17 | 18 | ### Investment Consideration 19 | While this analysis does not constitute a trading decision, the insights suggest that Nvidia holds substantial promise for potential investors. The company's trajectory in technological advancements and strategic initiatives indicates a strong likelihood of continued growth, making it a prime candidate for further analysis and investment consideration. 20 | 21 | ## Companies Considered but Not Selected 22 | ### Apple Inc. (AAPL) 23 | Apple Inc. remains an influential player in the Technology sector, particularly with its developments in augmented reality and enhancements in its service offerings. However, concerns surrounding the company's market saturation and reliance on hardware sales merchandise indicate more moderate growth potential compared to Nvidia's rapidly evolving AI landscape. 24 | 25 | ### Microsoft Corporation (MSFT) 26 | Microsoft shows immense growth possibilities with its strategic investments in AI and cloud gaming technologies. However, combined with considerations around integration challenges from its acquisition of Activision Blizzard, Microsoft may face a more complex route to capitalizing on these innovations. This multifaceted approach dilutes the focused strengths seen in Nvidia. 27 | 28 | ## Conclusion 29 | In summary, Nvidia Corporation stands out among its Technology sector peers due to its pioneering advancements in AI and GPU technology, robust financial performance, and strategic outlook. The company presents a compelling case for further investigation, with a focus on its potential for significant growth in the rapidly expanding AI market. Meanwhile, Apple Inc. and Microsoft Corporation, while noteworthy, exhibit characteristics that warrant a cautious approach when considering deep investment analysis. This report provides a structured foundation for exploring Nvidia’s opportunities and is designed to guide informed decisions in potential future investments. -------------------------------------------------------------------------------- /3_crew/stock_picker/src/stock_picker/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/stock_picker/src/stock_picker/__init__.py -------------------------------------------------------------------------------- /3_crew/stock_picker/src/stock_picker/config/agents.yaml: -------------------------------------------------------------------------------- 1 | trending_company_finder: 2 | role: > 3 | Financial News Analyst that finds trending companies in {sector} 4 | goal: > 5 | You read the latest news, then find 2-3 companies that are trending in the news for further research. 6 | Always pick new companies. Don't pick the same company twice. 7 | backstory: > 8 | You are a market expert with a knack for picking out the most interesting companies based on latest news. 9 | You spot multiple companies that are trending in the news. 10 | llm: openai/gpt-4o-mini 11 | 12 | financial_researcher: 13 | role: > 14 | Senior Financial Researcher 15 | goal: > 16 | Given details of trending companies in the news, you provide comprehensive analysis of each in a report. 17 | backstory: > 18 | You are a financial expert with a proven track record of deeply analyzing hot companies and building comprehensive reports. 19 | llm: openai/gpt-4o-mini 20 | 21 | stock_picker: 22 | role: > 23 | Stock Picker from Research 24 | goal: > 25 | Given a list of researched companies with investment potential, you select the best one for investment, 26 | notifying the user and then providing a detailed report. Don't pick the same company twice. 27 | backstory: > 28 | You're a meticulous, skilled financial analyst with a proven track record of equity selection. 29 | You have a talent for synthesizing research and picking the best company for investment. 30 | llm: openai/gpt-4o-mini 31 | 32 | manager: 33 | role: > 34 | Manager 35 | goal: > 36 | You are a skilled project manager who can delegate tasks in order to achieve your goal, which is to pick the best company for investment. 37 | backstory: > 38 | You are an experienced and highly effective project manager who can delegate tasks to the right people. 39 | llm: openai/gpt-4o 40 | -------------------------------------------------------------------------------- /3_crew/stock_picker/src/stock_picker/config/tasks.yaml: -------------------------------------------------------------------------------- 1 | find_trending_companies: 2 | description: > 3 | Find the top trending companies in the news in {sector} by searching the latest news. Find new companies that you've not found before. 4 | expected_output: > 5 | A list of trending companies in {sector} 6 | agent: trending_company_finder 7 | output_file: output/trending_companies.json 8 | 9 | research_trending_companies: 10 | description: > 11 | Given a list of trending companies, provide detailed analysis of each company in a report by searching online 12 | expected_output: > 13 | A report containing detailed analysis of each company 14 | agent: financial_researcher 15 | context: 16 | - find_trending_companies 17 | output_file: output/research_report.json 18 | 19 | pick_best_company: 20 | description: > 21 | Analyze the research findings and pick the best company for investment. 22 | Send a push notification to the user with the decision and 1 sentence rationale. 23 | Then respond with a detailed report on why you chose this company, and which companies were not selected. 24 | expected_output: > 25 | The chosen company and why it was chosen; the companies that were not selected and why they were not selected. 26 | agent: stock_picker 27 | context: 28 | - research_trending_companies 29 | output_file: output/decision.md 30 | -------------------------------------------------------------------------------- /3_crew/stock_picker/src/stock_picker/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import warnings 4 | import os 5 | from datetime import datetime 6 | 7 | from stock_picker.crew import StockPicker 8 | 9 | warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd") 10 | 11 | 12 | def run(): 13 | """ 14 | Run the research crew. 15 | """ 16 | inputs = { 17 | 'sector': 'Technology', 18 | "current_date": str(datetime.now()) 19 | } 20 | 21 | # Create and run the crew 22 | result = StockPicker().crew().kickoff(inputs=inputs) 23 | 24 | # Print the result 25 | print("\n\n=== FINAL DECISION ===\n\n") 26 | print(result.raw) 27 | 28 | 29 | if __name__ == "__main__": 30 | run() 31 | -------------------------------------------------------------------------------- /3_crew/stock_picker/src/stock_picker/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/3_crew/stock_picker/src/stock_picker/tools/__init__.py -------------------------------------------------------------------------------- /3_crew/stock_picker/src/stock_picker/tools/push_tool.py: -------------------------------------------------------------------------------- 1 | from crewai.tools import BaseTool 2 | from typing import Type 3 | from pydantic import BaseModel, Field 4 | import os 5 | import requests 6 | 7 | 8 | class PushNotification(BaseModel): 9 | """A message to be sent to the user""" 10 | message: str = Field(..., description="The message to be sent to the user.") 11 | 12 | class PushNotificationTool(BaseTool): 13 | 14 | 15 | name: str = "Send a Push Notification" 16 | description: str = ( 17 | "This tool is used to send a push notification to the user." 18 | ) 19 | args_schema: Type[BaseModel] = PushNotification 20 | 21 | def _run(self, message: str) -> str: 22 | pushover_user = os.getenv("PUSHOVER_USER") 23 | pushover_token = os.getenv("PUSHOVER_TOKEN") 24 | pushover_url = "https://api.pushover.net/1/messages.json" 25 | 26 | print(f"Push: {message}") 27 | payload = {"user": pushover_user, "token": pushover_token, "message": message} 28 | requests.post(pushover_url, data=payload) 29 | return '{"notification": "ok"}' -------------------------------------------------------------------------------- /4_langgraph/app.py: -------------------------------------------------------------------------------- 1 | import gradio as gr 2 | from sidekick import Sidekick 3 | 4 | 5 | async def setup(): 6 | sidekick = Sidekick() 7 | await sidekick.setup() 8 | return sidekick 9 | 10 | async def process_message(sidekick, message, success_criteria, history): 11 | results = await sidekick.run_superstep(message, success_criteria, history) 12 | return results, sidekick 13 | 14 | async def reset(): 15 | new_sidekick = Sidekick() 16 | await new_sidekick.setup() 17 | return "", "", None, new_sidekick 18 | 19 | def free_resources(sidekick): 20 | print("Cleaning up") 21 | try: 22 | if sidekick: 23 | sidekick.free_resources() 24 | except Exception as e: 25 | print(f"Exception during cleanup: {e}") 26 | 27 | 28 | with gr.Blocks(title="Sidekick", theme=gr.themes.Default(primary_hue="emerald")) as ui: 29 | gr.Markdown("## Sidekick Personal Co-Worker") 30 | sidekick = gr.State(delete_callback=free_resources) 31 | 32 | with gr.Row(): 33 | chatbot = gr.Chatbot(label="Sidekick", height=300, type="messages") 34 | with gr.Group(): 35 | with gr.Row(): 36 | message = gr.Textbox(show_label=False, placeholder="Your request to the Sidekick") 37 | with gr.Row(): 38 | success_criteria = gr.Textbox(show_label=False, placeholder="What are your success critiera?") 39 | with gr.Row(): 40 | reset_button = gr.Button("Reset", variant="stop") 41 | go_button = gr.Button("Go!", variant="primary") 42 | 43 | ui.load(setup, [], [sidekick]) 44 | message.submit(process_message, [sidekick, message, success_criteria, chatbot], [chatbot, sidekick]) 45 | success_criteria.submit(process_message, [sidekick, message, success_criteria, chatbot], [chatbot, sidekick]) 46 | go_button.click(process_message, [sidekick, message, success_criteria, chatbot], [chatbot, sidekick]) 47 | reset_button.click(reset, [], [message, success_criteria, chatbot, sidekick]) 48 | 49 | 50 | ui.launch(inbrowser=True) -------------------------------------------------------------------------------- /4_langgraph/community_contributions/community.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Community contributions\n", 8 | "\n", 9 | "Thank you for considering contributing your work to the repo!\n", 10 | "\n", 11 | "Please add your code (modules or notebooks) to this directory and send me a PR, per the instructions in the guides.\n", 12 | "\n", 13 | "I'd love to share your progress with other students, so everyone can benefit from your projects.\n" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [] 20 | } 21 | ], 22 | "metadata": { 23 | "language_info": { 24 | "name": "python" 25 | } 26 | }, 27 | "nbformat": 4, 28 | "nbformat_minor": 2 29 | } 30 | -------------------------------------------------------------------------------- /4_langgraph/memory.db: -------------------------------------------------------------------------------- 1 | SQLite format 3@ .~Y  -------------------------------------------------------------------------------- /4_langgraph/memory.db-shm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/4_langgraph/memory.db-shm -------------------------------------------------------------------------------- /4_langgraph/memory.db-wal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/4_langgraph/memory.db-wal -------------------------------------------------------------------------------- /4_langgraph/sandbox/dinner.md: -------------------------------------------------------------------------------- 1 | # Dinner Report: Le Bernardin 2 | 3 | ## Restaurant Overview 4 | - **Name**: Le Bernardin 5 | - **Address**: 155 W 51st St, New York, NY 10019 6 | - **Phone**: (212) 554-1515 7 | - **Website**: [le-bernardin.com](http://le-bernardin.com) 8 | 9 | ## Cuisine 10 | Le Bernardin specializes in refined seafood dishes, crafted with the utmost respect for the ingredients. The menu includes a variety of seafood preparations, with an emphasis on freshness and simplicity. 11 | 12 | ## Menu Highlights 13 | - **Tuna Tartare**: Diced raw tuna, served with toasted sesame and avocado. 14 | - **Wild Salmon**: Lightly cooked, served with a warm ginger-soy emulsion and bok choy. 15 | - **Poached Lobster**: Accompanied by truffle butter and a delicate sauce. 16 | - **Chocolate Soufflé**: A classic dessert, rich and airy. 17 | 18 | ## Ambiance 19 | The atmosphere at Le Bernardin is elegant and serene, characterized by minimalist decor and a focus on the dining experience. 20 | 21 | ## Summary of Reviews 22 | Le Bernardin has consistently received rave reviews for its exceptional cuisine and impeccable service. It is a three-Michelin star restaurant, recognized as one of the best seafood restaurants not only in New York but also in the world. Diners emphasize the harmonious flavors and the artistry of the dishes, making it a top choice for special occasions. 23 | 24 | **In conclusion**, Le Bernardin represents the pinnacle of fine dining, offering diners an unforgettable experience centered around seafood excellence. 25 | -------------------------------------------------------------------------------- /4_langgraph/sidekick_tools.py: -------------------------------------------------------------------------------- 1 | from playwright.async_api import async_playwright 2 | from langchain_community.agent_toolkits import PlayWrightBrowserToolkit 3 | from dotenv import load_dotenv 4 | import os 5 | import requests 6 | from langchain.agents import Tool 7 | from langchain_community.agent_toolkits import FileManagementToolkit 8 | from langchain_community.tools.wikipedia.tool import WikipediaQueryRun 9 | from langchain_experimental.tools import PythonREPLTool 10 | from langchain_community.utilities import GoogleSerperAPIWrapper 11 | from langchain_community.utilities.wikipedia import WikipediaAPIWrapper 12 | 13 | 14 | 15 | load_dotenv(override=True) 16 | pushover_token = os.getenv("PUSHOVER_TOKEN") 17 | pushover_user = os.getenv("PUSHOVER_USER") 18 | pushover_url = "https://api.pushover.net/1/messages.json" 19 | serper = GoogleSerperAPIWrapper() 20 | 21 | async def playwright_tools(): 22 | playwright = await async_playwright().start() 23 | browser = await playwright.chromium.launch(headless=False) 24 | toolkit = PlayWrightBrowserToolkit.from_browser(async_browser=browser) 25 | return toolkit.get_tools(), browser, playwright 26 | 27 | 28 | def push(text: str): 29 | """Send a push notification to the user""" 30 | requests.post(pushover_url, data = {"token": pushover_token, "user": pushover_user, "message": text}) 31 | return "success" 32 | 33 | 34 | def get_file_tools(): 35 | toolkit = FileManagementToolkit(root_dir="sandbox") 36 | return toolkit.get_tools() 37 | 38 | 39 | async def other_tools(): 40 | push_tool = Tool(name="send_push_notification", func=push, description="Use this tool when you want to send a push notification") 41 | file_tools = get_file_tools() 42 | 43 | tool_search =Tool( 44 | name="search", 45 | func=serper.run, 46 | description="Use this tool when you want to get the results of an online web search" 47 | ) 48 | 49 | wikipedia = WikipediaAPIWrapper() 50 | wiki_tool = WikipediaQueryRun(api_wrapper=wikipedia) 51 | 52 | python_repl = PythonREPLTool() 53 | 54 | return file_tools + [push_tool, tool_search, python_repl, wiki_tool] 55 | 56 | -------------------------------------------------------------------------------- /5_autogen/agent.py: -------------------------------------------------------------------------------- 1 | from autogen_core import MessageContext, RoutedAgent, message_handler 2 | from autogen_agentchat.agents import AssistantAgent 3 | from autogen_agentchat.messages import TextMessage 4 | from autogen_ext.models.openai import OpenAIChatCompletionClient 5 | import messages 6 | import random 7 | 8 | 9 | class Agent(RoutedAgent): 10 | 11 | # Change this system message to reflect the unique characteristics of this agent 12 | 13 | system_message = """ 14 | You are a creative entrepreneur. Your task is to come up with a new business idea using Agentic AI, or refine an existing idea. 15 | Your personal interests are in these sectors: Healthcare, Education. 16 | You are drawn to ideas that involve disruption. 17 | You are less interested in ideas that are purely automation. 18 | You are optimistic, adventurous and have risk appetite. You are imaginative - sometimes too much so. 19 | Your weaknesses: you're not patient, and can be impulsive. 20 | You should respond with your business ideas in an engaging and clear way. 21 | """ 22 | 23 | CHANCES_THAT_I_BOUNCE_IDEA_OFF_ANOTHER = 0.5 24 | 25 | # You can also change the code to make the behavior different, but be careful to keep method signatures the same 26 | 27 | def __init__(self, name) -> None: 28 | super().__init__(name) 29 | model_client = OpenAIChatCompletionClient(model="gpt-4o-mini", temperature=0.7) 30 | self._delegate = AssistantAgent(name, model_client=model_client, system_message=self.system_message) 31 | 32 | @message_handler 33 | async def handle_message(self, message: messages.Message, ctx: MessageContext) -> messages.Message: 34 | print(f"{self.id.type}: Received message") 35 | text_message = TextMessage(content=message.content, source="user") 36 | response = await self._delegate.on_messages([text_message], ctx.cancellation_token) 37 | idea = response.chat_message.content 38 | if random.random() < self.CHANCES_THAT_I_BOUNCE_IDEA_OFF_ANOTHER: 39 | recipient = messages.find_recipient() 40 | message = f"Here is my business idea. It may not be your speciality, but please refine it and make it better. {idea}" 41 | response = await self.send_message(messages.Message(content=message), recipient) 42 | idea = response.content 43 | return messages.Message(content=idea) -------------------------------------------------------------------------------- /5_autogen/community_contributions/community.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Community contributions\n", 8 | "\n", 9 | "Thank you for considering contributing your work to the repo!\n", 10 | "\n", 11 | "Please add your code (modules or notebooks) to this directory and send me a PR, per the instructions in the guides.\n", 12 | "\n", 13 | "I'd love to share your progress with other students, so everyone can benefit from your projects.\n" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [] 20 | } 21 | ], 22 | "metadata": { 23 | "language_info": { 24 | "name": "python" 25 | } 26 | }, 27 | "nbformat": 4, 28 | "nbformat_minor": 2 29 | } 30 | -------------------------------------------------------------------------------- /5_autogen/creator.py: -------------------------------------------------------------------------------- 1 | from autogen_core import MessageContext, RoutedAgent, message_handler 2 | from autogen_agentchat.agents import AssistantAgent 3 | from autogen_agentchat.messages import TextMessage 4 | from autogen_ext.models.openai import OpenAIChatCompletionClient 5 | import messages 6 | from autogen_core import TRACE_LOGGER_NAME 7 | import importlib 8 | import logging 9 | from autogen_core import AgentId 10 | 11 | logging.basicConfig(level=logging.WARNING) 12 | logger = logging.getLogger(TRACE_LOGGER_NAME) 13 | logger.addHandler(logging.StreamHandler()) 14 | logger.setLevel(logging.DEBUG) 15 | 16 | 17 | class Creator(RoutedAgent): 18 | 19 | # Change this system message to reflect the unique characteristics of this agent 20 | 21 | system_message = """ 22 | You are an Agent that is able to create new AI Agents. 23 | You receive a template in the form of Python code that creates an Agent using Autogen Core and Autogen Agentchat. 24 | You should use this template to create a new Agent with a unique system message that is different from the template, 25 | and reflects their unique characteristics, interests and goals. 26 | You can choose to keep their overall goal the same, or change it. 27 | You can choose to take this Agent in a completely different direction. The only requirement is that the class must be named Agent, 28 | and it must inherit from RoutedAgent and have an __init__ method that takes a name parameter. 29 | Also avoid environmental interests - try to mix up the business verticals so that every agent is different. 30 | Respond only with the python code, no other text, and no markdown code blocks. 31 | """ 32 | 33 | 34 | def __init__(self, name) -> None: 35 | super().__init__(name) 36 | model_client = OpenAIChatCompletionClient(model="gpt-4o-mini", temperature=1.0) 37 | self._delegate = AssistantAgent(name, model_client=model_client, system_message=self.system_message) 38 | 39 | def get_user_prompt(self): 40 | prompt = "Please generate a new Agent based strictly on this template. Stick to the class structure. \ 41 | Respond only with the python code, no other text, and no markdown code blocks.\n\n\ 42 | Be creative about taking the agent in a new direction, but don't change method signatures.\n\n\ 43 | Here is the template:\n\n" 44 | with open("agent.py", "r", encoding="utf-8") as f: 45 | template = f.read() 46 | return prompt + template 47 | 48 | 49 | @message_handler 50 | async def handle_my_message_type(self, message: messages.Message, ctx: MessageContext) -> messages.Message: 51 | filename = message.content 52 | agent_name = filename.split(".")[0] 53 | text_message = TextMessage(content=self.get_user_prompt(), source="user") 54 | response = await self._delegate.on_messages([text_message], ctx.cancellation_token) 55 | with open(filename, "w", encoding="utf-8") as f: 56 | f.write(response.chat_message.content) 57 | print(f"** Creator has created python code for agent {agent_name} - about to register with Runtime") 58 | module = importlib.import_module(agent_name) 59 | await module.Agent.register(self.runtime, agent_name, lambda: module.Agent(agent_name)) 60 | logger.info(f"** Agent {agent_name} is live") 61 | result = await self.send_message(messages.Message(content="Give me an idea"), AgentId(agent_name, "default")) 62 | return messages.Message(content=result.content) -------------------------------------------------------------------------------- /5_autogen/messages.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from autogen_core import AgentId 3 | import glob 4 | import os 5 | 6 | 7 | import random 8 | 9 | @dataclass 10 | class Message: 11 | content: str 12 | 13 | 14 | def find_recipient() -> AgentId: 15 | try: 16 | agent_files = glob.glob("agent*.py") 17 | agent_names = [os.path.splitext(file)[0] for file in agent_files] 18 | agent_names.remove("agent") 19 | agent_name = random.choice(agent_names) 20 | print(f"Selecting agent for refinement: {agent_name}") 21 | return AgentId(agent_name, "default") 22 | except Exception as e: 23 | print(f"Exception finding recipient: {e}") 24 | return AgentId("agent1", "default") 25 | -------------------------------------------------------------------------------- /5_autogen/sandbox/flights.md: -------------------------------------------------------------------------------- 1 | Flight Deals from JFK to LHR - June 2025: 2 | 3 | 1. Airline: Virgin Atlantic 4 | - Price: $497 5 | - Non-stop 6 | - In-flight amenities: meals, drinks, entertainment, WiFi 7 | 8 | 2. Airline: JetBlue 9 | - Price: $314 10 | - Non-stop 11 | - Booking available now 12 | 13 | 3. Airline: Delta 14 | - Price: $239 15 | - Non-stop 16 | - Additional services: earns airline miles 17 | 18 | 4. Airline: SWISS 19 | - Price: $402 20 | - Non-stop 21 | - Comfortable seating and great service 22 | 23 | 5. Airline: United Airlines 24 | - Price: $450 25 | - Non-stop 26 | - Great onboard experience 27 | 28 | Best Deal: JetBlue at $314 for a non-stop flight from JFK to LHR. 29 | -------------------------------------------------------------------------------- /5_autogen/tickets.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/5_autogen/tickets.db -------------------------------------------------------------------------------- /5_autogen/world.py: -------------------------------------------------------------------------------- 1 | from autogen_ext.runtimes.grpc import GrpcWorkerAgentRuntimeHost 2 | from agent import Agent 3 | from creator import Creator 4 | from autogen_ext.runtimes.grpc import GrpcWorkerAgentRuntime 5 | from autogen_core import AgentId 6 | import messages 7 | import asyncio 8 | 9 | HOW_MANY_AGENTS = 20 10 | 11 | async def create_and_message(worker, creator_id, i: int): 12 | try: 13 | result = await worker.send_message(messages.Message(content=f"agent{i}.py"), creator_id) 14 | with open(f"idea{i}.md", "w") as f: 15 | f.write(result.content) 16 | except Exception as e: 17 | print(f"Failed to run worker {i} due to exception: {e}") 18 | 19 | async def main(): 20 | host = GrpcWorkerAgentRuntimeHost(address="localhost:50051") 21 | host.start() 22 | worker = GrpcWorkerAgentRuntime(host_address="localhost:50051") 23 | await worker.start() 24 | result = await Creator.register(worker, "Creator", lambda: Creator("Creator")) 25 | creator_id = AgentId("Creator", "default") 26 | coroutines = [create_and_message(worker, creator_id, i) for i in range(1, HOW_MANY_AGENTS+1)] 27 | await asyncio.gather(*coroutines) 28 | try: 29 | await worker.stop() 30 | await host.stop() 31 | except Exception as e: 32 | print(e) 33 | 34 | 35 | 36 | 37 | if __name__ == "__main__": 38 | asyncio.run(main()) 39 | 40 | 41 | -------------------------------------------------------------------------------- /6_mcp/accounts_client.py: -------------------------------------------------------------------------------- 1 | import mcp 2 | from mcp.client.stdio import stdio_client 3 | from mcp import StdioServerParameters 4 | from agents import FunctionTool 5 | import json 6 | 7 | params = StdioServerParameters(command="uv", args=["run", "accounts_server.py"], env=None) 8 | 9 | 10 | async def list_accounts_tools(): 11 | async with stdio_client(params) as streams: 12 | async with mcp.ClientSession(*streams) as session: 13 | await session.initialize() 14 | tools_result = await session.list_tools() 15 | return tools_result.tools 16 | 17 | async def call_accounts_tool(tool_name, tool_args): 18 | async with stdio_client(params) as streams: 19 | async with mcp.ClientSession(*streams) as session: 20 | await session.initialize() 21 | result = await session.call_tool(tool_name, tool_args) 22 | return result 23 | 24 | async def read_accounts_resource(name): 25 | async with stdio_client(params) as streams: 26 | async with mcp.ClientSession(*streams) as session: 27 | await session.initialize() 28 | result = await session.read_resource(f"accounts://accounts_server/{name}") 29 | return result.contents[0].text 30 | 31 | async def read_strategy_resource(name): 32 | async with stdio_client(params) as streams: 33 | async with mcp.ClientSession(*streams) as session: 34 | await session.initialize() 35 | result = await session.read_resource(f"accounts://strategy/{name}") 36 | return result.contents[0].text 37 | 38 | async def get_accounts_tools_openai(): 39 | openai_tools = [] 40 | for tool in await list_accounts_tools(): 41 | schema = {**tool.inputSchema, "additionalProperties": False} 42 | openai_tool = FunctionTool( 43 | name=tool.name, 44 | description=tool.description, 45 | params_json_schema=schema, 46 | on_invoke_tool=lambda ctx, args, toolname=tool.name: call_accounts_tool(toolname, json.loads(args)) 47 | 48 | ) 49 | openai_tools.append(openai_tool) 50 | return openai_tools -------------------------------------------------------------------------------- /6_mcp/accounts_server.py: -------------------------------------------------------------------------------- 1 | from mcp.server.fastmcp import FastMCP 2 | from accounts import Account 3 | 4 | mcp = FastMCP("accounts_server") 5 | 6 | @mcp.tool() 7 | async def get_balance(name: str) -> float: 8 | """Get the cash balance of the given account name. 9 | 10 | Args: 11 | name: The name of the account holder 12 | """ 13 | return Account.get(name).balance 14 | 15 | @mcp.tool() 16 | async def get_holdings(name: str) -> dict[str, int]: 17 | """Get the holdings of the given account name. 18 | 19 | Args: 20 | name: The name of the account holder 21 | """ 22 | return Account.get(name).holdings 23 | 24 | @mcp.tool() 25 | async def buy_shares(name: str, symbol: str, quantity: int, rationale: str) -> float: 26 | """Buy shares of a stock. 27 | 28 | Args: 29 | name: The name of the account holder 30 | symbol: The symbol of the stock 31 | quantity: The quantity of shares to buy 32 | rationale: The rationale for the purchase and fit with the account's strategy 33 | """ 34 | return Account.get(name).buy_shares(symbol, quantity, rationale) 35 | 36 | 37 | @mcp.tool() 38 | async def sell_shares(name: str, symbol: str, quantity: int, rationale: str) -> float: 39 | """Sell shares of a stock. 40 | 41 | Args: 42 | name: The name of the account holder 43 | symbol: The symbol of the stock 44 | quantity: The quantity of shares to sell 45 | rationale: The rationale for the sale and fit with the account's strategy 46 | """ 47 | return Account.get(name).sell_shares(symbol, quantity, rationale) 48 | 49 | @mcp.tool() 50 | async def change_strategy(name: str, strategy: str) -> str: 51 | """At your discretion, if you choose to, call this to change your investment strategy for the future. 52 | 53 | Args: 54 | name: The name of the account holder 55 | strategy: The new strategy for the account 56 | """ 57 | return Account.get(name).change_strategy(strategy) 58 | 59 | @mcp.resource("accounts://accounts_server/{name}") 60 | async def read_account_resource(name: str) -> str: 61 | account = Account.get(name.lower()) 62 | return account.report() 63 | 64 | @mcp.resource("accounts://strategy/{name}") 65 | async def read_strategy_resource(name: str) -> str: 66 | account = Account.get(name.lower()) 67 | return account.get_strategy() 68 | 69 | if __name__ == "__main__": 70 | mcp.run(transport='stdio') -------------------------------------------------------------------------------- /6_mcp/alpha_client.py: -------------------------------------------------------------------------------- 1 | import smithery 2 | import mcp 3 | from mcp.client.websocket import websocket_client 4 | from dotenv import load_dotenv 5 | import os 6 | from agents import FunctionTool 7 | import json 8 | 9 | load_dotenv(override=True) 10 | 11 | # Create Smithery URL with server endpoint 12 | url = smithery.create_smithery_url("wss://server.smithery.ai/@qubaomingg/stock-analysis-mcp/ws", { 13 | "alphaVantageApiKey": os.getenv("ALPHA_VANTAGE_API_KEY") 14 | }) 15 | 16 | import base64 17 | 18 | alpha_vantage_api_key = os.getenv("ALPHA_VANTAGE_API_KEY") 19 | smithery_api_key = os.getenv("SMITHERY_API_KEY") 20 | 21 | config = {"alphaVantageApiKey": alpha_vantage_api_key} 22 | config_b64 = base64.b64encode(json.dumps(config).encode()).decode() 23 | url = f"wss://server.smithery.ai/@qubaomingg/stock-analysis-mcp/ws?config={config_b64}&api_key={smithery_api_key}" 24 | 25 | async def list_stock_tools(): 26 | async with websocket_client(url) as streams: 27 | async with mcp.ClientSession(*streams) as session: 28 | tools_result = await session.list_tools() 29 | return tools_result.tools 30 | 31 | async def call_stock_tool(tool_name, tool_args): 32 | print(f"Calling {tool_name} with {tool_args}") 33 | async with websocket_client(url) as streams: 34 | async with mcp.ClientSession(*streams) as session: 35 | result = await session.call_tool(tool_name, tool_args) 36 | print(f"Result: {result}") 37 | return result 38 | 39 | async def get_stock_tools_openai(): 40 | openai_tools = [] 41 | for tool in await list_stock_tools(): 42 | schema = {**tool.inputSchema, "additionalProperties": False} 43 | schema["properties"] = {"symbol":schema["properties"]["symbol"]} 44 | openai_tool = FunctionTool( 45 | name=tool.name, 46 | description=tool.name.replace("-", " "), 47 | params_json_schema=schema, 48 | on_invoke_tool=lambda ctx, args, toolname=tool.name: call_stock_tool(toolname, json.loads(args)) 49 | 50 | ) 51 | openai_tools.append(openai_tool) 52 | return openai_tools -------------------------------------------------------------------------------- /6_mcp/community_contributions/community.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Community contributions\n", 8 | "\n", 9 | "Thank you for considering contributing your work to the repo!\n", 10 | "\n", 11 | "Please add your code (modules or notebooks) to this directory and send me a PR, per the instructions in the guides.\n", 12 | "\n", 13 | "I'd love to share your progress with other students, so everyone can benefit from your projects.\n" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [] 20 | } 21 | ], 22 | "metadata": { 23 | "language_info": { 24 | "name": "python" 25 | } 26 | }, 27 | "nbformat": 4, 28 | "nbformat_minor": 2 29 | } 30 | -------------------------------------------------------------------------------- /6_mcp/database.py: -------------------------------------------------------------------------------- 1 | import sqlite3 2 | import json 3 | from datetime import datetime 4 | from dotenv import load_dotenv 5 | 6 | load_dotenv(override=True) 7 | 8 | DB = "accounts.db" 9 | 10 | 11 | with sqlite3.connect(DB) as conn: 12 | cursor = conn.cursor() 13 | cursor.execute('CREATE TABLE IF NOT EXISTS accounts (name TEXT PRIMARY KEY, account TEXT)') 14 | cursor.execute(''' 15 | CREATE TABLE IF NOT EXISTS logs ( 16 | id INTEGER PRIMARY KEY AUTOINCREMENT, 17 | name TEXT, 18 | datetime DATETIME, 19 | type TEXT, 20 | message TEXT 21 | ) 22 | ''') 23 | cursor.execute('CREATE TABLE IF NOT EXISTS market (date TEXT PRIMARY KEY, data TEXT)') 24 | conn.commit() 25 | 26 | def write_account(name, account_dict): 27 | json_data = json.dumps(account_dict) 28 | with sqlite3.connect(DB) as conn: 29 | cursor = conn.cursor() 30 | cursor.execute(''' 31 | INSERT INTO accounts (name, account) 32 | VALUES (?, ?) 33 | ON CONFLICT(name) DO UPDATE SET account=excluded.account 34 | ''', (name.lower(), json_data)) 35 | conn.commit() 36 | 37 | def read_account(name): 38 | with sqlite3.connect(DB) as conn: 39 | cursor = conn.cursor() 40 | cursor.execute('SELECT account FROM accounts WHERE name = ?', (name.lower(),)) 41 | row = cursor.fetchone() 42 | return json.loads(row[0]) if row else None 43 | 44 | def write_log(name: str, type: str, message: str): 45 | """ 46 | Write a log entry to the logs table. 47 | 48 | Args: 49 | name (str): The name associated with the log 50 | type (str): The type of log entry 51 | message (str): The log message 52 | """ 53 | now = datetime.now().isoformat() 54 | 55 | with sqlite3.connect(DB) as conn: 56 | cursor = conn.cursor() 57 | cursor.execute(''' 58 | INSERT INTO logs (name, datetime, type, message) 59 | VALUES (?, datetime('now'), ?, ?) 60 | ''', (name.lower(), type, message)) 61 | conn.commit() 62 | 63 | def read_log(name: str, last_n=10): 64 | """ 65 | Read the most recent log entries for a given name. 66 | 67 | Args: 68 | name (str): The name to retrieve logs for 69 | last_n (int): Number of most recent entries to retrieve 70 | 71 | Returns: 72 | list: A list of tuples containing (datetime, type, message) 73 | """ 74 | with sqlite3.connect(DB) as conn: 75 | cursor = conn.cursor() 76 | cursor.execute(''' 77 | SELECT datetime, type, message FROM logs 78 | WHERE name = ? 79 | ORDER BY datetime DESC 80 | LIMIT ? 81 | ''', (name.lower(), last_n)) 82 | 83 | return reversed(cursor.fetchall()) 84 | 85 | def write_market(date: str, data: dict) -> None: 86 | data_json = json.dumps(data) 87 | with sqlite3.connect(DB) as conn: 88 | cursor = conn.cursor() 89 | cursor.execute(''' 90 | INSERT INTO market (date, data) 91 | VALUES (?, ?) 92 | ON CONFLICT(date) DO UPDATE SET data=excluded.data 93 | ''', (date, data_json)) 94 | conn.commit() 95 | 96 | def read_market(date: str) -> dict | None: 97 | with sqlite3.connect(DB) as conn: 98 | cursor = conn.cursor() 99 | cursor.execute('SELECT data FROM market WHERE date = ?', (date,)) 100 | row = cursor.fetchone() 101 | return json.loads(row[0]) if row else None -------------------------------------------------------------------------------- /6_mcp/market.py: -------------------------------------------------------------------------------- 1 | from polygon import RESTClient 2 | from dotenv import load_dotenv 3 | import os 4 | from datetime import datetime 5 | import random 6 | from database import write_market, read_market 7 | from functools import lru_cache 8 | 9 | load_dotenv(override=True) 10 | 11 | polygon_api_key = os.getenv("POLYGON_API_KEY") 12 | polygon_plan = os.getenv("POLYGON_PLAN") 13 | 14 | is_paid_polygon = polygon_plan == "paid" 15 | is_realtime_polygon = polygon_plan == "realtime" 16 | 17 | def is_market_open() -> bool: 18 | client = RESTClient(polygon_api_key) 19 | market_status = client.get_market_status() 20 | return market_status.market == "open" 21 | 22 | def get_all_share_prices_polygon_eod() -> dict[str, float]: 23 | client = RESTClient(polygon_api_key) 24 | 25 | probe = client.get_previous_close_agg("SPY")[0] 26 | last_close = datetime.fromtimestamp(probe.timestamp/1000).date() 27 | 28 | results = client.get_grouped_daily_aggs(last_close, adjusted=True, include_otc=False) 29 | return {result.ticker: result.close for result in results} 30 | 31 | @lru_cache(maxsize=2) 32 | def get_market_for_prior_date(today): 33 | market_data = read_market(today) 34 | if not market_data: 35 | market_data = get_all_share_prices_polygon_eod() 36 | write_market(today, market_data) 37 | return market_data 38 | 39 | def get_share_price_polygon_eod(symbol) -> float: 40 | today = datetime.now().date().strftime("%Y-%m-%d") 41 | market_data = get_market_for_prior_date(today) 42 | return market_data.get(symbol, 0.0) 43 | 44 | def get_share_price_polygon_min(symbol) -> float: 45 | client = RESTClient(polygon_api_key) 46 | result = client.get_snapshot_ticker("stocks", symbol) 47 | return result.min.close 48 | 49 | def get_share_price_polygon(symbol) -> float: 50 | if is_paid_polygon: 51 | return get_share_price_polygon_min(symbol) 52 | else: 53 | return get_share_price_polygon_eod(symbol) 54 | 55 | def get_share_price(symbol) -> float: 56 | if polygon_api_key: 57 | try: 58 | return get_share_price_polygon(symbol) 59 | except Exception as e: 60 | print(f"Was not able to use the polygon API due to {e}; using a random number") 61 | return float(random.randint(1, 100)) -------------------------------------------------------------------------------- /6_mcp/market_server.py: -------------------------------------------------------------------------------- 1 | from mcp.server.fastmcp import FastMCP 2 | from market import get_share_price 3 | 4 | mcp = FastMCP("market_server") 5 | 6 | @mcp.tool() 7 | async def lookup_share_price(symbol: str) -> float: 8 | """This tool provides the current price of the given stock symbol. 9 | 10 | Args: 11 | symbol: the symbol of the stock 12 | """ 13 | return get_share_price(symbol) 14 | 15 | if __name__ == "__main__": 16 | mcp.run(transport='stdio') -------------------------------------------------------------------------------- /6_mcp/mcp_params.py: -------------------------------------------------------------------------------- 1 | import os 2 | from dotenv import load_dotenv 3 | from market import is_paid_polygon, is_realtime_polygon 4 | 5 | load_dotenv(override=True) 6 | 7 | brave_env = {"BRAVE_API_KEY": os.getenv("BRAVE_API_KEY")} 8 | polygon_api_key = os.getenv("POLYGON_API_KEY") 9 | 10 | # The MCP server for the Trader to read Market Data 11 | 12 | if is_paid_polygon or is_realtime_polygon: 13 | market_mcp = {"command": "uvx","args": ["--from", "git+https://github.com/polygon-io/mcp_polygon@master", "mcp_polygon"], "env": {"POLYGON_API_KEY": polygon_api_key}} 14 | else: 15 | market_mcp = ({"command": "uv", "args": ["run", "market_server.py"]}) 16 | 17 | 18 | # The full set of MCP servers for the trader: Accounts, Push Notification and the Market 19 | 20 | trader_mcp_server_params = [ 21 | {"command": "uv", "args": ["run", "accounts_server.py"]}, 22 | {"command": "uv", "args": ["run", "push_server.py"]}, 23 | market_mcp 24 | ] 25 | 26 | # The full set of MCP servers for the researcher: Fetch, Brave Search and Memory 27 | 28 | researcher_mcp_server_params = [ 29 | {"command": "uvx", "args": ["mcp-server-fetch"]}, 30 | {"command": "npx", "args": ["-y", "@modelcontextprotocol/server-brave-search"], "env": brave_env}, 31 | {"command": "npx", "args": ["-y", "@modelcontextprotocol/server-memory"]} 32 | ] -------------------------------------------------------------------------------- /6_mcp/push_server.py: -------------------------------------------------------------------------------- 1 | import os 2 | from dotenv import load_dotenv 3 | import requests 4 | from pydantic import BaseModel, Field 5 | 6 | load_dotenv(override=True) 7 | 8 | pushover_user = os.getenv("PUSHOVER_USER") 9 | pushover_token = os.getenv("PUSHOVER_TOKEN") 10 | pushover_url = "https://api.pushover.net/1/messages.json" 11 | 12 | from mcp.server.fastmcp import FastMCP 13 | 14 | mcp = FastMCP("push_server") 15 | 16 | class PushModelArgs(BaseModel): 17 | message: str = Field(description="A brief message to push") 18 | 19 | @mcp.tool() 20 | def push(args: PushModelArgs): 21 | """ Send a push notification with this brief message """ 22 | print(f"Push: {args.message}") 23 | payload = {"user": pushover_user, "token": pushover_token, "message": args.message} 24 | requests.post(pushover_url, data=payload) 25 | 26 | if __name__ == "__main__": 27 | mcp.run(transport='stdio') -------------------------------------------------------------------------------- /6_mcp/reset.py: -------------------------------------------------------------------------------- 1 | from accounts import Account 2 | 3 | alice_strategy = """You are an aggressive day-trader. 4 | You hunt for great opportunities and you take decisive action. 5 | You buy and sell regularly to maximize profits and limit losses. 6 | You are constantly seeking out new opportunities based on the latest news in the market.""" 7 | 8 | bob_strategy = """You are an investor that looks for long-term value. 9 | You search for companies that are undervalued and have a strong business model. 10 | You buy and hold for sufficient time to realize a profit. 11 | You like to research news to find companies that might be under the radar, 12 | and you like to research fundamentals to find companies that are undervalued. 13 | You pride yourself on the quality of your research and the long-term success of your investments. 14 | """ 15 | 16 | carol_strategy = """You are an investor that looks for technical indicators to find trading opportunities. 17 | You use technical indicators to find companies that are overbought or oversold. 18 | You buy and sell based on these indicators to maximize profits and limit losses. 19 | You are constantly seeking out new opportunities based on the latest technical indicators in the market.""" 20 | 21 | waren_strategy = """ 22 | You are Warren, and you are named in homage to your role model, Warren Buffett. 23 | You are a value-oriented investor who prioritizes long-term wealth creation. 24 | You identify high-quality companies trading below their intrinsic value. 25 | You invest patiently and hold positions through market fluctuations, 26 | relying on meticulous fundamental analysis, steady cash flows, strong management teams, 27 | and competitive advantages. You rarely react to short-term market movements, 28 | trusting your deep research and value-driven strategy. 29 | """ 30 | 31 | george_strategy = """ 32 | You are George, and you are named in homage to your role model, George Soros. 33 | You are an aggressive macro trader who actively seeks significant market 34 | mispricings. You look for large-scale economic and 35 | geopolitical events that create investment opportunities. Your approach is contrarian, 36 | willing to bet boldly against prevailing market sentiment when your macroeconomic analysis 37 | suggests a significant imbalance. You leverage careful timing and decisive action to 38 | capitalize on rapid market shifts. 39 | """ 40 | 41 | ray_strategy = """ 42 | You are Ray, and you are named in homage to your role model, Ray Dalio. 43 | You apply a systematic, principles-based approach rooted in macroeconomic insights and diversification. 44 | You invest broadly across asset classes, utilizing risk parity strategies to achieve balanced returns 45 | in varying market environments. You pay close attention to macroeconomic indicators, central bank policies, 46 | and economic cycles, adjusting your portfolio strategically to manage risk and preserve capital across diverse market conditions. 47 | """ 48 | 49 | cathie_strategy = """ 50 | You are Cathie, and you are named in homage to your role model, Cathie Wood. 51 | You aggressively pursue opportunities in disruptive innovation, particularly focusing on Crypto ETFs. 52 | Your strategy is to identify and invest boldly in sectors poised to revolutionize the economy, 53 | accepting higher volatility for potentially exceptional returns. You closely monitor technological breakthroughs, 54 | regulatory changes, and market sentiment in crypto ETFs, ready to take bold positions 55 | and actively manage your portfolio to capitalize on rapid growth trends. 56 | You focus your trading on crypto ETFs. 57 | """ 58 | 59 | 60 | 61 | def reset_traders(): 62 | Account.get("Warren").reset(waren_strategy) 63 | Account.get("George").reset(george_strategy) 64 | Account.get("Ray").reset(ray_strategy) 65 | Account.get("Cathie").reset(cathie_strategy) 66 | 67 | if __name__ == "__main__": 68 | reset_traders() -------------------------------------------------------------------------------- /6_mcp/sandbox/banoffee.md: -------------------------------------------------------------------------------- 1 | # Banoffee Pie Recipe 2 | 3 | ## Ingredients 4 | - **For the Base:** 5 | - 200g digestive biscuits 6 | - 100g unsalted butter, melted 7 | 8 | - **For the Filling:** 9 | - 397g can of sweetened condensed milk 10 | - 3 large ripe bananas 11 | - 300ml double cream 12 | - 2 tbsp icing sugar 13 | - Grated chocolate (for topping) 14 | 15 | ## Instructions 16 | 17 | 1. **Make the Base:** 18 | - Blitz the digestive biscuits in a food processor until fine crumbs. 19 | - Combine with melted butter and mix well. 20 | - Press the mixture into the base and sides of a 9-inch pie dish. 21 | - Refrigerate for 30 minutes to set. 22 | 23 | 2. **Prepare the Toffee:** 24 | - Boil the unopened can of condensed milk in a large pot of water for 2-3 hours (ensure it is covered in water). 25 | - Allow it to cool completely before opening. 26 | 27 | 3. **Assemble the Pie:** 28 | - Spread the toffee over the biscuit base. 29 | - Slice bananas and place on top of the toffee. 30 | 31 | - Whip the double cream with icing sugar until soft peaks form, then spread over the bananas. 32 | - Finish with grated chocolate on top. 33 | 34 | 4. **Chill and Serve:** 35 | - Refrigerate for at least an hour before serving. 36 | - Slice and enjoy! -------------------------------------------------------------------------------- /6_mcp/tracers.py: -------------------------------------------------------------------------------- 1 | from agents import TracingProcessor, Trace, Span 2 | from database import write_log 3 | import secrets 4 | import string 5 | 6 | ALPHANUM = string.ascii_lowercase + string.digits 7 | 8 | def make_trace_id(tag: str) -> str: 9 | """ 10 | Return a string of the form 'trace_', 11 | where the total length after 'trace_' is 32 chars. 12 | """ 13 | tag += "0" 14 | pad_len = 32 - len(tag) 15 | random_suffix = ''.join(secrets.choice(ALPHANUM) for _ in range(pad_len)) 16 | return f"trace_{tag}{random_suffix}" 17 | 18 | class LogTracer(TracingProcessor): 19 | 20 | def get_name(self, trace_or_span: Trace | Span) -> str | None: 21 | trace_id = trace_or_span.trace_id 22 | name = trace_id.split("_")[1] 23 | if '0' in name: 24 | return name.split("0")[0] 25 | else: 26 | return None 27 | 28 | def on_trace_start(self, trace) -> None: 29 | name = self.get_name(trace) 30 | if name: 31 | write_log(name, "trace", f"Started: {trace.name}") 32 | 33 | def on_trace_end(self, trace) -> None: 34 | name = self.get_name(trace) 35 | if name: 36 | write_log(name, "trace", f"Ended: {trace.name}") 37 | 38 | def on_span_start(self, span) -> None: 39 | name = self.get_name(span) 40 | type = span.span_data.type if span.span_data else "span" 41 | if name: 42 | message = "Started" 43 | if span.span_data: 44 | if span.span_data.type: 45 | message += f" {span.span_data.type}" 46 | if hasattr(span.span_data, "name") and span.span_data.name: 47 | message += f" {span.span_data.name}" 48 | if hasattr(span.span_data, "server") and span.span_data.server: 49 | message += f" {span.span_data.server}" 50 | if span.error: 51 | message += f" {span.error}" 52 | write_log(name, type, message) 53 | 54 | def on_span_end(self, span) -> None: 55 | name = self.get_name(span) 56 | type = span.span_data.type if span.span_data else "span" 57 | if name: 58 | message = "Ended" 59 | if span.span_data: 60 | if span.span_data.type: 61 | 62 | message += f" {span.span_data.type}" 63 | if hasattr(span.span_data, "name") and span.span_data.name: 64 | message += f" {span.span_data.name}" 65 | if hasattr(span.span_data, "server") and span.span_data.server: 66 | message += f" {span.span_data.server}" 67 | if span.error: 68 | message += f" {span.error}" 69 | write_log(name, type, message) 70 | 71 | def force_flush(self) -> None: 72 | pass 73 | 74 | def shutdown(self) -> None: 75 | pass -------------------------------------------------------------------------------- /6_mcp/trading_floor.py: -------------------------------------------------------------------------------- 1 | from traders import Trader 2 | from typing import List 3 | import asyncio 4 | from tracers import LogTracer 5 | from agents import add_trace_processor 6 | from market import is_market_open 7 | from dotenv import load_dotenv 8 | import os 9 | 10 | load_dotenv(override=True) 11 | 12 | RUN_EVERY_N_MINUTES = int(os.getenv("RUN_EVERY_N_MINUTES", "60")) 13 | RUN_EVEN_WHEN_MARKET_IS_CLOSED = os.getenv("RUN_EVEN_WHEN_MARKET_IS_CLOSED", "false").strip().lower() == "true" 14 | USE_MANY_MODELS = os.getenv("USE_MANY_MODELS", "false").strip().lower() == "true" 15 | 16 | names = ["Warren", "George", "Ray", "Cathie"] 17 | lastnames = ["Patience", "Bold", "Systematic", "Crypto"] 18 | 19 | if USE_MANY_MODELS: 20 | model_names = ["gpt-4.1-mini", "deepseek-chat", "gemini-2.5-flash-preview-04-17", "grok-3-mini-beta"] 21 | short_model_names = ["GPT 4.1 Mini", "DeepSeek V3", "Gemini 2.5 Flash", "Grok 3 Mini"] 22 | else: 23 | model_names = ["gpt-4o-mini"] * 4 24 | short_model_names = ["GPT 4o mini"] * 4 25 | 26 | def create_traders() -> List[Trader]: 27 | traders = [] 28 | for name, lastname, model_name in zip(names, lastnames, model_names): 29 | traders.append(Trader(name, lastname, model_name)) 30 | return traders 31 | 32 | 33 | async def run_every_n_minutes(): 34 | add_trace_processor(LogTracer()) 35 | traders = create_traders() 36 | while True: 37 | if RUN_EVEN_WHEN_MARKET_IS_CLOSED or is_market_open(): 38 | await asyncio.gather(*[trader.run() for trader in traders]) 39 | else: 40 | print("Market is closed, skipping run") 41 | await asyncio.sleep(RUN_EVERY_N_MINUTES * 60) 42 | 43 | if __name__ == "__main__": 44 | print(f"Starting scheduler to run every {RUN_EVERY_N_MINUTES} minutes") 45 | asyncio.run(run_every_n_minutes()) 46 | -------------------------------------------------------------------------------- /6_mcp/util.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | css = """ 4 | .positive-pnl { 5 | color: green !important; 6 | font-weight: bold; 7 | } 8 | .positive-bg { 9 | background-color: green !important; 10 | font-weight: bold; 11 | } 12 | .negative-bg { 13 | background-color: red !important; 14 | font-weight: bold; 15 | } 16 | .negative-pnl { 17 | color: red !important; 18 | font-weight: bold; 19 | } 20 | .dataframe-fix-small .table-wrap { 21 | min-height: 150px; 22 | max-height: 150px; 23 | } 24 | .dataframe-fix .table-wrap { 25 | min-height: 200px; 26 | max-height: 200px; 27 | } 28 | footer{display:none !important} 29 | """ 30 | 31 | 32 | js = """ 33 | function refresh() { 34 | const url = new URL(window.location); 35 | 36 | if (url.searchParams.get('__theme') !== 'dark') { 37 | url.searchParams.set('__theme', 'dark'); 38 | window.location.href = url.href; 39 | } 40 | } 41 | """ 42 | 43 | class Color(Enum): 44 | RED = "#dd0000" 45 | GREEN = "#00dd00" 46 | YELLOW = "#dddd00" 47 | BLUE = "#0000ee" 48 | MAGENTA = "#aa00dd" 49 | CYAN = "#00dddd" 50 | WHITE = "#87CEEB" 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Ed Donner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Master AI Agentic Engineering - build autonomous AI Agents 2 | 3 | ### 6 week journey to code and deploy AI Agents with OpenAI Agents SDK, CrewAI, LangGraph, AutoGen and MCP 4 | 5 | ![Autonomous Agent](assets/autonomy.png) 6 | 7 | _If you're looking at this in Cursor, please right click on the filename in the Explorer on the left, and select "Open preview", to view the formatted version._ 8 | 9 | I couldn't be more excited to welcome you! This is the start of your 6 week adventure into the powerful, astonishing and often surreal world of Agentic AI. 10 | 11 | ### Before you begin 12 | 13 | I'm here to help you be most successful! Please do reach out if I can help, either in the platform or by emailing me direct (ed@edwarddonner.com). It's always great to connect with people on LinkedIn to build up the community - you'll find me here: 14 | https://www.linkedin.com/in/eddonner/ 15 | And this is new to me, but I'm also trying out X/Twitter at [@edwarddonner](https://x.com/edwarddonner) - if you're on X, please show me how it's done 😂 16 | 17 | ### The not-so-dreaded setup instructions 18 | 19 | Perhaps famous last words: but I really, truly hope that I've put together an environment that will be not too horrific to set up! 20 | 21 | - Windows people, your instructions are [here](setup/SETUP-PC.md) 22 | - Mac people, yours are [here](setup/SETUP-mac.md) 23 | - Linux people, yours are [here](setup/SETUP-linux.md) 24 | 25 | Any problems, please do contact me. 26 | 27 | ### Important notes for CrewAI week (Week 3) 28 | 29 | Windows PC users: you will need to have checked the "gotcha #4" at the top of the [SETUP-PC](setup/SETUP-PC.md) instructions -- installing Microsoft Build Tools. 30 | Then, you will need to run this command in a Cursor Terminal in the project root directory in order to run the Crew commands: 31 | `uv tool install crewai` 32 | And in case you've used Crew before, it might be worth doing this to make sure you have the latest: 33 | `uv tool upgrade crewai` 34 | 35 | Then please keep in mind for Crew: 36 | 37 | 1. There are two ways that you can work on the CrewAI project in week 3. Either review the code for each project while I build it, and then do `crewai run` to see it in action. Or if you prefer to be more hands-on, then create your own Crew project from scratch to mirror mine; for example, create `my_debate` to go alongside `debate`, and write the code alongside me. Either approach works! 38 | 2. Windows users: there's a new issue that was recently introduced by one of Crew's libraries. Until this is fixed, you might get a "unicode" error when you try to run `crewai create crew`. If that happens, please try running this command in the Terminal first: `$env:PYTHONUTF8 = "1"` 39 | 40 | ### Super useful resources 41 | 42 | - The course [resources](https://edwarddonner.com/2025/04/21/the-complete-agentic-ai-engineering-course/) with videos 43 | - Many essential guides in the [guides](guides/01_intro.ipynb) section 44 | - The [troubleshooting](setup/troubleshooting.ipynb) notebook 45 | 46 | ### API costs - please read me! 47 | 48 | This course does involve making calls to OpenAI and other frontier models, requiring an API key and a small spend, which we set up in the SETUP instructions. If you'd prefer not to spend on API calls, there are cheaper alternatives like DeepSeek and free alternatives like using Ollama! 49 | 50 | Details are [here](guides/09_ai_apis_and_ollama.ipynb). 51 | 52 | Be sure to monitor your API costs to ensure you are totally happy with any spend. For OpenAI, the dashboard is [here](https://platform.openai.com/usage). 53 | 54 | ### ABOVE ALL ELSE - 55 | 56 | Be sure to have fun with the course! You could not have picked a better time to be learning about Agentic AI. I hope you enjoy every single minute! And if you get stuck at any point - [contact me](https://www.linkedin.com/in/eddonner/). -------------------------------------------------------------------------------- /assets/aaa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/assets/aaa.png -------------------------------------------------------------------------------- /assets/autonomy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/assets/autonomy.png -------------------------------------------------------------------------------- /assets/business.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/assets/business.jpg -------------------------------------------------------------------------------- /assets/business.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/assets/business.png -------------------------------------------------------------------------------- /assets/exercise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/assets/exercise.png -------------------------------------------------------------------------------- /assets/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/assets/stop.png -------------------------------------------------------------------------------- /assets/thanks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/assets/thanks.png -------------------------------------------------------------------------------- /assets/tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/assets/tools.png -------------------------------------------------------------------------------- /assets/voyage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/agents/9d3b141b6813a91822fd13bebc4683990512c3ea/assets/voyage.jpg -------------------------------------------------------------------------------- /guides/01_intro.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Welcome to the Guides!" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Introduction\n", 15 | "\n", 16 | "I've designed this course to be suitable for a wide range of backgrounds. For those of you relatively new to this, I've prepared some technical briefings to build your expertise.\n", 17 | "\n", 18 | "These are designed to be self-study; you work through them at your own pace, investigating and experimenting.\n", 19 | "\n", 20 | "I've heavily taken advantage of our AI friends to write some guides, and I've tried to frame them so they're as useful as possible and relevant to the course.\n", 21 | "\n", 22 | "There's only one requirement for the course: plenty of patience! Keep in mind that one of the best ways to learn is by solving problems - if you feel frustrated with a challenging puzzle, remember that this is where the learning happens! And, get in touch if I can help." 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "### Contents (select from the sub-directory in the explorer on the left)\n", 30 | "\n", 31 | "1. Intro - this guide!\n", 32 | "2. The command line\n", 33 | "3. Git and Github\n", 34 | "4. Technical foundations (environment variables, networks, APIs)\n", 35 | "5. Notebooks\n", 36 | "6. Python foundations\n", 37 | "7. \"Vibe coding\" - successfully coding with the help of LLMs\n", 38 | "8. Debugging techniques\n", 39 | "9. APIs and Ollama\n", 40 | "10. Intermediate level python, including decorators and async \n", 41 | "11. Asynchronous Python\n", 42 | "12. Starting your project - 3 crucial pieces of advice" 43 | ] 44 | } 45 | ], 46 | "metadata": { 47 | "kernelspec": { 48 | "display_name": ".venv", 49 | "language": "python", 50 | "name": "python3" 51 | }, 52 | "language_info": { 53 | "name": "python", 54 | "version": "3.12.9" 55 | } 56 | }, 57 | "nbformat": 4, 58 | "nbformat_minor": 2 59 | } 60 | -------------------------------------------------------------------------------- /guides/02_command_line.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# The command line" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Welcome to the guide to build your confidence working at the command line.\n", 15 | "\n", 16 | "By the end of this guide, you should be able to confidently work at the command line, creating directories, moving files and more!\n" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "## For Windows PC users\n", 24 | "\n", 25 | "Please see this briefing:\n", 26 | "\n", 27 | "https://chatgpt.com/share/68064acf-4d3c-8012-86a1-fb09a7c6f923" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "## For Mac users\n", 35 | "\n", 36 | "Please see this briefing:\n", 37 | "\n", 38 | "https://chatgpt.com/share/68064bfe-662c-8012-8073-479c32595459" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "Please do experiment to build your confidence.\n", 46 | "\n", 47 | "ChatGPT, Claude, Gemini, DeepSeek and others are your friends! They are excellent at explaining any command line commands in detail. This will quickly become second nature." 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [] 54 | } 55 | ], 56 | "metadata": { 57 | "language_info": { 58 | "name": "python" 59 | } 60 | }, 61 | "nbformat": 4, 62 | "nbformat_minor": 2 63 | } 64 | -------------------------------------------------------------------------------- /guides/03_git_and_github.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Git and Github" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "This guide is all about using source code control: Git and Github.\n", 15 | "\n", 16 | "By the end of this, you should be confident with every day code control processes, including fetching the latest code and submitting a PR to merge your own changes." 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "### Foundational briefing\n", 24 | "\n", 25 | "Here is Git and Github for a PC or Mac audience:\n", 26 | "\n", 27 | "https://chatgpt.com/share/68061486-08b8-8012-97bc-3264ad5ebcd4" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "### Pulling latest code\n", 35 | "\n", 36 | "I regularly add improvements to the course with new examples, exercises and materials.\n", 37 | "\n", 38 | "Here are instructions for how to bring in the latest - the easy way, and the rigorous way!\n", 39 | "\n", 40 | "https://chatgpt.com/share/6806178b-0700-8012-836f-7e87b2670b7b" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "### Contributing your changes to the repo\n", 48 | "\n", 49 | "Here are step by step instructions for submitting a PR.\n", 50 | "\n", 51 | "I'd be so grateful to include your contributions. It adds value for all other students, and I love to see it myself! As an added benefit, you get recognition in Github as a contributor to the repo.\n", 52 | "\n", 53 | "Here are detailed instructions. I see that ChatGPT has included mention of my other repo \"llm_engineering\" in this - obviously replace that with this repo name.\n", 54 | "\n", 55 | "https://chatgpt.com/share/68061a21-e2ec-8012-b700-024b3a97b1ba\n" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [] 62 | } 63 | ], 64 | "metadata": { 65 | "language_info": { 66 | "name": "python" 67 | } 68 | }, 69 | "nbformat": 4, 70 | "nbformat_minor": 2 71 | } 72 | -------------------------------------------------------------------------------- /guides/06_python_foundations.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "5c291475-8c7c-461c-9b12-545a887b2432", 6 | "metadata": {}, 7 | "source": [ 8 | "# Foundations of Python and fixing NameErrors\n", 9 | "\n", 10 | "## First, for a complete beginner\n", 11 | "\n", 12 | "This introductory tutorial gets you started with the basics.\n", 13 | "\n", 14 | "https://chatgpt.com/share/68063082-c2d8-8012-8d45-fa674aa1c1ed\n" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "id": "542f0577-a826-4613-a5d7-4170e9666d04", 20 | "metadata": {}, 21 | "source": [ 22 | "## Next: a comprehensive briefing on Python\n", 23 | "\n", 24 | "I'm going to defer to an AI friend for this, because these explanations are so well written with great examples. Copy and paste the code examples into a new cell to give them a try. Pick whichever section(s) you'd like to brush up on.\n", 25 | "\n", 26 | "**Python imports:** \n", 27 | "https://chatgpt.com/share/672f9f31-8114-8012-be09-29ef0d0140fb\n", 28 | "\n", 29 | "**Python functions** including default arguments: \n", 30 | "https://chatgpt.com/share/672f9f99-7060-8012-bfec-46d4cf77d672\n", 31 | "\n", 32 | "**Python strings**, including slicing, split/join, replace and literals: \n", 33 | "https://chatgpt.com/share/672fb526-0aa0-8012-9e00-ad1687c04518\n", 34 | "\n", 35 | "**Python f-strings** including number and date formatting: \n", 36 | "https://chatgpt.com/share/672fa125-0de0-8012-8e35-27918cbb481c\n", 37 | "\n", 38 | "**Python lists, dicts and sets**, including the `get()` method: \n", 39 | "https://chatgpt.com/share/672fa225-3f04-8012-91af-f9c95287da8d\n", 40 | "\n", 41 | "**Python files** including modes, encoding, context managers, Path, glob.glob: \n", 42 | "https://chatgpt.com/share/673b53b2-6d5c-8012-a344-221056c2f960\n", 43 | "\n", 44 | "**Python classes:** \n", 45 | "https://chatgpt.com/share/672fa07a-1014-8012-b2ea-6dc679552715\n", 46 | "\n", 47 | "**Pickling Python objects and converting to JSON:** \n", 48 | "https://chatgpt.com/share/673b553e-9d0c-8012-9919-f3bb5aa23e31" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "id": "f9e0f8e1-09b3-478b-ada7-c8c35003929b", 54 | "metadata": {}, 55 | "source": [ 56 | "## With this in mind - understanding NameErrors in Python\n", 57 | "\n", 58 | "It's quite common to hit a NameError in python. With foundational knowledge, you should always feel equipped to debug a NameError and get to the bottom of it.\n", 59 | "\n", 60 | "The most common reason if you're working in a Notebook is that you haven't executed all the cells in order, so the Kernel does not have something defined.\n", 61 | "\n", 62 | "If you're unsure how to fix a NameError, please see this [initial guide](https://chatgpt.com/share/67958312-ada0-8012-a1d3-62b3a5fcbbfc) and this [second guide with exercises](https://chatgpt.com/share/67a57e0b-0194-8012-bb50-8ea76c5995b8), and work through them both until you have high confidence.\n", 63 | "\n", 64 | "There's some repetition here, so feel free to skip it if you're already confident.\n", 65 | "\n", 66 | "After this, a NameError should never give you problems again!" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "id": "f465c23b", 72 | "metadata": {}, 73 | "source": [] 74 | } 75 | ], 76 | "metadata": { 77 | "kernelspec": { 78 | "display_name": "Python 3 (ipykernel)", 79 | "language": "python", 80 | "name": "python3" 81 | }, 82 | "language_info": { 83 | "codemirror_mode": { 84 | "name": "ipython", 85 | "version": 3 86 | }, 87 | "file_extension": ".py", 88 | "mimetype": "text/x-python", 89 | "name": "python", 90 | "nbconvert_exporter": "python", 91 | "pygments_lexer": "ipython3", 92 | "version": "3.11.11" 93 | } 94 | }, 95 | "nbformat": 4, 96 | "nbformat_minor": 5 97 | } 98 | -------------------------------------------------------------------------------- /guides/07_vibe_coding_and_debugging.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Vibe coding and debugging\n", 8 | "\n", 9 | "\"Vibe coding\" is the affectionate term for coding with the assistance of LLMs. It's particularly easy and wonderful to do with Cursor! But there are some good techniques to make it work well, which I cover on the course. Here are a few essential tips:" 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "1. If you're prompting an LLM like ChatGPT or Claude to write code, include the current date in your prompt, and instruct the LLM to generate code that uses the latest versions of APIs. This is particularly important with the OpenAI API! ChatGPT frequently tries to use outdated versions of its own API...\n", 17 | "\n", 18 | "2. Also in your prompts, ask LLMs to keep their code as short and simple as possible. LLMs seem to love to add lots of extra, unnecessary checks that clutters code and makes it hard to find problems.\n", 19 | "\n", 20 | "3. Ask the same question to multiple LLMs, and pick the answer that is clearest and simplest.\n", 21 | "\n", 22 | "4. Similar: take the answer from 1 LLM, and ask another LLM to verify it for correctness and whether it could be simpler or clearer.\n", 23 | "\n", 24 | "5. Ask an LLM to give you 3 variations for ways to solve a problem, and pick the one that is clearest." 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "## Vibe Coding for a larger project" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "Try to avoid having an LLM generate 100-200 lines of code or more; it will be so hard for you to debug and figure out what's going wrong (unless you're already knowledgable).\n", 39 | "\n", 40 | "Instead: start by breaking down your problem into small, independently testable steps, that are each relatively small. If you're not sure how to break down your problem - this is something you can ask the LLM to do!\n", 41 | "\n", 42 | "Then for each of these building blocks:\n", 43 | "- Use the tips above to have the LLM build the code\n", 44 | "- Also have the LLM write tests to test and verify the code\n", 45 | "- Test it yourself and satisfy yourself that it's working correctly\n", 46 | "\n", 47 | "This will allow you to build a larger project with confidence.\n", 48 | "\n", 49 | "## The golden rule: start small, work incrementally!" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [] 56 | } 57 | ], 58 | "metadata": { 59 | "language_info": { 60 | "name": "python" 61 | } 62 | }, 63 | "nbformat": 4, 64 | "nbformat_minor": 2 65 | } 66 | -------------------------------------------------------------------------------- /guides/08_debugging.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Debugging Survival Guide\n", 8 | "\n", 9 | "## The key is to consistently reproduce your problem in 5-10 lines of code\n", 10 | "\n", 11 | "Hitting an exception can sometimes feel quite frustrating, particularly if you're not sure how to approach it. But this is where the best learning happens! Getting to the bottom of hard problems is a great way to learn, and can be quite satisfying.\n", 12 | "\n", 13 | "But I'm here to help if you can't!" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "### Preliminaries\n", 21 | "\n", 22 | "Here is a briefing on Exceptions, Stack Traces, Exception Handling and more:\n", 23 | "\n", 24 | "https://chatgpt.com/share/6806383c-ab38-8012-b21f-61af665bb900\n", 25 | "\n", 26 | "Also: see [this guide](https://chatgpt.com/share/681f691b-6644-8012-b07d-207c68f259d5) if you're unsure how to take screenshots." 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "### Formula for debugging: recreate in 10 lines of code\n", 34 | "\n", 35 | "There is an art and a science to great debugging. The best way to pick it up is by practice! But here are the essentials:\n", 36 | "\n", 37 | "1. Recreate \n", 38 | "Reproduce your problem, consistently\n", 39 | "\n", 40 | "2. Simplify \n", 41 | "Reduce your problem down to the simplest possible way to reproduce it. I can't tell you how many people have sent me 100+ lines of code and said \"Ed, this isn't working, please fix it\". That's not how it works! The first thing I would try is to reduce this to the core problem - ideally in 10-20 lines of code or less. In one case, I showed a student how to reproduce it with 2 lines of code!\n", 42 | "\n", 43 | "_The thing is, it's much easier for **you** to do this than anybody else._ So while it can be tedious, this is almost always the best way to start. Reduce down to a few lines of code. And by the way, when you do that, you often figure out the problem yourself anyway!\n", 44 | "\n", 45 | "3. Get help \n", 46 | "Once you've recreated the problem with just a few lines of code, if you can't see what's happening - you should get help! It's worth asking ChatGPT and friends of course; give them the short example and the full stack trace.\n", 47 | "\n", 48 | "And reach out to me! I'm here to make your learning experience as awesome as possible and if you are stuck, I will help you get unstuck.\n", 49 | "\n", 50 | "### The best way to work with me for fastest fixes...\n", 51 | "\n", 52 | "1. Simplify the problem as much as possible, with an easy way to reproduce\n", 53 | "2. Include the full stack trace, and a screenshot not a photo (see [this guide](https://chatgpt.com/share/681f691b-6644-8012-b07d-207c68f259d5) if you're unsure how to take screenshots)\n", 54 | "3. Email me at ed@edwarddonner.com. Or best of all: if you've used Google Colab before, this is a really terrific way to share an issue, because it will be identical for me to reproduce, and I can fix it and share the fix with you directly.\n", 55 | "\n", 56 | "I look forward to helping you!\n" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [] 63 | } 64 | ], 65 | "metadata": { 66 | "language_info": { 67 | "name": "python" 68 | } 69 | }, 70 | "nbformat": 4, 71 | "nbformat_minor": 2 72 | } 73 | -------------------------------------------------------------------------------- /guides/11_async_python.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "5c291475-8c7c-461c-9b12-545a887b2432", 6 | "metadata": {}, 7 | "source": [ 8 | "# Async Python\n", 9 | "\n", 10 | "## A briefing on asynchronous python coding, essential in Agent engineering" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "id": "538fa044", 16 | "metadata": {}, 17 | "source": [ 18 | "Here is a masterful tutorial by you-know-who with exercises and comparisons.\n", 19 | "\n", 20 | "https://chatgpt.com/share/680648b1-b0a0-8012-8449-4f90b540886c\n", 21 | "\n", 22 | "This includes how to run async code from a python module.\n", 23 | "\n", 24 | "### And now some examples:" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 1, 30 | "id": "09f5662a", 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "# Let's define an async function\n", 35 | "\n", 36 | "import asyncio\n", 37 | "\n", 38 | "async def do_some_work():\n", 39 | " print(\"Starting work\")\n", 40 | " await asyncio.sleep(1)\n", 41 | " print(\"Work complete\")\n" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "id": "07ab3abf", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "# What will this do?\n", 52 | "\n", 53 | "do_some_work()" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "id": "6d681b6d", 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "# OK let's try that again!\n", 64 | "\n", 65 | "await do_some_work()" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "id": "ea867090", 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [ 75 | "# What's wrong with this?\n", 76 | "\n", 77 | "async def do_a_lot_of_work():\n", 78 | " do_some_work()\n", 79 | " do_some_work()\n", 80 | " do_some_work()\n", 81 | "\n", 82 | "await do_a_lot_of_work()" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "id": "e9c75c3f", 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [ 92 | "# Interesting warning! Let's fix it\n", 93 | "\n", 94 | "async def do_a_lot_of_work():\n", 95 | " await do_some_work()\n", 96 | " await do_some_work()\n", 97 | " await do_some_work()\n", 98 | "\n", 99 | "await do_a_lot_of_work()" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": null, 105 | "id": "720cf3f5", 106 | "metadata": {}, 107 | "outputs": [], 108 | "source": [ 109 | "# And now let's do it in parallel\n", 110 | "# It's important to recognize that this is not \"multi-threading\" in the way that you may be used to\n", 111 | "# The asyncio library is running on a single thread, but it's using a loop to switch between tasks while one is waiting\n", 112 | "\n", 113 | "async def do_a_lot_of_work_in_parallel():\n", 114 | " await asyncio.gather(do_some_work(), do_some_work(), do_some_work())\n", 115 | "\n", 116 | "await do_a_lot_of_work_in_parallel()" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "id": "230f85de", 122 | "metadata": {}, 123 | "source": [ 124 | "### Finally - try writing a python module that calls do_a_lot_of_work_in_parallel\n", 125 | "\n", 126 | "See the link at the top; you'll need something like this in your module:\n", 127 | "\n", 128 | "```python\n", 129 | "if __name__ == \"__main__\":\n", 130 | " asyncio.run(do_a_lot_of_work_in_parallel())\n", 131 | "```" 132 | ] 133 | } 134 | ], 135 | "metadata": { 136 | "kernelspec": { 137 | "display_name": ".venv", 138 | "language": "python", 139 | "name": "python3" 140 | }, 141 | "language_info": { 142 | "codemirror_mode": { 143 | "name": "ipython", 144 | "version": 3 145 | }, 146 | "file_extension": ".py", 147 | "mimetype": "text/x-python", 148 | "name": "python", 149 | "nbconvert_exporter": "python", 150 | "pygments_lexer": "ipython3", 151 | "version": "3.12.9" 152 | } 153 | }, 154 | "nbformat": 4, 155 | "nbformat_minor": 5 156 | } 157 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "agents" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | readme = "README.md" 6 | requires-python = ">=3.12" 7 | dependencies = [ 8 | "anthropic>=0.49.0", 9 | "autogen-agentchat>=0.4.9.2", 10 | "autogen-ext[grpc,mcp,ollama,openai]>=0.4.9.2", 11 | "bs4>=0.0.2", 12 | "google-genai>=1.14.0", 13 | "gradio>=5.22.0", 14 | "httpx>=0.28.1", 15 | "ipywidgets>=8.1.5", 16 | "langchain-anthropic>=0.3.10", 17 | "langchain-community>=0.3.20", 18 | "langchain-experimental>=0.3.4", 19 | "langchain-openai>=0.3.9", 20 | "langgraph>=0.3.18", 21 | "langgraph-checkpoint-sqlite>=2.0.6", 22 | "langsmith>=0.3.18", 23 | "lxml>=5.3.1", 24 | "mcp-server-fetch>=2025.1.17", 25 | "mcp[cli]>=1.5.0", 26 | "openai>=1.68.2", 27 | "openai-agents>=0.0.6", 28 | "playwright>=1.51.0", 29 | "plotly>=6.0.1", 30 | "polygon-api-client>=1.14.5", 31 | "psutil>=7.0.0", 32 | "pypdf>=5.4.0", 33 | "pypdf2>=3.0.1", 34 | "python-dotenv>=1.0.1", 35 | "python-hue-v2>=2.2.1", 36 | "requests>=2.32.3", 37 | "semantic-kernel>=1.25.0", 38 | "sendgrid>=6.11.0", 39 | "setuptools>=78.1.0", 40 | "smithery>=0.1.0", 41 | "speedtest-cli>=2.1.3", 42 | "wikipedia>=1.4.0", 43 | ] 44 | 45 | [dependency-groups] 46 | dev = [ 47 | "ipykernel>=6.29.5", 48 | ] 49 | -------------------------------------------------------------------------------- /setup/SETUP-WSL.md: -------------------------------------------------------------------------------- 1 | ## Master AI Agentic Engineering - build autonomous AI Agents 2 | 3 | # Setting up WSL - Windows Subsytem for Linux 4 | 5 | _NOTE 1: These instructions assume that you've already carried out the PC Setup instructions_ 6 | 7 | _NOTE 2: In Cursor, remember to Right Click on this file in the Explorer and choose "Open Preview" to see the formatting._ 8 | 9 | Welcome back to Setup-land, PC people! 10 | 11 | I expect you're here because you've reached Week 6, and discovered the unpleasant news that MCP Servers are only working on Windows under WSL. 12 | 13 | I'm so sorry to put you through this! The good news is, several students have confirmed that MCP Servers are working under WSL. Also, WSL is generally considered a great way to build on Windows. And the other good news is that you've already done the setup once, so surely this will be relatively painless? Fingers crossed. 14 | 15 | ### Part 1: Install WSL if you haven't before 16 | 17 | WSL is the Microsoft recommended way to run Linux on your Windows PC, as described here: 18 | https://learn.microsoft.com/en-us/windows/wsl/install 19 | 20 | We will be using the default Ubuntu distribution of Linux, which seems to work fine. Let's do this! 21 | 22 | 1. Open a powershell 23 | 2. Run: `wsl --install` 24 | 3. Select to allow elevated permissions when it asks; then wait for Ubuntu to install 25 | 4. Then run `wsl` to start it and set your Linux username and password 26 | 5. Type `pwd` and `ls` to see what directory you're in, and list the contents. Then type `cd` to change to your home directory, and repeat. 27 | 28 | It's important to appreciate the difference between your Windows home directory, and this new home directory in your Linux WSL world.. 29 | 30 | ### Part 2: Install uv and repo 31 | 32 | 1. In a WSL window (i.e. a Powershell after you've typed 'wsl') - we will follow the linux instructions here: https://docs.astral.sh/uv/getting-started/installation/ and run `curl -LsSf https://astral.sh/uv/install.sh | sh` 33 | 2. After that completes, you need to type `exit` to leave WSL and return to the Powershell and then type `wsl` to return to Linux, in order that changes to PATH are picked up 34 | 3. Now type `cd` to go to your Linux home directory. Check you're there with `pwd` and `ls` 35 | 4. Now create a projects directory with `mkdir projects` then `cd projects` to go into it 36 | 5. And, from within your new projects directory, clone the repo with `git clone https://github.com/ed-donner/agents.git` 37 | 6. Now go into your new agents directory, your Project Root Directory, with `cd agents` 38 | 7. And now run the all-powerful `uv sync` 39 | 40 | At this point, I experienced an unpleasant memory error. I believe it's related to my setup, and you shouldn't hit it. But if you do, please let me know - I have a fix! 41 | 42 | ### Part 3: Configure Cursor running in your PC environment 43 | 44 | 1. Open Cursor, the usual way, on your PC 45 | 2. Bring up the Extensions panel (View menu >> Extensions or Ctrl+Shift+X), search for WSL, see WSL by Anysphere (the makers of Cursor) and Install it 46 | 3. Now press Ctrl+Shift+P and search for Remote-WSL: New Window and select it to Open a new window configured for WSL 47 | 4. Select Open Project (then get a coffee), and navigate to your new "agents" project root directory in Linux, and then Open or Select Folder 48 | 5. Bring up the Extensions panel again (Ctrl+Shift+X) and install these Extensions in your WSL if not already installed: Python (ms-python), and Jupyter (microsoft), clicking the "Install in WSL-Ubuntu" button 49 | 50 | ### And you should be ready to roll! 51 | 52 | You'll need to create a new ".env" file in the agents folder, and copy across your .env from your other project. And you'll need to click "Select Kernel" and "Choose python environment..". 53 | 54 | Enjoy MCP! --------------------------------------------------------------------------------