solidworks-mcp-python 1.5.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.
- solidworks_mcp/__init__.py +57 -0
- solidworks_mcp/adapters/__init__.py +40 -0
- solidworks_mcp/adapters/base.py +1882 -0
- solidworks_mcp/adapters/circuit_breaker.py +2052 -0
- solidworks_mcp/adapters/com_executor.py +252 -0
- solidworks_mcp/adapters/complexity_analyzer.py +272 -0
- solidworks_mcp/adapters/connection_pool.py +1884 -0
- solidworks_mcp/adapters/factory.py +366 -0
- solidworks_mcp/adapters/intelligent_router.py +218 -0
- solidworks_mcp/adapters/mock_adapter.py +4016 -0
- solidworks_mcp/adapters/pywin32_adapter.py +2842 -0
- solidworks_mcp/adapters/solidworks/__init__.py +17 -0
- solidworks_mcp/adapters/solidworks/bitmap.py +180 -0
- solidworks_mcp/adapters/solidworks/com_utils.py +56 -0
- solidworks_mcp/adapters/solidworks/dimension_layout.py +753 -0
- solidworks_mcp/adapters/solidworks/documentation.py +1476 -0
- solidworks_mcp/adapters/solidworks/drawing_standard.py +1993 -0
- solidworks_mcp/adapters/solidworks/face_selection.py +392 -0
- solidworks_mcp/adapters/solidworks/features.py +3362 -0
- solidworks_mcp/adapters/solidworks/io.py +3649 -0
- solidworks_mcp/adapters/solidworks/rebuild_diagnostics.py +269 -0
- solidworks_mcp/adapters/solidworks/rebuild_inspector.py +146 -0
- solidworks_mcp/adapters/solidworks/selection.py +308 -0
- solidworks_mcp/adapters/solidworks/sketch.py +2545 -0
- solidworks_mcp/adapters/sw_feature_errors.py +66 -0
- solidworks_mcp/adapters/sw_type_info.py +317 -0
- solidworks_mcp/adapters/vba_adapter.py +318 -0
- solidworks_mcp/adapters/vba_macro_executor.py +215 -0
- solidworks_mcp/agents/__init__.py +68 -0
- solidworks_mcp/agents/design_knowledge/assembly_patterns.md +127 -0
- solidworks_mcp/agents/design_knowledge/hinges.md +118 -0
- solidworks_mcp/agents/design_knowledge/snap_fits.md +93 -0
- solidworks_mcp/agents/design_knowledge/solidworks_basics.md +3 -0
- solidworks_mcp/agents/design_knowledge/tolerancing.md +128 -0
- solidworks_mcp/agents/harness.py +216 -0
- solidworks_mcp/agents/history_db.py +1508 -0
- solidworks_mcp/agents/retrieval_index.py +164 -0
- solidworks_mcp/agents/schemas.py +165 -0
- solidworks_mcp/agents/smoke_test.py +285 -0
- solidworks_mcp/agents/soc_exporter.py +650 -0
- solidworks_mcp/agents/soc_pickup.py +332 -0
- solidworks_mcp/agents/soc_rewind.py +221 -0
- solidworks_mcp/agents/vector_rag.py +665 -0
- solidworks_mcp/cache/__init__.py +5 -0
- solidworks_mcp/cache/response_cache.py +164 -0
- solidworks_mcp/config.py +729 -0
- solidworks_mcp/exceptions.py +37 -0
- solidworks_mcp/security/__init__.py +68 -0
- solidworks_mcp/security/auth.py +128 -0
- solidworks_mcp/security/cors.py +27 -0
- solidworks_mcp/security/rate_limiting.py +90 -0
- solidworks_mcp/security/runtime.py +155 -0
- solidworks_mcp/server.py +777 -0
- solidworks_mcp/server_cli_fixed.py +120 -0
- solidworks_mcp/setup/__init__.py +1 -0
- solidworks_mcp/setup/cli.py +399 -0
- solidworks_mcp/setup/clients.py +157 -0
- solidworks_mcp/setup/config_file.py +230 -0
- solidworks_mcp/setup/handshake.py +202 -0
- solidworks_mcp/setup/launcher.py +102 -0
- solidworks_mcp/setup/legacy.py +100 -0
- solidworks_mcp/setup/registration.py +193 -0
- solidworks_mcp/setup/solidworks.py +49 -0
- solidworks_mcp/tools/__init__.py +64 -0
- solidworks_mcp/tools/analysis.py +723 -0
- solidworks_mcp/tools/automation.py +578 -0
- solidworks_mcp/tools/docs_discovery.py +1476 -0
- solidworks_mcp/tools/drawing.py +1015 -0
- solidworks_mcp/tools/drawing_analysis.py +456 -0
- solidworks_mcp/tools/drawing_automation.py +627 -0
- solidworks_mcp/tools/engineering_data.py +466 -0
- solidworks_mcp/tools/error_classifier.py +232 -0
- solidworks_mcp/tools/export.py +833 -0
- solidworks_mcp/tools/file_facts.py +40 -0
- solidworks_mcp/tools/file_management.py +1473 -0
- solidworks_mcp/tools/input_compat.py +17 -0
- solidworks_mcp/tools/macro_recording.py +464 -0
- solidworks_mcp/tools/modeling.py +2360 -0
- solidworks_mcp/tools/sketching.py +1422 -0
- solidworks_mcp/tools/template_management.py +367 -0
- solidworks_mcp/tools/tool_boundary.py +280 -0
- solidworks_mcp/tools/vba_generation.py +1145 -0
- solidworks_mcp/ui/__init__.py +9 -0
- solidworks_mcp/ui/local_llm.py +725 -0
- solidworks_mcp/ui/routers/__init__.py +10 -0
- solidworks_mcp/ui/routers/checkpoint.py +24 -0
- solidworks_mcp/ui/routers/docs.py +47 -0
- solidworks_mcp/ui/routers/llm.py +83 -0
- solidworks_mcp/ui/routers/local_model.py +69 -0
- solidworks_mcp/ui/routers/model.py +75 -0
- solidworks_mcp/ui/routers/preview.py +38 -0
- solidworks_mcp/ui/routers/session.py +161 -0
- solidworks_mcp/ui/routers/viewer.py +154 -0
- solidworks_mcp/ui/schemas.py +502 -0
- solidworks_mcp/ui/server.py +298 -0
- solidworks_mcp/ui/service.py +481 -0
- solidworks_mcp/ui/services/__init__.py +136 -0
- solidworks_mcp/ui/services/_utils.py +958 -0
- solidworks_mcp/ui/services/checkpoint_service.py +1110 -0
- solidworks_mcp/ui/services/docs_service.py +282 -0
- solidworks_mcp/ui/services/llm_service.py +956 -0
- solidworks_mcp/ui/services/model_service.py +459 -0
- solidworks_mcp/ui/services/parameter_repair_service.py +314 -0
- solidworks_mcp/ui/services/preview_service.py +489 -0
- solidworks_mcp/ui/services/session_service.py +1389 -0
- solidworks_mcp/utils/__init__.py +9 -0
- solidworks_mcp/utils/feature_tree_classifier.py +342 -0
- solidworks_mcp/utils/logging.py +76 -0
- solidworks_mcp/utils/validation.py +77 -0
- solidworks_mcp/version.py +8 -0
- solidworks_mcp_python-1.5.0.dist-info/METADATA +410 -0
- solidworks_mcp_python-1.5.0.dist-info/RECORD +115 -0
- solidworks_mcp_python-1.5.0.dist-info/WHEEL +4 -0
- solidworks_mcp_python-1.5.0.dist-info/entry_points.txt +3 -0
- solidworks_mcp_python-1.5.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
"""Compatibility shim for legacy imports from solidworks_mcp.ui.service.
|
|
2
|
+
|
|
3
|
+
The UI backend was split into focused modules under solidworks_mcp.ui.services.
|
|
4
|
+
This module preserves historical import paths used by tests and external callers.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import os as os # re-exported: tests read service.os
|
|
10
|
+
from contextlib import contextmanager
|
|
11
|
+
from io import BytesIO
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Any
|
|
14
|
+
from urllib.parse import urlparse
|
|
15
|
+
from urllib.request import Request, urlopen
|
|
16
|
+
|
|
17
|
+
from ..adapters import create_adapter
|
|
18
|
+
|
|
19
|
+
# Re-exported (``name as name``) for the legacy ``ui.service.<name>`` imports.
|
|
20
|
+
from ..agents.history_db import (
|
|
21
|
+
get_design_session as get_design_session,
|
|
22
|
+
)
|
|
23
|
+
from ..agents.history_db import (
|
|
24
|
+
insert_model_state_snapshot as insert_model_state_snapshot,
|
|
25
|
+
)
|
|
26
|
+
from ..agents.history_db import (
|
|
27
|
+
list_plan_checkpoints,
|
|
28
|
+
)
|
|
29
|
+
from ..agents.history_db import (
|
|
30
|
+
upsert_design_session as upsert_design_session,
|
|
31
|
+
)
|
|
32
|
+
from ..agents.retrieval_index import _chunk_text
|
|
33
|
+
from ..agents.schemas import RecoverableFailure as _AgentRecoverableFailure
|
|
34
|
+
from ..config import load_config
|
|
35
|
+
from .services import * # noqa: F401,F403,F405
|
|
36
|
+
from .services import _utils as _utils_service
|
|
37
|
+
from .services import checkpoint_service as _checkpoint_service
|
|
38
|
+
from .services import docs_service as _docs_service
|
|
39
|
+
from .services import llm_service as _llm_service
|
|
40
|
+
from .services import model_service as _model_service
|
|
41
|
+
from .services import preview_service as _preview_service
|
|
42
|
+
from .services import session_service as _session_service
|
|
43
|
+
from .services._utils import DEFAULT_API_ORIGIN, DEFAULT_PREVIEW_ORIENTATION
|
|
44
|
+
from .services._utils import (
|
|
45
|
+
context_file_path as _context_file_path_impl,
|
|
46
|
+
)
|
|
47
|
+
from .services._utils import (
|
|
48
|
+
materialize_uploaded_model as _materialize_uploaded_model_impl,
|
|
49
|
+
)
|
|
50
|
+
from .services._utils import (
|
|
51
|
+
merge_metadata as _merge_metadata,
|
|
52
|
+
)
|
|
53
|
+
from .services._utils import (
|
|
54
|
+
normalize_feature_targets as _normalize_feature_targets,
|
|
55
|
+
)
|
|
56
|
+
from .services._utils import (
|
|
57
|
+
safe_context_name as _safe_context_name,
|
|
58
|
+
)
|
|
59
|
+
from .services._utils import (
|
|
60
|
+
sanitize_model_path_text as _sanitize_model_path_text,
|
|
61
|
+
)
|
|
62
|
+
from .services._utils import (
|
|
63
|
+
sanitize_preview_viewer_url as _sanitize_preview_viewer_url,
|
|
64
|
+
)
|
|
65
|
+
from .services.llm_service import (
|
|
66
|
+
Agent,
|
|
67
|
+
OpenAIChatModel,
|
|
68
|
+
OpenAIProvider,
|
|
69
|
+
_ensure_provider_credentials,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
_ORIG_BUILD_AGENT_MODEL = _llm_service._build_agent_model
|
|
73
|
+
_ORIG_RUN_STRUCTURED_AGENT = _llm_service._run_structured_agent
|
|
74
|
+
|
|
75
|
+
# Keep compatibility with tests importing this symbol from agents.schemas.
|
|
76
|
+
RecoverableFailure = _AgentRecoverableFailure
|
|
77
|
+
|
|
78
|
+
# Legacy constants expected by helper tests.
|
|
79
|
+
DEFAULT_CONTEXT_DIR = _utils_service._DEFAULT_CONTEXT_DIR
|
|
80
|
+
DEFAULT_UPLOADED_MODEL_DIR = _utils_service._DEFAULT_UPLOADED_MODEL_DIR
|
|
81
|
+
|
|
82
|
+
# Keep this symbol available for tests that monkeypatch PDF ingestion behavior.
|
|
83
|
+
try:
|
|
84
|
+
from pypdf import PdfReader # type: ignore
|
|
85
|
+
except Exception:
|
|
86
|
+
PdfReader = None
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# Legacy helper retained for test compatibility.
|
|
90
|
+
def _default_model_for_profile(provider: str, profile: str) -> str:
|
|
91
|
+
if provider == "local":
|
|
92
|
+
profile_models = {
|
|
93
|
+
"small": "local:gemma4:e2b",
|
|
94
|
+
"balanced": "local:gemma4:e4b",
|
|
95
|
+
"large": "local:gemma4:26b",
|
|
96
|
+
}
|
|
97
|
+
return profile_models.get(
|
|
98
|
+
(profile or "balanced").lower(), profile_models["balanced"]
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
profile_models = {
|
|
102
|
+
"small": "github:openai/gpt-4.1-mini",
|
|
103
|
+
"balanced": "github:openai/gpt-4.1",
|
|
104
|
+
"large": "github:openai/gpt-4.1",
|
|
105
|
+
}
|
|
106
|
+
return profile_models.get(
|
|
107
|
+
(profile or "balanced").lower(), profile_models["balanced"]
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@contextmanager
|
|
112
|
+
def _temporary_module_bindings(module: Any, **bindings: Any):
|
|
113
|
+
original: dict[str, Any] = {}
|
|
114
|
+
for name, value in bindings.items():
|
|
115
|
+
if hasattr(module, name):
|
|
116
|
+
original[name] = getattr(module, name)
|
|
117
|
+
setattr(module, name, value)
|
|
118
|
+
try:
|
|
119
|
+
yield
|
|
120
|
+
finally:
|
|
121
|
+
for name in bindings:
|
|
122
|
+
if name in original:
|
|
123
|
+
setattr(module, name, original[name])
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _read_reference_source(source_path: Path) -> str:
|
|
127
|
+
return _utils_service.read_reference_source(source_path)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _read_reference_url(source_url: str) -> tuple[str, str]:
|
|
131
|
+
parsed = urlparse(source_url)
|
|
132
|
+
if parsed.scheme not in {"http", "https"}:
|
|
133
|
+
raise ValueError(f"Disallowed URL scheme: {parsed.scheme!r}")
|
|
134
|
+
request = Request(source_url, headers={"User-Agent": "SolidWorksMCP/1.0"})
|
|
135
|
+
with urlopen(request, timeout=20) as response: # nosec B310
|
|
136
|
+
content_type = response.headers.get_content_type()
|
|
137
|
+
charset = response.headers.get_content_charset() or "utf-8"
|
|
138
|
+
raw_bytes = response.read()
|
|
139
|
+
label = Path(parsed.path).name or parsed.netloc or source_url
|
|
140
|
+
suffix = Path(parsed.path).suffix.lower()
|
|
141
|
+
|
|
142
|
+
if content_type == "application/pdf" or suffix == ".pdf":
|
|
143
|
+
if PdfReader is None:
|
|
144
|
+
raise RuntimeError(
|
|
145
|
+
"Install pypdf to ingest PDF sources, or provide a text, markdown, or HTML source instead."
|
|
146
|
+
)
|
|
147
|
+
reader = PdfReader(BytesIO(raw_bytes))
|
|
148
|
+
text = "\n\n".join((page.extract_text() or "") for page in reader.pages).strip()
|
|
149
|
+
return text, label
|
|
150
|
+
|
|
151
|
+
decoded = raw_bytes.decode(charset, errors="ignore")
|
|
152
|
+
if "html" in content_type or suffix in {".html", ".htm"}:
|
|
153
|
+
parser = _utils_service.HTMLTextExtractor()
|
|
154
|
+
parser.feed(decoded)
|
|
155
|
+
return parser.text().strip(), label
|
|
156
|
+
|
|
157
|
+
return decoded.strip(), label
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _build_agent_model(model_name: str, local_endpoint: str | None = None):
|
|
161
|
+
with _temporary_module_bindings(
|
|
162
|
+
_llm_service,
|
|
163
|
+
OpenAIProvider=OpenAIProvider,
|
|
164
|
+
OpenAIChatModel=OpenAIChatModel,
|
|
165
|
+
):
|
|
166
|
+
return _ORIG_BUILD_AGENT_MODEL(model_name, local_endpoint)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
async def _run_structured_agent(*args: Any, **kwargs: Any):
|
|
170
|
+
with _temporary_module_bindings(
|
|
171
|
+
_llm_service,
|
|
172
|
+
Agent=Agent,
|
|
173
|
+
RecoverableFailure=RecoverableFailure,
|
|
174
|
+
_ensure_provider_credentials=_ensure_provider_credentials,
|
|
175
|
+
_build_agent_model=_build_agent_model,
|
|
176
|
+
):
|
|
177
|
+
result = await _ORIG_RUN_STRUCTURED_AGENT(*args, **kwargs)
|
|
178
|
+
if isinstance(result, RecoverableFailure):
|
|
179
|
+
return result
|
|
180
|
+
if all(
|
|
181
|
+
hasattr(result, name)
|
|
182
|
+
for name in (
|
|
183
|
+
"explanation",
|
|
184
|
+
"remediation_steps",
|
|
185
|
+
"retry_focus",
|
|
186
|
+
"should_retry",
|
|
187
|
+
)
|
|
188
|
+
):
|
|
189
|
+
return RecoverableFailure(
|
|
190
|
+
explanation=str(getattr(result, "explanation", "")),
|
|
191
|
+
remediation_steps=list(getattr(result, "remediation_steps", []) or []),
|
|
192
|
+
retry_focus=str(getattr(result, "retry_focus", "")) or None,
|
|
193
|
+
should_retry=bool(getattr(result, "should_retry", False)),
|
|
194
|
+
)
|
|
195
|
+
return result
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def ensure_uploaded_model_dir(upload_dir: Path | None = None) -> Path:
|
|
199
|
+
return _utils_service.ensure_uploaded_model_dir(
|
|
200
|
+
upload_dir or DEFAULT_UPLOADED_MODEL_DIR
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def ensure_context_dir(context_dir: Path | None = None) -> Path:
|
|
205
|
+
return _utils_service.ensure_context_dir(context_dir or DEFAULT_CONTEXT_DIR)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def _materialize_uploaded_model(
|
|
209
|
+
session_id: str,
|
|
210
|
+
uploaded_files: list[dict[str, Any]] | None,
|
|
211
|
+
*,
|
|
212
|
+
upload_dir: Path | None = None,
|
|
213
|
+
) -> Path:
|
|
214
|
+
return _materialize_uploaded_model_impl(
|
|
215
|
+
session_id,
|
|
216
|
+
uploaded_files,
|
|
217
|
+
upload_dir=upload_dir or DEFAULT_UPLOADED_MODEL_DIR,
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def _context_file_path(
|
|
222
|
+
session_id: str,
|
|
223
|
+
*,
|
|
224
|
+
context_name: str | None = None,
|
|
225
|
+
context_dir: Path | None = None,
|
|
226
|
+
) -> Path:
|
|
227
|
+
return _context_file_path_impl(
|
|
228
|
+
session_id,
|
|
229
|
+
context_name=context_name,
|
|
230
|
+
context_dir=context_dir or DEFAULT_CONTEXT_DIR,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
async def _run_checkpoint_tools(planned: dict[str, Any]) -> dict[str, Any]:
|
|
235
|
+
with _temporary_module_bindings(
|
|
236
|
+
_checkpoint_service,
|
|
237
|
+
create_adapter=create_adapter,
|
|
238
|
+
load_config=load_config,
|
|
239
|
+
):
|
|
240
|
+
return await _checkpoint_service._run_checkpoint_tools(planned)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
async def open_target_model(
|
|
244
|
+
session_id: str,
|
|
245
|
+
*,
|
|
246
|
+
model_path: str | None = None,
|
|
247
|
+
uploaded_files: list[dict[str, Any]] | None = None,
|
|
248
|
+
feature_target_text: str = "",
|
|
249
|
+
db_path: Path | None = None,
|
|
250
|
+
api_origin: str = DEFAULT_API_ORIGIN,
|
|
251
|
+
) -> dict[str, Any]:
|
|
252
|
+
with _temporary_module_bindings(
|
|
253
|
+
_model_service,
|
|
254
|
+
create_adapter=create_adapter,
|
|
255
|
+
load_config=load_config,
|
|
256
|
+
):
|
|
257
|
+
return await _model_service.open_target_model(
|
|
258
|
+
session_id,
|
|
259
|
+
model_path=model_path,
|
|
260
|
+
uploaded_files=uploaded_files,
|
|
261
|
+
feature_target_text=feature_target_text,
|
|
262
|
+
db_path=db_path,
|
|
263
|
+
api_origin=api_origin,
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def fetch_docs_context(
|
|
268
|
+
session_id: str,
|
|
269
|
+
*,
|
|
270
|
+
docs_query: str = "",
|
|
271
|
+
db_path: Path | None = None,
|
|
272
|
+
api_origin: str = DEFAULT_API_ORIGIN,
|
|
273
|
+
) -> dict[str, Any]:
|
|
274
|
+
with _temporary_module_bindings(
|
|
275
|
+
_docs_service,
|
|
276
|
+
urlopen=urlopen,
|
|
277
|
+
):
|
|
278
|
+
return _docs_service.fetch_docs_context(
|
|
279
|
+
session_id,
|
|
280
|
+
docs_query=docs_query,
|
|
281
|
+
db_path=db_path,
|
|
282
|
+
api_origin=api_origin,
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
async def execute_next_checkpoint(
|
|
287
|
+
session_id: str,
|
|
288
|
+
*,
|
|
289
|
+
db_path: Path | None = None,
|
|
290
|
+
) -> dict[str, Any]:
|
|
291
|
+
with (
|
|
292
|
+
_temporary_module_bindings(
|
|
293
|
+
_session_service,
|
|
294
|
+
ensure_dashboard_session=ensure_dashboard_session, # noqa: F405
|
|
295
|
+
build_dashboard_state=build_dashboard_state, # noqa: F405
|
|
296
|
+
),
|
|
297
|
+
_temporary_module_bindings(
|
|
298
|
+
_checkpoint_service,
|
|
299
|
+
list_plan_checkpoints=list_plan_checkpoints,
|
|
300
|
+
merge_metadata=_merge_metadata,
|
|
301
|
+
),
|
|
302
|
+
):
|
|
303
|
+
return await _checkpoint_service.execute_next_checkpoint(
|
|
304
|
+
session_id, db_path=db_path
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
async def refresh_preview(
|
|
309
|
+
session_id: str,
|
|
310
|
+
*,
|
|
311
|
+
orientation: str = DEFAULT_PREVIEW_ORIENTATION,
|
|
312
|
+
db_path: Path | None = None,
|
|
313
|
+
preview_dir: Path | None = None,
|
|
314
|
+
api_origin: str = DEFAULT_API_ORIGIN,
|
|
315
|
+
) -> dict[str, Any]:
|
|
316
|
+
with _temporary_module_bindings(
|
|
317
|
+
_preview_service,
|
|
318
|
+
create_adapter=create_adapter,
|
|
319
|
+
load_config=load_config,
|
|
320
|
+
):
|
|
321
|
+
return await _preview_service.refresh_preview(
|
|
322
|
+
session_id,
|
|
323
|
+
orientation=orientation,
|
|
324
|
+
db_path=db_path,
|
|
325
|
+
preview_dir=preview_dir,
|
|
326
|
+
api_origin=api_origin,
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
async def connect_target_model(
|
|
331
|
+
session_id: str,
|
|
332
|
+
*,
|
|
333
|
+
model_path: str | None = None,
|
|
334
|
+
uploaded_files: list[dict[str, Any]] | None = None,
|
|
335
|
+
feature_target_text: str = "",
|
|
336
|
+
db_path: Path | None = None,
|
|
337
|
+
api_origin: str = DEFAULT_API_ORIGIN,
|
|
338
|
+
) -> dict[str, Any]:
|
|
339
|
+
with (
|
|
340
|
+
_temporary_module_bindings(
|
|
341
|
+
_model_service,
|
|
342
|
+
create_adapter=create_adapter,
|
|
343
|
+
load_config=load_config,
|
|
344
|
+
refresh_preview=refresh_preview,
|
|
345
|
+
),
|
|
346
|
+
_temporary_module_bindings(
|
|
347
|
+
_preview_service,
|
|
348
|
+
create_adapter=create_adapter,
|
|
349
|
+
load_config=load_config,
|
|
350
|
+
),
|
|
351
|
+
):
|
|
352
|
+
return await _model_service.connect_target_model(
|
|
353
|
+
session_id,
|
|
354
|
+
model_path=model_path,
|
|
355
|
+
uploaded_files=uploaded_files,
|
|
356
|
+
feature_target_text=feature_target_text,
|
|
357
|
+
db_path=db_path,
|
|
358
|
+
api_origin=api_origin,
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def ingest_reference_source(
|
|
363
|
+
session_id: str,
|
|
364
|
+
*,
|
|
365
|
+
source_path: str,
|
|
366
|
+
namespace: str,
|
|
367
|
+
chunk_size: int = 1200,
|
|
368
|
+
overlap: int = 200,
|
|
369
|
+
db_path: Path | None = None,
|
|
370
|
+
) -> dict[str, Any]:
|
|
371
|
+
with _temporary_module_bindings(
|
|
372
|
+
_docs_service,
|
|
373
|
+
_chunk_text=_chunk_text,
|
|
374
|
+
read_reference_url=_read_reference_url,
|
|
375
|
+
read_reference_source=_read_reference_source,
|
|
376
|
+
):
|
|
377
|
+
return _docs_service.ingest_reference_source(
|
|
378
|
+
session_id,
|
|
379
|
+
source_path=source_path,
|
|
380
|
+
namespace=namespace,
|
|
381
|
+
chunk_size=chunk_size,
|
|
382
|
+
overlap=overlap,
|
|
383
|
+
db_path=db_path,
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
async def _compat_run_structured_agent(*args: Any, **kwargs: Any) -> Any:
|
|
388
|
+
"""Run the structured agent and normalise any failure to the LLM service's type.
|
|
389
|
+
|
|
390
|
+
Callers may receive this module's ``RecoverableFailure`` or any object with
|
|
391
|
+
the same four fields; the LLM service only understands its own class.
|
|
392
|
+
"""
|
|
393
|
+
result = await _run_structured_agent(*args, **kwargs)
|
|
394
|
+
if isinstance(result, RecoverableFailure):
|
|
395
|
+
return _llm_service.RecoverableFailure(
|
|
396
|
+
explanation=str(getattr(result, "explanation", "")),
|
|
397
|
+
remediation_steps=list(getattr(result, "remediation_steps", []) or []),
|
|
398
|
+
retry_focus=str(getattr(result, "retry_focus", "")) or "",
|
|
399
|
+
should_retry=bool(getattr(result, "should_retry", False)),
|
|
400
|
+
)
|
|
401
|
+
if all(
|
|
402
|
+
hasattr(result, name)
|
|
403
|
+
for name in (
|
|
404
|
+
"explanation",
|
|
405
|
+
"remediation_steps",
|
|
406
|
+
"retry_focus",
|
|
407
|
+
"should_retry",
|
|
408
|
+
)
|
|
409
|
+
):
|
|
410
|
+
return _llm_service.RecoverableFailure(
|
|
411
|
+
explanation=str(getattr(result, "explanation", "")),
|
|
412
|
+
remediation_steps=list(getattr(result, "remediation_steps", []) or []),
|
|
413
|
+
retry_focus=str(getattr(result, "retry_focus", "")),
|
|
414
|
+
should_retry=bool(getattr(result, "should_retry", False)),
|
|
415
|
+
)
|
|
416
|
+
return result
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
async def request_clarifications(
|
|
420
|
+
session_id: str,
|
|
421
|
+
user_goal: str,
|
|
422
|
+
*,
|
|
423
|
+
user_answer: str = "",
|
|
424
|
+
model_name: str | None = None,
|
|
425
|
+
db_path: Path | None = None,
|
|
426
|
+
) -> dict[str, Any]:
|
|
427
|
+
with _temporary_module_bindings(
|
|
428
|
+
_llm_service, _run_structured_agent=_compat_run_structured_agent
|
|
429
|
+
):
|
|
430
|
+
return await _llm_service.request_clarifications(
|
|
431
|
+
session_id,
|
|
432
|
+
user_goal,
|
|
433
|
+
user_answer=user_answer,
|
|
434
|
+
model_name=model_name,
|
|
435
|
+
db_path=db_path,
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
async def inspect_family(
|
|
440
|
+
session_id: str,
|
|
441
|
+
user_goal: str,
|
|
442
|
+
*,
|
|
443
|
+
model_name: str | None = None,
|
|
444
|
+
db_path: Path | None = None,
|
|
445
|
+
) -> dict[str, Any]:
|
|
446
|
+
with _temporary_module_bindings(
|
|
447
|
+
_llm_service, _run_structured_agent=_compat_run_structured_agent
|
|
448
|
+
):
|
|
449
|
+
return await _llm_service.inspect_family(
|
|
450
|
+
session_id,
|
|
451
|
+
user_goal,
|
|
452
|
+
model_name=model_name,
|
|
453
|
+
db_path=db_path,
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
# Legacy private helper aliases expected by compatibility tests.
|
|
458
|
+
_sanitize_model_path_text = _sanitize_model_path_text
|
|
459
|
+
_safe_context_name = _safe_context_name
|
|
460
|
+
_normalize_feature_targets = _normalize_feature_targets
|
|
461
|
+
_sanitize_preview_viewer_url = _sanitize_preview_viewer_url
|
|
462
|
+
_sanitize_ui_text = _utils_service.sanitize_ui_text
|
|
463
|
+
_provider_from_model_name = _utils_service.provider_from_model_name
|
|
464
|
+
_workflow_copy = _utils_service.workflow_copy
|
|
465
|
+
_filter_docs_text = _utils_service.filter_docs_text
|
|
466
|
+
_feature_target_status = _utils_service.feature_target_status
|
|
467
|
+
_feature_grounding_warning_text = _utils_service.feature_grounding_warning_text
|
|
468
|
+
_parse_json_blob = _utils_service.parse_json_blob
|
|
469
|
+
_trace_json_default = _utils_service._trace_json_default
|
|
470
|
+
_looks_like_path_token = _utils_service._looks_like_path_token
|
|
471
|
+
_normalize_model_name_for_provider = _utils_service.normalize_model_name_for_provider
|
|
472
|
+
_provider_has_credentials = _utils_service.provider_has_credentials
|
|
473
|
+
_trace_json = _utils_service.trace_json
|
|
474
|
+
_trace_session_row = _utils_service.trace_session_row
|
|
475
|
+
_trace_tool_records = _utils_service.trace_tool_records
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
__all__ = [
|
|
479
|
+
# core shimmed services
|
|
480
|
+
*[name for name in globals() if not name.startswith("__")],
|
|
481
|
+
]
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""Public re-exports for the ``solidworks_mcp.ui.services`` package.
|
|
2
|
+
|
|
3
|
+
Import all public service functions from this package to maintain backward
|
|
4
|
+
compatibility with code that previously imported directly from
|
|
5
|
+
``solidworks_mcp.ui.service``.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from ._utils import (
|
|
11
|
+
DEFAULT_API_ORIGIN,
|
|
12
|
+
DEFAULT_PREVIEW_ORIENTATION,
|
|
13
|
+
DEFAULT_RAG_DIR,
|
|
14
|
+
DEFAULT_SESSION_ID,
|
|
15
|
+
DEFAULT_SOURCE_MODE,
|
|
16
|
+
DEFAULT_USER_GOAL,
|
|
17
|
+
DEFAULT_WORKFLOW_MODE,
|
|
18
|
+
SUPPORTED_MODEL_UPLOAD_SUFFIXES,
|
|
19
|
+
ensure_context_dir,
|
|
20
|
+
ensure_preview_dir,
|
|
21
|
+
ensure_uploaded_model_dir,
|
|
22
|
+
feature_grounding_warning_text,
|
|
23
|
+
feature_target_status,
|
|
24
|
+
filter_docs_text,
|
|
25
|
+
is_url_reference,
|
|
26
|
+
materialize_uploaded_model,
|
|
27
|
+
merge_metadata,
|
|
28
|
+
normalize_feature_targets,
|
|
29
|
+
normalize_workflow_mode,
|
|
30
|
+
parse_json_blob,
|
|
31
|
+
persist_ui_action,
|
|
32
|
+
provider_from_model_name,
|
|
33
|
+
provider_has_credentials,
|
|
34
|
+
read_reference_source,
|
|
35
|
+
read_reference_url,
|
|
36
|
+
safe_context_name,
|
|
37
|
+
sanitize_model_path_text,
|
|
38
|
+
sanitize_preview_viewer_url,
|
|
39
|
+
sanitize_ui_text,
|
|
40
|
+
trace_json,
|
|
41
|
+
trace_session_row,
|
|
42
|
+
trace_tool_records,
|
|
43
|
+
workflow_copy,
|
|
44
|
+
)
|
|
45
|
+
from .checkpoint_service import execute_next_checkpoint
|
|
46
|
+
from .docs_service import fetch_docs_context, ingest_reference_source
|
|
47
|
+
from .llm_service import (
|
|
48
|
+
CheckpointCandidate,
|
|
49
|
+
ClarificationResponse,
|
|
50
|
+
FamilyInspection,
|
|
51
|
+
inspect_family,
|
|
52
|
+
request_clarifications,
|
|
53
|
+
run_go_orchestration,
|
|
54
|
+
)
|
|
55
|
+
from .model_service import connect_target_model, open_target_model
|
|
56
|
+
from .preview_service import highlight_feature, refresh_preview
|
|
57
|
+
from .session_service import (
|
|
58
|
+
accept_family_choice,
|
|
59
|
+
approve_design_brief,
|
|
60
|
+
build_dashboard_state,
|
|
61
|
+
build_dashboard_trace_payload,
|
|
62
|
+
ensure_dashboard_session,
|
|
63
|
+
load_session_context,
|
|
64
|
+
reconcile_manual_edits,
|
|
65
|
+
save_session_context,
|
|
66
|
+
select_workflow_mode,
|
|
67
|
+
update_session_notes,
|
|
68
|
+
update_ui_preferences,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
__all__ = [
|
|
72
|
+
# utils
|
|
73
|
+
"DEFAULT_API_ORIGIN",
|
|
74
|
+
"DEFAULT_PREVIEW_ORIENTATION",
|
|
75
|
+
"DEFAULT_RAG_DIR",
|
|
76
|
+
"DEFAULT_SESSION_ID",
|
|
77
|
+
"DEFAULT_SOURCE_MODE",
|
|
78
|
+
"DEFAULT_USER_GOAL",
|
|
79
|
+
"DEFAULT_WORKFLOW_MODE",
|
|
80
|
+
"SUPPORTED_MODEL_UPLOAD_SUFFIXES",
|
|
81
|
+
"ensure_context_dir",
|
|
82
|
+
"ensure_preview_dir",
|
|
83
|
+
"ensure_uploaded_model_dir",
|
|
84
|
+
"feature_grounding_warning_text",
|
|
85
|
+
"feature_target_status",
|
|
86
|
+
"filter_docs_text",
|
|
87
|
+
"is_url_reference",
|
|
88
|
+
"materialize_uploaded_model",
|
|
89
|
+
"merge_metadata",
|
|
90
|
+
"normalize_feature_targets",
|
|
91
|
+
"normalize_workflow_mode",
|
|
92
|
+
"parse_json_blob",
|
|
93
|
+
"persist_ui_action",
|
|
94
|
+
"provider_from_model_name",
|
|
95
|
+
"provider_has_credentials",
|
|
96
|
+
"read_reference_source",
|
|
97
|
+
"read_reference_url",
|
|
98
|
+
"safe_context_name",
|
|
99
|
+
"sanitize_model_path_text",
|
|
100
|
+
"sanitize_preview_viewer_url",
|
|
101
|
+
"sanitize_ui_text",
|
|
102
|
+
"trace_json",
|
|
103
|
+
"trace_session_row",
|
|
104
|
+
"trace_tool_records",
|
|
105
|
+
"workflow_copy",
|
|
106
|
+
# session
|
|
107
|
+
"accept_family_choice",
|
|
108
|
+
"approve_design_brief",
|
|
109
|
+
"build_dashboard_state",
|
|
110
|
+
"build_dashboard_trace_payload",
|
|
111
|
+
"ensure_dashboard_session",
|
|
112
|
+
"load_session_context",
|
|
113
|
+
"reconcile_manual_edits",
|
|
114
|
+
"save_session_context",
|
|
115
|
+
"select_workflow_mode",
|
|
116
|
+
"update_session_notes",
|
|
117
|
+
"update_ui_preferences",
|
|
118
|
+
# llm
|
|
119
|
+
"ClarificationResponse",
|
|
120
|
+
"CheckpointCandidate",
|
|
121
|
+
"FamilyInspection",
|
|
122
|
+
"inspect_family",
|
|
123
|
+
"request_clarifications",
|
|
124
|
+
"run_go_orchestration",
|
|
125
|
+
# checkpoint
|
|
126
|
+
"execute_next_checkpoint",
|
|
127
|
+
# docs
|
|
128
|
+
"fetch_docs_context",
|
|
129
|
+
"ingest_reference_source",
|
|
130
|
+
# model
|
|
131
|
+
"connect_target_model",
|
|
132
|
+
"open_target_model",
|
|
133
|
+
# preview
|
|
134
|
+
"highlight_feature",
|
|
135
|
+
"refresh_preview",
|
|
136
|
+
]
|