dslighting 1.3.1__tar.gz → 1.3.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.
- {dslighting-1.3.1 → dslighting-1.3.6}/PKG-INFO +1 -1
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/llm.py +2 -1
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/llm_single.py +2 -1
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/sandbox.py +34 -5
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting/__init__.py +10 -3
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting/core/agent.py +6 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting/core/config_builder.py +30 -1
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting/core/data_loader.py +38 -6
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting.egg-info/PKG-INFO +1 -1
- {dslighting-1.3.1 → dslighting-1.3.6}/pyproject.toml +1 -1
- {dslighting-1.3.1 → dslighting-1.3.6}/README.md +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/benchmark/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/benchmark/benchmark.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/benchmark/datasci.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/benchmark/mle.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/benchmark/sciencebench.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/common/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/common/constants.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/common/exceptions.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/common/typing.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/config.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/models/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/models/candidates.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/models/formats.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/models/task.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/operators/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/operators/aflow_ops.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/operators/autokaggle_ops.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/operators/automind_ops.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/operators/base.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/operators/code.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/operators/dsagent_ops.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/operators/llm_basic.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/prompts/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/prompts/aflow_prompt.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/prompts/aide_prompt.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/prompts/autokaggle_prompt.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/prompts/automind_prompt.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/prompts/common.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/prompts/data_interpreter_prompt.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/prompts/dsagent_prompt.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/runner.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/data_analyzer.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/states/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/states/autokaggle_state.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/states/base.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/states/dsa_log.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/states/experience.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/states/journal.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/states/operator_library.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/vdb.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/services/workspace.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/tasks/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/tasks/handlers.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/templates/open_ended/grade_template.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/tools/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/utils/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/utils/context.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/utils/dynamic_import.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/utils/parsing.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/base.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/factory.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/manual/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/manual/autokaggle_workflow.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/manual/data_interpreter_workflow.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/manual/deepanalyze_workflow.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/manual/dsagent_workflow.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/search/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/search/aflow_workflow.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/search/aide_workflow.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/search/automind_workflow.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/templates/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dsat/workflows/templates/basic_kaggle_loop.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting/core/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting/core/task_detector.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting/utils/__init__.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting/utils/defaults.py +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting.egg-info/SOURCES.txt +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting.egg-info/dependency_links.txt +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting.egg-info/requires.txt +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/dslighting.egg-info/top_level.txt +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/setup.cfg +0 -0
- {dslighting-1.3.1 → dslighting-1.3.6}/tests/test_dslighting_api.py +0 -0
|
@@ -43,7 +43,8 @@ def _load_custom_model_pricing():
|
|
|
43
43
|
config = yaml.safe_load(f)
|
|
44
44
|
return config.get('custom_model_pricing', {})
|
|
45
45
|
else:
|
|
46
|
-
|
|
46
|
+
# Changed to debug to avoid confusing warnings for pip-installed packages
|
|
47
|
+
logger.debug(f"Config file not found at {config_yaml_path} (this is expected for pip-installed packages)")
|
|
47
48
|
return {}
|
|
48
49
|
except Exception as e:
|
|
49
50
|
logger.error(f"Failed to load cost configuration: {e}")
|
|
@@ -43,7 +43,8 @@ def _load_custom_model_pricing():
|
|
|
43
43
|
config = yaml.safe_load(f)
|
|
44
44
|
return config.get('custom_model_pricing', {})
|
|
45
45
|
else:
|
|
46
|
-
|
|
46
|
+
# Changed to debug to avoid confusing warnings for pip-installed packages
|
|
47
|
+
logger.debug(f"Config file not found at {config_yaml_path} (this is expected for pip-installed packages)")
|
|
47
48
|
return {}
|
|
48
49
|
except Exception as e:
|
|
49
50
|
logger.error(f"Failed to load cost configuration: {e}")
|
|
@@ -245,17 +245,46 @@ class ProcessIsolatedNotebookExecutor:
|
|
|
245
245
|
class SandboxService:
|
|
246
246
|
"""
|
|
247
247
|
Provides unified access to isolated script and notebook code execution environments.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
workspace: Workspace service for managing files
|
|
251
|
+
timeout: Default timeout for script execution (seconds)
|
|
252
|
+
auto_matplotlib: Automatically inject matplotlib backend (default: False).
|
|
253
|
+
Set to True for Web UI environments that need visualization.
|
|
254
|
+
Set to False for standalone package usage.
|
|
248
255
|
"""
|
|
249
|
-
def __init__(
|
|
256
|
+
def __init__(
|
|
257
|
+
self,
|
|
258
|
+
workspace: WorkspaceService,
|
|
259
|
+
timeout: int = 600,
|
|
260
|
+
auto_matplotlib: bool = False
|
|
261
|
+
):
|
|
250
262
|
self.workspace = workspace
|
|
251
263
|
self.timeout = timeout
|
|
264
|
+
self.auto_matplotlib = auto_matplotlib # Store matplotlib injection preference
|
|
252
265
|
self.execution_history: List[Dict[str, Any]] = []
|
|
253
266
|
|
|
254
267
|
def run_script(self, script_code: str, timeout: Optional[int] = None) -> ExecutionResult:
|
|
255
|
-
"""
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
268
|
+
"""
|
|
269
|
+
Runs a Python script within the sandbox workspace.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
script_code: Python code to execute
|
|
273
|
+
timeout: Optional timeout override (uses self.timeout if None)
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
ExecutionResult with stdout, stderr, success status, etc.
|
|
277
|
+
"""
|
|
278
|
+
# Optionally inject matplotlib non-interactive backend
|
|
279
|
+
# This is only done if auto_matplotlib=True (used by Web UI for visualization)
|
|
280
|
+
if self.auto_matplotlib:
|
|
281
|
+
# Force non-interactive backend for matplotlib to prevent blocking plt.show()
|
|
282
|
+
fixed_code = "import matplotlib\nmatplotlib.use('Agg')\n" + script_code
|
|
283
|
+
logger.debug("Auto-injected matplotlib non-interactive backend")
|
|
284
|
+
else:
|
|
285
|
+
# Use code as-is without modification (default for DSLighting package)
|
|
286
|
+
fixed_code = script_code
|
|
287
|
+
|
|
259
288
|
script_name = f"_sandbox_script_{uuid.uuid4().hex}.py"
|
|
260
289
|
script_path = self.workspace.run_dir / script_name
|
|
261
290
|
execution_id = uuid.uuid4().hex
|
|
@@ -26,7 +26,7 @@ Advanced Usage:
|
|
|
26
26
|
For more information, see: https://github.com/usail-hkust/dslighting
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
|
-
__version__ = "1.3.
|
|
29
|
+
__version__ = "1.3.6"
|
|
30
30
|
__author__ = "DSLighting Team"
|
|
31
31
|
|
|
32
32
|
# Core API classes
|
|
@@ -60,7 +60,7 @@ def load_data(source, **kwargs):
|
|
|
60
60
|
return loader.load(source, **kwargs)
|
|
61
61
|
|
|
62
62
|
|
|
63
|
-
def run_agent(data=None, task_id=None, data_dir=None, **kwargs):
|
|
63
|
+
def run_agent(data=None, task_id=None, data_dir=None, keep_workspace=False, keep_workspace_on_failure=True, **kwargs):
|
|
64
64
|
"""
|
|
65
65
|
Quick one-liner: load data and run with defaults.
|
|
66
66
|
|
|
@@ -70,6 +70,8 @@ def run_agent(data=None, task_id=None, data_dir=None, **kwargs):
|
|
|
70
70
|
data: Optional data source (path, DataFrame, dict, etc.)
|
|
71
71
|
task_id: Task/Competition identifier (e.g., "bike-sharing-demand")
|
|
72
72
|
data_dir: Base data directory (default: "data/competitions")
|
|
73
|
+
keep_workspace: Keep workspace after completion (default: False)
|
|
74
|
+
keep_workspace_on_failure: Keep workspace on failure (default: True)
|
|
73
75
|
**kwargs: Parameters passed to Agent.__init__ and Agent.run
|
|
74
76
|
|
|
75
77
|
Returns:
|
|
@@ -90,7 +92,8 @@ def run_agent(data=None, task_id=None, data_dir=None, **kwargs):
|
|
|
90
92
|
>>> result = dslighting.run_agent(
|
|
91
93
|
... task_id="bike-sharing-demand",
|
|
92
94
|
... workflow="autokaggle",
|
|
93
|
-
... model="gpt-4o"
|
|
95
|
+
... model="gpt-4o",
|
|
96
|
+
... keep_workspace=True # Keep workspace for debugging
|
|
94
97
|
... )
|
|
95
98
|
"""
|
|
96
99
|
# Extract run-specific parameters if present
|
|
@@ -112,6 +115,10 @@ def run_agent(data=None, task_id=None, data_dir=None, **kwargs):
|
|
|
112
115
|
if data_dir is not None:
|
|
113
116
|
run_kwargs['data_dir'] = data_dir
|
|
114
117
|
|
|
118
|
+
# Add workspace preservation parameters to agent
|
|
119
|
+
agent_params['keep_workspace'] = keep_workspace
|
|
120
|
+
agent_params['keep_workspace_on_failure'] = keep_workspace_on_failure
|
|
121
|
+
|
|
115
122
|
# Create agent and run
|
|
116
123
|
agent = Agent(**agent_params)
|
|
117
124
|
return agent.run(data, **run_kwargs)
|
|
@@ -108,6 +108,8 @@ class Agent:
|
|
|
108
108
|
num_drafts: int = None,
|
|
109
109
|
workspace_dir: str = None,
|
|
110
110
|
run_name: str = None,
|
|
111
|
+
keep_workspace: bool = False,
|
|
112
|
+
keep_workspace_on_failure: bool = True,
|
|
111
113
|
verbose: bool = True,
|
|
112
114
|
**kwargs
|
|
113
115
|
):
|
|
@@ -129,6 +131,8 @@ class Agent:
|
|
|
129
131
|
num_drafts: Number of drafts to generate
|
|
130
132
|
workspace_dir: Custom workspace directory
|
|
131
133
|
run_name: Name for this run
|
|
134
|
+
keep_workspace: Keep workspace after completion (default: False)
|
|
135
|
+
keep_workspace_on_failure: Keep workspace on failure (default: True)
|
|
132
136
|
verbose: Enable verbose logging
|
|
133
137
|
**kwargs: Additional parameters passed to DSATConfig
|
|
134
138
|
"""
|
|
@@ -148,6 +152,8 @@ class Agent:
|
|
|
148
152
|
num_drafts=num_drafts,
|
|
149
153
|
workspace_dir=workspace_dir,
|
|
150
154
|
run_name=run_name,
|
|
155
|
+
keep_workspace=keep_workspace,
|
|
156
|
+
keep_workspace_on_failure=keep_workspace_on_failure,
|
|
151
157
|
**kwargs
|
|
152
158
|
)
|
|
153
159
|
|
|
@@ -60,6 +60,8 @@ class ConfigBuilder:
|
|
|
60
60
|
num_drafts: int = None,
|
|
61
61
|
workspace_dir: str = None,
|
|
62
62
|
run_name: str = None,
|
|
63
|
+
keep_workspace: bool = None,
|
|
64
|
+
keep_workspace_on_failure: bool = None,
|
|
63
65
|
**kwargs
|
|
64
66
|
) -> DSATConfig:
|
|
65
67
|
"""
|
|
@@ -76,6 +78,8 @@ class ConfigBuilder:
|
|
|
76
78
|
num_drafts: Number of drafts to generate
|
|
77
79
|
workspace_dir: Workspace directory
|
|
78
80
|
run_name: Name for this run
|
|
81
|
+
keep_workspace: Keep workspace after completion
|
|
82
|
+
keep_workspace_on_failure: Keep workspace on failure
|
|
79
83
|
**kwargs: Additional parameters
|
|
80
84
|
|
|
81
85
|
Returns:
|
|
@@ -100,6 +104,8 @@ class ConfigBuilder:
|
|
|
100
104
|
num_drafts=num_drafts,
|
|
101
105
|
workspace_dir=workspace_dir,
|
|
102
106
|
run_name=run_name,
|
|
107
|
+
keep_workspace=keep_workspace,
|
|
108
|
+
keep_workspace_on_failure=keep_workspace_on_failure,
|
|
103
109
|
**kwargs
|
|
104
110
|
)
|
|
105
111
|
config = self._deep_merge(config, user_config)
|
|
@@ -180,7 +186,22 @@ class ConfigBuilder:
|
|
|
180
186
|
logger.warning("LLM_MODEL_CONFIGS must be a JSON object")
|
|
181
187
|
return {}
|
|
182
188
|
|
|
183
|
-
|
|
189
|
+
# Process each model config
|
|
190
|
+
result = {}
|
|
191
|
+
for k, v in parsed.items():
|
|
192
|
+
if not isinstance(k, str) or not isinstance(v, dict):
|
|
193
|
+
continue
|
|
194
|
+
|
|
195
|
+
# Handle api_key as list (take the first one)
|
|
196
|
+
if "api_key" in v and isinstance(v["api_key"], list):
|
|
197
|
+
if len(v["api_key"]) > 0:
|
|
198
|
+
v = v.copy() # Shallow copy to avoid mutating original
|
|
199
|
+
v["api_key"] = v["api_key"][0]
|
|
200
|
+
logger.debug(f"Model '{k}': using first API key from list of {len(v['api_key'])}")
|
|
201
|
+
|
|
202
|
+
result[k] = v
|
|
203
|
+
|
|
204
|
+
return result
|
|
184
205
|
|
|
185
206
|
def _build_user_config(
|
|
186
207
|
self,
|
|
@@ -194,6 +215,8 @@ class ConfigBuilder:
|
|
|
194
215
|
num_drafts: int = None,
|
|
195
216
|
workspace_dir: str = None,
|
|
196
217
|
run_name: str = None,
|
|
218
|
+
keep_workspace: bool = None,
|
|
219
|
+
keep_workspace_on_failure: bool = None,
|
|
197
220
|
**kwargs
|
|
198
221
|
) -> Dict[str, Any]:
|
|
199
222
|
"""Build user configuration from parameters."""
|
|
@@ -230,6 +253,12 @@ class ConfigBuilder:
|
|
|
230
253
|
if workspace_dir is not None:
|
|
231
254
|
config.setdefault("run", {}).setdefault("parameters", {})["workspace_dir"] = workspace_dir
|
|
232
255
|
|
|
256
|
+
if keep_workspace is not None:
|
|
257
|
+
config.setdefault("run", {})["keep_all_workspaces"] = keep_workspace
|
|
258
|
+
|
|
259
|
+
if keep_workspace_on_failure is not None:
|
|
260
|
+
config.setdefault("run", {})["keep_workspace_on_failure"] = keep_workspace_on_failure
|
|
261
|
+
|
|
233
262
|
# Additional kwargs are added to run.parameters
|
|
234
263
|
if kwargs:
|
|
235
264
|
config.setdefault("run", {}).setdefault("parameters", {}).update(kwargs)
|
|
@@ -297,13 +297,45 @@ class DataLoader:
|
|
|
297
297
|
pass
|
|
298
298
|
else:
|
|
299
299
|
self.logger.warning(f"Path does not exist: {path}")
|
|
300
|
-
|
|
301
|
-
|
|
300
|
+
|
|
301
|
+
# Try to find the data in common locations
|
|
302
|
+
competition_id = path.name
|
|
303
|
+
|
|
304
|
+
# Common search locations for data
|
|
305
|
+
search_locations = [
|
|
306
|
+
# Current project: ./data/competitions/
|
|
307
|
+
Path.cwd() / "data" / "competitions" / competition_id,
|
|
308
|
+
# Parent dslighting: ../dslighting/data/competitions/
|
|
309
|
+
Path.cwd().parent / "dslighting" / "data" / "competitions" / competition_id,
|
|
310
|
+
# Parent data: ../data/competitions/
|
|
311
|
+
Path.cwd().parent / "data" / "competitions" / competition_id,
|
|
312
|
+
# From package location: ../../data/competitions/
|
|
313
|
+
Path(__file__).parent.parent.parent / "data" / "competitions" / competition_id,
|
|
314
|
+
# Absolute path fallback
|
|
315
|
+
Path("/Users/liufan/Applications/Github/dslighting/data/competitions") / competition_id,
|
|
316
|
+
]
|
|
317
|
+
|
|
318
|
+
for location in search_locations:
|
|
319
|
+
self.logger.info(f" Trying: {location}")
|
|
320
|
+
if location.exists() and location.is_dir():
|
|
321
|
+
data_dir = location
|
|
322
|
+
self.logger.info(f" ✓ Found data at: {data_dir}")
|
|
323
|
+
break
|
|
324
|
+
|
|
325
|
+
if data_dir is None:
|
|
326
|
+
# Last resort: use the original resolved path
|
|
327
|
+
self.logger.warning(f" Could not find data, using original path: {path}")
|
|
302
328
|
data_dir = path
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
329
|
+
|
|
330
|
+
# Try to load description (if data_dir was found)
|
|
331
|
+
if data_dir and data_dir.exists():
|
|
332
|
+
desc_file = data_dir / "description.md"
|
|
333
|
+
if desc_file.exists():
|
|
334
|
+
try:
|
|
335
|
+
description = desc_file.read_text(encoding='utf-8')
|
|
336
|
+
self.logger.info(f"Loaded description from {desc_file}")
|
|
337
|
+
except Exception:
|
|
338
|
+
pass
|
|
307
339
|
|
|
308
340
|
# Create MLE-style detection
|
|
309
341
|
from dslighting.utils.defaults import WORKFLOW_RECOMMENDATIONS
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|