ivoryos 1.3.1__py3-none-any.whl → 1.3.2__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 CHANGED
@@ -2,12 +2,13 @@ from ivoryos.server import run
2
2
  from ivoryos.optimizer.registry import OPTIMIZER_REGISTRY
3
3
  from ivoryos.version import __version__ as ivoryos_version
4
4
  from ivoryos.utils.decorators import block, BUILDING_BLOCKS
5
-
5
+ from ivoryos.app import app
6
6
 
7
7
  __all__ = [
8
8
  "block",
9
9
  "BUILDING_BLOCKS",
10
10
  "OPTIMIZER_REGISTRY",
11
11
  "run",
12
+ "app",
12
13
  "ivoryos_version",
13
14
  ]
ivoryos/app.py CHANGED
@@ -20,6 +20,16 @@ from ivoryos.version import __version__ as ivoryos_version
20
20
  from sqlalchemy import inspect, text
21
21
  from flask import current_app
22
22
 
23
+ url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
24
+ app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
25
+ app.register_blueprint(main, url_prefix=url_prefix)
26
+ app.register_blueprint(auth, url_prefix=f'{url_prefix}/{auth.name}')
27
+ app.register_blueprint(library, url_prefix=f'{url_prefix}/{library.name}')
28
+ app.register_blueprint(control, url_prefix=f'{url_prefix}/instruments')
29
+ app.register_blueprint(design, url_prefix=f'{url_prefix}')
30
+ app.register_blueprint(execute, url_prefix=f'{url_prefix}')
31
+ app.register_blueprint(data, url_prefix=f'{url_prefix}')
32
+ app.register_blueprint(api, url_prefix=f'{url_prefix}/{api.name}')
23
33
 
24
34
  def reset_old_schema(engine, db_dir):
25
35
  inspector = inspect(engine)
@@ -28,7 +38,7 @@ def reset_old_schema(engine, db_dir):
28
38
 
29
39
  # Check if old tables exist (no workflow_phases table)
30
40
  has_workflow_phase = 'workflow_phases' in tables
31
- old_workflow_run = 'old_workflow_run' in tables
41
+ old_workflow_run = 'workflow_runs' in tables
32
42
  old_workflow_step = 'workflow_steps' in tables
33
43
 
34
44
  if not has_workflow_phase:
@@ -59,18 +69,6 @@ def create_app(config_class=None):
59
69
  create app, init database
60
70
  """
61
71
 
62
- url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
63
- app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
64
- app.register_blueprint(main, url_prefix=url_prefix)
65
- app.register_blueprint(auth, url_prefix=f'{url_prefix}/{auth.name}')
66
- app.register_blueprint(library, url_prefix=f'{url_prefix}/{library.name}')
67
- app.register_blueprint(control, url_prefix=f'{url_prefix}/instruments')
68
- app.register_blueprint(design, url_prefix=f'{url_prefix}')
69
- app.register_blueprint(execute, url_prefix=f'{url_prefix}')
70
- app.register_blueprint(data, url_prefix=f'{url_prefix}')
71
- app.register_blueprint(api, url_prefix=f'{url_prefix}/{api.name}')
72
-
73
-
74
72
  app.config.from_object(config_class or 'config.get_config()')
75
73
  os.makedirs(app.config["OUTPUT_FOLDER"], exist_ok=True)
76
74
  # Initialize extensions
@@ -15,16 +15,16 @@ def login():
15
15
  """
16
16
  .. :quickref: User; login user
17
17
 
18
- .. http:get:: /login
18
+ .. http:get:: /auth/login
19
19
 
20
20
  load user login form.
21
21
 
22
- .. http:post:: /login
22
+ .. http:post:: /auth/login
23
23
 
24
24
  :form username: username
25
25
  :form password: password
26
26
  :status 302: and then redirects to homepage
27
- :status 401: incorrect password, redirects to :http:get:`/ivoryos/login`
27
+ :status 401: incorrect password, redirects to :http:get:`/ivoryos/auth/login`
28
28
  """
29
29
  if request.method == 'POST':
30
30
  username = request.form.get('username')
@@ -57,16 +57,16 @@ def signup():
57
57
  """
58
58
  .. :quickref: User; signup for a new account
59
59
 
60
- .. http:get:: /signup
60
+ .. http:get:: /auth/signup
61
61
 
62
62
  load user sighup
63
63
 
64
- .. http:post:: /signup
64
+ .. http:post:: /auth/signup
65
65
 
66
66
  :form username: username
67
67
  :form password: password
68
- :status 302: and then redirects to :http:get:`/ivoryos/login`
69
- :status 409: when user already exists, redirects to :http:get:`/ivoryos/signup`
68
+ :status 302: and then redirects to :http:get:`/ivoryos/auth/login`
69
+ :status 409: when user already exists, redirects to :http:get:`/ivoryos/auth/signup`
70
70
  """
71
71
  if request.method == 'POST':
72
72
  username = request.form.get('username')
@@ -92,6 +92,8 @@ def logout():
92
92
  """
93
93
  .. :quickref: User; logout the user
94
94
 
95
+ .. http:get:: /auth/logout
96
+
95
97
  logout the current user, clear session info, and redirect to the login page.
96
98
  """
97
99
  logout_user()
@@ -1,3 +1,5 @@
1
+ import copy
2
+
1
3
  from flask import Blueprint, redirect, flash, request, render_template, session, current_app, jsonify
2
4
  from flask_login import login_required
3
5
 
@@ -95,8 +97,10 @@ def deck_controllers(instrument: str = None):
95
97
 
96
98
  # GET request → render web form or return snapshot for API
97
99
  if request.is_json or request.accept_mimetypes.best_match(['application/json', 'text/html']) == 'application/json':
98
-
99
- snapshot = global_config.deck_snapshot.copy()
100
+ # 1.3.2 fix snapshot copy, add building blocks to snapshots
101
+ snapshot = copy.deepcopy(global_config.deck_snapshot)
102
+ building_blocks = copy.deepcopy(global_config.building_blocks)
103
+ snapshot.update(building_blocks)
100
104
  for instrument_key, instrument_data in snapshot.items():
101
105
  for function_key, function_data in instrument_data.items():
102
106
  function_data["signature"] = str(function_data["signature"])
@@ -44,7 +44,7 @@ def workflow_logs(workflow_id:int):
44
44
 
45
45
  get workflow data logs by workflow id
46
46
 
47
- .. http:get:: /executions/<int:workflow_id>
47
+ .. http:get:: /executions/records/<int:workflow_id>
48
48
 
49
49
  :param workflow_id: workflow id
50
50
  :type workflow_id: int
@@ -109,6 +109,15 @@ def workflow_logs(workflow_id:int):
109
109
 
110
110
  @data.get("/executions/data/<int:workflow_id>")
111
111
  def workflow_phase_data(workflow_id: int):
112
+ """
113
+ .. :quickref: Workflow Data Database; get workflow data for plotting
114
+
115
+ get workflow data for plotting by workflow id
116
+
117
+ .. http:get:: /executions/data/<int: workflow_id>
118
+
119
+ :param workflow_id: workflow id
120
+ """
112
121
  workflow = db.session.get(WorkflowRun, workflow_id)
113
122
  if not workflow:
114
123
  return jsonify({})
@@ -140,7 +149,7 @@ def delete_workflow_record(workflow_id: int):
140
149
 
141
150
  delete a workflow execution record by workflow id
142
151
 
143
- .. http:delete:: /executions/records/<int:workflow_id>
152
+ .. http:delete:: /executions/records/<int: workflow_id>
144
153
 
145
154
  :param workflow_id: workflow id
146
155
  :type workflow_id: int
@@ -163,7 +172,7 @@ def download_results(filename:str):
163
172
  :param filename: workflow data filename
164
173
  :type filename: str
165
174
 
166
- # :status 302: load pseudo deck and then redirects to :http:get:`/ivoryos/executions`
175
+ # :status 302: load pseudo deck and then redirects to :http:get:`/ivoryos/executions/records`
167
176
  """
168
177
 
169
178
  filepath = os.path.join(current_app.config["DATA_FOLDER"], filename)
@@ -257,7 +257,7 @@ def submit_script():
257
257
  """
258
258
  .. :quickref: Workflow Design; convert Python to workflow script
259
259
 
260
- .. http:post:: /design/submit_python
260
+ .. http:post:: /draft/submit_python
261
261
 
262
262
  Convert a Python script to a workflow script and save it in the database.
263
263
 
@@ -393,7 +393,7 @@ def get_operation_sidebar(instrument: str = ''):
393
393
  """
394
394
  .. :quickref: Workflow Design; handle methods of a specific instrument
395
395
 
396
- .. http:get:: /design/instruments/<string:instrument>
396
+ .. http:get:: /draft/instruments/<string:instrument>
397
397
 
398
398
  :param instrument: The name of the instrument to handle methods for.
399
399
  :type instrument: str
@@ -17,7 +17,7 @@ def load_json():
17
17
  .. http:post:: /files/script-json
18
18
 
19
19
  :form file: workflow design JSON file
20
- :status 302: load script json and then redirects to :http:get:`/ivoryos/design/draft`
20
+ :status 302: load script json and then redirects to :http:get:`/ivoryos/draft`
21
21
  """
22
22
 
23
23
  if request.method == "POST":
@@ -38,7 +38,7 @@ def download_python():
38
38
 
39
39
  .. http:post:: /files/script-python
40
40
 
41
- :status 302: redirects to :http:get:`/ivoryos/design/script/`
41
+ :status 302: redirects to :http:get:`/ivoryos/draft`
42
42
  """
43
43
  script = utils.get_script_file()
44
44
  run_name = script.name if script.name else "untitled"
@@ -53,7 +53,7 @@ def download_json():
53
53
 
54
54
  .. http:post:: /files/script-json
55
55
 
56
- :status 302: redirects to :http:get:`/ivoryos/design/script/`
56
+ :status 302: redirects to :http:get:`/ivoryos/draft`
57
57
  """
58
58
  script = utils.get_script_file()
59
59
  run_name = script.name if script.name else "untitled"
@@ -12,7 +12,7 @@ def get_step(uuid: int):
12
12
  """
13
13
  .. :quickref: Workflow Design Steps; get an action step editing form
14
14
 
15
- .. http:get:: /steps/<int:uuid>
15
+ .. http:get:: /draft/steps/<int:uuid>
16
16
 
17
17
  get the editing form for an action step
18
18
 
@@ -36,7 +36,7 @@ def save_step(uuid: int):
36
36
  """
37
37
  .. :quickref: Workflow Design Steps; save an action step on canvas
38
38
 
39
- .. http:post:: /steps/<int:uuid>
39
+ .. http:post:: /draft/steps/<int:uuid>
40
40
 
41
41
  save the changes of an action step
42
42
 
@@ -69,7 +69,7 @@ def delete_step(uuid: int):
69
69
  """
70
70
  .. :quickref: Workflow Design Steps; delete an action step on canvas
71
71
 
72
- .. http:delete:: /steps/<int:uuid>
72
+ .. http:delete:: /draft/steps/<int:uuid>
73
73
 
74
74
  delete an action step
75
75
 
@@ -9,7 +9,7 @@ from flask_login import login_required
9
9
  from ivoryos.routes.execute.execute_file import files
10
10
  from ivoryos.utils import utils
11
11
  from ivoryos.utils.bo_campaign import parse_optimization_form
12
- from ivoryos.utils.db_models import SingleStep, WorkflowRun, WorkflowStep
12
+ from ivoryos.utils.db_models import SingleStep, WorkflowRun, WorkflowStep, WorkflowPhase
13
13
  from ivoryos.utils.global_config import GlobalConfig
14
14
  from ivoryos.utils.form import create_action_button
15
15
 
@@ -157,6 +157,7 @@ def experiment_run():
157
157
  def run_bo():
158
158
  """
159
159
  .. :quickref: Workflow Execution; run Bayesian Optimization
160
+
160
161
  Run Bayesian Optimization with the given parameters and objectives.
161
162
 
162
163
  .. http:post:: /executions/campaign
@@ -166,6 +167,7 @@ def run_bo():
166
167
  :form existing_data: existing data to use for optimization
167
168
  :form parameters: parameters for optimization
168
169
  :form objectives: objectives for optimization
170
+
169
171
  TODO: merge to experiment_run or not, add more details about the form fields and their expected values.
170
172
  """
171
173
  script = utils.get_script_file()
@@ -225,7 +227,9 @@ def runner_status():
225
227
  if task_type == "workflow":
226
228
  workflow = WorkflowRun.query.get(task_id)
227
229
  if workflow is not None:
228
- latest_step = WorkflowStep.query.filter_by(workflow_id=workflow.id).order_by(
230
+ phases = WorkflowPhase.query.filter_by(run_id=workflow.id).order_by(WorkflowPhase.start_time).all()
231
+ current_phase = phases[-1]
232
+ latest_step = WorkflowStep.query.filter_by(phase_id=current_phase.id).order_by(
229
233
  WorkflowStep.start_time.desc()).first()
230
234
  if latest_step is not None:
231
235
  current_step = latest_step.as_dict()
@@ -13,25 +13,25 @@ library = Blueprint('library', __name__, template_folder='templates')
13
13
  def workflow_script(script_name:str):
14
14
  # todo: split this into two routes, one for GET and POST, another for DELETE
15
15
  """
16
- .. :quickref: Workflow Script Database; get, post, delete workflow script
16
+ .. :quickref: Workflow Script Database; get, post, delete a workflow script
17
17
 
18
- .. http:get:: /<string:script_name>
18
+ .. http:get:: /library/<string: script_name>
19
19
 
20
20
  :param script_name: script name
21
21
  :type script_name: str
22
- :status 302: redirect to :http:get:`/ivoryos/design/script/`
22
+ :status 302: redirect to :http:get:`/ivoryos/draft`
23
23
 
24
- .. http:post:: /<string:script_name>
24
+ .. http:post:: /library/<string: script_name>
25
25
 
26
26
  :param script_name: script name
27
27
  :type script_name: str
28
28
  :status 200: json response with success status
29
29
 
30
- .. http:delete:: /<string:script_name>
30
+ .. http:delete:: /library/<string: script_name>
31
31
 
32
32
  :param script_name: script name
33
33
  :type script_name: str
34
- :status 302: redirect to :http:get:`/ivoryos/design/script/`
34
+ :status 302: redirect to :http:get:`/ivoryos/draft`
35
35
 
36
36
  """
37
37
  row = Script.query.get(script_name)
@@ -89,10 +89,8 @@ def load_from_database():
89
89
 
90
90
  backend control through http requests
91
91
 
92
- .. http:get:: /designs/get/<deck_name>
92
+ .. http:get:: /library
93
93
 
94
- :param deck_name: filter for deck name
95
- :type deck_name: str
96
94
 
97
95
  """
98
96
  session.pop('edit_action', None) # reset cache
@@ -132,10 +130,10 @@ def save_as():
132
130
 
133
131
  save the current workflow script as
134
132
 
135
- .. http:post:: /library/save_as
133
+ .. http:post:: /library
136
134
 
137
135
  : form run_name: new workflow name
138
- :status 302: redirect to :http:get:`/ivoryos/design/script/`
136
+ :status 302: redirect to :http:get:`/ivoryos/draft`
139
137
 
140
138
  """
141
139
  if request.method == "POST":
@@ -143,12 +143,38 @@ def convert_to_cards(source_code: str):
143
143
  f = f.value
144
144
  if isinstance(f, ast.Name):
145
145
  func_parts.insert(0, f.id)
146
- if not func_parts or not func_parts[0].startswith("deck"):
146
+ if not func_parts:
147
147
  return
148
148
 
149
149
  instrument = ".".join(func_parts[:-1])
150
150
  action = func_parts[-1]
151
151
 
152
+
153
+ # --- special case for time.sleep ---
154
+ if instrument == "time" and action == "sleep":
155
+ wait_value = None
156
+ if node.args:
157
+ arg_node = node.args[0]
158
+ if isinstance(arg_node, ast.Constant):
159
+ wait_value = arg_node.value
160
+ elif isinstance(arg_node, ast.Name):
161
+ wait_value = f"#{arg_node.id}"
162
+ else:
163
+ wait_value = ast.unparse(arg_node)
164
+
165
+ add_card({
166
+ "action": "wait",
167
+ "arg_types": {"statement": infer_type(wait_value)},
168
+ "args": {"statement": wait_value},
169
+ "id": new_id(),
170
+ "instrument": "wait",
171
+ "return": ret_var,
172
+ "uuid": generate_uuid()
173
+ })
174
+ return
175
+ # -----------------------------------
176
+
177
+
152
178
  args = {}
153
179
  arg_types = {}
154
180
 
ivoryos/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.3.1"
1
+ __version__ = "1.3.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ivoryos
3
- Version: 1.3.1
3
+ Version: 1.3.2
4
4
  Summary: an open-source Python package enabling Self-Driving Labs (SDLs) interoperability
5
5
  Author-email: Ivory Zhang <ivoryzhang@chem.ubc.ca>
6
6
  License: MIT
@@ -1,9 +1,9 @@
1
- ivoryos/__init__.py,sha256=eUtNgSskl--l94VUTT1bgiBR8gdMMFQgjHEsHOxdHyI,320
2
- ivoryos/app.py,sha256=tnFimgKnjRLhgIiraAVhEZFmcp6TGho7mQ5a5Y35rlY,4794
1
+ ivoryos/__init__.py,sha256=Or4kPfDSQA5WYrQdnBlWl_dA4wwjhEqNkuE5XPX3bqI,358
2
+ ivoryos/app.py,sha256=fuHVjJcJVc0i3Qe5aOOVQCe1Vetc4zTa4S1Z_xCjBZs,4749
3
3
  ivoryos/config.py,sha256=y3RxNjiIola9tK7jg-mHM8EzLMwiLwOzoisXkDvj0gA,2174
4
4
  ivoryos/server.py,sha256=K0_Ioui0uKshKl5fxGB_1wJD4OckXyR9DdOfCIhvkfE,6742
5
5
  ivoryos/socket_handlers.py,sha256=VWVWiIdm4jYAutwGu6R0t1nK5MuMyOCL0xAnFn06jWQ,1302
6
- ivoryos/version.py,sha256=-ypEJktJToAL9by62JJKWEzDo_KPCQtmE5kwFgX24z4,22
6
+ ivoryos/version.py,sha256=HgKA3RqZvC7slo8MgLyffCGwJbQ3cY6I7oUMFvGLWps,22
7
7
  ivoryos/optimizer/ax_optimizer.py,sha256=PoSu8hrDFFpqyhRBnaSMswIUsDfEX6sPWt8NEZ_sobs,7112
8
8
  ivoryos/optimizer/base_optimizer.py,sha256=JTbUharZKn0t8_BDbAFuwZIbT1VOnX1Xuog1pJuU8hY,1992
9
9
  ivoryos/optimizer/baybe_optimizer.py,sha256=EdrrRiYO-IOx610cPXiQhH4qG8knUP0uiZ0YoyaGIU8,7954
@@ -11,25 +11,25 @@ ivoryos/optimizer/registry.py,sha256=lr0cqdI2iEjw227ZPRpVkvsdYdddjeJJRzawDv77cEc
11
11
  ivoryos/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  ivoryos/routes/api/api.py,sha256=97Y7pqTwOaWgZgI5ovEPxEBm6Asrt0Iy0VhBkVp2xqA,2304
13
13
  ivoryos/routes/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- ivoryos/routes/auth/auth.py,sha256=CqoP9cM8BuXVGHGujX7-0sNAOdWILU9amyBrObOD6Ss,3283
14
+ ivoryos/routes/auth/auth.py,sha256=D-sPEaUsc8vefly36h74rgU-ILulf7hiK6xc5sBEl58,3350
15
15
  ivoryos/routes/auth/templates/login.html,sha256=WSRrKbdM_oobqSXFRTo-j9UlOgp6sYzS9tm7TqqPULI,1207
16
16
  ivoryos/routes/auth/templates/signup.html,sha256=b5LTXtpfTSkSS7X8u1ldwQbbgEFTk6UNMAediA5BwBY,1465
17
17
  ivoryos/routes/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- ivoryos/routes/control/control.py,sha256=6LnVF4mGgfLQvzmrSFxaFz9lBtBe4WnXlIouDxtaR2E,6230
18
+ ivoryos/routes/control/control.py,sha256=rYXMHIfX17tFBgIZoXxKfDSoeZaRdCd621twh0V4DgQ,6430
19
19
  ivoryos/routes/control/control_file.py,sha256=3fQ9R8EcdqKs_hABn2EqRAB1xC2DHAT_q_pwsMIDDQI,864
20
20
  ivoryos/routes/control/control_new_device.py,sha256=mfJKg5JAOagIpUKbp2b5nRwvd2V3bzT3M0zIhIsEaFM,5456
21
21
  ivoryos/routes/control/utils.py,sha256=XlhhqAtOj7n3XfHPDxJ8TvCV2K2I2IixB0CBkl1QeQc,1242
22
22
  ivoryos/routes/control/templates/controllers.html,sha256=5hF3zcx5Rpy0Zaoq-5YGrR_TvPD9MGIa30fI4smEii0,9702
23
23
  ivoryos/routes/control/templates/controllers_new.html,sha256=eVeLABT39DWOIYrwWClw7sAD3lCoAGCznygPgFbQoRc,5945
24
24
  ivoryos/routes/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- ivoryos/routes/data/data.py,sha256=wJCd9TytdYCeU6BaGEUhBQHRYo7yn9OagIWa2qwSZEo,5583
25
+ ivoryos/routes/data/data.py,sha256=2YqiUJuZOv13Z6wtqzZKBfeHHSjo5KrHRA-p6sZU5fo,5832
26
26
  ivoryos/routes/data/templates/workflow_database.html,sha256=ofvHcovpwmJXo1SFiSrL8I9kLU_3U1UxsJUUrQ2CJUU,4878
27
27
  ivoryos/routes/data/templates/workflow_view.html,sha256=Ti17kzlPlYTmzx5MkdsPlXJ1_k6QgMYQBM6FHjG50go,12491
28
28
  ivoryos/routes/data/templates/components/step_card.html,sha256=XWsr7qxAY76RCuQHETubWjWBlPgs2HkviH4ju6qfBKo,1923
29
29
  ivoryos/routes/design/__init__.py,sha256=zS3HXKaw0ALL5n6t_W1rUz5Uj5_tTQ-Y1VMXyzewvR0,113
30
- ivoryos/routes/design/design.py,sha256=xYDwtCdTcCd282guaIeNvfUFc5UsiypkQVpRvFqRujQ,18246
31
- ivoryos/routes/design/design_file.py,sha256=m4yku8fkpLUs4XvLJBqR5V-kyaGKbGB6ZoRxGbjEU5Q,2140
32
- ivoryos/routes/design/design_step.py,sha256=l8U3-FuXmap__sYm51AueKdbTaLCFaKjAz-j02b4g-E,5200
30
+ ivoryos/routes/design/design.py,sha256=h55RZ_SDbkmA647GmkD-Sc2_en5vyBK8foE-arrPEdk,18244
31
+ ivoryos/routes/design/design_file.py,sha256=MVIc5uGSaGxZhs86hfPjX2n0iy1OcXeLq7b9Ucdg4VQ,2115
32
+ ivoryos/routes/design/design_step.py,sha256=zW6kOhX-zJbtX1x5NaVPm79HZjKBzAWevmqJ2Y3qqpg,5218
33
33
  ivoryos/routes/design/templates/experiment_builder.html,sha256=hh-d2tOc_40gww5WfUYIf8sM3qBaALZnR8Sx7Ja4tpU,1623
34
34
  ivoryos/routes/design/templates/components/action_form.html,sha256=kXJOrJLbFsMHHWVSuMQHpt1xFrUMnwgzTG8e6Qfn0Cg,3042
35
35
  ivoryos/routes/design/templates/components/actions_panel.html,sha256=jHTR58saTUIZInBdC-vLc1ZTbStLiULeWbupjB4hQzo,977
@@ -51,7 +51,7 @@ ivoryos/routes/design/templates/components/modals/new_script_modal.html,sha256=p
51
51
  ivoryos/routes/design/templates/components/modals/rename_modal.html,sha256=40rLNF9JprdXekB3mv_S3OdqVuQYOe-BZSCgOnIkxJQ,1202
52
52
  ivoryos/routes/design/templates/components/modals/saveas_modal.html,sha256=N5PEqUuK3qxDFbtDKFnzHwhLarQLPHiX-XQAdQPL1AU,1555
53
53
  ivoryos/routes/execute/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
- ivoryos/routes/execute/execute.py,sha256=hFnCvzO1OzR0XckCRzHfP_RZV70DtbH_p7kw1YhIe3o,12250
54
+ ivoryos/routes/execute/execute.py,sha256=lxJ0jHILomJ9kRBlqcnuScC6DTHVDJZRNTwz1ZC4yR8,12428
55
55
  ivoryos/routes/execute/execute_file.py,sha256=TelWYV295p4ZPhkUDJSVxfYROfVaKodEmDPTS2plQHI,2816
56
56
  ivoryos/routes/execute/templates/experiment_run.html,sha256=D-ek7ISQrIQXy4PH37TnsURihbGNdpCgdTC8w79cwQc,10355
57
57
  ivoryos/routes/execute/templates/components/error_modal.html,sha256=5Dmp9V0Ys6781Y-pKn_mc4N9J46c8EwIkjkHX22xCsw,1025
@@ -63,7 +63,7 @@ ivoryos/routes/execute/templates/components/tab_bayesian.html,sha256=5XTMHZzbGxc
63
63
  ivoryos/routes/execute/templates/components/tab_configuration.html,sha256=JIHsYvwcYQZmJJz503NXnhcceKxd9B3JKFUSvGNWe_0,5131
64
64
  ivoryos/routes/execute/templates/components/tab_repeat.html,sha256=X-r7p78tVRrfwmAbhhZGBZbm78C4nTJS6O2A4dvzGEg,760
65
65
  ivoryos/routes/library/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
- ivoryos/routes/library/library.py,sha256=ZruIoaa06GlqpvJ383PSDEFdlPJFl2E2YI0H8aK7Hc0,5477
66
+ ivoryos/routes/library/library.py,sha256=QKeP34COssXDipn3d9yEn7pVPYbPb-eFg_X0C8JTvVQ,5387
67
67
  ivoryos/routes/library/templates/library.html,sha256=kMaQphkoGQdxIRcQmVcEIn8eghuv2AAClHpo7jGDVv8,4021
68
68
  ivoryos/routes/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
69
  ivoryos/routes/main/main.py,sha256=1AcSouCocHWjlpEED-ECn5OFiu0-3u0N-0st5RtKCVY,952
@@ -91,13 +91,13 @@ ivoryos/utils/decorators.py,sha256=p1Bdl3dCeaHNv6-cCCUOZMiFu9kRaqqQnkFJUkzPoJE,9
91
91
  ivoryos/utils/form.py,sha256=Ej9tx06KZZ5fPQm1ho1byotNocF3u24aatc2ZyI0rK4,22301
92
92
  ivoryos/utils/global_config.py,sha256=D6oz5dttyaP24jbqnw1sR64moSb-7jJkSpRuufdA_TI,2747
93
93
  ivoryos/utils/llm_agent.py,sha256=-lVCkjPlpLues9sNTmaT7bT4sdhWvV2DiojNwzB2Lcw,6422
94
- ivoryos/utils/py_to_json.py,sha256=fyqjaxDHPh-sahgT6IHSn34ktwf6y51_x1qvhbNlH-U,7314
94
+ ivoryos/utils/py_to_json.py,sha256=xnxWHNEc9QtOB2gkRyWMICGKyj6vhN9iMtCLTqoNcNM,8248
95
95
  ivoryos/utils/script_runner.py,sha256=I_ghDVT7_O9RQ30J0rC3guaAM76-sin6OJc50uB1u8Q,19362
96
96
  ivoryos/utils/serilize.py,sha256=lkBhkz8r2bLmz2_xOb0c4ptSSOqjIu6krj5YYK4Nvj8,6784
97
97
  ivoryos/utils/task_runner.py,sha256=bfG6GubdlzgD8rBwzD00aGB5LDFmb9hLFJIOMH8hVv4,3248
98
98
  ivoryos/utils/utils.py,sha256=09VPNRaIoA-mp1TXLGC3BwM2tDaAJ36csvNtW19KsU0,14792
99
- ivoryos-1.3.1.dist-info/licenses/LICENSE,sha256=p2c8S8i-8YqMpZCJnadLz1-ofxnRMILzz6NCMIypRag,1084
100
- ivoryos-1.3.1.dist-info/METADATA,sha256=DR_s-D1bHUyzhqpD47ug8zAottUkrSnVTcDka53J4GI,7351
101
- ivoryos-1.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
102
- ivoryos-1.3.1.dist-info/top_level.txt,sha256=FRIWWdiEvRKqw-XfF_UK3XV0CrnNb6EmVbEgjaVazRM,8
103
- ivoryos-1.3.1.dist-info/RECORD,,
99
+ ivoryos-1.3.2.dist-info/licenses/LICENSE,sha256=p2c8S8i-8YqMpZCJnadLz1-ofxnRMILzz6NCMIypRag,1084
100
+ ivoryos-1.3.2.dist-info/METADATA,sha256=VAaEJtoPD86dQvtY0V_CarIh3I_Otrbo02CGYqk8J80,7351
101
+ ivoryos-1.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
102
+ ivoryos-1.3.2.dist-info/top_level.txt,sha256=FRIWWdiEvRKqw-XfF_UK3XV0CrnNb6EmVbEgjaVazRM,8
103
+ ivoryos-1.3.2.dist-info/RECORD,,