| Tool | Owner | Permission |
|---|---|---|
search_catalog | product-lookup skill | READ_ONLY |
create_order | order-placement skill | ADMIN |
update_order_status | order-placement skill | ADMIN |
check_inventory | inventory-check skill | READ_ONLY |
get_customer_profile | agent-level (no skill) | READ_ONLY |
get_customer_profile is declared directly on the agent, not inside any skill. It is available across all skills without restriction.
To see these tools in action, see the Sample query walkthrough.
Full implementation
PYTHON
from ibm_watsonx_orchestrate.agent_builder.tools import tool, ToolPermission
_ORDER_SEQ = 2000
_PRODUCTS = {
"SKU-001": {"name": "Widget Pro", "price": 29.99, "stock": 250, "category": "electronics"},
"SKU-002": {"name": "Gadget Max", "price": 149.00, "stock": 5, "category": "electronics"},
"SKU-003": {"name": "Comfort Chair", "price": 399.00, "stock": 0, "category": "home"},
"SKU-004": {"name": "Running Shoes", "price": 89.50, "stock": 120, "category": "sports"},
}
_ORDERS: dict = {}
_CUSTOMERS = {
"CUST-001": {"name": "Alice Johnson", "tier": "gold", "credit_limit": 50000},
"CUST-002": {"name": "Bob Smith", "tier": "standard", "credit_limit": 5000},
}
@tool(name="search_catalog",
description="Search the product catalog by keyword or category",
permission=ToolPermission.READ_ONLY)
def search_catalog(query: str, category: str = None) -> dict:
"""
Search the product catalog by keyword or category.
:param query: search term (product name, SKU, or keyword)
:param category: optional category filter (electronics, clothing, home, sports)
"""
results = []
q = query.lower()
for sku, p in _PRODUCTS.items():
if category and p["category"] != category:
continue
if q in p["name"].lower() or q in sku.lower() or q in p["category"]:
results.append({
"sku": sku,
"name": p["name"],
"price": p["price"],
"category": p["category"],
"in_stock": p["stock"] > 0,
"stock_count": p["stock"],
})
return {"query": query, "count": len(results), "results": results}
@tool(name="create_order",
description="Create a new customer order and return its record",
permission=ToolPermission.ADMIN)
def create_order(product_id: str, quantity: int, unit_price: float) -> dict:
"""
Create a new customer order and return its record.
:param product_id: product identifier (e.g. SKU-001)
:param quantity: number of units to order
:param unit_price: price per unit in USD
"""
global _ORDER_SEQ
_ORDER_SEQ += 1
order_id = f"ORD-{_ORDER_SEQ}"
_ORDERS[order_id] = {
"order_id": order_id,
"product_id": product_id,
"quantity": quantity,
"unit_price": unit_price,
"total": round(quantity * unit_price, 2),
"status": "pending",
}
return _ORDERS[order_id]
@tool(name="update_order_status",
description="Update the status of an existing order",
permission=ToolPermission.ADMIN)
def update_order_status(order_id: str, status: str) -> dict:
"""
Update the status of an existing order.
:param order_id: the order identifier (e.g. ORD-2001)
:param status: new status — one of: pending, confirmed, shipped, delivered, cancelled
"""
allowed = {"pending", "confirmed", "shipped", "delivered", "cancelled"}
if status not in allowed:
return {"success": False, "error": f"Invalid status '{status}'. Allowed: {sorted(allowed)}"}
if order_id not in _ORDERS:
return {"success": False, "error": f"Order '{order_id}' not found"}
_ORDERS[order_id]["status"] = status
return {"success": True, "order_id": order_id, "status": status}
@tool(name="check_inventory",
description="Return current inventory data for a product",
permission=ToolPermission.READ_ONLY)
def check_inventory(product_id: str) -> dict:
"""
Return current inventory data for a product.
:param product_id: product identifier (e.g. SKU-001)
"""
p = _PRODUCTS.get(product_id)
if not p:
return {"found": False, "product_id": product_id, "error": "Product not found"}
return {
"found": True,
"product_id": product_id,
"name": p["name"],
"current_stock": p["stock"],
"daily_demand": 8.5,
}
@tool(name="get_customer_profile",
description="Retrieve a customer's profile including account tier and credit limit",
permission=ToolPermission.READ_ONLY)
def get_customer_profile(customer_id: str) -> dict:
"""
Retrieve a customer's profile including account tier and credit limit.
This is an agent-level tool — it belongs to the agent, not to any skill.
:param customer_id: customer identifier (e.g. CUST-001)
"""
c = _CUSTOMERS.get(customer_id)
if not c:
return {"found": False, "customer_id": customer_id, "error": "Customer not found"}
return {"found": True, "customer_id": customer_id, **c}
Next steps
- See Operations assistant to understand how these tools are assigned to the agent and its skills.
- See Order placement skill for how
create_orderandupdate_order_statusare used. - See Inventory check skill for how
check_inventoryis used.

