-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtools.py
More file actions
77 lines (60 loc) · 2.24 KB
/
Copy pathtools.py
File metadata and controls
77 lines (60 loc) · 2.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# pyright: strict
"""
Commerce tools for the shopping-assistant agent.
These are plain Python functions. A "tool" is nothing more than a function
the model is allowed to call — these are deliberately ordinary so you can
see that for yourself. Both notebooks in this folder import them:
* 01-raw-agent.ipynb describes them with a hand-written JSON schema
* 02-langgraph-agent.ipynb wraps them with the @tool decorator
Same functions, two ways of handing them to a model.
"""
import json
from pathlib import Path
from typing import TypedDict
class Product(TypedDict):
"""One row of the product catalogue (see products.json)."""
product_id: str
name: str
category: str
price_chf: float
tags: list[str]
in_stock: bool
rating: float
description: str
_CATALOG: list[Product] = json.loads(
(Path(__file__).parent / "products.json").read_text()
)
def search_products(query: str) -> str:
"""Search the product catalogue by keyword.
Returns a JSON list of matching products (id, name, price, category).
"""
q = query.lower().strip()
hits = [p for p in _CATALOG if _matches(p, q)]
# Fall back to per-word matching so "warm jacket" still finds "jacket".
if not hits:
words = [w for w in q.split() if len(w) > 2]
hits = [p for p in _CATALOG if any(_matches(p, w) for w in words)]
return json.dumps(
[
{
"product_id": p["product_id"],
"name": p["name"],
"price_chf": p["price_chf"],
"category": p["category"],
"in_stock": p["in_stock"],
}
for p in hits[:5]
]
)
def get_product_details(product_id: str) -> str:
"""Return the full record for one product, by its product_id, as JSON."""
for p in _CATALOG:
if p["product_id"].lower() == product_id.lower().strip():
return json.dumps(p)
return json.dumps({"error": f"No product found with id '{product_id}'"})
def _matches(product: Product, term: str) -> bool:
"""True if `term` appears anywhere in a product's searchable text."""
haystack = " ".join(
[product["name"], product["category"], " ".join(product["tags"])]
).lower()
return term in haystack