alchemist-nrel 0.3.1__py3-none-any.whl → 0.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.
Files changed (32) hide show
  1. alchemist_core/__init__.py +2 -2
  2. alchemist_core/acquisition/botorch_acquisition.py +83 -126
  3. alchemist_core/data/experiment_manager.py +181 -12
  4. alchemist_core/models/botorch_model.py +292 -63
  5. alchemist_core/models/sklearn_model.py +145 -13
  6. alchemist_core/session.py +3330 -31
  7. alchemist_core/utils/__init__.py +3 -1
  8. alchemist_core/utils/acquisition_utils.py +60 -0
  9. alchemist_core/visualization/__init__.py +45 -0
  10. alchemist_core/visualization/helpers.py +130 -0
  11. alchemist_core/visualization/plots.py +1449 -0
  12. {alchemist_nrel-0.3.1.dist-info → alchemist_nrel-0.3.2.dist-info}/METADATA +13 -13
  13. {alchemist_nrel-0.3.1.dist-info → alchemist_nrel-0.3.2.dist-info}/RECORD +31 -26
  14. {alchemist_nrel-0.3.1.dist-info → alchemist_nrel-0.3.2.dist-info}/WHEEL +1 -1
  15. api/main.py +1 -1
  16. api/models/requests.py +52 -0
  17. api/models/responses.py +79 -2
  18. api/routers/experiments.py +333 -8
  19. api/routers/sessions.py +84 -9
  20. api/routers/visualizations.py +6 -4
  21. api/routers/websocket.py +2 -2
  22. api/services/session_store.py +295 -71
  23. api/static/assets/index-B6Cf6s_b.css +1 -0
  24. api/static/assets/{index-DWfIKU9j.js → index-B7njvc9r.js} +201 -196
  25. api/static/index.html +2 -2
  26. ui/gpr_panel.py +11 -5
  27. ui/target_column_dialog.py +299 -0
  28. ui/ui.py +52 -5
  29. api/static/assets/index-sMIa_1hV.css +0 -1
  30. {alchemist_nrel-0.3.1.dist-info → alchemist_nrel-0.3.2.dist-info}/entry_points.txt +0 -0
  31. {alchemist_nrel-0.3.1.dist-info → alchemist_nrel-0.3.2.dist-info}/licenses/LICENSE +0 -0
  32. {alchemist_nrel-0.3.1.dist-info → alchemist_nrel-0.3.2.dist-info}/top_level.txt +0 -0
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alchemist-nrel
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Active learning and optimization toolkit for chemical and materials research
5
5
  Author-email: Caleb Coatney <caleb.coatney@nrel.gov>
6
6
  License: BSD-3-Clause
7
- Project-URL: Homepage, https://github.com/NREL/ALchemist
8
- Project-URL: Documentation, https://nrel.github.io/ALchemist/
9
- Project-URL: Source, https://github.com/NREL/ALchemist
10
- Project-URL: Bug Tracker, https://github.com/NREL/ALchemist/issues
11
- Project-URL: Changelog, https://github.com/NREL/ALchemist/releases
7
+ Project-URL: Homepage, https://github.com/NatLabRockies/ALchemist
8
+ Project-URL: Documentation, https://natlabrockies.github.io/ALchemist/
9
+ Project-URL: Source, https://github.com/NatLabRockies/ALchemist
10
+ Project-URL: Bug Tracker, https://github.com/NatLabRockies/ALchemist/issues
11
+ Project-URL: Changelog, https://github.com/NatLabRockies/ALchemist/releases
12
12
  Keywords: active learning,bayesian optimization,gaussian processes,materials science,chemistry
13
13
  Classifier: Development Status :: 4 - Beta
14
14
  Classifier: Intended Audience :: Science/Research
@@ -70,7 +70,7 @@ ALchemist is a modular Python toolkit that brings active learning and Bayesian o
70
70
  ## Documentation
71
71
 
72
72
  Full user guide and documentation:
73
- [https://nrel.github.io/ALchemist/](https://nrel.github.io/ALchemist/)
73
+ [https://natlabrockies.github.io/ALchemist/](https://natlabrockies.github.io/ALchemist/)
74
74
 
75
75
  ---
76
76
 
@@ -108,7 +108,7 @@ Session files (JSON format) are fully interoperable between desktop and web appl
108
108
  - **Autonomous Optimization**: Use the REST API to integrate ALchemist with automated laboratory equipment for real-time process control
109
109
  - **Remote Monitoring**: Web dashboard provides read-only monitoring mode when ALchemist is being remote-controlled
110
110
 
111
- For detailed application examples, see [Use Cases](https://nrel.github.io/ALchemist/use_cases/) in the documentation.
111
+ For detailed application examples, see [Use Cases](https://natlabrockies.github.io/ALchemist/use_cases/) in the documentation.
112
112
 
113
113
  ---
114
114
 
@@ -133,10 +133,10 @@ pip install alchemist-nrel
133
133
  > *Note: This installs the latest unreleased version. The web application is not pre-built with this method because static build files are not included in the repository.*
134
134
 
135
135
  ```bash
136
- pip install git+https://github.com/NREL/ALchemist.git
136
+ pip install git+https://github.com/NatLabRockies/ALchemist.git
137
137
  ```
138
138
 
139
- For advanced installation options, Docker deployment, and development setup, see the [Advanced Installation Guide](https://nrel.github.io/ALchemist/#advanced-installation) in the documentation.
139
+ For advanced installation options, Docker deployment, and development setup, see the [Advanced Installation Guide](https://natlabrockies.github.io/ALchemist/#advanced-installation) in the documentation.
140
140
 
141
141
  ---
142
142
 
@@ -153,7 +153,7 @@ Opens at [http://localhost:8000/app](http://localhost:8000/app)
153
153
  alchemist
154
154
  ```
155
155
 
156
- For detailed usage instructions, see [Getting Started](https://nrel.github.io/ALchemist/) in the documentation.
156
+ For detailed usage instructions, see [Getting Started](https://natlabrockies.github.io/ALchemist/) in the documentation.
157
157
 
158
158
  ---
159
159
 
@@ -165,7 +165,7 @@ ALchemist is under active development at NLR as part of the DataHub project with
165
165
 
166
166
  ## Issues & Troubleshooting
167
167
 
168
- If you encounter any issues or have questions, please [open an issue on GitHub](https://github.com/NREL/ALchemist/issues) or contact ccoatney@nrel.gov.
168
+ If you encounter any issues or have questions, please [open an issue on GitHub](https://github.com/NatLabRockies/ALchemist/issues) or contact ccoatney@nrel.gov.
169
169
 
170
170
  For the latest known issues and troubleshooting tips, see the [Issues & Troubleshooting Log](docs/ISSUES_LOG.md).
171
171
 
@@ -181,5 +181,5 @@ This project is licensed under the BSD 3-Clause License. See the [LICENSE](LICEN
181
181
 
182
182
  ## Repository
183
183
 
184
- [https://github.com/NREL/ALchemist](https://github.com/NREL/ALchemist)
184
+ [https://github.com/NatLabRockies/ALchemist](https://github.com/NatLabRockies/ALchemist)
185
185
 
@@ -1,66 +1,71 @@
1
1
  main.py,sha256=3sAO2QZxxibs4WRT82i2w6KVBBFmYEMNUoGiMYFowOw,126
2
- alchemist_core/__init__.py,sha256=jYIygJyhCXUmX3oAaxw687uLLQcRSuxNRQrMeuWuuuI,2023
2
+ alchemist_core/__init__.py,sha256=ajBg3qjyLqyDwkBxZdf161TrTPhBE6TcQZXb7Wr2fYs,2014
3
3
  alchemist_core/audit_log.py,sha256=s8h3YKBgvcu_tgIrjP69rNr6yOnbks5J2RR_m2bwB4Q,22531
4
4
  alchemist_core/config.py,sha256=Sk5eM1okktO5bUMlMPv9yzF2fpuiyGr9LUtlCWIBDc8,3366
5
5
  alchemist_core/events.py,sha256=ty9nRzfZGHzk6b09dALIwrMY_5PYSv0wMaw94JLDjSk,6717
6
- alchemist_core/session.py,sha256=OraGE2y78s9cbhfpxr4jllfet-GclCfTj0yV1D9S_2M,55330
6
+ alchemist_core/session.py,sha256=nTuRHNIPiwBXvETGgCkLYWgg3Q85z5d84nDdFjdq-NU,199174
7
7
  alchemist_core/acquisition/__init__.py,sha256=3CYGI24OTBS66ETrlGFyHCNpfS6DBMP41MZDhvjFEzg,32
8
8
  alchemist_core/acquisition/base_acquisition.py,sha256=s51vGx0b0Nt91lSCiVwYP9IClugVg2VJ21dn2n_4LIs,483
9
- alchemist_core/acquisition/botorch_acquisition.py,sha256=r2Z510UIrPZCS-uXWZzgtaNhmCUh0CsTrAJQCWdevxA,31401
9
+ alchemist_core/acquisition/botorch_acquisition.py,sha256=lnb3imslnihrRJO66SiIpNvAB6ljo0GY8M_lZ7xOwO4,29176
10
10
  alchemist_core/acquisition/skopt_acquisition.py,sha256=YRdANqgiN3GWd4sn16oruN6jVnI4RLmvLhBMUfYyLp4,13115
11
11
  alchemist_core/data/__init__.py,sha256=wgEb03x0RzVCi0uJXOzEKXkbA2oNHom5EgSB3tKgl1E,256
12
- alchemist_core/data/experiment_manager.py,sha256=LujWfFRlOSP7rok8sxTc6NTjetN7u7RnsOo5W2I5o-w,9013
12
+ alchemist_core/data/experiment_manager.py,sha256=67kSnGq0uvCiMF9B3BZRMQqJBII2fpzkUJqoQhysyBs,16465
13
13
  alchemist_core/data/search_space.py,sha256=oA9YEF3JRWpRklHzSo_Uxlmfy7bHwZfLZFDf4_nl4ew,6230
14
14
  alchemist_core/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  alchemist_core/models/base_model.py,sha256=gIpC2eoTZcp4ozI0Rctcxt_4bLhgaE6ALYCzvuIrMZw,3145
16
- alchemist_core/models/botorch_model.py,sha256=VbZjggt8PszTJeG0x1A1vGGM1kT95Bjset3HWT6PQEM,42263
17
- alchemist_core/models/sklearn_model.py,sha256=XEr2yAQtVQd3beGAoQnuNmt_inzEsKAwpGo-Gfdp2vY,38059
18
- alchemist_core/utils/__init__.py,sha256=oQsvUqukRng8GgiZSPMM-xmB-Lv46XveJzYQr2MdkOc,99
16
+ alchemist_core/models/botorch_model.py,sha256=YPkRjGFqig-ABhOt4L4XSzoIACpWgxzDGz43pqC1tCU,52524
17
+ alchemist_core/models/sklearn_model.py,sha256=k72kiBxYWC6CTjx4FX2yf7Q5CemhxZXqH1l3WwPJNZ4,43498
18
+ alchemist_core/utils/__init__.py,sha256=Lhko6s67xrX1EIAevGs059w2WWMWTA3eLMa2urzbbE8,174
19
+ alchemist_core/utils/acquisition_utils.py,sha256=oG8cegGnFuvlJlcswdxQcI1EKiQgeWFFor4YAkwHgr4,2433
19
20
  alchemist_core/utils/doe.py,sha256=hnrhIzm3Nz0qZBW4PXaNQ6pTDgiLn_lUhbMPmWmk_6Y,7110
20
- alchemist_nrel-0.3.1.dist-info/licenses/LICENSE,sha256=wdIWWEj59ztfQViDuT_9wG3L1K8afUpRSygimXw36wY,1511
21
+ alchemist_core/visualization/__init__.py,sha256=b0PsJOe3K4ErQF6lxsFuLo0mwWeY99nwX2gQ_y-2_-E,1175
22
+ alchemist_core/visualization/helpers.py,sha256=RL0DMbblglFtYP1po79gtS_RfYwschMG75I3N5SdFKU,3796
23
+ alchemist_core/visualization/plots.py,sha256=l9X8R9Jdz_vT7nAiNeA3O3tGA7aWIrL6omG5yb0_4Fo,51929
24
+ alchemist_nrel-0.3.2.dist-info/licenses/LICENSE,sha256=wdIWWEj59ztfQViDuT_9wG3L1K8afUpRSygimXw36wY,1511
21
25
  api/__init__.py,sha256=ODc6pq4OSImgK4xvhX_zMhqUjIc7JvLfqxKF_-Ubw7g,49
22
26
  api/dependencies.py,sha256=sF1YYjnFRaw7nj7Y7URKLF2Ek-EfaXqjOyV1Zbktz2g,1090
23
27
  api/example_client.py,sha256=RjEOvZItzgmGdP6V5j106LQqmQg0WIEr72xf4oMJZHo,6924
24
- api/main.py,sha256=Fee_u_dvNcLzNE-kRhoinfEYnIf5e-i71ZwdNOHu7hY,4301
28
+ api/main.py,sha256=gVIWLv5AZdXxTKC1oOr8cku2SBsGaGDnLUJjZGkvB98,4301
25
29
  api/run_api.py,sha256=YGyLUJNbdsDGEKsd_EsrA1gGheGW53etn8F3ku44q1g,1993
26
30
  api/middleware/__init__.py,sha256=WM4JEg3DibymvEvQ6hx_FJkv8lKLjHD48qNouSORGxA,313
27
31
  api/middleware/error_handlers.py,sha256=k5hNo6W5QDjGRHUY8Le-t7ubWkwSZBFpsTKcEF0nweI,4545
28
32
  api/models/__init__.py,sha256=YFtp8989mH9Zjzvd8W6pXklQJXTf8zWj4I2YWnLegDQ,1204
29
- api/models/requests.py,sha256=SvAL36-WcuaibKkI2hsNPDEpptZHw88_Oj961dD37vE,10853
30
- api/models/responses.py,sha256=58oWYfKcQpUpa3oF_VY-QfNTaLxGu_O1cgBHB-Banjs,13704
33
+ api/models/requests.py,sha256=d8Mt4rUDrXZ7ylUBaaTUGEVPBzW77HksrLY991KkaFw,12789
34
+ api/models/responses.py,sha256=Ce_EFxpzeFev1OfwcxdeuFAx5EGf8cLHh1cpz60DzSk,16654
31
35
  api/routers/__init__.py,sha256=Mhg62NdA6iaPy-L5HLVp_dd9aUHmJ72KtMSRyO2kusA,180
32
36
  api/routers/acquisition.py,sha256=GzncAXsQzhldB-gngpMcUa5choaoAqMqLrpqszRjMFc,6683
33
- api/routers/experiments.py,sha256=h4UI96MwSVL5VmibI-ebdsOl0f332edcifmdNL8OVFg,10329
37
+ api/routers/experiments.py,sha256=uy7aHUKE9E-BKacBssQbVyCix44_gEWTOVLPs9UV-L4,22421
34
38
  api/routers/models.py,sha256=32Ln0MtlnCEjfN3Q6Io_EBwwwGoJXb73UbQEMIcVGjI,3651
35
- api/routers/sessions.py,sha256=3h9veIWxx4F1bP_YgWwOCtuKIDe2e8VcaBCjQxmZT7c,19073
39
+ api/routers/sessions.py,sha256=6pnyi0-63yL7tC8bFdDjOpG6lQXZh-egFvhm6M1OLuE,21724
36
40
  api/routers/variables.py,sha256=TiByX1ITabBDdTSMGAPa1lGd0LBipNgDfmPsbvTEAdE,10108
37
- api/routers/visualizations.py,sha256=QPe1PkgGtzb4Oe4YYgFoi7J1oHJGS5pa1g75KKBDqUM,24180
38
- api/routers/websocket.py,sha256=AnENOTSk8LOZ5XD_5O29srOfdQ8U136Yzw6dwMca9t4,4361
41
+ api/routers/visualizations.py,sha256=sKw_edHHFOuW5tLm_oK_i7Ty1e6AHcqgQtL-qzH1tSw,24365
42
+ api/routers/websocket.py,sha256=pw-HWf7Sd_cVroQO9uF7KDwQFJEyItFluPcqS1Zst0o,4363
39
43
  api/services/__init__.py,sha256=0jw0tkL-8CtChv5ytdXRFeIz1OTVz7Vw1UaaDo86PQs,106
40
- api/services/session_store.py,sha256=BIGJUAiOEQ3uH40wUXuzqd7djy60SE6PQDKVBquJS9Y,18989
44
+ api/services/session_store.py,sha256=vybQYqw2319WFTJd8P7v2-5mdAh4fo8qhZGh0YdDeUo,27888
41
45
  api/static/NEW_ICON.ico,sha256=V4zY86qhPT24SSYK8VL5Ax5AezWxOfvfeHWBXisudOU,247870
42
46
  api/static/NEW_ICON.png,sha256=7UUPRgQ6-Ncv1xvB_57QMfrMY8xxHn16mLHc_zUGmCE,62788
43
47
  api/static/NEW_LOGO_DARK.png,sha256=O4p2tfTBuChSSPRl-Fzue1qoQdLkqXHBofNyiEzRNLs,128146
44
48
  api/static/NEW_LOGO_LIGHT.png,sha256=XBcv5-snGDTpjCrk7UfuJiFbSqrsGRafk7vNBj9eJnM,131686
45
- api/static/index.html,sha256=ttWE08A9TQ0ai63juHHo0SvcPWczYg4ANob2GB4ZQ5Q,499
49
+ api/static/index.html,sha256=xUHF19OS1aLKBWxz177l_mG6nFdAhwJXA4CYUqu5DhA,499
46
50
  api/static/vite.svg,sha256=SnSK_UQ5GLsWWRyDTEAdrjPoeGGrXbrQgRw6O0qSFPs,1497
47
51
  api/static/assets/api-vcoXEqyq.js,sha256=LDSOiSvi1Zc7SRry3ldpA__egc6GAFbzQt9QzBzbTIQ,303
48
- api/static/assets/index-DWfIKU9j.js,sha256=raGrwAEmx2gqVz8E7HlQ8KiqOFPYOQuHpKI4rqYdydw,5745850
49
- api/static/assets/index-sMIa_1hV.css,sha256=1-xNuB1JVE5hK0YzdpYb6ys1dMNJMDgx6IMv712yryI,20007
52
+ api/static/assets/index-B6Cf6s_b.css,sha256=NfVJy21eVUVIacLpJRSBelEVdkotUj8V-T3b0zEv5Qs,24358
53
+ api/static/assets/index-B7njvc9r.js,sha256=WZ5GDnb4fcANEKDpBAcKg44skpdcQwpv98QX-m0pUug,5757510
50
54
  ui/__init__.py,sha256=H4kWlVey7KKf3iPQi74zuM7FSOg5Gh-ii3UwSTuIp8A,1203
51
55
  ui/acquisition_panel.py,sha256=zF-mQDrs-Y7sf2GXYF-bPlO9UXZMTzYRMDN-Wn5FyWw,39647
52
56
  ui/custom_widgets.py,sha256=UXNv4DiTw3tFC0VaN1Qtcf_-9umX34uDn46-cEA6cs0,3812
53
57
  ui/experiment_logger.py,sha256=dP3IGaQ31sURyz7awd_VrZBWaKLH2xXEeRalWZpvVcQ,8366
54
- ui/gpr_panel.py,sha256=rQYCKZr8UlXVL3DVXTq4ArlIodzvDOtZXkYrdotERtw,26465
58
+ ui/gpr_panel.py,sha256=nSz7kWdmXFh7GjgVjFGA1CQulTLLpiiYkx5Jtm1KuUI,26779
55
59
  ui/notifications.py,sha256=hpUDo52_cQd7e8j7lOZikVRu1yLqRwlNR9vYNZdF5VM,35301
56
60
  ui/pool_viz.py,sha256=RwjggEfRSSEe-4nGjxc-I-1e5_aH64DgypT_YoubLIU,8765
57
- ui/ui.py,sha256=Lvg2H0_LrsrxJYFYFHr2LQsnbJWW5Q2fYqk63qVUJv4,101727
61
+ ui/target_column_dialog.py,sha256=We1eHAfkdRtpkMbC_w8v8qIyZVdruNuYy8ciuSKXH8Y,10496
62
+ ui/ui.py,sha256=IM2fFZVKtn25GVxE-BFe1yTxyUM6Zj_Rbl0uXzTbKOw,104512
58
63
  ui/ui_utils.py,sha256=yud2-9LvT4XBcjTyfwUX5tYGNZRlAUVlu2YpcNY1HKA,658
59
64
  ui/utils.py,sha256=m19YFFkEUAY46YSj6S5RBmfUFjIWOk7F8CB4oKDRRZw,1078
60
65
  ui/variables_setup.py,sha256=6hphCy66uLsjIX7FjFtY6-fBfZ6cgfpviXXX9JBhuc4,23618
61
66
  ui/visualizations.py,sha256=FCpuehMi2Cf3Jpuycqoj43oJoCU-QAr8-6Sp6LCO4hE,70371
62
- alchemist_nrel-0.3.1.dist-info/METADATA,sha256=SxYr-5UGvB6fL_O_OvopkBMkM4QsBSWBhi_t88t0nFw,7122
63
- alchemist_nrel-0.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
64
- alchemist_nrel-0.3.1.dist-info/entry_points.txt,sha256=e2QcTxh-pidX_eJlQRk9yE3hLMYA0YnUzSh3sxqvdzY,73
65
- alchemist_nrel-0.3.1.dist-info/top_level.txt,sha256=dwh-oxj7H6oAGYchcUDyfiu9UxxzCn4hUDx1oeM2k-8,27
66
- alchemist_nrel-0.3.1.dist-info/RECORD,,
67
+ alchemist_nrel-0.3.2.dist-info/METADATA,sha256=axydXtcrcxtmqMZfvYlg9pgc4_Dg3U34lh0wCKNNhl8,7248
68
+ alchemist_nrel-0.3.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
69
+ alchemist_nrel-0.3.2.dist-info/entry_points.txt,sha256=e2QcTxh-pidX_eJlQRk9yE3hLMYA0YnUzSh3sxqvdzY,73
70
+ alchemist_nrel-0.3.2.dist-info/top_level.txt,sha256=dwh-oxj7H6oAGYchcUDyfiu9UxxzCn4hUDx1oeM2k-8,27
71
+ alchemist_nrel-0.3.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
api/main.py CHANGED
@@ -32,7 +32,7 @@ logger = logging.getLogger(__name__)
32
32
  app = FastAPI(
33
33
  title="ALchemist API",
34
34
  description="REST API for Bayesian optimization and active learning",
35
- version="0.3.0",
35
+ version="0.3.2",
36
36
  docs_url="/api/docs",
37
37
  redoc_url="/api/redoc",
38
38
  openapi_url="/api/openapi.json"
api/models/requests.py CHANGED
@@ -109,6 +109,58 @@ class AddExperimentRequest(BaseModel):
109
109
  )
110
110
 
111
111
 
112
+ class StageExperimentRequest(BaseModel):
113
+ """Request to stage an experiment for later execution."""
114
+ inputs: Dict[str, Union[float, int, str]] = Field(..., description="Variable values")
115
+ reason: Optional[str] = Field(None, description="Reason for this experiment (e.g., acquisition strategy)")
116
+
117
+ model_config = ConfigDict(
118
+ json_schema_extra={
119
+ "example": {
120
+ "inputs": {"temperature": 375.2, "catalyst": "B"},
121
+ "reason": "qEI"
122
+ }
123
+ }
124
+ )
125
+
126
+
127
+ class StageExperimentsBatchRequest(BaseModel):
128
+ """Request to stage multiple experiments at once."""
129
+ experiments: List[Dict[str, Union[float, int, str]]] = Field(..., description="List of experiment inputs")
130
+ reason: Optional[str] = Field(None, description="Reason for these experiments")
131
+
132
+ model_config = ConfigDict(
133
+ json_schema_extra={
134
+ "example": {
135
+ "experiments": [
136
+ {"temperature": 375.2, "catalyst": "B"},
137
+ {"temperature": 412.8, "catalyst": "A"}
138
+ ],
139
+ "reason": "qEI batch"
140
+ }
141
+ }
142
+ )
143
+
144
+
145
+ class CompleteStagedExperimentsRequest(BaseModel):
146
+ """Request to complete staged experiments with outputs."""
147
+ outputs: List[float] = Field(..., description="Output values for staged experiments (same order)")
148
+ noises: Optional[List[float]] = Field(None, description="Measurement uncertainties (optional)")
149
+ iteration: Optional[int] = Field(None, description="Iteration number (auto-assigned if None)")
150
+ reason: Optional[str] = Field(None, description="Reason (uses staged reason if not provided)")
151
+
152
+ model_config = ConfigDict(
153
+ json_schema_extra={
154
+ "example": {
155
+ "outputs": [0.87, 0.92],
156
+ "noises": [0.02, 0.03],
157
+ "iteration": 5,
158
+ "reason": "qEI"
159
+ }
160
+ }
161
+ )
162
+
163
+
112
164
  class AddExperimentsBatchRequest(BaseModel):
113
165
  """Request to add multiple experiments."""
114
166
  experiments: List[AddExperimentRequest] = Field(..., description="List of experiments")
api/models/responses.py CHANGED
@@ -15,7 +15,7 @@ class SessionCreateResponse(BaseModel):
15
15
  """Response when creating a new session."""
16
16
  session_id: str = Field(..., description="Unique session identifier")
17
17
  created_at: str = Field(..., description="Session creation timestamp")
18
- expires_at: str = Field(..., description="Session expiration timestamp")
18
+ expires_at: Optional[str] = Field(None, description="Legacy field - no longer used (sessions don't expire)")
19
19
 
20
20
  model_config = ConfigDict(
21
21
  json_schema_extra={
@@ -58,7 +58,7 @@ class SessionInfoResponse(BaseModel):
58
58
  session_id: str
59
59
  created_at: str
60
60
  last_accessed: str
61
- expires_at: str
61
+ expires_at: Optional[str] = None # Legacy field - no longer used
62
62
  search_space: Dict[str, Any]
63
63
  data: DataSummary
64
64
  model: Optional[ModelSummary]
@@ -200,6 +200,83 @@ class InitialDesignResponse(BaseModel):
200
200
  )
201
201
 
202
202
 
203
+ # ============================================================
204
+ # Staged Experiments Models
205
+ # ============================================================
206
+
207
+ class StagedExperimentResponse(BaseModel):
208
+ """Response when staging an experiment."""
209
+ message: str = "Experiment staged successfully"
210
+ n_staged: int = Field(..., description="Total number of staged experiments")
211
+ staged_inputs: Dict[str, Any] = Field(..., description="The staged experiment inputs")
212
+
213
+ model_config = ConfigDict(
214
+ json_schema_extra={
215
+ "example": {
216
+ "message": "Experiment staged successfully",
217
+ "n_staged": 3,
218
+ "staged_inputs": {"temperature": 375.2, "catalyst": "B"}
219
+ }
220
+ }
221
+ )
222
+
223
+
224
+ class StagedExperimentsListResponse(BaseModel):
225
+ """Response containing all staged experiments."""
226
+ experiments: List[Dict[str, Any]] = Field(..., description="List of staged experiment inputs (variable values only)")
227
+ n_staged: int = Field(..., description="Number of staged experiments")
228
+ reason: Optional[str] = Field(None, description="Reason/strategy for these staged experiments")
229
+
230
+ model_config = ConfigDict(
231
+ json_schema_extra={
232
+ "example": {
233
+ "experiments": [
234
+ {"temperature": 375.2, "catalyst": "B"},
235
+ {"temperature": 412.8, "catalyst": "A"}
236
+ ],
237
+ "n_staged": 2,
238
+ "reason": "qEI"
239
+ }
240
+ }
241
+ )
242
+
243
+
244
+ class StagedExperimentsClearResponse(BaseModel):
245
+ """Response when clearing staged experiments."""
246
+ message: str = "Staged experiments cleared"
247
+ n_cleared: int = Field(..., description="Number of experiments cleared")
248
+
249
+ model_config = ConfigDict(
250
+ json_schema_extra={
251
+ "example": {
252
+ "message": "Staged experiments cleared",
253
+ "n_cleared": 3
254
+ }
255
+ }
256
+ )
257
+
258
+
259
+ class StagedExperimentsCompletedResponse(BaseModel):
260
+ """Response when completing staged experiments with outputs."""
261
+ message: str = "Staged experiments completed and added to dataset"
262
+ n_added: int = Field(..., description="Number of experiments added")
263
+ n_experiments: int = Field(..., description="Total experiments in dataset")
264
+ model_trained: bool = Field(default=False, description="Whether model was auto-trained")
265
+ training_metrics: Optional[Dict[str, Any]] = Field(None, description="Training metrics if auto-trained")
266
+
267
+ model_config = ConfigDict(
268
+ json_schema_extra={
269
+ "example": {
270
+ "message": "Staged experiments completed and added to dataset",
271
+ "n_added": 2,
272
+ "n_experiments": 15,
273
+ "model_trained": True,
274
+ "training_metrics": {"rmse": 0.05, "r2": 0.92}
275
+ }
276
+ }
277
+ )
278
+
279
+
203
280
  # ============================================================
204
281
  # Model Training Models
205
282
  # ============================================================