satif-ai 0.2.4__tar.gz → 0.2.6__tar.gz
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-0.2.4 → satif_ai-0.2.6}/PKG-INFO +1 -1
- {satif_ai-0.2.4 → satif_ai-0.2.6}/pyproject.toml +1 -1
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/code_builders/transformation.py +32 -15
- {satif_ai-0.2.4 → satif_ai-0.2.6}/LICENSE +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/README.md +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/__init__.py +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/adapters/__init__.py +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/adapters/tidy.py +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/code_builders/__init__.py +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/code_builders/adaptation.py +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/plot_builders/__init__.py +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/plot_builders/agent.py +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/plot_builders/prompt.py +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/plot_builders/tool.py +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/standardizers/__init__.py +0 -0
- {satif_ai-0.2.4 → satif_ai-0.2.6}/satif_ai/standardizers/ai_csv.py +0 -0
@@ -1,8 +1,9 @@
|
|
1
1
|
import base64
|
2
2
|
import os
|
3
3
|
import re
|
4
|
+
from collections import defaultdict
|
4
5
|
from pathlib import Path
|
5
|
-
from typing import Dict, List, Optional, Union
|
6
|
+
from typing import Any, Dict, List, Optional, Union
|
6
7
|
|
7
8
|
from agents import Agent, Runner, function_tool
|
8
9
|
from agents.mcp.server import MCPServer
|
@@ -15,6 +16,7 @@ from satif_sdk.transformers import CodeTransformer
|
|
15
16
|
# Global variables for transformation
|
16
17
|
INPUT_SDIF_PATH: Optional[Path] = None
|
17
18
|
OUTPUT_TARGET_FILES: Optional[Dict[Union[str, Path], str]] = None
|
19
|
+
SCHEMA_ONLY: Optional[bool] = None
|
18
20
|
|
19
21
|
|
20
22
|
@function_tool
|
@@ -32,6 +34,9 @@ async def execute_transformation(code: str) -> str:
|
|
32
34
|
generated_output_path = code_transformer.export(INPUT_SDIF_PATH)
|
33
35
|
|
34
36
|
comparisons = []
|
37
|
+
comparator_kwargs = {"check_structure_only": True}
|
38
|
+
if SCHEMA_ONLY:
|
39
|
+
comparator_kwargs["check_structure_only"] = True
|
35
40
|
|
36
41
|
if os.path.isdir(generated_output_path):
|
37
42
|
# If it's a directory, compare each file with its corresponding target
|
@@ -46,7 +51,9 @@ async def execute_transformation(code: str) -> str:
|
|
46
51
|
generated_output_path, output_target_file_name
|
47
52
|
)
|
48
53
|
comparator = get_comparator(output_target_file_name.split(".")[-1])
|
49
|
-
comparison = comparator.compare(
|
54
|
+
comparison = comparator.compare(
|
55
|
+
generated_file_path, output_base_file, **comparator_kwargs
|
56
|
+
)
|
50
57
|
comparisons.append(
|
51
58
|
f"Comparison for {generated_file_path} [SOURCE] with {output_target_file_name} [TARGET]: {comparison}"
|
52
59
|
)
|
@@ -60,7 +67,9 @@ async def execute_transformation(code: str) -> str:
|
|
60
67
|
output_file = list(OUTPUT_TARGET_FILES.keys())[0]
|
61
68
|
output_target_file_name = list(OUTPUT_TARGET_FILES.values())[0]
|
62
69
|
comparator = get_comparator(output_file.split(".")[-1])
|
63
|
-
comparison = comparator.compare(
|
70
|
+
comparison = comparator.compare(
|
71
|
+
generated_output_path, output_file, **comparator_kwargs
|
72
|
+
)
|
64
73
|
comparisons.append(
|
65
74
|
f"Comparison for {generated_output_path} [SOURCE] with {output_target_file_name} [TARGET]: {comparison}"
|
66
75
|
)
|
@@ -91,7 +100,7 @@ class TransformationAsyncCodeBuilder(AsyncCodeBuilder):
|
|
91
100
|
self,
|
92
101
|
mcp_server: MCPServer,
|
93
102
|
mcp_session: ClientSession,
|
94
|
-
llm_model: str = "
|
103
|
+
llm_model: str = "o4-mini",
|
95
104
|
):
|
96
105
|
self.mcp_server = mcp_server
|
97
106
|
self.mcp_session = mcp_session
|
@@ -103,17 +112,17 @@ class TransformationAsyncCodeBuilder(AsyncCodeBuilder):
|
|
103
112
|
output_target_files: Dict[Union[str, Path], str] | List[Path],
|
104
113
|
output_sdif: Optional[Path] = None, # This will now be relative or None
|
105
114
|
instructions: Optional[str] = None,
|
115
|
+
schema_only: bool = False,
|
116
|
+
representer_options_for_build: Optional[Dict[str, Any]] = None,
|
106
117
|
) -> str:
|
107
|
-
global INPUT_SDIF_PATH, OUTPUT_TARGET_FILES
|
118
|
+
global INPUT_SDIF_PATH, OUTPUT_TARGET_FILES, SCHEMA_ONLY
|
108
119
|
# INPUT_SDIF_PATH is used by execute_transformation tool, needs to be accessible from where that tool runs.
|
109
120
|
# If execute_transformation runs in the same process as the builder, absolute path is fine.
|
110
121
|
# If it were a separate context, this might need adjustment.
|
111
122
|
# For now, assume execute_transformation can access absolute paths if needed for its *input SDIF*.
|
112
123
|
# However, the sdif for MCP URIs must be relative.
|
113
|
-
INPUT_SDIF_PATH = Path(
|
114
|
-
|
115
|
-
).resolve() # Keep this as absolute for the tool's potential direct access.
|
116
|
-
|
124
|
+
INPUT_SDIF_PATH = Path(sdif).resolve()
|
125
|
+
SCHEMA_ONLY = schema_only
|
117
126
|
# Paths for MCP URIs are now expected to be relative to MCP server CWD (project root)
|
118
127
|
# So, use them directly as strings.
|
119
128
|
input_sdif_mcp_uri_path = base64.b64encode(str(sdif).encode()).decode()
|
@@ -172,16 +181,21 @@ class TransformationAsyncCodeBuilder(AsyncCodeBuilder):
|
|
172
181
|
else:
|
173
182
|
OUTPUT_TARGET_FILES = {}
|
174
183
|
|
175
|
-
output_representation =
|
184
|
+
output_representation = defaultdict(dict)
|
176
185
|
if OUTPUT_TARGET_FILES:
|
177
186
|
for file_key_abs_path in list(OUTPUT_TARGET_FILES.keys()):
|
178
187
|
agent_facing_name = OUTPUT_TARGET_FILES[file_key_abs_path]
|
179
|
-
print(f"Representing {agent_facing_name} from {file_key_abs_path}
|
188
|
+
print(f"Representing {agent_facing_name} from {file_key_abs_path}")
|
180
189
|
try:
|
181
190
|
# Representer uses the absolute path (file_key_abs_path) to read the example file.
|
182
|
-
|
183
|
-
|
184
|
-
|
191
|
+
representer = get_representer(file_key_abs_path)
|
192
|
+
representation, used_params = representer.represent(
|
193
|
+
file_key_abs_path, **(representer_options_for_build or {})
|
194
|
+
)
|
195
|
+
output_representation[agent_facing_name] = {
|
196
|
+
"representation": representation,
|
197
|
+
"used_params": used_params,
|
198
|
+
}
|
185
199
|
except Exception as e:
|
186
200
|
print(
|
187
201
|
f"Warning: Could not get representation for {agent_facing_name} (path {file_key_abs_path}): {e}"
|
@@ -204,10 +218,13 @@ class TransformationAsyncCodeBuilder(AsyncCodeBuilder):
|
|
204
218
|
else "Error reading input sample",
|
205
219
|
"output_files": str(list(OUTPUT_TARGET_FILES.values())),
|
206
220
|
"output_schema": output_schema_text,
|
207
|
-
"output_sample": output_sample_text
|
221
|
+
"output_sample": output_sample_text
|
222
|
+
if not SCHEMA_ONLY
|
223
|
+
else "Sample not available.",
|
208
224
|
"output_representation": str(
|
209
225
|
output_representation
|
210
226
|
), # Representation keyed by agent-facing name
|
227
|
+
"instructions": instructions,
|
211
228
|
},
|
212
229
|
)
|
213
230
|
agent = Agent(
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|