Jurabek commited on
Commit
20f50df
Β·
verified Β·
1 Parent(s): b9bc86b

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +56 -34
src/streamlit_app.py CHANGED
@@ -4,7 +4,6 @@ import logging
4
  from datetime import datetime, timedelta
5
  import streamlit as st
6
  from openai import OpenAI
7
- import os
8
 
9
  # ==================================================
10
  # LOGGING
@@ -15,11 +14,6 @@ logging.basicConfig(
15
  )
16
  logger = logging.getLogger("AI-Agent")
17
 
18
- # ==================================================
19
- # OPENAI CLIENT
20
- # ==================================================
21
- client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
22
-
23
  # ==================================================
24
  # RAW DATA (600+ ROWS WITH DATE)
25
  # ==================================================
@@ -53,13 +47,28 @@ def generate_data(rows: int = 600):
53
  DATA = generate_data()
54
 
55
  # ==================================================
56
- # TOOLS (FUNCTION CALLING)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  # ==================================================
58
  def tool_get_stats():
59
  prices = [x["price"] for x in DATA]
60
  days = [x["delivery_days"] for x in DATA]
61
- logger.info("Tool β†’ get_stats")
62
 
 
63
  return {
64
  "rows": len(DATA),
65
  "avg_price": round(sum(prices) / len(prices), 2),
@@ -73,17 +82,12 @@ def tool_query_product(product: str):
73
  def tool_query_last_days(days: int):
74
  logger.info("Tool β†’ query_last_days(%d)", days)
75
  cutoff = datetime.today().date() - timedelta(days=days)
76
- return [x for x in DATA if x["order_date"] >= cutoff][:10]
77
 
78
  def tool_create_support_ticket(text: str):
79
  ticket_id = str(uuid.uuid4())[:8]
80
  logger.info("Tool β†’ create_support_ticket (%s)", ticket_id)
81
- return {
82
- "ticket_id": ticket_id,
83
- "system": "GitHub Issues (mock)",
84
- "status": "Created",
85
- "description": text,
86
- }
87
 
88
  # ==================================================
89
  # SAFETY
@@ -95,7 +99,7 @@ def is_dangerous(text: str):
95
  # ==================================================
96
  # AGENT
97
  # ==================================================
98
- def agent(user_input: str):
99
  logger.info("User input: %s", user_input)
100
 
101
  if is_dangerous(user_input):
@@ -107,10 +111,10 @@ def agent(user_input: str):
107
  if "stats" in text or "summary" in text:
108
  s = tool_get_stats()
109
  return (
110
- f"πŸ“Š **Business Overview**\n"
111
- f"- Rows: {s['rows']}\n"
112
- f"- Avg Price: ${s['avg_price']}\n"
113
- f"- Avg Delivery Days: {s['avg_delivery_days']}"
114
  )
115
 
116
  # ---- LAST N DAYS ----
@@ -119,38 +123,43 @@ def agent(user_input: str):
119
  days = int([x for x in text.split() if x.isdigit()][0])
120
  except:
121
  days = 3
 
122
  rows = tool_query_last_days(days)
123
- return rows if rows else f"No data for last {days} days."
 
 
 
124
 
125
  # ---- PRODUCT ----
126
  if text.startswith("show"):
127
  product = user_input.replace("show", "").strip()
128
  rows = tool_query_product(product)
 
129
  if not rows:
130
- return "No data found. Would you like to create a support ticket?"
131
- return rows
 
132
 
133
  # ---- SUPPORT ----
134
  if "support" in text or "ticket" in text:
135
- t = tool_create_support_ticket(user_input)
136
  return (
137
- f"🎫 **Support Ticket Created**\n"
138
- f"ID: {t['ticket_id']}\n"
139
- f"System: {t['system']}"
140
  )
141
 
142
  # ---- OPENAI FALLBACK ----
143
  logger.info("LLM fallback via OpenAI")
144
 
145
- response = client.chat.completions.create(
146
  model="gpt-4o-mini",
147
  messages=[
148
  {
149
  "role": "system",
150
  "content": (
151
  "You are an AI procurement assistant. "
152
- "You do NOT have direct access to raw data. "
153
- "Suggest support if needed."
154
  )
155
  },
156
  {"role": "user", "content": user_input}
@@ -165,9 +174,16 @@ def agent(user_input: str):
165
  # STREAMLIT UI
166
  # ==================================================
167
  st.set_page_config(page_title="AI Procurement Agent", layout="wide")
168
- st.title("πŸ€– AI Procurement Agent (OpenAI powered)")
 
 
 
 
 
 
 
 
169
 
170
- # Sidebar
171
  stats = tool_get_stats()
172
  st.sidebar.header("πŸ“Š Business Information")
173
  st.sidebar.metric("Rows", stats["rows"])
@@ -182,7 +198,13 @@ st.sidebar.code(
182
  "create support ticket"
183
  )
184
 
185
- # Chat
 
 
 
 
 
 
186
  if "messages" not in st.session_state:
187
  st.session_state.messages = []
188
 
@@ -190,7 +212,7 @@ user_input = st.chat_input("Ask the procurement agent...")
190
 
191
  if user_input:
192
  st.session_state.messages.append(("user", user_input))
193
- reply = agent(user_input)
194
  st.session_state.messages.append(("assistant", reply))
195
 
196
  for role, message in st.session_state.messages:
 
4
  from datetime import datetime, timedelta
5
  import streamlit as st
6
  from openai import OpenAI
 
7
 
8
  # ==================================================
9
  # LOGGING
 
14
  )
15
  logger = logging.getLogger("AI-Agent")
16
 
 
 
 
 
 
17
  # ==================================================
18
  # RAW DATA (600+ ROWS WITH DATE)
19
  # ==================================================
 
47
  DATA = generate_data()
48
 
49
  # ==================================================
50
+ # UTILS: FORMAT RESPONSE AS TEXT
51
+ # ==================================================
52
+ def format_rows_as_text(rows):
53
+ lines = []
54
+ for r in rows:
55
+ lines.append(
56
+ f"🧾 Order #{r['order_id']} | {r['order_date']}\n"
57
+ f" Product: {r['product']}\n"
58
+ f" Supplier: {r['supplier']}\n"
59
+ f" Qty: {r['quantity']} | Price: ${r['price']}\n"
60
+ f" Delivery: {r['delivery_days']} days | Status: {r['status']}\n"
61
+ )
62
+ return "\n".join(lines)
63
+
64
+ # ==================================================
65
+ # TOOLS
66
  # ==================================================
67
  def tool_get_stats():
68
  prices = [x["price"] for x in DATA]
69
  days = [x["delivery_days"] for x in DATA]
 
70
 
71
+ logger.info("Tool β†’ get_stats")
72
  return {
73
  "rows": len(DATA),
74
  "avg_price": round(sum(prices) / len(prices), 2),
 
82
  def tool_query_last_days(days: int):
83
  logger.info("Tool β†’ query_last_days(%d)", days)
84
  cutoff = datetime.today().date() - timedelta(days=days)
85
+ return [x for x in DATA if x["order_date"] >= cutoff][:5]
86
 
87
  def tool_create_support_ticket(text: str):
88
  ticket_id = str(uuid.uuid4())[:8]
89
  logger.info("Tool β†’ create_support_ticket (%s)", ticket_id)
90
+ return ticket_id
 
 
 
 
 
91
 
92
  # ==================================================
93
  # SAFETY
 
99
  # ==================================================
100
  # AGENT
101
  # ==================================================
102
+ def agent(user_input: str, openai_client: OpenAI):
103
  logger.info("User input: %s", user_input)
104
 
105
  if is_dangerous(user_input):
 
111
  if "stats" in text or "summary" in text:
112
  s = tool_get_stats()
113
  return (
114
+ "πŸ“Š Business Overview\n"
115
+ f"- Total rows: {s['rows']}\n"
116
+ f"- Average price: ${s['avg_price']}\n"
117
+ f"- Average delivery days: {s['avg_delivery_days']}"
118
  )
119
 
120
  # ---- LAST N DAYS ----
 
123
  days = int([x for x in text.split() if x.isdigit()][0])
124
  except:
125
  days = 3
126
+
127
  rows = tool_query_last_days(days)
128
+ if not rows:
129
+ return f"No data found for last {days} days."
130
+
131
+ return f"πŸ“¦ Orders from last {days} days:\n\n" + format_rows_as_text(rows)
132
 
133
  # ---- PRODUCT ----
134
  if text.startswith("show"):
135
  product = user_input.replace("show", "").strip()
136
  rows = tool_query_product(product)
137
+
138
  if not rows:
139
+ return "No records found. Would you like me to create a support ticket?"
140
+
141
+ return f"πŸ“¦ Showing orders for **{product}**:\n\n" + format_rows_as_text(rows)
142
 
143
  # ---- SUPPORT ----
144
  if "support" in text or "ticket" in text:
145
+ ticket_id = tool_create_support_ticket(user_input)
146
  return (
147
+ "🎫 Support Ticket Created\n"
148
+ f"- Ticket ID: {ticket_id}\n"
149
+ "- System: GitHub Issues (mock)"
150
  )
151
 
152
  # ---- OPENAI FALLBACK ----
153
  logger.info("LLM fallback via OpenAI")
154
 
155
+ response = openai_client.chat.completions.create(
156
  model="gpt-4o-mini",
157
  messages=[
158
  {
159
  "role": "system",
160
  "content": (
161
  "You are an AI procurement assistant. "
162
+ "You do NOT have access to raw data."
 
163
  )
164
  },
165
  {"role": "user", "content": user_input}
 
174
  # STREAMLIT UI
175
  # ==================================================
176
  st.set_page_config(page_title="AI Procurement Agent", layout="wide")
177
+ st.title("πŸ€– AI Procurement Agent (OpenAI)")
178
+
179
+ # ---- SIDEBAR ----
180
+ st.sidebar.header("πŸ”‘ OpenAI Configuration")
181
+ api_key = st.sidebar.text_input(
182
+ "OpenAI API Key",
183
+ type="password",
184
+ help="Paste your OpenAI API key here"
185
+ )
186
 
 
187
  stats = tool_get_stats()
188
  st.sidebar.header("πŸ“Š Business Information")
189
  st.sidebar.metric("Rows", stats["rows"])
 
198
  "create support ticket"
199
  )
200
 
201
+ if not api_key:
202
+ st.warning("Please enter your OpenAI API key to continue.")
203
+ st.stop()
204
+
205
+ openai_client = OpenAI(api_key=api_key)
206
+
207
+ # ---- CHAT ----
208
  if "messages" not in st.session_state:
209
  st.session_state.messages = []
210
 
 
212
 
213
  if user_input:
214
  st.session_state.messages.append(("user", user_input))
215
+ reply = agent(user_input, openai_client)
216
  st.session_state.messages.append(("assistant", reply))
217
 
218
  for role, message in st.session_state.messages: