ivoryos 0.1.20__py3-none-any.whl → 0.1.22__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.
Potentially problematic release.
This version of ivoryos might be problematic. Click here for more details.
- ivoryos/__init__.py +21 -16
- ivoryos/routes/control/control.py +2 -2
- ivoryos/routes/control/templates/control/controllers_home.html +6 -1
- ivoryos/routes/database/database.py +45 -2
- ivoryos/routes/database/templates/database/experiment_database.html +4 -2
- ivoryos/routes/database/templates/database/workflow_run_database.html +81 -0
- ivoryos/routes/design/design.py +74 -18
- ivoryos/routes/design/templates/design/experiment_builder.html +84 -94
- ivoryos/routes/design/templates/design/experiment_run.html +188 -101
- ivoryos/routes/main/templates/main/home.html +80 -47
- ivoryos/static/js/socket_handler.js +59 -16
- ivoryos/static/js/sortable_design.js +102 -33
- ivoryos/static/style.css +9 -0
- ivoryos/templates/base.html +9 -6
- ivoryos/utils/client_proxy.py +57 -0
- ivoryos/utils/db_models.py +66 -11
- ivoryos/utils/form.py +50 -2
- ivoryos/utils/global_config.py +10 -0
- ivoryos/utils/llm_agent.py +1 -1
- ivoryos/utils/script_runner.py +115 -43
- ivoryos/utils/utils.py +24 -1
- ivoryos/version.py +1 -1
- {ivoryos-0.1.20.dist-info → ivoryos-0.1.22.dist-info}/METADATA +7 -3
- {ivoryos-0.1.20.dist-info → ivoryos-0.1.22.dist-info}/RECORD +27 -25
- {ivoryos-0.1.20.dist-info → ivoryos-0.1.22.dist-info}/LICENSE +0 -0
- {ivoryos-0.1.20.dist-info → ivoryos-0.1.22.dist-info}/WHEEL +0 -0
- {ivoryos-0.1.20.dist-info → ivoryos-0.1.22.dist-info}/top_level.txt +0 -0
ivoryos/utils/script_runner.py
CHANGED
|
@@ -6,12 +6,14 @@ import time
|
|
|
6
6
|
from datetime import datetime
|
|
7
7
|
|
|
8
8
|
from ivoryos.utils import utils
|
|
9
|
-
from ivoryos.utils.db_models import Script
|
|
9
|
+
from ivoryos.utils.db_models import Script, WorkflowRun, WorkflowStep, db
|
|
10
10
|
from ivoryos.utils.global_config import GlobalConfig
|
|
11
11
|
|
|
12
12
|
global_config = GlobalConfig()
|
|
13
13
|
global deck
|
|
14
14
|
deck = None
|
|
15
|
+
# global deck, registered_workflows
|
|
16
|
+
# deck, registered_workflows = None, None
|
|
15
17
|
|
|
16
18
|
class ScriptRunner:
|
|
17
19
|
def __init__(self, globals_dict=None):
|
|
@@ -24,9 +26,11 @@ class ScriptRunner:
|
|
|
24
26
|
self.stop_current_event = threading.Event()
|
|
25
27
|
self.is_running = False
|
|
26
28
|
self.lock = threading.Lock()
|
|
29
|
+
self.paused = False
|
|
27
30
|
|
|
28
31
|
def toggle_pause(self):
|
|
29
32
|
"""Toggles between pausing and resuming the script"""
|
|
33
|
+
self.paused = not self.paused
|
|
30
34
|
if self.pause_event.is_set():
|
|
31
35
|
self.pause_event.clear() # Pause the script
|
|
32
36
|
return "Paused"
|
|
@@ -34,10 +38,15 @@ class ScriptRunner:
|
|
|
34
38
|
self.pause_event.set() # Resume the script
|
|
35
39
|
return "Resumed"
|
|
36
40
|
|
|
41
|
+
def pause_status(self):
|
|
42
|
+
"""Toggles between pausing and resuming the script"""
|
|
43
|
+
return self.paused
|
|
44
|
+
|
|
37
45
|
def reset_stop_event(self):
|
|
38
46
|
"""Resets the stop event"""
|
|
39
47
|
self.stop_pending_event.clear()
|
|
40
48
|
self.stop_current_event.clear()
|
|
49
|
+
self.pause_event.set()
|
|
41
50
|
|
|
42
51
|
def abort_pending(self):
|
|
43
52
|
"""Abort the pending iteration after the current is finished"""
|
|
@@ -50,7 +59,8 @@ class ScriptRunner:
|
|
|
50
59
|
self.abort_pending()
|
|
51
60
|
|
|
52
61
|
def run_script(self, script, repeat_count=1, run_name=None, logger=None, socketio=None, config=None, bo_args=None,
|
|
53
|
-
output_path=""):
|
|
62
|
+
output_path="", current_app=None):
|
|
63
|
+
# Get run.id
|
|
54
64
|
global deck
|
|
55
65
|
if deck is None:
|
|
56
66
|
deck = global_config.deck
|
|
@@ -64,85 +74,146 @@ class ScriptRunner:
|
|
|
64
74
|
self.reset_stop_event()
|
|
65
75
|
|
|
66
76
|
thread = threading.Thread(target=self._run_with_stop_check,
|
|
67
|
-
args=(script, repeat_count, run_name, logger, socketio, config, bo_args, output_path))
|
|
77
|
+
args=(script, repeat_count, run_name, logger, socketio, config, bo_args, output_path, current_app))
|
|
68
78
|
thread.start()
|
|
69
79
|
return thread
|
|
70
80
|
|
|
71
|
-
def
|
|
81
|
+
def exec_steps(self, script, section_name, logger, socketio, run_id, i_progress, **kwargs):
|
|
72
82
|
"""
|
|
73
|
-
Executes a function defined in a string line by line
|
|
74
|
-
|
|
83
|
+
Executes a function defined in a string line by line
|
|
75
84
|
:param func_str: The function as a string
|
|
76
85
|
:param kwargs: Arguments to pass to the function
|
|
77
86
|
:return: The final result of the function execution
|
|
78
87
|
"""
|
|
88
|
+
_func_str = script.compile()
|
|
89
|
+
step_list: list = script.convert_to_lines(_func_str).get(section_name, [])
|
|
79
90
|
global deck
|
|
91
|
+
# global deck, registered_workflows
|
|
80
92
|
if deck is None:
|
|
81
93
|
deck = global_config.deck
|
|
94
|
+
# if registered_workflows is None:
|
|
95
|
+
# registered_workflows = global_config.registered_workflows
|
|
96
|
+
|
|
97
|
+
# for i, line in enumerate(step_list):
|
|
98
|
+
# if line.startswith("registered_workflows"):
|
|
99
|
+
#
|
|
82
100
|
# func_str = script.compile()
|
|
83
101
|
# Parse function body from string
|
|
84
|
-
|
|
102
|
+
temp_connections = global_config.defined_variables
|
|
85
103
|
# Prepare execution environment
|
|
86
|
-
exec_globals = {"deck": deck} # Add required global objects
|
|
104
|
+
exec_globals = {"deck": deck, "time":time} # Add required global objects
|
|
105
|
+
# exec_globals = {"deck": deck, "time": time, "registered_workflows":registered_workflows} # Add required global objects
|
|
106
|
+
exec_globals.update(temp_connections)
|
|
87
107
|
exec_locals = {} # Local execution scope
|
|
88
108
|
|
|
89
109
|
# Define function arguments manually in exec_locals
|
|
90
110
|
exec_locals.update(kwargs)
|
|
111
|
+
index = 0
|
|
91
112
|
|
|
92
113
|
# Execute each line dynamically
|
|
93
|
-
|
|
114
|
+
while index < len(step_list):
|
|
94
115
|
if self.stop_current_event.is_set():
|
|
95
116
|
logger.info(f'Stopping execution during {section_name}')
|
|
117
|
+
step = WorkflowStep(
|
|
118
|
+
workflow_id=run_id,
|
|
119
|
+
phase=section_name,
|
|
120
|
+
repeat_index=i_progress,
|
|
121
|
+
step_index=index,
|
|
122
|
+
method_name="stop",
|
|
123
|
+
start_time=datetime.now(),
|
|
124
|
+
end_time=datetime.now(),
|
|
125
|
+
run_error=False,
|
|
126
|
+
)
|
|
127
|
+
db.session.add(step)
|
|
96
128
|
break
|
|
97
|
-
|
|
129
|
+
line = step_list[index]
|
|
130
|
+
method_name = line.strip().split("(")[0] if "(" in line else line.strip()
|
|
131
|
+
start_time = datetime.now()
|
|
132
|
+
step = WorkflowStep(
|
|
133
|
+
workflow_id=run_id,
|
|
134
|
+
phase=section_name,
|
|
135
|
+
repeat_index=i_progress,
|
|
136
|
+
step_index=index,
|
|
137
|
+
method_name=method_name,
|
|
138
|
+
start_time=start_time,
|
|
139
|
+
)
|
|
140
|
+
logger.info(f"Executing: {line}")
|
|
98
141
|
socketio.emit('execution', {'section': f"{section_name}-{index}"})
|
|
99
142
|
# self._emit_progress(socketio, 100)
|
|
100
|
-
|
|
143
|
+
# if line.startswith("registered_workflows"):
|
|
144
|
+
# line = line.replace("registered_workflows.", "")
|
|
145
|
+
try:
|
|
146
|
+
exec(line, exec_globals, exec_locals)
|
|
147
|
+
step.run_error = False
|
|
148
|
+
except Exception as e:
|
|
149
|
+
logger.error(f"Error during script execution: {e}")
|
|
150
|
+
socketio.emit('error', {'message': str(e)})
|
|
151
|
+
|
|
152
|
+
step.run_error = True
|
|
153
|
+
self.toggle_pause()
|
|
154
|
+
step.end_time = datetime.now()
|
|
101
155
|
self.pause_event.wait()
|
|
102
156
|
|
|
157
|
+
# todo update script during the run
|
|
158
|
+
# _func_str = script.compile()
|
|
159
|
+
# step_list: list = script.convert_to_lines(_func_str).get(section_name, [])
|
|
160
|
+
db.session.add(step)
|
|
161
|
+
db.session.commit()
|
|
162
|
+
index += 1
|
|
103
163
|
return exec_locals # Return the 'results' variable
|
|
104
164
|
|
|
105
165
|
def _run_with_stop_check(self, script: Script, repeat_count: int, run_name: str, logger, socketio, config, bo_args,
|
|
106
|
-
output_path):
|
|
166
|
+
output_path, current_app):
|
|
107
167
|
time.sleep(1)
|
|
108
|
-
|
|
109
|
-
|
|
168
|
+
# _func_str = script.compile()
|
|
169
|
+
# step_list_dict: dict = script.convert_to_lines(_func_str)
|
|
110
170
|
self._emit_progress(socketio, 1)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
171
|
+
|
|
172
|
+
# Run "prep" section once
|
|
173
|
+
script_dict = script.script_dict
|
|
174
|
+
with current_app.app_context():
|
|
175
|
+
|
|
176
|
+
run = WorkflowRun(name=script.name or "untitled", platform=script.deck,start_time=datetime.now())
|
|
177
|
+
db.session.add(run)
|
|
178
|
+
db.session.flush()
|
|
179
|
+
|
|
180
|
+
self._run_actions(script, section_name="prep", logger=logger, socketio=socketio, run_id=run.id)
|
|
115
181
|
output_list = []
|
|
116
182
|
_, arg_type = script.config("script")
|
|
117
183
|
_, return_list = script.config_return()
|
|
184
|
+
|
|
118
185
|
# Run "script" section multiple times
|
|
119
186
|
if repeat_count:
|
|
120
|
-
self._run_repeat_section(repeat_count, arg_type, bo_args, output_list,
|
|
121
|
-
run_name, return_list, logger, socketio)
|
|
187
|
+
self._run_repeat_section(repeat_count, arg_type, bo_args, output_list, script,
|
|
188
|
+
run_name, return_list, logger, socketio, run_id=run.id)
|
|
122
189
|
elif config:
|
|
123
|
-
self._run_config_section(config, arg_type, output_list,
|
|
124
|
-
socketio)
|
|
190
|
+
self._run_config_section(config, arg_type, output_list, script, run_name, logger,
|
|
191
|
+
socketio, run_id=run.id)
|
|
192
|
+
|
|
125
193
|
# Run "cleanup" section once
|
|
126
|
-
self._run_actions(
|
|
127
|
-
|
|
194
|
+
self._run_actions(script, section_name="cleanup", logger=logger, socketio=socketio,run_id=run.id)
|
|
195
|
+
# Reset the running flag when done
|
|
196
|
+
with self.lock:
|
|
197
|
+
self.is_running = False
|
|
128
198
|
# Save results if necessary
|
|
199
|
+
filename = None
|
|
129
200
|
if output_list:
|
|
130
|
-
self._save_results(run_name, arg_type, return_list, output_list, logger, output_path)
|
|
131
|
-
except Exception as e:
|
|
132
|
-
logger.error(f"Error during script execution: {e}")
|
|
133
|
-
finally:
|
|
134
|
-
with self.lock:
|
|
135
|
-
self.is_running = False # Reset the running flag when done
|
|
201
|
+
filename = self._save_results(run_name, arg_type, return_list, output_list, logger, output_path)
|
|
136
202
|
self._emit_progress(socketio, 100)
|
|
203
|
+
run.end_time = datetime.now()
|
|
204
|
+
run.data_path = filename
|
|
205
|
+
db.session.commit()
|
|
137
206
|
|
|
138
|
-
def _run_actions(self,
|
|
139
|
-
|
|
207
|
+
def _run_actions(self, script, section_name="", logger=None, socketio=None, run_id=None):
|
|
208
|
+
_func_str = script.compile()
|
|
209
|
+
step_list: list = script.convert_to_lines(_func_str).get(section_name, [])
|
|
210
|
+
logger.info(f'Executing {section_name} steps') if step_list else logger.info(f'No {section_name} steps')
|
|
140
211
|
if self.stop_pending_event.is_set():
|
|
141
212
|
logger.info(f"Stopping execution during {section_name} section.")
|
|
142
213
|
return
|
|
143
|
-
self.
|
|
214
|
+
self.exec_steps(script, section_name, logger, socketio, run_id=run_id, i_progress=0)
|
|
144
215
|
|
|
145
|
-
def _run_config_section(self, config, arg_type, output_list,
|
|
216
|
+
def _run_config_section(self, config, arg_type, output_list, script, run_name, logger, socketio, run_id):
|
|
146
217
|
compiled = True
|
|
147
218
|
for i in config:
|
|
148
219
|
try:
|
|
@@ -162,22 +233,22 @@ class ScriptRunner:
|
|
|
162
233
|
self._emit_progress(socketio, progress)
|
|
163
234
|
# fname = f"{run_name}_script"
|
|
164
235
|
# function = self.globals_dict[fname]
|
|
165
|
-
output = self.
|
|
236
|
+
output = self.exec_steps(script, "script", logger, socketio, run_id, i, **kwargs)
|
|
166
237
|
if output:
|
|
167
238
|
# kwargs.update(output)
|
|
168
239
|
output_list.append(output)
|
|
169
240
|
|
|
170
|
-
def _run_repeat_section(self, repeat_count, arg_types, bo_args, output_list,
|
|
171
|
-
logger, socketio):
|
|
241
|
+
def _run_repeat_section(self, repeat_count, arg_types, bo_args, output_list, script, run_name, return_list,
|
|
242
|
+
logger, socketio, run_id):
|
|
172
243
|
if bo_args:
|
|
173
244
|
logger.info('Initializing optimizer...')
|
|
174
245
|
ax_client = utils.ax_initiation(bo_args, arg_types)
|
|
175
|
-
for
|
|
246
|
+
for i_progress in range(int(repeat_count)):
|
|
176
247
|
if self.stop_pending_event.is_set():
|
|
177
|
-
logger.info(f'Stopping execution during {run_name}: {
|
|
248
|
+
logger.info(f'Stopping execution during {run_name}: {i_progress + 1}/{int(repeat_count)}')
|
|
178
249
|
break
|
|
179
|
-
logger.info(f'Executing {run_name} experiment: {
|
|
180
|
-
progress = (
|
|
250
|
+
logger.info(f'Executing {run_name} experiment: {i_progress + 1}/{int(repeat_count)}')
|
|
251
|
+
progress = (i_progress + 1) * 100 / int(repeat_count) - 0.1
|
|
181
252
|
self._emit_progress(socketio, progress)
|
|
182
253
|
if bo_args:
|
|
183
254
|
try:
|
|
@@ -185,7 +256,7 @@ class ScriptRunner:
|
|
|
185
256
|
logger.info(f'Output value: {parameters}')
|
|
186
257
|
# fname = f"{run_name}_script"
|
|
187
258
|
# function = self.globals_dict[fname]
|
|
188
|
-
output = self.
|
|
259
|
+
output = self.exec_steps(script, "script", logger, socketio, run_id, i_progress, **parameters)
|
|
189
260
|
|
|
190
261
|
_output = {key: value for key, value in output.items() if key in return_list}
|
|
191
262
|
ax_client.complete_trial(trial_index=trial_index, raw_data=_output)
|
|
@@ -196,7 +267,7 @@ class ScriptRunner:
|
|
|
196
267
|
else:
|
|
197
268
|
# fname = f"{run_name}_script"
|
|
198
269
|
# function = self.globals_dict[fname]
|
|
199
|
-
output = self.
|
|
270
|
+
output = self.exec_steps(script, "script", logger, socketio, run_id, i_progress)
|
|
200
271
|
|
|
201
272
|
if output:
|
|
202
273
|
output_list.append(output)
|
|
@@ -214,6 +285,7 @@ class ScriptRunner:
|
|
|
214
285
|
writer.writeheader()
|
|
215
286
|
writer.writerows(output_list)
|
|
216
287
|
logger.info(f'Results saved to {file_path}')
|
|
288
|
+
return filename
|
|
217
289
|
|
|
218
290
|
@staticmethod
|
|
219
291
|
def _emit_progress(socketio, progress):
|
ivoryos/utils/utils.py
CHANGED
|
@@ -97,7 +97,7 @@ def _inspect_class(class_object=None, debug=False):
|
|
|
97
97
|
under_score = "_"
|
|
98
98
|
if debug:
|
|
99
99
|
under_score = "__"
|
|
100
|
-
for function, method in inspect.getmembers(type(class_object), predicate=
|
|
100
|
+
for function, method in inspect.getmembers(type(class_object), predicate=callable):
|
|
101
101
|
if not function.startswith(under_score) and not function.isupper():
|
|
102
102
|
try:
|
|
103
103
|
annotation = inspect.signature(method)
|
|
@@ -407,3 +407,26 @@ def check_config_duplicate(config):
|
|
|
407
407
|
"""
|
|
408
408
|
hashable_data = [tuple(sorted(d.items())) for d in config]
|
|
409
409
|
return any(count > 1 for count in Counter(hashable_data).values())
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def get_method_from_workflow(function_string, func_name="workflow"):
|
|
413
|
+
"""Creates a function from a string and assigns it a new name."""
|
|
414
|
+
|
|
415
|
+
namespace = {}
|
|
416
|
+
exec(function_string, globals(), namespace) # Execute the string in a safe namespace
|
|
417
|
+
# func_name = next(iter(namespace))
|
|
418
|
+
# Get the function name dynamically
|
|
419
|
+
return namespace[func_name]
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
# def load_workflows(script):
|
|
423
|
+
#
|
|
424
|
+
# class RegisteredWorkflows:
|
|
425
|
+
# pass
|
|
426
|
+
# deck_name = script.deck
|
|
427
|
+
# workflows = Script.query.filter(Script.deck == deck_name, Script.name != script.name, Script.registered==True).all()
|
|
428
|
+
# for workflow in workflows:
|
|
429
|
+
# compiled_strs = workflow.compile().get('script', "")
|
|
430
|
+
# method = get_method_from_workflow(compiled_strs, func_name=workflow.name)
|
|
431
|
+
# setattr(RegisteredWorkflows, workflow.name, staticmethod(method))
|
|
432
|
+
# global_config.registered_workflows = RegisteredWorkflows()
|
ivoryos/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.22"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ivoryos
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.22
|
|
4
4
|
Summary: an open-source Python package enabling Self-Driving Labs (SDLs) interoperability
|
|
5
5
|
Home-page: https://gitlab.com/heingroup/ivoryos
|
|
6
6
|
Author: Ivory Zhang
|
|
@@ -36,7 +36,7 @@ Requires-Dist: python-dotenv
|
|
|
36
36
|
- [Instructions for use](#instructions-for-use)
|
|
37
37
|
- [Demo](#demo)
|
|
38
38
|
- [Roadmap](#roadmap)
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
|
|
41
41
|
## Description
|
|
42
42
|
Granting SDLs flexibility and modularity makes it almost impossible to design a UI, yet it's a necessity for allowing more people to interact with it (democratisation).
|
|
@@ -93,6 +93,10 @@ Create an account and login (local database)
|
|
|
93
93
|
- **Database**: manage workflows in _Library_ tab.
|
|
94
94
|
- **Info page**: additional info in _About_ tab.
|
|
95
95
|
|
|
96
|
+
[//]: # ()
|
|
97
|
+
|
|
98
|
+
[//]: # ()
|
|
99
|
+
|
|
96
100
|
|
|
97
101
|
### Additional settings
|
|
98
102
|
#### AI assistant
|
|
@@ -133,7 +137,7 @@ After one successful connection, a blueprint will be automatically saved and mad
|
|
|
133
137
|
ivoryos.run()
|
|
134
138
|
```
|
|
135
139
|
## Demo
|
|
136
|
-
In the [abstract_sdl.py](https://gitlab.com/heingroup/ivoryos/-/blob/main/example/
|
|
140
|
+
In the [abstract_sdl.py](https://gitlab.com/heingroup/ivoryos/-/blob/main/example/abstract_sdl_example/abstract_sdl.py), where instances of `AbstractSDL` is created as `sdl`,
|
|
137
141
|
addresses will be available on terminal.
|
|
138
142
|
```Python
|
|
139
143
|
ivoryos.run(__name__)
|
|
@@ -1,46 +1,48 @@
|
|
|
1
|
-
ivoryos/__init__.py,sha256=
|
|
1
|
+
ivoryos/__init__.py,sha256=MVzYifnYAyHZvr0PfMs9ck3Nf4Xfj3fJz4djCq3rcC4,6081
|
|
2
2
|
ivoryos/config.py,sha256=3FPBYTIBhQTKDvsEoR8ZeTmg65D-CSFEdGmOuIL4pSI,1311
|
|
3
|
-
ivoryos/version.py,sha256=
|
|
3
|
+
ivoryos/version.py,sha256=zmP2TRnzKPjZJ1eiBcT-cRInsji6FW-OVD3FafQFCc4,23
|
|
4
4
|
ivoryos/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
ivoryos/routes/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
ivoryos/routes/auth/auth.py,sha256=7CdXjGAr1B_xsmwweakTWOoROgsOJf0MNTzlMP_5Nus,3240
|
|
7
7
|
ivoryos/routes/auth/templates/auth/login.html,sha256=WSRrKbdM_oobqSXFRTo-j9UlOgp6sYzS9tm7TqqPULI,1207
|
|
8
8
|
ivoryos/routes/auth/templates/auth/signup.html,sha256=b5LTXtpfTSkSS7X8u1ldwQbbgEFTk6UNMAediA5BwBY,1465
|
|
9
9
|
ivoryos/routes/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
ivoryos/routes/control/control.py,sha256=
|
|
10
|
+
ivoryos/routes/control/control.py,sha256=bxNYR-VAFA7tSswDt5k130AnIx1f64_R9N2B9kMridI,14160
|
|
11
11
|
ivoryos/routes/control/templates/control/controllers.html,sha256=iIp0h6WA68gQj9OsoiB7dU1BqH8CGomTueR73F4C8eY,4274
|
|
12
|
-
ivoryos/routes/control/templates/control/controllers_home.html,sha256=
|
|
12
|
+
ivoryos/routes/control/templates/control/controllers_home.html,sha256=VQ77HRvBlyBrQ3al5fcKF5Y6_vKtU8WeAhilqQQltAo,2997
|
|
13
13
|
ivoryos/routes/control/templates/control/controllers_new.html,sha256=uOQo9kYmwX2jk3KZDkMUF_ylfNUIs_oIWb_kk_MMVDM,4921
|
|
14
14
|
ivoryos/routes/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
ivoryos/routes/database/database.py,sha256=
|
|
16
|
-
ivoryos/routes/database/templates/database/experiment_database.html,sha256=
|
|
15
|
+
ivoryos/routes/database/database.py,sha256=UY-6tHKPZaDch0whXVwgu201SQ231tPCE8ej374GOZ8,7140
|
|
16
|
+
ivoryos/routes/database/templates/database/experiment_database.html,sha256=edlCcKfrS91gGG1dPFQjC9xD7F7nWNNqS3S6Oa7apzs,3460
|
|
17
|
+
ivoryos/routes/database/templates/database/workflow_run_database.html,sha256=MczK9my9u0SyQsMFLbc6CXeZqKaBo5vk1SpwjkcZdqk,3571
|
|
17
18
|
ivoryos/routes/design/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
ivoryos/routes/design/design.py,sha256=
|
|
19
|
-
ivoryos/routes/design/templates/design/experiment_builder.html,sha256
|
|
20
|
-
ivoryos/routes/design/templates/design/experiment_run.html,sha256=
|
|
19
|
+
ivoryos/routes/design/design.py,sha256=HxEGPL5KTG2-roOB7UB9Ph28haY37IS5irKfloNEld0,25054
|
|
20
|
+
ivoryos/routes/design/templates/design/experiment_builder.html,sha256=2cT25URI6NoRDKuU6xl8Vsv4pqyQhhx-Fu8JOfPIP8k,27110
|
|
21
|
+
ivoryos/routes/design/templates/design/experiment_run.html,sha256=2CWbHx2M4h4EW7E0EapGPtwza56VEqhZDAIX4IDzYjQ,30266
|
|
21
22
|
ivoryos/routes/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
23
|
ivoryos/routes/main/main.py,sha256=yuVJzXAob1kc1dfflkTBIZQ0tdf6kChfuq-uQlN1e9Q,957
|
|
23
24
|
ivoryos/routes/main/templates/main/help.html,sha256=IOktMEsOPk0SCiMBXZ4mpffClERAyX8W82fel71M3M0,9370
|
|
24
|
-
ivoryos/routes/main/templates/main/home.html,sha256=
|
|
25
|
+
ivoryos/routes/main/templates/main/home.html,sha256=8AhQOWakD-1TyWA0s-B9ZK96L_f8ywYUEGHW1UzMGZA,4634
|
|
25
26
|
ivoryos/static/favicon.ico,sha256=RhlrPtfITOkzC9BjP1UB1V5L9Oyp6NwNtWeMcGOnpyc,15406
|
|
26
27
|
ivoryos/static/logo.webp,sha256=lXgfQR-4mHTH83k7VV9iB54-oC2ipe6uZvbwdOnLETc,14974
|
|
27
|
-
ivoryos/static/style.css,sha256=
|
|
28
|
+
ivoryos/static/style.css,sha256=zQVx35A5g6JMJ-K84-6fSKtzXGjp_p5ZVG6KLHPM2IE,4021
|
|
28
29
|
ivoryos/static/gui_annotation/Slide1.png,sha256=Lm4gdOkUF5HIUFaB94tl6koQVkzpitKj43GXV_XYMMc,121727
|
|
29
30
|
ivoryos/static/gui_annotation/Slide2.PNG,sha256=z3wQ9oVgg4JTWVLQGKK_KhtepRHUYP1e05XUWGT2A0I,118761
|
|
30
31
|
ivoryos/static/js/overlay.js,sha256=dPxop19es0E0ZUSY3d_4exIk7CJuQEnlW5uTt5fZfzI,483
|
|
31
|
-
ivoryos/static/js/socket_handler.js,sha256=
|
|
32
|
+
ivoryos/static/js/socket_handler.js,sha256=fJ_SKCfS2ZejnECPKZuD8DTEPhBxmm0m-yCvxf2UtIQ,4885
|
|
32
33
|
ivoryos/static/js/sortable_card.js,sha256=ifmlGe3yy0U_KzMphV4ClRhK2DLOvkELYMlq1vECuac,807
|
|
33
|
-
ivoryos/static/js/sortable_design.js,sha256=
|
|
34
|
-
ivoryos/templates/base.html,sha256=
|
|
34
|
+
ivoryos/static/js/sortable_design.js,sha256=wwpKfIzZGDxfX3moNz0cvPvm9YyHmopZK3wmkUdnBiw,4333
|
|
35
|
+
ivoryos/templates/base.html,sha256=sDdwqOIUP2Get-py4E59PkieoGWLFpX6wAJe93s4aRo,8518
|
|
35
36
|
ivoryos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
-
ivoryos/utils/
|
|
37
|
-
ivoryos/utils/
|
|
38
|
-
ivoryos/utils/
|
|
39
|
-
ivoryos/utils/
|
|
40
|
-
ivoryos/utils/
|
|
41
|
-
ivoryos/utils/
|
|
42
|
-
ivoryos
|
|
43
|
-
ivoryos-0.1.
|
|
44
|
-
ivoryos-0.1.
|
|
45
|
-
ivoryos-0.1.
|
|
46
|
-
ivoryos-0.1.
|
|
37
|
+
ivoryos/utils/client_proxy.py,sha256=AzcSQGMqeCqVULP1a7vEKNe135NZYryVX63ke0wgK04,2099
|
|
38
|
+
ivoryos/utils/db_models.py,sha256=1G2De1nLRCGwuY4zqgMeIQ-p1XJ_PkBxH1cd0fJ9YgY,26740
|
|
39
|
+
ivoryos/utils/form.py,sha256=Eqrg4G44hoG6TizxTEP4DNd-rEoyN77t9Y7cB1WdrcQ,19205
|
|
40
|
+
ivoryos/utils/global_config.py,sha256=P0xs_33bZfNQ-D71lCkq7HJyT4ngQWPqUKnkoMrmM8c,1908
|
|
41
|
+
ivoryos/utils/llm_agent.py,sha256=-lVCkjPlpLues9sNTmaT7bT4sdhWvV2DiojNwzB2Lcw,6422
|
|
42
|
+
ivoryos/utils/script_runner.py,sha256=jVQzZQXmeVBNREBr5yP2grAKrO_1PXIlN5Uny87-PfI,12547
|
|
43
|
+
ivoryos/utils/utils.py,sha256=VP-4Wf-slK2pMe659K5TJLbZXVNvyCD1-3kdfp_COxI,14990
|
|
44
|
+
ivoryos-0.1.22.dist-info/LICENSE,sha256=p2c8S8i-8YqMpZCJnadLz1-ofxnRMILzz6NCMIypRag,1084
|
|
45
|
+
ivoryos-0.1.22.dist-info/METADATA,sha256=13bJFUatG0fTMy8ZfocdZvmOdqZvQZYhwu-vL3Q2kEo,6846
|
|
46
|
+
ivoryos-0.1.22.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
47
|
+
ivoryos-0.1.22.dist-info/top_level.txt,sha256=FRIWWdiEvRKqw-XfF_UK3XV0CrnNb6EmVbEgjaVazRM,8
|
|
48
|
+
ivoryos-0.1.22.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|