scitex 2.11.0__py3-none-any.whl → 2.13.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.
- scitex/__main__.py +24 -5
- scitex/__version__.py +1 -1
- scitex/_optional_deps.py +33 -0
- scitex/ai/classification/reporters/_ClassificationReporter.py +1 -1
- scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +2 -2
- scitex/ai/classification/timeseries/_normalize_timestamp.py +1 -1
- scitex/ai/metrics/_calc_seizure_prediction_metrics.py +1 -1
- scitex/ai/plt/_plot_feature_importance.py +1 -1
- scitex/ai/plt/_plot_learning_curve.py +1 -1
- scitex/ai/plt/_plot_optuna_study.py +1 -1
- scitex/ai/plt/_plot_pre_rec_curve.py +1 -1
- scitex/ai/plt/_plot_roc_curve.py +1 -1
- scitex/ai/plt/_stx_conf_mat.py +1 -1
- scitex/ai/training/_LearningCurveLogger.py +1 -1
- scitex/audio/mcp_server.py +38 -8
- scitex/browser/automation/CookieHandler.py +1 -1
- scitex/browser/core/BrowserMixin.py +1 -1
- scitex/browser/core/ChromeProfileManager.py +1 -1
- scitex/browser/debugging/_browser_logger.py +1 -1
- scitex/browser/debugging/_highlight_element.py +1 -1
- scitex/browser/debugging/_show_grid.py +1 -1
- scitex/browser/interaction/click_center.py +1 -1
- scitex/browser/interaction/click_with_fallbacks.py +1 -1
- scitex/browser/interaction/close_popups.py +1 -1
- scitex/browser/interaction/fill_with_fallbacks.py +1 -1
- scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +1 -1
- scitex/browser/pdf/detect_chrome_pdf_viewer.py +1 -1
- scitex/browser/stealth/HumanBehavior.py +1 -1
- scitex/browser/stealth/StealthManager.py +1 -1
- scitex/canvas/_mcp_handlers.py +372 -0
- scitex/canvas/_mcp_tool_schemas.py +219 -0
- scitex/canvas/mcp_server.py +151 -0
- scitex/capture/mcp_server.py +41 -12
- scitex/cli/audio.py +233 -0
- scitex/cli/capture.py +307 -0
- scitex/cli/main.py +27 -4
- scitex/cli/repro.py +233 -0
- scitex/cli/resource.py +240 -0
- scitex/cli/stats.py +325 -0
- scitex/cli/template.py +236 -0
- scitex/cli/tex.py +286 -0
- scitex/cli/web.py +11 -12
- scitex/dev/__init__.py +3 -0
- scitex/dev/_pyproject.py +405 -0
- scitex/dev/plt/__init__.py +2 -2
- scitex/dev/plt/mpl/get_dir_ax.py +1 -1
- scitex/dev/plt/mpl/get_signatures.py +1 -1
- scitex/dev/plt/mpl/get_signatures_details.py +1 -1
- scitex/diagram/_mcp_handlers.py +400 -0
- scitex/diagram/_mcp_tool_schemas.py +157 -0
- scitex/diagram/mcp_server.py +151 -0
- scitex/dsp/_demo_sig.py +51 -5
- scitex/dsp/_mne.py +13 -2
- scitex/dsp/_modulation_index.py +15 -3
- scitex/dsp/_pac.py +23 -5
- scitex/dsp/_psd.py +16 -4
- scitex/dsp/_resample.py +24 -4
- scitex/dsp/_transform.py +16 -3
- scitex/dsp/add_noise.py +15 -1
- scitex/dsp/norm.py +17 -2
- scitex/dsp/reference.py +17 -1
- scitex/dsp/utils/_differential_bandpass_filters.py +20 -2
- scitex/dsp/utils/_zero_pad.py +18 -4
- scitex/dt/_normalize_timestamp.py +1 -1
- scitex/git/_session.py +1 -1
- scitex/io/_load_modules/_con.py +12 -1
- scitex/io/_load_modules/_eeg.py +12 -1
- scitex/io/_load_modules/_optuna.py +21 -63
- scitex/io/_load_modules/_torch.py +11 -3
- scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +13 -2
- scitex/io/_save_modules/_torch.py +11 -3
- scitex/mcp_server.py +159 -0
- scitex/plt/_mcp_handlers.py +361 -0
- scitex/plt/_mcp_tool_schemas.py +169 -0
- scitex/plt/mcp_server.py +205 -0
- scitex/repro/README_RandomStateManager.md +3 -3
- scitex/repro/_RandomStateManager.py +14 -14
- scitex/repro/_gen_ID.py +1 -1
- scitex/repro/_gen_timestamp.py +1 -1
- scitex/repro/_hash_array.py +4 -4
- scitex/scholar/__main__.py +24 -2
- scitex/scholar/_mcp_handlers.py +685 -0
- scitex/scholar/_mcp_tool_schemas.py +339 -0
- scitex/scholar/docs/template.py +1 -1
- scitex/scholar/examples/07_storage_integration.py +1 -1
- scitex/scholar/impact_factor/jcr/ImpactFactorJCREngine.py +1 -1
- scitex/scholar/impact_factor/jcr/build_database.py +1 -1
- scitex/scholar/mcp_server.py +315 -0
- scitex/scholar/pdf_download/ScholarPDFDownloader.py +1 -1
- scitex/scholar/pipelines/ScholarPipelineBibTeX.py +1 -1
- scitex/scholar/pipelines/ScholarPipelineParallel.py +1 -1
- scitex/scholar/pipelines/ScholarPipelineSingle.py +1 -1
- scitex/scholar/storage/PaperIO.py +1 -1
- scitex/session/README.md +4 -4
- scitex/session/__init__.py +1 -1
- scitex/session/_decorator.py +9 -9
- scitex/session/_lifecycle.py +5 -5
- scitex/session/template.py +1 -1
- scitex/stats/__main__.py +281 -0
- scitex/stats/_mcp_handlers.py +1191 -0
- scitex/stats/_mcp_tool_schemas.py +384 -0
- scitex/stats/correct/_correct_bonferroni.py +1 -1
- scitex/stats/correct/_correct_fdr.py +1 -1
- scitex/stats/correct/_correct_fdr_.py +1 -1
- scitex/stats/correct/_correct_holm.py +1 -1
- scitex/stats/correct/_correct_sidak.py +1 -1
- scitex/stats/effect_sizes/_cliffs_delta.py +1 -1
- scitex/stats/effect_sizes/_cohens_d.py +1 -1
- scitex/stats/effect_sizes/_epsilon_squared.py +1 -1
- scitex/stats/effect_sizes/_eta_squared.py +1 -1
- scitex/stats/effect_sizes/_prob_superiority.py +1 -1
- scitex/stats/mcp_server.py +405 -0
- scitex/stats/posthoc/_dunnett.py +1 -1
- scitex/stats/posthoc/_games_howell.py +1 -1
- scitex/stats/posthoc/_tukey_hsd.py +1 -1
- scitex/stats/power/_power.py +1 -1
- scitex/stats/utils/_effect_size.py +1 -1
- scitex/stats/utils/_formatters.py +1 -1
- scitex/stats/utils/_power.py +1 -1
- scitex/template/_mcp_handlers.py +259 -0
- scitex/template/_mcp_tool_schemas.py +112 -0
- scitex/template/mcp_server.py +186 -0
- scitex/utils/_verify_scitex_format.py +2 -2
- scitex/utils/template.py +1 -1
- scitex/web/__init__.py +12 -11
- scitex/web/_scraping.py +26 -265
- scitex/web/download_images.py +316 -0
- scitex/writer/Writer.py +1 -1
- scitex/writer/_clone_writer_project.py +1 -1
- scitex/writer/_validate_tree_structures.py +1 -1
- scitex/writer/dataclasses/config/_WriterConfig.py +1 -1
- scitex/writer/dataclasses/contents/_ManuscriptContents.py +1 -1
- scitex/writer/dataclasses/core/_Document.py +1 -1
- scitex/writer/dataclasses/core/_DocumentSection.py +1 -1
- scitex/writer/dataclasses/results/_CompilationResult.py +1 -1
- scitex/writer/dataclasses/results/_LaTeXIssue.py +1 -1
- scitex/writer/utils/.legacy_git_retry.py +7 -5
- scitex/writer/utils/_parse_latex_logs.py +1 -1
- {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/METADATA +431 -269
- {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/RECORD +147 -118
- scitex-2.13.0.dist-info/entry_points.txt +11 -0
- scitex-2.11.0.dist-info/entry_points.txt +0 -2
- {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/WHEEL +0 -0
- {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: 2026-01-08
|
|
3
|
+
# File: src/scitex/canvas/_mcp_handlers.py
|
|
4
|
+
# ----------------------------------------
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
MCP Handler implementations for SciTeX canvas module.
|
|
8
|
+
|
|
9
|
+
Provides async handlers for multi-panel figure composition.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import asyncio
|
|
15
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
async def create_canvas_handler(
|
|
19
|
+
parent_dir: str,
|
|
20
|
+
canvas_name: str,
|
|
21
|
+
width_mm: float = 180,
|
|
22
|
+
height_mm: float = 120,
|
|
23
|
+
) -> dict:
|
|
24
|
+
"""
|
|
25
|
+
Create a new canvas workspace.
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
parent_dir : str
|
|
30
|
+
Parent directory for canvas
|
|
31
|
+
canvas_name : str
|
|
32
|
+
Name for the canvas
|
|
33
|
+
width_mm : float
|
|
34
|
+
Canvas width in mm
|
|
35
|
+
height_mm : float
|
|
36
|
+
Canvas height in mm
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
dict
|
|
41
|
+
Success status and canvas info
|
|
42
|
+
"""
|
|
43
|
+
try:
|
|
44
|
+
import scitex.canvas as canvas_module
|
|
45
|
+
|
|
46
|
+
loop = asyncio.get_event_loop()
|
|
47
|
+
await loop.run_in_executor(
|
|
48
|
+
None,
|
|
49
|
+
lambda: canvas_module.create_canvas(
|
|
50
|
+
parent_dir,
|
|
51
|
+
canvas_name,
|
|
52
|
+
),
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
canvas_path = canvas_module.get_canvas_path(parent_dir, canvas_name)
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
"success": True,
|
|
59
|
+
"canvas_name": canvas_name,
|
|
60
|
+
"canvas_path": str(canvas_path),
|
|
61
|
+
"size_mm": {"width": width_mm, "height": height_mm},
|
|
62
|
+
"message": f"Created canvas '{canvas_name}' at {canvas_path}",
|
|
63
|
+
}
|
|
64
|
+
except Exception as e:
|
|
65
|
+
return {
|
|
66
|
+
"success": False,
|
|
67
|
+
"error": str(e),
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
async def add_panel_handler(
|
|
72
|
+
parent_dir: str,
|
|
73
|
+
canvas_name: str,
|
|
74
|
+
panel_name: str,
|
|
75
|
+
source: str,
|
|
76
|
+
x_mm: float = 0,
|
|
77
|
+
y_mm: float = 0,
|
|
78
|
+
width_mm: float = 50,
|
|
79
|
+
height_mm: float = 50,
|
|
80
|
+
label: Optional[str] = None,
|
|
81
|
+
) -> dict:
|
|
82
|
+
"""
|
|
83
|
+
Add a panel to a canvas.
|
|
84
|
+
|
|
85
|
+
Parameters
|
|
86
|
+
----------
|
|
87
|
+
parent_dir : str
|
|
88
|
+
Parent directory containing canvas
|
|
89
|
+
canvas_name : str
|
|
90
|
+
Canvas name
|
|
91
|
+
panel_name : str
|
|
92
|
+
Name for this panel
|
|
93
|
+
source : str
|
|
94
|
+
Path to source file
|
|
95
|
+
x_mm, y_mm : float
|
|
96
|
+
Position in mm
|
|
97
|
+
width_mm, height_mm : float
|
|
98
|
+
Size in mm
|
|
99
|
+
label : str, optional
|
|
100
|
+
Panel label (A, B, C...)
|
|
101
|
+
|
|
102
|
+
Returns
|
|
103
|
+
-------
|
|
104
|
+
dict
|
|
105
|
+
Success status and panel info
|
|
106
|
+
"""
|
|
107
|
+
try:
|
|
108
|
+
import scitex.canvas as canvas_module
|
|
109
|
+
|
|
110
|
+
loop = asyncio.get_event_loop()
|
|
111
|
+
await loop.run_in_executor(
|
|
112
|
+
None,
|
|
113
|
+
lambda: canvas_module.add_panel(
|
|
114
|
+
parent_dir=parent_dir,
|
|
115
|
+
canvas_name=canvas_name,
|
|
116
|
+
panel_name=panel_name,
|
|
117
|
+
source=source,
|
|
118
|
+
xy_mm=(x_mm, y_mm),
|
|
119
|
+
size_mm=(width_mm, height_mm),
|
|
120
|
+
label=label or "",
|
|
121
|
+
),
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
"success": True,
|
|
126
|
+
"canvas_name": canvas_name,
|
|
127
|
+
"panel_name": panel_name,
|
|
128
|
+
"source": source,
|
|
129
|
+
"position_mm": {"x": x_mm, "y": y_mm},
|
|
130
|
+
"size_mm": {"width": width_mm, "height": height_mm},
|
|
131
|
+
"label": label,
|
|
132
|
+
"message": f"Added panel '{panel_name}' to canvas '{canvas_name}'",
|
|
133
|
+
}
|
|
134
|
+
except Exception as e:
|
|
135
|
+
return {
|
|
136
|
+
"success": False,
|
|
137
|
+
"error": str(e),
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
async def list_panels_handler(
|
|
142
|
+
parent_dir: str,
|
|
143
|
+
canvas_name: str,
|
|
144
|
+
) -> dict:
|
|
145
|
+
"""
|
|
146
|
+
List all panels in a canvas.
|
|
147
|
+
|
|
148
|
+
Parameters
|
|
149
|
+
----------
|
|
150
|
+
parent_dir : str
|
|
151
|
+
Parent directory
|
|
152
|
+
canvas_name : str
|
|
153
|
+
Canvas name
|
|
154
|
+
|
|
155
|
+
Returns
|
|
156
|
+
-------
|
|
157
|
+
dict
|
|
158
|
+
Success status and panel list
|
|
159
|
+
"""
|
|
160
|
+
try:
|
|
161
|
+
import scitex.canvas as canvas_module
|
|
162
|
+
|
|
163
|
+
loop = asyncio.get_event_loop()
|
|
164
|
+
panels = await loop.run_in_executor(
|
|
165
|
+
None,
|
|
166
|
+
lambda: canvas_module.list_panels(parent_dir, canvas_name),
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
"success": True,
|
|
171
|
+
"canvas_name": canvas_name,
|
|
172
|
+
"count": len(panels) if panels else 0,
|
|
173
|
+
"panels": panels or [],
|
|
174
|
+
}
|
|
175
|
+
except Exception as e:
|
|
176
|
+
return {
|
|
177
|
+
"success": False,
|
|
178
|
+
"error": str(e),
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
async def remove_panel_handler(
|
|
183
|
+
parent_dir: str,
|
|
184
|
+
canvas_name: str,
|
|
185
|
+
panel_name: str,
|
|
186
|
+
) -> dict:
|
|
187
|
+
"""
|
|
188
|
+
Remove a panel from a canvas.
|
|
189
|
+
|
|
190
|
+
Parameters
|
|
191
|
+
----------
|
|
192
|
+
parent_dir : str
|
|
193
|
+
Parent directory
|
|
194
|
+
canvas_name : str
|
|
195
|
+
Canvas name
|
|
196
|
+
panel_name : str
|
|
197
|
+
Panel to remove
|
|
198
|
+
|
|
199
|
+
Returns
|
|
200
|
+
-------
|
|
201
|
+
dict
|
|
202
|
+
Success status
|
|
203
|
+
"""
|
|
204
|
+
try:
|
|
205
|
+
import scitex.canvas as canvas_module
|
|
206
|
+
|
|
207
|
+
loop = asyncio.get_event_loop()
|
|
208
|
+
await loop.run_in_executor(
|
|
209
|
+
None,
|
|
210
|
+
lambda: canvas_module.remove_panel(parent_dir, canvas_name, panel_name),
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
"success": True,
|
|
215
|
+
"canvas_name": canvas_name,
|
|
216
|
+
"panel_name": panel_name,
|
|
217
|
+
"message": f"Removed panel '{panel_name}' from canvas '{canvas_name}'",
|
|
218
|
+
}
|
|
219
|
+
except Exception as e:
|
|
220
|
+
return {
|
|
221
|
+
"success": False,
|
|
222
|
+
"error": str(e),
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
async def export_canvas_handler(
|
|
227
|
+
parent_dir: str,
|
|
228
|
+
canvas_name: str,
|
|
229
|
+
output_path: Optional[str] = None,
|
|
230
|
+
format: Optional[str] = None,
|
|
231
|
+
dpi: int = 300,
|
|
232
|
+
) -> dict:
|
|
233
|
+
"""
|
|
234
|
+
Export canvas to file.
|
|
235
|
+
|
|
236
|
+
Parameters
|
|
237
|
+
----------
|
|
238
|
+
parent_dir : str
|
|
239
|
+
Parent directory
|
|
240
|
+
canvas_name : str
|
|
241
|
+
Canvas name
|
|
242
|
+
output_path : str, optional
|
|
243
|
+
Output file path
|
|
244
|
+
format : str, optional
|
|
245
|
+
Output format (png, pdf, svg)
|
|
246
|
+
dpi : int
|
|
247
|
+
Output DPI
|
|
248
|
+
|
|
249
|
+
Returns
|
|
250
|
+
-------
|
|
251
|
+
dict
|
|
252
|
+
Success status and output path
|
|
253
|
+
"""
|
|
254
|
+
try:
|
|
255
|
+
from pathlib import Path
|
|
256
|
+
|
|
257
|
+
import scitex.canvas as canvas_module
|
|
258
|
+
|
|
259
|
+
# Build output path if not provided
|
|
260
|
+
if output_path is None:
|
|
261
|
+
canvas_path = canvas_module.get_canvas_path(parent_dir, canvas_name)
|
|
262
|
+
fmt = format or "png"
|
|
263
|
+
output_path = str(Path(canvas_path) / "exports" / f"{canvas_name}.{fmt}")
|
|
264
|
+
|
|
265
|
+
loop = asyncio.get_event_loop()
|
|
266
|
+
result_path = await loop.run_in_executor(
|
|
267
|
+
None,
|
|
268
|
+
lambda: canvas_module.export_canvas(
|
|
269
|
+
parent_dir,
|
|
270
|
+
canvas_name,
|
|
271
|
+
output_path,
|
|
272
|
+
),
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
"success": True,
|
|
277
|
+
"canvas_name": canvas_name,
|
|
278
|
+
"output_path": str(result_path) if result_path else output_path,
|
|
279
|
+
"format": format or Path(output_path).suffix.lstrip("."),
|
|
280
|
+
"dpi": dpi,
|
|
281
|
+
"message": f"Exported canvas to {output_path}",
|
|
282
|
+
}
|
|
283
|
+
except Exception as e:
|
|
284
|
+
return {
|
|
285
|
+
"success": False,
|
|
286
|
+
"error": str(e),
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
async def list_canvases_handler(parent_dir: str) -> dict:
|
|
291
|
+
"""
|
|
292
|
+
List all canvases in a directory.
|
|
293
|
+
|
|
294
|
+
Parameters
|
|
295
|
+
----------
|
|
296
|
+
parent_dir : str
|
|
297
|
+
Directory to search
|
|
298
|
+
|
|
299
|
+
Returns
|
|
300
|
+
-------
|
|
301
|
+
dict
|
|
302
|
+
Success status and canvas list
|
|
303
|
+
"""
|
|
304
|
+
try:
|
|
305
|
+
import scitex.canvas as canvas_module
|
|
306
|
+
|
|
307
|
+
loop = asyncio.get_event_loop()
|
|
308
|
+
canvases = await loop.run_in_executor(
|
|
309
|
+
None,
|
|
310
|
+
lambda: canvas_module.list_canvases(parent_dir),
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
return {
|
|
314
|
+
"success": True,
|
|
315
|
+
"parent_dir": parent_dir,
|
|
316
|
+
"count": len(canvases) if canvases else 0,
|
|
317
|
+
"canvases": canvases or [],
|
|
318
|
+
}
|
|
319
|
+
except Exception as e:
|
|
320
|
+
return {
|
|
321
|
+
"success": False,
|
|
322
|
+
"error": str(e),
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
async def canvas_exists_handler(
|
|
327
|
+
parent_dir: str,
|
|
328
|
+
canvas_name: str,
|
|
329
|
+
) -> dict:
|
|
330
|
+
"""
|
|
331
|
+
Check if a canvas exists.
|
|
332
|
+
|
|
333
|
+
Parameters
|
|
334
|
+
----------
|
|
335
|
+
parent_dir : str
|
|
336
|
+
Parent directory
|
|
337
|
+
canvas_name : str
|
|
338
|
+
Canvas name
|
|
339
|
+
|
|
340
|
+
Returns
|
|
341
|
+
-------
|
|
342
|
+
dict
|
|
343
|
+
Success status and existence flag
|
|
344
|
+
"""
|
|
345
|
+
try:
|
|
346
|
+
import scitex.canvas as canvas_module
|
|
347
|
+
|
|
348
|
+
exists = canvas_module.canvas_exists(parent_dir, canvas_name)
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
"success": True,
|
|
352
|
+
"canvas_name": canvas_name,
|
|
353
|
+
"exists": exists,
|
|
354
|
+
}
|
|
355
|
+
except Exception as e:
|
|
356
|
+
return {
|
|
357
|
+
"success": False,
|
|
358
|
+
"error": str(e),
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
__all__ = [
|
|
363
|
+
"create_canvas_handler",
|
|
364
|
+
"add_panel_handler",
|
|
365
|
+
"list_panels_handler",
|
|
366
|
+
"remove_panel_handler",
|
|
367
|
+
"export_canvas_handler",
|
|
368
|
+
"list_canvases_handler",
|
|
369
|
+
"canvas_exists_handler",
|
|
370
|
+
]
|
|
371
|
+
|
|
372
|
+
# EOF
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: 2026-01-08
|
|
3
|
+
# File: src/scitex/canvas/_mcp_tool_schemas.py
|
|
4
|
+
# ----------------------------------------
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
MCP Tool schemas for SciTeX canvas module.
|
|
8
|
+
|
|
9
|
+
Defines tools for multi-panel figure composition:
|
|
10
|
+
- create_canvas: Create paper figure workspace
|
|
11
|
+
- add_panel: Add subplot to canvas
|
|
12
|
+
- list_panels: List panels in canvas
|
|
13
|
+
- export_canvas: Render final figure
|
|
14
|
+
- list_canvases: List available canvases
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import mcp.types as types
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_tool_schemas() -> list[types.Tool]:
|
|
23
|
+
"""Return list of available MCP tools for canvas operations."""
|
|
24
|
+
return [
|
|
25
|
+
# Create canvas
|
|
26
|
+
types.Tool(
|
|
27
|
+
name="create_canvas",
|
|
28
|
+
description="Create a new paper figure canvas workspace for multi-panel composition",
|
|
29
|
+
inputSchema={
|
|
30
|
+
"type": "object",
|
|
31
|
+
"properties": {
|
|
32
|
+
"parent_dir": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"description": "Parent directory for the canvas",
|
|
35
|
+
},
|
|
36
|
+
"canvas_name": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "Name for the canvas (e.g., 'fig1', 'Figure_2')",
|
|
39
|
+
},
|
|
40
|
+
"width_mm": {
|
|
41
|
+
"type": "number",
|
|
42
|
+
"description": "Canvas width in millimeters (default: 180 for double column)",
|
|
43
|
+
"default": 180,
|
|
44
|
+
},
|
|
45
|
+
"height_mm": {
|
|
46
|
+
"type": "number",
|
|
47
|
+
"description": "Canvas height in millimeters (default: 120)",
|
|
48
|
+
"default": 120,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
"required": ["parent_dir", "canvas_name"],
|
|
52
|
+
},
|
|
53
|
+
),
|
|
54
|
+
# Add panel
|
|
55
|
+
types.Tool(
|
|
56
|
+
name="add_panel",
|
|
57
|
+
description="Add a panel (subplot) to an existing canvas from an image or plot file",
|
|
58
|
+
inputSchema={
|
|
59
|
+
"type": "object",
|
|
60
|
+
"properties": {
|
|
61
|
+
"parent_dir": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"description": "Parent directory containing the canvas",
|
|
64
|
+
},
|
|
65
|
+
"canvas_name": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"description": "Canvas name",
|
|
68
|
+
},
|
|
69
|
+
"panel_name": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"description": "Name for this panel (e.g., 'panel_a', 'timecourse')",
|
|
72
|
+
},
|
|
73
|
+
"source": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"description": "Path to source file (PNG, JPG, SVG, or SciTeX plot)",
|
|
76
|
+
},
|
|
77
|
+
"x_mm": {
|
|
78
|
+
"type": "number",
|
|
79
|
+
"description": "X position in millimeters from left edge",
|
|
80
|
+
"default": 0,
|
|
81
|
+
},
|
|
82
|
+
"y_mm": {
|
|
83
|
+
"type": "number",
|
|
84
|
+
"description": "Y position in millimeters from top edge",
|
|
85
|
+
"default": 0,
|
|
86
|
+
},
|
|
87
|
+
"width_mm": {
|
|
88
|
+
"type": "number",
|
|
89
|
+
"description": "Panel width in millimeters",
|
|
90
|
+
"default": 50,
|
|
91
|
+
},
|
|
92
|
+
"height_mm": {
|
|
93
|
+
"type": "number",
|
|
94
|
+
"description": "Panel height in millimeters",
|
|
95
|
+
"default": 50,
|
|
96
|
+
},
|
|
97
|
+
"label": {
|
|
98
|
+
"type": "string",
|
|
99
|
+
"description": "Panel label (e.g., 'A', 'B', 'C')",
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
"required": ["parent_dir", "canvas_name", "panel_name", "source"],
|
|
103
|
+
},
|
|
104
|
+
),
|
|
105
|
+
# List panels
|
|
106
|
+
types.Tool(
|
|
107
|
+
name="list_panels",
|
|
108
|
+
description="List all panels in a canvas with their properties",
|
|
109
|
+
inputSchema={
|
|
110
|
+
"type": "object",
|
|
111
|
+
"properties": {
|
|
112
|
+
"parent_dir": {
|
|
113
|
+
"type": "string",
|
|
114
|
+
"description": "Parent directory containing the canvas",
|
|
115
|
+
},
|
|
116
|
+
"canvas_name": {
|
|
117
|
+
"type": "string",
|
|
118
|
+
"description": "Canvas name",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
"required": ["parent_dir", "canvas_name"],
|
|
122
|
+
},
|
|
123
|
+
),
|
|
124
|
+
# Remove panel
|
|
125
|
+
types.Tool(
|
|
126
|
+
name="remove_panel",
|
|
127
|
+
description="Remove a panel from a canvas",
|
|
128
|
+
inputSchema={
|
|
129
|
+
"type": "object",
|
|
130
|
+
"properties": {
|
|
131
|
+
"parent_dir": {
|
|
132
|
+
"type": "string",
|
|
133
|
+
"description": "Parent directory containing the canvas",
|
|
134
|
+
},
|
|
135
|
+
"canvas_name": {
|
|
136
|
+
"type": "string",
|
|
137
|
+
"description": "Canvas name",
|
|
138
|
+
},
|
|
139
|
+
"panel_name": {
|
|
140
|
+
"type": "string",
|
|
141
|
+
"description": "Name of the panel to remove",
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
"required": ["parent_dir", "canvas_name", "panel_name"],
|
|
145
|
+
},
|
|
146
|
+
),
|
|
147
|
+
# Export canvas
|
|
148
|
+
types.Tool(
|
|
149
|
+
name="export_canvas",
|
|
150
|
+
description="Export/render canvas to PNG, PDF, or SVG format",
|
|
151
|
+
inputSchema={
|
|
152
|
+
"type": "object",
|
|
153
|
+
"properties": {
|
|
154
|
+
"parent_dir": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"description": "Parent directory containing the canvas",
|
|
157
|
+
},
|
|
158
|
+
"canvas_name": {
|
|
159
|
+
"type": "string",
|
|
160
|
+
"description": "Canvas name",
|
|
161
|
+
},
|
|
162
|
+
"output_path": {
|
|
163
|
+
"type": "string",
|
|
164
|
+
"description": "Output file path (format determined by extension)",
|
|
165
|
+
},
|
|
166
|
+
"format": {
|
|
167
|
+
"type": "string",
|
|
168
|
+
"description": "Output format (auto-detected from path if not specified)",
|
|
169
|
+
"enum": ["png", "pdf", "svg"],
|
|
170
|
+
},
|
|
171
|
+
"dpi": {
|
|
172
|
+
"type": "integer",
|
|
173
|
+
"description": "Output DPI for raster formats (default: 300)",
|
|
174
|
+
"default": 300,
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
"required": ["parent_dir", "canvas_name"],
|
|
178
|
+
},
|
|
179
|
+
),
|
|
180
|
+
# List canvases
|
|
181
|
+
types.Tool(
|
|
182
|
+
name="list_canvases",
|
|
183
|
+
description="List all canvases in a directory",
|
|
184
|
+
inputSchema={
|
|
185
|
+
"type": "object",
|
|
186
|
+
"properties": {
|
|
187
|
+
"parent_dir": {
|
|
188
|
+
"type": "string",
|
|
189
|
+
"description": "Directory to search for canvases",
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
"required": ["parent_dir"],
|
|
193
|
+
},
|
|
194
|
+
),
|
|
195
|
+
# Canvas exists
|
|
196
|
+
types.Tool(
|
|
197
|
+
name="canvas_exists",
|
|
198
|
+
description="Check if a canvas exists",
|
|
199
|
+
inputSchema={
|
|
200
|
+
"type": "object",
|
|
201
|
+
"properties": {
|
|
202
|
+
"parent_dir": {
|
|
203
|
+
"type": "string",
|
|
204
|
+
"description": "Parent directory",
|
|
205
|
+
},
|
|
206
|
+
"canvas_name": {
|
|
207
|
+
"type": "string",
|
|
208
|
+
"description": "Canvas name to check",
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
"required": ["parent_dir", "canvas_name"],
|
|
212
|
+
},
|
|
213
|
+
),
|
|
214
|
+
]
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
__all__ = ["get_tool_schemas"]
|
|
218
|
+
|
|
219
|
+
# EOF
|