Build custom agents
Build an agent around your workflow. Combine TabulaFlow's reusable tools with
your own queries and actions, without adopting ChatSession.
Example: Build a customer support agent
A customer's USB-C dock won't charge their laptop, and they cannot find the order number. Build an agent that finds the order, consults product guides, and opens a support ticket.
custom_agents.py
import asyncio
from importlib.resources import files
from pathlib import Path
from tempfile import TemporaryDirectory
import pandas as pd
from tabulaflow.agents.llm import make_agent
from tabulaflow.agents.tools import RunQueryTool, ViewTool
from tabulaflow.data import SQLConnector
async def prepare_example(orders: SQLConnector, support_dir: Path) -> None:
await orders.write_dataframe_async(
pd.DataFrame(
[
(1001, 7, "USB-C dock", "2026-08-18", "delivered"),
(1002, 8, "Monitor", "2026-08-20", "shipped"),
(1003, 7, "Laptop stand", "2026-08-22", "shipped"),
(1004, 7, "USB-C dock", "2025-11-05", "delivered"),
],
columns=["order_id", "customer_id", "product", "purchased_on", "status"],
),
"orders",
)
bundled = files("tabulaflow.examples.support")
for name in ("faq.txt", "dock-guide.pdf"):
(support_dir / name).write_bytes(bundled.joinpath(name).read_bytes())
async def run_support_agent(orders: SQLConnector, support_dir: Path) -> None:
query = RunQueryTool(orders)
tickets: list[dict[str, str | int]] = []
async def get_orders() -> str:
"""List the signed-in customer's orders, newest first."""
result = await query.execute(
"SELECT order_id, product, purchased_on, status FROM orders "
"WHERE customer_id = 7 ORDER BY purchased_on DESC"
)
return result.output
async def open_support_ticket(order_id: int, issue: str) -> str:
"""Open a support ticket and return its ID."""
ticket_id = f"SUP-{len(tickets) + 1}"
tickets.append({"ticket_id": ticket_id, "order_id": order_id, "issue": issue})
return ticket_id
agent = make_agent(
"openai:gpt-5.6-sol",
instructions=(
"You are a customer support agent. Follow faq.txt, consult product guides, "
"look up the customer's order, and cite the files you use."
),
tools=[
ViewTool(working_dir=str(support_dir)).as_pydantic_ai_tool(),
get_orders,
open_support_ticket,
],
)
result = await agent.run(
"My newest USB-C dock still won't charge my laptop. I already enabled Laptop charging "
"and reconnected the USB-C cable. Please open a support ticket."
)
print(result.output)
print("Tickets:", tickets)
async def main() -> None:
with TemporaryDirectory() as directory:
orders = await SQLConnector.from_url_async("sqlite+aiosqlite:///:memory:", read_only=False)
async with orders:
await prepare_example(orders, Path(directory))
await run_support_agent(orders, Path(directory))
if __name__ == "__main__":
asyncio.run(main())
Sample output
Thanks — I opened a technical-support ticket for your newest USB-C dock (order 1001).
Summary (from your report and our checks)
- Product/order: USB-C dock — order 1001 (purchased 2026-08-18). I looked this up in your orders list (orders table).
- Reported issue: Dock will not charge the laptop.
- Troubleshooting already tried (per your message): You enabled Laptop charging in Dock settings and reconnected the host USB-C cable (matches steps 1–2 in the dock guide).
- Guide consulted: dock-guide.pdf (USB-C dock: charging help).
- FAQ consulted: faq.txt (USB-C dock not charging a laptop).
Support ticket
- Ticket ID: SUP-1
- Included in ticket: product, order number, reported issue, and steps already tried.
Next steps
- Our support team will follow up on ticket SUP-1. If you can, please reply with:
- The laptop make/model and operating system,
- Whether the dock’s external power adapter is connected and showing any LEDs,
- Any error messages or indicators on the dock or laptop.
These details speed diagnosis.
Files I used
- faq.txt (customer-support FAQ, troubleshooting instructions)
- dock-guide.pdf (USB-C dock: charging help)
Anything else you’d like me to add to the ticket before I hand it over?
Tickets: [{'ticket_id': 'SUP-1', 'order_id': 1001, 'issue': "USB-C dock not charging laptop. Customer reports they enabled 'Laptop charging' in Dock settings > Power and disconnected/reconnected the host USB-C cable, but laptop still will not charge. Requested a technical-support ticket for order 1001 (USB-C dock)."}]
Set OPENAI_API_KEY, then run the complete example:
tabulaflow examples run custom-agents
The example intentionally keeps application concerns lightweight: the signed-in customer is fixed, and tickets are stored in memory. In a real application, derive customer identity from authentication and persist tickets in your support system. Use a model with PDF input support.