from typing import List, Optional
from agno.agent import Agent
from agno.media import File
from agno.models.openai import OpenAIResponses
from pydantic import BaseModel, Field
class LineItem(BaseModel):
description: str
quantity: Optional[float] = None
unit_price: Optional[float] = None
amount: Optional[float] = None
class Invoice(BaseModel):
invoice_number: Optional[str] = Field(None, description="As printed on the invoice")
vendor: Optional[str] = None
invoice_date: Optional[str] = None
due_date: Optional[str] = None
subtotal: Optional[float] = None
tax: Optional[float] = None
total: Optional[float] = None
currency: Optional[str] = Field(None, description="ISO 4217, e.g. USD, EUR")
lines: List[LineItem] = Field(default_factory=list)
agent = Agent(
model=OpenAIResponses(id="gpt-5.5"),
instructions=(
"Extract invoice fields and line items from the attached PDF. "
"Use exactly what the document shows. If a field is missing, "
"leave it null. Do not guess."
),
output_schema=Invoice,
)
result = agent.run(
"Extract the invoice.",
files=[File(url="https://example.com/invoice-1042.pdf")],
).content
# Invoice(invoice_number='1042', vendor='Acme Corp', invoice_date='2026-04-12',
# due_date='2026-05-12', subtotal=1200.0, tax=96.0, total=1296.0,
# currency='USD', lines=[LineItem(...), LineItem(...)])