PD03 commited on
Commit
33004b7
·
verified ·
1 Parent(s): fc2bbb9

Upload app 2.py

Browse files
Files changed (1) hide show
  1. app 2.py +157 -0
app 2.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json, os, time, uuid
3
+ from smolagents import CodeAgent, tool
4
+ from smolagents.models import LiteLLMModel
5
+ try:
6
+ from smolagents import HfApiModel
7
+ except Exception:
8
+ HfApiModel = None
9
+
10
+ # --------- Shared model factory ---------
11
+ def get_model():
12
+ if os.getenv("OPENAI_API_KEY"):
13
+ return LiteLLMModel(model_id=os.getenv("OPENAI_MODEL","gpt-5"),
14
+ api_key=os.getenv("OPENAI_API_KEY"))
15
+ elif HfApiModel is not None:
16
+ return HfApiModel(os.getenv("HF_MODEL","Qwen/Qwen2.5-7B-Instruct"))
17
+ else:
18
+ raise RuntimeError("No model available. Set OPENAI_API_KEY or install HF Inference support.")
19
+
20
+ # =======================================
21
+ # Exercise 1: Hello Tools (add + multiply)
22
+ # =======================================
23
+ @tool
24
+ def add(a: float, b: float) -> float:
25
+ """Return a+b"""
26
+ return a + b
27
+
28
+ @tool
29
+ def mul(a: float, b: float) -> float:
30
+ """Return a*b"""
31
+ return a * b
32
+
33
+ def run_ex1():
34
+ system = (
35
+ "You are a careful math assistant. Use the available tools to compute the answer.\n"
36
+ "Finally, PRINT ONLY a JSON object like {\"result\": <number>}."
37
+ )
38
+ agent = CodeAgent(
39
+ tools=[add, mul],
40
+ model=get_model(),
41
+ system_prompt=system,
42
+ add_base_tools=False,
43
+ verbosity_level=1,
44
+ temperature=0.0,
45
+ )
46
+ goal = "Compute 2 * (3 + 4) and return {\"result\": 14}."
47
+ out = agent.run(goal)
48
+ return str(out)
49
+
50
+ # =======================================
51
+ # Exercise 2: Guardrails + fixed plan
52
+ # =======================================
53
+ def run_ex2():
54
+ system = (
55
+ "Follow this fixed plan exactly:\n"
56
+ "1) Call add(a=3, b=4) and store the result in x.\n"
57
+ "2) Call mul(a=2, b=x) to compute y.\n"
58
+ "3) PRINT ONLY this JSON: {\"result\": y}\n"
59
+ "Never print explanations."
60
+ )
61
+ agent = CodeAgent(
62
+ tools=[add, mul],
63
+ model=get_model(),
64
+ system_prompt=system,
65
+ add_base_tools=False,
66
+ verbosity_level=1,
67
+ temperature=0.0,
68
+ )
69
+ goal = "Please give me the product of two and the sum of three and four — as JSON."
70
+ out = agent.run(goal)
71
+ return str(out)
72
+
73
+ # =======================================
74
+ # Exercise 3: Mini PR -> PO
75
+ # =======================================
76
+ @tool
77
+ def validate_pr(pr: dict) -> dict:
78
+ """Return {ok: bool, errors: [...]} after checking pr_id, requester, cost_center, currency, items."""
79
+ req = ["pr_id","requester","cost_center","currency","items"]
80
+ errors = [f"Missing {k}" for k in req if k not in pr]
81
+ if not isinstance(pr.get("items", []), list) or not pr["items"]:
82
+ errors.append("Items must be a non-empty list")
83
+ return {"ok": len(errors)==0, "errors": errors}
84
+
85
+ @tool
86
+ def create_po(pr: dict) -> dict:
87
+ """Create a simple PO JSON with totals and a generated po_id."""
88
+ subtotal = 0.0
89
+ items_out = []
90
+ for it in pr.get("items", []):
91
+ line = float(it["quantity"]) * float(it["unit_price"])
92
+ items_out.append({"sku": it["sku"], "line_total": round(line,2)})
93
+ subtotal += line
94
+ tax = round(subtotal * 0.08, 2)
95
+ total = round(subtotal + tax, 2)
96
+ return {
97
+ "po_id": f"PO-{int(time.time())}-{uuid.uuid4().hex[:6].upper()}",
98
+ "currency": pr.get("currency","SGD"),
99
+ "items": items_out,
100
+ "subtotal": round(subtotal,2),
101
+ "tax": tax,
102
+ "total": total,
103
+ "source_pr_id": pr.get("pr_id")
104
+ }
105
+
106
+ DEFAULT_PR = json.dumps({
107
+ "pr_id": "PR-1001",
108
+ "requester": "A. Tan",
109
+ "cost_center": "CC-SG-OPS",
110
+ "currency": "SGD",
111
+ "items": [
112
+ {"sku":"PAPER-A4-80G","quantity":20,"unit_price":6.8},
113
+ {"sku":"STAPLER-01","quantity":5,"unit_price":18.5}
114
+ ]
115
+ }, indent=2)
116
+
117
+ def run_ex3(pr_text):
118
+ try:
119
+ pr = json.loads(pr_text)
120
+ except Exception as e:
121
+ return f"Invalid JSON: {e}"
122
+ system = (
123
+ "You are a procurement agent. Use the tools as follows:\n"
124
+ "1) validate_pr(pr). If ok==false, PRINT ONLY {\"error\": errors}.\n"
125
+ "2) If ok==true, call create_po(pr).\n"
126
+ "3) PRINT ONLY the resulting PO JSON. No extra text."
127
+ )
128
+ agent = CodeAgent(
129
+ tools=[validate_pr, create_po],
130
+ model=get_model(),
131
+ system_prompt=system,
132
+ add_base_tools=False,
133
+ verbosity_level=1,
134
+ temperature=0.0,
135
+ )
136
+ goal = "Convert this PR to a PO (strict JSON). PR is in additional_context['pr']."
137
+ out = agent.run(goal, additional_context={"pr": pr})
138
+ return str(out)
139
+
140
+ with gr.Blocks(title="Smolagents Beginner Lab (Online)") as demo:
141
+ gr.Markdown("# Smolagents Beginner Lab (Online)")
142
+ gr.Markdown("Click the buttons to run the exercises in the cloud. Set `OPENAI_API_KEY` in Space secrets for best results.")
143
+ with gr.Tab("1) Hello Tools"):
144
+ btn1 = gr.Button("Run Exercise 1")
145
+ out1 = gr.Textbox(label="Output", lines=6)
146
+ btn1.click(lambda: run_ex1(), inputs=None, outputs=out1)
147
+ with gr.Tab("2) Guardrails (deterministic)"):
148
+ btn2 = gr.Button("Run Exercise 2")
149
+ out2 = gr.Textbox(label="Output", lines=6)
150
+ btn2.click(lambda: run_ex2(), inputs=None, outputs=out2)
151
+ with gr.Tab("3) Mini PR → PO"):
152
+ pr_input = gr.Textbox(label="PR JSON", value=DEFAULT_PR, lines=16)
153
+ btn3 = gr.Button("Run Exercise 3")
154
+ out3 = gr.Textbox(label="Output", lines=10)
155
+ btn3.click(run_ex3, inputs=pr_input, outputs=out3)
156
+
157
+ demo.launch()