新增内部Task系统,包括验证、反馈门控机制,实现自动质量验证 (通过率>=0.75)和用户反馈闭环(satisfied/revise/abandon)。 实现Agent Team v1协调器,支持sequence/parallel/dag执行策略, sub-agent复用主AgentLoop,每个run使用独立memory snapshot。 建立Skill学习pipeline,包含draft/审核/发布/回滚完整生命周期, 通过Task验证通过且用户满意才生成学习候选。 重构目录结构,移除third_party依赖,建立统一engine内核, 所有agent共享运行时基础组件。 更新ContextBuilder清理provider消息字段,增强SkillContext版本管理, 集成TaskExecutionPlanner和TaskSkillResolver实现技能解析机制。
143 lines
4.5 KiB
Python
143 lines
4.5 KiB
Python
"""Run-level receipts and skill effect records."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from typing import Any
|
|
|
|
from beaver.skills.specs import SkillActivationReceipt
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class RunOutcome:
|
|
success: bool
|
|
finish_reason: str
|
|
feedback_score: float | None = None
|
|
notes: str = ""
|
|
|
|
def to_dict(self) -> dict[str, Any]:
|
|
return {
|
|
"success": self.success,
|
|
"finish_reason": self.finish_reason,
|
|
"feedback_score": self.feedback_score,
|
|
"notes": self.notes,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, payload: dict[str, Any]) -> "RunOutcome":
|
|
return cls(
|
|
success=bool(payload.get("success")),
|
|
finish_reason=str(payload.get("finish_reason") or ""),
|
|
feedback_score=_coerce_optional_float(payload.get("feedback_score")),
|
|
notes=str(payload.get("notes") or ""),
|
|
)
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class RunRecord:
|
|
run_id: str
|
|
session_id: str
|
|
task_text: str
|
|
started_at: str
|
|
ended_at: str
|
|
success: bool
|
|
finish_reason: str
|
|
feedback: dict[str, Any] = field(default_factory=dict)
|
|
activated_skills: list[SkillActivationReceipt] = field(default_factory=list)
|
|
task_id: str | None = None
|
|
attempt_index: int | None = None
|
|
validation_result: dict[str, Any] | None = None
|
|
|
|
def to_dict(self) -> dict[str, Any]:
|
|
return {
|
|
"run_id": self.run_id,
|
|
"session_id": self.session_id,
|
|
"task_id": self.task_id,
|
|
"attempt_index": self.attempt_index,
|
|
"task_text": self.task_text,
|
|
"started_at": self.started_at,
|
|
"ended_at": self.ended_at,
|
|
"success": self.success,
|
|
"finish_reason": self.finish_reason,
|
|
"feedback": dict(self.feedback),
|
|
"activated_skills": [receipt.to_dict() for receipt in self.activated_skills],
|
|
"validation_result": self.validation_result,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, payload: dict[str, Any]) -> "RunRecord":
|
|
return cls(
|
|
run_id=str(payload["run_id"]),
|
|
session_id=str(payload["session_id"]),
|
|
task_id=_coerce_optional_str(payload.get("task_id")),
|
|
attempt_index=_coerce_optional_int(payload.get("attempt_index")),
|
|
task_text=str(payload.get("task_text") or ""),
|
|
started_at=str(payload.get("started_at") or ""),
|
|
ended_at=str(payload.get("ended_at") or ""),
|
|
success=bool(payload.get("success")),
|
|
finish_reason=str(payload.get("finish_reason") or ""),
|
|
feedback=dict(payload.get("feedback") or {}),
|
|
activated_skills=[
|
|
SkillActivationReceipt.from_dict(item)
|
|
for item in payload.get("activated_skills") or []
|
|
if isinstance(item, dict)
|
|
],
|
|
validation_result=(
|
|
dict(payload["validation_result"])
|
|
if isinstance(payload.get("validation_result"), dict)
|
|
else None
|
|
),
|
|
)
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class SkillEffectRecord:
|
|
run_id: str
|
|
skill_name: str
|
|
skill_version: str
|
|
success: bool
|
|
feedback_score: float | None
|
|
notes: str
|
|
created_at: str
|
|
|
|
def to_dict(self) -> dict[str, Any]:
|
|
return {
|
|
"run_id": self.run_id,
|
|
"skill_name": self.skill_name,
|
|
"skill_version": self.skill_version,
|
|
"success": self.success,
|
|
"feedback_score": self.feedback_score,
|
|
"notes": self.notes,
|
|
"created_at": self.created_at,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, payload: dict[str, Any]) -> "SkillEffectRecord":
|
|
return cls(
|
|
run_id=str(payload["run_id"]),
|
|
skill_name=str(payload["skill_name"]),
|
|
skill_version=str(payload["skill_version"]),
|
|
success=bool(payload.get("success")),
|
|
feedback_score=_coerce_optional_float(payload.get("feedback_score")),
|
|
notes=str(payload.get("notes") or ""),
|
|
created_at=str(payload.get("created_at") or ""),
|
|
)
|
|
|
|
|
|
def _coerce_optional_float(value: Any) -> float | None:
|
|
if value in (None, ""):
|
|
return None
|
|
return float(value)
|
|
|
|
|
|
def _coerce_optional_int(value: Any) -> int | None:
|
|
if value in (None, ""):
|
|
return None
|
|
return int(value)
|
|
|
|
|
|
def _coerce_optional_str(value: Any) -> str | None:
|
|
if value in (None, ""):
|
|
return None
|
|
return str(value)
|