workflow
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from runtime.executor import Executor, ExecutorConfig, StepResult, ToolCallable
|
||||
from runtime.planner import PlannedStep
|
||||
from skills_learning.models import FlowTemplateSkill
|
||||
|
||||
|
||||
class SkillExecutionError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def validate_skill_args(skill: FlowTemplateSkill, args: dict[str, Any]) -> None:
|
||||
if skill.metadata.kind != "flow_template":
|
||||
raise SkillExecutionError(f"skill {skill.id} is not a flow_template skill")
|
||||
required = set(skill.parameters)
|
||||
provided = set(args)
|
||||
missing = sorted(required - provided)
|
||||
extra = sorted(provided - required)
|
||||
errors: list[str] = []
|
||||
if missing:
|
||||
errors.append(f"missing required parameters: {', '.join(missing)}")
|
||||
if extra:
|
||||
errors.append(f"unrecognized parameters: {', '.join(extra)}")
|
||||
if errors:
|
||||
raise SkillExecutionError("; ".join(errors))
|
||||
|
||||
|
||||
def resolve_skill_steps(
|
||||
skill: FlowTemplateSkill,
|
||||
args: dict[str, Any],
|
||||
) -> list[dict[str, Any]]:
|
||||
validate_skill_args(skill, args)
|
||||
return [
|
||||
{
|
||||
"tool_name": step.tool_name,
|
||||
"args": _resolve_value(step.args, args),
|
||||
}
|
||||
for step in skill.steps
|
||||
]
|
||||
|
||||
|
||||
def run_flow_template_skill(
|
||||
skill: FlowTemplateSkill,
|
||||
args: dict[str, Any],
|
||||
*,
|
||||
tools: dict[str, ToolCallable] | None = None,
|
||||
) -> list[StepResult]:
|
||||
resolved_steps = resolve_skill_steps(skill, args)
|
||||
executor = Executor(
|
||||
tools=tools,
|
||||
config=ExecutorConfig(max_retries=1, backoff_seconds=0),
|
||||
)
|
||||
results: list[StepResult] = []
|
||||
for index, resolved in enumerate(resolved_steps, start=1):
|
||||
step = PlannedStep(
|
||||
action=resolved["tool_name"],
|
||||
description=f"Run skill {skill.name} step {index}",
|
||||
args=resolved["args"],
|
||||
)
|
||||
result = executor.execute(step)
|
||||
results.append(result)
|
||||
if not result.success:
|
||||
break
|
||||
return results
|
||||
|
||||
|
||||
def _resolve_value(value: Any, args: dict[str, Any]) -> Any:
|
||||
if isinstance(value, str) and value.startswith("{") and value.endswith("}"):
|
||||
name = value[1:-1]
|
||||
return args[name]
|
||||
if isinstance(value, dict):
|
||||
return {key: _resolve_value(nested, args) for key, nested in value.items()}
|
||||
if isinstance(value, list):
|
||||
return [_resolve_value(item, args) for item in value]
|
||||
return value
|
||||
Reference in New Issue
Block a user