satif-ai 0.2.3__py3-none-any.whl → 0.2.4__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/code_builders/transformation.py +100 -23
- {satif_ai-0.2.3.dist-info → satif_ai-0.2.4.dist-info}/METADATA +1 -1
- {satif_ai-0.2.3.dist-info → satif_ai-0.2.4.dist-info}/RECORD +6 -6
- satif_ai-0.2.4.dist-info/entry_points.txt +3 -0
- satif_ai-0.2.3.dist-info/entry_points.txt +0 -3
- {satif_ai-0.2.3.dist-info → satif_ai-0.2.4.dist-info}/LICENSE +0 -0
- {satif_ai-0.2.3.dist-info → satif_ai-0.2.4.dist-info}/WHEEL +0 -0
@@ -1,10 +1,11 @@
|
|
1
|
+
import base64
|
1
2
|
import os
|
2
3
|
import re
|
3
4
|
from pathlib import Path
|
4
5
|
from typing import Dict, List, Optional, Union
|
5
6
|
|
6
7
|
from agents import Agent, Runner, function_tool
|
7
|
-
from agents.mcp.server import
|
8
|
+
from agents.mcp.server import MCPServer
|
8
9
|
from mcp import ClientSession
|
9
10
|
from satif_core import AsyncCodeBuilder, CodeBuilder, SDIFDatabase
|
10
11
|
from satif_sdk.comparators import get_comparator
|
@@ -88,7 +89,7 @@ class TransformationAsyncCodeBuilder(AsyncCodeBuilder):
|
|
88
89
|
|
89
90
|
def __init__(
|
90
91
|
self,
|
91
|
-
mcp_server:
|
92
|
+
mcp_server: MCPServer,
|
92
93
|
mcp_session: ClientSession,
|
93
94
|
llm_model: str = "o3-mini",
|
94
95
|
):
|
@@ -98,39 +99,115 @@ class TransformationAsyncCodeBuilder(AsyncCodeBuilder):
|
|
98
99
|
|
99
100
|
async def build(
|
100
101
|
self,
|
101
|
-
sdif: Path,
|
102
|
+
sdif: Path, # This will now be relative to project root (MCP server CWD)
|
102
103
|
output_target_files: Dict[Union[str, Path], str] | List[Path],
|
103
|
-
output_sdif: Optional[Path] = None,
|
104
|
+
output_sdif: Optional[Path] = None, # This will now be relative or None
|
104
105
|
instructions: Optional[str] = None,
|
105
106
|
) -> str:
|
106
107
|
global INPUT_SDIF_PATH, OUTPUT_TARGET_FILES
|
107
|
-
INPUT_SDIF_PATH
|
108
|
+
# INPUT_SDIF_PATH is used by execute_transformation tool, needs to be accessible from where that tool runs.
|
109
|
+
# If execute_transformation runs in the same process as the builder, absolute path is fine.
|
110
|
+
# If it were a separate context, this might need adjustment.
|
111
|
+
# For now, assume execute_transformation can access absolute paths if needed for its *input SDIF*.
|
112
|
+
# However, the sdif for MCP URIs must be relative.
|
113
|
+
INPUT_SDIF_PATH = Path(
|
114
|
+
sdif
|
115
|
+
).resolve() # Keep this as absolute for the tool's potential direct access.
|
116
|
+
|
117
|
+
# Paths for MCP URIs are now expected to be relative to MCP server CWD (project root)
|
118
|
+
# So, use them directly as strings.
|
119
|
+
input_sdif_mcp_uri_path = base64.b64encode(str(sdif).encode()).decode()
|
120
|
+
output_sdif_mcp_uri_path = (
|
121
|
+
base64.b64encode(str(output_sdif).encode()).decode()
|
122
|
+
if output_sdif
|
123
|
+
else None
|
124
|
+
)
|
108
125
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
126
|
+
input_schema = await self.mcp_session.read_resource(
|
127
|
+
f"schema://{input_sdif_mcp_uri_path}"
|
128
|
+
)
|
129
|
+
input_sample = await self.mcp_session.read_resource(
|
130
|
+
f"sample://{input_sdif_mcp_uri_path}"
|
131
|
+
)
|
132
|
+
|
133
|
+
output_schema_text = "N/A"
|
134
|
+
output_sample_text = "N/A"
|
135
|
+
if output_sdif_mcp_uri_path:
|
136
|
+
try:
|
137
|
+
output_schema_content = await self.mcp_session.read_resource(
|
138
|
+
f"schema://{output_sdif_mcp_uri_path}"
|
139
|
+
)
|
140
|
+
if output_schema_content.contents:
|
141
|
+
output_schema_text = output_schema_content.contents[0].text
|
142
|
+
except Exception as e:
|
143
|
+
print(
|
144
|
+
f"Warning: Could not read schema for output_sdif {output_sdif_mcp_uri_path}: {e}"
|
145
|
+
)
|
113
146
|
|
114
|
-
|
115
|
-
|
147
|
+
try:
|
148
|
+
output_sample_content = await self.mcp_session.read_resource(
|
149
|
+
f"sample://{output_sdif_mcp_uri_path}"
|
150
|
+
)
|
151
|
+
if output_sample_content.contents:
|
152
|
+
output_sample_text = output_sample_content.contents[0].text
|
153
|
+
except Exception as e:
|
154
|
+
print(
|
155
|
+
f"Warning: Could not read sample for output_sdif {output_sdif_mcp_uri_path}: {e}"
|
156
|
+
)
|
116
157
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
158
|
+
# OUTPUT_TARGET_FILES keys are absolute paths to original example files for local reading by representers/comparators.
|
159
|
+
# Values are agent-facing filenames.
|
160
|
+
if isinstance(output_target_files, list):
|
161
|
+
OUTPUT_TARGET_FILES = {
|
162
|
+
file_path.resolve(): file_path.name for file_path in output_target_files
|
163
|
+
}
|
164
|
+
elif isinstance(output_target_files, dict):
|
165
|
+
temp_map = {}
|
166
|
+
for k, v in output_target_files.items():
|
167
|
+
if isinstance(k, Path):
|
168
|
+
temp_map[k.resolve()] = v
|
169
|
+
else:
|
170
|
+
temp_map[k] = v
|
171
|
+
OUTPUT_TARGET_FILES = temp_map
|
172
|
+
else:
|
173
|
+
OUTPUT_TARGET_FILES = {}
|
174
|
+
|
175
|
+
output_representation = {}
|
176
|
+
if OUTPUT_TARGET_FILES:
|
177
|
+
for file_key_abs_path in list(OUTPUT_TARGET_FILES.keys()):
|
178
|
+
agent_facing_name = OUTPUT_TARGET_FILES[file_key_abs_path]
|
179
|
+
print(f"Representing {agent_facing_name} from {file_key_abs_path}!!")
|
180
|
+
try:
|
181
|
+
# Representer uses the absolute path (file_key_abs_path) to read the example file.
|
182
|
+
output_representation[agent_facing_name] = get_representer(
|
183
|
+
file_key_abs_path
|
184
|
+
).represent(file_key_abs_path)
|
185
|
+
except Exception as e:
|
186
|
+
print(
|
187
|
+
f"Warning: Could not get representation for {agent_facing_name} (path {file_key_abs_path}): {e}"
|
188
|
+
)
|
189
|
+
output_representation[agent_facing_name] = (
|
190
|
+
f"Error representing file: {e}"
|
191
|
+
)
|
123
192
|
|
124
193
|
prompt = await self.mcp_session.get_prompt(
|
125
194
|
"create_transformation",
|
126
195
|
arguments={
|
127
|
-
"input_file":
|
128
|
-
|
129
|
-
|
196
|
+
"input_file": Path(
|
197
|
+
input_sdif_mcp_uri_path
|
198
|
+
).name, # Display name for prompt (from relative path)
|
199
|
+
"input_schema": input_schema.contents[0].text
|
200
|
+
if input_schema.contents
|
201
|
+
else "Error reading input schema",
|
202
|
+
"input_sample": input_sample.contents[0].text
|
203
|
+
if input_sample.contents
|
204
|
+
else "Error reading input sample",
|
130
205
|
"output_files": str(list(OUTPUT_TARGET_FILES.values())),
|
131
|
-
"output_schema":
|
132
|
-
"output_sample":
|
133
|
-
"output_representation": str(
|
206
|
+
"output_schema": output_schema_text,
|
207
|
+
"output_sample": output_sample_text,
|
208
|
+
"output_representation": str(
|
209
|
+
output_representation
|
210
|
+
), # Representation keyed by agent-facing name
|
134
211
|
},
|
135
212
|
)
|
136
213
|
agent = Agent(
|
@@ -3,15 +3,15 @@ satif_ai/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
|
|
3
3
|
satif_ai/adapters/tidy.py,sha256=2oYj7Gz3vOQtzcpoJI4JbftWlMKvOWL8rdwthjg-zUE,19884
|
4
4
|
satif_ai/code_builders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
satif_ai/code_builders/adaptation.py,sha256=E29YM0S6pMtAfB0uzSUexoeWKwXfF8iJVyYUCKWQz5k,188
|
6
|
-
satif_ai/code_builders/transformation.py,sha256=
|
6
|
+
satif_ai/code_builders/transformation.py,sha256=c0-7JTs5pgiDOYxjWtB-w8Z-nwwqDWSUPCY1kJo3xEs,9638
|
7
7
|
satif_ai/plot_builders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
satif_ai/plot_builders/agent.py,sha256=Ncw7SL9qkpRN0hw76ezSo1K8vVQK6gcXFp8x8VFwqUI,8291
|
9
9
|
satif_ai/plot_builders/prompt.py,sha256=m0W1SsxnB9_FhIYRumkthImJbK-7KUm4dygN3kjAXGk,6877
|
10
10
|
satif_ai/plot_builders/tool.py,sha256=MeLnG_wFoITSVWZcNFsQLCi157O4L3wItQgolBa4fAw,5994
|
11
11
|
satif_ai/standardizers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
12
|
satif_ai/standardizers/ai_csv.py,sha256=AAeTt7eqFAtayxF2b95Z_K_lnMdwBBnv2Cn-qTEpMp8,29499
|
13
|
-
satif_ai-0.2.
|
14
|
-
satif_ai-0.2.
|
15
|
-
satif_ai-0.2.
|
16
|
-
satif_ai-0.2.
|
17
|
-
satif_ai-0.2.
|
13
|
+
satif_ai-0.2.4.dist-info/LICENSE,sha256=kS8EN6yAaGZd7V5z6GKSn_x3ozcZltrfRky4vMPRCw8,1072
|
14
|
+
satif_ai-0.2.4.dist-info/METADATA,sha256=3wCHxt5KwmSGllAwhqSQus7rgtcbteW7DYPmKRxIO-A,670
|
15
|
+
satif_ai-0.2.4.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
16
|
+
satif_ai-0.2.4.dist-info/entry_points.txt,sha256=Mz2SwYALjktap1bF-Q3EWBgiZVNT6QJCVsCs_fCV33Y,43
|
17
|
+
satif_ai-0.2.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|