Pydentik Task Output Issue

Can anyone exyplain how to give pydantic task output as input for second task?

Task yaml:

email_classification_task:
  description: >
    Categorize new incoming emails based on the subject and content.
    Identify and separate diaper and dog food offers from other emails.
    Consider different words (also in German) for Hundefutter and Windeln in your analysis.
    You should use content from scraped links in ${link_docs}.
    Check if the ${sender} is a company.
    If it is a business, check if it is a business in a relevant area.
    Search for relevant information in the email.
    Only forward content that was classified as relevant to the offer_analyzer.
  expected_output: >
    The mail has a classification if it is relevant or not. It should have classification values for the offer analysis.
  output_pydantic: ClassifiedMail  # Ensure that this output is mapped correctly.
  agent: email_classifier
  inputs:
    - id: ${id}
    - link_docs: ${link_docs}  # Content from the scraped links to aid classification.
    - sender: ${sender}
    - content: ${content}
    - subject: ${subject}

offer_analysis_task:
  description: >
    Analyze the ${classified_emails} for Windeln and Hundefutter offers.
    Compare prices, discounts, and quality to determine the best offers available.
    Filter out offers that are not relevant.
    Do not make up offers; only use input from the email_classifier agent.
    Do not hallucinate.
  expected_output: >
    A markdown list with relevant offers for diapers and dog food, including prices, discounts, 
    and links to the respective offers.
  agent: offer_analyzer
  inputs:
    - classified_emails: ${email_classification_task.output_pydantic}

agent.yaml:

email_classifier:
  role: >
    Email Classification Expert
  goal: >
    Categorize incoming emails into diaper offers and dog food offers.
  backstory: >
    You are an experienced assistant who knows a lot about the following apps: GoogleMail.
    You are able to perform any task asked by the user through all the tools you have access to. 
    Your goal is to complete the user's task by using the tools you have access to.
    You think step by step.
        
offer_analyzer:
  role: >
    Offer Analysis Specialist
  goal: >
    Analyze diaper and dog food offers to find the best deals and report on them.
  backstory: >
    You are known for your expertise in offer comparison and 
    data-driven analysis of product deals. With a focus on finding 
    the best deals in baby and pet products, you ensure only the top 
    offers are selected.```

Pydantic Model:

class ClassifiedMail(BaseModel):
id: int = Field(…, description=“Unique identifier for the classified email”)
sender: str = Field(…, description=“Email address of the sender”)
subject: str = Field(…, description=“Subject line of the classified email”)
content: str = Field(…, description=“Body content of the classified email”)
link_doc: Dict[str, Any] = Field(…, description=“Dictionary containing links and their related documentation or metadata”)
classification_label: str = Field(…, description=“Label indicating the classification of the email (e.g., Hundefutter, Windeln, nicht relevant)”)

def __init__(self, **data):
    super().__init__(**data)

def get_field_info_json(self) -> str:
    field_info = "\n"
    for field_name, field_instance in self.__fields__.items():
        field_info += f"{field_name}, described as: {field_instance.description}\n"
    return field_info

Error: 

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\projects\mail_monitoring_agent\src\mail_monitoring_agent\main.py", line 49, in run
    asyncio.run(execute())
  File "C:\Users\cschn\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\cschn\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\cschn\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\projects\mail_monitoring_agent\src\mail_monitoring_agent\main.py", line 42, in execute
    MailMonitoringAgentCrew().crew().kickoff(inputs=inputs)
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\cschn\AppData\Local\pypoetry\Cache\virtualenvs\mail-monitoring-agent-ZvywjxM--py3.12\Lib\site-packages\crewai\project\crew_base.py", line 35, in __init__
    self.map_all_task_variables()
  File "C:\Users\cschn\AppData\Local\pypoetry\Cache\virtualenvs\mail-monitoring-agent-ZvywjxM--py3.12\Lib\site-packages\crewai\project\crew_base.py", line 133, in map_all_task_variables
    self._map_task_variables(
  File "C:\Users\cschn\AppData\Local\pypoetry\Cache\virtualenvs\mail-monitoring-agent-ZvywjxM--py3.12\Lib\site-packages\crewai\project\crew_base.py", line 175, in _map_task_variables
    output_pydantic_functions[output_pydantic]
    ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
KeyError: 'ClassifiedMail'
An error occurred while running the crew: Command '['poetry', 'run', 'run_crew']' returned non-zero exit status 1.

I don’t know if this is confusing things but I don’t see where inputs: is a valid Task attribute in the docs.

This was the recommendation of the crewai chat tool.
Is there somewhere an example of how i would do it correctly?

The goal is to use the pydantic model as structured output format from task 1 as input for task 2. I would like to have concrete properties that i can use within the prompt of task 2 to better guide what the task is about to achieve.

Removing the second task input doesn’t solve the problem.
It seems it cannot handle the output_pydantic model in the email_classification_task.

This seems to cause the errors: output_pydantic: ClassifiedMail
Any Idea what might be wrong?

It was just hallucinating. Look at this example.

Hmm, doesnt work. Same error.
I¨m using Ollama as Backend and starting to belive that output_json and output_pydantic only work with OpenAI…

Yes. Small open source models have a hard time with tool use etc. If you have enough vram, use command-r as the general llm and nexus raven v2 as function_calling_llm. Then in the description etc say that proper format must be used when using tools or converting data to pydsntic schema, etc.