PD03 commited on
Commit
107143e
·
verified ·
1 Parent(s): 837c0b8

Update agentic_sourcing_ppo_sap_colab.py

Browse files
Files changed (1) hide show
  1. agentic_sourcing_ppo_sap_colab.py +61 -18
agentic_sourcing_ppo_sap_colab.py CHANGED
@@ -1,7 +1,7 @@
1
  """
2
- agentic_sourcing_ppo_sap_colab.py - FIXED FOR STREAMLIT
3
- -------------------------------------------------------
4
- Fixed version that eliminates hanging and pickle errors
5
  """
6
 
7
  # ===================== STREAMLIT COMPATIBILITY SETUP =====================
@@ -81,7 +81,7 @@ def _build_obs(volatility: str, demand_mult: float, price_mult: float, suppliers
81
  ]
82
  return np.asarray(obs, dtype=np.float32)
83
 
84
- # ===================== GLOBAL MOCK MODEL CLASS (FIXES PICKLE ERROR) =====================
85
  class GlobalMockPPO:
86
  """Global mock PPO model that can be pickled properly"""
87
 
@@ -121,22 +121,34 @@ _MODEL_CACHE = {"obj": None, "path": None}
121
  def _get_model():
122
  """Get model without file operations that cause hanging"""
123
  if _MODEL_CACHE["obj"] is None:
124
- # Always use the global mock model - no file operations
125
  _MODEL_CACHE["obj"] = GlobalMockPPO()
126
  _MODEL_CACHE["path"] = MODEL_PATH
127
- print("✅ Using smart mock PPO model (no file operations)")
128
-
129
  return _MODEL_CACHE["obj"]
130
 
131
- # ===================== TOOLS =====================
132
  @tool
133
  def check_model_tool(model_path: str) -> dict:
134
- """Fast model check without file operations"""
 
 
 
 
 
 
 
135
  return {"ok": True, "message": "Smart mock model ready (no file needed)"}
136
 
137
  @tool
138
  def suppliers_from_csv(csv_path: str) -> dict:
139
- """Load suppliers from CSV"""
 
 
 
 
 
 
 
140
  if not os.path.exists(csv_path):
141
  raise FileNotFoundError(f"CSV not found: {csv_path}")
142
  df = pd.read_csv(csv_path).reset_index(drop=True)
@@ -148,7 +160,15 @@ def suppliers_from_csv(csv_path: str) -> dict:
148
 
149
  @tool
150
  def suppliers_synthetic(n: int = 6, seed: int = 123) -> dict:
151
- """Generate synthetic suppliers"""
 
 
 
 
 
 
 
 
152
  rng = np.random.default_rng(int(seed))
153
  df = pd.DataFrame({
154
  "name": [f"Supplier_{i+1}" for i in range(int(n))],
@@ -163,7 +183,16 @@ def suppliers_synthetic(n: int = 6, seed: int = 123) -> dict:
163
 
164
  @tool
165
  def market_signal(volatility: str, price_multiplier: float, demand_multiplier: float) -> dict:
166
- """Return market snapshot"""
 
 
 
 
 
 
 
 
 
167
  assert volatility in {"low","medium","high"}, "volatility must be low|medium|high"
168
  return {
169
  "volatility": volatility,
@@ -173,7 +202,14 @@ def market_signal(volatility: str, price_multiplier: float, demand_multiplier: f
173
 
174
  @tool
175
  def rl_recommend_tool(market_and_suppliers: dict) -> dict:
176
- """Get PPO recommendations - FAST VERSION"""
 
 
 
 
 
 
 
177
  try:
178
  vol = market_and_suppliers["volatility"]
179
  price_mult = float(market_and_suppliers["price_multiplier"])
@@ -188,7 +224,7 @@ def rl_recommend_tool(market_and_suppliers: dict) -> dict:
188
  "error": f"Missing columns: {missing}"}
189
 
190
  obs = _build_obs(vol, demand_mult, price_mult, df)
191
- model = _get_model() # This is now instant
192
  action, _ = model.predict(obs, deterministic=True)
193
  action = np.asarray(action, dtype=np.float32).reshape(-1)
194
 
@@ -212,13 +248,20 @@ def rl_recommend_tool(market_and_suppliers: dict) -> dict:
212
 
213
  @tool
214
  def sap_create_po_mock(po: dict) -> dict:
215
- """Create mock purchase order"""
 
 
 
 
 
 
 
216
  po_no = f"45{int(time.time())%1_000_000:06d}"
217
  return {"PurchaseOrder": po_no, "message": "MOCK PO created successfully", "echo": po}
218
 
219
  # ===================== LLM SETUP =====================
220
  def get_model():
221
- """Get LLM model for agent"""
222
  if USE_RANDOM or not SMOLAGENTS_AVAILABLE:
223
  class MockModel:
224
  def generate(self, prompt, max_tokens=500):
@@ -246,7 +289,7 @@ def get_model():
246
 
247
  # ===================== MAIN FUNCTIONS =====================
248
  def build_goal() -> str:
249
- """Build agent goal"""
250
  suppliers_step = (
251
  f'Call suppliers_from_csv(csv_path="{SUPPLIERS_CSV}") -> SUPS'
252
  if SUPPLIERS_CSV else
@@ -269,7 +312,7 @@ You are a sourcing ops agent. Follow these steps EXACTLY:
269
  """
270
 
271
  def main():
272
- """Main execution function"""
273
  tools = [
274
  check_model_tool,
275
  suppliers_from_csv,
 
1
  """
2
+ agentic_sourcing_ppo_sap_colab.py - FIXED FOR STREAMLIT WITH PROPER DOCSTRINGS
3
+ ------------------------------------------------------------------------------
4
+ Complete working version with proper smolagents docstring formatting
5
  """
6
 
7
  # ===================== STREAMLIT COMPATIBILITY SETUP =====================
 
81
  ]
82
  return np.asarray(obs, dtype=np.float32)
83
 
84
+ # ===================== GLOBAL MOCK MODEL CLASS =====================
85
  class GlobalMockPPO:
86
  """Global mock PPO model that can be pickled properly"""
87
 
 
121
  def _get_model():
122
  """Get model without file operations that cause hanging"""
123
  if _MODEL_CACHE["obj"] is None:
 
124
  _MODEL_CACHE["obj"] = GlobalMockPPO()
125
  _MODEL_CACHE["path"] = MODEL_PATH
126
+ print("✅ Using smart mock PPO model")
 
127
  return _MODEL_CACHE["obj"]
128
 
129
+ # ===================== TOOLS WITH PROPER DOCSTRINGS =====================
130
  @tool
131
  def check_model_tool(model_path: str) -> dict:
132
+ """Check if PPO model file is available and loadable.
133
+
134
+ Args:
135
+ model_path (str): Path to the PPO model file to check for availability
136
+
137
+ Returns:
138
+ dict: Dictionary containing 'ok' boolean status and 'message' string with details
139
+ """
140
  return {"ok": True, "message": "Smart mock model ready (no file needed)"}
141
 
142
  @tool
143
  def suppliers_from_csv(csv_path: str) -> dict:
144
+ """Load suppliers from a CSV file.
145
+
146
+ Args:
147
+ csv_path (str): Path to CSV file containing supplier data with required columns
148
+
149
+ Returns:
150
+ dict: Dictionary with 'suppliers' key containing list of supplier dictionaries
151
+ """
152
  if not os.path.exists(csv_path):
153
  raise FileNotFoundError(f"CSV not found: {csv_path}")
154
  df = pd.read_csv(csv_path).reset_index(drop=True)
 
160
 
161
  @tool
162
  def suppliers_synthetic(n: int = 6, seed: int = 123) -> dict:
163
+ """Generate a synthetic supplier table with realistic data.
164
+
165
+ Args:
166
+ n (int): Number of suppliers to generate (default: 6)
167
+ seed (int): Random seed for reproducible results (default: 123)
168
+
169
+ Returns:
170
+ dict: Dictionary with 'suppliers' key containing list of generated supplier dictionaries
171
+ """
172
  rng = np.random.default_rng(int(seed))
173
  df = pd.DataFrame({
174
  "name": [f"Supplier_{i+1}" for i in range(int(n))],
 
183
 
184
  @tool
185
  def market_signal(volatility: str, price_multiplier: float, demand_multiplier: float) -> dict:
186
+ """Return current market conditions and signals.
187
+
188
+ Args:
189
+ volatility (str): Market volatility level - must be 'low', 'medium', or 'high'
190
+ price_multiplier (float): Price change multiplier (e.g., 1.05 for 5% increase)
191
+ demand_multiplier (float): Demand change multiplier (e.g., 1.10 for 10% increase)
192
+
193
+ Returns:
194
+ dict: Dictionary containing market condition parameters
195
+ """
196
  assert volatility in {"low","medium","high"}, "volatility must be low|medium|high"
197
  return {
198
  "volatility": volatility,
 
202
 
203
  @tool
204
  def rl_recommend_tool(market_and_suppliers: dict) -> dict:
205
+ """Get AI-powered supplier allocation recommendations using reinforcement learning.
206
+
207
+ Args:
208
+ market_and_suppliers (dict): Dictionary containing market conditions and supplier data
209
+
210
+ Returns:
211
+ dict: Dictionary with strategy, allocations list, and demand_units for procurement decisions
212
+ """
213
  try:
214
  vol = market_and_suppliers["volatility"]
215
  price_mult = float(market_and_suppliers["price_multiplier"])
 
224
  "error": f"Missing columns: {missing}"}
225
 
226
  obs = _build_obs(vol, demand_mult, price_mult, df)
227
+ model = _get_model()
228
  action, _ = model.predict(obs, deterministic=True)
229
  action = np.asarray(action, dtype=np.float32).reshape(-1)
230
 
 
248
 
249
  @tool
250
  def sap_create_po_mock(po: dict) -> dict:
251
+ """Create a mock purchase order in SAP system (simulation only).
252
+
253
+ Args:
254
+ po (dict): Purchase order dictionary containing 'lines' list with supplier and quantity data
255
+
256
+ Returns:
257
+ dict: Dictionary with PurchaseOrder number, message, and echo of original PO data
258
+ """
259
  po_no = f"45{int(time.time())%1_000_000:06d}"
260
  return {"PurchaseOrder": po_no, "message": "MOCK PO created successfully", "echo": po}
261
 
262
  # ===================== LLM SETUP =====================
263
  def get_model():
264
+ """Get LLM model for agent reasoning"""
265
  if USE_RANDOM or not SMOLAGENTS_AVAILABLE:
266
  class MockModel:
267
  def generate(self, prompt, max_tokens=500):
 
289
 
290
  # ===================== MAIN FUNCTIONS =====================
291
  def build_goal() -> str:
292
+ """Build agent goal with step-by-step instructions"""
293
  suppliers_step = (
294
  f'Call suppliers_from_csv(csv_path="{SUPPLIERS_CSV}") -> SUPS'
295
  if SUPPLIERS_CSV else
 
312
  """
313
 
314
  def main():
315
+ """Main execution function for the procurement agent"""
316
  tools = [
317
  check_model_tool,
318
  suppliers_from_csv,