Add result schema and add TypedDict conversion.

(cherry picked from commit 8fa3407649)
This commit is contained in:
Xuwznln
2025-11-25 15:16:27 +08:00
parent 5d0807cba6
commit 343e87df0d
10 changed files with 879 additions and 94 deletions

View File

@@ -83,6 +83,96 @@ workstation.bioyond_dispensing_station:
title: batch_create_diamine_solution_tasks参数
type: object
type: UniLabJsonCommand
auto-brief_step_parameters:
feedback: {}
goal: {}
goal_default:
data: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
data:
type: object
required:
- data
type: object
result: {}
required:
- goal
title: brief_step_parameters参数
type: object
type: UniLabJsonCommand
auto-compute_experiment_design:
feedback: {}
goal: {}
goal_default:
m_tot: '70'
ratio: null
titration_percent: '0.03'
wt_percent: '0.25'
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
m_tot:
default: '70'
type: string
ratio:
type: object
titration_percent:
default: '0.03'
type: string
wt_percent:
default: '0.25'
type: string
required:
- ratio
type: object
result:
properties:
feeding_order:
items: {}
title: Feeding Order
type: array
return_info:
title: Return Info
type: string
solutions:
items: {}
title: Solutions
type: array
solvents:
additionalProperties: true
title: Solvents
type: object
titration:
additionalProperties: true
title: Titration
type: object
required:
- solutions
- titration
- solvents
- feeding_order
- return_info
title: ComputeExperimentDesignReturn
type: object
required:
- goal
title: compute_experiment_design参数
type: object
type: UniLabJsonCommand
auto-process_order_finish_report:
feedback: {}
goal: {}
@@ -112,6 +202,85 @@ workstation.bioyond_dispensing_station:
title: process_order_finish_report参数
type: object
type: UniLabJsonCommand
auto-project_order_report:
feedback: {}
goal: {}
goal_default:
order_id: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
order_id:
type: string
required:
- order_id
type: object
result: {}
required:
- goal
title: project_order_report参数
type: object
type: UniLabJsonCommand
auto-query_resource_by_name:
feedback: {}
goal: {}
goal_default:
material_name: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
material_name:
type: string
required:
- material_name
type: object
result: {}
required:
- goal
title: query_resource_by_name参数
type: object
type: UniLabJsonCommand
auto-transfer_materials_to_reaction_station:
feedback: {}
goal: {}
goal_default:
target_device_id: null
transfer_groups: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
target_device_id:
type: string
transfer_groups:
type: array
required:
- target_device_id
- transfer_groups
type: object
result: {}
required:
- goal
title: transfer_materials_to_reaction_station参数
type: object
type: UniLabJsonCommand
auto-wait_for_multiple_orders_and_get_reports:
feedback: {}
goal: {}
@@ -144,6 +313,31 @@ workstation.bioyond_dispensing_station:
title: wait_for_multiple_orders_and_get_reports参数
type: object
type: UniLabJsonCommand
auto-workflow_sample_locations:
feedback: {}
goal: {}
goal_default:
workflow_id: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
workflow_id:
type: string
required:
- workflow_id
type: object
result: {}
required:
- goal
title: workflow_sample_locations参数
type: object
type: UniLabJsonCommand
create_90_10_vial_feeding_task:
feedback: {}
goal:

View File

@@ -5,6 +5,96 @@ bioyond_dispensing_station:
- bioyond_dispensing_station
class:
action_value_mappings:
auto-brief_step_parameters:
feedback: {}
goal: {}
goal_default:
data: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
data:
type: object
required:
- data
type: object
result: {}
required:
- goal
title: brief_step_parameters参数
type: object
type: UniLabJsonCommand
auto-compute_experiment_design:
feedback: {}
goal: {}
goal_default:
m_tot: '70'
ratio: null
titration_percent: '0.03'
wt_percent: '0.25'
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
m_tot:
default: '70'
type: string
ratio:
type: object
titration_percent:
default: '0.03'
type: string
wt_percent:
default: '0.25'
type: string
required:
- ratio
type: object
result:
properties:
feeding_order:
items: {}
title: Feeding Order
type: array
return_info:
title: Return Info
type: string
solutions:
items: {}
title: Solutions
type: array
solvents:
additionalProperties: true
title: Solvents
type: object
titration:
additionalProperties: true
title: Titration
type: object
required:
- solutions
- titration
- solvents
- feeding_order
- return_info
title: ComputeExperimentDesignReturn
type: object
required:
- goal
title: compute_experiment_design参数
type: object
type: UniLabJsonCommand
auto-process_order_finish_report:
feedback: {}
goal: {}
@@ -34,6 +124,110 @@ bioyond_dispensing_station:
title: process_order_finish_report参数
type: object
type: UniLabJsonCommand
auto-project_order_report:
feedback: {}
goal: {}
goal_default:
order_id: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
order_id:
type: string
required:
- order_id
type: object
result: {}
required:
- goal
title: project_order_report参数
type: object
type: UniLabJsonCommand
auto-query_resource_by_name:
feedback: {}
goal: {}
goal_default:
material_name: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
material_name:
type: string
required:
- material_name
type: object
result: {}
required:
- goal
title: query_resource_by_name参数
type: object
type: UniLabJsonCommand
auto-transfer_materials_to_reaction_station:
feedback: {}
goal: {}
goal_default:
target_device_id: null
transfer_groups: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
target_device_id:
type: string
transfer_groups:
type: array
required:
- target_device_id
- transfer_groups
type: object
result: {}
required:
- goal
title: transfer_materials_to_reaction_station参数
type: object
type: UniLabJsonCommand
auto-workflow_sample_locations:
feedback: {}
goal: {}
goal_default:
workflow_id: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
workflow_id:
type: string
required:
- workflow_id
type: object
result: {}
required:
- goal
title: workflow_sample_locations参数
type: object
type: UniLabJsonCommand
batch_create_90_10_vial_feeding_tasks:
feedback: {}
goal:

View File

@@ -61,6 +61,9 @@ camera:
device_id:
default: video_publisher
type: string
device_uuid:
default: ''
type: string
period:
default: 0.1
type: number

View File

@@ -4497,9 +4497,6 @@ liquid_handler:
simulator:
default: false
type: boolean
total_height:
default: 310
type: number
required:
- backend
- deck

View File

@@ -4,6 +4,215 @@ reaction_station.bioyond:
- reaction_station_bioyond
class:
action_value_mappings:
auto-create_order:
feedback: {}
goal: {}
goal_default:
json_str: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
json_str:
type: string
required:
- json_str
type: object
result: {}
required:
- goal
title: create_order参数
type: object
type: UniLabJsonCommand
auto-hard_delete_merged_workflows:
feedback: {}
goal: {}
goal_default:
workflow_ids: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
workflow_ids:
items:
type: string
type: array
required:
- workflow_ids
type: object
result: {}
required:
- goal
title: hard_delete_merged_workflows参数
type: object
type: UniLabJsonCommand
auto-merge_workflow_with_parameters:
feedback: {}
goal: {}
goal_default:
json_str: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
json_str:
type: string
required:
- json_str
type: object
result: {}
required:
- goal
title: merge_workflow_with_parameters参数
type: object
type: UniLabJsonCommand
auto-process_temperature_cutoff_report:
feedback: {}
goal: {}
goal_default:
report_request: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
report_request:
type: string
required:
- report_request
type: object
result: {}
required:
- goal
title: process_temperature_cutoff_report参数
type: object
type: UniLabJsonCommand
auto-process_web_workflows:
feedback: {}
goal: {}
goal_default:
web_workflow_json: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
web_workflow_json:
type: string
required:
- web_workflow_json
type: object
result: {}
required:
- goal
title: process_web_workflows参数
type: object
type: UniLabJsonCommand
auto-skip_titration_steps:
feedback: {}
goal: {}
goal_default:
preintake_id: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
preintake_id:
type: string
required:
- preintake_id
type: object
result: {}
required:
- goal
title: skip_titration_steps参数
type: object
type: UniLabJsonCommand
auto-wait_for_multiple_orders_and_get_reports:
feedback: {}
goal: {}
goal_default:
batch_create_result: null
check_interval: 10
timeout: 7200
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
batch_create_result:
type: string
check_interval:
default: 10
type: integer
timeout:
default: 7200
type: integer
required: []
type: object
result: {}
required:
- goal
title: wait_for_multiple_orders_and_get_reports参数
type: object
type: UniLabJsonCommand
auto-workflow_step_query:
feedback: {}
goal: {}
goal_default:
workflow_id: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
workflow_id:
type: string
required:
- workflow_id
type: object
result: {}
required:
- goal
title: workflow_step_query参数
type: object
type: UniLabJsonCommand
drip_back:
feedback: {}
goal:
@@ -524,19 +733,7 @@ reaction_station.bioyond:
module: unilabos.devices.workstation.bioyond_studio.reaction_station:BioyondReactionStation
protocol_type: []
status_types:
all_workflows: dict
average_viscosity: float
bioyond_status: dict
force: float
in_temperature: float
out_temperature: float
pt100_temperature: float
sensor_average_temperature: float
setting_temperature: float
speed: float
target_temperature: float
viscosity: float
workstation_status: dict
workflow_sequence: String
type: python
config_info: []
description: Bioyond反应站
@@ -548,21 +745,19 @@ reaction_station.bioyond:
config:
type: object
deck:
type: object
type: string
protocol_type:
type: string
required: []
type: object
data:
properties:
all_workflows:
type: object
bioyond_status:
type: object
workstation_status:
type: object
workflow_sequence:
items:
type: string
type: array
required:
- bioyond_status
- all_workflows
- workstation_status
- workflow_sequence
type: object
version: 1.0.0
reaction_station.reactor:
@@ -570,19 +765,34 @@ reaction_station.reactor:
- reactor
- reaction_station_bioyond
class:
action_value_mappings: {}
action_value_mappings:
auto-update_metrics:
feedback: {}
goal: {}
goal_default:
payload: null
handles: {}
placeholder_keys: {}
result: {}
schema:
description: ''
properties:
feedback: {}
goal:
properties:
payload:
type: object
required:
- payload
type: object
result: {}
required:
- goal
title: update_metrics参数
type: object
type: UniLabJsonCommand
module: unilabos.devices.workstation.bioyond_studio.reaction_station:BioyondReactor
status_types:
average_viscosity: float
force: float
in_temperature: float
out_temperature: float
pt100_temperature: float
sensor_average_temperature: float
setting_temperature: float
speed: float
target_temperature: float
viscosity: float
status_types: {}
type: python
config_info: []
description: 反应站子设备-反应器
@@ -593,30 +803,14 @@ reaction_station.reactor:
properties:
config:
type: object
deck:
type: string
protocol_type:
type: string
required: []
type: object
data:
properties:
average_viscosity:
type: number
force:
type: number
in_temperature:
type: number
out_temperature:
type: number
pt100_temperature:
type: number
sensor_average_temperature:
type: number
setting_temperature:
type: number
speed:
type: number
target_temperature:
type: number
viscosity:
type: number
properties: {}
required: []
type: object
version: 1.0.0

View File

@@ -453,7 +453,7 @@ class Registry:
return status_schema
def _generate_unilab_json_command_schema(
self, method_args: List[Dict[str, Any]], method_name: str
self, method_args: List[Dict[str, Any]], method_name: str, return_annotation: Any = None
) -> Dict[str, Any]:
"""
根据UniLabJsonCommand方法信息生成JSON Schema暂不支持嵌套类型
@@ -461,6 +461,7 @@ class Registry:
Args:
method_args: 方法信息字典包含args等
method_name: 方法名称
return_annotation: 返回类型注解用于生成result schema仅支持TypedDict
Returns:
JSON Schema格式的参数schema
@@ -489,14 +490,68 @@ class Registry:
if param_required:
schema["required"].append(param_name)
# 生成result schema仅当return_annotation是TypedDict时
result_schema = {}
if return_annotation is not None and self._is_typed_dict(return_annotation):
result_schema = self._generate_typed_dict_result_schema(return_annotation)
return {
"title": f"{method_name}参数",
"description": f"",
"type": "object",
"properties": {"goal": schema, "feedback": {}, "result": {}},
"properties": {"goal": schema, "feedback": {}, "result": result_schema},
"required": ["goal"],
}
def _is_typed_dict(self, annotation: Any) -> bool:
"""
检查类型注解是否是TypedDict
Args:
annotation: 类型注解对象
Returns:
是否为TypedDict
"""
if annotation is None or annotation == inspect.Parameter.empty:
return False
# 使用 typing_extensions.is_typeddict 进行检查Python < 3.12 兼容)
try:
from typing_extensions import is_typeddict
return is_typeddict(annotation)
except ImportError:
# 回退方案:检查 TypedDict 特有的属性
if isinstance(annotation, type):
return hasattr(annotation, "__required_keys__") and hasattr(annotation, "__optional_keys__")
return False
def _generate_typed_dict_result_schema(self, return_annotation: Any) -> Dict[str, Any]:
"""
根据TypedDict类型生成result的JSON Schema
Args:
return_annotation: TypedDict类型注解
Returns:
JSON Schema格式的result schema
"""
if not self._is_typed_dict(return_annotation):
return {}
try:
from msgcenterpy.instances.typed_dict_instance import TypedDictMessageInstance
result_schema = TypedDictMessageInstance.get_json_schema_from_typed_dict(return_annotation)
return result_schema
except ImportError:
logger.warning("[UniLab Registry] msgcenterpy未安装无法生成TypedDict的result schema")
return {}
except Exception as e:
logger.warning(f"[UniLab Registry] 生成TypedDict result schema失败: {e}")
return {}
def _add_builtin_actions(self, device_config: Dict[str, Any], device_id: str):
"""
为设备配置添加内置的执行驱动命令动作
@@ -577,9 +632,15 @@ class Registry:
if "init_param_schema" not in device_config:
device_config["init_param_schema"] = {}
if "class" in device_config:
if "status_types" not in device_config["class"] or device_config["class"]["status_types"] is None:
if (
"status_types" not in device_config["class"]
or device_config["class"]["status_types"] is None
):
device_config["class"]["status_types"] = {}
if "action_value_mappings" not in device_config["class"] or device_config["class"]["action_value_mappings"] is None:
if (
"action_value_mappings" not in device_config["class"]
or device_config["class"]["action_value_mappings"] is None
):
device_config["class"]["action_value_mappings"] = {}
enhanced_info = {}
if complete_registry:
@@ -631,7 +692,9 @@ class Registry:
"goal": {},
"feedback": {},
"result": {},
"schema": self._generate_unilab_json_command_schema(v["args"], k),
"schema": self._generate_unilab_json_command_schema(
v["args"], k, v.get("return_annotation")
),
"goal_default": {i["name"]: i["default"] for i in v["args"]},
"handles": [],
"placeholder_keys": {