Upload 3 files
Browse files- app.py +164 -0
- customers-10000.csv +0 -0
- requirements.txt +3 -0
app.py
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import openai
|
3 |
+
import subprocess
|
4 |
+
import re
|
5 |
+
import os
|
6 |
+
import pandas as pd
|
7 |
+
from PIL import Image
|
8 |
+
|
9 |
+
df = pd.read_csv("./customers-10000.csv")
|
10 |
+
metadata = {
|
11 |
+
"columns": df.columns.tolist(),
|
12 |
+
"dtypes": df.dtypes.apply(lambda x: x.name).to_dict(),
|
13 |
+
"shape": df.shape,
|
14 |
+
}
|
15 |
+
|
16 |
+
def runcode(code: str) -> str:
|
17 |
+
with open("code.py", "w") as file:
|
18 |
+
file.write(code)
|
19 |
+
|
20 |
+
try:
|
21 |
+
result = subprocess.run(
|
22 |
+
["python", "code.py"], capture_output=True, text=True, check=True
|
23 |
+
)
|
24 |
+
output = "Output Generated Successfully" + "\n" + result.stdout
|
25 |
+
except subprocess.CalledProcessError as e:
|
26 |
+
output = f"An error occurred while running the code:\nSTDOUT:\n{e.stdout}\nSTDERR:\n{e.stderr}"
|
27 |
+
except Exception as e:
|
28 |
+
output = f"An unexpected error occurred: {str(e)}"
|
29 |
+
|
30 |
+
return output
|
31 |
+
|
32 |
+
|
33 |
+
class Agent:
|
34 |
+
def __init__(self, system_prompt="", known_actions=None):
|
35 |
+
self.system = system_prompt
|
36 |
+
self.messages = []
|
37 |
+
self.known_actions = known_actions if known_actions is not None else {}
|
38 |
+
|
39 |
+
self.client = openai.OpenAI(
|
40 |
+
api_key=os.environ.get('TOGETHER_API_KEY'),
|
41 |
+
base_url="https://api.together.xyz/v1",
|
42 |
+
)
|
43 |
+
self.messages.append({"role": "system", "content": self.system})
|
44 |
+
|
45 |
+
def __call__(self, message):
|
46 |
+
self.messages.append({"role": "user", "content": message})
|
47 |
+
result = self.execute()
|
48 |
+
self.messages.append({"role": "assistant", "content": result})
|
49 |
+
return result
|
50 |
+
|
51 |
+
def execute(self):
|
52 |
+
try:
|
53 |
+
response = self.client.chat.completions.create(
|
54 |
+
model="meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo",
|
55 |
+
stop=["PAUSE"],
|
56 |
+
messages=self.messages,
|
57 |
+
)
|
58 |
+
return response.choices[0].message.content
|
59 |
+
except Exception as e:
|
60 |
+
return f"Error executing model: {str(e)}"
|
61 |
+
|
62 |
+
def query(self, question, max_turns=5):
|
63 |
+
i = 0
|
64 |
+
next_prompt = question
|
65 |
+
while i < max_turns:
|
66 |
+
i += 1
|
67 |
+
result = self(next_prompt)
|
68 |
+
st.session_state.logs += f"Assistant: {result}\n"
|
69 |
+
action_re = re.search(r"Action: (\w+): (.*)", result, re.DOTALL)
|
70 |
+
if action_re:
|
71 |
+
action = action_re.group(1)
|
72 |
+
action_input = action_re.group(2).strip()
|
73 |
+
st.session_state.logs += (
|
74 |
+
f"Action: {action}\nAction Input: {action_input}\n"
|
75 |
+
)
|
76 |
+
if action not in self.known_actions:
|
77 |
+
raise Exception(f"Unknown action: {action}: {action_input}")
|
78 |
+
st.session_state.logs += (
|
79 |
+
f" ------------------------\n running {action} {action_input}\n"
|
80 |
+
)
|
81 |
+
observation = self.known_actions[action](action_input)
|
82 |
+
st.session_state.logs += f"Observation: {observation}\n"
|
83 |
+
next_prompt = f"Observation: {observation}"
|
84 |
+
else:
|
85 |
+
return
|
86 |
+
|
87 |
+
|
88 |
+
known_actions = {"runcode": runcode}
|
89 |
+
|
90 |
+
prompt = f"""
|
91 |
+
You are an expert in writing python code based on user request and you run in a loop of Thought, Action, PAUSE, Observation.
|
92 |
+
At the end of the loop you output an Answer
|
93 |
+
Use Thought to describe your thoughts about the question you have been asked.
|
94 |
+
Use Action to run one of the actions available to you - then return PAUSE.
|
95 |
+
Observation will be the result of running those actions.
|
96 |
+
Always return just code no need of ```
|
97 |
+
Always save generated plot as 'graph.png'
|
98 |
+
|
99 |
+
Your Task is help user get result of query about below dataset,Decide based on user query to make Plot or Just Textual Answer.
|
100 |
+
Here is the metadata of the dataset and name of dataset is customers-10000.csv:
|
101 |
+
|
102 |
+
Columns: {metadata['columns']}
|
103 |
+
Dtypes: {metadata['dtypes']}
|
104 |
+
Shape: {metadata['shape']}
|
105 |
+
You can use this metadata to generate results.
|
106 |
+
|
107 |
+
Your available actions are:
|
108 |
+
runcode
|
109 |
+
|
110 |
+
How to use actions
|
111 |
+
Action : action_name: input_to_action
|
112 |
+
|
113 |
+
if want to use matplotlib use backend as Agg
|
114 |
+
|
115 |
+
Example session:
|
116 |
+
|
117 |
+
Question: Get the average age of the customers
|
118 |
+
|
119 |
+
Thought: I need to run a query to get the average age of the customers
|
120 |
+
|
121 |
+
Action: runcode: import pandas as pd
|
122 |
+
df=pd.read_csv('./customers-10000.csv')
|
123 |
+
age = df['age'].mean()
|
124 |
+
print(age)
|
125 |
+
|
126 |
+
PAUSE
|
127 |
+
|
128 |
+
Observation : understand the output based its stdout and take necessary steps.
|
129 |
+
|
130 |
+
Answer: Final Answer for User Request if its graph send "Graph Generated" or Textual Answer "Your Interpretation of Answer"
|
131 |
+
""".strip()
|
132 |
+
|
133 |
+
bot = Agent(system_prompt=prompt, known_actions=known_actions)
|
134 |
+
|
135 |
+
st.set_page_config(layout="wide")
|
136 |
+
st.title("Customer Data Analysis")
|
137 |
+
|
138 |
+
query = st.text_area("Enter your query about the dataset:", height=100)
|
139 |
+
|
140 |
+
col1, col2 = st.columns(2)
|
141 |
+
|
142 |
+
if "logs" not in st.session_state:
|
143 |
+
st.session_state.logs = ""
|
144 |
+
|
145 |
+
with col1:
|
146 |
+
if st.button("Submit"):
|
147 |
+
if "graph.png" in os.listdir():
|
148 |
+
os.remove("graph.png")
|
149 |
+
st.session_state.logs = ""
|
150 |
+
with st.spinner("Generating response..."):
|
151 |
+
bot.query(query)
|
152 |
+
answer = re.findall(r"Answer: (.+)", st.session_state.logs)[-1]
|
153 |
+
st.success(answer)
|
154 |
+
|
155 |
+
with col2:
|
156 |
+
st.header("Output")
|
157 |
+
if "graph.png" in os.listdir():
|
158 |
+
image = Image.open("graph.png")
|
159 |
+
st.image(image, caption="Generated Plot")
|
160 |
+
else:
|
161 |
+
st.write("No plot generated yet.")
|
162 |
+
|
163 |
+
st.header("Live Logs")
|
164 |
+
st.text_area("Logs", value=st.session_state.logs, height=400)
|
customers-10000.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
openai
|
3 |
+
pillow
|