Skip to content

TypeError: Cannot instantiate typing.Union #1411

@abdulhadi240

Description

@abdulhadi240

Below is my full code

from __future__ import annotations
import asyncio
from typing import Optional
from tavily import TavilyClient
from agents import Agent, Runner, function_tool, set_tracing_disabled
from agents.extensions.models.litellm_model import LitellmModel
from agents.extensions.visualization import draw_graph
from openai import AsyncOpenAI
from openai.types.responses import ResponseTextDeltaEvent
from google.colab import userdata

# Get API keys
GEMINI_API_KEY = userdata.get('GOOGLE_API_KEY')
TAVILY_API_KEY = "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"  # Consider moving to userdata

# Model configuration
MODEL = 'gemini/gemini-2.0-flash'

# Initialize Tavily client for research
tavily_client = TavilyClient(TAVILY_API_KEY)

# Disable tracing for performance
set_tracing_disabled(disabled=True)


@function_tool
def send_email(body: str) -> str:
    """Send an email with the specified body text."""
    print(f"Sending email with body: {body[:100]}...")  # Show first 100 chars
    return "The email has been sent successfully"


@function_tool
def research(query: str) -> list:
    """Perform web research on a given query."""
    print(f"Researching: {query}")
    response = tavily_client.search(query=query)
    return response["results"]


# Email Agent
email_agent = Agent(
    name="Email Agent",
    instructions="""
        You are the Email Agent.
        Your sole responsibility is to send emails using the `send_email` tool.
        The `send_email` tool has a single parameter: `body` (string), which is the full text of the email.

        When you are asked to send an email:
        1. Extract the exact email text from the user's request (do not add or remove words unless explicitly instructed).
        2. Pass the complete email text as the `body` parameter to the `send_email` tool.

        Do not answer general questions, perform research, or do any other task.
        If the request is not about sending an email, hand it off to the appropriate agent.
    """,
    model=LitellmModel(
        model=MODEL,
        api_key=GEMINI_API_KEY
    ),
    tools=[send_email],
    handoff_description="Handles email sending requests."
)

# Research Agent
research_agent = Agent(
    name="Research Agent",
    instructions="""
        You are the Research Agent.
        Your job is to gather detailed, factual, and up-to-date information using the `research` tool.
        The `research` tool has one required parameter: `query` (string), which is the exact search query.

        For every user request you receive:
        1. Identify the core research topic from the request.
        2. Call the `research` tool with the topic as the `query` parameter (worded naturally for best search results).
        3. Return the research results to the user in a well-structured and concise way.

        Do not make up answers — always use the `research` tool for factual queries.
        If the request is unrelated to research, hand it off to the correct agent.
    """,
    model=LitellmModel(
        model=MODEL,
        api_key=GEMINI_API_KEY
    ),
    tools=[research],
    handoff_description="Handles research and fact-finding tasks."
)


async def main():
    """Main function to run the agent system."""
    
    # General Assistant (Orchestrator)
    general_assistant = Agent(
        name="General Assistant",
        instructions="""
            You are the General Assistant.
            Your goal is to help the user by either:
            - Answering the question directly if you have sufficient knowledge.
            - Handing off the request to the correct specialized agent when it matches their role.

            The specialized agents are:
            1. Research Agent — for fact-checking, gathering latest news, or answering knowledge-based questions.
            2. Email Agent — for composing and sending emails.

            Rules:
            - If the query is about research or factual updates, hand it off to the Research Agent.
            - If the query is about sending an email, hand it off to the Email Agent.
            - If the query involves both research and email sending, handle each part with the correct agent separately.
            - Do not ask the user if they want a transfer — just hand it off automatically.
            - Get back the results from the agent and return them in proper markdown format.
        """,
        model=LitellmModel(
            model=MODEL,
            api_key=GEMINI_API_KEY
        ),
        tools=[
            research_agent.as_tool(
                tool_name="research_agent",
                tool_description="This tool performs web searches and returns research results"
            ),
            email_agent.as_tool(
                tool_name="email_agent",
                tool_description="This tool is used to send emails"
            )
        ]
    )
    
    # Example query with both research and email tasks
    query = "Give me a detailed 300-word news article on OpenAI's latest model, and send an email saying 'Tomorrow is the meeting at 10 PM, be there on time.'"
    
    # Run the agent with streaming
    result = Runner.run_streamed(general_assistant, query)
    
    # Stream the response
    async for event in result.stream_events():
        if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent):
            print(event.data.delta, end="", flush=True)
    
    print("\n")  # New line after streaming completes


# Run the async main function
if __name__ == "__main__":
    asyncio.run(main())

ERROR :

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
[/tmp/ipython-input-3639346673.py](https://localhost:8080/#) in <cell line: 0>()
    139 
    140 
--> 141 asyncio.run(main())

17 frames
[/usr/lib/python3.11/typing.py](https://localhost:8080/#) in __call__(self, *args, **kwds)
    484 
    485     def __call__(self, *args, **kwds):
--> 486         raise TypeError(f"Cannot instantiate {self!r}")
    487 
    488     def __or__(self, other):

TypeError: Cannot instantiate typing.Union
----------------------------------------------------------------------------------------------------------------------

Note it was working perfectly Yesterday !

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingduplicateThis issue or pull request already exists

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions