plot-agent 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- plot_agent/plotly_agent.py +52 -30
- {plot_agent-0.1.0.dist-info → plot_agent-0.1.2.dist-info}/METADATA +5 -7
- plot_agent-0.1.2.dist-info/RECORD +7 -0
- plot_agent-0.1.0.dist-info/RECORD +0 -7
- {plot_agent-0.1.0.dist-info → plot_agent-0.1.2.dist-info}/WHEEL +0 -0
- {plot_agent-0.1.0.dist-info → plot_agent-0.1.2.dist-info}/licenses/LICENSE +0 -0
- {plot_agent-0.1.0.dist-info → plot_agent-0.1.2.dist-info}/top_level.txt +0 -0
plot_agent/plotly_agent.py
CHANGED
|
@@ -12,7 +12,7 @@ from typing import Dict, List, Optional, Any
|
|
|
12
12
|
|
|
13
13
|
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
|
14
14
|
from langchain_core.messages import AIMessage, HumanMessage
|
|
15
|
-
from langchain_core.tools import Tool
|
|
15
|
+
from langchain_core.tools import Tool, StructuredTool
|
|
16
16
|
from pydantic import BaseModel, Field
|
|
17
17
|
from langchain.agents import AgentExecutor, create_openai_tools_agent
|
|
18
18
|
from langchain_openai import ChatOpenAI
|
|
@@ -38,29 +38,37 @@ df.head():
|
|
|
38
38
|
{sql_context}
|
|
39
39
|
|
|
40
40
|
NOTES:
|
|
41
|
-
- You must use the execute_plotly_code(generated_code) tool
|
|
42
|
-
- You must paste the full code, not just a reference to the code
|
|
43
|
-
- You must not use fig.show() in your code as it will be executed in a headless environment
|
|
44
|
-
- If you need to do any data cleaning or wrangling, do it in the code before generating the plotly code as preprocessing steps assume the data is in the pandas df object
|
|
45
|
-
|
|
41
|
+
- You must use the execute_plotly_code(generated_code) tool run your code and use the does_fig_exist() tool to check that a fig object is available for display.
|
|
42
|
+
- You must paste the full code, not just a reference to the code.
|
|
43
|
+
- You must not use fig.show() in your code as it will ultimately be executed elsewhere in a headless environment.
|
|
44
|
+
- If you need to do any data cleaning or wrangling, do it in the code before generating the plotly code as preprocessing steps assume the data is in the pandas 'df' object.
|
|
45
|
+
|
|
46
|
+
TOOLS:
|
|
47
|
+
- execute_plotly_code(generated_code) to execute the generated code.
|
|
48
|
+
- does_fig_exist() to check that a fig object is available for display. This tool takes no arguments.
|
|
49
|
+
- view_generated_code() to view the generated code if need to fix it. This tool takes no arguments.
|
|
46
50
|
|
|
47
51
|
IMPORTANT CODE FORMATTING INSTRUCTIONS:
|
|
48
|
-
1. Include thorough, detailed comments in your code to explain what each section does
|
|
49
|
-
2. Use descriptive variable names
|
|
50
|
-
3. DO NOT include fig.show() in your code - the visualization will be rendered externally
|
|
51
|
-
4. Ensure your code creates a variable named 'fig' that contains the Plotly figure object
|
|
52
|
-
5. Structure your code with proper spacing for readability
|
|
52
|
+
1. Include thorough, detailed comments in your code to explain what each section does.
|
|
53
|
+
2. Use descriptive variable names.
|
|
54
|
+
3. DO NOT include fig.show() in your code - the visualization will be rendered externally.
|
|
55
|
+
4. Ensure your code creates a variable named 'fig' that contains the Plotly figure object.
|
|
53
56
|
|
|
54
57
|
When a user asks for a visualization:
|
|
55
|
-
1. YOU MUST ALWAYS use the execute_plotly_code(generated_code) tool to test and run your code
|
|
56
|
-
2. If there are errors,
|
|
58
|
+
1. YOU MUST ALWAYS use the execute_plotly_code(generated_code) tool to test and run your code.
|
|
59
|
+
2. If there are errors, view the generated code using view_generated_code() and fix the code.
|
|
57
60
|
3. Check that a figure object is available using does_fig_exist(). does_fig_exist() takes no arguments.
|
|
61
|
+
4. If the figure object is not available, repeat the process until it is available.
|
|
58
62
|
|
|
59
63
|
IMPORTANT: The code you generate MUST be executed using the execute_plotly_code tool or no figure will be created!
|
|
60
64
|
YOU MUST CALL execute_plotly_code WITH THE FULL CODE, NOT JUST A REFERENCE TO THE CODE.
|
|
61
65
|
|
|
62
66
|
YOUR WORKFLOW MUST BE:
|
|
63
|
-
1. execute_plotly_code(generated_code)
|
|
67
|
+
1. execute_plotly_code(generated_code) to make sure the code is ran and a figure object is created.
|
|
68
|
+
2. check that a figure object is available using does_fig_exist() to make sure the figure object was created.
|
|
69
|
+
3. if there are errors, view the generated code using view_generated_code() to see what went wrong.
|
|
70
|
+
4. fix the code and execute it again with execute_plotly_code(generated_code) to make sure the figure object is created.
|
|
71
|
+
5. repeat until the figure object is available.
|
|
64
72
|
|
|
65
73
|
Always return the final working code (with all the comments) to the user along with an explanation of what the visualization shows.
|
|
66
74
|
Make sure to follow best practices for data visualization, such as appropriate chart types, labels, and colors.
|
|
@@ -82,6 +90,18 @@ class GeneratedCodeInput(BaseModel):
|
|
|
82
90
|
)
|
|
83
91
|
|
|
84
92
|
|
|
93
|
+
class DoesFigExistInput(BaseModel):
|
|
94
|
+
"""Model indicating that the does_fig_exist function takes no arguments."""
|
|
95
|
+
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class ViewGeneratedCodeInput(BaseModel):
|
|
100
|
+
"""Model indicating that the view_generated_code function takes no arguments."""
|
|
101
|
+
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
|
|
85
105
|
class PlotlyAgentExecutionEnvironment:
|
|
86
106
|
"""Environment to safely execute plotly code and capture the fig object."""
|
|
87
107
|
|
|
@@ -100,13 +120,6 @@ class PlotlyAgentExecutionEnvironment:
|
|
|
100
120
|
self.error = None
|
|
101
121
|
self.fig = None
|
|
102
122
|
|
|
103
|
-
def preprocess_code(self, generated_code: str) -> str:
|
|
104
|
-
"""Preprocess code to remove fig.show() calls."""
|
|
105
|
-
# Remove fig.show() calls
|
|
106
|
-
generated_code = re.sub(r"fig\.show\(\s*\)", "", generated_code)
|
|
107
|
-
generated_code = re.sub(r"fig\.show\(.*\)", "", generated_code)
|
|
108
|
-
return generated_code
|
|
109
|
-
|
|
110
123
|
def execute_code(self, generated_code: str) -> Dict[str, Any]:
|
|
111
124
|
"""
|
|
112
125
|
Execute the provided code and capture the fig object if created.
|
|
@@ -120,23 +133,20 @@ class PlotlyAgentExecutionEnvironment:
|
|
|
120
133
|
self.output = None
|
|
121
134
|
self.error = None
|
|
122
135
|
|
|
123
|
-
# Preprocess code to remove fig.show() calls
|
|
124
|
-
processed_code = self.preprocess_code(generated_code)
|
|
125
|
-
|
|
126
136
|
# Capture stdout
|
|
127
137
|
old_stdout = sys.stdout
|
|
128
138
|
sys.stdout = mystdout = StringIO()
|
|
129
139
|
|
|
130
140
|
try:
|
|
131
141
|
# Execute the code
|
|
132
|
-
exec(
|
|
142
|
+
exec(generated_code, globals(), self.locals_dict)
|
|
133
143
|
|
|
134
144
|
# Check if a fig object was created
|
|
135
145
|
if "fig" in self.locals_dict:
|
|
136
146
|
self.fig = self.locals_dict["fig"]
|
|
137
|
-
self.output = "Code executed successfully.
|
|
147
|
+
self.output = "Code executed successfully. 'fig' object was created."
|
|
138
148
|
else:
|
|
139
|
-
print(f"no fig object created: {
|
|
149
|
+
print(f"no fig object created: {generated_code}")
|
|
140
150
|
self.error = "Code executed without errors, but no 'fig' object was created. Make sure your code creates a variable named 'fig'."
|
|
141
151
|
|
|
142
152
|
except Exception as e:
|
|
@@ -257,6 +267,12 @@ class PlotlyAgent:
|
|
|
257
267
|
else:
|
|
258
268
|
return "No figure has been created yet."
|
|
259
269
|
|
|
270
|
+
def view_generated_code(self, *args, **kwargs) -> str:
|
|
271
|
+
"""
|
|
272
|
+
View the generated code.
|
|
273
|
+
"""
|
|
274
|
+
return self.generated_code
|
|
275
|
+
|
|
260
276
|
def _initialize_agent(self):
|
|
261
277
|
"""Initialize the LangChain agent with the necessary tools and prompt."""
|
|
262
278
|
tools = [
|
|
@@ -266,11 +282,17 @@ class PlotlyAgent:
|
|
|
266
282
|
description="Execute the provided Plotly code and return the result",
|
|
267
283
|
args_schema=GeneratedCodeInput,
|
|
268
284
|
),
|
|
269
|
-
|
|
285
|
+
StructuredTool.from_function(
|
|
270
286
|
func=self.does_fig_exist,
|
|
271
287
|
name="does_fig_exist",
|
|
272
|
-
description="Check if a figure exists and is available for display",
|
|
273
|
-
args_schema=
|
|
288
|
+
description="Check if a figure exists and is available for display. This tool takes no arguments.",
|
|
289
|
+
args_schema=DoesFigExistInput,
|
|
290
|
+
),
|
|
291
|
+
StructuredTool.from_function(
|
|
292
|
+
func=self.view_generated_code,
|
|
293
|
+
name="view_generated_code",
|
|
294
|
+
description="View the generated code.",
|
|
295
|
+
args_schema=ViewGeneratedCodeInput,
|
|
274
296
|
),
|
|
275
297
|
]
|
|
276
298
|
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plot-agent
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: An AI-powered data visualization assistant using Plotly
|
|
5
|
-
Home-page: https://github.com/andrewm4894/plot-agent
|
|
6
|
-
Author: Andre
|
|
7
5
|
Author-email: andrewm4894 <andrewm4894@gmail.com>
|
|
8
6
|
Project-URL: Homepage, https://github.com/andrewm4894/plot-agent
|
|
9
7
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -12,10 +10,7 @@ Classifier: Operating System :: OS Independent
|
|
|
12
10
|
Requires-Python: >=3.8
|
|
13
11
|
Description-Content-Type: text/markdown
|
|
14
12
|
License-File: LICENSE
|
|
15
|
-
Dynamic: author
|
|
16
|
-
Dynamic: home-page
|
|
17
13
|
Dynamic: license-file
|
|
18
|
-
Dynamic: requires-python
|
|
19
14
|
|
|
20
15
|
# Plot Agent
|
|
21
16
|
|
|
@@ -35,7 +30,8 @@ Here's a simple example of how to use Plot Agent:
|
|
|
35
30
|
|
|
36
31
|
```python
|
|
37
32
|
import pandas as pd
|
|
38
|
-
from plot_agent import PlotlyAgent
|
|
33
|
+
from plot_agent.plotly_agent import PlotlyAgent
|
|
34
|
+
|
|
39
35
|
|
|
40
36
|
# Create a sample dataframe
|
|
41
37
|
df = pd.DataFrame({
|
|
@@ -51,6 +47,8 @@ agent.set_df(df)
|
|
|
51
47
|
|
|
52
48
|
# Process a visualization request
|
|
53
49
|
response = agent.process_message("Create a line plot of x vs y")
|
|
50
|
+
fig = agent.get_figure()
|
|
51
|
+
fig.show()
|
|
54
52
|
```
|
|
55
53
|
|
|
56
54
|
## Features
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
plot_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
plot_agent/plotly_agent.py,sha256=93DSwnPU7_915nsXs8SIUuL1hXFTEozBaqWQxs4HM9Y,13637
|
|
3
|
+
plot_agent-0.1.2.dist-info/licenses/LICENSE,sha256=A4DPih7wHrh4VMEG3p1PhorqdhjmGIo8nQdYNQL7daA,1062
|
|
4
|
+
plot_agent-0.1.2.dist-info/METADATA,sha256=GddWhRuPQ3DpujQGTANyk22oMsMASmZ2bdjz9CkZfdc,1589
|
|
5
|
+
plot_agent-0.1.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
6
|
+
plot_agent-0.1.2.dist-info/top_level.txt,sha256=KyOjpihUssx26Ra-37vKUQ71pI2qgJsHaRwXHJUhjzQ,11
|
|
7
|
+
plot_agent-0.1.2.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
plot_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
plot_agent/plotly_agent.py,sha256=5ddz0zyMRwqsdLzIDZwJtyyX72zqTjyp06FiJl1WEqg,12686
|
|
3
|
-
plot_agent-0.1.0.dist-info/licenses/LICENSE,sha256=A4DPih7wHrh4VMEG3p1PhorqdhjmGIo8nQdYNQL7daA,1062
|
|
4
|
-
plot_agent-0.1.0.dist-info/METADATA,sha256=2PcErKj7H4qXBm2GAsQJTnbPvDDL-od0GUk8YZ1FtUY,1666
|
|
5
|
-
plot_agent-0.1.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
6
|
-
plot_agent-0.1.0.dist-info/top_level.txt,sha256=KyOjpihUssx26Ra-37vKUQ71pI2qgJsHaRwXHJUhjzQ,11
|
|
7
|
-
plot_agent-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|