plot-agent 0.2.1__py3-none-any.whl → 0.3.0__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/agent.py CHANGED
@@ -1,13 +1,6 @@
1
1
  import pandas as pd
2
- import numpy as np
3
- import matplotlib.pyplot as plt
4
- import plotly.express as px
5
- import plotly.graph_objects as go
6
- from plotly.subplots import make_subplots
7
2
  from io import StringIO
8
- import traceback
9
- import sys
10
- from typing import Dict, Optional, Any
3
+ from typing import Optional
11
4
 
12
5
  from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
13
6
  from langchain_core.messages import AIMessage, HumanMessage
@@ -21,10 +14,10 @@ from plot_agent.models import (
21
14
  DoesFigExistInput,
22
15
  ViewGeneratedCodeInput,
23
16
  )
24
- from plot_agent.execution import PlotlyAgentExecutionEnvironment
17
+ from plot_agent.execution import PlotAgentExecutionEnvironment
25
18
 
26
19
 
27
- class PlotlyAgent:
20
+ class PlotAgent:
28
21
  """
29
22
  A class that uses an LLM to generate Plotly code based on a user's plot description.
30
23
  """
@@ -39,7 +32,7 @@ class PlotlyAgent:
39
32
  handle_parsing_errors: bool = True,
40
33
  ):
41
34
  """
42
- Initialize the PlotlyAgent.
35
+ Initialize the PlotAgent.
43
36
 
44
37
  Args:
45
38
  model (str): The model to use for the LLM.
@@ -75,6 +68,14 @@ class PlotlyAgent:
75
68
  Returns:
76
69
  None
77
70
  """
71
+
72
+ # Check df
73
+ assert isinstance(df, pd.DataFrame), "The dataframe must be a pandas dataframe."
74
+ assert not df.empty, "The dataframe must not be empty."
75
+
76
+ if sql_query:
77
+ assert isinstance(sql_query, str), "The SQL query must be a string."
78
+
78
79
  self.df = df
79
80
 
80
81
  # Capture df.info() output
@@ -89,7 +90,7 @@ class PlotlyAgent:
89
90
  self.sql_query = sql_query
90
91
 
91
92
  # Initialize execution environment
92
- self.execution_env = PlotlyAgentExecutionEnvironment(df)
93
+ self.execution_env = PlotAgentExecutionEnvironment(df)
93
94
 
94
95
  # Initialize the agent with tools
95
96
  self._initialize_agent()
@@ -104,18 +105,27 @@ class PlotlyAgent:
104
105
  Returns:
105
106
  str: The result of the execution.
106
107
  """
108
+ assert isinstance(generated_code, str), "The generated code must be a string."
109
+
107
110
  if not self.execution_env:
108
111
  return "Error: No dataframe has been set. Please set a dataframe first."
109
112
 
110
113
  # Store this as the last generated code
111
114
  self.generated_code = generated_code
112
115
 
113
- result = self.execution_env.execute_code(generated_code)
116
+ # Execute the generated code
117
+ code_execution_result = self.execution_env.execute_code(generated_code)
114
118
 
115
- if result["success"]:
116
- return f"Code executed successfully! A figure object was created.\n{result.get('output', '')}"
119
+ # Extract the results from the code execution
120
+ code_execution_success = code_execution_result.get("success", False)
121
+ code_execution_output = code_execution_result.get("output", "")
122
+ code_execution_error = code_execution_result.get("error", "")
123
+
124
+ # Check if the code executed successfully
125
+ if code_execution_success:
126
+ return f"Code executed successfully! A figure object was created.\n{code_execution_output}"
117
127
  else:
118
- return f"Error: {result.get('error', 'Unknown error')}\n{result.get('output', '')}"
128
+ return f"Error: {code_execution_error}\n{code_execution_output}"
119
129
 
120
130
  def does_fig_exist(self, *args, **kwargs) -> str:
121
131
  """
@@ -144,23 +154,25 @@ class PlotlyAgent:
144
154
 
145
155
  def _initialize_agent(self):
146
156
  """Initialize the LangChain agent with the necessary tools and prompt."""
157
+
158
+ # Initialize the tools
147
159
  tools = [
148
160
  Tool.from_function(
149
161
  func=self.execute_plotly_code,
150
162
  name="execute_plotly_code",
151
- description="Execute the provided Plotly code and return the result",
163
+ description="Execute the provided Plotly code and return a result indicating if the code executed successfully and if a figure object was created.",
152
164
  args_schema=GeneratedCodeInput,
153
165
  ),
154
166
  StructuredTool.from_function(
155
167
  func=self.does_fig_exist,
156
168
  name="does_fig_exist",
157
- description="Check if a figure exists and is available for display. This tool takes no arguments.",
169
+ description="Check if a figure exists and is available for display. This tool takes no arguments and returns a string indicating if a figure is available for display or not.",
158
170
  args_schema=DoesFigExistInput,
159
171
  ),
160
172
  StructuredTool.from_function(
161
173
  func=self.view_generated_code,
162
174
  name="view_generated_code",
163
- description="View the generated code.",
175
+ description="View the generated code. This tool takes no arguments and returns the generated code as a string.",
164
176
  args_schema=ViewGeneratedCodeInput,
165
177
  ),
166
178
  ]
@@ -198,6 +210,8 @@ class PlotlyAgent:
198
210
 
199
211
  def process_message(self, user_message: str) -> str:
200
212
  """Process a user message and return the agent's response."""
213
+ assert isinstance(user_message, str), "The user message must be a string."
214
+
201
215
  if not self.agent_executor:
202
216
  return "Please set a dataframe first using set_df() method."
203
217
 
@@ -238,3 +252,4 @@ class PlotlyAgent:
238
252
  def reset_conversation(self):
239
253
  """Reset the conversation history."""
240
254
  self.chat_history = []
255
+ self.generated_code = None
plot_agent/execution.py CHANGED
@@ -10,10 +10,21 @@ from plotly.subplots import make_subplots
10
10
  from typing import Dict, Any
11
11
 
12
12
 
13
- class PlotlyAgentExecutionEnvironment:
14
- """Environment to safely execute plotly code and capture the fig object."""
13
+ class PlotAgentExecutionEnvironment:
14
+ """
15
+ Environment to safely execute plotly code and capture the fig object.
16
+
17
+ Args:
18
+ df (pd.DataFrame): The dataframe to use for the execution environment.
19
+ """
15
20
 
16
21
  def __init__(self, df: pd.DataFrame):
22
+ """
23
+ Initialize the execution environment with the given dataframe.
24
+
25
+ Args:
26
+ df (pd.DataFrame): The dataframe to use for the execution environment.
27
+ """
17
28
  self.df = df
18
29
  self.locals_dict = {
19
30
  "df": df,
plot_agent/models.py CHANGED
@@ -1,14 +1,17 @@
1
1
  from pydantic import BaseModel, Field
2
2
 
3
3
 
4
- # Define input schemas for the tools
5
4
  class PlotDescriptionInput(BaseModel):
5
+ """Model indicating that the plot_description function takes a plot_description argument."""
6
+
6
7
  plot_description: str = Field(
7
8
  ..., description="Description of the plot the user wants to create"
8
9
  )
9
10
 
10
11
 
11
12
  class GeneratedCodeInput(BaseModel):
13
+ """Model indicating that the generated_code function takes a generated_code argument."""
14
+
12
15
  generated_code: str = Field(
13
16
  ..., description="Python code that creates a Plotly figure"
14
17
  )
@@ -23,4 +26,4 @@ class DoesFigExistInput(BaseModel):
23
26
  class ViewGeneratedCodeInput(BaseModel):
24
27
  """Model indicating that the view_generated_code function takes no arguments."""
25
28
 
26
- pass
29
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plot-agent
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: An AI-powered data visualization assistant using Plotly
5
5
  Author-email: andrewm4894 <andrewm4894@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/andrewm4894/plot-agent
@@ -35,7 +35,7 @@ Here's a simple minimal example of how to use Plot Agent:
35
35
 
36
36
  ```python
37
37
  import pandas as pd
38
- from plot_agent.agent import PlotlyAgent
38
+ from plot_agent.agent import PlotAgent
39
39
 
40
40
  # ensure OPENAI_API_KEY is set and available for langchain
41
41
 
@@ -46,7 +46,7 @@ df = pd.DataFrame({
46
46
  })
47
47
 
48
48
  # Initialize the agent
49
- agent = PlotlyAgent()
49
+ agent = PlotAgent()
50
50
 
51
51
  # Set the dataframe
52
52
  agent.set_df(df)
@@ -0,0 +1,10 @@
1
+ plot_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ plot_agent/agent.py,sha256=FPHma_u_77y3c5nBrCPS0VR8AWz-NFFRqURn0xHph-M,9584
3
+ plot_agent/execution.py,sha256=Ewnz6Pb2EWM0pDAmeVoJ5RmhY5gmO1F7iOvERkj2D28,2770
4
+ plot_agent/models.py,sha256=MkAaSELr54RfGRONKfiqCRA2ghlRbzTe5L5krVuqMsk,800
5
+ plot_agent/prompt.py,sha256=HjRgbsAe8HHs8arQogvzOGQdThEWKRqQhtQyaUplxhQ,3064
6
+ plot_agent-0.3.0.dist-info/licenses/LICENSE,sha256=A4DPih7wHrh4VMEG3p1PhorqdhjmGIo8nQdYNQL7daA,1062
7
+ plot_agent-0.3.0.dist-info/METADATA,sha256=Cqw5gPpT2OM0fPaV_XLFJChEjsAFrVKfiwvxWxdVphM,2837
8
+ plot_agent-0.3.0.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
9
+ plot_agent-0.3.0.dist-info/top_level.txt,sha256=KyOjpihUssx26Ra-37vKUQ71pI2qgJsHaRwXHJUhjzQ,11
10
+ plot_agent-0.3.0.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- plot_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- plot_agent/agent.py,sha256=8JhZf0r6_0HjV1dATzbiVgkf8g1fSLvOo8dLJkFzDVA,8682
3
- plot_agent/execution.py,sha256=B7XJCJOlOd99PUG5K9K9Al3TgvQtyta0X9LAxvodARo,2479
4
- plot_agent/models.py,sha256=ZOWWeYaqmnKJarXYyXnBQQ4nwUe71ae_gMul3bZXaWU,644
5
- plot_agent/prompt.py,sha256=HjRgbsAe8HHs8arQogvzOGQdThEWKRqQhtQyaUplxhQ,3064
6
- plot_agent-0.2.1.dist-info/licenses/LICENSE,sha256=A4DPih7wHrh4VMEG3p1PhorqdhjmGIo8nQdYNQL7daA,1062
7
- plot_agent-0.2.1.dist-info/METADATA,sha256=0GZe10CtdaXJ9qySDPFKjeCwmaTACYye6e23mCayMD8,2841
8
- plot_agent-0.2.1.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
9
- plot_agent-0.2.1.dist-info/top_level.txt,sha256=KyOjpihUssx26Ra-37vKUQ71pI2qgJsHaRwXHJUhjzQ,11
10
- plot_agent-0.2.1.dist-info/RECORD,,