Update app.py
Browse files
app.py
CHANGED
|
@@ -4,13 +4,13 @@ import numpy as np
|
|
| 4 |
import os
|
| 5 |
import requests
|
| 6 |
import json
|
| 7 |
-
import re
|
| 8 |
|
| 9 |
# --- Page config
|
| 10 |
st.set_page_config(page_title="CSV-Backed AI Chat Agent", layout="wide")
|
| 11 |
|
| 12 |
# --- Title & image
|
| 13 |
st.title("CSV-Backed AI Chat Agent")
|
|
|
|
| 14 |
|
| 15 |
# --- Load API key
|
| 16 |
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
|
@@ -68,7 +68,7 @@ function_schema = [
|
|
| 68 |
"properties": {
|
| 69 |
"query": {
|
| 70 |
"type": "string",
|
| 71 |
-
"description": "A Pandas query string, e.g. 'price > 100 and
|
| 72 |
},
|
| 73 |
},
|
| 74 |
"required": ["query"],
|
|
@@ -98,7 +98,6 @@ function_map = {
|
|
| 98 |
|
| 99 |
# --- Conversation memory: Use Streamlit session state
|
| 100 |
if "messages" not in st.session_state:
|
| 101 |
-
# Initial system prompt includes column info (blank at start)
|
| 102 |
st.session_state.messages = []
|
| 103 |
|
| 104 |
# If CSV is loaded, update the system prompt with current columns
|
|
@@ -123,13 +122,12 @@ if df is not None:
|
|
| 123 |
st.markdown("### Conversation")
|
| 124 |
|
| 125 |
# Display chat history (like ChatGPT)
|
| 126 |
-
for i, msg in enumerate(st.session_state.messages[1:]): # Skip
|
| 127 |
if msg["role"] == "user":
|
| 128 |
st.markdown(f"<div style='color: #4F8BF9;'><b>User:</b> {msg['content']}</div>", unsafe_allow_html=True)
|
| 129 |
elif msg["role"] == "assistant":
|
| 130 |
st.markdown(f"<div style='color: #1C6E4C;'><b>Agent:</b> {msg['content']}</div>", unsafe_allow_html=True)
|
| 131 |
elif msg["role"] == "function":
|
| 132 |
-
# Optionally, display function results
|
| 133 |
try:
|
| 134 |
result = json.loads(msg["content"])
|
| 135 |
st.markdown(f"<details><summary><b>Function '{msg['name']}' output:</b></summary><pre>{json.dumps(result, indent=2)}</pre></details>", unsafe_allow_html=True)
|
|
@@ -138,6 +136,8 @@ for i, msg in enumerate(st.session_state.messages[1:]): # Skip the system messa
|
|
| 138 |
|
| 139 |
# --- User input box at bottom (like ChatGPT)
|
| 140 |
if df is not None:
|
|
|
|
|
|
|
| 141 |
user_input = st.text_input("Your message:", key="user_input")
|
| 142 |
send = st.button("Send", key="send_btn")
|
| 143 |
else:
|
|
@@ -148,10 +148,10 @@ if send and user_input and user_input.strip():
|
|
| 148 |
# Append user's message to conversation
|
| 149 |
st.session_state.messages.append({"role": "user", "content": user_input})
|
| 150 |
|
| 151 |
-
#
|
| 152 |
chat_messages = st.session_state.messages.copy()
|
| 153 |
|
| 154 |
-
#
|
| 155 |
chat_resp = requests.post(
|
| 156 |
"https://api.openai.com/v1/chat/completions",
|
| 157 |
headers=HEADERS,
|
|
@@ -169,7 +169,7 @@ if send and user_input and user_input.strip():
|
|
| 169 |
response_json = chat_resp.json()
|
| 170 |
msg = response_json["choices"][0]["message"]
|
| 171 |
|
| 172 |
-
#
|
| 173 |
if msg.get("function_call"):
|
| 174 |
func_name = msg["function_call"]["name"]
|
| 175 |
args_json = msg["function_call"]["arguments"]
|
|
@@ -186,7 +186,7 @@ if send and user_input and user_input.strip():
|
|
| 186 |
"content": json.dumps(function_result),
|
| 187 |
})
|
| 188 |
|
| 189 |
-
#
|
| 190 |
followup_messages = st.session_state.messages.copy()
|
| 191 |
final_resp = requests.post(
|
| 192 |
"https://api.openai.com/v1/chat/completions",
|
|
@@ -206,6 +206,7 @@ if send and user_input and user_input.strip():
|
|
| 206 |
else:
|
| 207 |
# No function call: Just add model's reply
|
| 208 |
st.session_state.messages.append({"role": "assistant", "content": msg["content"]})
|
| 209 |
-
# Clear input after sending
|
| 210 |
-
st.experimental_rerun()
|
| 211 |
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
import os
|
| 5 |
import requests
|
| 6 |
import json
|
|
|
|
| 7 |
|
| 8 |
# --- Page config
|
| 9 |
st.set_page_config(page_title="CSV-Backed AI Chat Agent", layout="wide")
|
| 10 |
|
| 11 |
# --- Title & image
|
| 12 |
st.title("CSV-Backed AI Chat Agent")
|
| 13 |
+
st.image("./nadi-lok-image.png")
|
| 14 |
|
| 15 |
# --- Load API key
|
| 16 |
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
|
|
|
| 68 |
"properties": {
|
| 69 |
"query": {
|
| 70 |
"type": "string",
|
| 71 |
+
"description": "A Pandas query string, e.g. 'price > 100 and city == \"Miami\"'"
|
| 72 |
},
|
| 73 |
},
|
| 74 |
"required": ["query"],
|
|
|
|
| 98 |
|
| 99 |
# --- Conversation memory: Use Streamlit session state
|
| 100 |
if "messages" not in st.session_state:
|
|
|
|
| 101 |
st.session_state.messages = []
|
| 102 |
|
| 103 |
# If CSV is loaded, update the system prompt with current columns
|
|
|
|
| 122 |
st.markdown("### Conversation")
|
| 123 |
|
| 124 |
# Display chat history (like ChatGPT)
|
| 125 |
+
for i, msg in enumerate(st.session_state.messages[1:]): # Skip system message for display
|
| 126 |
if msg["role"] == "user":
|
| 127 |
st.markdown(f"<div style='color: #4F8BF9;'><b>User:</b> {msg['content']}</div>", unsafe_allow_html=True)
|
| 128 |
elif msg["role"] == "assistant":
|
| 129 |
st.markdown(f"<div style='color: #1C6E4C;'><b>Agent:</b> {msg['content']}</div>", unsafe_allow_html=True)
|
| 130 |
elif msg["role"] == "function":
|
|
|
|
| 131 |
try:
|
| 132 |
result = json.loads(msg["content"])
|
| 133 |
st.markdown(f"<details><summary><b>Function '{msg['name']}' output:</b></summary><pre>{json.dumps(result, indent=2)}</pre></details>", unsafe_allow_html=True)
|
|
|
|
| 136 |
|
| 137 |
# --- User input box at bottom (like ChatGPT)
|
| 138 |
if df is not None:
|
| 139 |
+
if "user_input" not in st.session_state:
|
| 140 |
+
st.session_state.user_input = ""
|
| 141 |
user_input = st.text_input("Your message:", key="user_input")
|
| 142 |
send = st.button("Send", key="send_btn")
|
| 143 |
else:
|
|
|
|
| 148 |
# Append user's message to conversation
|
| 149 |
st.session_state.messages.append({"role": "user", "content": user_input})
|
| 150 |
|
| 151 |
+
# Compose messages for OpenAI (entire chat history)
|
| 152 |
chat_messages = st.session_state.messages.copy()
|
| 153 |
|
| 154 |
+
# First OpenAI call: Check for function call
|
| 155 |
chat_resp = requests.post(
|
| 156 |
"https://api.openai.com/v1/chat/completions",
|
| 157 |
headers=HEADERS,
|
|
|
|
| 169 |
response_json = chat_resp.json()
|
| 170 |
msg = response_json["choices"][0]["message"]
|
| 171 |
|
| 172 |
+
# If OpenAI requests a function call
|
| 173 |
if msg.get("function_call"):
|
| 174 |
func_name = msg["function_call"]["name"]
|
| 175 |
args_json = msg["function_call"]["arguments"]
|
|
|
|
| 186 |
"content": json.dumps(function_result),
|
| 187 |
})
|
| 188 |
|
| 189 |
+
# Second OpenAI call: Get final answer with function result
|
| 190 |
followup_messages = st.session_state.messages.copy()
|
| 191 |
final_resp = requests.post(
|
| 192 |
"https://api.openai.com/v1/chat/completions",
|
|
|
|
| 206 |
else:
|
| 207 |
# No function call: Just add model's reply
|
| 208 |
st.session_state.messages.append({"role": "assistant", "content": msg["content"]})
|
|
|
|
|
|
|
| 209 |
|
| 210 |
+
# Clear input after sending
|
| 211 |
+
st.session_state.user_input = ""
|
| 212 |
+
# The UI will update on the next rerender (no need for manual rerun)
|