Spaces:
Sleeping
Sleeping
File size: 3,116 Bytes
116524e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | """UpdateStep — runs the SkillManager, which mutates the skillbook in place."""
from __future__ import annotations
from ..core.context import ACEStepContext
from ..core.insight_source import InsightSource, infer_trace_identity
from ..core.skillbook import Skillbook
from ..protocols import SkillManagerLike
class UpdateStep:
"""Run the agentic SkillManager against the current reflection.
The SkillManager mutates the real :class:`Skillbook` directly through
its tools (``add_skill`` / ``update_skill`` / ``remove_skill`` /
``tag_skill``). By the time this step returns the skillbook already
reflects the changes — ``ctx.skill_manager_output`` is a post-hoc
audit log, not a plan to apply.
``max_workers = 1`` because the SM reads the current skillbook state
and mutates it; concurrent calls would see stale state and race on
writes.
"""
requires = frozenset({"reflections", "skillbook"})
provides = frozenset({"skill_manager_output"})
max_workers = 1
def __init__(self, skill_manager: SkillManagerLike, skillbook: Skillbook) -> None:
self.skill_manager = skill_manager
self.skillbook = skillbook
def __call__(self, ctx: ACEStepContext) -> ACEStepContext:
progress = f"Epoch {ctx.epoch}/{ctx.total_epochs}"
if ctx.total_steps is not None:
progress += f", sample {ctx.step_index}/{ctx.total_steps}"
sample = getattr(ctx, "sample", None)
sample_question = getattr(sample, "question", "") or ""
sample_context = getattr(sample, "context", "") or ""
question_context = ""
if isinstance(ctx.trace, dict):
q = str(ctx.trace.get("question", "") or "")
c = str(ctx.trace.get("context", "") or "")
question_context = f"{q}\n{c}".strip() if c else q
elif sample_question:
question_context = (
f"{sample_question}\n{sample_context}".strip()
if sample_context
else sample_question
)
identity = infer_trace_identity(
trace=ctx.trace,
sample=sample,
metadata=ctx.metadata,
)
reflection = ctx.reflections[0]
source = InsightSource(
trace_uid=identity.trace_uid or "",
source_system=identity.source_system,
trace_id=identity.trace_id,
display_name=identity.display_name,
sample_question=sample_question or None,
epoch=ctx.epoch,
error_identification=reflection.error_identification or None,
learning_text=reflection.key_insight or None,
)
output = self.skill_manager.update_skills(
reflections=ctx.reflections,
skillbook=self.skillbook,
question_context=question_context,
progress=progress,
source=source,
injected_skill_ids=ctx.injected_skill_ids,
)
return ctx.replace(skill_manager_output=output.update)
|