mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-06-11 18:50:59 +08:00
feat(workflow): implement action contract management for inputs and outputs
This commit is contained in:
@@ -555,13 +555,28 @@ class WorkflowExecutor:
|
||||
根据动作输入声明读取上游节点输出。
|
||||
"""
|
||||
inputs = {}
|
||||
input_paths = action.inputs or self.get_action_data_value(action, "inputs") or []
|
||||
input_paths = action.inputs or self.get_action_data_value(action, "inputs")
|
||||
if not input_paths:
|
||||
input_paths = [
|
||||
field["name"] for field in self.get_action_contract(action).get("inputs") or []
|
||||
]
|
||||
if isinstance(input_paths, str):
|
||||
input_paths = [item.strip() for item in input_paths.splitlines() if item.strip()]
|
||||
for input_path in input_paths:
|
||||
inputs[input_path] = self.resolve_context_path(input_path)
|
||||
inputs[input_path] = self.resolve_action_input(input_path)
|
||||
return inputs
|
||||
|
||||
def resolve_action_input(self, input_path: str) -> Any:
|
||||
"""
|
||||
解析动作输入声明。
|
||||
"""
|
||||
if input_path in ActionContext.model_fields:
|
||||
value = getattr(self.context, input_path, None)
|
||||
if value not in (None, "", [], {}):
|
||||
return value
|
||||
return self.context.artifacts.get(input_path) if self.context.artifacts else value
|
||||
return self.resolve_context_path(input_path)
|
||||
|
||||
def build_action_runtime(self, action: Action) -> dict:
|
||||
"""
|
||||
构建传递给动作的新运行期数据。
|
||||
@@ -588,9 +603,14 @@ class WorkflowExecutor:
|
||||
根据动作输出声明整理当前节点输出。
|
||||
"""
|
||||
outputs = action_result.outputs or self.extract_context_outputs(result_context)
|
||||
declared_outputs = action.outputs or self.get_action_data_value(action, "outputs")
|
||||
declared_outputs = self.get_action_output_declarations(action)
|
||||
if isinstance(declared_outputs, list):
|
||||
return {key: outputs.get(key) for key in declared_outputs if outputs.get(key) not in (None, "", [], {})}
|
||||
normalized_outputs = {}
|
||||
for item in declared_outputs:
|
||||
key = item.get("name") if isinstance(item, dict) else item
|
||||
if key and outputs.get(key) not in (None, "", [], {}):
|
||||
normalized_outputs[key] = outputs.get(key)
|
||||
return normalized_outputs or outputs
|
||||
if isinstance(declared_outputs, dict):
|
||||
return {
|
||||
key: outputs.get(key)
|
||||
@@ -648,12 +668,28 @@ class WorkflowExecutor:
|
||||
"""
|
||||
获取动作输出声明配置。
|
||||
"""
|
||||
outputs_config = action.outputs or self.get_action_data_value(action, "outputs") or {}
|
||||
outputs_config = self.get_action_output_declarations(action)
|
||||
if isinstance(outputs_config, dict):
|
||||
value = outputs_config.get(output_key) or {}
|
||||
return value if isinstance(value, dict) else {}
|
||||
if isinstance(outputs_config, list):
|
||||
for item in outputs_config:
|
||||
if isinstance(item, dict) and item.get("name") == output_key:
|
||||
return {
|
||||
key: value for key, value in item.items()
|
||||
if key not in ("name", "label", "kind") and value not in (None, "", [], {})
|
||||
}
|
||||
return {}
|
||||
|
||||
def get_action_output_declarations(self, action: Action) -> Any:
|
||||
"""
|
||||
获取动作输出声明,优先使用节点显式配置,其次使用动作固定契约。
|
||||
"""
|
||||
outputs_config = action.outputs or self.get_action_data_value(action, "outputs")
|
||||
if outputs_config:
|
||||
return outputs_config
|
||||
return self.get_action_contract(action).get("outputs") or {}
|
||||
|
||||
def get_default_merge_policy(self, action: Action, key: str, value: Any) -> str:
|
||||
"""
|
||||
获取输出默认合并策略。
|
||||
@@ -796,7 +832,20 @@ class WorkflowExecutor:
|
||||
"""
|
||||
获取动作并发互斥键。
|
||||
"""
|
||||
return action.concurrency_key or self.get_action_data_value(action, "concurrency_key")
|
||||
return (
|
||||
action.concurrency_key
|
||||
or self.get_action_data_value(action, "concurrency_key")
|
||||
or self.get_action_contract(action).get("concurrency_key")
|
||||
)
|
||||
|
||||
def get_action_contract(self, action: Action) -> dict:
|
||||
"""
|
||||
获取动作固定输入输出契约。
|
||||
"""
|
||||
get_contract = getattr(self.workflowmanager, "get_action_contract", None)
|
||||
if not get_contract:
|
||||
return {}
|
||||
return get_contract(action.type) or {}
|
||||
|
||||
def get_flow_condition(self, flow: ActionFlow) -> Optional[str]:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user