feat: add skill learning runtime

This commit is contained in:
2026-07-06 18:07:53 +08:00
parent 5658735bca
commit c7ae2d86ec
17 changed files with 1470 additions and 31 deletions
+72
View File
@@ -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)