Skill Tracer
Skills › Scientific Agent Skills › pylabrobot › protocol-manifest.schema.json

protocol-manifest.schema.json

368 lines · skills/pylabrobot/assets/protocol-manifest.schema.json at 5f2bc03

1{
2 "$schema": "https://json-schema.org/draft/2020-12/schema",
3 "$id": "urn:pylabrobot-skill:protocol-manifest:1.0",
4 "title": "Offline PyLabRobot protocol manifest",
5 "description": "Documentation schema for the dependency-free validator. The bundled Python validator additionally enforces numeric bounds, unique names, well bounds, allowlists, and safety invariants without fetching this URI or any remote reference.",
6 "type": "object",
7 "additionalProperties": false,
8 "required": [
9 "schema_version",
10 "protocol_id",
11 "mode",
12 "units",
13 "deck",
14 "resources",
15 "constraints"
16 ],
17 "properties": {
18 "schema_version": {
19 "const": "1.0"
20 },
21 "protocol_id": {
22 "$ref": "#/$defs/name"
23 },
24 "mode": {
25 "const": "offline"
26 },
27 "units": {
28 "type": "object",
29 "additionalProperties": false,
30 "required": [
31 "volume",
32 "length",
33 "rate",
34 "time"
35 ],
36 "properties": {
37 "volume": {
38 "const": "uL"
39 },
40 "length": {
41 "const": "mm"
42 },
43 "rate": {
44 "const": "uL/s"
45 },
46 "time": {
47 "const": "s"
48 }
49 }
50 },
51 "deck": {
52 "type": "object",
53 "additionalProperties": false,
54 "required": [
55 "name",
56 "size_mm"
57 ],
58 "properties": {
59 "name": {
60 "$ref": "#/$defs/name"
61 },
62 "size_mm": {
63 "$ref": "#/$defs/positive_xyz"
64 }
65 }
66 },
67 "resources": {
68 "type": "array",
69 "minItems": 1,
70 "maxItems": 256,
71 "items": {
72 "oneOf": [
73 {
74 "$ref": "#/$defs/liquid_resource"
75 },
76 {
77 "$ref": "#/$defs/tip_rack"
78 },
79 {
80 "$ref": "#/$defs/waste"
81 }
82 ]
83 }
84 },
85 "constraints": {
86 "type": "object",
87 "additionalProperties": false,
88 "required": [
89 "allowed_liquid_classes",
90 "allowed_tip_types",
91 "channels",
92 "requires_human_confirmation",
93 "max_transfer_uL",
94 "max_rate_uL_s"
95 ],
96 "properties": {
97 "allowed_liquid_classes": {
98 "$ref": "#/$defs/name_list"
99 },
100 "allowed_tip_types": {
101 "$ref": "#/$defs/name_list"
102 },
103 "channels": {
104 "type": "integer",
105 "minimum": 1,
106 "maximum": 96
107 },
108 "requires_human_confirmation": {
109 "const": true
110 },
111 "max_transfer_uL": {
112 "$ref": "#/$defs/positive_volume"
113 },
114 "max_rate_uL_s": {
115 "type": "number",
116 "exclusiveMinimum": 0,
117 "maximum": 10000
118 }
119 }
120 }
121 },
122 "$defs": {
123 "name": {
124 "type": "string",
125 "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$"
126 },
127 "well": {
128 "type": "string",
129 "pattern": "^[A-Z]{1,2}[1-9][0-9]{0,2}$"
130 },
131 "positive_volume": {
132 "type": "number",
133 "exclusiveMinimum": 0,
134 "maximum": 1000000
135 },
136 "name_list": {
137 "type": "array",
138 "minItems": 1,
139 "maxItems": 256,
140 "uniqueItems": true,
141 "items": {
142 "$ref": "#/$defs/name"
143 }
144 },
145 "location_xyz": {
146 "type": "object",
147 "additionalProperties": false,
148 "required": [
149 "x",
150 "y",
151 "z"
152 ],
153 "properties": {
154 "x": {
155 "type": "number",
156 "minimum": 0,
157 "maximum": 5000
158 },
159 "y": {
160 "type": "number",
161 "minimum": 0,
162 "maximum": 5000
163 },
164 "z": {
165 "type": "number",
166 "minimum": 0,
167 "maximum": 5000
168 }
169 }
170 },
171 "positive_xyz": {
172 "type": "object",
173 "additionalProperties": false,
174 "required": [
175 "x",
176 "y",
177 "z"
178 ],
179 "properties": {
180 "x": {
181 "type": "number",
182 "exclusiveMinimum": 0,
183 "maximum": 5000
184 },
185 "y": {
186 "type": "number",
187 "exclusiveMinimum": 0,
188 "maximum": 5000
189 },
190 "z": {
191 "type": "number",
192 "exclusiveMinimum": 0,
193 "maximum": 5000
194 }
195 }
196 },
197 "liquid_grid": {
198 "type": "object",
199 "additionalProperties": false,
200 "required": [
201 "rows",
202 "columns",
203 "well_capacity_uL",
204 "dead_volume_uL",
205 "well_depth_mm"
206 ],
207 "properties": {
208 "rows": {
209 "type": "integer",
210 "minimum": 1,
211 "maximum": 384
212 },
213 "columns": {
214 "type": "integer",
215 "minimum": 1,
216 "maximum": 384
217 },
218 "well_capacity_uL": {
219 "$ref": "#/$defs/positive_volume"
220 },
221 "dead_volume_uL": {
222 "type": "number",
223 "minimum": 0,
224 "maximum": 1000000
225 },
226 "well_depth_mm": {
227 "type": "number",
228 "exclusiveMinimum": 0,
229 "maximum": 5000
230 }
231 }
232 },
233 "tip_grid": {
234 "type": "object",
235 "additionalProperties": false,
236 "required": [
237 "rows",
238 "columns",
239 "tip_capacity_uL"
240 ],
241 "properties": {
242 "rows": {
243 "type": "integer",
244 "minimum": 1,
245 "maximum": 384
246 },
247 "columns": {
248 "type": "integer",
249 "minimum": 1,
250 "maximum": 384
251 },
252 "tip_capacity_uL": {
253 "$ref": "#/$defs/positive_volume"
254 }
255 }
256 },
257 "liquid_resource": {
258 "type": "object",
259 "additionalProperties": false,
260 "required": [
261 "name",
262 "kind",
263 "location_mm",
264 "size_mm",
265 "grid",
266 "initial_volumes_uL"
267 ],
268 "properties": {
269 "name": {
270 "$ref": "#/$defs/name"
271 },
272 "kind": {
273 "enum": [
274 "plate",
275 "reservoir",
276 "tube_rack"
277 ]
278 },
279 "location_mm": {
280 "$ref": "#/$defs/location_xyz"
281 },
282 "size_mm": {
283 "$ref": "#/$defs/positive_xyz"
284 },
285 "grid": {
286 "$ref": "#/$defs/liquid_grid"
287 },
288 "initial_volumes_uL": {
289 "type": "object",
290 "propertyNames": {
291 "$ref": "#/$defs/well"
292 },
293 "additionalProperties": {
294 "type": "number",
295 "minimum": 0,
296 "maximum": 1000000
297 },
298 "description": "Declared initial volumes, including explicit zero for every empty destination. The planner rejects any source or destination well absent from this map."
299 }
300 }
301 },
302 "tip_rack": {
303 "type": "object",
304 "additionalProperties": false,
305 "required": [
306 "name",
307 "kind",
308 "location_mm",
309 "size_mm",
310 "grid",
311 "tip_type",
312 "tips_available"
313 ],
314 "properties": {
315 "name": {
316 "$ref": "#/$defs/name"
317 },
318 "kind": {
319 "const": "tip_rack"
320 },
321 "location_mm": {
322 "$ref": "#/$defs/location_xyz"
323 },
324 "size_mm": {
325 "$ref": "#/$defs/positive_xyz"
326 },
327 "grid": {
328 "$ref": "#/$defs/tip_grid"
329 },
330 "tip_type": {
331 "$ref": "#/$defs/name"
332 },
333 "tips_available": {
334 "type": "array",
335 "minItems": 1,
336 "uniqueItems": true,
337 "items": {
338 "$ref": "#/$defs/well"
339 }
340 }
341 }
342 },
343 "waste": {
344 "type": "object",
345 "additionalProperties": false,
346 "required": [
347 "name",
348 "kind",
349 "location_mm",
350 "size_mm"
351 ],
352 "properties": {
353 "name": {
354 "$ref": "#/$defs/name"
355 },
356 "kind": {
357 "const": "waste"
358 },
359 "location_mm": {
360 "$ref": "#/$defs/location_xyz"
361 },
362 "size_mm": {
363 "$ref": "#/$defs/positive_xyz"
364 }
365 }
366 }
367 }