feat: add skill learning runtime
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from skills_learning.models import FlowStep, FlowTemplateSkill
|
||||
from skills_learning.store import SkillStore
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class VersionDiff:
|
||||
structural_divergence: bool
|
||||
stored_sequence: list[str]
|
||||
executed_sequence: list[str]
|
||||
argument_differences: list[tuple[int, str, Any, Any]]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class VersioningResult:
|
||||
skill: FlowTemplateSkill
|
||||
created_new_version: bool
|
||||
|
||||
|
||||
def diff_flow_versions(
|
||||
stored_steps: list[FlowStep],
|
||||
executed_steps: list[FlowStep],
|
||||
) -> VersionDiff:
|
||||
stored_sequence = [step.tool_name for step in stored_steps]
|
||||
executed_sequence = [step.tool_name for step in executed_steps]
|
||||
structural = stored_sequence != executed_sequence
|
||||
differences: list[tuple[int, str, Any, Any]] = []
|
||||
if not structural:
|
||||
for index, (stored_step, executed_step) in enumerate(
|
||||
zip(stored_steps, executed_steps, strict=True)
|
||||
):
|
||||
keys = set(stored_step.args) | set(executed_step.args)
|
||||
for key in sorted(keys):
|
||||
stored_value = stored_step.args.get(key)
|
||||
executed_value = executed_step.args.get(key)
|
||||
if stored_value != executed_value:
|
||||
differences.append((index, key, stored_value, executed_value))
|
||||
return VersionDiff(
|
||||
structural_divergence=structural,
|
||||
stored_sequence=stored_sequence,
|
||||
executed_sequence=executed_sequence,
|
||||
argument_differences=differences,
|
||||
)
|
||||
|
||||
|
||||
def store_synthesized_skill(
|
||||
store: SkillStore,
|
||||
candidate: FlowTemplateSkill,
|
||||
) -> VersioningResult:
|
||||
latest = store.get_latest_by_name(candidate.name)
|
||||
if latest is None:
|
||||
return VersioningResult(store.create_version(candidate), True)
|
||||
|
||||
diff = diff_flow_versions(latest.steps, candidate.steps)
|
||||
if diff.structural_divergence:
|
||||
return VersioningResult(store.create_version(candidate, parent=latest), True)
|
||||
|
||||
merged_parameters = {
|
||||
**latest.parameters,
|
||||
**candidate.parameters,
|
||||
}
|
||||
updated = latest.with_updates(
|
||||
steps=candidate.steps,
|
||||
parameters=merged_parameters,
|
||||
description=candidate.description,
|
||||
originating_goal=candidate.originating_goal,
|
||||
)
|
||||
return VersioningResult(store.update_skill(updated), False)
|
||||
Reference in New Issue
Block a user