14 KiB
Peptide Four-Checkbox Reset Plan
Date: 2026-05-21 16:30 Status: Proposal only / not executed
Scope
This plan replaces 2026-05-21_1556_peptide_reset_sirna_reference_plan.md for Peptide reset work.
User direction captured here:
take_outis unnecessary for Peptide reset.- Do not add a material-cache refresh checkbox.
- Change reset to four checkbox-controlled operations:
- 调度器复位
- 订单状态复位
- 库位复位
- 仪器复位
- The first three checkboxes default to checked.
- The fourth checkbox, 仪器复位 /
reset_devices, defaults to unchecked. - Replace the current public
resetaction with:reset_auto: normal ILab action node. This is the renamed/replaced version of the current reset implementation.reset_manual: manual-confirm action node with a physical cleanup confirmation message.
Evidence Summary
Current Peptide source:
- Reset action code is currently in
unilabos/devices/workstation/bioyond_studio/peptide_station/peptide_station.py. - Current Peptide reset selects
scheduler_reset,reset_order_status, andreset_location, and passes ids to order/location resets. BioyondV1RPC.reset_devices()already calls/api/lims/device/reset-deviceswith onlyapiKeyandrequestTime.BioyondV1RPC.scheduler_reset()already calls/api/lims/scheduler/resetwith onlyapiKeyandrequestTime.BioyondV1RPC.reset_order_status(order_id)andreset_location(location_id)currently senddata, but live probes showed that omitteddatasucceeds.
Live Peptide no-data reset probes using temp_benyao/peptide/peptide_station_config.example.json:
POST /api/lims/order/reset-order-statuswith request keys["apiKey", "requestTime"]returned HTTP 200 andcode=1.POST /api/lims/scheduler/resetwith request keys["apiKey", "requestTime"]returned HTTP 200 andcode=1.POST /api/lims/storage/reset-locationwith request keys["apiKey", "requestTime"]returned HTTP 200 andcode=1.reset-deviceswas not live-probed in this session, but the current RPC wrapper already sends nodata.
Raw findings:
temp_benyao/peptide/_findings/2026-05-21_1613_reset_order_status_no_data_live.mdtemp_benyao/peptide/_findings/2026-05-21_1615_remaining_resets_no_data_live.md
Proposed Public Actions
reset_auto
Normal action node. This is the auto/no-manual-confirm path. It replaces the current public reset action; do not leave a second public reset action unless a later compatibility request explicitly asks for an alias.
Checkbox schema rule:
- Use plain
boolannotations in the action signature. - Do not use
Annotated[bool, Field(...)]for these checkbox params in this implementation plan. - The current AST registry schema path does not unwrap
Annotated[...]; plainboolis required so generated JSON Schema marks the fields as boolean and the renderer can show checkboxes. - Put human-facing labels/descriptions in the method docstring or action description. If field-level
Field(description=...)metadata is required later, add registryAnnotatedsupport and a schema test as a separate change.
Decorator shape:
@action(
always_free=True,
goal_default={
"reset_scheduler": True,
"reset_order_status": True,
"reset_location": True,
"reset_devices": False,
},
description="自动复位调度器/订单状态/库位,可选仪器复位",
)
def reset_auto(
self,
reset_scheduler: bool = True,
reset_order_status: bool = True,
reset_location: bool = True,
reset_devices: bool = False,
**kwargs: Any,
) -> Dict[str, Any]:
"""自动复位调度器/订单状态/库位,可选仪器复位。
Args:
reset_scheduler[调度器复位]: 调用 /api/lims/scheduler/reset,默认勾选。
reset_order_status[订单状态复位]: 调用 /api/lims/order/reset-order-status,默认勾选。
reset_location[库位复位]: 调用 /api/lims/storage/reset-location,默认勾选。
reset_devices[仪器复位]: 调用 /api/lims/device/reset-devices,默认不勾选。
"""
...
Implementation notes:
- Use real plain-
boolparameters, not hidden**kwargsand notAnnotated, so the action renderer can expose four checkboxes. - Rename/replace the existing
resetaction asreset_auto; the implementation should not keep the old id-shapedresetaction as another public path by default. - Keep the three routine reset defaults checked.
- Keep
reset_devicesunchecked because it can be broader and more disruptive. - Do not require or resolve order ids or location ids.
- Do not call
take_out. - Do not call
refresh_material_cache.
reset_manual
Manual-confirm node. It should show the operator a physical cleanup warning, then execute the same reset helper as reset_auto after the operator confirms.
Actual manual-confirm decorator pattern in this repo:
- Use
@action(node_type=NodeType.MANUAL_CONFIRM). - Set
always_free=True. - Add
placeholder_keys={"assignee_user_ids": "unilabos_manual_confirm"}. - Include
timeout_seconds: intandassignee_user_ids: list[str]. - Add
goal_defaultfortimeout_secondsandassignee_user_ids. - Manual-confirm actions are normally side-effect-light, but existing Peptide
start_experimentis already aMANUAL_CONFIRMaction that performs scheduler start after the operator gate, so a reset-after-confirm pattern is compatible with current Peptide style.
Proposed confirmation text:
请确认G3、CEM、Tecan、撕膜机、封膜机、打标机、旋转堆栈上下料位、3个转台等位置的物料已清理完毕;
请开门检查冰箱、IDOT、酶标仪、离心机、LCMS内部没有遗留物料。
Decorator/function shape:
RESET_MANUAL_CONFIRM_MESSAGE = (
"请确认G3、CEM、Tecan、撕膜机、封膜机、打标机、旋转堆栈上下料位、3个转台等位置的物料已清理完毕;\n"
"请开门检查冰箱、IDOT、酶标仪、离心机、LCMS内部没有遗留物料。"
)
@action(
always_free=True,
node_type=NodeType.MANUAL_CONFIRM,
placeholder_keys={"assignee_user_ids": "unilabos_manual_confirm"},
goal_default={
"reset_scheduler": True,
"reset_order_status": True,
"reset_location": True,
"reset_devices": False,
"physical_cleanup_confirmed": False,
"timeout_seconds": 3600,
"assignee_user_ids": [],
},
feedback_interval=300,
description=RESET_MANUAL_CONFIRM_MESSAGE,
)
def reset_manual(
self,
reset_scheduler: bool = True,
reset_order_status: bool = True,
reset_location: bool = True,
reset_devices: bool = False,
physical_cleanup_confirmed: bool = False,
timeout_seconds: int = 3600,
assignee_user_ids: Optional[List[str]] = None,
**kwargs: Any,
) -> Dict[str, Any]:
"""人工确认物理清理后执行复位。
Args:
reset_scheduler[调度器复位]: 调用 /api/lims/scheduler/reset,默认勾选。
reset_order_status[订单状态复位]: 调用 /api/lims/order/reset-order-status,默认勾选。
reset_location[库位复位]: 调用 /api/lims/storage/reset-location,默认勾选。
reset_devices[仪器复位]: 调用 /api/lims/device/reset-devices,默认不勾选。
physical_cleanup_confirmed[物理清理确认]: 确认清理提示中的物料检查已经完成,默认不勾选。
"""
...
Execution rule:
- If
physical_cleanup_confirmedis false, return a blocked result and do not call any reset API. - If it is true, call the same internal helper as
reset_auto. - Return
confirmation_messagein the result payload so call logs preserve the exact operator instruction text.
Renderer caveat:
descriptionshould carry the warning in generated action metadata.physical_cleanup_confirmedmust remain a plainboolso it renders as a checkbox.- The cleanup warning should be carried by the action
descriptionand the docstring param description. Do not rely onField(description=...)unless registryAnnotatedsupport has been implemented and tested. - If the current frontend does not show action descriptions or docstring field descriptions reliably, add a read-only string parameter such as
confirmation_message: str = RESET_MANUAL_CONFIRM_MESSAGEwithgoal_default, or use a handle-based display only after renderer behavior is verified.
Shared Internal Helper
Both public actions should delegate to one helper, for example:
def _execute_reset_operations(
self,
*,
reset_scheduler: bool,
reset_order_status: bool,
reset_location: bool,
reset_devices: bool,
) -> Dict[str, Any]:
...
Call order:
scheduler_resetreset_order_statusreset_locationreset_devices
Result shape:
{
"selected_operations": [
{"key": "reset_scheduler", "label": "调度器复位", "selected": True},
{"key": "reset_order_status", "label": "订单状态复位", "selected": True},
{"key": "reset_location", "label": "库位复位", "selected": True},
{"key": "reset_devices", "label": "仪器复位", "selected": False},
],
"executed_calls": [
{"operation": "scheduler_reset", "endpoint": "/api/lims/scheduler/reset", "result": {"code": 1}},
],
"skipped_operations": [
{"operation": "reset_devices", "reason": "checkbox_disabled"},
],
"warnings": [],
}
Failure handling:
- Execute selected operations sequentially and record each result.
- If an operation returns non-
1code, add a warning and continue unless the caller later requests fail-fast. - If an RPC method raises, catch it, record an error entry, and continue to the next selected operation unless fail-fast is introduced.
RPC Wrapper Adjustment
Adjust the two id-shaped wrappers to no-data calls:
BioyondV1RPC.reset_order_status()should no longer requireorder_id.BioyondV1RPC.reset_location()should no longer requirelocation_id.
Current no-data wrappers already exist:
scheduler_reset()reset_devices()
Suggested RPC signatures:
def scheduler_reset(self) -> int: ...
def reset_order_status(self) -> int: ...
def reset_location(self) -> int: ...
def reset_devices(self) -> int: ...
Compatibility option:
def reset_order_status(self, order_id: Optional[str] = None) -> int:
del order_id
...
def reset_location(self, location_id: Optional[str] = None) -> int:
del location_id
...
This keeps older code from crashing while making the actual wire request no-data.
Adjusted Runtime API Schemas
These are the schemas Peptide reset code should target at runtime after the live no-data probes. They intentionally omit data, even though OpenAPI models nullable data for these endpoints.
All four requests use:
{
"apiKey": "string",
"requestTime": "date-time"
}
No data field should be sent by default.
All four responses use:
{
"code": 1,
"message": "",
"timestamp": 0
}
调度器复位
Endpoint:
POST /api/lims/scheduler/reset
Adjusted request:
{
"apiKey": "B10B5995",
"requestTime": "2026-05-21T08:15:16.494Z"
}
Live response:
{
"code": 1,
"message": "",
"timestamp": 1779351316072
}
Notes:
- OpenAPI says
datais nullable int32. - Live Peptide accepted omitted
data.
订单状态复位
Endpoint:
POST /api/lims/order/reset-order-status
Adjusted request:
{
"apiKey": "B10B5995",
"requestTime": "2026-05-21T08:13:34.750Z"
}
Live response:
{
"code": 1,
"message": "",
"timestamp": 1779351214422
}
Notes:
- OpenAPI says
datais nullable string. - Live Peptide accepted omitted
data. - Do not model this as order-id scoped unless Bioyond confirms backend behavior.
库位复位
Endpoint:
POST /api/lims/storage/reset-location
Adjusted request:
{
"apiKey": "B10B5995",
"requestTime": "2026-05-21T08:15:18.924Z"
}
Live response:
{
"code": 1,
"message": "",
"timestamp": 1779351318565
}
Notes:
- OpenAPI says
datais nullable string. - Live Peptide accepted omitted
data. - Do not model this as location-id scoped unless Bioyond confirms backend behavior.
仪器复位
Endpoint:
POST /api/lims/device/reset-devices
Adjusted request:
{
"apiKey": "B10B5995",
"requestTime": "date-time"
}
Expected response shape:
{
"code": 1,
"message": "",
"timestamp": 0
}
Notes:
- OpenAPI says
datais nullable string. - Current
BioyondV1RPC.reset_devices()already sends nodata. - This endpoint was not live-probed in the no-data reset session.
- Keep checkbox default unchecked.
Tests To Add Before Implementation
reset_autois notNodeType.MANUAL_CONFIRM.reset_manualhasnode_type=NodeType.MANUAL_CONFIRM.reset_manualmetadata includes:always_free=Trueplaceholder_keys={"assignee_user_ids": "unilabos_manual_confirm"}timeout_seconds=3600assignee_user_ids=[]physical_cleanup_confirmed=False
- Both reset actions expose four real boolean params:
reset_schedulerreset_order_statusreset_locationreset_devices
- The generated registry schema marks those reset params as JSON Schema
type: boolean, notobjectorstring, so the frontend can render checkboxes. reset_autoreplaces the current publicresetaction. Unless a later compatibility request adds an alias, no old id-shaped publicresetaction remains.- Goal defaults are:
- first three reset checkboxes
True reset_devices=False
- first three reset checkboxes
reset_manual(..., physical_cleanup_confirmed=False)does not call any RPC reset method.reset_auto()with defaults calls:scheduler_reset()reset_order_status()reset_location()- not
reset_devices()
reset_auto(reset_devices=True)also callsreset_devices().reset_order_status()andreset_location()RPC wrappers send nodatakey.- No reset path calls
take_out. - No reset path calls
refresh_material_cache.
Non-Goals
- Do not implement
take_outin reset. - Do not refresh
material_cachefrom reset. - Do not resolve order ids or location ids for reset.
- Do not add Project/cache/browser cleanup routes.
- Do not make
reset_devicesdefault-on. - Do not execute this plan during planning.