feat(learning): add learning runtime with pattern mining
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
72
backend/app/agents/learning/signal_extractor.py
Normal file
72
backend/app/agents/learning/signal_extractor.py
Normal file
@@ -0,0 +1,72 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from app.agents.schemas.learning import LearningSignal, SessionRetrospective
|
||||
|
||||
|
||||
class RetrospectiveSignalExtractor:
|
||||
def extract(self, retrospective: SessionRetrospective) -> list[LearningSignal]:
|
||||
signals: list[LearningSignal] = []
|
||||
|
||||
if retrospective.outcome == "completed":
|
||||
signals.append(
|
||||
LearningSignal(
|
||||
signal_type="workflow",
|
||||
confidence=0.8,
|
||||
evidence_refs=retrospective.evidence_refs[:3],
|
||||
explanation="Completed runs can be mined as workflow hints later.",
|
||||
payload={
|
||||
"task_type": retrospective.task_type,
|
||||
"execution_mode": retrospective.execution_mode,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
if len(retrospective.task_refs) > 1:
|
||||
context_snapshot = retrospective.context_snapshot or {}
|
||||
merge_report = dict(context_snapshot.get("merge_report") or {})
|
||||
verification_report = dict(context_snapshot.get("verification_report") or {})
|
||||
effectiveness_score = 1.0
|
||||
if merge_report.get("status") == "conflicted":
|
||||
effectiveness_score = 0.45
|
||||
elif merge_report.get("status") == "fallback":
|
||||
effectiveness_score = 0.25
|
||||
elif verification_report.get("status") == "failed":
|
||||
effectiveness_score = 0.3
|
||||
signals.append(
|
||||
LearningSignal(
|
||||
signal_type="decomposition",
|
||||
confidence=0.7,
|
||||
evidence_refs=retrospective.task_refs[:3],
|
||||
explanation="Multiple completed task refs indicate a decomposition pattern.",
|
||||
payload={
|
||||
"task_count": len(retrospective.task_refs),
|
||||
"scheduled_subtask_count": context_snapshot.get("scheduled_subtask_count", 0),
|
||||
"effectiveness_score": effectiveness_score,
|
||||
"merge_status": merge_report.get("status"),
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
if retrospective.used_skill_names:
|
||||
signals.append(
|
||||
LearningSignal(
|
||||
signal_type="tool_success",
|
||||
confidence=0.65 if retrospective.outcome == "completed" else 0.35,
|
||||
evidence_refs=retrospective.evidence_refs[:2],
|
||||
explanation="Task-scoped skill shortlist was available during this run.",
|
||||
payload={"skills": retrospective.used_skill_names[:3]},
|
||||
)
|
||||
)
|
||||
|
||||
if retrospective.outcome == "failed":
|
||||
signals.append(
|
||||
LearningSignal(
|
||||
signal_type="correction",
|
||||
confidence=0.75,
|
||||
evidence_refs=retrospective.evidence_refs[:2],
|
||||
explanation="Failed retrospectives should remain auditable before any promotion.",
|
||||
payload={"verification_status": retrospective.verification_status},
|
||||
)
|
||||
)
|
||||
|
||||
return signals
|
||||
Reference in New Issue
Block a user