satif-ai 0.2.7__py3-none-any.whl → 0.2.9__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.
- satif_ai/__init__.py +19 -0
- satif_ai/adapters/tidy.py +19 -38
- satif_ai/standardize.py +112 -0
- satif_ai/standardizers/ai.py +485 -0
- satif_ai/standardizers/ai_csv.py +47 -129
- satif_ai/transform.py +121 -0
- satif_ai/{code_builders/transformation.py → transformation_builders/syncpulse.py} +28 -36
- satif_ai/utils/__init__.py +5 -0
- satif_ai/utils/merge_sdif.py +22 -0
- satif_ai/utils/openai_mcp.py +97 -0
- satif_ai/utils/zip.py +120 -0
- {satif_ai-0.2.7.dist-info → satif_ai-0.2.9.dist-info}/METADATA +4 -3
- satif_ai-0.2.9.dist-info/RECORD +19 -0
- satif_ai/code_builders/adaptation.py +0 -9
- satif_ai/plot_builders/__init__.py +0 -0
- satif_ai/plot_builders/agent.py +0 -204
- satif_ai/plot_builders/prompt.py +0 -92
- satif_ai/plot_builders/tool.py +0 -146
- satif_ai-0.2.7.dist-info/RECORD +0 -17
- /satif_ai/{code_builders → transformation_builders}/__init__.py +0 -0
- {satif_ai-0.2.7.dist-info → satif_ai-0.2.9.dist-info}/LICENSE +0 -0
- {satif_ai-0.2.7.dist-info → satif_ai-0.2.9.dist-info}/WHEEL +0 -0
- {satif_ai-0.2.7.dist-info → satif_ai-0.2.9.dist-info}/entry_points.txt +0 -0
satif_ai/plot_builders/tool.py
DELETED
@@ -1,146 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
import sqlite3 # Ensure sqlite3 is imported if needed
|
3
|
-
from pathlib import Path
|
4
|
-
|
5
|
-
import pandas as pd
|
6
|
-
from agents import function_tool
|
7
|
-
from satif_sdk import SDIFDatabase
|
8
|
-
from satif_sdk.code_executors import CodeExecutionError, LocalCodeExecutor
|
9
|
-
|
10
|
-
logger = logging.getLogger(__name__)
|
11
|
-
|
12
|
-
# Global or context for the tool (similar to TidyAdapter)
|
13
|
-
PLOTTING_TOOL_CONTEXT = {
|
14
|
-
"input_sdif_path": None,
|
15
|
-
"user_instructions": None,
|
16
|
-
"output_plot_path": None,
|
17
|
-
}
|
18
|
-
|
19
|
-
|
20
|
-
@function_tool
|
21
|
-
async def execute_plotting_code(code: str) -> str:
|
22
|
-
"""
|
23
|
-
Executes the provided Python plotting script code.
|
24
|
-
The code should use the pre-defined 'db' (SDIFDatabase instance)
|
25
|
-
and 'instructions' (string) variables.
|
26
|
-
The code MUST save the generated Plotly plot to 'plot.html'.
|
27
|
-
Returns the path to the saved plot on success or an error message.
|
28
|
-
"""
|
29
|
-
input_sdif_path = PLOTTING_TOOL_CONTEXT.get("input_sdif_path")
|
30
|
-
user_instructions = PLOTTING_TOOL_CONTEXT.get("user_instructions")
|
31
|
-
|
32
|
-
if not input_sdif_path:
|
33
|
-
return "Error: Input SDIF path not found in tool context."
|
34
|
-
# Check existence *before* trying to open
|
35
|
-
if not Path(input_sdif_path).exists():
|
36
|
-
return f"Error: Input SDIF file not found at {input_sdif_path}."
|
37
|
-
if user_instructions is None:
|
38
|
-
# Allow empty instructions, pass empty string
|
39
|
-
user_instructions = ""
|
40
|
-
logger.warning(
|
41
|
-
"User instructions not found in tool context, using empty string."
|
42
|
-
)
|
43
|
-
# return "Error: User instructions not found in tool context."
|
44
|
-
|
45
|
-
# Use LocalCodeExecutor - WARNING: Insecure for untrusted code
|
46
|
-
executor = LocalCodeExecutor()
|
47
|
-
|
48
|
-
expected_output_filename = "plot.html"
|
49
|
-
# Resolve path relative to the current working directory
|
50
|
-
expected_output_path = Path(expected_output_filename).resolve()
|
51
|
-
|
52
|
-
# Clear previous plot if it exists
|
53
|
-
if expected_output_path.exists():
|
54
|
-
try:
|
55
|
-
expected_output_path.unlink()
|
56
|
-
except OSError as e:
|
57
|
-
logger.error(
|
58
|
-
f"Could not remove existing plot file {expected_output_path}: {e}"
|
59
|
-
)
|
60
|
-
|
61
|
-
# Prepare the extra context for the executor
|
62
|
-
db_instance = None
|
63
|
-
try:
|
64
|
-
# Instantiate the DB instance to be passed to the code
|
65
|
-
# Use read-only mode as the code should only read for plotting
|
66
|
-
db_instance = SDIFDatabase(input_sdif_path, read_only=True)
|
67
|
-
|
68
|
-
# Define the context that will be available to the executed code
|
69
|
-
code_context = {
|
70
|
-
"db": db_instance,
|
71
|
-
"instructions": user_instructions,
|
72
|
-
# Add any other context variables if needed by the executor/code
|
73
|
-
}
|
74
|
-
|
75
|
-
# The code provided by the agent is now expected to be a script
|
76
|
-
script_code = f"""
|
77
|
-
import pandas as pd
|
78
|
-
import plotly.express as px
|
79
|
-
import plotly.graph_objects as go
|
80
|
-
from pathlib import Path
|
81
|
-
from satif.sdif_database.database import SDIFDatabase # Make class available for type hints etc.
|
82
|
-
import sqlite3 # For potential use by pandas/db interaction
|
83
|
-
|
84
|
-
# Pre-defined variables available:
|
85
|
-
# db: SDIFDatabase instance connected to {input_sdif_path}
|
86
|
-
# instructions: str = User's instructions
|
87
|
-
|
88
|
-
# --- User's Script Code Start ---
|
89
|
-
{code}
|
90
|
-
# --- User's Script Code End ---
|
91
|
-
"""
|
92
|
-
logger.debug(f"Executing plotting script code:\n---\n{code[:500]}...\n---")
|
93
|
-
|
94
|
-
# LocalCodeExecutor.execute expects 'db' and 'datasource' in its signature
|
95
|
-
# We pass our *actual* db instance as part of extra_context which overrides
|
96
|
-
# the dummy 'db' argument passed for signature compliance.
|
97
|
-
executor.execute(
|
98
|
-
code=script_code,
|
99
|
-
db=db_instance, # Pass instance for signature, but it's also in extra_context
|
100
|
-
datasource=None, # Not needed
|
101
|
-
extra_context=code_context, # Pass db and instructions here
|
102
|
-
)
|
103
|
-
|
104
|
-
# Check if the expected output file was created
|
105
|
-
if expected_output_path.exists():
|
106
|
-
logger.info(
|
107
|
-
f"Plotting code executed successfully. Output: {expected_output_path}"
|
108
|
-
)
|
109
|
-
PLOTTING_TOOL_CONTEXT["output_plot_path"] = expected_output_path
|
110
|
-
return f"Success: Plot saved to {expected_output_path}"
|
111
|
-
else:
|
112
|
-
logger.error(
|
113
|
-
"Plotting code executed but output file 'plot.html' not found."
|
114
|
-
)
|
115
|
-
# Check if the error might be within the script's own error handling
|
116
|
-
# (This requires parsing the execution output, which LocalExecutor doesn't provide easily)
|
117
|
-
return "Error: Code executed (possibly with internal errors), but the expected output file 'plot.html' was not created."
|
118
|
-
|
119
|
-
except (
|
120
|
-
CodeExecutionError,
|
121
|
-
sqlite3.Error,
|
122
|
-
FileNotFoundError,
|
123
|
-
ValueError,
|
124
|
-
TypeError,
|
125
|
-
) as e:
|
126
|
-
logger.error(f"Error executing plotting code or accessing DB: {e}")
|
127
|
-
# Attempt to provide more specific feedback if possible
|
128
|
-
error_message = f"Error executing plotting code: {e}"
|
129
|
-
# Look for common issues like table not found
|
130
|
-
if isinstance(e, pd.io.sql.DatabaseError) and "no such table" in str(e).lower():
|
131
|
-
error_message = f"Error executing plotting code: Table not found. {e}"
|
132
|
-
elif isinstance(e, KeyError): # Pandas KeyError on column access
|
133
|
-
error_message = f"Error executing plotting code: Column not found or data processing error. {e}"
|
134
|
-
|
135
|
-
return error_message # Return the formatted error
|
136
|
-
except Exception as e:
|
137
|
-
logger.exception("Unexpected error during plotting code execution via tool.")
|
138
|
-
return f"Unexpected Error during execution: {e}"
|
139
|
-
finally:
|
140
|
-
# Ensure the db instance created here is closed
|
141
|
-
if db_instance:
|
142
|
-
try:
|
143
|
-
db_instance.close()
|
144
|
-
logger.debug("Closed DB instance in plotting tool.")
|
145
|
-
except Exception as close_err:
|
146
|
-
logger.error(f"Error closing DB instance in plotting tool: {close_err}")
|
satif_ai-0.2.7.dist-info/RECORD
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
satif_ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
satif_ai/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
satif_ai/adapters/tidy.py,sha256=2oYj7Gz3vOQtzcpoJI4JbftWlMKvOWL8rdwthjg-zUE,19884
|
4
|
-
satif_ai/code_builders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
-
satif_ai/code_builders/adaptation.py,sha256=E29YM0S6pMtAfB0uzSUexoeWKwXfF8iJVyYUCKWQz5k,188
|
6
|
-
satif_ai/code_builders/transformation.py,sha256=h-7CqrFAIZF8lUHZqX137fVfxrl_I2K6jjbMyQk307Y,11897
|
7
|
-
satif_ai/plot_builders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
-
satif_ai/plot_builders/agent.py,sha256=Ncw7SL9qkpRN0hw76ezSo1K8vVQK6gcXFp8x8VFwqUI,8291
|
9
|
-
satif_ai/plot_builders/prompt.py,sha256=m0W1SsxnB9_FhIYRumkthImJbK-7KUm4dygN3kjAXGk,6877
|
10
|
-
satif_ai/plot_builders/tool.py,sha256=MeLnG_wFoITSVWZcNFsQLCi157O4L3wItQgolBa4fAw,5994
|
11
|
-
satif_ai/standardizers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
|
-
satif_ai/standardizers/ai_csv.py,sha256=AAeTt7eqFAtayxF2b95Z_K_lnMdwBBnv2Cn-qTEpMp8,29499
|
13
|
-
satif_ai-0.2.7.dist-info/LICENSE,sha256=kS8EN6yAaGZd7V5z6GKSn_x3ozcZltrfRky4vMPRCw8,1072
|
14
|
-
satif_ai-0.2.7.dist-info/METADATA,sha256=twBlNw3dmgfHjKG9QP2I_WEwf2Tp6Swr8YF0u1enJpI,670
|
15
|
-
satif_ai-0.2.7.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
16
|
-
satif_ai-0.2.7.dist-info/entry_points.txt,sha256=Mz2SwYALjktap1bF-Q3EWBgiZVNT6QJCVsCs_fCV33Y,43
|
17
|
-
satif_ai-0.2.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|